[
  {
    "path": ".github/workflows/test.yml",
    "content": "on: [push, pull_request]\nname: Test\njobs:\n  test:\n    strategy:\n      matrix:\n        go-version: [1.17.x]\n        os: [ubuntu-latest, macos-latest, windows-latest]\n    runs-on: ${{ matrix.os }}\n    steps:\n    - uses: actions/setup-go@v3\n      with:\n        go-version: ${{ matrix.go-version }}\n    - uses: actions/checkout@v3\n    - run: go install golang.org/x/tools/cmd/stringer@latest\n    - run: go test ./...\n"
  },
  {
    "path": ".gitignore",
    "content": "/cmd/bitstringer/bitstringer\n/cmd/branchstats/branchstats\n/cmd/memanim/memanim\n/cmd/memheat/memheat\n/cmd/memlat/memlat\n/cmd/perfdump/perfdump\n/cmd/prologuer/prologuer\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2015 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "README.md",
    "content": "go-perf is a set of tools for working with Linux perf.data profiles,\nas well as a set of Go packages for parsing and interpreting such\nprofiles.\n\nmemlat\n------\n\nmemlat is a web-based interactive browser for memory load latency\nprofiles. Such profiles give deep and detailed insight in to the\nsources of memory stalls and conflicts, but are difficult to interpret\nusing traditional profiling tools. See the\n[detailed documentation on godoc](http://godoc.org/github.com/aclements/go-perf/cmd/memlat).\n\nThere is also a predecessor of memlat in `cmd/memheat`. This tool\ngenerates static SVG files summarizing memory load latency\ndistributions by function and source line. This may be removed in the\nfuture.\n\ndump\n----\n\ndump prints the detailed decoded contents of a perf.data profile. It's\nsimilar to `perf report -D`, but is somewhat less mysterious. It's\nparticularly useful when developing with the perffile library because\nit prints everything in terms of perffile structures.\n\nLibraries\n---------\n\nThis repository also contains two Go packages for parsing and\ninterpreting perf.data files.\n\n[perffile](http://godoc.org/github.com/aclements/go-perf/perffile)\nprovides a parser for perf.data files. It can interpret all current\nrecord types and almost all metadata fields.\n\n[perfsession](http://godoc.org/github.com/aclements/go-perf/perfsession)\nprovides utilities for tracking session state while processing a\nperf.data file. Its API is still evolving and should be considered\nunstable.\n"
  },
  {
    "path": "cmd/bitstringer/main.go",
    "content": "// Copyright 2016 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Command bitstringer generates String methods for bit-mask types.\n//\n// bitstringer is like the stringer tool, but for bit-mask types. See\n// go doc stringer for details.\n//\n// bitstringer adds one flag, -strip, which specifies a prefix to\n// strip from stringified-constants. For bit-mask types in particular,\n// this can make the string representation much shorter, at the\n// expense of not being unambiguous and syntactically valid Go code.\npackage main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"go/ast\"\n\t\"go/build\"\n\t\"go/constant\"\n\t\"go/importer\"\n\t\"go/parser\"\n\t\"go/token\"\n\t\"go/types\"\n\t\"io\"\n\t\"log\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n)\n\nfunc main() {\n\tflagTypes := flag.String(\"type\", \"\", \"comma-separated list of `types` to generate Stringers for\")\n\tflagStrip := flag.String(\"strip\", \"\", \"strip `prefix` from constant names\")\n\tflag.Parse()\n\tif flag.NArg() != 0 {\n\t\tflag.PrintDefaults()\n\t\tos.Exit(2)\n\t}\n\n\t// Find source files.\n\twd, err := os.Getwd()\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tpkg, err := build.ImportDir(wd, 0)\n\tif err != nil {\n\t\tlog.Fatalf(\"importing %s: %v\", wd, err)\n\t}\n\tpaths := prefixDirectory(pkg.Dir, pkg.GoFiles)\n\n\t// Parse source files.\n\tfset := token.NewFileSet()\n\tvar files []*ast.File\n\tfor _, path := range paths {\n\t\tf, err := parser.ParseFile(fset, path, nil, 0)\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"parsing file %s: %v\", path, err)\n\t\t}\n\t\tfiles = append(files, f)\n\t}\n\n\t// Type check.\n\tconf := types.Config{Importer: importer.Default(), FakeImportC: true}\n\tinfo := &types.Info{\n\t\tDefs: make(map[*ast.Ident]types.Object),\n\t}\n\ttypesPkg, err := conf.Check(pkg.ImportPath, fset, files, info)\n\tif err != nil {\n\t\tlog.Fatalf(\"checking package: %v\", err)\n\t}\n\tscope := typesPkg.Scope()\n\n\t// Find the requested Types.\n\tnames := strings.Split(*flagTypes, \",\")\n\tname2Type := map[string]types.Type{}\n\tconsts := map[types.Type][]*types.Const{}\n\tfor _, name := range names {\n\t\ttname, ok := scope.Lookup(name).(*types.TypeName)\n\t\tif !ok {\n\t\t\tlog.Fatalf(\"unknown type %q\", name)\n\t\t}\n\t\t// Check that it's integral.\n\t\tutype := tname.Type().Underlying()\n\t\tif utype, ok := utype.(*types.Basic); !ok || utype.Info()&types.IsInteger == 0 {\n\t\t\tlog.Fatalf(\"type %q is not an integer type\", name)\n\t\t}\n\t\tname2Type[name] = tname.Type()\n\t\tconsts[tname.Type()] = nil\n\t}\n\n\t// Find all constants with each Type.\n\tfor _, name := range scope.Names() {\n\t\tobj := scope.Lookup(name)\n\t\tcobj, ok := obj.(*types.Const)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tconstList, ok := consts[cobj.Type()]\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tconstList = append(constList, cobj)\n\t\tconsts[cobj.Type()] = constList\n\t}\n\n\t// Construct String methods.\n\tfor _, name := range names {\n\t\tfname := strings.ToLower(name) + \"_string.go\"\n\t\tf, err := os.Create(fname)\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"error creating %s: %v\", fname, err)\n\t\t}\n\t\ttyp := name2Type[name]\n\t\twriteStringer(f, pkg.Name, name, *flagStrip, consts[typ])\n\t\tif err := f.Close(); err != nil {\n\t\t\tlog.Fatalf(\"error writing %s: %v\", fname, err)\n\t\t}\n\t}\n}\n\nfunc prefixDirectory(dir string, names []string) []string {\n\tif dir == \".\" {\n\t\treturn names\n\t}\n\tout := make([]string, len(names))\n\tfor i, name := range names {\n\t\tout[i] = filepath.Join(dir, name)\n\t}\n\treturn out\n}\n\nfunc writeStringer(w io.Writer, pkg, tname, prefix string, consts []*types.Const) {\n\tif len(consts) == 0 {\n\t\tfmt.Fprintf(os.Stderr, \"warning: no consts for type %q\\n\", tname)\n\t}\n\n\tfmt.Fprintf(w, `// Code generated by \"bitstringer -type=%s\"; DO NOT EDIT\n\npackage %s\n\nimport \"strconv\"\n\nfunc (i %s) String() string {\n`, tname, pkg, tname)\n\n\tstrip := func(s string) string {\n\t\treturn strings.TrimPrefix(s, prefix)\n\t}\n\n\t// Find and format any zero value.\n\tzero := constant.MakeInt64(0)\n\tzlabel := \"0\"\n\tfor _, c := range consts {\n\t\tval := c.Val()\n\t\tif constant.Compare(val, token.EQL, zero) {\n\t\t\t// Format it.\n\t\t\tzlabel = strip(c.Name())\n\t\t\tbreak\n\t\t}\n\t}\n\tfmt.Fprintf(w, \"\\tif i == 0 {\\n\\t\\treturn %q\\n\\t}\\n\", zlabel)\n\n\t// Create bit value formatters.\n\tfmt.Fprintf(w, \"\\ts := \\\"\\\"\\n\")\n\thave := constant.MakeInt64(0)\n\tfor _, c := range consts {\n\t\t// Does this contribute to the bit set?\n\t\thave2 := constant.BinaryOp(have, token.OR, c.Val())\n\t\tif constant.Compare(have, token.EQL, have2) {\n\t\t\t// Nope.\n\t\t\tcontinue\n\t\t}\n\t\thave = have2\n\t\t// Format it.\n\t\tfmt.Fprintf(w, \"\\tif i&%s != 0 {\\n\\t\\ts += %q\\n\\t}\\n\", c.Name(), strip(c.Name())+\"|\")\n\t}\n\t// Handle any left-over bits.\n\tfmt.Fprintf(w, `\ti &^= %s\n\tif i == 0 {\n\t\treturn s[:len(s)-1]\n\t}\n\treturn s + \"0x\" + strconv.FormatUint(uint64(i), 16)\n}\n`, have.ExactString())\n}\n"
  },
  {
    "path": "cmd/branchstats/main.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Command branchstats analyzes branch profiles for branch mispredict\n// rates.\n//\n// branchstats expects a perf.data collected with\n//\n//     perf record -e branches -j any -c 400009\n//\n// To collect only branches in user-space code, use\n//\n//     perf record -e branches:u -j any,u -c 400009\n//\n// The output is a table like\n//\n//     comm     PC                               branches mispredicts\n//     bench    scanner.go:258                  419609441 309206957 (73.7%)\n//         257 func isLetter(ch rune) bool {\n//         258         return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= 0x80 && unicode.IsLetter(ch)\n//         259 }\n//\n//     bench    mgcmark.go:1000                1967244262 236405319 (12.0%)\n//         999 }\n//        1000 if bits&bitPointer == 0 {\n//        1001         continue // not a pointer\n//\n// Each row shows a branch at a particular location and gives the\n// estimated number of times that branch executed, the estimated\n// number of mispredicts, and the mispredict rate. The table is sorted\n// by the number of mispredicts.\npackage main\n\nimport (\n\t\"bufio\"\n\t\"flag\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sort\"\n\n\t\"github.com/aclements/go-perf/perffile\"\n\t\"github.com/aclements/go-perf/perfsession\"\n)\n\ntype PC struct {\n\tPC   uint64\n\tComm string\n}\n\ntype Agg struct {\n\tMmap         *perfsession.Mmap\n\tEvents       uint64\n\tPredicted    int64\n\tMispredicted int64\n}\n\ntype pair struct {\n\tPC\n\tAgg\n\trate float64\n}\n\nfunc main() {\n\tvar (\n\t\tflagInput = flag.String(\"i\", \"perf.data\", \"input perf.data `file`\")\n\t)\n\tflag.Parse()\n\tif flag.NArg() > 0 {\n\t\tflag.Usage()\n\t\tos.Exit(1)\n\t}\n\n\tf, err := perffile.Open(*flagInput)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer f.Close()\n\ts := perfsession.New(f)\n\n\tagg := make(map[PC]Agg)\n\n\tconst requiredFormat = perffile.SampleFormatTID | perffile.SampleFormatBranchStack\n\trs := f.Records(perffile.RecordsCausalOrder)\n\tfor rs.Next() {\n\t\tr := rs.Record\n\t\ts.Update(r)\n\n\t\tswitch r := r.(type) {\n\t\tcase *perffile.RecordSample:\n\t\t\tif r.Format&requiredFormat != requiredFormat {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tpidinfo := s.LookupPID(r.PID)\n\t\t\tcomm := \"<unknown>\"\n\t\t\tvar mmap *perfsession.Mmap\n\t\t\tif pidinfo != nil {\n\t\t\t\tcomm = pidinfo.Comm\n\t\t\t\tmmap = pidinfo.LookupMmap(r.BranchStack[0].From)\n\t\t\t}\n\n\t\t\t// We ignore the location of the sample\n\t\t\t// because it's often not a branch (even in\n\t\t\t// precise mode). Instead, we take the most\n\t\t\t// recent branch record as an unbiased,\n\t\t\t// precise sampling of branches. Similarly, we\n\t\t\t// only take the prediction information from\n\t\t\t// the most recent branch. (Too bad there's no\n\t\t\t// way to tell perf we only want one branch\n\t\t\t// record.)\n\t\t\tbr := r.BranchStack[0]\n\t\t\tpc := PC{br.From, comm}\n\n\t\t\tvar events uint64\n\t\t\tif r.Format&perffile.SampleFormatPeriod != 0 {\n\t\t\t\tevents = r.Period\n\t\t\t} else if r.EventAttr.Flags&perffile.EventFlagFreq == 0 {\n\t\t\t\tevents = r.EventAttr.SamplePeriod\n\t\t\t} else {\n\t\t\t\tlog.Fatalf(\"sample %+v has no period\", r)\n\t\t\t}\n\n\t\t\ta := agg[pc]\n\t\t\ta.Events += events\n\t\t\ta.Mmap = mmap\n\t\t\tif br.Flags&perffile.BranchFlagMispredicted != 0 {\n\t\t\t\ta.Mispredicted++\n\t\t\t}\n\t\t\tif br.Flags&perffile.BranchFlagPredicted != 0 {\n\t\t\t\ta.Predicted++\n\t\t\t}\n\t\t\tagg[pc] = a\n\t\t}\n\t}\n\tif err := rs.Err(); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// Rescale and sort records.\n\tpairs := make([]pair, 0)\n\tfor pc, a := range agg {\n\t\tif a.Events == 0 {\n\t\t\tcontinue\n\t\t}\n\t\trate := float64(a.Mispredicted) / float64(a.Predicted+a.Mispredicted)\n\t\ta.Mispredicted = int64(rate * float64(a.Events))\n\t\ta.Predicted = int64(a.Events) - a.Mispredicted\n\n\t\tpairs = append(pairs, pair{pc, a, rate})\n\t}\n\tsort.Sort(sort.Reverse(pairSorter(pairs)))\n\n\t// Print summary information.\n\tvar total Agg\n\tfor _, a := range pairs {\n\t\ttotal.Events += a.Events\n\t\ttotal.Mispredicted += a.Mispredicted\n\t\ttotal.Predicted += a.Predicted\n\t}\n\tfmt.Printf(\"# Total branches: %d\\n\", total.Events)\n\tfmt.Printf(\"# Total mispredicts: %d (%2.1f%% of all branches)\\n\", total.Mispredicted, 100*float64(total.Mispredicted)/float64(total.Events))\n\tfmt.Printf(\"\\n\")\n\n\t// Print branch details.\n\tvar sym perfsession.Symbolic\n\tfmt.Printf(\"%-8s %-24s %16s %s\\n\", \"comm\", \"PC\", \"branches\", \"mispredicts\")\n\tfor _, pair := range pairs {\n\t\tvar pos string\n\t\tvar lines []string\n\t\tif pair.Mmap != nil && perfsession.Symbolize(s, pair.Mmap, pair.PC.PC, &sym) && sym.Line.File != nil {\n\t\t\tpos = fmt.Sprintf(\"%s:%d\", filepath.Base(sym.Line.File.Name), sym.Line.Line)\n\t\t\tlines, _ = getLines(sym.Line.File.Name, sym.Line.Line-1, sym.Line.Line+1)\n\t\t} else {\n\t\t\tpos = fmt.Sprintf(\"%#-24x\", pair.PC.PC)\n\t\t\tlines = nil\n\t\t}\n\n\t\tfmt.Printf(\"%-8.8s %-24s %16d %d (%2.1f%%)\\n\", pair.Comm, pos, pair.Events, pair.Mispredicted, 100*pair.rate)\n\t\ttrim := stringCommon(lines)\n\t\tfor i, line := range lines {\n\t\t\tfmt.Printf(\"%7d %s\\n\", i+sym.Line.Line-1, line[trim:])\n\t\t}\n\t\tfmt.Printf(\"\\n\")\n\t}\n}\n\ntype pairSorter []pair\n\nfunc (p pairSorter) Len() int {\n\treturn len(p)\n}\n\nfunc (p pairSorter) Swap(i, j int) {\n\tp[i], p[j] = p[j], p[i]\n}\n\nfunc (p pairSorter) Less(i, j int) bool {\n\tif p[i].Mispredicted != p[j].Mispredicted {\n\t\treturn p[i].Mispredicted < p[j].Mispredicted\n\t}\n\tif p[i].Events != p[j].Events {\n\t\treturn p[i].Events < p[j].Events\n\t}\n\tif p[i].Comm != p[j].Comm {\n\t\treturn p[i].Comm < p[j].Comm\n\t}\n\treturn p[i].PC.PC < p[j].PC.PC\n}\n\nfunc getLines(path string, minLine, maxLine int) ([]string, error) {\n\t// TODO: Make a nice line cache API. This isn't the only place\n\t// I've needed this.\n\n\tlines := make([]string, maxLine-minLine+1)\n\n\tfile, err := os.Open(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer file.Close()\n\n\t// Skip to minLine.\n\tscanner := bufio.NewScanner(file)\n\tfor i := 0; i < minLine && scanner.Scan(); i++ {\n\t\t// Do nothing\n\t}\n\n\tfor line := minLine; line <= maxLine && scanner.Err() == nil; line++ {\n\t\tlines[line-minLine] = scanner.Text()\n\t\tscanner.Scan()\n\t}\n\tif err := scanner.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn lines, nil\n}\n\nfunc stringCommon(strs []string) int {\n\tif len(strs) == 0 {\n\t\treturn 0\n\t}\n\n\tfor i := 0; i < len(strs[0]); i++ {\n\t\tc := strs[0][i]\n\t\tfor _, s := range strs {\n\t\t\tif i == len(s) || s[i] != c {\n\t\t\t\treturn i\n\t\t\t}\n\t\t}\n\t}\n\treturn len(strs[0])\n}\n"
  },
  {
    "path": "cmd/memanim/.gitignore",
    "content": "/addr.png\n/f*.png\n/out.mp4\n/memanim\n"
  },
  {
    "path": "cmd/memanim/hilbert_test.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport \"testing\"\n\nfunc TestHilbert(t *testing.T) {\n\tconst n = 64\n\tx0, y0 := hilbert(n, 0)\n\thave := make([]bool, n*n)\n\thave[x0+y0*n] = true\n\tfor d := 1; d < n*n; d++ {\n\t\tx1, y1 := hilbert(n, d)\n\t\tif !(x0 == x1 && abs(y0-y1) == 1 ||\n\t\t\ty0 == y1 && abs(x0-x1) == 1) {\n\t\t\tt.Fatalf(\"moved by more than 1: (%d,%d) -> (%d,%d)\", x0, y0, x1, y1)\n\t\t}\n\t\tif have[x1+y1*n] {\n\t\t\tt.Fatalf(\"repeated point (%d,%d)\", x1, y1)\n\t\t}\n\t\thave[x1+y1*n] = true\n\t\tx0, y0 = x1, y1\n\t}\n}\n\nfunc abs(n int) int {\n\tif n < 0 {\n\t\treturn -n\n\t}\n\treturn n\n}\n"
  },
  {
    "path": "cmd/memanim/main.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Command memanim creates an animation of memory accesses over time\n// from a \"perf mem record\" profile. In the animation, the address\n// space is compacted to remove pages that have no recorded references\n// and then mapped on to Hilbert curve so that nearby accesses appear\n// nearby in 2-D space. It is then broken in to panels showing all\n// accesses, L2-and-up accesses, etc.\n//\n// The simplest way to record a memory load profile is \"perf mem\n// record <cmd>\".\n//\n// To record only load latency events over a threshold number of\n// cycles, use the following command on Sandy Bridge or later:\n//\n//   perf record -W -d -e cpu/event=0xcd,umask=0x1,ldlat=<thresh>/pp <cmd>\n//\n// The minimum (and default) latency threshold is 3 cycles.\n//\n// At a reasonably high latency threshold, such as 50 cycles, it's\n// possible to crank up to recording every single load with, e.g.,\n// --count 1 -m 1024.\n//\n// To collect only user-space loads, change pp to ppu.\npackage main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"image\"\n\t\"image/color\"\n\t\"image/draw\"\n\t\"image/png\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"math\"\n\t\"os\"\n\t\"runtime/pprof\"\n\t\"sort\"\n\n\t\"github.com/aclements/go-perf/perffile\"\n\t\"github.com/golang/freetype\"\n)\n\nconst pageBytes = 4096\n\nfunc main() {\n\tvar (\n\t\tflagInput      = flag.String(\"i\", \"perf.data\", \"read memory latency profile from `file`\")\n\t\tflagBy         = flag.String(\"by\", \"address\", \"`layout` by \\\"address\\\" or \\\"pc\\\"\")\n\t\tflagFPS        = flag.Int(\"fps\", 24, \"frames per second\")\n\t\tflagDilation   = flag.Float64(\"dilation\", 1, \"time dilation factor\")\n\t\tflagWidth      = flag.Int(\"w\", 512, \"output width/height; must be a power of 2\")\n\t\tflagCpuProfile = flag.String(\"cpuprofile\", \"\", \"write cpu profile to file\")\n\t)\n\tflag.Parse()\n\tif flag.NArg() > 0 {\n\t\tflag.Usage()\n\t\tos.Exit(1)\n\t}\n\n\tif *flagWidth <= 0 || *flagWidth&(*flagWidth-1) != 0 {\n\t\tfmt.Fprintln(os.Stderr, \"width must be a power of two\")\n\t\tos.Exit(1)\n\t}\n\n\tif !(*flagBy == \"address\" || *flagBy == \"pc\") {\n\t\tfmt.Fprintln(os.Stderr, \"-by must be address or pc\")\n\t\tos.Exit(1)\n\t}\n\n\tif *flagCpuProfile != \"\" {\n\t\tf, err := os.Create(*flagCpuProfile)\n\t\tif err != nil {\n\t\t\tfmt.Fprintln(os.Stderr, err)\n\t\t\tos.Exit(1)\n\t\t}\n\t\tpprof.StartCPUProfile(f)\n\t\tdefer pprof.StopCPUProfile()\n\t}\n\n\t// TODO: Do something better with weight? I tried blue/red\n\t// coloring, but it really isn't obvious. Fade it out at a\n\t// certain rate? Shade? Ripples?\n\n\tevents := parsePerf(*flagInput, *flagBy)\n\n\t// Canonicalize the events.\n\timgSize := *flagWidth\n\tmapper := newAddrMapper(events, uint64(imgSize*imgSize-1))\n\tnormalizeWeight(events)\n\tzeroTime(events)\n\tlastTime := events[len(events)-1].time\n\n\t// Load font.\n\t//\n\t// TODO Don't hard-code it's location. Unfortunately, there's\n\t// no fontconfig equivalent for Go that I can find.\n\tfontCtx := freetype.NewContext()\n\tfontData, err := ioutil.ReadFile(\"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tfont, err := freetype.ParseFont(fontData)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tfontCtx.SetFontSize(12)\n\tfontCtx.SetSrc(image.Black)\n\tfontCtx.SetFont(font)\n\tfontBounds := font.Bounds(fontCtx.PointToFixed(12))\n\tlabelHeight := int((fontBounds.Max.Y - fontBounds.Min.Y) >> 6)\n\n\t// Create image.\n\timg := image.NewNRGBA(image.Rect(0, 0, (imgSize+1)*numPanels-1, imgSize+labelHeight))\n\tdraw.Draw(img, img.Bounds(), image.White, image.ZP, draw.Over)\n\tfontCtx.SetDst(img)\n\tfontCtx.SetClip(img.Bounds())\n\n\t// Construct sub-images for panels and draw framing elements.\n\tlevelImgs := make([]*image.NRGBA, numPanels)\n\tfor i := range levelImgs {\n\t\tleft := (imgSize + 1) * i\n\t\tlevelImgs[i] = img.SubImage(image.Rect(left, labelHeight, left+imgSize, imgSize+labelHeight)).(*image.NRGBA)\n\t\tlevelImgs[i].Rect = levelImgs[i].Rect.Sub(levelImgs[i].Rect.Min)\n\n\t\tif i > 0 {\n\t\t\tfor y := img.Rect.Min.Y; y < img.Rect.Max.Y; y++ {\n\t\t\t\timg.Set(left-1, y, color.Black)\n\t\t\t}\n\t\t}\n\t\tfontCtx.DrawString(\">= \"+panelLevels[i].String(), freetype.Pt(left+2, 12))\n\t}\n\n\t// Create address space reference image.\n\t//\n\t// TODO: This isn't very useful, it turns out. I could simply\n\t// print out the map from coordinate to address. Visually, I\n\t// could underlay boundaries between very distinct parts of\n\t// the address space (say, find points that have a >1GB break\n\t// and mark the boundary between all pixels before that break\n\t// and after that break).\n\tif false {\n\t\taddrStep := int(math.Floor(1 / mapper.normFactor))\n\t\tfor pfn := range mapper.pageBase {\n\t\t\tfor offset := 0; offset < pageBytes; offset += addrStep {\n\t\t\t\taddr := pfn*pageBytes + uint64(offset)\n\t\t\t\tx, y := hilbert(imgSize, int(mapper.mapAddr(addr)))\n\t\t\t\tnaddr := float64(addr%(1<<48)) / (1 << 48) * 2 * math.Pi\n\t\t\t\tcb, cr := math.Cos(naddr), -math.Sin(naddr)\n\t\t\t\t//fmt.Println(fmt.Sprintf(\"%016x\", addr), int(mapper.mapAddr(addr)), naddr, cb, cr)\n\t\t\t\tr, g, b := color.YCbCrToRGB(127, uint8((cb+1)*127), uint8((cr+1)*127))\n\t\t\t\timg.SetNRGBA(x, y, color.NRGBA{r, g, b, 255})\n\t\t\t}\n\t\t}\n\t\twritePNG(\"addr.png\", img)\n\t}\n\n\tnsPerFrame := int(1000000000 / (float64(*flagFPS) * *flagDilation))\n\tlastIndex := 0\n\tfor frame := 0; ; frame++ {\n\t\tt0 := uint64(frame * nsPerFrame)\n\t\tt1 := uint64((frame + 1) * nsPerFrame)\n\n\t\tif t0 > lastTime {\n\t\t\tbreak\n\t\t}\n\t\tlog.Println(\"frame\", frame)\n\n\t\t// Fade the frame.\n\t\t//\n\t\t// TODO: The fade rate should be proportional to FPS.\n\t\tfor _, levelImg := range levelImgs {\n\t\t\tfor y := 0; y < levelImg.Rect.Dy(); y++ {\n\t\t\t\tscan := levelImg.Pix[y*levelImg.Stride : y*levelImg.Stride+levelImg.Rect.Dx()*4]\n\t\t\t\tfor i, p := range scan {\n\t\t\t\t\tscan[i] = uint8(255 - (int(255-p) * 3 / 4))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Draw the events.\n\t\tfor evIndex, ev := range events[lastIndex:] {\n\t\t\tif ev.time < t0 {\n\t\t\t\tpanic(\"time went backwards\")\n\t\t\t}\n\t\t\tif t1 <= ev.time {\n\t\t\t\tlastIndex += evIndex\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\taddr := mapper.mapAddr(ev.addr)\n\t\t\tx, y := hilbert(imgSize, int(addr))\n\t\t\t//color := color.NRGBA{R: uint8(ev.weight), G: 0, B: 255 - uint8(ev.weight), A: 255}\n\t\t\tcolor := color.NRGBA{0, 0, 0, 255}\n\t\t\tfor level := 0; level <= ev.level; level++ {\n\t\t\t\tlevelImgs[level].SetNRGBA(x, y, color)\n\t\t\t}\n\t\t}\n\n\t\t// Write the frame out.\n\t\twritePNG(fmt.Sprintf(\"f%08d.png\", frame), img)\n\t}\n\n\tfmt.Printf(\"%g bytes/pixel\\n\", 1/mapper.normFactor)\n\tfmt.Printf(\"%g pixels/page\\n\", mapper.normFactor*pageBytes)\n\n\tfmt.Printf(\"To combine frames:\\n  mencoder 'mf://f*.png' -mf fps=%d -nosound -of lavf -lavfopts format=mp4 -ovc x264 -o out.mp4\\n\", *flagFPS)\n}\n\ntype event struct {\n\ttime   uint64\n\taddr   uint64\n\tweight uint64\n\tlevel  int\n}\n\n// parsePerf parses a perf.data profile and returns the cache miss\n// events.\nfunc parsePerf(fileName, by string) []event {\n\tf, err := perffile.Open(fileName)\n\tif err != nil {\n\t\tfmt.Fprintf(os.Stderr, \"error loading profile: %s\\n\", err)\n\t\tos.Exit(1)\n\t}\n\tdefer f.Close()\n\n\tbyPC := by == \"pc\"\n\n\tconst requiredFormat = perffile.SampleFormatTime | perffile.SampleFormatAddr | perffile.SampleFormatWeight | perffile.SampleFormatDataSrc\n\n\tevents := make([]event, 0)\n\trs := f.Records(perffile.RecordsTimeOrder)\n\tfor rs.Next() {\n\t\tr := rs.Record\n\t\tswitch r := r.(type) {\n\t\tcase *perffile.RecordSample:\n\t\t\tif r.Format&requiredFormat != requiredFormat {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tlevel := r.DataSrc.Level\n\t\t\tif r.DataSrc.Miss {\n\t\t\t\tlevel <<= 1\n\t\t\t}\n\t\t\taddr := r.Addr\n\t\t\tif byPC {\n\t\t\t\taddr = r.IP\n\t\t\t}\n\t\t\tevents = append(events, event{r.Time, addr, r.Weight, levelToPanel[level]})\n\t\t}\n\t}\n\n\treturn events\n}\n\ntype addrMapper struct {\n\tpageBase   map[uint64]uint64\n\tnormMax    uint64\n\tnormFactor float64 // pixels/byte\n}\n\n// newAddrMapper returns an addrMapper that maps addresses in events\n// to a compacted space in the range [0, normMax].\nfunc newAddrMapper(events []event, normMax uint64) *addrMapper {\n\tam := &addrMapper{normMax: normMax}\n\n\t// Find all distinct pages and max address.\n\tpages := make([]uint64, 0)\n\tpageSet := make(map[uint64]bool)\n\tmaxAddr := uint64(0)\n\tfor _, ev := range events {\n\t\tpage := ev.addr / pageBytes\n\t\tif pageSet[page] {\n\t\t\tcontinue\n\t\t}\n\t\tpageSet[page] = true\n\t\tpages = append(pages, page)\n\n\t\tif ev.addr > maxAddr {\n\t\t\tmaxAddr = ev.addr\n\t\t}\n\t}\n\tsort.Sort(uint64Slice(pages))\n\n\t// Map pages to a compact sequence.\n\tam.pageBase = make(map[uint64]uint64, len(pages))\n\tfor i, page := range pages {\n\t\tam.pageBase[page] = uint64(i) * pageBytes\n\t}\n\n\t// Compute normalization factor.\n\tcompactMax := am.pageBase[maxAddr/pageBytes] + maxAddr%pageBytes\n\tif compactMax <= normMax {\n\t\tam.normFactor = 1\n\t} else {\n\t\tam.normFactor = float64(normMax) / float64(compactMax)\n\t}\n\n\treturn am\n}\n\nfunc (am *addrMapper) mapAddr(addr uint64) uint64 {\n\tcompact := am.pageBase[addr/pageBytes] + addr%pageBytes\n\tnorm := uint64(float64(compact) * am.normFactor)\n\tif norm > am.normMax {\n\t\tnorm = am.normMax\n\t}\n\treturn norm\n}\n\nfunc normalizeWeight(events []event) {\n\t// Find the maximum weight.\n\tmaxW := uint64(0)\n\tfor _, ev := range events {\n\t\tif ev.weight > maxW {\n\t\t\tmaxW = ev.weight\n\t\t}\n\t}\n\n\t// TODO: Log scale?\n\n\t// Normalize [0, maxW] to [0, 255].\n\tfactor := float64(255) / float64(maxW)\n\tfor i, ev := range events {\n\t\tw := uint64(float64(ev.weight) * factor)\n\t\tif w > 255 {\n\t\t\tw = 255\n\t\t}\n\t\tevents[i].weight = w\n\t}\n}\n\nfunc zeroTime(events []event) {\n\tif len(events) == 0 {\n\t\treturn\n\t}\n\tt0 := events[0].time\n\tfor i := range events {\n\t\tevents[i].time -= t0\n\t}\n}\n\ntype uint64Slice []uint64\n\nfunc (s uint64Slice) Len() int {\n\treturn len(s)\n}\n\nfunc (s uint64Slice) Less(i, j int) bool {\n\treturn s[i] < s[j]\n}\n\nfunc (s uint64Slice) Swap(i, j int) {\n\ts[i], s[j] = s[j], s[i]\n}\n\n// hilbert converts a 1-D point d to a coordinate (x, y) in an n×n\n// Hilbert space.\nfunc hilbert(n, d int) (x, y int) {\n\t// Based on Wikipedia.\n\trot := func(s, x, y, rx, ry int) (int, int) {\n\t\tif ry == 0 {\n\t\t\tif rx == 1 {\n\t\t\t\tx = s - 1 - x\n\t\t\t\ty = s - 1 - y\n\t\t\t}\n\t\t\tx, y = y, x\n\t\t}\n\t\treturn x, y\n\t}\n\tfor s := 1; s < n; s *= 2 {\n\t\trx := 1 & (d / 2)\n\t\try := 1 & (d ^ rx)\n\t\tx, y = rot(s, x, y, rx, ry)\n\t\tx += s * rx\n\t\ty += s * ry\n\t\td /= 4\n\t}\n\treturn\n}\n\nfunc writePNG(path string, img image.Image) {\n\tf, err := os.Create(path)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tenc := png.Encoder{CompressionLevel: png.BestSpeed}\n\tif err := enc.Encode(f, img); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tif err := f.Close(); err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n\n// panelLevels maps from panel number to data source level.\nvar panelLevels = [...]perffile.DataSrcLevel{\n\tperffile.DataSrcLevelL1,\n\tperffile.DataSrcLevelL2,\n\tperffile.DataSrcLevelL3,\n\tperffile.DataSrcLevelLocalRAM,\n\tperffile.DataSrcLevelRemoteRAM1,\n}\n\nconst numPanels = len(panelLevels)\n\n// levelToPanel maps from a data source level to a panel number.\nvar levelToPanel = map[perffile.DataSrcLevel]int{\n\tperffile.DataSrcLevelNA: 0,\n}\n\nfunc init() {\n\tfor panel, level := range panelLevels {\n\t\tlevelToPanel[level] = panel\n\t}\n\n\tvar l int\n\tfor i := perffile.DataSrcLevelL1; i <= perffile.DataSrcLevelUncached; i++ {\n\t\tif l2, ok := levelToPanel[i]; ok {\n\t\t\tl = l2\n\t\t} else {\n\t\t\tlevelToPanel[i] = l\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "cmd/memheat/draw.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"image/color\"\n\n\t\"github.com/aclements/go-perf/scale\"\n)\n\ntype TicksFormat struct {\n\ttickLen, minorTickLen, textSep float64\n\ttickColor, labelColor          color.Color\n\tlabelFormat                    string\n}\n\nfunc (f *TicksFormat) HTicks(svg *SVG, scale scale.Interface, x scale.OutputScale, y float64) {\n\tx.Crop()\n\n\tmajor, minor := scale.Ticks(5)\n\n\t// Draw ticks\n\tif f.tickColor == nil {\n\t\tsvg.SetStroke(color.Black)\n\t} else {\n\t\tsvg.SetStroke(f.tickColor)\n\t}\n\tsvg.NewPath()\n\tfor _, sx := range major {\n\t\tif x, ok := x.Of(scale.Of(sx)); ok {\n\t\t\tsvg.MoveTo(x, y)\n\t\t\tsvg.LineToRel(0, -f.tickLen)\n\t\t}\n\t}\n\tfor _, sx := range minor {\n\t\tif x, ok := x.Of(scale.Of(sx)); ok {\n\t\t\tsvg.MoveTo(x, y)\n\t\t\tsvg.LineToRel(0, -f.minorTickLen)\n\t\t}\n\t}\n\tsvg.Stroke()\n\tsvg.SetStroke(nil)\n\n\t// Draw labels\n\tlOpts := TextOpts{Anchor: AnchorMiddle}\n\tif f.labelFormat != \"\" {\n\t\tif f.labelColor == nil {\n\t\t\tsvg.SetFill(color.Black)\n\t\t} else {\n\t\t\tsvg.SetFill(f.labelColor)\n\t\t}\n\t\tfor _, sx := range major {\n\t\t\tif x, ok := x.Of(scale.Of(sx)); ok {\n\t\t\t\tl := fmt.Sprintf(f.labelFormat, sx)\n\t\t\t\tsvg.Text(x, y-f.tickLen-f.textSep, lOpts, l)\n\t\t\t}\n\t\t}\n\t\tsvg.SetFill(nil)\n\t}\n}\n"
  },
  {
    "path": "cmd/memheat/main.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport (\n\t\"bufio\"\n\t\"debug/dwarf\"\n\t\"flag\"\n\t\"fmt\"\n\t\"image/color\"\n\t\"log\"\n\t\"os\"\n\t\"path\"\n\t\"sort\"\n\n\t\"github.com/aclements/go-perf/perffile\"\n\t\"github.com/aclements/go-perf/perfsession\"\n\t\"github.com/aclements/go-perf/scale\"\n)\n\ntype lineStat struct {\n\tip          uint64\n\ttotalWeight uint64\n\tweights     []uint64\n\n\tfn  string\n\tsrc *dwarf.LineEntry\n\n\tyCoord    float64\n\thistogram []int\n}\n\nfunc main() {\n\tvar (\n\t\tflagInput = flag.String(\"i\", \"perf.data\", \"input perf.data file\")\n\t\tflagLimit = flag.Int(\"limit\", 30, \"output top N functions\")\n\t)\n\tflag.Parse()\n\tif flag.NArg() > 0 {\n\t\tflag.Usage()\n\t\tos.Exit(1)\n\t}\n\n\tf, err := perffile.Open(*flagInput)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer f.Close()\n\n\ts := perfsession.New(f)\n\n\t// Collect samples by IP (TODO: by (comm, ip) or something)\n\tipToInfo := map[uint64]*lineStat{}\n\trs := f.Records(perffile.RecordsCausalOrder)\n\tfor rs.Next() {\n\t\tr := rs.Record\n\t\ts.Update(r)\n\n\t\tswitch r := r.(type) {\n\t\tcase *perffile.RecordSample:\n\t\t\tmmap := s.LookupPID(r.PID).LookupMmap(r.IP)\n\t\t\tif mmap == nil {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tline, ok := ipToInfo[r.IP]\n\t\t\tif !ok {\n\t\t\t\tvar symb perfsession.Symbolic\n\t\t\t\tif !perfsession.Symbolize(s, mmap, r.IP, &symb) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tline = &lineStat{\n\t\t\t\t\tip:  r.IP,\n\t\t\t\t\tfn:  symb.FuncName,\n\t\t\t\t\tsrc: &symb.Line,\n\t\t\t\t}\n\t\t\t\tipToInfo[r.IP] = line\n\t\t\t}\n\t\t\tweight := r.Weight\n\t\t\tif weight == 0 {\n\t\t\t\tweight = uint64(r.Weights.Var1)\n\t\t\t}\n\t\t\tline.weights = append(line.weights, weight)\n\t\t\tline.totalWeight += weight\n\t\t}\n\t}\n\n\t// Compute total function weight\n\tfnWeight := map[string]uint64{}\n\tfor _, ls := range ipToInfo {\n\t\tfnWeight[ls.fn] += ls.totalWeight\n\t}\n\n\t// Sort stats by function weight, line number\n\tstats := make([]*lineStat, 0, len(ipToInfo))\n\tfor _, ls := range ipToInfo {\n\t\tstats = append(stats, ls)\n\t}\n\tsort.Sort(lineStatSorter{stats, fnWeight})\n\n\t// Limit to the top N functions\n\tif *flagLimit > 0 {\n\t\tstats = limitFuncs(stats, *flagLimit)\n\t}\n\n\t// Find max weight\n\tmaxWeight := uint64(0)\n\tfor _, stat := range stats {\n\t\tfor _, w := range stat.weights {\n\t\t\tif w > maxWeight {\n\t\t\t\tmaxWeight = w\n\t\t\t}\n\t\t}\n\t}\n\twscale := scale.NewPower([]float64{0, float64(maxWeight)}, 1/2.0)\n\n\t// Compute histograms and find max bar height\n\tconst buckets = 50\n\tlscale := scale.NewLog([]float64{1, float64(maxWeight + 1)}, 10)\n\tlscale.Nice(5)\n\tmaxHeight := 0\n\tfor _, stat := range stats {\n\t\tstat.histogram = make([]int, buckets)\n\t\tfor _, w := range stat.weights {\n\t\t\tbucket := int(lscale.Of(float64(w)) * buckets)\n\t\t\tstat.histogram[bucket] += int(w)\n\t\t}\n\t\tfor _, height := range stat.histogram {\n\t\t\tif height > maxHeight {\n\t\t\t\tmaxHeight = height\n\t\t\t}\n\t\t}\n\t}\n\n\t// Assign Y coordinates\n\tconst (\n\t\tmarginTop      = 45\n\t\tcellHeight     = 10\n\t\tcellWidth      = 10\n\t\tfnGap          = 10\n\t\tlineLabelWidth = 30\n\t\tgroupWidth     = 20\n\t\tgroupGap       = 5\n\n\t\tmarginLeft  = groupWidth*2 + groupGap\n\t\tmarginRight = 300\n\n\t\tsourceLeft = marginLeft + buckets*cellWidth\n\t)\n\ty := marginTop\n\t// lastLine := -1\n\tfor i, stat := range stats {\n\t\tif i != 0 && (stat.fn != stats[i-1].fn || stat.src.File.Name != stats[i-1].src.File.Name) {\n\t\t\ty += fnGap\n\t\t\t// lastLine = -1\n\t\t}\n\t\t// if lastLine != -1 {\n\t\t// \ty += cellHeight * (stat.src.Line - lastLine)\n\t\t// }\n\t\tstat.yCoord = float64(y)\n\t\t// lastLine = stat.src.Line\n\t\ty += cellHeight\n\t}\n\n\t// Emit SVG\n\tsvg := NewSVG(os.Stdout, sourceLeft+marginRight, y)\n\n\tvar ticks = TicksFormat{\n\t\ttickLen:      5,\n\t\tminorTickLen: 3,\n\t\ttextSep:      5,\n\t\tlabelFormat:  \"%g\",\n\t}\n\n\t// TODO: Show command line and hostname\n\n\t{\n\t\tlOpts := TextOpts{Anchor: AnchorMiddle}\n\t\tsvg.SetFill(color.Black)\n\t\ty := float64(marginTop - ticks.tickLen - ticks.textSep)\n\t\tsvg.Text(marginLeft+cellWidth*buckets/2, y-20, lOpts, \"memory load latency (cycles)\")\n\t\tsvg.SetFill(nil)\n\t}\n\n\t// TODO: Draw color key\n\n\t// Label lines\n\tsvg.NewPath()\n\tlastLineY := -1.0\n\tfor _, idxs := range sections(len(stats), func(i int) bool {\n\t\treturn stats[i].src.Line != stats[i-1].src.Line\n\t}) {\n\t\tfirst, last := stats[idxs[0]], stats[idxs[1]-1]\n\t\ttop := first.yCoord\n\t\tbot := last.yCoord + cellHeight\n\n\t\tif lastLineY != top {\n\t\t\tsvg.MoveTo(sourceLeft, top)\n\t\t\tsvg.LineToRel(ticks.tickLen, 0)\n\t\t}\n\n\t\tsvg.MoveTo(sourceLeft, bot)\n\t\tsvg.LineToRel(ticks.tickLen, 0)\n\t\tlastLineY = bot\n\n\t\tlOpts := TextOpts{Anchor: AnchorStart, Baseline: BaselineMiddle, FontSize: 10}\n\t\tsvg.Text(sourceLeft+ticks.tickLen, (top+bot)/2, lOpts, fmt.Sprintf(\"%d\", first.src.Line))\n\n\t\tsvg.Text(sourceLeft+lineLabelWidth, (top+bot)/2, lOpts, getLine(first.src.File.Name, first.src.Line))\n\t}\n\tsvg.SetStroke(color.Black)\n\tsvg.Stroke()\n\tsvg.SetStroke(nil)\n\n\tgroupX := float64(marginLeft)\n\n\t// Label function groups\n\tfor _, idxs := range sections(len(stats), func(i int) bool {\n\t\treturn stats[i].fn != stats[i-1].fn\n\t}) {\n\t\tfirst, last := stats[idxs[0]], stats[idxs[1]-1]\n\t\ttop := first.yCoord\n\t\tbot := last.yCoord + cellHeight\n\n\t\t// Ticks at the top of each function\n\t\tticks.HTicks(svg, lscale, scale.NewOutputScale(marginLeft, marginLeft+cellWidth*buckets), top)\n\t\tticks.labelFormat = \"\"\n\n\t\t// Function label\n\t\tlOpts := TextOpts{Anchor: AnchorMiddle, Rotate: -90}\n\t\tsvg.SetFill(color.Gray{192})\n\t\tsvg.Rect(groupX-groupWidth, top, groupWidth, bot-top).FillPreserve().Clip()\n\t\tsvg.SetFill(color.Black)\n\t\tsvg.Text(groupX-5, (top+bot)/2, lOpts, first.fn)\n\t\tsvg.ResetClip()\n\t}\n\tgroupX -= groupWidth + groupGap\n\n\t// Label file name groups\n\tfor _, idxs := range sections(len(stats), func(i int) bool {\n\t\treturn stats[i].src.File.Name != stats[i-1].src.File.Name\n\t}) {\n\t\tlOpts := TextOpts{Anchor: AnchorMiddle, Rotate: -90}\n\t\tsvg.SetFill(color.Gray{192})\n\t\ttop := stats[idxs[0]].yCoord\n\t\tbot := stats[idxs[1]-1].yCoord + cellHeight\n\t\tsvg.Rect(groupX-groupWidth, top, groupWidth, bot-top).FillPreserve().Clip()\n\t\tsvg.SetFill(color.Black)\n\t\tfileName := path.Base(stats[idxs[0]].src.File.Name)\n\t\tsvg.Text(groupX-5, (top+bot)/2, lOpts, fileName)\n\t\tsvg.ResetClip()\n\t}\n\tgroupX -= groupWidth + groupGap\n\n\t// Draw heat map\n\tfor _, stat := range stats {\n\t\tfor x, height := range stat.histogram {\n\t\t\tif height == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tshade := wscale.Of(float64(height))\n\t\t\tsvg.SetFill(color.NRGBA{255, 0, 0, uint8(255 * shade)})\n\t\t\tsvg.Rect(float64(marginLeft+x*cellWidth), stat.yCoord,\n\t\t\t\tcellWidth, cellHeight).Fill()\n\t\t}\n\n\t\t// Tooltip for raw IP\n\t\tsvg.Rect(marginLeft, stat.yCoord, cellWidth*buckets, cellHeight).TooltipHighlight(fmt.Sprintf(\"IP: %#x\", stat.ip))\n\t}\n\tsvg.SetFill(nil)\n\tsvg.Done()\n}\n\ntype lineStatSorter struct {\n\tlines    []*lineStat\n\tfnWeight map[string]uint64\n}\n\nfunc (s lineStatSorter) Len() int {\n\treturn len(s.lines)\n}\n\nfunc (s lineStatSorter) Swap(i, j int) {\n\ts.lines[i], s.lines[j] = s.lines[j], s.lines[i]\n}\n\nfunc (s lineStatSorter) Less(i, j int) bool {\n\t// Sort by function weight first\n\tfni, fnj := s.lines[i].fn, s.lines[j].fn\n\tif s.fnWeight[fni] != s.fnWeight[fnj] {\n\t\treturn s.fnWeight[fni] > s.fnWeight[fnj]\n\t}\n\n\t// Sort by file:line\n\tli, lj := s.lines[i].src, s.lines[j].src\n\tif li != nil || lj != nil {\n\t\tif li == nil || lj == nil {\n\t\t\t// Unknown line info comes first\n\t\t\treturn li == nil\n\t\t}\n\t\tif li.File.Name != lj.File.Name {\n\t\t\treturn li.File.Name < lj.File.Name\n\t\t}\n\t\tif li.Line != lj.Line {\n\t\t\treturn li.Line < lj.Line\n\t\t}\n\t}\n\n\t// Finally, sort by IP\n\treturn s.lines[i].ip < s.lines[j].ip\n}\n\nfunc limitFuncs(stats []*lineStat, limit int) []*lineStat {\n\tseen := 0\n\tfor i, stat := range stats {\n\t\tif i == 0 || stat.fn != stats[i-1].fn {\n\t\t\tif seen == limit {\n\t\t\t\treturn stats[:i]\n\t\t\t}\n\t\t\tseen++\n\t\t}\n\t}\n\treturn stats\n}\n\nfunc sections(count int, newGroup func(int) bool) [][2]int {\n\tsections := make([][2]int, 0)\n\tif count == 0 {\n\t\treturn sections\n\t}\n\n\tstart := 0\n\tfor i := 1; i < count; i++ {\n\t\tif newGroup(i) {\n\t\t\tsections = append(sections, [2]int{start, i})\n\t\t\tstart = i\n\t\t}\n\t}\n\tsections = append(sections, [2]int{start, count})\n\treturn sections\n}\n\nfunc getLine(path string, line int) string {\n\t// TODO: Cache parsing\n\n\tfile, err := os.Open(path)\n\tif err != nil {\n\t\tlog.Println(err)\n\t\treturn \"\"\n\t}\n\tdefer file.Close()\n\n\tscanner := bufio.NewScanner(file)\n\tfor i := 0; i < line && scanner.Scan(); i++ {\n\t\t// Do nothing\n\t}\n\n\tif err := scanner.Err(); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\treturn scanner.Text()\n}\n"
  },
  {
    "path": "cmd/memheat/svg.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport (\n\t\"encoding/xml\"\n\t\"fmt\"\n\t\"image/color\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n)\n\ntype SVG struct {\n\tw   io.Writer\n\terr error\n\n\tfill, stroke string\n\tlineWidth    string\n\tclipPath     string\n\n\tid int\n\n\tpath []string\n}\n\nfunc NewSVG(w io.Writer, width, height int) *SVG {\n\ts := &SVG{w: w}\n\ts.fprintf(\"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" width=\\\"%d\\\" height=\\\"%d\\\">\\n\", width, height)\n\ts.fprintf(\"<style>.hover { fill:rgba(0,0,0,0) } .hover:hover { stroke:#000 }</style>\\n\")\n\ts.NewPath()\n\treturn s\n}\n\ntype svglen float64\n\nfunc (v svglen) String() string {\n\treturn strconv.FormatFloat(float64(v), 'f', -1, 32)\n}\n\nfunc colorToCSS(c color.Color) string {\n\tcc := color.NRGBAModel.Convert(c).(color.NRGBA)\n\tif cc.A == 0xff {\n\t\treturn fmt.Sprintf(\"rgb(%d,%d,%d)\", cc.R, cc.G, cc.B)\n\t}\n\treturn fmt.Sprintf(\"rgba(%d,%d,%d,%f)\", cc.R, cc.G, cc.B, float64(cc.A)/0xff)\n}\n\nfunc (s *SVG) fprintf(format string, a ...interface{}) {\n\tif s.err != nil {\n\t\treturn\n\t}\n\t_, s.err = fmt.Fprintf(s.w, format, a...)\n}\n\nfunc (s *SVG) SetFill(c color.Color) {\n\tif c == nil {\n\t\ts.fill = \"\"\n\t} else {\n\t\ts.fill = \"fill:\" + colorToCSS(c)\n\t}\n}\n\nfunc (s *SVG) SetStroke(c color.Color) {\n\tif c == nil {\n\t\ts.stroke = \"\"\n\t} else {\n\t\ts.stroke = \"stroke:\" + colorToCSS(c)\n\t}\n}\n\nfunc (s *SVG) SetLineWidth(lw float64) {\n\ts.lineWidth = fmt.Sprintf(\"stroke-width:%v\", svglen(lw))\n}\n\nfunc (s *SVG) style(parts ...string) string {\n\tval, sep := \"\", \"\"\n\tfor _, part := range parts {\n\t\tif part != \"\" {\n\t\t\tval += sep + part\n\t\t\tsep = \";\"\n\t\t}\n\t}\n\tif val != \"\" {\n\t\treturn \" style=\\\"\" + val + \"\\\"\"\n\t} else {\n\t\treturn \"\"\n\t}\n}\n\nfunc (s *SVG) NewPath() *SVG {\n\ts.path = []string{}\n\treturn s\n}\n\nfunc (s *SVG) MoveTo(x, y float64) *SVG {\n\ts.path = append(s.path, fmt.Sprintf(\"M%v %v\", svglen(x), svglen(y)))\n\treturn s\n}\n\nfunc (s *SVG) LineToRel(xd, yd float64) *SVG {\n\tvar op string\n\tif xd == 0 {\n\t\top = fmt.Sprintf(\"v%v\", svglen(yd))\n\t} else if yd == 0 {\n\t\top = fmt.Sprintf(\"h%v\", svglen(xd))\n\t} else {\n\t\top = fmt.Sprintf(\"l%v %v\", svglen(xd), svglen(yd))\n\t}\n\ts.path = append(s.path, op)\n\treturn s\n}\n\nfunc (s *SVG) Rect(x, y, w, h float64) *SVG {\n\treturn s.MoveTo(x, y).LineToRel(w, 0).LineToRel(0, h).LineToRel(-w, 0).ClosePath()\n}\n\nfunc (s *SVG) ClosePath() *SVG {\n\ts.path = append(s.path, \"z\")\n\treturn s\n}\n\nfunc (s *SVG) pathData() string {\n\treturn strings.Join(s.path, \"\")\n}\n\nfunc (s *SVG) Stroke() *SVG {\n\ts.fprintf(\"<path d=\\\"%s\\\"%s/>\\n\", s.pathData(), s.style(s.stroke, s.lineWidth, s.clipPath))\n\treturn s.NewPath()\n}\n\nfunc (s *SVG) FillPreserve() *SVG {\n\ts.fprintf(\"<path d=\\\"%s\\\"%s/>\\n\", s.pathData(), s.style(s.fill, s.clipPath))\n\treturn s\n}\n\nfunc (s *SVG) Fill() *SVG {\n\treturn s.FillPreserve().NewPath()\n}\n\nfunc (s *SVG) FillStroke() *SVG {\n\ts.fprintf(\"<path d=\\\"%s\\\"%s/>\\n\", s.pathData(), s.style(s.fill, s.stroke, s.lineWidth, s.clipPath))\n\treturn s.NewPath()\n}\n\nfunc (s *SVG) Clip() *SVG {\n\ts.fprintf(\"<clipPath id=\\\"i%d\\\"><path d=\\\"%s\\\"/></clipPath>\", s.id, s.pathData())\n\ts.clipPath = fmt.Sprintf(\"clip-path:url(#i%d)\", s.id)\n\ts.id++\n\treturn s.NewPath()\n}\n\nfunc (s *SVG) ResetClip() *SVG {\n\ts.clipPath = \"\"\n\treturn s\n}\n\nfunc (s *SVG) Tooltip(text string) *SVG {\n\ts.fprintf(\"<path d=\\\"%s\\\" fill=\\\"rgba(0,0,0,0)\\\"><title>\", s.pathData())\n\tif s.err == nil {\n\t\ts.err = xml.EscapeText(s.w, []byte(text))\n\t}\n\ts.fprintf(\"</title></path>\\n\")\n\treturn s.NewPath()\n}\n\nfunc (s *SVG) TooltipHighlight(text string) *SVG {\n\ts.fprintf(\"<path d=\\\"%s\\\" fill=\\\"rgba(0,0,0,0)\\\" class=\\\"hover\\\"><title>\", s.pathData())\n\tif s.err == nil {\n\t\ts.err = xml.EscapeText(s.w, []byte(text))\n\t}\n\ts.fprintf(\"</title></path>\\n\")\n\treturn s.NewPath()\n}\n\ntype Anchor int\n\nconst (\n\tAnchorStart Anchor = iota\n\tAnchorMiddle\n\tAnchorEnd\n)\n\ntype Baseline int\n\nconst (\n\tBaselineAuto Baseline = iota\n\tBaselineBaseline\n\tBaselineMiddle\n)\n\ntype TextOpts struct {\n\tAnchor   Anchor\n\tBaseline Baseline\n\tRotate   float64\n\tFontSize float64\n}\n\nfunc (s *SVG) Text(x, y float64, opts TextOpts, text string) {\n\tastr := map[Anchor]string{\n\t\tAnchorStart:  \"\",\n\t\tAnchorMiddle: \" text-anchor=\\\"middle\\\"\",\n\t\tAnchorEnd:    \" text-anchor=\\\"end\\\"\",\n\t}[opts.Anchor]\n\tbstr := map[Baseline]string{\n\t\tBaselineAuto:     \"\",\n\t\tBaselineBaseline: \" dominant-baseline=\\\"baseline\\\"\",\n\t\tBaselineMiddle:   \" dominant-baseline=\\\"middle\\\"\",\n\t}[opts.Baseline]\n\trstr := \"\"\n\tif opts.Rotate != 0 {\n\t\trstr = fmt.Sprintf(\" transform=\\\"rotate(%v,%v,%v)\\\"\", svglen(opts.Rotate), svglen(x), svglen(y))\n\t}\n\tfstr := \"\"\n\tif opts.FontSize != 0 {\n\t\tfstr = fmt.Sprintf(\" font-size=\\\"%v\\\"\", svglen(opts.FontSize))\n\t}\n\tclose := \"\"\n\tif s.clipPath != \"\" {\n\t\t// Don't apply rotation to clip path\n\t\ts.fprintf(\"<g%s>\", s.style(s.clipPath))\n\t\tclose = \"</g>\"\n\t}\n\ts.fprintf(\"<text x=\\\"%v\\\" y=\\\"%v\\\"%s%s%s%s%s>\", svglen(x), svglen(y), astr, bstr, rstr, fstr, s.style(s.fill))\n\tif s.err == nil {\n\t\ts.err = xml.EscapeText(s.w, []byte(text))\n\t}\n\ts.fprintf(\"</text>%s\\n\", close)\n}\n\nfunc (s *SVG) Done() error {\n\ts.fprintf(\"</svg>\")\n\treturn s.err\n}\n"
  },
  {
    "path": "cmd/memlat/database.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/aclements/go-perf/perffile\"\n\t\"github.com/aclements/go-perf/perfsession\"\n)\n\ntype database struct {\n\t// procs maps from PID to information and records for a\n\t// process.\n\tprocs map[int]*proc\n\n\t// dataSrcs maps dataSrcIDs to full DataSrc information.\n\t// There's a lot of information in a DataSrc, but in practice\n\t// a given architecture will generate a small subset of the\n\t// possibilities. Hence, rather than storing a whole DataSrc\n\t// in every record, we canonicalize it to a small identifier.\n\tdataSrcs []perffile.DataSrc\n\n\t// maxLatency is the maximum latency value across all records\n\t// in this database.\n\tmaxLatency uint32\n\n\t// metadata records metadata fields from the profile.\n\tmetadata Metadata\n}\n\ntype proc struct {\n\tpid     int\n\tcomm    string\n\trecords []record\n\tipInfo  map[uint64]ipInfo\n}\n\ntype record struct {\n\tip      uint64\n\taddress uint64\n\tlatency uint32\n\tdataSrc dataSrcID\n}\n\ntype ipInfo struct {\n\tfuncName string\n\tfileName string\n\tline     int\n}\n\n// dataSrcID is a small integer identifying a perffile.DataSrc.\ntype dataSrcID uint32\n\ntype Metadata struct {\n\tHostname string\n\tArch     string\n\tCPUDesc  string   `json:\"CPU\"`\n\tCmdLine  []string `json:\"Command line\"`\n}\n\n// parsePerf parses a perf.data profile into a database.\nfunc parsePerf(fileName string) *database {\n\tf, err := perffile.Open(fileName)\n\tif os.IsNotExist(err) && fileName == \"perf.data\" {\n\t\t// Give a friendly error for first-time users.\n\t\tfmt.Fprintf(os.Stderr, \"%s.\\nTo record a profile, use\\n  perf mem record <command>\\nor specify an alternate profile path with -i.\\n\", err)\n\t\tos.Exit(1)\n\t} else if err != nil {\n\t\tfmt.Fprintf(os.Stderr, \"error loading profile: %s\\n\", err)\n\t\tos.Exit(1)\n\t}\n\tdefer f.Close()\n\n\tdb := &database{\n\t\tprocs: make(map[int]*proc),\n\t}\n\tdb.metadata.Hostname = f.Meta.Hostname\n\tdb.metadata.Arch = f.Meta.Arch\n\tdb.metadata.CPUDesc = f.Meta.CPUDesc\n\tdb.metadata.CmdLine = f.Meta.CmdLine\n\n\tdataSrc2ID := make(map[perffile.DataSrc]dataSrcID)\n\ts := perfsession.New(f)\n\n\tnumSamples := 0\n\tdroppedMmaps := 0\n\tdroppedSymbols := 0\n\n\tconst requiredFormat = perffile.SampleFormatIP | perffile.SampleFormatAddr | perffile.SampleFormatDataSrc\n\n\trs := f.Records(perffile.RecordsCausalOrder)\n\tfor rs.Next() {\n\t\tr := rs.Record\n\t\ts.Update(r)\n\n\t\tswitch r := r.(type) {\n\t\tcase *perffile.RecordComm:\n\t\t\t// Comm events usually happen after the first\n\t\t\t// few samples from this PID.\n\t\t\tp := db.procs[r.PID]\n\t\t\tif p != nil {\n\t\t\t\tp.comm = r.Comm\n\t\t\t}\n\n\t\tcase *perffile.RecordSample:\n\t\t\tif r.Format&requiredFormat != requiredFormat {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\t// Either Weight or WeightStruct is required.\n\t\t\tif r.Format&(perffile.SampleFormatWeight|perffile.SampleFormatWeightStruct) == 0 {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tnumSamples++\n\n\t\t\tpidInfo := s.LookupPID(r.PID)\n\t\t\tmmap := pidInfo.LookupMmap(r.IP)\n\t\t\tif mmap == nil {\n\t\t\t\tdroppedMmaps++\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Find proc for r.PID.\n\t\t\tp, ok := db.procs[r.PID]\n\t\t\tif !ok {\n\t\t\t\tp = &proc{\n\t\t\t\t\tpid:    r.PID,\n\t\t\t\t\tcomm:   pidInfo.Comm,\n\t\t\t\t\tipInfo: make(map[uint64]ipInfo),\n\t\t\t\t}\n\t\t\t\tdb.procs[r.PID] = p\n\t\t\t}\n\n\t\t\t// Canonicalize data source.\n\t\t\tdsID, ok := dataSrc2ID[r.DataSrc]\n\t\t\tif !ok {\n\t\t\t\tdsID = dataSrcID(len(db.dataSrcs))\n\t\t\t\tdataSrc2ID[r.DataSrc] = dsID\n\t\t\t\tdb.dataSrcs = append(db.dataSrcs, r.DataSrc)\n\t\t\t}\n\n\t\t\t// Create the record.\n\t\t\tp.records = append(p.records, record{\n\t\t\t\tip:      r.IP,\n\t\t\t\taddress: r.Addr,\n\t\t\t\tlatency: uint32(r.Weight),\n\t\t\t\tdataSrc: dsID,\n\t\t\t})\n\n\t\t\t// Update database stats.\n\t\t\tif uint32(r.Weight) > db.maxLatency {\n\t\t\t\tdb.maxLatency = uint32(r.Weight)\n\t\t\t}\n\n\t\t\t// Symbolize IP.\n\t\t\tif _, ok := p.ipInfo[r.IP]; !ok {\n\t\t\t\t// TODO: Intern strings\n\t\t\t\tvar symb perfsession.Symbolic\n\t\t\t\tif !perfsession.Symbolize(s, mmap, r.IP, &symb) {\n\t\t\t\t\tdroppedSymbols++\n\t\t\t\t}\n\t\t\t\tif symb.FuncName == \"\" {\n\t\t\t\t\tsymb.FuncName = \"[unknown]\"\n\t\t\t\t}\n\t\t\t\tfileName := \"[unknown]\"\n\t\t\t\tif symb.Line.File != nil && symb.Line.File.Name != \"\" {\n\t\t\t\t\tfileName = symb.Line.File.Name\n\t\t\t\t}\n\t\t\t\tp.ipInfo[r.IP] = ipInfo{\n\t\t\t\t\tfuncName: symb.FuncName,\n\t\t\t\t\tfileName: fileName,\n\t\t\t\t\tline:     symb.Line.Line,\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif numSamples == 0 {\n\t\tfmt.Printf(\"no memory latency samples in %s (did you use \\\"perf mem record\\\"?)\\n\", fileName)\n\t\tos.Exit(1)\n\t}\n\tif droppedMmaps > 0 {\n\t\tfmt.Printf(\"warning: %d sample IPs (%d%%) occurred in unmapped memory regions\\n\", droppedMmaps, droppedMmaps*100/numSamples)\n\t}\n\tif droppedSymbols > 0 {\n\t\tfmt.Printf(\"warning: failed to symbolize %d samples (%d%%)\\n\", droppedSymbols, droppedSymbols*100/numSamples)\n\t}\n\n\treturn db\n}\n\n// filter specifies a set of field values to filter records on. The\n// zero value of each field means not to filter on that field.\ntype filter struct {\n\tpid      int\n\tfuncName string\n\tfileName string\n\tline     int // Requires fileName.\n\taddress  uint64\n\tdataSrc  perffile.DataSrc\n}\n\n// filter invokes cb for every record matching f.\nfunc (db *database) filter(f *filter, cb func(*proc, *record)) {\n\tdsFilter := f.dataSrc != perffile.DataSrc{}\n\tfilterProc := func(proc *proc) {\n\t\tvar ds perffile.DataSrc\n\n\t\t// TODO: Consider creating indexes for some or all of\n\t\t// these. Then just do a list merge of the record\n\t\t// indexes.\n\t\tfor i := range proc.records {\n\t\t\t// Avoid heap-allocating for passing rec to cb.\n\t\t\trec := &proc.records[i]\n\t\t\tif f.address != 0 && f.address != rec.address {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tipi := proc.ipInfo[rec.ip]\n\t\t\tif f.funcName != \"\" && f.funcName != ipi.funcName {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif f.fileName != \"\" && f.fileName != ipi.fileName {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif f.line != 0 && f.line != ipi.line {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif !dsFilter {\n\t\t\t\t// Short-circuit dataSrc checking.\n\t\t\t\tgoto good\n\t\t\t}\n\n\t\t\tds = db.dataSrcs[rec.dataSrc]\n\t\t\tif f.dataSrc.Op != 0 && f.dataSrc.Op != ds.Op {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif f.dataSrc.Level != 0 && (f.dataSrc.Level != ds.Level || f.dataSrc.Miss != ds.Miss) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif f.dataSrc.Snoop != 0 && f.dataSrc.Snoop != ds.Snoop {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif f.dataSrc.Locked != 0 && f.dataSrc.Locked != ds.Locked {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif f.dataSrc.TLB != 0 && f.dataSrc.TLB != ds.TLB {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\tgood:\n\t\t\tcb(proc, rec)\n\t\t}\n\t}\n\n\tif f.pid == 0 {\n\t\tfor _, proc := range db.procs {\n\t\t\tfilterProc(proc)\n\t\t}\n\t} else {\n\t\tproc := db.procs[f.pid]\n\t\tif proc != nil {\n\t\t\tfilterProc(proc)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "cmd/memlat/main.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Command memlat is a web-based browser for memory load latency profiles.\n//\n// Memory stalls and conflicts are increasingly important for software\n// performance. Memory load latency profiles can give deep insights in\n// to these problems; however, the richness of these profiles makes\n// them difficult to interpret using traditional profiling tools and\n// techniques.\n//\n// memlat is a profile browser built for understanding and\n// interpreting memory load latency profiles. The central concept is a\n// \"latency distribution\", which is a statistical distribution of the\n// number of cycles spent in memory load or store operations. For\n// example, if there are 10 loads that take 10 cycles and 2 loads that\n// takes 100 cycles, the latency distribution consists of a 100 cycle\n// spike at 10 cycles and a 200 cycle spike at 100 cycles. The total\n// weight of this distribution accounts for the total cycles spent\n// waiting on memory loads or stores.\n//\n// memlat presents a profile as a multidimensional latency\n// distribution and provides a tools for viewing and filtering this\n// distribution on each dimension, such as by function, by source\n// line, by data source (L1 hit, TLB miss, etc), by address, etc. Each\n// tab in the UI browses the profile on a different dimension and\n// clicking on a row filters the profile down to just that function,\n// source line, etc. An active filters can be removed by clicking on\n// it in the filter bar at the top.\n//\n// For example, suppose we want to understand the primary source of\n// memory latency in a profile. Select the \"By source line\" tab and\n// click on the top row to filter to the source line that contributed\n// the most total memory latency. You can select the \"Source\n// annotation\" tab to see the text of this line. To drill down to a\n// particular memory address, select the \"By address\" tab to see the\n// memory addresses touched by this source line. Click the top one to\n// further filter to the hottest address touched by this source line.\n// Then, click the source line filter in the filter bar at the top to\n// remove the source line filter. Finally, select the \"Source\n// annotation\" tab to see the other source code lines that touch this\n// hot address.\n//\n// Note that the latency reported by the hardware is the time from\n// instruction issue to retire. Hence, a \"fast load\" (say, an L1 hit)\n// that happens immediately after a \"slow load\" (say, an LLC miss),\n// will have a high reported latency because it has to wait for the\n// slow load, even though the actual memory operation for the fast\n// load is fast.\n//\n// Usage\n//\n// To download and install memlat, run\n//\n//    go get github.com/aclements/go-perf/cmd/memlat\n//\n// memlat works with the memory load latency profiles recorded by the\n// Linux perf tool. This requires hardware support that has been\n// available since Intel Nehalem. To record a memory latency profile,\n// use perf's \"mem\" subcommand. For example,\n//\n//    perf mem record <command>  # Record a memory profile for command\n//    perf mem record -a         # Record a system-wide memory profile\n//\n// This will write the profile to a file called perf.data. Then,\n// simply start memlat with\n//\n//    memlat\n//\n// memlat will parse and symbolize the profile and start a web server\n// listening by default on localhost;8001.\npackage main\n\nimport (\n\t\"bufio\"\n\t\"embed\"\n\t\"encoding/json\"\n\t\"flag\"\n\t\"fmt\"\n\t\"io/fs\"\n\t\"log\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"sort\"\n\t\"strconv\"\n\n\t\"github.com/aclements/go-moremath/scale\"\n\t\"github.com/aclements/go-moremath/vec\"\n\t\"github.com/aclements/go-perf/perffile\"\n)\n\n//go:embed static\nvar staticFiles embed.FS\n\n// TODO: Open a browser automatically. Maybe bind to any address in\n// this mode.\n\n// TODO: Does this correctly handle the dynamic sampling rate that\n// perf mem record uses by default?\n\nfunc main() {\n\tvar (\n\t\tflagInput   = flag.String(\"i\", \"perf.data\", \"read memory latency profile from `file`\")\n\t\tflagHttp    = flag.String(\"http\", \"localhost:8001\", \"serve HTTP on `address`\")\n\t\tflagDocRoot = flag.String(\"docroot\", \"\", \"alternate `path` to static web resources\")\n\t)\n\tflag.Parse()\n\tif flag.NArg() > 0 {\n\t\tflag.Usage()\n\t\tos.Exit(1)\n\t}\n\n\tfmt.Fprintln(os.Stderr, \"loading profile...\")\n\tdb := parsePerf(*flagInput)\n\tfmt.Fprintln(os.Stderr, \"profile loaded\")\n\n\tmux := http.NewServeMux()\n\tif *flagDocRoot == \"\" {\n\t\t// Use the embedded static assets.\n\t\tsub, _ := fs.Sub(staticFiles, \"static\")\n\t\tmux.Handle(\"/\", http.FileServer(http.FS(sub)))\n\t} else {\n\t\t// Use assets from the file system.\n\t\tmux.Handle(\"/\", http.FileServer(http.Dir(*flagDocRoot)))\n\t}\n\tmux.Handle(\"/h\", &heatMapHandler{db})\n\tmux.Handle(\"/metadata\", &metadataHandler{*flagInput, db.metadata})\n\n\tfmt.Fprintf(os.Stderr, \"serving on %s\\n\", *flagHttp)\n\tif err := http.ListenAndServe(*flagHttp, mux); err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n\ntype heatMapHandler struct {\n\tdb *database\n}\n\nfunc (h *heatMapHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {\n\t// TOOD: Include a signature for this profile in the request\n\t// and mark the response as cacheable.\n\n\t// TODO: Compress the output.\n\n\t// Request includes filter, group by. Response: map from group\n\t// by to histograms.\n\tqs, err := url.ParseQuery(req.URL.RawQuery)\n\tif err != nil {\n\t\thttp.Error(w, err.Error(), http.StatusBadRequest)\n\t\treturn\n\t}\n\tatoi := func(s string) int {\n\t\tx, _ := strconv.Atoi(s)\n\t\treturn x\n\t}\n\tf := filter{\n\t\tpid:      atoi(qs.Get(\"pid\")),\n\t\tfuncName: qs.Get(\"funcName\"),\n\t\tfileName: qs.Get(\"fileName\"),\n\t\tline:     atoi(qs.Get(\"line\")),\n\t\taddress:  uint64(atoi(qs.Get(\"address\"))),\n\t\tdataSrc: perffile.DataSrc{\n\t\t\tOp:     perffile.DataSrcOp(atoi(qs.Get(\"op\"))),\n\t\t\tMiss:   qs.Get(\"miss\") == \"miss\",\n\t\t\tLevel:  perffile.DataSrcLevel(atoi(qs.Get(\"level\"))),\n\t\t\tSnoop:  perffile.DataSrcSnoop(atoi(qs.Get(\"snoop\"))),\n\t\t\tLocked: perffile.DataSrcLock(atoi(qs.Get(\"locked\"))),\n\t\t\tTLB:    perffile.DataSrcTLB(atoi(qs.Get(\"tlb\"))),\n\t\t},\n\t}\n\tgroupBy := qs.Get(\"groupBy\")\n\tlimit := atoi(qs.Get(\"limit\"))\n\n\t// Compute the scale for this histogram set.\n\tconst useLocalScale = false\n\tvar maxLatency uint32 = 1\n\tif useLocalScale {\n\t\th.db.filter(&f, func(p *proc, rec *record) {\n\t\t\tif rec.latency > maxLatency {\n\t\t\t\tmaxLatency = rec.latency\n\t\t\t}\n\t\t})\n\t} else {\n\t\tmaxLatency = h.db.maxLatency\n\t}\n\tscaler, err := scale.NewLog(1, float64(maxLatency), 10)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tscaler.Nice(scale.TickOptions{Max: 6})\n\n\tvar histograms []*latencyHistogram\n\tnewHist := func() *latencyHistogram {\n\t\thist := newLatencyHistogram(&scaler)\n\t\thistograms = append(histograms, hist)\n\t\treturn hist\n\t}\n\n\t// Create aggregation function.\n\tvar agg func(*proc, *record)\n\tswitch groupBy {\n\tdefault:\n\t\thttp.Error(w, fmt.Sprintf(\"unknown groupby %q\", groupBy), http.StatusBadRequest)\n\t\treturn\n\n\tcase \"all\":\n\t\thist := newHist()\n\t\tagg = func(p *proc, r *record) {\n\t\t\thist.update(r)\n\n\t\t}\n\n\tcase \"pid\":\n\t\tgroups := make(map[*proc]*latencyHistogram)\n\t\tagg = func(p *proc, r *record) {\n\t\t\thist, ok := groups[p]\n\t\t\tif !ok {\n\t\t\t\thist = newHist()\n\t\t\t\thist.PID = p.pid\n\t\t\t\thist.Comm = p.comm\n\t\t\t\tgroups[p] = hist\n\t\t\t}\n\t\t\thist.update(r)\n\t\t}\n\n\tcase \"funcName\":\n\t\tgroups := make(map[string]*latencyHistogram)\n\t\tagg = func(p *proc, r *record) {\n\t\t\tfuncName := p.ipInfo[r.ip].funcName\n\t\t\thist, ok := groups[funcName]\n\t\t\tif !ok {\n\t\t\t\thist = newHist()\n\t\t\t\thist.FuncName = funcName\n\t\t\t\tgroups[funcName] = hist\n\t\t\t}\n\t\t\thist.update(r)\n\t\t}\n\n\tcase \"annotation\", \"line\":\n\t\tgroups := make(map[ipInfo]*latencyHistogram)\n\t\tagg = func(p *proc, r *record) {\n\t\t\tipInfo := p.ipInfo[r.ip]\n\t\t\thist, ok := groups[ipInfo]\n\t\t\tif !ok {\n\t\t\t\thist = newHist()\n\t\t\t\thist.FileName = ipInfo.fileName\n\t\t\t\thist.Line = ipInfo.line\n\t\t\t\tgroups[ipInfo] = hist\n\t\t\t}\n\t\t\thist.update(r)\n\t\t}\n\n\tcase \"address\":\n\t\tgroups := make(map[uint64]*latencyHistogram)\n\t\tagg = func(p *proc, r *record) {\n\t\t\thist, ok := groups[r.address]\n\t\t\tif !ok {\n\t\t\t\thist = newHist()\n\t\t\t\thist.Address = r.address\n\t\t\t\tgroups[r.address] = hist\n\t\t\t}\n\t\t\thist.update(r)\n\t\t}\n\n\tcase \"dataSrc\":\n\t\tgroups := make(map[perffile.DataSrc]*latencyHistogram)\n\t\tadd1 := func(r *record, key perffile.DataSrc, label, group string) {\n\t\t\thist, ok := groups[key]\n\t\t\tif !ok {\n\t\t\t\thist = newHist()\n\t\t\t\thist.group = group\n\t\t\t\thist.Op = key.Op\n\t\t\t\thist.Miss = key.Miss\n\t\t\t\thist.Level = key.Level\n\t\t\t\thist.Snoop = key.Snoop\n\t\t\t\thist.Locked = key.Locked\n\t\t\t\thist.TLB = key.TLB\n\t\t\t\thist.DataSrcLabel = label\n\t\t\t\tgroups[key] = hist\n\t\t\t}\n\t\t\thist.update(r)\n\t\t}\n\t\tagg = func(p *proc, r *record) {\n\t\t\tds := h.db.dataSrcs[r.dataSrc]\n\t\t\tif ds.Op != 0 {\n\t\t\t\tadd1(r, perffile.DataSrc{Op: ds.Op}, ds.Op.String(), \"Operation\")\n\t\t\t}\n\t\t\tif ds.Level != 0 {\n\t\t\t\tmiss := \" hit\"\n\t\t\t\tif ds.Miss {\n\t\t\t\t\tmiss = \" miss\"\n\t\t\t\t}\n\t\t\t\tadd1(r, perffile.DataSrc{Miss: ds.Miss, Level: ds.Level}, ds.Level.String()+miss, \"Cache level\")\n\t\t\t}\n\t\t\tif ds.Snoop != 0 {\n\t\t\t\tadd1(r, perffile.DataSrc{Snoop: ds.Snoop}, ds.Snoop.String(), \"Snoop\")\n\t\t\t}\n\t\t\tif ds.Locked != 0 {\n\t\t\t\tadd1(r, perffile.DataSrc{Locked: ds.Locked}, ds.Locked.String()[11:], \"Locked\")\n\t\t\t}\n\t\t\tif ds.TLB != 0 {\n\t\t\t\tadd1(r, perffile.DataSrc{TLB: ds.TLB}, ds.TLB.String(), \"TLB\")\n\t\t\t}\n\t\t}\n\t}\n\n\th.db.filter(&f, agg)\n\n\t// Sort histograms by weight.\n\tsort.Sort(sort.Reverse(weightSorter(histograms)))\n\n\t// Take the top N histograms.\n\tif groupBy == \"dataSrc\" {\n\t\tlimit = 0\n\t}\n\tif limit != 0 && limit < len(histograms) {\n\t\thistograms = histograms[:limit]\n\t}\n\n\t// Special processing for some grouping types.\n\tswitch groupBy {\n\tcase \"dataSrc\":\n\t\t// Add group headers\n\t\tfor i := 0; i < len(histograms); i++ {\n\t\t\tif i == 0 || histograms[i-1].group != histograms[i].group {\n\t\t\t\thistograms = append(histograms, nil)\n\t\t\t\tcopy(histograms[i+1:], histograms[i:])\n\t\t\t\thistograms[i] = &latencyHistogram{\n\t\t\t\t\tText:     histograms[i+1].group,\n\t\t\t\t\tIsHeader: true,\n\t\t\t\t}\n\t\t\t\ti++\n\t\t\t}\n\t\t}\n\n\tcase \"annotation\":\n\t\tif len(histograms) == 0 {\n\t\t\tbreak\n\t\t}\n\t\t// TODO: When loading profile, check for out-of-date\n\t\t// source files and warn.\n\n\t\tranges := []sourceRange{}\n\t\thistMap := map[ipInfo]*latencyHistogram{}\n\t\tfor _, hist := range histograms {\n\t\t\tranges = append(ranges, sourceRange{hist.FileName, hist.Line, hist.Line + 1, hist.weight})\n\t\t\thistMap[ipInfo{\"\", hist.FileName, hist.Line}] = hist\n\t\t}\n\t\tranges = expandSourceRanges(ranges, 5)\n\n\t\t// Sort ranges by max weight histogram.\n\t\tsort.Slice(ranges, func(i, j int) bool {\n\t\t\treturn ranges[i].maxWeight > ranges[j].maxWeight\n\t\t})\n\n\t\t// Collect lines from ranges.\n\t\thistograms = []*latencyHistogram{}\n\t\tfor _, r := range ranges {\n\t\t\tlines, r, err := getLines(r)\n\t\t\tif err != nil {\n\t\t\t\tlog.Println(err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif len(lines) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Add a header for this range of source.\n\t\t\theader := newLatencyHistogram(&scaler)\n\t\t\theader.Bins = nil\n\t\t\theader.Text = r.file\n\t\t\theader.IsHeader = true\n\t\t\thistograms = append(histograms, header)\n\n\t\t\tfor i, text := range lines {\n\t\t\t\thist := histMap[ipInfo{\"\", r.file, r.start + i}]\n\t\t\t\tif hist == nil {\n\t\t\t\t\thist = newLatencyHistogram(&scaler)\n\t\t\t\t\thist.FileName = r.file\n\t\t\t\t\thist.Line = r.start + i\n\t\t\t\t\thist.Bins = nil\n\t\t\t\t}\n\t\t\t\thist.Text = text\n\t\t\t\thistograms = append(histograms, hist)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compute maximum bin size for bin scaling.\n\tmaxBin := 0\n\tfor _, hist := range histograms {\n\t\tmax := hist.max()\n\t\tif max > maxBin {\n\t\t\tmaxBin = max\n\t\t}\n\t}\n\n\t// Construct JSON reply.\n\tmajor, minor := scaler.Ticks(scale.TickOptions{Max: 6})\n\tmajorX, minorX := vec.Map(scaler.Map, major), vec.Map(scaler.Map, minor)\n\terr = json.NewEncoder(w).Encode(struct {\n\t\tHistograms []*latencyHistogram\n\t\tMaxBin     int\n\n\t\tMajorTicks, MajorTicksX []float64\n\t\tMinorTicksX             []float64\n\t}{histograms, maxBin, major, majorX, minorX})\n\tif err != nil {\n\t\tlog.Print(err)\n\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t}\n}\n\nconst latencyHistogramBins = 60\n\n// TODO: There's a lot of code for transforming between filters in the\n// query string, latencyHistogram, and the filter struct. Unify these\n// better.\n\ntype latencyHistogram struct {\n\tscale  scale.Quantitative\n\tBins   []int `json:\",omitempty\"`\n\tweight int\n\tgroup  string\n\n\t// Filter specification.\n\tPID      int    `json:\"pid,omitempty\"`\n\tComm     string `json:\"comm,omitempty\"`\n\tFuncName string `json:\"funcName,omitempty\"`\n\tFileName string `json:\"fileName,omitempty\"`\n\tLine     int    `json:\"line,omitempty\"`\n\tAddress  uint64 `json:\"address,omitempty\"`\n\n\t// Data source filter specification.\n\tOp     perffile.DataSrcOp    `json:\"op,omitempty\"`\n\tMiss   bool                  `json:\"miss,omitempty\"`\n\tLevel  perffile.DataSrcLevel `json:\"level,omitempty\"`\n\tSnoop  perffile.DataSrcSnoop `json:\"snoop,omitempty\"`\n\tLocked perffile.DataSrcLock  `json:\"locked,omitempty\"`\n\tTLB    perffile.DataSrcTLB   `json:\"tlb,omitempty\"`\n\n\t// Presentation.\n\tText         string `json:\"text,omitempty\"`\n\tDataSrcLabel string `json:\"dataSrcLabel,omitempty\"`\n\tIsHeader     bool   `json:\"isHeader,omitempty\"`\n}\n\nfunc newLatencyHistogram(scale scale.Quantitative) *latencyHistogram {\n\treturn &latencyHistogram{\n\t\tscale:  scale,\n\t\tBins:   make([]int, latencyHistogramBins),\n\t\tweight: 0,\n\t}\n}\n\nfunc (h *latencyHistogram) update(r *record) {\n\tbin := int(h.scale.Map(float64(r.latency)) * latencyHistogramBins)\n\tif bin < 0 {\n\t\tbin = 0\n\t}\n\tif bin >= latencyHistogramBins {\n\t\tbin = latencyHistogramBins\n\t}\n\th.Bins[bin] += int(r.latency)\n\th.weight += int(r.latency)\n}\n\nfunc (h *latencyHistogram) max() int {\n\tout := 0\n\tfor _, count := range h.Bins {\n\t\tif count > out {\n\t\t\tout = count\n\t\t}\n\t}\n\treturn out\n}\n\ntype weightSorter []*latencyHistogram\n\nfunc (w weightSorter) Len() int {\n\treturn len(w)\n}\n\nfunc (w weightSorter) Less(i, j int) bool {\n\tif w[i].group != w[j].group {\n\t\treturn w[i].group > w[j].group\n\t}\n\treturn w[i].weight < w[j].weight\n}\n\nfunc (w weightSorter) Swap(i, j int) {\n\tw[i], w[j] = w[j], w[i]\n}\n\ntype sourceRange struct {\n\tfile       string\n\tstart, end int\n\tmaxWeight  int\n}\n\nfunc expandSourceRanges(r []sourceRange, by int) []sourceRange {\n\tsort.Slice(r, func(i, j int) bool {\n\t\tif r[i].file != r[j].file {\n\t\t\treturn r[i].file < r[j].file\n\t\t}\n\t\treturn r[i].start < r[j].start\n\t})\n\n\t// Expand ranges.\n\tfor i := range r {\n\t\tr[i].start -= by\n\t\tr[i].end += by\n\t}\n\n\t// Merge ranges.\n\ti := 0\n\tfor j := 1; j < len(r); j++ {\n\t\tif r[i].file == r[j].file && r[i].end >= r[j].start {\n\t\t\tif r[j].end > r[i].end {\n\t\t\t\tr[i].end = r[j].end\n\t\t\t}\n\t\t\tif r[j].maxWeight > r[i].maxWeight {\n\t\t\t\tr[i].maxWeight = r[j].maxWeight\n\t\t\t}\n\t\t} else {\n\t\t\ti++\n\t\t\tr[i] = r[j]\n\t\t}\n\t}\n\treturn r[:i+1]\n}\n\nfunc getLines(r sourceRange) ([]string, sourceRange, error) {\n\tlines := []string{}\n\n\tfile, err := os.Open(r.file)\n\tif err != nil {\n\t\treturn nil, r, err\n\t}\n\tdefer file.Close()\n\n\t// Skip to start.\n\tif r.start < 0 {\n\t\tr.start = 0\n\t}\n\tscanner := bufio.NewScanner(file)\n\tfor i := 0; i < r.start && scanner.Scan(); i++ {\n\t\t// Do nothing\n\t}\n\n\tfor i := 0; i < r.end-r.start && scanner.Err() == nil; i++ {\n\t\tlines = append(lines, scanner.Text())\n\t\tscanner.Scan()\n\t}\n\tif err := scanner.Err(); err != nil {\n\t\treturn nil, r, err\n\t}\n\n\treturn lines, r, nil\n}\n\ntype metadataHandler struct {\n\tFilename string\n\tMetadata\n}\n\nfunc (h *metadataHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {\n\terr := json.NewEncoder(w).Encode(h)\n\tif err != nil {\n\t\tlog.Print(err)\n\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t}\n}\n"
  },
  {
    "path": "cmd/memlat/static/bower.json",
    "content": "{\n  \"name\": \"memlat\",\n  \"version\": \"0.0.0\",\n  \"homepage\": \"https://github.com/aclements/go-perf\",\n  \"authors\": [\n    \"Austin Clements <(none)>\"\n  ],\n  \"license\": \"MIT\",\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"bower_components\",\n    \"test\",\n    \"tests\"\n  ],\n  \"dependencies\": {\n    \"polymer\": \"Polymer/polymer#^1.0.0\",\n    \"paper-button\": \"PolymerElements/paper-button#~1.0.3\",\n    \"paper-tabs\": \"PolymerElements/paper-tabs#~1.0.2\",\n    \"paper-styles\": \"PolymerElements/paper-styles#~1.0.11\",\n    \"iron-pages\": \"PolymerElements/iron-pages#~1.0.3\",\n    \"iron-ajax\": \"PolymerElements/iron-ajax#~1.0.4\",\n    \"paper-card\": \"PolymerElements/paper-card#~1.0.3\",\n    \"paper-header-panel\": \"PolymerElements/paper-header-panel#~1.0.4\",\n    \"paper-toolbar\": \"PolymerElements/paper-toolbar#~1.0.4\",\n    \"iron-icon\": \"PolymerElements/iron-icon#~1.0.3\",\n    \"iron-icons\": \"PolymerElements/iron-icons#~1.0.3\"\n  }\n}\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/font-roboto/.bower.json",
    "content": "{\n  \"name\": \"font-roboto\",\n  \"version\": \"1.0.1\",\n  \"description\": \"An HTML import for Roboto\",\n  \"authors\": [\n    \"The Polymer Authors\"\n  ],\n  \"keywords\": [\n    \"font\",\n    \"roboto\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/PolymerElements/font-roboto.git\"\n  },\n  \"main\": \"roboto.html\",\n  \"license\": \"http://polymer.github.io/LICENSE.txt\",\n  \"homepage\": \"https://github.com/PolymerElements/font-roboto/\",\n  \"ignore\": [\n    \"/.*\"\n  ],\n  \"_release\": \"1.0.1\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"v1.0.1\",\n    \"commit\": \"21ce9b51a417fa9995cf6606e886aba0728f70a1\"\n  },\n  \"_source\": \"git://github.com/PolymerElements/font-roboto.git\",\n  \"_target\": \"^1.0.1\",\n  \"_originalSource\": \"PolymerElements/font-roboto\"\n}"
  },
  {
    "path": "cmd/memlat/static/bower_components/font-roboto/README.md",
    "content": "# font-roboto\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/font-roboto/bower.json",
    "content": "{\n  \"name\": \"font-roboto\",\n  \"version\": \"1.0.1\",\n  \"description\": \"An HTML import for Roboto\",\n  \"authors\": [\n    \"The Polymer Authors\"\n  ],\n  \"keywords\": [\n    \"font\",\n    \"roboto\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/PolymerElements/font-roboto.git\"\n  },\n  \"main\": \"roboto.html\",\n  \"license\": \"http://polymer.github.io/LICENSE.txt\",\n  \"homepage\": \"https://github.com/PolymerElements/font-roboto/\",\n  \"ignore\": [\n    \"/.*\"\n  ]\n}\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/font-roboto/roboto.html",
    "content": "<!--\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n-->\n<link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:400,300,300italic,400italic,500,500italic,700,700italic\">\n<link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto+Mono:400,700\">\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/paper-styles/.bower.json",
    "content": "{\n  \"name\": \"paper-styles\",\n  \"version\": \"1.0.11\",\n  \"description\": \"Common (global) styles for Material Design elements.\",\n  \"authors\": [\n    \"The Polymer Authors\"\n  ],\n  \"keywords\": [\n    \"web-component\",\n    \"polymer\",\n    \"style\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/PolymerElements/paper-styles.git\"\n  },\n  \"main\": \"paper-styles.html\",\n  \"license\": \"http://polymer.github.io/LICENSE.txt\",\n  \"homepage\": \"https://github.com/polymerelements/paper-styles/\",\n  \"ignore\": [\n    \"/.*\"\n  ],\n  \"dependencies\": {\n    \"iron-flex-layout\": \"PolymerElements/iron-flex-layout#^1.0.0\",\n    \"font-roboto\": \"PolymerElements/font-roboto#^1.0.1\",\n    \"polymer\": \"Polymer/polymer#^1.0.0\"\n  },\n  \"devDependencies\": {\n    \"webcomponentsjs\": \"webcomponents/webcomponentsjs#^0.7.0\"\n  },\n  \"_release\": \"1.0.11\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"v1.0.11\",\n    \"commit\": \"347542e9ebe3e6e5f0830ee10e1c20c12956ff2c\"\n  },\n  \"_source\": \"git://github.com/polymerelements/paper-styles.git\",\n  \"_target\": \"^1.0.0\",\n  \"_originalSource\": \"polymerelements/paper-styles\"\n}"
  },
  {
    "path": "cmd/memlat/static/bower_components/paper-styles/README.md",
    "content": "# paper-styles\n\nMaterial design CSS styles.\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/paper-styles/bower.json",
    "content": "{\n  \"name\": \"paper-styles\",\n  \"version\": \"1.0.11\",\n  \"description\": \"Common (global) styles for Material Design elements.\",\n  \"authors\": [\n    \"The Polymer Authors\"\n  ],\n  \"keywords\": [\n    \"web-component\",\n    \"polymer\",\n    \"style\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/PolymerElements/paper-styles.git\"\n  },\n  \"main\": \"paper-styles.html\",\n  \"license\": \"http://polymer.github.io/LICENSE.txt\",\n  \"homepage\": \"https://github.com/polymerelements/paper-styles/\",\n  \"ignore\": [\n    \"/.*\"\n  ],\n  \"dependencies\": {\n    \"iron-flex-layout\": \"PolymerElements/iron-flex-layout#^1.0.0\",\n    \"font-roboto\": \"PolymerElements/font-roboto#^1.0.1\",\n    \"polymer\": \"Polymer/polymer#^1.0.0\"\n  },\n  \"devDependencies\": {\n    \"webcomponentsjs\": \"webcomponents/webcomponentsjs#^0.7.0\"\n  }\n}\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/paper-styles/classes/global.html",
    "content": "<!--\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n-->\n<link rel=\"import\" href=\"../paper-styles-classes.html\">\n\n<!--\nA set of base styles that are applied to the document and standard elements that\nmatch the Material Design spec.\n-->\n<style>\n/*\nNote that there is a lot of style duplication here. The hope is that the Polymer\n0.8 styling solution will allow for inheritance of properties so that we can\neventually avoid it.\n*/\n\n/* Mixins */\n\n/* [paper-font] */\nbody {\n  font-family: 'Roboto', 'Noto', sans-serif;\n  -webkit-font-smoothing: antialiased;  /* OS X subpixel AA bleed bug */\n}\n\n/* [paper-font=display2] */\nh1 {\n  font-size: 45px;\n  font-weight: 400;\n  letter-spacing: -.018em;\n  line-height: 48px;\n}\n\n/* [paper-font=display1] */\nh2 {\n  font-size: 34px;\n  font-weight: 400;\n  letter-spacing: -.01em;\n  line-height: 40px;\n}\n\n/* [paper-font=headline] */\nh3 {\n  font-size: 24px;\n  font-weight: 400;\n  letter-spacing: -.012em;\n  line-height: 32px;\n}\n\n/* [paper-font=subhead] */\nh4 {\n  font-size: 16px;\n  font-weight: 400;\n  line-height: 24px;\n}\n\n/* [paper-font=body2] */\nh5, h6 {\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 24px;\n}\n\n/* [paper-font=button] */\na {\n  font-size: 14px;\n  font-weight: 500;\n  letter-spacing: 0.018em;\n  line-height: 24px;\n  text-transform: uppercase;\n}\n\n/* Overrides */\n\nbody, a {\n  color: #212121;\n}\n\nh1, h2, h3, h4, h5, h6, p {\n  margin: 0 0 20px 0;\n}\n\nh1, h2, h3, h4, h5, h6, a {\n  text-rendering: optimizeLegibility;\n}\n\na {\n  text-decoration: none;\n}\n\n</style>\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/paper-styles/classes/shadow-layout.html",
    "content": "<!--\r\n@license\r\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\r\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\r\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\r\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\r\nCode distributed by Google as part of the polymer project is also\r\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\r\n-->\r\n<style>\r\n\r\n  /*******************************\r\n            Flex Layout\r\n  *******************************/\r\n\r\n  html /deep/ .layout.horizontal,\r\n  html /deep/ .layout.horizontal-reverse,\r\n  html /deep/ .layout.vertical,\r\n  html /deep/ .layout.vertical-reverse {\r\n    display: -ms-flexbox;\r\n    display: -webkit-flex;\r\n    display: flex;\r\n  }\r\n\r\n  html /deep/ .layout.inline {\r\n    display: -ms-inline-flexbox;\r\n    display: -webkit-inline-flex;\r\n    display: inline-flex;\r\n  }\r\n\r\n  html /deep/ .layout.horizontal {\r\n    -ms-flex-direction: row;\r\n    -webkit-flex-direction: row;\r\n    flex-direction: row;\r\n  }\r\n\r\n  html /deep/ .layout.horizontal-reverse {\r\n    -ms-flex-direction: row-reverse;\r\n    -webkit-flex-direction: row-reverse;\r\n    flex-direction: row-reverse;\r\n  }\r\n\r\n  html /deep/ .layout.vertical {\r\n    -ms-flex-direction: column;\r\n    -webkit-flex-direction: column;\r\n    flex-direction: column;\r\n  }\r\n\r\n  html /deep/ .layout.vertical-reverse {\r\n    -ms-flex-direction: column-reverse;\r\n    -webkit-flex-direction: column-reverse;\r\n    flex-direction: column-reverse;\r\n  }\r\n\r\n  html /deep/ .layout.wrap {\r\n    -ms-flex-wrap: wrap;\r\n    -webkit-flex-wrap: wrap;\r\n    flex-wrap: wrap;\r\n  }\r\n\r\n  html /deep/ .layout.wrap-reverse {\r\n    -ms-flex-wrap: wrap-reverse;\r\n    -webkit-flex-wrap: wrap-reverse;\r\n    flex-wrap: wrap-reverse;\r\n  }\r\n\r\n  html /deep/ .flex-auto {\r\n    -ms-flex: 1 1 auto;\r\n    -webkit-flex: 1 1 auto;\r\n    flex: 1 1 auto;\r\n  }\r\n\r\n  html /deep/ .flex-none {\r\n    -ms-flex: none;\r\n    -webkit-flex: none;\r\n    flex: none;\r\n  }\r\n\r\n  html /deep/ .flex,\r\n  html /deep/ .flex-1 {\r\n    -ms-flex: 1;\r\n    -webkit-flex: 1;\r\n    flex: 1;\r\n  }\r\n\r\n  html /deep/ .flex-2 {\r\n    -ms-flex: 2;\r\n    -webkit-flex: 2;\r\n    flex: 2;\r\n  }\r\n\r\n  html /deep/ .flex-3 {\r\n    -ms-flex: 3;\r\n    -webkit-flex: 3;\r\n    flex: 3;\r\n  }\r\n\r\n  html /deep/ .flex-4 {\r\n    -ms-flex: 4;\r\n    -webkit-flex: 4;\r\n    flex: 4;\r\n  }\r\n\r\n  html /deep/ .flex-5 {\r\n    -ms-flex: 5;\r\n    -webkit-flex: 5;\r\n    flex: 5;\r\n  }\r\n\r\n  html /deep/ .flex-6 {\r\n    -ms-flex: 6;\r\n    -webkit-flex: 6;\r\n    flex: 6;\r\n  }\r\n\r\n  html /deep/ .flex-7 {\r\n    -ms-flex: 7;\r\n    -webkit-flex: 7;\r\n    flex: 7;\r\n  }\r\n\r\n  html /deep/ .flex-8 {\r\n    -ms-flex: 8;\r\n    -webkit-flex: 8;\r\n    flex: 8;\r\n  }\r\n\r\n  html /deep/ .flex-9 {\r\n    -ms-flex: 9;\r\n    -webkit-flex: 9;\r\n    flex: 9;\r\n  }\r\n\r\n  html /deep/ .flex-10 {\r\n    -ms-flex: 10;\r\n    -webkit-flex: 10;\r\n    flex: 10;\r\n  }\r\n\r\n  html /deep/ .flex-11 {\r\n    -ms-flex: 11;\r\n    -webkit-flex: 11;\r\n    flex: 11;\r\n  }\r\n\r\n  html /deep/ .flex-12 {\r\n    -ms-flex: 12;\r\n    -webkit-flex: 12;\r\n    flex: 12;\r\n  }\r\n\r\n  /* alignment in cross axis */\r\n\r\n  html /deep/ .layout.start {\r\n    -ms-flex-align: start;\r\n    -webkit-align-items: flex-start;\r\n    align-items: flex-start;\r\n  }\r\n\r\n  html /deep/ .layout.center,\r\n  html /deep/ .layout.center-center {\r\n    -ms-flex-align: center;\r\n    -webkit-align-items: center;\r\n    align-items: center;\r\n  }\r\n\r\n  html /deep/ .layout.end {\r\n    -ms-flex-align: end;\r\n    -webkit-align-items: flex-end;\r\n    align-items: flex-end;\r\n  }\r\n\r\n  /* alignment in main axis */\r\n\r\n  html /deep/ .layout.start-justified {\r\n    -ms-flex-pack: start;\r\n    -webkit-justify-content: flex-start;\r\n    justify-content: flex-start;\r\n  }\r\n\r\n  html /deep/ .layout.center-justified,\r\n  html /deep/ .layout.center-center {\r\n    -ms-flex-pack: center;\r\n    -webkit-justify-content: center;\r\n    justify-content: center;\r\n  }\r\n\r\n  html /deep/ .layout.end-justified {\r\n    -ms-flex-pack: end;\r\n    -webkit-justify-content: flex-end;\r\n    justify-content: flex-end;\r\n  }\r\n\r\n  html /deep/ .layout.around-justified {\r\n    -ms-flex-pack: around;\r\n    -webkit-justify-content: space-around;\r\n    justify-content: space-around;\r\n  }\r\n\r\n  html /deep/ .layout.justified {\r\n    -ms-flex-pack: justify;\r\n    -webkit-justify-content: space-between;\r\n    justify-content: space-between;\r\n  }\r\n\r\n  /* self alignment */\r\n\r\n  html /deep/ .self-start {\r\n    -ms-align-self: flex-start;\r\n    -webkit-align-self: flex-start;\r\n    align-self: flex-start;\r\n  }\r\n\r\n  html /deep/ .self-center {\r\n    -ms-align-self: center;\r\n    -webkit-align-self: center;\r\n    align-self: center;\r\n  }\r\n\r\n  html /deep/ .self-end {\r\n    -ms-align-self: flex-end;\r\n    -webkit-align-self: flex-end;\r\n    align-self: flex-end;\r\n  }\r\n\r\n  html /deep/ .self-stretch {\r\n    -ms-align-self: stretch;\r\n    -webkit-align-self: stretch;\r\n    align-self: stretch;\r\n  }\r\n\r\n  /*******************************\r\n            Other Layout\r\n  *******************************/\r\n\r\n  html /deep/ .block {\r\n    display: block;\r\n  }\r\n\r\n  /* IE 10 support for HTML5 hidden attr */\r\n  html /deep/ [hidden] {\r\n    display: none !important;\r\n  }\r\n\r\n  html /deep/ .invisible {\r\n    visibility: hidden !important;\r\n  }\r\n\r\n  html /deep/ .relative {\r\n    position: relative;\r\n  }\r\n\r\n  html /deep/ .fit {\r\n    position: absolute;\r\n    top: 0;\r\n    right: 0;\r\n    bottom: 0;\r\n    left: 0;\r\n  }\r\n\r\n  body.fullbleed {\r\n    margin: 0;\r\n    height: 100vh;\r\n  }\r\n\r\n  html /deep/ .scroll {\r\n    -webkit-overflow-scrolling: touch;\r\n    overflow: auto;\r\n  }\r\n\r\n  .fixed-bottom,\r\n  .fixed-left,\r\n  .fixed-right,\r\n  .fixed-top {\r\n    position: fixed;\r\n  }\r\n\r\n  html /deep/ .fixed-top {\r\n    top: 0;\r\n    left: 0;\r\n    right: 0;\r\n  }\r\n\r\n  html /deep/ .fixed-right {\r\n    top: 0;\r\n    right: 0;\r\n    botttom: 0;\r\n  }\r\n\r\n  html /deep/ .fixed-bottom {\r\n    right: 0;\r\n    bottom: 0;\r\n    left: 0;\r\n  }\r\n\r\n  html /deep/ .fixed-left {\r\n    top: 0;\r\n    botttom: 0;\r\n    left: 0;\r\n  }\r\n\r\n</style>\r\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/paper-styles/classes/shadow.html",
    "content": "<!--\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n-->\n\n<style>\n.shadow-transition {\n  transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.shadow-elevation-2dp {\n  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),\n              0 1px 5px 0 rgba(0, 0, 0, 0.12),\n              0 3px 1px -2px rgba(0, 0, 0, 0.2);\n}\n\n.shadow-elevation-3dp {\n  box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14),\n              0 1px 8px 0 rgba(0, 0, 0, 0.12),\n              0 3px 3px -2px rgba(0, 0, 0, 0.4);\n}\n\n.shadow-elevation-4dp {\n  box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14),\n              0 1px 10px 0 rgba(0, 0, 0, 0.12),\n              0 2px 4px -1px rgba(0, 0, 0, 0.4);\n}\n\n.shadow-elevation-6dp {\n  box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.14),\n              0 1px 18px 0 rgba(0, 0, 0, 0.12),\n              0 3px 5px -1px rgba(0, 0, 0, 0.4);\n}\n\n.shadow-elevation-8dp {\n  box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14),\n              0 3px 14px 2px rgba(0, 0, 0, 0.12),\n              0 5px 5px -3px rgba(0, 0, 0, 0.4);\n}\n\n.shadow-elevation-16dp {\n  box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14),\n              0  6px 30px 5px rgba(0, 0, 0, 0.12),\n              0  8px 10px -5px rgba(0, 0, 0, 0.4);\n}\n\n</style>\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/paper-styles/classes/typography.html",
    "content": "<!--\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n-->\n<link rel=\"import\" href=\"../../font-roboto/roboto.html\">\n\n<!--\nTypographic styles are provided matching the Material Design standard styles:\nhttp://www.google.com/design/spec/style/typography.html#typography-standard-styles\n\nTo make use of them, apply a `paper-font-<style>` class to elements, matching\nthe font style you wish it to inherit.\n\n  <header class=\"paper-font-display2\">Hey there!</header>\n\nNote that these are English/Latin centric styles. You may need to further adjust\nline heights and weights for CJK typesetting. See the notes in the Material\nDesign typography section.\n-->\n<style>\n\n.paper-font-display4,\n.paper-font-display3,\n.paper-font-display2,\n.paper-font-display1,\n.paper-font-headline,\n.paper-font-title,\n.paper-font-subhead,\n.paper-font-body2,\n.paper-font-body1,\n.paper-font-caption,\n.paper-font-menu,\n.paper-font-button {\n  font-family: 'Roboto', 'Noto', sans-serif;\n  -webkit-font-smoothing: antialiased;  /* OS X subpixel AA bleed bug */\n}\n\n.paper-font-code2,\n.paper-font-code1 {\n  font-family: 'Roboto Mono', 'Consolas', 'Menlo', monospace;\n  -webkit-font-smoothing: antialiased;  /* OS X subpixel AA bleed bug */\n}\n\n/* Opt for better kerning for headers & other short labels. */\n.paper-font-display4,\n.paper-font-display3,\n.paper-font-display2,\n.paper-font-display1,\n.paper-font-headline,\n.paper-font-title,\n.paper-font-subhead,\n.paper-font-menu,\n.paper-font-button {\n  text-rendering: optimizeLegibility;\n}\n\n/*\n\"Line wrapping only applies to Body, Subhead, Headline, and the smaller Display\nstyles. All other styles should exist as single lines.\"\n*/\n.paper-font-display4,\n.paper-font-display3,\n.paper-font-title,\n.paper-font-caption,\n.paper-font-menu,\n.paper-font-button {\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.paper-font-display4 {\n  font-size: 112px;\n  font-weight: 300;\n  letter-spacing: -.044em;\n  line-height: 120px;\n}\n\n.paper-font-display3 {\n  font-size: 56px;\n  font-weight: 400;\n  letter-spacing: -.026em;\n  line-height: 60px;\n}\n\n.paper-font-display2 {\n  font-size: 45px;\n  font-weight: 400;\n  letter-spacing: -.018em;\n  line-height: 48px;\n}\n\n.paper-font-display1 {\n  font-size: 34px;\n  font-weight: 400;\n  letter-spacing: -.01em;\n  line-height: 40px;\n}\n\n.paper-font-headline {\n  font-size: 24px;\n  font-weight: 400;\n  letter-spacing: -.012em;\n  line-height: 32px;\n}\n\n.paper-font-title {\n  font-size: 20px;\n  font-weight: 500;\n  line-height: 28px;\n}\n\n.paper-font-subhead {\n  font-size: 16px;\n  font-weight: 400;\n  line-height: 24px;\n}\n\n.paper-font-body2 {\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 24px;\n}\n\n.paper-font-body1 {\n  font-size: 14px;\n  font-weight: 400;\n  line-height: 20px;\n}\n\n.paper-font-caption {\n  font-size: 12px;\n  font-weight: 400;\n  letter-spacing: 0.011em;\n  line-height: 20px;\n}\n\n.paper-font-menu {\n  font-size: 13px;\n  font-weight: 500;\n  line-height: 24px;\n}\n\n.paper-font-button {\n  font-size: 14px;\n  font-weight: 500;\n  letter-spacing: 0.018em;\n  line-height: 24px;\n  text-transform: uppercase;\n}\n\n.paper-font-code2 {\n  font-size: 14px;\n  font-weight: 700;\n  line-height: 20px;\n}\n\n.paper-font-code1 {\n  font-size: 14px;\n  font-weight: 700;\n  line-height: 20px;\n}\n\n</style>\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/paper-styles/color.html",
    "content": "<!--\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n-->\n\n<link rel=\"import\" href=\"../polymer/polymer.html\">\n\n<style is=\"custom-style\">\n\n  :root {\n\n    /* Material Design color palette for Google products */\n\n    --google-red-100: #f4c7c3;\n    --google-red-300: #e67c73;\n    --google-red-500: #db4437;\n    --google-red-700: #c53929;\n\n    --google-blue-100: #c6dafc;\n    --google-blue-300: #7baaf7;\n    --google-blue-500: #4285f4;\n    --google-blue-700: #3367d6;\n\n    --google-green-100: #b7e1cd;\n    --google-green-300: #57bb8a;\n    --google-green-500: #0f9d58;\n    --google-green-700: #0b8043;\n\n    --google-yellow-100: #fce8b2;\n    --google-yellow-300: #f7cb4d;\n    --google-yellow-500: #f4b400;\n    --google-yellow-700: #f09300;\n\n    --google-grey-100: #f5f5f5;\n    --google-grey-300: #e0e0e0;\n    --google-grey-500: #9e9e9e;\n    --google-grey-700: #616161;\n    \n    /* Material Design color palette from online spec document */\n\n    --paper-red-50: #ffebee;\n    --paper-red-100: #ffcdd2;\n    --paper-red-200: #ef9a9a;\n    --paper-red-300: #e57373;\n    --paper-red-400: #ef5350;\n    --paper-red-500: #f44336;\n    --paper-red-600: #e53935;\n    --paper-red-700: #d32f2f;\n    --paper-red-800: #c62828;\n    --paper-red-900: #b71c1c;\n    --paper-red-a100: #ff8a80;\n    --paper-red-a200: #ff5252;\n    --paper-red-a400: #ff1744;\n    --paper-red-a700: #d50000;\n \n    --paper-pink-50: #fce4ec;\n    --paper-pink-100: #f8bbd0;\n    --paper-pink-200: #f48fb1;\n    --paper-pink-300: #f06292;\n    --paper-pink-400: #ec407a;\n    --paper-pink-500: #e91e63;\n    --paper-pink-600: #d81b60;\n    --paper-pink-700: #c2185b;\n    --paper-pink-800: #ad1457;\n    --paper-pink-900: #880e4f;\n    --paper-pink-a100: #ff80ab;\n    --paper-pink-a200: #ff4081;\n    --paper-pink-a400: #f50057;\n    --paper-pink-a700: #c51162;\n \n    --paper-purple-50: #f3e5f5;\n    --paper-purple-100: #e1bee7;\n    --paper-purple-200: #ce93d8;\n    --paper-purple-300: #ba68c8;\n    --paper-purple-400: #ab47bc;\n    --paper-purple-500: #9c27b0;\n    --paper-purple-600: #8e24aa;\n    --paper-purple-700: #7b1fa2;\n    --paper-purple-800: #6a1b9a;\n    --paper-purple-900: #4a148c;\n    --paper-purple-a100: #ea80fc;\n    --paper-purple-a200: #e040fb;\n    --paper-purple-a400: #d500f9;\n    --paper-purple-a700: #aa00ff;\n \n    --paper-deep-purple-50: #ede7f6;\n    --paper-deep-purple-100: #d1c4e9;\n    --paper-deep-purple-200: #b39ddb;\n    --paper-deep-purple-300: #9575cd;\n    --paper-deep-purple-400: #7e57c2;\n    --paper-deep-purple-500: #673ab7;\n    --paper-deep-purple-600: #5e35b1;\n    --paper-deep-purple-700: #512da8;\n    --paper-deep-purple-800: #4527a0;\n    --paper-deep-purple-900: #311b92;\n    --paper-deep-purple-a100: #b388ff;\n    --paper-deep-purple-a200: #7c4dff;\n    --paper-deep-purple-a400: #651fff;\n    --paper-deep-purple-a700: #6200ea;\n \n    --paper-indigo-50: #e8eaf6;\n    --paper-indigo-100: #c5cae9;\n    --paper-indigo-200: #9fa8da;\n    --paper-indigo-300: #7986cb;\n    --paper-indigo-400: #5c6bc0;\n    --paper-indigo-500: #3f51b5;\n    --paper-indigo-600: #3949ab;\n    --paper-indigo-700: #303f9f;\n    --paper-indigo-800: #283593;\n    --paper-indigo-900: #1a237e;\n    --paper-indigo-a100: #8c9eff;\n    --paper-indigo-a200: #536dfe;\n    --paper-indigo-a400: #3d5afe;\n    --paper-indigo-a700: #304ffe;\n \n    --paper-blue-50: #e3f2fd;\n    --paper-blue-100: #bbdefb;\n    --paper-blue-200: #90caf9;\n    --paper-blue-300: #64b5f6;\n    --paper-blue-400: #42a5f5;\n    --paper-blue-500: #2196f3;\n    --paper-blue-600: #1e88e5;\n    --paper-blue-700: #1976d2;\n    --paper-blue-800: #1565c0;\n    --paper-blue-900: #0d47a1;\n    --paper-blue-a100: #82b1ff;\n    --paper-blue-a200: #448aff;\n    --paper-blue-a400: #2979ff;\n    --paper-blue-a700: #2962ff;\n \n    --paper-light-blue-50: #e1f5fe;\n    --paper-light-blue-100: #b3e5fc;\n    --paper-light-blue-200: #81d4fa;\n    --paper-light-blue-300: #4fc3f7;\n    --paper-light-blue-400: #29b6f6;\n    --paper-light-blue-500: #03a9f4;\n    --paper-light-blue-600: #039be5;\n    --paper-light-blue-700: #0288d1;\n    --paper-light-blue-800: #0277bd;\n    --paper-light-blue-900: #01579b;\n    --paper-light-blue-a100: #80d8ff;\n    --paper-light-blue-a200: #40c4ff;\n    --paper-light-blue-a400: #00b0ff;\n    --paper-light-blue-a700: #0091ea;\n \n    --paper-cyan-50: #e0f7fa;\n    --paper-cyan-100: #b2ebf2;\n    --paper-cyan-200: #80deea;\n    --paper-cyan-300: #4dd0e1;\n    --paper-cyan-400: #26c6da;\n    --paper-cyan-500: #00bcd4;\n    --paper-cyan-600: #00acc1;\n    --paper-cyan-700: #0097a7;\n    --paper-cyan-800: #00838f;\n    --paper-cyan-900: #006064;\n    --paper-cyan-a100: #84ffff;\n    --paper-cyan-a200: #18ffff;\n    --paper-cyan-a400: #00e5ff;\n    --paper-cyan-a700: #00b8d4;\n \n    --paper-teal-50: #e0f2f1;\n    --paper-teal-100: #b2dfdb;\n    --paper-teal-200: #80cbc4;\n    --paper-teal-300: #4db6ac;\n    --paper-teal-400: #26a69a;\n    --paper-teal-500: #009688;\n    --paper-teal-600: #00897b;\n    --paper-teal-700: #00796b;\n    --paper-teal-800: #00695c;\n    --paper-teal-900: #004d40;\n    --paper-teal-a100: #a7ffeb;\n    --paper-teal-a200: #64ffda;\n    --paper-teal-a400: #1de9b6;\n    --paper-teal-a700: #00bfa5;\n \n    --paper-green-50: #e8f5e9;\n    --paper-green-100: #c8e6c9;\n    --paper-green-200: #a5d6a7;\n    --paper-green-300: #81c784;\n    --paper-green-400: #66bb6a;\n    --paper-green-500: #4caf50;\n    --paper-green-600: #43a047;\n    --paper-green-700: #388e3c;\n    --paper-green-800: #2e7d32;\n    --paper-green-900: #1b5e20;\n    --paper-green-a100: #b9f6ca;\n    --paper-green-a200: #69f0ae;\n    --paper-green-a400: #00e676;\n    --paper-green-a700: #00c853;\n \n    --paper-light-green-50: #f1f8e9;\n    --paper-light-green-100: #dcedc8;\n    --paper-light-green-200: #c5e1a5;\n    --paper-light-green-300: #aed581;\n    --paper-light-green-400: #9ccc65;\n    --paper-light-green-500: #8bc34a;\n    --paper-light-green-600: #7cb342;\n    --paper-light-green-700: #689f38;\n    --paper-light-green-800: #558b2f;\n    --paper-light-green-900: #33691e;\n    --paper-light-green-a100: #ccff90;\n    --paper-light-green-a200: #b2ff59;\n    --paper-light-green-a400: #76ff03;\n    --paper-light-green-a700: #64dd17;\n \n    --paper-lime-50: #f9fbe7;\n    --paper-lime-100: #f0f4c3;\n    --paper-lime-200: #e6ee9c;\n    --paper-lime-300: #dce775;\n    --paper-lime-400: #d4e157;\n    --paper-lime-500: #cddc39;\n    --paper-lime-600: #c0ca33;\n    --paper-lime-700: #afb42b;\n    --paper-lime-800: #9e9d24;\n    --paper-lime-900: #827717;\n    --paper-lime-a100: #f4ff81;\n    --paper-lime-a200: #eeff41;\n    --paper-lime-a400: #c6ff00;\n    --paper-lime-a700: #aeea00;\n \n    --paper-yellow-50: #fffde7;\n    --paper-yellow-100: #fff9c4;\n    --paper-yellow-200: #fff59d;\n    --paper-yellow-300: #fff176;\n    --paper-yellow-400: #ffee58;\n    --paper-yellow-500: #ffeb3b;\n    --paper-yellow-600: #fdd835;\n    --paper-yellow-700: #fbc02d;\n    --paper-yellow-800: #f9a825;\n    --paper-yellow-900: #f57f17;\n    --paper-yellow-a100: #ffff8d;\n    --paper-yellow-a200: #ffff00;\n    --paper-yellow-a400: #ffea00;\n    --paper-yellow-a700: #ffd600;\n \n    --paper-amber-50: #fff8e1;\n    --paper-amber-100: #ffecb3;\n    --paper-amber-200: #ffe082;\n    --paper-amber-300: #ffd54f;\n    --paper-amber-400: #ffca28;\n    --paper-amber-500: #ffc107;\n    --paper-amber-600: #ffb300;\n    --paper-amber-700: #ffa000;\n    --paper-amber-800: #ff8f00;\n    --paper-amber-900: #ff6f00;\n    --paper-amber-a100: #ffe57f;\n    --paper-amber-a200: #ffd740;\n    --paper-amber-a400: #ffc400;\n    --paper-amber-a700: #ffab00;\n \n    --paper-orange-50: #fff3e0;\n    --paper-orange-100: #ffe0b2;\n    --paper-orange-200: #ffcc80;\n    --paper-orange-300: #ffb74d;\n    --paper-orange-400: #ffa726;\n    --paper-orange-500: #ff9800;\n    --paper-orange-600: #fb8c00;\n    --paper-orange-700: #f57c00;\n    --paper-orange-800: #ef6c00;\n    --paper-orange-900: #e65100;\n    --paper-orange-a100: #ffd180;\n    --paper-orange-a200: #ffab40;\n    --paper-orange-a400: #ff9100;\n    --paper-orange-a700: #ff6500;\n \n    --paper-deep-orange-50: #fbe9e7;\n    --paper-deep-orange-100: #ffccbc;\n    --paper-deep-orange-200: #ffab91;\n    --paper-deep-orange-300: #ff8a65;\n    --paper-deep-orange-400: #ff7043;\n    --paper-deep-orange-500: #ff5722;\n    --paper-deep-orange-600: #f4511e;\n    --paper-deep-orange-700: #e64a19;\n    --paper-deep-orange-800: #d84315;\n    --paper-deep-orange-900: #bf360c;\n    --paper-deep-orange-a100: #ff9e80;\n    --paper-deep-orange-a200: #ff6e40;\n    --paper-deep-orange-a400: #ff3d00;\n    --paper-deep-orange-a700: #dd2c00;\n \n    --paper-brown-50: #efebe9;\n    --paper-brown-100: #d7ccc8;\n    --paper-brown-200: #bcaaa4;\n    --paper-brown-300: #a1887f;\n    --paper-brown-400: #8d6e63;\n    --paper-brown-500: #795548;\n    --paper-brown-600: #6d4c41;\n    --paper-brown-700: #5d4037;\n    --paper-brown-800: #4e342e;\n    --paper-brown-900: #3e2723;\n \n    --paper-grey-50: #fafafa;\n    --paper-grey-100: #f5f5f5;\n    --paper-grey-200: #eeeeee;\n    --paper-grey-300: #e0e0e0;\n    --paper-grey-400: #bdbdbd;\n    --paper-grey-500: #9e9e9e;\n    --paper-grey-600: #757575;\n    --paper-grey-700: #616161;\n    --paper-grey-800: #424242;\n    --paper-grey-900: #212121;\n \n    --paper-blue-grey-50: #eceff1;\n    --paper-blue-grey-100: #cfd8dc;\n    --paper-blue-grey-200: #b0bec5;\n    --paper-blue-grey-300: #90a4ae;\n    --paper-blue-grey-400: #78909c;\n    --paper-blue-grey-500: #607d8b;\n    --paper-blue-grey-600: #546e7a;\n    --paper-blue-grey-700: #455a64;\n    --paper-blue-grey-800: #37474f;\n    --paper-blue-grey-900: #263238;\n\n    /* opacity for dark text on a light background */\n    --dark-divider-opacity: 0.12;\n    --dark-disabled-opacity: 0.26; /* or hint text */\n    --dark-secondary-opacity: 0.54; /* or icon */\n    --dark-primary-opacity: 0.87;\n\n    /* opacity for light text on a dark background */\n    --light-divider-opacity: 0.12;\n    --light-disabled-opacity: 0.3; /* or hint text */\n    --light-secondary-opacity: 0.7; /* or icon */\n    --light-primary-opacity: 1.0;\n\n  }\n\n</style>\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/paper-styles/default-theme.html",
    "content": "<!--\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n-->\n\n<link rel=\"import\" href=\"../polymer/polymer.html\">\n\n<style is=\"custom-style\">\n\n  :root {\n\n    --dark-primary-color: #303f9f;\n\n    --default-primary-color: #3f51b5;\n\n    --light-primary-color: #c5cae9;\n\n    --text-primary-color: #ffffff;\n\n    --accent-color: #ff4081;\n\n    --primary-background-color: #ffffff;\n\n    --primary-text-color: #212121;\n\n    --secondary-text-color: #757575;\n\n    --disabled-text-color: #bdbdbd;\n\n    --divider-color: #e0e0e0;\n\n  }\n\n</style>\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/paper-styles/demo/index.html",
    "content": "<!doctype html>\n\n<!--\n  @license\n  Copyright (c) 2015 The Polymer Project Authors. All rights reserved.\n  This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\n  The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\n  The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\n  Code distributed by Google as part of the polymer project is also\n  subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n-->\n\n<html>\n  <head>\n\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes\">\n\n    <title>paper-styles demo</title>\n\n    <script src=\"../../webcomponentsjs/webcomponents-lite.js\"></script>\n\n    <link rel=\"import\" href=\"../paper-styles.html\">\n    <link rel=\"import\" href=\"../demo-pages.html\">\n\n    <style>\n\n      .redlines {\n        background: linear-gradient(0deg, transparent, transparent 3.5px, rgba(255,0,0,0.2) 3.5px, rgba(255,0,0,0.2) 4px);\n        background-size: 100% 4px;\n      }\n\n      .paragraph {\n        margin-bottom: 20px;\n      }\n\n    </style>\n\n  </head>\n  <body unresolved>\n\n    <!-- FIXME remove when https://github.com/Polymer/polymer/issues/1415 is resolved -->\n    <dom-module id=\"x-demo\">\n\n      <style>\n\n        .paper-font-display4 {\n          @apply(--paper-font-display4);\n        }\n\n        .paper-font-display3 {\n          @apply(--paper-font-display3);\n        }\n\n        .paper-font-display2 {\n          @apply(--paper-font-display2);\n        }\n\n        .paper-font-display1 {\n          @apply(--paper-font-display1);\n        }\n\n        .paper-font-headline {\n          @apply(--paper-font-headline);\n        }\n\n        .paper-font-title {\n          @apply(--paper-font-title);\n        }\n\n        .paper-font-subhead {\n          @apply(--paper-font-subhead);\n        }\n\n        .paper-font-body2 {\n          @apply(--paper-font-body1);\n        }\n\n        .paper-font-body1 {\n          @apply(--paper-font-body1);\n        }\n\n        .paper-font-caption {\n          @apply(--paper-font-caption);\n        }\n\n        .paper-font-menu {\n          @apply(--paper-font-menu);\n        }\n\n        .paper-font-button {\n          @apply(--paper-font-button);\n        }\n\n        .mobile-app {\n          max-width: 320px;\n        }\n\n        .toolbar {\n          height: 144px;\n          padding: 16px;\n\n          background: var(--default-primary-color);\n          color: var(--text-primary-color);\n          @apply(--paper-font-display1);\n        }\n\n        .item, .disabled-item {\n          position: relative;\n          padding: 8px;\n          border: 1px solid;\n          border-color: var(--divider-color);\n          border-top: 0;\n        }\n\n        .item .primary {\n          color: var(--primary-text-color);\n\n          @apply(--paper-font-body2);\n        }\n\n        .item .secondary {\n          color: var(--secondary-text-color);\n\n          @apply(--paper-font-body1);\n        }\n\n        .disabled-item {\n          color: var(--disabled-text-color);\n\n          @apply(--paper-font-body2);\n        }\n\n        .fab {\n          position: absolute;\n          box-sizing: border-box;\n          padding: 8px;\n          width: 56px;\n          height: 56px;\n          right: 16px;\n          top: -28px;\n          border-radius: 50%;\n          text-align: center;\n\n          background: var(--accent-color);\n          color: var(--text-primary-color);\n          @apply(--paper-font-display1);\n        }\n\n        .shadow {\n          display: inline-block;\n          padding: 8px;\n          margin: 16px;\n          height: 50px;\n          width: 50px;\n        }\n\n        .shadow-2dp {\n          @apply(--shadow-elevation-2dp);\n        }\n\n        .shadow-3dp {\n          @apply(--shadow-elevation-3dp);\n        }\n\n        .shadow-4dp {\n          @apply(--shadow-elevation-4dp);\n        }\n\n        .shadow-6dp {\n          @apply(--shadow-elevation-6dp);\n        }\n\n        .shadow-8dp {\n          @apply(--shadow-elevation-8dp);\n        }\n\n        .shadow-16dp {\n          @apply(--shadow-elevation-16dp);\n        }\n\n      </style>\n\n      <template>\n\n        <h1>paper-styles</h1>\n\n        <section id=\"default-theme\">\n          <h2>default-theme.html</h2>\n\n          <section class=\"mobile-app\">\n            <div class=\"toolbar\">\n              Title\n            </div>\n            <div class=\"item\">\n              <div class=\"fab\">+</div>\n              <div class=\"primary\">Primary text</div>\n              <div class=\"secondary\">Secondary text</div>\n            </div>\n            <div class=\"disabled-item\">\n              Disabled\n            </div>\n          </section>\n        </section>\n\n        <section id=\"typography\">\n          <h2>typography.html</h2>\n          <p>\n            Grumpy wizards make toxic brew for the evil Queen and Jack.\n          </p>\n          <section class=\"redlines paragraph\">\n            <div class=\"paper-font-display4\">Display 4</div>\n            <div class=\"paper-font-display3\">Display 3</div>\n            <div class=\"paper-font-display2\">Display 2</div>\n            <div class=\"paper-font-display1\">Display 1</div>\n            <div class=\"paper-font-headline\">Headline</div>\n            <div class=\"paper-font-title\">Title</div>\n            <div class=\"paper-font-subhead\">Subhead</div>\n            <div class=\"paper-font-body2\">Body 2</div>\n            <div class=\"paper-font-body1\">Body 1</div>\n            <div class=\"paper-font-caption\">Caption</div>\n            <div class=\"paper-font-menu\">Menu</div>\n            <div class=\"paper-font-button\">Button</div>\n          </section>\n\n          <h3>Paragraphs</h3>\n\n          <h4>body2</h4>\n          <section class=\"paper-font-body2 redlines\">\n            <p>\n              Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi\n              tincidunt dui sit amet mi auctor, ac gravida magna aliquam. Fusce quis\n              purus elementum, tempus nisi vel, volutpat nulla. Vestibulum mollis\n              dictum tellus, vulputate porttitor arcu. Curabitur imperdiet risus id\n              egestas accumsan. Donec lectus felis, dignissim id iaculis sit amet,\n              faucibus in leo.\n            </p>\n            <p>\n              Mauris id urna ac ante ultrices commodo a imperdiet elit. Vivamus\n              interdum neque magna, eget dapibus est auctor et. Donec accumsan\n              libero nec augue scelerisque, ac egestas ante tincidunt. Proin\n              sollicitudin, mi eget sagittis mollis, arcu orci scelerisque turpis, a\n              sollicitudin tellus quam non sapien.\n            </p>\n          </section>\n\n          <h4>body1</h4>\n          <section class=\"paper-font-body1 redlines\">\n            <p>\n              Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi\n              tincidunt dui sit amet mi auctor, ac gravida magna aliquam. Fusce quis\n              purus elementum, tempus nisi vel, volutpat nulla. Vestibulum mollis\n              dictum tellus, vulputate porttitor arcu. Curabitur imperdiet risus id\n              egestas accumsan. Donec lectus felis, dignissim id iaculis sit amet,\n              faucibus in leo.\n            </p>\n            <p>\n              Mauris id urna ac ante ultrices commodo a imperdiet elit. Vivamus\n              interdum neque magna, eget dapibus est auctor et. Donec accumsan\n              libero nec augue scelerisque, ac egestas ante tincidunt. Proin\n              sollicitudin, mi eget sagittis mollis, arcu orci scelerisque turpis, a\n              sollicitudin tellus quam non sapien.\n            </p>\n          </section>\n        </section>\n\n        <section id=\"shadow\">\n          <h2>shadow.html</h2>\n          <div class=\"shadow shadow-2dp\">2dp</div>\n          <div class=\"shadow shadow-3dp\">3dp</div>\n          <div class=\"shadow shadow-4dp\">4dp</div>\n          <div class=\"shadow shadow-6dp\">6dp</div>\n          <div class=\"shadow shadow-8dp\">8dp</div>\n          <div class=\"shadow shadow-16dp\">16dp</div>\n        </section>\n\n      </template>\n    </dom-module>\n\n    <script>\n      document.addEventListener('HTMLImportsLoaded', function() {\n        Polymer({\n          is: 'x-demo',\n          enableCustomStyleProperties: true\n        });\n      });\n    </script>\n\n    <x-demo></x-demo>\n\n    <section id=\"demo-page\">\n      <h2>demo-pages.html</h2>\n\n      <h3>Horizontal sections</h3>\n      <div class=\"horizontal-section-container\">\n        <div>\n          <h4>Column 1</h4>\n          <div class=\"horizontal-section\">\n            <div>Oxygen</div>\n            <div>Carbon</div>\n            <div>Hydrogen</div>\n            <div>Nitrogen</div>\n            <div>Calcium</div>\n          </div>\n        </div>\n\n        <div>\n          <h4>Column 2</h4>\n          <div class=\"horizontal-section\">\n            <div>Oxygen</div>\n            <div>Carbon</div>\n            <div>Hydrogen</div>\n            <div>Nitrogen</div>\n            <div>Calcium</div>\n          </div>\n        </div>\n\n        <div>\n          <h4>Column 3</h4>\n          <div class=\"horizontal-section\">\n            <div>Oxygen</div>\n            <div>Carbon</div>\n            <div>Hydrogen</div>\n            <div>Nitrogen</div>\n            <div>Calcium</div>\n          </div>\n        </div>\n      </div>\n\n      <h3>Vertical sections</h3>\n      <div class=\"vertical-section-container\">\n        <div>\n          <h4>Section 1</h4>\n          <div class=\"vertical-section\">\n            <div>Oxygen</div>\n            <div>Carbon</div>\n            <div>Hydrogen</div>\n            <div>Nitrogen</div>\n            <div>Calcium</div>\n          </div>\n        </div>\n      </div>\n\n      <div class=\"vertical-section-container centered\">\n        <h4>Section 2 (centered)</h4>\n        <div class=\"vertical-section\">\n          <div>Oxygen</div>\n          <div>Carbon</div>\n          <div>Hydrogen</div>\n          <div>Nitrogen</div>\n          <div>Calcium</div>\n        </div>\n      </div>\n\n    </section>\n\n  </body>\n</html>\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/paper-styles/demo-pages.html",
    "content": "<!--\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n-->\n\n<link rel=\"import\" href=\"../polymer/polymer.html\">\n\n<link rel=\"import\" href=\"../iron-flex-layout/iron-flex-layout.html\">\n\n<link rel=\"import\" href=\"color.html\">\n<link rel=\"import\" href=\"typography.html\">\n<link rel=\"import\" href=\"shadow.html\">\n\n<style is=\"custom-style\">\n\n  body {\n    font-family: 'Roboto', 'Noto', sans-serif;\n    font-size: 14px;\n    margin: 0;\n    padding: 24px;\n    background-color: var(--paper-grey-50);\n  }\n\n  .horizontal-section-container {\n    @apply(--layout-horizontal);\n    @apply(--layout-center-justified);\n    @apply(--layout-wrap);\n  }\n\n  .vertical-section-container {\n    @apply(--layout-vertical);\n    @apply(--center-justified);\n  }\n\n  .horizontal-section {\n    background-color: white;\n    padding: 24px;\n    margin-right: 24px;\n    min-width: 200px;\n\n    @apply(--shadow-elevation-2dp);\n  }\n\n  .vertical-section {\n    background-color: white;\n    padding: 24px;\n    margin: 0 24px 24px 24px;\n\n    @apply(--shadow-elevation-2dp);\n  }\n\n  .centered {\n    max-width: 400px;\n    margin-left: auto;\n    margin-right: auto;\n  }\n\n  code {\n    color: var(--google-grey-700);\n  }\n\n  /* TODO: remove this hack and use horizontal-section-container instead */\n  body > div.layout.horizontal.center-justified {\n    @apply(--layout-wrap);\n  }\n\n</style>\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/paper-styles/demo.css",
    "content": "/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n\n*/\nbody {\n  font-family: 'Roboto', 'Noto', sans-serif;\n  font-size: 14px;\n  margin: 0;\n  padding: 24px;\n}\n\nsection {\n  padding: 20px 0;\n}\n\nsection > div {\n  padding: 14px;\n  font-size: 16px;\n}\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/paper-styles/paper-styles-classes.html",
    "content": "<!--\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n-->\n\n<link rel=\"import\" href=\"../iron-flex-layout/classes/iron-flex-layout.html\">\n\n<link rel=\"import\" href=\"classes/typography.html\">\n<link rel=\"import\" href=\"classes/shadow.html\">\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/paper-styles/paper-styles.html",
    "content": "<!--\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n-->\n\n<link rel=\"import\" href=\"../iron-flex-layout/iron-flex-layout.html\">\n<link rel=\"import\" href=\"../iron-flex-layout/classes/iron-flex-layout.html\">\n\n<link rel=\"import\" href=\"color.html\">\n<link rel=\"import\" href=\"default-theme.html\">\n<link rel=\"import\" href=\"shadow.html\">\n<link rel=\"import\" href=\"typography.html\">\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/paper-styles/shadow.html",
    "content": "<!--\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n-->\n\n<link rel=\"import\" href=\"../polymer/polymer.html\">\n\n<style is=\"custom-style\">\n\n  :root {\n\n    --shadow-transition: {\n      transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1);\n    };\n\n    --shadow-none: {\n      box-shadow: none;\n    };\n\n    /* from http://codepen.io/shyndman/pen/c5394ddf2e8b2a5c9185904b57421cdb */\n\n    --shadow-elevation-2dp: {\n      box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),\n                  0 1px 5px 0 rgba(0, 0, 0, 0.12),\n                  0 3px 1px -2px rgba(0, 0, 0, 0.2);\n    };\n\n    --shadow-elevation-3dp: {\n      box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14),\n                  0 1px 8px 0 rgba(0, 0, 0, 0.12),\n                  0 3px 3px -2px rgba(0, 0, 0, 0.4);\n    };\n\n    --shadow-elevation-4dp: {\n      box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14),\n                  0 1px 10px 0 rgba(0, 0, 0, 0.12),\n                  0 2px 4px -1px rgba(0, 0, 0, 0.4);\n    };\n\n    --shadow-elevation-6dp: {\n      box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.14),\n                  0 1px 18px 0 rgba(0, 0, 0, 0.12),\n                  0 3px 5px -1px rgba(0, 0, 0, 0.4);\n    };\n\n    --shadow-elevation-8dp: {\n      box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14),\n                  0 3px 14px 2px rgba(0, 0, 0, 0.12),\n                  0 5px 5px -3px rgba(0, 0, 0, 0.4);\n    };\n\n    --shadow-elevation-16dp: {\n      box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14),\n                  0  6px 30px 5px rgba(0, 0, 0, 0.12),\n                  0  8px 10px -5px rgba(0, 0, 0, 0.4);\n    };\n\n  }\n\n</style>\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/paper-styles/typography.html",
    "content": "<!--\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n-->\n\n<link rel=\"import\" href=\"../polymer/polymer.html\">\n<link rel=\"import\" href=\"../font-roboto/roboto.html\">\n\n<style is=\"custom-style\">\n\n  :root {\n\n    /* Shared Styles */\n\n    /*\n    Unfortunately, we can't use nested rules\n    See https://github.com/Polymer/polymer/issues/1399\n    */\n    --paper-font-common-base: {\n      font-family: 'Roboto', 'Noto', sans-serif;\n      -webkit-font-smoothing: antialiased;\n    };\n\n    --paper-font-common-code: {\n      font-family: 'Roboto Mono', 'Consolas', 'Menlo', monospace;\n      -webkit-font-smoothing: antialiased;\n    };\n\n    --paper-font-common-expensive-kerning: {\n      text-rendering: optimizeLegibility;\n    };\n\n    --paper-font-common-nowrap: {\n      white-space: nowrap;\n      overflow: hidden;\n      text-overflow: ellipsis;\n    };\n\n    /* Material Font Styles */\n\n    --paper-font-display4: {\n      /* @apply(--paper-font-common-base) */\n      font-family: 'Roboto', 'Noto', sans-serif;\n      -webkit-font-smoothing: antialiased;\n      /* @apply(--paper-font-common-expensive-kerning); */\n      text-rendering: optimizeLegibility;\n      /* @apply(--paper-font-common-nowrap); */\n      white-space: nowrap;\n      overflow: hidden;\n      text-overflow: ellipsis;\n\n      font-size: 112px;\n      font-weight: 300;\n      letter-spacing: -.044em;\n      line-height: 120px;\n    };\n\n    --paper-font-display3: {\n      /* @apply(--paper-font-common-base) */\n      font-family: 'Roboto', 'Noto', sans-serif;\n      -webkit-font-smoothing: antialiased;\n      /* @apply(--paper-font-common-expensive-kerning); */\n      text-rendering: optimizeLegibility;\n      /* @apply(--paper-font-common-nowrap); */\n      white-space: nowrap;\n      overflow: hidden;\n      text-overflow: ellipsis;\n\n      font-size: 56px;\n      font-weight: 400;\n      letter-spacing: -.026em;\n      line-height: 60px;\n    };\n\n    --paper-font-display2: {\n      /* @apply(--paper-font-common-base) */\n      font-family: 'Roboto', 'Noto', sans-serif;\n      -webkit-font-smoothing: antialiased;\n      /* @apply(--paper-font-common-expensive-kerning); */\n      text-rendering: optimizeLegibility;\n\n      font-size: 45px;\n      font-weight: 400;\n      letter-spacing: -.018em;\n      line-height: 48px;\n    };\n\n    --paper-font-display1: {\n      /* @apply(--paper-font-common-base) */\n      font-family: 'Roboto', 'Noto', sans-serif;\n      -webkit-font-smoothing: antialiased;\n      /* @apply(--paper-font-common-expensive-kerning); */\n      text-rendering: optimizeLegibility;\n\n      font-size: 34px;\n      font-weight: 400;\n      letter-spacing: -.01em;\n      line-height: 40px;\n    };\n\n    --paper-font-headline: {\n      /* @apply(--paper-font-common-base) */\n      font-family: 'Roboto', 'Noto', sans-serif;\n      -webkit-font-smoothing: antialiased;\n      /* @apply(--paper-font-common-expensive-kerning); */\n      text-rendering: optimizeLegibility;\n\n      font-size: 24px;\n      font-weight: 400;\n      letter-spacing: -.012em;\n      line-height: 32px;\n    };\n\n    --paper-font-title: {\n      /* @apply(--paper-font-common-base) */\n      font-family: 'Roboto', 'Noto', sans-serif;\n      -webkit-font-smoothing: antialiased;\n      /* @apply(--paper-font-common-expensive-kerning); */\n      text-rendering: optimizeLegibility;\n      /* @apply(--paper-font-common-nowrap); */\n      white-space: nowrap;\n      overflow: hidden;\n      text-overflow: ellipsis;\n\n      font-size: 20px;\n      font-weight: 500;\n      line-height: 28px;\n    };\n\n    --paper-font-subhead: {\n      /* @apply(--paper-font-common-base) */\n      font-family: 'Roboto', 'Noto', sans-serif;\n      -webkit-font-smoothing: antialiased;\n      /* @apply(--paper-font-common-expensive-kerning); */\n      text-rendering: optimizeLegibility;\n\n      font-size: 16px;\n      font-weight: 400;\n      line-height: 24px;\n    };\n\n    --paper-font-body2: {\n      /* @apply(--paper-font-common-base) */\n      font-family: 'Roboto', 'Noto', sans-serif;\n      -webkit-font-smoothing: antialiased;\n\n      font-size: 14px;\n      font-weight: 500;\n      line-height: 24px;\n    };\n\n    --paper-font-body1: {\n      /* @apply(--paper-font-common-base) */\n      font-family: 'Roboto', 'Noto', sans-serif;\n      -webkit-font-smoothing: antialiased;\n\n      font-size: 14px;\n      font-weight: 400;\n      line-height: 20px;\n    };\n\n    --paper-font-caption: {\n      /* @apply(--paper-font-common-base) */\n      font-family: 'Roboto', 'Noto', sans-serif;\n      -webkit-font-smoothing: antialiased;\n      /* @apply(--paper-font-common-nowrap); */\n      white-space: nowrap;\n      overflow: hidden;\n      text-overflow: ellipsis;\n\n      font-size: 12px;\n      font-weight: 400;\n      letter-spacing: 0.011em;\n      line-height: 20px;\n    };\n\n    --paper-font-menu: {\n      /* @apply(--paper-font-common-base) */\n      font-family: 'Roboto', 'Noto', sans-serif;\n      -webkit-font-smoothing: antialiased;\n      /* @apply(--paper-font-common-expensive-kerning); */\n      text-rendering: optimizeLegibility;\n      /* @apply(--paper-font-common-nowrap); */\n      white-space: nowrap;\n      overflow: hidden;\n      text-overflow: ellipsis;\n\n      font-size: 13px;\n      font-weight: 500;\n      line-height: 24px;\n    };\n\n    --paper-font-button: {\n      /* @apply(--paper-font-common-base) */\n      font-family: 'Roboto', 'Noto', sans-serif;\n      -webkit-font-smoothing: antialiased;\n      /* @apply(--paper-font-common-expensive-kerning); */\n      text-rendering: optimizeLegibility;\n      /* @apply(--paper-font-common-nowrap); */\n      white-space: nowrap;\n      overflow: hidden;\n      text-overflow: ellipsis;\n\n      font-size: 14px;\n      font-weight: 500;\n      letter-spacing: 0.018em;\n      line-height: 24px;\n      text-transform: uppercase;\n    };\n\n    --paper-font-code2: {\n      /* @apply(--paper-font-common-code); */\n      font-family: 'Roboto Mono', 'Consolas', 'Menlo', monospace;\n      -webkit-font-smoothing: antialiased;\n\n      font-size: 14px;\n      font-weight: 700;\n      line-height: 20px;\n    };\n\n    --paper-font-code1: {\n      /* @apply(--paper-font-common-code); */\n      font-family: 'Roboto Mono', 'Consolas', 'Menlo', monospace;\n      -webkit-font-smoothing: antialiased;\n\n      font-size: 14px;\n      font-weight: 500;\n      line-height: 20px;\n    };\n\n  }\n\n</style>\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/polymer/.bower.json",
    "content": "{\n  \"name\": \"polymer\",\n  \"version\": \"1.1.0\",\n  \"main\": [\n    \"polymer.html\"\n  ],\n  \"license\": \"http://polymer.github.io/LICENSE.txt\",\n  \"ignore\": [\n    \"/.*\",\n    \"/test/\"\n  ],\n  \"authors\": [\n    \"The Polymer Authors (http://polymer.github.io/AUTHORS.txt)\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/Polymer/polymer.git\"\n  },\n  \"dependencies\": {\n    \"webcomponentsjs\": \"^0.7.2\"\n  },\n  \"devDependencies\": {\n    \"web-component-tester\": \"*\"\n  },\n  \"private\": true,\n  \"homepage\": \"https://github.com/Polymer/polymer\",\n  \"_release\": \"1.1.0\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"v1.1.0\",\n    \"commit\": \"67fb2f85fd66d8556fc07cf1dec41ff5273fa68a\"\n  },\n  \"_source\": \"git://github.com/Polymer/polymer.git\",\n  \"_target\": \"^1.0.0\",\n  \"_originalSource\": \"Polymer/polymer\",\n  \"_direct\": true\n}"
  },
  {
    "path": "cmd/memlat/static/bower_components/polymer/LICENSE.txt",
    "content": "// Copyright (c) 2014 The Polymer Authors. All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//    * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//    * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//    * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/polymer/bower.json",
    "content": "{\n  \"name\": \"polymer\",\n  \"version\": \"1.1.0\",\n  \"main\": [\n    \"polymer.html\"\n  ],\n  \"license\": \"http://polymer.github.io/LICENSE.txt\",\n  \"ignore\": [\n    \"/.*\",\n    \"/test/\"\n  ],\n  \"authors\": [\n    \"The Polymer Authors (http://polymer.github.io/AUTHORS.txt)\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/Polymer/polymer.git\"\n  },\n  \"dependencies\": {\n    \"webcomponentsjs\": \"^0.7.2\"\n  },\n  \"devDependencies\": {\n    \"web-component-tester\": \"*\"\n  },\n  \"private\": true\n}\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/polymer/build.log",
    "content": "BUILD LOG\n---------\nBuild Time: 2015-08-13T16:56:33-0700\n\nNODEJS INFORMATION\n==================\nnodejs: v0.12.7\ndel: 1.2.0\ngulp: 3.9.0\ngulp-audit: 1.0.0\ngulp-rename: 1.2.2\ngulp-replace: 0.5.3\ngulp-vulcanize: 6.0.1\nlazypipe: 0.2.4\npolyclean: 1.2.0\nrun-sequence: 1.1.1\n\nREPO REVISIONS\n==============\npolymer: a42ca09c3b99749b1407d5fa68cd957c2eaf5ca6\n\nBUILD HASHES\n============\npolymer-mini.html: b40016f458e85bb815c898378b7bcd5c8abe5661\npolymer-micro.html: ef8ebb2dc40697c845c2b8ec64ee69838d0d7bfc\npolymer.html: 2f874995a3a3ada9e87da48a01d10c6d3ee297bb"
  },
  {
    "path": "cmd/memlat/static/bower_components/polymer/polymer-micro.html",
    "content": "<!--\n@license\nCopyright (c) 2014 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n--><script>(function () {\nfunction resolve() {\ndocument.body.removeAttribute('unresolved');\n}\nif (window.WebComponents) {\naddEventListener('WebComponentsReady', resolve);\n} else {\nif (document.readyState === 'interactive' || document.readyState === 'complete') {\nresolve();\n} else {\naddEventListener('DOMContentLoaded', resolve);\n}\n}\n}());\nPolymer = {\nSettings: function () {\nvar user = window.Polymer || {};\nlocation.search.slice(1).split('&').forEach(function (o) {\no = o.split('=');\no[0] && (user[o[0]] = o[1] || true);\n});\nvar wantShadow = user.dom === 'shadow';\nvar hasShadow = Boolean(Element.prototype.createShadowRoot);\nvar nativeShadow = hasShadow && !window.ShadowDOMPolyfill;\nvar useShadow = wantShadow && hasShadow;\nvar hasNativeImports = Boolean('import' in document.createElement('link'));\nvar useNativeImports = hasNativeImports;\nvar useNativeCustomElements = !window.CustomElements || window.CustomElements.useNative;\nreturn {\nwantShadow: wantShadow,\nhasShadow: hasShadow,\nnativeShadow: nativeShadow,\nuseShadow: useShadow,\nuseNativeShadow: useShadow && nativeShadow,\nuseNativeImports: useNativeImports,\nuseNativeCustomElements: useNativeCustomElements\n};\n}()\n};\n(function () {\nvar userPolymer = window.Polymer;\nwindow.Polymer = function (prototype) {\nvar ctor = desugar(prototype);\nprototype = ctor.prototype;\nvar options = { prototype: prototype };\nif (prototype.extends) {\noptions.extends = prototype.extends;\n}\nPolymer.telemetry._registrate(prototype);\ndocument.registerElement(prototype.is, options);\nreturn ctor;\n};\nvar desugar = function (prototype) {\nvar base = Polymer.Base;\nif (prototype.extends) {\nbase = Polymer.Base._getExtendedPrototype(prototype.extends);\n}\nprototype = Polymer.Base.chainObject(prototype, base);\nprototype.registerCallback();\nreturn prototype.constructor;\n};\nwindow.Polymer = Polymer;\nif (userPolymer) {\nfor (var i in userPolymer) {\nPolymer[i] = userPolymer[i];\n}\n}\nPolymer.Class = desugar;\n}());\nPolymer.telemetry = {\nregistrations: [],\n_regLog: function (prototype) {\nconsole.log('[' + prototype.is + ']: registered');\n},\n_registrate: function (prototype) {\nthis.registrations.push(prototype);\nPolymer.log && this._regLog(prototype);\n},\ndumpRegistrations: function () {\nthis.registrations.forEach(this._regLog);\n}\n};\nObject.defineProperty(window, 'currentImport', {\nenumerable: true,\nconfigurable: true,\nget: function () {\nreturn (document._currentScript || document.currentScript).ownerDocument;\n}\n});\nPolymer.RenderStatus = {\n_ready: false,\n_callbacks: [],\nwhenReady: function (cb) {\nif (this._ready) {\ncb();\n} else {\nthis._callbacks.push(cb);\n}\n},\n_makeReady: function () {\nthis._ready = true;\nthis._callbacks.forEach(function (cb) {\ncb();\n});\nthis._callbacks = [];\n},\n_catchFirstRender: function () {\nrequestAnimationFrame(function () {\nPolymer.RenderStatus._makeReady();\n});\n}\n};\nif (window.HTMLImports) {\nHTMLImports.whenReady(function () {\nPolymer.RenderStatus._catchFirstRender();\n});\n} else {\nPolymer.RenderStatus._catchFirstRender();\n}\nPolymer.ImportStatus = Polymer.RenderStatus;\nPolymer.ImportStatus.whenLoaded = Polymer.ImportStatus.whenReady;\nPolymer.Base = {\n__isPolymerInstance__: true,\n_addFeature: function (feature) {\nthis.extend(this, feature);\n},\nregisterCallback: function () {\nthis._registerFeatures();\nthis._doBehavior('registered');\n},\ncreatedCallback: function () {\nPolymer.telemetry.instanceCount++;\nthis.root = this;\nthis._doBehavior('created');\nthis._initFeatures();\n},\nattachedCallback: function () {\nPolymer.RenderStatus.whenReady(function () {\nthis.isAttached = true;\nthis._doBehavior('attached');\n}.bind(this));\n},\ndetachedCallback: function () {\nthis.isAttached = false;\nthis._doBehavior('detached');\n},\nattributeChangedCallback: function (name) {\nthis._attributeChangedImpl(name);\nthis._doBehavior('attributeChanged', arguments);\n},\n_attributeChangedImpl: function (name) {\nthis._setAttributeToProperty(this, name);\n},\nextend: function (prototype, api) {\nif (prototype && api) {\nObject.getOwnPropertyNames(api).forEach(function (n) {\nthis.copyOwnProperty(n, api, prototype);\n}, this);\n}\nreturn prototype || api;\n},\nmixin: function (target, source) {\nfor (var i in source) {\ntarget[i] = source[i];\n}\nreturn target;\n},\ncopyOwnProperty: function (name, source, target) {\nvar pd = Object.getOwnPropertyDescriptor(source, name);\nif (pd) {\nObject.defineProperty(target, name, pd);\n}\n},\n_log: console.log.apply.bind(console.log, console),\n_warn: console.warn.apply.bind(console.warn, console),\n_error: console.error.apply.bind(console.error, console),\n_logf: function () {\nreturn this._logPrefix.concat([this.is]).concat(Array.prototype.slice.call(arguments, 0));\n}\n};\nPolymer.Base._logPrefix = function () {\nvar color = window.chrome || /firefox/i.test(navigator.userAgent);\nreturn color ? [\n'%c[%s::%s]:',\n'font-weight: bold; background-color:#EEEE00;'\n] : ['[%s::%s]:'];\n}();\nPolymer.Base.chainObject = function (object, inherited) {\nif (object && inherited && object !== inherited) {\nif (!Object.__proto__) {\nobject = Polymer.Base.extend(Object.create(inherited), object);\n}\nobject.__proto__ = inherited;\n}\nreturn object;\n};\nPolymer.Base = Polymer.Base.chainObject(Polymer.Base, HTMLElement.prototype);\nif (window.CustomElements) {\nPolymer.instanceof = CustomElements.instanceof;\n} else {\nPolymer.instanceof = function (obj, ctor) {\nreturn obj instanceof ctor;\n};\n}\nPolymer.isInstance = function (obj) {\nreturn Boolean(obj && obj.__isPolymerInstance__);\n};\nPolymer.telemetry.instanceCount = 0;\n(function () {\nvar modules = {};\nvar lcModules = {};\nvar DomModule = function () {\nreturn document.createElement('dom-module');\n};\nDomModule.prototype = Object.create(HTMLElement.prototype);\nPolymer.Base.extend(DomModule.prototype, {\nconstructor: DomModule,\ncreatedCallback: function () {\nthis.register();\n},\nregister: function (id) {\nvar id = id || this.id || this.getAttribute('name') || this.getAttribute('is');\nif (id) {\nthis.id = id;\nmodules[id] = this;\nlcModules[id.toLowerCase()] = this;\n}\n},\nimport: function (id, selector) {\nvar m = modules[id] || lcModules[id.toLowerCase()];\nif (!m) {\nforceDocumentUpgrade();\nm = modules[id];\n}\nif (m && selector) {\nm = m.querySelector(selector);\n}\nreturn m;\n}\n});\nvar cePolyfill = window.CustomElements && !CustomElements.useNative;\ndocument.registerElement('dom-module', DomModule);\nfunction forceDocumentUpgrade() {\nif (cePolyfill) {\nvar script = document._currentScript || document.currentScript;\nvar doc = script && script.ownerDocument;\nif (doc && !doc.__customElementsForceUpgraded) {\ndoc.__customElementsForceUpgraded = true;\nCustomElements.upgradeAll(doc);\n}\n}\n}\n}());\nPolymer.Base._addFeature({\n_prepIs: function () {\nif (!this.is) {\nvar module = (document._currentScript || document.currentScript).parentNode;\nif (module.localName === 'dom-module') {\nvar id = module.id || module.getAttribute('name') || module.getAttribute('is');\nthis.is = id;\n}\n}\nif (this.is) {\nthis.is = this.is.toLowerCase();\n}\n}\n});\nPolymer.Base._addFeature({\nbehaviors: [],\n_prepBehaviors: function () {\nif (this.behaviors.length) {\nthis.behaviors = this._flattenBehaviorsList(this.behaviors);\n}\nthis._prepAllBehaviors(this.behaviors);\n},\n_flattenBehaviorsList: function (behaviors) {\nvar flat = [];\nbehaviors.forEach(function (b) {\nif (b instanceof Array) {\nflat = flat.concat(this._flattenBehaviorsList(b));\n} else if (b) {\nflat.push(b);\n} else {\nthis._warn(this._logf('_flattenBehaviorsList', 'behavior is null, check for missing or 404 import'));\n}\n}, this);\nreturn flat;\n},\n_prepAllBehaviors: function (behaviors) {\nfor (var i = behaviors.length - 1; i >= 0; i--) {\nthis._mixinBehavior(behaviors[i]);\n}\nfor (var i = 0, l = behaviors.length; i < l; i++) {\nthis._prepBehavior(behaviors[i]);\n}\nthis._prepBehavior(this);\n},\n_mixinBehavior: function (b) {\nObject.getOwnPropertyNames(b).forEach(function (n) {\nswitch (n) {\ncase 'hostAttributes':\ncase 'registered':\ncase 'properties':\ncase 'observers':\ncase 'listeners':\ncase 'created':\ncase 'attached':\ncase 'detached':\ncase 'attributeChanged':\ncase 'configure':\ncase 'ready':\nbreak;\ndefault:\nif (!this.hasOwnProperty(n)) {\nthis.copyOwnProperty(n, b, this);\n}\nbreak;\n}\n}, this);\n},\n_doBehavior: function (name, args) {\nthis.behaviors.forEach(function (b) {\nthis._invokeBehavior(b, name, args);\n}, this);\nthis._invokeBehavior(this, name, args);\n},\n_invokeBehavior: function (b, name, args) {\nvar fn = b[name];\nif (fn) {\nfn.apply(this, args || Polymer.nar);\n}\n},\n_marshalBehaviors: function () {\nthis.behaviors.forEach(function (b) {\nthis._marshalBehavior(b);\n}, this);\nthis._marshalBehavior(this);\n}\n});\nPolymer.Base._addFeature({\n_getExtendedPrototype: function (tag) {\nreturn this._getExtendedNativePrototype(tag);\n},\n_nativePrototypes: {},\n_getExtendedNativePrototype: function (tag) {\nvar p = this._nativePrototypes[tag];\nif (!p) {\nvar np = this.getNativePrototype(tag);\np = this.extend(Object.create(np), Polymer.Base);\nthis._nativePrototypes[tag] = p;\n}\nreturn p;\n},\ngetNativePrototype: function (tag) {\nreturn Object.getPrototypeOf(document.createElement(tag));\n}\n});\nPolymer.Base._addFeature({\n_prepConstructor: function () {\nthis._factoryArgs = this.extends ? [\nthis.extends,\nthis.is\n] : [this.is];\nvar ctor = function () {\nreturn this._factory(arguments);\n};\nif (this.hasOwnProperty('extends')) {\nctor.extends = this.extends;\n}\nObject.defineProperty(this, 'constructor', {\nvalue: ctor,\nwritable: true,\nconfigurable: true\n});\nctor.prototype = this;\n},\n_factory: function (args) {\nvar elt = document.createElement.apply(document, this._factoryArgs);\nif (this.factoryImpl) {\nthis.factoryImpl.apply(elt, args);\n}\nreturn elt;\n}\n});\nPolymer.nob = Object.create(null);\nPolymer.Base._addFeature({\nproperties: {},\ngetPropertyInfo: function (property) {\nvar info = this._getPropertyInfo(property, this.properties);\nif (!info) {\nthis.behaviors.some(function (b) {\nreturn info = this._getPropertyInfo(property, b.properties);\n}, this);\n}\nreturn info || Polymer.nob;\n},\n_getPropertyInfo: function (property, properties) {\nvar p = properties && properties[property];\nif (typeof p === 'function') {\np = properties[property] = { type: p };\n}\nif (p) {\np.defined = true;\n}\nreturn p;\n}\n});\nPolymer.CaseMap = {\n_caseMap: {},\ndashToCamelCase: function (dash) {\nvar mapped = Polymer.CaseMap._caseMap[dash];\nif (mapped) {\nreturn mapped;\n}\nif (dash.indexOf('-') < 0) {\nreturn Polymer.CaseMap._caseMap[dash] = dash;\n}\nreturn Polymer.CaseMap._caseMap[dash] = dash.replace(/-([a-z])/g, function (m) {\nreturn m[1].toUpperCase();\n});\n},\ncamelToDashCase: function (camel) {\nvar mapped = Polymer.CaseMap._caseMap[camel];\nif (mapped) {\nreturn mapped;\n}\nreturn Polymer.CaseMap._caseMap[camel] = camel.replace(/([a-z][A-Z])/g, function (g) {\nreturn g[0] + '-' + g[1].toLowerCase();\n});\n}\n};\nPolymer.Base._addFeature({\n_prepAttributes: function () {\nthis._aggregatedAttributes = {};\n},\n_addHostAttributes: function (attributes) {\nif (attributes) {\nthis.mixin(this._aggregatedAttributes, attributes);\n}\n},\n_marshalHostAttributes: function () {\nthis._applyAttributes(this, this._aggregatedAttributes);\n},\n_applyAttributes: function (node, attr$) {\nfor (var n in attr$) {\nif (!this.hasAttribute(n) && n !== 'class') {\nthis.serializeValueToAttribute(attr$[n], n, this);\n}\n}\n},\n_marshalAttributes: function () {\nthis._takeAttributesToModel(this);\n},\n_takeAttributesToModel: function (model) {\nfor (var i = 0, l = this.attributes.length; i < l; i++) {\nthis._setAttributeToProperty(model, this.attributes[i].name);\n}\n},\n_setAttributeToProperty: function (model, attrName) {\nif (!this._serializing) {\nvar propName = Polymer.CaseMap.dashToCamelCase(attrName);\nvar info = this.getPropertyInfo(propName);\nif (info.defined || this._propertyEffects && this._propertyEffects[propName]) {\nvar val = this.getAttribute(attrName);\nmodel[propName] = this.deserialize(val, info.type);\n}\n}\n},\n_serializing: false,\nreflectPropertyToAttribute: function (name) {\nthis._serializing = true;\nthis.serializeValueToAttribute(this[name], Polymer.CaseMap.camelToDashCase(name));\nthis._serializing = false;\n},\nserializeValueToAttribute: function (value, attribute, node) {\nvar str = this.serialize(value);\n(node || this)[str === undefined ? 'removeAttribute' : 'setAttribute'](attribute, str);\n},\ndeserialize: function (value, type) {\nswitch (type) {\ncase Number:\nvalue = Number(value);\nbreak;\ncase Boolean:\nvalue = value !== null;\nbreak;\ncase Object:\ntry {\nvalue = JSON.parse(value);\n} catch (x) {\n}\nbreak;\ncase Array:\ntry {\nvalue = JSON.parse(value);\n} catch (x) {\nvalue = null;\nconsole.warn('Polymer::Attributes: couldn`t decode Array as JSON');\n}\nbreak;\ncase Date:\nvalue = new Date(value);\nbreak;\ncase String:\ndefault:\nbreak;\n}\nreturn value;\n},\nserialize: function (value) {\nswitch (typeof value) {\ncase 'boolean':\nreturn value ? '' : undefined;\ncase 'object':\nif (value instanceof Date) {\nreturn value;\n} else if (value) {\ntry {\nreturn JSON.stringify(value);\n} catch (x) {\nreturn '';\n}\n}\ndefault:\nreturn value != null ? value : undefined;\n}\n}\n});\nPolymer.Base._addFeature({\n_setupDebouncers: function () {\nthis._debouncers = {};\n},\ndebounce: function (jobName, callback, wait) {\nreturn this._debouncers[jobName] = Polymer.Debounce.call(this, this._debouncers[jobName], callback, wait);\n},\nisDebouncerActive: function (jobName) {\nvar debouncer = this._debouncers[jobName];\nreturn debouncer && debouncer.finish;\n},\nflushDebouncer: function (jobName) {\nvar debouncer = this._debouncers[jobName];\nif (debouncer) {\ndebouncer.complete();\n}\n},\ncancelDebouncer: function (jobName) {\nvar debouncer = this._debouncers[jobName];\nif (debouncer) {\ndebouncer.stop();\n}\n}\n});\nPolymer.version = '1.1.0';\nPolymer.Base._addFeature({\n_registerFeatures: function () {\nthis._prepIs();\nthis._prepAttributes();\nthis._prepBehaviors();\nthis._prepConstructor();\n},\n_prepBehavior: function (b) {\nthis._addHostAttributes(b.hostAttributes);\n},\n_marshalBehavior: function (b) {\n},\n_initFeatures: function () {\nthis._marshalHostAttributes();\nthis._setupDebouncers();\nthis._marshalBehaviors();\n}\n});</script>\n\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/polymer/polymer-mini.html",
    "content": "<!--\n@license\nCopyright (c) 2014 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n--><link rel=\"import\" href=\"polymer-micro.html\">\n\n<script>Polymer.Base._addFeature({\n_prepTemplate: function () {\nthis._template = this._template || Polymer.DomModule.import(this.is, 'template');\nif (this._template && this._template.hasAttribute('is')) {\nthis._warn(this._logf('_prepTemplate', 'top-level Polymer template ' + 'must not be a type-extension, found', this._template, 'Move inside simple <template>.'));\n}\nif (this._template && !this._template.content && HTMLTemplateElement.bootstrap) {\nHTMLTemplateElement.decorate(this._template);\nHTMLTemplateElement.bootstrap(this._template.content);\n}\n},\n_stampTemplate: function () {\nif (this._template) {\nthis.root = this.instanceTemplate(this._template);\n}\n},\ninstanceTemplate: function (template) {\nvar dom = document.importNode(template._content || template.content, true);\nreturn dom;\n}\n});\n(function () {\nvar baseAttachedCallback = Polymer.Base.attachedCallback;\nPolymer.Base._addFeature({\n_hostStack: [],\nready: function () {\n},\n_pushHost: function (host) {\nthis.dataHost = host = host || Polymer.Base._hostStack[Polymer.Base._hostStack.length - 1];\nif (host && host._clients) {\nhost._clients.push(this);\n}\nthis._beginHost();\n},\n_beginHost: function () {\nPolymer.Base._hostStack.push(this);\nif (!this._clients) {\nthis._clients = [];\n}\n},\n_popHost: function () {\nPolymer.Base._hostStack.pop();\n},\n_tryReady: function () {\nif (this._canReady()) {\nthis._ready();\n}\n},\n_canReady: function () {\nreturn !this.dataHost || this.dataHost._clientsReadied;\n},\n_ready: function () {\nthis._beforeClientsReady();\nthis._setupRoot();\nthis._readyClients();\nthis._afterClientsReady();\nthis._readySelf();\n},\n_readyClients: function () {\nthis._beginDistribute();\nvar c$ = this._clients;\nfor (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {\nc._ready();\n}\nthis._finishDistribute();\nthis._clientsReadied = true;\nthis._clients = null;\n},\n_readySelf: function () {\nthis._doBehavior('ready');\nthis._readied = true;\nif (this._attachedPending) {\nthis._attachedPending = false;\nthis.attachedCallback();\n}\n},\n_beforeClientsReady: function () {\n},\n_afterClientsReady: function () {\n},\n_beforeAttached: function () {\n},\nattachedCallback: function () {\nif (this._readied) {\nthis._beforeAttached();\nbaseAttachedCallback.call(this);\n} else {\nthis._attachedPending = true;\n}\n}\n});\n}());\nPolymer.ArraySplice = function () {\nfunction newSplice(index, removed, addedCount) {\nreturn {\nindex: index,\nremoved: removed,\naddedCount: addedCount\n};\n}\nvar EDIT_LEAVE = 0;\nvar EDIT_UPDATE = 1;\nvar EDIT_ADD = 2;\nvar EDIT_DELETE = 3;\nfunction ArraySplice() {\n}\nArraySplice.prototype = {\ncalcEditDistances: function (current, currentStart, currentEnd, old, oldStart, oldEnd) {\nvar rowCount = oldEnd - oldStart + 1;\nvar columnCount = currentEnd - currentStart + 1;\nvar distances = new Array(rowCount);\nfor (var i = 0; i < rowCount; i++) {\ndistances[i] = new Array(columnCount);\ndistances[i][0] = i;\n}\nfor (var j = 0; j < columnCount; j++)\ndistances[0][j] = j;\nfor (var i = 1; i < rowCount; i++) {\nfor (var j = 1; j < columnCount; j++) {\nif (this.equals(current[currentStart + j - 1], old[oldStart + i - 1]))\ndistances[i][j] = distances[i - 1][j - 1];\nelse {\nvar north = distances[i - 1][j] + 1;\nvar west = distances[i][j - 1] + 1;\ndistances[i][j] = north < west ? north : west;\n}\n}\n}\nreturn distances;\n},\nspliceOperationsFromEditDistances: function (distances) {\nvar i = distances.length - 1;\nvar j = distances[0].length - 1;\nvar current = distances[i][j];\nvar edits = [];\nwhile (i > 0 || j > 0) {\nif (i == 0) {\nedits.push(EDIT_ADD);\nj--;\ncontinue;\n}\nif (j == 0) {\nedits.push(EDIT_DELETE);\ni--;\ncontinue;\n}\nvar northWest = distances[i - 1][j - 1];\nvar west = distances[i - 1][j];\nvar north = distances[i][j - 1];\nvar min;\nif (west < north)\nmin = west < northWest ? west : northWest;\nelse\nmin = north < northWest ? north : northWest;\nif (min == northWest) {\nif (northWest == current) {\nedits.push(EDIT_LEAVE);\n} else {\nedits.push(EDIT_UPDATE);\ncurrent = northWest;\n}\ni--;\nj--;\n} else if (min == west) {\nedits.push(EDIT_DELETE);\ni--;\ncurrent = west;\n} else {\nedits.push(EDIT_ADD);\nj--;\ncurrent = north;\n}\n}\nedits.reverse();\nreturn edits;\n},\ncalcSplices: function (current, currentStart, currentEnd, old, oldStart, oldEnd) {\nvar prefixCount = 0;\nvar suffixCount = 0;\nvar minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart);\nif (currentStart == 0 && oldStart == 0)\nprefixCount = this.sharedPrefix(current, old, minLength);\nif (currentEnd == current.length && oldEnd == old.length)\nsuffixCount = this.sharedSuffix(current, old, minLength - prefixCount);\ncurrentStart += prefixCount;\noldStart += prefixCount;\ncurrentEnd -= suffixCount;\noldEnd -= suffixCount;\nif (currentEnd - currentStart == 0 && oldEnd - oldStart == 0)\nreturn [];\nif (currentStart == currentEnd) {\nvar splice = newSplice(currentStart, [], 0);\nwhile (oldStart < oldEnd)\nsplice.removed.push(old[oldStart++]);\nreturn [splice];\n} else if (oldStart == oldEnd)\nreturn [newSplice(currentStart, [], currentEnd - currentStart)];\nvar ops = this.spliceOperationsFromEditDistances(this.calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd));\nvar splice = undefined;\nvar splices = [];\nvar index = currentStart;\nvar oldIndex = oldStart;\nfor (var i = 0; i < ops.length; i++) {\nswitch (ops[i]) {\ncase EDIT_LEAVE:\nif (splice) {\nsplices.push(splice);\nsplice = undefined;\n}\nindex++;\noldIndex++;\nbreak;\ncase EDIT_UPDATE:\nif (!splice)\nsplice = newSplice(index, [], 0);\nsplice.addedCount++;\nindex++;\nsplice.removed.push(old[oldIndex]);\noldIndex++;\nbreak;\ncase EDIT_ADD:\nif (!splice)\nsplice = newSplice(index, [], 0);\nsplice.addedCount++;\nindex++;\nbreak;\ncase EDIT_DELETE:\nif (!splice)\nsplice = newSplice(index, [], 0);\nsplice.removed.push(old[oldIndex]);\noldIndex++;\nbreak;\n}\n}\nif (splice) {\nsplices.push(splice);\n}\nreturn splices;\n},\nsharedPrefix: function (current, old, searchLength) {\nfor (var i = 0; i < searchLength; i++)\nif (!this.equals(current[i], old[i]))\nreturn i;\nreturn searchLength;\n},\nsharedSuffix: function (current, old, searchLength) {\nvar index1 = current.length;\nvar index2 = old.length;\nvar count = 0;\nwhile (count < searchLength && this.equals(current[--index1], old[--index2]))\ncount++;\nreturn count;\n},\ncalculateSplices: function (current, previous) {\nreturn this.calcSplices(current, 0, current.length, previous, 0, previous.length);\n},\nequals: function (currentValue, previousValue) {\nreturn currentValue === previousValue;\n}\n};\nreturn new ArraySplice();\n}();\nPolymer.EventApi = function () {\nvar Settings = Polymer.Settings;\nvar EventApi = function (event) {\nthis.event = event;\n};\nif (Settings.useShadow) {\nEventApi.prototype = {\nget rootTarget() {\nreturn this.event.path[0];\n},\nget localTarget() {\nreturn this.event.target;\n},\nget path() {\nreturn this.event.path;\n}\n};\n} else {\nEventApi.prototype = {\nget rootTarget() {\nreturn this.event.target;\n},\nget localTarget() {\nvar current = this.event.currentTarget;\nvar currentRoot = current && Polymer.dom(current).getOwnerRoot();\nvar p$ = this.path;\nfor (var i = 0; i < p$.length; i++) {\nif (Polymer.dom(p$[i]).getOwnerRoot() === currentRoot) {\nreturn p$[i];\n}\n}\n},\nget path() {\nif (!this.event._path) {\nvar path = [];\nvar o = this.rootTarget;\nwhile (o) {\npath.push(o);\no = Polymer.dom(o).parentNode || o.host;\n}\npath.push(window);\nthis.event._path = path;\n}\nreturn this.event._path;\n}\n};\n}\nvar factory = function (event) {\nif (!event.__eventApi) {\nevent.__eventApi = new EventApi(event);\n}\nreturn event.__eventApi;\n};\nreturn { factory: factory };\n}();\nPolymer.domInnerHTML = function () {\nvar escapeAttrRegExp = /[&\\u00A0\"]/g;\nvar escapeDataRegExp = /[&\\u00A0<>]/g;\nfunction escapeReplace(c) {\nswitch (c) {\ncase '&':\nreturn '&amp;';\ncase '<':\nreturn '&lt;';\ncase '>':\nreturn '&gt;';\ncase '\"':\nreturn '&quot;';\ncase '\\xA0':\nreturn '&nbsp;';\n}\n}\nfunction escapeAttr(s) {\nreturn s.replace(escapeAttrRegExp, escapeReplace);\n}\nfunction escapeData(s) {\nreturn s.replace(escapeDataRegExp, escapeReplace);\n}\nfunction makeSet(arr) {\nvar set = {};\nfor (var i = 0; i < arr.length; i++) {\nset[arr[i]] = true;\n}\nreturn set;\n}\nvar voidElements = makeSet([\n'area',\n'base',\n'br',\n'col',\n'command',\n'embed',\n'hr',\n'img',\n'input',\n'keygen',\n'link',\n'meta',\n'param',\n'source',\n'track',\n'wbr'\n]);\nvar plaintextParents = makeSet([\n'style',\n'script',\n'xmp',\n'iframe',\n'noembed',\n'noframes',\n'plaintext',\n'noscript'\n]);\nfunction getOuterHTML(node, parentNode, composed) {\nswitch (node.nodeType) {\ncase Node.ELEMENT_NODE:\nvar tagName = node.localName;\nvar s = '<' + tagName;\nvar attrs = node.attributes;\nfor (var i = 0, attr; attr = attrs[i]; i++) {\ns += ' ' + attr.name + '=\"' + escapeAttr(attr.value) + '\"';\n}\ns += '>';\nif (voidElements[tagName]) {\nreturn s;\n}\nreturn s + getInnerHTML(node, composed) + '</' + tagName + '>';\ncase Node.TEXT_NODE:\nvar data = node.data;\nif (parentNode && plaintextParents[parentNode.localName]) {\nreturn data;\n}\nreturn escapeData(data);\ncase Node.COMMENT_NODE:\nreturn '<!--' + node.data + '-->';\ndefault:\nconsole.error(node);\nthrow new Error('not implemented');\n}\n}\nfunction getInnerHTML(node, composed) {\nif (node instanceof HTMLTemplateElement)\nnode = node.content;\nvar s = '';\nvar c$ = Polymer.dom(node).childNodes;\nc$ = composed ? node._composedChildren : c$;\nfor (var i = 0, l = c$.length, child; i < l && (child = c$[i]); i++) {\ns += getOuterHTML(child, node, composed);\n}\nreturn s;\n}\nreturn { getInnerHTML: getInnerHTML };\n}();\nPolymer.DomApi = function () {\n'use strict';\nvar Settings = Polymer.Settings;\nvar getInnerHTML = Polymer.domInnerHTML.getInnerHTML;\nvar nativeInsertBefore = Element.prototype.insertBefore;\nvar nativeRemoveChild = Element.prototype.removeChild;\nvar nativeAppendChild = Element.prototype.appendChild;\nvar nativeCloneNode = Element.prototype.cloneNode;\nvar nativeImportNode = Document.prototype.importNode;\nvar DomApi = function (node) {\nthis.node = node;\nif (this.patch) {\nthis.patch();\n}\n};\nif (window.wrap && Settings.useShadow && !Settings.useNativeShadow) {\nDomApi = function (node) {\nthis.node = wrap(node);\nif (this.patch) {\nthis.patch();\n}\n};\n}\nDomApi.prototype = {\nflush: function () {\nPolymer.dom.flush();\n},\n_lazyDistribute: function (host) {\nif (host.shadyRoot && host.shadyRoot._distributionClean) {\nhost.shadyRoot._distributionClean = false;\nPolymer.dom.addDebouncer(host.debounce('_distribute', host._distributeContent));\n}\n},\nappendChild: function (node) {\nvar handled;\nthis._ensureContentLogicalInfo(node);\nthis._removeNodeFromHost(node, true);\nif (this._nodeIsInLogicalTree(this.node)) {\nthis._addLogicalInfo(node, this.node);\nthis._addNodeToHost(node);\nhandled = this._maybeDistribute(node, this.node);\n} else {\nthis._addNodeToHost(node);\n}\nif (!handled && !this._tryRemoveUndistributedNode(node)) {\nvar container = this.node._isShadyRoot ? this.node.host : this.node;\naddToComposedParent(container, node);\nnativeAppendChild.call(container, node);\n}\nreturn node;\n},\ninsertBefore: function (node, ref_node) {\nif (!ref_node) {\nreturn this.appendChild(node);\n}\nvar handled;\nthis._ensureContentLogicalInfo(node);\nthis._removeNodeFromHost(node, true);\nif (this._nodeIsInLogicalTree(this.node)) {\nvar children = this.childNodes;\nvar index = children.indexOf(ref_node);\nif (index < 0) {\nthrow Error('The ref_node to be inserted before is not a child ' + 'of this node');\n}\nthis._addLogicalInfo(node, this.node, index);\nthis._addNodeToHost(node);\nhandled = this._maybeDistribute(node, this.node);\n} else {\nthis._addNodeToHost(node);\n}\nif (!handled && !this._tryRemoveUndistributedNode(node)) {\nref_node = ref_node.localName === CONTENT ? this._firstComposedNode(ref_node) : ref_node;\nvar container = this.node._isShadyRoot ? this.node.host : this.node;\naddToComposedParent(container, node, ref_node);\nnativeInsertBefore.call(container, node, ref_node);\n}\nreturn node;\n},\nremoveChild: function (node) {\nif (factory(node).parentNode !== this.node) {\nconsole.warn('The node to be removed is not a child of this node', node);\n}\nvar handled;\nif (this._nodeIsInLogicalTree(this.node)) {\nthis._removeNodeFromHost(node);\nhandled = this._maybeDistribute(node, this.node);\n} else {\nthis._removeNodeFromHost(node);\n}\nif (!handled) {\nvar container = this.node._isShadyRoot ? this.node.host : this.node;\nif (container === node.parentNode) {\nremoveFromComposedParent(container, node);\nnativeRemoveChild.call(container, node);\n}\n}\nreturn node;\n},\nreplaceChild: function (node, ref_node) {\nthis.insertBefore(node, ref_node);\nthis.removeChild(ref_node);\nreturn node;\n},\n_hasCachedOwnerRoot: function (node) {\nreturn Boolean(node._ownerShadyRoot !== undefined);\n},\ngetOwnerRoot: function () {\nreturn this._ownerShadyRootForNode(this.node);\n},\n_ownerShadyRootForNode: function (node) {\nif (!node) {\nreturn;\n}\nif (node._ownerShadyRoot === undefined) {\nvar root;\nif (node._isShadyRoot) {\nroot = node;\n} else {\nvar parent = Polymer.dom(node).parentNode;\nif (parent) {\nroot = parent._isShadyRoot ? parent : this._ownerShadyRootForNode(parent);\n} else {\nroot = null;\n}\n}\nnode._ownerShadyRoot = root;\n}\nreturn node._ownerShadyRoot;\n},\n_maybeDistribute: function (node, parent) {\nvar fragContent = node.nodeType === Node.DOCUMENT_FRAGMENT_NODE && !node.__noContent && Polymer.dom(node).querySelector(CONTENT);\nvar wrappedContent = fragContent && Polymer.dom(fragContent).parentNode.nodeType !== Node.DOCUMENT_FRAGMENT_NODE;\nvar hasContent = fragContent || node.localName === CONTENT;\nif (hasContent) {\nvar root = this._ownerShadyRootForNode(parent);\nif (root) {\nvar host = root.host;\nthis._updateInsertionPoints(host);\nthis._lazyDistribute(host);\n}\n}\nvar parentNeedsDist = this._parentNeedsDistribution(parent);\nif (parentNeedsDist) {\nthis._lazyDistribute(parent);\n}\nreturn parentNeedsDist || hasContent && !wrappedContent;\n},\n_tryRemoveUndistributedNode: function (node) {\nif (this.node.shadyRoot) {\nif (node._composedParent) {\nnativeRemoveChild.call(node._composedParent, node);\n}\nreturn true;\n}\n},\n_updateInsertionPoints: function (host) {\nvar i$ = host.shadyRoot._insertionPoints = factory(host.shadyRoot).querySelectorAll(CONTENT);\nfor (var i = 0, c; i < i$.length; i++) {\nc = i$[i];\nsaveLightChildrenIfNeeded(c);\nsaveLightChildrenIfNeeded(factory(c).parentNode);\n}\n},\n_nodeIsInLogicalTree: function (node) {\nreturn Boolean(node._lightParent !== undefined || node._isShadyRoot || node.shadyRoot);\n},\n_ensureContentLogicalInfo: function (node) {\nif (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\nsaveLightChildrenIfNeeded(this.node);\nvar c$ = Array.prototype.slice.call(node.childNodes);\nfor (var i = 0, n; i < c$.length && (n = c$[i]); i++) {\nthis._ensureContentLogicalInfo(n);\n}\n} else if (node.localName === CONTENT) {\nsaveLightChildrenIfNeeded(this.node);\nsaveLightChildrenIfNeeded(node);\n}\n},\n_parentNeedsDistribution: function (parent) {\nreturn parent && parent.shadyRoot && hasInsertionPoint(parent.shadyRoot);\n},\n_removeNodeFromHost: function (node, ensureComposedRemoval) {\nvar hostNeedsDist;\nvar root;\nvar parent = node._lightParent;\nif (parent) {\nroot = this._ownerShadyRootForNode(node);\nif (root) {\nroot.host._elementRemove(node);\nhostNeedsDist = this._removeDistributedChildren(root, node);\n}\nthis._removeLogicalInfo(node, node._lightParent);\n}\nthis._removeOwnerShadyRoot(node);\nif (root && hostNeedsDist) {\nthis._updateInsertionPoints(root.host);\nthis._lazyDistribute(root.host);\n} else if (ensureComposedRemoval) {\nremoveFromComposedParent(parent || node.parentNode, node);\n}\n},\n_removeDistributedChildren: function (root, container) {\nvar hostNeedsDist;\nvar ip$ = root._insertionPoints;\nfor (var i = 0; i < ip$.length; i++) {\nvar content = ip$[i];\nif (this._contains(container, content)) {\nvar dc$ = factory(content).getDistributedNodes();\nfor (var j = 0; j < dc$.length; j++) {\nhostNeedsDist = true;\nvar node = dc$[j];\nvar parent = node.parentNode;\nif (parent) {\nremoveFromComposedParent(parent, node);\nnativeRemoveChild.call(parent, node);\n}\n}\n}\n}\nreturn hostNeedsDist;\n},\n_contains: function (container, node) {\nwhile (node) {\nif (node == container) {\nreturn true;\n}\nnode = factory(node).parentNode;\n}\n},\n_addNodeToHost: function (node) {\nvar root = this.getOwnerRoot();\nif (root) {\nroot.host._elementAdd(node);\n}\n},\n_addLogicalInfo: function (node, container, index) {\nvar children = factory(container).childNodes;\nindex = index === undefined ? children.length : index;\nif (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\nvar c$ = Array.prototype.slice.call(node.childNodes);\nfor (var i = 0, n; i < c$.length && (n = c$[i]); i++) {\nchildren.splice(index++, 0, n);\nn._lightParent = container;\n}\n} else {\nchildren.splice(index, 0, node);\nnode._lightParent = container;\n}\n},\n_removeLogicalInfo: function (node, container) {\nvar children = factory(container).childNodes;\nvar index = children.indexOf(node);\nif (index < 0 || container !== node._lightParent) {\nthrow Error('The node to be removed is not a child of this node');\n}\nchildren.splice(index, 1);\nnode._lightParent = null;\n},\n_removeOwnerShadyRoot: function (node) {\nif (this._hasCachedOwnerRoot(node)) {\nvar c$ = factory(node).childNodes;\nfor (var i = 0, l = c$.length, n; i < l && (n = c$[i]); i++) {\nthis._removeOwnerShadyRoot(n);\n}\n}\nnode._ownerShadyRoot = undefined;\n},\n_firstComposedNode: function (content) {\nvar n$ = factory(content).getDistributedNodes();\nfor (var i = 0, l = n$.length, n, p$; i < l && (n = n$[i]); i++) {\np$ = factory(n).getDestinationInsertionPoints();\nif (p$[p$.length - 1] === content) {\nreturn n;\n}\n}\n},\nquerySelector: function (selector) {\nreturn this.querySelectorAll(selector)[0];\n},\nquerySelectorAll: function (selector) {\nreturn this._query(function (n) {\nreturn matchesSelector.call(n, selector);\n}, this.node);\n},\n_query: function (matcher, node) {\nnode = node || this.node;\nvar list = [];\nthis._queryElements(factory(node).childNodes, matcher, list);\nreturn list;\n},\n_queryElements: function (elements, matcher, list) {\nfor (var i = 0, l = elements.length, c; i < l && (c = elements[i]); i++) {\nif (c.nodeType === Node.ELEMENT_NODE) {\nthis._queryElement(c, matcher, list);\n}\n}\n},\n_queryElement: function (node, matcher, list) {\nif (matcher(node)) {\nlist.push(node);\n}\nthis._queryElements(factory(node).childNodes, matcher, list);\n},\ngetDestinationInsertionPoints: function () {\nreturn this.node._destinationInsertionPoints || [];\n},\ngetDistributedNodes: function () {\nreturn this.node._distributedNodes || [];\n},\nqueryDistributedElements: function (selector) {\nvar c$ = this.childNodes;\nvar list = [];\nthis._distributedFilter(selector, c$, list);\nfor (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {\nif (c.localName === CONTENT) {\nthis._distributedFilter(selector, factory(c).getDistributedNodes(), list);\n}\n}\nreturn list;\n},\n_distributedFilter: function (selector, list, results) {\nresults = results || [];\nfor (var i = 0, l = list.length, d; i < l && (d = list[i]); i++) {\nif (d.nodeType === Node.ELEMENT_NODE && d.localName !== CONTENT && matchesSelector.call(d, selector)) {\nresults.push(d);\n}\n}\nreturn results;\n},\n_clear: function () {\nwhile (this.childNodes.length) {\nthis.removeChild(this.childNodes[0]);\n}\n},\nsetAttribute: function (name, value) {\nthis.node.setAttribute(name, value);\nthis._distributeParent();\n},\nremoveAttribute: function (name) {\nthis.node.removeAttribute(name);\nthis._distributeParent();\n},\n_distributeParent: function () {\nif (this._parentNeedsDistribution(this.parentNode)) {\nthis._lazyDistribute(this.parentNode);\n}\n},\ncloneNode: function (deep) {\nvar n = nativeCloneNode.call(this.node, false);\nif (deep) {\nvar c$ = this.childNodes;\nvar d = factory(n);\nfor (var i = 0, nc; i < c$.length; i++) {\nnc = factory(c$[i]).cloneNode(true);\nd.appendChild(nc);\n}\n}\nreturn n;\n},\nimportNode: function (externalNode, deep) {\nvar doc = this.node instanceof Document ? this.node : this.node.ownerDocument;\nvar n = nativeImportNode.call(doc, externalNode, false);\nif (deep) {\nvar c$ = factory(externalNode).childNodes;\nvar d = factory(n);\nfor (var i = 0, nc; i < c$.length; i++) {\nnc = factory(doc).importNode(c$[i], true);\nd.appendChild(nc);\n}\n}\nreturn n;\n}\n};\nObject.defineProperty(DomApi.prototype, 'classList', {\nget: function () {\nif (!this._classList) {\nthis._classList = new DomApi.ClassList(this);\n}\nreturn this._classList;\n},\nconfigurable: true\n});\nDomApi.ClassList = function (host) {\nthis.domApi = host;\nthis.node = host.node;\n};\nDomApi.ClassList.prototype = {\nadd: function () {\nthis.node.classList.add.apply(this.node.classList, arguments);\nthis.domApi._distributeParent();\n},\nremove: function () {\nthis.node.classList.remove.apply(this.node.classList, arguments);\nthis.domApi._distributeParent();\n},\ntoggle: function () {\nthis.node.classList.toggle.apply(this.node.classList, arguments);\nthis.domApi._distributeParent();\n},\ncontains: function () {\nreturn this.node.classList.contains.apply(this.node.classList, arguments);\n}\n};\nif (!Settings.useShadow) {\nObject.defineProperties(DomApi.prototype, {\nchildNodes: {\nget: function () {\nvar c$ = getLightChildren(this.node);\nreturn Array.isArray(c$) ? c$ : Array.prototype.slice.call(c$);\n},\nconfigurable: true\n},\nchildren: {\nget: function () {\nreturn Array.prototype.filter.call(this.childNodes, function (n) {\nreturn n.nodeType === Node.ELEMENT_NODE;\n});\n},\nconfigurable: true\n},\nparentNode: {\nget: function () {\nreturn this.node._lightParent || (this.node.__patched ? this.node._composedParent : this.node.parentNode);\n},\nconfigurable: true\n},\nfirstChild: {\nget: function () {\nreturn this.childNodes[0];\n},\nconfigurable: true\n},\nlastChild: {\nget: function () {\nvar c$ = this.childNodes;\nreturn c$[c$.length - 1];\n},\nconfigurable: true\n},\nnextSibling: {\nget: function () {\nvar c$ = this.parentNode && factory(this.parentNode).childNodes;\nif (c$) {\nreturn c$[Array.prototype.indexOf.call(c$, this.node) + 1];\n}\n},\nconfigurable: true\n},\npreviousSibling: {\nget: function () {\nvar c$ = this.parentNode && factory(this.parentNode).childNodes;\nif (c$) {\nreturn c$[Array.prototype.indexOf.call(c$, this.node) - 1];\n}\n},\nconfigurable: true\n},\nfirstElementChild: {\nget: function () {\nreturn this.children[0];\n},\nconfigurable: true\n},\nlastElementChild: {\nget: function () {\nvar c$ = this.children;\nreturn c$[c$.length - 1];\n},\nconfigurable: true\n},\nnextElementSibling: {\nget: function () {\nvar c$ = this.parentNode && factory(this.parentNode).children;\nif (c$) {\nreturn c$[Array.prototype.indexOf.call(c$, this.node) + 1];\n}\n},\nconfigurable: true\n},\npreviousElementSibling: {\nget: function () {\nvar c$ = this.parentNode && factory(this.parentNode).children;\nif (c$) {\nreturn c$[Array.prototype.indexOf.call(c$, this.node) - 1];\n}\n},\nconfigurable: true\n},\ntextContent: {\nget: function () {\nvar nt = this.node.nodeType;\nif (nt === Node.TEXT_NODE || nt === Node.COMMENT_NODE) {\nreturn this.node.textContent;\n} else {\nvar tc = [];\nfor (var i = 0, cn = this.childNodes, c; c = cn[i]; i++) {\nif (c.nodeType !== Node.COMMENT_NODE) {\ntc.push(c.textContent);\n}\n}\nreturn tc.join('');\n}\n},\nset: function (text) {\nvar nt = this.node.nodeType;\nif (nt === Node.TEXT_NODE || nt === Node.COMMENT_NODE) {\nthis.node.textContent = text;\n} else {\nthis._clear();\nif (text) {\nthis.appendChild(document.createTextNode(text));\n}\n}\n},\nconfigurable: true\n},\ninnerHTML: {\nget: function () {\nvar nt = this.node.nodeType;\nif (nt === Node.TEXT_NODE || nt === Node.COMMENT_NODE) {\nreturn null;\n} else {\nreturn getInnerHTML(this.node);\n}\n},\nset: function (text) {\nvar nt = this.node.nodeType;\nif (nt !== Node.TEXT_NODE || nt !== Node.COMMENT_NODE) {\nthis._clear();\nvar d = document.createElement('div');\nd.innerHTML = text;\nvar c$ = Array.prototype.slice.call(d.childNodes);\nfor (var i = 0; i < c$.length; i++) {\nthis.appendChild(c$[i]);\n}\n}\n},\nconfigurable: true\n}\n});\nDomApi.prototype._getComposedInnerHTML = function () {\nreturn getInnerHTML(this.node, true);\n};\n} else {\nDomApi.prototype.querySelectorAll = function (selector) {\nreturn Array.prototype.slice.call(this.node.querySelectorAll(selector));\n};\nDomApi.prototype.getOwnerRoot = function () {\nvar n = this.node;\nwhile (n) {\nif (n.nodeType === Node.DOCUMENT_FRAGMENT_NODE && n.host) {\nreturn n;\n}\nn = n.parentNode;\n}\n};\nDomApi.prototype.cloneNode = function (deep) {\nreturn this.node.cloneNode(deep);\n};\nDomApi.prototype.importNode = function (externalNode, deep) {\nvar doc = this.node instanceof Document ? this.node : this.node.ownerDocument;\nreturn doc.importNode(externalNode, deep);\n};\nDomApi.prototype.getDestinationInsertionPoints = function () {\nvar n$ = this.node.getDestinationInsertionPoints && this.node.getDestinationInsertionPoints();\nreturn n$ ? Array.prototype.slice.call(n$) : [];\n};\nDomApi.prototype.getDistributedNodes = function () {\nvar n$ = this.node.getDistributedNodes && this.node.getDistributedNodes();\nreturn n$ ? Array.prototype.slice.call(n$) : [];\n};\nDomApi.prototype._distributeParent = function () {\n};\nObject.defineProperties(DomApi.prototype, {\nchildNodes: {\nget: function () {\nreturn Array.prototype.slice.call(this.node.childNodes);\n},\nconfigurable: true\n},\nchildren: {\nget: function () {\nreturn Array.prototype.slice.call(this.node.children);\n},\nconfigurable: true\n},\ntextContent: {\nget: function () {\nreturn this.node.textContent;\n},\nset: function (value) {\nreturn this.node.textContent = value;\n},\nconfigurable: true\n},\ninnerHTML: {\nget: function () {\nreturn this.node.innerHTML;\n},\nset: function (value) {\nreturn this.node.innerHTML = value;\n},\nconfigurable: true\n}\n});\nvar forwards = [\n'parentNode',\n'firstChild',\n'lastChild',\n'nextSibling',\n'previousSibling',\n'firstElementChild',\n'lastElementChild',\n'nextElementSibling',\n'previousElementSibling'\n];\nforwards.forEach(function (name) {\nObject.defineProperty(DomApi.prototype, name, {\nget: function () {\nreturn this.node[name];\n},\nconfigurable: true\n});\n});\n}\nvar CONTENT = 'content';\nvar factory = function (node, patch) {\nnode = node || document;\nif (!node.__domApi) {\nnode.__domApi = new DomApi(node, patch);\n}\nreturn node.__domApi;\n};\nPolymer.dom = function (obj, patch) {\nif (obj instanceof Event) {\nreturn Polymer.EventApi.factory(obj);\n} else {\nreturn factory(obj, patch);\n}\n};\nPolymer.Base.extend(Polymer.dom, {\n_flushGuard: 0,\n_FLUSH_MAX: 100,\n_needsTakeRecords: !Polymer.Settings.useNativeCustomElements,\n_debouncers: [],\n_finishDebouncer: null,\nflush: function () {\nfor (var i = 0; i < this._debouncers.length; i++) {\nthis._debouncers[i].complete();\n}\nif (this._finishDebouncer) {\nthis._finishDebouncer.complete();\n}\nthis._flushPolyfills();\nif (this._debouncers.length && this._flushGuard < this._FLUSH_MAX) {\nthis._flushGuard++;\nthis.flush();\n} else {\nif (this._flushGuard >= this._FLUSH_MAX) {\nconsole.warn('Polymer.dom.flush aborted. Flush may not be complete.');\n}\nthis._flushGuard = 0;\n}\n},\n_flushPolyfills: function () {\nif (this._needsTakeRecords) {\nCustomElements.takeRecords();\n}\n},\naddDebouncer: function (debouncer) {\nthis._debouncers.push(debouncer);\nthis._finishDebouncer = Polymer.Debounce(this._finishDebouncer, this._finishFlush);\n},\n_finishFlush: function () {\nPolymer.dom._debouncers = [];\n}\n});\nfunction getLightChildren(node) {\nvar children = node._lightChildren;\nreturn children ? children : node.childNodes;\n}\nfunction getComposedChildren(node) {\nif (!node._composedChildren) {\nnode._composedChildren = Array.prototype.slice.call(node.childNodes);\n}\nreturn node._composedChildren;\n}\nfunction addToComposedParent(parent, node, ref_node) {\nvar children = getComposedChildren(parent);\nvar i = ref_node ? children.indexOf(ref_node) : -1;\nif (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\nvar fragChildren = getComposedChildren(node);\nfor (var j = 0; j < fragChildren.length; j++) {\naddNodeToComposedChildren(fragChildren[j], parent, children, i + j);\n}\nnode._composedChildren = null;\n} else {\naddNodeToComposedChildren(node, parent, children, i);\n}\n}\nfunction addNodeToComposedChildren(node, parent, children, i) {\nnode._composedParent = parent;\nchildren.splice(i >= 0 ? i : children.length, 0, node);\n}\nfunction removeFromComposedParent(parent, node) {\nnode._composedParent = null;\nif (parent) {\nvar children = getComposedChildren(parent);\nvar i = children.indexOf(node);\nif (i >= 0) {\nchildren.splice(i, 1);\n}\n}\n}\nfunction saveLightChildrenIfNeeded(node) {\nif (!node._lightChildren) {\nvar c$ = Array.prototype.slice.call(node.childNodes);\nfor (var i = 0, l = c$.length, child; i < l && (child = c$[i]); i++) {\nchild._lightParent = child._lightParent || node;\n}\nnode._lightChildren = c$;\n}\n}\nfunction hasInsertionPoint(root) {\nreturn Boolean(root._insertionPoints.length);\n}\nvar p = Element.prototype;\nvar matchesSelector = p.matches || p.matchesSelector || p.mozMatchesSelector || p.msMatchesSelector || p.oMatchesSelector || p.webkitMatchesSelector;\nreturn {\ngetLightChildren: getLightChildren,\ngetComposedChildren: getComposedChildren,\nremoveFromComposedParent: removeFromComposedParent,\nsaveLightChildrenIfNeeded: saveLightChildrenIfNeeded,\nmatchesSelector: matchesSelector,\nhasInsertionPoint: hasInsertionPoint,\nctor: DomApi,\nfactory: factory\n};\n}();\n(function () {\nPolymer.Base._addFeature({\n_prepShady: function () {\nthis._useContent = this._useContent || Boolean(this._template);\n},\n_poolContent: function () {\nif (this._useContent) {\nsaveLightChildrenIfNeeded(this);\n}\n},\n_setupRoot: function () {\nif (this._useContent) {\nthis._createLocalRoot();\nif (!this.dataHost) {\nupgradeLightChildren(this._lightChildren);\n}\n}\n},\n_createLocalRoot: function () {\nthis.shadyRoot = this.root;\nthis.shadyRoot._distributionClean = false;\nthis.shadyRoot._isShadyRoot = true;\nthis.shadyRoot._dirtyRoots = [];\nvar i$ = this.shadyRoot._insertionPoints = !this._notes || this._notes._hasContent ? this.shadyRoot.querySelectorAll('content') : [];\nsaveLightChildrenIfNeeded(this.shadyRoot);\nfor (var i = 0, c; i < i$.length; i++) {\nc = i$[i];\nsaveLightChildrenIfNeeded(c);\nsaveLightChildrenIfNeeded(c.parentNode);\n}\nthis.shadyRoot.host = this;\n},\nget domHost() {\nvar root = Polymer.dom(this).getOwnerRoot();\nreturn root && root.host;\n},\ndistributeContent: function (updateInsertionPoints) {\nif (this.shadyRoot) {\nvar dom = Polymer.dom(this);\nif (updateInsertionPoints) {\ndom._updateInsertionPoints(this);\n}\nvar host = getTopDistributingHost(this);\ndom._lazyDistribute(host);\n}\n},\n_distributeContent: function () {\nif (this._useContent && !this.shadyRoot._distributionClean) {\nthis._beginDistribute();\nthis._distributeDirtyRoots();\nthis._finishDistribute();\n}\n},\n_beginDistribute: function () {\nif (this._useContent && hasInsertionPoint(this.shadyRoot)) {\nthis._resetDistribution();\nthis._distributePool(this.shadyRoot, this._collectPool());\n}\n},\n_distributeDirtyRoots: function () {\nvar c$ = this.shadyRoot._dirtyRoots;\nfor (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {\nc._distributeContent();\n}\nthis.shadyRoot._dirtyRoots = [];\n},\n_finishDistribute: function () {\nif (this._useContent) {\nthis.shadyRoot._distributionClean = true;\nif (hasInsertionPoint(this.shadyRoot)) {\nthis._composeTree();\n} else {\nif (!this.shadyRoot._hasDistributed) {\nthis.textContent = '';\nthis._composedChildren = null;\nthis.appendChild(this.shadyRoot);\n} else {\nvar children = this._composeNode(this);\nthis._updateChildNodes(this, children);\n}\n}\nthis.shadyRoot._hasDistributed = true;\n}\n},\nelementMatches: function (selector, node) {\nnode = node || this;\nreturn matchesSelector.call(node, selector);\n},\n_resetDistribution: function () {\nvar children = getLightChildren(this);\nfor (var i = 0; i < children.length; i++) {\nvar child = children[i];\nif (child._destinationInsertionPoints) {\nchild._destinationInsertionPoints = undefined;\n}\nif (isInsertionPoint(child)) {\nclearDistributedDestinationInsertionPoints(child);\n}\n}\nvar root = this.shadyRoot;\nvar p$ = root._insertionPoints;\nfor (var j = 0; j < p$.length; j++) {\np$[j]._distributedNodes = [];\n}\n},\n_collectPool: function () {\nvar pool = [];\nvar children = getLightChildren(this);\nfor (var i = 0; i < children.length; i++) {\nvar child = children[i];\nif (isInsertionPoint(child)) {\npool.push.apply(pool, child._distributedNodes);\n} else {\npool.push(child);\n}\n}\nreturn pool;\n},\n_distributePool: function (node, pool) {\nvar p$ = node._insertionPoints;\nfor (var i = 0, l = p$.length, p; i < l && (p = p$[i]); i++) {\nthis._distributeInsertionPoint(p, pool);\nmaybeRedistributeParent(p, this);\n}\n},\n_distributeInsertionPoint: function (content, pool) {\nvar anyDistributed = false;\nfor (var i = 0, l = pool.length, node; i < l; i++) {\nnode = pool[i];\nif (!node) {\ncontinue;\n}\nif (this._matchesContentSelect(node, content)) {\ndistributeNodeInto(node, content);\npool[i] = undefined;\nanyDistributed = true;\n}\n}\nif (!anyDistributed) {\nvar children = getLightChildren(content);\nfor (var j = 0; j < children.length; j++) {\ndistributeNodeInto(children[j], content);\n}\n}\n},\n_composeTree: function () {\nthis._updateChildNodes(this, this._composeNode(this));\nvar p$ = this.shadyRoot._insertionPoints;\nfor (var i = 0, l = p$.length, p, parent; i < l && (p = p$[i]); i++) {\nparent = p._lightParent || p.parentNode;\nif (!parent._useContent && parent !== this && parent !== this.shadyRoot) {\nthis._updateChildNodes(parent, this._composeNode(parent));\n}\n}\n},\n_composeNode: function (node) {\nvar children = [];\nvar c$ = getLightChildren(node.shadyRoot || node);\nfor (var i = 0; i < c$.length; i++) {\nvar child = c$[i];\nif (isInsertionPoint(child)) {\nvar distributedNodes = child._distributedNodes;\nfor (var j = 0; j < distributedNodes.length; j++) {\nvar distributedNode = distributedNodes[j];\nif (isFinalDestination(child, distributedNode)) {\nchildren.push(distributedNode);\n}\n}\n} else {\nchildren.push(child);\n}\n}\nreturn children;\n},\n_updateChildNodes: function (container, children) {\nvar composed = getComposedChildren(container);\nvar splices = Polymer.ArraySplice.calculateSplices(children, composed);\nfor (var i = 0, d = 0, s; i < splices.length && (s = splices[i]); i++) {\nfor (var j = 0, n; j < s.removed.length && (n = s.removed[j]); j++) {\nremove(n);\ncomposed.splice(s.index + d, 1);\n}\nd -= s.addedCount;\n}\nfor (var i = 0, s, next; i < splices.length && (s = splices[i]); i++) {\nnext = composed[s.index];\nfor (var j = s.index, n; j < s.index + s.addedCount; j++) {\nn = children[j];\ninsertBefore(container, n, next);\ncomposed.splice(j, 0, n);\n}\n}\n},\n_matchesContentSelect: function (node, contentElement) {\nvar select = contentElement.getAttribute('select');\nif (!select) {\nreturn true;\n}\nselect = select.trim();\nif (!select) {\nreturn true;\n}\nif (!(node instanceof Element)) {\nreturn false;\n}\nvar validSelectors = /^(:not\\()?[*.#[a-zA-Z_|]/;\nif (!validSelectors.test(select)) {\nreturn false;\n}\nreturn this.elementMatches(select, node);\n},\n_elementAdd: function () {\n},\n_elementRemove: function () {\n}\n});\nvar saveLightChildrenIfNeeded = Polymer.DomApi.saveLightChildrenIfNeeded;\nvar getLightChildren = Polymer.DomApi.getLightChildren;\nvar matchesSelector = Polymer.DomApi.matchesSelector;\nvar hasInsertionPoint = Polymer.DomApi.hasInsertionPoint;\nvar getComposedChildren = Polymer.DomApi.getComposedChildren;\nvar removeFromComposedParent = Polymer.DomApi.removeFromComposedParent;\nfunction distributeNodeInto(child, insertionPoint) {\ninsertionPoint._distributedNodes.push(child);\nvar points = child._destinationInsertionPoints;\nif (!points) {\nchild._destinationInsertionPoints = [insertionPoint];\n} else {\npoints.push(insertionPoint);\n}\n}\nfunction clearDistributedDestinationInsertionPoints(content) {\nvar e$ = content._distributedNodes;\nif (e$) {\nfor (var i = 0; i < e$.length; i++) {\nvar d = e$[i]._destinationInsertionPoints;\nif (d) {\nd.splice(d.indexOf(content) + 1, d.length);\n}\n}\n}\n}\nfunction maybeRedistributeParent(content, host) {\nvar parent = content._lightParent;\nif (parent && parent.shadyRoot && hasInsertionPoint(parent.shadyRoot) && parent.shadyRoot._distributionClean) {\nparent.shadyRoot._distributionClean = false;\nhost.shadyRoot._dirtyRoots.push(parent);\n}\n}\nfunction isFinalDestination(insertionPoint, node) {\nvar points = node._destinationInsertionPoints;\nreturn points && points[points.length - 1] === insertionPoint;\n}\nfunction isInsertionPoint(node) {\nreturn node.localName == 'content';\n}\nvar nativeInsertBefore = Element.prototype.insertBefore;\nvar nativeRemoveChild = Element.prototype.removeChild;\nfunction insertBefore(parentNode, newChild, refChild) {\nvar newChildParent = getComposedParent(newChild);\nif (newChildParent !== parentNode) {\nremoveFromComposedParent(newChildParent, newChild);\n}\nremove(newChild);\nnativeInsertBefore.call(parentNode, newChild, refChild || null);\nnewChild._composedParent = parentNode;\n}\nfunction remove(node) {\nvar parentNode = getComposedParent(node);\nif (parentNode) {\nnode._composedParent = null;\nnativeRemoveChild.call(parentNode, node);\n}\n}\nfunction getComposedParent(node) {\nreturn node.__patched ? node._composedParent : node.parentNode;\n}\nfunction getTopDistributingHost(host) {\nwhile (host && hostNeedsRedistribution(host)) {\nhost = host.domHost;\n}\nreturn host;\n}\nfunction hostNeedsRedistribution(host) {\nvar c$ = Polymer.dom(host).children;\nfor (var i = 0, c; i < c$.length; i++) {\nc = c$[i];\nif (c.localName === 'content') {\nreturn host.domHost;\n}\n}\n}\nvar needsUpgrade = window.CustomElements && !CustomElements.useNative;\nfunction upgradeLightChildren(children) {\nif (needsUpgrade && children) {\nfor (var i = 0; i < children.length; i++) {\nCustomElements.upgrade(children[i]);\n}\n}\n}\n}());\nif (Polymer.Settings.useShadow) {\nPolymer.Base._addFeature({\n_poolContent: function () {\n},\n_beginDistribute: function () {\n},\ndistributeContent: function () {\n},\n_distributeContent: function () {\n},\n_finishDistribute: function () {\n},\n_createLocalRoot: function () {\nthis.createShadowRoot();\nthis.shadowRoot.appendChild(this.root);\nthis.root = this.shadowRoot;\n}\n});\n}\nPolymer.DomModule = document.createElement('dom-module');\nPolymer.Base._addFeature({\n_registerFeatures: function () {\nthis._prepIs();\nthis._prepAttributes();\nthis._prepBehaviors();\nthis._prepConstructor();\nthis._prepTemplate();\nthis._prepShady();\n},\n_prepBehavior: function (b) {\nthis._addHostAttributes(b.hostAttributes);\n},\n_initFeatures: function () {\nthis._poolContent();\nthis._pushHost();\nthis._stampTemplate();\nthis._popHost();\nthis._marshalHostAttributes();\nthis._setupDebouncers();\nthis._marshalBehaviors();\nthis._tryReady();\n},\n_marshalBehavior: function (b) {\n}\n});</script>\n\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/polymer/polymer.html",
    "content": "<!--\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n--><!--\n@license\nCopyright (c) 2014 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n--><link rel=\"import\" href=\"polymer-mini.html\">\n\n<script>Polymer.nar = [];\nPolymer.Annotations = {\nparseAnnotations: function (template) {\nvar list = [];\nvar content = template._content || template.content;\nthis._parseNodeAnnotations(content, list);\nreturn list;\n},\n_parseNodeAnnotations: function (node, list) {\nreturn node.nodeType === Node.TEXT_NODE ? this._parseTextNodeAnnotation(node, list) : this._parseElementAnnotations(node, list);\n},\n_testEscape: function (value) {\nvar escape = value.slice(0, 2);\nif (escape === '{{' || escape === '[[') {\nreturn escape;\n}\n},\n_parseTextNodeAnnotation: function (node, list) {\nvar v = node.textContent;\nvar escape = this._testEscape(v);\nif (escape) {\nnode.textContent = ' ';\nvar annote = {\nbindings: [{\nkind: 'text',\nmode: escape[0],\nvalue: v.slice(2, -2).trim()\n}]\n};\nlist.push(annote);\nreturn annote;\n}\n},\n_parseElementAnnotations: function (element, list) {\nvar annote = {\nbindings: [],\nevents: []\n};\nif (element.localName === 'content') {\nlist._hasContent = true;\n}\nthis._parseChildNodesAnnotations(element, annote, list);\nif (element.attributes) {\nthis._parseNodeAttributeAnnotations(element, annote, list);\nif (this.prepElement) {\nthis.prepElement(element);\n}\n}\nif (annote.bindings.length || annote.events.length || annote.id) {\nlist.push(annote);\n}\nreturn annote;\n},\n_parseChildNodesAnnotations: function (root, annote, list, callback) {\nif (root.firstChild) {\nfor (var i = 0, node = root.firstChild; node; node = node.nextSibling, i++) {\nif (node.localName === 'template' && !node.hasAttribute('preserve-content')) {\nthis._parseTemplate(node, i, list, annote);\n}\nif (node.nodeType === Node.TEXT_NODE) {\nvar n = node.nextSibling;\nwhile (n && n.nodeType === Node.TEXT_NODE) {\nnode.textContent += n.textContent;\nroot.removeChild(n);\nn = n.nextSibling;\n}\n}\nvar childAnnotation = this._parseNodeAnnotations(node, list, callback);\nif (childAnnotation) {\nchildAnnotation.parent = annote;\nchildAnnotation.index = i;\n}\n}\n}\n},\n_parseTemplate: function (node, index, list, parent) {\nvar content = document.createDocumentFragment();\ncontent._notes = this.parseAnnotations(node);\ncontent.appendChild(node.content);\nlist.push({\nbindings: Polymer.nar,\nevents: Polymer.nar,\ntemplateContent: content,\nparent: parent,\nindex: index\n});\n},\n_parseNodeAttributeAnnotations: function (node, annotation) {\nfor (var i = node.attributes.length - 1, a; a = node.attributes[i]; i--) {\nvar n = a.name, v = a.value;\nif (n === 'id' && !this._testEscape(v)) {\nannotation.id = v;\n} else if (n.slice(0, 3) === 'on-') {\nnode.removeAttribute(n);\nannotation.events.push({\nname: n.slice(3),\nvalue: v\n});\n} else {\nvar b = this._parseNodeAttributeAnnotation(node, n, v);\nif (b) {\nannotation.bindings.push(b);\n}\n}\n}\n},\n_parseNodeAttributeAnnotation: function (node, n, v) {\nvar escape = this._testEscape(v);\nif (escape) {\nvar customEvent;\nvar name = n;\nvar mode = escape[0];\nv = v.slice(2, -2).trim();\nvar not = false;\nif (v[0] == '!') {\nv = v.substring(1);\nnot = true;\n}\nvar kind = 'property';\nif (n[n.length - 1] == '$') {\nname = n.slice(0, -1);\nkind = 'attribute';\n}\nvar notifyEvent, colon;\nif (mode == '{' && (colon = v.indexOf('::')) > 0) {\nnotifyEvent = v.substring(colon + 2);\nv = v.substring(0, colon);\ncustomEvent = true;\n}\nif (node.localName == 'input' && n == 'value') {\nnode.setAttribute(n, '');\n}\nnode.removeAttribute(n);\nif (kind === 'property') {\nname = Polymer.CaseMap.dashToCamelCase(name);\n}\nreturn {\nkind: kind,\nmode: mode,\nname: name,\nvalue: v,\nnegate: not,\nevent: notifyEvent,\ncustomEvent: customEvent\n};\n}\n},\n_localSubTree: function (node, host) {\nreturn node === host ? node.childNodes : node._lightChildren || node.childNodes;\n},\nfindAnnotatedNode: function (root, annote) {\nvar parent = annote.parent && Polymer.Annotations.findAnnotatedNode(root, annote.parent);\nreturn !parent ? root : Polymer.Annotations._localSubTree(parent, root)[annote.index];\n}\n};\n(function () {\nfunction resolveCss(cssText, ownerDocument) {\nreturn cssText.replace(CSS_URL_RX, function (m, pre, url, post) {\nreturn pre + '\\'' + resolve(url.replace(/[\"']/g, ''), ownerDocument) + '\\'' + post;\n});\n}\nfunction resolveAttrs(element, ownerDocument) {\nfor (var name in URL_ATTRS) {\nvar a$ = URL_ATTRS[name];\nfor (var i = 0, l = a$.length, a, at, v; i < l && (a = a$[i]); i++) {\nif (name === '*' || element.localName === name) {\nat = element.attributes[a];\nv = at && at.value;\nif (v && v.search(BINDING_RX) < 0) {\nat.value = a === 'style' ? resolveCss(v, ownerDocument) : resolve(v, ownerDocument);\n}\n}\n}\n}\n}\nfunction resolve(url, ownerDocument) {\nif (url && url[0] === '#') {\nreturn url;\n}\nvar resolver = getUrlResolver(ownerDocument);\nresolver.href = url;\nreturn resolver.href || url;\n}\nvar tempDoc;\nvar tempDocBase;\nfunction resolveUrl(url, baseUri) {\nif (!tempDoc) {\ntempDoc = document.implementation.createHTMLDocument('temp');\ntempDocBase = tempDoc.createElement('base');\ntempDoc.head.appendChild(tempDocBase);\n}\ntempDocBase.href = baseUri;\nreturn resolve(url, tempDoc);\n}\nfunction getUrlResolver(ownerDocument) {\nreturn ownerDocument.__urlResolver || (ownerDocument.__urlResolver = ownerDocument.createElement('a'));\n}\nvar CSS_URL_RX = /(url\\()([^)]*)(\\))/g;\nvar URL_ATTRS = {\n'*': [\n'href',\n'src',\n'style',\n'url'\n],\nform: ['action']\n};\nvar BINDING_RX = /\\{\\{|\\[\\[/;\nPolymer.ResolveUrl = {\nresolveCss: resolveCss,\nresolveAttrs: resolveAttrs,\nresolveUrl: resolveUrl\n};\n}());\nPolymer.Base._addFeature({\n_prepAnnotations: function () {\nif (!this._template) {\nthis._notes = [];\n} else {\nPolymer.Annotations.prepElement = this._prepElement.bind(this);\nthis._notes = Polymer.Annotations.parseAnnotations(this._template);\nthis._processAnnotations(this._notes);\nPolymer.Annotations.prepElement = null;\n}\n},\n_processAnnotations: function (notes) {\nfor (var i = 0; i < notes.length; i++) {\nvar note = notes[i];\nfor (var j = 0; j < note.bindings.length; j++) {\nvar b = note.bindings[j];\nb.signature = this._parseMethod(b.value);\nif (!b.signature) {\nb.model = this._modelForPath(b.value);\n}\n}\nif (note.templateContent) {\nthis._processAnnotations(note.templateContent._notes);\nvar pp = note.templateContent._parentProps = this._discoverTemplateParentProps(note.templateContent._notes);\nvar bindings = [];\nfor (var prop in pp) {\nbindings.push({\nindex: note.index,\nkind: 'property',\nmode: '{',\nname: '_parent_' + prop,\nmodel: prop,\nvalue: prop\n});\n}\nnote.bindings = note.bindings.concat(bindings);\n}\n}\n},\n_discoverTemplateParentProps: function (notes) {\nvar pp = {};\nnotes.forEach(function (n) {\nn.bindings.forEach(function (b) {\nif (b.signature) {\nvar args = b.signature.args;\nfor (var k = 0; k < args.length; k++) {\npp[args[k].model] = true;\n}\n} else {\npp[b.model] = true;\n}\n});\nif (n.templateContent) {\nvar tpp = n.templateContent._parentProps;\nPolymer.Base.mixin(pp, tpp);\n}\n});\nreturn pp;\n},\n_prepElement: function (element) {\nPolymer.ResolveUrl.resolveAttrs(element, this._template.ownerDocument);\n},\n_findAnnotatedNode: Polymer.Annotations.findAnnotatedNode,\n_marshalAnnotationReferences: function () {\nif (this._template) {\nthis._marshalIdNodes();\nthis._marshalAnnotatedNodes();\nthis._marshalAnnotatedListeners();\n}\n},\n_configureAnnotationReferences: function () {\nthis._configureTemplateContent();\n},\n_configureTemplateContent: function () {\nthis._notes.forEach(function (note, i) {\nif (note.templateContent) {\nthis._nodes[i]._content = note.templateContent;\n}\n}, this);\n},\n_marshalIdNodes: function () {\nthis.$ = {};\nthis._notes.forEach(function (a) {\nif (a.id) {\nthis.$[a.id] = this._findAnnotatedNode(this.root, a);\n}\n}, this);\n},\n_marshalAnnotatedNodes: function () {\nif (this._nodes) {\nthis._nodes = this._nodes.map(function (a) {\nreturn this._findAnnotatedNode(this.root, a);\n}, this);\n}\n},\n_marshalAnnotatedListeners: function () {\nthis._notes.forEach(function (a) {\nif (a.events && a.events.length) {\nvar node = this._findAnnotatedNode(this.root, a);\na.events.forEach(function (e) {\nthis.listen(node, e.name, e.value);\n}, this);\n}\n}, this);\n}\n});\nPolymer.Base._addFeature({\nlisteners: {},\n_listenListeners: function (listeners) {\nvar node, name, key;\nfor (key in listeners) {\nif (key.indexOf('.') < 0) {\nnode = this;\nname = key;\n} else {\nname = key.split('.');\nnode = this.$[name[0]];\nname = name[1];\n}\nthis.listen(node, name, listeners[key]);\n}\n},\nlisten: function (node, eventName, methodName) {\nthis._listen(node, eventName, this._createEventHandler(node, eventName, methodName));\n},\n_boundListenerKey: function (eventName, methodName) {\nreturn eventName + ':' + methodName;\n},\n_recordEventHandler: function (host, eventName, target, methodName, handler) {\nvar hbl = host.__boundListeners;\nif (!hbl) {\nhbl = host.__boundListeners = new WeakMap();\n}\nvar bl = hbl.get(target);\nif (!bl) {\nbl = {};\nhbl.set(target, bl);\n}\nvar key = this._boundListenerKey(eventName, methodName);\nbl[key] = handler;\n},\n_recallEventHandler: function (host, eventName, target, methodName) {\nvar hbl = host.__boundListeners;\nif (!hbl) {\nreturn;\n}\nvar bl = hbl.get(target);\nif (!bl) {\nreturn;\n}\nvar key = this._boundListenerKey(eventName, methodName);\nreturn bl[key];\n},\n_createEventHandler: function (node, eventName, methodName) {\nvar host = this;\nvar handler = function (e) {\nif (host[methodName]) {\nhost[methodName](e, e.detail);\n} else {\nhost._warn(host._logf('_createEventHandler', 'listener method `' + methodName + '` not defined'));\n}\n};\nthis._recordEventHandler(host, eventName, node, methodName, handler);\nreturn handler;\n},\nunlisten: function (node, eventName, methodName) {\nvar handler = this._recallEventHandler(this, eventName, node, methodName);\nif (handler) {\nthis._unlisten(node, eventName, handler);\n}\n},\n_listen: function (node, eventName, handler) {\nnode.addEventListener(eventName, handler);\n},\n_unlisten: function (node, eventName, handler) {\nnode.removeEventListener(eventName, handler);\n}\n});\n(function () {\n'use strict';\nvar HAS_NATIVE_TA = typeof document.head.style.touchAction === 'string';\nvar GESTURE_KEY = '__polymerGestures';\nvar HANDLED_OBJ = '__polymerGesturesHandled';\nvar TOUCH_ACTION = '__polymerGesturesTouchAction';\nvar TAP_DISTANCE = 25;\nvar TRACK_DISTANCE = 5;\nvar TRACK_LENGTH = 2;\nvar MOUSE_TIMEOUT = 2500;\nvar MOUSE_EVENTS = [\n'mousedown',\n'mousemove',\n'mouseup',\n'click'\n];\nvar MOUSE_WHICH_TO_BUTTONS = [\n0,\n1,\n4,\n2\n];\nvar MOUSE_HAS_BUTTONS = function () {\ntry {\nreturn new MouseEvent('test', { buttons: 1 }).buttons === 1;\n} catch (e) {\nreturn false;\n}\n}();\nvar IS_TOUCH_ONLY = navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/);\nvar mouseCanceller = function (mouseEvent) {\nmouseEvent[HANDLED_OBJ] = { skip: true };\nif (mouseEvent.type === 'click') {\nvar path = Polymer.dom(mouseEvent).path;\nfor (var i = 0; i < path.length; i++) {\nif (path[i] === POINTERSTATE.mouse.target) {\nreturn;\n}\n}\nmouseEvent.preventDefault();\nmouseEvent.stopPropagation();\n}\n};\nfunction setupTeardownMouseCanceller(setup) {\nfor (var i = 0, en; i < MOUSE_EVENTS.length; i++) {\nen = MOUSE_EVENTS[i];\nif (setup) {\ndocument.addEventListener(en, mouseCanceller, true);\n} else {\ndocument.removeEventListener(en, mouseCanceller, true);\n}\n}\n}\nfunction ignoreMouse() {\nif (IS_TOUCH_ONLY) {\nreturn;\n}\nif (!POINTERSTATE.mouse.mouseIgnoreJob) {\nsetupTeardownMouseCanceller(true);\n}\nvar unset = function () {\nsetupTeardownMouseCanceller();\nPOINTERSTATE.mouse.target = null;\nPOINTERSTATE.mouse.mouseIgnoreJob = null;\n};\nPOINTERSTATE.mouse.mouseIgnoreJob = Polymer.Debounce(POINTERSTATE.mouse.mouseIgnoreJob, unset, MOUSE_TIMEOUT);\n}\nfunction hasLeftMouseButton(ev) {\nvar type = ev.type;\nif (MOUSE_EVENTS.indexOf(type) === -1) {\nreturn false;\n}\nif (type === 'mousemove') {\nvar buttons = ev.buttons === undefined ? 1 : ev.buttons;\nif (ev instanceof window.MouseEvent && !MOUSE_HAS_BUTTONS) {\nbuttons = MOUSE_WHICH_TO_BUTTONS[ev.which] || 0;\n}\nreturn Boolean(buttons & 1);\n} else {\nvar button = ev.button === undefined ? 0 : ev.button;\nreturn button === 0;\n}\n}\nfunction isSyntheticClick(ev) {\nif (ev.type === 'click') {\nif (ev.detail === 0) {\nreturn true;\n}\nvar t = Gestures.findOriginalTarget(ev);\nvar bcr = t.getBoundingClientRect();\nvar x = ev.pageX, y = ev.pageY;\nreturn !(x >= bcr.left && x <= bcr.right && (y >= bcr.top && y <= bcr.bottom));\n}\nreturn false;\n}\nvar POINTERSTATE = {\nmouse: {\ntarget: null,\nmouseIgnoreJob: null\n},\ntouch: {\nx: 0,\ny: 0,\nid: -1,\nscrollDecided: false\n}\n};\nfunction firstTouchAction(ev) {\nvar path = Polymer.dom(ev).path;\nvar ta = 'auto';\nfor (var i = 0, n; i < path.length; i++) {\nn = path[i];\nif (n[TOUCH_ACTION]) {\nta = n[TOUCH_ACTION];\nbreak;\n}\n}\nreturn ta;\n}\nfunction trackDocument(stateObj, movefn, upfn) {\nstateObj.movefn = movefn;\nstateObj.upfn = upfn;\ndocument.addEventListener('mousemove', movefn);\ndocument.addEventListener('mouseup', upfn);\n}\nfunction untrackDocument(stateObj) {\ndocument.removeEventListener('mousemove', stateObj.movefn);\ndocument.removeEventListener('mouseup', stateObj.upfn);\n}\nvar Gestures = {\ngestures: {},\nrecognizers: [],\ndeepTargetFind: function (x, y) {\nvar node = document.elementFromPoint(x, y);\nvar next = node;\nwhile (next && next.shadowRoot) {\nnext = next.shadowRoot.elementFromPoint(x, y);\nif (next) {\nnode = next;\n}\n}\nreturn node;\n},\nfindOriginalTarget: function (ev) {\nif (ev.path) {\nreturn ev.path[0];\n}\nreturn ev.target;\n},\nhandleNative: function (ev) {\nvar handled;\nvar type = ev.type;\nvar node = ev.currentTarget;\nvar gobj = node[GESTURE_KEY];\nvar gs = gobj[type];\nif (!gs) {\nreturn;\n}\nif (!ev[HANDLED_OBJ]) {\nev[HANDLED_OBJ] = {};\nif (type.slice(0, 5) === 'touch') {\nvar t = ev.changedTouches[0];\nif (type === 'touchstart') {\nif (ev.touches.length === 1) {\nPOINTERSTATE.touch.id = t.identifier;\n}\n}\nif (POINTERSTATE.touch.id !== t.identifier) {\nreturn;\n}\nif (!HAS_NATIVE_TA) {\nif (type === 'touchstart' || type === 'touchmove') {\nGestures.handleTouchAction(ev);\n}\n}\nif (type === 'touchend') {\nPOINTERSTATE.mouse.target = Polymer.dom(ev).rootTarget;\nignoreMouse(true);\n}\n}\n}\nhandled = ev[HANDLED_OBJ];\nif (handled.skip) {\nreturn;\n}\nvar recognizers = Gestures.recognizers;\nfor (var i = 0, r; i < recognizers.length; i++) {\nr = recognizers[i];\nif (gs[r.name] && !handled[r.name]) {\nif (r.flow && r.flow.start.indexOf(ev.type) > -1) {\nif (r.reset) {\nr.reset();\n}\n}\n}\n}\nfor (var i = 0, r; i < recognizers.length; i++) {\nr = recognizers[i];\nif (gs[r.name] && !handled[r.name]) {\nhandled[r.name] = true;\nr[type](ev);\n}\n}\n},\nhandleTouchAction: function (ev) {\nvar t = ev.changedTouches[0];\nvar type = ev.type;\nif (type === 'touchstart') {\nPOINTERSTATE.touch.x = t.clientX;\nPOINTERSTATE.touch.y = t.clientY;\nPOINTERSTATE.touch.scrollDecided = false;\n} else if (type === 'touchmove') {\nif (POINTERSTATE.touch.scrollDecided) {\nreturn;\n}\nPOINTERSTATE.touch.scrollDecided = true;\nvar ta = firstTouchAction(ev);\nvar prevent = false;\nvar dx = Math.abs(POINTERSTATE.touch.x - t.clientX);\nvar dy = Math.abs(POINTERSTATE.touch.y - t.clientY);\nif (!ev.cancelable) {\n} else if (ta === 'none') {\nprevent = true;\n} else if (ta === 'pan-x') {\nprevent = dy > dx;\n} else if (ta === 'pan-y') {\nprevent = dx > dy;\n}\nif (prevent) {\nev.preventDefault();\n} else {\nGestures.prevent('track');\n}\n}\n},\nadd: function (node, evType, handler) {\nvar recognizer = this.gestures[evType];\nvar deps = recognizer.deps;\nvar name = recognizer.name;\nvar gobj = node[GESTURE_KEY];\nif (!gobj) {\nnode[GESTURE_KEY] = gobj = {};\n}\nfor (var i = 0, dep, gd; i < deps.length; i++) {\ndep = deps[i];\nif (IS_TOUCH_ONLY && MOUSE_EVENTS.indexOf(dep) > -1) {\ncontinue;\n}\ngd = gobj[dep];\nif (!gd) {\ngobj[dep] = gd = { _count: 0 };\n}\nif (gd._count === 0) {\nnode.addEventListener(dep, this.handleNative);\n}\ngd[name] = (gd[name] || 0) + 1;\ngd._count = (gd._count || 0) + 1;\n}\nnode.addEventListener(evType, handler);\nif (recognizer.touchAction) {\nthis.setTouchAction(node, recognizer.touchAction);\n}\n},\nremove: function (node, evType, handler) {\nvar recognizer = this.gestures[evType];\nvar deps = recognizer.deps;\nvar name = recognizer.name;\nvar gobj = node[GESTURE_KEY];\nif (gobj) {\nfor (var i = 0, dep, gd; i < deps.length; i++) {\ndep = deps[i];\ngd = gobj[dep];\nif (gd && gd[name]) {\ngd[name] = (gd[name] || 1) - 1;\ngd._count = (gd._count || 1) - 1;\n}\nif (gd._count === 0) {\nnode.removeEventListener(dep, this.handleNative);\n}\n}\n}\nnode.removeEventListener(evType, handler);\n},\nregister: function (recog) {\nthis.recognizers.push(recog);\nfor (var i = 0; i < recog.emits.length; i++) {\nthis.gestures[recog.emits[i]] = recog;\n}\n},\nfindRecognizerByEvent: function (evName) {\nfor (var i = 0, r; i < this.recognizers.length; i++) {\nr = this.recognizers[i];\nfor (var j = 0, n; j < r.emits.length; j++) {\nn = r.emits[j];\nif (n === evName) {\nreturn r;\n}\n}\n}\nreturn null;\n},\nsetTouchAction: function (node, value) {\nif (HAS_NATIVE_TA) {\nnode.style.touchAction = value;\n}\nnode[TOUCH_ACTION] = value;\n},\nfire: function (target, type, detail) {\nvar ev = Polymer.Base.fire(type, detail, {\nnode: target,\nbubbles: true,\ncancelable: true\n});\nif (ev.defaultPrevented) {\nvar se = detail.sourceEvent;\nif (se && se.preventDefault) {\nse.preventDefault();\n}\n}\n},\nprevent: function (evName) {\nvar recognizer = this.findRecognizerByEvent(evName);\nif (recognizer.info) {\nrecognizer.info.prevent = true;\n}\n}\n};\nGestures.register({\nname: 'downup',\ndeps: [\n'mousedown',\n'touchstart',\n'touchend'\n],\nflow: {\nstart: [\n'mousedown',\n'touchstart'\n],\nend: [\n'mouseup',\n'touchend'\n]\n},\nemits: [\n'down',\n'up'\n],\ninfo: {\nmovefn: function () {\n},\nupfn: function () {\n}\n},\nreset: function () {\nuntrackDocument(this.info);\n},\nmousedown: function (e) {\nif (!hasLeftMouseButton(e)) {\nreturn;\n}\nvar t = Gestures.findOriginalTarget(e);\nvar self = this;\nvar movefn = function movefn(e) {\nif (!hasLeftMouseButton(e)) {\nself.fire('up', t, e);\nuntrackDocument(self.info);\n}\n};\nvar upfn = function upfn(e) {\nif (hasLeftMouseButton(e)) {\nself.fire('up', t, e);\n}\nuntrackDocument(self.info);\n};\ntrackDocument(this.info, movefn, upfn);\nthis.fire('down', t, e);\n},\ntouchstart: function (e) {\nthis.fire('down', Gestures.findOriginalTarget(e), e.changedTouches[0]);\n},\ntouchend: function (e) {\nthis.fire('up', Gestures.findOriginalTarget(e), e.changedTouches[0]);\n},\nfire: function (type, target, event) {\nvar self = this;\nGestures.fire(target, type, {\nx: event.clientX,\ny: event.clientY,\nsourceEvent: event,\nprevent: Gestures.prevent.bind(Gestures)\n});\n}\n});\nGestures.register({\nname: 'track',\ntouchAction: 'none',\ndeps: [\n'mousedown',\n'touchstart',\n'touchmove',\n'touchend'\n],\nflow: {\nstart: [\n'mousedown',\n'touchstart'\n],\nend: [\n'mouseup',\n'touchend'\n]\n},\nemits: ['track'],\ninfo: {\nx: 0,\ny: 0,\nstate: 'start',\nstarted: false,\nmoves: [],\naddMove: function (move) {\nif (this.moves.length > TRACK_LENGTH) {\nthis.moves.shift();\n}\nthis.moves.push(move);\n},\nmovefn: function () {\n},\nupfn: function () {\n},\nprevent: false\n},\nreset: function () {\nthis.info.state = 'start';\nthis.info.started = false;\nthis.info.moves = [];\nthis.info.x = 0;\nthis.info.y = 0;\nthis.info.prevent = false;\nuntrackDocument(this.info);\n},\nhasMovedEnough: function (x, y) {\nif (this.info.prevent) {\nreturn false;\n}\nif (this.info.started) {\nreturn true;\n}\nvar dx = Math.abs(this.info.x - x);\nvar dy = Math.abs(this.info.y - y);\nreturn dx >= TRACK_DISTANCE || dy >= TRACK_DISTANCE;\n},\nmousedown: function (e) {\nif (!hasLeftMouseButton(e)) {\nreturn;\n}\nvar t = Gestures.findOriginalTarget(e);\nvar self = this;\nvar movefn = function movefn(e) {\nvar x = e.clientX, y = e.clientY;\nif (self.hasMovedEnough(x, y)) {\nself.info.state = self.info.started ? e.type === 'mouseup' ? 'end' : 'track' : 'start';\nself.info.addMove({\nx: x,\ny: y\n});\nif (!hasLeftMouseButton(e)) {\nself.info.state = 'end';\nuntrackDocument(self.info);\n}\nself.fire(t, e);\nself.info.started = true;\n}\n};\nvar upfn = function upfn(e) {\nif (self.info.started) {\nGestures.prevent('tap');\nmovefn(e);\n}\nuntrackDocument(self.info);\n};\ntrackDocument(this.info, movefn, upfn);\nthis.info.x = e.clientX;\nthis.info.y = e.clientY;\n},\ntouchstart: function (e) {\nvar ct = e.changedTouches[0];\nthis.info.x = ct.clientX;\nthis.info.y = ct.clientY;\n},\ntouchmove: function (e) {\nvar t = Gestures.findOriginalTarget(e);\nvar ct = e.changedTouches[0];\nvar x = ct.clientX, y = ct.clientY;\nif (this.hasMovedEnough(x, y)) {\nthis.info.addMove({\nx: x,\ny: y\n});\nthis.fire(t, ct);\nthis.info.state = 'track';\nthis.info.started = true;\n}\n},\ntouchend: function (e) {\nvar t = Gestures.findOriginalTarget(e);\nvar ct = e.changedTouches[0];\nif (this.info.started) {\nGestures.prevent('tap');\nthis.info.state = 'end';\nthis.info.addMove({\nx: ct.clientX,\ny: ct.clientY\n});\nthis.fire(t, ct);\n}\n},\nfire: function (target, touch) {\nvar secondlast = this.info.moves[this.info.moves.length - 2];\nvar lastmove = this.info.moves[this.info.moves.length - 1];\nvar dx = lastmove.x - this.info.x;\nvar dy = lastmove.y - this.info.y;\nvar ddx, ddy = 0;\nif (secondlast) {\nddx = lastmove.x - secondlast.x;\nddy = lastmove.y - secondlast.y;\n}\nreturn Gestures.fire(target, 'track', {\nstate: this.info.state,\nx: touch.clientX,\ny: touch.clientY,\ndx: dx,\ndy: dy,\nddx: ddx,\nddy: ddy,\nsourceEvent: touch,\nhover: function () {\nreturn Gestures.deepTargetFind(touch.clientX, touch.clientY);\n}\n});\n}\n});\nGestures.register({\nname: 'tap',\ndeps: [\n'mousedown',\n'click',\n'touchstart',\n'touchend'\n],\nflow: {\nstart: [\n'mousedown',\n'touchstart'\n],\nend: [\n'click',\n'touchend'\n]\n},\nemits: ['tap'],\ninfo: {\nx: NaN,\ny: NaN,\nprevent: false\n},\nreset: function () {\nthis.info.x = NaN;\nthis.info.y = NaN;\nthis.info.prevent = false;\n},\nsave: function (e) {\nthis.info.x = e.clientX;\nthis.info.y = e.clientY;\n},\nmousedown: function (e) {\nif (hasLeftMouseButton(e)) {\nthis.save(e);\n}\n},\nclick: function (e) {\nif (hasLeftMouseButton(e)) {\nthis.forward(e);\n}\n},\ntouchstart: function (e) {\nthis.save(e.changedTouches[0]);\n},\ntouchend: function (e) {\nthis.forward(e.changedTouches[0]);\n},\nforward: function (e) {\nvar dx = Math.abs(e.clientX - this.info.x);\nvar dy = Math.abs(e.clientY - this.info.y);\nvar t = Gestures.findOriginalTarget(e);\nif (isNaN(dx) || isNaN(dy) || dx <= TAP_DISTANCE && dy <= TAP_DISTANCE || isSyntheticClick(e)) {\nif (!this.info.prevent) {\nGestures.fire(t, 'tap', {\nx: e.clientX,\ny: e.clientY,\nsourceEvent: e\n});\n}\n}\n}\n});\nvar DIRECTION_MAP = {\nx: 'pan-x',\ny: 'pan-y',\nnone: 'none',\nall: 'auto'\n};\nPolymer.Base._addFeature({\n_listen: function (node, eventName, handler) {\nif (Gestures.gestures[eventName]) {\nGestures.add(node, eventName, handler);\n} else {\nnode.addEventListener(eventName, handler);\n}\n},\n_unlisten: function (node, eventName, handler) {\nif (Gestures.gestures[eventName]) {\nGestures.remove(node, eventName, handler);\n} else {\nnode.removeEventListener(eventName, handler);\n}\n},\nsetScrollDirection: function (direction, node) {\nnode = node || this;\nGestures.setTouchAction(node, DIRECTION_MAP[direction] || 'auto');\n}\n});\nPolymer.Gestures = Gestures;\n}());\nPolymer.Async = {\n_currVal: 0,\n_lastVal: 0,\n_callbacks: [],\n_twiddleContent: 0,\n_twiddle: document.createTextNode(''),\nrun: function (callback, waitTime) {\nif (waitTime > 0) {\nreturn ~setTimeout(callback, waitTime);\n} else {\nthis._twiddle.textContent = this._twiddleContent++;\nthis._callbacks.push(callback);\nreturn this._currVal++;\n}\n},\ncancel: function (handle) {\nif (handle < 0) {\nclearTimeout(~handle);\n} else {\nvar idx = handle - this._lastVal;\nif (idx >= 0) {\nif (!this._callbacks[idx]) {\nthrow 'invalid async handle: ' + handle;\n}\nthis._callbacks[idx] = null;\n}\n}\n},\n_atEndOfMicrotask: function () {\nvar len = this._callbacks.length;\nfor (var i = 0; i < len; i++) {\nvar cb = this._callbacks[i];\nif (cb) {\ntry {\ncb();\n} catch (e) {\ni++;\nthis._callbacks.splice(0, i);\nthis._lastVal += i;\nthis._twiddle.textContent = this._twiddleContent++;\nthrow e;\n}\n}\n}\nthis._callbacks.splice(0, len);\nthis._lastVal += len;\n}\n};\nnew (window.MutationObserver || JsMutationObserver)(Polymer.Async._atEndOfMicrotask.bind(Polymer.Async)).observe(Polymer.Async._twiddle, { characterData: true });\nPolymer.Debounce = function () {\nvar Async = Polymer.Async;\nvar Debouncer = function (context) {\nthis.context = context;\nthis.boundComplete = this.complete.bind(this);\n};\nDebouncer.prototype = {\ngo: function (callback, wait) {\nvar h;\nthis.finish = function () {\nAsync.cancel(h);\n};\nh = Async.run(this.boundComplete, wait);\nthis.callback = callback;\n},\nstop: function () {\nif (this.finish) {\nthis.finish();\nthis.finish = null;\n}\n},\ncomplete: function () {\nif (this.finish) {\nthis.stop();\nthis.callback.call(this.context);\n}\n}\n};\nfunction debounce(debouncer, callback, wait) {\nif (debouncer) {\ndebouncer.stop();\n} else {\ndebouncer = new Debouncer(this);\n}\ndebouncer.go(callback, wait);\nreturn debouncer;\n}\nreturn debounce;\n}();\nPolymer.Base._addFeature({\n$$: function (slctr) {\nreturn Polymer.dom(this.root).querySelector(slctr);\n},\ntoggleClass: function (name, bool, node) {\nnode = node || this;\nif (arguments.length == 1) {\nbool = !node.classList.contains(name);\n}\nif (bool) {\nPolymer.dom(node).classList.add(name);\n} else {\nPolymer.dom(node).classList.remove(name);\n}\n},\ntoggleAttribute: function (name, bool, node) {\nnode = node || this;\nif (arguments.length == 1) {\nbool = !node.hasAttribute(name);\n}\nif (bool) {\nPolymer.dom(node).setAttribute(name, '');\n} else {\nPolymer.dom(node).removeAttribute(name);\n}\n},\nclassFollows: function (name, toElement, fromElement) {\nif (fromElement) {\nPolymer.dom(fromElement).classList.remove(name);\n}\nif (toElement) {\nPolymer.dom(toElement).classList.add(name);\n}\n},\nattributeFollows: function (name, toElement, fromElement) {\nif (fromElement) {\nPolymer.dom(fromElement).removeAttribute(name);\n}\nif (toElement) {\nPolymer.dom(toElement).setAttribute(name, '');\n}\n},\ngetContentChildNodes: function (slctr) {\nvar content = Polymer.dom(this.root).querySelector(slctr || 'content');\nreturn content ? Polymer.dom(content).getDistributedNodes() : [];\n},\ngetContentChildren: function (slctr) {\nreturn this.getContentChildNodes(slctr).filter(function (n) {\nreturn n.nodeType === Node.ELEMENT_NODE;\n});\n},\nfire: function (type, detail, options) {\noptions = options || Polymer.nob;\nvar node = options.node || this;\nvar detail = detail === null || detail === undefined ? Polymer.nob : detail;\nvar bubbles = options.bubbles === undefined ? true : options.bubbles;\nvar cancelable = Boolean(options.cancelable);\nvar event = new CustomEvent(type, {\nbubbles: Boolean(bubbles),\ncancelable: cancelable,\ndetail: detail\n});\nnode.dispatchEvent(event);\nreturn event;\n},\nasync: function (callback, waitTime) {\nreturn Polymer.Async.run(callback.bind(this), waitTime);\n},\ncancelAsync: function (handle) {\nPolymer.Async.cancel(handle);\n},\narrayDelete: function (path, item) {\nvar index;\nif (Array.isArray(path)) {\nindex = path.indexOf(item);\nif (index >= 0) {\nreturn path.splice(index, 1);\n}\n} else {\nvar arr = this.get(path);\nindex = arr.indexOf(item);\nif (index >= 0) {\nreturn this.splice(path, index, 1);\n}\n}\n},\ntransform: function (transform, node) {\nnode = node || this;\nnode.style.webkitTransform = transform;\nnode.style.transform = transform;\n},\ntranslate3d: function (x, y, z, node) {\nnode = node || this;\nthis.transform('translate3d(' + x + ',' + y + ',' + z + ')', node);\n},\nimportHref: function (href, onload, onerror) {\nvar l = document.createElement('link');\nl.rel = 'import';\nl.href = href;\nif (onload) {\nl.onload = onload.bind(this);\n}\nif (onerror) {\nl.onerror = onerror.bind(this);\n}\ndocument.head.appendChild(l);\nreturn l;\n},\ncreate: function (tag, props) {\nvar elt = document.createElement(tag);\nif (props) {\nfor (var n in props) {\nelt[n] = props[n];\n}\n}\nreturn elt;\n}\n});\nPolymer.Bind = {\nprepareModel: function (model) {\nmodel._propertyEffects = {};\nmodel._bindListeners = [];\nPolymer.Base.mixin(model, this._modelApi);\n},\n_modelApi: {\n_notifyChange: function (property) {\nvar eventName = Polymer.CaseMap.camelToDashCase(property) + '-changed';\nPolymer.Base.fire(eventName, { value: this[property] }, {\nbubbles: false,\nnode: this\n});\n},\n_propertySetter: function (property, value, effects, fromAbove) {\nvar old = this.__data__[property];\nif (old !== value && (old === old || value === value)) {\nthis.__data__[property] = value;\nif (typeof value == 'object') {\nthis._clearPath(property);\n}\nif (this._propertyChanged) {\nthis._propertyChanged(property, value, old);\n}\nif (effects) {\nthis._effectEffects(property, value, effects, old, fromAbove);\n}\n}\nreturn old;\n},\n__setProperty: function (property, value, quiet, node) {\nnode = node || this;\nvar effects = node._propertyEffects && node._propertyEffects[property];\nif (effects) {\nnode._propertySetter(property, value, effects, quiet);\n} else {\nnode[property] = value;\n}\n},\n_effectEffects: function (property, value, effects, old, fromAbove) {\neffects.forEach(function (fx) {\nvar fn = Polymer.Bind['_' + fx.kind + 'Effect'];\nif (fn) {\nfn.call(this, property, value, fx.effect, old, fromAbove);\n}\n}, this);\n},\n_clearPath: function (path) {\nfor (var prop in this.__data__) {\nif (prop.indexOf(path + '.') === 0) {\nthis.__data__[prop] = undefined;\n}\n}\n}\n},\nensurePropertyEffects: function (model, property) {\nvar fx = model._propertyEffects[property];\nif (!fx) {\nfx = model._propertyEffects[property] = [];\n}\nreturn fx;\n},\naddPropertyEffect: function (model, property, kind, effect) {\nvar fx = this.ensurePropertyEffects(model, property);\nfx.push({\nkind: kind,\neffect: effect\n});\n},\ncreateBindings: function (model) {\nvar fx$ = model._propertyEffects;\nif (fx$) {\nfor (var n in fx$) {\nvar fx = fx$[n];\nfx.sort(this._sortPropertyEffects);\nthis._createAccessors(model, n, fx);\n}\n}\n},\n_sortPropertyEffects: function () {\nvar EFFECT_ORDER = {\n'compute': 0,\n'annotation': 1,\n'computedAnnotation': 2,\n'reflect': 3,\n'notify': 4,\n'observer': 5,\n'complexObserver': 6,\n'function': 7\n};\nreturn function (a, b) {\nreturn EFFECT_ORDER[a.kind] - EFFECT_ORDER[b.kind];\n};\n}(),\n_createAccessors: function (model, property, effects) {\nvar defun = {\nget: function () {\nreturn this.__data__[property];\n}\n};\nvar setter = function (value) {\nthis._propertySetter(property, value, effects);\n};\nvar info = model.getPropertyInfo && model.getPropertyInfo(property);\nif (info && info.readOnly) {\nif (!info.computed) {\nmodel['_set' + this.upper(property)] = setter;\n}\n} else {\ndefun.set = setter;\n}\nObject.defineProperty(model, property, defun);\n},\nupper: function (name) {\nreturn name[0].toUpperCase() + name.substring(1);\n},\n_addAnnotatedListener: function (model, index, property, path, event) {\nvar fn = this._notedListenerFactory(property, path, this._isStructured(path), this._isEventBogus);\nvar eventName = event || Polymer.CaseMap.camelToDashCase(property) + '-changed';\nmodel._bindListeners.push({\nindex: index,\nproperty: property,\npath: path,\nchangedFn: fn,\nevent: eventName\n});\n},\n_isStructured: function (path) {\nreturn path.indexOf('.') > 0;\n},\n_isEventBogus: function (e, target) {\nreturn e.path && e.path[0] !== target;\n},\n_notedListenerFactory: function (property, path, isStructured, bogusTest) {\nreturn function (e, target) {\nif (!bogusTest(e, target)) {\nif (e.detail && e.detail.path) {\nthis.notifyPath(this._fixPath(path, property, e.detail.path), e.detail.value);\n} else {\nvar value = target[property];\nif (!isStructured) {\nthis[path] = target[property];\n} else {\nif (this.__data__[path] != value) {\nthis.set(path, value);\n}\n}\n}\n}\n};\n},\nprepareInstance: function (inst) {\ninst.__data__ = Object.create(null);\n},\nsetupBindListeners: function (inst) {\ninst._bindListeners.forEach(function (info) {\nvar node = inst._nodes[info.index];\nnode.addEventListener(info.event, inst._notifyListener.bind(inst, info.changedFn));\n});\n}\n};\nPolymer.Base.extend(Polymer.Bind, {\n_shouldAddListener: function (effect) {\nreturn effect.name && effect.mode === '{' && !effect.negate && effect.kind != 'attribute';\n},\n_annotationEffect: function (source, value, effect) {\nif (source != effect.value) {\nvalue = this.get(effect.value);\nthis.__data__[effect.value] = value;\n}\nvar calc = effect.negate ? !value : value;\nif (!effect.customEvent || this._nodes[effect.index][effect.name] !== calc) {\nreturn this._applyEffectValue(calc, effect);\n}\n},\n_reflectEffect: function (source) {\nthis.reflectPropertyToAttribute(source);\n},\n_notifyEffect: function (source, value, effect, old, fromAbove) {\nif (!fromAbove) {\nthis._notifyChange(source);\n}\n},\n_functionEffect: function (source, value, fn, old, fromAbove) {\nfn.call(this, source, value, old, fromAbove);\n},\n_observerEffect: function (source, value, effect, old) {\nvar fn = this[effect.method];\nif (fn) {\nfn.call(this, value, old);\n} else {\nthis._warn(this._logf('_observerEffect', 'observer method `' + effect.method + '` not defined'));\n}\n},\n_complexObserverEffect: function (source, value, effect) {\nvar fn = this[effect.method];\nif (fn) {\nvar args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);\nif (args) {\nfn.apply(this, args);\n}\n} else {\nthis._warn(this._logf('_complexObserverEffect', 'observer method `' + effect.method + '` not defined'));\n}\n},\n_computeEffect: function (source, value, effect) {\nvar args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);\nif (args) {\nvar fn = this[effect.method];\nif (fn) {\nthis.__setProperty(effect.property, fn.apply(this, args));\n} else {\nthis._warn(this._logf('_computeEffect', 'compute method `' + effect.method + '` not defined'));\n}\n}\n},\n_annotatedComputationEffect: function (source, value, effect) {\nvar computedHost = this._rootDataHost || this;\nvar fn = computedHost[effect.method];\nif (fn) {\nvar args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);\nif (args) {\nvar computedvalue = fn.apply(computedHost, args);\nif (effect.negate) {\ncomputedvalue = !computedvalue;\n}\nthis._applyEffectValue(computedvalue, effect);\n}\n} else {\ncomputedHost._warn(computedHost._logf('_annotatedComputationEffect', 'compute method `' + effect.method + '` not defined'));\n}\n},\n_marshalArgs: function (model, effect, path, value) {\nvar values = [];\nvar args = effect.args;\nfor (var i = 0, l = args.length; i < l; i++) {\nvar arg = args[i];\nvar name = arg.name;\nvar v;\nif (arg.literal) {\nv = arg.value;\n} else if (arg.structured) {\nv = Polymer.Base.get(name, model);\n} else {\nv = model[name];\n}\nif (args.length > 1 && v === undefined) {\nreturn;\n}\nif (arg.wildcard) {\nvar baseChanged = name.indexOf(path + '.') === 0;\nvar matches = effect.trigger.name.indexOf(name) === 0 && !baseChanged;\nvalues[i] = {\npath: matches ? path : name,\nvalue: matches ? value : v,\nbase: v\n};\n} else {\nvalues[i] = v;\n}\n}\nreturn values;\n}\n});\nPolymer.Base._addFeature({\n_addPropertyEffect: function (property, kind, effect) {\nPolymer.Bind.addPropertyEffect(this, property, kind, effect);\n},\n_prepEffects: function () {\nPolymer.Bind.prepareModel(this);\nthis._addAnnotationEffects(this._notes);\n},\n_prepBindings: function () {\nPolymer.Bind.createBindings(this);\n},\n_addPropertyEffects: function (properties) {\nif (properties) {\nfor (var p in properties) {\nvar prop = properties[p];\nif (prop.observer) {\nthis._addObserverEffect(p, prop.observer);\n}\nif (prop.computed) {\nprop.readOnly = true;\nthis._addComputedEffect(p, prop.computed);\n}\nif (prop.notify) {\nthis._addPropertyEffect(p, 'notify');\n}\nif (prop.reflectToAttribute) {\nthis._addPropertyEffect(p, 'reflect');\n}\nif (prop.readOnly) {\nPolymer.Bind.ensurePropertyEffects(this, p);\n}\n}\n}\n},\n_addComputedEffect: function (name, expression) {\nvar sig = this._parseMethod(expression);\nsig.args.forEach(function (arg) {\nthis._addPropertyEffect(arg.model, 'compute', {\nmethod: sig.method,\nargs: sig.args,\ntrigger: arg,\nproperty: name\n});\n}, this);\n},\n_addObserverEffect: function (property, observer) {\nthis._addPropertyEffect(property, 'observer', {\nmethod: observer,\nproperty: property\n});\n},\n_addComplexObserverEffects: function (observers) {\nif (observers) {\nobservers.forEach(function (observer) {\nthis._addComplexObserverEffect(observer);\n}, this);\n}\n},\n_addComplexObserverEffect: function (observer) {\nvar sig = this._parseMethod(observer);\nsig.args.forEach(function (arg) {\nthis._addPropertyEffect(arg.model, 'complexObserver', {\nmethod: sig.method,\nargs: sig.args,\ntrigger: arg\n});\n}, this);\n},\n_addAnnotationEffects: function (notes) {\nthis._nodes = [];\nnotes.forEach(function (note) {\nvar index = this._nodes.push(note) - 1;\nnote.bindings.forEach(function (binding) {\nthis._addAnnotationEffect(binding, index);\n}, this);\n}, this);\n},\n_addAnnotationEffect: function (note, index) {\nif (Polymer.Bind._shouldAddListener(note)) {\nPolymer.Bind._addAnnotatedListener(this, index, note.name, note.value, note.event);\n}\nif (note.signature) {\nthis._addAnnotatedComputationEffect(note, index);\n} else {\nnote.index = index;\nthis._addPropertyEffect(note.model, 'annotation', note);\n}\n},\n_addAnnotatedComputationEffect: function (note, index) {\nvar sig = note.signature;\nif (sig.static) {\nthis.__addAnnotatedComputationEffect('__static__', index, note, sig, null);\n} else {\nsig.args.forEach(function (arg) {\nif (!arg.literal) {\nthis.__addAnnotatedComputationEffect(arg.model, index, note, sig, arg);\n}\n}, this);\n}\n},\n__addAnnotatedComputationEffect: function (property, index, note, sig, trigger) {\nthis._addPropertyEffect(property, 'annotatedComputation', {\nindex: index,\nkind: note.kind,\nproperty: note.name,\nnegate: note.negate,\nmethod: sig.method,\nargs: sig.args,\ntrigger: trigger\n});\n},\n_parseMethod: function (expression) {\nvar m = expression.match(/([^\\s]+)\\((.*)\\)/);\nif (m) {\nvar sig = {\nmethod: m[1],\nstatic: true\n};\nif (m[2].trim()) {\nvar args = m[2].replace(/\\\\,/g, '&comma;').split(',');\nreturn this._parseArgs(args, sig);\n} else {\nsig.args = Polymer.nar;\nreturn sig;\n}\n}\n},\n_parseArgs: function (argList, sig) {\nsig.args = argList.map(function (rawArg) {\nvar arg = this._parseArg(rawArg);\nif (!arg.literal) {\nsig.static = false;\n}\nreturn arg;\n}, this);\nreturn sig;\n},\n_parseArg: function (rawArg) {\nvar arg = rawArg.trim().replace(/&comma;/g, ',').replace(/\\\\(.)/g, '$1');\nvar a = {\nname: arg,\nmodel: this._modelForPath(arg)\n};\nvar fc = arg[0];\nif (fc >= '0' && fc <= '9') {\nfc = '#';\n}\nswitch (fc) {\ncase '\\'':\ncase '\"':\na.value = arg.slice(1, -1);\na.literal = true;\nbreak;\ncase '#':\na.value = Number(arg);\na.literal = true;\nbreak;\n}\nif (!a.literal) {\na.structured = arg.indexOf('.') > 0;\nif (a.structured) {\na.wildcard = arg.slice(-2) == '.*';\nif (a.wildcard) {\na.name = arg.slice(0, -2);\n}\n}\n}\nreturn a;\n},\n_marshalInstanceEffects: function () {\nPolymer.Bind.prepareInstance(this);\nPolymer.Bind.setupBindListeners(this);\n},\n_applyEffectValue: function (value, info) {\nvar node = this._nodes[info.index];\nvar property = info.property || info.name || 'textContent';\nif (info.kind == 'attribute') {\nthis.serializeValueToAttribute(value, property, node);\n} else {\nif (property === 'className') {\nvalue = this._scopeElementClass(node, value);\n}\nif (property === 'textContent' || node.localName == 'input' && property == 'value') {\nvalue = value == undefined ? '' : value;\n}\nreturn node[property] = value;\n}\n},\n_executeStaticEffects: function () {\nif (this._propertyEffects.__static__) {\nthis._effectEffects('__static__', null, this._propertyEffects.__static__);\n}\n}\n});\nPolymer.Base._addFeature({\n_setupConfigure: function (initialConfig) {\nthis._config = {};\nfor (var i in initialConfig) {\nif (initialConfig[i] !== undefined) {\nthis._config[i] = initialConfig[i];\n}\n}\nthis._handlers = [];\n},\n_marshalAttributes: function () {\nthis._takeAttributesToModel(this._config);\n},\n_attributeChangedImpl: function (name) {\nvar model = this._clientsReadied ? this : this._config;\nthis._setAttributeToProperty(model, name);\n},\n_configValue: function (name, value) {\nthis._config[name] = value;\n},\n_beforeClientsReady: function () {\nthis._configure();\n},\n_configure: function () {\nthis._configureAnnotationReferences();\nthis._aboveConfig = this.mixin({}, this._config);\nvar config = {};\nthis.behaviors.forEach(function (b) {\nthis._configureProperties(b.properties, config);\n}, this);\nthis._configureProperties(this.properties, config);\nthis._mixinConfigure(config, this._aboveConfig);\nthis._config = config;\nthis._distributeConfig(this._config);\n},\n_configureProperties: function (properties, config) {\nfor (var i in properties) {\nvar c = properties[i];\nif (c.value !== undefined) {\nvar value = c.value;\nif (typeof value == 'function') {\nvalue = value.call(this, this._config);\n}\nconfig[i] = value;\n}\n}\n},\n_mixinConfigure: function (a, b) {\nfor (var prop in b) {\nif (!this.getPropertyInfo(prop).readOnly) {\na[prop] = b[prop];\n}\n}\n},\n_distributeConfig: function (config) {\nvar fx$ = this._propertyEffects;\nif (fx$) {\nfor (var p in config) {\nvar fx = fx$[p];\nif (fx) {\nfor (var i = 0, l = fx.length, x; i < l && (x = fx[i]); i++) {\nif (x.kind === 'annotation') {\nvar node = this._nodes[x.effect.index];\nif (node._configValue) {\nvar value = p === x.effect.value ? config[p] : this.get(x.effect.value, config);\nnode._configValue(x.effect.name, value);\n}\n}\n}\n}\n}\n}\n},\n_afterClientsReady: function () {\nthis._executeStaticEffects();\nthis._applyConfig(this._config, this._aboveConfig);\nthis._flushHandlers();\n},\n_applyConfig: function (config, aboveConfig) {\nfor (var n in config) {\nif (this[n] === undefined) {\nthis.__setProperty(n, config[n], n in aboveConfig);\n}\n}\n},\n_notifyListener: function (fn, e) {\nif (!this._clientsReadied) {\nthis._queueHandler([\nfn,\ne,\ne.target\n]);\n} else {\nreturn fn.call(this, e, e.target);\n}\n},\n_queueHandler: function (args) {\nthis._handlers.push(args);\n},\n_flushHandlers: function () {\nvar h$ = this._handlers;\nfor (var i = 0, l = h$.length, h; i < l && (h = h$[i]); i++) {\nh[0].call(this, h[1], h[2]);\n}\n}\n});\n(function () {\n'use strict';\nPolymer.Base._addFeature({\nnotifyPath: function (path, value, fromAbove) {\nvar old = this._propertySetter(path, value);\nif (old !== value && (old === old || value === value)) {\nthis._pathEffector(path, value);\nif (!fromAbove) {\nthis._notifyPath(path, value);\n}\nreturn true;\n}\n},\n_getPathParts: function (path) {\nif (Array.isArray(path)) {\nvar parts = [];\nfor (var i = 0; i < path.length; i++) {\nvar args = path[i].toString().split('.');\nfor (var j = 0; j < args.length; j++) {\nparts.push(args[j]);\n}\n}\nreturn parts;\n} else {\nreturn path.toString().split('.');\n}\n},\nset: function (path, value, root) {\nvar prop = root || this;\nvar parts = this._getPathParts(path);\nvar array;\nvar last = parts[parts.length - 1];\nif (parts.length > 1) {\nfor (var i = 0; i < parts.length - 1; i++) {\nvar part = parts[i];\nprop = prop[part];\nif (array && parseInt(part) == part) {\nparts[i] = Polymer.Collection.get(array).getKey(prop);\n}\nif (!prop) {\nreturn;\n}\narray = Array.isArray(prop) ? prop : null;\n}\nif (array && parseInt(last) == last) {\nvar coll = Polymer.Collection.get(array);\nvar old = prop[last];\nvar key = coll.getKey(old);\nparts[i] = key;\ncoll.setItem(key, value);\n}\nprop[last] = value;\nif (!root) {\nthis.notifyPath(parts.join('.'), value);\n}\n} else {\nprop[path] = value;\n}\n},\nget: function (path, root) {\nvar prop = root || this;\nvar parts = this._getPathParts(path);\nvar last = parts.pop();\nwhile (parts.length) {\nprop = prop[parts.shift()];\nif (!prop) {\nreturn;\n}\n}\nreturn prop[last];\n},\n_pathEffector: function (path, value) {\nvar model = this._modelForPath(path);\nvar fx$ = this._propertyEffects[model];\nif (fx$) {\nfx$.forEach(function (fx) {\nvar fxFn = this['_' + fx.kind + 'PathEffect'];\nif (fxFn) {\nfxFn.call(this, path, value, fx.effect);\n}\n}, this);\n}\nif (this._boundPaths) {\nthis._notifyBoundPaths(path, value);\n}\n},\n_annotationPathEffect: function (path, value, effect) {\nif (effect.value === path || effect.value.indexOf(path + '.') === 0) {\nPolymer.Bind._annotationEffect.call(this, path, value, effect);\n} else if (path.indexOf(effect.value + '.') === 0 && !effect.negate) {\nvar node = this._nodes[effect.index];\nif (node && node.notifyPath) {\nvar p = this._fixPath(effect.name, effect.value, path);\nnode.notifyPath(p, value, true);\n}\n}\n},\n_complexObserverPathEffect: function (path, value, effect) {\nif (this._pathMatchesEffect(path, effect)) {\nPolymer.Bind._complexObserverEffect.call(this, path, value, effect);\n}\n},\n_computePathEffect: function (path, value, effect) {\nif (this._pathMatchesEffect(path, effect)) {\nPolymer.Bind._computeEffect.call(this, path, value, effect);\n}\n},\n_annotatedComputationPathEffect: function (path, value, effect) {\nif (this._pathMatchesEffect(path, effect)) {\nPolymer.Bind._annotatedComputationEffect.call(this, path, value, effect);\n}\n},\n_pathMatchesEffect: function (path, effect) {\nvar effectArg = effect.trigger.name;\nreturn effectArg == path || effectArg.indexOf(path + '.') === 0 || effect.trigger.wildcard && path.indexOf(effectArg) === 0;\n},\nlinkPaths: function (to, from) {\nthis._boundPaths = this._boundPaths || {};\nif (from) {\nthis._boundPaths[to] = from;\n} else {\nthis.unbindPath(to);\n}\n},\nunlinkPaths: function (path) {\nif (this._boundPaths) {\ndelete this._boundPaths[path];\n}\n},\n_notifyBoundPaths: function (path, value) {\nvar from, to;\nfor (var a in this._boundPaths) {\nvar b = this._boundPaths[a];\nif (path.indexOf(a + '.') == 0) {\nfrom = a;\nto = b;\nbreak;\n}\nif (path.indexOf(b + '.') == 0) {\nfrom = b;\nto = a;\nbreak;\n}\n}\nif (from && to) {\nvar p = this._fixPath(to, from, path);\nthis.notifyPath(p, value);\n}\n},\n_fixPath: function (property, root, path) {\nreturn property + path.slice(root.length);\n},\n_notifyPath: function (path, value) {\nvar rootName = this._modelForPath(path);\nvar dashCaseName = Polymer.CaseMap.camelToDashCase(rootName);\nvar eventName = dashCaseName + this._EVENT_CHANGED;\nthis.fire(eventName, {\npath: path,\nvalue: value\n}, { bubbles: false });\n},\n_modelForPath: function (path) {\nvar dot = path.indexOf('.');\nreturn dot < 0 ? path : path.slice(0, dot);\n},\n_EVENT_CHANGED: '-changed',\n_notifySplice: function (array, path, index, added, removed) {\nvar splices = [{\nindex: index,\naddedCount: added,\nremoved: removed,\nobject: array,\ntype: 'splice'\n}];\nvar change = {\nkeySplices: Polymer.Collection.applySplices(array, splices),\nindexSplices: splices\n};\nthis.set(path + '.splices', change);\nif (added != removed.length) {\nthis.notifyPath(path + '.length', array.length);\n}\nchange.keySplices = null;\nchange.indexSplices = null;\n},\npush: function (path) {\nvar array = this.get(path);\nvar args = Array.prototype.slice.call(arguments, 1);\nvar len = array.length;\nvar ret = array.push.apply(array, args);\nif (args.length) {\nthis._notifySplice(array, path, len, args.length, []);\n}\nreturn ret;\n},\npop: function (path) {\nvar array = this.get(path);\nvar hadLength = Boolean(array.length);\nvar args = Array.prototype.slice.call(arguments, 1);\nvar ret = array.pop.apply(array, args);\nif (hadLength) {\nthis._notifySplice(array, path, array.length, 0, [ret]);\n}\nreturn ret;\n},\nsplice: function (path, start, deleteCount) {\nvar array = this.get(path);\nif (start < 0) {\nstart = array.length - Math.floor(-start);\n} else {\nstart = Math.floor(start);\n}\nif (!start) {\nstart = 0;\n}\nvar args = Array.prototype.slice.call(arguments, 1);\nvar ret = array.splice.apply(array, args);\nvar addedCount = Math.max(args.length - 2, 0);\nif (addedCount || ret.length) {\nthis._notifySplice(array, path, start, addedCount, ret);\n}\nreturn ret;\n},\nshift: function (path) {\nvar array = this.get(path);\nvar hadLength = Boolean(array.length);\nvar args = Array.prototype.slice.call(arguments, 1);\nvar ret = array.shift.apply(array, args);\nif (hadLength) {\nthis._notifySplice(array, path, 0, 0, [ret]);\n}\nreturn ret;\n},\nunshift: function (path) {\nvar array = this.get(path);\nvar args = Array.prototype.slice.call(arguments, 1);\nvar ret = array.unshift.apply(array, args);\nif (args.length) {\nthis._notifySplice(array, path, 0, args.length, []);\n}\nreturn ret;\n}\n});\n}());\nPolymer.Base._addFeature({\nresolveUrl: function (url) {\nvar module = Polymer.DomModule.import(this.is);\nvar root = '';\nif (module) {\nvar assetPath = module.getAttribute('assetpath') || '';\nroot = Polymer.ResolveUrl.resolveUrl(assetPath, module.ownerDocument.baseURI);\n}\nreturn Polymer.ResolveUrl.resolveUrl(url, root);\n}\n});\nPolymer.CssParse = function () {\nvar api = {\nparse: function (text) {\ntext = this._clean(text);\nreturn this._parseCss(this._lex(text), text);\n},\n_clean: function (cssText) {\nreturn cssText.replace(this._rx.comments, '').replace(this._rx.port, '');\n},\n_lex: function (text) {\nvar root = {\nstart: 0,\nend: text.length\n};\nvar n = root;\nfor (var i = 0, s = 0, l = text.length; i < l; i++) {\nswitch (text[i]) {\ncase this.OPEN_BRACE:\nif (!n.rules) {\nn.rules = [];\n}\nvar p = n;\nvar previous = p.rules[p.rules.length - 1];\nn = {\nstart: i + 1,\nparent: p,\nprevious: previous\n};\np.rules.push(n);\nbreak;\ncase this.CLOSE_BRACE:\nn.end = i + 1;\nn = n.parent || root;\nbreak;\n}\n}\nreturn root;\n},\n_parseCss: function (node, text) {\nvar t = text.substring(node.start, node.end - 1);\nnode.parsedCssText = node.cssText = t.trim();\nif (node.parent) {\nvar ss = node.previous ? node.previous.end : node.parent.start;\nt = text.substring(ss, node.start - 1);\nt = t.substring(t.lastIndexOf(';') + 1);\nvar s = node.parsedSelector = node.selector = t.trim();\nnode.atRule = s.indexOf(this.AT_START) === 0;\nif (node.atRule) {\nif (s.indexOf(this.MEDIA_START) === 0) {\nnode.type = this.types.MEDIA_RULE;\n} else if (s.match(this._rx.keyframesRule)) {\nnode.type = this.types.KEYFRAMES_RULE;\n}\n} else {\nif (s.indexOf(this.VAR_START) === 0) {\nnode.type = this.types.MIXIN_RULE;\n} else {\nnode.type = this.types.STYLE_RULE;\n}\n}\n}\nvar r$ = node.rules;\nif (r$) {\nfor (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) {\nthis._parseCss(r, text);\n}\n}\nreturn node;\n},\nstringify: function (node, preserveProperties, text) {\ntext = text || '';\nvar cssText = '';\nif (node.cssText || node.rules) {\nvar r$ = node.rules;\nif (r$ && (preserveProperties || !this._hasMixinRules(r$))) {\nfor (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) {\ncssText = this.stringify(r, preserveProperties, cssText);\n}\n} else {\ncssText = preserveProperties ? node.cssText : this.removeCustomProps(node.cssText);\ncssText = cssText.trim();\nif (cssText) {\ncssText = '  ' + cssText + '\\n';\n}\n}\n}\nif (cssText) {\nif (node.selector) {\ntext += node.selector + ' ' + this.OPEN_BRACE + '\\n';\n}\ntext += cssText;\nif (node.selector) {\ntext += this.CLOSE_BRACE + '\\n\\n';\n}\n}\nreturn text;\n},\n_hasMixinRules: function (rules) {\nreturn rules[0].selector.indexOf(this.VAR_START) >= 0;\n},\nremoveCustomProps: function (cssText) {\ncssText = this.removeCustomPropAssignment(cssText);\nreturn this.removeCustomPropApply(cssText);\n},\nremoveCustomPropAssignment: function (cssText) {\nreturn cssText.replace(this._rx.customProp, '').replace(this._rx.mixinProp, '');\n},\nremoveCustomPropApply: function (cssText) {\nreturn cssText.replace(this._rx.mixinApply, '').replace(this._rx.varApply, '');\n},\ntypes: {\nSTYLE_RULE: 1,\nKEYFRAMES_RULE: 7,\nMEDIA_RULE: 4,\nMIXIN_RULE: 1000\n},\nOPEN_BRACE: '{',\nCLOSE_BRACE: '}',\n_rx: {\ncomments: /\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\//gim,\nport: /@import[^;]*;/gim,\ncustomProp: /(?:^|[\\s;])--[^;{]*?:[^{};]*?(?:[;\\n]|$)/gim,\nmixinProp: /(?:^|[\\s;])--[^;{]*?:[^{;]*?{[^}]*?}(?:[;\\n]|$)?/gim,\nmixinApply: /@apply[\\s]*\\([^)]*?\\)[\\s]*(?:[;\\n]|$)?/gim,\nvarApply: /[^;:]*?:[^;]*var[^;]*(?:[;\\n]|$)?/gim,\nkeyframesRule: /^@[^\\s]*keyframes/\n},\nVAR_START: '--',\nMEDIA_START: '@media',\nAT_START: '@'\n};\nreturn api;\n}();\nPolymer.StyleUtil = function () {\nreturn {\nMODULE_STYLES_SELECTOR: 'style, link[rel=import][type~=css], template',\nINCLUDE_ATTR: 'include',\ntoCssText: function (rules, callback, preserveProperties) {\nif (typeof rules === 'string') {\nrules = this.parser.parse(rules);\n}\nif (callback) {\nthis.forEachStyleRule(rules, callback);\n}\nreturn this.parser.stringify(rules, preserveProperties);\n},\nforRulesInStyles: function (styles, callback) {\nif (styles) {\nfor (var i = 0, l = styles.length, s; i < l && (s = styles[i]); i++) {\nthis.forEachStyleRule(this.rulesForStyle(s), callback);\n}\n}\n},\nrulesForStyle: function (style) {\nif (!style.__cssRules && style.textContent) {\nstyle.__cssRules = this.parser.parse(style.textContent);\n}\nreturn style.__cssRules;\n},\nclearStyleRules: function (style) {\nstyle.__cssRules = null;\n},\nforEachStyleRule: function (node, callback) {\nvar s = node.parsedSelector;\nvar skipRules = false;\nif (node.type === this.ruleTypes.STYLE_RULE) {\ncallback(node);\n} else if (node.type === this.ruleTypes.KEYFRAMES_RULE || node.type === this.ruleTypes.MIXIN_RULE) {\nskipRules = true;\n}\nvar r$ = node.rules;\nif (r$ && !skipRules) {\nfor (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) {\nthis.forEachStyleRule(r, callback);\n}\n}\n},\napplyCss: function (cssText, moniker, target, afterNode) {\nvar style = document.createElement('style');\nif (moniker) {\nstyle.setAttribute('scope', moniker);\n}\nstyle.textContent = cssText;\ntarget = target || document.head;\nif (!afterNode) {\nvar n$ = target.querySelectorAll('style[scope]');\nafterNode = n$[n$.length - 1];\n}\ntarget.insertBefore(style, afterNode && afterNode.nextSibling || target.firstChild);\nreturn style;\n},\ncssFromModules: function (moduleIds) {\nvar modules = moduleIds.trim().split(' ');\nvar cssText = '';\nfor (var i = 0; i < modules.length; i++) {\ncssText += this.cssFromModule(modules[i]);\n}\nreturn cssText;\n},\ncssFromModule: function (moduleId) {\nvar m = Polymer.DomModule.import(moduleId);\nif (m && !m._cssText) {\nm._cssText = this._cssFromElement(m);\n}\nreturn m && m._cssText || '';\n},\n_cssFromElement: function (element) {\nvar cssText = '';\nvar content = element.content || element;\nvar sourceDoc = element.ownerDocument;\nvar e$ = Array.prototype.slice.call(content.querySelectorAll(this.MODULE_STYLES_SELECTOR));\nfor (var i = 0, e, resolveDoc, addModule; i < e$.length; i++) {\ne = e$[i];\nresolveDoc = sourceDoc;\naddModule = null;\nif (e.localName === 'template') {\ncssText += this._cssFromElement(e);\n} else {\nif (e.localName === 'style') {\naddModule = e.getAttribute(this.INCLUDE_ATTR);\ne = e.__appliedElement || e;\ne.parentNode.removeChild(e);\n} else {\ne = e.import && e.import.body;\nresolveDoc = e.ownerDocument;\n}\nif (e) {\ncssText += this.resolveCss(e.textContent, resolveDoc);\n}\n}\nif (addModule) {\ncssText += this.cssFromModules(addModule);\n}\n}\nreturn cssText;\n},\nresolveCss: Polymer.ResolveUrl.resolveCss,\nparser: Polymer.CssParse,\nruleTypes: Polymer.CssParse.types\n};\n}();\nPolymer.StyleTransformer = function () {\nvar nativeShadow = Polymer.Settings.useNativeShadow;\nvar styleUtil = Polymer.StyleUtil;\nvar api = {\ndom: function (node, scope, useAttr, shouldRemoveScope) {\nthis._transformDom(node, scope || '', useAttr, shouldRemoveScope);\n},\n_transformDom: function (node, selector, useAttr, shouldRemoveScope) {\nif (node.setAttribute) {\nthis.element(node, selector, useAttr, shouldRemoveScope);\n}\nvar c$ = Polymer.dom(node).childNodes;\nfor (var i = 0; i < c$.length; i++) {\nthis._transformDom(c$[i], selector, useAttr, shouldRemoveScope);\n}\n},\nelement: function (element, scope, useAttr, shouldRemoveScope) {\nif (useAttr) {\nif (shouldRemoveScope) {\nelement.removeAttribute(SCOPE_NAME);\n} else {\nelement.setAttribute(SCOPE_NAME, scope);\n}\n} else {\nif (scope) {\nif (element.classList) {\nif (shouldRemoveScope) {\nelement.classList.remove(SCOPE_NAME);\nelement.classList.remove(scope);\n} else {\nelement.classList.add(SCOPE_NAME);\nelement.classList.add(scope);\n}\n} else if (element.getAttribute) {\nvar c = element.getAttribute(CLASS);\nif (shouldRemoveScope) {\nif (c) {\nelement.setAttribute(CLASS, c.replace(SCOPE_NAME, '').replace(scope, ''));\n}\n} else {\nelement.setAttribute(CLASS, c + (c ? ' ' : '') + SCOPE_NAME + ' ' + scope);\n}\n}\n}\n}\n},\nelementStyles: function (element, callback) {\nvar styles = element._styles;\nvar cssText = '';\nfor (var i = 0, l = styles.length, s, text; i < l && (s = styles[i]); i++) {\nvar rules = styleUtil.rulesForStyle(s);\ncssText += nativeShadow ? styleUtil.toCssText(rules, callback) : this.css(rules, element.is, element.extends, callback, element._scopeCssViaAttr) + '\\n\\n';\n}\nreturn cssText.trim();\n},\ncss: function (rules, scope, ext, callback, useAttr) {\nvar hostScope = this._calcHostScope(scope, ext);\nscope = this._calcElementScope(scope, useAttr);\nvar self = this;\nreturn styleUtil.toCssText(rules, function (rule) {\nif (!rule.isScoped) {\nself.rule(rule, scope, hostScope);\nrule.isScoped = true;\n}\nif (callback) {\ncallback(rule, scope, hostScope);\n}\n});\n},\n_calcElementScope: function (scope, useAttr) {\nif (scope) {\nreturn useAttr ? CSS_ATTR_PREFIX + scope + CSS_ATTR_SUFFIX : CSS_CLASS_PREFIX + scope;\n} else {\nreturn '';\n}\n},\n_calcHostScope: function (scope, ext) {\nreturn ext ? '[is=' + scope + ']' : scope;\n},\nrule: function (rule, scope, hostScope) {\nthis._transformRule(rule, this._transformComplexSelector, scope, hostScope);\n},\n_transformRule: function (rule, transformer, scope, hostScope) {\nvar p$ = rule.selector.split(COMPLEX_SELECTOR_SEP);\nfor (var i = 0, l = p$.length, p; i < l && (p = p$[i]); i++) {\np$[i] = transformer.call(this, p, scope, hostScope);\n}\nrule.selector = rule.transformedSelector = p$.join(COMPLEX_SELECTOR_SEP);\n},\n_transformComplexSelector: function (selector, scope, hostScope) {\nvar stop = false;\nvar hostContext = false;\nvar self = this;\nselector = selector.replace(SIMPLE_SELECTOR_SEP, function (m, c, s) {\nif (!stop) {\nvar info = self._transformCompoundSelector(s, c, scope, hostScope);\nstop = stop || info.stop;\nhostContext = hostContext || info.hostContext;\nc = info.combinator;\ns = info.value;\n} else {\ns = s.replace(SCOPE_JUMP, ' ');\n}\nreturn c + s;\n});\nif (hostContext) {\nselector = selector.replace(HOST_CONTEXT_PAREN, function (m, pre, paren, post) {\nreturn pre + paren + ' ' + hostScope + post + COMPLEX_SELECTOR_SEP + ' ' + pre + hostScope + paren + post;\n});\n}\nreturn selector;\n},\n_transformCompoundSelector: function (selector, combinator, scope, hostScope) {\nvar jumpIndex = selector.search(SCOPE_JUMP);\nvar hostContext = false;\nif (selector.indexOf(HOST_CONTEXT) >= 0) {\nhostContext = true;\n} else if (selector.indexOf(HOST) >= 0) {\nselector = selector.replace(HOST_PAREN, function (m, host, paren) {\nreturn hostScope + paren;\n});\nselector = selector.replace(HOST, hostScope);\n} else if (jumpIndex !== 0) {\nselector = scope ? this._transformSimpleSelector(selector, scope) : selector;\n}\nif (selector.indexOf(CONTENT) >= 0) {\ncombinator = '';\n}\nvar stop;\nif (jumpIndex >= 0) {\nselector = selector.replace(SCOPE_JUMP, ' ');\nstop = true;\n}\nreturn {\nvalue: selector,\ncombinator: combinator,\nstop: stop,\nhostContext: hostContext\n};\n},\n_transformSimpleSelector: function (selector, scope) {\nvar p$ = selector.split(PSEUDO_PREFIX);\np$[0] += scope;\nreturn p$.join(PSEUDO_PREFIX);\n},\ndocumentRule: function (rule) {\nrule.selector = rule.parsedSelector;\nthis.normalizeRootSelector(rule);\nif (!nativeShadow) {\nthis._transformRule(rule, this._transformDocumentSelector);\n}\n},\nnormalizeRootSelector: function (rule) {\nif (rule.selector === ROOT) {\nrule.selector = 'body';\n}\n},\n_transformDocumentSelector: function (selector) {\nreturn selector.match(SCOPE_JUMP) ? this._transformComplexSelector(selector, SCOPE_DOC_SELECTOR) : this._transformSimpleSelector(selector.trim(), SCOPE_DOC_SELECTOR);\n},\nSCOPE_NAME: 'style-scope'\n};\nvar SCOPE_NAME = api.SCOPE_NAME;\nvar SCOPE_DOC_SELECTOR = ':not([' + SCOPE_NAME + '])' + ':not(.' + SCOPE_NAME + ')';\nvar COMPLEX_SELECTOR_SEP = ',';\nvar SIMPLE_SELECTOR_SEP = /(^|[\\s>+~]+)([^\\s>+~]+)/g;\nvar HOST = ':host';\nvar ROOT = ':root';\nvar HOST_PAREN = /(\\:host)(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))/g;\nvar HOST_CONTEXT = ':host-context';\nvar HOST_CONTEXT_PAREN = /(.*)(?:\\:host-context)(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))(.*)/;\nvar CONTENT = '::content';\nvar SCOPE_JUMP = /\\:\\:content|\\:\\:shadow|\\/deep\\//;\nvar CSS_CLASS_PREFIX = '.';\nvar CSS_ATTR_PREFIX = '[' + SCOPE_NAME + '~=';\nvar CSS_ATTR_SUFFIX = ']';\nvar PSEUDO_PREFIX = ':';\nvar CLASS = 'class';\nreturn api;\n}();\nPolymer.StyleExtends = function () {\nvar styleUtil = Polymer.StyleUtil;\nreturn {\nhasExtends: function (cssText) {\nreturn Boolean(cssText.match(this.rx.EXTEND));\n},\ntransform: function (style) {\nvar rules = styleUtil.rulesForStyle(style);\nvar self = this;\nstyleUtil.forEachStyleRule(rules, function (rule) {\nvar map = self._mapRule(rule);\nif (rule.parent) {\nvar m;\nwhile (m = self.rx.EXTEND.exec(rule.cssText)) {\nvar extend = m[1];\nvar extendor = self._findExtendor(extend, rule);\nif (extendor) {\nself._extendRule(rule, extendor);\n}\n}\n}\nrule.cssText = rule.cssText.replace(self.rx.EXTEND, '');\n});\nreturn styleUtil.toCssText(rules, function (rule) {\nif (rule.selector.match(self.rx.STRIP)) {\nrule.cssText = '';\n}\n}, true);\n},\n_mapRule: function (rule) {\nif (rule.parent) {\nvar map = rule.parent.map || (rule.parent.map = {});\nvar parts = rule.selector.split(',');\nfor (var i = 0, p; i < parts.length; i++) {\np = parts[i];\nmap[p.trim()] = rule;\n}\nreturn map;\n}\n},\n_findExtendor: function (extend, rule) {\nreturn rule.parent && rule.parent.map && rule.parent.map[extend] || this._findExtendor(extend, rule.parent);\n},\n_extendRule: function (target, source) {\nif (target.parent !== source.parent) {\nthis._cloneAndAddRuleToParent(source, target.parent);\n}\ntarget.extends = target.extends || (target.extends = []);\ntarget.extends.push(source);\nsource.selector = source.selector.replace(this.rx.STRIP, '');\nsource.selector = (source.selector && source.selector + ',\\n') + target.selector;\nif (source.extends) {\nsource.extends.forEach(function (e) {\nthis._extendRule(target, e);\n}, this);\n}\n},\n_cloneAndAddRuleToParent: function (rule, parent) {\nrule = Object.create(rule);\nrule.parent = parent;\nif (rule.extends) {\nrule.extends = rule.extends.slice();\n}\nparent.rules.push(rule);\n},\nrx: {\nEXTEND: /@extends\\(([^)]*)\\)\\s*?;/gim,\nSTRIP: /%[^,]*$/\n}\n};\n}();\n(function () {\nvar prepElement = Polymer.Base._prepElement;\nvar nativeShadow = Polymer.Settings.useNativeShadow;\nvar styleUtil = Polymer.StyleUtil;\nvar styleTransformer = Polymer.StyleTransformer;\nvar styleExtends = Polymer.StyleExtends;\nPolymer.Base._addFeature({\n_prepElement: function (element) {\nif (this._encapsulateStyle) {\nstyleTransformer.element(element, this.is, this._scopeCssViaAttr);\n}\nprepElement.call(this, element);\n},\n_prepStyles: function () {\nif (this._encapsulateStyle === undefined) {\nthis._encapsulateStyle = !nativeShadow && Boolean(this._template);\n}\nthis._styles = this._collectStyles();\nvar cssText = styleTransformer.elementStyles(this);\nif (cssText && this._template) {\nvar style = styleUtil.applyCss(cssText, this.is, nativeShadow ? this._template.content : null);\nif (!nativeShadow) {\nthis._scopeStyle = style;\n}\n}\n},\n_collectStyles: function () {\nvar styles = [];\nvar cssText = '', m$ = this.styleModules;\nif (m$) {\nfor (var i = 0, l = m$.length, m; i < l && (m = m$[i]); i++) {\ncssText += styleUtil.cssFromModule(m);\n}\n}\ncssText += styleUtil.cssFromModule(this.is);\nif (cssText) {\nvar style = document.createElement('style');\nstyle.textContent = cssText;\nif (styleExtends.hasExtends(style.textContent)) {\ncssText = styleExtends.transform(style);\n}\nstyles.push(style);\n}\nreturn styles;\n},\n_elementAdd: function (node) {\nif (this._encapsulateStyle) {\nif (node.__styleScoped) {\nnode.__styleScoped = false;\n} else {\nstyleTransformer.dom(node, this.is, this._scopeCssViaAttr);\n}\n}\n},\n_elementRemove: function (node) {\nif (this._encapsulateStyle) {\nstyleTransformer.dom(node, this.is, this._scopeCssViaAttr, true);\n}\n},\nscopeSubtree: function (container, shouldObserve) {\nif (nativeShadow) {\nreturn;\n}\nvar self = this;\nvar scopify = function (node) {\nif (node.nodeType === Node.ELEMENT_NODE) {\nnode.className = self._scopeElementClass(node, node.className);\nvar n$ = node.querySelectorAll('*');\nArray.prototype.forEach.call(n$, function (n) {\nn.className = self._scopeElementClass(n, n.className);\n});\n}\n};\nscopify(container);\nif (shouldObserve) {\nvar mo = new MutationObserver(function (mxns) {\nmxns.forEach(function (m) {\nif (m.addedNodes) {\nfor (var i = 0; i < m.addedNodes.length; i++) {\nscopify(m.addedNodes[i]);\n}\n}\n});\n});\nmo.observe(container, {\nchildList: true,\nsubtree: true\n});\nreturn mo;\n}\n}\n});\n}());\nPolymer.StyleProperties = function () {\n'use strict';\nvar nativeShadow = Polymer.Settings.useNativeShadow;\nvar matchesSelector = Polymer.DomApi.matchesSelector;\nvar styleUtil = Polymer.StyleUtil;\nvar styleTransformer = Polymer.StyleTransformer;\nreturn {\ndecorateStyles: function (styles) {\nvar self = this, props = {};\nstyleUtil.forRulesInStyles(styles, function (rule) {\nself.decorateRule(rule);\nself.collectPropertiesInCssText(rule.propertyInfo.cssText, props);\n});\nvar names = [];\nfor (var i in props) {\nnames.push(i);\n}\nreturn names;\n},\ndecorateRule: function (rule) {\nif (rule.propertyInfo) {\nreturn rule.propertyInfo;\n}\nvar info = {}, properties = {};\nvar hasProperties = this.collectProperties(rule, properties);\nif (hasProperties) {\ninfo.properties = properties;\nrule.rules = null;\n}\ninfo.cssText = this.collectCssText(rule);\nrule.propertyInfo = info;\nreturn info;\n},\ncollectProperties: function (rule, properties) {\nvar info = rule.propertyInfo;\nif (info) {\nif (info.properties) {\nPolymer.Base.mixin(properties, info.properties);\nreturn true;\n}\n} else {\nvar m, rx = this.rx.VAR_ASSIGN;\nvar cssText = rule.parsedCssText;\nvar any;\nwhile (m = rx.exec(cssText)) {\nproperties[m[1]] = (m[2] || m[3]).trim();\nany = true;\n}\nreturn any;\n}\n},\ncollectCssText: function (rule) {\nvar customCssText = '';\nvar cssText = rule.parsedCssText;\ncssText = cssText.replace(this.rx.BRACKETED, '').replace(this.rx.VAR_ASSIGN, '');\nvar parts = cssText.split(';');\nfor (var i = 0, p; i < parts.length; i++) {\np = parts[i];\nif (p.match(this.rx.MIXIN_MATCH) || p.match(this.rx.VAR_MATCH)) {\ncustomCssText += p + ';\\n';\n}\n}\nreturn customCssText;\n},\ncollectPropertiesInCssText: function (cssText, props) {\nvar m;\nwhile (m = this.rx.VAR_CAPTURE.exec(cssText)) {\nprops[m[1]] = true;\nvar def = m[2];\nif (def && def.match(this.rx.IS_VAR)) {\nprops[def] = true;\n}\n}\n},\nreify: function (props) {\nvar names = Object.getOwnPropertyNames(props);\nfor (var i = 0, n; i < names.length; i++) {\nn = names[i];\nprops[n] = this.valueForProperty(props[n], props);\n}\n},\nvalueForProperty: function (property, props) {\nif (property) {\nif (property.indexOf(';') >= 0) {\nproperty = this.valueForProperties(property, props);\n} else {\nvar self = this;\nvar fn = function (all, prefix, value, fallback) {\nvar propertyValue = self.valueForProperty(props[value], props) || (props[fallback] ? self.valueForProperty(props[fallback], props) : fallback);\nreturn prefix + (propertyValue || '');\n};\nproperty = property.replace(this.rx.VAR_MATCH, fn);\n}\n}\nreturn property && property.trim() || '';\n},\nvalueForProperties: function (property, props) {\nvar parts = property.split(';');\nfor (var i = 0, p, m; i < parts.length; i++) {\nif (p = parts[i]) {\nm = p.match(this.rx.MIXIN_MATCH);\nif (m) {\np = this.valueForProperty(props[m[1]], props);\n} else {\nvar pp = p.split(':');\nif (pp[1]) {\npp[1] = pp[1].trim();\npp[1] = this.valueForProperty(pp[1], props) || pp[1];\n}\np = pp.join(':');\n}\nparts[i] = p && p.lastIndexOf(';') === p.length - 1 ? p.slice(0, -1) : p || '';\n}\n}\nreturn parts.join(';');\n},\napplyProperties: function (rule, props) {\nvar output = '';\nif (!rule.propertyInfo) {\nthis.decorateRule(rule);\n}\nif (rule.propertyInfo.cssText) {\noutput = this.valueForProperties(rule.propertyInfo.cssText, props);\n}\nrule.cssText = output;\n},\npropertyDataFromStyles: function (styles, element) {\nvar props = {}, self = this;\nvar o = [], i = 0;\nstyleUtil.forRulesInStyles(styles, function (rule) {\nif (!rule.propertyInfo) {\nself.decorateRule(rule);\n}\nif (element && rule.propertyInfo.properties && matchesSelector.call(element, rule.transformedSelector || rule.parsedSelector)) {\nself.collectProperties(rule, props);\naddToBitMask(i, o);\n}\ni++;\n});\nreturn {\nproperties: props,\nkey: o\n};\n},\nscopePropertiesFromStyles: function (styles) {\nif (!styles._scopeStyleProperties) {\nstyles._scopeStyleProperties = this.selectedPropertiesFromStyles(styles, this.SCOPE_SELECTORS);\n}\nreturn styles._scopeStyleProperties;\n},\nhostPropertiesFromStyles: function (styles) {\nif (!styles._hostStyleProperties) {\nstyles._hostStyleProperties = this.selectedPropertiesFromStyles(styles, this.HOST_SELECTORS);\n}\nreturn styles._hostStyleProperties;\n},\nselectedPropertiesFromStyles: function (styles, selectors) {\nvar props = {}, self = this;\nstyleUtil.forRulesInStyles(styles, function (rule) {\nif (!rule.propertyInfo) {\nself.decorateRule(rule);\n}\nfor (var i = 0; i < selectors.length; i++) {\nif (rule.parsedSelector === selectors[i]) {\nself.collectProperties(rule, props);\nreturn;\n}\n}\n});\nreturn props;\n},\ntransformStyles: function (element, properties, scopeSelector) {\nvar self = this;\nvar hostSelector = styleTransformer._calcHostScope(element.is, element.extends);\nvar rxHostSelector = element.extends ? '\\\\' + hostSelector.slice(0, -1) + '\\\\]' : hostSelector;\nvar hostRx = new RegExp(this.rx.HOST_PREFIX + rxHostSelector + this.rx.HOST_SUFFIX);\nreturn styleTransformer.elementStyles(element, function (rule) {\nself.applyProperties(rule, properties);\nif (rule.cssText && !nativeShadow) {\nself._scopeSelector(rule, hostRx, hostSelector, element._scopeCssViaAttr, scopeSelector);\n}\n});\n},\n_scopeSelector: function (rule, hostRx, hostSelector, viaAttr, scopeId) {\nrule.transformedSelector = rule.transformedSelector || rule.selector;\nvar selector = rule.transformedSelector;\nvar scope = viaAttr ? '[' + styleTransformer.SCOPE_NAME + '~=' + scopeId + ']' : '.' + scopeId;\nvar parts = selector.split(',');\nfor (var i = 0, l = parts.length, p; i < l && (p = parts[i]); i++) {\nparts[i] = p.match(hostRx) ? p.replace(hostSelector, hostSelector + scope) : scope + ' ' + p;\n}\nrule.selector = parts.join(',');\n},\napplyElementScopeSelector: function (element, selector, old, viaAttr) {\nvar c = viaAttr ? element.getAttribute(styleTransformer.SCOPE_NAME) : element.className;\nvar v = old ? c.replace(old, selector) : (c ? c + ' ' : '') + this.XSCOPE_NAME + ' ' + selector;\nif (c !== v) {\nif (viaAttr) {\nelement.setAttribute(styleTransformer.SCOPE_NAME, v);\n} else {\nelement.className = v;\n}\n}\n},\napplyElementStyle: function (element, properties, selector, style) {\nvar cssText = style ? style.textContent || '' : this.transformStyles(element, properties, selector);\nvar s = element._customStyle;\nif (s && !nativeShadow && s !== style) {\ns._useCount--;\nif (s._useCount <= 0 && s.parentNode) {\ns.parentNode.removeChild(s);\n}\n}\nif (nativeShadow || (!style || !style.parentNode)) {\nif (nativeShadow && element._customStyle) {\nelement._customStyle.textContent = cssText;\nstyle = element._customStyle;\n} else if (cssText) {\nstyle = styleUtil.applyCss(cssText, selector, nativeShadow ? element.root : null, element._scopeStyle);\n}\n}\nif (style) {\nstyle._useCount = style._useCount || 0;\nif (element._customStyle != style) {\nstyle._useCount++;\n}\nelement._customStyle = style;\n}\nreturn style;\n},\nmixinCustomStyle: function (props, customStyle) {\nvar v;\nfor (var i in customStyle) {\nv = customStyle[i];\nif (v || v === 0) {\nprops[i] = v;\n}\n}\n},\nrx: {\nVAR_ASSIGN: /(?:^|[;\\n]\\s*)(--[\\w-]*?):\\s*(?:([^;{]*)|{([^}]*)})(?:(?=[;\\n])|$)/gi,\nMIXIN_MATCH: /(?:^|\\W+)@apply[\\s]*\\(([^)]*)\\)/i,\nVAR_MATCH: /(^|\\W+)var\\([\\s]*([^,)]*)[\\s]*,?[\\s]*((?:[^,)]*)|(?:[^;]*\\([^;)]*\\)))[\\s]*?\\)/gi,\nVAR_CAPTURE: /\\([\\s]*(--[^,\\s)]*)(?:,[\\s]*(--[^,\\s)]*))?(?:\\)|,)/gi,\nIS_VAR: /^--/,\nBRACKETED: /\\{[^}]*\\}/g,\nHOST_PREFIX: '(?:^|[^.#[:])',\nHOST_SUFFIX: '($|[.:[\\\\s>+~])'\n},\nHOST_SELECTORS: [':host'],\nSCOPE_SELECTORS: [':root'],\nXSCOPE_NAME: 'x-scope'\n};\nfunction addToBitMask(n, bits) {\nvar o = parseInt(n / 32);\nvar v = 1 << n % 32;\nbits[o] = (bits[o] || 0) | v;\n}\n}();\n(function () {\nPolymer.StyleCache = function () {\nthis.cache = {};\n};\nPolymer.StyleCache.prototype = {\nMAX: 100,\nstore: function (is, data, keyValues, keyStyles) {\ndata.keyValues = keyValues;\ndata.styles = keyStyles;\nvar s$ = this.cache[is] = this.cache[is] || [];\ns$.push(data);\nif (s$.length > this.MAX) {\ns$.shift();\n}\n},\nretrieve: function (is, keyValues, keyStyles) {\nvar cache = this.cache[is];\nif (cache) {\nfor (var i = cache.length - 1, data; i >= 0; i--) {\ndata = cache[i];\nif (keyStyles === data.styles && this._objectsEqual(keyValues, data.keyValues)) {\nreturn data;\n}\n}\n}\n},\nclear: function () {\nthis.cache = {};\n},\n_objectsEqual: function (target, source) {\nvar t, s;\nfor (var i in target) {\nt = target[i], s = source[i];\nif (!(typeof t === 'object' && t ? this._objectsStrictlyEqual(t, s) : t === s)) {\nreturn false;\n}\n}\nif (Array.isArray(target)) {\nreturn target.length === source.length;\n}\nreturn true;\n},\n_objectsStrictlyEqual: function (target, source) {\nreturn this._objectsEqual(target, source) && this._objectsEqual(source, target);\n}\n};\n}());\nPolymer.StyleDefaults = function () {\nvar styleProperties = Polymer.StyleProperties;\nvar styleUtil = Polymer.StyleUtil;\nvar StyleCache = Polymer.StyleCache;\nvar api = {\n_styles: [],\n_properties: null,\ncustomStyle: {},\n_styleCache: new StyleCache(),\naddStyle: function (style) {\nthis._styles.push(style);\nthis._properties = null;\n},\nget _styleProperties() {\nif (!this._properties) {\nstyleProperties.decorateStyles(this._styles);\nthis._styles._scopeStyleProperties = null;\nthis._properties = styleProperties.scopePropertiesFromStyles(this._styles);\nstyleProperties.mixinCustomStyle(this._properties, this.customStyle);\nstyleProperties.reify(this._properties);\n}\nreturn this._properties;\n},\n_needsStyleProperties: function () {\n},\n_computeStyleProperties: function () {\nreturn this._styleProperties;\n},\nupdateStyles: function (properties) {\nthis._properties = null;\nif (properties) {\nPolymer.Base.mixin(this.customStyle, properties);\n}\nthis._styleCache.clear();\nfor (var i = 0, s; i < this._styles.length; i++) {\ns = this._styles[i];\ns = s.__importElement || s;\ns._apply();\n}\n}\n};\nreturn api;\n}();\n(function () {\n'use strict';\nvar serializeValueToAttribute = Polymer.Base.serializeValueToAttribute;\nvar propertyUtils = Polymer.StyleProperties;\nvar styleTransformer = Polymer.StyleTransformer;\nvar styleUtil = Polymer.StyleUtil;\nvar styleDefaults = Polymer.StyleDefaults;\nvar nativeShadow = Polymer.Settings.useNativeShadow;\nPolymer.Base._addFeature({\n_prepStyleProperties: function () {\nthis._ownStylePropertyNames = this._styles ? propertyUtils.decorateStyles(this._styles) : [];\n},\ncustomStyle: {},\n_setupStyleProperties: function () {\nthis.customStyle = {};\n},\n_needsStyleProperties: function () {\nreturn Boolean(this._ownStylePropertyNames && this._ownStylePropertyNames.length);\n},\n_beforeAttached: function () {\nif (!this._scopeSelector && this._needsStyleProperties()) {\nthis._updateStyleProperties();\n}\n},\n_findStyleHost: function () {\nvar e = this, root;\nwhile (root = Polymer.dom(e).getOwnerRoot()) {\nif (Polymer.isInstance(root.host)) {\nreturn root.host;\n}\ne = root.host;\n}\nreturn styleDefaults;\n},\n_updateStyleProperties: function () {\nvar info, scope = this._findStyleHost();\nif (!scope._styleCache) {\nscope._styleCache = new Polymer.StyleCache();\n}\nvar scopeData = propertyUtils.propertyDataFromStyles(scope._styles, this);\nscopeData.key.customStyle = this.customStyle;\ninfo = scope._styleCache.retrieve(this.is, scopeData.key, this._styles);\nvar scopeCached = Boolean(info);\nif (scopeCached) {\nthis._styleProperties = info._styleProperties;\n} else {\nthis._computeStyleProperties(scopeData.properties);\n}\nthis._computeOwnStyleProperties();\nif (!scopeCached) {\ninfo = styleCache.retrieve(this.is, this._ownStyleProperties, this._styles);\n}\nvar globalCached = Boolean(info) && !scopeCached;\nvar style = this._applyStyleProperties(info);\nif (!scopeCached) {\nstyle = style && nativeShadow ? style.cloneNode(true) : style;\ninfo = {\nstyle: style,\n_scopeSelector: this._scopeSelector,\n_styleProperties: this._styleProperties\n};\nscopeData.key.customStyle = {};\nthis.mixin(scopeData.key.customStyle, this.customStyle);\nscope._styleCache.store(this.is, info, scopeData.key, this._styles);\nif (!globalCached) {\nstyleCache.store(this.is, Object.create(info), this._ownStyleProperties, this._styles);\n}\n}\n},\n_computeStyleProperties: function (scopeProps) {\nvar scope = this._findStyleHost();\nif (!scope._styleProperties) {\nscope._computeStyleProperties();\n}\nvar props = Object.create(scope._styleProperties);\nthis.mixin(props, propertyUtils.hostPropertiesFromStyles(this._styles));\nscopeProps = scopeProps || propertyUtils.propertyDataFromStyles(scope._styles, this).properties;\nthis.mixin(props, scopeProps);\nthis.mixin(props, propertyUtils.scopePropertiesFromStyles(this._styles));\npropertyUtils.mixinCustomStyle(props, this.customStyle);\npropertyUtils.reify(props);\nthis._styleProperties = props;\n},\n_computeOwnStyleProperties: function () {\nvar props = {};\nfor (var i = 0, n; i < this._ownStylePropertyNames.length; i++) {\nn = this._ownStylePropertyNames[i];\nprops[n] = this._styleProperties[n];\n}\nthis._ownStyleProperties = props;\n},\n_scopeCount: 0,\n_applyStyleProperties: function (info) {\nvar oldScopeSelector = this._scopeSelector;\nthis._scopeSelector = info ? info._scopeSelector : this.is + '-' + this.__proto__._scopeCount++;\nvar style = propertyUtils.applyElementStyle(this, this._styleProperties, this._scopeSelector, info && info.style);\nif (!nativeShadow) {\npropertyUtils.applyElementScopeSelector(this, this._scopeSelector, oldScopeSelector, this._scopeCssViaAttr);\n}\nreturn style;\n},\nserializeValueToAttribute: function (value, attribute, node) {\nnode = node || this;\nif (attribute === 'class' && !nativeShadow) {\nvar host = node === this ? this.domHost || this.dataHost : this;\nif (host) {\nvalue = host._scopeElementClass(node, value);\n}\n}\nnode = Polymer.dom(node);\nserializeValueToAttribute.call(this, value, attribute, node);\n},\n_scopeElementClass: function (element, selector) {\nif (!nativeShadow && !this._scopeCssViaAttr) {\nselector += (selector ? ' ' : '') + SCOPE_NAME + ' ' + this.is + (element._scopeSelector ? ' ' + XSCOPE_NAME + ' ' + element._scopeSelector : '');\n}\nreturn selector;\n},\nupdateStyles: function (properties) {\nif (this.isAttached) {\nif (properties) {\nthis.mixin(this.customStyle, properties);\n}\nif (this._needsStyleProperties()) {\nthis._updateStyleProperties();\n} else {\nthis._styleProperties = null;\n}\nif (this._styleCache) {\nthis._styleCache.clear();\n}\nthis._updateRootStyles();\n}\n},\n_updateRootStyles: function (root) {\nroot = root || this.root;\nvar c$ = Polymer.dom(root)._query(function (e) {\nreturn e.shadyRoot || e.shadowRoot;\n});\nfor (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {\nif (c.updateStyles) {\nc.updateStyles();\n}\n}\n}\n});\nPolymer.updateStyles = function (properties) {\nstyleDefaults.updateStyles(properties);\nPolymer.Base._updateRootStyles(document);\n};\nvar styleCache = new Polymer.StyleCache();\nPolymer.customStyleCache = styleCache;\nvar SCOPE_NAME = styleTransformer.SCOPE_NAME;\nvar XSCOPE_NAME = propertyUtils.XSCOPE_NAME;\n}());\nPolymer.Base._addFeature({\n_registerFeatures: function () {\nthis._prepIs();\nthis._prepAttributes();\nthis._prepConstructor();\nthis._prepTemplate();\nthis._prepStyles();\nthis._prepStyleProperties();\nthis._prepAnnotations();\nthis._prepEffects();\nthis._prepBehaviors();\nthis._prepBindings();\nthis._prepShady();\n},\n_prepBehavior: function (b) {\nthis._addPropertyEffects(b.properties);\nthis._addComplexObserverEffects(b.observers);\nthis._addHostAttributes(b.hostAttributes);\n},\n_initFeatures: function () {\nthis._poolContent();\nthis._setupConfigure();\nthis._setupStyleProperties();\nthis._pushHost();\nthis._stampTemplate();\nthis._popHost();\nthis._marshalAnnotationReferences();\nthis._setupDebouncers();\nthis._marshalInstanceEffects();\nthis._marshalHostAttributes();\nthis._marshalBehaviors();\nthis._marshalAttributes();\nthis._tryReady();\n},\n_marshalBehavior: function (b) {\nthis._listenListeners(b.listeners);\n}\n});\n(function () {\nvar nativeShadow = Polymer.Settings.useNativeShadow;\nvar propertyUtils = Polymer.StyleProperties;\nvar styleUtil = Polymer.StyleUtil;\nvar cssParse = Polymer.CssParse;\nvar styleDefaults = Polymer.StyleDefaults;\nvar styleTransformer = Polymer.StyleTransformer;\nPolymer({\nis: 'custom-style',\nextends: 'style',\nproperties: { include: String },\nready: function () {\nthis._tryApply();\n},\nattached: function () {\nthis._tryApply();\n},\n_tryApply: function () {\nif (!this._appliesToDocument) {\nif (this.parentNode && this.parentNode.localName !== 'dom-module') {\nthis._appliesToDocument = true;\nvar e = this.__appliedElement || this;\nstyleDefaults.addStyle(e);\nif (e.textContent || this.include) {\nthis._apply();\n} else {\nvar observer = new MutationObserver(function () {\nobserver.disconnect();\nthis._apply();\n}.bind(this));\nobserver.observe(e, { childList: true });\n}\n}\n}\n},\n_apply: function () {\nvar e = this.__appliedElement || this;\nif (this.include) {\ne.textContent += styleUtil.cssFromModules(this.include);\n}\nthis._computeStyleProperties();\nvar props = this._styleProperties;\nvar self = this;\ne.textContent = styleUtil.toCssText(styleUtil.rulesForStyle(e), function (rule) {\nvar css = rule.cssText = rule.parsedCssText;\nif (rule.propertyInfo && rule.propertyInfo.cssText) {\ncss = cssParse.removeCustomPropAssignment(css);\nrule.cssText = propertyUtils.valueForProperties(css, props);\n}\nstyleTransformer.documentRule(rule);\n});\n}\n});\n}());\nPolymer.Templatizer = {\nproperties: { __hideTemplateChildren__: { observer: '_showHideChildren' } },\n_instanceProps: Polymer.nob,\n_parentPropPrefix: '_parent_',\ntemplatize: function (template) {\nif (!template._content) {\ntemplate._content = template.content;\n}\nif (template._content._ctor) {\nthis.ctor = template._content._ctor;\nthis._prepParentProperties(this.ctor.prototype, template);\nreturn;\n}\nvar archetype = Object.create(Polymer.Base);\nthis._customPrepAnnotations(archetype, template);\narchetype._prepEffects();\nthis._customPrepEffects(archetype);\narchetype._prepBehaviors();\narchetype._prepBindings();\nthis._prepParentProperties(archetype, template);\narchetype._notifyPath = this._notifyPathImpl;\narchetype._scopeElementClass = this._scopeElementClassImpl;\narchetype.listen = this._listenImpl;\narchetype._showHideChildren = this._showHideChildrenImpl;\nvar _constructor = this._constructorImpl;\nvar ctor = function TemplateInstance(model, host) {\n_constructor.call(this, model, host);\n};\nctor.prototype = archetype;\narchetype.constructor = ctor;\ntemplate._content._ctor = ctor;\nthis.ctor = ctor;\n},\n_getRootDataHost: function () {\nreturn this.dataHost && this.dataHost._rootDataHost || this.dataHost;\n},\n_showHideChildrenImpl: function (hide) {\nvar c = this._children;\nfor (var i = 0; i < c.length; i++) {\nvar n = c[i];\nif (Boolean(hide) != Boolean(n.__hideTemplateChildren__)) {\nif (n.nodeType === Node.TEXT_NODE) {\nif (hide) {\nn.__polymerTextContent__ = n.textContent;\nn.textContent = '';\n} else {\nn.textContent = n.__polymerTextContent__;\n}\n} else if (n.style) {\nif (hide) {\nn.__polymerDisplay__ = n.style.display;\nn.style.display = 'none';\n} else {\nn.style.display = n.__polymerDisplay__;\n}\n}\n}\nn.__hideTemplateChildren__ = hide;\n}\n},\n_debounceTemplate: function (fn) {\nPolymer.dom.addDebouncer(this.debounce('_debounceTemplate', fn));\n},\n_flushTemplates: function (debouncerExpired) {\nPolymer.dom.flush();\n},\n_customPrepEffects: function (archetype) {\nvar parentProps = archetype._parentProps;\nfor (var prop in parentProps) {\narchetype._addPropertyEffect(prop, 'function', this._createHostPropEffector(prop));\n}\nfor (var prop in this._instanceProps) {\narchetype._addPropertyEffect(prop, 'function', this._createInstancePropEffector(prop));\n}\n},\n_customPrepAnnotations: function (archetype, template) {\narchetype._template = template;\nvar c = template._content;\nif (!c._notes) {\nvar rootDataHost = archetype._rootDataHost;\nif (rootDataHost) {\nPolymer.Annotations.prepElement = rootDataHost._prepElement.bind(rootDataHost);\n}\nc._notes = Polymer.Annotations.parseAnnotations(template);\nPolymer.Annotations.prepElement = null;\nthis._processAnnotations(c._notes);\n}\narchetype._notes = c._notes;\narchetype._parentProps = c._parentProps;\n},\n_prepParentProperties: function (archetype, template) {\nvar parentProps = this._parentProps = archetype._parentProps;\nif (this._forwardParentProp && parentProps) {\nvar proto = archetype._parentPropProto;\nvar prop;\nif (!proto) {\nfor (prop in this._instanceProps) {\ndelete parentProps[prop];\n}\nproto = archetype._parentPropProto = Object.create(null);\nif (template != this) {\nPolymer.Bind.prepareModel(proto);\n}\nfor (prop in parentProps) {\nvar parentProp = this._parentPropPrefix + prop;\nvar effects = [\n{\nkind: 'function',\neffect: this._createForwardPropEffector(prop)\n},\n{ kind: 'notify' }\n];\nPolymer.Bind._createAccessors(proto, parentProp, effects);\n}\n}\nif (template != this) {\nPolymer.Bind.prepareInstance(template);\ntemplate._forwardParentProp = this._forwardParentProp.bind(this);\n}\nthis._extendTemplate(template, proto);\n}\n},\n_createForwardPropEffector: function (prop) {\nreturn function (source, value) {\nthis._forwardParentProp(prop, value);\n};\n},\n_createHostPropEffector: function (prop) {\nvar prefix = this._parentPropPrefix;\nreturn function (source, value) {\nthis.dataHost[prefix + prop] = value;\n};\n},\n_createInstancePropEffector: function (prop) {\nreturn function (source, value, old, fromAbove) {\nif (!fromAbove) {\nthis.dataHost._forwardInstanceProp(this, prop, value);\n}\n};\n},\n_extendTemplate: function (template, proto) {\nObject.getOwnPropertyNames(proto).forEach(function (n) {\nvar val = template[n];\nvar pd = Object.getOwnPropertyDescriptor(proto, n);\nObject.defineProperty(template, n, pd);\nif (val !== undefined) {\ntemplate._propertySetter(n, val);\n}\n});\n},\n_showHideChildren: function (hidden) {\n},\n_forwardInstancePath: function (inst, path, value) {\n},\n_forwardInstanceProp: function (inst, prop, value) {\n},\n_notifyPathImpl: function (path, value) {\nvar dataHost = this.dataHost;\nvar dot = path.indexOf('.');\nvar root = dot < 0 ? path : path.slice(0, dot);\ndataHost._forwardInstancePath.call(dataHost, this, path, value);\nif (root in dataHost._parentProps) {\ndataHost.notifyPath(dataHost._parentPropPrefix + path, value);\n}\n},\n_pathEffector: function (path, value, fromAbove) {\nif (this._forwardParentPath) {\nif (path.indexOf(this._parentPropPrefix) === 0) {\nthis._forwardParentPath(path.substring(8), value);\n}\n}\nPolymer.Base._pathEffector.apply(this, arguments);\n},\n_constructorImpl: function (model, host) {\nthis._rootDataHost = host._getRootDataHost();\nthis._setupConfigure(model);\nthis._pushHost(host);\nthis.root = this.instanceTemplate(this._template);\nthis.root.__noContent = !this._notes._hasContent;\nthis.root.__styleScoped = true;\nthis._popHost();\nthis._marshalAnnotatedNodes();\nthis._marshalInstanceEffects();\nthis._marshalAnnotatedListeners();\nvar children = [];\nfor (var n = this.root.firstChild; n; n = n.nextSibling) {\nchildren.push(n);\nn._templateInstance = this;\n}\nthis._children = children;\nif (host.__hideTemplateChildren__) {\nthis._showHideChildren(true);\n}\nthis._tryReady();\n},\n_listenImpl: function (node, eventName, methodName) {\nvar model = this;\nvar host = this._rootDataHost;\nvar handler = host._createEventHandler(node, eventName, methodName);\nvar decorated = function (e) {\ne.model = model;\nhandler(e);\n};\nhost._listen(node, eventName, decorated);\n},\n_scopeElementClassImpl: function (node, value) {\nvar host = this._rootDataHost;\nif (host) {\nreturn host._scopeElementClass(node, value);\n}\n},\nstamp: function (model) {\nmodel = model || {};\nif (this._parentProps) {\nfor (var prop in this._parentProps) {\nmodel[prop] = this[this._parentPropPrefix + prop];\n}\n}\nreturn new this.ctor(model, this);\n},\nmodelForElement: function (el) {\nvar model;\nwhile (el) {\nif (model = el._templateInstance) {\nif (model.dataHost != this) {\nel = model.dataHost;\n} else {\nreturn model;\n}\n} else {\nel = el.parentNode;\n}\n}\n}\n};\nPolymer({\nis: 'dom-template',\nextends: 'template',\nbehaviors: [Polymer.Templatizer],\nready: function () {\nthis.templatize(this);\n}\n});\nPolymer._collections = new WeakMap();\nPolymer.Collection = function (userArray) {\nPolymer._collections.set(userArray, this);\nthis.userArray = userArray;\nthis.store = userArray.slice();\nthis.initMap();\n};\nPolymer.Collection.prototype = {\nconstructor: Polymer.Collection,\ninitMap: function () {\nvar omap = this.omap = new WeakMap();\nvar pmap = this.pmap = {};\nvar s = this.store;\nfor (var i = 0; i < s.length; i++) {\nvar item = s[i];\nif (item && typeof item == 'object') {\nomap.set(item, i);\n} else {\npmap[item] = i;\n}\n}\n},\nadd: function (item) {\nvar key = this.store.push(item) - 1;\nif (item && typeof item == 'object') {\nthis.omap.set(item, key);\n} else {\nthis.pmap[item] = key;\n}\nreturn key;\n},\nremoveKey: function (key) {\nthis._removeFromMap(this.store[key]);\ndelete this.store[key];\n},\n_removeFromMap: function (item) {\nif (item && typeof item == 'object') {\nthis.omap.delete(item);\n} else {\ndelete this.pmap[item];\n}\n},\nremove: function (item) {\nvar key = this.getKey(item);\nthis.removeKey(key);\nreturn key;\n},\ngetKey: function (item) {\nif (item && typeof item == 'object') {\nreturn this.omap.get(item);\n} else {\nreturn this.pmap[item];\n}\n},\ngetKeys: function () {\nreturn Object.keys(this.store);\n},\nsetItem: function (key, item) {\nvar old = this.store[key];\nif (old) {\nthis._removeFromMap(old);\n}\nif (item && typeof item == 'object') {\nthis.omap.set(item, key);\n} else {\nthis.pmap[item] = key;\n}\nthis.store[key] = item;\n},\ngetItem: function (key) {\nreturn this.store[key];\n},\ngetItems: function () {\nvar items = [], store = this.store;\nfor (var key in store) {\nitems.push(store[key]);\n}\nreturn items;\n},\n_applySplices: function (splices) {\nvar keyMap = {}, key, i;\nsplices.forEach(function (s) {\ns.addedKeys = [];\nfor (i = 0; i < s.removed.length; i++) {\nkey = this.getKey(s.removed[i]);\nkeyMap[key] = keyMap[key] ? null : -1;\n}\nfor (i = 0; i < s.addedCount; i++) {\nvar item = this.userArray[s.index + i];\nkey = this.getKey(item);\nkey = key === undefined ? this.add(item) : key;\nkeyMap[key] = keyMap[key] ? null : 1;\ns.addedKeys.push(key);\n}\n}, this);\nvar removed = [];\nvar added = [];\nfor (var key in keyMap) {\nif (keyMap[key] < 0) {\nthis.removeKey(key);\nremoved.push(key);\n}\nif (keyMap[key] > 0) {\nadded.push(key);\n}\n}\nreturn [{\nremoved: removed,\nadded: added\n}];\n}\n};\nPolymer.Collection.get = function (userArray) {\nreturn Polymer._collections.get(userArray) || new Polymer.Collection(userArray);\n};\nPolymer.Collection.applySplices = function (userArray, splices) {\nvar coll = Polymer._collections.get(userArray);\nreturn coll ? coll._applySplices(splices) : null;\n};\nPolymer({\nis: 'dom-repeat',\nextends: 'template',\nproperties: {\nitems: { type: Array },\nas: {\ntype: String,\nvalue: 'item'\n},\nindexAs: {\ntype: String,\nvalue: 'index'\n},\nsort: {\ntype: Function,\nobserver: '_sortChanged'\n},\nfilter: {\ntype: Function,\nobserver: '_filterChanged'\n},\nobserve: {\ntype: String,\nobserver: '_observeChanged'\n},\ndelay: Number\n},\nbehaviors: [Polymer.Templatizer],\nobservers: ['_itemsChanged(items.*)'],\ncreated: function () {\nthis._instances = [];\n},\ndetached: function () {\nfor (var i = 0; i < this._instances.length; i++) {\nthis._detachRow(i);\n}\n},\nattached: function () {\nvar parentNode = Polymer.dom(this).parentNode;\nfor (var i = 0; i < this._instances.length; i++) {\nPolymer.dom(parentNode).insertBefore(this._instances[i].root, this);\n}\n},\nready: function () {\nthis._instanceProps = { __key__: true };\nthis._instanceProps[this.as] = true;\nthis._instanceProps[this.indexAs] = true;\nif (!this.ctor) {\nthis.templatize(this);\n}\n},\n_sortChanged: function () {\nvar dataHost = this._getRootDataHost();\nvar sort = this.sort;\nthis._sortFn = sort && (typeof sort == 'function' ? sort : function () {\nreturn dataHost[sort].apply(dataHost, arguments);\n});\nthis._needFullRefresh = true;\nif (this.items) {\nthis._debounceTemplate(this._render);\n}\n},\n_filterChanged: function () {\nvar dataHost = this._getRootDataHost();\nvar filter = this.filter;\nthis._filterFn = filter && (typeof filter == 'function' ? filter : function () {\nreturn dataHost[filter].apply(dataHost, arguments);\n});\nthis._needFullRefresh = true;\nif (this.items) {\nthis._debounceTemplate(this._render);\n}\n},\n_observeChanged: function () {\nthis._observePaths = this.observe && this.observe.replace('.*', '.').split(' ');\n},\n_itemsChanged: function (change) {\nif (change.path == 'items') {\nif (Array.isArray(this.items)) {\nthis.collection = Polymer.Collection.get(this.items);\n} else if (!this.items) {\nthis.collection = null;\n} else {\nthis._error(this._logf('dom-repeat', 'expected array for `items`,' + ' found', this.items));\n}\nthis._keySplices = [];\nthis._indexSplices = [];\nthis._needFullRefresh = true;\nthis._debounceTemplate(this._render);\n} else if (change.path == 'items.splices') {\nthis._keySplices = this._keySplices.concat(change.value.keySplices);\nthis._indexSplices = this._indexSplices.concat(change.value.indexSplices);\nthis._debounceTemplate(this._render);\n} else {\nvar subpath = change.path.slice(6);\nthis._forwardItemPath(subpath, change.value);\nthis._checkObservedPaths(subpath);\n}\n},\n_checkObservedPaths: function (path) {\nif (this._observePaths) {\npath = path.substring(path.indexOf('.') + 1);\nvar paths = this._observePaths;\nfor (var i = 0; i < paths.length; i++) {\nif (path.indexOf(paths[i]) === 0) {\nthis._needFullRefresh = true;\nif (this.delay) {\nthis.debounce('render', this._render, this.delay);\n} else {\nthis._debounceTemplate(this._render);\n}\nreturn;\n}\n}\n}\n},\nrender: function () {\nthis._needFullRefresh = true;\nthis._debounceTemplate(this._render);\nthis._flushTemplates();\n},\n_render: function () {\nvar c = this.collection;\nif (this._needFullRefresh) {\nthis._applyFullRefresh();\nthis._needFullRefresh = false;\n} else {\nif (this._sortFn) {\nthis._applySplicesUserSort(this._keySplices);\n} else {\nif (this._filterFn) {\nthis._applyFullRefresh();\n} else {\nthis._applySplicesArrayOrder(this._indexSplices);\n}\n}\n}\nthis._keySplices = [];\nthis._indexSplices = [];\nvar keyToIdx = this._keyToInstIdx = {};\nfor (var i = 0; i < this._instances.length; i++) {\nvar inst = this._instances[i];\nkeyToIdx[inst.__key__] = i;\ninst.__setProperty(this.indexAs, i, true);\n}\nthis.fire('dom-change');\n},\n_applyFullRefresh: function () {\nvar c = this.collection;\nvar keys;\nif (this._sortFn) {\nkeys = c ? c.getKeys() : [];\n} else {\nkeys = [];\nvar items = this.items;\nif (items) {\nfor (var i = 0; i < items.length; i++) {\nkeys.push(c.getKey(items[i]));\n}\n}\n}\nif (this._filterFn) {\nkeys = keys.filter(function (a) {\nreturn this._filterFn(c.getItem(a));\n}, this);\n}\nif (this._sortFn) {\nkeys.sort(function (a, b) {\nreturn this._sortFn(c.getItem(a), c.getItem(b));\n}.bind(this));\n}\nfor (var i = 0; i < keys.length; i++) {\nvar key = keys[i];\nvar inst = this._instances[i];\nif (inst) {\ninst.__setProperty('__key__', key, true);\ninst.__setProperty(this.as, c.getItem(key), true);\n} else {\nthis._instances.push(this._insertRow(i, key));\n}\n}\nfor (; i < this._instances.length; i++) {\nthis._detachRow(i);\n}\nthis._instances.splice(keys.length, this._instances.length - keys.length);\n},\n_keySort: function (a, b) {\nreturn this.collection.getKey(a) - this.collection.getKey(b);\n},\n_applySplicesUserSort: function (splices) {\nvar c = this.collection;\nvar instances = this._instances;\nvar keyMap = {};\nvar pool = [];\nvar sortFn = this._sortFn || this._keySort.bind(this);\nsplices.forEach(function (s) {\nfor (var i = 0; i < s.removed.length; i++) {\nvar key = s.removed[i];\nkeyMap[key] = keyMap[key] ? null : -1;\n}\nfor (var i = 0; i < s.added.length; i++) {\nvar key = s.added[i];\nkeyMap[key] = keyMap[key] ? null : 1;\n}\n}, this);\nvar removedIdxs = [];\nvar addedKeys = [];\nfor (var key in keyMap) {\nif (keyMap[key] === -1) {\nremovedIdxs.push(this._keyToInstIdx[key]);\n}\nif (keyMap[key] === 1) {\naddedKeys.push(key);\n}\n}\nif (removedIdxs.length) {\nremovedIdxs.sort();\nfor (var i = removedIdxs.length - 1; i >= 0; i--) {\nvar idx = removedIdxs[i];\nif (idx !== undefined) {\npool.push(this._detachRow(idx));\ninstances.splice(idx, 1);\n}\n}\n}\nif (addedKeys.length) {\nif (this._filterFn) {\naddedKeys = addedKeys.filter(function (a) {\nreturn this._filterFn(c.getItem(a));\n}, this);\n}\naddedKeys.sort(function (a, b) {\nreturn this._sortFn(c.getItem(a), c.getItem(b));\n}.bind(this));\nvar start = 0;\nfor (var i = 0; i < addedKeys.length; i++) {\nstart = this._insertRowUserSort(start, addedKeys[i], pool);\n}\n}\n},\n_insertRowUserSort: function (start, key, pool) {\nvar c = this.collection;\nvar item = c.getItem(key);\nvar end = this._instances.length - 1;\nvar idx = -1;\nvar sortFn = this._sortFn || this._keySort.bind(this);\nwhile (start <= end) {\nvar mid = start + end >> 1;\nvar midKey = this._instances[mid].__key__;\nvar cmp = sortFn(c.getItem(midKey), item);\nif (cmp < 0) {\nstart = mid + 1;\n} else if (cmp > 0) {\nend = mid - 1;\n} else {\nidx = mid;\nbreak;\n}\n}\nif (idx < 0) {\nidx = end + 1;\n}\nthis._instances.splice(idx, 0, this._insertRow(idx, key, pool));\nreturn idx;\n},\n_applySplicesArrayOrder: function (splices) {\nvar pool = [];\nvar c = this.collection;\nsplices.forEach(function (s) {\nfor (var i = 0; i < s.removed.length; i++) {\nvar inst = this._detachRow(s.index + i);\nif (!inst.isPlaceholder) {\npool.push(inst);\n}\n}\nthis._instances.splice(s.index, s.removed.length);\nfor (var i = 0; i < s.addedKeys.length; i++) {\nvar inst = {\nisPlaceholder: true,\nkey: s.addedKeys[i]\n};\nthis._instances.splice(s.index + i, 0, inst);\n}\n}, this);\nfor (var i = this._instances.length - 1; i >= 0; i--) {\nvar inst = this._instances[i];\nif (inst.isPlaceholder) {\nthis._instances[i] = this._insertRow(i, inst.key, pool, true);\n}\n}\n},\n_detachRow: function (idx) {\nvar inst = this._instances[idx];\nif (!inst.isPlaceholder) {\nvar parentNode = Polymer.dom(this).parentNode;\nfor (var i = 0; i < inst._children.length; i++) {\nvar el = inst._children[i];\nPolymer.dom(inst.root).appendChild(el);\n}\n}\nreturn inst;\n},\n_insertRow: function (idx, key, pool, replace) {\nvar inst;\nif (inst = pool && pool.pop()) {\ninst.__setProperty(this.as, this.collection.getItem(key), true);\ninst.__setProperty('__key__', key, true);\n} else {\ninst = this._generateRow(idx, key);\n}\nvar beforeRow = this._instances[replace ? idx + 1 : idx];\nvar beforeNode = beforeRow ? beforeRow._children[0] : this;\nvar parentNode = Polymer.dom(this).parentNode;\nPolymer.dom(parentNode).insertBefore(inst.root, beforeNode);\nreturn inst;\n},\n_generateRow: function (idx, key) {\nvar model = { __key__: key };\nmodel[this.as] = this.collection.getItem(key);\nmodel[this.indexAs] = idx;\nvar inst = this.stamp(model);\nreturn inst;\n},\n_showHideChildren: function (hidden) {\nfor (var i = 0; i < this._instances.length; i++) {\nthis._instances[i]._showHideChildren(hidden);\n}\n},\n_forwardInstanceProp: function (inst, prop, value) {\nif (prop == this.as) {\nvar idx;\nif (this._sortFn || this._filterFn) {\nidx = this.items.indexOf(this.collection.getItem(inst.__key__));\n} else {\nidx = inst[this.indexAs];\n}\nthis.set('items.' + idx, value);\n}\n},\n_forwardInstancePath: function (inst, path, value) {\nif (path.indexOf(this.as + '.') === 0) {\nthis.notifyPath('items.' + inst.__key__ + '.' + path.slice(this.as.length + 1), value);\n}\n},\n_forwardParentProp: function (prop, value) {\nthis._instances.forEach(function (inst) {\ninst.__setProperty(prop, value, true);\n}, this);\n},\n_forwardParentPath: function (path, value) {\nthis._instances.forEach(function (inst) {\ninst.notifyPath(path, value, true);\n}, this);\n},\n_forwardItemPath: function (path, value) {\nif (this._keyToInstIdx) {\nvar dot = path.indexOf('.');\nvar key = path.substring(0, dot < 0 ? path.length : dot);\nvar idx = this._keyToInstIdx[key];\nvar inst = this._instances[idx];\nif (inst) {\nif (dot >= 0) {\npath = this.as + '.' + path.substring(dot + 1);\ninst.notifyPath(path, value, true);\n} else {\ninst.__setProperty(this.as, value, true);\n}\n}\n}\n},\nitemForElement: function (el) {\nvar instance = this.modelForElement(el);\nreturn instance && instance[this.as];\n},\nkeyForElement: function (el) {\nvar instance = this.modelForElement(el);\nreturn instance && instance.__key__;\n},\nindexForElement: function (el) {\nvar instance = this.modelForElement(el);\nreturn instance && instance[this.indexAs];\n}\n});\nPolymer({\nis: 'array-selector',\nproperties: {\nitems: {\ntype: Array,\nobserver: 'clearSelection'\n},\nmulti: {\ntype: Boolean,\nvalue: false,\nobserver: 'clearSelection'\n},\nselected: {\ntype: Object,\nnotify: true\n},\ntoggle: {\ntype: Boolean,\nvalue: false\n}\n},\nclearSelection: function () {\nif (Array.isArray(this.selected)) {\nfor (var i = 0; i < this.selected.length; i++) {\nthis.unlinkPaths('selected.' + i);\n}\n} else {\nthis.unlinkPaths('selected');\n}\nif (this.multi) {\nif (!this.selected || this.selected.length) {\nthis.selected = [];\nthis._selectedColl = Polymer.Collection.get(this.selected);\n}\n} else {\nthis.selected = null;\nthis._selectedColl = null;\n}\n},\nisSelected: function (item) {\nif (this.multi) {\nreturn this._selectedColl.getKey(item) !== undefined;\n} else {\nreturn this.selected == item;\n}\n},\ndeselect: function (item) {\nif (this.multi) {\nif (this.isSelected(item)) {\nvar skey = this._selectedColl.getKey(item);\nthis.arrayDelete('selected', item);\nthis.unlinkPaths('selected.' + skey);\n}\n} else {\nthis.selected = null;\nthis.unlinkPaths('selected');\n}\n},\nselect: function (item) {\nvar icol = Polymer.Collection.get(this.items);\nvar key = icol.getKey(item);\nif (this.multi) {\nif (this.isSelected(item)) {\nif (this.toggle) {\nthis.deselect(item);\n}\n} else {\nthis.push('selected', item);\nskey = this._selectedColl.getKey(item);\nthis.linkPaths('selected.' + skey, 'items.' + key);\n}\n} else {\nif (this.toggle && item == this.selected) {\nthis.deselect();\n} else {\nthis.linkPaths('selected', 'items.' + key);\nthis.selected = item;\n}\n}\n}\n});\nPolymer({\nis: 'dom-if',\nextends: 'template',\nproperties: {\n'if': {\ntype: Boolean,\nvalue: false,\nobserver: '_queueRender'\n},\nrestamp: {\ntype: Boolean,\nvalue: false,\nobserver: '_queueRender'\n}\n},\nbehaviors: [Polymer.Templatizer],\n_queueRender: function () {\nthis._debounceTemplate(this._render);\n},\ndetached: function () {\nthis._teardownInstance();\n},\nattached: function () {\nif (this.if && this.ctor) {\nthis.async(this._ensureInstance);\n}\n},\nrender: function () {\nthis._flushTemplates();\n},\n_render: function () {\nif (this.if) {\nif (!this.ctor) {\nthis.templatize(this);\n}\nthis._ensureInstance();\nthis._showHideChildren();\n} else if (this.restamp) {\nthis._teardownInstance();\n}\nif (!this.restamp && this._instance) {\nthis._showHideChildren();\n}\nif (this.if != this._lastIf) {\nthis.fire('dom-change');\nthis._lastIf = this.if;\n}\n},\n_ensureInstance: function () {\nif (!this._instance) {\nthis._instance = this.stamp();\nvar root = this._instance.root;\nvar parent = Polymer.dom(Polymer.dom(this).parentNode);\nparent.insertBefore(root, this);\n}\n},\n_teardownInstance: function () {\nif (this._instance) {\nvar c = this._instance._children;\nif (c) {\nvar parent = Polymer.dom(Polymer.dom(c[0]).parentNode);\nc.forEach(function (n) {\nparent.removeChild(n);\n});\n}\nthis._instance = null;\n}\n},\n_showHideChildren: function () {\nvar hidden = this.__hideTemplateChildren__ || !this.if;\nif (this._instance) {\nthis._instance._showHideChildren(hidden);\n}\n},\n_forwardParentProp: function (prop, value) {\nif (this._instance) {\nthis._instance[prop] = value;\n}\n},\n_forwardParentPath: function (path, value) {\nif (this._instance) {\nthis._instance.notifyPath(path, value, true);\n}\n}\n});\nPolymer({\nis: 'dom-bind',\nextends: 'template',\ncreated: function () {\nPolymer.RenderStatus.whenReady(this._markImportsReady.bind(this));\n},\n_ensureReady: function () {\nif (!this._readied) {\nthis._readySelf();\n}\n},\n_markImportsReady: function () {\nthis._importsReady = true;\nthis._ensureReady();\n},\n_registerFeatures: function () {\nthis._prepConstructor();\n},\n_insertChildren: function () {\nvar parentDom = Polymer.dom(Polymer.dom(this).parentNode);\nparentDom.insertBefore(this.root, this);\n},\n_removeChildren: function () {\nif (this._children) {\nfor (var i = 0; i < this._children.length; i++) {\nthis.root.appendChild(this._children[i]);\n}\n}\n},\n_initFeatures: function () {\n},\n_scopeElementClass: function (element, selector) {\nif (this.dataHost) {\nreturn this.dataHost._scopeElementClass(element, selector);\n} else {\nreturn selector;\n}\n},\n_prepConfigure: function () {\nvar config = {};\nfor (var prop in this._propertyEffects) {\nconfig[prop] = this[prop];\n}\nthis._setupConfigure = this._setupConfigure.bind(this, config);\n},\nattached: function () {\nif (this._importsReady) {\nthis.render();\n}\n},\ndetached: function () {\nthis._removeChildren();\n},\nrender: function () {\nthis._ensureReady();\nif (!this._children) {\nthis._template = this;\nthis._prepAnnotations();\nthis._prepEffects();\nthis._prepBehaviors();\nthis._prepConfigure();\nthis._prepBindings();\nPolymer.Base._initFeatures.call(this);\nthis._children = Array.prototype.slice.call(this.root.childNodes);\n}\nthis._insertChildren();\nthis.fire('dom-change');\n}\n});</script>\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/promise-polyfill/.bower.json",
    "content": "{\n  \"name\": \"promise-polyfill\",\n  \"version\": \"1.0.0\",\n  \"homepage\": \"https://github.com/taylorhakes/promise-polyfill\",\n  \"authors\": [\n    \"Taylor Hakes\"\n  ],\n  \"description\": \"Lightweight promise polyfill for the browser and node. A+ Compliant.\",\n  \"main\": \"Promise.js\",\n  \"moduleType\": [\n    \"globals\",\n    \"node\"\n  ],\n  \"keywords\": [\n    \"promise\",\n    \"es6\",\n    \"polyfill\",\n    \"html5\"\n  ],\n  \"license\": \"MIT\",\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"bower_components\",\n    \"test\",\n    \"tests\"\n  ],\n  \"dependencies\": {\n    \"polymer\": \"polymer/polymer#^1.0.0\"\n  },\n  \"_release\": \"1.0.0\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"v1.0.0\",\n    \"commit\": \"2ef7dada161cae30e69ffff918485c57121d4b88\"\n  },\n  \"_source\": \"git://github.com/polymerlabs/promise-polyfill.git\",\n  \"_target\": \"^1.0.0\",\n  \"_originalSource\": \"polymerlabs/promise-polyfill\"\n}"
  },
  {
    "path": "cmd/memlat/static/bower_components/promise-polyfill/Gruntfile.js",
    "content": "module.exports = function(grunt) {\n\n\tgrunt.initConfig({\n\t\tpkg: grunt.file.readJSON('package.json'),\n\n\t\tuglify: {\n\t\t\toptions: {\n\t\t\t\tbanner: '/*! <%= pkg.name %> <%= pkg.version %> */\\n'\n\t\t\t},\n\t\t\tdist: {\n\t\t\t\tfiles: {\n\t\t\t\t\t'Promise.min.uglify.js': ['Promise.js']\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n    closurecompiler: {\n      options: {\n        compilation_level: 'ADVANCED_OPTIMIZATIONS',\n      },\n      dist: {\n        files: {\n          'Promise.min.js': ['Promise.js']\n        }\n      }\n    },\n\n    bytesize: {\n      dist: {\n        src: ['Promise*.js']\n      }\n    }\n\t});\n\n\tgrunt.loadNpmTasks('grunt-contrib-uglify');\n\tgrunt.loadNpmTasks('grunt-closurecompiler');\n\tgrunt.loadNpmTasks('grunt-bytesize');\n\n\tgrunt.registerTask('build', ['closurecompiler', 'bytesize']);\n};\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/promise-polyfill/LICENSE",
    "content": "Copyright (c) 2014 Taylor Hakes\nCopyright (c) 2014 Forbes Lindesay\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE."
  },
  {
    "path": "cmd/memlat/static/bower_components/promise-polyfill/Promise-Statics.js",
    "content": "Promise.all = Promise.all || function () {\n  var args = Array.prototype.slice.call(arguments.length === 1 && Array.isArray(arguments[0]) ? arguments[0] : arguments);\n\n  return new Promise(function (resolve, reject) {\n    if (args.length === 0) return resolve([]);\n    var remaining = args.length;\n    function res(i, val) {\n      try {\n        if (val && (typeof val === 'object' || typeof val === 'function')) {\n          var then = val.then;\n          if (typeof then === 'function') {\n            then.call(val, function (val) { res(i, val) }, reject);\n            return;\n          }\n        }\n        args[i] = val;\n        if (--remaining === 0) {\n          resolve(args);\n        }\n      } catch (ex) {\n        reject(ex);\n      }\n    }\n    for (var i = 0; i < args.length; i++) {\n      res(i, args[i]);\n    }\n  });\n};\n\nPromise.race = Promise.race || function (values) {\n  return new Promise(function (resolve, reject) {\n    for(var i = 0, len = values.length; i < len; i++) {\n      values[i].then(resolve, reject);\n    }\n  });\n};\n\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/promise-polyfill/Promise.js",
    "content": "function MakePromise (asap) {\n  function Promise(fn) {\n\t\tif (typeof this !== 'object' || typeof fn !== 'function') throw new TypeError();\n\t\tthis._state = null;\n\t\tthis._value = null;\n\t\tthis._deferreds = []\n\n\t\tdoResolve(fn, resolve.bind(this), reject.bind(this));\n\t}\n\n\tfunction handle(deferred) {\n\t\tvar me = this;\n\t\tif (this._state === null) {\n\t\t\tthis._deferreds.push(deferred);\n\t\t\treturn\n\t\t}\n\t\tasap(function() {\n\t\t\tvar cb = me._state ? deferred.onFulfilled : deferred.onRejected\n\t\t\tif (typeof cb !== 'function') {\n\t\t\t\t(me._state ? deferred.resolve : deferred.reject)(me._value);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar ret;\n\t\t\ttry {\n\t\t\t\tret = cb(me._value);\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\tdeferred.reject(e);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdeferred.resolve(ret);\n\t\t})\n\t}\n\n\tfunction resolve(newValue) {\n\t\ttry { //Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure\n\t\t\tif (newValue === this) throw new TypeError();\n\t\t\tif (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {\n\t\t\t\tvar then = newValue.then;\n\t\t\t\tif (typeof then === 'function') {\n\t\t\t\t\tdoResolve(then.bind(newValue), resolve.bind(this), reject.bind(this));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._state = true;\n\t\t\tthis._value = newValue;\n\t\t\tfinale.call(this);\n\t\t} catch (e) { reject.call(this, e); }\n\t}\n\n\tfunction reject(newValue) {\n\t\tthis._state = false;\n\t\tthis._value = newValue;\n\t\tfinale.call(this);\n\t}\n\n\tfunction finale() {\n\t\tfor (var i = 0, len = this._deferreds.length; i < len; i++) {\n\t\t\thandle.call(this, this._deferreds[i]);\n\t\t}\n\t\tthis._deferreds = null;\n\t}\n\n\t/**\n\t * Take a potentially misbehaving resolver function and make sure\n\t * onFulfilled and onRejected are only called once.\n\t *\n\t * Makes no guarantees about asynchrony.\n\t */\n\tfunction doResolve(fn, onFulfilled, onRejected) {\n\t\tvar done = false;\n\t\ttry {\n\t\t\tfn(function (value) {\n\t\t\t\tif (done) return;\n\t\t\t\tdone = true;\n\t\t\t\tonFulfilled(value);\n\t\t\t}, function (reason) {\n\t\t\t\tif (done) return;\n\t\t\t\tdone = true;\n\t\t\t\tonRejected(reason);\n\t\t\t})\n\t\t} catch (ex) {\n\t\t\tif (done) return;\n\t\t\tdone = true;\n\t\t\tonRejected(ex);\n\t\t}\n\t}\n\n\tPromise.prototype['catch'] = function (onRejected) {\n\t\treturn this.then(null, onRejected);\n\t};\n\n\tPromise.prototype.then = function(onFulfilled, onRejected) {\n\t\tvar me = this;\n\t\treturn new Promise(function(resolve, reject) {\n      handle.call(me, {\n        onFulfilled: onFulfilled,\n        onRejected: onRejected,\n        resolve: resolve,\n        reject: reject\n      });\n\t\t})\n\t};\n\n\tPromise.resolve = function (value) {\n\t\tif (value && typeof value === 'object' && value.constructor === Promise) {\n\t\t\treturn value;\n\t\t}\n\n\t\treturn new Promise(function (resolve) {\n\t\t\tresolve(value);\n\t\t});\n\t};\n\n\tPromise.reject = function (value) {\n\t\treturn new Promise(function (resolve, reject) {\n\t\t\treject(value);\n\t\t});\n\t};\n\n\t\n  return Promise;\n}\n\nif (typeof module !== 'undefined') {\n  module.exports = MakePromise;\n}\n\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/promise-polyfill/README.md",
    "content": "# Promise Polyfill\n\nNote: this is an unsolicited fork of [taylorhakes/promise-polyfill](https://github.com/taylorhakes/promise-polyfill)\nand should be considered experimental and unstable compared to upstream.\n\n## Testing\n```\nnpm install\nnpm test\n```\n\n## License\nMIT\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/promise-polyfill/bower.json",
    "content": "{\n  \"name\": \"promise-polyfill\",\n  \"version\": \"1.0.0\",\n  \"homepage\": \"https://github.com/taylorhakes/promise-polyfill\",\n  \"authors\": [\n    \"Taylor Hakes\"\n  ],\n  \"description\": \"Lightweight promise polyfill for the browser and node. A+ Compliant.\",\n  \"main\": \"Promise.js\",\n  \"moduleType\": [\n    \"globals\",\n    \"node\"\n  ],\n  \"keywords\": [\n    \"promise\",\n    \"es6\",\n    \"polyfill\",\n    \"html5\"\n  ],\n  \"license\": \"MIT\",\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"bower_components\",\n    \"test\",\n    \"tests\"\n  ],\n  \"dependencies\": {\n    \"polymer\": \"polymer/polymer#^1.0.0\"\n  }\n}\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/promise-polyfill/package.json",
    "content": "{\n  \"name\": \"promise-polyfill\",\n  \"version\": \"2.0.0\",\n  \"description\": \"Lightweight promise polyfill. A+ compliant\",\n  \"main\": \"Promise.js\",\n  \"scripts\": {\n    \"test\": \"./node_modules/.bin/promises-aplus-tests tests/adapter.js; ./node_modules/.bin/promises-es6-tests tests/adapter.js\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://taylorhakes@github.com/taylorhakes/promise-polyfill.git\"\n  },\n  \"author\": \"Taylor Hakes\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/taylorhakes/promise-polyfill/issues\"\n  },\n  \"homepage\": \"https://github.com/taylorhakes/promise-polyfill\",\n  \"devDependencies\": {\n    \"grunt\": \"^0.4.5\",\n    \"grunt-bytesize\": \"^0.1.1\",\n    \"grunt-closurecompiler\": \"^0.9.9\",\n    \"grunt-contrib-uglify\": \"^0.4.0\",\n    \"mocha\": \"^2.2.1\",\n    \"promises-aplus-tests\": \"*\",\n    \"promises-es6-tests\": \"^0.5.0\"\n  },\n  \"keywords\": [\n    \"promise\",\n    \"promise-polyfill\",\n    \"ES6\",\n    \"promises-aplus\"\n  ],\n  \"dependencies\": {}\n}\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/promise-polyfill/promise-polyfill-lite.html",
    "content": "<link rel=\"import\" href=\"../polymer/polymer.html\">\n<script src='./Promise.js'></script>\n<script>\nif (!window.Promise) {\n  window.Promise = MakePromise(Polymer.Base.async);\n}\n</script>\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/promise-polyfill/promise-polyfill.html",
    "content": "<link rel=\"import\" href=\"./promise-polyfill-lite.html\">\n<script src='./Promise-Statics.js'></script>\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/webcomponentsjs/.bower.json",
    "content": "{\n  \"name\": \"webcomponentsjs\",\n  \"main\": \"webcomponents.js\",\n  \"version\": \"0.7.11\",\n  \"homepage\": \"http://webcomponents.org\",\n  \"authors\": [\n    \"The Polymer Authors\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/webcomponents/webcomponentsjs.git\"\n  },\n  \"keywords\": [\n    \"webcomponents\"\n  ],\n  \"license\": \"BSD\",\n  \"ignore\": [],\n  \"_release\": \"0.7.11\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"v0.7.11\",\n    \"commit\": \"ce6321507de6161ec52b43f82a6c36eda614d750\"\n  },\n  \"_source\": \"git://github.com/Polymer/webcomponentsjs.git\",\n  \"_target\": \"^0.7.2\",\n  \"_originalSource\": \"webcomponentsjs\"\n}"
  },
  {
    "path": "cmd/memlat/static/bower_components/webcomponentsjs/CustomElements.js",
    "content": "/**\n * @license\n * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n */\n// @version 0.7.11\nif (typeof WeakMap === \"undefined\") {\n  (function() {\n    var defineProperty = Object.defineProperty;\n    var counter = Date.now() % 1e9;\n    var WeakMap = function() {\n      this.name = \"__st\" + (Math.random() * 1e9 >>> 0) + (counter++ + \"__\");\n    };\n    WeakMap.prototype = {\n      set: function(key, value) {\n        var entry = key[this.name];\n        if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {\n          value: [ key, value ],\n          writable: true\n        });\n        return this;\n      },\n      get: function(key) {\n        var entry;\n        return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;\n      },\n      \"delete\": function(key) {\n        var entry = key[this.name];\n        if (!entry || entry[0] !== key) return false;\n        entry[0] = entry[1] = undefined;\n        return true;\n      },\n      has: function(key) {\n        var entry = key[this.name];\n        if (!entry) return false;\n        return entry[0] === key;\n      }\n    };\n    window.WeakMap = WeakMap;\n  })();\n}\n\n(function(global) {\n  var registrationsTable = new WeakMap();\n  var setImmediate;\n  if (/Trident|Edge/.test(navigator.userAgent)) {\n    setImmediate = setTimeout;\n  } else if (window.setImmediate) {\n    setImmediate = window.setImmediate;\n  } else {\n    var setImmediateQueue = [];\n    var sentinel = String(Math.random());\n    window.addEventListener(\"message\", function(e) {\n      if (e.data === sentinel) {\n        var queue = setImmediateQueue;\n        setImmediateQueue = [];\n        queue.forEach(function(func) {\n          func();\n        });\n      }\n    });\n    setImmediate = function(func) {\n      setImmediateQueue.push(func);\n      window.postMessage(sentinel, \"*\");\n    };\n  }\n  var isScheduled = false;\n  var scheduledObservers = [];\n  function scheduleCallback(observer) {\n    scheduledObservers.push(observer);\n    if (!isScheduled) {\n      isScheduled = true;\n      setImmediate(dispatchCallbacks);\n    }\n  }\n  function wrapIfNeeded(node) {\n    return window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrapIfNeeded(node) || node;\n  }\n  function dispatchCallbacks() {\n    isScheduled = false;\n    var observers = scheduledObservers;\n    scheduledObservers = [];\n    observers.sort(function(o1, o2) {\n      return o1.uid_ - o2.uid_;\n    });\n    var anyNonEmpty = false;\n    observers.forEach(function(observer) {\n      var queue = observer.takeRecords();\n      removeTransientObserversFor(observer);\n      if (queue.length) {\n        observer.callback_(queue, observer);\n        anyNonEmpty = true;\n      }\n    });\n    if (anyNonEmpty) dispatchCallbacks();\n  }\n  function removeTransientObserversFor(observer) {\n    observer.nodes_.forEach(function(node) {\n      var registrations = registrationsTable.get(node);\n      if (!registrations) return;\n      registrations.forEach(function(registration) {\n        if (registration.observer === observer) registration.removeTransientObservers();\n      });\n    });\n  }\n  function forEachAncestorAndObserverEnqueueRecord(target, callback) {\n    for (var node = target; node; node = node.parentNode) {\n      var registrations = registrationsTable.get(node);\n      if (registrations) {\n        for (var j = 0; j < registrations.length; j++) {\n          var registration = registrations[j];\n          var options = registration.options;\n          if (node !== target && !options.subtree) continue;\n          var record = callback(options);\n          if (record) registration.enqueue(record);\n        }\n      }\n    }\n  }\n  var uidCounter = 0;\n  function JsMutationObserver(callback) {\n    this.callback_ = callback;\n    this.nodes_ = [];\n    this.records_ = [];\n    this.uid_ = ++uidCounter;\n  }\n  JsMutationObserver.prototype = {\n    observe: function(target, options) {\n      target = wrapIfNeeded(target);\n      if (!options.childList && !options.attributes && !options.characterData || options.attributeOldValue && !options.attributes || options.attributeFilter && options.attributeFilter.length && !options.attributes || options.characterDataOldValue && !options.characterData) {\n        throw new SyntaxError();\n      }\n      var registrations = registrationsTable.get(target);\n      if (!registrations) registrationsTable.set(target, registrations = []);\n      var registration;\n      for (var i = 0; i < registrations.length; i++) {\n        if (registrations[i].observer === this) {\n          registration = registrations[i];\n          registration.removeListeners();\n          registration.options = options;\n          break;\n        }\n      }\n      if (!registration) {\n        registration = new Registration(this, target, options);\n        registrations.push(registration);\n        this.nodes_.push(target);\n      }\n      registration.addListeners();\n    },\n    disconnect: function() {\n      this.nodes_.forEach(function(node) {\n        var registrations = registrationsTable.get(node);\n        for (var i = 0; i < registrations.length; i++) {\n          var registration = registrations[i];\n          if (registration.observer === this) {\n            registration.removeListeners();\n            registrations.splice(i, 1);\n            break;\n          }\n        }\n      }, this);\n      this.records_ = [];\n    },\n    takeRecords: function() {\n      var copyOfRecords = this.records_;\n      this.records_ = [];\n      return copyOfRecords;\n    }\n  };\n  function MutationRecord(type, target) {\n    this.type = type;\n    this.target = target;\n    this.addedNodes = [];\n    this.removedNodes = [];\n    this.previousSibling = null;\n    this.nextSibling = null;\n    this.attributeName = null;\n    this.attributeNamespace = null;\n    this.oldValue = null;\n  }\n  function copyMutationRecord(original) {\n    var record = new MutationRecord(original.type, original.target);\n    record.addedNodes = original.addedNodes.slice();\n    record.removedNodes = original.removedNodes.slice();\n    record.previousSibling = original.previousSibling;\n    record.nextSibling = original.nextSibling;\n    record.attributeName = original.attributeName;\n    record.attributeNamespace = original.attributeNamespace;\n    record.oldValue = original.oldValue;\n    return record;\n  }\n  var currentRecord, recordWithOldValue;\n  function getRecord(type, target) {\n    return currentRecord = new MutationRecord(type, target);\n  }\n  function getRecordWithOldValue(oldValue) {\n    if (recordWithOldValue) return recordWithOldValue;\n    recordWithOldValue = copyMutationRecord(currentRecord);\n    recordWithOldValue.oldValue = oldValue;\n    return recordWithOldValue;\n  }\n  function clearRecords() {\n    currentRecord = recordWithOldValue = undefined;\n  }\n  function recordRepresentsCurrentMutation(record) {\n    return record === recordWithOldValue || record === currentRecord;\n  }\n  function selectRecord(lastRecord, newRecord) {\n    if (lastRecord === newRecord) return lastRecord;\n    if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord)) return recordWithOldValue;\n    return null;\n  }\n  function Registration(observer, target, options) {\n    this.observer = observer;\n    this.target = target;\n    this.options = options;\n    this.transientObservedNodes = [];\n  }\n  Registration.prototype = {\n    enqueue: function(record) {\n      var records = this.observer.records_;\n      var length = records.length;\n      if (records.length > 0) {\n        var lastRecord = records[length - 1];\n        var recordToReplaceLast = selectRecord(lastRecord, record);\n        if (recordToReplaceLast) {\n          records[length - 1] = recordToReplaceLast;\n          return;\n        }\n      } else {\n        scheduleCallback(this.observer);\n      }\n      records[length] = record;\n    },\n    addListeners: function() {\n      this.addListeners_(this.target);\n    },\n    addListeners_: function(node) {\n      var options = this.options;\n      if (options.attributes) node.addEventListener(\"DOMAttrModified\", this, true);\n      if (options.characterData) node.addEventListener(\"DOMCharacterDataModified\", this, true);\n      if (options.childList) node.addEventListener(\"DOMNodeInserted\", this, true);\n      if (options.childList || options.subtree) node.addEventListener(\"DOMNodeRemoved\", this, true);\n    },\n    removeListeners: function() {\n      this.removeListeners_(this.target);\n    },\n    removeListeners_: function(node) {\n      var options = this.options;\n      if (options.attributes) node.removeEventListener(\"DOMAttrModified\", this, true);\n      if (options.characterData) node.removeEventListener(\"DOMCharacterDataModified\", this, true);\n      if (options.childList) node.removeEventListener(\"DOMNodeInserted\", this, true);\n      if (options.childList || options.subtree) node.removeEventListener(\"DOMNodeRemoved\", this, true);\n    },\n    addTransientObserver: function(node) {\n      if (node === this.target) return;\n      this.addListeners_(node);\n      this.transientObservedNodes.push(node);\n      var registrations = registrationsTable.get(node);\n      if (!registrations) registrationsTable.set(node, registrations = []);\n      registrations.push(this);\n    },\n    removeTransientObservers: function() {\n      var transientObservedNodes = this.transientObservedNodes;\n      this.transientObservedNodes = [];\n      transientObservedNodes.forEach(function(node) {\n        this.removeListeners_(node);\n        var registrations = registrationsTable.get(node);\n        for (var i = 0; i < registrations.length; i++) {\n          if (registrations[i] === this) {\n            registrations.splice(i, 1);\n            break;\n          }\n        }\n      }, this);\n    },\n    handleEvent: function(e) {\n      e.stopImmediatePropagation();\n      switch (e.type) {\n       case \"DOMAttrModified\":\n        var name = e.attrName;\n        var namespace = e.relatedNode.namespaceURI;\n        var target = e.target;\n        var record = new getRecord(\"attributes\", target);\n        record.attributeName = name;\n        record.attributeNamespace = namespace;\n        var oldValue = e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;\n        forEachAncestorAndObserverEnqueueRecord(target, function(options) {\n          if (!options.attributes) return;\n          if (options.attributeFilter && options.attributeFilter.length && options.attributeFilter.indexOf(name) === -1 && options.attributeFilter.indexOf(namespace) === -1) {\n            return;\n          }\n          if (options.attributeOldValue) return getRecordWithOldValue(oldValue);\n          return record;\n        });\n        break;\n\n       case \"DOMCharacterDataModified\":\n        var target = e.target;\n        var record = getRecord(\"characterData\", target);\n        var oldValue = e.prevValue;\n        forEachAncestorAndObserverEnqueueRecord(target, function(options) {\n          if (!options.characterData) return;\n          if (options.characterDataOldValue) return getRecordWithOldValue(oldValue);\n          return record;\n        });\n        break;\n\n       case \"DOMNodeRemoved\":\n        this.addTransientObserver(e.target);\n\n       case \"DOMNodeInserted\":\n        var changedNode = e.target;\n        var addedNodes, removedNodes;\n        if (e.type === \"DOMNodeInserted\") {\n          addedNodes = [ changedNode ];\n          removedNodes = [];\n        } else {\n          addedNodes = [];\n          removedNodes = [ changedNode ];\n        }\n        var previousSibling = changedNode.previousSibling;\n        var nextSibling = changedNode.nextSibling;\n        var record = getRecord(\"childList\", e.target.parentNode);\n        record.addedNodes = addedNodes;\n        record.removedNodes = removedNodes;\n        record.previousSibling = previousSibling;\n        record.nextSibling = nextSibling;\n        forEachAncestorAndObserverEnqueueRecord(e.relatedNode, function(options) {\n          if (!options.childList) return;\n          return record;\n        });\n      }\n      clearRecords();\n    }\n  };\n  global.JsMutationObserver = JsMutationObserver;\n  if (!global.MutationObserver) global.MutationObserver = JsMutationObserver;\n})(this);\n\nwindow.CustomElements = window.CustomElements || {\n  flags: {}\n};\n\n(function(scope) {\n  var flags = scope.flags;\n  var modules = [];\n  var addModule = function(module) {\n    modules.push(module);\n  };\n  var initializeModules = function() {\n    modules.forEach(function(module) {\n      module(scope);\n    });\n  };\n  scope.addModule = addModule;\n  scope.initializeModules = initializeModules;\n  scope.hasNative = Boolean(document.registerElement);\n  scope.useNative = !flags.register && scope.hasNative && !window.ShadowDOMPolyfill && (!window.HTMLImports || window.HTMLImports.useNative);\n})(window.CustomElements);\n\nwindow.CustomElements.addModule(function(scope) {\n  var IMPORT_LINK_TYPE = window.HTMLImports ? window.HTMLImports.IMPORT_LINK_TYPE : \"none\";\n  function forSubtree(node, cb) {\n    findAllElements(node, function(e) {\n      if (cb(e)) {\n        return true;\n      }\n      forRoots(e, cb);\n    });\n    forRoots(node, cb);\n  }\n  function findAllElements(node, find, data) {\n    var e = node.firstElementChild;\n    if (!e) {\n      e = node.firstChild;\n      while (e && e.nodeType !== Node.ELEMENT_NODE) {\n        e = e.nextSibling;\n      }\n    }\n    while (e) {\n      if (find(e, data) !== true) {\n        findAllElements(e, find, data);\n      }\n      e = e.nextElementSibling;\n    }\n    return null;\n  }\n  function forRoots(node, cb) {\n    var root = node.shadowRoot;\n    while (root) {\n      forSubtree(root, cb);\n      root = root.olderShadowRoot;\n    }\n  }\n  function forDocumentTree(doc, cb) {\n    _forDocumentTree(doc, cb, []);\n  }\n  function _forDocumentTree(doc, cb, processingDocuments) {\n    doc = window.wrap(doc);\n    if (processingDocuments.indexOf(doc) >= 0) {\n      return;\n    }\n    processingDocuments.push(doc);\n    var imports = doc.querySelectorAll(\"link[rel=\" + IMPORT_LINK_TYPE + \"]\");\n    for (var i = 0, l = imports.length, n; i < l && (n = imports[i]); i++) {\n      if (n.import) {\n        _forDocumentTree(n.import, cb, processingDocuments);\n      }\n    }\n    cb(doc);\n  }\n  scope.forDocumentTree = forDocumentTree;\n  scope.forSubtree = forSubtree;\n});\n\nwindow.CustomElements.addModule(function(scope) {\n  var flags = scope.flags;\n  var forSubtree = scope.forSubtree;\n  var forDocumentTree = scope.forDocumentTree;\n  function addedNode(node, isAttached) {\n    return added(node, isAttached) || addedSubtree(node, isAttached);\n  }\n  function added(node, isAttached) {\n    if (scope.upgrade(node, isAttached)) {\n      return true;\n    }\n    if (isAttached) {\n      attached(node);\n    }\n  }\n  function addedSubtree(node, isAttached) {\n    forSubtree(node, function(e) {\n      if (added(e, isAttached)) {\n        return true;\n      }\n    });\n  }\n  var hasPolyfillMutations = !window.MutationObserver || window.MutationObserver === window.JsMutationObserver;\n  scope.hasPolyfillMutations = hasPolyfillMutations;\n  var isPendingMutations = false;\n  var pendingMutations = [];\n  function deferMutation(fn) {\n    pendingMutations.push(fn);\n    if (!isPendingMutations) {\n      isPendingMutations = true;\n      setTimeout(takeMutations);\n    }\n  }\n  function takeMutations() {\n    isPendingMutations = false;\n    var $p = pendingMutations;\n    for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {\n      p();\n    }\n    pendingMutations = [];\n  }\n  function attached(element) {\n    if (hasPolyfillMutations) {\n      deferMutation(function() {\n        _attached(element);\n      });\n    } else {\n      _attached(element);\n    }\n  }\n  function _attached(element) {\n    if (element.__upgraded__ && !element.__attached) {\n      element.__attached = true;\n      if (element.attachedCallback) {\n        element.attachedCallback();\n      }\n    }\n  }\n  function detachedNode(node) {\n    detached(node);\n    forSubtree(node, function(e) {\n      detached(e);\n    });\n  }\n  function detached(element) {\n    if (hasPolyfillMutations) {\n      deferMutation(function() {\n        _detached(element);\n      });\n    } else {\n      _detached(element);\n    }\n  }\n  function _detached(element) {\n    if (element.__upgraded__ && element.__attached) {\n      element.__attached = false;\n      if (element.detachedCallback) {\n        element.detachedCallback();\n      }\n    }\n  }\n  function inDocument(element) {\n    var p = element;\n    var doc = window.wrap(document);\n    while (p) {\n      if (p == doc) {\n        return true;\n      }\n      p = p.parentNode || p.nodeType === Node.DOCUMENT_FRAGMENT_NODE && p.host;\n    }\n  }\n  function watchShadow(node) {\n    if (node.shadowRoot && !node.shadowRoot.__watched) {\n      flags.dom && console.log(\"watching shadow-root for: \", node.localName);\n      var root = node.shadowRoot;\n      while (root) {\n        observe(root);\n        root = root.olderShadowRoot;\n      }\n    }\n  }\n  function handler(root, mutations) {\n    if (flags.dom) {\n      var mx = mutations[0];\n      if (mx && mx.type === \"childList\" && mx.addedNodes) {\n        if (mx.addedNodes) {\n          var d = mx.addedNodes[0];\n          while (d && d !== document && !d.host) {\n            d = d.parentNode;\n          }\n          var u = d && (d.URL || d._URL || d.host && d.host.localName) || \"\";\n          u = u.split(\"/?\").shift().split(\"/\").pop();\n        }\n      }\n      console.group(\"mutations (%d) [%s]\", mutations.length, u || \"\");\n    }\n    var isAttached = inDocument(root);\n    mutations.forEach(function(mx) {\n      if (mx.type === \"childList\") {\n        forEach(mx.addedNodes, function(n) {\n          if (!n.localName) {\n            return;\n          }\n          addedNode(n, isAttached);\n        });\n        forEach(mx.removedNodes, function(n) {\n          if (!n.localName) {\n            return;\n          }\n          detachedNode(n);\n        });\n      }\n    });\n    flags.dom && console.groupEnd();\n  }\n  function takeRecords(node) {\n    node = window.wrap(node);\n    if (!node) {\n      node = window.wrap(document);\n    }\n    while (node.parentNode) {\n      node = node.parentNode;\n    }\n    var observer = node.__observer;\n    if (observer) {\n      handler(node, observer.takeRecords());\n      takeMutations();\n    }\n  }\n  var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);\n  function observe(inRoot) {\n    if (inRoot.__observer) {\n      return;\n    }\n    var observer = new MutationObserver(handler.bind(this, inRoot));\n    observer.observe(inRoot, {\n      childList: true,\n      subtree: true\n    });\n    inRoot.__observer = observer;\n  }\n  function upgradeDocument(doc) {\n    doc = window.wrap(doc);\n    flags.dom && console.group(\"upgradeDocument: \", doc.baseURI.split(\"/\").pop());\n    var isMainDocument = doc === window.wrap(document);\n    addedNode(doc, isMainDocument);\n    observe(doc);\n    flags.dom && console.groupEnd();\n  }\n  function upgradeDocumentTree(doc) {\n    forDocumentTree(doc, upgradeDocument);\n  }\n  var originalCreateShadowRoot = Element.prototype.createShadowRoot;\n  if (originalCreateShadowRoot) {\n    Element.prototype.createShadowRoot = function() {\n      var root = originalCreateShadowRoot.call(this);\n      window.CustomElements.watchShadow(this);\n      return root;\n    };\n  }\n  scope.watchShadow = watchShadow;\n  scope.upgradeDocumentTree = upgradeDocumentTree;\n  scope.upgradeDocument = upgradeDocument;\n  scope.upgradeSubtree = addedSubtree;\n  scope.upgradeAll = addedNode;\n  scope.attached = attached;\n  scope.takeRecords = takeRecords;\n});\n\nwindow.CustomElements.addModule(function(scope) {\n  var flags = scope.flags;\n  function upgrade(node, isAttached) {\n    if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) {\n      var is = node.getAttribute(\"is\");\n      var definition = scope.getRegisteredDefinition(node.localName) || scope.getRegisteredDefinition(is);\n      if (definition) {\n        if (is && definition.tag == node.localName || !is && !definition.extends) {\n          return upgradeWithDefinition(node, definition, isAttached);\n        }\n      }\n    }\n  }\n  function upgradeWithDefinition(element, definition, isAttached) {\n    flags.upgrade && console.group(\"upgrade:\", element.localName);\n    if (definition.is) {\n      element.setAttribute(\"is\", definition.is);\n    }\n    implementPrototype(element, definition);\n    element.__upgraded__ = true;\n    created(element);\n    if (isAttached) {\n      scope.attached(element);\n    }\n    scope.upgradeSubtree(element, isAttached);\n    flags.upgrade && console.groupEnd();\n    return element;\n  }\n  function implementPrototype(element, definition) {\n    if (Object.__proto__) {\n      element.__proto__ = definition.prototype;\n    } else {\n      customMixin(element, definition.prototype, definition.native);\n      element.__proto__ = definition.prototype;\n    }\n  }\n  function customMixin(inTarget, inSrc, inNative) {\n    var used = {};\n    var p = inSrc;\n    while (p !== inNative && p !== HTMLElement.prototype) {\n      var keys = Object.getOwnPropertyNames(p);\n      for (var i = 0, k; k = keys[i]; i++) {\n        if (!used[k]) {\n          Object.defineProperty(inTarget, k, Object.getOwnPropertyDescriptor(p, k));\n          used[k] = 1;\n        }\n      }\n      p = Object.getPrototypeOf(p);\n    }\n  }\n  function created(element) {\n    if (element.createdCallback) {\n      element.createdCallback();\n    }\n  }\n  scope.upgrade = upgrade;\n  scope.upgradeWithDefinition = upgradeWithDefinition;\n  scope.implementPrototype = implementPrototype;\n});\n\nwindow.CustomElements.addModule(function(scope) {\n  var isIE11OrOlder = scope.isIE11OrOlder;\n  var upgradeDocumentTree = scope.upgradeDocumentTree;\n  var upgradeAll = scope.upgradeAll;\n  var upgradeWithDefinition = scope.upgradeWithDefinition;\n  var implementPrototype = scope.implementPrototype;\n  var useNative = scope.useNative;\n  function register(name, options) {\n    var definition = options || {};\n    if (!name) {\n      throw new Error(\"document.registerElement: first argument `name` must not be empty\");\n    }\n    if (name.indexOf(\"-\") < 0) {\n      throw new Error(\"document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '\" + String(name) + \"'.\");\n    }\n    if (isReservedTag(name)) {\n      throw new Error(\"Failed to execute 'registerElement' on 'Document': Registration failed for type '\" + String(name) + \"'. The type name is invalid.\");\n    }\n    if (getRegisteredDefinition(name)) {\n      throw new Error(\"DuplicateDefinitionError: a type with name '\" + String(name) + \"' is already registered\");\n    }\n    if (!definition.prototype) {\n      definition.prototype = Object.create(HTMLElement.prototype);\n    }\n    definition.__name = name.toLowerCase();\n    definition.lifecycle = definition.lifecycle || {};\n    definition.ancestry = ancestry(definition.extends);\n    resolveTagName(definition);\n    resolvePrototypeChain(definition);\n    overrideAttributeApi(definition.prototype);\n    registerDefinition(definition.__name, definition);\n    definition.ctor = generateConstructor(definition);\n    definition.ctor.prototype = definition.prototype;\n    definition.prototype.constructor = definition.ctor;\n    if (scope.ready) {\n      upgradeDocumentTree(document);\n    }\n    return definition.ctor;\n  }\n  function overrideAttributeApi(prototype) {\n    if (prototype.setAttribute._polyfilled) {\n      return;\n    }\n    var setAttribute = prototype.setAttribute;\n    prototype.setAttribute = function(name, value) {\n      changeAttribute.call(this, name, value, setAttribute);\n    };\n    var removeAttribute = prototype.removeAttribute;\n    prototype.removeAttribute = function(name) {\n      changeAttribute.call(this, name, null, removeAttribute);\n    };\n    prototype.setAttribute._polyfilled = true;\n  }\n  function changeAttribute(name, value, operation) {\n    name = name.toLowerCase();\n    var oldValue = this.getAttribute(name);\n    operation.apply(this, arguments);\n    var newValue = this.getAttribute(name);\n    if (this.attributeChangedCallback && newValue !== oldValue) {\n      this.attributeChangedCallback(name, oldValue, newValue);\n    }\n  }\n  function isReservedTag(name) {\n    for (var i = 0; i < reservedTagList.length; i++) {\n      if (name === reservedTagList[i]) {\n        return true;\n      }\n    }\n  }\n  var reservedTagList = [ \"annotation-xml\", \"color-profile\", \"font-face\", \"font-face-src\", \"font-face-uri\", \"font-face-format\", \"font-face-name\", \"missing-glyph\" ];\n  function ancestry(extnds) {\n    var extendee = getRegisteredDefinition(extnds);\n    if (extendee) {\n      return ancestry(extendee.extends).concat([ extendee ]);\n    }\n    return [];\n  }\n  function resolveTagName(definition) {\n    var baseTag = definition.extends;\n    for (var i = 0, a; a = definition.ancestry[i]; i++) {\n      baseTag = a.is && a.tag;\n    }\n    definition.tag = baseTag || definition.__name;\n    if (baseTag) {\n      definition.is = definition.__name;\n    }\n  }\n  function resolvePrototypeChain(definition) {\n    if (!Object.__proto__) {\n      var nativePrototype = HTMLElement.prototype;\n      if (definition.is) {\n        var inst = document.createElement(definition.tag);\n        nativePrototype = Object.getPrototypeOf(inst);\n      }\n      var proto = definition.prototype, ancestor;\n      var foundPrototype = false;\n      while (proto) {\n        if (proto == nativePrototype) {\n          foundPrototype = true;\n        }\n        ancestor = Object.getPrototypeOf(proto);\n        if (ancestor) {\n          proto.__proto__ = ancestor;\n        }\n        proto = ancestor;\n      }\n      if (!foundPrototype) {\n        console.warn(definition.tag + \" prototype not found in prototype chain for \" + definition.is);\n      }\n      definition.native = nativePrototype;\n    }\n  }\n  function instantiate(definition) {\n    return upgradeWithDefinition(domCreateElement(definition.tag), definition);\n  }\n  var registry = {};\n  function getRegisteredDefinition(name) {\n    if (name) {\n      return registry[name.toLowerCase()];\n    }\n  }\n  function registerDefinition(name, definition) {\n    registry[name] = definition;\n  }\n  function generateConstructor(definition) {\n    return function() {\n      return instantiate(definition);\n    };\n  }\n  var HTML_NAMESPACE = \"http://www.w3.org/1999/xhtml\";\n  function createElementNS(namespace, tag, typeExtension) {\n    if (namespace === HTML_NAMESPACE) {\n      return createElement(tag, typeExtension);\n    } else {\n      return domCreateElementNS(namespace, tag);\n    }\n  }\n  function createElement(tag, typeExtension) {\n    if (tag) {\n      tag = tag.toLowerCase();\n    }\n    if (typeExtension) {\n      typeExtension = typeExtension.toLowerCase();\n    }\n    var definition = getRegisteredDefinition(typeExtension || tag);\n    if (definition) {\n      if (tag == definition.tag && typeExtension == definition.is) {\n        return new definition.ctor();\n      }\n      if (!typeExtension && !definition.is) {\n        return new definition.ctor();\n      }\n    }\n    var element;\n    if (typeExtension) {\n      element = createElement(tag);\n      element.setAttribute(\"is\", typeExtension);\n      return element;\n    }\n    element = domCreateElement(tag);\n    if (tag.indexOf(\"-\") >= 0) {\n      implementPrototype(element, HTMLElement);\n    }\n    return element;\n  }\n  var domCreateElement = document.createElement.bind(document);\n  var domCreateElementNS = document.createElementNS.bind(document);\n  var isInstance;\n  if (!Object.__proto__ && !useNative) {\n    isInstance = function(obj, ctor) {\n      if (obj instanceof ctor) {\n        return true;\n      }\n      var p = obj;\n      while (p) {\n        if (p === ctor.prototype) {\n          return true;\n        }\n        p = p.__proto__;\n      }\n      return false;\n    };\n  } else {\n    isInstance = function(obj, base) {\n      return obj instanceof base;\n    };\n  }\n  function wrapDomMethodToForceUpgrade(obj, methodName) {\n    var orig = obj[methodName];\n    obj[methodName] = function() {\n      var n = orig.apply(this, arguments);\n      upgradeAll(n);\n      return n;\n    };\n  }\n  wrapDomMethodToForceUpgrade(Node.prototype, \"cloneNode\");\n  wrapDomMethodToForceUpgrade(document, \"importNode\");\n  if (isIE11OrOlder) {\n    (function() {\n      var importNode = document.importNode;\n      document.importNode = function() {\n        var n = importNode.apply(document, arguments);\n        if (n.nodeType == n.DOCUMENT_FRAGMENT_NODE) {\n          var f = document.createDocumentFragment();\n          f.appendChild(n);\n          return f;\n        } else {\n          return n;\n        }\n      };\n    })();\n  }\n  document.registerElement = register;\n  document.createElement = createElement;\n  document.createElementNS = createElementNS;\n  scope.registry = registry;\n  scope.instanceof = isInstance;\n  scope.reservedTagList = reservedTagList;\n  scope.getRegisteredDefinition = getRegisteredDefinition;\n  document.register = document.registerElement;\n});\n\n(function(scope) {\n  var useNative = scope.useNative;\n  var initializeModules = scope.initializeModules;\n  var isIE11OrOlder = /Trident/.test(navigator.userAgent);\n  if (useNative) {\n    var nop = function() {};\n    scope.watchShadow = nop;\n    scope.upgrade = nop;\n    scope.upgradeAll = nop;\n    scope.upgradeDocumentTree = nop;\n    scope.upgradeSubtree = nop;\n    scope.takeRecords = nop;\n    scope.instanceof = function(obj, base) {\n      return obj instanceof base;\n    };\n  } else {\n    initializeModules();\n  }\n  var upgradeDocumentTree = scope.upgradeDocumentTree;\n  var upgradeDocument = scope.upgradeDocument;\n  if (!window.wrap) {\n    if (window.ShadowDOMPolyfill) {\n      window.wrap = window.ShadowDOMPolyfill.wrapIfNeeded;\n      window.unwrap = window.ShadowDOMPolyfill.unwrapIfNeeded;\n    } else {\n      window.wrap = window.unwrap = function(node) {\n        return node;\n      };\n    }\n  }\n  if (window.HTMLImports) {\n    window.HTMLImports.__importsParsingHook = function(elt) {\n      if (elt.import) {\n        upgradeDocument(wrap(elt.import));\n      }\n    };\n  }\n  function bootstrap() {\n    upgradeDocumentTree(window.wrap(document));\n    window.CustomElements.ready = true;\n    requestAnimationFrame(function() {\n      setTimeout(function() {\n        window.CustomElements.readyTime = Date.now();\n        if (window.HTMLImports) {\n          window.CustomElements.elapsed = window.CustomElements.readyTime - window.HTMLImports.readyTime;\n        }\n        document.dispatchEvent(new CustomEvent(\"WebComponentsReady\", {\n          bubbles: true\n        }));\n      });\n    });\n  }\n  if (isIE11OrOlder && typeof window.CustomEvent !== \"function\") {\n    window.CustomEvent = function(inType, params) {\n      params = params || {};\n      var e = document.createEvent(\"CustomEvent\");\n      e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);\n      e.preventDefault = function() {\n        Object.defineProperty(this, \"defaultPrevented\", {\n          get: function() {\n            return true;\n          }\n        });\n      };\n      return e;\n    };\n    window.CustomEvent.prototype = window.Event.prototype;\n  }\n  if (document.readyState === \"complete\" || scope.flags.eager) {\n    bootstrap();\n  } else if (document.readyState === \"interactive\" && !window.attachEvent && (!window.HTMLImports || window.HTMLImports.ready)) {\n    bootstrap();\n  } else {\n    var loadEvent = window.HTMLImports && !window.HTMLImports.ready ? \"HTMLImportsLoaded\" : \"DOMContentLoaded\";\n    window.addEventListener(loadEvent, bootstrap);\n  }\n  scope.isIE11OrOlder = isIE11OrOlder;\n})(window.CustomElements);"
  },
  {
    "path": "cmd/memlat/static/bower_components/webcomponentsjs/HTMLImports.js",
    "content": "/**\n * @license\n * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n */\n// @version 0.7.11\nif (typeof WeakMap === \"undefined\") {\n  (function() {\n    var defineProperty = Object.defineProperty;\n    var counter = Date.now() % 1e9;\n    var WeakMap = function() {\n      this.name = \"__st\" + (Math.random() * 1e9 >>> 0) + (counter++ + \"__\");\n    };\n    WeakMap.prototype = {\n      set: function(key, value) {\n        var entry = key[this.name];\n        if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {\n          value: [ key, value ],\n          writable: true\n        });\n        return this;\n      },\n      get: function(key) {\n        var entry;\n        return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;\n      },\n      \"delete\": function(key) {\n        var entry = key[this.name];\n        if (!entry || entry[0] !== key) return false;\n        entry[0] = entry[1] = undefined;\n        return true;\n      },\n      has: function(key) {\n        var entry = key[this.name];\n        if (!entry) return false;\n        return entry[0] === key;\n      }\n    };\n    window.WeakMap = WeakMap;\n  })();\n}\n\n(function(global) {\n  var registrationsTable = new WeakMap();\n  var setImmediate;\n  if (/Trident|Edge/.test(navigator.userAgent)) {\n    setImmediate = setTimeout;\n  } else if (window.setImmediate) {\n    setImmediate = window.setImmediate;\n  } else {\n    var setImmediateQueue = [];\n    var sentinel = String(Math.random());\n    window.addEventListener(\"message\", function(e) {\n      if (e.data === sentinel) {\n        var queue = setImmediateQueue;\n        setImmediateQueue = [];\n        queue.forEach(function(func) {\n          func();\n        });\n      }\n    });\n    setImmediate = function(func) {\n      setImmediateQueue.push(func);\n      window.postMessage(sentinel, \"*\");\n    };\n  }\n  var isScheduled = false;\n  var scheduledObservers = [];\n  function scheduleCallback(observer) {\n    scheduledObservers.push(observer);\n    if (!isScheduled) {\n      isScheduled = true;\n      setImmediate(dispatchCallbacks);\n    }\n  }\n  function wrapIfNeeded(node) {\n    return window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrapIfNeeded(node) || node;\n  }\n  function dispatchCallbacks() {\n    isScheduled = false;\n    var observers = scheduledObservers;\n    scheduledObservers = [];\n    observers.sort(function(o1, o2) {\n      return o1.uid_ - o2.uid_;\n    });\n    var anyNonEmpty = false;\n    observers.forEach(function(observer) {\n      var queue = observer.takeRecords();\n      removeTransientObserversFor(observer);\n      if (queue.length) {\n        observer.callback_(queue, observer);\n        anyNonEmpty = true;\n      }\n    });\n    if (anyNonEmpty) dispatchCallbacks();\n  }\n  function removeTransientObserversFor(observer) {\n    observer.nodes_.forEach(function(node) {\n      var registrations = registrationsTable.get(node);\n      if (!registrations) return;\n      registrations.forEach(function(registration) {\n        if (registration.observer === observer) registration.removeTransientObservers();\n      });\n    });\n  }\n  function forEachAncestorAndObserverEnqueueRecord(target, callback) {\n    for (var node = target; node; node = node.parentNode) {\n      var registrations = registrationsTable.get(node);\n      if (registrations) {\n        for (var j = 0; j < registrations.length; j++) {\n          var registration = registrations[j];\n          var options = registration.options;\n          if (node !== target && !options.subtree) continue;\n          var record = callback(options);\n          if (record) registration.enqueue(record);\n        }\n      }\n    }\n  }\n  var uidCounter = 0;\n  function JsMutationObserver(callback) {\n    this.callback_ = callback;\n    this.nodes_ = [];\n    this.records_ = [];\n    this.uid_ = ++uidCounter;\n  }\n  JsMutationObserver.prototype = {\n    observe: function(target, options) {\n      target = wrapIfNeeded(target);\n      if (!options.childList && !options.attributes && !options.characterData || options.attributeOldValue && !options.attributes || options.attributeFilter && options.attributeFilter.length && !options.attributes || options.characterDataOldValue && !options.characterData) {\n        throw new SyntaxError();\n      }\n      var registrations = registrationsTable.get(target);\n      if (!registrations) registrationsTable.set(target, registrations = []);\n      var registration;\n      for (var i = 0; i < registrations.length; i++) {\n        if (registrations[i].observer === this) {\n          registration = registrations[i];\n          registration.removeListeners();\n          registration.options = options;\n          break;\n        }\n      }\n      if (!registration) {\n        registration = new Registration(this, target, options);\n        registrations.push(registration);\n        this.nodes_.push(target);\n      }\n      registration.addListeners();\n    },\n    disconnect: function() {\n      this.nodes_.forEach(function(node) {\n        var registrations = registrationsTable.get(node);\n        for (var i = 0; i < registrations.length; i++) {\n          var registration = registrations[i];\n          if (registration.observer === this) {\n            registration.removeListeners();\n            registrations.splice(i, 1);\n            break;\n          }\n        }\n      }, this);\n      this.records_ = [];\n    },\n    takeRecords: function() {\n      var copyOfRecords = this.records_;\n      this.records_ = [];\n      return copyOfRecords;\n    }\n  };\n  function MutationRecord(type, target) {\n    this.type = type;\n    this.target = target;\n    this.addedNodes = [];\n    this.removedNodes = [];\n    this.previousSibling = null;\n    this.nextSibling = null;\n    this.attributeName = null;\n    this.attributeNamespace = null;\n    this.oldValue = null;\n  }\n  function copyMutationRecord(original) {\n    var record = new MutationRecord(original.type, original.target);\n    record.addedNodes = original.addedNodes.slice();\n    record.removedNodes = original.removedNodes.slice();\n    record.previousSibling = original.previousSibling;\n    record.nextSibling = original.nextSibling;\n    record.attributeName = original.attributeName;\n    record.attributeNamespace = original.attributeNamespace;\n    record.oldValue = original.oldValue;\n    return record;\n  }\n  var currentRecord, recordWithOldValue;\n  function getRecord(type, target) {\n    return currentRecord = new MutationRecord(type, target);\n  }\n  function getRecordWithOldValue(oldValue) {\n    if (recordWithOldValue) return recordWithOldValue;\n    recordWithOldValue = copyMutationRecord(currentRecord);\n    recordWithOldValue.oldValue = oldValue;\n    return recordWithOldValue;\n  }\n  function clearRecords() {\n    currentRecord = recordWithOldValue = undefined;\n  }\n  function recordRepresentsCurrentMutation(record) {\n    return record === recordWithOldValue || record === currentRecord;\n  }\n  function selectRecord(lastRecord, newRecord) {\n    if (lastRecord === newRecord) return lastRecord;\n    if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord)) return recordWithOldValue;\n    return null;\n  }\n  function Registration(observer, target, options) {\n    this.observer = observer;\n    this.target = target;\n    this.options = options;\n    this.transientObservedNodes = [];\n  }\n  Registration.prototype = {\n    enqueue: function(record) {\n      var records = this.observer.records_;\n      var length = records.length;\n      if (records.length > 0) {\n        var lastRecord = records[length - 1];\n        var recordToReplaceLast = selectRecord(lastRecord, record);\n        if (recordToReplaceLast) {\n          records[length - 1] = recordToReplaceLast;\n          return;\n        }\n      } else {\n        scheduleCallback(this.observer);\n      }\n      records[length] = record;\n    },\n    addListeners: function() {\n      this.addListeners_(this.target);\n    },\n    addListeners_: function(node) {\n      var options = this.options;\n      if (options.attributes) node.addEventListener(\"DOMAttrModified\", this, true);\n      if (options.characterData) node.addEventListener(\"DOMCharacterDataModified\", this, true);\n      if (options.childList) node.addEventListener(\"DOMNodeInserted\", this, true);\n      if (options.childList || options.subtree) node.addEventListener(\"DOMNodeRemoved\", this, true);\n    },\n    removeListeners: function() {\n      this.removeListeners_(this.target);\n    },\n    removeListeners_: function(node) {\n      var options = this.options;\n      if (options.attributes) node.removeEventListener(\"DOMAttrModified\", this, true);\n      if (options.characterData) node.removeEventListener(\"DOMCharacterDataModified\", this, true);\n      if (options.childList) node.removeEventListener(\"DOMNodeInserted\", this, true);\n      if (options.childList || options.subtree) node.removeEventListener(\"DOMNodeRemoved\", this, true);\n    },\n    addTransientObserver: function(node) {\n      if (node === this.target) return;\n      this.addListeners_(node);\n      this.transientObservedNodes.push(node);\n      var registrations = registrationsTable.get(node);\n      if (!registrations) registrationsTable.set(node, registrations = []);\n      registrations.push(this);\n    },\n    removeTransientObservers: function() {\n      var transientObservedNodes = this.transientObservedNodes;\n      this.transientObservedNodes = [];\n      transientObservedNodes.forEach(function(node) {\n        this.removeListeners_(node);\n        var registrations = registrationsTable.get(node);\n        for (var i = 0; i < registrations.length; i++) {\n          if (registrations[i] === this) {\n            registrations.splice(i, 1);\n            break;\n          }\n        }\n      }, this);\n    },\n    handleEvent: function(e) {\n      e.stopImmediatePropagation();\n      switch (e.type) {\n       case \"DOMAttrModified\":\n        var name = e.attrName;\n        var namespace = e.relatedNode.namespaceURI;\n        var target = e.target;\n        var record = new getRecord(\"attributes\", target);\n        record.attributeName = name;\n        record.attributeNamespace = namespace;\n        var oldValue = e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;\n        forEachAncestorAndObserverEnqueueRecord(target, function(options) {\n          if (!options.attributes) return;\n          if (options.attributeFilter && options.attributeFilter.length && options.attributeFilter.indexOf(name) === -1 && options.attributeFilter.indexOf(namespace) === -1) {\n            return;\n          }\n          if (options.attributeOldValue) return getRecordWithOldValue(oldValue);\n          return record;\n        });\n        break;\n\n       case \"DOMCharacterDataModified\":\n        var target = e.target;\n        var record = getRecord(\"characterData\", target);\n        var oldValue = e.prevValue;\n        forEachAncestorAndObserverEnqueueRecord(target, function(options) {\n          if (!options.characterData) return;\n          if (options.characterDataOldValue) return getRecordWithOldValue(oldValue);\n          return record;\n        });\n        break;\n\n       case \"DOMNodeRemoved\":\n        this.addTransientObserver(e.target);\n\n       case \"DOMNodeInserted\":\n        var changedNode = e.target;\n        var addedNodes, removedNodes;\n        if (e.type === \"DOMNodeInserted\") {\n          addedNodes = [ changedNode ];\n          removedNodes = [];\n        } else {\n          addedNodes = [];\n          removedNodes = [ changedNode ];\n        }\n        var previousSibling = changedNode.previousSibling;\n        var nextSibling = changedNode.nextSibling;\n        var record = getRecord(\"childList\", e.target.parentNode);\n        record.addedNodes = addedNodes;\n        record.removedNodes = removedNodes;\n        record.previousSibling = previousSibling;\n        record.nextSibling = nextSibling;\n        forEachAncestorAndObserverEnqueueRecord(e.relatedNode, function(options) {\n          if (!options.childList) return;\n          return record;\n        });\n      }\n      clearRecords();\n    }\n  };\n  global.JsMutationObserver = JsMutationObserver;\n  if (!global.MutationObserver) global.MutationObserver = JsMutationObserver;\n})(this);\n\nwindow.HTMLImports = window.HTMLImports || {\n  flags: {}\n};\n\n(function(scope) {\n  var IMPORT_LINK_TYPE = \"import\";\n  var useNative = Boolean(IMPORT_LINK_TYPE in document.createElement(\"link\"));\n  var hasShadowDOMPolyfill = Boolean(window.ShadowDOMPolyfill);\n  var wrap = function(node) {\n    return hasShadowDOMPolyfill ? window.ShadowDOMPolyfill.wrapIfNeeded(node) : node;\n  };\n  var rootDocument = wrap(document);\n  var currentScriptDescriptor = {\n    get: function() {\n      var script = window.HTMLImports.currentScript || document.currentScript || (document.readyState !== \"complete\" ? document.scripts[document.scripts.length - 1] : null);\n      return wrap(script);\n    },\n    configurable: true\n  };\n  Object.defineProperty(document, \"_currentScript\", currentScriptDescriptor);\n  Object.defineProperty(rootDocument, \"_currentScript\", currentScriptDescriptor);\n  var isIE = /Trident/.test(navigator.userAgent);\n  function whenReady(callback, doc) {\n    doc = doc || rootDocument;\n    whenDocumentReady(function() {\n      watchImportsLoad(callback, doc);\n    }, doc);\n  }\n  var requiredReadyState = isIE ? \"complete\" : \"interactive\";\n  var READY_EVENT = \"readystatechange\";\n  function isDocumentReady(doc) {\n    return doc.readyState === \"complete\" || doc.readyState === requiredReadyState;\n  }\n  function whenDocumentReady(callback, doc) {\n    if (!isDocumentReady(doc)) {\n      var checkReady = function() {\n        if (doc.readyState === \"complete\" || doc.readyState === requiredReadyState) {\n          doc.removeEventListener(READY_EVENT, checkReady);\n          whenDocumentReady(callback, doc);\n        }\n      };\n      doc.addEventListener(READY_EVENT, checkReady);\n    } else if (callback) {\n      callback();\n    }\n  }\n  function markTargetLoaded(event) {\n    event.target.__loaded = true;\n  }\n  function watchImportsLoad(callback, doc) {\n    var imports = doc.querySelectorAll(\"link[rel=import]\");\n    var parsedCount = 0, importCount = imports.length, newImports = [], errorImports = [];\n    function checkDone() {\n      if (parsedCount == importCount && callback) {\n        callback({\n          allImports: imports,\n          loadedImports: newImports,\n          errorImports: errorImports\n        });\n      }\n    }\n    function loadedImport(e) {\n      markTargetLoaded(e);\n      newImports.push(this);\n      parsedCount++;\n      checkDone();\n    }\n    function errorLoadingImport(e) {\n      errorImports.push(this);\n      parsedCount++;\n      checkDone();\n    }\n    if (importCount) {\n      for (var i = 0, imp; i < importCount && (imp = imports[i]); i++) {\n        if (isImportLoaded(imp)) {\n          parsedCount++;\n          checkDone();\n        } else {\n          imp.addEventListener(\"load\", loadedImport);\n          imp.addEventListener(\"error\", errorLoadingImport);\n        }\n      }\n    } else {\n      checkDone();\n    }\n  }\n  function isImportLoaded(link) {\n    return useNative ? link.__loaded || link.import && link.import.readyState !== \"loading\" : link.__importParsed;\n  }\n  if (useNative) {\n    new MutationObserver(function(mxns) {\n      for (var i = 0, l = mxns.length, m; i < l && (m = mxns[i]); i++) {\n        if (m.addedNodes) {\n          handleImports(m.addedNodes);\n        }\n      }\n    }).observe(document.head, {\n      childList: true\n    });\n    function handleImports(nodes) {\n      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {\n        if (isImport(n)) {\n          handleImport(n);\n        }\n      }\n    }\n    function isImport(element) {\n      return element.localName === \"link\" && element.rel === \"import\";\n    }\n    function handleImport(element) {\n      var loaded = element.import;\n      if (loaded) {\n        markTargetLoaded({\n          target: element\n        });\n      } else {\n        element.addEventListener(\"load\", markTargetLoaded);\n        element.addEventListener(\"error\", markTargetLoaded);\n      }\n    }\n    (function() {\n      if (document.readyState === \"loading\") {\n        var imports = document.querySelectorAll(\"link[rel=import]\");\n        for (var i = 0, l = imports.length, imp; i < l && (imp = imports[i]); i++) {\n          handleImport(imp);\n        }\n      }\n    })();\n  }\n  whenReady(function(detail) {\n    window.HTMLImports.ready = true;\n    window.HTMLImports.readyTime = new Date().getTime();\n    var evt = rootDocument.createEvent(\"CustomEvent\");\n    evt.initCustomEvent(\"HTMLImportsLoaded\", true, true, detail);\n    rootDocument.dispatchEvent(evt);\n  });\n  scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;\n  scope.useNative = useNative;\n  scope.rootDocument = rootDocument;\n  scope.whenReady = whenReady;\n  scope.isIE = isIE;\n})(window.HTMLImports);\n\n(function(scope) {\n  var modules = [];\n  var addModule = function(module) {\n    modules.push(module);\n  };\n  var initializeModules = function() {\n    modules.forEach(function(module) {\n      module(scope);\n    });\n  };\n  scope.addModule = addModule;\n  scope.initializeModules = initializeModules;\n})(window.HTMLImports);\n\nwindow.HTMLImports.addModule(function(scope) {\n  var CSS_URL_REGEXP = /(url\\()([^)]*)(\\))/g;\n  var CSS_IMPORT_REGEXP = /(@import[\\s]+(?!url\\())([^;]*)(;)/g;\n  var path = {\n    resolveUrlsInStyle: function(style, linkUrl) {\n      var doc = style.ownerDocument;\n      var resolver = doc.createElement(\"a\");\n      style.textContent = this.resolveUrlsInCssText(style.textContent, linkUrl, resolver);\n      return style;\n    },\n    resolveUrlsInCssText: function(cssText, linkUrl, urlObj) {\n      var r = this.replaceUrls(cssText, urlObj, linkUrl, CSS_URL_REGEXP);\n      r = this.replaceUrls(r, urlObj, linkUrl, CSS_IMPORT_REGEXP);\n      return r;\n    },\n    replaceUrls: function(text, urlObj, linkUrl, regexp) {\n      return text.replace(regexp, function(m, pre, url, post) {\n        var urlPath = url.replace(/[\"']/g, \"\");\n        if (linkUrl) {\n          urlPath = new URL(urlPath, linkUrl).href;\n        }\n        urlObj.href = urlPath;\n        urlPath = urlObj.href;\n        return pre + \"'\" + urlPath + \"'\" + post;\n      });\n    }\n  };\n  scope.path = path;\n});\n\nwindow.HTMLImports.addModule(function(scope) {\n  var xhr = {\n    async: true,\n    ok: function(request) {\n      return request.status >= 200 && request.status < 300 || request.status === 304 || request.status === 0;\n    },\n    load: function(url, next, nextContext) {\n      var request = new XMLHttpRequest();\n      if (scope.flags.debug || scope.flags.bust) {\n        url += \"?\" + Math.random();\n      }\n      request.open(\"GET\", url, xhr.async);\n      request.addEventListener(\"readystatechange\", function(e) {\n        if (request.readyState === 4) {\n          var locationHeader = request.getResponseHeader(\"Location\");\n          var redirectedUrl = null;\n          if (locationHeader) {\n            var redirectedUrl = locationHeader.substr(0, 1) === \"/\" ? location.origin + locationHeader : locationHeader;\n          }\n          next.call(nextContext, !xhr.ok(request) && request, request.response || request.responseText, redirectedUrl);\n        }\n      });\n      request.send();\n      return request;\n    },\n    loadDocument: function(url, next, nextContext) {\n      this.load(url, next, nextContext).responseType = \"document\";\n    }\n  };\n  scope.xhr = xhr;\n});\n\nwindow.HTMLImports.addModule(function(scope) {\n  var xhr = scope.xhr;\n  var flags = scope.flags;\n  var Loader = function(onLoad, onComplete) {\n    this.cache = {};\n    this.onload = onLoad;\n    this.oncomplete = onComplete;\n    this.inflight = 0;\n    this.pending = {};\n  };\n  Loader.prototype = {\n    addNodes: function(nodes) {\n      this.inflight += nodes.length;\n      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {\n        this.require(n);\n      }\n      this.checkDone();\n    },\n    addNode: function(node) {\n      this.inflight++;\n      this.require(node);\n      this.checkDone();\n    },\n    require: function(elt) {\n      var url = elt.src || elt.href;\n      elt.__nodeUrl = url;\n      if (!this.dedupe(url, elt)) {\n        this.fetch(url, elt);\n      }\n    },\n    dedupe: function(url, elt) {\n      if (this.pending[url]) {\n        this.pending[url].push(elt);\n        return true;\n      }\n      var resource;\n      if (this.cache[url]) {\n        this.onload(url, elt, this.cache[url]);\n        this.tail();\n        return true;\n      }\n      this.pending[url] = [ elt ];\n      return false;\n    },\n    fetch: function(url, elt) {\n      flags.load && console.log(\"fetch\", url, elt);\n      if (!url) {\n        setTimeout(function() {\n          this.receive(url, elt, {\n            error: \"href must be specified\"\n          }, null);\n        }.bind(this), 0);\n      } else if (url.match(/^data:/)) {\n        var pieces = url.split(\",\");\n        var header = pieces[0];\n        var body = pieces[1];\n        if (header.indexOf(\";base64\") > -1) {\n          body = atob(body);\n        } else {\n          body = decodeURIComponent(body);\n        }\n        setTimeout(function() {\n          this.receive(url, elt, null, body);\n        }.bind(this), 0);\n      } else {\n        var receiveXhr = function(err, resource, redirectedUrl) {\n          this.receive(url, elt, err, resource, redirectedUrl);\n        }.bind(this);\n        xhr.load(url, receiveXhr);\n      }\n    },\n    receive: function(url, elt, err, resource, redirectedUrl) {\n      this.cache[url] = resource;\n      var $p = this.pending[url];\n      for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {\n        this.onload(url, p, resource, err, redirectedUrl);\n        this.tail();\n      }\n      this.pending[url] = null;\n    },\n    tail: function() {\n      --this.inflight;\n      this.checkDone();\n    },\n    checkDone: function() {\n      if (!this.inflight) {\n        this.oncomplete();\n      }\n    }\n  };\n  scope.Loader = Loader;\n});\n\nwindow.HTMLImports.addModule(function(scope) {\n  var Observer = function(addCallback) {\n    this.addCallback = addCallback;\n    this.mo = new MutationObserver(this.handler.bind(this));\n  };\n  Observer.prototype = {\n    handler: function(mutations) {\n      for (var i = 0, l = mutations.length, m; i < l && (m = mutations[i]); i++) {\n        if (m.type === \"childList\" && m.addedNodes.length) {\n          this.addedNodes(m.addedNodes);\n        }\n      }\n    },\n    addedNodes: function(nodes) {\n      if (this.addCallback) {\n        this.addCallback(nodes);\n      }\n      for (var i = 0, l = nodes.length, n, loading; i < l && (n = nodes[i]); i++) {\n        if (n.children && n.children.length) {\n          this.addedNodes(n.children);\n        }\n      }\n    },\n    observe: function(root) {\n      this.mo.observe(root, {\n        childList: true,\n        subtree: true\n      });\n    }\n  };\n  scope.Observer = Observer;\n});\n\nwindow.HTMLImports.addModule(function(scope) {\n  var path = scope.path;\n  var rootDocument = scope.rootDocument;\n  var flags = scope.flags;\n  var isIE = scope.isIE;\n  var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;\n  var IMPORT_SELECTOR = \"link[rel=\" + IMPORT_LINK_TYPE + \"]\";\n  var importParser = {\n    documentSelectors: IMPORT_SELECTOR,\n    importsSelectors: [ IMPORT_SELECTOR, \"link[rel=stylesheet]:not([type])\", \"style:not([type])\", \"script:not([type])\", 'script[type=\"application/javascript\"]', 'script[type=\"text/javascript\"]' ].join(\",\"),\n    map: {\n      link: \"parseLink\",\n      script: \"parseScript\",\n      style: \"parseStyle\"\n    },\n    dynamicElements: [],\n    parseNext: function() {\n      var next = this.nextToParse();\n      if (next) {\n        this.parse(next);\n      }\n    },\n    parse: function(elt) {\n      if (this.isParsed(elt)) {\n        flags.parse && console.log(\"[%s] is already parsed\", elt.localName);\n        return;\n      }\n      var fn = this[this.map[elt.localName]];\n      if (fn) {\n        this.markParsing(elt);\n        fn.call(this, elt);\n      }\n    },\n    parseDynamic: function(elt, quiet) {\n      this.dynamicElements.push(elt);\n      if (!quiet) {\n        this.parseNext();\n      }\n    },\n    markParsing: function(elt) {\n      flags.parse && console.log(\"parsing\", elt);\n      this.parsingElement = elt;\n    },\n    markParsingComplete: function(elt) {\n      elt.__importParsed = true;\n      this.markDynamicParsingComplete(elt);\n      if (elt.__importElement) {\n        elt.__importElement.__importParsed = true;\n        this.markDynamicParsingComplete(elt.__importElement);\n      }\n      this.parsingElement = null;\n      flags.parse && console.log(\"completed\", elt);\n    },\n    markDynamicParsingComplete: function(elt) {\n      var i = this.dynamicElements.indexOf(elt);\n      if (i >= 0) {\n        this.dynamicElements.splice(i, 1);\n      }\n    },\n    parseImport: function(elt) {\n      elt.import = elt.__doc;\n      if (window.HTMLImports.__importsParsingHook) {\n        window.HTMLImports.__importsParsingHook(elt);\n      }\n      if (elt.import) {\n        elt.import.__importParsed = true;\n      }\n      this.markParsingComplete(elt);\n      if (elt.__resource && !elt.__error) {\n        elt.dispatchEvent(new CustomEvent(\"load\", {\n          bubbles: false\n        }));\n      } else {\n        elt.dispatchEvent(new CustomEvent(\"error\", {\n          bubbles: false\n        }));\n      }\n      if (elt.__pending) {\n        var fn;\n        while (elt.__pending.length) {\n          fn = elt.__pending.shift();\n          if (fn) {\n            fn({\n              target: elt\n            });\n          }\n        }\n      }\n      this.parseNext();\n    },\n    parseLink: function(linkElt) {\n      if (nodeIsImport(linkElt)) {\n        this.parseImport(linkElt);\n      } else {\n        linkElt.href = linkElt.href;\n        this.parseGeneric(linkElt);\n      }\n    },\n    parseStyle: function(elt) {\n      var src = elt;\n      elt = cloneStyle(elt);\n      src.__appliedElement = elt;\n      elt.__importElement = src;\n      this.parseGeneric(elt);\n    },\n    parseGeneric: function(elt) {\n      this.trackElement(elt);\n      this.addElementToDocument(elt);\n    },\n    rootImportForElement: function(elt) {\n      var n = elt;\n      while (n.ownerDocument.__importLink) {\n        n = n.ownerDocument.__importLink;\n      }\n      return n;\n    },\n    addElementToDocument: function(elt) {\n      var port = this.rootImportForElement(elt.__importElement || elt);\n      port.parentNode.insertBefore(elt, port);\n    },\n    trackElement: function(elt, callback) {\n      var self = this;\n      var done = function(e) {\n        elt.removeEventListener(\"load\", done);\n        elt.removeEventListener(\"error\", done);\n        if (callback) {\n          callback(e);\n        }\n        self.markParsingComplete(elt);\n        self.parseNext();\n      };\n      elt.addEventListener(\"load\", done);\n      elt.addEventListener(\"error\", done);\n      if (isIE && elt.localName === \"style\") {\n        var fakeLoad = false;\n        if (elt.textContent.indexOf(\"@import\") == -1) {\n          fakeLoad = true;\n        } else if (elt.sheet) {\n          fakeLoad = true;\n          var csr = elt.sheet.cssRules;\n          var len = csr ? csr.length : 0;\n          for (var i = 0, r; i < len && (r = csr[i]); i++) {\n            if (r.type === CSSRule.IMPORT_RULE) {\n              fakeLoad = fakeLoad && Boolean(r.styleSheet);\n            }\n          }\n        }\n        if (fakeLoad) {\n          setTimeout(function() {\n            elt.dispatchEvent(new CustomEvent(\"load\", {\n              bubbles: false\n            }));\n          });\n        }\n      }\n    },\n    parseScript: function(scriptElt) {\n      var script = document.createElement(\"script\");\n      script.__importElement = scriptElt;\n      script.src = scriptElt.src ? scriptElt.src : generateScriptDataUrl(scriptElt);\n      scope.currentScript = scriptElt;\n      this.trackElement(script, function(e) {\n        if (script.parentNode) {\n          script.parentNode.removeChild(script);\n        }\n        scope.currentScript = null;\n      });\n      this.addElementToDocument(script);\n    },\n    nextToParse: function() {\n      this._mayParse = [];\n      return !this.parsingElement && (this.nextToParseInDoc(rootDocument) || this.nextToParseDynamic());\n    },\n    nextToParseInDoc: function(doc, link) {\n      if (doc && this._mayParse.indexOf(doc) < 0) {\n        this._mayParse.push(doc);\n        var nodes = doc.querySelectorAll(this.parseSelectorsForNode(doc));\n        for (var i = 0, l = nodes.length, p = 0, n; i < l && (n = nodes[i]); i++) {\n          if (!this.isParsed(n)) {\n            if (this.hasResource(n)) {\n              return nodeIsImport(n) ? this.nextToParseInDoc(n.__doc, n) : n;\n            } else {\n              return;\n            }\n          }\n        }\n      }\n      return link;\n    },\n    nextToParseDynamic: function() {\n      return this.dynamicElements[0];\n    },\n    parseSelectorsForNode: function(node) {\n      var doc = node.ownerDocument || node;\n      return doc === rootDocument ? this.documentSelectors : this.importsSelectors;\n    },\n    isParsed: function(node) {\n      return node.__importParsed;\n    },\n    needsDynamicParsing: function(elt) {\n      return this.dynamicElements.indexOf(elt) >= 0;\n    },\n    hasResource: function(node) {\n      if (nodeIsImport(node) && node.__doc === undefined) {\n        return false;\n      }\n      return true;\n    }\n  };\n  function nodeIsImport(elt) {\n    return elt.localName === \"link\" && elt.rel === IMPORT_LINK_TYPE;\n  }\n  function generateScriptDataUrl(script) {\n    var scriptContent = generateScriptContent(script);\n    return \"data:text/javascript;charset=utf-8,\" + encodeURIComponent(scriptContent);\n  }\n  function generateScriptContent(script) {\n    return script.textContent + generateSourceMapHint(script);\n  }\n  function generateSourceMapHint(script) {\n    var owner = script.ownerDocument;\n    owner.__importedScripts = owner.__importedScripts || 0;\n    var moniker = script.ownerDocument.baseURI;\n    var num = owner.__importedScripts ? \"-\" + owner.__importedScripts : \"\";\n    owner.__importedScripts++;\n    return \"\\n//# sourceURL=\" + moniker + num + \".js\\n\";\n  }\n  function cloneStyle(style) {\n    var clone = style.ownerDocument.createElement(\"style\");\n    clone.textContent = style.textContent;\n    path.resolveUrlsInStyle(clone);\n    return clone;\n  }\n  scope.parser = importParser;\n  scope.IMPORT_SELECTOR = IMPORT_SELECTOR;\n});\n\nwindow.HTMLImports.addModule(function(scope) {\n  var flags = scope.flags;\n  var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;\n  var IMPORT_SELECTOR = scope.IMPORT_SELECTOR;\n  var rootDocument = scope.rootDocument;\n  var Loader = scope.Loader;\n  var Observer = scope.Observer;\n  var parser = scope.parser;\n  var importer = {\n    documents: {},\n    documentPreloadSelectors: IMPORT_SELECTOR,\n    importsPreloadSelectors: [ IMPORT_SELECTOR ].join(\",\"),\n    loadNode: function(node) {\n      importLoader.addNode(node);\n    },\n    loadSubtree: function(parent) {\n      var nodes = this.marshalNodes(parent);\n      importLoader.addNodes(nodes);\n    },\n    marshalNodes: function(parent) {\n      return parent.querySelectorAll(this.loadSelectorsForNode(parent));\n    },\n    loadSelectorsForNode: function(node) {\n      var doc = node.ownerDocument || node;\n      return doc === rootDocument ? this.documentPreloadSelectors : this.importsPreloadSelectors;\n    },\n    loaded: function(url, elt, resource, err, redirectedUrl) {\n      flags.load && console.log(\"loaded\", url, elt);\n      elt.__resource = resource;\n      elt.__error = err;\n      if (isImportLink(elt)) {\n        var doc = this.documents[url];\n        if (doc === undefined) {\n          doc = err ? null : makeDocument(resource, redirectedUrl || url);\n          if (doc) {\n            doc.__importLink = elt;\n            this.bootDocument(doc);\n          }\n          this.documents[url] = doc;\n        }\n        elt.__doc = doc;\n      }\n      parser.parseNext();\n    },\n    bootDocument: function(doc) {\n      this.loadSubtree(doc);\n      this.observer.observe(doc);\n      parser.parseNext();\n    },\n    loadedAll: function() {\n      parser.parseNext();\n    }\n  };\n  var importLoader = new Loader(importer.loaded.bind(importer), importer.loadedAll.bind(importer));\n  importer.observer = new Observer();\n  function isImportLink(elt) {\n    return isLinkRel(elt, IMPORT_LINK_TYPE);\n  }\n  function isLinkRel(elt, rel) {\n    return elt.localName === \"link\" && elt.getAttribute(\"rel\") === rel;\n  }\n  function hasBaseURIAccessor(doc) {\n    return !!Object.getOwnPropertyDescriptor(doc, \"baseURI\");\n  }\n  function makeDocument(resource, url) {\n    var doc = document.implementation.createHTMLDocument(IMPORT_LINK_TYPE);\n    doc._URL = url;\n    var base = doc.createElement(\"base\");\n    base.setAttribute(\"href\", url);\n    if (!doc.baseURI && !hasBaseURIAccessor(doc)) {\n      Object.defineProperty(doc, \"baseURI\", {\n        value: url\n      });\n    }\n    var meta = doc.createElement(\"meta\");\n    meta.setAttribute(\"charset\", \"utf-8\");\n    doc.head.appendChild(meta);\n    doc.head.appendChild(base);\n    doc.body.innerHTML = resource;\n    if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {\n      HTMLTemplateElement.bootstrap(doc);\n    }\n    return doc;\n  }\n  if (!document.baseURI) {\n    var baseURIDescriptor = {\n      get: function() {\n        var base = document.querySelector(\"base\");\n        return base ? base.href : window.location.href;\n      },\n      configurable: true\n    };\n    Object.defineProperty(document, \"baseURI\", baseURIDescriptor);\n    Object.defineProperty(rootDocument, \"baseURI\", baseURIDescriptor);\n  }\n  scope.importer = importer;\n  scope.importLoader = importLoader;\n});\n\nwindow.HTMLImports.addModule(function(scope) {\n  var parser = scope.parser;\n  var importer = scope.importer;\n  var dynamic = {\n    added: function(nodes) {\n      var owner, parsed, loading;\n      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {\n        if (!owner) {\n          owner = n.ownerDocument;\n          parsed = parser.isParsed(owner);\n        }\n        loading = this.shouldLoadNode(n);\n        if (loading) {\n          importer.loadNode(n);\n        }\n        if (this.shouldParseNode(n) && parsed) {\n          parser.parseDynamic(n, loading);\n        }\n      }\n    },\n    shouldLoadNode: function(node) {\n      return node.nodeType === 1 && matches.call(node, importer.loadSelectorsForNode(node));\n    },\n    shouldParseNode: function(node) {\n      return node.nodeType === 1 && matches.call(node, parser.parseSelectorsForNode(node));\n    }\n  };\n  importer.observer.addCallback = dynamic.added.bind(dynamic);\n  var matches = HTMLElement.prototype.matches || HTMLElement.prototype.matchesSelector || HTMLElement.prototype.webkitMatchesSelector || HTMLElement.prototype.mozMatchesSelector || HTMLElement.prototype.msMatchesSelector;\n});\n\n(function(scope) {\n  var initializeModules = scope.initializeModules;\n  var isIE = scope.isIE;\n  if (scope.useNative) {\n    return;\n  }\n  if (isIE && typeof window.CustomEvent !== \"function\") {\n    window.CustomEvent = function(inType, params) {\n      params = params || {};\n      var e = document.createEvent(\"CustomEvent\");\n      e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);\n      e.preventDefault = function() {\n        Object.defineProperty(this, \"defaultPrevented\", {\n          get: function() {\n            return true;\n          }\n        });\n      };\n      return e;\n    };\n    window.CustomEvent.prototype = window.Event.prototype;\n  }\n  initializeModules();\n  var rootDocument = scope.rootDocument;\n  function bootstrap() {\n    window.HTMLImports.importer.bootDocument(rootDocument);\n  }\n  if (document.readyState === \"complete\" || document.readyState === \"interactive\" && !window.attachEvent) {\n    bootstrap();\n  } else {\n    document.addEventListener(\"DOMContentLoaded\", bootstrap);\n  }\n})(window.HTMLImports);"
  },
  {
    "path": "cmd/memlat/static/bower_components/webcomponentsjs/MutationObserver.js",
    "content": "/**\n * @license\n * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n */\n// @version 0.7.11\nif (typeof WeakMap === \"undefined\") {\n  (function() {\n    var defineProperty = Object.defineProperty;\n    var counter = Date.now() % 1e9;\n    var WeakMap = function() {\n      this.name = \"__st\" + (Math.random() * 1e9 >>> 0) + (counter++ + \"__\");\n    };\n    WeakMap.prototype = {\n      set: function(key, value) {\n        var entry = key[this.name];\n        if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {\n          value: [ key, value ],\n          writable: true\n        });\n        return this;\n      },\n      get: function(key) {\n        var entry;\n        return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;\n      },\n      \"delete\": function(key) {\n        var entry = key[this.name];\n        if (!entry || entry[0] !== key) return false;\n        entry[0] = entry[1] = undefined;\n        return true;\n      },\n      has: function(key) {\n        var entry = key[this.name];\n        if (!entry) return false;\n        return entry[0] === key;\n      }\n    };\n    window.WeakMap = WeakMap;\n  })();\n}\n\n(function(global) {\n  var registrationsTable = new WeakMap();\n  var setImmediate;\n  if (/Trident|Edge/.test(navigator.userAgent)) {\n    setImmediate = setTimeout;\n  } else if (window.setImmediate) {\n    setImmediate = window.setImmediate;\n  } else {\n    var setImmediateQueue = [];\n    var sentinel = String(Math.random());\n    window.addEventListener(\"message\", function(e) {\n      if (e.data === sentinel) {\n        var queue = setImmediateQueue;\n        setImmediateQueue = [];\n        queue.forEach(function(func) {\n          func();\n        });\n      }\n    });\n    setImmediate = function(func) {\n      setImmediateQueue.push(func);\n      window.postMessage(sentinel, \"*\");\n    };\n  }\n  var isScheduled = false;\n  var scheduledObservers = [];\n  function scheduleCallback(observer) {\n    scheduledObservers.push(observer);\n    if (!isScheduled) {\n      isScheduled = true;\n      setImmediate(dispatchCallbacks);\n    }\n  }\n  function wrapIfNeeded(node) {\n    return window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrapIfNeeded(node) || node;\n  }\n  function dispatchCallbacks() {\n    isScheduled = false;\n    var observers = scheduledObservers;\n    scheduledObservers = [];\n    observers.sort(function(o1, o2) {\n      return o1.uid_ - o2.uid_;\n    });\n    var anyNonEmpty = false;\n    observers.forEach(function(observer) {\n      var queue = observer.takeRecords();\n      removeTransientObserversFor(observer);\n      if (queue.length) {\n        observer.callback_(queue, observer);\n        anyNonEmpty = true;\n      }\n    });\n    if (anyNonEmpty) dispatchCallbacks();\n  }\n  function removeTransientObserversFor(observer) {\n    observer.nodes_.forEach(function(node) {\n      var registrations = registrationsTable.get(node);\n      if (!registrations) return;\n      registrations.forEach(function(registration) {\n        if (registration.observer === observer) registration.removeTransientObservers();\n      });\n    });\n  }\n  function forEachAncestorAndObserverEnqueueRecord(target, callback) {\n    for (var node = target; node; node = node.parentNode) {\n      var registrations = registrationsTable.get(node);\n      if (registrations) {\n        for (var j = 0; j < registrations.length; j++) {\n          var registration = registrations[j];\n          var options = registration.options;\n          if (node !== target && !options.subtree) continue;\n          var record = callback(options);\n          if (record) registration.enqueue(record);\n        }\n      }\n    }\n  }\n  var uidCounter = 0;\n  function JsMutationObserver(callback) {\n    this.callback_ = callback;\n    this.nodes_ = [];\n    this.records_ = [];\n    this.uid_ = ++uidCounter;\n  }\n  JsMutationObserver.prototype = {\n    observe: function(target, options) {\n      target = wrapIfNeeded(target);\n      if (!options.childList && !options.attributes && !options.characterData || options.attributeOldValue && !options.attributes || options.attributeFilter && options.attributeFilter.length && !options.attributes || options.characterDataOldValue && !options.characterData) {\n        throw new SyntaxError();\n      }\n      var registrations = registrationsTable.get(target);\n      if (!registrations) registrationsTable.set(target, registrations = []);\n      var registration;\n      for (var i = 0; i < registrations.length; i++) {\n        if (registrations[i].observer === this) {\n          registration = registrations[i];\n          registration.removeListeners();\n          registration.options = options;\n          break;\n        }\n      }\n      if (!registration) {\n        registration = new Registration(this, target, options);\n        registrations.push(registration);\n        this.nodes_.push(target);\n      }\n      registration.addListeners();\n    },\n    disconnect: function() {\n      this.nodes_.forEach(function(node) {\n        var registrations = registrationsTable.get(node);\n        for (var i = 0; i < registrations.length; i++) {\n          var registration = registrations[i];\n          if (registration.observer === this) {\n            registration.removeListeners();\n            registrations.splice(i, 1);\n            break;\n          }\n        }\n      }, this);\n      this.records_ = [];\n    },\n    takeRecords: function() {\n      var copyOfRecords = this.records_;\n      this.records_ = [];\n      return copyOfRecords;\n    }\n  };\n  function MutationRecord(type, target) {\n    this.type = type;\n    this.target = target;\n    this.addedNodes = [];\n    this.removedNodes = [];\n    this.previousSibling = null;\n    this.nextSibling = null;\n    this.attributeName = null;\n    this.attributeNamespace = null;\n    this.oldValue = null;\n  }\n  function copyMutationRecord(original) {\n    var record = new MutationRecord(original.type, original.target);\n    record.addedNodes = original.addedNodes.slice();\n    record.removedNodes = original.removedNodes.slice();\n    record.previousSibling = original.previousSibling;\n    record.nextSibling = original.nextSibling;\n    record.attributeName = original.attributeName;\n    record.attributeNamespace = original.attributeNamespace;\n    record.oldValue = original.oldValue;\n    return record;\n  }\n  var currentRecord, recordWithOldValue;\n  function getRecord(type, target) {\n    return currentRecord = new MutationRecord(type, target);\n  }\n  function getRecordWithOldValue(oldValue) {\n    if (recordWithOldValue) return recordWithOldValue;\n    recordWithOldValue = copyMutationRecord(currentRecord);\n    recordWithOldValue.oldValue = oldValue;\n    return recordWithOldValue;\n  }\n  function clearRecords() {\n    currentRecord = recordWithOldValue = undefined;\n  }\n  function recordRepresentsCurrentMutation(record) {\n    return record === recordWithOldValue || record === currentRecord;\n  }\n  function selectRecord(lastRecord, newRecord) {\n    if (lastRecord === newRecord) return lastRecord;\n    if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord)) return recordWithOldValue;\n    return null;\n  }\n  function Registration(observer, target, options) {\n    this.observer = observer;\n    this.target = target;\n    this.options = options;\n    this.transientObservedNodes = [];\n  }\n  Registration.prototype = {\n    enqueue: function(record) {\n      var records = this.observer.records_;\n      var length = records.length;\n      if (records.length > 0) {\n        var lastRecord = records[length - 1];\n        var recordToReplaceLast = selectRecord(lastRecord, record);\n        if (recordToReplaceLast) {\n          records[length - 1] = recordToReplaceLast;\n          return;\n        }\n      } else {\n        scheduleCallback(this.observer);\n      }\n      records[length] = record;\n    },\n    addListeners: function() {\n      this.addListeners_(this.target);\n    },\n    addListeners_: function(node) {\n      var options = this.options;\n      if (options.attributes) node.addEventListener(\"DOMAttrModified\", this, true);\n      if (options.characterData) node.addEventListener(\"DOMCharacterDataModified\", this, true);\n      if (options.childList) node.addEventListener(\"DOMNodeInserted\", this, true);\n      if (options.childList || options.subtree) node.addEventListener(\"DOMNodeRemoved\", this, true);\n    },\n    removeListeners: function() {\n      this.removeListeners_(this.target);\n    },\n    removeListeners_: function(node) {\n      var options = this.options;\n      if (options.attributes) node.removeEventListener(\"DOMAttrModified\", this, true);\n      if (options.characterData) node.removeEventListener(\"DOMCharacterDataModified\", this, true);\n      if (options.childList) node.removeEventListener(\"DOMNodeInserted\", this, true);\n      if (options.childList || options.subtree) node.removeEventListener(\"DOMNodeRemoved\", this, true);\n    },\n    addTransientObserver: function(node) {\n      if (node === this.target) return;\n      this.addListeners_(node);\n      this.transientObservedNodes.push(node);\n      var registrations = registrationsTable.get(node);\n      if (!registrations) registrationsTable.set(node, registrations = []);\n      registrations.push(this);\n    },\n    removeTransientObservers: function() {\n      var transientObservedNodes = this.transientObservedNodes;\n      this.transientObservedNodes = [];\n      transientObservedNodes.forEach(function(node) {\n        this.removeListeners_(node);\n        var registrations = registrationsTable.get(node);\n        for (var i = 0; i < registrations.length; i++) {\n          if (registrations[i] === this) {\n            registrations.splice(i, 1);\n            break;\n          }\n        }\n      }, this);\n    },\n    handleEvent: function(e) {\n      e.stopImmediatePropagation();\n      switch (e.type) {\n       case \"DOMAttrModified\":\n        var name = e.attrName;\n        var namespace = e.relatedNode.namespaceURI;\n        var target = e.target;\n        var record = new getRecord(\"attributes\", target);\n        record.attributeName = name;\n        record.attributeNamespace = namespace;\n        var oldValue = e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;\n        forEachAncestorAndObserverEnqueueRecord(target, function(options) {\n          if (!options.attributes) return;\n          if (options.attributeFilter && options.attributeFilter.length && options.attributeFilter.indexOf(name) === -1 && options.attributeFilter.indexOf(namespace) === -1) {\n            return;\n          }\n          if (options.attributeOldValue) return getRecordWithOldValue(oldValue);\n          return record;\n        });\n        break;\n\n       case \"DOMCharacterDataModified\":\n        var target = e.target;\n        var record = getRecord(\"characterData\", target);\n        var oldValue = e.prevValue;\n        forEachAncestorAndObserverEnqueueRecord(target, function(options) {\n          if (!options.characterData) return;\n          if (options.characterDataOldValue) return getRecordWithOldValue(oldValue);\n          return record;\n        });\n        break;\n\n       case \"DOMNodeRemoved\":\n        this.addTransientObserver(e.target);\n\n       case \"DOMNodeInserted\":\n        var changedNode = e.target;\n        var addedNodes, removedNodes;\n        if (e.type === \"DOMNodeInserted\") {\n          addedNodes = [ changedNode ];\n          removedNodes = [];\n        } else {\n          addedNodes = [];\n          removedNodes = [ changedNode ];\n        }\n        var previousSibling = changedNode.previousSibling;\n        var nextSibling = changedNode.nextSibling;\n        var record = getRecord(\"childList\", e.target.parentNode);\n        record.addedNodes = addedNodes;\n        record.removedNodes = removedNodes;\n        record.previousSibling = previousSibling;\n        record.nextSibling = nextSibling;\n        forEachAncestorAndObserverEnqueueRecord(e.relatedNode, function(options) {\n          if (!options.childList) return;\n          return record;\n        });\n      }\n      clearRecords();\n    }\n  };\n  global.JsMutationObserver = JsMutationObserver;\n  if (!global.MutationObserver) global.MutationObserver = JsMutationObserver;\n})(this);"
  },
  {
    "path": "cmd/memlat/static/bower_components/webcomponentsjs/README.md",
    "content": "webcomponents.js\n================\n\n[![Join the chat at https://gitter.im/webcomponents/webcomponentsjs](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/webcomponents/webcomponentsjs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n\nA suite of polyfills supporting the [Web Components](http://webcomponents.org) specs:\n\n**Custom Elements**: allows authors to define their own custom tags ([spec](https://w3c.github.io/webcomponents/spec/custom/)).\n\n**HTML Imports**: a way to include and reuse HTML documents via other HTML documents ([spec](https://w3c.github.io/webcomponents/spec/imports/)).\n\n**Shadow DOM**: provides encapsulation by hiding DOM subtrees under shadow roots ([spec](https://w3c.github.io/webcomponents/spec/shadow/)).\n\nThis also folds in polyfills for `MutationObserver` and `WeakMap`.\n\n\n## Releases\n\nPre-built (concatenated & minified) versions of the polyfills are maintained in the [tagged versions](https://github.com/webcomponents/webcomponentsjs/releases) of this repo. There are two variants:\n\n`webcomponents.js` includes all of the polyfills.\n\n`webcomponents-lite.js` includes all polyfills except for shadow DOM.\n\n\n## Browser Support\n\nOur polyfills are intended to work in the latest versions of evergreen browsers. See below\nfor our complete browser support matrix:\n\n| Polyfill   | IE10 | IE11+ | Chrome* | Firefox* | Safari 7+* | Chrome Android* | Mobile Safari* |\n| ---------- |:----:|:-----:|:-------:|:--------:|:----------:|:---------------:|:--------------:|\n| Custom Elements | ~ | ✓ | ✓ | ✓ | ✓ | ✓| ✓ |\n| HTML Imports | ~ | ✓ | ✓ | ✓ | ✓| ✓| ✓ |\n| Shadow DOM | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |\n| Templates | ✓ | ✓ | ✓ | ✓| ✓ | ✓ | ✓ |\n\n\n*Indicates the current version of the browser\n\n~Indicates support may be flaky. If using Custom Elements or HTML Imports with Shadow DOM,\nyou will get the non-flaky Mutation Observer polyfill that Shadow DOM includes.\n\nThe polyfills may work in older browsers, however require additional polyfills (such as classList)\nto be used. We cannot guarantee support for browsers outside of our compatibility matrix.\n\n\n### Manually Building\n\nIf you wish to build the polyfills yourself, you'll need `node` and `gulp` on your system:\n\n * install [node.js](http://nodejs.org/) using the instructions on their website\n * use `npm` to install [gulp.js](http://gulpjs.com/): `npm install -g gulp`\n\nNow you are ready to build the polyfills with:\n\n    # install dependencies\n    npm install\n    # build\n    gulp build\n\nThe builds will be placed into the `dist/` directory.\n\n## Contribute\n\nSee the [contributing guide](CONTRIBUTING.md)\n\n## License\n\nEverything in this repository is BSD style license unless otherwise specified.\n\nCopyright (c) 2015 The Polymer Authors. All rights reserved.\n\n## Helper utilities\n\n### `WebComponentsReady`\n\nUnder native HTML Imports, `<script>` tags in the main document block the loading of such imports. This is to ensure the imports have loaded and any registered elements in them have been upgraded. \n\nThe webcomponents.js and webcomponents-lite.js polyfills parse element definitions and handle their upgrade asynchronously. If prematurely fetching the element from the DOM before it has an opportunity to upgrade, you'll be working with an `HTMLUnknownElement`. \n\nFor these situations (or when you need an approximate replacement for the Polymer 0.5 `polymer-ready` behavior), you can use the `WebComponentsReady` event as a signal before interacting with the element. The criteria for this event to fire is all Custom Elements with definitions registered by the time HTML Imports available at load time have loaded have upgraded.\n\n```js\nwindow.addEventListener('WebComponentsReady', function(e) {\n  // imports are loaded and elements have been registered\n  console.log('Components are ready');\n});\n```\n\n## Known Issues\n\n  * [Custom element's constructor property is unreliable](#constructor)\n  * [Contenteditable elements do not trigger MutationObserver](#contentedit)\n  * [ShadowCSS: :host-context(...):host(...) doesn't work](#hostcontext)\n  * [execCommand isn't supported under Shadow DOM](#execcommand)\n\n### Custom element's constructor property is unreliable <a id=\"constructor\"></a>\nSee [#215](https://github.com/webcomponents/webcomponentsjs/issues/215) for background.\n\nIn Safari and IE, instances of Custom Elements have a `constructor` property of `HTMLUnknownElementConstructor` and `HTMLUnknownElement`, respectively. It's unsafe to rely on this property for checking element types.\n\nIt's worth noting that `customElement.__proto__.__proto__.constructor` is `HTMLElementPrototype` and that the prototype chain isn't modified by the polyfills(onto `ElementPrototype`, etc.)\n\n### Contenteditable elements do not trigger MutationObserver <a id=\"contentedit\"></a>\nUsing the MutationObserver polyfill, it isn't possible to monitor mutations of an element marked `contenteditable`.\nSee [the mailing list](https://groups.google.com/forum/#!msg/polymer-dev/LHdtRVXXVsA/v1sGoiTYWUkJ)\n\n### ShadowCSS: :host-context(...):host(...) doesn't work <a id=\"hostcontext\"></a>\nSee [#16](https://github.com/webcomponents/webcomponentsjs/issues/16) for background.\n\nUnder the shadow DOM polyfill, rules like:\n```\n:host-context(.foo):host(.bar) {...}\n```\ndon't work, despite working under native Shadow DOM. The solution is to use `polyfill-next-selector` like:\n\n```\npolyfill-next-selector { content: '.foo :host.bar, :host.foo.bar'; }\n```\n\n### execCommand and contenteditable isn't supported under Shadow DOM <a id=\"execcommand\"></a>\nSee [#212](https://github.com/webcomponents/webcomponentsjs/issues/212)\n\n`execCommand`, and `contenteditable` aren't supported under the ShadowDOM polyfill, with commands that insert or remove nodes being especially prone to failure.\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/webcomponentsjs/ShadowDOM.js",
    "content": "/**\n * @license\n * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n */\n// @version 0.7.11\nif (typeof WeakMap === \"undefined\") {\n  (function() {\n    var defineProperty = Object.defineProperty;\n    var counter = Date.now() % 1e9;\n    var WeakMap = function() {\n      this.name = \"__st\" + (Math.random() * 1e9 >>> 0) + (counter++ + \"__\");\n    };\n    WeakMap.prototype = {\n      set: function(key, value) {\n        var entry = key[this.name];\n        if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {\n          value: [ key, value ],\n          writable: true\n        });\n        return this;\n      },\n      get: function(key) {\n        var entry;\n        return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;\n      },\n      \"delete\": function(key) {\n        var entry = key[this.name];\n        if (!entry || entry[0] !== key) return false;\n        entry[0] = entry[1] = undefined;\n        return true;\n      },\n      has: function(key) {\n        var entry = key[this.name];\n        if (!entry) return false;\n        return entry[0] === key;\n      }\n    };\n    window.WeakMap = WeakMap;\n  })();\n}\n\nwindow.ShadowDOMPolyfill = {};\n\n(function(scope) {\n  \"use strict\";\n  var constructorTable = new WeakMap();\n  var nativePrototypeTable = new WeakMap();\n  var wrappers = Object.create(null);\n  function detectEval() {\n    if (typeof chrome !== \"undefined\" && chrome.app && chrome.app.runtime) {\n      return false;\n    }\n    if (navigator.getDeviceStorage) {\n      return false;\n    }\n    try {\n      var f = new Function(\"return true;\");\n      return f();\n    } catch (ex) {\n      return false;\n    }\n  }\n  var hasEval = detectEval();\n  function assert(b) {\n    if (!b) throw new Error(\"Assertion failed\");\n  }\n  var defineProperty = Object.defineProperty;\n  var getOwnPropertyNames = Object.getOwnPropertyNames;\n  var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n  function mixin(to, from) {\n    var names = getOwnPropertyNames(from);\n    for (var i = 0; i < names.length; i++) {\n      var name = names[i];\n      defineProperty(to, name, getOwnPropertyDescriptor(from, name));\n    }\n    return to;\n  }\n  function mixinStatics(to, from) {\n    var names = getOwnPropertyNames(from);\n    for (var i = 0; i < names.length; i++) {\n      var name = names[i];\n      switch (name) {\n       case \"arguments\":\n       case \"caller\":\n       case \"length\":\n       case \"name\":\n       case \"prototype\":\n       case \"toString\":\n        continue;\n      }\n      defineProperty(to, name, getOwnPropertyDescriptor(from, name));\n    }\n    return to;\n  }\n  function oneOf(object, propertyNames) {\n    for (var i = 0; i < propertyNames.length; i++) {\n      if (propertyNames[i] in object) return propertyNames[i];\n    }\n  }\n  var nonEnumerableDataDescriptor = {\n    value: undefined,\n    configurable: true,\n    enumerable: false,\n    writable: true\n  };\n  function defineNonEnumerableDataProperty(object, name, value) {\n    nonEnumerableDataDescriptor.value = value;\n    defineProperty(object, name, nonEnumerableDataDescriptor);\n  }\n  getOwnPropertyNames(window);\n  function getWrapperConstructor(node, opt_instance) {\n    var nativePrototype = node.__proto__ || Object.getPrototypeOf(node);\n    if (isFirefox) {\n      try {\n        getOwnPropertyNames(nativePrototype);\n      } catch (error) {\n        nativePrototype = nativePrototype.__proto__;\n      }\n    }\n    var wrapperConstructor = constructorTable.get(nativePrototype);\n    if (wrapperConstructor) return wrapperConstructor;\n    var parentWrapperConstructor = getWrapperConstructor(nativePrototype);\n    var GeneratedWrapper = createWrapperConstructor(parentWrapperConstructor);\n    registerInternal(nativePrototype, GeneratedWrapper, opt_instance);\n    return GeneratedWrapper;\n  }\n  function addForwardingProperties(nativePrototype, wrapperPrototype) {\n    installProperty(nativePrototype, wrapperPrototype, true);\n  }\n  function registerInstanceProperties(wrapperPrototype, instanceObject) {\n    installProperty(instanceObject, wrapperPrototype, false);\n  }\n  var isFirefox = /Firefox/.test(navigator.userAgent);\n  var dummyDescriptor = {\n    get: function() {},\n    set: function(v) {},\n    configurable: true,\n    enumerable: true\n  };\n  function isEventHandlerName(name) {\n    return /^on[a-z]+$/.test(name);\n  }\n  function isIdentifierName(name) {\n    return /^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(name);\n  }\n  function getGetter(name) {\n    return hasEval && isIdentifierName(name) ? new Function(\"return this.__impl4cf1e782hg__.\" + name) : function() {\n      return this.__impl4cf1e782hg__[name];\n    };\n  }\n  function getSetter(name) {\n    return hasEval && isIdentifierName(name) ? new Function(\"v\", \"this.__impl4cf1e782hg__.\" + name + \" = v\") : function(v) {\n      this.__impl4cf1e782hg__[name] = v;\n    };\n  }\n  function getMethod(name) {\n    return hasEval && isIdentifierName(name) ? new Function(\"return this.__impl4cf1e782hg__.\" + name + \".apply(this.__impl4cf1e782hg__, arguments)\") : function() {\n      return this.__impl4cf1e782hg__[name].apply(this.__impl4cf1e782hg__, arguments);\n    };\n  }\n  function getDescriptor(source, name) {\n    try {\n      return Object.getOwnPropertyDescriptor(source, name);\n    } catch (ex) {\n      return dummyDescriptor;\n    }\n  }\n  var isBrokenSafari = function() {\n    var descr = Object.getOwnPropertyDescriptor(Node.prototype, \"nodeType\");\n    return descr && !descr.get && !descr.set;\n  }();\n  function installProperty(source, target, allowMethod, opt_blacklist) {\n    var names = getOwnPropertyNames(source);\n    for (var i = 0; i < names.length; i++) {\n      var name = names[i];\n      if (name === \"polymerBlackList_\") continue;\n      if (name in target) continue;\n      if (source.polymerBlackList_ && source.polymerBlackList_[name]) continue;\n      if (isFirefox) {\n        source.__lookupGetter__(name);\n      }\n      var descriptor = getDescriptor(source, name);\n      var getter, setter;\n      if (typeof descriptor.value === \"function\") {\n        if (allowMethod) {\n          target[name] = getMethod(name);\n        }\n        continue;\n      }\n      var isEvent = isEventHandlerName(name);\n      if (isEvent) getter = scope.getEventHandlerGetter(name); else getter = getGetter(name);\n      if (descriptor.writable || descriptor.set || isBrokenSafari) {\n        if (isEvent) setter = scope.getEventHandlerSetter(name); else setter = getSetter(name);\n      }\n      var configurable = isBrokenSafari || descriptor.configurable;\n      defineProperty(target, name, {\n        get: getter,\n        set: setter,\n        configurable: configurable,\n        enumerable: descriptor.enumerable\n      });\n    }\n  }\n  function register(nativeConstructor, wrapperConstructor, opt_instance) {\n    if (nativeConstructor == null) {\n      return;\n    }\n    var nativePrototype = nativeConstructor.prototype;\n    registerInternal(nativePrototype, wrapperConstructor, opt_instance);\n    mixinStatics(wrapperConstructor, nativeConstructor);\n  }\n  function registerInternal(nativePrototype, wrapperConstructor, opt_instance) {\n    var wrapperPrototype = wrapperConstructor.prototype;\n    assert(constructorTable.get(nativePrototype) === undefined);\n    constructorTable.set(nativePrototype, wrapperConstructor);\n    nativePrototypeTable.set(wrapperPrototype, nativePrototype);\n    addForwardingProperties(nativePrototype, wrapperPrototype);\n    if (opt_instance) registerInstanceProperties(wrapperPrototype, opt_instance);\n    defineNonEnumerableDataProperty(wrapperPrototype, \"constructor\", wrapperConstructor);\n    wrapperConstructor.prototype = wrapperPrototype;\n  }\n  function isWrapperFor(wrapperConstructor, nativeConstructor) {\n    return constructorTable.get(nativeConstructor.prototype) === wrapperConstructor;\n  }\n  function registerObject(object) {\n    var nativePrototype = Object.getPrototypeOf(object);\n    var superWrapperConstructor = getWrapperConstructor(nativePrototype);\n    var GeneratedWrapper = createWrapperConstructor(superWrapperConstructor);\n    registerInternal(nativePrototype, GeneratedWrapper, object);\n    return GeneratedWrapper;\n  }\n  function createWrapperConstructor(superWrapperConstructor) {\n    function GeneratedWrapper(node) {\n      superWrapperConstructor.call(this, node);\n    }\n    var p = Object.create(superWrapperConstructor.prototype);\n    p.constructor = GeneratedWrapper;\n    GeneratedWrapper.prototype = p;\n    return GeneratedWrapper;\n  }\n  function isWrapper(object) {\n    return object && object.__impl4cf1e782hg__;\n  }\n  function isNative(object) {\n    return !isWrapper(object);\n  }\n  function wrap(impl) {\n    if (impl === null) return null;\n    assert(isNative(impl));\n    var wrapper = impl.__wrapper8e3dd93a60__;\n    if (wrapper != null) {\n      return wrapper;\n    }\n    return impl.__wrapper8e3dd93a60__ = new (getWrapperConstructor(impl, impl))(impl);\n  }\n  function unwrap(wrapper) {\n    if (wrapper === null) return null;\n    assert(isWrapper(wrapper));\n    return wrapper.__impl4cf1e782hg__;\n  }\n  function unsafeUnwrap(wrapper) {\n    return wrapper.__impl4cf1e782hg__;\n  }\n  function setWrapper(impl, wrapper) {\n    wrapper.__impl4cf1e782hg__ = impl;\n    impl.__wrapper8e3dd93a60__ = wrapper;\n  }\n  function unwrapIfNeeded(object) {\n    return object && isWrapper(object) ? unwrap(object) : object;\n  }\n  function wrapIfNeeded(object) {\n    return object && !isWrapper(object) ? wrap(object) : object;\n  }\n  function rewrap(node, wrapper) {\n    if (wrapper === null) return;\n    assert(isNative(node));\n    assert(wrapper === undefined || isWrapper(wrapper));\n    node.__wrapper8e3dd93a60__ = wrapper;\n  }\n  var getterDescriptor = {\n    get: undefined,\n    configurable: true,\n    enumerable: true\n  };\n  function defineGetter(constructor, name, getter) {\n    getterDescriptor.get = getter;\n    defineProperty(constructor.prototype, name, getterDescriptor);\n  }\n  function defineWrapGetter(constructor, name) {\n    defineGetter(constructor, name, function() {\n      return wrap(this.__impl4cf1e782hg__[name]);\n    });\n  }\n  function forwardMethodsToWrapper(constructors, names) {\n    constructors.forEach(function(constructor) {\n      names.forEach(function(name) {\n        constructor.prototype[name] = function() {\n          var w = wrapIfNeeded(this);\n          return w[name].apply(w, arguments);\n        };\n      });\n    });\n  }\n  scope.assert = assert;\n  scope.constructorTable = constructorTable;\n  scope.defineGetter = defineGetter;\n  scope.defineWrapGetter = defineWrapGetter;\n  scope.forwardMethodsToWrapper = forwardMethodsToWrapper;\n  scope.isIdentifierName = isIdentifierName;\n  scope.isWrapper = isWrapper;\n  scope.isWrapperFor = isWrapperFor;\n  scope.mixin = mixin;\n  scope.nativePrototypeTable = nativePrototypeTable;\n  scope.oneOf = oneOf;\n  scope.registerObject = registerObject;\n  scope.registerWrapper = register;\n  scope.rewrap = rewrap;\n  scope.setWrapper = setWrapper;\n  scope.unsafeUnwrap = unsafeUnwrap;\n  scope.unwrap = unwrap;\n  scope.unwrapIfNeeded = unwrapIfNeeded;\n  scope.wrap = wrap;\n  scope.wrapIfNeeded = wrapIfNeeded;\n  scope.wrappers = wrappers;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  function newSplice(index, removed, addedCount) {\n    return {\n      index: index,\n      removed: removed,\n      addedCount: addedCount\n    };\n  }\n  var EDIT_LEAVE = 0;\n  var EDIT_UPDATE = 1;\n  var EDIT_ADD = 2;\n  var EDIT_DELETE = 3;\n  function ArraySplice() {}\n  ArraySplice.prototype = {\n    calcEditDistances: function(current, currentStart, currentEnd, old, oldStart, oldEnd) {\n      var rowCount = oldEnd - oldStart + 1;\n      var columnCount = currentEnd - currentStart + 1;\n      var distances = new Array(rowCount);\n      for (var i = 0; i < rowCount; i++) {\n        distances[i] = new Array(columnCount);\n        distances[i][0] = i;\n      }\n      for (var j = 0; j < columnCount; j++) distances[0][j] = j;\n      for (var i = 1; i < rowCount; i++) {\n        for (var j = 1; j < columnCount; j++) {\n          if (this.equals(current[currentStart + j - 1], old[oldStart + i - 1])) distances[i][j] = distances[i - 1][j - 1]; else {\n            var north = distances[i - 1][j] + 1;\n            var west = distances[i][j - 1] + 1;\n            distances[i][j] = north < west ? north : west;\n          }\n        }\n      }\n      return distances;\n    },\n    spliceOperationsFromEditDistances: function(distances) {\n      var i = distances.length - 1;\n      var j = distances[0].length - 1;\n      var current = distances[i][j];\n      var edits = [];\n      while (i > 0 || j > 0) {\n        if (i == 0) {\n          edits.push(EDIT_ADD);\n          j--;\n          continue;\n        }\n        if (j == 0) {\n          edits.push(EDIT_DELETE);\n          i--;\n          continue;\n        }\n        var northWest = distances[i - 1][j - 1];\n        var west = distances[i - 1][j];\n        var north = distances[i][j - 1];\n        var min;\n        if (west < north) min = west < northWest ? west : northWest; else min = north < northWest ? north : northWest;\n        if (min == northWest) {\n          if (northWest == current) {\n            edits.push(EDIT_LEAVE);\n          } else {\n            edits.push(EDIT_UPDATE);\n            current = northWest;\n          }\n          i--;\n          j--;\n        } else if (min == west) {\n          edits.push(EDIT_DELETE);\n          i--;\n          current = west;\n        } else {\n          edits.push(EDIT_ADD);\n          j--;\n          current = north;\n        }\n      }\n      edits.reverse();\n      return edits;\n    },\n    calcSplices: function(current, currentStart, currentEnd, old, oldStart, oldEnd) {\n      var prefixCount = 0;\n      var suffixCount = 0;\n      var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart);\n      if (currentStart == 0 && oldStart == 0) prefixCount = this.sharedPrefix(current, old, minLength);\n      if (currentEnd == current.length && oldEnd == old.length) suffixCount = this.sharedSuffix(current, old, minLength - prefixCount);\n      currentStart += prefixCount;\n      oldStart += prefixCount;\n      currentEnd -= suffixCount;\n      oldEnd -= suffixCount;\n      if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0) return [];\n      if (currentStart == currentEnd) {\n        var splice = newSplice(currentStart, [], 0);\n        while (oldStart < oldEnd) splice.removed.push(old[oldStart++]);\n        return [ splice ];\n      } else if (oldStart == oldEnd) return [ newSplice(currentStart, [], currentEnd - currentStart) ];\n      var ops = this.spliceOperationsFromEditDistances(this.calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd));\n      var splice = undefined;\n      var splices = [];\n      var index = currentStart;\n      var oldIndex = oldStart;\n      for (var i = 0; i < ops.length; i++) {\n        switch (ops[i]) {\n         case EDIT_LEAVE:\n          if (splice) {\n            splices.push(splice);\n            splice = undefined;\n          }\n          index++;\n          oldIndex++;\n          break;\n\n         case EDIT_UPDATE:\n          if (!splice) splice = newSplice(index, [], 0);\n          splice.addedCount++;\n          index++;\n          splice.removed.push(old[oldIndex]);\n          oldIndex++;\n          break;\n\n         case EDIT_ADD:\n          if (!splice) splice = newSplice(index, [], 0);\n          splice.addedCount++;\n          index++;\n          break;\n\n         case EDIT_DELETE:\n          if (!splice) splice = newSplice(index, [], 0);\n          splice.removed.push(old[oldIndex]);\n          oldIndex++;\n          break;\n        }\n      }\n      if (splice) {\n        splices.push(splice);\n      }\n      return splices;\n    },\n    sharedPrefix: function(current, old, searchLength) {\n      for (var i = 0; i < searchLength; i++) if (!this.equals(current[i], old[i])) return i;\n      return searchLength;\n    },\n    sharedSuffix: function(current, old, searchLength) {\n      var index1 = current.length;\n      var index2 = old.length;\n      var count = 0;\n      while (count < searchLength && this.equals(current[--index1], old[--index2])) count++;\n      return count;\n    },\n    calculateSplices: function(current, previous) {\n      return this.calcSplices(current, 0, current.length, previous, 0, previous.length);\n    },\n    equals: function(currentValue, previousValue) {\n      return currentValue === previousValue;\n    }\n  };\n  scope.ArraySplice = ArraySplice;\n})(window.ShadowDOMPolyfill);\n\n(function(context) {\n  \"use strict\";\n  var OriginalMutationObserver = window.MutationObserver;\n  var callbacks = [];\n  var pending = false;\n  var timerFunc;\n  function handle() {\n    pending = false;\n    var copies = callbacks.slice(0);\n    callbacks = [];\n    for (var i = 0; i < copies.length; i++) {\n      (0, copies[i])();\n    }\n  }\n  if (OriginalMutationObserver) {\n    var counter = 1;\n    var observer = new OriginalMutationObserver(handle);\n    var textNode = document.createTextNode(counter);\n    observer.observe(textNode, {\n      characterData: true\n    });\n    timerFunc = function() {\n      counter = (counter + 1) % 2;\n      textNode.data = counter;\n    };\n  } else {\n    timerFunc = window.setTimeout;\n  }\n  function setEndOfMicrotask(func) {\n    callbacks.push(func);\n    if (pending) return;\n    pending = true;\n    timerFunc(handle, 0);\n  }\n  context.setEndOfMicrotask = setEndOfMicrotask;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var setEndOfMicrotask = scope.setEndOfMicrotask;\n  var wrapIfNeeded = scope.wrapIfNeeded;\n  var wrappers = scope.wrappers;\n  var registrationsTable = new WeakMap();\n  var globalMutationObservers = [];\n  var isScheduled = false;\n  function scheduleCallback(observer) {\n    if (observer.scheduled_) return;\n    observer.scheduled_ = true;\n    globalMutationObservers.push(observer);\n    if (isScheduled) return;\n    setEndOfMicrotask(notifyObservers);\n    isScheduled = true;\n  }\n  function notifyObservers() {\n    isScheduled = false;\n    while (globalMutationObservers.length) {\n      var notifyList = globalMutationObservers;\n      globalMutationObservers = [];\n      notifyList.sort(function(x, y) {\n        return x.uid_ - y.uid_;\n      });\n      for (var i = 0; i < notifyList.length; i++) {\n        var mo = notifyList[i];\n        mo.scheduled_ = false;\n        var queue = mo.takeRecords();\n        removeTransientObserversFor(mo);\n        if (queue.length) {\n          mo.callback_(queue, mo);\n        }\n      }\n    }\n  }\n  function MutationRecord(type, target) {\n    this.type = type;\n    this.target = target;\n    this.addedNodes = new wrappers.NodeList();\n    this.removedNodes = new wrappers.NodeList();\n    this.previousSibling = null;\n    this.nextSibling = null;\n    this.attributeName = null;\n    this.attributeNamespace = null;\n    this.oldValue = null;\n  }\n  function registerTransientObservers(ancestor, node) {\n    for (;ancestor; ancestor = ancestor.parentNode) {\n      var registrations = registrationsTable.get(ancestor);\n      if (!registrations) continue;\n      for (var i = 0; i < registrations.length; i++) {\n        var registration = registrations[i];\n        if (registration.options.subtree) registration.addTransientObserver(node);\n      }\n    }\n  }\n  function removeTransientObserversFor(observer) {\n    for (var i = 0; i < observer.nodes_.length; i++) {\n      var node = observer.nodes_[i];\n      var registrations = registrationsTable.get(node);\n      if (!registrations) return;\n      for (var j = 0; j < registrations.length; j++) {\n        var registration = registrations[j];\n        if (registration.observer === observer) registration.removeTransientObservers();\n      }\n    }\n  }\n  function enqueueMutation(target, type, data) {\n    var interestedObservers = Object.create(null);\n    var associatedStrings = Object.create(null);\n    for (var node = target; node; node = node.parentNode) {\n      var registrations = registrationsTable.get(node);\n      if (!registrations) continue;\n      for (var j = 0; j < registrations.length; j++) {\n        var registration = registrations[j];\n        var options = registration.options;\n        if (node !== target && !options.subtree) continue;\n        if (type === \"attributes\" && !options.attributes) continue;\n        if (type === \"attributes\" && options.attributeFilter && (data.namespace !== null || options.attributeFilter.indexOf(data.name) === -1)) {\n          continue;\n        }\n        if (type === \"characterData\" && !options.characterData) continue;\n        if (type === \"childList\" && !options.childList) continue;\n        var observer = registration.observer;\n        interestedObservers[observer.uid_] = observer;\n        if (type === \"attributes\" && options.attributeOldValue || type === \"characterData\" && options.characterDataOldValue) {\n          associatedStrings[observer.uid_] = data.oldValue;\n        }\n      }\n    }\n    for (var uid in interestedObservers) {\n      var observer = interestedObservers[uid];\n      var record = new MutationRecord(type, target);\n      if (\"name\" in data && \"namespace\" in data) {\n        record.attributeName = data.name;\n        record.attributeNamespace = data.namespace;\n      }\n      if (data.addedNodes) record.addedNodes = data.addedNodes;\n      if (data.removedNodes) record.removedNodes = data.removedNodes;\n      if (data.previousSibling) record.previousSibling = data.previousSibling;\n      if (data.nextSibling) record.nextSibling = data.nextSibling;\n      if (associatedStrings[uid] !== undefined) record.oldValue = associatedStrings[uid];\n      scheduleCallback(observer);\n      observer.records_.push(record);\n    }\n  }\n  var slice = Array.prototype.slice;\n  function MutationObserverOptions(options) {\n    this.childList = !!options.childList;\n    this.subtree = !!options.subtree;\n    if (!(\"attributes\" in options) && (\"attributeOldValue\" in options || \"attributeFilter\" in options)) {\n      this.attributes = true;\n    } else {\n      this.attributes = !!options.attributes;\n    }\n    if (\"characterDataOldValue\" in options && !(\"characterData\" in options)) this.characterData = true; else this.characterData = !!options.characterData;\n    if (!this.attributes && (options.attributeOldValue || \"attributeFilter\" in options) || !this.characterData && options.characterDataOldValue) {\n      throw new TypeError();\n    }\n    this.characterData = !!options.characterData;\n    this.attributeOldValue = !!options.attributeOldValue;\n    this.characterDataOldValue = !!options.characterDataOldValue;\n    if (\"attributeFilter\" in options) {\n      if (options.attributeFilter == null || typeof options.attributeFilter !== \"object\") {\n        throw new TypeError();\n      }\n      this.attributeFilter = slice.call(options.attributeFilter);\n    } else {\n      this.attributeFilter = null;\n    }\n  }\n  var uidCounter = 0;\n  function MutationObserver(callback) {\n    this.callback_ = callback;\n    this.nodes_ = [];\n    this.records_ = [];\n    this.uid_ = ++uidCounter;\n    this.scheduled_ = false;\n  }\n  MutationObserver.prototype = {\n    constructor: MutationObserver,\n    observe: function(target, options) {\n      target = wrapIfNeeded(target);\n      var newOptions = new MutationObserverOptions(options);\n      var registration;\n      var registrations = registrationsTable.get(target);\n      if (!registrations) registrationsTable.set(target, registrations = []);\n      for (var i = 0; i < registrations.length; i++) {\n        if (registrations[i].observer === this) {\n          registration = registrations[i];\n          registration.removeTransientObservers();\n          registration.options = newOptions;\n        }\n      }\n      if (!registration) {\n        registration = new Registration(this, target, newOptions);\n        registrations.push(registration);\n        this.nodes_.push(target);\n      }\n    },\n    disconnect: function() {\n      this.nodes_.forEach(function(node) {\n        var registrations = registrationsTable.get(node);\n        for (var i = 0; i < registrations.length; i++) {\n          var registration = registrations[i];\n          if (registration.observer === this) {\n            registrations.splice(i, 1);\n            break;\n          }\n        }\n      }, this);\n      this.records_ = [];\n    },\n    takeRecords: function() {\n      var copyOfRecords = this.records_;\n      this.records_ = [];\n      return copyOfRecords;\n    }\n  };\n  function Registration(observer, target, options) {\n    this.observer = observer;\n    this.target = target;\n    this.options = options;\n    this.transientObservedNodes = [];\n  }\n  Registration.prototype = {\n    addTransientObserver: function(node) {\n      if (node === this.target) return;\n      scheduleCallback(this.observer);\n      this.transientObservedNodes.push(node);\n      var registrations = registrationsTable.get(node);\n      if (!registrations) registrationsTable.set(node, registrations = []);\n      registrations.push(this);\n    },\n    removeTransientObservers: function() {\n      var transientObservedNodes = this.transientObservedNodes;\n      this.transientObservedNodes = [];\n      for (var i = 0; i < transientObservedNodes.length; i++) {\n        var node = transientObservedNodes[i];\n        var registrations = registrationsTable.get(node);\n        for (var j = 0; j < registrations.length; j++) {\n          if (registrations[j] === this) {\n            registrations.splice(j, 1);\n            break;\n          }\n        }\n      }\n    }\n  };\n  scope.enqueueMutation = enqueueMutation;\n  scope.registerTransientObservers = registerTransientObservers;\n  scope.wrappers.MutationObserver = MutationObserver;\n  scope.wrappers.MutationRecord = MutationRecord;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  function TreeScope(root, parent) {\n    this.root = root;\n    this.parent = parent;\n  }\n  TreeScope.prototype = {\n    get renderer() {\n      if (this.root instanceof scope.wrappers.ShadowRoot) {\n        return scope.getRendererForHost(this.root.host);\n      }\n      return null;\n    },\n    contains: function(treeScope) {\n      for (;treeScope; treeScope = treeScope.parent) {\n        if (treeScope === this) return true;\n      }\n      return false;\n    }\n  };\n  function setTreeScope(node, treeScope) {\n    if (node.treeScope_ !== treeScope) {\n      node.treeScope_ = treeScope;\n      for (var sr = node.shadowRoot; sr; sr = sr.olderShadowRoot) {\n        sr.treeScope_.parent = treeScope;\n      }\n      for (var child = node.firstChild; child; child = child.nextSibling) {\n        setTreeScope(child, treeScope);\n      }\n    }\n  }\n  function getTreeScope(node) {\n    if (node instanceof scope.wrappers.Window) {\n      debugger;\n    }\n    if (node.treeScope_) return node.treeScope_;\n    var parent = node.parentNode;\n    var treeScope;\n    if (parent) treeScope = getTreeScope(parent); else treeScope = new TreeScope(node, null);\n    return node.treeScope_ = treeScope;\n  }\n  scope.TreeScope = TreeScope;\n  scope.getTreeScope = getTreeScope;\n  scope.setTreeScope = setTreeScope;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;\n  var getTreeScope = scope.getTreeScope;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var setWrapper = scope.setWrapper;\n  var unsafeUnwrap = scope.unsafeUnwrap;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var wrappers = scope.wrappers;\n  var wrappedFuns = new WeakMap();\n  var listenersTable = new WeakMap();\n  var handledEventsTable = new WeakMap();\n  var currentlyDispatchingEvents = new WeakMap();\n  var targetTable = new WeakMap();\n  var currentTargetTable = new WeakMap();\n  var relatedTargetTable = new WeakMap();\n  var eventPhaseTable = new WeakMap();\n  var stopPropagationTable = new WeakMap();\n  var stopImmediatePropagationTable = new WeakMap();\n  var eventHandlersTable = new WeakMap();\n  var eventPathTable = new WeakMap();\n  function isShadowRoot(node) {\n    return node instanceof wrappers.ShadowRoot;\n  }\n  function rootOfNode(node) {\n    return getTreeScope(node).root;\n  }\n  function getEventPath(node, event) {\n    var path = [];\n    var current = node;\n    path.push(current);\n    while (current) {\n      var destinationInsertionPoints = getDestinationInsertionPoints(current);\n      if (destinationInsertionPoints && destinationInsertionPoints.length > 0) {\n        for (var i = 0; i < destinationInsertionPoints.length; i++) {\n          var insertionPoint = destinationInsertionPoints[i];\n          if (isShadowInsertionPoint(insertionPoint)) {\n            var shadowRoot = rootOfNode(insertionPoint);\n            var olderShadowRoot = shadowRoot.olderShadowRoot;\n            if (olderShadowRoot) path.push(olderShadowRoot);\n          }\n          path.push(insertionPoint);\n        }\n        current = destinationInsertionPoints[destinationInsertionPoints.length - 1];\n      } else {\n        if (isShadowRoot(current)) {\n          if (inSameTree(node, current) && eventMustBeStopped(event)) {\n            break;\n          }\n          current = current.host;\n          path.push(current);\n        } else {\n          current = current.parentNode;\n          if (current) path.push(current);\n        }\n      }\n    }\n    return path;\n  }\n  function eventMustBeStopped(event) {\n    if (!event) return false;\n    switch (event.type) {\n     case \"abort\":\n     case \"error\":\n     case \"select\":\n     case \"change\":\n     case \"load\":\n     case \"reset\":\n     case \"resize\":\n     case \"scroll\":\n     case \"selectstart\":\n      return true;\n    }\n    return false;\n  }\n  function isShadowInsertionPoint(node) {\n    return node instanceof HTMLShadowElement;\n  }\n  function getDestinationInsertionPoints(node) {\n    return scope.getDestinationInsertionPoints(node);\n  }\n  function eventRetargetting(path, currentTarget) {\n    if (path.length === 0) return currentTarget;\n    if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;\n    var currentTargetTree = getTreeScope(currentTarget);\n    var originalTarget = path[0];\n    var originalTargetTree = getTreeScope(originalTarget);\n    var relativeTargetTree = lowestCommonInclusiveAncestor(currentTargetTree, originalTargetTree);\n    for (var i = 0; i < path.length; i++) {\n      var node = path[i];\n      if (getTreeScope(node) === relativeTargetTree) return node;\n    }\n    return path[path.length - 1];\n  }\n  function getTreeScopeAncestors(treeScope) {\n    var ancestors = [];\n    for (;treeScope; treeScope = treeScope.parent) {\n      ancestors.push(treeScope);\n    }\n    return ancestors;\n  }\n  function lowestCommonInclusiveAncestor(tsA, tsB) {\n    var ancestorsA = getTreeScopeAncestors(tsA);\n    var ancestorsB = getTreeScopeAncestors(tsB);\n    var result = null;\n    while (ancestorsA.length > 0 && ancestorsB.length > 0) {\n      var a = ancestorsA.pop();\n      var b = ancestorsB.pop();\n      if (a === b) result = a; else break;\n    }\n    return result;\n  }\n  function getTreeScopeRoot(ts) {\n    if (!ts.parent) return ts;\n    return getTreeScopeRoot(ts.parent);\n  }\n  function relatedTargetResolution(event, currentTarget, relatedTarget) {\n    if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;\n    var currentTargetTree = getTreeScope(currentTarget);\n    var relatedTargetTree = getTreeScope(relatedTarget);\n    var relatedTargetEventPath = getEventPath(relatedTarget, event);\n    var lowestCommonAncestorTree;\n    var lowestCommonAncestorTree = lowestCommonInclusiveAncestor(currentTargetTree, relatedTargetTree);\n    if (!lowestCommonAncestorTree) lowestCommonAncestorTree = relatedTargetTree.root;\n    for (var commonAncestorTree = lowestCommonAncestorTree; commonAncestorTree; commonAncestorTree = commonAncestorTree.parent) {\n      var adjustedRelatedTarget;\n      for (var i = 0; i < relatedTargetEventPath.length; i++) {\n        var node = relatedTargetEventPath[i];\n        if (getTreeScope(node) === commonAncestorTree) return node;\n      }\n    }\n    return null;\n  }\n  function inSameTree(a, b) {\n    return getTreeScope(a) === getTreeScope(b);\n  }\n  var NONE = 0;\n  var CAPTURING_PHASE = 1;\n  var AT_TARGET = 2;\n  var BUBBLING_PHASE = 3;\n  var pendingError;\n  function dispatchOriginalEvent(originalEvent) {\n    if (handledEventsTable.get(originalEvent)) return;\n    handledEventsTable.set(originalEvent, true);\n    dispatchEvent(wrap(originalEvent), wrap(originalEvent.target));\n    if (pendingError) {\n      var err = pendingError;\n      pendingError = null;\n      throw err;\n    }\n  }\n  function isLoadLikeEvent(event) {\n    switch (event.type) {\n     case \"load\":\n     case \"beforeunload\":\n     case \"unload\":\n      return true;\n    }\n    return false;\n  }\n  function dispatchEvent(event, originalWrapperTarget) {\n    if (currentlyDispatchingEvents.get(event)) throw new Error(\"InvalidStateError\");\n    currentlyDispatchingEvents.set(event, true);\n    scope.renderAllPending();\n    var eventPath;\n    var overrideTarget;\n    var win;\n    if (isLoadLikeEvent(event) && !event.bubbles) {\n      var doc = originalWrapperTarget;\n      if (doc instanceof wrappers.Document && (win = doc.defaultView)) {\n        overrideTarget = doc;\n        eventPath = [];\n      }\n    }\n    if (!eventPath) {\n      if (originalWrapperTarget instanceof wrappers.Window) {\n        win = originalWrapperTarget;\n        eventPath = [];\n      } else {\n        eventPath = getEventPath(originalWrapperTarget, event);\n        if (!isLoadLikeEvent(event)) {\n          var doc = eventPath[eventPath.length - 1];\n          if (doc instanceof wrappers.Document) win = doc.defaultView;\n        }\n      }\n    }\n    eventPathTable.set(event, eventPath);\n    if (dispatchCapturing(event, eventPath, win, overrideTarget)) {\n      if (dispatchAtTarget(event, eventPath, win, overrideTarget)) {\n        dispatchBubbling(event, eventPath, win, overrideTarget);\n      }\n    }\n    eventPhaseTable.set(event, NONE);\n    currentTargetTable.delete(event, null);\n    currentlyDispatchingEvents.delete(event);\n    return event.defaultPrevented;\n  }\n  function dispatchCapturing(event, eventPath, win, overrideTarget) {\n    var phase = CAPTURING_PHASE;\n    if (win) {\n      if (!invoke(win, event, phase, eventPath, overrideTarget)) return false;\n    }\n    for (var i = eventPath.length - 1; i > 0; i--) {\n      if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return false;\n    }\n    return true;\n  }\n  function dispatchAtTarget(event, eventPath, win, overrideTarget) {\n    var phase = AT_TARGET;\n    var currentTarget = eventPath[0] || win;\n    return invoke(currentTarget, event, phase, eventPath, overrideTarget);\n  }\n  function dispatchBubbling(event, eventPath, win, overrideTarget) {\n    var phase = BUBBLING_PHASE;\n    for (var i = 1; i < eventPath.length; i++) {\n      if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return;\n    }\n    if (win && eventPath.length > 0) {\n      invoke(win, event, phase, eventPath, overrideTarget);\n    }\n  }\n  function invoke(currentTarget, event, phase, eventPath, overrideTarget) {\n    var listeners = listenersTable.get(currentTarget);\n    if (!listeners) return true;\n    var target = overrideTarget || eventRetargetting(eventPath, currentTarget);\n    if (target === currentTarget) {\n      if (phase === CAPTURING_PHASE) return true;\n      if (phase === BUBBLING_PHASE) phase = AT_TARGET;\n    } else if (phase === BUBBLING_PHASE && !event.bubbles) {\n      return true;\n    }\n    if (\"relatedTarget\" in event) {\n      var originalEvent = unwrap(event);\n      var unwrappedRelatedTarget = originalEvent.relatedTarget;\n      if (unwrappedRelatedTarget) {\n        if (unwrappedRelatedTarget instanceof Object && unwrappedRelatedTarget.addEventListener) {\n          var relatedTarget = wrap(unwrappedRelatedTarget);\n          var adjusted = relatedTargetResolution(event, currentTarget, relatedTarget);\n          if (adjusted === target) return true;\n        } else {\n          adjusted = null;\n        }\n        relatedTargetTable.set(event, adjusted);\n      }\n    }\n    eventPhaseTable.set(event, phase);\n    var type = event.type;\n    var anyRemoved = false;\n    targetTable.set(event, target);\n    currentTargetTable.set(event, currentTarget);\n    listeners.depth++;\n    for (var i = 0, len = listeners.length; i < len; i++) {\n      var listener = listeners[i];\n      if (listener.removed) {\n        anyRemoved = true;\n        continue;\n      }\n      if (listener.type !== type || !listener.capture && phase === CAPTURING_PHASE || listener.capture && phase === BUBBLING_PHASE) {\n        continue;\n      }\n      try {\n        if (typeof listener.handler === \"function\") listener.handler.call(currentTarget, event); else listener.handler.handleEvent(event);\n        if (stopImmediatePropagationTable.get(event)) return false;\n      } catch (ex) {\n        if (!pendingError) pendingError = ex;\n      }\n    }\n    listeners.depth--;\n    if (anyRemoved && listeners.depth === 0) {\n      var copy = listeners.slice();\n      listeners.length = 0;\n      for (var i = 0; i < copy.length; i++) {\n        if (!copy[i].removed) listeners.push(copy[i]);\n      }\n    }\n    return !stopPropagationTable.get(event);\n  }\n  function Listener(type, handler, capture) {\n    this.type = type;\n    this.handler = handler;\n    this.capture = Boolean(capture);\n  }\n  Listener.prototype = {\n    equals: function(that) {\n      return this.handler === that.handler && this.type === that.type && this.capture === that.capture;\n    },\n    get removed() {\n      return this.handler === null;\n    },\n    remove: function() {\n      this.handler = null;\n    }\n  };\n  var OriginalEvent = window.Event;\n  OriginalEvent.prototype.polymerBlackList_ = {\n    returnValue: true,\n    keyLocation: true\n  };\n  function Event(type, options) {\n    if (type instanceof OriginalEvent) {\n      var impl = type;\n      if (!OriginalBeforeUnloadEvent && impl.type === \"beforeunload\" && !(this instanceof BeforeUnloadEvent)) {\n        return new BeforeUnloadEvent(impl);\n      }\n      setWrapper(impl, this);\n    } else {\n      return wrap(constructEvent(OriginalEvent, \"Event\", type, options));\n    }\n  }\n  Event.prototype = {\n    get target() {\n      return targetTable.get(this);\n    },\n    get currentTarget() {\n      return currentTargetTable.get(this);\n    },\n    get eventPhase() {\n      return eventPhaseTable.get(this);\n    },\n    get path() {\n      var eventPath = eventPathTable.get(this);\n      if (!eventPath) return [];\n      return eventPath.slice();\n    },\n    stopPropagation: function() {\n      stopPropagationTable.set(this, true);\n    },\n    stopImmediatePropagation: function() {\n      stopPropagationTable.set(this, true);\n      stopImmediatePropagationTable.set(this, true);\n    }\n  };\n  registerWrapper(OriginalEvent, Event, document.createEvent(\"Event\"));\n  function unwrapOptions(options) {\n    if (!options || !options.relatedTarget) return options;\n    return Object.create(options, {\n      relatedTarget: {\n        value: unwrap(options.relatedTarget)\n      }\n    });\n  }\n  function registerGenericEvent(name, SuperEvent, prototype) {\n    var OriginalEvent = window[name];\n    var GenericEvent = function(type, options) {\n      if (type instanceof OriginalEvent) setWrapper(type, this); else return wrap(constructEvent(OriginalEvent, name, type, options));\n    };\n    GenericEvent.prototype = Object.create(SuperEvent.prototype);\n    if (prototype) mixin(GenericEvent.prototype, prototype);\n    if (OriginalEvent) {\n      try {\n        registerWrapper(OriginalEvent, GenericEvent, new OriginalEvent(\"temp\"));\n      } catch (ex) {\n        registerWrapper(OriginalEvent, GenericEvent, document.createEvent(name));\n      }\n    }\n    return GenericEvent;\n  }\n  var UIEvent = registerGenericEvent(\"UIEvent\", Event);\n  var CustomEvent = registerGenericEvent(\"CustomEvent\", Event);\n  var relatedTargetProto = {\n    get relatedTarget() {\n      var relatedTarget = relatedTargetTable.get(this);\n      if (relatedTarget !== undefined) return relatedTarget;\n      return wrap(unwrap(this).relatedTarget);\n    }\n  };\n  function getInitFunction(name, relatedTargetIndex) {\n    return function() {\n      arguments[relatedTargetIndex] = unwrap(arguments[relatedTargetIndex]);\n      var impl = unwrap(this);\n      impl[name].apply(impl, arguments);\n    };\n  }\n  var mouseEventProto = mixin({\n    initMouseEvent: getInitFunction(\"initMouseEvent\", 14)\n  }, relatedTargetProto);\n  var focusEventProto = mixin({\n    initFocusEvent: getInitFunction(\"initFocusEvent\", 5)\n  }, relatedTargetProto);\n  var MouseEvent = registerGenericEvent(\"MouseEvent\", UIEvent, mouseEventProto);\n  var FocusEvent = registerGenericEvent(\"FocusEvent\", UIEvent, focusEventProto);\n  var defaultInitDicts = Object.create(null);\n  var supportsEventConstructors = function() {\n    try {\n      new window.FocusEvent(\"focus\");\n    } catch (ex) {\n      return false;\n    }\n    return true;\n  }();\n  function constructEvent(OriginalEvent, name, type, options) {\n    if (supportsEventConstructors) return new OriginalEvent(type, unwrapOptions(options));\n    var event = unwrap(document.createEvent(name));\n    var defaultDict = defaultInitDicts[name];\n    var args = [ type ];\n    Object.keys(defaultDict).forEach(function(key) {\n      var v = options != null && key in options ? options[key] : defaultDict[key];\n      if (key === \"relatedTarget\") v = unwrap(v);\n      args.push(v);\n    });\n    event[\"init\" + name].apply(event, args);\n    return event;\n  }\n  if (!supportsEventConstructors) {\n    var configureEventConstructor = function(name, initDict, superName) {\n      if (superName) {\n        var superDict = defaultInitDicts[superName];\n        initDict = mixin(mixin({}, superDict), initDict);\n      }\n      defaultInitDicts[name] = initDict;\n    };\n    configureEventConstructor(\"Event\", {\n      bubbles: false,\n      cancelable: false\n    });\n    configureEventConstructor(\"CustomEvent\", {\n      detail: null\n    }, \"Event\");\n    configureEventConstructor(\"UIEvent\", {\n      view: null,\n      detail: 0\n    }, \"Event\");\n    configureEventConstructor(\"MouseEvent\", {\n      screenX: 0,\n      screenY: 0,\n      clientX: 0,\n      clientY: 0,\n      ctrlKey: false,\n      altKey: false,\n      shiftKey: false,\n      metaKey: false,\n      button: 0,\n      relatedTarget: null\n    }, \"UIEvent\");\n    configureEventConstructor(\"FocusEvent\", {\n      relatedTarget: null\n    }, \"UIEvent\");\n  }\n  var OriginalBeforeUnloadEvent = window.BeforeUnloadEvent;\n  function BeforeUnloadEvent(impl) {\n    Event.call(this, impl);\n  }\n  BeforeUnloadEvent.prototype = Object.create(Event.prototype);\n  mixin(BeforeUnloadEvent.prototype, {\n    get returnValue() {\n      return unsafeUnwrap(this).returnValue;\n    },\n    set returnValue(v) {\n      unsafeUnwrap(this).returnValue = v;\n    }\n  });\n  if (OriginalBeforeUnloadEvent) registerWrapper(OriginalBeforeUnloadEvent, BeforeUnloadEvent);\n  function isValidListener(fun) {\n    if (typeof fun === \"function\") return true;\n    return fun && fun.handleEvent;\n  }\n  function isMutationEvent(type) {\n    switch (type) {\n     case \"DOMAttrModified\":\n     case \"DOMAttributeNameChanged\":\n     case \"DOMCharacterDataModified\":\n     case \"DOMElementNameChanged\":\n     case \"DOMNodeInserted\":\n     case \"DOMNodeInsertedIntoDocument\":\n     case \"DOMNodeRemoved\":\n     case \"DOMNodeRemovedFromDocument\":\n     case \"DOMSubtreeModified\":\n      return true;\n    }\n    return false;\n  }\n  var OriginalEventTarget = window.EventTarget;\n  function EventTarget(impl) {\n    setWrapper(impl, this);\n  }\n  var methodNames = [ \"addEventListener\", \"removeEventListener\", \"dispatchEvent\" ];\n  [ Node, Window ].forEach(function(constructor) {\n    var p = constructor.prototype;\n    methodNames.forEach(function(name) {\n      Object.defineProperty(p, name + \"_\", {\n        value: p[name]\n      });\n    });\n  });\n  function getTargetToListenAt(wrapper) {\n    if (wrapper instanceof wrappers.ShadowRoot) wrapper = wrapper.host;\n    return unwrap(wrapper);\n  }\n  EventTarget.prototype = {\n    addEventListener: function(type, fun, capture) {\n      if (!isValidListener(fun) || isMutationEvent(type)) return;\n      var listener = new Listener(type, fun, capture);\n      var listeners = listenersTable.get(this);\n      if (!listeners) {\n        listeners = [];\n        listeners.depth = 0;\n        listenersTable.set(this, listeners);\n      } else {\n        for (var i = 0; i < listeners.length; i++) {\n          if (listener.equals(listeners[i])) return;\n        }\n      }\n      listeners.push(listener);\n      var target = getTargetToListenAt(this);\n      target.addEventListener_(type, dispatchOriginalEvent, true);\n    },\n    removeEventListener: function(type, fun, capture) {\n      capture = Boolean(capture);\n      var listeners = listenersTable.get(this);\n      if (!listeners) return;\n      var count = 0, found = false;\n      for (var i = 0; i < listeners.length; i++) {\n        if (listeners[i].type === type && listeners[i].capture === capture) {\n          count++;\n          if (listeners[i].handler === fun) {\n            found = true;\n            listeners[i].remove();\n          }\n        }\n      }\n      if (found && count === 1) {\n        var target = getTargetToListenAt(this);\n        target.removeEventListener_(type, dispatchOriginalEvent, true);\n      }\n    },\n    dispatchEvent: function(event) {\n      var nativeEvent = unwrap(event);\n      var eventType = nativeEvent.type;\n      handledEventsTable.set(nativeEvent, false);\n      scope.renderAllPending();\n      var tempListener;\n      if (!hasListenerInAncestors(this, eventType)) {\n        tempListener = function() {};\n        this.addEventListener(eventType, tempListener, true);\n      }\n      try {\n        return unwrap(this).dispatchEvent_(nativeEvent);\n      } finally {\n        if (tempListener) this.removeEventListener(eventType, tempListener, true);\n      }\n    }\n  };\n  function hasListener(node, type) {\n    var listeners = listenersTable.get(node);\n    if (listeners) {\n      for (var i = 0; i < listeners.length; i++) {\n        if (!listeners[i].removed && listeners[i].type === type) return true;\n      }\n    }\n    return false;\n  }\n  function hasListenerInAncestors(target, type) {\n    for (var node = unwrap(target); node; node = node.parentNode) {\n      if (hasListener(wrap(node), type)) return true;\n    }\n    return false;\n  }\n  if (OriginalEventTarget) registerWrapper(OriginalEventTarget, EventTarget);\n  function wrapEventTargetMethods(constructors) {\n    forwardMethodsToWrapper(constructors, methodNames);\n  }\n  var originalElementFromPoint = document.elementFromPoint;\n  function elementFromPoint(self, document, x, y) {\n    scope.renderAllPending();\n    var element = wrap(originalElementFromPoint.call(unsafeUnwrap(document), x, y));\n    if (!element) return null;\n    var path = getEventPath(element, null);\n    var idx = path.lastIndexOf(self);\n    if (idx == -1) return null; else path = path.slice(0, idx);\n    return eventRetargetting(path, self);\n  }\n  function getEventHandlerGetter(name) {\n    return function() {\n      var inlineEventHandlers = eventHandlersTable.get(this);\n      return inlineEventHandlers && inlineEventHandlers[name] && inlineEventHandlers[name].value || null;\n    };\n  }\n  function getEventHandlerSetter(name) {\n    var eventType = name.slice(2);\n    return function(value) {\n      var inlineEventHandlers = eventHandlersTable.get(this);\n      if (!inlineEventHandlers) {\n        inlineEventHandlers = Object.create(null);\n        eventHandlersTable.set(this, inlineEventHandlers);\n      }\n      var old = inlineEventHandlers[name];\n      if (old) this.removeEventListener(eventType, old.wrapped, false);\n      if (typeof value === \"function\") {\n        var wrapped = function(e) {\n          var rv = value.call(this, e);\n          if (rv === false) e.preventDefault(); else if (name === \"onbeforeunload\" && typeof rv === \"string\") e.returnValue = rv;\n        };\n        this.addEventListener(eventType, wrapped, false);\n        inlineEventHandlers[name] = {\n          value: value,\n          wrapped: wrapped\n        };\n      }\n    };\n  }\n  scope.elementFromPoint = elementFromPoint;\n  scope.getEventHandlerGetter = getEventHandlerGetter;\n  scope.getEventHandlerSetter = getEventHandlerSetter;\n  scope.wrapEventTargetMethods = wrapEventTargetMethods;\n  scope.wrappers.BeforeUnloadEvent = BeforeUnloadEvent;\n  scope.wrappers.CustomEvent = CustomEvent;\n  scope.wrappers.Event = Event;\n  scope.wrappers.EventTarget = EventTarget;\n  scope.wrappers.FocusEvent = FocusEvent;\n  scope.wrappers.MouseEvent = MouseEvent;\n  scope.wrappers.UIEvent = UIEvent;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var UIEvent = scope.wrappers.UIEvent;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var setWrapper = scope.setWrapper;\n  var unsafeUnwrap = scope.unsafeUnwrap;\n  var wrap = scope.wrap;\n  var OriginalTouchEvent = window.TouchEvent;\n  if (!OriginalTouchEvent) return;\n  var nativeEvent;\n  try {\n    nativeEvent = document.createEvent(\"TouchEvent\");\n  } catch (ex) {\n    return;\n  }\n  var nonEnumDescriptor = {\n    enumerable: false\n  };\n  function nonEnum(obj, prop) {\n    Object.defineProperty(obj, prop, nonEnumDescriptor);\n  }\n  function Touch(impl) {\n    setWrapper(impl, this);\n  }\n  Touch.prototype = {\n    get target() {\n      return wrap(unsafeUnwrap(this).target);\n    }\n  };\n  var descr = {\n    configurable: true,\n    enumerable: true,\n    get: null\n  };\n  [ \"clientX\", \"clientY\", \"screenX\", \"screenY\", \"pageX\", \"pageY\", \"identifier\", \"webkitRadiusX\", \"webkitRadiusY\", \"webkitRotationAngle\", \"webkitForce\" ].forEach(function(name) {\n    descr.get = function() {\n      return unsafeUnwrap(this)[name];\n    };\n    Object.defineProperty(Touch.prototype, name, descr);\n  });\n  function TouchList() {\n    this.length = 0;\n    nonEnum(this, \"length\");\n  }\n  TouchList.prototype = {\n    item: function(index) {\n      return this[index];\n    }\n  };\n  function wrapTouchList(nativeTouchList) {\n    var list = new TouchList();\n    for (var i = 0; i < nativeTouchList.length; i++) {\n      list[i] = new Touch(nativeTouchList[i]);\n    }\n    list.length = i;\n    return list;\n  }\n  function TouchEvent(impl) {\n    UIEvent.call(this, impl);\n  }\n  TouchEvent.prototype = Object.create(UIEvent.prototype);\n  mixin(TouchEvent.prototype, {\n    get touches() {\n      return wrapTouchList(unsafeUnwrap(this).touches);\n    },\n    get targetTouches() {\n      return wrapTouchList(unsafeUnwrap(this).targetTouches);\n    },\n    get changedTouches() {\n      return wrapTouchList(unsafeUnwrap(this).changedTouches);\n    },\n    initTouchEvent: function() {\n      throw new Error(\"Not implemented\");\n    }\n  });\n  registerWrapper(OriginalTouchEvent, TouchEvent, nativeEvent);\n  scope.wrappers.Touch = Touch;\n  scope.wrappers.TouchEvent = TouchEvent;\n  scope.wrappers.TouchList = TouchList;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var unsafeUnwrap = scope.unsafeUnwrap;\n  var wrap = scope.wrap;\n  var nonEnumDescriptor = {\n    enumerable: false\n  };\n  function nonEnum(obj, prop) {\n    Object.defineProperty(obj, prop, nonEnumDescriptor);\n  }\n  function NodeList() {\n    this.length = 0;\n    nonEnum(this, \"length\");\n  }\n  NodeList.prototype = {\n    item: function(index) {\n      return this[index];\n    }\n  };\n  nonEnum(NodeList.prototype, \"item\");\n  function wrapNodeList(list) {\n    if (list == null) return list;\n    var wrapperList = new NodeList();\n    for (var i = 0, length = list.length; i < length; i++) {\n      wrapperList[i] = wrap(list[i]);\n    }\n    wrapperList.length = length;\n    return wrapperList;\n  }\n  function addWrapNodeListMethod(wrapperConstructor, name) {\n    wrapperConstructor.prototype[name] = function() {\n      return wrapNodeList(unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments));\n    };\n  }\n  scope.wrappers.NodeList = NodeList;\n  scope.addWrapNodeListMethod = addWrapNodeListMethod;\n  scope.wrapNodeList = wrapNodeList;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  scope.wrapHTMLCollection = scope.wrapNodeList;\n  scope.wrappers.HTMLCollection = scope.wrappers.NodeList;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var EventTarget = scope.wrappers.EventTarget;\n  var NodeList = scope.wrappers.NodeList;\n  var TreeScope = scope.TreeScope;\n  var assert = scope.assert;\n  var defineWrapGetter = scope.defineWrapGetter;\n  var enqueueMutation = scope.enqueueMutation;\n  var getTreeScope = scope.getTreeScope;\n  var isWrapper = scope.isWrapper;\n  var mixin = scope.mixin;\n  var registerTransientObservers = scope.registerTransientObservers;\n  var registerWrapper = scope.registerWrapper;\n  var setTreeScope = scope.setTreeScope;\n  var unsafeUnwrap = scope.unsafeUnwrap;\n  var unwrap = scope.unwrap;\n  var unwrapIfNeeded = scope.unwrapIfNeeded;\n  var wrap = scope.wrap;\n  var wrapIfNeeded = scope.wrapIfNeeded;\n  var wrappers = scope.wrappers;\n  function assertIsNodeWrapper(node) {\n    assert(node instanceof Node);\n  }\n  function createOneElementNodeList(node) {\n    var nodes = new NodeList();\n    nodes[0] = node;\n    nodes.length = 1;\n    return nodes;\n  }\n  var surpressMutations = false;\n  function enqueueRemovalForInsertedNodes(node, parent, nodes) {\n    enqueueMutation(parent, \"childList\", {\n      removedNodes: nodes,\n      previousSibling: node.previousSibling,\n      nextSibling: node.nextSibling\n    });\n  }\n  function enqueueRemovalForInsertedDocumentFragment(df, nodes) {\n    enqueueMutation(df, \"childList\", {\n      removedNodes: nodes\n    });\n  }\n  function collectNodes(node, parentNode, previousNode, nextNode) {\n    if (node instanceof DocumentFragment) {\n      var nodes = collectNodesForDocumentFragment(node);\n      surpressMutations = true;\n      for (var i = nodes.length - 1; i >= 0; i--) {\n        node.removeChild(nodes[i]);\n        nodes[i].parentNode_ = parentNode;\n      }\n      surpressMutations = false;\n      for (var i = 0; i < nodes.length; i++) {\n        nodes[i].previousSibling_ = nodes[i - 1] || previousNode;\n        nodes[i].nextSibling_ = nodes[i + 1] || nextNode;\n      }\n      if (previousNode) previousNode.nextSibling_ = nodes[0];\n      if (nextNode) nextNode.previousSibling_ = nodes[nodes.length - 1];\n      return nodes;\n    }\n    var nodes = createOneElementNodeList(node);\n    var oldParent = node.parentNode;\n    if (oldParent) {\n      oldParent.removeChild(node);\n    }\n    node.parentNode_ = parentNode;\n    node.previousSibling_ = previousNode;\n    node.nextSibling_ = nextNode;\n    if (previousNode) previousNode.nextSibling_ = node;\n    if (nextNode) nextNode.previousSibling_ = node;\n    return nodes;\n  }\n  function collectNodesNative(node) {\n    if (node instanceof DocumentFragment) return collectNodesForDocumentFragment(node);\n    var nodes = createOneElementNodeList(node);\n    var oldParent = node.parentNode;\n    if (oldParent) enqueueRemovalForInsertedNodes(node, oldParent, nodes);\n    return nodes;\n  }\n  function collectNodesForDocumentFragment(node) {\n    var nodes = new NodeList();\n    var i = 0;\n    for (var child = node.firstChild; child; child = child.nextSibling) {\n      nodes[i++] = child;\n    }\n    nodes.length = i;\n    enqueueRemovalForInsertedDocumentFragment(node, nodes);\n    return nodes;\n  }\n  function snapshotNodeList(nodeList) {\n    return nodeList;\n  }\n  function nodeWasAdded(node, treeScope) {\n    setTreeScope(node, treeScope);\n    node.nodeIsInserted_();\n  }\n  function nodesWereAdded(nodes, parent) {\n    var treeScope = getTreeScope(parent);\n    for (var i = 0; i < nodes.length; i++) {\n      nodeWasAdded(nodes[i], treeScope);\n    }\n  }\n  function nodeWasRemoved(node) {\n    setTreeScope(node, new TreeScope(node, null));\n  }\n  function nodesWereRemoved(nodes) {\n    for (var i = 0; i < nodes.length; i++) {\n      nodeWasRemoved(nodes[i]);\n    }\n  }\n  function ensureSameOwnerDocument(parent, child) {\n    var ownerDoc = parent.nodeType === Node.DOCUMENT_NODE ? parent : parent.ownerDocument;\n    if (ownerDoc !== child.ownerDocument) ownerDoc.adoptNode(child);\n  }\n  function adoptNodesIfNeeded(owner, nodes) {\n    if (!nodes.length) return;\n    var ownerDoc = owner.ownerDocument;\n    if (ownerDoc === nodes[0].ownerDocument) return;\n    for (var i = 0; i < nodes.length; i++) {\n      scope.adoptNodeNoRemove(nodes[i], ownerDoc);\n    }\n  }\n  function unwrapNodesForInsertion(owner, nodes) {\n    adoptNodesIfNeeded(owner, nodes);\n    var length = nodes.length;\n    if (length === 1) return unwrap(nodes[0]);\n    var df = unwrap(owner.ownerDocument.createDocumentFragment());\n    for (var i = 0; i < length; i++) {\n      df.appendChild(unwrap(nodes[i]));\n    }\n    return df;\n  }\n  function clearChildNodes(wrapper) {\n    if (wrapper.firstChild_ !== undefined) {\n      var child = wrapper.firstChild_;\n      while (child) {\n        var tmp = child;\n        child = child.nextSibling_;\n        tmp.parentNode_ = tmp.previousSibling_ = tmp.nextSibling_ = undefined;\n      }\n    }\n    wrapper.firstChild_ = wrapper.lastChild_ = undefined;\n  }\n  function removeAllChildNodes(wrapper) {\n    if (wrapper.invalidateShadowRenderer()) {\n      var childWrapper = wrapper.firstChild;\n      while (childWrapper) {\n        assert(childWrapper.parentNode === wrapper);\n        var nextSibling = childWrapper.nextSibling;\n        var childNode = unwrap(childWrapper);\n        var parentNode = childNode.parentNode;\n        if (parentNode) originalRemoveChild.call(parentNode, childNode);\n        childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = null;\n        childWrapper = nextSibling;\n      }\n      wrapper.firstChild_ = wrapper.lastChild_ = null;\n    } else {\n      var node = unwrap(wrapper);\n      var child = node.firstChild;\n      var nextSibling;\n      while (child) {\n        nextSibling = child.nextSibling;\n        originalRemoveChild.call(node, child);\n        child = nextSibling;\n      }\n    }\n  }\n  function invalidateParent(node) {\n    var p = node.parentNode;\n    return p && p.invalidateShadowRenderer();\n  }\n  function cleanupNodes(nodes) {\n    for (var i = 0, n; i < nodes.length; i++) {\n      n = nodes[i];\n      n.parentNode.removeChild(n);\n    }\n  }\n  var originalImportNode = document.importNode;\n  var originalCloneNode = window.Node.prototype.cloneNode;\n  function cloneNode(node, deep, opt_doc) {\n    var clone;\n    if (opt_doc) clone = wrap(originalImportNode.call(opt_doc, unsafeUnwrap(node), false)); else clone = wrap(originalCloneNode.call(unsafeUnwrap(node), false));\n    if (deep) {\n      for (var child = node.firstChild; child; child = child.nextSibling) {\n        clone.appendChild(cloneNode(child, true, opt_doc));\n      }\n      if (node instanceof wrappers.HTMLTemplateElement) {\n        var cloneContent = clone.content;\n        for (var child = node.content.firstChild; child; child = child.nextSibling) {\n          cloneContent.appendChild(cloneNode(child, true, opt_doc));\n        }\n      }\n    }\n    return clone;\n  }\n  function contains(self, child) {\n    if (!child || getTreeScope(self) !== getTreeScope(child)) return false;\n    for (var node = child; node; node = node.parentNode) {\n      if (node === self) return true;\n    }\n    return false;\n  }\n  var OriginalNode = window.Node;\n  function Node(original) {\n    assert(original instanceof OriginalNode);\n    EventTarget.call(this, original);\n    this.parentNode_ = undefined;\n    this.firstChild_ = undefined;\n    this.lastChild_ = undefined;\n    this.nextSibling_ = undefined;\n    this.previousSibling_ = undefined;\n    this.treeScope_ = undefined;\n  }\n  var OriginalDocumentFragment = window.DocumentFragment;\n  var originalAppendChild = OriginalNode.prototype.appendChild;\n  var originalCompareDocumentPosition = OriginalNode.prototype.compareDocumentPosition;\n  var originalIsEqualNode = OriginalNode.prototype.isEqualNode;\n  var originalInsertBefore = OriginalNode.prototype.insertBefore;\n  var originalRemoveChild = OriginalNode.prototype.removeChild;\n  var originalReplaceChild = OriginalNode.prototype.replaceChild;\n  var isIe = /Trident|Edge/.test(navigator.userAgent);\n  var removeChildOriginalHelper = isIe ? function(parent, child) {\n    try {\n      originalRemoveChild.call(parent, child);\n    } catch (ex) {\n      if (!(parent instanceof OriginalDocumentFragment)) throw ex;\n    }\n  } : function(parent, child) {\n    originalRemoveChild.call(parent, child);\n  };\n  Node.prototype = Object.create(EventTarget.prototype);\n  mixin(Node.prototype, {\n    appendChild: function(childWrapper) {\n      return this.insertBefore(childWrapper, null);\n    },\n    insertBefore: function(childWrapper, refWrapper) {\n      assertIsNodeWrapper(childWrapper);\n      var refNode;\n      if (refWrapper) {\n        if (isWrapper(refWrapper)) {\n          refNode = unwrap(refWrapper);\n        } else {\n          refNode = refWrapper;\n          refWrapper = wrap(refNode);\n        }\n      } else {\n        refWrapper = null;\n        refNode = null;\n      }\n      refWrapper && assert(refWrapper.parentNode === this);\n      var nodes;\n      var previousNode = refWrapper ? refWrapper.previousSibling : this.lastChild;\n      var useNative = !this.invalidateShadowRenderer() && !invalidateParent(childWrapper);\n      if (useNative) nodes = collectNodesNative(childWrapper); else nodes = collectNodes(childWrapper, this, previousNode, refWrapper);\n      if (useNative) {\n        ensureSameOwnerDocument(this, childWrapper);\n        clearChildNodes(this);\n        originalInsertBefore.call(unsafeUnwrap(this), unwrap(childWrapper), refNode);\n      } else {\n        if (!previousNode) this.firstChild_ = nodes[0];\n        if (!refWrapper) {\n          this.lastChild_ = nodes[nodes.length - 1];\n          if (this.firstChild_ === undefined) this.firstChild_ = this.firstChild;\n        }\n        var parentNode = refNode ? refNode.parentNode : unsafeUnwrap(this);\n        if (parentNode) {\n          originalInsertBefore.call(parentNode, unwrapNodesForInsertion(this, nodes), refNode);\n        } else {\n          adoptNodesIfNeeded(this, nodes);\n        }\n      }\n      enqueueMutation(this, \"childList\", {\n        addedNodes: nodes,\n        nextSibling: refWrapper,\n        previousSibling: previousNode\n      });\n      nodesWereAdded(nodes, this);\n      return childWrapper;\n    },\n    removeChild: function(childWrapper) {\n      assertIsNodeWrapper(childWrapper);\n      if (childWrapper.parentNode !== this) {\n        var found = false;\n        var childNodes = this.childNodes;\n        for (var ieChild = this.firstChild; ieChild; ieChild = ieChild.nextSibling) {\n          if (ieChild === childWrapper) {\n            found = true;\n            break;\n          }\n        }\n        if (!found) {\n          throw new Error(\"NotFoundError\");\n        }\n      }\n      var childNode = unwrap(childWrapper);\n      var childWrapperNextSibling = childWrapper.nextSibling;\n      var childWrapperPreviousSibling = childWrapper.previousSibling;\n      if (this.invalidateShadowRenderer()) {\n        var thisFirstChild = this.firstChild;\n        var thisLastChild = this.lastChild;\n        var parentNode = childNode.parentNode;\n        if (parentNode) removeChildOriginalHelper(parentNode, childNode);\n        if (thisFirstChild === childWrapper) this.firstChild_ = childWrapperNextSibling;\n        if (thisLastChild === childWrapper) this.lastChild_ = childWrapperPreviousSibling;\n        if (childWrapperPreviousSibling) childWrapperPreviousSibling.nextSibling_ = childWrapperNextSibling;\n        if (childWrapperNextSibling) {\n          childWrapperNextSibling.previousSibling_ = childWrapperPreviousSibling;\n        }\n        childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = undefined;\n      } else {\n        clearChildNodes(this);\n        removeChildOriginalHelper(unsafeUnwrap(this), childNode);\n      }\n      if (!surpressMutations) {\n        enqueueMutation(this, \"childList\", {\n          removedNodes: createOneElementNodeList(childWrapper),\n          nextSibling: childWrapperNextSibling,\n          previousSibling: childWrapperPreviousSibling\n        });\n      }\n      registerTransientObservers(this, childWrapper);\n      return childWrapper;\n    },\n    replaceChild: function(newChildWrapper, oldChildWrapper) {\n      assertIsNodeWrapper(newChildWrapper);\n      var oldChildNode;\n      if (isWrapper(oldChildWrapper)) {\n        oldChildNode = unwrap(oldChildWrapper);\n      } else {\n        oldChildNode = oldChildWrapper;\n        oldChildWrapper = wrap(oldChildNode);\n      }\n      if (oldChildWrapper.parentNode !== this) {\n        throw new Error(\"NotFoundError\");\n      }\n      var nextNode = oldChildWrapper.nextSibling;\n      var previousNode = oldChildWrapper.previousSibling;\n      var nodes;\n      var useNative = !this.invalidateShadowRenderer() && !invalidateParent(newChildWrapper);\n      if (useNative) {\n        nodes = collectNodesNative(newChildWrapper);\n      } else {\n        if (nextNode === newChildWrapper) nextNode = newChildWrapper.nextSibling;\n        nodes = collectNodes(newChildWrapper, this, previousNode, nextNode);\n      }\n      if (!useNative) {\n        if (this.firstChild === oldChildWrapper) this.firstChild_ = nodes[0];\n        if (this.lastChild === oldChildWrapper) this.lastChild_ = nodes[nodes.length - 1];\n        oldChildWrapper.previousSibling_ = oldChildWrapper.nextSibling_ = oldChildWrapper.parentNode_ = undefined;\n        if (oldChildNode.parentNode) {\n          originalReplaceChild.call(oldChildNode.parentNode, unwrapNodesForInsertion(this, nodes), oldChildNode);\n        }\n      } else {\n        ensureSameOwnerDocument(this, newChildWrapper);\n        clearChildNodes(this);\n        originalReplaceChild.call(unsafeUnwrap(this), unwrap(newChildWrapper), oldChildNode);\n      }\n      enqueueMutation(this, \"childList\", {\n        addedNodes: nodes,\n        removedNodes: createOneElementNodeList(oldChildWrapper),\n        nextSibling: nextNode,\n        previousSibling: previousNode\n      });\n      nodeWasRemoved(oldChildWrapper);\n      nodesWereAdded(nodes, this);\n      return oldChildWrapper;\n    },\n    nodeIsInserted_: function() {\n      for (var child = this.firstChild; child; child = child.nextSibling) {\n        child.nodeIsInserted_();\n      }\n    },\n    hasChildNodes: function() {\n      return this.firstChild !== null;\n    },\n    get parentNode() {\n      return this.parentNode_ !== undefined ? this.parentNode_ : wrap(unsafeUnwrap(this).parentNode);\n    },\n    get firstChild() {\n      return this.firstChild_ !== undefined ? this.firstChild_ : wrap(unsafeUnwrap(this).firstChild);\n    },\n    get lastChild() {\n      return this.lastChild_ !== undefined ? this.lastChild_ : wrap(unsafeUnwrap(this).lastChild);\n    },\n    get nextSibling() {\n      return this.nextSibling_ !== undefined ? this.nextSibling_ : wrap(unsafeUnwrap(this).nextSibling);\n    },\n    get previousSibling() {\n      return this.previousSibling_ !== undefined ? this.previousSibling_ : wrap(unsafeUnwrap(this).previousSibling);\n    },\n    get parentElement() {\n      var p = this.parentNode;\n      while (p && p.nodeType !== Node.ELEMENT_NODE) {\n        p = p.parentNode;\n      }\n      return p;\n    },\n    get textContent() {\n      var s = \"\";\n      for (var child = this.firstChild; child; child = child.nextSibling) {\n        if (child.nodeType != Node.COMMENT_NODE) {\n          s += child.textContent;\n        }\n      }\n      return s;\n    },\n    set textContent(textContent) {\n      if (textContent == null) textContent = \"\";\n      var removedNodes = snapshotNodeList(this.childNodes);\n      if (this.invalidateShadowRenderer()) {\n        removeAllChildNodes(this);\n        if (textContent !== \"\") {\n          var textNode = unsafeUnwrap(this).ownerDocument.createTextNode(textContent);\n          this.appendChild(textNode);\n        }\n      } else {\n        clearChildNodes(this);\n        unsafeUnwrap(this).textContent = textContent;\n      }\n      var addedNodes = snapshotNodeList(this.childNodes);\n      enqueueMutation(this, \"childList\", {\n        addedNodes: addedNodes,\n        removedNodes: removedNodes\n      });\n      nodesWereRemoved(removedNodes);\n      nodesWereAdded(addedNodes, this);\n    },\n    get childNodes() {\n      var wrapperList = new NodeList();\n      var i = 0;\n      for (var child = this.firstChild; child; child = child.nextSibling) {\n        wrapperList[i++] = child;\n      }\n      wrapperList.length = i;\n      return wrapperList;\n    },\n    cloneNode: function(deep) {\n      return cloneNode(this, deep);\n    },\n    contains: function(child) {\n      return contains(this, wrapIfNeeded(child));\n    },\n    compareDocumentPosition: function(otherNode) {\n      return originalCompareDocumentPosition.call(unsafeUnwrap(this), unwrapIfNeeded(otherNode));\n    },\n    isEqualNode: function(otherNode) {\n      return originalIsEqualNode.call(unsafeUnwrap(this), unwrapIfNeeded(otherNode));\n    },\n    normalize: function() {\n      var nodes = snapshotNodeList(this.childNodes);\n      var remNodes = [];\n      var s = \"\";\n      var modNode;\n      for (var i = 0, n; i < nodes.length; i++) {\n        n = nodes[i];\n        if (n.nodeType === Node.TEXT_NODE) {\n          if (!modNode && !n.data.length) this.removeChild(n); else if (!modNode) modNode = n; else {\n            s += n.data;\n            remNodes.push(n);\n          }\n        } else {\n          if (modNode && remNodes.length) {\n            modNode.data += s;\n            cleanupNodes(remNodes);\n          }\n          remNodes = [];\n          s = \"\";\n          modNode = null;\n          if (n.childNodes.length) n.normalize();\n        }\n      }\n      if (modNode && remNodes.length) {\n        modNode.data += s;\n        cleanupNodes(remNodes);\n      }\n    }\n  });\n  defineWrapGetter(Node, \"ownerDocument\");\n  registerWrapper(OriginalNode, Node, document.createDocumentFragment());\n  delete Node.prototype.querySelector;\n  delete Node.prototype.querySelectorAll;\n  Node.prototype = mixin(Object.create(EventTarget.prototype), Node.prototype);\n  scope.cloneNode = cloneNode;\n  scope.nodeWasAdded = nodeWasAdded;\n  scope.nodeWasRemoved = nodeWasRemoved;\n  scope.nodesWereAdded = nodesWereAdded;\n  scope.nodesWereRemoved = nodesWereRemoved;\n  scope.originalInsertBefore = originalInsertBefore;\n  scope.originalRemoveChild = originalRemoveChild;\n  scope.snapshotNodeList = snapshotNodeList;\n  scope.wrappers.Node = Node;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var HTMLCollection = scope.wrappers.HTMLCollection;\n  var NodeList = scope.wrappers.NodeList;\n  var getTreeScope = scope.getTreeScope;\n  var unsafeUnwrap = scope.unsafeUnwrap;\n  var wrap = scope.wrap;\n  var originalDocumentQuerySelector = document.querySelector;\n  var originalElementQuerySelector = document.documentElement.querySelector;\n  var originalDocumentQuerySelectorAll = document.querySelectorAll;\n  var originalElementQuerySelectorAll = document.documentElement.querySelectorAll;\n  var originalDocumentGetElementsByTagName = document.getElementsByTagName;\n  var originalElementGetElementsByTagName = document.documentElement.getElementsByTagName;\n  var originalDocumentGetElementsByTagNameNS = document.getElementsByTagNameNS;\n  var originalElementGetElementsByTagNameNS = document.documentElement.getElementsByTagNameNS;\n  var OriginalElement = window.Element;\n  var OriginalDocument = window.HTMLDocument || window.Document;\n  function filterNodeList(list, index, result, deep) {\n    var wrappedItem = null;\n    var root = null;\n    for (var i = 0, length = list.length; i < length; i++) {\n      wrappedItem = wrap(list[i]);\n      if (!deep && (root = getTreeScope(wrappedItem).root)) {\n        if (root instanceof scope.wrappers.ShadowRoot) {\n          continue;\n        }\n      }\n      result[index++] = wrappedItem;\n    }\n    return index;\n  }\n  function shimSelector(selector) {\n    return String(selector).replace(/\\/deep\\/|::shadow|>>>/g, \" \");\n  }\n  function shimMatchesSelector(selector) {\n    return String(selector).replace(/:host\\(([^\\s]+)\\)/g, \"$1\").replace(/([^\\s]):host/g, \"$1\").replace(\":host\", \"*\").replace(/\\^|\\/shadow\\/|\\/shadow-deep\\/|::shadow|\\/deep\\/|::content|>>>/g, \" \");\n  }\n  function findOne(node, selector) {\n    var m, el = node.firstElementChild;\n    while (el) {\n      if (el.matches(selector)) return el;\n      m = findOne(el, selector);\n      if (m) return m;\n      el = el.nextElementSibling;\n    }\n    return null;\n  }\n  function matchesSelector(el, selector) {\n    return el.matches(selector);\n  }\n  var XHTML_NS = \"http://www.w3.org/1999/xhtml\";\n  function matchesTagName(el, localName, localNameLowerCase) {\n    var ln = el.localName;\n    return ln === localName || ln === localNameLowerCase && el.namespaceURI === XHTML_NS;\n  }\n  function matchesEveryThing() {\n    return true;\n  }\n  function matchesLocalNameOnly(el, ns, localName) {\n    return el.localName === localName;\n  }\n  function matchesNameSpace(el, ns) {\n    return el.namespaceURI === ns;\n  }\n  function matchesLocalNameNS(el, ns, localName) {\n    return el.namespaceURI === ns && el.localName === localName;\n  }\n  function findElements(node, index, result, p, arg0, arg1) {\n    var el = node.firstElementChild;\n    while (el) {\n      if (p(el, arg0, arg1)) result[index++] = el;\n      index = findElements(el, index, result, p, arg0, arg1);\n      el = el.nextElementSibling;\n    }\n    return index;\n  }\n  function querySelectorAllFiltered(p, index, result, selector, deep) {\n    var target = unsafeUnwrap(this);\n    var list;\n    var root = getTreeScope(this).root;\n    if (root instanceof scope.wrappers.ShadowRoot) {\n      return findElements(this, index, result, p, selector, null);\n    } else if (target instanceof OriginalElement) {\n      list = originalElementQuerySelectorAll.call(target, selector);\n    } else if (target instanceof OriginalDocument) {\n      list = originalDocumentQuerySelectorAll.call(target, selector);\n    } else {\n      return findElements(this, index, result, p, selector, null);\n    }\n    return filterNodeList(list, index, result, deep);\n  }\n  var SelectorsInterface = {\n    querySelector: function(selector) {\n      var shimmed = shimSelector(selector);\n      var deep = shimmed !== selector;\n      selector = shimmed;\n      var target = unsafeUnwrap(this);\n      var wrappedItem;\n      var root = getTreeScope(this).root;\n      if (root instanceof scope.wrappers.ShadowRoot) {\n        return findOne(this, selector);\n      } else if (target instanceof OriginalElement) {\n        wrappedItem = wrap(originalElementQuerySelector.call(target, selector));\n      } else if (target instanceof OriginalDocument) {\n        wrappedItem = wrap(originalDocumentQuerySelector.call(target, selector));\n      } else {\n        return findOne(this, selector);\n      }\n      if (!wrappedItem) {\n        return wrappedItem;\n      } else if (!deep && (root = getTreeScope(wrappedItem).root)) {\n        if (root instanceof scope.wrappers.ShadowRoot) {\n          return findOne(this, selector);\n        }\n      }\n      return wrappedItem;\n    },\n    querySelectorAll: function(selector) {\n      var shimmed = shimSelector(selector);\n      var deep = shimmed !== selector;\n      selector = shimmed;\n      var result = new NodeList();\n      result.length = querySelectorAllFiltered.call(this, matchesSelector, 0, result, selector, deep);\n      return result;\n    }\n  };\n  var MatchesInterface = {\n    matches: function(selector) {\n      selector = shimMatchesSelector(selector);\n      return scope.originalMatches.call(unsafeUnwrap(this), selector);\n    }\n  };\n  function getElementsByTagNameFiltered(p, index, result, localName, lowercase) {\n    var target = unsafeUnwrap(this);\n    var list;\n    var root = getTreeScope(this).root;\n    if (root instanceof scope.wrappers.ShadowRoot) {\n      return findElements(this, index, result, p, localName, lowercase);\n    } else if (target instanceof OriginalElement) {\n      list = originalElementGetElementsByTagName.call(target, localName, lowercase);\n    } else if (target instanceof OriginalDocument) {\n      list = originalDocumentGetElementsByTagName.call(target, localName, lowercase);\n    } else {\n      return findElements(this, index, result, p, localName, lowercase);\n    }\n    return filterNodeList(list, index, result, false);\n  }\n  function getElementsByTagNameNSFiltered(p, index, result, ns, localName) {\n    var target = unsafeUnwrap(this);\n    var list;\n    var root = getTreeScope(this).root;\n    if (root instanceof scope.wrappers.ShadowRoot) {\n      return findElements(this, index, result, p, ns, localName);\n    } else if (target instanceof OriginalElement) {\n      list = originalElementGetElementsByTagNameNS.call(target, ns, localName);\n    } else if (target instanceof OriginalDocument) {\n      list = originalDocumentGetElementsByTagNameNS.call(target, ns, localName);\n    } else {\n      return findElements(this, index, result, p, ns, localName);\n    }\n    return filterNodeList(list, index, result, false);\n  }\n  var GetElementsByInterface = {\n    getElementsByTagName: function(localName) {\n      var result = new HTMLCollection();\n      var match = localName === \"*\" ? matchesEveryThing : matchesTagName;\n      result.length = getElementsByTagNameFiltered.call(this, match, 0, result, localName, localName.toLowerCase());\n      return result;\n    },\n    getElementsByClassName: function(className) {\n      return this.querySelectorAll(\".\" + className);\n    },\n    getElementsByTagNameNS: function(ns, localName) {\n      var result = new HTMLCollection();\n      var match = null;\n      if (ns === \"*\") {\n        match = localName === \"*\" ? matchesEveryThing : matchesLocalNameOnly;\n      } else {\n        match = localName === \"*\" ? matchesNameSpace : matchesLocalNameNS;\n      }\n      result.length = getElementsByTagNameNSFiltered.call(this, match, 0, result, ns || null, localName);\n      return result;\n    }\n  };\n  scope.GetElementsByInterface = GetElementsByInterface;\n  scope.SelectorsInterface = SelectorsInterface;\n  scope.MatchesInterface = MatchesInterface;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var NodeList = scope.wrappers.NodeList;\n  function forwardElement(node) {\n    while (node && node.nodeType !== Node.ELEMENT_NODE) {\n      node = node.nextSibling;\n    }\n    return node;\n  }\n  function backwardsElement(node) {\n    while (node && node.nodeType !== Node.ELEMENT_NODE) {\n      node = node.previousSibling;\n    }\n    return node;\n  }\n  var ParentNodeInterface = {\n    get firstElementChild() {\n      return forwardElement(this.firstChild);\n    },\n    get lastElementChild() {\n      return backwardsElement(this.lastChild);\n    },\n    get childElementCount() {\n      var count = 0;\n      for (var child = this.firstElementChild; child; child = child.nextElementSibling) {\n        count++;\n      }\n      return count;\n    },\n    get children() {\n      var wrapperList = new NodeList();\n      var i = 0;\n      for (var child = this.firstElementChild; child; child = child.nextElementSibling) {\n        wrapperList[i++] = child;\n      }\n      wrapperList.length = i;\n      return wrapperList;\n    },\n    remove: function() {\n      var p = this.parentNode;\n      if (p) p.removeChild(this);\n    }\n  };\n  var ChildNodeInterface = {\n    get nextElementSibling() {\n      return forwardElement(this.nextSibling);\n    },\n    get previousElementSibling() {\n      return backwardsElement(this.previousSibling);\n    }\n  };\n  var NonElementParentNodeInterface = {\n    getElementById: function(id) {\n      if (/[ \\t\\n\\r\\f]/.test(id)) return null;\n      return this.querySelector('[id=\"' + id + '\"]');\n    }\n  };\n  scope.ChildNodeInterface = ChildNodeInterface;\n  scope.NonElementParentNodeInterface = NonElementParentNodeInterface;\n  scope.ParentNodeInterface = ParentNodeInterface;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var ChildNodeInterface = scope.ChildNodeInterface;\n  var Node = scope.wrappers.Node;\n  var enqueueMutation = scope.enqueueMutation;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unsafeUnwrap = scope.unsafeUnwrap;\n  var OriginalCharacterData = window.CharacterData;\n  function CharacterData(node) {\n    Node.call(this, node);\n  }\n  CharacterData.prototype = Object.create(Node.prototype);\n  mixin(CharacterData.prototype, {\n    get nodeValue() {\n      return this.data;\n    },\n    set nodeValue(data) {\n      this.data = data;\n    },\n    get textContent() {\n      return this.data;\n    },\n    set textContent(value) {\n      this.data = value;\n    },\n    get data() {\n      return unsafeUnwrap(this).data;\n    },\n    set data(value) {\n      var oldValue = unsafeUnwrap(this).data;\n      enqueueMutation(this, \"characterData\", {\n        oldValue: oldValue\n      });\n      unsafeUnwrap(this).data = value;\n    }\n  });\n  mixin(CharacterData.prototype, ChildNodeInterface);\n  registerWrapper(OriginalCharacterData, CharacterData, document.createTextNode(\"\"));\n  scope.wrappers.CharacterData = CharacterData;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var CharacterData = scope.wrappers.CharacterData;\n  var enqueueMutation = scope.enqueueMutation;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  function toUInt32(x) {\n    return x >>> 0;\n  }\n  var OriginalText = window.Text;\n  function Text(node) {\n    CharacterData.call(this, node);\n  }\n  Text.prototype = Object.create(CharacterData.prototype);\n  mixin(Text.prototype, {\n    splitText: function(offset) {\n      offset = toUInt32(offset);\n      var s = this.data;\n      if (offset > s.length) throw new Error(\"IndexSizeError\");\n      var head = s.slice(0, offset);\n      var tail = s.slice(offset);\n      this.data = head;\n      var newTextNode = this.ownerDocument.createTextNode(tail);\n      if (this.parentNode) this.parentNode.insertBefore(newTextNode, this.nextSibling);\n      return newTextNode;\n    }\n  });\n  registerWrapper(OriginalText, Text, document.createTextNode(\"\"));\n  scope.wrappers.Text = Text;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  if (!window.DOMTokenList) {\n    console.warn(\"Missing DOMTokenList prototype, please include a \" + \"compatible classList polyfill such as http://goo.gl/uTcepH.\");\n    return;\n  }\n  var unsafeUnwrap = scope.unsafeUnwrap;\n  var enqueueMutation = scope.enqueueMutation;\n  function getClass(el) {\n    return unsafeUnwrap(el).getAttribute(\"class\");\n  }\n  function enqueueClassAttributeChange(el, oldValue) {\n    enqueueMutation(el, \"attributes\", {\n      name: \"class\",\n      namespace: null,\n      oldValue: oldValue\n    });\n  }\n  function invalidateClass(el) {\n    scope.invalidateRendererBasedOnAttribute(el, \"class\");\n  }\n  function changeClass(tokenList, method, args) {\n    var ownerElement = tokenList.ownerElement_;\n    if (ownerElement == null) {\n      return method.apply(tokenList, args);\n    }\n    var oldValue = getClass(ownerElement);\n    var retv = method.apply(tokenList, args);\n    if (getClass(ownerElement) !== oldValue) {\n      enqueueClassAttributeChange(ownerElement, oldValue);\n      invalidateClass(ownerElement);\n    }\n    return retv;\n  }\n  var oldAdd = DOMTokenList.prototype.add;\n  DOMTokenList.prototype.add = function() {\n    changeClass(this, oldAdd, arguments);\n  };\n  var oldRemove = DOMTokenList.prototype.remove;\n  DOMTokenList.prototype.remove = function() {\n    changeClass(this, oldRemove, arguments);\n  };\n  var oldToggle = DOMTokenList.prototype.toggle;\n  DOMTokenList.prototype.toggle = function() {\n    return changeClass(this, oldToggle, arguments);\n  };\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var ChildNodeInterface = scope.ChildNodeInterface;\n  var GetElementsByInterface = scope.GetElementsByInterface;\n  var Node = scope.wrappers.Node;\n  var ParentNodeInterface = scope.ParentNodeInterface;\n  var SelectorsInterface = scope.SelectorsInterface;\n  var MatchesInterface = scope.MatchesInterface;\n  var addWrapNodeListMethod = scope.addWrapNodeListMethod;\n  var enqueueMutation = scope.enqueueMutation;\n  var mixin = scope.mixin;\n  var oneOf = scope.oneOf;\n  var registerWrapper = scope.registerWrapper;\n  var unsafeUnwrap = scope.unsafeUnwrap;\n  var wrappers = scope.wrappers;\n  var OriginalElement = window.Element;\n  var matchesNames = [ \"matches\", \"mozMatchesSelector\", \"msMatchesSelector\", \"webkitMatchesSelector\" ].filter(function(name) {\n    return OriginalElement.prototype[name];\n  });\n  var matchesName = matchesNames[0];\n  var originalMatches = OriginalElement.prototype[matchesName];\n  function invalidateRendererBasedOnAttribute(element, name) {\n    var p = element.parentNode;\n    if (!p || !p.shadowRoot) return;\n    var renderer = scope.getRendererForHost(p);\n    if (renderer.dependsOnAttribute(name)) renderer.invalidate();\n  }\n  function enqueAttributeChange(element, name, oldValue) {\n    enqueueMutation(element, \"attributes\", {\n      name: name,\n      namespace: null,\n      oldValue: oldValue\n    });\n  }\n  var classListTable = new WeakMap();\n  function Element(node) {\n    Node.call(this, node);\n  }\n  Element.prototype = Object.create(Node.prototype);\n  mixin(Element.prototype, {\n    createShadowRoot: function() {\n      var newShadowRoot = new wrappers.ShadowRoot(this);\n      unsafeUnwrap(this).polymerShadowRoot_ = newShadowRoot;\n      var renderer = scope.getRendererForHost(this);\n      renderer.invalidate();\n      return newShadowRoot;\n    },\n    get shadowRoot() {\n      return unsafeUnwrap(this).polymerShadowRoot_ || null;\n    },\n    setAttribute: function(name, value) {\n      var oldValue = unsafeUnwrap(this).getAttribute(name);\n      unsafeUnwrap(this).setAttribute(name, value);\n      enqueAttributeChange(this, name, oldValue);\n      invalidateRendererBasedOnAttribute(this, name);\n    },\n    removeAttribute: function(name) {\n      var oldValue = unsafeUnwrap(this).getAttribute(name);\n      unsafeUnwrap(this).removeAttribute(name);\n      enqueAttributeChange(this, name, oldValue);\n      invalidateRendererBasedOnAttribute(this, name);\n    },\n    get classList() {\n      var list = classListTable.get(this);\n      if (!list) {\n        list = unsafeUnwrap(this).classList;\n        if (!list) return;\n        list.ownerElement_ = this;\n        classListTable.set(this, list);\n      }\n      return list;\n    },\n    get className() {\n      return unsafeUnwrap(this).className;\n    },\n    set className(v) {\n      this.setAttribute(\"class\", v);\n    },\n    get id() {\n      return unsafeUnwrap(this).id;\n    },\n    set id(v) {\n      this.setAttribute(\"id\", v);\n    }\n  });\n  matchesNames.forEach(function(name) {\n    if (name !== \"matches\") {\n      Element.prototype[name] = function(selector) {\n        return this.matches(selector);\n      };\n    }\n  });\n  if (OriginalElement.prototype.webkitCreateShadowRoot) {\n    Element.prototype.webkitCreateShadowRoot = Element.prototype.createShadowRoot;\n  }\n  mixin(Element.prototype, ChildNodeInterface);\n  mixin(Element.prototype, GetElementsByInterface);\n  mixin(Element.prototype, ParentNodeInterface);\n  mixin(Element.prototype, SelectorsInterface);\n  mixin(Element.prototype, MatchesInterface);\n  registerWrapper(OriginalElement, Element, document.createElementNS(null, \"x\"));\n  scope.invalidateRendererBasedOnAttribute = invalidateRendererBasedOnAttribute;\n  scope.matchesNames = matchesNames;\n  scope.originalMatches = originalMatches;\n  scope.wrappers.Element = Element;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var Element = scope.wrappers.Element;\n  var defineGetter = scope.defineGetter;\n  var enqueueMutation = scope.enqueueMutation;\n  var mixin = scope.mixin;\n  var nodesWereAdded = scope.nodesWereAdded;\n  var nodesWereRemoved = scope.nodesWereRemoved;\n  var registerWrapper = scope.registerWrapper;\n  var snapshotNodeList = scope.snapshotNodeList;\n  var unsafeUnwrap = scope.unsafeUnwrap;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var wrappers = scope.wrappers;\n  var escapeAttrRegExp = /[&\\u00A0\"]/g;\n  var escapeDataRegExp = /[&\\u00A0<>]/g;\n  function escapeReplace(c) {\n    switch (c) {\n     case \"&\":\n      return \"&amp;\";\n\n     case \"<\":\n      return \"&lt;\";\n\n     case \">\":\n      return \"&gt;\";\n\n     case '\"':\n      return \"&quot;\";\n\n     case \" \":\n      return \"&nbsp;\";\n    }\n  }\n  function escapeAttr(s) {\n    return s.replace(escapeAttrRegExp, escapeReplace);\n  }\n  function escapeData(s) {\n    return s.replace(escapeDataRegExp, escapeReplace);\n  }\n  function makeSet(arr) {\n    var set = {};\n    for (var i = 0; i < arr.length; i++) {\n      set[arr[i]] = true;\n    }\n    return set;\n  }\n  var voidElements = makeSet([ \"area\", \"base\", \"br\", \"col\", \"command\", \"embed\", \"hr\", \"img\", \"input\", \"keygen\", \"link\", \"meta\", \"param\", \"source\", \"track\", \"wbr\" ]);\n  var plaintextParents = makeSet([ \"style\", \"script\", \"xmp\", \"iframe\", \"noembed\", \"noframes\", \"plaintext\", \"noscript\" ]);\n  var XHTML_NS = \"http://www.w3.org/1999/xhtml\";\n  function needsSelfClosingSlash(node) {\n    if (node.namespaceURI !== XHTML_NS) return true;\n    var doctype = node.ownerDocument.doctype;\n    return doctype && doctype.publicId && doctype.systemId;\n  }\n  function getOuterHTML(node, parentNode) {\n    switch (node.nodeType) {\n     case Node.ELEMENT_NODE:\n      var tagName = node.tagName.toLowerCase();\n      var s = \"<\" + tagName;\n      var attrs = node.attributes;\n      for (var i = 0, attr; attr = attrs[i]; i++) {\n        s += \" \" + attr.name + '=\"' + escapeAttr(attr.value) + '\"';\n      }\n      if (voidElements[tagName]) {\n        if (needsSelfClosingSlash(node)) s += \"/\";\n        return s + \">\";\n      }\n      return s + \">\" + getInnerHTML(node) + \"</\" + tagName + \">\";\n\n     case Node.TEXT_NODE:\n      var data = node.data;\n      if (parentNode && plaintextParents[parentNode.localName]) return data;\n      return escapeData(data);\n\n     case Node.COMMENT_NODE:\n      return \"<!--\" + node.data + \"-->\";\n\n     default:\n      console.error(node);\n      throw new Error(\"not implemented\");\n    }\n  }\n  function getInnerHTML(node) {\n    if (node instanceof wrappers.HTMLTemplateElement) node = node.content;\n    var s = \"\";\n    for (var child = node.firstChild; child; child = child.nextSibling) {\n      s += getOuterHTML(child, node);\n    }\n    return s;\n  }\n  function setInnerHTML(node, value, opt_tagName) {\n    var tagName = opt_tagName || \"div\";\n    node.textContent = \"\";\n    var tempElement = unwrap(node.ownerDocument.createElement(tagName));\n    tempElement.innerHTML = value;\n    var firstChild;\n    while (firstChild = tempElement.firstChild) {\n      node.appendChild(wrap(firstChild));\n    }\n  }\n  var oldIe = /MSIE/.test(navigator.userAgent);\n  var OriginalHTMLElement = window.HTMLElement;\n  var OriginalHTMLTemplateElement = window.HTMLTemplateElement;\n  function HTMLElement(node) {\n    Element.call(this, node);\n  }\n  HTMLElement.prototype = Object.create(Element.prototype);\n  mixin(HTMLElement.prototype, {\n    get innerHTML() {\n      return getInnerHTML(this);\n    },\n    set innerHTML(value) {\n      if (oldIe && plaintextParents[this.localName]) {\n        this.textContent = value;\n        return;\n      }\n      var removedNodes = snapshotNodeList(this.childNodes);\n      if (this.invalidateShadowRenderer()) {\n        if (this instanceof wrappers.HTMLTemplateElement) setInnerHTML(this.content, value); else setInnerHTML(this, value, this.tagName);\n      } else if (!OriginalHTMLTemplateElement && this instanceof wrappers.HTMLTemplateElement) {\n        setInnerHTML(this.content, value);\n      } else {\n        unsafeUnwrap(this).innerHTML = value;\n      }\n      var addedNodes = snapshotNodeList(this.childNodes);\n      enqueueMutation(this, \"childList\", {\n        addedNodes: addedNodes,\n        removedNodes: removedNodes\n      });\n      nodesWereRemoved(removedNodes);\n      nodesWereAdded(addedNodes, this);\n    },\n    get outerHTML() {\n      return getOuterHTML(this, this.parentNode);\n    },\n    set outerHTML(value) {\n      var p = this.parentNode;\n      if (p) {\n        p.invalidateShadowRenderer();\n        var df = frag(p, value);\n        p.replaceChild(df, this);\n      }\n    },\n    insertAdjacentHTML: function(position, text) {\n      var contextElement, refNode;\n      switch (String(position).toLowerCase()) {\n       case \"beforebegin\":\n        contextElement = this.parentNode;\n        refNode = this;\n        break;\n\n       case \"afterend\":\n        contextElement = this.parentNode;\n        refNode = this.nextSibling;\n        break;\n\n       case \"afterbegin\":\n        contextElement = this;\n        refNode = this.firstChild;\n        break;\n\n       case \"beforeend\":\n        contextElement = this;\n        refNode = null;\n        break;\n\n       default:\n        return;\n      }\n      var df = frag(contextElement, text);\n      contextElement.insertBefore(df, refNode);\n    },\n    get hidden() {\n      return this.hasAttribute(\"hidden\");\n    },\n    set hidden(v) {\n      if (v) {\n        this.setAttribute(\"hidden\", \"\");\n      } else {\n        this.removeAttribute(\"hidden\");\n      }\n    }\n  });\n  function frag(contextElement, html) {\n    var p = unwrap(contextElement.cloneNode(false));\n    p.innerHTML = html;\n    var df = unwrap(document.createDocumentFragment());\n    var c;\n    while (c = p.firstChild) {\n      df.appendChild(c);\n    }\n    return wrap(df);\n  }\n  function getter(name) {\n    return function() {\n      scope.renderAllPending();\n      return unsafeUnwrap(this)[name];\n    };\n  }\n  function getterRequiresRendering(name) {\n    defineGetter(HTMLElement, name, getter(name));\n  }\n  [ \"clientHeight\", \"clientLeft\", \"clientTop\", \"clientWidth\", \"offsetHeight\", \"offsetLeft\", \"offsetTop\", \"offsetWidth\", \"scrollHeight\", \"scrollWidth\" ].forEach(getterRequiresRendering);\n  function getterAndSetterRequiresRendering(name) {\n    Object.defineProperty(HTMLElement.prototype, name, {\n      get: getter(name),\n      set: function(v) {\n        scope.renderAllPending();\n        unsafeUnwrap(this)[name] = v;\n      },\n      configurable: true,\n      enumerable: true\n    });\n  }\n  [ \"scrollLeft\", \"scrollTop\" ].forEach(getterAndSetterRequiresRendering);\n  function methodRequiresRendering(name) {\n    Object.defineProperty(HTMLElement.prototype, name, {\n      value: function() {\n        scope.renderAllPending();\n        return unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments);\n      },\n      configurable: true,\n      enumerable: true\n    });\n  }\n  [ \"getBoundingClientRect\", \"getClientRects\", \"scrollIntoView\" ].forEach(methodRequiresRendering);\n  registerWrapper(OriginalHTMLElement, HTMLElement, document.createElement(\"b\"));\n  scope.wrappers.HTMLElement = HTMLElement;\n  scope.getInnerHTML = getInnerHTML;\n  scope.setInnerHTML = setInnerHTML;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unsafeUnwrap = scope.unsafeUnwrap;\n  var wrap = scope.wrap;\n  var OriginalHTMLCanvasElement = window.HTMLCanvasElement;\n  function HTMLCanvasElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLCanvasElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLCanvasElement.prototype, {\n    getContext: function() {\n      var context = unsafeUnwrap(this).getContext.apply(unsafeUnwrap(this), arguments);\n      return context && wrap(context);\n    }\n  });\n  registerWrapper(OriginalHTMLCanvasElement, HTMLCanvasElement, document.createElement(\"canvas\"));\n  scope.wrappers.HTMLCanvasElement = HTMLCanvasElement;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var OriginalHTMLContentElement = window.HTMLContentElement;\n  function HTMLContentElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLContentElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLContentElement.prototype, {\n    constructor: HTMLContentElement,\n    get select() {\n      return this.getAttribute(\"select\");\n    },\n    set select(value) {\n      this.setAttribute(\"select\", value);\n    },\n    setAttribute: function(n, v) {\n      HTMLElement.prototype.setAttribute.call(this, n, v);\n      if (String(n).toLowerCase() === \"select\") this.invalidateShadowRenderer(true);\n    }\n  });\n  if (OriginalHTMLContentElement) registerWrapper(OriginalHTMLContentElement, HTMLContentElement);\n  scope.wrappers.HTMLContentElement = HTMLContentElement;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var wrapHTMLCollection = scope.wrapHTMLCollection;\n  var unwrap = scope.unwrap;\n  var OriginalHTMLFormElement = window.HTMLFormElement;\n  function HTMLFormElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLFormElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLFormElement.prototype, {\n    get elements() {\n      return wrapHTMLCollection(unwrap(this).elements);\n    }\n  });\n  registerWrapper(OriginalHTMLFormElement, HTMLFormElement, document.createElement(\"form\"));\n  scope.wrappers.HTMLFormElement = HTMLFormElement;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var rewrap = scope.rewrap;\n  var OriginalHTMLImageElement = window.HTMLImageElement;\n  function HTMLImageElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLImageElement.prototype = Object.create(HTMLElement.prototype);\n  registerWrapper(OriginalHTMLImageElement, HTMLImageElement, document.createElement(\"img\"));\n  function Image(width, height) {\n    if (!(this instanceof Image)) {\n      throw new TypeError(\"DOM object constructor cannot be called as a function.\");\n    }\n    var node = unwrap(document.createElement(\"img\"));\n    HTMLElement.call(this, node);\n    rewrap(node, this);\n    if (width !== undefined) node.width = width;\n    if (height !== undefined) node.height = height;\n  }\n  Image.prototype = HTMLImageElement.prototype;\n  scope.wrappers.HTMLImageElement = HTMLImageElement;\n  scope.wrappers.Image = Image;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var NodeList = scope.wrappers.NodeList;\n  var registerWrapper = scope.registerWrapper;\n  var OriginalHTMLShadowElement = window.HTMLShadowElement;\n  function HTMLShadowElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLShadowElement.prototype = Object.create(HTMLElement.prototype);\n  HTMLShadowElement.prototype.constructor = HTMLShadowElement;\n  if (OriginalHTMLShadowElement) registerWrapper(OriginalHTMLShadowElement, HTMLShadowElement);\n  scope.wrappers.HTMLShadowElement = HTMLShadowElement;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unsafeUnwrap = scope.unsafeUnwrap;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var contentTable = new WeakMap();\n  var templateContentsOwnerTable = new WeakMap();\n  function getTemplateContentsOwner(doc) {\n    if (!doc.defaultView) return doc;\n    var d = templateContentsOwnerTable.get(doc);\n    if (!d) {\n      d = doc.implementation.createHTMLDocument(\"\");\n      while (d.lastChild) {\n        d.removeChild(d.lastChild);\n      }\n      templateContentsOwnerTable.set(doc, d);\n    }\n    return d;\n  }\n  function extractContent(templateElement) {\n    var doc = getTemplateContentsOwner(templateElement.ownerDocument);\n    var df = unwrap(doc.createDocumentFragment());\n    var child;\n    while (child = templateElement.firstChild) {\n      df.appendChild(child);\n    }\n    return df;\n  }\n  var OriginalHTMLTemplateElement = window.HTMLTemplateElement;\n  function HTMLTemplateElement(node) {\n    HTMLElement.call(this, node);\n    if (!OriginalHTMLTemplateElement) {\n      var content = extractContent(node);\n      contentTable.set(this, wrap(content));\n    }\n  }\n  HTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLTemplateElement.prototype, {\n    constructor: HTMLTemplateElement,\n    get content() {\n      if (OriginalHTMLTemplateElement) return wrap(unsafeUnwrap(this).content);\n      return contentTable.get(this);\n    }\n  });\n  if (OriginalHTMLTemplateElement) registerWrapper(OriginalHTMLTemplateElement, HTMLTemplateElement);\n  scope.wrappers.HTMLTemplateElement = HTMLTemplateElement;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var registerWrapper = scope.registerWrapper;\n  var OriginalHTMLMediaElement = window.HTMLMediaElement;\n  if (!OriginalHTMLMediaElement) return;\n  function HTMLMediaElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLMediaElement.prototype = Object.create(HTMLElement.prototype);\n  registerWrapper(OriginalHTMLMediaElement, HTMLMediaElement, document.createElement(\"audio\"));\n  scope.wrappers.HTMLMediaElement = HTMLMediaElement;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var HTMLMediaElement = scope.wrappers.HTMLMediaElement;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var rewrap = scope.rewrap;\n  var OriginalHTMLAudioElement = window.HTMLAudioElement;\n  if (!OriginalHTMLAudioElement) return;\n  function HTMLAudioElement(node) {\n    HTMLMediaElement.call(this, node);\n  }\n  HTMLAudioElement.prototype = Object.create(HTMLMediaElement.prototype);\n  registerWrapper(OriginalHTMLAudioElement, HTMLAudioElement, document.createElement(\"audio\"));\n  function Audio(src) {\n    if (!(this instanceof Audio)) {\n      throw new TypeError(\"DOM object constructor cannot be called as a function.\");\n    }\n    var node = unwrap(document.createElement(\"audio\"));\n    HTMLMediaElement.call(this, node);\n    rewrap(node, this);\n    node.setAttribute(\"preload\", \"auto\");\n    if (src !== undefined) node.setAttribute(\"src\", src);\n  }\n  Audio.prototype = HTMLAudioElement.prototype;\n  scope.wrappers.HTMLAudioElement = HTMLAudioElement;\n  scope.wrappers.Audio = Audio;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var rewrap = scope.rewrap;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var OriginalHTMLOptionElement = window.HTMLOptionElement;\n  function trimText(s) {\n    return s.replace(/\\s+/g, \" \").trim();\n  }\n  function HTMLOptionElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLOptionElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLOptionElement.prototype, {\n    get text() {\n      return trimText(this.textContent);\n    },\n    set text(value) {\n      this.textContent = trimText(String(value));\n    },\n    get form() {\n      return wrap(unwrap(this).form);\n    }\n  });\n  registerWrapper(OriginalHTMLOptionElement, HTMLOptionElement, document.createElement(\"option\"));\n  function Option(text, value, defaultSelected, selected) {\n    if (!(this instanceof Option)) {\n      throw new TypeError(\"DOM object constructor cannot be called as a function.\");\n    }\n    var node = unwrap(document.createElement(\"option\"));\n    HTMLElement.call(this, node);\n    rewrap(node, this);\n    if (text !== undefined) node.text = text;\n    if (value !== undefined) node.setAttribute(\"value\", value);\n    if (defaultSelected === true) node.setAttribute(\"selected\", \"\");\n    node.selected = selected === true;\n  }\n  Option.prototype = HTMLOptionElement.prototype;\n  scope.wrappers.HTMLOptionElement = HTMLOptionElement;\n  scope.wrappers.Option = Option;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var OriginalHTMLSelectElement = window.HTMLSelectElement;\n  function HTMLSelectElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLSelectElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLSelectElement.prototype, {\n    add: function(element, before) {\n      if (typeof before === \"object\") before = unwrap(before);\n      unwrap(this).add(unwrap(element), before);\n    },\n    remove: function(indexOrNode) {\n      if (indexOrNode === undefined) {\n        HTMLElement.prototype.remove.call(this);\n        return;\n      }\n      if (typeof indexOrNode === \"object\") indexOrNode = unwrap(indexOrNode);\n      unwrap(this).remove(indexOrNode);\n    },\n    get form() {\n      return wrap(unwrap(this).form);\n    }\n  });\n  registerWrapper(OriginalHTMLSelectElement, HTMLSelectElement, document.createElement(\"select\"));\n  scope.wrappers.HTMLSelectElement = HTMLSelectElement;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var wrapHTMLCollection = scope.wrapHTMLCollection;\n  var OriginalHTMLTableElement = window.HTMLTableElement;\n  function HTMLTableElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLTableElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLTableElement.prototype, {\n    get caption() {\n      return wrap(unwrap(this).caption);\n    },\n    createCaption: function() {\n      return wrap(unwrap(this).createCaption());\n    },\n    get tHead() {\n      return wrap(unwrap(this).tHead);\n    },\n    createTHead: function() {\n      return wrap(unwrap(this).createTHead());\n    },\n    createTFoot: function() {\n      return wrap(unwrap(this).createTFoot());\n    },\n    get tFoot() {\n      return wrap(unwrap(this).tFoot);\n    },\n    get tBodies() {\n      return wrapHTMLCollection(unwrap(this).tBodies);\n    },\n    createTBody: function() {\n      return wrap(unwrap(this).createTBody());\n    },\n    get rows() {\n      return wrapHTMLCollection(unwrap(this).rows);\n    },\n    insertRow: function(index) {\n      return wrap(unwrap(this).insertRow(index));\n    }\n  });\n  registerWrapper(OriginalHTMLTableElement, HTMLTableElement, document.createElement(\"table\"));\n  scope.wrappers.HTMLTableElement = HTMLTableElement;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var wrapHTMLCollection = scope.wrapHTMLCollection;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var OriginalHTMLTableSectionElement = window.HTMLTableSectionElement;\n  function HTMLTableSectionElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLTableSectionElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLTableSectionElement.prototype, {\n    constructor: HTMLTableSectionElement,\n    get rows() {\n      return wrapHTMLCollection(unwrap(this).rows);\n    },\n    insertRow: function(index) {\n      return wrap(unwrap(this).insertRow(index));\n    }\n  });\n  registerWrapper(OriginalHTMLTableSectionElement, HTMLTableSectionElement, document.createElement(\"thead\"));\n  scope.wrappers.HTMLTableSectionElement = HTMLTableSectionElement;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var wrapHTMLCollection = scope.wrapHTMLCollection;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var OriginalHTMLTableRowElement = window.HTMLTableRowElement;\n  function HTMLTableRowElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLTableRowElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLTableRowElement.prototype, {\n    get cells() {\n      return wrapHTMLCollection(unwrap(this).cells);\n    },\n    insertCell: function(index) {\n      return wrap(unwrap(this).insertCell(index));\n    }\n  });\n  registerWrapper(OriginalHTMLTableRowElement, HTMLTableRowElement, document.createElement(\"tr\"));\n  scope.wrappers.HTMLTableRowElement = HTMLTableRowElement;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var HTMLContentElement = scope.wrappers.HTMLContentElement;\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var HTMLShadowElement = scope.wrappers.HTMLShadowElement;\n  var HTMLTemplateElement = scope.wrappers.HTMLTemplateElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var OriginalHTMLUnknownElement = window.HTMLUnknownElement;\n  function HTMLUnknownElement(node) {\n    switch (node.localName) {\n     case \"content\":\n      return new HTMLContentElement(node);\n\n     case \"shadow\":\n      return new HTMLShadowElement(node);\n\n     case \"template\":\n      return new HTMLTemplateElement(node);\n    }\n    HTMLElement.call(this, node);\n  }\n  HTMLUnknownElement.prototype = Object.create(HTMLElement.prototype);\n  registerWrapper(OriginalHTMLUnknownElement, HTMLUnknownElement);\n  scope.wrappers.HTMLUnknownElement = HTMLUnknownElement;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var Element = scope.wrappers.Element;\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var registerObject = scope.registerObject;\n  var defineWrapGetter = scope.defineWrapGetter;\n  var SVG_NS = \"http://www.w3.org/2000/svg\";\n  var svgTitleElement = document.createElementNS(SVG_NS, \"title\");\n  var SVGTitleElement = registerObject(svgTitleElement);\n  var SVGElement = Object.getPrototypeOf(SVGTitleElement.prototype).constructor;\n  if (!(\"classList\" in svgTitleElement)) {\n    var descr = Object.getOwnPropertyDescriptor(Element.prototype, \"classList\");\n    Object.defineProperty(HTMLElement.prototype, \"classList\", descr);\n    delete Element.prototype.classList;\n  }\n  defineWrapGetter(SVGElement, \"ownerSVGElement\");\n  scope.wrappers.SVGElement = SVGElement;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var OriginalSVGUseElement = window.SVGUseElement;\n  var SVG_NS = \"http://www.w3.org/2000/svg\";\n  var gWrapper = wrap(document.createElementNS(SVG_NS, \"g\"));\n  var useElement = document.createElementNS(SVG_NS, \"use\");\n  var SVGGElement = gWrapper.constructor;\n  var parentInterfacePrototype = Object.getPrototypeOf(SVGGElement.prototype);\n  var parentInterface = parentInterfacePrototype.constructor;\n  function SVGUseElement(impl) {\n    parentInterface.call(this, impl);\n  }\n  SVGUseElement.prototype = Object.create(parentInterfacePrototype);\n  if (\"instanceRoot\" in useElement) {\n    mixin(SVGUseElement.prototype, {\n      get instanceRoot() {\n        return wrap(unwrap(this).instanceRoot);\n      },\n      get animatedInstanceRoot() {\n        return wrap(unwrap(this).animatedInstanceRoot);\n      }\n    });\n  }\n  registerWrapper(OriginalSVGUseElement, SVGUseElement, useElement);\n  scope.wrappers.SVGUseElement = SVGUseElement;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var EventTarget = scope.wrappers.EventTarget;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unsafeUnwrap = scope.unsafeUnwrap;\n  var wrap = scope.wrap;\n  var OriginalSVGElementInstance = window.SVGElementInstance;\n  if (!OriginalSVGElementInstance) return;\n  function SVGElementInstance(impl) {\n    EventTarget.call(this, impl);\n  }\n  SVGElementInstance.prototype = Object.create(EventTarget.prototype);\n  mixin(SVGElementInstance.prototype, {\n    get correspondingElement() {\n      return wrap(unsafeUnwrap(this).correspondingElement);\n    },\n    get correspondingUseElement() {\n      return wrap(unsafeUnwrap(this).correspondingUseElement);\n    },\n    get parentNode() {\n      return wrap(unsafeUnwrap(this).parentNode);\n    },\n    get childNodes() {\n      throw new Error(\"Not implemented\");\n    },\n    get firstChild() {\n      return wrap(unsafeUnwrap(this).firstChild);\n    },\n    get lastChild() {\n      return wrap(unsafeUnwrap(this).lastChild);\n    },\n    get previousSibling() {\n      return wrap(unsafeUnwrap(this).previousSibling);\n    },\n    get nextSibling() {\n      return wrap(unsafeUnwrap(this).nextSibling);\n    }\n  });\n  registerWrapper(OriginalSVGElementInstance, SVGElementInstance);\n  scope.wrappers.SVGElementInstance = SVGElementInstance;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var setWrapper = scope.setWrapper;\n  var unsafeUnwrap = scope.unsafeUnwrap;\n  var unwrap = scope.unwrap;\n  var unwrapIfNeeded = scope.unwrapIfNeeded;\n  var wrap = scope.wrap;\n  var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;\n  function CanvasRenderingContext2D(impl) {\n    setWrapper(impl, this);\n  }\n  mixin(CanvasRenderingContext2D.prototype, {\n    get canvas() {\n      return wrap(unsafeUnwrap(this).canvas);\n    },\n    drawImage: function() {\n      arguments[0] = unwrapIfNeeded(arguments[0]);\n      unsafeUnwrap(this).drawImage.apply(unsafeUnwrap(this), arguments);\n    },\n    createPattern: function() {\n      arguments[0] = unwrap(arguments[0]);\n      return unsafeUnwrap(this).createPattern.apply(unsafeUnwrap(this), arguments);\n    }\n  });\n  registerWrapper(OriginalCanvasRenderingContext2D, CanvasRenderingContext2D, document.createElement(\"canvas\").getContext(\"2d\"));\n  scope.wrappers.CanvasRenderingContext2D = CanvasRenderingContext2D;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var setWrapper = scope.setWrapper;\n  var unsafeUnwrap = scope.unsafeUnwrap;\n  var unwrapIfNeeded = scope.unwrapIfNeeded;\n  var wrap = scope.wrap;\n  var OriginalWebGLRenderingContext = window.WebGLRenderingContext;\n  if (!OriginalWebGLRenderingContext) return;\n  function WebGLRenderingContext(impl) {\n    setWrapper(impl, this);\n  }\n  mixin(WebGLRenderingContext.prototype, {\n    get canvas() {\n      return wrap(unsafeUnwrap(this).canvas);\n    },\n    texImage2D: function() {\n      arguments[5] = unwrapIfNeeded(arguments[5]);\n      unsafeUnwrap(this).texImage2D.apply(unsafeUnwrap(this), arguments);\n    },\n    texSubImage2D: function() {\n      arguments[6] = unwrapIfNeeded(arguments[6]);\n      unsafeUnwrap(this).texSubImage2D.apply(unsafeUnwrap(this), arguments);\n    }\n  });\n  var instanceProperties = /WebKit/.test(navigator.userAgent) ? {\n    drawingBufferHeight: null,\n    drawingBufferWidth: null\n  } : {};\n  registerWrapper(OriginalWebGLRenderingContext, WebGLRenderingContext, instanceProperties);\n  scope.wrappers.WebGLRenderingContext = WebGLRenderingContext;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var GetElementsByInterface = scope.GetElementsByInterface;\n  var NonElementParentNodeInterface = scope.NonElementParentNodeInterface;\n  var ParentNodeInterface = scope.ParentNodeInterface;\n  var SelectorsInterface = scope.SelectorsInterface;\n  var mixin = scope.mixin;\n  var registerObject = scope.registerObject;\n  var DocumentFragment = registerObject(document.createDocumentFragment());\n  mixin(DocumentFragment.prototype, ParentNodeInterface);\n  mixin(DocumentFragment.prototype, SelectorsInterface);\n  mixin(DocumentFragment.prototype, GetElementsByInterface);\n  mixin(DocumentFragment.prototype, NonElementParentNodeInterface);\n  var Comment = registerObject(document.createComment(\"\"));\n  scope.wrappers.Comment = Comment;\n  scope.wrappers.DocumentFragment = DocumentFragment;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var DocumentFragment = scope.wrappers.DocumentFragment;\n  var TreeScope = scope.TreeScope;\n  var elementFromPoint = scope.elementFromPoint;\n  var getInnerHTML = scope.getInnerHTML;\n  var getTreeScope = scope.getTreeScope;\n  var mixin = scope.mixin;\n  var rewrap = scope.rewrap;\n  var setInnerHTML = scope.setInnerHTML;\n  var unsafeUnwrap = scope.unsafeUnwrap;\n  var unwrap = scope.unwrap;\n  var shadowHostTable = new WeakMap();\n  var nextOlderShadowTreeTable = new WeakMap();\n  function ShadowRoot(hostWrapper) {\n    var node = unwrap(unsafeUnwrap(hostWrapper).ownerDocument.createDocumentFragment());\n    DocumentFragment.call(this, node);\n    rewrap(node, this);\n    var oldShadowRoot = hostWrapper.shadowRoot;\n    nextOlderShadowTreeTable.set(this, oldShadowRoot);\n    this.treeScope_ = new TreeScope(this, getTreeScope(oldShadowRoot || hostWrapper));\n    shadowHostTable.set(this, hostWrapper);\n  }\n  ShadowRoot.prototype = Object.create(DocumentFragment.prototype);\n  mixin(ShadowRoot.prototype, {\n    constructor: ShadowRoot,\n    get innerHTML() {\n      return getInnerHTML(this);\n    },\n    set innerHTML(value) {\n      setInnerHTML(this, value);\n      this.invalidateShadowRenderer();\n    },\n    get olderShadowRoot() {\n      return nextOlderShadowTreeTable.get(this) || null;\n    },\n    get host() {\n      return shadowHostTable.get(this) || null;\n    },\n    invalidateShadowRenderer: function() {\n      return shadowHostTable.get(this).invalidateShadowRenderer();\n    },\n    elementFromPoint: function(x, y) {\n      return elementFromPoint(this, this.ownerDocument, x, y);\n    }\n  });\n  scope.wrappers.ShadowRoot = ShadowRoot;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var registerWrapper = scope.registerWrapper;\n  var setWrapper = scope.setWrapper;\n  var unsafeUnwrap = scope.unsafeUnwrap;\n  var unwrap = scope.unwrap;\n  var unwrapIfNeeded = scope.unwrapIfNeeded;\n  var wrap = scope.wrap;\n  var getTreeScope = scope.getTreeScope;\n  var OriginalRange = window.Range;\n  var ShadowRoot = scope.wrappers.ShadowRoot;\n  function getHost(node) {\n    var root = getTreeScope(node).root;\n    if (root instanceof ShadowRoot) {\n      return root.host;\n    }\n    return null;\n  }\n  function hostNodeToShadowNode(refNode, offset) {\n    if (refNode.shadowRoot) {\n      offset = Math.min(refNode.childNodes.length - 1, offset);\n      var child = refNode.childNodes[offset];\n      if (child) {\n        var insertionPoint = scope.getDestinationInsertionPoints(child);\n        if (insertionPoint.length > 0) {\n          var parentNode = insertionPoint[0].parentNode;\n          if (parentNode.nodeType == Node.ELEMENT_NODE) {\n            refNode = parentNode;\n          }\n        }\n      }\n    }\n    return refNode;\n  }\n  function shadowNodeToHostNode(node) {\n    node = wrap(node);\n    return getHost(node) || node;\n  }\n  function Range(impl) {\n    setWrapper(impl, this);\n  }\n  Range.prototype = {\n    get startContainer() {\n      return shadowNodeToHostNode(unsafeUnwrap(this).startContainer);\n    },\n    get endContainer() {\n      return shadowNodeToHostNode(unsafeUnwrap(this).endContainer);\n    },\n    get commonAncestorContainer() {\n      return shadowNodeToHostNode(unsafeUnwrap(this).commonAncestorContainer);\n    },\n    setStart: function(refNode, offset) {\n      refNode = hostNodeToShadowNode(refNode, offset);\n      unsafeUnwrap(this).setStart(unwrapIfNeeded(refNode), offset);\n    },\n    setEnd: function(refNode, offset) {\n      refNode = hostNodeToShadowNode(refNode, offset);\n      unsafeUnwrap(this).setEnd(unwrapIfNeeded(refNode), offset);\n    },\n    setStartBefore: function(refNode) {\n      unsafeUnwrap(this).setStartBefore(unwrapIfNeeded(refNode));\n    },\n    setStartAfter: function(refNode) {\n      unsafeUnwrap(this).setStartAfter(unwrapIfNeeded(refNode));\n    },\n    setEndBefore: function(refNode) {\n      unsafeUnwrap(this).setEndBefore(unwrapIfNeeded(refNode));\n    },\n    setEndAfter: function(refNode) {\n      unsafeUnwrap(this).setEndAfter(unwrapIfNeeded(refNode));\n    },\n    selectNode: function(refNode) {\n      unsafeUnwrap(this).selectNode(unwrapIfNeeded(refNode));\n    },\n    selectNodeContents: function(refNode) {\n      unsafeUnwrap(this).selectNodeContents(unwrapIfNeeded(refNode));\n    },\n    compareBoundaryPoints: function(how, sourceRange) {\n      return unsafeUnwrap(this).compareBoundaryPoints(how, unwrap(sourceRange));\n    },\n    extractContents: function() {\n      return wrap(unsafeUnwrap(this).extractContents());\n    },\n    cloneContents: function() {\n      return wrap(unsafeUnwrap(this).cloneContents());\n    },\n    insertNode: function(node) {\n      unsafeUnwrap(this).insertNode(unwrapIfNeeded(node));\n    },\n    surroundContents: function(newParent) {\n      unsafeUnwrap(this).surroundContents(unwrapIfNeeded(newParent));\n    },\n    cloneRange: function() {\n      return wrap(unsafeUnwrap(this).cloneRange());\n    },\n    isPointInRange: function(node, offset) {\n      return unsafeUnwrap(this).isPointInRange(unwrapIfNeeded(node), offset);\n    },\n    comparePoint: function(node, offset) {\n      return unsafeUnwrap(this).comparePoint(unwrapIfNeeded(node), offset);\n    },\n    intersectsNode: function(node) {\n      return unsafeUnwrap(this).intersectsNode(unwrapIfNeeded(node));\n    },\n    toString: function() {\n      return unsafeUnwrap(this).toString();\n    }\n  };\n  if (OriginalRange.prototype.createContextualFragment) {\n    Range.prototype.createContextualFragment = function(html) {\n      return wrap(unsafeUnwrap(this).createContextualFragment(html));\n    };\n  }\n  registerWrapper(window.Range, Range, document.createRange());\n  scope.wrappers.Range = Range;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var Element = scope.wrappers.Element;\n  var HTMLContentElement = scope.wrappers.HTMLContentElement;\n  var HTMLShadowElement = scope.wrappers.HTMLShadowElement;\n  var Node = scope.wrappers.Node;\n  var ShadowRoot = scope.wrappers.ShadowRoot;\n  var assert = scope.assert;\n  var getTreeScope = scope.getTreeScope;\n  var mixin = scope.mixin;\n  var oneOf = scope.oneOf;\n  var unsafeUnwrap = scope.unsafeUnwrap;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var ArraySplice = scope.ArraySplice;\n  function updateWrapperUpAndSideways(wrapper) {\n    wrapper.previousSibling_ = wrapper.previousSibling;\n    wrapper.nextSibling_ = wrapper.nextSibling;\n    wrapper.parentNode_ = wrapper.parentNode;\n  }\n  function updateWrapperDown(wrapper) {\n    wrapper.firstChild_ = wrapper.firstChild;\n    wrapper.lastChild_ = wrapper.lastChild;\n  }\n  function updateAllChildNodes(parentNodeWrapper) {\n    assert(parentNodeWrapper instanceof Node);\n    for (var childWrapper = parentNodeWrapper.firstChild; childWrapper; childWrapper = childWrapper.nextSibling) {\n      updateWrapperUpAndSideways(childWrapper);\n    }\n    updateWrapperDown(parentNodeWrapper);\n  }\n  function insertBefore(parentNodeWrapper, newChildWrapper, refChildWrapper) {\n    var parentNode = unwrap(parentNodeWrapper);\n    var newChild = unwrap(newChildWrapper);\n    var refChild = refChildWrapper ? unwrap(refChildWrapper) : null;\n    remove(newChildWrapper);\n    updateWrapperUpAndSideways(newChildWrapper);\n    if (!refChildWrapper) {\n      parentNodeWrapper.lastChild_ = parentNodeWrapper.lastChild;\n      if (parentNodeWrapper.lastChild === parentNodeWrapper.firstChild) parentNodeWrapper.firstChild_ = parentNodeWrapper.firstChild;\n      var lastChildWrapper = wrap(parentNode.lastChild);\n      if (lastChildWrapper) lastChildWrapper.nextSibling_ = lastChildWrapper.nextSibling;\n    } else {\n      if (parentNodeWrapper.firstChild === refChildWrapper) parentNodeWrapper.firstChild_ = refChildWrapper;\n      refChildWrapper.previousSibling_ = refChildWrapper.previousSibling;\n    }\n    scope.originalInsertBefore.call(parentNode, newChild, refChild);\n  }\n  function remove(nodeWrapper) {\n    var node = unwrap(nodeWrapper);\n    var parentNode = node.parentNode;\n    if (!parentNode) return;\n    var parentNodeWrapper = wrap(parentNode);\n    updateWrapperUpAndSideways(nodeWrapper);\n    if (nodeWrapper.previousSibling) nodeWrapper.previousSibling.nextSibling_ = nodeWrapper;\n    if (nodeWrapper.nextSibling) nodeWrapper.nextSibling.previousSibling_ = nodeWrapper;\n    if (parentNodeWrapper.lastChild === nodeWrapper) parentNodeWrapper.lastChild_ = nodeWrapper;\n    if (parentNodeWrapper.firstChild === nodeWrapper) parentNodeWrapper.firstChild_ = nodeWrapper;\n    scope.originalRemoveChild.call(parentNode, node);\n  }\n  var distributedNodesTable = new WeakMap();\n  var destinationInsertionPointsTable = new WeakMap();\n  var rendererForHostTable = new WeakMap();\n  function resetDistributedNodes(insertionPoint) {\n    distributedNodesTable.set(insertionPoint, []);\n  }\n  function getDistributedNodes(insertionPoint) {\n    var rv = distributedNodesTable.get(insertionPoint);\n    if (!rv) distributedNodesTable.set(insertionPoint, rv = []);\n    return rv;\n  }\n  function getChildNodesSnapshot(node) {\n    var result = [], i = 0;\n    for (var child = node.firstChild; child; child = child.nextSibling) {\n      result[i++] = child;\n    }\n    return result;\n  }\n  var request = oneOf(window, [ \"requestAnimationFrame\", \"mozRequestAnimationFrame\", \"webkitRequestAnimationFrame\", \"setTimeout\" ]);\n  var pendingDirtyRenderers = [];\n  var renderTimer;\n  function renderAllPending() {\n    for (var i = 0; i < pendingDirtyRenderers.length; i++) {\n      var renderer = pendingDirtyRenderers[i];\n      var parentRenderer = renderer.parentRenderer;\n      if (parentRenderer && parentRenderer.dirty) continue;\n      renderer.render();\n    }\n    pendingDirtyRenderers = [];\n  }\n  function handleRequestAnimationFrame() {\n    renderTimer = null;\n    renderAllPending();\n  }\n  function getRendererForHost(host) {\n    var renderer = rendererForHostTable.get(host);\n    if (!renderer) {\n      renderer = new ShadowRenderer(host);\n      rendererForHostTable.set(host, renderer);\n    }\n    return renderer;\n  }\n  function getShadowRootAncestor(node) {\n    var root = getTreeScope(node).root;\n    if (root instanceof ShadowRoot) return root;\n    return null;\n  }\n  function getRendererForShadowRoot(shadowRoot) {\n    return getRendererForHost(shadowRoot.host);\n  }\n  var spliceDiff = new ArraySplice();\n  spliceDiff.equals = function(renderNode, rawNode) {\n    return unwrap(renderNode.node) === rawNode;\n  };\n  function RenderNode(node) {\n    this.skip = false;\n    this.node = node;\n    this.childNodes = [];\n  }\n  RenderNode.prototype = {\n    append: function(node) {\n      var rv = new RenderNode(node);\n      this.childNodes.push(rv);\n      return rv;\n    },\n    sync: function(opt_added) {\n      if (this.skip) return;\n      var nodeWrapper = this.node;\n      var newChildren = this.childNodes;\n      var oldChildren = getChildNodesSnapshot(unwrap(nodeWrapper));\n      var added = opt_added || new WeakMap();\n      var splices = spliceDiff.calculateSplices(newChildren, oldChildren);\n      var newIndex = 0, oldIndex = 0;\n      var lastIndex = 0;\n      for (var i = 0; i < splices.length; i++) {\n        var splice = splices[i];\n        for (;lastIndex < splice.index; lastIndex++) {\n          oldIndex++;\n          newChildren[newIndex++].sync(added);\n        }\n        var removedCount = splice.removed.length;\n        for (var j = 0; j < removedCount; j++) {\n          var wrapper = wrap(oldChildren[oldIndex++]);\n          if (!added.get(wrapper)) remove(wrapper);\n        }\n        var addedCount = splice.addedCount;\n        var refNode = oldChildren[oldIndex] && wrap(oldChildren[oldIndex]);\n        for (var j = 0; j < addedCount; j++) {\n          var newChildRenderNode = newChildren[newIndex++];\n          var newChildWrapper = newChildRenderNode.node;\n          insertBefore(nodeWrapper, newChildWrapper, refNode);\n          added.set(newChildWrapper, true);\n          newChildRenderNode.sync(added);\n        }\n        lastIndex += addedCount;\n      }\n      for (var i = lastIndex; i < newChildren.length; i++) {\n        newChildren[i].sync(added);\n      }\n    }\n  };\n  function ShadowRenderer(host) {\n    this.host = host;\n    this.dirty = false;\n    this.invalidateAttributes();\n    this.associateNode(host);\n  }\n  ShadowRenderer.prototype = {\n    render: function(opt_renderNode) {\n      if (!this.dirty) return;\n      this.invalidateAttributes();\n      var host = this.host;\n      this.distribution(host);\n      var renderNode = opt_renderNode || new RenderNode(host);\n      this.buildRenderTree(renderNode, host);\n      var topMostRenderer = !opt_renderNode;\n      if (topMostRenderer) renderNode.sync();\n      this.dirty = false;\n    },\n    get parentRenderer() {\n      return getTreeScope(this.host).renderer;\n    },\n    invalidate: function() {\n      if (!this.dirty) {\n        this.dirty = true;\n        var parentRenderer = this.parentRenderer;\n        if (parentRenderer) parentRenderer.invalidate();\n        pendingDirtyRenderers.push(this);\n        if (renderTimer) return;\n        renderTimer = window[request](handleRequestAnimationFrame, 0);\n      }\n    },\n    distribution: function(root) {\n      this.resetAllSubtrees(root);\n      this.distributionResolution(root);\n    },\n    resetAll: function(node) {\n      if (isInsertionPoint(node)) resetDistributedNodes(node); else resetDestinationInsertionPoints(node);\n      this.resetAllSubtrees(node);\n    },\n    resetAllSubtrees: function(node) {\n      for (var child = node.firstChild; child; child = child.nextSibling) {\n        this.resetAll(child);\n      }\n      if (node.shadowRoot) this.resetAll(node.shadowRoot);\n      if (node.olderShadowRoot) this.resetAll(node.olderShadowRoot);\n    },\n    distributionResolution: function(node) {\n      if (isShadowHost(node)) {\n        var shadowHost = node;\n        var pool = poolPopulation(shadowHost);\n        var shadowTrees = getShadowTrees(shadowHost);\n        for (var i = 0; i < shadowTrees.length; i++) {\n          this.poolDistribution(shadowTrees[i], pool);\n        }\n        for (var i = shadowTrees.length - 1; i >= 0; i--) {\n          var shadowTree = shadowTrees[i];\n          var shadow = getShadowInsertionPoint(shadowTree);\n          if (shadow) {\n            var olderShadowRoot = shadowTree.olderShadowRoot;\n            if (olderShadowRoot) {\n              pool = poolPopulation(olderShadowRoot);\n            }\n            for (var j = 0; j < pool.length; j++) {\n              destributeNodeInto(pool[j], shadow);\n            }\n          }\n          this.distributionResolution(shadowTree);\n        }\n      }\n      for (var child = node.firstChild; child; child = child.nextSibling) {\n        this.distributionResolution(child);\n      }\n    },\n    poolDistribution: function(node, pool) {\n      if (node instanceof HTMLShadowElement) return;\n      if (node instanceof HTMLContentElement) {\n        var content = node;\n        this.updateDependentAttributes(content.getAttribute(\"select\"));\n        var anyDistributed = false;\n        for (var i = 0; i < pool.length; i++) {\n          var node = pool[i];\n          if (!node) continue;\n          if (matches(node, content)) {\n            destributeNodeInto(node, content);\n            pool[i] = undefined;\n            anyDistributed = true;\n          }\n        }\n        if (!anyDistributed) {\n          for (var child = content.firstChild; child; child = child.nextSibling) {\n            destributeNodeInto(child, content);\n          }\n        }\n        return;\n      }\n      for (var child = node.firstChild; child; child = child.nextSibling) {\n        this.poolDistribution(child, pool);\n      }\n    },\n    buildRenderTree: function(renderNode, node) {\n      var children = this.compose(node);\n      for (var i = 0; i < children.length; i++) {\n        var child = children[i];\n        var childRenderNode = renderNode.append(child);\n        this.buildRenderTree(childRenderNode, child);\n      }\n      if (isShadowHost(node)) {\n        var renderer = getRendererForHost(node);\n        renderer.dirty = false;\n      }\n    },\n    compose: function(node) {\n      var children = [];\n      var p = node.shadowRoot || node;\n      for (var child = p.firstChild; child; child = child.nextSibling) {\n        if (isInsertionPoint(child)) {\n          this.associateNode(p);\n          var distributedNodes = getDistributedNodes(child);\n          for (var j = 0; j < distributedNodes.length; j++) {\n            var distributedNode = distributedNodes[j];\n            if (isFinalDestination(child, distributedNode)) children.push(distributedNode);\n          }\n        } else {\n          children.push(child);\n        }\n      }\n      return children;\n    },\n    invalidateAttributes: function() {\n      this.attributes = Object.create(null);\n    },\n    updateDependentAttributes: function(selector) {\n      if (!selector) return;\n      var attributes = this.attributes;\n      if (/\\.\\w+/.test(selector)) attributes[\"class\"] = true;\n      if (/#\\w+/.test(selector)) attributes[\"id\"] = true;\n      selector.replace(/\\[\\s*([^\\s=\\|~\\]]+)/g, function(_, name) {\n        attributes[name] = true;\n      });\n    },\n    dependsOnAttribute: function(name) {\n      return this.attributes[name];\n    },\n    associateNode: function(node) {\n      unsafeUnwrap(node).polymerShadowRenderer_ = this;\n    }\n  };\n  function poolPopulation(node) {\n    var pool = [];\n    for (var child = node.firstChild; child; child = child.nextSibling) {\n      if (isInsertionPoint(child)) {\n        pool.push.apply(pool, getDistributedNodes(child));\n      } else {\n        pool.push(child);\n      }\n    }\n    return pool;\n  }\n  function getShadowInsertionPoint(node) {\n    if (node instanceof HTMLShadowElement) return node;\n    if (node instanceof HTMLContentElement) return null;\n    for (var child = node.firstChild; child; child = child.nextSibling) {\n      var res = getShadowInsertionPoint(child);\n      if (res) return res;\n    }\n    return null;\n  }\n  function destributeNodeInto(child, insertionPoint) {\n    getDistributedNodes(insertionPoint).push(child);\n    var points = destinationInsertionPointsTable.get(child);\n    if (!points) destinationInsertionPointsTable.set(child, [ insertionPoint ]); else points.push(insertionPoint);\n  }\n  function getDestinationInsertionPoints(node) {\n    return destinationInsertionPointsTable.get(node);\n  }\n  function resetDestinationInsertionPoints(node) {\n    destinationInsertionPointsTable.set(node, undefined);\n  }\n  var selectorStartCharRe = /^(:not\\()?[*.#[a-zA-Z_|]/;\n  function matches(node, contentElement) {\n    var select = contentElement.getAttribute(\"select\");\n    if (!select) return true;\n    select = select.trim();\n    if (!select) return true;\n    if (!(node instanceof Element)) return false;\n    if (!selectorStartCharRe.test(select)) return false;\n    try {\n      return node.matches(select);\n    } catch (ex) {\n      return false;\n    }\n  }\n  function isFinalDestination(insertionPoint, node) {\n    var points = getDestinationInsertionPoints(node);\n    return points && points[points.length - 1] === insertionPoint;\n  }\n  function isInsertionPoint(node) {\n    return node instanceof HTMLContentElement || node instanceof HTMLShadowElement;\n  }\n  function isShadowHost(shadowHost) {\n    return shadowHost.shadowRoot;\n  }\n  function getShadowTrees(host) {\n    var trees = [];\n    for (var tree = host.shadowRoot; tree; tree = tree.olderShadowRoot) {\n      trees.push(tree);\n    }\n    return trees;\n  }\n  function render(host) {\n    new ShadowRenderer(host).render();\n  }\n  Node.prototype.invalidateShadowRenderer = function(force) {\n    var renderer = unsafeUnwrap(this).polymerShadowRenderer_;\n    if (renderer) {\n      renderer.invalidate();\n      return true;\n    }\n    return false;\n  };\n  HTMLContentElement.prototype.getDistributedNodes = HTMLShadowElement.prototype.getDistributedNodes = function() {\n    renderAllPending();\n    return getDistributedNodes(this);\n  };\n  Element.prototype.getDestinationInsertionPoints = function() {\n    renderAllPending();\n    return getDestinationInsertionPoints(this) || [];\n  };\n  HTMLContentElement.prototype.nodeIsInserted_ = HTMLShadowElement.prototype.nodeIsInserted_ = function() {\n    this.invalidateShadowRenderer();\n    var shadowRoot = getShadowRootAncestor(this);\n    var renderer;\n    if (shadowRoot) renderer = getRendererForShadowRoot(shadowRoot);\n    unsafeUnwrap(this).polymerShadowRenderer_ = renderer;\n    if (renderer) renderer.invalidate();\n  };\n  scope.getRendererForHost = getRendererForHost;\n  scope.getShadowTrees = getShadowTrees;\n  scope.renderAllPending = renderAllPending;\n  scope.getDestinationInsertionPoints = getDestinationInsertionPoints;\n  scope.visual = {\n    insertBefore: insertBefore,\n    remove: remove\n  };\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var assert = scope.assert;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var elementsWithFormProperty = [ \"HTMLButtonElement\", \"HTMLFieldSetElement\", \"HTMLInputElement\", \"HTMLKeygenElement\", \"HTMLLabelElement\", \"HTMLLegendElement\", \"HTMLObjectElement\", \"HTMLOutputElement\", \"HTMLTextAreaElement\" ];\n  function createWrapperConstructor(name) {\n    if (!window[name]) return;\n    assert(!scope.wrappers[name]);\n    var GeneratedWrapper = function(node) {\n      HTMLElement.call(this, node);\n    };\n    GeneratedWrapper.prototype = Object.create(HTMLElement.prototype);\n    mixin(GeneratedWrapper.prototype, {\n      get form() {\n        return wrap(unwrap(this).form);\n      }\n    });\n    registerWrapper(window[name], GeneratedWrapper, document.createElement(name.slice(4, -7)));\n    scope.wrappers[name] = GeneratedWrapper;\n  }\n  elementsWithFormProperty.forEach(createWrapperConstructor);\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var registerWrapper = scope.registerWrapper;\n  var setWrapper = scope.setWrapper;\n  var unsafeUnwrap = scope.unsafeUnwrap;\n  var unwrap = scope.unwrap;\n  var unwrapIfNeeded = scope.unwrapIfNeeded;\n  var wrap = scope.wrap;\n  var OriginalSelection = window.Selection;\n  function Selection(impl) {\n    setWrapper(impl, this);\n  }\n  Selection.prototype = {\n    get anchorNode() {\n      return wrap(unsafeUnwrap(this).anchorNode);\n    },\n    get focusNode() {\n      return wrap(unsafeUnwrap(this).focusNode);\n    },\n    addRange: function(range) {\n      unsafeUnwrap(this).addRange(unwrapIfNeeded(range));\n    },\n    collapse: function(node, index) {\n      unsafeUnwrap(this).collapse(unwrapIfNeeded(node), index);\n    },\n    containsNode: function(node, allowPartial) {\n      return unsafeUnwrap(this).containsNode(unwrapIfNeeded(node), allowPartial);\n    },\n    getRangeAt: function(index) {\n      return wrap(unsafeUnwrap(this).getRangeAt(index));\n    },\n    removeRange: function(range) {\n      unsafeUnwrap(this).removeRange(unwrap(range));\n    },\n    selectAllChildren: function(node) {\n      unsafeUnwrap(this).selectAllChildren(unwrapIfNeeded(node));\n    },\n    toString: function() {\n      return unsafeUnwrap(this).toString();\n    }\n  };\n  if (OriginalSelection.prototype.extend) {\n    Selection.prototype.extend = function(node, offset) {\n      unsafeUnwrap(this).extend(unwrapIfNeeded(node), offset);\n    };\n  }\n  registerWrapper(window.Selection, Selection, window.getSelection());\n  scope.wrappers.Selection = Selection;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var registerWrapper = scope.registerWrapper;\n  var setWrapper = scope.setWrapper;\n  var unsafeUnwrap = scope.unsafeUnwrap;\n  var unwrapIfNeeded = scope.unwrapIfNeeded;\n  var wrap = scope.wrap;\n  var OriginalTreeWalker = window.TreeWalker;\n  function TreeWalker(impl) {\n    setWrapper(impl, this);\n  }\n  TreeWalker.prototype = {\n    get root() {\n      return wrap(unsafeUnwrap(this).root);\n    },\n    get currentNode() {\n      return wrap(unsafeUnwrap(this).currentNode);\n    },\n    set currentNode(node) {\n      unsafeUnwrap(this).currentNode = unwrapIfNeeded(node);\n    },\n    get filter() {\n      return unsafeUnwrap(this).filter;\n    },\n    parentNode: function() {\n      return wrap(unsafeUnwrap(this).parentNode());\n    },\n    firstChild: function() {\n      return wrap(unsafeUnwrap(this).firstChild());\n    },\n    lastChild: function() {\n      return wrap(unsafeUnwrap(this).lastChild());\n    },\n    previousSibling: function() {\n      return wrap(unsafeUnwrap(this).previousSibling());\n    },\n    previousNode: function() {\n      return wrap(unsafeUnwrap(this).previousNode());\n    },\n    nextNode: function() {\n      return wrap(unsafeUnwrap(this).nextNode());\n    }\n  };\n  registerWrapper(OriginalTreeWalker, TreeWalker);\n  scope.wrappers.TreeWalker = TreeWalker;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var GetElementsByInterface = scope.GetElementsByInterface;\n  var Node = scope.wrappers.Node;\n  var ParentNodeInterface = scope.ParentNodeInterface;\n  var NonElementParentNodeInterface = scope.NonElementParentNodeInterface;\n  var Selection = scope.wrappers.Selection;\n  var SelectorsInterface = scope.SelectorsInterface;\n  var ShadowRoot = scope.wrappers.ShadowRoot;\n  var TreeScope = scope.TreeScope;\n  var cloneNode = scope.cloneNode;\n  var defineWrapGetter = scope.defineWrapGetter;\n  var elementFromPoint = scope.elementFromPoint;\n  var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;\n  var matchesNames = scope.matchesNames;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var renderAllPending = scope.renderAllPending;\n  var rewrap = scope.rewrap;\n  var setWrapper = scope.setWrapper;\n  var unsafeUnwrap = scope.unsafeUnwrap;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var wrapEventTargetMethods = scope.wrapEventTargetMethods;\n  var wrapNodeList = scope.wrapNodeList;\n  var implementationTable = new WeakMap();\n  function Document(node) {\n    Node.call(this, node);\n    this.treeScope_ = new TreeScope(this, null);\n  }\n  Document.prototype = Object.create(Node.prototype);\n  defineWrapGetter(Document, \"documentElement\");\n  defineWrapGetter(Document, \"body\");\n  defineWrapGetter(Document, \"head\");\n  function wrapMethod(name) {\n    var original = document[name];\n    Document.prototype[name] = function() {\n      return wrap(original.apply(unsafeUnwrap(this), arguments));\n    };\n  }\n  [ \"createComment\", \"createDocumentFragment\", \"createElement\", \"createElementNS\", \"createEvent\", \"createEventNS\", \"createRange\", \"createTextNode\" ].forEach(wrapMethod);\n  var originalAdoptNode = document.adoptNode;\n  function adoptNodeNoRemove(node, doc) {\n    originalAdoptNode.call(unsafeUnwrap(doc), unwrap(node));\n    adoptSubtree(node, doc);\n  }\n  function adoptSubtree(node, doc) {\n    if (node.shadowRoot) doc.adoptNode(node.shadowRoot);\n    if (node instanceof ShadowRoot) adoptOlderShadowRoots(node, doc);\n    for (var child = node.firstChild; child; child = child.nextSibling) {\n      adoptSubtree(child, doc);\n    }\n  }\n  function adoptOlderShadowRoots(shadowRoot, doc) {\n    var oldShadowRoot = shadowRoot.olderShadowRoot;\n    if (oldShadowRoot) doc.adoptNode(oldShadowRoot);\n  }\n  var originalGetSelection = document.getSelection;\n  mixin(Document.prototype, {\n    adoptNode: function(node) {\n      if (node.parentNode) node.parentNode.removeChild(node);\n      adoptNodeNoRemove(node, this);\n      return node;\n    },\n    elementFromPoint: function(x, y) {\n      return elementFromPoint(this, this, x, y);\n    },\n    importNode: function(node, deep) {\n      return cloneNode(node, deep, unsafeUnwrap(this));\n    },\n    getSelection: function() {\n      renderAllPending();\n      return new Selection(originalGetSelection.call(unwrap(this)));\n    },\n    getElementsByName: function(name) {\n      return SelectorsInterface.querySelectorAll.call(this, \"[name=\" + JSON.stringify(String(name)) + \"]\");\n    }\n  });\n  var originalCreateTreeWalker = document.createTreeWalker;\n  var TreeWalkerWrapper = scope.wrappers.TreeWalker;\n  Document.prototype.createTreeWalker = function(root, whatToShow, filter, expandEntityReferences) {\n    var newFilter = null;\n    if (filter) {\n      if (filter.acceptNode && typeof filter.acceptNode === \"function\") {\n        newFilter = {\n          acceptNode: function(node) {\n            return filter.acceptNode(wrap(node));\n          }\n        };\n      } else if (typeof filter === \"function\") {\n        newFilter = function(node) {\n          return filter(wrap(node));\n        };\n      }\n    }\n    return new TreeWalkerWrapper(originalCreateTreeWalker.call(unwrap(this), unwrap(root), whatToShow, newFilter, expandEntityReferences));\n  };\n  if (document.registerElement) {\n    var originalRegisterElement = document.registerElement;\n    Document.prototype.registerElement = function(tagName, object) {\n      var prototype, extendsOption;\n      if (object !== undefined) {\n        prototype = object.prototype;\n        extendsOption = object.extends;\n      }\n      if (!prototype) prototype = Object.create(HTMLElement.prototype);\n      if (scope.nativePrototypeTable.get(prototype)) {\n        throw new Error(\"NotSupportedError\");\n      }\n      var proto = Object.getPrototypeOf(prototype);\n      var nativePrototype;\n      var prototypes = [];\n      while (proto) {\n        nativePrototype = scope.nativePrototypeTable.get(proto);\n        if (nativePrototype) break;\n        prototypes.push(proto);\n        proto = Object.getPrototypeOf(proto);\n      }\n      if (!nativePrototype) {\n        throw new Error(\"NotSupportedError\");\n      }\n      var newPrototype = Object.create(nativePrototype);\n      for (var i = prototypes.length - 1; i >= 0; i--) {\n        newPrototype = Object.create(newPrototype);\n      }\n      [ \"createdCallback\", \"attachedCallback\", \"detachedCallback\", \"attributeChangedCallback\" ].forEach(function(name) {\n        var f = prototype[name];\n        if (!f) return;\n        newPrototype[name] = function() {\n          if (!(wrap(this) instanceof CustomElementConstructor)) {\n            rewrap(this);\n          }\n          f.apply(wrap(this), arguments);\n        };\n      });\n      var p = {\n        prototype: newPrototype\n      };\n      if (extendsOption) p.extends = extendsOption;\n      function CustomElementConstructor(node) {\n        if (!node) {\n          if (extendsOption) {\n            return document.createElement(extendsOption, tagName);\n          } else {\n            return document.createElement(tagName);\n          }\n        }\n        setWrapper(node, this);\n      }\n      CustomElementConstructor.prototype = prototype;\n      CustomElementConstructor.prototype.constructor = CustomElementConstructor;\n      scope.constructorTable.set(newPrototype, CustomElementConstructor);\n      scope.nativePrototypeTable.set(prototype, newPrototype);\n      var nativeConstructor = originalRegisterElement.call(unwrap(this), tagName, p);\n      return CustomElementConstructor;\n    };\n    forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ \"registerElement\" ]);\n  }\n  forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement, window.HTMLHtmlElement ], [ \"appendChild\", \"compareDocumentPosition\", \"contains\", \"getElementsByClassName\", \"getElementsByTagName\", \"getElementsByTagNameNS\", \"insertBefore\", \"querySelector\", \"querySelectorAll\", \"removeChild\", \"replaceChild\" ]);\n  forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLHeadElement, window.HTMLHtmlElement ], matchesNames);\n  forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ \"adoptNode\", \"importNode\", \"contains\", \"createComment\", \"createDocumentFragment\", \"createElement\", \"createElementNS\", \"createEvent\", \"createEventNS\", \"createRange\", \"createTextNode\", \"createTreeWalker\", \"elementFromPoint\", \"getElementById\", \"getElementsByName\", \"getSelection\" ]);\n  mixin(Document.prototype, GetElementsByInterface);\n  mixin(Document.prototype, ParentNodeInterface);\n  mixin(Document.prototype, SelectorsInterface);\n  mixin(Document.prototype, NonElementParentNodeInterface);\n  mixin(Document.prototype, {\n    get implementation() {\n      var implementation = implementationTable.get(this);\n      if (implementation) return implementation;\n      implementation = new DOMImplementation(unwrap(this).implementation);\n      implementationTable.set(this, implementation);\n      return implementation;\n    },\n    get defaultView() {\n      return wrap(unwrap(this).defaultView);\n    }\n  });\n  registerWrapper(window.Document, Document, document.implementation.createHTMLDocument(\"\"));\n  if (window.HTMLDocument) registerWrapper(window.HTMLDocument, Document);\n  wrapEventTargetMethods([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement ]);\n  function DOMImplementation(impl) {\n    setWrapper(impl, this);\n  }\n  var originalCreateDocument = document.implementation.createDocument;\n  DOMImplementation.prototype.createDocument = function() {\n    arguments[2] = unwrap(arguments[2]);\n    return wrap(originalCreateDocument.apply(unsafeUnwrap(this), arguments));\n  };\n  function wrapImplMethod(constructor, name) {\n    var original = document.implementation[name];\n    constructor.prototype[name] = function() {\n      return wrap(original.apply(unsafeUnwrap(this), arguments));\n    };\n  }\n  function forwardImplMethod(constructor, name) {\n    var original = document.implementation[name];\n    constructor.prototype[name] = function() {\n      return original.apply(unsafeUnwrap(this), arguments);\n    };\n  }\n  wrapImplMethod(DOMImplementation, \"createDocumentType\");\n  wrapImplMethod(DOMImplementation, \"createHTMLDocument\");\n  forwardImplMethod(DOMImplementation, \"hasFeature\");\n  registerWrapper(window.DOMImplementation, DOMImplementation);\n  forwardMethodsToWrapper([ window.DOMImplementation ], [ \"createDocument\", \"createDocumentType\", \"createHTMLDocument\", \"hasFeature\" ]);\n  scope.adoptNodeNoRemove = adoptNodeNoRemove;\n  scope.wrappers.DOMImplementation = DOMImplementation;\n  scope.wrappers.Document = Document;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var EventTarget = scope.wrappers.EventTarget;\n  var Selection = scope.wrappers.Selection;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var renderAllPending = scope.renderAllPending;\n  var unwrap = scope.unwrap;\n  var unwrapIfNeeded = scope.unwrapIfNeeded;\n  var wrap = scope.wrap;\n  var OriginalWindow = window.Window;\n  var originalGetComputedStyle = window.getComputedStyle;\n  var originalGetDefaultComputedStyle = window.getDefaultComputedStyle;\n  var originalGetSelection = window.getSelection;\n  function Window(impl) {\n    EventTarget.call(this, impl);\n  }\n  Window.prototype = Object.create(EventTarget.prototype);\n  OriginalWindow.prototype.getComputedStyle = function(el, pseudo) {\n    return wrap(this || window).getComputedStyle(unwrapIfNeeded(el), pseudo);\n  };\n  if (originalGetDefaultComputedStyle) {\n    OriginalWindow.prototype.getDefaultComputedStyle = function(el, pseudo) {\n      return wrap(this || window).getDefaultComputedStyle(unwrapIfNeeded(el), pseudo);\n    };\n  }\n  OriginalWindow.prototype.getSelection = function() {\n    return wrap(this || window).getSelection();\n  };\n  delete window.getComputedStyle;\n  delete window.getDefaultComputedStyle;\n  delete window.getSelection;\n  [ \"addEventListener\", \"removeEventListener\", \"dispatchEvent\" ].forEach(function(name) {\n    OriginalWindow.prototype[name] = function() {\n      var w = wrap(this || window);\n      return w[name].apply(w, arguments);\n    };\n    delete window[name];\n  });\n  mixin(Window.prototype, {\n    getComputedStyle: function(el, pseudo) {\n      renderAllPending();\n      return originalGetComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);\n    },\n    getSelection: function() {\n      renderAllPending();\n      return new Selection(originalGetSelection.call(unwrap(this)));\n    },\n    get document() {\n      return wrap(unwrap(this).document);\n    }\n  });\n  if (originalGetDefaultComputedStyle) {\n    Window.prototype.getDefaultComputedStyle = function(el, pseudo) {\n      renderAllPending();\n      return originalGetDefaultComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);\n    };\n  }\n  registerWrapper(OriginalWindow, Window, window);\n  scope.wrappers.Window = Window;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var unwrap = scope.unwrap;\n  var OriginalDataTransfer = window.DataTransfer || window.Clipboard;\n  var OriginalDataTransferSetDragImage = OriginalDataTransfer.prototype.setDragImage;\n  if (OriginalDataTransferSetDragImage) {\n    OriginalDataTransfer.prototype.setDragImage = function(image, x, y) {\n      OriginalDataTransferSetDragImage.call(this, unwrap(image), x, y);\n    };\n  }\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var registerWrapper = scope.registerWrapper;\n  var setWrapper = scope.setWrapper;\n  var unwrap = scope.unwrap;\n  var OriginalFormData = window.FormData;\n  if (!OriginalFormData) return;\n  function FormData(formElement) {\n    var impl;\n    if (formElement instanceof OriginalFormData) {\n      impl = formElement;\n    } else {\n      impl = new OriginalFormData(formElement && unwrap(formElement));\n    }\n    setWrapper(impl, this);\n  }\n  registerWrapper(OriginalFormData, FormData, new OriginalFormData());\n  scope.wrappers.FormData = FormData;\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var unwrapIfNeeded = scope.unwrapIfNeeded;\n  var originalSend = XMLHttpRequest.prototype.send;\n  XMLHttpRequest.prototype.send = function(obj) {\n    return originalSend.call(this, unwrapIfNeeded(obj));\n  };\n})(window.ShadowDOMPolyfill);\n\n(function(scope) {\n  \"use strict\";\n  var isWrapperFor = scope.isWrapperFor;\n  var elements = {\n    a: \"HTMLAnchorElement\",\n    area: \"HTMLAreaElement\",\n    audio: \"HTMLAudioElement\",\n    base: \"HTMLBaseElement\",\n    body: \"HTMLBodyElement\",\n    br: \"HTMLBRElement\",\n    button: \"HTMLButtonElement\",\n    canvas: \"HTMLCanvasElement\",\n    caption: \"HTMLTableCaptionElement\",\n    col: \"HTMLTableColElement\",\n    content: \"HTMLContentElement\",\n    data: \"HTMLDataElement\",\n    datalist: \"HTMLDataListElement\",\n    del: \"HTMLModElement\",\n    dir: \"HTMLDirectoryElement\",\n    div: \"HTMLDivElement\",\n    dl: \"HTMLDListElement\",\n    embed: \"HTMLEmbedElement\",\n    fieldset: \"HTMLFieldSetElement\",\n    font: \"HTMLFontElement\",\n    form: \"HTMLFormElement\",\n    frame: \"HTMLFrameElement\",\n    frameset: \"HTMLFrameSetElement\",\n    h1: \"HTMLHeadingElement\",\n    head: \"HTMLHeadElement\",\n    hr: \"HTMLHRElement\",\n    html: \"HTMLHtmlElement\",\n    iframe: \"HTMLIFrameElement\",\n    img: \"HTMLImageElement\",\n    input: \"HTMLInputElement\",\n    keygen: \"HTMLKeygenElement\",\n    label: \"HTMLLabelElement\",\n    legend: \"HTMLLegendElement\",\n    li: \"HTMLLIElement\",\n    link: \"HTMLLinkElement\",\n    map: \"HTMLMapElement\",\n    marquee: \"HTMLMarqueeElement\",\n    menu: \"HTMLMenuElement\",\n    menuitem: \"HTMLMenuItemElement\",\n    meta: \"HTMLMetaElement\",\n    meter: \"HTMLMeterElement\",\n    object: \"HTMLObjectElement\",\n    ol: \"HTMLOListElement\",\n    optgroup: \"HTMLOptGroupElement\",\n    option: \"HTMLOptionElement\",\n    output: \"HTMLOutputElement\",\n    p: \"HTMLParagraphElement\",\n    param: \"HTMLParamElement\",\n    pre: \"HTMLPreElement\",\n    progress: \"HTMLProgressElement\",\n    q: \"HTMLQuoteElement\",\n    script: \"HTMLScriptElement\",\n    select: \"HTMLSelectElement\",\n    shadow: \"HTMLShadowElement\",\n    source: \"HTMLSourceElement\",\n    span: \"HTMLSpanElement\",\n    style: \"HTMLStyleElement\",\n    table: \"HTMLTableElement\",\n    tbody: \"HTMLTableSectionElement\",\n    template: \"HTMLTemplateElement\",\n    textarea: \"HTMLTextAreaElement\",\n    thead: \"HTMLTableSectionElement\",\n    time: \"HTMLTimeElement\",\n    title: \"HTMLTitleElement\",\n    tr: \"HTMLTableRowElement\",\n    track: \"HTMLTrackElement\",\n    ul: \"HTMLUListElement\",\n    video: \"HTMLVideoElement\"\n  };\n  function overrideConstructor(tagName) {\n    var nativeConstructorName = elements[tagName];\n    var nativeConstructor = window[nativeConstructorName];\n    if (!nativeConstructor) return;\n    var element = document.createElement(tagName);\n    var wrapperConstructor = element.constructor;\n    window[nativeConstructorName] = wrapperConstructor;\n  }\n  Object.keys(elements).forEach(overrideConstructor);\n  Object.getOwnPropertyNames(scope.wrappers).forEach(function(name) {\n    window[name] = scope.wrappers[name];\n  });\n})(window.ShadowDOMPolyfill);"
  },
  {
    "path": "cmd/memlat/static/bower_components/webcomponentsjs/bower.json",
    "content": "{\n  \"name\": \"webcomponentsjs\",\n  \"main\": \"webcomponents.js\",\n  \"version\": \"0.7.11\",\n  \"homepage\": \"http://webcomponents.org\",\n  \"authors\": [\n    \"The Polymer Authors\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/webcomponents/webcomponentsjs.git\"\n  },\n  \"keywords\": [\n    \"webcomponents\"\n  ],\n  \"license\": \"BSD\",\n  \"ignore\": []\n}\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/webcomponentsjs/build.log",
    "content": "BUILD LOG\n---------\nBuild Time: 2015-08-13T12:57:18-0700\n\nNODEJS INFORMATION\n==================\nnodejs: v0.12.7\ngulp: 3.9.0\ngulp-audit: 1.0.0\ngulp-concat: 2.6.0\ngulp-header: 1.2.2\ngulp-uglify: 1.2.0\nrun-sequence: 1.1.2\nweb-component-tester: 3.3.10\n\nREPO REVISIONS\n==============\nwebcomponentsjs: 0fc12104ac6f39421c5105a3694aa740ed3835df\n\nBUILD HASHES\n============\nCustomElements.js: 174a3a08af4a551dbd436f5dc527e29c4b989919\nCustomElements.min.js: 5d7f8991d0ce8a10307114de07d7ce0d1481f3a5\nHTMLImports.js: 6bb55981141fcf206496c34dad811e176f0d13f8\nHTMLImports.min.js: f956c8f8751b4e87fd93f5d4a3d053e6e8654d52\nMutationObserver.js: e0fce524fed93243c80971b72be846775bb74d53\nMutationObserver.min.js: 25c795fa01bd9d9feb3a52cf60ab2b6749b78c75\nShadowDOM.js: 1874e157c0462484bbb34b812d6ec7a97cf63995\nShadowDOM.min.js: 9a7fca60240b59961eba22b941ab0f890124e96b\nwebcomponents-lite.js: 406c7a34b1ab536e7bdf943c22d4293fbbe464e9\nwebcomponents-lite.min.js: 97f3d2215d0390bc2e246bd1c1f363b257050f70\nwebcomponents.js: 8aa2b2a294e917ec792f6b52f27cfbf9b00f519f\nwebcomponents.min.js: 4df2e85a7b0cd173494a9e8ab71660943734fcf9"
  },
  {
    "path": "cmd/memlat/static/bower_components/webcomponentsjs/package.json",
    "content": "{\n  \"name\": \"webcomponents.js\",\n  \"version\": \"0.7.11\",\n  \"description\": \"webcomponents.js\",\n  \"main\": \"webcomponents.js\",\n  \"directories\": {\n    \"test\": \"tests\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/webcomponents/webcomponentsjs.git\"\n  },\n  \"author\": \"The Polymer Authors\",\n  \"license\": {\n    \"type\": \"BSD-3-Clause\",\n    \"url\": \"http://polymer.github.io/LICENSE.txt\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/webcomponents/webcomponentsjs/issues\"\n  },\n  \"homepage\": \"http://webcomponents.org\",\n  \"devDependencies\": {\n    \"gulp\": \"^3.8.8\",\n    \"gulp-audit\": \"^1.0.0\",\n    \"gulp-concat\": \"^2.4.1\",\n    \"gulp-header\": \"^1.1.1\",\n    \"gulp-uglify\": \"^1.0.1\",\n    \"run-sequence\": \"^1.0.1\",\n    \"web-component-tester\": \"*\"\n  }\n}\n"
  },
  {
    "path": "cmd/memlat/static/bower_components/webcomponentsjs/webcomponents-lite.js",
    "content": "/**\n * @license\n * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n */\n// @version 0.7.11\nwindow.WebComponents = window.WebComponents || {};\n\n(function(scope) {\n  var flags = scope.flags || {};\n  var file = \"webcomponents-lite.js\";\n  var script = document.querySelector('script[src*=\"' + file + '\"]');\n  if (!flags.noOpts) {\n    location.search.slice(1).split(\"&\").forEach(function(option) {\n      var parts = option.split(\"=\");\n      var match;\n      if (parts[0] && (match = parts[0].match(/wc-(.+)/))) {\n        flags[match[1]] = parts[1] || true;\n      }\n    });\n    if (script) {\n      for (var i = 0, a; a = script.attributes[i]; i++) {\n        if (a.name !== \"src\") {\n          flags[a.name] = a.value || true;\n        }\n      }\n    }\n    if (flags.log) {\n      var parts = flags.log.split(\",\");\n      flags.log = {};\n      parts.forEach(function(f) {\n        flags.log[f] = true;\n      });\n    } else {\n      flags.log = {};\n    }\n  }\n  flags.shadow = flags.shadow || flags.shadowdom || flags.polyfill;\n  if (flags.shadow === \"native\") {\n    flags.shadow = false;\n  } else {\n    flags.shadow = flags.shadow || !HTMLElement.prototype.createShadowRoot;\n  }\n  if (flags.register) {\n    window.CustomElements = window.CustomElements || {\n      flags: {}\n    };\n    window.CustomElements.flags.register = flags.register;\n  }\n  scope.flags = flags;\n})(window.WebComponents);\n\n(function(scope) {\n  \"use strict\";\n  var hasWorkingUrl = false;\n  if (!scope.forceJURL) {\n    try {\n      var u = new URL(\"b\", \"http://a\");\n      u.pathname = \"c%20d\";\n      hasWorkingUrl = u.href === \"http://a/c%20d\";\n    } catch (e) {}\n  }\n  if (hasWorkingUrl) return;\n  var relative = Object.create(null);\n  relative[\"ftp\"] = 21;\n  relative[\"file\"] = 0;\n  relative[\"gopher\"] = 70;\n  relative[\"http\"] = 80;\n  relative[\"https\"] = 443;\n  relative[\"ws\"] = 80;\n  relative[\"wss\"] = 443;\n  var relativePathDotMapping = Object.create(null);\n  relativePathDotMapping[\"%2e\"] = \".\";\n  relativePathDotMapping[\".%2e\"] = \"..\";\n  relativePathDotMapping[\"%2e.\"] = \"..\";\n  relativePathDotMapping[\"%2e%2e\"] = \"..\";\n  function isRelativeScheme(scheme) {\n    return relative[scheme] !== undefined;\n  }\n  function invalid() {\n    clear.call(this);\n    this._isInvalid = true;\n  }\n  function IDNAToASCII(h) {\n    if (\"\" == h) {\n      invalid.call(this);\n    }\n    return h.toLowerCase();\n  }\n  function percentEscape(c) {\n    var unicode = c.charCodeAt(0);\n    if (unicode > 32 && unicode < 127 && [ 34, 35, 60, 62, 63, 96 ].indexOf(unicode) == -1) {\n      return c;\n    }\n    return encodeURIComponent(c);\n  }\n  function percentEscapeQuery(c) {\n    var unicode = c.charCodeAt(0);\n    if (unicode > 32 && unicode < 127 && [ 34, 35, 60, 62, 96 ].indexOf(unicode) == -1) {\n      return c;\n    }\n    return encodeURIComponent(c);\n  }\n  var EOF = undefined, ALPHA = /[a-zA-Z]/, ALPHANUMERIC = /[a-zA-Z0-9\\+\\-\\.]/;\n  function parse(input, stateOverride, base) {\n    function err(message) {\n      errors.push(message);\n    }\n    var state = stateOverride || \"scheme start\", cursor = 0, buffer = \"\", seenAt = false, seenBracket = false, errors = [];\n    loop: while ((input[cursor - 1] != EOF || cursor == 0) && !this._isInvalid) {\n      var c = input[cursor];\n      switch (state) {\n       case \"scheme start\":\n        if (c && ALPHA.test(c)) {\n          buffer += c.toLowerCase();\n          state = \"scheme\";\n        } else if (!stateOverride) {\n          buffer = \"\";\n          state = \"no scheme\";\n          continue;\n        } else {\n          err(\"Invalid scheme.\");\n          break loop;\n        }\n        break;\n\n       case \"scheme\":\n        if (c && ALPHANUMERIC.test(c)) {\n          buffer += c.toLowerCase();\n        } else if (\":\" == c) {\n          this._scheme = buffer;\n          buffer = \"\";\n          if (stateOverride) {\n            break loop;\n          }\n          if (isRelativeScheme(this._scheme)) {\n            this._isRelative = true;\n          }\n          if (\"file\" == this._scheme) {\n            state = \"relative\";\n          } else if (this._isRelative && base && base._scheme == this._scheme) {\n            state = \"relative or authority\";\n          } else if (this._isRelative) {\n            state = \"authority first slash\";\n          } else {\n            state = \"scheme data\";\n          }\n        } else if (!stateOverride) {\n          buffer = \"\";\n          cursor = 0;\n          state = \"no scheme\";\n          continue;\n        } else if (EOF == c) {\n          break loop;\n        } else {\n          err(\"Code point not allowed in scheme: \" + c);\n          break loop;\n        }\n        break;\n\n       case \"scheme data\":\n        if (\"?\" == c) {\n          this._query = \"?\";\n          state = \"query\";\n        } else if (\"#\" == c) {\n          this._fragment = \"#\";\n          state = \"fragment\";\n        } else {\n          if (EOF != c && \"\t\" != c && \"\\n\" != c && \"\\r\" != c) {\n            this._schemeData += percentEscape(c);\n          }\n        }\n        break;\n\n       case \"no scheme\":\n        if (!base || !isRelativeScheme(base._scheme)) {\n          err(\"Missing scheme.\");\n          invalid.call(this);\n        } else {\n          state = \"relative\";\n          continue;\n        }\n        break;\n\n       case \"relative or authority\":\n        if (\"/\" == c && \"/\" == input[cursor + 1]) {\n          state = \"authority ignore slashes\";\n        } else {\n          err(\"Expected /, got: \" + c);\n          state = \"relative\";\n          continue;\n        }\n        break;\n\n       case \"relative\":\n        this._isRelative = true;\n        if (\"file\" != this._scheme) this._scheme = base._scheme;\n        if (EOF == c) {\n          this._host = base._host;\n          this._port = base._port;\n          this._path = base._path.slice();\n          this._query = base._query;\n          this._username = base._username;\n          this._password = base._password;\n          break loop;\n        } else if (\"/\" == c || \"\\\\\" == c) {\n          if (\"\\\\\" == c) err(\"\\\\ is an invalid code point.\");\n          state = \"relative slash\";\n        } else if (\"?\" == c) {\n          this._host = base._host;\n          this._port = base._port;\n          this._path = base._path.slice();\n          this._query = \"?\";\n          this._username = base._username;\n          this._password = base._password;\n          state = \"query\";\n        } else if (\"#\" == c) {\n          this._host = base._host;\n          this._port = base._port;\n          this._path = base._path.slice();\n          this._query = base._query;\n          this._fragment = \"#\";\n          this._username = base._username;\n          this._password = base._password;\n          state = \"fragment\";\n        } else {\n          var nextC = input[cursor + 1];\n          var nextNextC = input[cursor + 2];\n          if (\"file\" != this._scheme || !ALPHA.test(c) || nextC != \":\" && nextC != \"|\" || EOF != nextNextC && \"/\" != nextNextC && \"\\\\\" != nextNextC && \"?\" != nextNextC && \"#\" != nextNextC) {\n            this._host = base._host;\n            this._port = base._port;\n            this._username = base._username;\n            this._password = base._password;\n            this._path = base._path.slice();\n            this._path.pop();\n          }\n          state = \"relative path\";\n          continue;\n        }\n        break;\n\n       case \"relative slash\":\n        if (\"/\" == c || \"\\\\\" == c) {\n          if (\"\\\\\" == c) {\n            err(\"\\\\ is an invalid code point.\");\n          }\n          if (\"file\" == this._scheme) {\n            state = \"file host\";\n          } else {\n            state = \"authority ignore slashes\";\n          }\n        } else {\n          if (\"file\" != this._scheme) {\n            this._host = base._host;\n            this._port = base._port;\n            this._username = base._username;\n            this._password = base._password;\n          }\n          state = \"relative path\";\n          continue;\n        }\n        break;\n\n       case \"authority first slash\":\n        if (\"/\" == c) {\n          state = \"authority second slash\";\n        } else {\n          err(\"Expected '/', got: \" + c);\n          state = \"authority ignore slashes\";\n          continue;\n        }\n        break;\n\n       case \"authority second slash\":\n        state = \"authority ignore slashes\";\n        if (\"/\" != c) {\n          err(\"Expected '/', got: \" + c);\n          continue;\n        }\n        break;\n\n       case \"authority ignore slashes\":\n        if (\"/\" != c && \"\\\\\" != c) {\n          state = \"authority\";\n          continue;\n        } else {\n          err(\"Expected authority, got: \" + c);\n        }\n        break;\n\n       case \"authority\":\n        if (\"@\" == c) {\n          if (seenAt) {\n            err(\"@ already seen.\");\n            buffer += \"%40\";\n          }\n          seenAt = true;\n          for (var i = 0; i < buffer.length; i++) {\n            var cp = buffer[i];\n            if (\"\t\" == cp || \"\\n\" == cp || \"\\r\" == cp) {\n              err(\"Invalid whitespace in authority.\");\n              continue;\n            }\n            if (\":\" == cp && null === this._password) {\n              this._password = \"\";\n              continue;\n            }\n            var tempC = percentEscape(cp);\n            null !== this._password ? this._password += tempC : this._username += tempC;\n          }\n          buffer = \"\";\n        } else if (EOF == c || \"/\" == c || \"\\\\\" == c || \"?\" == c || \"#\" == c) {\n          cursor -= buffer.length;\n          buffer = \"\";\n          state = \"host\";\n          continue;\n        } else {\n          buffer += c;\n        }\n        break;\n\n       case \"file host\":\n        if (EOF == c || \"/\" == c || \"\\\\\" == c || \"?\" == c || \"#\" == c) {\n          if (buffer.length == 2 && ALPHA.test(buffer[0]) && (buffer[1] == \":\" || buffer[1] == \"|\")) {\n            state = \"relative path\";\n          } else if (buffer.length == 0) {\n            state = \"relative path start\";\n          } else {\n            this._host = IDNAToASCII.call(this, buffer);\n            buffer = \"\";\n            state = \"relative path start\";\n          }\n          continue;\n        } else if (\"\t\" == c || \"\\n\" == c || \"\\r\" == c) {\n          err(\"Invalid whitespace in file host.\");\n        } else {\n          buffer += c;\n        }\n        break;\n\n       case \"host\":\n       case \"hostname\":\n        if (\":\" == c && !seenBracket) {\n          this._host = IDNAToASCII.call(this, buffer);\n          buffer = \"\";\n          state = \"port\";\n          if (\"hostname\" == stateOverride) {\n            break loop;\n          }\n        } else if (EOF == c || \"/\" == c || \"\\\\\" == c || \"?\" == c || \"#\" == c) {\n          this._host = IDNAToASCII.call(this, buffer);\n          buffer = \"\";\n          state = \"relative path start\";\n          if (stateOverride) {\n            break loop;\n          }\n          continue;\n        } else if (\"\t\" != c && \"\\n\" != c && \"\\r\" != c) {\n          if (\"[\" == c) {\n            seenBracket = true;\n          } else if (\"]\" == c) {\n            seenBracket = false;\n          }\n          buffer += c;\n        } else {\n          err(\"Invalid code point in host/hostname: \" + c);\n        }\n        break;\n\n       case \"port\":\n        if (/[0-9]/.test(c)) {\n          buffer += c;\n        } else if (EOF == c || \"/\" == c || \"\\\\\" == c || \"?\" == c || \"#\" == c || stateOverride) {\n          if (\"\" != buffer) {\n            var temp = parseInt(buffer, 10);\n            if (temp != relative[this._scheme]) {\n              this._port = temp + \"\";\n            }\n            buffer = \"\";\n          }\n          if (stateOverride) {\n            break loop;\n          }\n          state = \"relative path start\";\n          continue;\n        } else if (\"\t\" == c || \"\\n\" == c || \"\\r\" == c) {\n          err(\"Invalid code point in port: \" + c);\n        } else {\n          invalid.call(this);\n        }\n        break;\n\n       case \"relative path start\":\n        if (\"\\\\\" == c) err(\"'\\\\' not allowed in path.\");\n        state = \"relative path\";\n        if (\"/\" != c && \"\\\\\" != c) {\n          continue;\n        }\n        break;\n\n       case \"relative path\":\n        if (EOF == c || \"/\" == c || \"\\\\\" == c || !stateOverride && (\"?\" == c || \"#\" == c)) {\n          if (\"\\\\\" == c) {\n            err(\"\\\\ not allowed in relative path.\");\n          }\n          var tmp;\n          if (tmp = relativePathDotMapping[buffer.toLowerCase()]) {\n            buffer = tmp;\n          }\n          if (\"..\" == buffer) {\n            this._path.pop();\n            if (\"/\" != c && \"\\\\\" != c) {\n              this._path.push(\"\");\n            }\n          } else if (\".\" == buffer && \"/\" != c && \"\\\\\" != c) {\n            this._path.push(\"\");\n          } else if (\".\" != buffer) {\n            if (\"file\" == this._scheme && this._path.length == 0 && buffer.length == 2 && ALPHA.test(buffer[0]) && buffer[1] == \"|\") {\n              buffer = buffer[0] + \":\";\n            }\n            this._path.push(buffer);\n          }\n          buffer = \"\";\n          if (\"?\" == c) {\n            this._query = \"?\";\n            state = \"query\";\n          } else if (\"#\" == c) {\n            this._fragment = \"#\";\n            state = \"fragment\";\n          }\n        } else if (\"\t\" != c && \"\\n\" != c && \"\\r\" != c) {\n          buffer += percentEscape(c);\n        }\n        break;\n\n       case \"query\":\n        if (!stateOverride && \"#\" == c) {\n          this._fragment = \"#\";\n          state = \"fragment\";\n        } else if (EOF != c && \"\t\" != c && \"\\n\" != c && \"\\r\" != c) {\n          this._query += percentEscapeQuery(c);\n        }\n        break;\n\n       case \"fragment\":\n        if (EOF != c && \"\t\" != c && \"\\n\" != c && \"\\r\" != c) {\n          this._fragment += c;\n        }\n        break;\n      }\n      cursor++;\n    }\n  }\n  function clear() {\n    this._scheme = \"\";\n    this._schemeData = \"\";\n    this._username = \"\";\n    this._password = null;\n    this._host = \"\";\n    this._port = \"\";\n    this._path = [];\n    this._query = \"\";\n    this._fragment = \"\";\n    this._isInvalid = false;\n    this._isRelative = false;\n  }\n  function jURL(url, base) {\n    if (base !== undefined && !(base instanceof jURL)) base = new jURL(String(base));\n    this._url = url;\n    clear.call(this);\n    var input = url.replace(/^[ \\t\\r\\n\\f]+|[ \\t\\r\\n\\f]+$/g, \"\");\n    parse.call(this, input, null, base);\n  }\n  jURL.prototype = {\n    toString: function() {\n      return this.href;\n    },\n    get href() {\n      if (this._isInvalid) return this._url;\n      var authority = \"\";\n      if (\"\" != this._username || null != this._password) {\n        authority = this._username + (null != this._password ? \":\" + this._password : \"\") + \"@\";\n      }\n      return this.protocol + (this._isRelative ? \"//\" + authority + this.host : \"\") + this.pathname + this._query + this._fragment;\n    },\n    set href(href) {\n      clear.call(this);\n      parse.call(this, href);\n    },\n    get protocol() {\n      return this._scheme + \":\";\n    },\n    set protocol(protocol) {\n      if (this._isInvalid) return;\n      parse.call(this, protocol + \":\", \"scheme start\");\n    },\n    get host() {\n      return this._isInvalid ? \"\" : this._port ? this._host + \":\" + this._port : this._host;\n    },\n    set host(host) {\n      if (this._isInvalid || !this._isRelative) return;\n      parse.call(this, host, \"host\");\n    },\n    get hostname() {\n      return this._host;\n    },\n    set hostname(hostname) {\n      if (this._isInvalid || !this._isRelative) return;\n      parse.call(this, hostname, \"hostname\");\n    },\n    get port() {\n      return this._port;\n    },\n    set port(port) {\n      if (this._isInvalid || !this._isRelative) return;\n      parse.call(this, port, \"port\");\n    },\n    get pathname() {\n      return this._isInvalid ? \"\" : this._isRelative ? \"/\" + this._path.join(\"/\") : this._schemeData;\n    },\n    set pathname(pathname) {\n      if (this._isInvalid || !this._isRelative) return;\n      this._path = [];\n      parse.call(this, pathname, \"relative path start\");\n    },\n    get search() {\n      return this._isInvalid || !this._query || \"?\" == this._query ? \"\" : this._query;\n    },\n    set search(search) {\n      if (this._isInvalid || !this._isRelative) return;\n      this._query = \"?\";\n      if (\"?\" == search[0]) search = search.slice(1);\n      parse.call(this, search, \"query\");\n    },\n    get hash() {\n      return this._isInvalid || !this._fragment || \"#\" == this._fragment ? \"\" : this._fragment;\n    },\n    set hash(hash) {\n      if (this._isInvalid) return;\n      this._fragment = \"#\";\n      if (\"#\" == hash[0]) hash = hash.slice(1);\n      parse.call(this, hash, \"fragment\");\n    },\n    get origin() {\n      var host;\n      if (this._isInvalid || !this._scheme) {\n        return \"\";\n      }\n      switch (this._scheme) {\n       case \"data\":\n       case \"file\":\n       case \"javascript\":\n       case \"mailto\":\n        return \"null\";\n      }\n      host = this.host;\n      if (!host) {\n        return \"\";\n      }\n      return this._scheme + \"://\" + host;\n    }\n  };\n  var OriginalURL = scope.URL;\n  if (OriginalURL) {\n    jURL.createObjectURL = function(blob) {\n      return OriginalURL.createObjectURL.apply(OriginalURL, arguments);\n    };\n    jURL.revokeObjectURL = function(url) {\n      OriginalURL.revokeObjectURL(url);\n    };\n  }\n  scope.URL = jURL;\n})(this);\n\nif (typeof WeakMap === \"undefined\") {\n  (function() {\n    var defineProperty = Object.defineProperty;\n    var counter = Date.now() % 1e9;\n    var WeakMap = function() {\n      this.name = \"__st\" + (Math.random() * 1e9 >>> 0) + (counter++ + \"__\");\n    };\n    WeakMap.prototype = {\n      set: function(key, value) {\n        var entry = key[this.name];\n        if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {\n          value: [ key, value ],\n          writable: true\n        });\n        return this;\n      },\n      get: function(key) {\n        var entry;\n        return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;\n      },\n      \"delete\": function(key) {\n        var entry = key[this.name];\n        if (!entry || entry[0] !== key) return false;\n        entry[0] = entry[1] = undefined;\n        return true;\n      },\n      has: function(key) {\n        var entry = key[this.name];\n        if (!entry) return false;\n        return entry[0] === key;\n      }\n    };\n    window.WeakMap = WeakMap;\n  })();\n}\n\n(function(global) {\n  var registrationsTable = new WeakMap();\n  var setImmediate;\n  if (/Trident|Edge/.test(navigator.userAgent)) {\n    setImmediate = setTimeout;\n  } else if (window.setImmediate) {\n    setImmediate = window.setImmediate;\n  } else {\n    var setImmediateQueue = [];\n    var sentinel = String(Math.random());\n    window.addEventListener(\"message\", function(e) {\n      if (e.data === sentinel) {\n        var queue = setImmediateQueue;\n        setImmediateQueue = [];\n        queue.forEach(function(func) {\n          func();\n        });\n      }\n    });\n    setImmediate = function(func) {\n      setImmediateQueue.push(func);\n      window.postMessage(sentinel, \"*\");\n    };\n  }\n  var isScheduled = false;\n  var scheduledObservers = [];\n  function scheduleCallback(observer) {\n    scheduledObservers.push(observer);\n    if (!isScheduled) {\n      isScheduled = true;\n      setImmediate(dispatchCallbacks);\n    }\n  }\n  function wrapIfNeeded(node) {\n    return window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrapIfNeeded(node) || node;\n  }\n  function dispatchCallbacks() {\n    isScheduled = false;\n    var observers = scheduledObservers;\n    scheduledObservers = [];\n    observers.sort(function(o1, o2) {\n      return o1.uid_ - o2.uid_;\n    });\n    var anyNonEmpty = false;\n    observers.forEach(function(observer) {\n      var queue = observer.takeRecords();\n      removeTransientObserversFor(observer);\n      if (queue.length) {\n        observer.callback_(queue, observer);\n        anyNonEmpty = true;\n      }\n    });\n    if (anyNonEmpty) dispatchCallbacks();\n  }\n  function removeTransientObserversFor(observer) {\n    observer.nodes_.forEach(function(node) {\n      var registrations = registrationsTable.get(node);\n      if (!registrations) return;\n      registrations.forEach(function(registration) {\n        if (registration.observer === observer) registration.removeTransientObservers();\n      });\n    });\n  }\n  function forEachAncestorAndObserverEnqueueRecord(target, callback) {\n    for (var node = target; node; node = node.parentNode) {\n      var registrations = registrationsTable.get(node);\n      if (registrations) {\n        for (var j = 0; j < registrations.length; j++) {\n          var registration = registrations[j];\n          var options = registration.options;\n          if (node !== target && !options.subtree) continue;\n          var record = callback(options);\n          if (record) registration.enqueue(record);\n        }\n      }\n    }\n  }\n  var uidCounter = 0;\n  function JsMutationObserver(callback) {\n    this.callback_ = callback;\n    this.nodes_ = [];\n    this.records_ = [];\n    this.uid_ = ++uidCounter;\n  }\n  JsMutationObserver.prototype = {\n    observe: function(target, options) {\n      target = wrapIfNeeded(target);\n      if (!options.childList && !options.attributes && !options.characterData || options.attributeOldValue && !options.attributes || options.attributeFilter && options.attributeFilter.length && !options.attributes || options.characterDataOldValue && !options.characterData) {\n        throw new SyntaxError();\n      }\n      var registrations = registrationsTable.get(target);\n      if (!registrations) registrationsTable.set(target, registrations = []);\n      var registration;\n      for (var i = 0; i < registrations.length; i++) {\n        if (registrations[i].observer === this) {\n          registration = registrations[i];\n          registration.removeListeners();\n          registration.options = options;\n          break;\n        }\n      }\n      if (!registration) {\n        registration = new Registration(this, target, options);\n        registrations.push(registration);\n        this.nodes_.push(target);\n      }\n      registration.addListeners();\n    },\n    disconnect: function() {\n      this.nodes_.forEach(function(node) {\n        var registrations = registrationsTable.get(node);\n        for (var i = 0; i < registrations.length; i++) {\n          var registration = registrations[i];\n          if (registration.observer === this) {\n            registration.removeListeners();\n            registrations.splice(i, 1);\n            break;\n          }\n        }\n      }, this);\n      this.records_ = [];\n    },\n    takeRecords: function() {\n      var copyOfRecords = this.records_;\n      this.records_ = [];\n      return copyOfRecords;\n    }\n  };\n  function MutationRecord(type, target) {\n    this.type = type;\n    this.target = target;\n    this.addedNodes = [];\n    this.removedNodes = [];\n    this.previousSibling = null;\n    this.nextSibling = null;\n    this.attributeName = null;\n    this.attributeNamespace = null;\n    this.oldValue = null;\n  }\n  function copyMutationRecord(original) {\n    var record = new MutationRecord(original.type, original.target);\n    record.addedNodes = original.addedNodes.slice();\n    record.removedNodes = original.removedNodes.slice();\n    record.previousSibling = original.previousSibling;\n    record.nextSibling = original.nextSibling;\n    record.attributeName = original.attributeName;\n    record.attributeNamespace = original.attributeNamespace;\n    record.oldValue = original.oldValue;\n    return record;\n  }\n  var currentRecord, recordWithOldValue;\n  function getRecord(type, target) {\n    return currentRecord = new MutationRecord(type, target);\n  }\n  function getRecordWithOldValue(oldValue) {\n    if (recordWithOldValue) return recordWithOldValue;\n    recordWithOldValue = copyMutationRecord(currentRecord);\n    recordWithOldValue.oldValue = oldValue;\n    return recordWithOldValue;\n  }\n  function clearRecords() {\n    currentRecord = recordWithOldValue = undefined;\n  }\n  function recordRepresentsCurrentMutation(record) {\n    return record === recordWithOldValue || record === currentRecord;\n  }\n  function selectRecord(lastRecord, newRecord) {\n    if (lastRecord === newRecord) return lastRecord;\n    if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord)) return recordWithOldValue;\n    return null;\n  }\n  function Registration(observer, target, options) {\n    this.observer = observer;\n    this.target = target;\n    this.options = options;\n    this.transientObservedNodes = [];\n  }\n  Registration.prototype = {\n    enqueue: function(record) {\n      var records = this.observer.records_;\n      var length = records.length;\n      if (records.length > 0) {\n        var lastRecord = records[length - 1];\n        var recordToReplaceLast = selectRecord(lastRecord, record);\n        if (recordToReplaceLast) {\n          records[length - 1] = recordToReplaceLast;\n          return;\n        }\n      } else {\n        scheduleCallback(this.observer);\n      }\n      records[length] = record;\n    },\n    addListeners: function() {\n      this.addListeners_(this.target);\n    },\n    addListeners_: function(node) {\n      var options = this.options;\n      if (options.attributes) node.addEventListener(\"DOMAttrModified\", this, true);\n      if (options.characterData) node.addEventListener(\"DOMCharacterDataModified\", this, true);\n      if (options.childList) node.addEventListener(\"DOMNodeInserted\", this, true);\n      if (options.childList || options.subtree) node.addEventListener(\"DOMNodeRemoved\", this, true);\n    },\n    removeListeners: function() {\n      this.removeListeners_(this.target);\n    },\n    removeListeners_: function(node) {\n      var options = this.options;\n      if (options.attributes) node.removeEventListener(\"DOMAttrModified\", this, true);\n      if (options.characterData) node.removeEventListener(\"DOMCharacterDataModified\", this, true);\n      if (options.childList) node.removeEventListener(\"DOMNodeInserted\", this, true);\n      if (options.childList || options.subtree) node.removeEventListener(\"DOMNodeRemoved\", this, true);\n    },\n    addTransientObserver: function(node) {\n      if (node === this.target) return;\n      this.addListeners_(node);\n      this.transientObservedNodes.push(node);\n      var registrations = registrationsTable.get(node);\n      if (!registrations) registrationsTable.set(node, registrations = []);\n      registrations.push(this);\n    },\n    removeTransientObservers: function() {\n      var transientObservedNodes = this.transientObservedNodes;\n      this.transientObservedNodes = [];\n      transientObservedNodes.forEach(function(node) {\n        this.removeListeners_(node);\n        var registrations = registrationsTable.get(node);\n        for (var i = 0; i < registrations.length; i++) {\n          if (registrations[i] === this) {\n            registrations.splice(i, 1);\n            break;\n          }\n        }\n      }, this);\n    },\n    handleEvent: function(e) {\n      e.stopImmediatePropagation();\n      switch (e.type) {\n       case \"DOMAttrModified\":\n        var name = e.attrName;\n        var namespace = e.relatedNode.namespaceURI;\n        var target = e.target;\n        var record = new getRecord(\"attributes\", target);\n        record.attributeName = name;\n        record.attributeNamespace = namespace;\n        var oldValue = e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;\n        forEachAncestorAndObserverEnqueueRecord(target, function(options) {\n          if (!options.attributes) return;\n          if (options.attributeFilter && options.attributeFilter.length && options.attributeFilter.indexOf(name) === -1 && options.attributeFilter.indexOf(namespace) === -1) {\n            return;\n          }\n          if (options.attributeOldValue) return getRecordWithOldValue(oldValue);\n          return record;\n        });\n        break;\n\n       case \"DOMCharacterDataModified\":\n        var target = e.target;\n        var record = getRecord(\"characterData\", target);\n        var oldValue = e.prevValue;\n        forEachAncestorAndObserverEnqueueRecord(target, function(options) {\n          if (!options.characterData) return;\n          if (options.characterDataOldValue) return getRecordWithOldValue(oldValue);\n          return record;\n        });\n        break;\n\n       case \"DOMNodeRemoved\":\n        this.addTransientObserver(e.target);\n\n       case \"DOMNodeInserted\":\n        var changedNode = e.target;\n        var addedNodes, removedNodes;\n        if (e.type === \"DOMNodeInserted\") {\n          addedNodes = [ changedNode ];\n          removedNodes = [];\n        } else {\n          addedNodes = [];\n          removedNodes = [ changedNode ];\n        }\n        var previousSibling = changedNode.previousSibling;\n        var nextSibling = changedNode.nextSibling;\n        var record = getRecord(\"childList\", e.target.parentNode);\n        record.addedNodes = addedNodes;\n        record.removedNodes = removedNodes;\n        record.previousSibling = previousSibling;\n        record.nextSibling = nextSibling;\n        forEachAncestorAndObserverEnqueueRecord(e.relatedNode, function(options) {\n          if (!options.childList) return;\n          return record;\n        });\n      }\n      clearRecords();\n    }\n  };\n  global.JsMutationObserver = JsMutationObserver;\n  if (!global.MutationObserver) global.MutationObserver = JsMutationObserver;\n})(this);\n\nwindow.HTMLImports = window.HTMLImports || {\n  flags: {}\n};\n\n(function(scope) {\n  var IMPORT_LINK_TYPE = \"import\";\n  var useNative = Boolean(IMPORT_LINK_TYPE in document.createElement(\"link\"));\n  var hasShadowDOMPolyfill = Boolean(window.ShadowDOMPolyfill);\n  var wrap = function(node) {\n    return hasShadowDOMPolyfill ? window.ShadowDOMPolyfill.wrapIfNeeded(node) : node;\n  };\n  var rootDocument = wrap(document);\n  var currentScriptDescriptor = {\n    get: function() {\n      var script = window.HTMLImports.currentScript || document.currentScript || (document.readyState !== \"complete\" ? document.scripts[document.scripts.length - 1] : null);\n      return wrap(script);\n    },\n    configurable: true\n  };\n  Object.defineProperty(document, \"_currentScript\", currentScriptDescriptor);\n  Object.defineProperty(rootDocument, \"_currentScript\", currentScriptDescriptor);\n  var isIE = /Trident/.test(navigator.userAgent);\n  function whenReady(callback, doc) {\n    doc = doc || rootDocument;\n    whenDocumentReady(function() {\n      watchImportsLoad(callback, doc);\n    }, doc);\n  }\n  var requiredReadyState = isIE ? \"complete\" : \"interactive\";\n  var READY_EVENT = \"readystatechange\";\n  function isDocumentReady(doc) {\n    return doc.readyState === \"complete\" || doc.readyState === requiredReadyState;\n  }\n  function whenDocumentReady(callback, doc) {\n    if (!isDocumentReady(doc)) {\n      var checkReady = function() {\n        if (doc.readyState === \"complete\" || doc.readyState === requiredReadyState) {\n          doc.removeEventListener(READY_EVENT, checkReady);\n          whenDocumentReady(callback, doc);\n        }\n      };\n      doc.addEventListener(READY_EVENT, checkReady);\n    } else if (callback) {\n      callback();\n    }\n  }\n  function markTargetLoaded(event) {\n    event.target.__loaded = true;\n  }\n  function watchImportsLoad(callback, doc) {\n    var imports = doc.querySelectorAll(\"link[rel=import]\");\n    var parsedCount = 0, importCount = imports.length, newImports = [], errorImports = [];\n    function checkDone() {\n      if (parsedCount == importCount && callback) {\n        callback({\n          allImports: imports,\n          loadedImports: newImports,\n          errorImports: errorImports\n        });\n      }\n    }\n    function loadedImport(e) {\n      markTargetLoaded(e);\n      newImports.push(this);\n      parsedCount++;\n      checkDone();\n    }\n    function errorLoadingImport(e) {\n      errorImports.push(this);\n      parsedCount++;\n      checkDone();\n    }\n    if (importCount) {\n      for (var i = 0, imp; i < importCount && (imp = imports[i]); i++) {\n        if (isImportLoaded(imp)) {\n          parsedCount++;\n          checkDone();\n        } else {\n          imp.addEventListener(\"load\", loadedImport);\n          imp.addEventListener(\"error\", errorLoadingImport);\n        }\n      }\n    } else {\n      checkDone();\n    }\n  }\n  function isImportLoaded(link) {\n    return useNative ? link.__loaded || link.import && link.import.readyState !== \"loading\" : link.__importParsed;\n  }\n  if (useNative) {\n    new MutationObserver(function(mxns) {\n      for (var i = 0, l = mxns.length, m; i < l && (m = mxns[i]); i++) {\n        if (m.addedNodes) {\n          handleImports(m.addedNodes);\n        }\n      }\n    }).observe(document.head, {\n      childList: true\n    });\n    function handleImports(nodes) {\n      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {\n        if (isImport(n)) {\n          handleImport(n);\n        }\n      }\n    }\n    function isImport(element) {\n      return element.localName === \"link\" && element.rel === \"import\";\n    }\n    function handleImport(element) {\n      var loaded = element.import;\n      if (loaded) {\n        markTargetLoaded({\n          target: element\n        });\n      } else {\n        element.addEventListener(\"load\", markTargetLoaded);\n        element.addEventListener(\"error\", markTargetLoaded);\n      }\n    }\n    (function() {\n      if (document.readyState === \"loading\") {\n        var imports = document.querySelectorAll(\"link[rel=import]\");\n        for (var i = 0, l = imports.length, imp; i < l && (imp = imports[i]); i++) {\n          handleImport(imp);\n        }\n      }\n    })();\n  }\n  whenReady(function(detail) {\n    window.HTMLImports.ready = true;\n    window.HTMLImports.readyTime = new Date().getTime();\n    var evt = rootDocument.createEvent(\"CustomEvent\");\n    evt.initCustomEvent(\"HTMLImportsLoaded\", true, true, detail);\n    rootDocument.dispatchEvent(evt);\n  });\n  scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;\n  scope.useNative = useNative;\n  scope.rootDocument = rootDocument;\n  scope.whenReady = whenReady;\n  scope.isIE = isIE;\n})(window.HTMLImports);\n\n(function(scope) {\n  var modules = [];\n  var addModule = function(module) {\n    modules.push(module);\n  };\n  var initializeModules = function() {\n    modules.forEach(function(module) {\n      module(scope);\n    });\n  };\n  scope.addModule = addModule;\n  scope.initializeModules = initializeModules;\n})(window.HTMLImports);\n\nwindow.HTMLImports.addModule(function(scope) {\n  var CSS_URL_REGEXP = /(url\\()([^)]*)(\\))/g;\n  var CSS_IMPORT_REGEXP = /(@import[\\s]+(?!url\\())([^;]*)(;)/g;\n  var path = {\n    resolveUrlsInStyle: function(style, linkUrl) {\n      var doc = style.ownerDocument;\n      var resolver = doc.createElement(\"a\");\n      style.textContent = this.resolveUrlsInCssText(style.textContent, linkUrl, resolver);\n      return style;\n    },\n    resolveUrlsInCssText: function(cssText, linkUrl, urlObj) {\n      var r = this.replaceUrls(cssText, urlObj, linkUrl, CSS_URL_REGEXP);\n      r = this.replaceUrls(r, urlObj, linkUrl, CSS_IMPORT_REGEXP);\n      return r;\n    },\n    replaceUrls: function(text, urlObj, linkUrl, regexp) {\n      return text.replace(regexp, function(m, pre, url, post) {\n        var urlPath = url.replace(/[\"']/g, \"\");\n        if (linkUrl) {\n          urlPath = new URL(urlPath, linkUrl).href;\n        }\n        urlObj.href = urlPath;\n        urlPath = urlObj.href;\n        return pre + \"'\" + urlPath + \"'\" + post;\n      });\n    }\n  };\n  scope.path = path;\n});\n\nwindow.HTMLImports.addModule(function(scope) {\n  var xhr = {\n    async: true,\n    ok: function(request) {\n      return request.status >= 200 && request.status < 300 || request.status === 304 || request.status === 0;\n    },\n    load: function(url, next, nextContext) {\n      var request = new XMLHttpRequest();\n      if (scope.flags.debug || scope.flags.bust) {\n        url += \"?\" + Math.random();\n      }\n      request.open(\"GET\", url, xhr.async);\n      request.addEventListener(\"readystatechange\", function(e) {\n        if (request.readyState === 4) {\n          var locationHeader = request.getResponseHeader(\"Location\");\n          var redirectedUrl = null;\n          if (locationHeader) {\n            var redirectedUrl = locationHeader.substr(0, 1) === \"/\" ? location.origin + locationHeader : locationHeader;\n          }\n          next.call(nextContext, !xhr.ok(request) && request, request.response || request.responseText, redirectedUrl);\n        }\n      });\n      request.send();\n      return request;\n    },\n    loadDocument: function(url, next, nextContext) {\n      this.load(url, next, nextContext).responseType = \"document\";\n    }\n  };\n  scope.xhr = xhr;\n});\n\nwindow.HTMLImports.addModule(function(scope) {\n  var xhr = scope.xhr;\n  var flags = scope.flags;\n  var Loader = function(onLoad, onComplete) {\n    this.cache = {};\n    this.onload = onLoad;\n    this.oncomplete = onComplete;\n    this.inflight = 0;\n    this.pending = {};\n  };\n  Loader.prototype = {\n    addNodes: function(nodes) {\n      this.inflight += nodes.length;\n      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {\n        this.require(n);\n      }\n      this.checkDone();\n    },\n    addNode: function(node) {\n      this.inflight++;\n      this.require(node);\n      this.checkDone();\n    },\n    require: function(elt) {\n      var url = elt.src || elt.href;\n      elt.__nodeUrl = url;\n      if (!this.dedupe(url, elt)) {\n        this.fetch(url, elt);\n      }\n    },\n    dedupe: function(url, elt) {\n      if (this.pending[url]) {\n        this.pending[url].push(elt);\n        return true;\n      }\n      var resource;\n      if (this.cache[url]) {\n        this.onload(url, elt, this.cache[url]);\n        this.tail();\n        return true;\n      }\n      this.pending[url] = [ elt ];\n      return false;\n    },\n    fetch: function(url, elt) {\n      flags.load && console.log(\"fetch\", url, elt);\n      if (!url) {\n        setTimeout(function() {\n          this.receive(url, elt, {\n            error: \"href must be specified\"\n          }, null);\n        }.bind(this), 0);\n      } else if (url.match(/^data:/)) {\n        var pieces = url.split(\",\");\n        var header = pieces[0];\n        var body = pieces[1];\n        if (header.indexOf(\";base64\") > -1) {\n          body = atob(body);\n        } else {\n          body = decodeURIComponent(body);\n        }\n        setTimeout(function() {\n          this.receive(url, elt, null, body);\n        }.bind(this), 0);\n      } else {\n        var receiveXhr = function(err, resource, redirectedUrl) {\n          this.receive(url, elt, err, resource, redirectedUrl);\n        }.bind(this);\n        xhr.load(url, receiveXhr);\n      }\n    },\n    receive: function(url, elt, err, resource, redirectedUrl) {\n      this.cache[url] = resource;\n      var $p = this.pending[url];\n      for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {\n        this.onload(url, p, resource, err, redirectedUrl);\n        this.tail();\n      }\n      this.pending[url] = null;\n    },\n    tail: function() {\n      --this.inflight;\n      this.checkDone();\n    },\n    checkDone: function() {\n      if (!this.inflight) {\n        this.oncomplete();\n      }\n    }\n  };\n  scope.Loader = Loader;\n});\n\nwindow.HTMLImports.addModule(function(scope) {\n  var Observer = function(addCallback) {\n    this.addCallback = addCallback;\n    this.mo = new MutationObserver(this.handler.bind(this));\n  };\n  Observer.prototype = {\n    handler: function(mutations) {\n      for (var i = 0, l = mutations.length, m; i < l && (m = mutations[i]); i++) {\n        if (m.type === \"childList\" && m.addedNodes.length) {\n          this.addedNodes(m.addedNodes);\n        }\n      }\n    },\n    addedNodes: function(nodes) {\n      if (this.addCallback) {\n        this.addCallback(nodes);\n      }\n      for (var i = 0, l = nodes.length, n, loading; i < l && (n = nodes[i]); i++) {\n        if (n.children && n.children.length) {\n          this.addedNodes(n.children);\n        }\n      }\n    },\n    observe: function(root) {\n      this.mo.observe(root, {\n        childList: true,\n        subtree: true\n      });\n    }\n  };\n  scope.Observer = Observer;\n});\n\nwindow.HTMLImports.addModule(function(scope) {\n  var path = scope.path;\n  var rootDocument = scope.rootDocument;\n  var flags = scope.flags;\n  var isIE = scope.isIE;\n  var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;\n  var IMPORT_SELECTOR = \"link[rel=\" + IMPORT_LINK_TYPE + \"]\";\n  var importParser = {\n    documentSelectors: IMPORT_SELECTOR,\n    importsSelectors: [ IMPORT_SELECTOR, \"link[rel=stylesheet]:not([type])\", \"style:not([type])\", \"script:not([type])\", 'script[type=\"application/javascript\"]', 'script[type=\"text/javascript\"]' ].join(\",\"),\n    map: {\n      link: \"parseLink\",\n      script: \"parseScript\",\n      style: \"parseStyle\"\n    },\n    dynamicElements: [],\n    parseNext: function() {\n      var next = this.nextToParse();\n      if (next) {\n        this.parse(next);\n      }\n    },\n    parse: function(elt) {\n      if (this.isParsed(elt)) {\n        flags.parse && console.log(\"[%s] is already parsed\", elt.localName);\n        return;\n      }\n      var fn = this[this.map[elt.localName]];\n      if (fn) {\n        this.markParsing(elt);\n        fn.call(this, elt);\n      }\n    },\n    parseDynamic: function(elt, quiet) {\n      this.dynamicElements.push(elt);\n      if (!quiet) {\n        this.parseNext();\n      }\n    },\n    markParsing: function(elt) {\n      flags.parse && console.log(\"parsing\", elt);\n      this.parsingElement = elt;\n    },\n    markParsingComplete: function(elt) {\n      elt.__importParsed = true;\n      this.markDynamicParsingComplete(elt);\n      if (elt.__importElement) {\n        elt.__importElement.__importParsed = true;\n        this.markDynamicParsingComplete(elt.__importElement);\n      }\n      this.parsingElement = null;\n      flags.parse && console.log(\"completed\", elt);\n    },\n    markDynamicParsingComplete: function(elt) {\n      var i = this.dynamicElements.indexOf(elt);\n      if (i >= 0) {\n        this.dynamicElements.splice(i, 1);\n      }\n    },\n    parseImport: function(elt) {\n      elt.import = elt.__doc;\n      if (window.HTMLImports.__importsParsingHook) {\n        window.HTMLImports.__importsParsingHook(elt);\n      }\n      if (elt.import) {\n        elt.import.__importParsed = true;\n      }\n      this.markParsingComplete(elt);\n      if (elt.__resource && !elt.__error) {\n        elt.dispatchEvent(new CustomEvent(\"load\", {\n          bubbles: false\n        }));\n      } else {\n        elt.dispatchEvent(new CustomEvent(\"error\", {\n          bubbles: false\n        }));\n      }\n      if (elt.__pending) {\n        var fn;\n        while (elt.__pending.length) {\n          fn = elt.__pending.shift();\n          if (fn) {\n            fn({\n              target: elt\n            });\n          }\n        }\n      }\n      this.parseNext();\n    },\n    parseLink: function(linkElt) {\n      if (nodeIsImport(linkElt)) {\n        this.parseImport(linkElt);\n      } else {\n        linkElt.href = linkElt.href;\n        this.parseGeneric(linkElt);\n      }\n    },\n    parseStyle: function(elt) {\n      var src = elt;\n      elt = cloneStyle(elt);\n      src.__appliedElement = elt;\n      elt.__importElement = src;\n      this.parseGeneric(elt);\n    },\n    parseGeneric: function(elt) {\n      this.trackElement(elt);\n      this.addElementToDocument(elt);\n    },\n    rootImportForElement: function(elt) {\n      var n = elt;\n      while (n.ownerDocument.__importLink) {\n        n = n.ownerDocument.__importLink;\n      }\n      return n;\n    },\n    addElementToDocument: function(elt) {\n      var port = this.rootImportForElement(elt.__importElement || elt);\n      port.parentNode.insertBefore(elt, port);\n    },\n    trackElement: function(elt, callback) {\n      var self = this;\n      var done = function(e) {\n        elt.removeEventListener(\"load\", done);\n        elt.removeEventListener(\"error\", done);\n        if (callback) {\n          callback(e);\n        }\n        self.markParsingComplete(elt);\n        self.parseNext();\n      };\n      elt.addEventListener(\"load\", done);\n      elt.addEventListener(\"error\", done);\n      if (isIE && elt.localName === \"style\") {\n        var fakeLoad = false;\n        if (elt.textContent.indexOf(\"@import\") == -1) {\n          fakeLoad = true;\n        } else if (elt.sheet) {\n          fakeLoad = true;\n          var csr = elt.sheet.cssRules;\n          var len = csr ? csr.length : 0;\n          for (var i = 0, r; i < len && (r = csr[i]); i++) {\n            if (r.type === CSSRule.IMPORT_RULE) {\n              fakeLoad = fakeLoad && Boolean(r.styleSheet);\n            }\n          }\n        }\n        if (fakeLoad) {\n          setTimeout(function() {\n            elt.dispatchEvent(new CustomEvent(\"load\", {\n              bubbles: false\n            }));\n          });\n        }\n      }\n    },\n    parseScript: function(scriptElt) {\n      var script = document.createElement(\"script\");\n      script.__importElement = scriptElt;\n      script.src = scriptElt.src ? scriptElt.src : generateScriptDataUrl(scriptElt);\n      scope.currentScript = scriptElt;\n      this.trackElement(script, function(e) {\n        if (script.parentNode) {\n          script.parentNode.removeChild(script);\n        }\n        scope.currentScript = null;\n      });\n      this.addElementToDocument(script);\n    },\n    nextToParse: function() {\n      this._mayParse = [];\n      return !this.parsingElement && (this.nextToParseInDoc(rootDocument) || this.nextToParseDynamic());\n    },\n    nextToParseInDoc: function(doc, link) {\n      if (doc && this._mayParse.indexOf(doc) < 0) {\n        this._mayParse.push(doc);\n        var nodes = doc.querySelectorAll(this.parseSelectorsForNode(doc));\n        for (var i = 0, l = nodes.length, p = 0, n; i < l && (n = nodes[i]); i++) {\n          if (!this.isParsed(n)) {\n            if (this.hasResource(n)) {\n              return nodeIsImport(n) ? this.nextToParseInDoc(n.__doc, n) : n;\n            } else {\n              return;\n            }\n          }\n        }\n      }\n      return link;\n    },\n    nextToParseDynamic: function() {\n      return this.dynamicElements[0];\n    },\n    parseSelectorsForNode: function(node) {\n      var doc = node.ownerDocument || node;\n      return doc === rootDocument ? this.documentSelectors : this.importsSelectors;\n    },\n    isParsed: function(node) {\n      return node.__importParsed;\n    },\n    needsDynamicParsing: function(elt) {\n      return this.dynamicElements.indexOf(elt) >= 0;\n    },\n    hasResource: function(node) {\n      if (nodeIsImport(node) && node.__doc === undefined) {\n        return false;\n      }\n      return true;\n    }\n  };\n  function nodeIsImport(elt) {\n    return elt.localName === \"link\" && elt.rel === IMPORT_LINK_TYPE;\n  }\n  function generateScriptDataUrl(script) {\n    var scriptContent = generateScriptContent(script);\n    return \"data:text/javascript;charset=utf-8,\" + encodeURIComponent(scriptContent);\n  }\n  function generateScriptContent(script) {\n    return script.textContent + generateSourceMapHint(script);\n  }\n  function generateSourceMapHint(script) {\n    var owner = script.ownerDocument;\n    owner.__importedScripts = owner.__importedScripts || 0;\n    var moniker = script.ownerDocument.baseURI;\n    var num = owner.__importedScripts ? \"-\" + owner.__importedScripts : \"\";\n    owner.__importedScripts++;\n    return \"\\n//# sourceURL=\" + moniker + num + \".js\\n\";\n  }\n  function cloneStyle(style) {\n    var clone = style.ownerDocument.createElement(\"style\");\n    clone.textContent = style.textContent;\n    path.resolveUrlsInStyle(clone);\n    return clone;\n  }\n  scope.parser = importParser;\n  scope.IMPORT_SELECTOR = IMPORT_SELECTOR;\n});\n\nwindow.HTMLImports.addModule(function(scope) {\n  var flags = scope.flags;\n  var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;\n  var IMPORT_SELECTOR = scope.IMPORT_SELECTOR;\n  var rootDocument = scope.rootDocument;\n  var Loader = scope.Loader;\n  var Observer = scope.Observer;\n  var parser = scope.parser;\n  var importer = {\n    documents: {},\n    documentPreloadSelectors: IMPORT_SELECTOR,\n    importsPreloadSelectors: [ IMPORT_SELECTOR ].join(\",\"),\n    loadNode: function(node) {\n      importLoader.addNode(node);\n    },\n    loadSubtree: function(parent) {\n      var nodes = this.marshalNodes(parent);\n      importLoader.addNodes(nodes);\n    },\n    marshalNodes: function(parent) {\n      return parent.querySelectorAll(this.loadSelectorsForNode(parent));\n    },\n    loadSelectorsForNode: function(node) {\n      var doc = node.ownerDocument || node;\n      return doc === rootDocument ? this.documentPreloadSelectors : this.importsPreloadSelectors;\n    },\n    loaded: function(url, elt, resource, err, redirectedUrl) {\n      flags.load && console.log(\"loaded\", url, elt);\n      elt.__resource = resource;\n      elt.__error = err;\n      if (isImportLink(elt)) {\n        var doc = this.documents[url];\n        if (doc === undefined) {\n          doc = err ? null : makeDocument(resource, redirectedUrl || url);\n          if (doc) {\n            doc.__importLink = elt;\n            this.bootDocument(doc);\n          }\n          this.documents[url] = doc;\n        }\n        elt.__doc = doc;\n      }\n      parser.parseNext();\n    },\n    bootDocument: function(doc) {\n      this.loadSubtree(doc);\n      this.observer.observe(doc);\n      parser.parseNext();\n    },\n    loadedAll: function() {\n      parser.parseNext();\n    }\n  };\n  var importLoader = new Loader(importer.loaded.bind(importer), importer.loadedAll.bind(importer));\n  importer.observer = new Observer();\n  function isImportLink(elt) {\n    return isLinkRel(elt, IMPORT_LINK_TYPE);\n  }\n  function isLinkRel(elt, rel) {\n    return elt.localName === \"link\" && elt.getAttribute(\"rel\") === rel;\n  }\n  function hasBaseURIAccessor(doc) {\n    return !!Object.getOwnPropertyDescriptor(doc, \"baseURI\");\n  }\n  function makeDocument(resource, url) {\n    var doc = document.implementation.createHTMLDocument(IMPORT_LINK_TYPE);\n    doc._URL = url;\n    var base = doc.createElement(\"base\");\n    base.setAttribute(\"href\", url);\n    if (!doc.baseURI && !hasBaseURIAccessor(doc)) {\n      Object.defineProperty(doc, \"baseURI\", {\n        value: url\n      });\n    }\n    var meta = doc.createElement(\"meta\");\n    meta.setAttribute(\"charset\", \"utf-8\");\n    doc.head.appendChild(meta);\n    doc.head.appendChild(base);\n    doc.body.innerHTML = resource;\n    if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {\n      HTMLTemplateElement.bootstrap(doc);\n    }\n    return doc;\n  }\n  if (!document.baseURI) {\n    var baseURIDescriptor = {\n      get: function() {\n        var base = document.querySelector(\"base\");\n        return base ? base.href : window.location.href;\n      },\n      configurable: true\n    };\n    Object.defineProperty(document, \"baseURI\", baseURIDescriptor);\n    Object.defineProperty(rootDocument, \"baseURI\", baseURIDescriptor);\n  }\n  scope.importer = importer;\n  scope.importLoader = importLoader;\n});\n\nwindow.HTMLImports.addModule(function(scope) {\n  var parser = scope.parser;\n  var importer = scope.importer;\n  var dynamic = {\n    added: function(nodes) {\n      var owner, parsed, loading;\n      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {\n        if (!owner) {\n          owner = n.ownerDocument;\n          parsed = parser.isParsed(owner);\n        }\n        loading = this.shouldLoadNode(n);\n        if (loading) {\n          importer.loadNode(n);\n        }\n        if (this.shouldParseNode(n) && parsed) {\n          parser.parseDynamic(n, loading);\n        }\n      }\n    },\n    shouldLoadNode: function(node) {\n      return node.nodeType === 1 && matches.call(node, importer.loadSelectorsForNode(node));\n    },\n    shouldParseNode: function(node) {\n      return node.nodeType === 1 && matches.call(node, parser.parseSelectorsForNode(node));\n    }\n  };\n  importer.observer.addCallback = dynamic.added.bind(dynamic);\n  var matches = HTMLElement.prototype.matches || HTMLElement.prototype.matchesSelector || HTMLElement.prototype.webkitMatchesSelector || HTMLElement.prototype.mozMatchesSelector || HTMLElement.prototype.msMatchesSelector;\n});\n\n(function(scope) {\n  var initializeModules = scope.initializeModules;\n  var isIE = scope.isIE;\n  if (scope.useNative) {\n    return;\n  }\n  if (isIE && typeof window.CustomEvent !== \"function\") {\n    window.CustomEvent = function(inType, params) {\n      params = params || {};\n      var e = document.createEvent(\"CustomEvent\");\n      e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);\n      e.preventDefault = function() {\n        Object.defineProperty(this, \"defaultPrevented\", {\n          get: function() {\n            return true;\n          }\n        });\n      };\n      return e;\n    };\n    window.CustomEvent.prototype = window.Event.prototype;\n  }\n  initializeModules();\n  var rootDocument = scope.rootDocument;\n  function bootstrap() {\n    window.HTMLImports.importer.bootDocument(rootDocument);\n  }\n  if (document.readyState === \"complete\" || document.readyState === \"interactive\" && !window.attachEvent) {\n    bootstrap();\n  } else {\n    document.addEventListener(\"DOMContentLoaded\", bootstrap);\n  }\n})(window.HTMLImports);\n\nwindow.CustomElements = window.CustomElements || {\n  flags: {}\n};\n\n(function(scope) {\n  var flags = scope.flags;\n  var modules = [];\n  var addModule = function(module) {\n    modules.push(module);\n  };\n  var initializeModules = function() {\n    modules.forEach(function(module) {\n      module(scope);\n    });\n  };\n  scope.addModule = addModule;\n  scope.initializeModules = initializeModules;\n  scope.hasNative = Boolean(document.registerElement);\n  scope.useNative = !flags.register && scope.hasNative && !window.ShadowDOMPolyfill && (!window.HTMLImports || window.HTMLImports.useNative);\n})(window.CustomElements);\n\nwindow.CustomElements.addModule(function(scope) {\n  var IMPORT_LINK_TYPE = window.HTMLImports ? window.HTMLImports.IMPORT_LINK_TYPE : \"none\";\n  function forSubtree(node, cb) {\n    findAllElements(node, function(e) {\n      if (cb(e)) {\n        return true;\n      }\n      forRoots(e, cb);\n    });\n    forRoots(node, cb);\n  }\n  function findAllElements(node, find, data) {\n    var e = node.firstElementChild;\n    if (!e) {\n      e = node.firstChild;\n      while (e && e.nodeType !== Node.ELEMENT_NODE) {\n        e = e.nextSibling;\n      }\n    }\n    while (e) {\n      if (find(e, data) !== true) {\n        findAllElements(e, find, data);\n      }\n      e = e.nextElementSibling;\n    }\n    return null;\n  }\n  function forRoots(node, cb) {\n    var root = node.shadowRoot;\n    while (root) {\n      forSubtree(root, cb);\n      root = root.olderShadowRoot;\n    }\n  }\n  function forDocumentTree(doc, cb) {\n    _forDocumentTree(doc, cb, []);\n  }\n  function _forDocumentTree(doc, cb, processingDocuments) {\n    doc = window.wrap(doc);\n    if (processingDocuments.indexOf(doc) >= 0) {\n      return;\n    }\n    processingDocuments.push(doc);\n    var imports = doc.querySelectorAll(\"link[rel=\" + IMPORT_LINK_TYPE + \"]\");\n    for (var i = 0, l = imports.length, n; i < l && (n = imports[i]); i++) {\n      if (n.import) {\n        _forDocumentTree(n.import, cb, processingDocuments);\n      }\n    }\n    cb(doc);\n  }\n  scope.forDocumentTree = forDocumentTree;\n  scope.forSubtree = forSubtree;\n});\n\nwindow.CustomElements.addModule(function(scope) {\n  var flags = scope.flags;\n  var forSubtree = scope.forSubtree;\n  var forDocumentTree = scope.forDocumentTree;\n  function addedNode(node, isAttached) {\n    return added(node, isAttached) || addedSubtree(node, isAttached);\n  }\n  function added(node, isAttached) {\n    if (scope.upgrade(node, isAttached)) {\n      return true;\n    }\n    if (isAttached) {\n      attached(node);\n    }\n  }\n  function addedSubtree(node, isAttached) {\n    forSubtree(node, function(e) {\n      if (added(e, isAttached)) {\n        return true;\n      }\n    });\n  }\n  var hasPolyfillMutations = !window.MutationObserver || window.MutationObserver === window.JsMutationObserver;\n  scope.hasPolyfillMutations = hasPolyfillMutations;\n  var isPendingMutations = false;\n  var pendingMutations = [];\n  function deferMutation(fn) {\n    pendingMutations.push(fn);\n    if (!isPendingMutations) {\n      isPendingMutations = true;\n      setTimeout(takeMutations);\n    }\n  }\n  function takeMutations() {\n    isPendingMutations = false;\n    var $p = pendingMutations;\n    for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {\n      p();\n    }\n    pendingMutations = [];\n  }\n  function attached(element) {\n    if (hasPolyfillMutations) {\n      deferMutation(function() {\n        _attached(element);\n      });\n    } else {\n      _attached(element);\n    }\n  }\n  function _attached(element) {\n    if (element.__upgraded__ && !element.__attached) {\n      element.__attached = true;\n      if (element.attachedCallback) {\n        element.attachedCallback();\n      }\n    }\n  }\n  function detachedNode(node) {\n    detached(node);\n    forSubtree(node, function(e) {\n      detached(e);\n    });\n  }\n  function detached(element) {\n    if (hasPolyfillMutations) {\n      deferMutation(function() {\n        _detached(element);\n      });\n    } else {\n      _detached(element);\n    }\n  }\n  function _detached(element) {\n    if (element.__upgraded__ && element.__attached) {\n      element.__attached = false;\n      if (element.detachedCallback) {\n        element.detachedCallback();\n      }\n    }\n  }\n  function inDocument(element) {\n    var p = element;\n    var doc = window.wrap(document);\n    while (p) {\n      if (p == doc) {\n        return true;\n      }\n      p = p.parentNode || p.nodeType === Node.DOCUMENT_FRAGMENT_NODE && p.host;\n    }\n  }\n  function watchShadow(node) {\n    if (node.shadowRoot && !node.shadowRoot.__watched) {\n      flags.dom && console.log(\"watching shadow-root for: \", node.localName);\n      var root = node.shadowRoot;\n      while (root) {\n        observe(root);\n        root = root.olderShadowRoot;\n      }\n    }\n  }\n  function handler(root, mutations) {\n    if (flags.dom) {\n      var mx = mutations[0];\n      if (mx && mx.type === \"childList\" && mx.addedNodes) {\n        if (mx.addedNodes) {\n          var d = mx.addedNodes[0];\n          while (d && d !== document && !d.host) {\n            d = d.parentNode;\n          }\n          var u = d && (d.URL || d._URL || d.host && d.host.localName) || \"\";\n          u = u.split(\"/?\").shift().split(\"/\").pop();\n        }\n      }\n      console.group(\"mutations (%d) [%s]\", mutations.length, u || \"\");\n    }\n    var isAttached = inDocument(root);\n    mutations.forEach(function(mx) {\n      if (mx.type === \"childList\") {\n        forEach(mx.addedNodes, function(n) {\n          if (!n.localName) {\n            return;\n          }\n          addedNode(n, isAttached);\n        });\n        forEach(mx.removedNodes, function(n) {\n          if (!n.localName) {\n            return;\n          }\n          detachedNode(n);\n        });\n      }\n    });\n    flags.dom && console.groupEnd();\n  }\n  function takeRecords(node) {\n    node = window.wrap(node);\n    if (!node) {\n      node = window.wrap(document);\n    }\n    while (node.parentNode) {\n      node = node.parentNode;\n    }\n    var observer = node.__observer;\n    if (observer) {\n      handler(node, observer.takeRecords());\n      takeMutations();\n    }\n  }\n  var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);\n  function observe(inRoot) {\n    if (inRoot.__observer) {\n      return;\n    }\n    var observer = new MutationObserver(handler.bind(this, inRoot));\n    observer.observe(inRoot, {\n      childList: true,\n      subtree: true\n    });\n    inRoot.__observer = observer;\n  }\n  function upgradeDocument(doc) {\n    doc = window.wrap(doc);\n    flags.dom && console.group(\"upgradeDocument: \", doc.baseURI.split(\"/\").pop());\n    var isMainDocument = doc === window.wrap(document);\n    addedNode(doc, isMainDocument);\n    observe(doc);\n    flags.dom && console.groupEnd();\n  }\n  function upgradeDocumentTree(doc) {\n    forDocumentTree(doc, upgradeDocument);\n  }\n  var originalCreateShadowRoot = Element.prototype.createShadowRoot;\n  if (originalCreateShadowRoot) {\n    Element.prototype.createShadowRoot = function() {\n      var root = originalCreateShadowRoot.call(this);\n      window.CustomElements.watchShadow(this);\n      return root;\n    };\n  }\n  scope.watchShadow = watchShadow;\n  scope.upgradeDocumentTree = upgradeDocumentTree;\n  scope.upgradeDocument = upgradeDocument;\n  scope.upgradeSubtree = addedSubtree;\n  scope.upgradeAll = addedNode;\n  scope.attached = attached;\n  scope.takeRecords = takeRecords;\n});\n\nwindow.CustomElements.addModule(function(scope) {\n  var flags = scope.flags;\n  function upgrade(node, isAttached) {\n    if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) {\n      var is = node.getAttribute(\"is\");\n      var definition = scope.getRegisteredDefinition(node.localName) || scope.getRegisteredDefinition(is);\n      if (definition) {\n        if (is && definition.tag == node.localName || !is && !definition.extends) {\n          return upgradeWithDefinition(node, definition, isAttached);\n        }\n      }\n    }\n  }\n  function upgradeWithDefinition(element, definition, isAttached) {\n    flags.upgrade && console.group(\"upgrade:\", element.localName);\n    if (definition.is) {\n      element.setAttribute(\"is\", definition.is);\n    }\n    implementPrototype(element, definition);\n    element.__upgraded__ = true;\n    created(element);\n    if (isAttached) {\n      scope.attached(element);\n    }\n    scope.upgradeSubtree(element, isAttached);\n    flags.upgrade && console.groupEnd();\n    return element;\n  }\n  function implementPrototype(element, definition) {\n    if (Object.__proto__) {\n      element.__proto__ = definition.prototype;\n    } else {\n      customMixin(element, definition.prototype, definition.native);\n      element.__proto__ = definition.prototype;\n    }\n  }\n  function customMixin(inTarget, inSrc, inNative) {\n    var used = {};\n    var p = inSrc;\n    while (p !== inNative && p !== HTMLElement.prototype) {\n      var keys = Object.getOwnPropertyNames(p);\n      for (var i = 0, k; k = keys[i]; i++) {\n        if (!used[k]) {\n          Object.defineProperty(inTarget, k, Object.getOwnPropertyDescriptor(p, k));\n          used[k] = 1;\n        }\n      }\n      p = Object.getPrototypeOf(p);\n    }\n  }\n  function created(element) {\n    if (element.createdCallback) {\n      element.createdCallback();\n    }\n  }\n  scope.upgrade = upgrade;\n  scope.upgradeWithDefinition = upgradeWithDefinition;\n  scope.implementPrototype = implementPrototype;\n});\n\nwindow.CustomElements.addModule(function(scope) {\n  var isIE11OrOlder = scope.isIE11OrOlder;\n  var upgradeDocumentTree = scope.upgradeDocumentTree;\n  var upgradeAll = scope.upgradeAll;\n  var upgradeWithDefinition = scope.upgradeWithDefinition;\n  var implementPrototype = scope.implementPrototype;\n  var useNative = scope.useNative;\n  function register(name, options) {\n    var definition = options || {};\n    if (!name) {\n      throw new Error(\"document.registerElement: first argument `name` must not be empty\");\n    }\n    if (name.indexOf(\"-\") < 0) {\n      throw new Error(\"document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '\" + String(name) + \"'.\");\n    }\n    if (isReservedTag(name)) {\n      throw new Error(\"Failed to execute 'registerElement' on 'Document': Registration failed for type '\" + String(name) + \"'. The type name is invalid.\");\n    }\n    if (getRegisteredDefinition(name)) {\n      throw new Error(\"DuplicateDefinitionError: a type with name '\" + String(name) + \"' is already registered\");\n    }\n    if (!definition.prototype) {\n      definition.prototype = Object.create(HTMLElement.prototype);\n    }\n    definition.__name = name.toLowerCase();\n    definition.lifecycle = definition.lifecycle || {};\n    definition.ancestry = ancestry(definition.extends);\n    resolveTagName(definition);\n    resolvePrototypeChain(definition);\n    overrideAttributeApi(definition.prototype);\n    registerDefinition(definition.__name, definition);\n    definition.ctor = generateConstructor(definition);\n    definition.ctor.prototype = definition.prototype;\n    definition.prototype.constructor = definition.ctor;\n    if (scope.ready) {\n      upgradeDocumentTree(document);\n    }\n    return definition.ctor;\n  }\n  function overrideAttributeApi(prototype) {\n    if (prototype.setAttribute._polyfilled) {\n      return;\n    }\n    var setAttribute = prototype.setAttribute;\n    prototype.setAttribute = function(name, value) {\n      changeAttribute.call(this, name, value, setAttribute);\n    };\n    var removeAttribute = prototype.removeAttribute;\n    prototype.removeAttribute = function(name) {\n      changeAttribute.call(this, name, null, removeAttribute);\n    };\n    prototype.setAttribute._polyfilled = true;\n  }\n  function changeAttribute(name, value, operation) {\n    name = name.toLowerCase();\n    var oldValue = this.getAttribute(name);\n    operation.apply(this, arguments);\n    var newValue = this.getAttribute(name);\n    if (this.attributeChangedCallback && newValue !== oldValue) {\n      this.attributeChangedCallback(name, oldValue, newValue);\n    }\n  }\n  function isReservedTag(name) {\n    for (var i = 0; i < reservedTagList.length; i++) {\n      if (name === reservedTagList[i]) {\n        return true;\n      }\n    }\n  }\n  var reservedTagList = [ \"annotation-xml\", \"color-profile\", \"font-face\", \"font-face-src\", \"font-face-uri\", \"font-face-format\", \"font-face-name\", \"missing-glyph\" ];\n  function ancestry(extnds) {\n    var extendee = getRegisteredDefinition(extnds);\n    if (extendee) {\n      return ancestry(extendee.extends).concat([ extendee ]);\n    }\n    return [];\n  }\n  function resolveTagName(definition) {\n    var baseTag = definition.extends;\n    for (var i = 0, a; a = definition.ancestry[i]; i++) {\n      baseTag = a.is && a.tag;\n    }\n    definition.tag = baseTag || definition.__name;\n    if (baseTag) {\n      definition.is = definition.__name;\n    }\n  }\n  function resolvePrototypeChain(definition) {\n    if (!Object.__proto__) {\n      var nativePrototype = HTMLElement.prototype;\n      if (definition.is) {\n        var inst = document.createElement(definition.tag);\n        nativePrototype = Object.getPrototypeOf(inst);\n      }\n      var proto = definition.prototype, ancestor;\n      var foundPrototype = false;\n      while (proto) {\n        if (proto == nativePrototype) {\n          foundPrototype = true;\n        }\n        ancestor = Object.getPrototypeOf(proto);\n        if (ancestor) {\n          proto.__proto__ = ancestor;\n        }\n        proto = ancestor;\n      }\n      if (!foundPrototype) {\n        console.warn(definition.tag + \" prototype not found in prototype chain for \" + definition.is);\n      }\n      definition.native = nativePrototype;\n    }\n  }\n  function instantiate(definition) {\n    return upgradeWithDefinition(domCreateElement(definition.tag), definition);\n  }\n  var registry = {};\n  function getRegisteredDefinition(name) {\n    if (name) {\n      return registry[name.toLowerCase()];\n    }\n  }\n  function registerDefinition(name, definition) {\n    registry[name] = definition;\n  }\n  function generateConstructor(definition) {\n    return function() {\n      return instantiate(definition);\n    };\n  }\n  var HTML_NAMESPACE = \"http://www.w3.org/1999/xhtml\";\n  function createElementNS(namespace, tag, typeExtension) {\n    if (namespace === HTML_NAMESPACE) {\n      return createElement(tag, typeExtension);\n    } else {\n      return domCreateElementNS(namespace, tag);\n    }\n  }\n  function createElement(tag, typeExtension) {\n    if (tag) {\n      tag = tag.toLowerCase();\n    }\n    if (typeExtension) {\n      typeExtension = typeExtension.toLowerCase();\n    }\n    var definition = getRegisteredDefinition(typeExtension || tag);\n    if (definition) {\n      if (tag == definition.tag && typeExtension == definition.is) {\n        return new definition.ctor();\n      }\n      if (!typeExtension && !definition.is) {\n        return new definition.ctor();\n      }\n    }\n    var element;\n    if (typeExtension) {\n      element = createElement(tag);\n      element.setAttribute(\"is\", typeExtension);\n      return element;\n    }\n    element = domCreateElement(tag);\n    if (tag.indexOf(\"-\") >= 0) {\n      implementPrototype(element, HTMLElement);\n    }\n    return element;\n  }\n  var domCreateElement = document.createElement.bind(document);\n  var domCreateElementNS = document.createElementNS.bind(document);\n  var isInstance;\n  if (!Object.__proto__ && !useNative) {\n    isInstance = function(obj, ctor) {\n      if (obj instanceof ctor) {\n        return true;\n      }\n      var p = obj;\n      while (p) {\n        if (p === ctor.prototype) {\n          return true;\n        }\n        p = p.__proto__;\n      }\n      return false;\n    };\n  } else {\n    isInstance = function(obj, base) {\n      return obj instanceof base;\n    };\n  }\n  function wrapDomMethodToForceUpgrade(obj, methodName) {\n    var orig = obj[methodName];\n    obj[methodName] = function() {\n      var n = orig.apply(this, arguments);\n      upgradeAll(n);\n      return n;\n    };\n  }\n  wrapDomMethodToForceUpgrade(Node.prototype, \"cloneNode\");\n  wrapDomMethodToForceUpgrade(document, \"importNode\");\n  if (isIE11OrOlder) {\n    (function() {\n      var importNode = document.importNode;\n      document.importNode = function() {\n        var n = importNode.apply(document, arguments);\n        if (n.nodeType == n.DOCUMENT_FRAGMENT_NODE) {\n          var f = document.createDocumentFragment();\n          f.appendChild(n);\n          return f;\n        } else {\n          return n;\n        }\n      };\n    })();\n  }\n  document.registerElement = register;\n  document.createElement = createElement;\n  document.createElementNS = createElementNS;\n  scope.registry = registry;\n  scope.instanceof = isInstance;\n  scope.reservedTagList = reservedTagList;\n  scope.getRegisteredDefinition = getRegisteredDefinition;\n  document.register = document.registerElement;\n});\n\n(function(scope) {\n  var useNative = scope.useNative;\n  var initializeModules = scope.initializeModules;\n  var isIE11OrOlder = /Trident/.test(navigator.userAgent);\n  if (useNative) {\n    var nop = function() {};\n    scope.watchShadow = nop;\n    scope.upgrade = nop;\n    scope.upgradeAll = nop;\n    scope.upgradeDocumentTree = nop;\n    scope.upgradeSubtree = nop;\n    scope.takeRecords = nop;\n    scope.instanceof = function(obj, base) {\n      return obj instanceof base;\n    };\n  } else {\n    initializeModules();\n  }\n  var upgradeDocumentTree = scope.upgradeDocumentTree;\n  var upgradeDocument = scope.upgradeDocument;\n  if (!window.wrap) {\n    if (window.ShadowDOMPolyfill) {\n      window.wrap = window.ShadowDOMPolyfill.wrapIfNeeded;\n      window.unwrap = window.ShadowDOMPolyfill.unwrapIfNeeded;\n    } else {\n      window.wrap = window.unwrap = function(node) {\n        return node;\n      };\n    }\n  }\n  if (window.HTMLImports) {\n    window.HTMLImports.__importsParsingHook = function(elt) {\n      if (elt.import) {\n        upgradeDocument(wrap(elt.import));\n      }\n    };\n  }\n  function bootstrap() {\n    upgradeDocumentTree(window.wrap(document));\n    window.CustomElements.ready = true;\n    requestAnimationFrame(function() {\n      setTimeout(function() {\n        window.CustomElements.readyTime = Date.now();\n        if (window.HTMLImports) {\n          window.CustomElements.elapsed = window.CustomElements.readyTime - window.HTMLImports.readyTime;\n        }\n        document.dispatchEvent(new CustomEvent(\"WebComponentsReady\", {\n          bubbles: true\n        }));\n      });\n    });\n  }\n  if (isIE11OrOlder && typeof window.CustomEvent !== \"function\") {\n    window.CustomEvent = function(inType, params) {\n      params = params || {};\n      var e = document.createEvent(\"CustomEvent\");\n      e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);\n      e.preventDefault = function() {\n        Object.defineProperty(this, \"defaultPrevented\", {\n          get: function() {\n            return true;\n          }\n        });\n      };\n      return e;\n    };\n    window.CustomEvent.prototype = window.Event.prototype;\n  }\n  if (document.readyState === \"complete\" || scope.flags.eager) {\n    bootstrap();\n  } else if (document.readyState === \"interactive\" && !window.attachEvent && (!window.HTMLImports || window.HTMLImports.ready)) {\n    bootstrap();\n  } else {\n    var loadEvent = window.HTMLImports && !window.HTMLImports.ready ? \"HTMLImportsLoaded\" : \"DOMContentLoaded\";\n    window.addEventListener(loadEvent, bootstrap);\n  }\n  scope.isIE11OrOlder = isIE11OrOlder;\n})(window.CustomElements);\n\nif (typeof HTMLTemplateElement === \"undefined\") {\n  (function() {\n    var TEMPLATE_TAG = \"template\";\n    var contentDoc = document.implementation.createHTMLDocument(\"template\");\n    var canDecorate = true;\n    HTMLTemplateElement = function() {};\n    HTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);\n    HTMLTemplateElement.decorate = function(template) {\n      if (!template.content) {\n        template.content = contentDoc.createDocumentFragment();\n      }\n      var child;\n      while (child = template.firstChild) {\n        template.content.appendChild(child);\n      }\n      if (canDecorate) {\n        try {\n          Object.defineProperty(template, \"innerHTML\", {\n            get: function() {\n              var o = \"\";\n              for (var e = this.content.firstChild; e; e = e.nextSibling) {\n                o += e.outerHTML || escapeData(e.data);\n              }\n              return o;\n            },\n            set: function(text) {\n              contentDoc.body.innerHTML = text;\n              HTMLTemplateElement.bootstrap(contentDoc);\n              while (this.content.firstChild) {\n                this.content.removeChild(this.content.firstChild);\n              }\n              while (contentDoc.body.firstChild) {\n                this.content.appendChild(contentDoc.body.firstChild);\n              }\n            },\n            configurable: true\n          });\n        } catch (err) {\n          canDecorate = false;\n        }\n      }\n    };\n    HTMLTemplateElement.bootstrap = function(doc) {\n      var templates = doc.querySelectorAll(TEMPLATE_TAG);\n      for (var i = 0, l = templates.length, t; i < l && (t = templates[i]); i++) {\n        HTMLTemplateElement.decorate(t);\n      }\n    };\n    window.addEventListener(\"DOMContentLoaded\", function() {\n      HTMLTemplateElement.bootstrap(document);\n    });\n    var createElement = document.createElement;\n    document.createElement = function() {\n      \"use strict\";\n      var el = createElement.apply(document, arguments);\n      if (el.localName == \"template\") {\n        HTMLTemplateElement.decorate(el);\n      }\n      return el;\n    };\n    var escapeDataRegExp = /[&\\u00A0<>]/g;\n    function escapeReplace(c) {\n      switch (c) {\n       case \"&\":\n        return \"&amp;\";\n\n       case \"<\":\n        return \"&lt;\";\n\n       case \">\":\n        return \"&gt;\";\n\n       case \" \":\n        return \"&nbsp;\";\n      }\n    }\n    function escapeData(s) {\n      return s.replace(escapeDataRegExp, escapeReplace);\n    }\n  })();\n}\n\n(function(scope) {\n  var style = document.createElement(\"style\");\n  style.textContent = \"\" + \"body {\" + \"transition: opacity ease-in 0.2s;\" + \" } \\n\" + \"body[unresolved] {\" + \"opacity: 0; display: block; overflow: hidden; position: relative;\" + \" } \\n\";\n  var head = document.querySelector(\"head\");\n  head.insertBefore(style, head.firstChild);\n})(window.WebComponents);"
  },
  {
    "path": "cmd/memlat/static/bower_components/webcomponentsjs/webcomponents.js",
    "content": "/**\n * @license\n * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n */\n// @version 0.7.11\nwindow.WebComponents = window.WebComponents || {};\n\n(function(scope) {\n  var flags = scope.flags || {};\n  var file = \"webcomponents.js\";\n  var script = document.querySelector('script[src*=\"' + file + '\"]');\n  if (!flags.noOpts) {\n    location.search.slice(1).split(\"&\").forEach(function(option) {\n      var parts = option.split(\"=\");\n      var match;\n      if (parts[0] && (match = parts[0].match(/wc-(.+)/))) {\n        flags[match[1]] = parts[1] || true;\n      }\n    });\n    if (script) {\n      for (var i = 0, a; a = script.attributes[i]; i++) {\n        if (a.name !== \"src\") {\n          flags[a.name] = a.value || true;\n        }\n      }\n    }\n    if (flags.log && flags.log.split) {\n      var parts = flags.log.split(\",\");\n      flags.log = {};\n      parts.forEach(function(f) {\n        flags.log[f] = true;\n      });\n    } else {\n      flags.log = {};\n    }\n  }\n  flags.shadow = flags.shadow || flags.shadowdom || flags.polyfill;\n  if (flags.shadow === \"native\") {\n    flags.shadow = false;\n  } else {\n    flags.shadow = flags.shadow || !HTMLElement.prototype.createShadowRoot;\n  }\n  if (flags.register) {\n    window.CustomElements = window.CustomElements || {\n      flags: {}\n    };\n    window.CustomElements.flags.register = flags.register;\n  }\n  scope.flags = flags;\n})(WebComponents);\n\nif (WebComponents.flags.shadow) {\n  if (typeof WeakMap === \"undefined\") {\n    (function() {\n      var defineProperty = Object.defineProperty;\n      var counter = Date.now() % 1e9;\n      var WeakMap = function() {\n        this.name = \"__st\" + (Math.random() * 1e9 >>> 0) + (counter++ + \"__\");\n      };\n      WeakMap.prototype = {\n        set: function(key, value) {\n          var entry = key[this.name];\n          if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {\n            value: [ key, value ],\n            writable: true\n          });\n          return this;\n        },\n        get: function(key) {\n          var entry;\n          return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;\n        },\n        \"delete\": function(key) {\n          var entry = key[this.name];\n          if (!entry || entry[0] !== key) return false;\n          entry[0] = entry[1] = undefined;\n          return true;\n        },\n        has: function(key) {\n          var entry = key[this.name];\n          if (!entry) return false;\n          return entry[0] === key;\n        }\n      };\n      window.WeakMap = WeakMap;\n    })();\n  }\n  window.ShadowDOMPolyfill = {};\n  (function(scope) {\n    \"use strict\";\n    var constructorTable = new WeakMap();\n    var nativePrototypeTable = new WeakMap();\n    var wrappers = Object.create(null);\n    function detectEval() {\n      if (typeof chrome !== \"undefined\" && chrome.app && chrome.app.runtime) {\n        return false;\n      }\n      if (navigator.getDeviceStorage) {\n        return false;\n      }\n      try {\n        var f = new Function(\"return true;\");\n        return f();\n      } catch (ex) {\n        return false;\n      }\n    }\n    var hasEval = detectEval();\n    function assert(b) {\n      if (!b) throw new Error(\"Assertion failed\");\n    }\n    var defineProperty = Object.defineProperty;\n    var getOwnPropertyNames = Object.getOwnPropertyNames;\n    var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n    function mixin(to, from) {\n      var names = getOwnPropertyNames(from);\n      for (var i = 0; i < names.length; i++) {\n        var name = names[i];\n        defineProperty(to, name, getOwnPropertyDescriptor(from, name));\n      }\n      return to;\n    }\n    function mixinStatics(to, from) {\n      var names = getOwnPropertyNames(from);\n      for (var i = 0; i < names.length; i++) {\n        var name = names[i];\n        switch (name) {\n         case \"arguments\":\n         case \"caller\":\n         case \"length\":\n         case \"name\":\n         case \"prototype\":\n         case \"toString\":\n          continue;\n        }\n        defineProperty(to, name, getOwnPropertyDescriptor(from, name));\n      }\n      return to;\n    }\n    function oneOf(object, propertyNames) {\n      for (var i = 0; i < propertyNames.length; i++) {\n        if (propertyNames[i] in object) return propertyNames[i];\n      }\n    }\n    var nonEnumerableDataDescriptor = {\n      value: undefined,\n      configurable: true,\n      enumerable: false,\n      writable: true\n    };\n    function defineNonEnumerableDataProperty(object, name, value) {\n      nonEnumerableDataDescriptor.value = value;\n      defineProperty(object, name, nonEnumerableDataDescriptor);\n    }\n    getOwnPropertyNames(window);\n    function getWrapperConstructor(node, opt_instance) {\n      var nativePrototype = node.__proto__ || Object.getPrototypeOf(node);\n      if (isFirefox) {\n        try {\n          getOwnPropertyNames(nativePrototype);\n        } catch (error) {\n          nativePrototype = nativePrototype.__proto__;\n        }\n      }\n      var wrapperConstructor = constructorTable.get(nativePrototype);\n      if (wrapperConstructor) return wrapperConstructor;\n      var parentWrapperConstructor = getWrapperConstructor(nativePrototype);\n      var GeneratedWrapper = createWrapperConstructor(parentWrapperConstructor);\n      registerInternal(nativePrototype, GeneratedWrapper, opt_instance);\n      return GeneratedWrapper;\n    }\n    function addForwardingProperties(nativePrototype, wrapperPrototype) {\n      installProperty(nativePrototype, wrapperPrototype, true);\n    }\n    function registerInstanceProperties(wrapperPrototype, instanceObject) {\n      installProperty(instanceObject, wrapperPrototype, false);\n    }\n    var isFirefox = /Firefox/.test(navigator.userAgent);\n    var dummyDescriptor = {\n      get: function() {},\n      set: function(v) {},\n      configurable: true,\n      enumerable: true\n    };\n    function isEventHandlerName(name) {\n      return /^on[a-z]+$/.test(name);\n    }\n    function isIdentifierName(name) {\n      return /^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(name);\n    }\n    function getGetter(name) {\n      return hasEval && isIdentifierName(name) ? new Function(\"return this.__impl4cf1e782hg__.\" + name) : function() {\n        return this.__impl4cf1e782hg__[name];\n      };\n    }\n    function getSetter(name) {\n      return hasEval && isIdentifierName(name) ? new Function(\"v\", \"this.__impl4cf1e782hg__.\" + name + \" = v\") : function(v) {\n        this.__impl4cf1e782hg__[name] = v;\n      };\n    }\n    function getMethod(name) {\n      return hasEval && isIdentifierName(name) ? new Function(\"return this.__impl4cf1e782hg__.\" + name + \".apply(this.__impl4cf1e782hg__, arguments)\") : function() {\n        return this.__impl4cf1e782hg__[name].apply(this.__impl4cf1e782hg__, arguments);\n      };\n    }\n    function getDescriptor(source, name) {\n      try {\n        return Object.getOwnPropertyDescriptor(source, name);\n      } catch (ex) {\n        return dummyDescriptor;\n      }\n    }\n    var isBrokenSafari = function() {\n      var descr = Object.getOwnPropertyDescriptor(Node.prototype, \"nodeType\");\n      return descr && !descr.get && !descr.set;\n    }();\n    function installProperty(source, target, allowMethod, opt_blacklist) {\n      var names = getOwnPropertyNames(source);\n      for (var i = 0; i < names.length; i++) {\n        var name = names[i];\n        if (name === \"polymerBlackList_\") continue;\n        if (name in target) continue;\n        if (source.polymerBlackList_ && source.polymerBlackList_[name]) continue;\n        if (isFirefox) {\n          source.__lookupGetter__(name);\n        }\n        var descriptor = getDescriptor(source, name);\n        var getter, setter;\n        if (typeof descriptor.value === \"function\") {\n          if (allowMethod) {\n            target[name] = getMethod(name);\n          }\n          continue;\n        }\n        var isEvent = isEventHandlerName(name);\n        if (isEvent) getter = scope.getEventHandlerGetter(name); else getter = getGetter(name);\n        if (descriptor.writable || descriptor.set || isBrokenSafari) {\n          if (isEvent) setter = scope.getEventHandlerSetter(name); else setter = getSetter(name);\n        }\n        var configurable = isBrokenSafari || descriptor.configurable;\n        defineProperty(target, name, {\n          get: getter,\n          set: setter,\n          configurable: configurable,\n          enumerable: descriptor.enumerable\n        });\n      }\n    }\n    function register(nativeConstructor, wrapperConstructor, opt_instance) {\n      if (nativeConstructor == null) {\n        return;\n      }\n      var nativePrototype = nativeConstructor.prototype;\n      registerInternal(nativePrototype, wrapperConstructor, opt_instance);\n      mixinStatics(wrapperConstructor, nativeConstructor);\n    }\n    function registerInternal(nativePrototype, wrapperConstructor, opt_instance) {\n      var wrapperPrototype = wrapperConstructor.prototype;\n      assert(constructorTable.get(nativePrototype) === undefined);\n      constructorTable.set(nativePrototype, wrapperConstructor);\n      nativePrototypeTable.set(wrapperPrototype, nativePrototype);\n      addForwardingProperties(nativePrototype, wrapperPrototype);\n      if (opt_instance) registerInstanceProperties(wrapperPrototype, opt_instance);\n      defineNonEnumerableDataProperty(wrapperPrototype, \"constructor\", wrapperConstructor);\n      wrapperConstructor.prototype = wrapperPrototype;\n    }\n    function isWrapperFor(wrapperConstructor, nativeConstructor) {\n      return constructorTable.get(nativeConstructor.prototype) === wrapperConstructor;\n    }\n    function registerObject(object) {\n      var nativePrototype = Object.getPrototypeOf(object);\n      var superWrapperConstructor = getWrapperConstructor(nativePrototype);\n      var GeneratedWrapper = createWrapperConstructor(superWrapperConstructor);\n      registerInternal(nativePrototype, GeneratedWrapper, object);\n      return GeneratedWrapper;\n    }\n    function createWrapperConstructor(superWrapperConstructor) {\n      function GeneratedWrapper(node) {\n        superWrapperConstructor.call(this, node);\n      }\n      var p = Object.create(superWrapperConstructor.prototype);\n      p.constructor = GeneratedWrapper;\n      GeneratedWrapper.prototype = p;\n      return GeneratedWrapper;\n    }\n    function isWrapper(object) {\n      return object && object.__impl4cf1e782hg__;\n    }\n    function isNative(object) {\n      return !isWrapper(object);\n    }\n    function wrap(impl) {\n      if (impl === null) return null;\n      assert(isNative(impl));\n      var wrapper = impl.__wrapper8e3dd93a60__;\n      if (wrapper != null) {\n        return wrapper;\n      }\n      return impl.__wrapper8e3dd93a60__ = new (getWrapperConstructor(impl, impl))(impl);\n    }\n    function unwrap(wrapper) {\n      if (wrapper === null) return null;\n      assert(isWrapper(wrapper));\n      return wrapper.__impl4cf1e782hg__;\n    }\n    function unsafeUnwrap(wrapper) {\n      return wrapper.__impl4cf1e782hg__;\n    }\n    function setWrapper(impl, wrapper) {\n      wrapper.__impl4cf1e782hg__ = impl;\n      impl.__wrapper8e3dd93a60__ = wrapper;\n    }\n    function unwrapIfNeeded(object) {\n      return object && isWrapper(object) ? unwrap(object) : object;\n    }\n    function wrapIfNeeded(object) {\n      return object && !isWrapper(object) ? wrap(object) : object;\n    }\n    function rewrap(node, wrapper) {\n      if (wrapper === null) return;\n      assert(isNative(node));\n      assert(wrapper === undefined || isWrapper(wrapper));\n      node.__wrapper8e3dd93a60__ = wrapper;\n    }\n    var getterDescriptor = {\n      get: undefined,\n      configurable: true,\n      enumerable: true\n    };\n    function defineGetter(constructor, name, getter) {\n      getterDescriptor.get = getter;\n      defineProperty(constructor.prototype, name, getterDescriptor);\n    }\n    function defineWrapGetter(constructor, name) {\n      defineGetter(constructor, name, function() {\n        return wrap(this.__impl4cf1e782hg__[name]);\n      });\n    }\n    function forwardMethodsToWrapper(constructors, names) {\n      constructors.forEach(function(constructor) {\n        names.forEach(function(name) {\n          constructor.prototype[name] = function() {\n            var w = wrapIfNeeded(this);\n            return w[name].apply(w, arguments);\n          };\n        });\n      });\n    }\n    scope.assert = assert;\n    scope.constructorTable = constructorTable;\n    scope.defineGetter = defineGetter;\n    scope.defineWrapGetter = defineWrapGetter;\n    scope.forwardMethodsToWrapper = forwardMethodsToWrapper;\n    scope.isIdentifierName = isIdentifierName;\n    scope.isWrapper = isWrapper;\n    scope.isWrapperFor = isWrapperFor;\n    scope.mixin = mixin;\n    scope.nativePrototypeTable = nativePrototypeTable;\n    scope.oneOf = oneOf;\n    scope.registerObject = registerObject;\n    scope.registerWrapper = register;\n    scope.rewrap = rewrap;\n    scope.setWrapper = setWrapper;\n    scope.unsafeUnwrap = unsafeUnwrap;\n    scope.unwrap = unwrap;\n    scope.unwrapIfNeeded = unwrapIfNeeded;\n    scope.wrap = wrap;\n    scope.wrapIfNeeded = wrapIfNeeded;\n    scope.wrappers = wrappers;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    function newSplice(index, removed, addedCount) {\n      return {\n        index: index,\n        removed: removed,\n        addedCount: addedCount\n      };\n    }\n    var EDIT_LEAVE = 0;\n    var EDIT_UPDATE = 1;\n    var EDIT_ADD = 2;\n    var EDIT_DELETE = 3;\n    function ArraySplice() {}\n    ArraySplice.prototype = {\n      calcEditDistances: function(current, currentStart, currentEnd, old, oldStart, oldEnd) {\n        var rowCount = oldEnd - oldStart + 1;\n        var columnCount = currentEnd - currentStart + 1;\n        var distances = new Array(rowCount);\n        for (var i = 0; i < rowCount; i++) {\n          distances[i] = new Array(columnCount);\n          distances[i][0] = i;\n        }\n        for (var j = 0; j < columnCount; j++) distances[0][j] = j;\n        for (var i = 1; i < rowCount; i++) {\n          for (var j = 1; j < columnCount; j++) {\n            if (this.equals(current[currentStart + j - 1], old[oldStart + i - 1])) distances[i][j] = distances[i - 1][j - 1]; else {\n              var north = distances[i - 1][j] + 1;\n              var west = distances[i][j - 1] + 1;\n              distances[i][j] = north < west ? north : west;\n            }\n          }\n        }\n        return distances;\n      },\n      spliceOperationsFromEditDistances: function(distances) {\n        var i = distances.length - 1;\n        var j = distances[0].length - 1;\n        var current = distances[i][j];\n        var edits = [];\n        while (i > 0 || j > 0) {\n          if (i == 0) {\n            edits.push(EDIT_ADD);\n            j--;\n            continue;\n          }\n          if (j == 0) {\n            edits.push(EDIT_DELETE);\n            i--;\n            continue;\n          }\n          var northWest = distances[i - 1][j - 1];\n          var west = distances[i - 1][j];\n          var north = distances[i][j - 1];\n          var min;\n          if (west < north) min = west < northWest ? west : northWest; else min = north < northWest ? north : northWest;\n          if (min == northWest) {\n            if (northWest == current) {\n              edits.push(EDIT_LEAVE);\n            } else {\n              edits.push(EDIT_UPDATE);\n              current = northWest;\n            }\n            i--;\n            j--;\n          } else if (min == west) {\n            edits.push(EDIT_DELETE);\n            i--;\n            current = west;\n          } else {\n            edits.push(EDIT_ADD);\n            j--;\n            current = north;\n          }\n        }\n        edits.reverse();\n        return edits;\n      },\n      calcSplices: function(current, currentStart, currentEnd, old, oldStart, oldEnd) {\n        var prefixCount = 0;\n        var suffixCount = 0;\n        var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart);\n        if (currentStart == 0 && oldStart == 0) prefixCount = this.sharedPrefix(current, old, minLength);\n        if (currentEnd == current.length && oldEnd == old.length) suffixCount = this.sharedSuffix(current, old, minLength - prefixCount);\n        currentStart += prefixCount;\n        oldStart += prefixCount;\n        currentEnd -= suffixCount;\n        oldEnd -= suffixCount;\n        if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0) return [];\n        if (currentStart == currentEnd) {\n          var splice = newSplice(currentStart, [], 0);\n          while (oldStart < oldEnd) splice.removed.push(old[oldStart++]);\n          return [ splice ];\n        } else if (oldStart == oldEnd) return [ newSplice(currentStart, [], currentEnd - currentStart) ];\n        var ops = this.spliceOperationsFromEditDistances(this.calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd));\n        var splice = undefined;\n        var splices = [];\n        var index = currentStart;\n        var oldIndex = oldStart;\n        for (var i = 0; i < ops.length; i++) {\n          switch (ops[i]) {\n           case EDIT_LEAVE:\n            if (splice) {\n              splices.push(splice);\n              splice = undefined;\n            }\n            index++;\n            oldIndex++;\n            break;\n\n           case EDIT_UPDATE:\n            if (!splice) splice = newSplice(index, [], 0);\n            splice.addedCount++;\n            index++;\n            splice.removed.push(old[oldIndex]);\n            oldIndex++;\n            break;\n\n           case EDIT_ADD:\n            if (!splice) splice = newSplice(index, [], 0);\n            splice.addedCount++;\n            index++;\n            break;\n\n           case EDIT_DELETE:\n            if (!splice) splice = newSplice(index, [], 0);\n            splice.removed.push(old[oldIndex]);\n            oldIndex++;\n            break;\n          }\n        }\n        if (splice) {\n          splices.push(splice);\n        }\n        return splices;\n      },\n      sharedPrefix: function(current, old, searchLength) {\n        for (var i = 0; i < searchLength; i++) if (!this.equals(current[i], old[i])) return i;\n        return searchLength;\n      },\n      sharedSuffix: function(current, old, searchLength) {\n        var index1 = current.length;\n        var index2 = old.length;\n        var count = 0;\n        while (count < searchLength && this.equals(current[--index1], old[--index2])) count++;\n        return count;\n      },\n      calculateSplices: function(current, previous) {\n        return this.calcSplices(current, 0, current.length, previous, 0, previous.length);\n      },\n      equals: function(currentValue, previousValue) {\n        return currentValue === previousValue;\n      }\n    };\n    scope.ArraySplice = ArraySplice;\n  })(window.ShadowDOMPolyfill);\n  (function(context) {\n    \"use strict\";\n    var OriginalMutationObserver = window.MutationObserver;\n    var callbacks = [];\n    var pending = false;\n    var timerFunc;\n    function handle() {\n      pending = false;\n      var copies = callbacks.slice(0);\n      callbacks = [];\n      for (var i = 0; i < copies.length; i++) {\n        (0, copies[i])();\n      }\n    }\n    if (OriginalMutationObserver) {\n      var counter = 1;\n      var observer = new OriginalMutationObserver(handle);\n      var textNode = document.createTextNode(counter);\n      observer.observe(textNode, {\n        characterData: true\n      });\n      timerFunc = function() {\n        counter = (counter + 1) % 2;\n        textNode.data = counter;\n      };\n    } else {\n      timerFunc = window.setTimeout;\n    }\n    function setEndOfMicrotask(func) {\n      callbacks.push(func);\n      if (pending) return;\n      pending = true;\n      timerFunc(handle, 0);\n    }\n    context.setEndOfMicrotask = setEndOfMicrotask;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var setEndOfMicrotask = scope.setEndOfMicrotask;\n    var wrapIfNeeded = scope.wrapIfNeeded;\n    var wrappers = scope.wrappers;\n    var registrationsTable = new WeakMap();\n    var globalMutationObservers = [];\n    var isScheduled = false;\n    function scheduleCallback(observer) {\n      if (observer.scheduled_) return;\n      observer.scheduled_ = true;\n      globalMutationObservers.push(observer);\n      if (isScheduled) return;\n      setEndOfMicrotask(notifyObservers);\n      isScheduled = true;\n    }\n    function notifyObservers() {\n      isScheduled = false;\n      while (globalMutationObservers.length) {\n        var notifyList = globalMutationObservers;\n        globalMutationObservers = [];\n        notifyList.sort(function(x, y) {\n          return x.uid_ - y.uid_;\n        });\n        for (var i = 0; i < notifyList.length; i++) {\n          var mo = notifyList[i];\n          mo.scheduled_ = false;\n          var queue = mo.takeRecords();\n          removeTransientObserversFor(mo);\n          if (queue.length) {\n            mo.callback_(queue, mo);\n          }\n        }\n      }\n    }\n    function MutationRecord(type, target) {\n      this.type = type;\n      this.target = target;\n      this.addedNodes = new wrappers.NodeList();\n      this.removedNodes = new wrappers.NodeList();\n      this.previousSibling = null;\n      this.nextSibling = null;\n      this.attributeName = null;\n      this.attributeNamespace = null;\n      this.oldValue = null;\n    }\n    function registerTransientObservers(ancestor, node) {\n      for (;ancestor; ancestor = ancestor.parentNode) {\n        var registrations = registrationsTable.get(ancestor);\n        if (!registrations) continue;\n        for (var i = 0; i < registrations.length; i++) {\n          var registration = registrations[i];\n          if (registration.options.subtree) registration.addTransientObserver(node);\n        }\n      }\n    }\n    function removeTransientObserversFor(observer) {\n      for (var i = 0; i < observer.nodes_.length; i++) {\n        var node = observer.nodes_[i];\n        var registrations = registrationsTable.get(node);\n        if (!registrations) return;\n        for (var j = 0; j < registrations.length; j++) {\n          var registration = registrations[j];\n          if (registration.observer === observer) registration.removeTransientObservers();\n        }\n      }\n    }\n    function enqueueMutation(target, type, data) {\n      var interestedObservers = Object.create(null);\n      var associatedStrings = Object.create(null);\n      for (var node = target; node; node = node.parentNode) {\n        var registrations = registrationsTable.get(node);\n        if (!registrations) continue;\n        for (var j = 0; j < registrations.length; j++) {\n          var registration = registrations[j];\n          var options = registration.options;\n          if (node !== target && !options.subtree) continue;\n          if (type === \"attributes\" && !options.attributes) continue;\n          if (type === \"attributes\" && options.attributeFilter && (data.namespace !== null || options.attributeFilter.indexOf(data.name) === -1)) {\n            continue;\n          }\n          if (type === \"characterData\" && !options.characterData) continue;\n          if (type === \"childList\" && !options.childList) continue;\n          var observer = registration.observer;\n          interestedObservers[observer.uid_] = observer;\n          if (type === \"attributes\" && options.attributeOldValue || type === \"characterData\" && options.characterDataOldValue) {\n            associatedStrings[observer.uid_] = data.oldValue;\n          }\n        }\n      }\n      for (var uid in interestedObservers) {\n        var observer = interestedObservers[uid];\n        var record = new MutationRecord(type, target);\n        if (\"name\" in data && \"namespace\" in data) {\n          record.attributeName = data.name;\n          record.attributeNamespace = data.namespace;\n        }\n        if (data.addedNodes) record.addedNodes = data.addedNodes;\n        if (data.removedNodes) record.removedNodes = data.removedNodes;\n        if (data.previousSibling) record.previousSibling = data.previousSibling;\n        if (data.nextSibling) record.nextSibling = data.nextSibling;\n        if (associatedStrings[uid] !== undefined) record.oldValue = associatedStrings[uid];\n        scheduleCallback(observer);\n        observer.records_.push(record);\n      }\n    }\n    var slice = Array.prototype.slice;\n    function MutationObserverOptions(options) {\n      this.childList = !!options.childList;\n      this.subtree = !!options.subtree;\n      if (!(\"attributes\" in options) && (\"attributeOldValue\" in options || \"attributeFilter\" in options)) {\n        this.attributes = true;\n      } else {\n        this.attributes = !!options.attributes;\n      }\n      if (\"characterDataOldValue\" in options && !(\"characterData\" in options)) this.characterData = true; else this.characterData = !!options.characterData;\n      if (!this.attributes && (options.attributeOldValue || \"attributeFilter\" in options) || !this.characterData && options.characterDataOldValue) {\n        throw new TypeError();\n      }\n      this.characterData = !!options.characterData;\n      this.attributeOldValue = !!options.attributeOldValue;\n      this.characterDataOldValue = !!options.characterDataOldValue;\n      if (\"attributeFilter\" in options) {\n        if (options.attributeFilter == null || typeof options.attributeFilter !== \"object\") {\n          throw new TypeError();\n        }\n        this.attributeFilter = slice.call(options.attributeFilter);\n      } else {\n        this.attributeFilter = null;\n      }\n    }\n    var uidCounter = 0;\n    function MutationObserver(callback) {\n      this.callback_ = callback;\n      this.nodes_ = [];\n      this.records_ = [];\n      this.uid_ = ++uidCounter;\n      this.scheduled_ = false;\n    }\n    MutationObserver.prototype = {\n      constructor: MutationObserver,\n      observe: function(target, options) {\n        target = wrapIfNeeded(target);\n        var newOptions = new MutationObserverOptions(options);\n        var registration;\n        var registrations = registrationsTable.get(target);\n        if (!registrations) registrationsTable.set(target, registrations = []);\n        for (var i = 0; i < registrations.length; i++) {\n          if (registrations[i].observer === this) {\n            registration = registrations[i];\n            registration.removeTransientObservers();\n            registration.options = newOptions;\n          }\n        }\n        if (!registration) {\n          registration = new Registration(this, target, newOptions);\n          registrations.push(registration);\n          this.nodes_.push(target);\n        }\n      },\n      disconnect: function() {\n        this.nodes_.forEach(function(node) {\n          var registrations = registrationsTable.get(node);\n          for (var i = 0; i < registrations.length; i++) {\n            var registration = registrations[i];\n            if (registration.observer === this) {\n              registrations.splice(i, 1);\n              break;\n            }\n          }\n        }, this);\n        this.records_ = [];\n      },\n      takeRecords: function() {\n        var copyOfRecords = this.records_;\n        this.records_ = [];\n        return copyOfRecords;\n      }\n    };\n    function Registration(observer, target, options) {\n      this.observer = observer;\n      this.target = target;\n      this.options = options;\n      this.transientObservedNodes = [];\n    }\n    Registration.prototype = {\n      addTransientObserver: function(node) {\n        if (node === this.target) return;\n        scheduleCallback(this.observer);\n        this.transientObservedNodes.push(node);\n        var registrations = registrationsTable.get(node);\n        if (!registrations) registrationsTable.set(node, registrations = []);\n        registrations.push(this);\n      },\n      removeTransientObservers: function() {\n        var transientObservedNodes = this.transientObservedNodes;\n        this.transientObservedNodes = [];\n        for (var i = 0; i < transientObservedNodes.length; i++) {\n          var node = transientObservedNodes[i];\n          var registrations = registrationsTable.get(node);\n          for (var j = 0; j < registrations.length; j++) {\n            if (registrations[j] === this) {\n              registrations.splice(j, 1);\n              break;\n            }\n          }\n        }\n      }\n    };\n    scope.enqueueMutation = enqueueMutation;\n    scope.registerTransientObservers = registerTransientObservers;\n    scope.wrappers.MutationObserver = MutationObserver;\n    scope.wrappers.MutationRecord = MutationRecord;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    function TreeScope(root, parent) {\n      this.root = root;\n      this.parent = parent;\n    }\n    TreeScope.prototype = {\n      get renderer() {\n        if (this.root instanceof scope.wrappers.ShadowRoot) {\n          return scope.getRendererForHost(this.root.host);\n        }\n        return null;\n      },\n      contains: function(treeScope) {\n        for (;treeScope; treeScope = treeScope.parent) {\n          if (treeScope === this) return true;\n        }\n        return false;\n      }\n    };\n    function setTreeScope(node, treeScope) {\n      if (node.treeScope_ !== treeScope) {\n        node.treeScope_ = treeScope;\n        for (var sr = node.shadowRoot; sr; sr = sr.olderShadowRoot) {\n          sr.treeScope_.parent = treeScope;\n        }\n        for (var child = node.firstChild; child; child = child.nextSibling) {\n          setTreeScope(child, treeScope);\n        }\n      }\n    }\n    function getTreeScope(node) {\n      if (node instanceof scope.wrappers.Window) {\n        debugger;\n      }\n      if (node.treeScope_) return node.treeScope_;\n      var parent = node.parentNode;\n      var treeScope;\n      if (parent) treeScope = getTreeScope(parent); else treeScope = new TreeScope(node, null);\n      return node.treeScope_ = treeScope;\n    }\n    scope.TreeScope = TreeScope;\n    scope.getTreeScope = getTreeScope;\n    scope.setTreeScope = setTreeScope;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;\n    var getTreeScope = scope.getTreeScope;\n    var mixin = scope.mixin;\n    var registerWrapper = scope.registerWrapper;\n    var setWrapper = scope.setWrapper;\n    var unsafeUnwrap = scope.unsafeUnwrap;\n    var unwrap = scope.unwrap;\n    var wrap = scope.wrap;\n    var wrappers = scope.wrappers;\n    var wrappedFuns = new WeakMap();\n    var listenersTable = new WeakMap();\n    var handledEventsTable = new WeakMap();\n    var currentlyDispatchingEvents = new WeakMap();\n    var targetTable = new WeakMap();\n    var currentTargetTable = new WeakMap();\n    var relatedTargetTable = new WeakMap();\n    var eventPhaseTable = new WeakMap();\n    var stopPropagationTable = new WeakMap();\n    var stopImmediatePropagationTable = new WeakMap();\n    var eventHandlersTable = new WeakMap();\n    var eventPathTable = new WeakMap();\n    function isShadowRoot(node) {\n      return node instanceof wrappers.ShadowRoot;\n    }\n    function rootOfNode(node) {\n      return getTreeScope(node).root;\n    }\n    function getEventPath(node, event) {\n      var path = [];\n      var current = node;\n      path.push(current);\n      while (current) {\n        var destinationInsertionPoints = getDestinationInsertionPoints(current);\n        if (destinationInsertionPoints && destinationInsertionPoints.length > 0) {\n          for (var i = 0; i < destinationInsertionPoints.length; i++) {\n            var insertionPoint = destinationInsertionPoints[i];\n            if (isShadowInsertionPoint(insertionPoint)) {\n              var shadowRoot = rootOfNode(insertionPoint);\n              var olderShadowRoot = shadowRoot.olderShadowRoot;\n              if (olderShadowRoot) path.push(olderShadowRoot);\n            }\n            path.push(insertionPoint);\n          }\n          current = destinationInsertionPoints[destinationInsertionPoints.length - 1];\n        } else {\n          if (isShadowRoot(current)) {\n            if (inSameTree(node, current) && eventMustBeStopped(event)) {\n              break;\n            }\n            current = current.host;\n            path.push(current);\n          } else {\n            current = current.parentNode;\n            if (current) path.push(current);\n          }\n        }\n      }\n      return path;\n    }\n    function eventMustBeStopped(event) {\n      if (!event) return false;\n      switch (event.type) {\n       case \"abort\":\n       case \"error\":\n       case \"select\":\n       case \"change\":\n       case \"load\":\n       case \"reset\":\n       case \"resize\":\n       case \"scroll\":\n       case \"selectstart\":\n        return true;\n      }\n      return false;\n    }\n    function isShadowInsertionPoint(node) {\n      return node instanceof HTMLShadowElement;\n    }\n    function getDestinationInsertionPoints(node) {\n      return scope.getDestinationInsertionPoints(node);\n    }\n    function eventRetargetting(path, currentTarget) {\n      if (path.length === 0) return currentTarget;\n      if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;\n      var currentTargetTree = getTreeScope(currentTarget);\n      var originalTarget = path[0];\n      var originalTargetTree = getTreeScope(originalTarget);\n      var relativeTargetTree = lowestCommonInclusiveAncestor(currentTargetTree, originalTargetTree);\n      for (var i = 0; i < path.length; i++) {\n        var node = path[i];\n        if (getTreeScope(node) === relativeTargetTree) return node;\n      }\n      return path[path.length - 1];\n    }\n    function getTreeScopeAncestors(treeScope) {\n      var ancestors = [];\n      for (;treeScope; treeScope = treeScope.parent) {\n        ancestors.push(treeScope);\n      }\n      return ancestors;\n    }\n    function lowestCommonInclusiveAncestor(tsA, tsB) {\n      var ancestorsA = getTreeScopeAncestors(tsA);\n      var ancestorsB = getTreeScopeAncestors(tsB);\n      var result = null;\n      while (ancestorsA.length > 0 && ancestorsB.length > 0) {\n        var a = ancestorsA.pop();\n        var b = ancestorsB.pop();\n        if (a === b) result = a; else break;\n      }\n      return result;\n    }\n    function getTreeScopeRoot(ts) {\n      if (!ts.parent) return ts;\n      return getTreeScopeRoot(ts.parent);\n    }\n    function relatedTargetResolution(event, currentTarget, relatedTarget) {\n      if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;\n      var currentTargetTree = getTreeScope(currentTarget);\n      var relatedTargetTree = getTreeScope(relatedTarget);\n      var relatedTargetEventPath = getEventPath(relatedTarget, event);\n      var lowestCommonAncestorTree;\n      var lowestCommonAncestorTree = lowestCommonInclusiveAncestor(currentTargetTree, relatedTargetTree);\n      if (!lowestCommonAncestorTree) lowestCommonAncestorTree = relatedTargetTree.root;\n      for (var commonAncestorTree = lowestCommonAncestorTree; commonAncestorTree; commonAncestorTree = commonAncestorTree.parent) {\n        var adjustedRelatedTarget;\n        for (var i = 0; i < relatedTargetEventPath.length; i++) {\n          var node = relatedTargetEventPath[i];\n          if (getTreeScope(node) === commonAncestorTree) return node;\n        }\n      }\n      return null;\n    }\n    function inSameTree(a, b) {\n      return getTreeScope(a) === getTreeScope(b);\n    }\n    var NONE = 0;\n    var CAPTURING_PHASE = 1;\n    var AT_TARGET = 2;\n    var BUBBLING_PHASE = 3;\n    var pendingError;\n    function dispatchOriginalEvent(originalEvent) {\n      if (handledEventsTable.get(originalEvent)) return;\n      handledEventsTable.set(originalEvent, true);\n      dispatchEvent(wrap(originalEvent), wrap(originalEvent.target));\n      if (pendingError) {\n        var err = pendingError;\n        pendingError = null;\n        throw err;\n      }\n    }\n    function isLoadLikeEvent(event) {\n      switch (event.type) {\n       case \"load\":\n       case \"beforeunload\":\n       case \"unload\":\n        return true;\n      }\n      return false;\n    }\n    function dispatchEvent(event, originalWrapperTarget) {\n      if (currentlyDispatchingEvents.get(event)) throw new Error(\"InvalidStateError\");\n      currentlyDispatchingEvents.set(event, true);\n      scope.renderAllPending();\n      var eventPath;\n      var overrideTarget;\n      var win;\n      if (isLoadLikeEvent(event) && !event.bubbles) {\n        var doc = originalWrapperTarget;\n        if (doc instanceof wrappers.Document && (win = doc.defaultView)) {\n          overrideTarget = doc;\n          eventPath = [];\n        }\n      }\n      if (!eventPath) {\n        if (originalWrapperTarget instanceof wrappers.Window) {\n          win = originalWrapperTarget;\n          eventPath = [];\n        } else {\n          eventPath = getEventPath(originalWrapperTarget, event);\n          if (!isLoadLikeEvent(event)) {\n            var doc = eventPath[eventPath.length - 1];\n            if (doc instanceof wrappers.Document) win = doc.defaultView;\n          }\n        }\n      }\n      eventPathTable.set(event, eventPath);\n      if (dispatchCapturing(event, eventPath, win, overrideTarget)) {\n        if (dispatchAtTarget(event, eventPath, win, overrideTarget)) {\n          dispatchBubbling(event, eventPath, win, overrideTarget);\n        }\n      }\n      eventPhaseTable.set(event, NONE);\n      currentTargetTable.delete(event, null);\n      currentlyDispatchingEvents.delete(event);\n      return event.defaultPrevented;\n    }\n    function dispatchCapturing(event, eventPath, win, overrideTarget) {\n      var phase = CAPTURING_PHASE;\n      if (win) {\n        if (!invoke(win, event, phase, eventPath, overrideTarget)) return false;\n      }\n      for (var i = eventPath.length - 1; i > 0; i--) {\n        if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return false;\n      }\n      return true;\n    }\n    function dispatchAtTarget(event, eventPath, win, overrideTarget) {\n      var phase = AT_TARGET;\n      var currentTarget = eventPath[0] || win;\n      return invoke(currentTarget, event, phase, eventPath, overrideTarget);\n    }\n    function dispatchBubbling(event, eventPath, win, overrideTarget) {\n      var phase = BUBBLING_PHASE;\n      for (var i = 1; i < eventPath.length; i++) {\n        if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return;\n      }\n      if (win && eventPath.length > 0) {\n        invoke(win, event, phase, eventPath, overrideTarget);\n      }\n    }\n    function invoke(currentTarget, event, phase, eventPath, overrideTarget) {\n      var listeners = listenersTable.get(currentTarget);\n      if (!listeners) return true;\n      var target = overrideTarget || eventRetargetting(eventPath, currentTarget);\n      if (target === currentTarget) {\n        if (phase === CAPTURING_PHASE) return true;\n        if (phase === BUBBLING_PHASE) phase = AT_TARGET;\n      } else if (phase === BUBBLING_PHASE && !event.bubbles) {\n        return true;\n      }\n      if (\"relatedTarget\" in event) {\n        var originalEvent = unwrap(event);\n        var unwrappedRelatedTarget = originalEvent.relatedTarget;\n        if (unwrappedRelatedTarget) {\n          if (unwrappedRelatedTarget instanceof Object && unwrappedRelatedTarget.addEventListener) {\n            var relatedTarget = wrap(unwrappedRelatedTarget);\n            var adjusted = relatedTargetResolution(event, currentTarget, relatedTarget);\n            if (adjusted === target) return true;\n          } else {\n            adjusted = null;\n          }\n          relatedTargetTable.set(event, adjusted);\n        }\n      }\n      eventPhaseTable.set(event, phase);\n      var type = event.type;\n      var anyRemoved = false;\n      targetTable.set(event, target);\n      currentTargetTable.set(event, currentTarget);\n      listeners.depth++;\n      for (var i = 0, len = listeners.length; i < len; i++) {\n        var listener = listeners[i];\n        if (listener.removed) {\n          anyRemoved = true;\n          continue;\n        }\n        if (listener.type !== type || !listener.capture && phase === CAPTURING_PHASE || listener.capture && phase === BUBBLING_PHASE) {\n          continue;\n        }\n        try {\n          if (typeof listener.handler === \"function\") listener.handler.call(currentTarget, event); else listener.handler.handleEvent(event);\n          if (stopImmediatePropagationTable.get(event)) return false;\n        } catch (ex) {\n          if (!pendingError) pendingError = ex;\n        }\n      }\n      listeners.depth--;\n      if (anyRemoved && listeners.depth === 0) {\n        var copy = listeners.slice();\n        listeners.length = 0;\n        for (var i = 0; i < copy.length; i++) {\n          if (!copy[i].removed) listeners.push(copy[i]);\n        }\n      }\n      return !stopPropagationTable.get(event);\n    }\n    function Listener(type, handler, capture) {\n      this.type = type;\n      this.handler = handler;\n      this.capture = Boolean(capture);\n    }\n    Listener.prototype = {\n      equals: function(that) {\n        return this.handler === that.handler && this.type === that.type && this.capture === that.capture;\n      },\n      get removed() {\n        return this.handler === null;\n      },\n      remove: function() {\n        this.handler = null;\n      }\n    };\n    var OriginalEvent = window.Event;\n    OriginalEvent.prototype.polymerBlackList_ = {\n      returnValue: true,\n      keyLocation: true\n    };\n    function Event(type, options) {\n      if (type instanceof OriginalEvent) {\n        var impl = type;\n        if (!OriginalBeforeUnloadEvent && impl.type === \"beforeunload\" && !(this instanceof BeforeUnloadEvent)) {\n          return new BeforeUnloadEvent(impl);\n        }\n        setWrapper(impl, this);\n      } else {\n        return wrap(constructEvent(OriginalEvent, \"Event\", type, options));\n      }\n    }\n    Event.prototype = {\n      get target() {\n        return targetTable.get(this);\n      },\n      get currentTarget() {\n        return currentTargetTable.get(this);\n      },\n      get eventPhase() {\n        return eventPhaseTable.get(this);\n      },\n      get path() {\n        var eventPath = eventPathTable.get(this);\n        if (!eventPath) return [];\n        return eventPath.slice();\n      },\n      stopPropagation: function() {\n        stopPropagationTable.set(this, true);\n      },\n      stopImmediatePropagation: function() {\n        stopPropagationTable.set(this, true);\n        stopImmediatePropagationTable.set(this, true);\n      }\n    };\n    registerWrapper(OriginalEvent, Event, document.createEvent(\"Event\"));\n    function unwrapOptions(options) {\n      if (!options || !options.relatedTarget) return options;\n      return Object.create(options, {\n        relatedTarget: {\n          value: unwrap(options.relatedTarget)\n        }\n      });\n    }\n    function registerGenericEvent(name, SuperEvent, prototype) {\n      var OriginalEvent = window[name];\n      var GenericEvent = function(type, options) {\n        if (type instanceof OriginalEvent) setWrapper(type, this); else return wrap(constructEvent(OriginalEvent, name, type, options));\n      };\n      GenericEvent.prototype = Object.create(SuperEvent.prototype);\n      if (prototype) mixin(GenericEvent.prototype, prototype);\n      if (OriginalEvent) {\n        try {\n          registerWrapper(OriginalEvent, GenericEvent, new OriginalEvent(\"temp\"));\n        } catch (ex) {\n          registerWrapper(OriginalEvent, GenericEvent, document.createEvent(name));\n        }\n      }\n      return GenericEvent;\n    }\n    var UIEvent = registerGenericEvent(\"UIEvent\", Event);\n    var CustomEvent = registerGenericEvent(\"CustomEvent\", Event);\n    var relatedTargetProto = {\n      get relatedTarget() {\n        var relatedTarget = relatedTargetTable.get(this);\n        if (relatedTarget !== undefined) return relatedTarget;\n        return wrap(unwrap(this).relatedTarget);\n      }\n    };\n    function getInitFunction(name, relatedTargetIndex) {\n      return function() {\n        arguments[relatedTargetIndex] = unwrap(arguments[relatedTargetIndex]);\n        var impl = unwrap(this);\n        impl[name].apply(impl, arguments);\n      };\n    }\n    var mouseEventProto = mixin({\n      initMouseEvent: getInitFunction(\"initMouseEvent\", 14)\n    }, relatedTargetProto);\n    var focusEventProto = mixin({\n      initFocusEvent: getInitFunction(\"initFocusEvent\", 5)\n    }, relatedTargetProto);\n    var MouseEvent = registerGenericEvent(\"MouseEvent\", UIEvent, mouseEventProto);\n    var FocusEvent = registerGenericEvent(\"FocusEvent\", UIEvent, focusEventProto);\n    var defaultInitDicts = Object.create(null);\n    var supportsEventConstructors = function() {\n      try {\n        new window.FocusEvent(\"focus\");\n      } catch (ex) {\n        return false;\n      }\n      return true;\n    }();\n    function constructEvent(OriginalEvent, name, type, options) {\n      if (supportsEventConstructors) return new OriginalEvent(type, unwrapOptions(options));\n      var event = unwrap(document.createEvent(name));\n      var defaultDict = defaultInitDicts[name];\n      var args = [ type ];\n      Object.keys(defaultDict).forEach(function(key) {\n        var v = options != null && key in options ? options[key] : defaultDict[key];\n        if (key === \"relatedTarget\") v = unwrap(v);\n        args.push(v);\n      });\n      event[\"init\" + name].apply(event, args);\n      return event;\n    }\n    if (!supportsEventConstructors) {\n      var configureEventConstructor = function(name, initDict, superName) {\n        if (superName) {\n          var superDict = defaultInitDicts[superName];\n          initDict = mixin(mixin({}, superDict), initDict);\n        }\n        defaultInitDicts[name] = initDict;\n      };\n      configureEventConstructor(\"Event\", {\n        bubbles: false,\n        cancelable: false\n      });\n      configureEventConstructor(\"CustomEvent\", {\n        detail: null\n      }, \"Event\");\n      configureEventConstructor(\"UIEvent\", {\n        view: null,\n        detail: 0\n      }, \"Event\");\n      configureEventConstructor(\"MouseEvent\", {\n        screenX: 0,\n        screenY: 0,\n        clientX: 0,\n        clientY: 0,\n        ctrlKey: false,\n        altKey: false,\n        shiftKey: false,\n        metaKey: false,\n        button: 0,\n        relatedTarget: null\n      }, \"UIEvent\");\n      configureEventConstructor(\"FocusEvent\", {\n        relatedTarget: null\n      }, \"UIEvent\");\n    }\n    var OriginalBeforeUnloadEvent = window.BeforeUnloadEvent;\n    function BeforeUnloadEvent(impl) {\n      Event.call(this, impl);\n    }\n    BeforeUnloadEvent.prototype = Object.create(Event.prototype);\n    mixin(BeforeUnloadEvent.prototype, {\n      get returnValue() {\n        return unsafeUnwrap(this).returnValue;\n      },\n      set returnValue(v) {\n        unsafeUnwrap(this).returnValue = v;\n      }\n    });\n    if (OriginalBeforeUnloadEvent) registerWrapper(OriginalBeforeUnloadEvent, BeforeUnloadEvent);\n    function isValidListener(fun) {\n      if (typeof fun === \"function\") return true;\n      return fun && fun.handleEvent;\n    }\n    function isMutationEvent(type) {\n      switch (type) {\n       case \"DOMAttrModified\":\n       case \"DOMAttributeNameChanged\":\n       case \"DOMCharacterDataModified\":\n       case \"DOMElementNameChanged\":\n       case \"DOMNodeInserted\":\n       case \"DOMNodeInsertedIntoDocument\":\n       case \"DOMNodeRemoved\":\n       case \"DOMNodeRemovedFromDocument\":\n       case \"DOMSubtreeModified\":\n        return true;\n      }\n      return false;\n    }\n    var OriginalEventTarget = window.EventTarget;\n    function EventTarget(impl) {\n      setWrapper(impl, this);\n    }\n    var methodNames = [ \"addEventListener\", \"removeEventListener\", \"dispatchEvent\" ];\n    [ Node, Window ].forEach(function(constructor) {\n      var p = constructor.prototype;\n      methodNames.forEach(function(name) {\n        Object.defineProperty(p, name + \"_\", {\n          value: p[name]\n        });\n      });\n    });\n    function getTargetToListenAt(wrapper) {\n      if (wrapper instanceof wrappers.ShadowRoot) wrapper = wrapper.host;\n      return unwrap(wrapper);\n    }\n    EventTarget.prototype = {\n      addEventListener: function(type, fun, capture) {\n        if (!isValidListener(fun) || isMutationEvent(type)) return;\n        var listener = new Listener(type, fun, capture);\n        var listeners = listenersTable.get(this);\n        if (!listeners) {\n          listeners = [];\n          listeners.depth = 0;\n          listenersTable.set(this, listeners);\n        } else {\n          for (var i = 0; i < listeners.length; i++) {\n            if (listener.equals(listeners[i])) return;\n          }\n        }\n        listeners.push(listener);\n        var target = getTargetToListenAt(this);\n        target.addEventListener_(type, dispatchOriginalEvent, true);\n      },\n      removeEventListener: function(type, fun, capture) {\n        capture = Boolean(capture);\n        var listeners = listenersTable.get(this);\n        if (!listeners) return;\n        var count = 0, found = false;\n        for (var i = 0; i < listeners.length; i++) {\n          if (listeners[i].type === type && listeners[i].capture === capture) {\n            count++;\n            if (listeners[i].handler === fun) {\n              found = true;\n              listeners[i].remove();\n            }\n          }\n        }\n        if (found && count === 1) {\n          var target = getTargetToListenAt(this);\n          target.removeEventListener_(type, dispatchOriginalEvent, true);\n        }\n      },\n      dispatchEvent: function(event) {\n        var nativeEvent = unwrap(event);\n        var eventType = nativeEvent.type;\n        handledEventsTable.set(nativeEvent, false);\n        scope.renderAllPending();\n        var tempListener;\n        if (!hasListenerInAncestors(this, eventType)) {\n          tempListener = function() {};\n          this.addEventListener(eventType, tempListener, true);\n        }\n        try {\n          return unwrap(this).dispatchEvent_(nativeEvent);\n        } finally {\n          if (tempListener) this.removeEventListener(eventType, tempListener, true);\n        }\n      }\n    };\n    function hasListener(node, type) {\n      var listeners = listenersTable.get(node);\n      if (listeners) {\n        for (var i = 0; i < listeners.length; i++) {\n          if (!listeners[i].removed && listeners[i].type === type) return true;\n        }\n      }\n      return false;\n    }\n    function hasListenerInAncestors(target, type) {\n      for (var node = unwrap(target); node; node = node.parentNode) {\n        if (hasListener(wrap(node), type)) return true;\n      }\n      return false;\n    }\n    if (OriginalEventTarget) registerWrapper(OriginalEventTarget, EventTarget);\n    function wrapEventTargetMethods(constructors) {\n      forwardMethodsToWrapper(constructors, methodNames);\n    }\n    var originalElementFromPoint = document.elementFromPoint;\n    function elementFromPoint(self, document, x, y) {\n      scope.renderAllPending();\n      var element = wrap(originalElementFromPoint.call(unsafeUnwrap(document), x, y));\n      if (!element) return null;\n      var path = getEventPath(element, null);\n      var idx = path.lastIndexOf(self);\n      if (idx == -1) return null; else path = path.slice(0, idx);\n      return eventRetargetting(path, self);\n    }\n    function getEventHandlerGetter(name) {\n      return function() {\n        var inlineEventHandlers = eventHandlersTable.get(this);\n        return inlineEventHandlers && inlineEventHandlers[name] && inlineEventHandlers[name].value || null;\n      };\n    }\n    function getEventHandlerSetter(name) {\n      var eventType = name.slice(2);\n      return function(value) {\n        var inlineEventHandlers = eventHandlersTable.get(this);\n        if (!inlineEventHandlers) {\n          inlineEventHandlers = Object.create(null);\n          eventHandlersTable.set(this, inlineEventHandlers);\n        }\n        var old = inlineEventHandlers[name];\n        if (old) this.removeEventListener(eventType, old.wrapped, false);\n        if (typeof value === \"function\") {\n          var wrapped = function(e) {\n            var rv = value.call(this, e);\n            if (rv === false) e.preventDefault(); else if (name === \"onbeforeunload\" && typeof rv === \"string\") e.returnValue = rv;\n          };\n          this.addEventListener(eventType, wrapped, false);\n          inlineEventHandlers[name] = {\n            value: value,\n            wrapped: wrapped\n          };\n        }\n      };\n    }\n    scope.elementFromPoint = elementFromPoint;\n    scope.getEventHandlerGetter = getEventHandlerGetter;\n    scope.getEventHandlerSetter = getEventHandlerSetter;\n    scope.wrapEventTargetMethods = wrapEventTargetMethods;\n    scope.wrappers.BeforeUnloadEvent = BeforeUnloadEvent;\n    scope.wrappers.CustomEvent = CustomEvent;\n    scope.wrappers.Event = Event;\n    scope.wrappers.EventTarget = EventTarget;\n    scope.wrappers.FocusEvent = FocusEvent;\n    scope.wrappers.MouseEvent = MouseEvent;\n    scope.wrappers.UIEvent = UIEvent;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var UIEvent = scope.wrappers.UIEvent;\n    var mixin = scope.mixin;\n    var registerWrapper = scope.registerWrapper;\n    var setWrapper = scope.setWrapper;\n    var unsafeUnwrap = scope.unsafeUnwrap;\n    var wrap = scope.wrap;\n    var OriginalTouchEvent = window.TouchEvent;\n    if (!OriginalTouchEvent) return;\n    var nativeEvent;\n    try {\n      nativeEvent = document.createEvent(\"TouchEvent\");\n    } catch (ex) {\n      return;\n    }\n    var nonEnumDescriptor = {\n      enumerable: false\n    };\n    function nonEnum(obj, prop) {\n      Object.defineProperty(obj, prop, nonEnumDescriptor);\n    }\n    function Touch(impl) {\n      setWrapper(impl, this);\n    }\n    Touch.prototype = {\n      get target() {\n        return wrap(unsafeUnwrap(this).target);\n      }\n    };\n    var descr = {\n      configurable: true,\n      enumerable: true,\n      get: null\n    };\n    [ \"clientX\", \"clientY\", \"screenX\", \"screenY\", \"pageX\", \"pageY\", \"identifier\", \"webkitRadiusX\", \"webkitRadiusY\", \"webkitRotationAngle\", \"webkitForce\" ].forEach(function(name) {\n      descr.get = function() {\n        return unsafeUnwrap(this)[name];\n      };\n      Object.defineProperty(Touch.prototype, name, descr);\n    });\n    function TouchList() {\n      this.length = 0;\n      nonEnum(this, \"length\");\n    }\n    TouchList.prototype = {\n      item: function(index) {\n        return this[index];\n      }\n    };\n    function wrapTouchList(nativeTouchList) {\n      var list = new TouchList();\n      for (var i = 0; i < nativeTouchList.length; i++) {\n        list[i] = new Touch(nativeTouchList[i]);\n      }\n      list.length = i;\n      return list;\n    }\n    function TouchEvent(impl) {\n      UIEvent.call(this, impl);\n    }\n    TouchEvent.prototype = Object.create(UIEvent.prototype);\n    mixin(TouchEvent.prototype, {\n      get touches() {\n        return wrapTouchList(unsafeUnwrap(this).touches);\n      },\n      get targetTouches() {\n        return wrapTouchList(unsafeUnwrap(this).targetTouches);\n      },\n      get changedTouches() {\n        return wrapTouchList(unsafeUnwrap(this).changedTouches);\n      },\n      initTouchEvent: function() {\n        throw new Error(\"Not implemented\");\n      }\n    });\n    registerWrapper(OriginalTouchEvent, TouchEvent, nativeEvent);\n    scope.wrappers.Touch = Touch;\n    scope.wrappers.TouchEvent = TouchEvent;\n    scope.wrappers.TouchList = TouchList;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var unsafeUnwrap = scope.unsafeUnwrap;\n    var wrap = scope.wrap;\n    var nonEnumDescriptor = {\n      enumerable: false\n    };\n    function nonEnum(obj, prop) {\n      Object.defineProperty(obj, prop, nonEnumDescriptor);\n    }\n    function NodeList() {\n      this.length = 0;\n      nonEnum(this, \"length\");\n    }\n    NodeList.prototype = {\n      item: function(index) {\n        return this[index];\n      }\n    };\n    nonEnum(NodeList.prototype, \"item\");\n    function wrapNodeList(list) {\n      if (list == null) return list;\n      var wrapperList = new NodeList();\n      for (var i = 0, length = list.length; i < length; i++) {\n        wrapperList[i] = wrap(list[i]);\n      }\n      wrapperList.length = length;\n      return wrapperList;\n    }\n    function addWrapNodeListMethod(wrapperConstructor, name) {\n      wrapperConstructor.prototype[name] = function() {\n        return wrapNodeList(unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments));\n      };\n    }\n    scope.wrappers.NodeList = NodeList;\n    scope.addWrapNodeListMethod = addWrapNodeListMethod;\n    scope.wrapNodeList = wrapNodeList;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    scope.wrapHTMLCollection = scope.wrapNodeList;\n    scope.wrappers.HTMLCollection = scope.wrappers.NodeList;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var EventTarget = scope.wrappers.EventTarget;\n    var NodeList = scope.wrappers.NodeList;\n    var TreeScope = scope.TreeScope;\n    var assert = scope.assert;\n    var defineWrapGetter = scope.defineWrapGetter;\n    var enqueueMutation = scope.enqueueMutation;\n    var getTreeScope = scope.getTreeScope;\n    var isWrapper = scope.isWrapper;\n    var mixin = scope.mixin;\n    var registerTransientObservers = scope.registerTransientObservers;\n    var registerWrapper = scope.registerWrapper;\n    var setTreeScope = scope.setTreeScope;\n    var unsafeUnwrap = scope.unsafeUnwrap;\n    var unwrap = scope.unwrap;\n    var unwrapIfNeeded = scope.unwrapIfNeeded;\n    var wrap = scope.wrap;\n    var wrapIfNeeded = scope.wrapIfNeeded;\n    var wrappers = scope.wrappers;\n    function assertIsNodeWrapper(node) {\n      assert(node instanceof Node);\n    }\n    function createOneElementNodeList(node) {\n      var nodes = new NodeList();\n      nodes[0] = node;\n      nodes.length = 1;\n      return nodes;\n    }\n    var surpressMutations = false;\n    function enqueueRemovalForInsertedNodes(node, parent, nodes) {\n      enqueueMutation(parent, \"childList\", {\n        removedNodes: nodes,\n        previousSibling: node.previousSibling,\n        nextSibling: node.nextSibling\n      });\n    }\n    function enqueueRemovalForInsertedDocumentFragment(df, nodes) {\n      enqueueMutation(df, \"childList\", {\n        removedNodes: nodes\n      });\n    }\n    function collectNodes(node, parentNode, previousNode, nextNode) {\n      if (node instanceof DocumentFragment) {\n        var nodes = collectNodesForDocumentFragment(node);\n        surpressMutations = true;\n        for (var i = nodes.length - 1; i >= 0; i--) {\n          node.removeChild(nodes[i]);\n          nodes[i].parentNode_ = parentNode;\n        }\n        surpressMutations = false;\n        for (var i = 0; i < nodes.length; i++) {\n          nodes[i].previousSibling_ = nodes[i - 1] || previousNode;\n          nodes[i].nextSibling_ = nodes[i + 1] || nextNode;\n        }\n        if (previousNode) previousNode.nextSibling_ = nodes[0];\n        if (nextNode) nextNode.previousSibling_ = nodes[nodes.length - 1];\n        return nodes;\n      }\n      var nodes = createOneElementNodeList(node);\n      var oldParent = node.parentNode;\n      if (oldParent) {\n        oldParent.removeChild(node);\n      }\n      node.parentNode_ = parentNode;\n      node.previousSibling_ = previousNode;\n      node.nextSibling_ = nextNode;\n      if (previousNode) previousNode.nextSibling_ = node;\n      if (nextNode) nextNode.previousSibling_ = node;\n      return nodes;\n    }\n    function collectNodesNative(node) {\n      if (node instanceof DocumentFragment) return collectNodesForDocumentFragment(node);\n      var nodes = createOneElementNodeList(node);\n      var oldParent = node.parentNode;\n      if (oldParent) enqueueRemovalForInsertedNodes(node, oldParent, nodes);\n      return nodes;\n    }\n    function collectNodesForDocumentFragment(node) {\n      var nodes = new NodeList();\n      var i = 0;\n      for (var child = node.firstChild; child; child = child.nextSibling) {\n        nodes[i++] = child;\n      }\n      nodes.length = i;\n      enqueueRemovalForInsertedDocumentFragment(node, nodes);\n      return nodes;\n    }\n    function snapshotNodeList(nodeList) {\n      return nodeList;\n    }\n    function nodeWasAdded(node, treeScope) {\n      setTreeScope(node, treeScope);\n      node.nodeIsInserted_();\n    }\n    function nodesWereAdded(nodes, parent) {\n      var treeScope = getTreeScope(parent);\n      for (var i = 0; i < nodes.length; i++) {\n        nodeWasAdded(nodes[i], treeScope);\n      }\n    }\n    function nodeWasRemoved(node) {\n      setTreeScope(node, new TreeScope(node, null));\n    }\n    function nodesWereRemoved(nodes) {\n      for (var i = 0; i < nodes.length; i++) {\n        nodeWasRemoved(nodes[i]);\n      }\n    }\n    function ensureSameOwnerDocument(parent, child) {\n      var ownerDoc = parent.nodeType === Node.DOCUMENT_NODE ? parent : parent.ownerDocument;\n      if (ownerDoc !== child.ownerDocument) ownerDoc.adoptNode(child);\n    }\n    function adoptNodesIfNeeded(owner, nodes) {\n      if (!nodes.length) return;\n      var ownerDoc = owner.ownerDocument;\n      if (ownerDoc === nodes[0].ownerDocument) return;\n      for (var i = 0; i < nodes.length; i++) {\n        scope.adoptNodeNoRemove(nodes[i], ownerDoc);\n      }\n    }\n    function unwrapNodesForInsertion(owner, nodes) {\n      adoptNodesIfNeeded(owner, nodes);\n      var length = nodes.length;\n      if (length === 1) return unwrap(nodes[0]);\n      var df = unwrap(owner.ownerDocument.createDocumentFragment());\n      for (var i = 0; i < length; i++) {\n        df.appendChild(unwrap(nodes[i]));\n      }\n      return df;\n    }\n    function clearChildNodes(wrapper) {\n      if (wrapper.firstChild_ !== undefined) {\n        var child = wrapper.firstChild_;\n        while (child) {\n          var tmp = child;\n          child = child.nextSibling_;\n          tmp.parentNode_ = tmp.previousSibling_ = tmp.nextSibling_ = undefined;\n        }\n      }\n      wrapper.firstChild_ = wrapper.lastChild_ = undefined;\n    }\n    function removeAllChildNodes(wrapper) {\n      if (wrapper.invalidateShadowRenderer()) {\n        var childWrapper = wrapper.firstChild;\n        while (childWrapper) {\n          assert(childWrapper.parentNode === wrapper);\n          var nextSibling = childWrapper.nextSibling;\n          var childNode = unwrap(childWrapper);\n          var parentNode = childNode.parentNode;\n          if (parentNode) originalRemoveChild.call(parentNode, childNode);\n          childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = null;\n          childWrapper = nextSibling;\n        }\n        wrapper.firstChild_ = wrapper.lastChild_ = null;\n      } else {\n        var node = unwrap(wrapper);\n        var child = node.firstChild;\n        var nextSibling;\n        while (child) {\n          nextSibling = child.nextSibling;\n          originalRemoveChild.call(node, child);\n          child = nextSibling;\n        }\n      }\n    }\n    function invalidateParent(node) {\n      var p = node.parentNode;\n      return p && p.invalidateShadowRenderer();\n    }\n    function cleanupNodes(nodes) {\n      for (var i = 0, n; i < nodes.length; i++) {\n        n = nodes[i];\n        n.parentNode.removeChild(n);\n      }\n    }\n    var originalImportNode = document.importNode;\n    var originalCloneNode = window.Node.prototype.cloneNode;\n    function cloneNode(node, deep, opt_doc) {\n      var clone;\n      if (opt_doc) clone = wrap(originalImportNode.call(opt_doc, unsafeUnwrap(node), false)); else clone = wrap(originalCloneNode.call(unsafeUnwrap(node), false));\n      if (deep) {\n        for (var child = node.firstChild; child; child = child.nextSibling) {\n          clone.appendChild(cloneNode(child, true, opt_doc));\n        }\n        if (node instanceof wrappers.HTMLTemplateElement) {\n          var cloneContent = clone.content;\n          for (var child = node.content.firstChild; child; child = child.nextSibling) {\n            cloneContent.appendChild(cloneNode(child, true, opt_doc));\n          }\n        }\n      }\n      return clone;\n    }\n    function contains(self, child) {\n      if (!child || getTreeScope(self) !== getTreeScope(child)) return false;\n      for (var node = child; node; node = node.parentNode) {\n        if (node === self) return true;\n      }\n      return false;\n    }\n    var OriginalNode = window.Node;\n    function Node(original) {\n      assert(original instanceof OriginalNode);\n      EventTarget.call(this, original);\n      this.parentNode_ = undefined;\n      this.firstChild_ = undefined;\n      this.lastChild_ = undefined;\n      this.nextSibling_ = undefined;\n      this.previousSibling_ = undefined;\n      this.treeScope_ = undefined;\n    }\n    var OriginalDocumentFragment = window.DocumentFragment;\n    var originalAppendChild = OriginalNode.prototype.appendChild;\n    var originalCompareDocumentPosition = OriginalNode.prototype.compareDocumentPosition;\n    var originalIsEqualNode = OriginalNode.prototype.isEqualNode;\n    var originalInsertBefore = OriginalNode.prototype.insertBefore;\n    var originalRemoveChild = OriginalNode.prototype.removeChild;\n    var originalReplaceChild = OriginalNode.prototype.replaceChild;\n    var isIe = /Trident|Edge/.test(navigator.userAgent);\n    var removeChildOriginalHelper = isIe ? function(parent, child) {\n      try {\n        originalRemoveChild.call(parent, child);\n      } catch (ex) {\n        if (!(parent instanceof OriginalDocumentFragment)) throw ex;\n      }\n    } : function(parent, child) {\n      originalRemoveChild.call(parent, child);\n    };\n    Node.prototype = Object.create(EventTarget.prototype);\n    mixin(Node.prototype, {\n      appendChild: function(childWrapper) {\n        return this.insertBefore(childWrapper, null);\n      },\n      insertBefore: function(childWrapper, refWrapper) {\n        assertIsNodeWrapper(childWrapper);\n        var refNode;\n        if (refWrapper) {\n          if (isWrapper(refWrapper)) {\n            refNode = unwrap(refWrapper);\n          } else {\n            refNode = refWrapper;\n            refWrapper = wrap(refNode);\n          }\n        } else {\n          refWrapper = null;\n          refNode = null;\n        }\n        refWrapper && assert(refWrapper.parentNode === this);\n        var nodes;\n        var previousNode = refWrapper ? refWrapper.previousSibling : this.lastChild;\n        var useNative = !this.invalidateShadowRenderer() && !invalidateParent(childWrapper);\n        if (useNative) nodes = collectNodesNative(childWrapper); else nodes = collectNodes(childWrapper, this, previousNode, refWrapper);\n        if (useNative) {\n          ensureSameOwnerDocument(this, childWrapper);\n          clearChildNodes(this);\n          originalInsertBefore.call(unsafeUnwrap(this), unwrap(childWrapper), refNode);\n        } else {\n          if (!previousNode) this.firstChild_ = nodes[0];\n          if (!refWrapper) {\n            this.lastChild_ = nodes[nodes.length - 1];\n            if (this.firstChild_ === undefined) this.firstChild_ = this.firstChild;\n          }\n          var parentNode = refNode ? refNode.parentNode : unsafeUnwrap(this);\n          if (parentNode) {\n            originalInsertBefore.call(parentNode, unwrapNodesForInsertion(this, nodes), refNode);\n          } else {\n            adoptNodesIfNeeded(this, nodes);\n          }\n        }\n        enqueueMutation(this, \"childList\", {\n          addedNodes: nodes,\n          nextSibling: refWrapper,\n          previousSibling: previousNode\n        });\n        nodesWereAdded(nodes, this);\n        return childWrapper;\n      },\n      removeChild: function(childWrapper) {\n        assertIsNodeWrapper(childWrapper);\n        if (childWrapper.parentNode !== this) {\n          var found = false;\n          var childNodes = this.childNodes;\n          for (var ieChild = this.firstChild; ieChild; ieChild = ieChild.nextSibling) {\n            if (ieChild === childWrapper) {\n              found = true;\n              break;\n            }\n          }\n          if (!found) {\n            throw new Error(\"NotFoundError\");\n          }\n        }\n        var childNode = unwrap(childWrapper);\n        var childWrapperNextSibling = childWrapper.nextSibling;\n        var childWrapperPreviousSibling = childWrapper.previousSibling;\n        if (this.invalidateShadowRenderer()) {\n          var thisFirstChild = this.firstChild;\n          var thisLastChild = this.lastChild;\n          var parentNode = childNode.parentNode;\n          if (parentNode) removeChildOriginalHelper(parentNode, childNode);\n          if (thisFirstChild === childWrapper) this.firstChild_ = childWrapperNextSibling;\n          if (thisLastChild === childWrapper) this.lastChild_ = childWrapperPreviousSibling;\n          if (childWrapperPreviousSibling) childWrapperPreviousSibling.nextSibling_ = childWrapperNextSibling;\n          if (childWrapperNextSibling) {\n            childWrapperNextSibling.previousSibling_ = childWrapperPreviousSibling;\n          }\n          childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = undefined;\n        } else {\n          clearChildNodes(this);\n          removeChildOriginalHelper(unsafeUnwrap(this), childNode);\n        }\n        if (!surpressMutations) {\n          enqueueMutation(this, \"childList\", {\n            removedNodes: createOneElementNodeList(childWrapper),\n            nextSibling: childWrapperNextSibling,\n            previousSibling: childWrapperPreviousSibling\n          });\n        }\n        registerTransientObservers(this, childWrapper);\n        return childWrapper;\n      },\n      replaceChild: function(newChildWrapper, oldChildWrapper) {\n        assertIsNodeWrapper(newChildWrapper);\n        var oldChildNode;\n        if (isWrapper(oldChildWrapper)) {\n          oldChildNode = unwrap(oldChildWrapper);\n        } else {\n          oldChildNode = oldChildWrapper;\n          oldChildWrapper = wrap(oldChildNode);\n        }\n        if (oldChildWrapper.parentNode !== this) {\n          throw new Error(\"NotFoundError\");\n        }\n        var nextNode = oldChildWrapper.nextSibling;\n        var previousNode = oldChildWrapper.previousSibling;\n        var nodes;\n        var useNative = !this.invalidateShadowRenderer() && !invalidateParent(newChildWrapper);\n        if (useNative) {\n          nodes = collectNodesNative(newChildWrapper);\n        } else {\n          if (nextNode === newChildWrapper) nextNode = newChildWrapper.nextSibling;\n          nodes = collectNodes(newChildWrapper, this, previousNode, nextNode);\n        }\n        if (!useNative) {\n          if (this.firstChild === oldChildWrapper) this.firstChild_ = nodes[0];\n          if (this.lastChild === oldChildWrapper) this.lastChild_ = nodes[nodes.length - 1];\n          oldChildWrapper.previousSibling_ = oldChildWrapper.nextSibling_ = oldChildWrapper.parentNode_ = undefined;\n          if (oldChildNode.parentNode) {\n            originalReplaceChild.call(oldChildNode.parentNode, unwrapNodesForInsertion(this, nodes), oldChildNode);\n          }\n        } else {\n          ensureSameOwnerDocument(this, newChildWrapper);\n          clearChildNodes(this);\n          originalReplaceChild.call(unsafeUnwrap(this), unwrap(newChildWrapper), oldChildNode);\n        }\n        enqueueMutation(this, \"childList\", {\n          addedNodes: nodes,\n          removedNodes: createOneElementNodeList(oldChildWrapper),\n          nextSibling: nextNode,\n          previousSibling: previousNode\n        });\n        nodeWasRemoved(oldChildWrapper);\n        nodesWereAdded(nodes, this);\n        return oldChildWrapper;\n      },\n      nodeIsInserted_: function() {\n        for (var child = this.firstChild; child; child = child.nextSibling) {\n          child.nodeIsInserted_();\n        }\n      },\n      hasChildNodes: function() {\n        return this.firstChild !== null;\n      },\n      get parentNode() {\n        return this.parentNode_ !== undefined ? this.parentNode_ : wrap(unsafeUnwrap(this).parentNode);\n      },\n      get firstChild() {\n        return this.firstChild_ !== undefined ? this.firstChild_ : wrap(unsafeUnwrap(this).firstChild);\n      },\n      get lastChild() {\n        return this.lastChild_ !== undefined ? this.lastChild_ : wrap(unsafeUnwrap(this).lastChild);\n      },\n      get nextSibling() {\n        return this.nextSibling_ !== undefined ? this.nextSibling_ : wrap(unsafeUnwrap(this).nextSibling);\n      },\n      get previousSibling() {\n        return this.previousSibling_ !== undefined ? this.previousSibling_ : wrap(unsafeUnwrap(this).previousSibling);\n      },\n      get parentElement() {\n        var p = this.parentNode;\n        while (p && p.nodeType !== Node.ELEMENT_NODE) {\n          p = p.parentNode;\n        }\n        return p;\n      },\n      get textContent() {\n        var s = \"\";\n        for (var child = this.firstChild; child; child = child.nextSibling) {\n          if (child.nodeType != Node.COMMENT_NODE) {\n            s += child.textContent;\n          }\n        }\n        return s;\n      },\n      set textContent(textContent) {\n        if (textContent == null) textContent = \"\";\n        var removedNodes = snapshotNodeList(this.childNodes);\n        if (this.invalidateShadowRenderer()) {\n          removeAllChildNodes(this);\n          if (textContent !== \"\") {\n            var textNode = unsafeUnwrap(this).ownerDocument.createTextNode(textContent);\n            this.appendChild(textNode);\n          }\n        } else {\n          clearChildNodes(this);\n          unsafeUnwrap(this).textContent = textContent;\n        }\n        var addedNodes = snapshotNodeList(this.childNodes);\n        enqueueMutation(this, \"childList\", {\n          addedNodes: addedNodes,\n          removedNodes: removedNodes\n        });\n        nodesWereRemoved(removedNodes);\n        nodesWereAdded(addedNodes, this);\n      },\n      get childNodes() {\n        var wrapperList = new NodeList();\n        var i = 0;\n        for (var child = this.firstChild; child; child = child.nextSibling) {\n          wrapperList[i++] = child;\n        }\n        wrapperList.length = i;\n        return wrapperList;\n      },\n      cloneNode: function(deep) {\n        return cloneNode(this, deep);\n      },\n      contains: function(child) {\n        return contains(this, wrapIfNeeded(child));\n      },\n      compareDocumentPosition: function(otherNode) {\n        return originalCompareDocumentPosition.call(unsafeUnwrap(this), unwrapIfNeeded(otherNode));\n      },\n      isEqualNode: function(otherNode) {\n        return originalIsEqualNode.call(unsafeUnwrap(this), unwrapIfNeeded(otherNode));\n      },\n      normalize: function() {\n        var nodes = snapshotNodeList(this.childNodes);\n        var remNodes = [];\n        var s = \"\";\n        var modNode;\n        for (var i = 0, n; i < nodes.length; i++) {\n          n = nodes[i];\n          if (n.nodeType === Node.TEXT_NODE) {\n            if (!modNode && !n.data.length) this.removeChild(n); else if (!modNode) modNode = n; else {\n              s += n.data;\n              remNodes.push(n);\n            }\n          } else {\n            if (modNode && remNodes.length) {\n              modNode.data += s;\n              cleanupNodes(remNodes);\n            }\n            remNodes = [];\n            s = \"\";\n            modNode = null;\n            if (n.childNodes.length) n.normalize();\n          }\n        }\n        if (modNode && remNodes.length) {\n          modNode.data += s;\n          cleanupNodes(remNodes);\n        }\n      }\n    });\n    defineWrapGetter(Node, \"ownerDocument\");\n    registerWrapper(OriginalNode, Node, document.createDocumentFragment());\n    delete Node.prototype.querySelector;\n    delete Node.prototype.querySelectorAll;\n    Node.prototype = mixin(Object.create(EventTarget.prototype), Node.prototype);\n    scope.cloneNode = cloneNode;\n    scope.nodeWasAdded = nodeWasAdded;\n    scope.nodeWasRemoved = nodeWasRemoved;\n    scope.nodesWereAdded = nodesWereAdded;\n    scope.nodesWereRemoved = nodesWereRemoved;\n    scope.originalInsertBefore = originalInsertBefore;\n    scope.originalRemoveChild = originalRemoveChild;\n    scope.snapshotNodeList = snapshotNodeList;\n    scope.wrappers.Node = Node;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var HTMLCollection = scope.wrappers.HTMLCollection;\n    var NodeList = scope.wrappers.NodeList;\n    var getTreeScope = scope.getTreeScope;\n    var unsafeUnwrap = scope.unsafeUnwrap;\n    var wrap = scope.wrap;\n    var originalDocumentQuerySelector = document.querySelector;\n    var originalElementQuerySelector = document.documentElement.querySelector;\n    var originalDocumentQuerySelectorAll = document.querySelectorAll;\n    var originalElementQuerySelectorAll = document.documentElement.querySelectorAll;\n    var originalDocumentGetElementsByTagName = document.getElementsByTagName;\n    var originalElementGetElementsByTagName = document.documentElement.getElementsByTagName;\n    var originalDocumentGetElementsByTagNameNS = document.getElementsByTagNameNS;\n    var originalElementGetElementsByTagNameNS = document.documentElement.getElementsByTagNameNS;\n    var OriginalElement = window.Element;\n    var OriginalDocument = window.HTMLDocument || window.Document;\n    function filterNodeList(list, index, result, deep) {\n      var wrappedItem = null;\n      var root = null;\n      for (var i = 0, length = list.length; i < length; i++) {\n        wrappedItem = wrap(list[i]);\n        if (!deep && (root = getTreeScope(wrappedItem).root)) {\n          if (root instanceof scope.wrappers.ShadowRoot) {\n            continue;\n          }\n        }\n        result[index++] = wrappedItem;\n      }\n      return index;\n    }\n    function shimSelector(selector) {\n      return String(selector).replace(/\\/deep\\/|::shadow|>>>/g, \" \");\n    }\n    function shimMatchesSelector(selector) {\n      return String(selector).replace(/:host\\(([^\\s]+)\\)/g, \"$1\").replace(/([^\\s]):host/g, \"$1\").replace(\":host\", \"*\").replace(/\\^|\\/shadow\\/|\\/shadow-deep\\/|::shadow|\\/deep\\/|::content|>>>/g, \" \");\n    }\n    function findOne(node, selector) {\n      var m, el = node.firstElementChild;\n      while (el) {\n        if (el.matches(selector)) return el;\n        m = findOne(el, selector);\n        if (m) return m;\n        el = el.nextElementSibling;\n      }\n      return null;\n    }\n    function matchesSelector(el, selector) {\n      return el.matches(selector);\n    }\n    var XHTML_NS = \"http://www.w3.org/1999/xhtml\";\n    function matchesTagName(el, localName, localNameLowerCase) {\n      var ln = el.localName;\n      return ln === localName || ln === localNameLowerCase && el.namespaceURI === XHTML_NS;\n    }\n    function matchesEveryThing() {\n      return true;\n    }\n    function matchesLocalNameOnly(el, ns, localName) {\n      return el.localName === localName;\n    }\n    function matchesNameSpace(el, ns) {\n      return el.namespaceURI === ns;\n    }\n    function matchesLocalNameNS(el, ns, localName) {\n      return el.namespaceURI === ns && el.localName === localName;\n    }\n    function findElements(node, index, result, p, arg0, arg1) {\n      var el = node.firstElementChild;\n      while (el) {\n        if (p(el, arg0, arg1)) result[index++] = el;\n        index = findElements(el, index, result, p, arg0, arg1);\n        el = el.nextElementSibling;\n      }\n      return index;\n    }\n    function querySelectorAllFiltered(p, index, result, selector, deep) {\n      var target = unsafeUnwrap(this);\n      var list;\n      var root = getTreeScope(this).root;\n      if (root instanceof scope.wrappers.ShadowRoot) {\n        return findElements(this, index, result, p, selector, null);\n      } else if (target instanceof OriginalElement) {\n        list = originalElementQuerySelectorAll.call(target, selector);\n      } else if (target instanceof OriginalDocument) {\n        list = originalDocumentQuerySelectorAll.call(target, selector);\n      } else {\n        return findElements(this, index, result, p, selector, null);\n      }\n      return filterNodeList(list, index, result, deep);\n    }\n    var SelectorsInterface = {\n      querySelector: function(selector) {\n        var shimmed = shimSelector(selector);\n        var deep = shimmed !== selector;\n        selector = shimmed;\n        var target = unsafeUnwrap(this);\n        var wrappedItem;\n        var root = getTreeScope(this).root;\n        if (root instanceof scope.wrappers.ShadowRoot) {\n          return findOne(this, selector);\n        } else if (target instanceof OriginalElement) {\n          wrappedItem = wrap(originalElementQuerySelector.call(target, selector));\n        } else if (target instanceof OriginalDocument) {\n          wrappedItem = wrap(originalDocumentQuerySelector.call(target, selector));\n        } else {\n          return findOne(this, selector);\n        }\n        if (!wrappedItem) {\n          return wrappedItem;\n        } else if (!deep && (root = getTreeScope(wrappedItem).root)) {\n          if (root instanceof scope.wrappers.ShadowRoot) {\n            return findOne(this, selector);\n          }\n        }\n        return wrappedItem;\n      },\n      querySelectorAll: function(selector) {\n        var shimmed = shimSelector(selector);\n        var deep = shimmed !== selector;\n        selector = shimmed;\n        var result = new NodeList();\n        result.length = querySelectorAllFiltered.call(this, matchesSelector, 0, result, selector, deep);\n        return result;\n      }\n    };\n    var MatchesInterface = {\n      matches: function(selector) {\n        selector = shimMatchesSelector(selector);\n        return scope.originalMatches.call(unsafeUnwrap(this), selector);\n      }\n    };\n    function getElementsByTagNameFiltered(p, index, result, localName, lowercase) {\n      var target = unsafeUnwrap(this);\n      var list;\n      var root = getTreeScope(this).root;\n      if (root instanceof scope.wrappers.ShadowRoot) {\n        return findElements(this, index, result, p, localName, lowercase);\n      } else if (target instanceof OriginalElement) {\n        list = originalElementGetElementsByTagName.call(target, localName, lowercase);\n      } else if (target instanceof OriginalDocument) {\n        list = originalDocumentGetElementsByTagName.call(target, localName, lowercase);\n      } else {\n        return findElements(this, index, result, p, localName, lowercase);\n      }\n      return filterNodeList(list, index, result, false);\n    }\n    function getElementsByTagNameNSFiltered(p, index, result, ns, localName) {\n      var target = unsafeUnwrap(this);\n      var list;\n      var root = getTreeScope(this).root;\n      if (root instanceof scope.wrappers.ShadowRoot) {\n        return findElements(this, index, result, p, ns, localName);\n      } else if (target instanceof OriginalElement) {\n        list = originalElementGetElementsByTagNameNS.call(target, ns, localName);\n      } else if (target instanceof OriginalDocument) {\n        list = originalDocumentGetElementsByTagNameNS.call(target, ns, localName);\n      } else {\n        return findElements(this, index, result, p, ns, localName);\n      }\n      return filterNodeList(list, index, result, false);\n    }\n    var GetElementsByInterface = {\n      getElementsByTagName: function(localName) {\n        var result = new HTMLCollection();\n        var match = localName === \"*\" ? matchesEveryThing : matchesTagName;\n        result.length = getElementsByTagNameFiltered.call(this, match, 0, result, localName, localName.toLowerCase());\n        return result;\n      },\n      getElementsByClassName: function(className) {\n        return this.querySelectorAll(\".\" + className);\n      },\n      getElementsByTagNameNS: function(ns, localName) {\n        var result = new HTMLCollection();\n        var match = null;\n        if (ns === \"*\") {\n          match = localName === \"*\" ? matchesEveryThing : matchesLocalNameOnly;\n        } else {\n          match = localName === \"*\" ? matchesNameSpace : matchesLocalNameNS;\n        }\n        result.length = getElementsByTagNameNSFiltered.call(this, match, 0, result, ns || null, localName);\n        return result;\n      }\n    };\n    scope.GetElementsByInterface = GetElementsByInterface;\n    scope.SelectorsInterface = SelectorsInterface;\n    scope.MatchesInterface = MatchesInterface;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var NodeList = scope.wrappers.NodeList;\n    function forwardElement(node) {\n      while (node && node.nodeType !== Node.ELEMENT_NODE) {\n        node = node.nextSibling;\n      }\n      return node;\n    }\n    function backwardsElement(node) {\n      while (node && node.nodeType !== Node.ELEMENT_NODE) {\n        node = node.previousSibling;\n      }\n      return node;\n    }\n    var ParentNodeInterface = {\n      get firstElementChild() {\n        return forwardElement(this.firstChild);\n      },\n      get lastElementChild() {\n        return backwardsElement(this.lastChild);\n      },\n      get childElementCount() {\n        var count = 0;\n        for (var child = this.firstElementChild; child; child = child.nextElementSibling) {\n          count++;\n        }\n        return count;\n      },\n      get children() {\n        var wrapperList = new NodeList();\n        var i = 0;\n        for (var child = this.firstElementChild; child; child = child.nextElementSibling) {\n          wrapperList[i++] = child;\n        }\n        wrapperList.length = i;\n        return wrapperList;\n      },\n      remove: function() {\n        var p = this.parentNode;\n        if (p) p.removeChild(this);\n      }\n    };\n    var ChildNodeInterface = {\n      get nextElementSibling() {\n        return forwardElement(this.nextSibling);\n      },\n      get previousElementSibling() {\n        return backwardsElement(this.previousSibling);\n      }\n    };\n    var NonElementParentNodeInterface = {\n      getElementById: function(id) {\n        if (/[ \\t\\n\\r\\f]/.test(id)) return null;\n        return this.querySelector('[id=\"' + id + '\"]');\n      }\n    };\n    scope.ChildNodeInterface = ChildNodeInterface;\n    scope.NonElementParentNodeInterface = NonElementParentNodeInterface;\n    scope.ParentNodeInterface = ParentNodeInterface;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var ChildNodeInterface = scope.ChildNodeInterface;\n    var Node = scope.wrappers.Node;\n    var enqueueMutation = scope.enqueueMutation;\n    var mixin = scope.mixin;\n    var registerWrapper = scope.registerWrapper;\n    var unsafeUnwrap = scope.unsafeUnwrap;\n    var OriginalCharacterData = window.CharacterData;\n    function CharacterData(node) {\n      Node.call(this, node);\n    }\n    CharacterData.prototype = Object.create(Node.prototype);\n    mixin(CharacterData.prototype, {\n      get nodeValue() {\n        return this.data;\n      },\n      set nodeValue(data) {\n        this.data = data;\n      },\n      get textContent() {\n        return this.data;\n      },\n      set textContent(value) {\n        this.data = value;\n      },\n      get data() {\n        return unsafeUnwrap(this).data;\n      },\n      set data(value) {\n        var oldValue = unsafeUnwrap(this).data;\n        enqueueMutation(this, \"characterData\", {\n          oldValue: oldValue\n        });\n        unsafeUnwrap(this).data = value;\n      }\n    });\n    mixin(CharacterData.prototype, ChildNodeInterface);\n    registerWrapper(OriginalCharacterData, CharacterData, document.createTextNode(\"\"));\n    scope.wrappers.CharacterData = CharacterData;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var CharacterData = scope.wrappers.CharacterData;\n    var enqueueMutation = scope.enqueueMutation;\n    var mixin = scope.mixin;\n    var registerWrapper = scope.registerWrapper;\n    function toUInt32(x) {\n      return x >>> 0;\n    }\n    var OriginalText = window.Text;\n    function Text(node) {\n      CharacterData.call(this, node);\n    }\n    Text.prototype = Object.create(CharacterData.prototype);\n    mixin(Text.prototype, {\n      splitText: function(offset) {\n        offset = toUInt32(offset);\n        var s = this.data;\n        if (offset > s.length) throw new Error(\"IndexSizeError\");\n        var head = s.slice(0, offset);\n        var tail = s.slice(offset);\n        this.data = head;\n        var newTextNode = this.ownerDocument.createTextNode(tail);\n        if (this.parentNode) this.parentNode.insertBefore(newTextNode, this.nextSibling);\n        return newTextNode;\n      }\n    });\n    registerWrapper(OriginalText, Text, document.createTextNode(\"\"));\n    scope.wrappers.Text = Text;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    if (!window.DOMTokenList) {\n      console.warn(\"Missing DOMTokenList prototype, please include a \" + \"compatible classList polyfill such as http://goo.gl/uTcepH.\");\n      return;\n    }\n    var unsafeUnwrap = scope.unsafeUnwrap;\n    var enqueueMutation = scope.enqueueMutation;\n    function getClass(el) {\n      return unsafeUnwrap(el).getAttribute(\"class\");\n    }\n    function enqueueClassAttributeChange(el, oldValue) {\n      enqueueMutation(el, \"attributes\", {\n        name: \"class\",\n        namespace: null,\n        oldValue: oldValue\n      });\n    }\n    function invalidateClass(el) {\n      scope.invalidateRendererBasedOnAttribute(el, \"class\");\n    }\n    function changeClass(tokenList, method, args) {\n      var ownerElement = tokenList.ownerElement_;\n      if (ownerElement == null) {\n        return method.apply(tokenList, args);\n      }\n      var oldValue = getClass(ownerElement);\n      var retv = method.apply(tokenList, args);\n      if (getClass(ownerElement) !== oldValue) {\n        enqueueClassAttributeChange(ownerElement, oldValue);\n        invalidateClass(ownerElement);\n      }\n      return retv;\n    }\n    var oldAdd = DOMTokenList.prototype.add;\n    DOMTokenList.prototype.add = function() {\n      changeClass(this, oldAdd, arguments);\n    };\n    var oldRemove = DOMTokenList.prototype.remove;\n    DOMTokenList.prototype.remove = function() {\n      changeClass(this, oldRemove, arguments);\n    };\n    var oldToggle = DOMTokenList.prototype.toggle;\n    DOMTokenList.prototype.toggle = function() {\n      return changeClass(this, oldToggle, arguments);\n    };\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var ChildNodeInterface = scope.ChildNodeInterface;\n    var GetElementsByInterface = scope.GetElementsByInterface;\n    var Node = scope.wrappers.Node;\n    var ParentNodeInterface = scope.ParentNodeInterface;\n    var SelectorsInterface = scope.SelectorsInterface;\n    var MatchesInterface = scope.MatchesInterface;\n    var addWrapNodeListMethod = scope.addWrapNodeListMethod;\n    var enqueueMutation = scope.enqueueMutation;\n    var mixin = scope.mixin;\n    var oneOf = scope.oneOf;\n    var registerWrapper = scope.registerWrapper;\n    var unsafeUnwrap = scope.unsafeUnwrap;\n    var wrappers = scope.wrappers;\n    var OriginalElement = window.Element;\n    var matchesNames = [ \"matches\", \"mozMatchesSelector\", \"msMatchesSelector\", \"webkitMatchesSelector\" ].filter(function(name) {\n      return OriginalElement.prototype[name];\n    });\n    var matchesName = matchesNames[0];\n    var originalMatches = OriginalElement.prototype[matchesName];\n    function invalidateRendererBasedOnAttribute(element, name) {\n      var p = element.parentNode;\n      if (!p || !p.shadowRoot) return;\n      var renderer = scope.getRendererForHost(p);\n      if (renderer.dependsOnAttribute(name)) renderer.invalidate();\n    }\n    function enqueAttributeChange(element, name, oldValue) {\n      enqueueMutation(element, \"attributes\", {\n        name: name,\n        namespace: null,\n        oldValue: oldValue\n      });\n    }\n    var classListTable = new WeakMap();\n    function Element(node) {\n      Node.call(this, node);\n    }\n    Element.prototype = Object.create(Node.prototype);\n    mixin(Element.prototype, {\n      createShadowRoot: function() {\n        var newShadowRoot = new wrappers.ShadowRoot(this);\n        unsafeUnwrap(this).polymerShadowRoot_ = newShadowRoot;\n        var renderer = scope.getRendererForHost(this);\n        renderer.invalidate();\n        return newShadowRoot;\n      },\n      get shadowRoot() {\n        return unsafeUnwrap(this).polymerShadowRoot_ || null;\n      },\n      setAttribute: function(name, value) {\n        var oldValue = unsafeUnwrap(this).getAttribute(name);\n        unsafeUnwrap(this).setAttribute(name, value);\n        enqueAttributeChange(this, name, oldValue);\n        invalidateRendererBasedOnAttribute(this, name);\n      },\n      removeAttribute: function(name) {\n        var oldValue = unsafeUnwrap(this).getAttribute(name);\n        unsafeUnwrap(this).removeAttribute(name);\n        enqueAttributeChange(this, name, oldValue);\n        invalidateRendererBasedOnAttribute(this, name);\n      },\n      get classList() {\n        var list = classListTable.get(this);\n        if (!list) {\n          list = unsafeUnwrap(this).classList;\n          if (!list) return;\n          list.ownerElement_ = this;\n          classListTable.set(this, list);\n        }\n        return list;\n      },\n      get className() {\n        return unsafeUnwrap(this).className;\n      },\n      set className(v) {\n        this.setAttribute(\"class\", v);\n      },\n      get id() {\n        return unsafeUnwrap(this).id;\n      },\n      set id(v) {\n        this.setAttribute(\"id\", v);\n      }\n    });\n    matchesNames.forEach(function(name) {\n      if (name !== \"matches\") {\n        Element.prototype[name] = function(selector) {\n          return this.matches(selector);\n        };\n      }\n    });\n    if (OriginalElement.prototype.webkitCreateShadowRoot) {\n      Element.prototype.webkitCreateShadowRoot = Element.prototype.createShadowRoot;\n    }\n    mixin(Element.prototype, ChildNodeInterface);\n    mixin(Element.prototype, GetElementsByInterface);\n    mixin(Element.prototype, ParentNodeInterface);\n    mixin(Element.prototype, SelectorsInterface);\n    mixin(Element.prototype, MatchesInterface);\n    registerWrapper(OriginalElement, Element, document.createElementNS(null, \"x\"));\n    scope.invalidateRendererBasedOnAttribute = invalidateRendererBasedOnAttribute;\n    scope.matchesNames = matchesNames;\n    scope.originalMatches = originalMatches;\n    scope.wrappers.Element = Element;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var Element = scope.wrappers.Element;\n    var defineGetter = scope.defineGetter;\n    var enqueueMutation = scope.enqueueMutation;\n    var mixin = scope.mixin;\n    var nodesWereAdded = scope.nodesWereAdded;\n    var nodesWereRemoved = scope.nodesWereRemoved;\n    var registerWrapper = scope.registerWrapper;\n    var snapshotNodeList = scope.snapshotNodeList;\n    var unsafeUnwrap = scope.unsafeUnwrap;\n    var unwrap = scope.unwrap;\n    var wrap = scope.wrap;\n    var wrappers = scope.wrappers;\n    var escapeAttrRegExp = /[&\\u00A0\"]/g;\n    var escapeDataRegExp = /[&\\u00A0<>]/g;\n    function escapeReplace(c) {\n      switch (c) {\n       case \"&\":\n        return \"&amp;\";\n\n       case \"<\":\n        return \"&lt;\";\n\n       case \">\":\n        return \"&gt;\";\n\n       case '\"':\n        return \"&quot;\";\n\n       case \" \":\n        return \"&nbsp;\";\n      }\n    }\n    function escapeAttr(s) {\n      return s.replace(escapeAttrRegExp, escapeReplace);\n    }\n    function escapeData(s) {\n      return s.replace(escapeDataRegExp, escapeReplace);\n    }\n    function makeSet(arr) {\n      var set = {};\n      for (var i = 0; i < arr.length; i++) {\n        set[arr[i]] = true;\n      }\n      return set;\n    }\n    var voidElements = makeSet([ \"area\", \"base\", \"br\", \"col\", \"command\", \"embed\", \"hr\", \"img\", \"input\", \"keygen\", \"link\", \"meta\", \"param\", \"source\", \"track\", \"wbr\" ]);\n    var plaintextParents = makeSet([ \"style\", \"script\", \"xmp\", \"iframe\", \"noembed\", \"noframes\", \"plaintext\", \"noscript\" ]);\n    var XHTML_NS = \"http://www.w3.org/1999/xhtml\";\n    function needsSelfClosingSlash(node) {\n      if (node.namespaceURI !== XHTML_NS) return true;\n      var doctype = node.ownerDocument.doctype;\n      return doctype && doctype.publicId && doctype.systemId;\n    }\n    function getOuterHTML(node, parentNode) {\n      switch (node.nodeType) {\n       case Node.ELEMENT_NODE:\n        var tagName = node.tagName.toLowerCase();\n        var s = \"<\" + tagName;\n        var attrs = node.attributes;\n        for (var i = 0, attr; attr = attrs[i]; i++) {\n          s += \" \" + attr.name + '=\"' + escapeAttr(attr.value) + '\"';\n        }\n        if (voidElements[tagName]) {\n          if (needsSelfClosingSlash(node)) s += \"/\";\n          return s + \">\";\n        }\n        return s + \">\" + getInnerHTML(node) + \"</\" + tagName + \">\";\n\n       case Node.TEXT_NODE:\n        var data = node.data;\n        if (parentNode && plaintextParents[parentNode.localName]) return data;\n        return escapeData(data);\n\n       case Node.COMMENT_NODE:\n        return \"<!--\" + node.data + \"-->\";\n\n       default:\n        console.error(node);\n        throw new Error(\"not implemented\");\n      }\n    }\n    function getInnerHTML(node) {\n      if (node instanceof wrappers.HTMLTemplateElement) node = node.content;\n      var s = \"\";\n      for (var child = node.firstChild; child; child = child.nextSibling) {\n        s += getOuterHTML(child, node);\n      }\n      return s;\n    }\n    function setInnerHTML(node, value, opt_tagName) {\n      var tagName = opt_tagName || \"div\";\n      node.textContent = \"\";\n      var tempElement = unwrap(node.ownerDocument.createElement(tagName));\n      tempElement.innerHTML = value;\n      var firstChild;\n      while (firstChild = tempElement.firstChild) {\n        node.appendChild(wrap(firstChild));\n      }\n    }\n    var oldIe = /MSIE/.test(navigator.userAgent);\n    var OriginalHTMLElement = window.HTMLElement;\n    var OriginalHTMLTemplateElement = window.HTMLTemplateElement;\n    function HTMLElement(node) {\n      Element.call(this, node);\n    }\n    HTMLElement.prototype = Object.create(Element.prototype);\n    mixin(HTMLElement.prototype, {\n      get innerHTML() {\n        return getInnerHTML(this);\n      },\n      set innerHTML(value) {\n        if (oldIe && plaintextParents[this.localName]) {\n          this.textContent = value;\n          return;\n        }\n        var removedNodes = snapshotNodeList(this.childNodes);\n        if (this.invalidateShadowRenderer()) {\n          if (this instanceof wrappers.HTMLTemplateElement) setInnerHTML(this.content, value); else setInnerHTML(this, value, this.tagName);\n        } else if (!OriginalHTMLTemplateElement && this instanceof wrappers.HTMLTemplateElement) {\n          setInnerHTML(this.content, value);\n        } else {\n          unsafeUnwrap(this).innerHTML = value;\n        }\n        var addedNodes = snapshotNodeList(this.childNodes);\n        enqueueMutation(this, \"childList\", {\n          addedNodes: addedNodes,\n          removedNodes: removedNodes\n        });\n        nodesWereRemoved(removedNodes);\n        nodesWereAdded(addedNodes, this);\n      },\n      get outerHTML() {\n        return getOuterHTML(this, this.parentNode);\n      },\n      set outerHTML(value) {\n        var p = this.parentNode;\n        if (p) {\n          p.invalidateShadowRenderer();\n          var df = frag(p, value);\n          p.replaceChild(df, this);\n        }\n      },\n      insertAdjacentHTML: function(position, text) {\n        var contextElement, refNode;\n        switch (String(position).toLowerCase()) {\n         case \"beforebegin\":\n          contextElement = this.parentNode;\n          refNode = this;\n          break;\n\n         case \"afterend\":\n          contextElement = this.parentNode;\n          refNode = this.nextSibling;\n          break;\n\n         case \"afterbegin\":\n          contextElement = this;\n          refNode = this.firstChild;\n          break;\n\n         case \"beforeend\":\n          contextElement = this;\n          refNode = null;\n          break;\n\n         default:\n          return;\n        }\n        var df = frag(contextElement, text);\n        contextElement.insertBefore(df, refNode);\n      },\n      get hidden() {\n        return this.hasAttribute(\"hidden\");\n      },\n      set hidden(v) {\n        if (v) {\n          this.setAttribute(\"hidden\", \"\");\n        } else {\n          this.removeAttribute(\"hidden\");\n        }\n      }\n    });\n    function frag(contextElement, html) {\n      var p = unwrap(contextElement.cloneNode(false));\n      p.innerHTML = html;\n      var df = unwrap(document.createDocumentFragment());\n      var c;\n      while (c = p.firstChild) {\n        df.appendChild(c);\n      }\n      return wrap(df);\n    }\n    function getter(name) {\n      return function() {\n        scope.renderAllPending();\n        return unsafeUnwrap(this)[name];\n      };\n    }\n    function getterRequiresRendering(name) {\n      defineGetter(HTMLElement, name, getter(name));\n    }\n    [ \"clientHeight\", \"clientLeft\", \"clientTop\", \"clientWidth\", \"offsetHeight\", \"offsetLeft\", \"offsetTop\", \"offsetWidth\", \"scrollHeight\", \"scrollWidth\" ].forEach(getterRequiresRendering);\n    function getterAndSetterRequiresRendering(name) {\n      Object.defineProperty(HTMLElement.prototype, name, {\n        get: getter(name),\n        set: function(v) {\n          scope.renderAllPending();\n          unsafeUnwrap(this)[name] = v;\n        },\n        configurable: true,\n        enumerable: true\n      });\n    }\n    [ \"scrollLeft\", \"scrollTop\" ].forEach(getterAndSetterRequiresRendering);\n    function methodRequiresRendering(name) {\n      Object.defineProperty(HTMLElement.prototype, name, {\n        value: function() {\n          scope.renderAllPending();\n          return unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments);\n        },\n        configurable: true,\n        enumerable: true\n      });\n    }\n    [ \"getBoundingClientRect\", \"getClientRects\", \"scrollIntoView\" ].forEach(methodRequiresRendering);\n    registerWrapper(OriginalHTMLElement, HTMLElement, document.createElement(\"b\"));\n    scope.wrappers.HTMLElement = HTMLElement;\n    scope.getInnerHTML = getInnerHTML;\n    scope.setInnerHTML = setInnerHTML;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var HTMLElement = scope.wrappers.HTMLElement;\n    var mixin = scope.mixin;\n    var registerWrapper = scope.registerWrapper;\n    var unsafeUnwrap = scope.unsafeUnwrap;\n    var wrap = scope.wrap;\n    var OriginalHTMLCanvasElement = window.HTMLCanvasElement;\n    function HTMLCanvasElement(node) {\n      HTMLElement.call(this, node);\n    }\n    HTMLCanvasElement.prototype = Object.create(HTMLElement.prototype);\n    mixin(HTMLCanvasElement.prototype, {\n      getContext: function() {\n        var context = unsafeUnwrap(this).getContext.apply(unsafeUnwrap(this), arguments);\n        return context && wrap(context);\n      }\n    });\n    registerWrapper(OriginalHTMLCanvasElement, HTMLCanvasElement, document.createElement(\"canvas\"));\n    scope.wrappers.HTMLCanvasElement = HTMLCanvasElement;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var HTMLElement = scope.wrappers.HTMLElement;\n    var mixin = scope.mixin;\n    var registerWrapper = scope.registerWrapper;\n    var OriginalHTMLContentElement = window.HTMLContentElement;\n    function HTMLContentElement(node) {\n      HTMLElement.call(this, node);\n    }\n    HTMLContentElement.prototype = Object.create(HTMLElement.prototype);\n    mixin(HTMLContentElement.prototype, {\n      constructor: HTMLContentElement,\n      get select() {\n        return this.getAttribute(\"select\");\n      },\n      set select(value) {\n        this.setAttribute(\"select\", value);\n      },\n      setAttribute: function(n, v) {\n        HTMLElement.prototype.setAttribute.call(this, n, v);\n        if (String(n).toLowerCase() === \"select\") this.invalidateShadowRenderer(true);\n      }\n    });\n    if (OriginalHTMLContentElement) registerWrapper(OriginalHTMLContentElement, HTMLContentElement);\n    scope.wrappers.HTMLContentElement = HTMLContentElement;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var HTMLElement = scope.wrappers.HTMLElement;\n    var mixin = scope.mixin;\n    var registerWrapper = scope.registerWrapper;\n    var wrapHTMLCollection = scope.wrapHTMLCollection;\n    var unwrap = scope.unwrap;\n    var OriginalHTMLFormElement = window.HTMLFormElement;\n    function HTMLFormElement(node) {\n      HTMLElement.call(this, node);\n    }\n    HTMLFormElement.prototype = Object.create(HTMLElement.prototype);\n    mixin(HTMLFormElement.prototype, {\n      get elements() {\n        return wrapHTMLCollection(unwrap(this).elements);\n      }\n    });\n    registerWrapper(OriginalHTMLFormElement, HTMLFormElement, document.createElement(\"form\"));\n    scope.wrappers.HTMLFormElement = HTMLFormElement;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var HTMLElement = scope.wrappers.HTMLElement;\n    var registerWrapper = scope.registerWrapper;\n    var unwrap = scope.unwrap;\n    var rewrap = scope.rewrap;\n    var OriginalHTMLImageElement = window.HTMLImageElement;\n    function HTMLImageElement(node) {\n      HTMLElement.call(this, node);\n    }\n    HTMLImageElement.prototype = Object.create(HTMLElement.prototype);\n    registerWrapper(OriginalHTMLImageElement, HTMLImageElement, document.createElement(\"img\"));\n    function Image(width, height) {\n      if (!(this instanceof Image)) {\n        throw new TypeError(\"DOM object constructor cannot be called as a function.\");\n      }\n      var node = unwrap(document.createElement(\"img\"));\n      HTMLElement.call(this, node);\n      rewrap(node, this);\n      if (width !== undefined) node.width = width;\n      if (height !== undefined) node.height = height;\n    }\n    Image.prototype = HTMLImageElement.prototype;\n    scope.wrappers.HTMLImageElement = HTMLImageElement;\n    scope.wrappers.Image = Image;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var HTMLElement = scope.wrappers.HTMLElement;\n    var mixin = scope.mixin;\n    var NodeList = scope.wrappers.NodeList;\n    var registerWrapper = scope.registerWrapper;\n    var OriginalHTMLShadowElement = window.HTMLShadowElement;\n    function HTMLShadowElement(node) {\n      HTMLElement.call(this, node);\n    }\n    HTMLShadowElement.prototype = Object.create(HTMLElement.prototype);\n    HTMLShadowElement.prototype.constructor = HTMLShadowElement;\n    if (OriginalHTMLShadowElement) registerWrapper(OriginalHTMLShadowElement, HTMLShadowElement);\n    scope.wrappers.HTMLShadowElement = HTMLShadowElement;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var HTMLElement = scope.wrappers.HTMLElement;\n    var mixin = scope.mixin;\n    var registerWrapper = scope.registerWrapper;\n    var unsafeUnwrap = scope.unsafeUnwrap;\n    var unwrap = scope.unwrap;\n    var wrap = scope.wrap;\n    var contentTable = new WeakMap();\n    var templateContentsOwnerTable = new WeakMap();\n    function getTemplateContentsOwner(doc) {\n      if (!doc.defaultView) return doc;\n      var d = templateContentsOwnerTable.get(doc);\n      if (!d) {\n        d = doc.implementation.createHTMLDocument(\"\");\n        while (d.lastChild) {\n          d.removeChild(d.lastChild);\n        }\n        templateContentsOwnerTable.set(doc, d);\n      }\n      return d;\n    }\n    function extractContent(templateElement) {\n      var doc = getTemplateContentsOwner(templateElement.ownerDocument);\n      var df = unwrap(doc.createDocumentFragment());\n      var child;\n      while (child = templateElement.firstChild) {\n        df.appendChild(child);\n      }\n      return df;\n    }\n    var OriginalHTMLTemplateElement = window.HTMLTemplateElement;\n    function HTMLTemplateElement(node) {\n      HTMLElement.call(this, node);\n      if (!OriginalHTMLTemplateElement) {\n        var content = extractContent(node);\n        contentTable.set(this, wrap(content));\n      }\n    }\n    HTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);\n    mixin(HTMLTemplateElement.prototype, {\n      constructor: HTMLTemplateElement,\n      get content() {\n        if (OriginalHTMLTemplateElement) return wrap(unsafeUnwrap(this).content);\n        return contentTable.get(this);\n      }\n    });\n    if (OriginalHTMLTemplateElement) registerWrapper(OriginalHTMLTemplateElement, HTMLTemplateElement);\n    scope.wrappers.HTMLTemplateElement = HTMLTemplateElement;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var HTMLElement = scope.wrappers.HTMLElement;\n    var registerWrapper = scope.registerWrapper;\n    var OriginalHTMLMediaElement = window.HTMLMediaElement;\n    if (!OriginalHTMLMediaElement) return;\n    function HTMLMediaElement(node) {\n      HTMLElement.call(this, node);\n    }\n    HTMLMediaElement.prototype = Object.create(HTMLElement.prototype);\n    registerWrapper(OriginalHTMLMediaElement, HTMLMediaElement, document.createElement(\"audio\"));\n    scope.wrappers.HTMLMediaElement = HTMLMediaElement;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var HTMLMediaElement = scope.wrappers.HTMLMediaElement;\n    var registerWrapper = scope.registerWrapper;\n    var unwrap = scope.unwrap;\n    var rewrap = scope.rewrap;\n    var OriginalHTMLAudioElement = window.HTMLAudioElement;\n    if (!OriginalHTMLAudioElement) return;\n    function HTMLAudioElement(node) {\n      HTMLMediaElement.call(this, node);\n    }\n    HTMLAudioElement.prototype = Object.create(HTMLMediaElement.prototype);\n    registerWrapper(OriginalHTMLAudioElement, HTMLAudioElement, document.createElement(\"audio\"));\n    function Audio(src) {\n      if (!(this instanceof Audio)) {\n        throw new TypeError(\"DOM object constructor cannot be called as a function.\");\n      }\n      var node = unwrap(document.createElement(\"audio\"));\n      HTMLMediaElement.call(this, node);\n      rewrap(node, this);\n      node.setAttribute(\"preload\", \"auto\");\n      if (src !== undefined) node.setAttribute(\"src\", src);\n    }\n    Audio.prototype = HTMLAudioElement.prototype;\n    scope.wrappers.HTMLAudioElement = HTMLAudioElement;\n    scope.wrappers.Audio = Audio;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var HTMLElement = scope.wrappers.HTMLElement;\n    var mixin = scope.mixin;\n    var registerWrapper = scope.registerWrapper;\n    var rewrap = scope.rewrap;\n    var unwrap = scope.unwrap;\n    var wrap = scope.wrap;\n    var OriginalHTMLOptionElement = window.HTMLOptionElement;\n    function trimText(s) {\n      return s.replace(/\\s+/g, \" \").trim();\n    }\n    function HTMLOptionElement(node) {\n      HTMLElement.call(this, node);\n    }\n    HTMLOptionElement.prototype = Object.create(HTMLElement.prototype);\n    mixin(HTMLOptionElement.prototype, {\n      get text() {\n        return trimText(this.textContent);\n      },\n      set text(value) {\n        this.textContent = trimText(String(value));\n      },\n      get form() {\n        return wrap(unwrap(this).form);\n      }\n    });\n    registerWrapper(OriginalHTMLOptionElement, HTMLOptionElement, document.createElement(\"option\"));\n    function Option(text, value, defaultSelected, selected) {\n      if (!(this instanceof Option)) {\n        throw new TypeError(\"DOM object constructor cannot be called as a function.\");\n      }\n      var node = unwrap(document.createElement(\"option\"));\n      HTMLElement.call(this, node);\n      rewrap(node, this);\n      if (text !== undefined) node.text = text;\n      if (value !== undefined) node.setAttribute(\"value\", value);\n      if (defaultSelected === true) node.setAttribute(\"selected\", \"\");\n      node.selected = selected === true;\n    }\n    Option.prototype = HTMLOptionElement.prototype;\n    scope.wrappers.HTMLOptionElement = HTMLOptionElement;\n    scope.wrappers.Option = Option;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var HTMLElement = scope.wrappers.HTMLElement;\n    var mixin = scope.mixin;\n    var registerWrapper = scope.registerWrapper;\n    var unwrap = scope.unwrap;\n    var wrap = scope.wrap;\n    var OriginalHTMLSelectElement = window.HTMLSelectElement;\n    function HTMLSelectElement(node) {\n      HTMLElement.call(this, node);\n    }\n    HTMLSelectElement.prototype = Object.create(HTMLElement.prototype);\n    mixin(HTMLSelectElement.prototype, {\n      add: function(element, before) {\n        if (typeof before === \"object\") before = unwrap(before);\n        unwrap(this).add(unwrap(element), before);\n      },\n      remove: function(indexOrNode) {\n        if (indexOrNode === undefined) {\n          HTMLElement.prototype.remove.call(this);\n          return;\n        }\n        if (typeof indexOrNode === \"object\") indexOrNode = unwrap(indexOrNode);\n        unwrap(this).remove(indexOrNode);\n      },\n      get form() {\n        return wrap(unwrap(this).form);\n      }\n    });\n    registerWrapper(OriginalHTMLSelectElement, HTMLSelectElement, document.createElement(\"select\"));\n    scope.wrappers.HTMLSelectElement = HTMLSelectElement;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var HTMLElement = scope.wrappers.HTMLElement;\n    var mixin = scope.mixin;\n    var registerWrapper = scope.registerWrapper;\n    var unwrap = scope.unwrap;\n    var wrap = scope.wrap;\n    var wrapHTMLCollection = scope.wrapHTMLCollection;\n    var OriginalHTMLTableElement = window.HTMLTableElement;\n    function HTMLTableElement(node) {\n      HTMLElement.call(this, node);\n    }\n    HTMLTableElement.prototype = Object.create(HTMLElement.prototype);\n    mixin(HTMLTableElement.prototype, {\n      get caption() {\n        return wrap(unwrap(this).caption);\n      },\n      createCaption: function() {\n        return wrap(unwrap(this).createCaption());\n      },\n      get tHead() {\n        return wrap(unwrap(this).tHead);\n      },\n      createTHead: function() {\n        return wrap(unwrap(this).createTHead());\n      },\n      createTFoot: function() {\n        return wrap(unwrap(this).createTFoot());\n      },\n      get tFoot() {\n        return wrap(unwrap(this).tFoot);\n      },\n      get tBodies() {\n        return wrapHTMLCollection(unwrap(this).tBodies);\n      },\n      createTBody: function() {\n        return wrap(unwrap(this).createTBody());\n      },\n      get rows() {\n        return wrapHTMLCollection(unwrap(this).rows);\n      },\n      insertRow: function(index) {\n        return wrap(unwrap(this).insertRow(index));\n      }\n    });\n    registerWrapper(OriginalHTMLTableElement, HTMLTableElement, document.createElement(\"table\"));\n    scope.wrappers.HTMLTableElement = HTMLTableElement;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var HTMLElement = scope.wrappers.HTMLElement;\n    var mixin = scope.mixin;\n    var registerWrapper = scope.registerWrapper;\n    var wrapHTMLCollection = scope.wrapHTMLCollection;\n    var unwrap = scope.unwrap;\n    var wrap = scope.wrap;\n    var OriginalHTMLTableSectionElement = window.HTMLTableSectionElement;\n    function HTMLTableSectionElement(node) {\n      HTMLElement.call(this, node);\n    }\n    HTMLTableSectionElement.prototype = Object.create(HTMLElement.prototype);\n    mixin(HTMLTableSectionElement.prototype, {\n      constructor: HTMLTableSectionElement,\n      get rows() {\n        return wrapHTMLCollection(unwrap(this).rows);\n      },\n      insertRow: function(index) {\n        return wrap(unwrap(this).insertRow(index));\n      }\n    });\n    registerWrapper(OriginalHTMLTableSectionElement, HTMLTableSectionElement, document.createElement(\"thead\"));\n    scope.wrappers.HTMLTableSectionElement = HTMLTableSectionElement;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var HTMLElement = scope.wrappers.HTMLElement;\n    var mixin = scope.mixin;\n    var registerWrapper = scope.registerWrapper;\n    var wrapHTMLCollection = scope.wrapHTMLCollection;\n    var unwrap = scope.unwrap;\n    var wrap = scope.wrap;\n    var OriginalHTMLTableRowElement = window.HTMLTableRowElement;\n    function HTMLTableRowElement(node) {\n      HTMLElement.call(this, node);\n    }\n    HTMLTableRowElement.prototype = Object.create(HTMLElement.prototype);\n    mixin(HTMLTableRowElement.prototype, {\n      get cells() {\n        return wrapHTMLCollection(unwrap(this).cells);\n      },\n      insertCell: function(index) {\n        return wrap(unwrap(this).insertCell(index));\n      }\n    });\n    registerWrapper(OriginalHTMLTableRowElement, HTMLTableRowElement, document.createElement(\"tr\"));\n    scope.wrappers.HTMLTableRowElement = HTMLTableRowElement;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var HTMLContentElement = scope.wrappers.HTMLContentElement;\n    var HTMLElement = scope.wrappers.HTMLElement;\n    var HTMLShadowElement = scope.wrappers.HTMLShadowElement;\n    var HTMLTemplateElement = scope.wrappers.HTMLTemplateElement;\n    var mixin = scope.mixin;\n    var registerWrapper = scope.registerWrapper;\n    var OriginalHTMLUnknownElement = window.HTMLUnknownElement;\n    function HTMLUnknownElement(node) {\n      switch (node.localName) {\n       case \"content\":\n        return new HTMLContentElement(node);\n\n       case \"shadow\":\n        return new HTMLShadowElement(node);\n\n       case \"template\":\n        return new HTMLTemplateElement(node);\n      }\n      HTMLElement.call(this, node);\n    }\n    HTMLUnknownElement.prototype = Object.create(HTMLElement.prototype);\n    registerWrapper(OriginalHTMLUnknownElement, HTMLUnknownElement);\n    scope.wrappers.HTMLUnknownElement = HTMLUnknownElement;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var Element = scope.wrappers.Element;\n    var HTMLElement = scope.wrappers.HTMLElement;\n    var registerObject = scope.registerObject;\n    var defineWrapGetter = scope.defineWrapGetter;\n    var SVG_NS = \"http://www.w3.org/2000/svg\";\n    var svgTitleElement = document.createElementNS(SVG_NS, \"title\");\n    var SVGTitleElement = registerObject(svgTitleElement);\n    var SVGElement = Object.getPrototypeOf(SVGTitleElement.prototype).constructor;\n    if (!(\"classList\" in svgTitleElement)) {\n      var descr = Object.getOwnPropertyDescriptor(Element.prototype, \"classList\");\n      Object.defineProperty(HTMLElement.prototype, \"classList\", descr);\n      delete Element.prototype.classList;\n    }\n    defineWrapGetter(SVGElement, \"ownerSVGElement\");\n    scope.wrappers.SVGElement = SVGElement;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var mixin = scope.mixin;\n    var registerWrapper = scope.registerWrapper;\n    var unwrap = scope.unwrap;\n    var wrap = scope.wrap;\n    var OriginalSVGUseElement = window.SVGUseElement;\n    var SVG_NS = \"http://www.w3.org/2000/svg\";\n    var gWrapper = wrap(document.createElementNS(SVG_NS, \"g\"));\n    var useElement = document.createElementNS(SVG_NS, \"use\");\n    var SVGGElement = gWrapper.constructor;\n    var parentInterfacePrototype = Object.getPrototypeOf(SVGGElement.prototype);\n    var parentInterface = parentInterfacePrototype.constructor;\n    function SVGUseElement(impl) {\n      parentInterface.call(this, impl);\n    }\n    SVGUseElement.prototype = Object.create(parentInterfacePrototype);\n    if (\"instanceRoot\" in useElement) {\n      mixin(SVGUseElement.prototype, {\n        get instanceRoot() {\n          return wrap(unwrap(this).instanceRoot);\n        },\n        get animatedInstanceRoot() {\n          return wrap(unwrap(this).animatedInstanceRoot);\n        }\n      });\n    }\n    registerWrapper(OriginalSVGUseElement, SVGUseElement, useElement);\n    scope.wrappers.SVGUseElement = SVGUseElement;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var EventTarget = scope.wrappers.EventTarget;\n    var mixin = scope.mixin;\n    var registerWrapper = scope.registerWrapper;\n    var unsafeUnwrap = scope.unsafeUnwrap;\n    var wrap = scope.wrap;\n    var OriginalSVGElementInstance = window.SVGElementInstance;\n    if (!OriginalSVGElementInstance) return;\n    function SVGElementInstance(impl) {\n      EventTarget.call(this, impl);\n    }\n    SVGElementInstance.prototype = Object.create(EventTarget.prototype);\n    mixin(SVGElementInstance.prototype, {\n      get correspondingElement() {\n        return wrap(unsafeUnwrap(this).correspondingElement);\n      },\n      get correspondingUseElement() {\n        return wrap(unsafeUnwrap(this).correspondingUseElement);\n      },\n      get parentNode() {\n        return wrap(unsafeUnwrap(this).parentNode);\n      },\n      get childNodes() {\n        throw new Error(\"Not implemented\");\n      },\n      get firstChild() {\n        return wrap(unsafeUnwrap(this).firstChild);\n      },\n      get lastChild() {\n        return wrap(unsafeUnwrap(this).lastChild);\n      },\n      get previousSibling() {\n        return wrap(unsafeUnwrap(this).previousSibling);\n      },\n      get nextSibling() {\n        return wrap(unsafeUnwrap(this).nextSibling);\n      }\n    });\n    registerWrapper(OriginalSVGElementInstance, SVGElementInstance);\n    scope.wrappers.SVGElementInstance = SVGElementInstance;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var mixin = scope.mixin;\n    var registerWrapper = scope.registerWrapper;\n    var setWrapper = scope.setWrapper;\n    var unsafeUnwrap = scope.unsafeUnwrap;\n    var unwrap = scope.unwrap;\n    var unwrapIfNeeded = scope.unwrapIfNeeded;\n    var wrap = scope.wrap;\n    var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;\n    function CanvasRenderingContext2D(impl) {\n      setWrapper(impl, this);\n    }\n    mixin(CanvasRenderingContext2D.prototype, {\n      get canvas() {\n        return wrap(unsafeUnwrap(this).canvas);\n      },\n      drawImage: function() {\n        arguments[0] = unwrapIfNeeded(arguments[0]);\n        unsafeUnwrap(this).drawImage.apply(unsafeUnwrap(this), arguments);\n      },\n      createPattern: function() {\n        arguments[0] = unwrap(arguments[0]);\n        return unsafeUnwrap(this).createPattern.apply(unsafeUnwrap(this), arguments);\n      }\n    });\n    registerWrapper(OriginalCanvasRenderingContext2D, CanvasRenderingContext2D, document.createElement(\"canvas\").getContext(\"2d\"));\n    scope.wrappers.CanvasRenderingContext2D = CanvasRenderingContext2D;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var mixin = scope.mixin;\n    var registerWrapper = scope.registerWrapper;\n    var setWrapper = scope.setWrapper;\n    var unsafeUnwrap = scope.unsafeUnwrap;\n    var unwrapIfNeeded = scope.unwrapIfNeeded;\n    var wrap = scope.wrap;\n    var OriginalWebGLRenderingContext = window.WebGLRenderingContext;\n    if (!OriginalWebGLRenderingContext) return;\n    function WebGLRenderingContext(impl) {\n      setWrapper(impl, this);\n    }\n    mixin(WebGLRenderingContext.prototype, {\n      get canvas() {\n        return wrap(unsafeUnwrap(this).canvas);\n      },\n      texImage2D: function() {\n        arguments[5] = unwrapIfNeeded(arguments[5]);\n        unsafeUnwrap(this).texImage2D.apply(unsafeUnwrap(this), arguments);\n      },\n      texSubImage2D: function() {\n        arguments[6] = unwrapIfNeeded(arguments[6]);\n        unsafeUnwrap(this).texSubImage2D.apply(unsafeUnwrap(this), arguments);\n      }\n    });\n    var instanceProperties = /WebKit/.test(navigator.userAgent) ? {\n      drawingBufferHeight: null,\n      drawingBufferWidth: null\n    } : {};\n    registerWrapper(OriginalWebGLRenderingContext, WebGLRenderingContext, instanceProperties);\n    scope.wrappers.WebGLRenderingContext = WebGLRenderingContext;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var GetElementsByInterface = scope.GetElementsByInterface;\n    var NonElementParentNodeInterface = scope.NonElementParentNodeInterface;\n    var ParentNodeInterface = scope.ParentNodeInterface;\n    var SelectorsInterface = scope.SelectorsInterface;\n    var mixin = scope.mixin;\n    var registerObject = scope.registerObject;\n    var DocumentFragment = registerObject(document.createDocumentFragment());\n    mixin(DocumentFragment.prototype, ParentNodeInterface);\n    mixin(DocumentFragment.prototype, SelectorsInterface);\n    mixin(DocumentFragment.prototype, GetElementsByInterface);\n    mixin(DocumentFragment.prototype, NonElementParentNodeInterface);\n    var Comment = registerObject(document.createComment(\"\"));\n    scope.wrappers.Comment = Comment;\n    scope.wrappers.DocumentFragment = DocumentFragment;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var DocumentFragment = scope.wrappers.DocumentFragment;\n    var TreeScope = scope.TreeScope;\n    var elementFromPoint = scope.elementFromPoint;\n    var getInnerHTML = scope.getInnerHTML;\n    var getTreeScope = scope.getTreeScope;\n    var mixin = scope.mixin;\n    var rewrap = scope.rewrap;\n    var setInnerHTML = scope.setInnerHTML;\n    var unsafeUnwrap = scope.unsafeUnwrap;\n    var unwrap = scope.unwrap;\n    var shadowHostTable = new WeakMap();\n    var nextOlderShadowTreeTable = new WeakMap();\n    function ShadowRoot(hostWrapper) {\n      var node = unwrap(unsafeUnwrap(hostWrapper).ownerDocument.createDocumentFragment());\n      DocumentFragment.call(this, node);\n      rewrap(node, this);\n      var oldShadowRoot = hostWrapper.shadowRoot;\n      nextOlderShadowTreeTable.set(this, oldShadowRoot);\n      this.treeScope_ = new TreeScope(this, getTreeScope(oldShadowRoot || hostWrapper));\n      shadowHostTable.set(this, hostWrapper);\n    }\n    ShadowRoot.prototype = Object.create(DocumentFragment.prototype);\n    mixin(ShadowRoot.prototype, {\n      constructor: ShadowRoot,\n      get innerHTML() {\n        return getInnerHTML(this);\n      },\n      set innerHTML(value) {\n        setInnerHTML(this, value);\n        this.invalidateShadowRenderer();\n      },\n      get olderShadowRoot() {\n        return nextOlderShadowTreeTable.get(this) || null;\n      },\n      get host() {\n        return shadowHostTable.get(this) || null;\n      },\n      invalidateShadowRenderer: function() {\n        return shadowHostTable.get(this).invalidateShadowRenderer();\n      },\n      elementFromPoint: function(x, y) {\n        return elementFromPoint(this, this.ownerDocument, x, y);\n      }\n    });\n    scope.wrappers.ShadowRoot = ShadowRoot;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var registerWrapper = scope.registerWrapper;\n    var setWrapper = scope.setWrapper;\n    var unsafeUnwrap = scope.unsafeUnwrap;\n    var unwrap = scope.unwrap;\n    var unwrapIfNeeded = scope.unwrapIfNeeded;\n    var wrap = scope.wrap;\n    var getTreeScope = scope.getTreeScope;\n    var OriginalRange = window.Range;\n    var ShadowRoot = scope.wrappers.ShadowRoot;\n    function getHost(node) {\n      var root = getTreeScope(node).root;\n      if (root instanceof ShadowRoot) {\n        return root.host;\n      }\n      return null;\n    }\n    function hostNodeToShadowNode(refNode, offset) {\n      if (refNode.shadowRoot) {\n        offset = Math.min(refNode.childNodes.length - 1, offset);\n        var child = refNode.childNodes[offset];\n        if (child) {\n          var insertionPoint = scope.getDestinationInsertionPoints(child);\n          if (insertionPoint.length > 0) {\n            var parentNode = insertionPoint[0].parentNode;\n            if (parentNode.nodeType == Node.ELEMENT_NODE) {\n              refNode = parentNode;\n            }\n          }\n        }\n      }\n      return refNode;\n    }\n    function shadowNodeToHostNode(node) {\n      node = wrap(node);\n      return getHost(node) || node;\n    }\n    function Range(impl) {\n      setWrapper(impl, this);\n    }\n    Range.prototype = {\n      get startContainer() {\n        return shadowNodeToHostNode(unsafeUnwrap(this).startContainer);\n      },\n      get endContainer() {\n        return shadowNodeToHostNode(unsafeUnwrap(this).endContainer);\n      },\n      get commonAncestorContainer() {\n        return shadowNodeToHostNode(unsafeUnwrap(this).commonAncestorContainer);\n      },\n      setStart: function(refNode, offset) {\n        refNode = hostNodeToShadowNode(refNode, offset);\n        unsafeUnwrap(this).setStart(unwrapIfNeeded(refNode), offset);\n      },\n      setEnd: function(refNode, offset) {\n        refNode = hostNodeToShadowNode(refNode, offset);\n        unsafeUnwrap(this).setEnd(unwrapIfNeeded(refNode), offset);\n      },\n      setStartBefore: function(refNode) {\n        unsafeUnwrap(this).setStartBefore(unwrapIfNeeded(refNode));\n      },\n      setStartAfter: function(refNode) {\n        unsafeUnwrap(this).setStartAfter(unwrapIfNeeded(refNode));\n      },\n      setEndBefore: function(refNode) {\n        unsafeUnwrap(this).setEndBefore(unwrapIfNeeded(refNode));\n      },\n      setEndAfter: function(refNode) {\n        unsafeUnwrap(this).setEndAfter(unwrapIfNeeded(refNode));\n      },\n      selectNode: function(refNode) {\n        unsafeUnwrap(this).selectNode(unwrapIfNeeded(refNode));\n      },\n      selectNodeContents: function(refNode) {\n        unsafeUnwrap(this).selectNodeContents(unwrapIfNeeded(refNode));\n      },\n      compareBoundaryPoints: function(how, sourceRange) {\n        return unsafeUnwrap(this).compareBoundaryPoints(how, unwrap(sourceRange));\n      },\n      extractContents: function() {\n        return wrap(unsafeUnwrap(this).extractContents());\n      },\n      cloneContents: function() {\n        return wrap(unsafeUnwrap(this).cloneContents());\n      },\n      insertNode: function(node) {\n        unsafeUnwrap(this).insertNode(unwrapIfNeeded(node));\n      },\n      surroundContents: function(newParent) {\n        unsafeUnwrap(this).surroundContents(unwrapIfNeeded(newParent));\n      },\n      cloneRange: function() {\n        return wrap(unsafeUnwrap(this).cloneRange());\n      },\n      isPointInRange: function(node, offset) {\n        return unsafeUnwrap(this).isPointInRange(unwrapIfNeeded(node), offset);\n      },\n      comparePoint: function(node, offset) {\n        return unsafeUnwrap(this).comparePoint(unwrapIfNeeded(node), offset);\n      },\n      intersectsNode: function(node) {\n        return unsafeUnwrap(this).intersectsNode(unwrapIfNeeded(node));\n      },\n      toString: function() {\n        return unsafeUnwrap(this).toString();\n      }\n    };\n    if (OriginalRange.prototype.createContextualFragment) {\n      Range.prototype.createContextualFragment = function(html) {\n        return wrap(unsafeUnwrap(this).createContextualFragment(html));\n      };\n    }\n    registerWrapper(window.Range, Range, document.createRange());\n    scope.wrappers.Range = Range;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var Element = scope.wrappers.Element;\n    var HTMLContentElement = scope.wrappers.HTMLContentElement;\n    var HTMLShadowElement = scope.wrappers.HTMLShadowElement;\n    var Node = scope.wrappers.Node;\n    var ShadowRoot = scope.wrappers.ShadowRoot;\n    var assert = scope.assert;\n    var getTreeScope = scope.getTreeScope;\n    var mixin = scope.mixin;\n    var oneOf = scope.oneOf;\n    var unsafeUnwrap = scope.unsafeUnwrap;\n    var unwrap = scope.unwrap;\n    var wrap = scope.wrap;\n    var ArraySplice = scope.ArraySplice;\n    function updateWrapperUpAndSideways(wrapper) {\n      wrapper.previousSibling_ = wrapper.previousSibling;\n      wrapper.nextSibling_ = wrapper.nextSibling;\n      wrapper.parentNode_ = wrapper.parentNode;\n    }\n    function updateWrapperDown(wrapper) {\n      wrapper.firstChild_ = wrapper.firstChild;\n      wrapper.lastChild_ = wrapper.lastChild;\n    }\n    function updateAllChildNodes(parentNodeWrapper) {\n      assert(parentNodeWrapper instanceof Node);\n      for (var childWrapper = parentNodeWrapper.firstChild; childWrapper; childWrapper = childWrapper.nextSibling) {\n        updateWrapperUpAndSideways(childWrapper);\n      }\n      updateWrapperDown(parentNodeWrapper);\n    }\n    function insertBefore(parentNodeWrapper, newChildWrapper, refChildWrapper) {\n      var parentNode = unwrap(parentNodeWrapper);\n      var newChild = unwrap(newChildWrapper);\n      var refChild = refChildWrapper ? unwrap(refChildWrapper) : null;\n      remove(newChildWrapper);\n      updateWrapperUpAndSideways(newChildWrapper);\n      if (!refChildWrapper) {\n        parentNodeWrapper.lastChild_ = parentNodeWrapper.lastChild;\n        if (parentNodeWrapper.lastChild === parentNodeWrapper.firstChild) parentNodeWrapper.firstChild_ = parentNodeWrapper.firstChild;\n        var lastChildWrapper = wrap(parentNode.lastChild);\n        if (lastChildWrapper) lastChildWrapper.nextSibling_ = lastChildWrapper.nextSibling;\n      } else {\n        if (parentNodeWrapper.firstChild === refChildWrapper) parentNodeWrapper.firstChild_ = refChildWrapper;\n        refChildWrapper.previousSibling_ = refChildWrapper.previousSibling;\n      }\n      scope.originalInsertBefore.call(parentNode, newChild, refChild);\n    }\n    function remove(nodeWrapper) {\n      var node = unwrap(nodeWrapper);\n      var parentNode = node.parentNode;\n      if (!parentNode) return;\n      var parentNodeWrapper = wrap(parentNode);\n      updateWrapperUpAndSideways(nodeWrapper);\n      if (nodeWrapper.previousSibling) nodeWrapper.previousSibling.nextSibling_ = nodeWrapper;\n      if (nodeWrapper.nextSibling) nodeWrapper.nextSibling.previousSibling_ = nodeWrapper;\n      if (parentNodeWrapper.lastChild === nodeWrapper) parentNodeWrapper.lastChild_ = nodeWrapper;\n      if (parentNodeWrapper.firstChild === nodeWrapper) parentNodeWrapper.firstChild_ = nodeWrapper;\n      scope.originalRemoveChild.call(parentNode, node);\n    }\n    var distributedNodesTable = new WeakMap();\n    var destinationInsertionPointsTable = new WeakMap();\n    var rendererForHostTable = new WeakMap();\n    function resetDistributedNodes(insertionPoint) {\n      distributedNodesTable.set(insertionPoint, []);\n    }\n    function getDistributedNodes(insertionPoint) {\n      var rv = distributedNodesTable.get(insertionPoint);\n      if (!rv) distributedNodesTable.set(insertionPoint, rv = []);\n      return rv;\n    }\n    function getChildNodesSnapshot(node) {\n      var result = [], i = 0;\n      for (var child = node.firstChild; child; child = child.nextSibling) {\n        result[i++] = child;\n      }\n      return result;\n    }\n    var request = oneOf(window, [ \"requestAnimationFrame\", \"mozRequestAnimationFrame\", \"webkitRequestAnimationFrame\", \"setTimeout\" ]);\n    var pendingDirtyRenderers = [];\n    var renderTimer;\n    function renderAllPending() {\n      for (var i = 0; i < pendingDirtyRenderers.length; i++) {\n        var renderer = pendingDirtyRenderers[i];\n        var parentRenderer = renderer.parentRenderer;\n        if (parentRenderer && parentRenderer.dirty) continue;\n        renderer.render();\n      }\n      pendingDirtyRenderers = [];\n    }\n    function handleRequestAnimationFrame() {\n      renderTimer = null;\n      renderAllPending();\n    }\n    function getRendererForHost(host) {\n      var renderer = rendererForHostTable.get(host);\n      if (!renderer) {\n        renderer = new ShadowRenderer(host);\n        rendererForHostTable.set(host, renderer);\n      }\n      return renderer;\n    }\n    function getShadowRootAncestor(node) {\n      var root = getTreeScope(node).root;\n      if (root instanceof ShadowRoot) return root;\n      return null;\n    }\n    function getRendererForShadowRoot(shadowRoot) {\n      return getRendererForHost(shadowRoot.host);\n    }\n    var spliceDiff = new ArraySplice();\n    spliceDiff.equals = function(renderNode, rawNode) {\n      return unwrap(renderNode.node) === rawNode;\n    };\n    function RenderNode(node) {\n      this.skip = false;\n      this.node = node;\n      this.childNodes = [];\n    }\n    RenderNode.prototype = {\n      append: function(node) {\n        var rv = new RenderNode(node);\n        this.childNodes.push(rv);\n        return rv;\n      },\n      sync: function(opt_added) {\n        if (this.skip) return;\n        var nodeWrapper = this.node;\n        var newChildren = this.childNodes;\n        var oldChildren = getChildNodesSnapshot(unwrap(nodeWrapper));\n        var added = opt_added || new WeakMap();\n        var splices = spliceDiff.calculateSplices(newChildren, oldChildren);\n        var newIndex = 0, oldIndex = 0;\n        var lastIndex = 0;\n        for (var i = 0; i < splices.length; i++) {\n          var splice = splices[i];\n          for (;lastIndex < splice.index; lastIndex++) {\n            oldIndex++;\n            newChildren[newIndex++].sync(added);\n          }\n          var removedCount = splice.removed.length;\n          for (var j = 0; j < removedCount; j++) {\n            var wrapper = wrap(oldChildren[oldIndex++]);\n            if (!added.get(wrapper)) remove(wrapper);\n          }\n          var addedCount = splice.addedCount;\n          var refNode = oldChildren[oldIndex] && wrap(oldChildren[oldIndex]);\n          for (var j = 0; j < addedCount; j++) {\n            var newChildRenderNode = newChildren[newIndex++];\n            var newChildWrapper = newChildRenderNode.node;\n            insertBefore(nodeWrapper, newChildWrapper, refNode);\n            added.set(newChildWrapper, true);\n            newChildRenderNode.sync(added);\n          }\n          lastIndex += addedCount;\n        }\n        for (var i = lastIndex; i < newChildren.length; i++) {\n          newChildren[i].sync(added);\n        }\n      }\n    };\n    function ShadowRenderer(host) {\n      this.host = host;\n      this.dirty = false;\n      this.invalidateAttributes();\n      this.associateNode(host);\n    }\n    ShadowRenderer.prototype = {\n      render: function(opt_renderNode) {\n        if (!this.dirty) return;\n        this.invalidateAttributes();\n        var host = this.host;\n        this.distribution(host);\n        var renderNode = opt_renderNode || new RenderNode(host);\n        this.buildRenderTree(renderNode, host);\n        var topMostRenderer = !opt_renderNode;\n        if (topMostRenderer) renderNode.sync();\n        this.dirty = false;\n      },\n      get parentRenderer() {\n        return getTreeScope(this.host).renderer;\n      },\n      invalidate: function() {\n        if (!this.dirty) {\n          this.dirty = true;\n          var parentRenderer = this.parentRenderer;\n          if (parentRenderer) parentRenderer.invalidate();\n          pendingDirtyRenderers.push(this);\n          if (renderTimer) return;\n          renderTimer = window[request](handleRequestAnimationFrame, 0);\n        }\n      },\n      distribution: function(root) {\n        this.resetAllSubtrees(root);\n        this.distributionResolution(root);\n      },\n      resetAll: function(node) {\n        if (isInsertionPoint(node)) resetDistributedNodes(node); else resetDestinationInsertionPoints(node);\n        this.resetAllSubtrees(node);\n      },\n      resetAllSubtrees: function(node) {\n        for (var child = node.firstChild; child; child = child.nextSibling) {\n          this.resetAll(child);\n        }\n        if (node.shadowRoot) this.resetAll(node.shadowRoot);\n        if (node.olderShadowRoot) this.resetAll(node.olderShadowRoot);\n      },\n      distributionResolution: function(node) {\n        if (isShadowHost(node)) {\n          var shadowHost = node;\n          var pool = poolPopulation(shadowHost);\n          var shadowTrees = getShadowTrees(shadowHost);\n          for (var i = 0; i < shadowTrees.length; i++) {\n            this.poolDistribution(shadowTrees[i], pool);\n          }\n          for (var i = shadowTrees.length - 1; i >= 0; i--) {\n            var shadowTree = shadowTrees[i];\n            var shadow = getShadowInsertionPoint(shadowTree);\n            if (shadow) {\n              var olderShadowRoot = shadowTree.olderShadowRoot;\n              if (olderShadowRoot) {\n                pool = poolPopulation(olderShadowRoot);\n              }\n              for (var j = 0; j < pool.length; j++) {\n                destributeNodeInto(pool[j], shadow);\n              }\n            }\n            this.distributionResolution(shadowTree);\n          }\n        }\n        for (var child = node.firstChild; child; child = child.nextSibling) {\n          this.distributionResolution(child);\n        }\n      },\n      poolDistribution: function(node, pool) {\n        if (node instanceof HTMLShadowElement) return;\n        if (node instanceof HTMLContentElement) {\n          var content = node;\n          this.updateDependentAttributes(content.getAttribute(\"select\"));\n          var anyDistributed = false;\n          for (var i = 0; i < pool.length; i++) {\n            var node = pool[i];\n            if (!node) continue;\n            if (matches(node, content)) {\n              destributeNodeInto(node, content);\n              pool[i] = undefined;\n              anyDistributed = true;\n            }\n          }\n          if (!anyDistributed) {\n            for (var child = content.firstChild; child; child = child.nextSibling) {\n              destributeNodeInto(child, content);\n            }\n          }\n          return;\n        }\n        for (var child = node.firstChild; child; child = child.nextSibling) {\n          this.poolDistribution(child, pool);\n        }\n      },\n      buildRenderTree: function(renderNode, node) {\n        var children = this.compose(node);\n        for (var i = 0; i < children.length; i++) {\n          var child = children[i];\n          var childRenderNode = renderNode.append(child);\n          this.buildRenderTree(childRenderNode, child);\n        }\n        if (isShadowHost(node)) {\n          var renderer = getRendererForHost(node);\n          renderer.dirty = false;\n        }\n      },\n      compose: function(node) {\n        var children = [];\n        var p = node.shadowRoot || node;\n        for (var child = p.firstChild; child; child = child.nextSibling) {\n          if (isInsertionPoint(child)) {\n            this.associateNode(p);\n            var distributedNodes = getDistributedNodes(child);\n            for (var j = 0; j < distributedNodes.length; j++) {\n              var distributedNode = distributedNodes[j];\n              if (isFinalDestination(child, distributedNode)) children.push(distributedNode);\n            }\n          } else {\n            children.push(child);\n          }\n        }\n        return children;\n      },\n      invalidateAttributes: function() {\n        this.attributes = Object.create(null);\n      },\n      updateDependentAttributes: function(selector) {\n        if (!selector) return;\n        var attributes = this.attributes;\n        if (/\\.\\w+/.test(selector)) attributes[\"class\"] = true;\n        if (/#\\w+/.test(selector)) attributes[\"id\"] = true;\n        selector.replace(/\\[\\s*([^\\s=\\|~\\]]+)/g, function(_, name) {\n          attributes[name] = true;\n        });\n      },\n      dependsOnAttribute: function(name) {\n        return this.attributes[name];\n      },\n      associateNode: function(node) {\n        unsafeUnwrap(node).polymerShadowRenderer_ = this;\n      }\n    };\n    function poolPopulation(node) {\n      var pool = [];\n      for (var child = node.firstChild; child; child = child.nextSibling) {\n        if (isInsertionPoint(child)) {\n          pool.push.apply(pool, getDistributedNodes(child));\n        } else {\n          pool.push(child);\n        }\n      }\n      return pool;\n    }\n    function getShadowInsertionPoint(node) {\n      if (node instanceof HTMLShadowElement) return node;\n      if (node instanceof HTMLContentElement) return null;\n      for (var child = node.firstChild; child; child = child.nextSibling) {\n        var res = getShadowInsertionPoint(child);\n        if (res) return res;\n      }\n      return null;\n    }\n    function destributeNodeInto(child, insertionPoint) {\n      getDistributedNodes(insertionPoint).push(child);\n      var points = destinationInsertionPointsTable.get(child);\n      if (!points) destinationInsertionPointsTable.set(child, [ insertionPoint ]); else points.push(insertionPoint);\n    }\n    function getDestinationInsertionPoints(node) {\n      return destinationInsertionPointsTable.get(node);\n    }\n    function resetDestinationInsertionPoints(node) {\n      destinationInsertionPointsTable.set(node, undefined);\n    }\n    var selectorStartCharRe = /^(:not\\()?[*.#[a-zA-Z_|]/;\n    function matches(node, contentElement) {\n      var select = contentElement.getAttribute(\"select\");\n      if (!select) return true;\n      select = select.trim();\n      if (!select) return true;\n      if (!(node instanceof Element)) return false;\n      if (!selectorStartCharRe.test(select)) return false;\n      try {\n        return node.matches(select);\n      } catch (ex) {\n        return false;\n      }\n    }\n    function isFinalDestination(insertionPoint, node) {\n      var points = getDestinationInsertionPoints(node);\n      return points && points[points.length - 1] === insertionPoint;\n    }\n    function isInsertionPoint(node) {\n      return node instanceof HTMLContentElement || node instanceof HTMLShadowElement;\n    }\n    function isShadowHost(shadowHost) {\n      return shadowHost.shadowRoot;\n    }\n    function getShadowTrees(host) {\n      var trees = [];\n      for (var tree = host.shadowRoot; tree; tree = tree.olderShadowRoot) {\n        trees.push(tree);\n      }\n      return trees;\n    }\n    function render(host) {\n      new ShadowRenderer(host).render();\n    }\n    Node.prototype.invalidateShadowRenderer = function(force) {\n      var renderer = unsafeUnwrap(this).polymerShadowRenderer_;\n      if (renderer) {\n        renderer.invalidate();\n        return true;\n      }\n      return false;\n    };\n    HTMLContentElement.prototype.getDistributedNodes = HTMLShadowElement.prototype.getDistributedNodes = function() {\n      renderAllPending();\n      return getDistributedNodes(this);\n    };\n    Element.prototype.getDestinationInsertionPoints = function() {\n      renderAllPending();\n      return getDestinationInsertionPoints(this) || [];\n    };\n    HTMLContentElement.prototype.nodeIsInserted_ = HTMLShadowElement.prototype.nodeIsInserted_ = function() {\n      this.invalidateShadowRenderer();\n      var shadowRoot = getShadowRootAncestor(this);\n      var renderer;\n      if (shadowRoot) renderer = getRendererForShadowRoot(shadowRoot);\n      unsafeUnwrap(this).polymerShadowRenderer_ = renderer;\n      if (renderer) renderer.invalidate();\n    };\n    scope.getRendererForHost = getRendererForHost;\n    scope.getShadowTrees = getShadowTrees;\n    scope.renderAllPending = renderAllPending;\n    scope.getDestinationInsertionPoints = getDestinationInsertionPoints;\n    scope.visual = {\n      insertBefore: insertBefore,\n      remove: remove\n    };\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var HTMLElement = scope.wrappers.HTMLElement;\n    var assert = scope.assert;\n    var mixin = scope.mixin;\n    var registerWrapper = scope.registerWrapper;\n    var unwrap = scope.unwrap;\n    var wrap = scope.wrap;\n    var elementsWithFormProperty = [ \"HTMLButtonElement\", \"HTMLFieldSetElement\", \"HTMLInputElement\", \"HTMLKeygenElement\", \"HTMLLabelElement\", \"HTMLLegendElement\", \"HTMLObjectElement\", \"HTMLOutputElement\", \"HTMLTextAreaElement\" ];\n    function createWrapperConstructor(name) {\n      if (!window[name]) return;\n      assert(!scope.wrappers[name]);\n      var GeneratedWrapper = function(node) {\n        HTMLElement.call(this, node);\n      };\n      GeneratedWrapper.prototype = Object.create(HTMLElement.prototype);\n      mixin(GeneratedWrapper.prototype, {\n        get form() {\n          return wrap(unwrap(this).form);\n        }\n      });\n      registerWrapper(window[name], GeneratedWrapper, document.createElement(name.slice(4, -7)));\n      scope.wrappers[name] = GeneratedWrapper;\n    }\n    elementsWithFormProperty.forEach(createWrapperConstructor);\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var registerWrapper = scope.registerWrapper;\n    var setWrapper = scope.setWrapper;\n    var unsafeUnwrap = scope.unsafeUnwrap;\n    var unwrap = scope.unwrap;\n    var unwrapIfNeeded = scope.unwrapIfNeeded;\n    var wrap = scope.wrap;\n    var OriginalSelection = window.Selection;\n    function Selection(impl) {\n      setWrapper(impl, this);\n    }\n    Selection.prototype = {\n      get anchorNode() {\n        return wrap(unsafeUnwrap(this).anchorNode);\n      },\n      get focusNode() {\n        return wrap(unsafeUnwrap(this).focusNode);\n      },\n      addRange: function(range) {\n        unsafeUnwrap(this).addRange(unwrapIfNeeded(range));\n      },\n      collapse: function(node, index) {\n        unsafeUnwrap(this).collapse(unwrapIfNeeded(node), index);\n      },\n      containsNode: function(node, allowPartial) {\n        return unsafeUnwrap(this).containsNode(unwrapIfNeeded(node), allowPartial);\n      },\n      getRangeAt: function(index) {\n        return wrap(unsafeUnwrap(this).getRangeAt(index));\n      },\n      removeRange: function(range) {\n        unsafeUnwrap(this).removeRange(unwrap(range));\n      },\n      selectAllChildren: function(node) {\n        unsafeUnwrap(this).selectAllChildren(unwrapIfNeeded(node));\n      },\n      toString: function() {\n        return unsafeUnwrap(this).toString();\n      }\n    };\n    if (OriginalSelection.prototype.extend) {\n      Selection.prototype.extend = function(node, offset) {\n        unsafeUnwrap(this).extend(unwrapIfNeeded(node), offset);\n      };\n    }\n    registerWrapper(window.Selection, Selection, window.getSelection());\n    scope.wrappers.Selection = Selection;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var registerWrapper = scope.registerWrapper;\n    var setWrapper = scope.setWrapper;\n    var unsafeUnwrap = scope.unsafeUnwrap;\n    var unwrapIfNeeded = scope.unwrapIfNeeded;\n    var wrap = scope.wrap;\n    var OriginalTreeWalker = window.TreeWalker;\n    function TreeWalker(impl) {\n      setWrapper(impl, this);\n    }\n    TreeWalker.prototype = {\n      get root() {\n        return wrap(unsafeUnwrap(this).root);\n      },\n      get currentNode() {\n        return wrap(unsafeUnwrap(this).currentNode);\n      },\n      set currentNode(node) {\n        unsafeUnwrap(this).currentNode = unwrapIfNeeded(node);\n      },\n      get filter() {\n        return unsafeUnwrap(this).filter;\n      },\n      parentNode: function() {\n        return wrap(unsafeUnwrap(this).parentNode());\n      },\n      firstChild: function() {\n        return wrap(unsafeUnwrap(this).firstChild());\n      },\n      lastChild: function() {\n        return wrap(unsafeUnwrap(this).lastChild());\n      },\n      previousSibling: function() {\n        return wrap(unsafeUnwrap(this).previousSibling());\n      },\n      previousNode: function() {\n        return wrap(unsafeUnwrap(this).previousNode());\n      },\n      nextNode: function() {\n        return wrap(unsafeUnwrap(this).nextNode());\n      }\n    };\n    registerWrapper(OriginalTreeWalker, TreeWalker);\n    scope.wrappers.TreeWalker = TreeWalker;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var GetElementsByInterface = scope.GetElementsByInterface;\n    var Node = scope.wrappers.Node;\n    var ParentNodeInterface = scope.ParentNodeInterface;\n    var NonElementParentNodeInterface = scope.NonElementParentNodeInterface;\n    var Selection = scope.wrappers.Selection;\n    var SelectorsInterface = scope.SelectorsInterface;\n    var ShadowRoot = scope.wrappers.ShadowRoot;\n    var TreeScope = scope.TreeScope;\n    var cloneNode = scope.cloneNode;\n    var defineWrapGetter = scope.defineWrapGetter;\n    var elementFromPoint = scope.elementFromPoint;\n    var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;\n    var matchesNames = scope.matchesNames;\n    var mixin = scope.mixin;\n    var registerWrapper = scope.registerWrapper;\n    var renderAllPending = scope.renderAllPending;\n    var rewrap = scope.rewrap;\n    var setWrapper = scope.setWrapper;\n    var unsafeUnwrap = scope.unsafeUnwrap;\n    var unwrap = scope.unwrap;\n    var wrap = scope.wrap;\n    var wrapEventTargetMethods = scope.wrapEventTargetMethods;\n    var wrapNodeList = scope.wrapNodeList;\n    var implementationTable = new WeakMap();\n    function Document(node) {\n      Node.call(this, node);\n      this.treeScope_ = new TreeScope(this, null);\n    }\n    Document.prototype = Object.create(Node.prototype);\n    defineWrapGetter(Document, \"documentElement\");\n    defineWrapGetter(Document, \"body\");\n    defineWrapGetter(Document, \"head\");\n    function wrapMethod(name) {\n      var original = document[name];\n      Document.prototype[name] = function() {\n        return wrap(original.apply(unsafeUnwrap(this), arguments));\n      };\n    }\n    [ \"createComment\", \"createDocumentFragment\", \"createElement\", \"createElementNS\", \"createEvent\", \"createEventNS\", \"createRange\", \"createTextNode\" ].forEach(wrapMethod);\n    var originalAdoptNode = document.adoptNode;\n    function adoptNodeNoRemove(node, doc) {\n      originalAdoptNode.call(unsafeUnwrap(doc), unwrap(node));\n      adoptSubtree(node, doc);\n    }\n    function adoptSubtree(node, doc) {\n      if (node.shadowRoot) doc.adoptNode(node.shadowRoot);\n      if (node instanceof ShadowRoot) adoptOlderShadowRoots(node, doc);\n      for (var child = node.firstChild; child; child = child.nextSibling) {\n        adoptSubtree(child, doc);\n      }\n    }\n    function adoptOlderShadowRoots(shadowRoot, doc) {\n      var oldShadowRoot = shadowRoot.olderShadowRoot;\n      if (oldShadowRoot) doc.adoptNode(oldShadowRoot);\n    }\n    var originalGetSelection = document.getSelection;\n    mixin(Document.prototype, {\n      adoptNode: function(node) {\n        if (node.parentNode) node.parentNode.removeChild(node);\n        adoptNodeNoRemove(node, this);\n        return node;\n      },\n      elementFromPoint: function(x, y) {\n        return elementFromPoint(this, this, x, y);\n      },\n      importNode: function(node, deep) {\n        return cloneNode(node, deep, unsafeUnwrap(this));\n      },\n      getSelection: function() {\n        renderAllPending();\n        return new Selection(originalGetSelection.call(unwrap(this)));\n      },\n      getElementsByName: function(name) {\n        return SelectorsInterface.querySelectorAll.call(this, \"[name=\" + JSON.stringify(String(name)) + \"]\");\n      }\n    });\n    var originalCreateTreeWalker = document.createTreeWalker;\n    var TreeWalkerWrapper = scope.wrappers.TreeWalker;\n    Document.prototype.createTreeWalker = function(root, whatToShow, filter, expandEntityReferences) {\n      var newFilter = null;\n      if (filter) {\n        if (filter.acceptNode && typeof filter.acceptNode === \"function\") {\n          newFilter = {\n            acceptNode: function(node) {\n              return filter.acceptNode(wrap(node));\n            }\n          };\n        } else if (typeof filter === \"function\") {\n          newFilter = function(node) {\n            return filter(wrap(node));\n          };\n        }\n      }\n      return new TreeWalkerWrapper(originalCreateTreeWalker.call(unwrap(this), unwrap(root), whatToShow, newFilter, expandEntityReferences));\n    };\n    if (document.registerElement) {\n      var originalRegisterElement = document.registerElement;\n      Document.prototype.registerElement = function(tagName, object) {\n        var prototype, extendsOption;\n        if (object !== undefined) {\n          prototype = object.prototype;\n          extendsOption = object.extends;\n        }\n        if (!prototype) prototype = Object.create(HTMLElement.prototype);\n        if (scope.nativePrototypeTable.get(prototype)) {\n          throw new Error(\"NotSupportedError\");\n        }\n        var proto = Object.getPrototypeOf(prototype);\n        var nativePrototype;\n        var prototypes = [];\n        while (proto) {\n          nativePrototype = scope.nativePrototypeTable.get(proto);\n          if (nativePrototype) break;\n          prototypes.push(proto);\n          proto = Object.getPrototypeOf(proto);\n        }\n        if (!nativePrototype) {\n          throw new Error(\"NotSupportedError\");\n        }\n        var newPrototype = Object.create(nativePrototype);\n        for (var i = prototypes.length - 1; i >= 0; i--) {\n          newPrototype = Object.create(newPrototype);\n        }\n        [ \"createdCallback\", \"attachedCallback\", \"detachedCallback\", \"attributeChangedCallback\" ].forEach(function(name) {\n          var f = prototype[name];\n          if (!f) return;\n          newPrototype[name] = function() {\n            if (!(wrap(this) instanceof CustomElementConstructor)) {\n              rewrap(this);\n            }\n            f.apply(wrap(this), arguments);\n          };\n        });\n        var p = {\n          prototype: newPrototype\n        };\n        if (extendsOption) p.extends = extendsOption;\n        function CustomElementConstructor(node) {\n          if (!node) {\n            if (extendsOption) {\n              return document.createElement(extendsOption, tagName);\n            } else {\n              return document.createElement(tagName);\n            }\n          }\n          setWrapper(node, this);\n        }\n        CustomElementConstructor.prototype = prototype;\n        CustomElementConstructor.prototype.constructor = CustomElementConstructor;\n        scope.constructorTable.set(newPrototype, CustomElementConstructor);\n        scope.nativePrototypeTable.set(prototype, newPrototype);\n        var nativeConstructor = originalRegisterElement.call(unwrap(this), tagName, p);\n        return CustomElementConstructor;\n      };\n      forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ \"registerElement\" ]);\n    }\n    forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement, window.HTMLHtmlElement ], [ \"appendChild\", \"compareDocumentPosition\", \"contains\", \"getElementsByClassName\", \"getElementsByTagName\", \"getElementsByTagNameNS\", \"insertBefore\", \"querySelector\", \"querySelectorAll\", \"removeChild\", \"replaceChild\" ]);\n    forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLHeadElement, window.HTMLHtmlElement ], matchesNames);\n    forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ \"adoptNode\", \"importNode\", \"contains\", \"createComment\", \"createDocumentFragment\", \"createElement\", \"createElementNS\", \"createEvent\", \"createEventNS\", \"createRange\", \"createTextNode\", \"createTreeWalker\", \"elementFromPoint\", \"getElementById\", \"getElementsByName\", \"getSelection\" ]);\n    mixin(Document.prototype, GetElementsByInterface);\n    mixin(Document.prototype, ParentNodeInterface);\n    mixin(Document.prototype, SelectorsInterface);\n    mixin(Document.prototype, NonElementParentNodeInterface);\n    mixin(Document.prototype, {\n      get implementation() {\n        var implementation = implementationTable.get(this);\n        if (implementation) return implementation;\n        implementation = new DOMImplementation(unwrap(this).implementation);\n        implementationTable.set(this, implementation);\n        return implementation;\n      },\n      get defaultView() {\n        return wrap(unwrap(this).defaultView);\n      }\n    });\n    registerWrapper(window.Document, Document, document.implementation.createHTMLDocument(\"\"));\n    if (window.HTMLDocument) registerWrapper(window.HTMLDocument, Document);\n    wrapEventTargetMethods([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement ]);\n    function DOMImplementation(impl) {\n      setWrapper(impl, this);\n    }\n    var originalCreateDocument = document.implementation.createDocument;\n    DOMImplementation.prototype.createDocument = function() {\n      arguments[2] = unwrap(arguments[2]);\n      return wrap(originalCreateDocument.apply(unsafeUnwrap(this), arguments));\n    };\n    function wrapImplMethod(constructor, name) {\n      var original = document.implementation[name];\n      constructor.prototype[name] = function() {\n        return wrap(original.apply(unsafeUnwrap(this), arguments));\n      };\n    }\n    function forwardImplMethod(constructor, name) {\n      var original = document.implementation[name];\n      constructor.prototype[name] = function() {\n        return original.apply(unsafeUnwrap(this), arguments);\n      };\n    }\n    wrapImplMethod(DOMImplementation, \"createDocumentType\");\n    wrapImplMethod(DOMImplementation, \"createHTMLDocument\");\n    forwardImplMethod(DOMImplementation, \"hasFeature\");\n    registerWrapper(window.DOMImplementation, DOMImplementation);\n    forwardMethodsToWrapper([ window.DOMImplementation ], [ \"createDocument\", \"createDocumentType\", \"createHTMLDocument\", \"hasFeature\" ]);\n    scope.adoptNodeNoRemove = adoptNodeNoRemove;\n    scope.wrappers.DOMImplementation = DOMImplementation;\n    scope.wrappers.Document = Document;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var EventTarget = scope.wrappers.EventTarget;\n    var Selection = scope.wrappers.Selection;\n    var mixin = scope.mixin;\n    var registerWrapper = scope.registerWrapper;\n    var renderAllPending = scope.renderAllPending;\n    var unwrap = scope.unwrap;\n    var unwrapIfNeeded = scope.unwrapIfNeeded;\n    var wrap = scope.wrap;\n    var OriginalWindow = window.Window;\n    var originalGetComputedStyle = window.getComputedStyle;\n    var originalGetDefaultComputedStyle = window.getDefaultComputedStyle;\n    var originalGetSelection = window.getSelection;\n    function Window(impl) {\n      EventTarget.call(this, impl);\n    }\n    Window.prototype = Object.create(EventTarget.prototype);\n    OriginalWindow.prototype.getComputedStyle = function(el, pseudo) {\n      return wrap(this || window).getComputedStyle(unwrapIfNeeded(el), pseudo);\n    };\n    if (originalGetDefaultComputedStyle) {\n      OriginalWindow.prototype.getDefaultComputedStyle = function(el, pseudo) {\n        return wrap(this || window).getDefaultComputedStyle(unwrapIfNeeded(el), pseudo);\n      };\n    }\n    OriginalWindow.prototype.getSelection = function() {\n      return wrap(this || window).getSelection();\n    };\n    delete window.getComputedStyle;\n    delete window.getDefaultComputedStyle;\n    delete window.getSelection;\n    [ \"addEventListener\", \"removeEventListener\", \"dispatchEvent\" ].forEach(function(name) {\n      OriginalWindow.prototype[name] = function() {\n        var w = wrap(this || window);\n        return w[name].apply(w, arguments);\n      };\n      delete window[name];\n    });\n    mixin(Window.prototype, {\n      getComputedStyle: function(el, pseudo) {\n        renderAllPending();\n        return originalGetComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);\n      },\n      getSelection: function() {\n        renderAllPending();\n        return new Selection(originalGetSelection.call(unwrap(this)));\n      },\n      get document() {\n        return wrap(unwrap(this).document);\n      }\n    });\n    if (originalGetDefaultComputedStyle) {\n      Window.prototype.getDefaultComputedStyle = function(el, pseudo) {\n        renderAllPending();\n        return originalGetDefaultComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);\n      };\n    }\n    registerWrapper(OriginalWindow, Window, window);\n    scope.wrappers.Window = Window;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var unwrap = scope.unwrap;\n    var OriginalDataTransfer = window.DataTransfer || window.Clipboard;\n    var OriginalDataTransferSetDragImage = OriginalDataTransfer.prototype.setDragImage;\n    if (OriginalDataTransferSetDragImage) {\n      OriginalDataTransfer.prototype.setDragImage = function(image, x, y) {\n        OriginalDataTransferSetDragImage.call(this, unwrap(image), x, y);\n      };\n    }\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var registerWrapper = scope.registerWrapper;\n    var setWrapper = scope.setWrapper;\n    var unwrap = scope.unwrap;\n    var OriginalFormData = window.FormData;\n    if (!OriginalFormData) return;\n    function FormData(formElement) {\n      var impl;\n      if (formElement instanceof OriginalFormData) {\n        impl = formElement;\n      } else {\n        impl = new OriginalFormData(formElement && unwrap(formElement));\n      }\n      setWrapper(impl, this);\n    }\n    registerWrapper(OriginalFormData, FormData, new OriginalFormData());\n    scope.wrappers.FormData = FormData;\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var unwrapIfNeeded = scope.unwrapIfNeeded;\n    var originalSend = XMLHttpRequest.prototype.send;\n    XMLHttpRequest.prototype.send = function(obj) {\n      return originalSend.call(this, unwrapIfNeeded(obj));\n    };\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    \"use strict\";\n    var isWrapperFor = scope.isWrapperFor;\n    var elements = {\n      a: \"HTMLAnchorElement\",\n      area: \"HTMLAreaElement\",\n      audio: \"HTMLAudioElement\",\n      base: \"HTMLBaseElement\",\n      body: \"HTMLBodyElement\",\n      br: \"HTMLBRElement\",\n      button: \"HTMLButtonElement\",\n      canvas: \"HTMLCanvasElement\",\n      caption: \"HTMLTableCaptionElement\",\n      col: \"HTMLTableColElement\",\n      content: \"HTMLContentElement\",\n      data: \"HTMLDataElement\",\n      datalist: \"HTMLDataListElement\",\n      del: \"HTMLModElement\",\n      dir: \"HTMLDirectoryElement\",\n      div: \"HTMLDivElement\",\n      dl: \"HTMLDListElement\",\n      embed: \"HTMLEmbedElement\",\n      fieldset: \"HTMLFieldSetElement\",\n      font: \"HTMLFontElement\",\n      form: \"HTMLFormElement\",\n      frame: \"HTMLFrameElement\",\n      frameset: \"HTMLFrameSetElement\",\n      h1: \"HTMLHeadingElement\",\n      head: \"HTMLHeadElement\",\n      hr: \"HTMLHRElement\",\n      html: \"HTMLHtmlElement\",\n      iframe: \"HTMLIFrameElement\",\n      img: \"HTMLImageElement\",\n      input: \"HTMLInputElement\",\n      keygen: \"HTMLKeygenElement\",\n      label: \"HTMLLabelElement\",\n      legend: \"HTMLLegendElement\",\n      li: \"HTMLLIElement\",\n      link: \"HTMLLinkElement\",\n      map: \"HTMLMapElement\",\n      marquee: \"HTMLMarqueeElement\",\n      menu: \"HTMLMenuElement\",\n      menuitem: \"HTMLMenuItemElement\",\n      meta: \"HTMLMetaElement\",\n      meter: \"HTMLMeterElement\",\n      object: \"HTMLObjectElement\",\n      ol: \"HTMLOListElement\",\n      optgroup: \"HTMLOptGroupElement\",\n      option: \"HTMLOptionElement\",\n      output: \"HTMLOutputElement\",\n      p: \"HTMLParagraphElement\",\n      param: \"HTMLParamElement\",\n      pre: \"HTMLPreElement\",\n      progress: \"HTMLProgressElement\",\n      q: \"HTMLQuoteElement\",\n      script: \"HTMLScriptElement\",\n      select: \"HTMLSelectElement\",\n      shadow: \"HTMLShadowElement\",\n      source: \"HTMLSourceElement\",\n      span: \"HTMLSpanElement\",\n      style: \"HTMLStyleElement\",\n      table: \"HTMLTableElement\",\n      tbody: \"HTMLTableSectionElement\",\n      template: \"HTMLTemplateElement\",\n      textarea: \"HTMLTextAreaElement\",\n      thead: \"HTMLTableSectionElement\",\n      time: \"HTMLTimeElement\",\n      title: \"HTMLTitleElement\",\n      tr: \"HTMLTableRowElement\",\n      track: \"HTMLTrackElement\",\n      ul: \"HTMLUListElement\",\n      video: \"HTMLVideoElement\"\n    };\n    function overrideConstructor(tagName) {\n      var nativeConstructorName = elements[tagName];\n      var nativeConstructor = window[nativeConstructorName];\n      if (!nativeConstructor) return;\n      var element = document.createElement(tagName);\n      var wrapperConstructor = element.constructor;\n      window[nativeConstructorName] = wrapperConstructor;\n    }\n    Object.keys(elements).forEach(overrideConstructor);\n    Object.getOwnPropertyNames(scope.wrappers).forEach(function(name) {\n      window[name] = scope.wrappers[name];\n    });\n  })(window.ShadowDOMPolyfill);\n  (function(scope) {\n    var ShadowCSS = {\n      strictStyling: false,\n      registry: {},\n      shimStyling: function(root, name, extendsName) {\n        var scopeStyles = this.prepareRoot(root, name, extendsName);\n        var typeExtension = this.isTypeExtension(extendsName);\n        var scopeSelector = this.makeScopeSelector(name, typeExtension);\n        var cssText = stylesToCssText(scopeStyles, true);\n        cssText = this.scopeCssText(cssText, scopeSelector);\n        if (root) {\n          root.shimmedStyle = cssText;\n        }\n        this.addCssToDocument(cssText, name);\n      },\n      shimStyle: function(style, selector) {\n        return this.shimCssText(style.textContent, selector);\n      },\n      shimCssText: function(cssText, selector) {\n        cssText = this.insertDirectives(cssText);\n        return this.scopeCssText(cssText, selector);\n      },\n      makeScopeSelector: function(name, typeExtension) {\n        if (name) {\n          return typeExtension ? \"[is=\" + name + \"]\" : name;\n        }\n        return \"\";\n      },\n      isTypeExtension: function(extendsName) {\n        return extendsName && extendsName.indexOf(\"-\") < 0;\n      },\n      prepareRoot: function(root, name, extendsName) {\n        var def = this.registerRoot(root, name, extendsName);\n        this.replaceTextInStyles(def.rootStyles, this.insertDirectives);\n        this.removeStyles(root, def.rootStyles);\n        if (this.strictStyling) {\n          this.applyScopeToContent(root, name);\n        }\n        return def.scopeStyles;\n      },\n      removeStyles: function(root, styles) {\n        for (var i = 0, l = styles.length, s; i < l && (s = styles[i]); i++) {\n          s.parentNode.removeChild(s);\n        }\n      },\n      registerRoot: function(root, name, extendsName) {\n        var def = this.registry[name] = {\n          root: root,\n          name: name,\n          extendsName: extendsName\n        };\n        var styles = this.findStyles(root);\n        def.rootStyles = styles;\n        def.scopeStyles = def.rootStyles;\n        var extendee = this.registry[def.extendsName];\n        if (extendee) {\n          def.scopeStyles = extendee.scopeStyles.concat(def.scopeStyles);\n        }\n        return def;\n      },\n      findStyles: function(root) {\n        if (!root) {\n          return [];\n        }\n        var styles = root.querySelectorAll(\"style\");\n        return Array.prototype.filter.call(styles, function(s) {\n          return !s.hasAttribute(NO_SHIM_ATTRIBUTE);\n        });\n      },\n      applyScopeToContent: function(root, name) {\n        if (root) {\n          Array.prototype.forEach.call(root.querySelectorAll(\"*\"), function(node) {\n            node.setAttribute(name, \"\");\n          });\n          Array.prototype.forEach.call(root.querySelectorAll(\"template\"), function(template) {\n            this.applyScopeToContent(template.content, name);\n          }, this);\n        }\n      },\n      insertDirectives: function(cssText) {\n        cssText = this.insertPolyfillDirectivesInCssText(cssText);\n        return this.insertPolyfillRulesInCssText(cssText);\n      },\n      insertPolyfillDirectivesInCssText: function(cssText) {\n        cssText = cssText.replace(cssCommentNextSelectorRe, function(match, p1) {\n          return p1.slice(0, -2) + \"{\";\n        });\n        return cssText.replace(cssContentNextSelectorRe, function(match, p1) {\n          return p1 + \" {\";\n        });\n      },\n      insertPolyfillRulesInCssText: function(cssText) {\n        cssText = cssText.replace(cssCommentRuleRe, function(match, p1) {\n          return p1.slice(0, -1);\n        });\n        return cssText.replace(cssContentRuleRe, function(match, p1, p2, p3) {\n          var rule = match.replace(p1, \"\").replace(p2, \"\");\n          return p3 + rule;\n        });\n      },\n      scopeCssText: function(cssText, scopeSelector) {\n        var unscoped = this.extractUnscopedRulesFromCssText(cssText);\n        cssText = this.insertPolyfillHostInCssText(cssText);\n        cssText = this.convertColonHost(cssText);\n        cssText = this.convertColonHostContext(cssText);\n        cssText = this.convertShadowDOMSelectors(cssText);\n        if (scopeSelector) {\n          var self = this, cssText;\n          withCssRules(cssText, function(rules) {\n            cssText = self.scopeRules(rules, scopeSelector);\n          });\n        }\n        cssText = cssText + \"\\n\" + unscoped;\n        return cssText.trim();\n      },\n      extractUnscopedRulesFromCssText: function(cssText) {\n        var r = \"\", m;\n        while (m = cssCommentUnscopedRuleRe.exec(cssText)) {\n          r += m[1].slice(0, -1) + \"\\n\\n\";\n        }\n        while (m = cssContentUnscopedRuleRe.exec(cssText)) {\n          r += m[0].replace(m[2], \"\").replace(m[1], m[3]) + \"\\n\\n\";\n        }\n        return r;\n      },\n      convertColonHost: function(cssText) {\n        return this.convertColonRule(cssText, cssColonHostRe, this.colonHostPartReplacer);\n      },\n      convertColonHostContext: function(cssText) {\n        return this.convertColonRule(cssText, cssColonHostContextRe, this.colonHostContextPartReplacer);\n      },\n      convertColonRule: function(cssText, regExp, partReplacer) {\n        return cssText.replace(regExp, function(m, p1, p2, p3) {\n          p1 = polyfillHostNoCombinator;\n          if (p2) {\n            var parts = p2.split(\",\"), r = [];\n            for (var i = 0, l = parts.length, p; i < l && (p = parts[i]); i++) {\n              p = p.trim();\n              r.push(partReplacer(p1, p, p3));\n            }\n            return r.join(\",\");\n          } else {\n            return p1 + p3;\n          }\n        });\n      },\n      colonHostContextPartReplacer: function(host, part, suffix) {\n        if (part.match(polyfillHost)) {\n          return this.colonHostPartReplacer(host, part, suffix);\n        } else {\n          return host + part + suffix + \", \" + part + \" \" + host + suffix;\n        }\n      },\n      colonHostPartReplacer: function(host, part, suffix) {\n        return host + part.replace(polyfillHost, \"\") + suffix;\n      },\n      convertShadowDOMSelectors: function(cssText) {\n        for (var i = 0; i < shadowDOMSelectorsRe.length; i++) {\n          cssText = cssText.replace(shadowDOMSelectorsRe[i], \" \");\n        }\n        return cssText;\n      },\n      scopeRules: function(cssRules, scopeSelector) {\n        var cssText = \"\";\n        if (cssRules) {\n          Array.prototype.forEach.call(cssRules, function(rule) {\n            if (rule.selectorText && (rule.style && rule.style.cssText !== undefined)) {\n              cssText += this.scopeSelector(rule.selectorText, scopeSelector, this.strictStyling) + \" {\\n\t\";\n              cssText += this.propertiesFromRule(rule) + \"\\n}\\n\\n\";\n            } else if (rule.type === CSSRule.MEDIA_RULE) {\n              cssText += \"@media \" + rule.media.mediaText + \" {\\n\";\n              cssText += this.scopeRules(rule.cssRules, scopeSelector);\n              cssText += \"\\n}\\n\\n\";\n            } else {\n              try {\n                if (rule.cssText) {\n                  cssText += rule.cssText + \"\\n\\n\";\n                }\n              } catch (x) {\n                if (rule.type === CSSRule.KEYFRAMES_RULE && rule.cssRules) {\n                  cssText += this.ieSafeCssTextFromKeyFrameRule(rule);\n                }\n              }\n            }\n          }, this);\n        }\n        return cssText;\n      },\n      ieSafeCssTextFromKeyFrameRule: function(rule) {\n        var cssText = \"@keyframes \" + rule.name + \" {\";\n        Array.prototype.forEach.call(rule.cssRules, function(rule) {\n          cssText += \" \" + rule.keyText + \" {\" + rule.style.cssText + \"}\";\n        });\n        cssText += \" }\";\n        return cssText;\n      },\n      scopeSelector: function(selector, scopeSelector, strict) {\n        var r = [], parts = selector.split(\",\");\n        parts.forEach(function(p) {\n          p = p.trim();\n          if (this.selectorNeedsScoping(p, scopeSelector)) {\n            p = strict && !p.match(polyfillHostNoCombinator) ? this.applyStrictSelectorScope(p, scopeSelector) : this.applySelectorScope(p, scopeSelector);\n          }\n          r.push(p);\n        }, this);\n        return r.join(\", \");\n      },\n      selectorNeedsScoping: function(selector, scopeSelector) {\n        if (Array.isArray(scopeSelector)) {\n          return true;\n        }\n        var re = this.makeScopeMatcher(scopeSelector);\n        return !selector.match(re);\n      },\n      makeScopeMatcher: function(scopeSelector) {\n        scopeSelector = scopeSelector.replace(/\\[/g, \"\\\\[\").replace(/\\]/g, \"\\\\]\");\n        return new RegExp(\"^(\" + scopeSelector + \")\" + selectorReSuffix, \"m\");\n      },\n      applySelectorScope: function(selector, selectorScope) {\n        return Array.isArray(selectorScope) ? this.applySelectorScopeList(selector, selectorScope) : this.applySimpleSelectorScope(selector, selectorScope);\n      },\n      applySelectorScopeList: function(selector, scopeSelectorList) {\n        var r = [];\n        for (var i = 0, s; s = scopeSelectorList[i]; i++) {\n          r.push(this.applySimpleSelectorScope(selector, s));\n        }\n        return r.join(\", \");\n      },\n      applySimpleSelectorScope: function(selector, scopeSelector) {\n        if (selector.match(polyfillHostRe)) {\n          selector = selector.replace(polyfillHostNoCombinator, scopeSelector);\n          return selector.replace(polyfillHostRe, scopeSelector + \" \");\n        } else {\n          return scopeSelector + \" \" + selector;\n        }\n      },\n      applyStrictSelectorScope: function(selector, scopeSelector) {\n        scopeSelector = scopeSelector.replace(/\\[is=([^\\]]*)\\]/g, \"$1\");\n        var splits = [ \" \", \">\", \"+\", \"~\" ], scoped = selector, attrName = \"[\" + scopeSelector + \"]\";\n        splits.forEach(function(sep) {\n          var parts = scoped.split(sep);\n          scoped = parts.map(function(p) {\n            var t = p.trim().replace(polyfillHostRe, \"\");\n            if (t && splits.indexOf(t) < 0 && t.indexOf(attrName) < 0) {\n              p = t.replace(/([^:]*)(:*)(.*)/, \"$1\" + attrName + \"$2$3\");\n            }\n            return p;\n          }).join(sep);\n        });\n        return scoped;\n      },\n      insertPolyfillHostInCssText: function(selector) {\n        return selector.replace(colonHostContextRe, polyfillHostContext).replace(colonHostRe, polyfillHost);\n      },\n      propertiesFromRule: function(rule) {\n        var cssText = rule.style.cssText;\n        if (rule.style.content && !rule.style.content.match(/['\"]+|attr/)) {\n          cssText = cssText.replace(/content:[^;]*;/g, \"content: '\" + rule.style.content + \"';\");\n        }\n        var style = rule.style;\n        for (var i in style) {\n          if (style[i] === \"initial\") {\n            cssText += i + \": initial; \";\n          }\n        }\n        return cssText;\n      },\n      replaceTextInStyles: function(styles, action) {\n        if (styles && action) {\n          if (!(styles instanceof Array)) {\n            styles = [ styles ];\n          }\n          Array.prototype.forEach.call(styles, function(s) {\n            s.textContent = action.call(this, s.textContent);\n          }, this);\n        }\n      },\n      addCssToDocument: function(cssText, name) {\n        if (cssText.match(\"@import\")) {\n          addOwnSheet(cssText, name);\n        } else {\n          addCssToDocument(cssText);\n        }\n      }\n    };\n    var selectorRe = /([^{]*)({[\\s\\S]*?})/gim, cssCommentRe = /\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\//gim, cssCommentNextSelectorRe = /\\/\\*\\s*@polyfill ([^*]*\\*+([^/*][^*]*\\*+)*\\/)([^{]*?){/gim, cssContentNextSelectorRe = /polyfill-next-selector[^}]*content\\:[\\s]*?['\"](.*?)['\"][;\\s]*}([^{]*?){/gim, cssCommentRuleRe = /\\/\\*\\s@polyfill-rule([^*]*\\*+([^/*][^*]*\\*+)*)\\//gim, cssContentRuleRe = /(polyfill-rule)[^}]*(content\\:[\\s]*['\"](.*?)['\"])[;\\s]*[^}]*}/gim, cssCommentUnscopedRuleRe = /\\/\\*\\s@polyfill-unscoped-rule([^*]*\\*+([^/*][^*]*\\*+)*)\\//gim, cssContentUnscopedRuleRe = /(polyfill-unscoped-rule)[^}]*(content\\:[\\s]*['\"](.*?)['\"])[;\\s]*[^}]*}/gim, cssPseudoRe = /::(x-[^\\s{,(]*)/gim, cssPartRe = /::part\\(([^)]*)\\)/gim, polyfillHost = \"-shadowcsshost\", polyfillHostContext = \"-shadowcsscontext\", parenSuffix = \")(?:\\\\((\" + \"(?:\\\\([^)(]*\\\\)|[^)(]*)+?\" + \")\\\\))?([^,{]*)\";\n    var cssColonHostRe = new RegExp(\"(\" + polyfillHost + parenSuffix, \"gim\"), cssColonHostContextRe = new RegExp(\"(\" + polyfillHostContext + parenSuffix, \"gim\"), selectorReSuffix = \"([>\\\\s~+[.,{:][\\\\s\\\\S]*)?$\", colonHostRe = /\\:host/gim, colonHostContextRe = /\\:host-context/gim, polyfillHostNoCombinator = polyfillHost + \"-no-combinator\", polyfillHostRe = new RegExp(polyfillHost, \"gim\"), polyfillHostContextRe = new RegExp(polyfillHostContext, \"gim\"), shadowDOMSelectorsRe = [ />>>/g, /::shadow/g, /::content/g, /\\/deep\\//g, /\\/shadow\\//g, /\\/shadow-deep\\//g, /\\^\\^/g, /\\^/g ];\n    function stylesToCssText(styles, preserveComments) {\n      var cssText = \"\";\n      Array.prototype.forEach.call(styles, function(s) {\n        cssText += s.textContent + \"\\n\\n\";\n      });\n      if (!preserveComments) {\n        cssText = cssText.replace(cssCommentRe, \"\");\n      }\n      return cssText;\n    }\n    function cssTextToStyle(cssText) {\n      var style = document.createElement(\"style\");\n      style.textContent = cssText;\n      return style;\n    }\n    function cssToRules(cssText) {\n      var style = cssTextToStyle(cssText);\n      document.head.appendChild(style);\n      var rules = [];\n      if (style.sheet) {\n        try {\n          rules = style.sheet.cssRules;\n        } catch (e) {}\n      } else {\n        console.warn(\"sheet not found\", style);\n      }\n      style.parentNode.removeChild(style);\n      return rules;\n    }\n    var frame = document.createElement(\"iframe\");\n    frame.style.display = \"none\";\n    function initFrame() {\n      frame.initialized = true;\n      document.body.appendChild(frame);\n      var doc = frame.contentDocument;\n      var base = doc.createElement(\"base\");\n      base.href = document.baseURI;\n      doc.head.appendChild(base);\n    }\n    function inFrame(fn) {\n      if (!frame.initialized) {\n        initFrame();\n      }\n      document.body.appendChild(frame);\n      fn(frame.contentDocument);\n      document.body.removeChild(frame);\n    }\n    var isChrome = navigator.userAgent.match(\"Chrome\");\n    function withCssRules(cssText, callback) {\n      if (!callback) {\n        return;\n      }\n      var rules;\n      if (cssText.match(\"@import\") && isChrome) {\n        var style = cssTextToStyle(cssText);\n        inFrame(function(doc) {\n          doc.head.appendChild(style.impl);\n          rules = Array.prototype.slice.call(style.sheet.cssRules, 0);\n          callback(rules);\n        });\n      } else {\n        rules = cssToRules(cssText);\n        callback(rules);\n      }\n    }\n    function rulesToCss(cssRules) {\n      for (var i = 0, css = []; i < cssRules.length; i++) {\n        css.push(cssRules[i].cssText);\n      }\n      return css.join(\"\\n\\n\");\n    }\n    function addCssToDocument(cssText) {\n      if (cssText) {\n        getSheet().appendChild(document.createTextNode(cssText));\n      }\n    }\n    function addOwnSheet(cssText, name) {\n      var style = cssTextToStyle(cssText);\n      style.setAttribute(name, \"\");\n      style.setAttribute(SHIMMED_ATTRIBUTE, \"\");\n      document.head.appendChild(style);\n    }\n    var SHIM_ATTRIBUTE = \"shim-shadowdom\";\n    var SHIMMED_ATTRIBUTE = \"shim-shadowdom-css\";\n    var NO_SHIM_ATTRIBUTE = \"no-shim\";\n    var sheet;\n    function getSheet() {\n      if (!sheet) {\n        sheet = document.createElement(\"style\");\n        sheet.setAttribute(SHIMMED_ATTRIBUTE, \"\");\n        sheet[SHIMMED_ATTRIBUTE] = true;\n      }\n      return sheet;\n    }\n    if (window.ShadowDOMPolyfill) {\n      addCssToDocument(\"style { display: none !important; }\\n\");\n      var doc = ShadowDOMPolyfill.wrap(document);\n      var head = doc.querySelector(\"head\");\n      head.insertBefore(getSheet(), head.childNodes[0]);\n      document.addEventListener(\"DOMContentLoaded\", function() {\n        var urlResolver = scope.urlResolver;\n        if (window.HTMLImports && !HTMLImports.useNative) {\n          var SHIM_SHEET_SELECTOR = \"link[rel=stylesheet]\" + \"[\" + SHIM_ATTRIBUTE + \"]\";\n          var SHIM_STYLE_SELECTOR = \"style[\" + SHIM_ATTRIBUTE + \"]\";\n          HTMLImports.importer.documentPreloadSelectors += \",\" + SHIM_SHEET_SELECTOR;\n          HTMLImports.importer.importsPreloadSelectors += \",\" + SHIM_SHEET_SELECTOR;\n          HTMLImports.parser.documentSelectors = [ HTMLImports.parser.documentSelectors, SHIM_SHEET_SELECTOR, SHIM_STYLE_SELECTOR ].join(\",\");\n          var originalParseGeneric = HTMLImports.parser.parseGeneric;\n          HTMLImports.parser.parseGeneric = function(elt) {\n            if (elt[SHIMMED_ATTRIBUTE]) {\n              return;\n            }\n            var style = elt.__importElement || elt;\n            if (!style.hasAttribute(SHIM_ATTRIBUTE)) {\n              originalParseGeneric.call(this, elt);\n              return;\n            }\n            if (elt.__resource) {\n              style = elt.ownerDocument.createElement(\"style\");\n              style.textContent = elt.__resource;\n            }\n            HTMLImports.path.resolveUrlsInStyle(style, elt.href);\n            style.textContent = ShadowCSS.shimStyle(style);\n            style.removeAttribute(SHIM_ATTRIBUTE, \"\");\n            style.setAttribute(SHIMMED_ATTRIBUTE, \"\");\n            style[SHIMMED_ATTRIBUTE] = true;\n            if (style.parentNode !== head) {\n              if (elt.parentNode === head) {\n                head.replaceChild(style, elt);\n              } else {\n                this.addElementToDocument(style);\n              }\n            }\n            style.__importParsed = true;\n            this.markParsingComplete(elt);\n            this.parseNext();\n          };\n          var hasResource = HTMLImports.parser.hasResource;\n          HTMLImports.parser.hasResource = function(node) {\n            if (node.localName === \"link\" && node.rel === \"stylesheet\" && node.hasAttribute(SHIM_ATTRIBUTE)) {\n              return node.__resource;\n            } else {\n              return hasResource.call(this, node);\n            }\n          };\n        }\n      });\n    }\n    scope.ShadowCSS = ShadowCSS;\n  })(window.WebComponents);\n}\n\n(function(scope) {\n  if (window.ShadowDOMPolyfill) {\n    window.wrap = ShadowDOMPolyfill.wrapIfNeeded;\n    window.unwrap = ShadowDOMPolyfill.unwrapIfNeeded;\n  } else {\n    window.wrap = window.unwrap = function(n) {\n      return n;\n    };\n  }\n})(window.WebComponents);\n\n(function(scope) {\n  \"use strict\";\n  var hasWorkingUrl = false;\n  if (!scope.forceJURL) {\n    try {\n      var u = new URL(\"b\", \"http://a\");\n      u.pathname = \"c%20d\";\n      hasWorkingUrl = u.href === \"http://a/c%20d\";\n    } catch (e) {}\n  }\n  if (hasWorkingUrl) return;\n  var relative = Object.create(null);\n  relative[\"ftp\"] = 21;\n  relative[\"file\"] = 0;\n  relative[\"gopher\"] = 70;\n  relative[\"http\"] = 80;\n  relative[\"https\"] = 443;\n  relative[\"ws\"] = 80;\n  relative[\"wss\"] = 443;\n  var relativePathDotMapping = Object.create(null);\n  relativePathDotMapping[\"%2e\"] = \".\";\n  relativePathDotMapping[\".%2e\"] = \"..\";\n  relativePathDotMapping[\"%2e.\"] = \"..\";\n  relativePathDotMapping[\"%2e%2e\"] = \"..\";\n  function isRelativeScheme(scheme) {\n    return relative[scheme] !== undefined;\n  }\n  function invalid() {\n    clear.call(this);\n    this._isInvalid = true;\n  }\n  function IDNAToASCII(h) {\n    if (\"\" == h) {\n      invalid.call(this);\n    }\n    return h.toLowerCase();\n  }\n  function percentEscape(c) {\n    var unicode = c.charCodeAt(0);\n    if (unicode > 32 && unicode < 127 && [ 34, 35, 60, 62, 63, 96 ].indexOf(unicode) == -1) {\n      return c;\n    }\n    return encodeURIComponent(c);\n  }\n  function percentEscapeQuery(c) {\n    var unicode = c.charCodeAt(0);\n    if (unicode > 32 && unicode < 127 && [ 34, 35, 60, 62, 96 ].indexOf(unicode) == -1) {\n      return c;\n    }\n    return encodeURIComponent(c);\n  }\n  var EOF = undefined, ALPHA = /[a-zA-Z]/, ALPHANUMERIC = /[a-zA-Z0-9\\+\\-\\.]/;\n  function parse(input, stateOverride, base) {\n    function err(message) {\n      errors.push(message);\n    }\n    var state = stateOverride || \"scheme start\", cursor = 0, buffer = \"\", seenAt = false, seenBracket = false, errors = [];\n    loop: while ((input[cursor - 1] != EOF || cursor == 0) && !this._isInvalid) {\n      var c = input[cursor];\n      switch (state) {\n       case \"scheme start\":\n        if (c && ALPHA.test(c)) {\n          buffer += c.toLowerCase();\n          state = \"scheme\";\n        } else if (!stateOverride) {\n          buffer = \"\";\n          state = \"no scheme\";\n          continue;\n        } else {\n          err(\"Invalid scheme.\");\n          break loop;\n        }\n        break;\n\n       case \"scheme\":\n        if (c && ALPHANUMERIC.test(c)) {\n          buffer += c.toLowerCase();\n        } else if (\":\" == c) {\n          this._scheme = buffer;\n          buffer = \"\";\n          if (stateOverride) {\n            break loop;\n          }\n          if (isRelativeScheme(this._scheme)) {\n            this._isRelative = true;\n          }\n          if (\"file\" == this._scheme) {\n            state = \"relative\";\n          } else if (this._isRelative && base && base._scheme == this._scheme) {\n            state = \"relative or authority\";\n          } else if (this._isRelative) {\n            state = \"authority first slash\";\n          } else {\n            state = \"scheme data\";\n          }\n        } else if (!stateOverride) {\n          buffer = \"\";\n          cursor = 0;\n          state = \"no scheme\";\n          continue;\n        } else if (EOF == c) {\n          break loop;\n        } else {\n          err(\"Code point not allowed in scheme: \" + c);\n          break loop;\n        }\n        break;\n\n       case \"scheme data\":\n        if (\"?\" == c) {\n          this._query = \"?\";\n          state = \"query\";\n        } else if (\"#\" == c) {\n          this._fragment = \"#\";\n          state = \"fragment\";\n        } else {\n          if (EOF != c && \"\t\" != c && \"\\n\" != c && \"\\r\" != c) {\n            this._schemeData += percentEscape(c);\n          }\n        }\n        break;\n\n       case \"no scheme\":\n        if (!base || !isRelativeScheme(base._scheme)) {\n          err(\"Missing scheme.\");\n          invalid.call(this);\n        } else {\n          state = \"relative\";\n          continue;\n        }\n        break;\n\n       case \"relative or authority\":\n        if (\"/\" == c && \"/\" == input[cursor + 1]) {\n          state = \"authority ignore slashes\";\n        } else {\n          err(\"Expected /, got: \" + c);\n          state = \"relative\";\n          continue;\n        }\n        break;\n\n       case \"relative\":\n        this._isRelative = true;\n        if (\"file\" != this._scheme) this._scheme = base._scheme;\n        if (EOF == c) {\n          this._host = base._host;\n          this._port = base._port;\n          this._path = base._path.slice();\n          this._query = base._query;\n          this._username = base._username;\n          this._password = base._password;\n          break loop;\n        } else if (\"/\" == c || \"\\\\\" == c) {\n          if (\"\\\\\" == c) err(\"\\\\ is an invalid code point.\");\n          state = \"relative slash\";\n        } else if (\"?\" == c) {\n          this._host = base._host;\n          this._port = base._port;\n          this._path = base._path.slice();\n          this._query = \"?\";\n          this._username = base._username;\n          this._password = base._password;\n          state = \"query\";\n        } else if (\"#\" == c) {\n          this._host = base._host;\n          this._port = base._port;\n          this._path = base._path.slice();\n          this._query = base._query;\n          this._fragment = \"#\";\n          this._username = base._username;\n          this._password = base._password;\n          state = \"fragment\";\n        } else {\n          var nextC = input[cursor + 1];\n          var nextNextC = input[cursor + 2];\n          if (\"file\" != this._scheme || !ALPHA.test(c) || nextC != \":\" && nextC != \"|\" || EOF != nextNextC && \"/\" != nextNextC && \"\\\\\" != nextNextC && \"?\" != nextNextC && \"#\" != nextNextC) {\n            this._host = base._host;\n            this._port = base._port;\n            this._username = base._username;\n            this._password = base._password;\n            this._path = base._path.slice();\n            this._path.pop();\n          }\n          state = \"relative path\";\n          continue;\n        }\n        break;\n\n       case \"relative slash\":\n        if (\"/\" == c || \"\\\\\" == c) {\n          if (\"\\\\\" == c) {\n            err(\"\\\\ is an invalid code point.\");\n          }\n          if (\"file\" == this._scheme) {\n            state = \"file host\";\n          } else {\n            state = \"authority ignore slashes\";\n          }\n        } else {\n          if (\"file\" != this._scheme) {\n            this._host = base._host;\n            this._port = base._port;\n            this._username = base._username;\n            this._password = base._password;\n          }\n          state = \"relative path\";\n          continue;\n        }\n        break;\n\n       case \"authority first slash\":\n        if (\"/\" == c) {\n          state = \"authority second slash\";\n        } else {\n          err(\"Expected '/', got: \" + c);\n          state = \"authority ignore slashes\";\n          continue;\n        }\n        break;\n\n       case \"authority second slash\":\n        state = \"authority ignore slashes\";\n        if (\"/\" != c) {\n          err(\"Expected '/', got: \" + c);\n          continue;\n        }\n        break;\n\n       case \"authority ignore slashes\":\n        if (\"/\" != c && \"\\\\\" != c) {\n          state = \"authority\";\n          continue;\n        } else {\n          err(\"Expected authority, got: \" + c);\n        }\n        break;\n\n       case \"authority\":\n        if (\"@\" == c) {\n          if (seenAt) {\n            err(\"@ already seen.\");\n            buffer += \"%40\";\n          }\n          seenAt = true;\n          for (var i = 0; i < buffer.length; i++) {\n            var cp = buffer[i];\n            if (\"\t\" == cp || \"\\n\" == cp || \"\\r\" == cp) {\n              err(\"Invalid whitespace in authority.\");\n              continue;\n            }\n            if (\":\" == cp && null === this._password) {\n              this._password = \"\";\n              continue;\n            }\n            var tempC = percentEscape(cp);\n            null !== this._password ? this._password += tempC : this._username += tempC;\n          }\n          buffer = \"\";\n        } else if (EOF == c || \"/\" == c || \"\\\\\" == c || \"?\" == c || \"#\" == c) {\n          cursor -= buffer.length;\n          buffer = \"\";\n          state = \"host\";\n          continue;\n        } else {\n          buffer += c;\n        }\n        break;\n\n       case \"file host\":\n        if (EOF == c || \"/\" == c || \"\\\\\" == c || \"?\" == c || \"#\" == c) {\n          if (buffer.length == 2 && ALPHA.test(buffer[0]) && (buffer[1] == \":\" || buffer[1] == \"|\")) {\n            state = \"relative path\";\n          } else if (buffer.length == 0) {\n            state = \"relative path start\";\n          } else {\n            this._host = IDNAToASCII.call(this, buffer);\n            buffer = \"\";\n            state = \"relative path start\";\n          }\n          continue;\n        } else if (\"\t\" == c || \"\\n\" == c || \"\\r\" == c) {\n          err(\"Invalid whitespace in file host.\");\n        } else {\n          buffer += c;\n        }\n        break;\n\n       case \"host\":\n       case \"hostname\":\n        if (\":\" == c && !seenBracket) {\n          this._host = IDNAToASCII.call(this, buffer);\n          buffer = \"\";\n          state = \"port\";\n          if (\"hostname\" == stateOverride) {\n            break loop;\n          }\n        } else if (EOF == c || \"/\" == c || \"\\\\\" == c || \"?\" == c || \"#\" == c) {\n          this._host = IDNAToASCII.call(this, buffer);\n          buffer = \"\";\n          state = \"relative path start\";\n          if (stateOverride) {\n            break loop;\n          }\n          continue;\n        } else if (\"\t\" != c && \"\\n\" != c && \"\\r\" != c) {\n          if (\"[\" == c) {\n            seenBracket = true;\n          } else if (\"]\" == c) {\n            seenBracket = false;\n          }\n          buffer += c;\n        } else {\n          err(\"Invalid code point in host/hostname: \" + c);\n        }\n        break;\n\n       case \"port\":\n        if (/[0-9]/.test(c)) {\n          buffer += c;\n        } else if (EOF == c || \"/\" == c || \"\\\\\" == c || \"?\" == c || \"#\" == c || stateOverride) {\n          if (\"\" != buffer) {\n            var temp = parseInt(buffer, 10);\n            if (temp != relative[this._scheme]) {\n              this._port = temp + \"\";\n            }\n            buffer = \"\";\n          }\n          if (stateOverride) {\n            break loop;\n          }\n          state = \"relative path start\";\n          continue;\n        } else if (\"\t\" == c || \"\\n\" == c || \"\\r\" == c) {\n          err(\"Invalid code point in port: \" + c);\n        } else {\n          invalid.call(this);\n        }\n        break;\n\n       case \"relative path start\":\n        if (\"\\\\\" == c) err(\"'\\\\' not allowed in path.\");\n        state = \"relative path\";\n        if (\"/\" != c && \"\\\\\" != c) {\n          continue;\n        }\n        break;\n\n       case \"relative path\":\n        if (EOF == c || \"/\" == c || \"\\\\\" == c || !stateOverride && (\"?\" == c || \"#\" == c)) {\n          if (\"\\\\\" == c) {\n            err(\"\\\\ not allowed in relative path.\");\n          }\n          var tmp;\n          if (tmp = relativePathDotMapping[buffer.toLowerCase()]) {\n            buffer = tmp;\n          }\n          if (\"..\" == buffer) {\n            this._path.pop();\n            if (\"/\" != c && \"\\\\\" != c) {\n              this._path.push(\"\");\n            }\n          } else if (\".\" == buffer && \"/\" != c && \"\\\\\" != c) {\n            this._path.push(\"\");\n          } else if (\".\" != buffer) {\n            if (\"file\" == this._scheme && this._path.length == 0 && buffer.length == 2 && ALPHA.test(buffer[0]) && buffer[1] == \"|\") {\n              buffer = buffer[0] + \":\";\n            }\n            this._path.push(buffer);\n          }\n          buffer = \"\";\n          if (\"?\" == c) {\n            this._query = \"?\";\n            state = \"query\";\n          } else if (\"#\" == c) {\n            this._fragment = \"#\";\n            state = \"fragment\";\n          }\n        } else if (\"\t\" != c && \"\\n\" != c && \"\\r\" != c) {\n          buffer += percentEscape(c);\n        }\n        break;\n\n       case \"query\":\n        if (!stateOverride && \"#\" == c) {\n          this._fragment = \"#\";\n          state = \"fragment\";\n        } else if (EOF != c && \"\t\" != c && \"\\n\" != c && \"\\r\" != c) {\n          this._query += percentEscapeQuery(c);\n        }\n        break;\n\n       case \"fragment\":\n        if (EOF != c && \"\t\" != c && \"\\n\" != c && \"\\r\" != c) {\n          this._fragment += c;\n        }\n        break;\n      }\n      cursor++;\n    }\n  }\n  function clear() {\n    this._scheme = \"\";\n    this._schemeData = \"\";\n    this._username = \"\";\n    this._password = null;\n    this._host = \"\";\n    this._port = \"\";\n    this._path = [];\n    this._query = \"\";\n    this._fragment = \"\";\n    this._isInvalid = false;\n    this._isRelative = false;\n  }\n  function jURL(url, base) {\n    if (base !== undefined && !(base instanceof jURL)) base = new jURL(String(base));\n    this._url = url;\n    clear.call(this);\n    var input = url.replace(/^[ \\t\\r\\n\\f]+|[ \\t\\r\\n\\f]+$/g, \"\");\n    parse.call(this, input, null, base);\n  }\n  jURL.prototype = {\n    toString: function() {\n      return this.href;\n    },\n    get href() {\n      if (this._isInvalid) return this._url;\n      var authority = \"\";\n      if (\"\" != this._username || null != this._password) {\n        authority = this._username + (null != this._password ? \":\" + this._password : \"\") + \"@\";\n      }\n      return this.protocol + (this._isRelative ? \"//\" + authority + this.host : \"\") + this.pathname + this._query + this._fragment;\n    },\n    set href(href) {\n      clear.call(this);\n      parse.call(this, href);\n    },\n    get protocol() {\n      return this._scheme + \":\";\n    },\n    set protocol(protocol) {\n      if (this._isInvalid) return;\n      parse.call(this, protocol + \":\", \"scheme start\");\n    },\n    get host() {\n      return this._isInvalid ? \"\" : this._port ? this._host + \":\" + this._port : this._host;\n    },\n    set host(host) {\n      if (this._isInvalid || !this._isRelative) return;\n      parse.call(this, host, \"host\");\n    },\n    get hostname() {\n      return this._host;\n    },\n    set hostname(hostname) {\n      if (this._isInvalid || !this._isRelative) return;\n      parse.call(this, hostname, \"hostname\");\n    },\n    get port() {\n      return this._port;\n    },\n    set port(port) {\n      if (this._isInvalid || !this._isRelative) return;\n      parse.call(this, port, \"port\");\n    },\n    get pathname() {\n      return this._isInvalid ? \"\" : this._isRelative ? \"/\" + this._path.join(\"/\") : this._schemeData;\n    },\n    set pathname(pathname) {\n      if (this._isInvalid || !this._isRelative) return;\n      this._path = [];\n      parse.call(this, pathname, \"relative path start\");\n    },\n    get search() {\n      return this._isInvalid || !this._query || \"?\" == this._query ? \"\" : this._query;\n    },\n    set search(search) {\n      if (this._isInvalid || !this._isRelative) return;\n      this._query = \"?\";\n      if (\"?\" == search[0]) search = search.slice(1);\n      parse.call(this, search, \"query\");\n    },\n    get hash() {\n      return this._isInvalid || !this._fragment || \"#\" == this._fragment ? \"\" : this._fragment;\n    },\n    set hash(hash) {\n      if (this._isInvalid) return;\n      this._fragment = \"#\";\n      if (\"#\" == hash[0]) hash = hash.slice(1);\n      parse.call(this, hash, \"fragment\");\n    },\n    get origin() {\n      var host;\n      if (this._isInvalid || !this._scheme) {\n        return \"\";\n      }\n      switch (this._scheme) {\n       case \"data\":\n       case \"file\":\n       case \"javascript\":\n       case \"mailto\":\n        return \"null\";\n      }\n      host = this.host;\n      if (!host) {\n        return \"\";\n      }\n      return this._scheme + \"://\" + host;\n    }\n  };\n  var OriginalURL = scope.URL;\n  if (OriginalURL) {\n    jURL.createObjectURL = function(blob) {\n      return OriginalURL.createObjectURL.apply(OriginalURL, arguments);\n    };\n    jURL.revokeObjectURL = function(url) {\n      OriginalURL.revokeObjectURL(url);\n    };\n  }\n  scope.URL = jURL;\n})(this);\n\n(function(global) {\n  var registrationsTable = new WeakMap();\n  var setImmediate;\n  if (/Trident|Edge/.test(navigator.userAgent)) {\n    setImmediate = setTimeout;\n  } else if (window.setImmediate) {\n    setImmediate = window.setImmediate;\n  } else {\n    var setImmediateQueue = [];\n    var sentinel = String(Math.random());\n    window.addEventListener(\"message\", function(e) {\n      if (e.data === sentinel) {\n        var queue = setImmediateQueue;\n        setImmediateQueue = [];\n        queue.forEach(function(func) {\n          func();\n        });\n      }\n    });\n    setImmediate = function(func) {\n      setImmediateQueue.push(func);\n      window.postMessage(sentinel, \"*\");\n    };\n  }\n  var isScheduled = false;\n  var scheduledObservers = [];\n  function scheduleCallback(observer) {\n    scheduledObservers.push(observer);\n    if (!isScheduled) {\n      isScheduled = true;\n      setImmediate(dispatchCallbacks);\n    }\n  }\n  function wrapIfNeeded(node) {\n    return window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrapIfNeeded(node) || node;\n  }\n  function dispatchCallbacks() {\n    isScheduled = false;\n    var observers = scheduledObservers;\n    scheduledObservers = [];\n    observers.sort(function(o1, o2) {\n      return o1.uid_ - o2.uid_;\n    });\n    var anyNonEmpty = false;\n    observers.forEach(function(observer) {\n      var queue = observer.takeRecords();\n      removeTransientObserversFor(observer);\n      if (queue.length) {\n        observer.callback_(queue, observer);\n        anyNonEmpty = true;\n      }\n    });\n    if (anyNonEmpty) dispatchCallbacks();\n  }\n  function removeTransientObserversFor(observer) {\n    observer.nodes_.forEach(function(node) {\n      var registrations = registrationsTable.get(node);\n      if (!registrations) return;\n      registrations.forEach(function(registration) {\n        if (registration.observer === observer) registration.removeTransientObservers();\n      });\n    });\n  }\n  function forEachAncestorAndObserverEnqueueRecord(target, callback) {\n    for (var node = target; node; node = node.parentNode) {\n      var registrations = registrationsTable.get(node);\n      if (registrations) {\n        for (var j = 0; j < registrations.length; j++) {\n          var registration = registrations[j];\n          var options = registration.options;\n          if (node !== target && !options.subtree) continue;\n          var record = callback(options);\n          if (record) registration.enqueue(record);\n        }\n      }\n    }\n  }\n  var uidCounter = 0;\n  function JsMutationObserver(callback) {\n    this.callback_ = callback;\n    this.nodes_ = [];\n    this.records_ = [];\n    this.uid_ = ++uidCounter;\n  }\n  JsMutationObserver.prototype = {\n    observe: function(target, options) {\n      target = wrapIfNeeded(target);\n      if (!options.childList && !options.attributes && !options.characterData || options.attributeOldValue && !options.attributes || options.attributeFilter && options.attributeFilter.length && !options.attributes || options.characterDataOldValue && !options.characterData) {\n        throw new SyntaxError();\n      }\n      var registrations = registrationsTable.get(target);\n      if (!registrations) registrationsTable.set(target, registrations = []);\n      var registration;\n      for (var i = 0; i < registrations.length; i++) {\n        if (registrations[i].observer === this) {\n          registration = registrations[i];\n          registration.removeListeners();\n          registration.options = options;\n          break;\n        }\n      }\n      if (!registration) {\n        registration = new Registration(this, target, options);\n        registrations.push(registration);\n        this.nodes_.push(target);\n      }\n      registration.addListeners();\n    },\n    disconnect: function() {\n      this.nodes_.forEach(function(node) {\n        var registrations = registrationsTable.get(node);\n        for (var i = 0; i < registrations.length; i++) {\n          var registration = registrations[i];\n          if (registration.observer === this) {\n            registration.removeListeners();\n            registrations.splice(i, 1);\n            break;\n          }\n        }\n      }, this);\n      this.records_ = [];\n    },\n    takeRecords: function() {\n      var copyOfRecords = this.records_;\n      this.records_ = [];\n      return copyOfRecords;\n    }\n  };\n  function MutationRecord(type, target) {\n    this.type = type;\n    this.target = target;\n    this.addedNodes = [];\n    this.removedNodes = [];\n    this.previousSibling = null;\n    this.nextSibling = null;\n    this.attributeName = null;\n    this.attributeNamespace = null;\n    this.oldValue = null;\n  }\n  function copyMutationRecord(original) {\n    var record = new MutationRecord(original.type, original.target);\n    record.addedNodes = original.addedNodes.slice();\n    record.removedNodes = original.removedNodes.slice();\n    record.previousSibling = original.previousSibling;\n    record.nextSibling = original.nextSibling;\n    record.attributeName = original.attributeName;\n    record.attributeNamespace = original.attributeNamespace;\n    record.oldValue = original.oldValue;\n    return record;\n  }\n  var currentRecord, recordWithOldValue;\n  function getRecord(type, target) {\n    return currentRecord = new MutationRecord(type, target);\n  }\n  function getRecordWithOldValue(oldValue) {\n    if (recordWithOldValue) return recordWithOldValue;\n    recordWithOldValue = copyMutationRecord(currentRecord);\n    recordWithOldValue.oldValue = oldValue;\n    return recordWithOldValue;\n  }\n  function clearRecords() {\n    currentRecord = recordWithOldValue = undefined;\n  }\n  function recordRepresentsCurrentMutation(record) {\n    return record === recordWithOldValue || record === currentRecord;\n  }\n  function selectRecord(lastRecord, newRecord) {\n    if (lastRecord === newRecord) return lastRecord;\n    if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord)) return recordWithOldValue;\n    return null;\n  }\n  function Registration(observer, target, options) {\n    this.observer = observer;\n    this.target = target;\n    this.options = options;\n    this.transientObservedNodes = [];\n  }\n  Registration.prototype = {\n    enqueue: function(record) {\n      var records = this.observer.records_;\n      var length = records.length;\n      if (records.length > 0) {\n        var lastRecord = records[length - 1];\n        var recordToReplaceLast = selectRecord(lastRecord, record);\n        if (recordToReplaceLast) {\n          records[length - 1] = recordToReplaceLast;\n          return;\n        }\n      } else {\n        scheduleCallback(this.observer);\n      }\n      records[length] = record;\n    },\n    addListeners: function() {\n      this.addListeners_(this.target);\n    },\n    addListeners_: function(node) {\n      var options = this.options;\n      if (options.attributes) node.addEventListener(\"DOMAttrModified\", this, true);\n      if (options.characterData) node.addEventListener(\"DOMCharacterDataModified\", this, true);\n      if (options.childList) node.addEventListener(\"DOMNodeInserted\", this, true);\n      if (options.childList || options.subtree) node.addEventListener(\"DOMNodeRemoved\", this, true);\n    },\n    removeListeners: function() {\n      this.removeListeners_(this.target);\n    },\n    removeListeners_: function(node) {\n      var options = this.options;\n      if (options.attributes) node.removeEventListener(\"DOMAttrModified\", this, true);\n      if (options.characterData) node.removeEventListener(\"DOMCharacterDataModified\", this, true);\n      if (options.childList) node.removeEventListener(\"DOMNodeInserted\", this, true);\n      if (options.childList || options.subtree) node.removeEventListener(\"DOMNodeRemoved\", this, true);\n    },\n    addTransientObserver: function(node) {\n      if (node === this.target) return;\n      this.addListeners_(node);\n      this.transientObservedNodes.push(node);\n      var registrations = registrationsTable.get(node);\n      if (!registrations) registrationsTable.set(node, registrations = []);\n      registrations.push(this);\n    },\n    removeTransientObservers: function() {\n      var transientObservedNodes = this.transientObservedNodes;\n      this.transientObservedNodes = [];\n      transientObservedNodes.forEach(function(node) {\n        this.removeListeners_(node);\n        var registrations = registrationsTable.get(node);\n        for (var i = 0; i < registrations.length; i++) {\n          if (registrations[i] === this) {\n            registrations.splice(i, 1);\n            break;\n          }\n        }\n      }, this);\n    },\n    handleEvent: function(e) {\n      e.stopImmediatePropagation();\n      switch (e.type) {\n       case \"DOMAttrModified\":\n        var name = e.attrName;\n        var namespace = e.relatedNode.namespaceURI;\n        var target = e.target;\n        var record = new getRecord(\"attributes\", target);\n        record.attributeName = name;\n        record.attributeNamespace = namespace;\n        var oldValue = e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;\n        forEachAncestorAndObserverEnqueueRecord(target, function(options) {\n          if (!options.attributes) return;\n          if (options.attributeFilter && options.attributeFilter.length && options.attributeFilter.indexOf(name) === -1 && options.attributeFilter.indexOf(namespace) === -1) {\n            return;\n          }\n          if (options.attributeOldValue) return getRecordWithOldValue(oldValue);\n          return record;\n        });\n        break;\n\n       case \"DOMCharacterDataModified\":\n        var target = e.target;\n        var record = getRecord(\"characterData\", target);\n        var oldValue = e.prevValue;\n        forEachAncestorAndObserverEnqueueRecord(target, function(options) {\n          if (!options.characterData) return;\n          if (options.characterDataOldValue) return getRecordWithOldValue(oldValue);\n          return record;\n        });\n        break;\n\n       case \"DOMNodeRemoved\":\n        this.addTransientObserver(e.target);\n\n       case \"DOMNodeInserted\":\n        var changedNode = e.target;\n        var addedNodes, removedNodes;\n        if (e.type === \"DOMNodeInserted\") {\n          addedNodes = [ changedNode ];\n          removedNodes = [];\n        } else {\n          addedNodes = [];\n          removedNodes = [ changedNode ];\n        }\n        var previousSibling = changedNode.previousSibling;\n        var nextSibling = changedNode.nextSibling;\n        var record = getRecord(\"childList\", e.target.parentNode);\n        record.addedNodes = addedNodes;\n        record.removedNodes = removedNodes;\n        record.previousSibling = previousSibling;\n        record.nextSibling = nextSibling;\n        forEachAncestorAndObserverEnqueueRecord(e.relatedNode, function(options) {\n          if (!options.childList) return;\n          return record;\n        });\n      }\n      clearRecords();\n    }\n  };\n  global.JsMutationObserver = JsMutationObserver;\n  if (!global.MutationObserver) global.MutationObserver = JsMutationObserver;\n})(this);\n\nwindow.HTMLImports = window.HTMLImports || {\n  flags: {}\n};\n\n(function(scope) {\n  var IMPORT_LINK_TYPE = \"import\";\n  var useNative = Boolean(IMPORT_LINK_TYPE in document.createElement(\"link\"));\n  var hasShadowDOMPolyfill = Boolean(window.ShadowDOMPolyfill);\n  var wrap = function(node) {\n    return hasShadowDOMPolyfill ? window.ShadowDOMPolyfill.wrapIfNeeded(node) : node;\n  };\n  var rootDocument = wrap(document);\n  var currentScriptDescriptor = {\n    get: function() {\n      var script = window.HTMLImports.currentScript || document.currentScript || (document.readyState !== \"complete\" ? document.scripts[document.scripts.length - 1] : null);\n      return wrap(script);\n    },\n    configurable: true\n  };\n  Object.defineProperty(document, \"_currentScript\", currentScriptDescriptor);\n  Object.defineProperty(rootDocument, \"_currentScript\", currentScriptDescriptor);\n  var isIE = /Trident/.test(navigator.userAgent);\n  function whenReady(callback, doc) {\n    doc = doc || rootDocument;\n    whenDocumentReady(function() {\n      watchImportsLoad(callback, doc);\n    }, doc);\n  }\n  var requiredReadyState = isIE ? \"complete\" : \"interactive\";\n  var READY_EVENT = \"readystatechange\";\n  function isDocumentReady(doc) {\n    return doc.readyState === \"complete\" || doc.readyState === requiredReadyState;\n  }\n  function whenDocumentReady(callback, doc) {\n    if (!isDocumentReady(doc)) {\n      var checkReady = function() {\n        if (doc.readyState === \"complete\" || doc.readyState === requiredReadyState) {\n          doc.removeEventListener(READY_EVENT, checkReady);\n          whenDocumentReady(callback, doc);\n        }\n      };\n      doc.addEventListener(READY_EVENT, checkReady);\n    } else if (callback) {\n      callback();\n    }\n  }\n  function markTargetLoaded(event) {\n    event.target.__loaded = true;\n  }\n  function watchImportsLoad(callback, doc) {\n    var imports = doc.querySelectorAll(\"link[rel=import]\");\n    var parsedCount = 0, importCount = imports.length, newImports = [], errorImports = [];\n    function checkDone() {\n      if (parsedCount == importCount && callback) {\n        callback({\n          allImports: imports,\n          loadedImports: newImports,\n          errorImports: errorImports\n        });\n      }\n    }\n    function loadedImport(e) {\n      markTargetLoaded(e);\n      newImports.push(this);\n      parsedCount++;\n      checkDone();\n    }\n    function errorLoadingImport(e) {\n      errorImports.push(this);\n      parsedCount++;\n      checkDone();\n    }\n    if (importCount) {\n      for (var i = 0, imp; i < importCount && (imp = imports[i]); i++) {\n        if (isImportLoaded(imp)) {\n          parsedCount++;\n          checkDone();\n        } else {\n          imp.addEventListener(\"load\", loadedImport);\n          imp.addEventListener(\"error\", errorLoadingImport);\n        }\n      }\n    } else {\n      checkDone();\n    }\n  }\n  function isImportLoaded(link) {\n    return useNative ? link.__loaded || link.import && link.import.readyState !== \"loading\" : link.__importParsed;\n  }\n  if (useNative) {\n    new MutationObserver(function(mxns) {\n      for (var i = 0, l = mxns.length, m; i < l && (m = mxns[i]); i++) {\n        if (m.addedNodes) {\n          handleImports(m.addedNodes);\n        }\n      }\n    }).observe(document.head, {\n      childList: true\n    });\n    function handleImports(nodes) {\n      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {\n        if (isImport(n)) {\n          handleImport(n);\n        }\n      }\n    }\n    function isImport(element) {\n      return element.localName === \"link\" && element.rel === \"import\";\n    }\n    function handleImport(element) {\n      var loaded = element.import;\n      if (loaded) {\n        markTargetLoaded({\n          target: element\n        });\n      } else {\n        element.addEventListener(\"load\", markTargetLoaded);\n        element.addEventListener(\"error\", markTargetLoaded);\n      }\n    }\n    (function() {\n      if (document.readyState === \"loading\") {\n        var imports = document.querySelectorAll(\"link[rel=import]\");\n        for (var i = 0, l = imports.length, imp; i < l && (imp = imports[i]); i++) {\n          handleImport(imp);\n        }\n      }\n    })();\n  }\n  whenReady(function(detail) {\n    window.HTMLImports.ready = true;\n    window.HTMLImports.readyTime = new Date().getTime();\n    var evt = rootDocument.createEvent(\"CustomEvent\");\n    evt.initCustomEvent(\"HTMLImportsLoaded\", true, true, detail);\n    rootDocument.dispatchEvent(evt);\n  });\n  scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;\n  scope.useNative = useNative;\n  scope.rootDocument = rootDocument;\n  scope.whenReady = whenReady;\n  scope.isIE = isIE;\n})(window.HTMLImports);\n\n(function(scope) {\n  var modules = [];\n  var addModule = function(module) {\n    modules.push(module);\n  };\n  var initializeModules = function() {\n    modules.forEach(function(module) {\n      module(scope);\n    });\n  };\n  scope.addModule = addModule;\n  scope.initializeModules = initializeModules;\n})(window.HTMLImports);\n\nwindow.HTMLImports.addModule(function(scope) {\n  var CSS_URL_REGEXP = /(url\\()([^)]*)(\\))/g;\n  var CSS_IMPORT_REGEXP = /(@import[\\s]+(?!url\\())([^;]*)(;)/g;\n  var path = {\n    resolveUrlsInStyle: function(style, linkUrl) {\n      var doc = style.ownerDocument;\n      var resolver = doc.createElement(\"a\");\n      style.textContent = this.resolveUrlsInCssText(style.textContent, linkUrl, resolver);\n      return style;\n    },\n    resolveUrlsInCssText: function(cssText, linkUrl, urlObj) {\n      var r = this.replaceUrls(cssText, urlObj, linkUrl, CSS_URL_REGEXP);\n      r = this.replaceUrls(r, urlObj, linkUrl, CSS_IMPORT_REGEXP);\n      return r;\n    },\n    replaceUrls: function(text, urlObj, linkUrl, regexp) {\n      return text.replace(regexp, function(m, pre, url, post) {\n        var urlPath = url.replace(/[\"']/g, \"\");\n        if (linkUrl) {\n          urlPath = new URL(urlPath, linkUrl).href;\n        }\n        urlObj.href = urlPath;\n        urlPath = urlObj.href;\n        return pre + \"'\" + urlPath + \"'\" + post;\n      });\n    }\n  };\n  scope.path = path;\n});\n\nwindow.HTMLImports.addModule(function(scope) {\n  var xhr = {\n    async: true,\n    ok: function(request) {\n      return request.status >= 200 && request.status < 300 || request.status === 304 || request.status === 0;\n    },\n    load: function(url, next, nextContext) {\n      var request = new XMLHttpRequest();\n      if (scope.flags.debug || scope.flags.bust) {\n        url += \"?\" + Math.random();\n      }\n      request.open(\"GET\", url, xhr.async);\n      request.addEventListener(\"readystatechange\", function(e) {\n        if (request.readyState === 4) {\n          var locationHeader = request.getResponseHeader(\"Location\");\n          var redirectedUrl = null;\n          if (locationHeader) {\n            var redirectedUrl = locationHeader.substr(0, 1) === \"/\" ? location.origin + locationHeader : locationHeader;\n          }\n          next.call(nextContext, !xhr.ok(request) && request, request.response || request.responseText, redirectedUrl);\n        }\n      });\n      request.send();\n      return request;\n    },\n    loadDocument: function(url, next, nextContext) {\n      this.load(url, next, nextContext).responseType = \"document\";\n    }\n  };\n  scope.xhr = xhr;\n});\n\nwindow.HTMLImports.addModule(function(scope) {\n  var xhr = scope.xhr;\n  var flags = scope.flags;\n  var Loader = function(onLoad, onComplete) {\n    this.cache = {};\n    this.onload = onLoad;\n    this.oncomplete = onComplete;\n    this.inflight = 0;\n    this.pending = {};\n  };\n  Loader.prototype = {\n    addNodes: function(nodes) {\n      this.inflight += nodes.length;\n      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {\n        this.require(n);\n      }\n      this.checkDone();\n    },\n    addNode: function(node) {\n      this.inflight++;\n      this.require(node);\n      this.checkDone();\n    },\n    require: function(elt) {\n      var url = elt.src || elt.href;\n      elt.__nodeUrl = url;\n      if (!this.dedupe(url, elt)) {\n        this.fetch(url, elt);\n      }\n    },\n    dedupe: function(url, elt) {\n      if (this.pending[url]) {\n        this.pending[url].push(elt);\n        return true;\n      }\n      var resource;\n      if (this.cache[url]) {\n        this.onload(url, elt, this.cache[url]);\n        this.tail();\n        return true;\n      }\n      this.pending[url] = [ elt ];\n      return false;\n    },\n    fetch: function(url, elt) {\n      flags.load && console.log(\"fetch\", url, elt);\n      if (!url) {\n        setTimeout(function() {\n          this.receive(url, elt, {\n            error: \"href must be specified\"\n          }, null);\n        }.bind(this), 0);\n      } else if (url.match(/^data:/)) {\n        var pieces = url.split(\",\");\n        var header = pieces[0];\n        var body = pieces[1];\n        if (header.indexOf(\";base64\") > -1) {\n          body = atob(body);\n        } else {\n          body = decodeURIComponent(body);\n        }\n        setTimeout(function() {\n          this.receive(url, elt, null, body);\n        }.bind(this), 0);\n      } else {\n        var receiveXhr = function(err, resource, redirectedUrl) {\n          this.receive(url, elt, err, resource, redirectedUrl);\n        }.bind(this);\n        xhr.load(url, receiveXhr);\n      }\n    },\n    receive: function(url, elt, err, resource, redirectedUrl) {\n      this.cache[url] = resource;\n      var $p = this.pending[url];\n      for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {\n        this.onload(url, p, resource, err, redirectedUrl);\n        this.tail();\n      }\n      this.pending[url] = null;\n    },\n    tail: function() {\n      --this.inflight;\n      this.checkDone();\n    },\n    checkDone: function() {\n      if (!this.inflight) {\n        this.oncomplete();\n      }\n    }\n  };\n  scope.Loader = Loader;\n});\n\nwindow.HTMLImports.addModule(function(scope) {\n  var Observer = function(addCallback) {\n    this.addCallback = addCallback;\n    this.mo = new MutationObserver(this.handler.bind(this));\n  };\n  Observer.prototype = {\n    handler: function(mutations) {\n      for (var i = 0, l = mutations.length, m; i < l && (m = mutations[i]); i++) {\n        if (m.type === \"childList\" && m.addedNodes.length) {\n          this.addedNodes(m.addedNodes);\n        }\n      }\n    },\n    addedNodes: function(nodes) {\n      if (this.addCallback) {\n        this.addCallback(nodes);\n      }\n      for (var i = 0, l = nodes.length, n, loading; i < l && (n = nodes[i]); i++) {\n        if (n.children && n.children.length) {\n          this.addedNodes(n.children);\n        }\n      }\n    },\n    observe: function(root) {\n      this.mo.observe(root, {\n        childList: true,\n        subtree: true\n      });\n    }\n  };\n  scope.Observer = Observer;\n});\n\nwindow.HTMLImports.addModule(function(scope) {\n  var path = scope.path;\n  var rootDocument = scope.rootDocument;\n  var flags = scope.flags;\n  var isIE = scope.isIE;\n  var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;\n  var IMPORT_SELECTOR = \"link[rel=\" + IMPORT_LINK_TYPE + \"]\";\n  var importParser = {\n    documentSelectors: IMPORT_SELECTOR,\n    importsSelectors: [ IMPORT_SELECTOR, \"link[rel=stylesheet]:not([type])\", \"style:not([type])\", \"script:not([type])\", 'script[type=\"application/javascript\"]', 'script[type=\"text/javascript\"]' ].join(\",\"),\n    map: {\n      link: \"parseLink\",\n      script: \"parseScript\",\n      style: \"parseStyle\"\n    },\n    dynamicElements: [],\n    parseNext: function() {\n      var next = this.nextToParse();\n      if (next) {\n        this.parse(next);\n      }\n    },\n    parse: function(elt) {\n      if (this.isParsed(elt)) {\n        flags.parse && console.log(\"[%s] is already parsed\", elt.localName);\n        return;\n      }\n      var fn = this[this.map[elt.localName]];\n      if (fn) {\n        this.markParsing(elt);\n        fn.call(this, elt);\n      }\n    },\n    parseDynamic: function(elt, quiet) {\n      this.dynamicElements.push(elt);\n      if (!quiet) {\n        this.parseNext();\n      }\n    },\n    markParsing: function(elt) {\n      flags.parse && console.log(\"parsing\", elt);\n      this.parsingElement = elt;\n    },\n    markParsingComplete: function(elt) {\n      elt.__importParsed = true;\n      this.markDynamicParsingComplete(elt);\n      if (elt.__importElement) {\n        elt.__importElement.__importParsed = true;\n        this.markDynamicParsingComplete(elt.__importElement);\n      }\n      this.parsingElement = null;\n      flags.parse && console.log(\"completed\", elt);\n    },\n    markDynamicParsingComplete: function(elt) {\n      var i = this.dynamicElements.indexOf(elt);\n      if (i >= 0) {\n        this.dynamicElements.splice(i, 1);\n      }\n    },\n    parseImport: function(elt) {\n      elt.import = elt.__doc;\n      if (window.HTMLImports.__importsParsingHook) {\n        window.HTMLImports.__importsParsingHook(elt);\n      }\n      if (elt.import) {\n        elt.import.__importParsed = true;\n      }\n      this.markParsingComplete(elt);\n      if (elt.__resource && !elt.__error) {\n        elt.dispatchEvent(new CustomEvent(\"load\", {\n          bubbles: false\n        }));\n      } else {\n        elt.dispatchEvent(new CustomEvent(\"error\", {\n          bubbles: false\n        }));\n      }\n      if (elt.__pending) {\n        var fn;\n        while (elt.__pending.length) {\n          fn = elt.__pending.shift();\n          if (fn) {\n            fn({\n              target: elt\n            });\n          }\n        }\n      }\n      this.parseNext();\n    },\n    parseLink: function(linkElt) {\n      if (nodeIsImport(linkElt)) {\n        this.parseImport(linkElt);\n      } else {\n        linkElt.href = linkElt.href;\n        this.parseGeneric(linkElt);\n      }\n    },\n    parseStyle: function(elt) {\n      var src = elt;\n      elt = cloneStyle(elt);\n      src.__appliedElement = elt;\n      elt.__importElement = src;\n      this.parseGeneric(elt);\n    },\n    parseGeneric: function(elt) {\n      this.trackElement(elt);\n      this.addElementToDocument(elt);\n    },\n    rootImportForElement: function(elt) {\n      var n = elt;\n      while (n.ownerDocument.__importLink) {\n        n = n.ownerDocument.__importLink;\n      }\n      return n;\n    },\n    addElementToDocument: function(elt) {\n      var port = this.rootImportForElement(elt.__importElement || elt);\n      port.parentNode.insertBefore(elt, port);\n    },\n    trackElement: function(elt, callback) {\n      var self = this;\n      var done = function(e) {\n        elt.removeEventListener(\"load\", done);\n        elt.removeEventListener(\"error\", done);\n        if (callback) {\n          callback(e);\n        }\n        self.markParsingComplete(elt);\n        self.parseNext();\n      };\n      elt.addEventListener(\"load\", done);\n      elt.addEventListener(\"error\", done);\n      if (isIE && elt.localName === \"style\") {\n        var fakeLoad = false;\n        if (elt.textContent.indexOf(\"@import\") == -1) {\n          fakeLoad = true;\n        } else if (elt.sheet) {\n          fakeLoad = true;\n          var csr = elt.sheet.cssRules;\n          var len = csr ? csr.length : 0;\n          for (var i = 0, r; i < len && (r = csr[i]); i++) {\n            if (r.type === CSSRule.IMPORT_RULE) {\n              fakeLoad = fakeLoad && Boolean(r.styleSheet);\n            }\n          }\n        }\n        if (fakeLoad) {\n          setTimeout(function() {\n            elt.dispatchEvent(new CustomEvent(\"load\", {\n              bubbles: false\n            }));\n          });\n        }\n      }\n    },\n    parseScript: function(scriptElt) {\n      var script = document.createElement(\"script\");\n      script.__importElement = scriptElt;\n      script.src = scriptElt.src ? scriptElt.src : generateScriptDataUrl(scriptElt);\n      scope.currentScript = scriptElt;\n      this.trackElement(script, function(e) {\n        if (script.parentNode) {\n          script.parentNode.removeChild(script);\n        }\n        scope.currentScript = null;\n      });\n      this.addElementToDocument(script);\n    },\n    nextToParse: function() {\n      this._mayParse = [];\n      return !this.parsingElement && (this.nextToParseInDoc(rootDocument) || this.nextToParseDynamic());\n    },\n    nextToParseInDoc: function(doc, link) {\n      if (doc && this._mayParse.indexOf(doc) < 0) {\n        this._mayParse.push(doc);\n        var nodes = doc.querySelectorAll(this.parseSelectorsForNode(doc));\n        for (var i = 0, l = nodes.length, p = 0, n; i < l && (n = nodes[i]); i++) {\n          if (!this.isParsed(n)) {\n            if (this.hasResource(n)) {\n              return nodeIsImport(n) ? this.nextToParseInDoc(n.__doc, n) : n;\n            } else {\n              return;\n            }\n          }\n        }\n      }\n      return link;\n    },\n    nextToParseDynamic: function() {\n      return this.dynamicElements[0];\n    },\n    parseSelectorsForNode: function(node) {\n      var doc = node.ownerDocument || node;\n      return doc === rootDocument ? this.documentSelectors : this.importsSelectors;\n    },\n    isParsed: function(node) {\n      return node.__importParsed;\n    },\n    needsDynamicParsing: function(elt) {\n      return this.dynamicElements.indexOf(elt) >= 0;\n    },\n    hasResource: function(node) {\n      if (nodeIsImport(node) && node.__doc === undefined) {\n        return false;\n      }\n      return true;\n    }\n  };\n  function nodeIsImport(elt) {\n    return elt.localName === \"link\" && elt.rel === IMPORT_LINK_TYPE;\n  }\n  function generateScriptDataUrl(script) {\n    var scriptContent = generateScriptContent(script);\n    return \"data:text/javascript;charset=utf-8,\" + encodeURIComponent(scriptContent);\n  }\n  function generateScriptContent(script) {\n    return script.textContent + generateSourceMapHint(script);\n  }\n  function generateSourceMapHint(script) {\n    var owner = script.ownerDocument;\n    owner.__importedScripts = owner.__importedScripts || 0;\n    var moniker = script.ownerDocument.baseURI;\n    var num = owner.__importedScripts ? \"-\" + owner.__importedScripts : \"\";\n    owner.__importedScripts++;\n    return \"\\n//# sourceURL=\" + moniker + num + \".js\\n\";\n  }\n  function cloneStyle(style) {\n    var clone = style.ownerDocument.createElement(\"style\");\n    clone.textContent = style.textContent;\n    path.resolveUrlsInStyle(clone);\n    return clone;\n  }\n  scope.parser = importParser;\n  scope.IMPORT_SELECTOR = IMPORT_SELECTOR;\n});\n\nwindow.HTMLImports.addModule(function(scope) {\n  var flags = scope.flags;\n  var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;\n  var IMPORT_SELECTOR = scope.IMPORT_SELECTOR;\n  var rootDocument = scope.rootDocument;\n  var Loader = scope.Loader;\n  var Observer = scope.Observer;\n  var parser = scope.parser;\n  var importer = {\n    documents: {},\n    documentPreloadSelectors: IMPORT_SELECTOR,\n    importsPreloadSelectors: [ IMPORT_SELECTOR ].join(\",\"),\n    loadNode: function(node) {\n      importLoader.addNode(node);\n    },\n    loadSubtree: function(parent) {\n      var nodes = this.marshalNodes(parent);\n      importLoader.addNodes(nodes);\n    },\n    marshalNodes: function(parent) {\n      return parent.querySelectorAll(this.loadSelectorsForNode(parent));\n    },\n    loadSelectorsForNode: function(node) {\n      var doc = node.ownerDocument || node;\n      return doc === rootDocument ? this.documentPreloadSelectors : this.importsPreloadSelectors;\n    },\n    loaded: function(url, elt, resource, err, redirectedUrl) {\n      flags.load && console.log(\"loaded\", url, elt);\n      elt.__resource = resource;\n      elt.__error = err;\n      if (isImportLink(elt)) {\n        var doc = this.documents[url];\n        if (doc === undefined) {\n          doc = err ? null : makeDocument(resource, redirectedUrl || url);\n          if (doc) {\n            doc.__importLink = elt;\n            this.bootDocument(doc);\n          }\n          this.documents[url] = doc;\n        }\n        elt.__doc = doc;\n      }\n      parser.parseNext();\n    },\n    bootDocument: function(doc) {\n      this.loadSubtree(doc);\n      this.observer.observe(doc);\n      parser.parseNext();\n    },\n    loadedAll: function() {\n      parser.parseNext();\n    }\n  };\n  var importLoader = new Loader(importer.loaded.bind(importer), importer.loadedAll.bind(importer));\n  importer.observer = new Observer();\n  function isImportLink(elt) {\n    return isLinkRel(elt, IMPORT_LINK_TYPE);\n  }\n  function isLinkRel(elt, rel) {\n    return elt.localName === \"link\" && elt.getAttribute(\"rel\") === rel;\n  }\n  function hasBaseURIAccessor(doc) {\n    return !!Object.getOwnPropertyDescriptor(doc, \"baseURI\");\n  }\n  function makeDocument(resource, url) {\n    var doc = document.implementation.createHTMLDocument(IMPORT_LINK_TYPE);\n    doc._URL = url;\n    var base = doc.createElement(\"base\");\n    base.setAttribute(\"href\", url);\n    if (!doc.baseURI && !hasBaseURIAccessor(doc)) {\n      Object.defineProperty(doc, \"baseURI\", {\n        value: url\n      });\n    }\n    var meta = doc.createElement(\"meta\");\n    meta.setAttribute(\"charset\", \"utf-8\");\n    doc.head.appendChild(meta);\n    doc.head.appendChild(base);\n    doc.body.innerHTML = resource;\n    if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {\n      HTMLTemplateElement.bootstrap(doc);\n    }\n    return doc;\n  }\n  if (!document.baseURI) {\n    var baseURIDescriptor = {\n      get: function() {\n        var base = document.querySelector(\"base\");\n        return base ? base.href : window.location.href;\n      },\n      configurable: true\n    };\n    Object.defineProperty(document, \"baseURI\", baseURIDescriptor);\n    Object.defineProperty(rootDocument, \"baseURI\", baseURIDescriptor);\n  }\n  scope.importer = importer;\n  scope.importLoader = importLoader;\n});\n\nwindow.HTMLImports.addModule(function(scope) {\n  var parser = scope.parser;\n  var importer = scope.importer;\n  var dynamic = {\n    added: function(nodes) {\n      var owner, parsed, loading;\n      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {\n        if (!owner) {\n          owner = n.ownerDocument;\n          parsed = parser.isParsed(owner);\n        }\n        loading = this.shouldLoadNode(n);\n        if (loading) {\n          importer.loadNode(n);\n        }\n        if (this.shouldParseNode(n) && parsed) {\n          parser.parseDynamic(n, loading);\n        }\n      }\n    },\n    shouldLoadNode: function(node) {\n      return node.nodeType === 1 && matches.call(node, importer.loadSelectorsForNode(node));\n    },\n    shouldParseNode: function(node) {\n      return node.nodeType === 1 && matches.call(node, parser.parseSelectorsForNode(node));\n    }\n  };\n  importer.observer.addCallback = dynamic.added.bind(dynamic);\n  var matches = HTMLElement.prototype.matches || HTMLElement.prototype.matchesSelector || HTMLElement.prototype.webkitMatchesSelector || HTMLElement.prototype.mozMatchesSelector || HTMLElement.prototype.msMatchesSelector;\n});\n\n(function(scope) {\n  var initializeModules = scope.initializeModules;\n  var isIE = scope.isIE;\n  if (scope.useNative) {\n    return;\n  }\n  if (isIE && typeof window.CustomEvent !== \"function\") {\n    window.CustomEvent = function(inType, params) {\n      params = params || {};\n      var e = document.createEvent(\"CustomEvent\");\n      e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);\n      e.preventDefault = function() {\n        Object.defineProperty(this, \"defaultPrevented\", {\n          get: function() {\n            return true;\n          }\n        });\n      };\n      return e;\n    };\n    window.CustomEvent.prototype = window.Event.prototype;\n  }\n  initializeModules();\n  var rootDocument = scope.rootDocument;\n  function bootstrap() {\n    window.HTMLImports.importer.bootDocument(rootDocument);\n  }\n  if (document.readyState === \"complete\" || document.readyState === \"interactive\" && !window.attachEvent) {\n    bootstrap();\n  } else {\n    document.addEventListener(\"DOMContentLoaded\", bootstrap);\n  }\n})(window.HTMLImports);\n\nwindow.CustomElements = window.CustomElements || {\n  flags: {}\n};\n\n(function(scope) {\n  var flags = scope.flags;\n  var modules = [];\n  var addModule = function(module) {\n    modules.push(module);\n  };\n  var initializeModules = function() {\n    modules.forEach(function(module) {\n      module(scope);\n    });\n  };\n  scope.addModule = addModule;\n  scope.initializeModules = initializeModules;\n  scope.hasNative = Boolean(document.registerElement);\n  scope.useNative = !flags.register && scope.hasNative && !window.ShadowDOMPolyfill && (!window.HTMLImports || window.HTMLImports.useNative);\n})(window.CustomElements);\n\nwindow.CustomElements.addModule(function(scope) {\n  var IMPORT_LINK_TYPE = window.HTMLImports ? window.HTMLImports.IMPORT_LINK_TYPE : \"none\";\n  function forSubtree(node, cb) {\n    findAllElements(node, function(e) {\n      if (cb(e)) {\n        return true;\n      }\n      forRoots(e, cb);\n    });\n    forRoots(node, cb);\n  }\n  function findAllElements(node, find, data) {\n    var e = node.firstElementChild;\n    if (!e) {\n      e = node.firstChild;\n      while (e && e.nodeType !== Node.ELEMENT_NODE) {\n        e = e.nextSibling;\n      }\n    }\n    while (e) {\n      if (find(e, data) !== true) {\n        findAllElements(e, find, data);\n      }\n      e = e.nextElementSibling;\n    }\n    return null;\n  }\n  function forRoots(node, cb) {\n    var root = node.shadowRoot;\n    while (root) {\n      forSubtree(root, cb);\n      root = root.olderShadowRoot;\n    }\n  }\n  function forDocumentTree(doc, cb) {\n    _forDocumentTree(doc, cb, []);\n  }\n  function _forDocumentTree(doc, cb, processingDocuments) {\n    doc = window.wrap(doc);\n    if (processingDocuments.indexOf(doc) >= 0) {\n      return;\n    }\n    processingDocuments.push(doc);\n    var imports = doc.querySelectorAll(\"link[rel=\" + IMPORT_LINK_TYPE + \"]\");\n    for (var i = 0, l = imports.length, n; i < l && (n = imports[i]); i++) {\n      if (n.import) {\n        _forDocumentTree(n.import, cb, processingDocuments);\n      }\n    }\n    cb(doc);\n  }\n  scope.forDocumentTree = forDocumentTree;\n  scope.forSubtree = forSubtree;\n});\n\nwindow.CustomElements.addModule(function(scope) {\n  var flags = scope.flags;\n  var forSubtree = scope.forSubtree;\n  var forDocumentTree = scope.forDocumentTree;\n  function addedNode(node, isAttached) {\n    return added(node, isAttached) || addedSubtree(node, isAttached);\n  }\n  function added(node, isAttached) {\n    if (scope.upgrade(node, isAttached)) {\n      return true;\n    }\n    if (isAttached) {\n      attached(node);\n    }\n  }\n  function addedSubtree(node, isAttached) {\n    forSubtree(node, function(e) {\n      if (added(e, isAttached)) {\n        return true;\n      }\n    });\n  }\n  var hasPolyfillMutations = !window.MutationObserver || window.MutationObserver === window.JsMutationObserver;\n  scope.hasPolyfillMutations = hasPolyfillMutations;\n  var isPendingMutations = false;\n  var pendingMutations = [];\n  function deferMutation(fn) {\n    pendingMutations.push(fn);\n    if (!isPendingMutations) {\n      isPendingMutations = true;\n      setTimeout(takeMutations);\n    }\n  }\n  function takeMutations() {\n    isPendingMutations = false;\n    var $p = pendingMutations;\n    for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {\n      p();\n    }\n    pendingMutations = [];\n  }\n  function attached(element) {\n    if (hasPolyfillMutations) {\n      deferMutation(function() {\n        _attached(element);\n      });\n    } else {\n      _attached(element);\n    }\n  }\n  function _attached(element) {\n    if (element.__upgraded__ && !element.__attached) {\n      element.__attached = true;\n      if (element.attachedCallback) {\n        element.attachedCallback();\n      }\n    }\n  }\n  function detachedNode(node) {\n    detached(node);\n    forSubtree(node, function(e) {\n      detached(e);\n    });\n  }\n  function detached(element) {\n    if (hasPolyfillMutations) {\n      deferMutation(function() {\n        _detached(element);\n      });\n    } else {\n      _detached(element);\n    }\n  }\n  function _detached(element) {\n    if (element.__upgraded__ && element.__attached) {\n      element.__attached = false;\n      if (element.detachedCallback) {\n        element.detachedCallback();\n      }\n    }\n  }\n  function inDocument(element) {\n    var p = element;\n    var doc = window.wrap(document);\n    while (p) {\n      if (p == doc) {\n        return true;\n      }\n      p = p.parentNode || p.nodeType === Node.DOCUMENT_FRAGMENT_NODE && p.host;\n    }\n  }\n  function watchShadow(node) {\n    if (node.shadowRoot && !node.shadowRoot.__watched) {\n      flags.dom && console.log(\"watching shadow-root for: \", node.localName);\n      var root = node.shadowRoot;\n      while (root) {\n        observe(root);\n        root = root.olderShadowRoot;\n      }\n    }\n  }\n  function handler(root, mutations) {\n    if (flags.dom) {\n      var mx = mutations[0];\n      if (mx && mx.type === \"childList\" && mx.addedNodes) {\n        if (mx.addedNodes) {\n          var d = mx.addedNodes[0];\n          while (d && d !== document && !d.host) {\n            d = d.parentNode;\n          }\n          var u = d && (d.URL || d._URL || d.host && d.host.localName) || \"\";\n          u = u.split(\"/?\").shift().split(\"/\").pop();\n        }\n      }\n      console.group(\"mutations (%d) [%s]\", mutations.length, u || \"\");\n    }\n    var isAttached = inDocument(root);\n    mutations.forEach(function(mx) {\n      if (mx.type === \"childList\") {\n        forEach(mx.addedNodes, function(n) {\n          if (!n.localName) {\n            return;\n          }\n          addedNode(n, isAttached);\n        });\n        forEach(mx.removedNodes, function(n) {\n          if (!n.localName) {\n            return;\n          }\n          detachedNode(n);\n        });\n      }\n    });\n    flags.dom && console.groupEnd();\n  }\n  function takeRecords(node) {\n    node = window.wrap(node);\n    if (!node) {\n      node = window.wrap(document);\n    }\n    while (node.parentNode) {\n      node = node.parentNode;\n    }\n    var observer = node.__observer;\n    if (observer) {\n      handler(node, observer.takeRecords());\n      takeMutations();\n    }\n  }\n  var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);\n  function observe(inRoot) {\n    if (inRoot.__observer) {\n      return;\n    }\n    var observer = new MutationObserver(handler.bind(this, inRoot));\n    observer.observe(inRoot, {\n      childList: true,\n      subtree: true\n    });\n    inRoot.__observer = observer;\n  }\n  function upgradeDocument(doc) {\n    doc = window.wrap(doc);\n    flags.dom && console.group(\"upgradeDocument: \", doc.baseURI.split(\"/\").pop());\n    var isMainDocument = doc === window.wrap(document);\n    addedNode(doc, isMainDocument);\n    observe(doc);\n    flags.dom && console.groupEnd();\n  }\n  function upgradeDocumentTree(doc) {\n    forDocumentTree(doc, upgradeDocument);\n  }\n  var originalCreateShadowRoot = Element.prototype.createShadowRoot;\n  if (originalCreateShadowRoot) {\n    Element.prototype.createShadowRoot = function() {\n      var root = originalCreateShadowRoot.call(this);\n      window.CustomElements.watchShadow(this);\n      return root;\n    };\n  }\n  scope.watchShadow = watchShadow;\n  scope.upgradeDocumentTree = upgradeDocumentTree;\n  scope.upgradeDocument = upgradeDocument;\n  scope.upgradeSubtree = addedSubtree;\n  scope.upgradeAll = addedNode;\n  scope.attached = attached;\n  scope.takeRecords = takeRecords;\n});\n\nwindow.CustomElements.addModule(function(scope) {\n  var flags = scope.flags;\n  function upgrade(node, isAttached) {\n    if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) {\n      var is = node.getAttribute(\"is\");\n      var definition = scope.getRegisteredDefinition(node.localName) || scope.getRegisteredDefinition(is);\n      if (definition) {\n        if (is && definition.tag == node.localName || !is && !definition.extends) {\n          return upgradeWithDefinition(node, definition, isAttached);\n        }\n      }\n    }\n  }\n  function upgradeWithDefinition(element, definition, isAttached) {\n    flags.upgrade && console.group(\"upgrade:\", element.localName);\n    if (definition.is) {\n      element.setAttribute(\"is\", definition.is);\n    }\n    implementPrototype(element, definition);\n    element.__upgraded__ = true;\n    created(element);\n    if (isAttached) {\n      scope.attached(element);\n    }\n    scope.upgradeSubtree(element, isAttached);\n    flags.upgrade && console.groupEnd();\n    return element;\n  }\n  function implementPrototype(element, definition) {\n    if (Object.__proto__) {\n      element.__proto__ = definition.prototype;\n    } else {\n      customMixin(element, definition.prototype, definition.native);\n      element.__proto__ = definition.prototype;\n    }\n  }\n  function customMixin(inTarget, inSrc, inNative) {\n    var used = {};\n    var p = inSrc;\n    while (p !== inNative && p !== HTMLElement.prototype) {\n      var keys = Object.getOwnPropertyNames(p);\n      for (var i = 0, k; k = keys[i]; i++) {\n        if (!used[k]) {\n          Object.defineProperty(inTarget, k, Object.getOwnPropertyDescriptor(p, k));\n          used[k] = 1;\n        }\n      }\n      p = Object.getPrototypeOf(p);\n    }\n  }\n  function created(element) {\n    if (element.createdCallback) {\n      element.createdCallback();\n    }\n  }\n  scope.upgrade = upgrade;\n  scope.upgradeWithDefinition = upgradeWithDefinition;\n  scope.implementPrototype = implementPrototype;\n});\n\nwindow.CustomElements.addModule(function(scope) {\n  var isIE11OrOlder = scope.isIE11OrOlder;\n  var upgradeDocumentTree = scope.upgradeDocumentTree;\n  var upgradeAll = scope.upgradeAll;\n  var upgradeWithDefinition = scope.upgradeWithDefinition;\n  var implementPrototype = scope.implementPrototype;\n  var useNative = scope.useNative;\n  function register(name, options) {\n    var definition = options || {};\n    if (!name) {\n      throw new Error(\"document.registerElement: first argument `name` must not be empty\");\n    }\n    if (name.indexOf(\"-\") < 0) {\n      throw new Error(\"document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '\" + String(name) + \"'.\");\n    }\n    if (isReservedTag(name)) {\n      throw new Error(\"Failed to execute 'registerElement' on 'Document': Registration failed for type '\" + String(name) + \"'. The type name is invalid.\");\n    }\n    if (getRegisteredDefinition(name)) {\n      throw new Error(\"DuplicateDefinitionError: a type with name '\" + String(name) + \"' is already registered\");\n    }\n    if (!definition.prototype) {\n      definition.prototype = Object.create(HTMLElement.prototype);\n    }\n    definition.__name = name.toLowerCase();\n    definition.lifecycle = definition.lifecycle || {};\n    definition.ancestry = ancestry(definition.extends);\n    resolveTagName(definition);\n    resolvePrototypeChain(definition);\n    overrideAttributeApi(definition.prototype);\n    registerDefinition(definition.__name, definition);\n    definition.ctor = generateConstructor(definition);\n    definition.ctor.prototype = definition.prototype;\n    definition.prototype.constructor = definition.ctor;\n    if (scope.ready) {\n      upgradeDocumentTree(document);\n    }\n    return definition.ctor;\n  }\n  function overrideAttributeApi(prototype) {\n    if (prototype.setAttribute._polyfilled) {\n      return;\n    }\n    var setAttribute = prototype.setAttribute;\n    prototype.setAttribute = function(name, value) {\n      changeAttribute.call(this, name, value, setAttribute);\n    };\n    var removeAttribute = prototype.removeAttribute;\n    prototype.removeAttribute = function(name) {\n      changeAttribute.call(this, name, null, removeAttribute);\n    };\n    prototype.setAttribute._polyfilled = true;\n  }\n  function changeAttribute(name, value, operation) {\n    name = name.toLowerCase();\n    var oldValue = this.getAttribute(name);\n    operation.apply(this, arguments);\n    var newValue = this.getAttribute(name);\n    if (this.attributeChangedCallback && newValue !== oldValue) {\n      this.attributeChangedCallback(name, oldValue, newValue);\n    }\n  }\n  function isReservedTag(name) {\n    for (var i = 0; i < reservedTagList.length; i++) {\n      if (name === reservedTagList[i]) {\n        return true;\n      }\n    }\n  }\n  var reservedTagList = [ \"annotation-xml\", \"color-profile\", \"font-face\", \"font-face-src\", \"font-face-uri\", \"font-face-format\", \"font-face-name\", \"missing-glyph\" ];\n  function ancestry(extnds) {\n    var extendee = getRegisteredDefinition(extnds);\n    if (extendee) {\n      return ancestry(extendee.extends).concat([ extendee ]);\n    }\n    return [];\n  }\n  function resolveTagName(definition) {\n    var baseTag = definition.extends;\n    for (var i = 0, a; a = definition.ancestry[i]; i++) {\n      baseTag = a.is && a.tag;\n    }\n    definition.tag = baseTag || definition.__name;\n    if (baseTag) {\n      definition.is = definition.__name;\n    }\n  }\n  function resolvePrototypeChain(definition) {\n    if (!Object.__proto__) {\n      var nativePrototype = HTMLElement.prototype;\n      if (definition.is) {\n        var inst = document.createElement(definition.tag);\n        nativePrototype = Object.getPrototypeOf(inst);\n      }\n      var proto = definition.prototype, ancestor;\n      var foundPrototype = false;\n      while (proto) {\n        if (proto == nativePrototype) {\n          foundPrototype = true;\n        }\n        ancestor = Object.getPrototypeOf(proto);\n        if (ancestor) {\n          proto.__proto__ = ancestor;\n        }\n        proto = ancestor;\n      }\n      if (!foundPrototype) {\n        console.warn(definition.tag + \" prototype not found in prototype chain for \" + definition.is);\n      }\n      definition.native = nativePrototype;\n    }\n  }\n  function instantiate(definition) {\n    return upgradeWithDefinition(domCreateElement(definition.tag), definition);\n  }\n  var registry = {};\n  function getRegisteredDefinition(name) {\n    if (name) {\n      return registry[name.toLowerCase()];\n    }\n  }\n  function registerDefinition(name, definition) {\n    registry[name] = definition;\n  }\n  function generateConstructor(definition) {\n    return function() {\n      return instantiate(definition);\n    };\n  }\n  var HTML_NAMESPACE = \"http://www.w3.org/1999/xhtml\";\n  function createElementNS(namespace, tag, typeExtension) {\n    if (namespace === HTML_NAMESPACE) {\n      return createElement(tag, typeExtension);\n    } else {\n      return domCreateElementNS(namespace, tag);\n    }\n  }\n  function createElement(tag, typeExtension) {\n    if (tag) {\n      tag = tag.toLowerCase();\n    }\n    if (typeExtension) {\n      typeExtension = typeExtension.toLowerCase();\n    }\n    var definition = getRegisteredDefinition(typeExtension || tag);\n    if (definition) {\n      if (tag == definition.tag && typeExtension == definition.is) {\n        return new definition.ctor();\n      }\n      if (!typeExtension && !definition.is) {\n        return new definition.ctor();\n      }\n    }\n    var element;\n    if (typeExtension) {\n      element = createElement(tag);\n      element.setAttribute(\"is\", typeExtension);\n      return element;\n    }\n    element = domCreateElement(tag);\n    if (tag.indexOf(\"-\") >= 0) {\n      implementPrototype(element, HTMLElement);\n    }\n    return element;\n  }\n  var domCreateElement = document.createElement.bind(document);\n  var domCreateElementNS = document.createElementNS.bind(document);\n  var isInstance;\n  if (!Object.__proto__ && !useNative) {\n    isInstance = function(obj, ctor) {\n      if (obj instanceof ctor) {\n        return true;\n      }\n      var p = obj;\n      while (p) {\n        if (p === ctor.prototype) {\n          return true;\n        }\n        p = p.__proto__;\n      }\n      return false;\n    };\n  } else {\n    isInstance = function(obj, base) {\n      return obj instanceof base;\n    };\n  }\n  function wrapDomMethodToForceUpgrade(obj, methodName) {\n    var orig = obj[methodName];\n    obj[methodName] = function() {\n      var n = orig.apply(this, arguments);\n      upgradeAll(n);\n      return n;\n    };\n  }\n  wrapDomMethodToForceUpgrade(Node.prototype, \"cloneNode\");\n  wrapDomMethodToForceUpgrade(document, \"importNode\");\n  if (isIE11OrOlder) {\n    (function() {\n      var importNode = document.importNode;\n      document.importNode = function() {\n        var n = importNode.apply(document, arguments);\n        if (n.nodeType == n.DOCUMENT_FRAGMENT_NODE) {\n          var f = document.createDocumentFragment();\n          f.appendChild(n);\n          return f;\n        } else {\n          return n;\n        }\n      };\n    })();\n  }\n  document.registerElement = register;\n  document.createElement = createElement;\n  document.createElementNS = createElementNS;\n  scope.registry = registry;\n  scope.instanceof = isInstance;\n  scope.reservedTagList = reservedTagList;\n  scope.getRegisteredDefinition = getRegisteredDefinition;\n  document.register = document.registerElement;\n});\n\n(function(scope) {\n  var useNative = scope.useNative;\n  var initializeModules = scope.initializeModules;\n  var isIE11OrOlder = /Trident/.test(navigator.userAgent);\n  if (useNative) {\n    var nop = function() {};\n    scope.watchShadow = nop;\n    scope.upgrade = nop;\n    scope.upgradeAll = nop;\n    scope.upgradeDocumentTree = nop;\n    scope.upgradeSubtree = nop;\n    scope.takeRecords = nop;\n    scope.instanceof = function(obj, base) {\n      return obj instanceof base;\n    };\n  } else {\n    initializeModules();\n  }\n  var upgradeDocumentTree = scope.upgradeDocumentTree;\n  var upgradeDocument = scope.upgradeDocument;\n  if (!window.wrap) {\n    if (window.ShadowDOMPolyfill) {\n      window.wrap = window.ShadowDOMPolyfill.wrapIfNeeded;\n      window.unwrap = window.ShadowDOMPolyfill.unwrapIfNeeded;\n    } else {\n      window.wrap = window.unwrap = function(node) {\n        return node;\n      };\n    }\n  }\n  if (window.HTMLImports) {\n    window.HTMLImports.__importsParsingHook = function(elt) {\n      if (elt.import) {\n        upgradeDocument(wrap(elt.import));\n      }\n    };\n  }\n  function bootstrap() {\n    upgradeDocumentTree(window.wrap(document));\n    window.CustomElements.ready = true;\n    requestAnimationFrame(function() {\n      setTimeout(function() {\n        window.CustomElements.readyTime = Date.now();\n        if (window.HTMLImports) {\n          window.CustomElements.elapsed = window.CustomElements.readyTime - window.HTMLImports.readyTime;\n        }\n        document.dispatchEvent(new CustomEvent(\"WebComponentsReady\", {\n          bubbles: true\n        }));\n      });\n    });\n  }\n  if (isIE11OrOlder && typeof window.CustomEvent !== \"function\") {\n    window.CustomEvent = function(inType, params) {\n      params = params || {};\n      var e = document.createEvent(\"CustomEvent\");\n      e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);\n      e.preventDefault = function() {\n        Object.defineProperty(this, \"defaultPrevented\", {\n          get: function() {\n            return true;\n          }\n        });\n      };\n      return e;\n    };\n    window.CustomEvent.prototype = window.Event.prototype;\n  }\n  if (document.readyState === \"complete\" || scope.flags.eager) {\n    bootstrap();\n  } else if (document.readyState === \"interactive\" && !window.attachEvent && (!window.HTMLImports || window.HTMLImports.ready)) {\n    bootstrap();\n  } else {\n    var loadEvent = window.HTMLImports && !window.HTMLImports.ready ? \"HTMLImportsLoaded\" : \"DOMContentLoaded\";\n    window.addEventListener(loadEvent, bootstrap);\n  }\n  scope.isIE11OrOlder = isIE11OrOlder;\n})(window.CustomElements);\n\n(function(scope) {\n  if (!Function.prototype.bind) {\n    Function.prototype.bind = function(scope) {\n      var self = this;\n      var args = Array.prototype.slice.call(arguments, 1);\n      return function() {\n        var args2 = args.slice();\n        args2.push.apply(args2, arguments);\n        return self.apply(scope, args2);\n      };\n    };\n  }\n})(window.WebComponents);\n\n(function(scope) {\n  \"use strict\";\n  if (!window.performance) {\n    var start = Date.now();\n    window.performance = {\n      now: function() {\n        return Date.now() - start;\n      }\n    };\n  }\n  if (!window.requestAnimationFrame) {\n    window.requestAnimationFrame = function() {\n      var nativeRaf = window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame;\n      return nativeRaf ? function(callback) {\n        return nativeRaf(function() {\n          callback(performance.now());\n        });\n      } : function(callback) {\n        return window.setTimeout(callback, 1e3 / 60);\n      };\n    }();\n  }\n  if (!window.cancelAnimationFrame) {\n    window.cancelAnimationFrame = function() {\n      return window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || function(id) {\n        clearTimeout(id);\n      };\n    }();\n  }\n})(window.WebComponents);\n\n(function(scope) {\n  var style = document.createElement(\"style\");\n  style.textContent = \"\" + \"body {\" + \"transition: opacity ease-in 0.2s;\" + \" } \\n\" + \"body[unresolved] {\" + \"opacity: 0; display: block; overflow: hidden; position: relative;\" + \" } \\n\";\n  var head = document.querySelector(\"head\");\n  head.insertBefore(style, head.firstChild);\n})(window.WebComponents);\n\n(function(scope) {\n  window.Platform = scope;\n})(window.WebComponents);"
  },
  {
    "path": "cmd/memlat/static/index.html",
    "content": "<!DOCTYPE html>\n<!-- Copyright 2015 The Go Authors. All rights reserved.\n  -- Use of this source code is governed by a BSD-style\n  -- license that can be found in the LICENSE file.\n  -->\n<html>\n  <head>\n    <meta name=\"viewport\" content=\"width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes\">\n    <meta charset=\"utf-8\">\n    <title>Memory latency profile browser</title>\n    <script src=\"bower_components/webcomponentsjs/webcomponents-lite.min.js\"></script>\n    <link rel=\"import\" href=\"bower_components/paper-styles/paper-styles-classes.html\">\n    <link rel=\"import\" href=\"memlat-browser.html\">\n    <style>\n      html {\n        overflow-y: scroll; /* Always show scroll bar */\n      }\n      body {\n        font-family: 'Roboto', 'Helvetica Neue', Helvetica, Arial, sans-serif;\n        font-weight: 300;\n      }\n    </style>\n  </head>\n  <body unresolved class=\"layout vertical center\">\n    <app-memlat-browser style=\"max-width: 1500px\"></app-memlat-browser>\n  </body>\n</html>\n"
  },
  {
    "path": "cmd/memlat/static/memlat-browser.html",
    "content": "<!-- Copyright 2015 The Go Authors. All rights reserved.\n  -- Use of this source code is governed by a BSD-style\n  -- license that can be found in the LICENSE file.\n  -->\n\n<link rel=\"import\"\n      href=\"bower_components/polymer/polymer.html\">\n\n<link rel=\"import\"\n      href=\"bower_components/iron-flex-layout/classes/iron-flex-layout.html\">\n<link rel=\"import\"\n      href=\"bower_components/iron-ajax/iron-ajax.html\">\n<link rel=\"import\"\n      href=\"bower_components/iron-icon/iron-icon.html\">\n<link rel=\"import\"\n      href=\"bower_components/iron-icons/iron-icons.html\">\n\n<link rel=\"import\"\n      href=\"bower_components/paper-card/paper-card.html\">\n<link rel=\"import\"\n      href=\"bower_components/paper-tabs/paper-tab.html\">\n<link rel=\"import\"\n      href=\"bower_components/paper-tabs/paper-tabs.html\">\n\n<!-- TODO: Animate adding/removing filter to make the change clearer -->\n\n<!-- TODO: Option to expand data address filter to all addresses on --\n  -- cache line or pair of cache lines. -->\n\n<script>\n  var Memlat = {};\n\n  Memlat.filterToLabel = function(filter) {\n    function trimFile(path) {\n      var parts = path.split('/');\n      if (parts.length <= 2)\n        return path;\n      return '.../' + parts[parts.length-2] + '/' + parts[parts.length-1];\n    }\n    if (filter.pid && filter.comm)\n      return filter.pid + ' (' + filter.comm + ')';\n    if (filter.pid)\n      return '' + filter.pid;\n    if (filter.funcName)\n      return filter.funcName;\n    if (filter.fileName && filter.line)\n      return trimFile(filter.fileName) + ':' + filter.line;\n    if (filter.fileName)\n      return trimFile(filter.fileName);\n    if (filter.address)\n      return '0x' + filter.address.toString(16);\n    if (filter.dataSrcLabel)\n      return filter.dataSrcLabel;\n    return '[all]';\n  };\n</script>\n\n<dom-module id=\"app-memlat-browser\">\n  <!-- Top-level memory latency browser. -->\n\n  <style>\n    :host {\n      @apply(--layout-horizontal);\n    }\n  </style>\n\n  <template>\n    <div class=\"layout horizontal wrap\">\n      <memlat-profile-metadata class=\"layout flex-2\" style=\"min-width: 100px\"></memlat-profile-metadata>\n      <div class=\"layout vertical flex-8\" style=\"min-width: 800px\">\n        <memlat-query-filter filters=\"{{filters}}\"></memlat-query-filter>\n        <memlat-query-groupby group-by=\"{{groupBy}}\" filters=\"{{filters}}\" on-select=\"_addFilter\"></memlat-query-groupby>\n      </div>\n    </div>\n  </template>\n\n  <script>\n    Polymer({\n      is: \"app-memlat-browser\",\n      properties: {\n        groupBy: {type: String, value: 'funcName'},\n        filters: {type: Array, value: []},\n      },\n      observers: [\n        '_stateChanged(groupBy, filters.*)',\n      ],\n      _addFilter: function(ev) {\n        this.push('filters', ev.detail);\n      },\n\n      // Hash state management\n      //\n      // TODO: Try to abstract this out.\n      ready: function() {\n        window.addEventListener('hashchange', this._hashChanged.bind(this), false);\n        this._hashChanged();\n      },\n      _hashChanged: function() {\n        function parseQueryString(qs)\n        {\n            var query = {};\n            qs.split('&').forEach(function(kv) {\n                var parts = kv.split('=');\n                query[decodeURIComponent(parts[0])] =\n                    JSON.parse(decodeURIComponent(parts[1]));\n            })\n            return query;\n        }\n\n        var hash = window.location.hash;\n        if (hash.substr(0, 1) !== '#') {\n          this._hashReady = true;\n          return;\n        }\n        var state = parseQueryString(hash.substr(1));\n        this.set('groupBy', state.groupBy);\n        this.set('filters', state.filters);\n        this._hashReady = true;\n      },\n      _stateChanged: function(groupBy, filtersCR) {\n        if (!this._hashReady)\n          return;\n        function printQueryString(obj) {\n            var kvs = [];\n            for (var k in obj) {\n                if (Object.prototype.hasOwnProperty.call(obj, k))\n                    kvs.push(encodeFragment(k) + '=' +\n                             encodeFragment(JSON.stringify(obj[k])));\n            }\n            return kvs.join('&');\n        }\n        // encodeFragment is like encodeURIComponent but explicitly\n        // reintroduces some \"unsafe\" characters that are in practice safe\n        // in fragments.  We use this because otherwise JSON becomes\n        // completely impenetrable in URIs.\n        function encodeFragment(s) {\n            s = encodeURIComponent(s);\n            return s.replace(/%22/gi, '\"').replace(/%2C/gi, ','). //\"\n                replace(/%3A/gi, ':').replace(/%2F/gi, '/').\n                replace(/%5B/gi, '[').replace(/%5D/gi, ']').\n                replace(/%7B/gi, '{').replace(/%7D/gi, '}');\n        }\n        var nhash = '#' + printQueryString({groupBy:groupBy, filters:filtersCR.base});\n\n        // Don't push the same state on the history stack\n        if (window.location.hash === nhash)\n            return;\n\n        window.location.hash = nhash;\n      },\n    });\n  </script>\n\n</dom-module>\n\n<dom-module id=\"memlat-profile-metadata\">\n  <!-- UI card for showing profile metadata. -->\n\n  <style is=\"custom-style\">\n    :host {\n      margin: 8px;\n    }\n\n    paper-card {\n        display: block;\n    }\n\n    p:first-child {\n      margin-top: 0px;\n    }\n\n    p {\n      margin-bottom: 0px;\n    }\n\n    .label {\n      font-weight: bold;\n    }\n  </style>\n\n  <template>\n    <iron-ajax auto url=\"metadata\" last-response=\"{{_m}}\"></iron-ajax>\n    <paper-card class=\"layout center\">\n      <div class=\"card-content\">\n        <p>{{_m.Filename}}</p>\n        <template is=\"dom-repeat\" items=\"{{_kvPretty(_m)}}\">\n          <p><span class=\"label\">{{item.k}}</span> <span>{{item.v}}</span></p>\n        </template>\n      </div>\n    </paper-card>\n  </template>\n\n  <script>\n    Polymer({\n      is: \"memlat-profile-metadata\",\n      properties: {\n        _m: Object,\n      },\n      _kvPretty: function(obj) {\n        return Object.keys(obj).map(function(key) {\n          if (key === 'Filename')\n            return;\n          var val = obj[key];\n          if (Array.isArray(val))\n            val = val.join(' ');\n          return {k: key + ':', v: val};\n        });\n      },\n    });\n  </script>\n\n</dom-module>\n\n<dom-module id=\"memlat-query-filter\">\n  <!-- UI for active query filter and removing filters. -->\n\n  <style is=\"custom-style\">\n    :host {\n      @apply(--layout-horizontal);\n      margin: 8px;\n    }\n\n    .title, .filter, .all {\n      padding: 16px;\n      display: inline-block;\n    }\n\n    .title {\n      background-color: #00bcd4;\n      color: #fff;\n      font-weight: 500;\n    }\n\n    .filter {\n      border-left: 1px solid #ccc;\n      cursor: pointer;\n      transition: all 0.2s;\n    }\n\n    .filter:hover {\n      background: #eee;\n    }\n\n    iron-icon {\n      margin-left: 6px;\n      --iron-icon-width: 16px;\n      --iron-icon-height: 16px;\n      fill: #ccc;\n      transition: all 0.2s;\n    }\n\n    .filter:hover iron-icon {\n      fill: #000;\n    }\n  </style>\n\n  <template>\n    <paper-card class=\"layout flex justified\">\n      <!-- TODO: Better separators -->\n      <div style=\"display: flex\">\n        <div class=\"title\">\n          Filter\n        </div>\n        <template is=\"dom-if\" if=\"{{!filters.length}}\">\n          <div class=\"all\">\n            <span style=\"font-weight:bold\">All</span>\n          </div>\n        </template>\n        <template is=\"dom-repeat\" items=\"{{filters}}\">\n          <div class=\"filter\" on-click=\"_removeFilter\">\n            <span>{{_label(item)}}</span>\n            <iron-icon icon=\"icons:cancel\"></iron-icon>\n          </div>\n        </template>\n      </div>\n    </paper-card>\n  </template>\n\n  <script>\n    Polymer({\n      is: \"memlat-query-filter\",\n      properties: {\n        filters: {type: Array, value: []},\n      },\n      _removeFilter: function(ev) {\n        this.splice('filters', ev.model.index, 1);\n      },\n      _label: function(filter) {\n        return Memlat.filterToLabel(filter);\n      },\n    });\n  </script>\n\n</dom-module>\n\n<dom-module id=\"memlat-query-groupby\">\n  <!-- UI for selecting groupBy and displaying grouped histograms. -->\n\n  <style is=\"custom-style\">\n    :host {\n      @apply(--layout-vertical);\n      margin: 8px;\n    }\n\n    paper-tabs, paper-toolbar {\n      background-color: #00bcd4;\n      color: #fff;\n      box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.2);\n    }\n\n    paper-tab {\n      /* Left-align tab bar */\n      flex: none;\n    }\n  </style>\n\n  <template>\n    <paper-card class=\"layout flex justified\">\n      <paper-tabs id=\"tabs\" selected=\"{{groupBy}}\" attr-for-selected=\"name\" noink>\n        <paper-tab name=\"funcName\">By function</paper-tab>\n        <paper-tab name=\"annotation\">Source annotation</paper-tab>\n        <paper-tab name=\"line\">By source line</paper-tab>\n        <paper-tab name=\"dataSrc\">By data source</paper-tab>\n        <paper-tab name=\"address\">By address</paper-tab>\n        <paper-tab name=\"pid\">By process</paper-tab>\n      </paper-tabs>\n      <div class=\"card-content\">\n        <memlat-query-table filter=\"{{_filter}}\" group-by=\"{{groupBy}}\"></memlat-query-table>\n      </div>\n    </paper-card>\n  </template>\n\n  <script>\n    // TODO: Use dynamically-constructed pages for tab content so we can\n    // keep them around.\n    Polymer({\n      is: \"memlat-query-groupby\",\n      properties: {\n        groupBy: {type: String, notify: true},\n        filters: Array,\n        _filter: {type: Object, computed: '_getFilter(filters.*)'},\n        _legal: {type: Object, computed: '_getLegal(_filter)', observer:'_legalChanged'},\n      },\n      ready: function() {\n        this.$.tabs.notifyResize();\n      },\n      _getFilter: function(changeRecord) {\n        var filters = changeRecord.base;\n        // Combine filters.\n        var cfilter = {};\n        for (var i = 0; i < filters.length; i++)\n          for (var prop in filters[i])\n            if (filters[i].hasOwnProperty(prop))\n              cfilter[prop] = filters[i][prop];\n        return cfilter;\n      },\n      _getLegal: function(filter) {\n        // Return the currently legal groupBys.\n        return {\n          funcName: !filter.funcName,\n          annotation: !filter.line,\n          line: !filter.line,\n          address: !filter.address,\n          pid: !filter.pid,\n        };\n      },\n      _legalChanged: function(newLegal, oldLegal) {\n        // Compute the best legal groupBy.\n        if (oldLegal !== undefined && oldLegal[this.groupBy] && !newLegal[this.groupBy]) {\n          var order = ['funcName', 'annotation', 'line', 'dataSrc', 'address', 'pid'];\n          var best;\n          for (var i = 0; i < order.length && !best; i++)\n            if (newLegal[order[i]])\n              best = order[i];\n          this.groupBy = best || 'all';\n        }\n\n        // Force a resize of the tabs since it doesn't detect that\n        // the set of tabs changed.\n        this.$.tabs.notifyResize();\n      },\n    });\n  </script>\n\n</dom-module>\n\n<dom-module id=\"memlat-query-table\">\n  <!-- UI for displaying a table of latency histograms. -->\n\n  <!-- TODO: There are lots of annoying if's in this for source\n    -- annotation mode. Abstract this better so we can just use a\n    -- different tag for annotation mode without lots of duplication. -->\n\n  <style>\n    table {\n      table-layout: fixed;\n      width: 100%;\n    }\n    tbody > tr > td {\n      overflow: hidden;\n      text-overflow: ellipsis;\n      white-space: nowrap;\n      cursor: pointer;\n    }\n    tbody > tr:hover {\n      background: #eee;\n    }\n    tr > td:last-child {\n      text-align: center;\n    }\n    tr > th {\n      text-align: left;\n      padding-top: 1em;\n    }\n    td.line {\n      text-align: right;\n      padding-right: 0.5em;\n      color: #888;\n    }\n    td.line:before {\n      content: attr(data-line);\n    }\n    #thead-fixed {\n        background: rgba(255,255,255,0.8);\n    }\n    td, th {\n        /* Make is easy to use getBoundingClientRect as width/height */\n        box-sizing: border-box;\n    }\n  </style>\n\n  <template>\n    <iron-ajax auto url=\"h\" params=\"{{_getQueryParams(filter, groupBy)}}\" last-response=\"{{_reply}}\"></iron-ajax>\n    <table cellspacing=\"0\" cellpadding=\"2px\">\n      <colgroup>\n        <template is=\"dom-if\" if=\"{{_isAnnotation(groupBy)}}\" restamp=\"true\">\n          <col style=\"width: 3em\"></col>\n        </template>\n        <col></col><col width=\"620px\"></col>\n      </colgroup>\n      <thead id=\"thead-spacer\">\n        <tr>\n          <template is=\"dom-if\" if=\"{{_isAnnotation(groupBy)}}\" restamp=\"true\">\n            <td></td>\n          </template>\n          <td></td><td></td>\n        </tr>\n      </thead>\n      <thead id=\"thead-fixed\">\n        <tr>\n          <template is=\"dom-if\" if=\"{{_isAnnotation(groupBy)}}\" restamp=\"true\">\n            <td></td>\n          </template>\n          <td></td><td style=\"font-weight: bold\">Memory access cycles distribution</td>\n        </tr>\n        <tr>\n          <template is=\"dom-if\" if=\"{{_isAnnotation(groupBy)}}\" restamp=\"true\">\n            <td></td>\n          </template>\n          <td></td><td><memlat-scale ticks=\"{{_reply.MajorTicksX}}\" tick-labels=\"{{_reply.MajorTicks}}\" minor-ticks=\"{{_reply.MinorTicksX}}\"></memlat-scale></td>\n        </tr>\n      </thead>\n      <tbody>\n        <template is=\"dom-repeat\" items=\"{{_reply.Histograms}}\">\n          <template is=\"dom-if\" if=\"{{item.isHeader}}\" restamp=\"true\">\n            <template is=\"dom-if\" if=\"{{_isAnnotation(groupBy)}}\" restamp=\"true\">\n              <tr><th colspan=\"3\">{{item.text}}</th></tr>\n            </template>\n            <template is=\"dom-if\" if=\"{{!_isAnnotation(groupBy)}}\" restamp=\"true\">\n              <tr><th colspan=\"2\">{{item.text}}</th></tr>\n            </template>\n          </template>\n          <template is=\"dom-if\" if=\"{{!item.isHeader}}\" restamp=\"true\">\n            <tr on-click=\"_rowClicked\">\n              <template is=\"dom-if\" if=\"{{_isAnnotation(groupBy)}}\" restamp=\"true\">\n                <td class=\"line\" data-line$=\"{{item.line}}\"></td>\n                <td style=\"white-space: pre\">{{item.text}}</td>\n              </template>\n              <template is=\"dom-if\" if=\"{{!_isAnnotation(groupBy)}}\" restamp=\"true\">\n                <td>{{_label(item)}}</td>\n              </template>\n              <td>\n                <template is=\"dom-if\" if=\"{{item.Bins}}\">\n                  <memlat-heat-map bins=\"{{item.Bins}}\" max-val=\"{{_reply.MaxBin}}\"></memlat-heat-map></td>\n                </template>\n            </tr>\n          </template>\n        </template>\n      </tbody>\n    </table>\n  </template>\n\n  <script>\n    // TODO: Make it possible to increase the query limit.\n    //\n    // TODO: Consider showing percent contribution of each row.\n    //\n    // TODO: Assembly-level annotation.\n    Polymer({\n      is: \"memlat-query-table\",\n      properties: {\n        groupBy: String,\n        filter: Object,\n        _reply: Object,\n      },\n      ready: function() {\n        window.addEventListener('scroll', this._updateHeader.bind(this));\n        window.addEventListener('resize', this._updateHeader.bind(this));\n      },\n      _updateHeader: function() {\n        var spacer = this.$$('#thead-spacer > tr');\n        var head = this.$$('#thead-fixed');\n\n        // Get the absolute top and bottom of the table\n        var table = this.$$('table');\n        var tableTop = 0;\n        if (table.offsetParent) {\n          var obj = table;\n          do {\n            tableTop += obj.offsetTop;\n          } while (obj = obj.offsetParent);\n        }\n        var tableBot = tableTop + table.getBoundingClientRect().height;\n\n        var headHeight = head.getBoundingClientRect().height;\n        if (tableTop < window.pageYOffset && window.pageYOffset < tableBot - headHeight) {\n          // Fixed header positioning\n          spacer.style.height = headHeight + 'px';\n          head.style.position = 'fixed';\n          head.style.top = '0px';\n        } else {\n          // Standard header positioning\n          spacer.style.height = '';\n          head.style.position = '';\n        }\n\n        // \"position: fixed\" messes up column widths, so paste them in\n        // from the spacer.\n        var spacerTDs = spacer.querySelectorAll('td');\n        var headTDs = head.querySelectorAll('td');\n        for (var i = 0; i < spacerTDs.length; i++)\n          headTDs[i].style.width = spacerTDs[i].getBoundingClientRect().width + 'px';\n      },\n      _getQueryParams: function(filter, groupBy) {\n        var params = {groupBy: groupBy, limit: groupBy == 'annotation' ? 30 : 100};\n        Object.keys(filter).forEach(function(key) {\n          params[key] = filter[key];\n        });\n        return params;\n      },\n      _label: function(hist) {\n        return Memlat.filterToLabel(hist);\n      },\n      _rowClicked: function(ev) {\n        var hist = ev.model.get('item');\n\n        // Create the filter from hist's properties.\n        var filter = {}, anyProps = false;\n        var fprops = ['pid', 'comm', 'funcName', 'fileName', 'line', 'address',\n                      'op', 'miss', 'level', 'snoop', 'locked', 'tlb'];\n        for (var i = 0; i < fprops.length; i++) {\n          if (hist.hasOwnProperty(fprops[i])) {\n            filter[fprops[i]] = hist[fprops[i]];\n            anyProps = true;\n            // If we're already filtering on this property, don't\n            // filter again.\n            if (this.filter.hasOwnProperty(fprops[i]))\n              return;\n          }\n        }\n        // If this is an [all] result, there isn't anything to filter on.\n        if (!anyProps)\n          return;\n\n        // The client side can't format data sources, so keep the\n        // server-provided label in the filter.\n        if (hist.hasOwnProperty('dataSrcLabel'))\n          filter.dataSrcLabel = hist.dataSrcLabel;\n\n        this.fire('select', filter);\n      },\n      _isAnnotation: function(groupBy) {\n        return groupBy == 'annotation';\n      },\n    });\n  </script>\n\n</dom-module>\n\n<dom-module id=\"memlat-heat-map\">\n  <!-- UI for displaying a single latency histogram as a heat map. -->\n\n  <template>\n    <canvas id=\"heatmap\" height=\"10\"></canvas>\n  </template>\n\n  <script>\n    Polymer({\n      is: \"memlat-heat-map\",\n      properties: {\n        bins: Array,\n        maxVal: Number,\n      },\n      observers: [\n        '_binsChanged(bins, maxVal)',\n      ],\n      _color: function(v) {\n        var pal = [[255,255,255],[255,255,204],[255,237,160],[254,217,118],[254,178,76],[253,141,60],[252,78,42],[227,26,28],[189,0,38],[128,0,38]];\n        v *= pal.length-1;\n        if (v >= pal.length-1)\n          return pal[pal.length-1];\n        if (v <= 0)\n          return pal[0];\n        var p1 = pal[Math.floor(v)], p2 = pal[Math.floor(v)+1];\n        var x = v - Math.floor(v);\n        return [p1[0]*(1-x)+p2[0]*x, p1[1]*(1-x)+p2[1]*x, p1[2]*(1-x)+p2[2]*x];\n      },\n      _rgba: function(rgb, a) {\n        return 'rgba('+Math.floor(rgb[0])+','+Math.floor(rgb[1])+','+Math.floor(rgb[2])+','+a+')';\n      },\n      _binsChanged: function(bins, maxVal) {\n        // TODO: Janky for big lists. Maybe iron-list? Even just sizing\n        // the canvas is slow. Works fine with default query limit.\n        var size = 10;\n        var canvas = this.$.heatmap;\n        canvas.width = bins.length * size;\n        canvas.height = size;\n        if (maxVal === 0)\n          return;\n        var ctx = canvas.getContext('2d');\n        for (var i = 0; i < bins.length; i++) { //>\n          var val = Math.pow(bins[i] / maxVal, 0.5);\n          ctx.fillStyle = this._rgba(this._color(val), Math.min(1, val*5));\n          ctx.fillRect(i*size, 0, size, size);\n        }\n      },\n    });\n  </script>\n\n</dom-module>\n\n<dom-module id=\"memlat-scale\">\n  <!-- Graph scale. -->\n\n  <style is=\"custom-style\">\n    .tick-label {\n      position: absolute;\n      transform: translateX(-50%);\n      top: 0px;\n    }\n    canvas {\n      margin-top: 1.4em;\n    }\n  </style>\n\n  <template>\n    <div style=\"position:relative; display:inline-block\">\n      <template is=\"dom-repeat\" items=\"{{_labels}}\">\n        <div class=\"tick-label\" style$=\"[[item.style]]\">{{item.label}}</div>\n      </template>\n      <canvas id=\"scale\" height=\"10\"></canvas>\n    </div>\n  </template>\n\n  <script>\n    Polymer({\n      is: \"memlat-scale\",\n      properties: {\n        width: {type: Number, value: 600},\n        ticks: Array,\n        tickLabels: Array,\n        minorTicks: Array,\n        _labels: {type: Array, computed: '_getLabels(width, ticks, tickLabels)'},\n      },\n      observers: [\n        '_ticksChanged(width, ticks, tickLabels, minorTicks)',\n      ],\n      _getLabels: function(width, ticks, tickLabels) {\n        var labels = [];\n        for (var i = 0; i < ticks.length; i++) {\n          var val = tickLabels[i], unit = '';\n          if (val >= 1000) { val /= 1000; unit = 'k'; }\n          if (val >= 1000) { val /= 1000; unit = 'm'; }\n          if (val >= 1000) { val /= 1000; unit = 'g'; }\n          var label = val + unit;\n          labels.push({style: 'left:'+(width*ticks[i])+'px', label: label});\n        }\n        return labels;\n      },\n      _ticksChanged: function(width, ticks, tickLabels, minorTicks) {\n        var canvas = this.$.scale;\n        canvas.width = width;\n        var ctx = canvas.getContext('2d');\n        ctx.beginPath();\n        ctx.strokeStyle = 'rgba(0,0,0)';\n        ctx.strokeWidth = '2px';\n        ticks.forEach(function(pos) {\n          ctx.moveTo(Math.round(pos*(width-2)+1), 0);\n          ctx.lineTo(Math.round(pos*(width-2)+1), 10);\n        });\n        ctx.stroke();\n        ctx.strokeStyle = 'rgba(0,0,0,0.3)';\n        ctx.strokeWidth = '1px';\n        ctx.beginPath();\n        minorTicks.forEach(function(pos) {\n          ctx.moveTo(Math.round(pos*(width-2)+1)+0.5, 5);\n          ctx.lineTo(Math.round(pos*(width-2)+1)+0.5, 10);\n        });\n        ctx.stroke();\n      },\n    })\n  </script>\n\n</dom-module>\n"
  },
  {
    "path": "cmd/perfdump/main.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Command perfdump prints the raw contents of a perf.data profile.\npackage main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"reflect\"\n\n\t\"github.com/aclements/go-perf/perffile\"\n)\n\nfunc main() {\n\tvar (\n\t\tflagInput = flag.String(\"i\", \"perf.data\", \"input perf.data `file`\")\n\t\tflagOrder = flag.String(\"order\", \"time\", \"sort `order`; one of: file, time, causal\")\n\t)\n\tflag.Parse()\n\torder, ok := parseOrder(*flagOrder)\n\tif flag.NArg() > 0 || !ok {\n\t\tflag.Usage()\n\t\tos.Exit(1)\n\t}\n\n\tf, err := perffile.Open(*flagInput)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer f.Close()\n\n\tfmt.Printf(\"events:\\n\")\n\tfor _, event := range f.Events {\n\t\tfmt.Printf(\"  %p=%+v\\n\", event, *event)\n\t}\n\n\tif f.Meta.BuildIDs != nil {\n\t\tfmt.Printf(\"build IDs:\\n\")\n\t\tfor _, bid := range f.Meta.BuildIDs {\n\t\t\tfmt.Printf(\"  %v\\n\", bid)\n\t\t}\n\t}\n\n\tfor _, hdr := range []struct {\n\t\tlabel string\n\t\tval   interface{}\n\t}{\n\t\t//{\"build IDs\", &f.Meta.BuildIDs},\n\t\t{\"hostname\", f.Meta.Hostname},\n\t\t{\"OS release\", f.Meta.OSRelease},\n\t\t{\"version\", f.Meta.Version},\n\t\t{\"arch\", f.Meta.Arch},\n\t\t{\"CPUs online\", f.Meta.CPUsOnline},\n\t\t{\"CPUs available\", f.Meta.CPUsAvail},\n\t\t{\"CPU desc\", f.Meta.CPUDesc},\n\t\t{\"CPUID\", f.Meta.CPUID},\n\t\t{\"total memory\", f.Meta.TotalMem},\n\t\t{\"cmdline\", f.Meta.CmdLine},\n\t\t{\"core groups\", f.Meta.CoreGroups},\n\t\t{\"thread groups\", f.Meta.ThreadGroups},\n\t\t{\"NUMA nodes\", f.Meta.NUMANodes},\n\t\t{\"PMU mappings\", f.Meta.PMUMappings},\n\t\t{\"groups\", f.Meta.Groups},\n\t} {\n\t\tif hdr.val == reflect.Zero(reflect.ValueOf(hdr.val).Type()) {\n\t\t\tcontinue\n\t\t}\n\t\tfmt.Printf(\"%s: %v\\n\", hdr.label, hdr.val)\n\t}\n\n\tfmt.Println()\n\n\trs := f.Records(order)\n\tfor rs.Next() {\n\t\tfmt.Printf(\"%v{\\n\", rs.Record.Type())\n\t\tswitch r := rs.Record.(type) {\n\t\tcase *perffile.RecordSample:\n\t\t\tv := reflect.ValueOf(r).Elem()\n\t\t\tfor _, n := range r.Fields() {\n\t\t\t\tf := v.FieldByName(n)\n\t\t\t\tfmt.Printf(\"\\t%s,\\n\", fmtVal(n, f))\n\t\t\t}\n\t\tdefault:\n\t\t\tprintFields(reflect.ValueOf(r))\n\t\t}\n\t\tfmt.Printf(\"}\\n\")\n\n\t\t//fmt.Printf(\"%v %+v\\n\", rs.Record.Type(), rs.Record)\n\t}\n\tif err := rs.Err(); err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n\nfunc parseOrder(order string) (perffile.RecordsOrder, bool) {\n\tswitch order {\n\tcase \"file\":\n\t\treturn perffile.RecordsFileOrder, true\n\tcase \"time\":\n\t\treturn perffile.RecordsTimeOrder, true\n\tcase \"causal\":\n\t\treturn perffile.RecordsCausalOrder, true\n\t}\n\treturn 0, false\n}\n\nfunc printFields(v reflect.Value) {\n\tfor v.Kind() == reflect.Ptr {\n\t\tv = v.Elem()\n\t}\n\tt := v.Type()\n\tfor i := 0; i < t.NumField(); i++ {\n\t\tinfo := t.Field(i)\n\t\tf := v.Field(i)\n\t\tif info.Anonymous {\n\t\t\tprintFields(f)\n\t\t} else if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice) && f.IsNil() {\n\t\t\t// Skip\n\t\t} else {\n\t\t\tfmt.Printf(\"\\t%s,\\n\", fmtVal(info.Name, f))\n\t\t}\n\t}\n}\n\nfunc fmtVal(name string, v reflect.Value) string {\n\tif v.Kind() == reflect.Ptr {\n\t\treturn fmt.Sprintf(\"%-14s %p\", name+\":\", v.Interface())\n\t}\n\tswitch name {\n\tcase \"IP\", \"Addr\", \"Callchain\":\n\t\treturn fmt.Sprintf(\"%-14s %#x\", name+\":\", v.Interface())\n\t}\n\treturn fmt.Sprintf(\"%-14s %+v\", name+\":\", v.Interface())\n}\n"
  },
  {
    "path": "cmd/prologuer/main.go",
    "content": "// Copyright 2019 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Command prologuer reports what fraction of samples from a profile\n// are from IPs marked as function prologue in DWARF line tables.\n//\n// In Go binaries (as of Go 1.12), this counts the stack bounds check\n// up to and including the conditional branch to morestack. It does\n// not the instructions that call morestack or the instructions that\n// create a function's stack frame.\n//\n// This is best used with precise profile samples, such as\n//\n//   perf record -e cycles:ppp -- <cmd>\npackage main\n\nimport (\n\t\"debug/dwarf\"\n\t\"debug/elf\"\n\t\"flag\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"os\"\n\t\"sort\"\n\n\t\"github.com/aclements/go-perf/perffile\"\n\t\"github.com/aclements/go-perf/perfsession\"\n)\n\nfunc main() {\n\tvar flagInput = flag.String(\"i\", \"perf.data\", \"input perf.data `file`\")\n\tflag.Parse()\n\tif flag.NArg() > 0 {\n\t\tflag.Usage()\n\t\tos.Exit(1)\n\t}\n\n\tf, err := perffile.Open(*flagInput)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer f.Close()\n\n\ts := perfsession.New(f)\n\n\tvar samples, prologueSamples uint64\n\trs := f.Records(perffile.RecordsFileOrder)\n\tfor rs.Next() {\n\t\ts.Update(rs.Record)\n\n\t\tswitch r := rs.Record.(type) {\n\t\tcase *perffile.RecordSample:\n\t\t\tpidInfo := s.LookupPID(r.PID)\n\t\t\tmmap := pidInfo.LookupMmap(r.IP)\n\t\t\tif mmap == nil {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tsamples++\n\t\t\tpr := prologueRanges(s, mmap)\n\t\t\tif _, _, _, ok := pr.Get(r.IP); ok {\n\t\t\t\tprologueSamples++\n\t\t\t}\n\t\t}\n\t}\n\n\tfmt.Printf(\"%d of %d samples (%.2f%%) in prologue\\n\", prologueSamples, samples, float64(prologueSamples)*100/float64(samples))\n}\n\nvar prologueRangesKey = perfsession.NewExtraKey(\"prologuer.prologueRanges\")\n\nfunc prologueRanges(session *perfsession.Session, mmap *perfsession.Mmap) *perfsession.Ranges {\n\tfileTab, ok := session.Extra[prologueRangesKey].(map[string]*perfsession.Ranges)\n\tif !ok {\n\t\tfileTab = make(map[string]*perfsession.Ranges)\n\t\tsession.Extra[prologueRangesKey] = fileTab\n\t}\n\tfilename := mmap.Filename\n\tif r, ok := fileTab[filename]; ok {\n\t\treturn r\n\t}\n\n\tif len(filename) > 0 && filename[0] == '[' {\n\t\t// Not a real file.\n\t\treturn nil\n\t}\n\n\tr := new(perfsession.Ranges)\n\tfileTab[filename] = r\n\n\telff, err := elf.Open(filename)\n\tif err != nil {\n\t\tlog.Printf(\"error loading ELF file %s: %s\", filename, err)\n\t\treturn r\n\t}\n\tdefer elff.Close()\n\n\tif elff.Section(\".debug_info\") == nil && elff.Section(\".zdebug_info\") == nil {\n\t\t// No DWARF info.\n\t\treturn r\n\t}\n\n\tdwarff, err := elff.DWARF()\n\tif err != nil {\n\t\tlog.Printf(\"error loading DWARF from %s: %s\", filename, err)\n\t\treturn r\n\t}\n\n\tpb, cb := fillRanges(r, dwarff)\n\tfmt.Printf(\"%s: %d of %d bytes (%.2f%%) in prologue\\n\", filename, pb, cb, float64(pb)*100/float64(cb))\n\n\treturn r\n}\n\nfunc fillRanges(r *perfsession.Ranges, dwarff *dwarf.Data) (prologueBytes, codeBytes uint64) {\n\tdr := dwarff.Reader()\n\tfor {\n\t\tent, err := dr.Next()\n\t\tif ent == nil || err != nil {\n\t\t\tbreak\n\t\t}\n\n\t\tswitch ent.Tag {\n\t\tdefault:\n\t\t\tdr.SkipChildren()\n\n\t\tcase dwarf.TagModule, dwarf.TagNamespace:\n\t\t\tbreak\n\n\t\tcase dwarf.TagCompileUnit:\n\t\t\tpend := prologueEndPCs(dwarff, ent)\n\n\t\t\t// Process functions in this CU.\n\t\t\tvar funcRanges [][2]uint64\n\t\tcu:\n\t\t\tfor {\n\t\t\t\tent, err = dr.Next()\n\t\t\t\tif ent == nil || err != nil {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tswitch ent.Tag {\n\t\t\t\tcase 0:\n\t\t\t\t\t// End of children of the CU.\n\t\t\t\t\tbreak cu\n\n\t\t\t\tdefault:\n\t\t\t\t\tdr.SkipChildren()\n\n\t\t\t\tcase dwarf.TagSubprogram:\n\t\t\t\t\tdr.SkipChildren()\n\t\t\t\t\tfr, err := dwarff.Ranges(ent)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tlog.Fatal(err)\n\t\t\t\t\t}\n\t\t\t\t\tfuncRanges = append(funcRanges, fr...)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor _, fr := range funcRanges {\n\t\t\t\tcodeBytes += fr[1] - fr[0]\n\t\t\t}\n\n\t\t\t// Match function ranges against prologue ends.\n\t\t\tsort.Slice(funcRanges, func(i, j int) bool {\n\t\t\t\treturn funcRanges[i][0] < funcRanges[j][0]\n\t\t\t})\n\t\t\tfor len(pend) > 0 && len(funcRanges) > 0 {\n\t\t\t\tif pend[0] < funcRanges[0][0] {\n\t\t\t\t\tpend = pend[1:]\n\t\t\t\t} else if pend[0] >= funcRanges[0][1] {\n\t\t\t\t\tfuncRanges = funcRanges[1:]\n\t\t\t\t} else {\n\t\t\t\t\tr.Add(funcRanges[0][0], pend[0], nil)\n\t\t\t\t\tprologueBytes += pend[0] - funcRanges[0][0]\n\t\t\t\t\tpend = pend[1:]\n\t\t\t\t\tfuncRanges = funcRanges[1:]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n\nfunc prologueEndPCs(dwarff *dwarf.Data, cu *dwarf.Entry) []uint64 {\n\t// Decode CU's line table to find prologue end\n\t// PCs\n\tvar pend []uint64\n\tlr, err := dwarff.LineReader(cu)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t} else if lr == nil {\n\t\treturn nil\n\t}\n\n\tfor {\n\t\tvar lent dwarf.LineEntry\n\t\terr := lr.Next(&lent)\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tif lent.PrologueEnd {\n\t\t\tpend = append(pend, lent.Address)\n\t\t}\n\t}\n\n\treturn pend\n}\n"
  },
  {
    "path": "fmt_test.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n)\n\n// TestGofmt tests that all files are formatted.\nfunc TestGofmt(t *testing.T) {\n\troot, fileMap := copyTree(t)\n\n\tgofmt := exec.Command(\"gofmt\", \"-w\", \".\")\n\tgofmt.Dir = root\n\tgofmt.Stdout, gofmt.Stderr = os.Stdout, os.Stderr\n\tif err := gofmt.Run(); err != nil {\n\t\tt.Fatalf(\"gofmt failed: %v\", err)\n\t}\n\n\t// Diff the trees.\n\tif diffFiles(t, fileMap) {\n\t\tt.Errorf(\"Files are not gofmt clean. Please run gofmt.\")\n\t}\n}\n\n// TestGenerated tests that all generated files are up-to-date.\nfunc TestGenerated(t *testing.T) {\n\troot, fileMap := copyTree(t)\n\n\t// Build bitstringer\n\tbuild := exec.Command(\"go\", \"build\")\n\tbuild.Dir = filepath.Join(root, \"cmd/bitstringer\")\n\tbuild.Stdout, build.Stderr = os.Stdout, os.Stderr\n\tif err := build.Run(); err != nil {\n\t\tt.Fatalf(\"go build failed: %v\", err)\n\t}\n\n\tgen := exec.Command(\"go\", \"generate\", \"./...\")\n\tgen.Dir = root\n\tgen.Stdout, gen.Stderr = os.Stdout, os.Stderr\n\tif err := gen.Run(); err != nil {\n\t\tt.Fatalf(\"go generate failed: %v\", err)\n\t}\n\n\t// Diff the trees.\n\tif diffFiles(t, fileMap) {\n\t\tt.Errorf(\"Please run go generate.\")\n\t}\n}\n\nfunc copyTree(t *testing.T) (string, map[string]string) {\n\tsrc, err := os.Getwd()\n\tif err != nil {\n\t\tt.Fatalf(\"getting working directory: %v\", err)\n\t}\n\tdst := t.TempDir()\n\n\t// Ensure src ends with \"/\"\n\tsrc = fmt.Sprintf(\"%s%c\", filepath.Clean(src), filepath.Separator)\n\n\tfileMap := make(map[string]string)\n\terr = filepath.WalkDir(src, func(path string, d fs.DirEntry, err error) error {\n\t\tif !strings.HasPrefix(path, src) {\n\t\t\tpanic(fmt.Sprintf(\"WalkDir path %q does not start with source path %q\", path, src))\n\t\t}\n\n\t\trel := path[len(src):]\n\t\tif d.Name() == \".git\" {\n\t\t\treturn filepath.SkipDir\n\t\t}\n\t\tif d.IsDir() {\n\t\t\tif rel == \"\" {\n\t\t\t\t// This is the root of the tree, so\n\t\t\t\t// the destination already exists.\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn os.Mkdir(filepath.Join(dst, rel), 0777)\n\t\t}\n\t\t// Only copy .go and related files.\n\t\tif n := d.Name(); !(filepath.Ext(n) == \".go\" || n == \"go.mod\" || n == \"go.sum\") {\n\t\t\treturn nil\n\t\t}\n\n\t\t// Copy file.\n\t\tfileMap[path] = filepath.Join(dst, rel)\n\t\treturn copyFile(path, filepath.Join(dst, rel))\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"error copying source tree: %v\", err)\n\t}\n\n\tt.Logf(\"copied source tree to %s\", dst)\n\n\treturn dst, fileMap\n}\n\nfunc copyFile(src, dst string) error {\n\tout, err := os.Create(dst)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer out.Close()\n\n\tin, err := os.Open(src)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer in.Close()\n\n\t_, err = io.Copy(out, in)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn out.Close()\n}\n\nfunc diffFiles(t *testing.T, fileMap map[string]string) bool {\n\tdiffs := 0\n\tfor orig, new := range fileMap {\n\t\t// --strip-trailing-cr is important on Windows where\n\t\t// git and gofmt may disagree on newline conventions.\n\t\tdiff := exec.Command(\"diff\", \"-u\", \"--strip-trailing-cr\", orig, new)\n\t\tdiff.Stdout = os.Stdout\n\t\tdiff.Stderr = os.Stderr\n\t\tif err := diff.Run(); err != nil {\n\t\t\tswitch err := err.(type) {\n\t\t\tcase *exec.ExitError:\n\t\t\t\tif err.ExitCode() == 1 {\n\t\t\t\t\tdiffs++\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tt.Errorf(\"diff failed: %v\", err)\n\t\t}\n\t}\n\treturn diffs != 0\n}\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/aclements/go-perf\n\ngo 1.18\n\nrequire (\n\tgithub.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794\n\tgithub.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0\n\tgithub.com/ianlancetaylor/demangle v0.0.0-20220517205856-0058ec4f073c\n)\n\nrequire golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 // indirect\n"
  },
  {
    "path": "go.sum",
    "content": "github.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794 h1:xlwdaKcTNVW4PtpQb8aKA4Pjy0CdJHEqvFbAnvR5m2g=\ngithub.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794/go.mod h1:7e+I0LQFUI9AXWxOfsQROs9xPhoJtbsyWcjJqDd4KPY=\ngithub.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=\ngithub.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=\ngithub.com/ianlancetaylor/demangle v0.0.0-20220517205856-0058ec4f073c h1:rwmN+hgiyp8QyBqzdEX43lTjKAxaqCrYHaU5op5P9J8=\ngithub.com/ianlancetaylor/demangle v0.0.0-20220517205856-0058ec4f073c/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=\ngolang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 h1:LRtI4W37N+KFebI/qV0OFiLUv4GLOWeEW5hn/KEJvxE=\ngolang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=\ngolang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\n"
  },
  {
    "path": "internal/cparse/enums.go",
    "content": "// Copyright 2018 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage cparse\n\nimport (\n\t\"fmt\"\n)\n\ntype Enum struct {\n\tTag   Tok\n\tIdent Tok\n}\n\n// FindEnums finds top-level enumeration constants in toks.\nfunc FindEnums(tokens []Tok) ([]Enum, error) {\n\tt := toks(tokens)\n\tvar enums []Enum\n\tfor len(t) > 0 {\n\t\tswitch {\n\t\tcase t.Try(TokOp, \"{\"):\n\t\t\tt.SkipBalanced(\"}\")\n\t\tcase t.Try(TokOp, \"(\"):\n\t\t\tt.SkipBalanced(\")\")\n\t\tcase t.Try(TokOp, \"[\"):\n\t\t\tt.SkipBalanced(\"]\")\n\t\tcase t.Try(TokKeyword, \"enum\"):\n\t\t\t// Found an enum. Skip tag, if any.\n\t\t\ttag, _ := t.TryIdent()\n\t\t\tif t.Try(TokOp, \"{\") {\n\t\t\t\tfor {\n\t\t\t\t\tif t.Try(TokOp, \"}\") {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tid, ok := t.TryIdent()\n\t\t\t\t\tif !ok {\n\t\t\t\t\t\treturn nil, fmt.Errorf(\"expected identifier\")\n\t\t\t\t\t}\n\t\t\t\t\tenums = append(enums, Enum{tag, id})\n\t\t\t\t\t// Consume initializer.\n\t\t\t\t\tif t.Try(TokOp, \"=\") {\n\t\t\t\t\t\tt.SkipBalanced(\",\", \"}\")\n\t\t\t\t\t}\n\t\t\t\t\tt.Try(TokOp, \",\")\n\t\t\t\t}\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Skip(1)\n\t\t}\n\t}\n\treturn enums, nil\n}\n"
  },
  {
    "path": "internal/cparse/enums_test.go",
    "content": "// Copyright 2018 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage cparse\n\nimport (\n\t\"testing\"\n)\n\nfunc TestFindEnums(t *testing.T) {\n\tneedCC(t)\n\n\tpp := preprocess(t, \"int foo(); enum tag { A, B = 2 + (C, D), E };\")\n\ttoks, err := Tokenize(pp)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tenums, err := FindEnums(toks)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif len(enums) != 3 {\n\t\tt.Fatalf(\"expected 3 enums, got %d\", len(enums))\n\t}\n\tfor i, name := range []string{\"A\", \"B\", \"E\"} {\n\t\tif enums[i].Tag.Text != \"tag\" || enums[i].Ident.Text != name {\n\t\t\tt.Errorf(\"expected enum tag.%s, got %v\", name, enums[i])\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "internal/cparse/lex.go",
    "content": "// Copyright 2018 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage cparse\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"strconv\"\n)\n\ntype Toks struct {\n\tToks []Tok\n}\n\ntype Tok struct {\n\tKind TokKind\n\tText string\n}\n\ntype TokKind uint8\n\nconst (\n\tTokKeyword TokKind = 1 + iota\n\tTokIdent\n\tTokNumber\n\tTokString\n\tTokChar\n\tTokOp\n\tTokEOF\n)\n\nfunc (t Tok) Int() int {\n\tif t.Kind != TokNumber {\n\t\tpanic(\"token is not a number\")\n\t}\n\tv, err := strconv.Atoi(t.Text)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn v\n}\n\nfunc (t Tok) Match(kind TokKind, text string) bool {\n\treturn t.Kind == kind && t.Text == text\n}\n\nvar tokTab, puncTab, keyTab = mkTokTab([]string{\n\t\"[\", \"]\", \"(\", \")\", \"{\", \"}\", \".\", \"->\",\n\t\"++\", \"--\", \"&\", \"*\", \"+\", \"-\", \"~\", \"!\",\n\t\"/\", \"%\", \"<<\", \">>\", \"<\", \">\", \"<=\", \">=\", \"!=\",\n\t\"^\", \"|\", \"&&\", \"||\",\n\t\"?\", \":\", \";\", \"...\",\n\t\"=\", \"*=\", \"/=\", \"%=\", \"+=\", \"-=\", \"<<=\", \">>=\", \"&=\", \"^=\", \"|=\",\n\t\",\", \"#\", \"##\",\n}, []string{\"auto\", \"break\", \"case\", \"char\", \"const\",\n\t\"continue\", \"default\", \"do\", \"double\", \"else\",\n\t\"enum\", \"extern\", \"float\", \"for\", \"goto\",\n\t\"if\", \"inline\", \"int\", \"long\", \"register\",\n\t\"restrict\", \"return\", \"short\", \"signed\", \"sizeof\",\n\t\"static\", \"struct\", \"switch\", \"typedef\", \"union\",\n\t\"unsigned\", \"void\", \"volatile\", \"while\", \"_Bool\",\n\t\"_Complex\", \"_Imaginary\",\n})\n\nvar escTab = map[byte]byte{\n\t'\\'': '\\'', '\"': '\"', '?': '?', '\\\\': '\\\\',\n\t'a': '\\a', 'b': '\\b', 'f': '\\f', 'n': '\\n',\n\t'r': '\\r', 't': '\\t', 'v': '\\v'}\n\ntype chProps uint8\n\nconst (\n\tchNonDigit chProps = 1 << iota\n\tchDigit\n\tchOct\n\tchHex\n\tchChars // Character constant or string literal\n\tchPunct\n)\n\nfunc mkTokTab(punct, keywords []string) (tab [256]chProps, ptab map[string]bool, ktab map[string]bool) {\n\tfor i := range tab {\n\t\tif i == '_' || 'a' <= i && i <= 'z' || 'A' <= i && i <= 'Z' {\n\t\t\ttab[i] |= chNonDigit\n\t\t\tif 'a' <= i && i <= 'f' || 'A' <= i && i <= 'F' {\n\t\t\t\ttab[i] |= chHex\n\t\t\t}\n\t\t} else if '0' <= i && i <= '9' {\n\t\t\ttab[i] |= chDigit | chHex\n\t\t\tif i <= '7' {\n\t\t\t\ttab[i] |= chOct\n\t\t\t}\n\t\t} else {\n\t\t\tswitch i {\n\t\t\tcase '\\'', '\"':\n\t\t\t\ttab[i] |= chChars\n\t\t\t}\n\t\t}\n\t}\n\n\tptab = make(map[string]bool)\n\tfor _, p := range punct {\n\t\ttab[p[0]] |= chPunct\n\t\tptab[p] = true\n\t}\n\n\tktab = make(map[string]bool)\n\tfor _, k := range keywords {\n\t\tktab[k] = true\n\t}\n\n\treturn\n}\n\ntype pos struct {\n\tpath      string\n\tline, col int\n}\n\nfunc (p pos) error(f string, args ...interface{}) error {\n\tmsg := fmt.Sprintf(f, args...)\n\treturn fmt.Errorf(\"%s:%d:%d: %s\", p.path, p.line, p.col, msg)\n}\n\n// charReader implements translation phases 1 and 2: mapping to the\n// source character set, and deleting \"\\\\\\n\". It doesn't implement\n// trigraph sequences, so phase 1 is trivial.\ntype charReader struct {\n\tsrc []byte\n\tpos pos\n}\n\nfunc (r *charReader) ReadByte() byte {\n\t// Fold \"\\\\\\n\".\n\tfor len(r.src) >= 2 && r.src[0] == '\\\\' && r.src[1] == '\\n' {\n\t\tr.pos.line++\n\t\tr.pos.col = 0\n\t\tr.src = r.src[2:]\n\t}\n\tif len(r.src) == 0 {\n\t\treturn 0\n\t}\n\tnext := r.src[0]\n\tr.src = r.src[1:]\n\tr.pos.col++\n\tif next == '\\n' {\n\t\tr.pos.line++\n\t\tr.pos.col = 0\n\t}\n\treturn next\n}\n\nfunc (r *charReader) EOF() bool {\n\treturn len(r.src) == 0\n}\n\n// Tokenize parses src into C tokens. src must already be\n// pre-processed.\nfunc Tokenize(src []byte) ([]Tok, error) {\n\ttoks := []Tok{}\n\tcr := charReader{src: src, pos: pos{\"<none>\", 1, 0}}\n\n\tvar buf []byte\n\tvar ch byte\n\thaveCh := false\n\tinLine, lineStart := false, 0 // Processing line directive\n\n\tfor {\n\t\tif !haveCh {\n\t\t\tch = cr.ReadByte()\n\t\t}\n\t\thaveCh = false\n\n\t\tif inLine && (ch == '\\n' || cr.EOF()) {\n\t\t\t// Line directive complete.\n\t\t\tinLine = false\n\t\t\tlineToks := toks[lineStart:]\n\t\t\ttoks = toks[:lineStart]\n\t\t\tcr.pos = pos{lineToks[2].Text, lineToks[1].Int(), 0}\n\t\t}\n\n\t\tif cr.EOF() {\n\t\t\treturn toks, nil\n\t\t}\n\n\t\t// Skip whitespace.\n\t\tif bytes.IndexByte([]byte(\" \\t\\n\\v\\f\"), ch) >= 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Consume token.\n\t\tbuf = append(buf[:0], ch)\n\t\tstart := cr.pos\n\t\tswitch {\n\t\tcase tokTab[ch]&chNonDigit != 0:\n\t\t\t// Identifier or keyword\n\t\t\tfor {\n\t\t\t\tch = cr.ReadByte()\n\t\t\t\tif tokTab[ch]&(chNonDigit|chDigit) == 0 {\n\t\t\t\t\thaveCh = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tbuf = append(buf, ch)\n\t\t\t}\n\t\t\tif keyTab[string(buf)] {\n\t\t\t\ttoks = append(toks, Tok{TokKeyword, string(buf)})\n\t\t\t} else {\n\t\t\t\ttoks = append(toks, Tok{TokIdent, string(buf)})\n\t\t\t}\n\n\t\tcase tokTab[ch]&chDigit != 0:\n\t\t\t// Number\n\t\t\t//\n\t\t\t// TODO: Floating-point constants.\n\t\t\thex, oct := false, false\n\t\t\tfor i := 0; ; i++ {\n\t\t\t\tch = cr.ReadByte()\n\t\t\t\tif i == 0 && ch == 'x' {\n\t\t\t\t\thex = true\n\t\t\t\t} else if i == 0 && ch == '0' {\n\t\t\t\t\toct = true\n\t\t\t\t} else if hex && tokTab[ch]&chHex != 0 ||\n\t\t\t\t\toct && tokTab[ch]&chOct != 0 ||\n\t\t\t\t\ttokTab[ch]&chDigit != 0 {\n\t\t\t\t\t// Consume\n\t\t\t\t} else {\n\t\t\t\t\thaveCh = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tbuf = append(buf, ch)\n\t\t\t}\n\t\t\ttoks = append(toks, Tok{TokNumber, string(buf)})\n\n\t\tcase tokTab[ch]&chChars != 0:\n\t\t\t// Character constant or string literal\n\t\t\tterm := ch\n\t\t\tkind := \"character constant\"\n\t\t\tif ch == '\"' {\n\t\t\t\tkind = \"string literal\"\n\t\t\t}\n\t\t\tbuf = buf[:0]\n\t\t\tvar escPos pos\n\t\t\tesc, hex, oct := false, 0, 0\n\t\t\tval := uint8(0)\n\t\t\tfor {\n\t\t\t\tch = cr.ReadByte()\n\t\t\tunread:\n\t\t\t\tif cr.EOF() {\n\t\t\t\t\treturn nil, start.error(\"unterminated \" + kind)\n\t\t\t\t}\n\n\t\t\t\tif esc {\n\t\t\t\t\tesc = false\n\t\t\t\t\tif rep, ok := escTab[ch]; ok {\n\t\t\t\t\t\t// Simple escape sequence\n\t\t\t\t\t\tbuf = append(buf, rep)\n\t\t\t\t\t} else if ch == 'x' {\n\t\t\t\t\t\t// Hex escape sequence\n\t\t\t\t\t\thex, val = 1, 0\n\t\t\t\t\t} else if tokTab[ch]&chOct != 0 {\n\t\t\t\t\t\toct = 1\n\t\t\t\t\t\tval = ch - '0'\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn nil, escPos.error(\"bad escape sequence\")\n\t\t\t\t\t}\n\t\t\t\t} else if hex > 0 {\n\t\t\t\t\tif tokTab[ch]&chHex != 0 {\n\t\t\t\t\t\thex++\n\t\t\t\t\t\tval = (val << 4) | hexVal(ch)\n\t\t\t\t\t} else if hex == 1 {\n\t\t\t\t\t\treturn nil, escPos.error(\"bad escape sequence\")\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbuf = append(buf, val)\n\t\t\t\t\t\thex = 0\n\t\t\t\t\t\tgoto unread\n\t\t\t\t\t}\n\t\t\t\t} else if oct > 0 {\n\t\t\t\t\tif oct <= 3 && tokTab[ch]&chOct != 0 {\n\t\t\t\t\t\toct++\n\t\t\t\t\t\tval = (val << 3) | (ch - '0')\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbuf = append(buf, val)\n\t\t\t\t\t\toct = 0\n\t\t\t\t\t\tgoto unread\n\t\t\t\t\t}\n\t\t\t\t} else if ch == term {\n\t\t\t\t\tbreak\n\t\t\t\t} else if ch == '\\\\' {\n\t\t\t\t\tesc = true\n\t\t\t\t\tescPos = cr.pos\n\t\t\t\t} else if ch == '\\n' {\n\t\t\t\t\treturn nil, start.error(\"newline in \" + kind)\n\t\t\t\t} else {\n\t\t\t\t\tbuf = append(buf, ch)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif term == '\"' {\n\t\t\t\ttoks = append(toks, Tok{TokString, string(buf)})\n\t\t\t} else {\n\t\t\t\ttoks = append(toks, Tok{TokChar, string(buf)})\n\t\t\t}\n\n\t\tcase tokTab[ch]&chPunct != 0:\n\t\t\t// Punctuation or line directive\n\t\t\tsol := cr.pos.col == 1\n\t\t\tfor {\n\t\t\t\tch = cr.ReadByte()\n\t\t\t\tbuf = append(buf, ch)\n\t\t\t\tif !puncTab[string(buf)] {\n\t\t\t\t\tbuf = buf[:len(buf)-1]\n\t\t\t\t\thaveCh = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttext := string(buf)\n\t\t\tif sol && text == \"#\" {\n\t\t\t\t// Line directive.\n\t\t\t\tlineStart, inLine = len(toks), true\n\t\t\t}\n\t\t\ttoks = append(toks, Tok{TokOp, text})\n\n\t\tdefault:\n\t\t\treturn nil, start.error(\"unexpected character %q\", string(ch))\n\t\t}\n\t}\n}\n\nfunc hexVal(ch byte) uint8 {\n\tswitch {\n\tcase '0' <= ch && ch <= '9':\n\t\treturn ch - '0'\n\tcase 'a' <= ch && ch <= 'f':\n\t\treturn ch - 'a' + 10\n\tcase 'A' <= ch && ch <= 'F':\n\t\treturn ch - 'A' + 10\n\t}\n\tpanic(\"not a hex digit\")\n}\n\ntype toks []Tok\n\nfunc (s toks) Next() Tok {\n\tif len(s) > 0 {\n\t\treturn s[0]\n\t}\n\treturn Tok{Kind: TokEOF, Text: \"EOF\"}\n}\n\nfunc (s toks) Peek(kind TokKind, text string) bool {\n\treturn len(s) > 0 && s[0].Match(kind, text)\n}\n\nfunc (s *toks) Try(kind TokKind, text string) bool {\n\tif s.Peek(kind, text) {\n\t\t*s = (*s)[1:]\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (s *toks) TryIdent() (Tok, bool) {\n\ttok := s.Next()\n\tif tok.Kind == TokIdent {\n\t\ts.Skip(1)\n\t\treturn tok, true\n\t}\n\treturn Tok{}, false\n}\n\nfunc (s *toks) Skip(n int) {\n\tif n > len(*s) {\n\t\tn = len(*s)\n\t}\n\t(*s) = (*s)[n:]\n}\n\nfunc (s *toks) SkipBalanced(until ...string) {\n\tlevel := 0\n\tfor len(*s) != 0 {\n\t\tnext := s.Next()\n\t\tif level == 0 {\n\t\t\t// Are we at a terminator?\n\t\t\tfor _, u := range until {\n\t\t\t\tif next.Match(TokOp, u) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\ts.Skip(1)\n\t\tif next.Kind == TokOp {\n\t\t\tswitch next.Text {\n\t\t\tcase \"{\", \"(\", \"[\":\n\t\t\t\tlevel++\n\t\t\tcase \"]\", \")\", \"}\":\n\t\t\t\tlevel--\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "internal/cparse/lex_test.go",
    "content": "// Copyright 2018 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage cparse\n\nimport (\n\t\"testing\"\n)\n\nfunc TestTokenize(t *testing.T) {\n\tneedCC(t)\n\n\tpp := preprocess(t, \"#include <stdio.h>\")\n\ttoks, err := Tokenize(pp)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\t// Look for \"int fprintf(FILE *\".\n\tsubSeq := []Tok{{TokKeyword, \"int\"}, {TokIdent, \"fprintf\"}, {TokOp, \"(\"}, {TokIdent, \"FILE\"}, {TokOp, \"*\"}}\nouter:\n\tfor start := range toks {\n\t\tif len(toks)-start < len(subSeq) {\n\t\t\tt.Fatal(\"didn't find fprintf declaration in token stream\")\n\t\t}\n\t\tfor i, tok := range subSeq {\n\t\t\tif toks[start+i] != tok {\n\t\t\t\tcontinue outer\n\t\t\t}\n\t\t}\n\t\t// Found the subsequence.\n\t\tbreak\n\t}\n}\n"
  },
  {
    "path": "internal/cparse/pp.go",
    "content": "// Copyright 2018 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage cparse\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"regexp\"\n\t\"strings\"\n)\n\ntype BuildEnv struct {\n\tCCArgs []string\n}\n\nvar macroRe = regexp.MustCompile(`^#define ([_a-zA-Z][_a-zA-Z0-9]*)`)\n\n// FindMacros returns the names of all macros defined by the C source\n// in r.\nfunc FindMacros(env *BuildEnv, r io.Reader) ([]string, error) {\n\tccArgs := append([]string(nil), env.CCArgs...)\n\tccArgs = append(ccArgs, \"-x\", \"c\", \"-E\", \"-dM\", \"-\")\n\tcc := exec.Command(\"cc\", ccArgs...)\n\tcc.Stdin = r\n\tcc.Stderr = os.Stderr\n\tout, err := cc.Output()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar macros []string\n\tlines := strings.Split(string(out), \"\\n\")\n\tfor _, line := range lines {\n\t\tif line == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tm := macroRe.FindStringSubmatch(line)\n\t\tif m == nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to parse macro %q\", line)\n\t\t}\n\t\tmacros = append(macros, m[1])\n\t}\n\treturn macros, nil\n}\n\n// Preprocess invokes the C preprocessor to pre-process the C source\n// in r.\nfunc Preprocess(env *BuildEnv, r io.Reader) ([]byte, error) {\n\t// Invoke C compiler for pre-processing.\n\tccArgs := append([]string(nil), env.CCArgs...)\n\tccArgs = append(ccArgs, \"-x\", \"c\", \"-E\", \"-\")\n\tcc := exec.Command(\"cc\", ccArgs...)\n\tcc.Stdin = r\n\tcc.Stderr = os.Stderr\n\treturn cc.Output()\n}\n"
  },
  {
    "path": "internal/cparse/pp_test.go",
    "content": "// Copyright 2018 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage cparse\n\nimport (\n\t\"bytes\"\n\t\"os/exec\"\n\t\"testing\"\n)\n\nvar defaultEnv = BuildEnv{}\n\nfunc TestMacros(t *testing.T) {\n\tneedCC(t)\n\n\tsrc := bytes.NewBufferString(\"#define TEST 123\\n#define EMPTY\")\n\tmacros, err := FindMacros(&defaultEnv, src)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\nouter:\n\tfor _, want := range []string{\"EMPTY\", \"TEST\", \"__STDC__\"} {\n\t\tfor _, have := range macros {\n\t\t\tif have == want {\n\t\t\t\tcontinue outer\n\t\t\t}\n\t\t}\n\t\tt.Errorf(\"%q is not defined\", want)\n\t}\n}\n\nfunc needCC(t *testing.T) {\n\tt.Helper()\n\n\tconst bin = \"cc\"\n\tif _, err := exec.LookPath(bin); err != nil {\n\t\tt.Skipf(\"need %s binary in PATH\", bin)\n\t}\n}\n\nfunc preprocess(t *testing.T, src string) []byte {\n\tt.Helper()\n\n\tsb := bytes.NewBufferString(src)\n\tpp, err := Preprocess(&defaultEnv, sb)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\treturn pp\n}\n"
  },
  {
    "path": "internal/cparse/vals.go",
    "content": "// Copyright 2018 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage cparse\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n)\n\ntype Extractor struct {\n\tPrologue string\n\tNames    []string\n\tVals     map[string]interface{}\n}\n\nfunc (e *Extractor) Extract(env *BuildEnv) error {\n\t// Other ways to do this:\n\t//\n\t// __typeof__(x) xxx = x;\n\t//\n\t// Or generate inline assembly.\n\t//\n\t// Extract from object file (requires different object format\n\t// readers) or asm.\n\n\t// Construct printer program.\n\tsrc := bytes.NewBufferString(e.Prologue)\n\tsrc.WriteString(`\n#include <stdio.h>\n#include <string.h>\n\n#define __CPARSE_PR(x) _Generic((x), \\\n\tint                : __cparse_pr_int,  \\\n\tlong               : __cparse_pr_int,  \\\n\tlong long          : __cparse_pr_int,  \\\n\tunsigned int       : __cparse_pr_uint,  \\\n\tunsigned long      : __cparse_pr_uint, \\\n\tunsigned long long : __cparse_pr_uint, \\\n\tchar*    : __cparse_pr_str)(x)\nvoid __cparse_pr_int(long long x) {\n\tprintf(\"int %lld\\n\", x);\n}\nvoid __cparse_pr_uint(unsigned long long x) {\n\tprintf(\"uint %llu\\n\", x);\n}\nvoid __cparse_pr_str(const char *x) {\n\tprintf(\"str %zu %s\\n\", strlen(x), x);\n}\n\nint main(int argc, char **argv) {\n`)\n\tfor _, n := range e.Names {\n\t\tfmt.Fprintf(src, \"__CPARSE_PR(%s);\\n\", n)\n\t}\n\tsrc.WriteString(\"return 0;\\n}\\n\")\n\n\t// Compiler printer.\n\ttdir, err := ioutil.TempDir(\"\", \"cparse-\")\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer os.RemoveAll(tdir)\n\tprPath := filepath.Join(tdir, \"cparse-pr.exe\")\n\n\tccArgs := append([]string(nil), env.CCArgs...)\n\tccArgs = append(ccArgs, \"-Wformat\", \"-Werror\", \"-std=c11\", \"-x\", \"c\", \"-o\", prPath, \"-\")\n\tcc := exec.Command(\"cc\", ccArgs...)\n\tcc.Stdin = src\n\tcc.Stderr = os.Stderr\n\tif _, err := cc.Output(); err != nil {\n\t\tfmt.Fprintf(os.Stderr, \"compiling source:\\n%s\", src)\n\t\treturn err\n\t}\n\n\t// Run printer.\n\tpr := exec.Command(prPath)\n\toutb, err := pr.Output()\n\tif err != nil {\n\t\treturn err\n\t}\n\tout := string(outb)\n\n\t// Parse printer output.\n\te.Vals = make(map[string]interface{})\n\tfor i := 0; len(out) > 0; i++ {\n\t\tsep := strings.Index(out, \" \")\n\t\ttyp := out[:sep]\n\t\tout = out[sep+1:]\n\t\tswitch typ {\n\t\tcase \"int\":\n\t\t\tsep = strings.Index(out, \"\\n\")\n\t\t\tval, err := strconv.Atoi(out[:sep])\n\t\t\tif err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}\n\t\t\tout = out[sep+1:]\n\t\t\te.Vals[e.Names[i]] = val\n\t\tcase \"uint\":\n\t\t\tsep = strings.Index(out, \"\\n\")\n\t\t\tval, err := strconv.ParseUint(out[:sep], 10, 0)\n\t\t\tif err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}\n\t\t\tout = out[sep+1:]\n\t\t\te.Vals[e.Names[i]] = uint(val)\n\t\tcase \"str\":\n\t\t\tpanic(\"not implemented: str\")\n\t\tdefault:\n\t\t\tpanic(\"unexpected type \" + typ)\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "internal/gendefs/edit.go",
    "content": "// Copyright 2018 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport \"sort\"\n\ntype Edit struct {\n\tPos    int    // Byte offset of edit\n\tDel    int    // Number of bytes to delete at Pos\n\tInsert []byte // Bytes to insert at Pos\n}\n\nfunc DoEdit(src []byte, edits []Edit) []byte {\n\t// Sort the edits in order.\n\tsort.SliceStable(edits, func(i, j int) bool {\n\t\treturn edits[i].Pos < edits[j].Pos\n\t})\n\n\t// Check for overlapping edits.\n\tfor i := 1; i < len(edits); i++ {\n\t\tif edits[i-1].Pos+edits[i-1].Del > edits[i].Pos {\n\t\t\tpanic(\"overlapping edits\")\n\t\t}\n\t}\n\n\t// Process edits.\n\tout := []byte{}\n\tsrcPos := 0\n\tfor _, edit := range edits {\n\t\tout = append(out, src[srcPos:edit.Pos]...)\n\t\tout = append(out, edit.Insert...)\n\t\tsrcPos = edit.Pos + edit.Del\n\t}\n\tout = append(out, src[srcPos:]...)\n\n\treturn out\n}\n"
  },
  {
    "path": "internal/gendefs/main.go",
    "content": "// Copyright 2018 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport (\n\t\"bytes\"\n\t\"flag\"\n\t\"fmt\"\n\t\"go/ast\"\n\t\"go/parser\"\n\t\"go/printer\"\n\t\"go/token\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"os\"\n\t\"strings\"\n\t\"unicode\"\n\n\t\"github.com/aclements/go-perf/internal/cparse\"\n)\n\nvar ccflags = flag.String(\"ccflags\", \"\", \"space-separated list of flags to pass to cc\")\n\nfunc main() {\n\tflag.Parse()\n\n\t// Process each Go source file.\n\tfor _, path := range flag.Args() {\n\t\tprocess(path)\n\t}\n}\n\nfunc process(path string) {\n\tsrc, err := ioutil.ReadFile(path)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfset := token.NewFileSet()\n\tf, err := parser.ParseFile(fset, path, src, parser.ParseComments)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// Extract directives.\n\tvar defs []*def\n\tcsrc := new(bytes.Buffer)\n\tfor _, cg := range f.Comments {\n\t\tfor _, c := range cg.List {\n\t\t\tsp := strings.IndexAny(c.Text, \" \\r\\n\\t\\v\\f\")\n\t\t\tif sp < 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tcmd := c.Text[2:sp]\n\t\t\tif cmd == \"gendefs:C\" {\n\t\t\t\tfmt.Fprintf(csrc, \"%s\\n\", c.Text[sp:len(c.Text)-2])\n\t\t\t} else if cmd == \"gendefs\" {\n\t\t\t\tdefs = append(defs, parseDef(c))\n\t\t\t}\n\t\t}\n\t}\n\t// Attach declaration blocks to def directives.\n\tdefsTodo := defs\n\tfor _, decl := range f.Decls {\n\t\t// Skip decls before the next def.\n\t\tif len(defsTodo) == 0 {\n\t\t\tbreak\n\t\t}\n\t\tif decl.Pos() < defsTodo[0].Pos {\n\t\t\tcontinue\n\t\t}\n\t\t// Attach this decl.\n\t\tif decl, ok := decl.(*ast.GenDecl); !ok || decl.Tok != token.CONST {\n\t\t\tlog.Fatalf(\"%s: def must be applied to const\", fset.Position(defsTodo[0].Pos))\n\t\t}\n\t\tdefsTodo[0].Decl = decl.(*ast.GenDecl)\n\t\tdefsTodo = defsTodo[1:]\n\t\t// Check for more than one def per decl.\n\t\tif len(defsTodo) > 0 && defsTodo[0].Pos < decl.Pos() {\n\t\t\tlog.Fatalf(\"%s: multiple defs for declaration\", fset.Position(decl.Pos()))\n\t\t}\n\t}\n\tif len(defsTodo) > 0 {\n\t\tlog.Fatalf(\"%s: def without a declaration\", fset.Position(defsTodo[0].Pos))\n\t}\n\n\t// Get identifier names from C code.\n\tenv := cparse.BuildEnv{CCArgs: strings.Fields(*ccflags)}\n\tpp, err := cparse.Preprocess(&env, bytes.NewBuffer(csrc.Bytes()))\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\ttoks, err := cparse.Tokenize(pp)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// TODO: Macros aren't in source order. :( Maybe I need to\n\t// sort them by value? Or do my own pre-processor scan just to\n\t// get the names (and hope that ignoring other pre-processor\n\t// directives is okay)?\n\tmacros, err := cparse.FindMacros(&env, bytes.NewBuffer(csrc.Bytes()))\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tconsts, err := cparse.FindEnums(toks)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tfor _, m := range macros {\n\t\tconsts = append(consts, cparse.Enum{Ident: cparse.Tok{Text: m}})\n\t}\n\n\t// Extract values of defs.\n\tex := cparse.Extractor{Prologue: csrc.String()}\n\tfor _, def := range defs {\n\t\tfor i, c := range consts {\n\t\t\tid := c.Ident.Text\n\t\t\tif def.OmitMax && i == len(consts)-1 && strings.HasSuffix(id, \"_MAX\") {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif def.Omit[id] {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t_, ok1 := def.CTag(c.Tag.Text)\n\t\t\t_, ok2 := def.CIdent(id)\n\t\t\tif ok1 && ok2 {\n\t\t\t\tdef.Names = append(def.Names, id)\n\t\t\t\tex.Names = append(ex.Names, id)\n\t\t\t}\n\t\t}\n\t\tif def.OmitMax && len(def.Names) > 0 {\n\t\t\tif last := def.Names[len(def.Names)-1]; !strings.HasSuffix(last, \"_MAX\") {\n\t\t\t\tlog.Fatalf(\"%s: final name is %s, expected *_MAX\", fset.Position(def.Pos), last)\n\t\t\t}\n\t\t\tdef.Names = def.Names[:len(def.Names)-1]\n\t\t\tex.Names = ex.Names[:len(ex.Names)-1]\n\t\t}\n\n\t\tif len(def.Names) == 0 {\n\t\t\tlog.Fatalf(\"%s: no constants match C name\", fset.Position(def.Pos))\n\t\t}\n\t}\n\n\tif err := ex.Extract(&env); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// Replace decls.\n\tvar edits []Edit\n\tfilePos := func(pos token.Pos) int {\n\t\treturn fset.Position(pos).Offset\n\t}\n\tfor _, def := range defs {\n\t\t// Delete the const block.\n\t\tlparen := filePos(def.Decl.Lparen)\n\t\trparen := filePos(def.Decl.Rparen)\n\t\tedit := Edit{Pos: lparen + 1, Del: rparen - lparen - 1}\n\t\tinsert := new(bytes.Buffer)\n\n\t\t// Translate values to expressions.\n\t\tvar vals []interface{}\n\t\tfor _, name := range def.Names {\n\t\t\tvals = append(vals, ex.Vals[name])\n\t\t}\n\n\t\t// Clean up value sequence.\n\t\tvalExprs := cleanVals(vals)\n\n\t\t// Collect comments on existing values. We do this\n\t\t// straight from the text to avoid depending on how\n\t\t// package ast attaches comments to nodes. This\n\t\t// maintains interstitial comments and other\n\t\t// formatting.\n\t\tdocText := map[string][]byte{}\n\t\tlineText := map[string][]byte{}\n\t\tprevEnd := lparen + 2 // Skip newline\n\t\tfor _, spec := range def.Decl.Specs {\n\t\t\tspec := spec.(*ast.ValueSpec)\n\t\t\tdocEnd := filePos(spec.Pos())\n\t\t\t// Back up to the end of the previous line,\n\t\t\t// where the comment ended.\n\t\t\tfor src[docEnd] != '\\n' {\n\t\t\t\tdocEnd--\n\t\t\t}\n\t\t\tdocEnd++\n\t\t\t// Extract the doc text from before the spec.\n\t\t\tif prevEnd < docEnd {\n\t\t\t\tdocText[spec.Names[0].Name] = src[prevEnd:docEnd]\n\t\t\t}\n\n\t\t\t// Extract the line text from after the spec.\n\t\t\tend := filePos(spec.End())\n\t\t\tlineLen := bytes.IndexByte(src[end:], '\\n')\n\t\t\tif lineLen > 0 {\n\t\t\t\tlineText[spec.Names[0].Name] = src[end : end+lineLen]\n\t\t\t}\n\t\t\tprevEnd = end + lineLen + 1 // Skip newline\n\t\t}\n\n\t\tvar prevType string\n\t\tfor i, name := range def.Names {\n\t\t\tsuff, _ := def.CIdent(name)\n\t\t\tgoName := def.GoPrefix + cNameToGo(suff)\n\n\t\t\t// Emit doc comment.\n\t\t\tif text, ok := docText[goName]; ok {\n\t\t\t\tfmt.Fprintf(insert, \"\\n%s\", text)\n\t\t\t}\n\n\t\t\t// Emit name.\n\t\t\tfmt.Fprintf(insert, \"\\n\\t%s\", goName)\n\n\t\t\t// Emit type.\n\t\t\tif def.GoType != prevType {\n\t\t\t\tfmt.Fprintf(insert, \" %s\", def.GoType)\n\t\t\t\tprevType = def.GoType\n\t\t\t}\n\n\t\t\t// Emit value.\n\t\t\tif valExprs[i] != nil {\n\t\t\t\tfmt.Fprintf(insert, \"=\")\n\t\t\t\tprinter.Fprint(insert, fset, valExprs[i])\n\t\t\t}\n\n\t\t\t// Emit line comment.\n\t\t\tif text, ok := lineText[goName]; ok {\n\t\t\t\tfmt.Fprintf(insert, \"%s\", text)\n\t\t\t}\n\t\t}\n\n\t\tfmt.Fprintf(insert, \"\\n\")\n\t\tedit.Insert = insert.Bytes()\n\t\tedits = append(edits, edit)\n\t}\n\n\tfmt.Printf(\"%s\", format(DoEdit(src, edits)))\n}\n\ntype def struct {\n\tCTag     func(string) (string, bool)\n\tCIdent   func(string) (string, bool)\n\tGoPrefix string\n\tGoType   string\n\tOmit     map[string]bool\n\tOmitMax  bool\n\tPos      token.Pos\n\tDecl     *ast.GenDecl\n\tNames    []string\n}\n\nfunc parseDef(c *ast.Comment) *def {\n\tvar d def\n\targs := strings.Fields(c.Text)[1:]\n\n\t// Extract flags, leaving only positional args.\n\tvar pos []string\n\tfor len(args) > 0 {\n\t\targ := args[0]\n\t\targs = args[1:]\n\t\tswitch {\n\t\tcase arg == \"-omit\":\n\t\t\tif len(args) < 1 {\n\t\t\t\tlog.Fatalf(\"missing argument: -no\")\n\t\t\t}\n\t\t\tif d.Omit == nil {\n\t\t\t\td.Omit = make(map[string]bool)\n\t\t\t}\n\t\t\td.Omit[args[0]] = true\n\t\t\targs = args[1:]\n\t\tcase arg == \"-omit-max\":\n\t\t\td.OmitMax = true\n\t\tcase arg[0] == '-':\n\t\t\tlog.Fatalf(\"unknown directive flag %s\", arg)\n\t\tdefault:\n\t\t\tpos = append(pos, arg)\n\t\t}\n\t}\n\n\tif len(pos) < 2 || len(pos) > 3 {\n\t\tlog.Fatalf(\"wrong number of directive arguments; expected 2 or 3\")\n\t}\n\tif i := strings.Index(pos[0], \".\"); i < 0 {\n\t\td.CTag = func(x string) (string, bool) { return x, true }\n\t\td.CIdent = compileGlob(pos[0])\n\t} else {\n\t\td.CTag = compileGlob(pos[0][:i])\n\t\td.CIdent = compileGlob(pos[0][i+1:])\n\t}\n\td.GoPrefix = pos[1]\n\tif len(pos) == 2 {\n\t\td.GoType = pos[1]\n\t} else {\n\t\td.GoType = pos[2]\n\t}\n\td.Pos = c.Slash\n\n\treturn &d\n}\n\nfunc compileGlob(glob string) func(string) (suff string, match bool) {\n\tif !strings.HasSuffix(glob, \"*\") {\n\t\treturn func(x string) (string, bool) {\n\t\t\treturn \"\", glob == x\n\t\t}\n\t}\n\tpfx := glob[:len(glob)-1]\n\treturn func(x string) (string, bool) {\n\t\tif strings.HasPrefix(x, pfx) {\n\t\t\treturn x[len(pfx):], true\n\t\t}\n\t\treturn \"\", false\n\t}\n}\n\nfunc cleanVals(lits []interface{}) []ast.Expr {\n\t// Look for sequential patterns.\n\tisOffset := make([]bool, len(lits))\n\toffsets := make([]int, len(lits))\n\tisShift := make([]bool, len(lits))\n\tfor i, lit := range lits {\n\t\tswitch val := lit.(type) {\n\t\tcase int:\n\t\t\tisOffset[i] = true\n\t\t\toffsets[i] = val - i\n\t\t\tisShift[i] = val == (1 << uint(i))\n\t\tcase uint:\n\t\tdefault:\n\t\t\tlog.Fatalf(\"unhandled constant type %T\", lit)\n\t\t}\n\t}\n\n\t// Extract longest runs and create exprs.\n\trunLen := func(len int, fn func(int) bool) int {\n\t\tfor i := 0; i < len; i++ {\n\t\t\tif !fn(i) {\n\t\t\t\treturn i\n\t\t\t}\n\t\t}\n\t\treturn len\n\t}\n\tintLit := func(v int) ast.Expr {\n\t\treturn &ast.BasicLit{\n\t\t\tKind:  token.INT,\n\t\t\tValue: fmt.Sprint(v),\n\t\t}\n\t}\n\texprs := make([]ast.Expr, len(lits))\n\tiota := ast.NewIdent(\"iota\")\n\tfor i := 0; i < len(lits); {\n\t\toffsetRun := runLen(len(offsets)-i, func(j int) bool {\n\t\t\treturn isOffset[i+j] && offsets[i+j] == offsets[i]\n\t\t})\n\t\tshiftRun := runLen(len(isShift)-i, func(j int) bool {\n\t\t\treturn isShift[i+j]\n\t\t})\n\t\tif offsetRun > 1 && offsetRun >= shiftRun {\n\t\t\t// Run of iota offsets.\n\t\t\tif offsets[i] == 0 {\n\t\t\t\texprs[i] = iota\n\t\t\t} else {\n\t\t\t\texprs[i] = &ast.BinaryExpr{X: iota, Op: token.ADD, Y: intLit(offsets[i])}\n\t\t\t}\n\t\t\ti += offsetRun\n\t\t} else if shiftRun > 1 {\n\t\t\t// Run of iota shifts.\n\t\t\texprs[i] = &ast.BinaryExpr{X: intLit(1), Op: token.SHL, Y: iota}\n\t\t\ti += shiftRun\n\t\t} else {\n\t\t\t// Singleton.\n\t\t\tswitch val := lits[i].(type) {\n\t\t\tcase int:\n\t\t\t\texprs[i] = intLit(val)\n\t\t\tcase uint:\n\t\t\t\texprs[i] = &ast.BasicLit{\n\t\t\t\t\tKind:  token.INT,\n\t\t\t\t\tValue: fmt.Sprintf(\"%#x\", val),\n\t\t\t\t}\n\t\t\t}\n\t\t\ti++\n\t\t}\n\t}\n\treturn exprs\n}\n\nvar words = map[string]string{\n\t\"CPU\":  \"CPU\",\n\t\"PMU\":  \"PMU\",\n\t\"TSC\":  \"TSC\",\n\t\"MTC\":  \"MTC\",\n\t\"CTC\":  \"CTC\",\n\t\"ID\":   \"ID\",\n\t\"PID\":  \"PID\",\n\t\"TID\":  \"TID\",\n\t\"IP\":   \"IP\",\n\t\"L1D\":  \"L1D\",\n\t\"L1I\":  \"L1I\",\n\t\"LL\":   \"LL\",\n\t\"DTLB\": \"DTLB\",\n\t\"ITLB\": \"ITLB\",\n\t\"BPU\":  \"BPU\", // Branch prediction unit?\n\t\"HW\":   \"HW\",  // Hardware\n\t\"TX\":   \"TX\",  // Transaction\n\t\"HV\":   \"HV\",  // Hypervisor\n\n\t\"CGROUP\":  \"CGroup\",\n\t\"CPUMODE\": \"CPUMode\",\n}\n\nfunc cNameToGo(c string) string {\n\tvar out []rune\n\tparts := strings.Split(c, \"_\")\n\tfor _, part := range parts {\n\t\tif w, ok := words[part]; ok {\n\t\t\tout = append(out, []rune(w)...)\n\t\t\tcontinue\n\t\t}\n\t\tfor i, r := range part {\n\t\t\tif i == 0 {\n\t\t\t\tout = append(out, unicode.ToTitle(r))\n\t\t\t} else {\n\t\t\t\tout = append(out, unicode.ToLower(r))\n\t\t\t}\n\t\t}\n\t}\n\treturn string(out)\n}\n\nfunc format(src []byte) []byte {\n\tfset := token.NewFileSet()\n\tf, err := parser.ParseFile(fset, \"<output>\", src, parser.ParseComments)\n\tif err != nil {\n\t\tfmt.Fprintf(os.Stderr, \"%s\", src)\n\t\tlog.Fatal(err)\n\t}\n\n\tcfg := printer.Config{Mode: printer.TabIndent | printer.UseSpaces, Tabwidth: 8}\n\tbuf := new(bytes.Buffer)\n\tcfg.Fprint(buf, fset, f)\n\treturn buf.Bytes()\n}\n"
  },
  {
    "path": "perffile/auxflags_string.go",
    "content": "// Code generated by \"bitstringer -type=AuxFlags\"; DO NOT EDIT\n\npackage perffile\n\nimport \"strconv\"\n\nfunc (i AuxFlags) String() string {\n\tif i == 0 {\n\t\treturn \"0\"\n\t}\n\ts := \"\"\n\tif i&AuxFlagCollision != 0 {\n\t\ts += \"Collision|\"\n\t}\n\tif i&AuxFlagOverwrite != 0 {\n\t\ts += \"Overwrite|\"\n\t}\n\tif i&AuxFlagPartial != 0 {\n\t\ts += \"Partial|\"\n\t}\n\tif i&AuxFlagTruncated != 0 {\n\t\ts += \"Truncated|\"\n\t}\n\ti &^= 15\n\tif i == 0 {\n\t\treturn s[:len(s)-1]\n\t}\n\treturn s + \"0x\" + strconv.FormatUint(uint64(i), 16)\n}\n"
  },
  {
    "path": "perffile/auxpmuformat_string.go",
    "content": "// Code generated by \"stringer -type=AuxPMUFormat\"; DO NOT EDIT.\n\npackage perffile\n\nimport \"strconv\"\n\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[AuxPMUFormatCoresightCoresight-0]\n\t_ = x[AuxPMUFormatCoresightRaw-1]\n\t_ = x[AuxPMUFormatDefault-0]\n}\n\nconst _AuxPMUFormat_name = \"AuxPMUFormatCoresightCoresightAuxPMUFormatCoresightRaw\"\n\nvar _AuxPMUFormat_index = [...]uint8{0, 30, 54}\n\nfunc (i AuxPMUFormat) String() string {\n\tif i >= AuxPMUFormat(len(_AuxPMUFormat_index)-1) {\n\t\treturn \"AuxPMUFormat(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n\treturn _AuxPMUFormat_name[_AuxPMUFormat_index[i]:_AuxPMUFormat_index[i+1]]\n}\n"
  },
  {
    "path": "perffile/bpfeventtype_string.go",
    "content": "// Code generated by \"bitstringer -type=BPFEventType\"; DO NOT EDIT\n\npackage perffile\n\nimport \"strconv\"\n\nfunc (i BPFEventType) String() string {\n\tif i == 0 {\n\t\treturn \"Unknown\"\n\t}\n\ts := \"\"\n\tif i&BPFEventTypeProgLoad != 0 {\n\t\ts += \"ProgLoad|\"\n\t}\n\tif i&BPFEventTypeProgUnload != 0 {\n\t\ts += \"ProgUnload|\"\n\t}\n\ti &^= 3\n\tif i == 0 {\n\t\treturn s[:len(s)-1]\n\t}\n\treturn s + \"0x\" + strconv.FormatUint(uint64(i), 16)\n}\n"
  },
  {
    "path": "perffile/branchflags_string.go",
    "content": "// Code generated by \"bitstringer -type=BranchFlags\"; DO NOT EDIT\n\npackage perffile\n\nimport \"strconv\"\n\nfunc (i BranchFlags) String() string {\n\tif i == 0 {\n\t\treturn \"0\"\n\t}\n\ts := \"\"\n\tif i&BranchFlagAbort != 0 {\n\t\ts += \"Abort|\"\n\t}\n\tif i&BranchFlagInTransaction != 0 {\n\t\ts += \"InTransaction|\"\n\t}\n\tif i&BranchFlagMispredicted != 0 {\n\t\ts += \"Mispredicted|\"\n\t}\n\tif i&BranchFlagPredicted != 0 {\n\t\ts += \"Predicted|\"\n\t}\n\ti &^= 15\n\tif i == 0 {\n\t\treturn s[:len(s)-1]\n\t}\n\treturn s + \"0x\" + strconv.FormatUint(uint64(i), 16)\n}\n"
  },
  {
    "path": "perffile/branchsampletype_string.go",
    "content": "// Code generated by \"bitstringer -type=BranchSampleType\"; DO NOT EDIT\n\npackage perffile\n\nimport \"strconv\"\n\nfunc (i BranchSampleType) String() string {\n\tif i == 0 {\n\t\treturn \"0\"\n\t}\n\ts := \"\"\n\tif i&BranchSampleAbortTX != 0 {\n\t\ts += \"AbortTX|\"\n\t}\n\tif i&BranchSampleAny != 0 {\n\t\ts += \"Any|\"\n\t}\n\tif i&BranchSampleAnyCall != 0 {\n\t\ts += \"AnyCall|\"\n\t}\n\tif i&BranchSampleAnyReturn != 0 {\n\t\ts += \"AnyReturn|\"\n\t}\n\tif i&BranchSampleCall != 0 {\n\t\ts += \"Call|\"\n\t}\n\tif i&BranchSampleCallStack != 0 {\n\t\ts += \"CallStack|\"\n\t}\n\tif i&BranchSampleCond != 0 {\n\t\ts += \"Cond|\"\n\t}\n\tif i&BranchSampleHV != 0 {\n\t\ts += \"HV|\"\n\t}\n\tif i&BranchSampleHWIndex != 0 {\n\t\ts += \"HWIndex|\"\n\t}\n\tif i&BranchSampleInTX != 0 {\n\t\ts += \"InTX|\"\n\t}\n\tif i&BranchSampleIndCall != 0 {\n\t\ts += \"IndCall|\"\n\t}\n\tif i&BranchSampleIndJump != 0 {\n\t\ts += \"IndJump|\"\n\t}\n\tif i&BranchSampleKernel != 0 {\n\t\ts += \"Kernel|\"\n\t}\n\tif i&BranchSampleNoCycles != 0 {\n\t\ts += \"NoCycles|\"\n\t}\n\tif i&BranchSampleNoFlags != 0 {\n\t\ts += \"NoFlags|\"\n\t}\n\tif i&BranchSampleNoTX != 0 {\n\t\ts += \"NoTX|\"\n\t}\n\tif i&BranchSampleTypeSave != 0 {\n\t\ts += \"TypeSave|\"\n\t}\n\tif i&BranchSampleUser != 0 {\n\t\ts += \"User|\"\n\t}\n\ti &^= 262143\n\tif i == 0 {\n\t\treturn s[:len(s)-1]\n\t}\n\treturn s + \"0x\" + strconv.FormatUint(uint64(i), 16)\n}\n"
  },
  {
    "path": "perffile/breakpointop_string.go",
    "content": "// Code generated by \"bitstringer -type=BreakpointOp\"; DO NOT EDIT\n\npackage perffile\n\nimport \"strconv\"\n\nfunc (i BreakpointOp) String() string {\n\tif i == 0 {\n\t\treturn \"0\"\n\t}\n\ts := \"\"\n\tif i&BreakpointOpR != 0 {\n\t\ts += \"R|\"\n\t}\n\tif i&BreakpointOpRW != 0 {\n\t\ts += \"RW|\"\n\t}\n\ti &^= 3\n\tif i == 0 {\n\t\treturn s[:len(s)-1]\n\t}\n\treturn s + \"0x\" + strconv.FormatUint(uint64(i), 16)\n}\n"
  },
  {
    "path": "perffile/buf.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage perffile\n\nimport (\n\t\"errors\"\n\t\"io\"\n)\n\n// bufferedSectionReader is a buffered io.SectionReader with offset\n// tracking.\n//\n// This is based on bufio.Reader. This could apply to an arbitrary\n// io.Reader, but it's specialized for our one current use so the\n// linker can statically resolve the method calls.\ntype bufferedSectionReader struct {\n\tbuf  []byte\n\trd   *io.SectionReader\n\tr, w int // buf read and write positions\n\terr  error\n\tpos  int64 // file position of read\n}\n\nfunc newBufferedSectionReader(rd *io.SectionReader) *bufferedSectionReader {\n\tpos, err := rd.Seek(0, 1)\n\treturn &bufferedSectionReader{\n\t\tbuf: make([]byte, 16<<10),\n\t\trd:  rd,\n\t\tpos: pos,\n\t\terr: err,\n\t}\n}\n\nvar errNegativeRead = errors.New(\"reader returned negative count from Read\")\n\nfunc (b *bufferedSectionReader) readErr() error {\n\terr := b.err\n\tb.err = nil\n\treturn err\n}\n\nfunc (b *bufferedSectionReader) Seek(offset int64, whence int) (int64, error) {\n\tif whence == 0 && offset == b.pos || whence == 1 && offset == 0 {\n\t\treturn b.pos, nil\n\t}\n\n\tvar err error\n\tb.pos, err = b.rd.Seek(offset, whence)\n\tif err == nil {\n\t\tb.r, b.w = 0, 0\n\t}\n\treturn b.pos, err\n}\n\nfunc (b *bufferedSectionReader) Read(p []byte) (n int, err error) {\n\tn = len(p)\n\tif n == 0 {\n\t\treturn 0, b.readErr()\n\t}\n\tif b.r == b.w {\n\t\tif b.err != nil {\n\t\t\treturn 0, b.readErr()\n\t\t}\n\t\tif len(p) >= len(b.buf) {\n\t\t\t// Large read, empty buffer.\n\t\t\t// Read directly into p to avoid copy.\n\t\t\tn, b.err = b.rd.Read(p)\n\t\t\tif n < 0 {\n\t\t\t\tpanic(errNegativeRead)\n\t\t\t}\n\t\t\tb.pos += int64(n)\n\t\t\treturn n, b.readErr()\n\t\t}\n\t\tb.fill() // buffer is empty\n\t\tif b.r == b.w {\n\t\t\treturn 0, b.readErr()\n\t\t}\n\t}\n\n\t// copy as much as we can\n\tn = copy(p, b.buf[b.r:b.w])\n\tb.r += n\n\tb.pos += int64(n)\n\treturn n, nil\n}\n\n// fill reads a new chunk into the buffer.\nfunc (b *bufferedSectionReader) fill() {\n\t// Slide existing data to beginning.\n\tif b.r > 0 {\n\t\tcopy(b.buf, b.buf[b.r:b.w])\n\t\tb.w -= b.r\n\t\tb.r = 0\n\t}\n\n\tif b.w >= len(b.buf) {\n\t\tpanic(\"tried to fill full buffer\")\n\t}\n\n\t// Read new data: try a limited number of times.\n\tfor i := 0; i < 100; i++ {\n\t\tn, err := b.rd.Read(b.buf[b.w:])\n\t\tif n < 0 {\n\t\t\tpanic(errNegativeRead)\n\t\t}\n\t\tb.w += n\n\t\tif err != nil {\n\t\t\tb.err = err\n\t\t\treturn\n\t\t}\n\t\tif n > 0 {\n\t\t\treturn\n\t\t}\n\t}\n\tb.err = io.ErrNoProgress\n}\n"
  },
  {
    "path": "perffile/bufdecoder.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage perffile\n\nimport \"encoding/binary\"\n\ntype bufDecoder struct {\n\tbuf   []byte\n\torder binary.ByteOrder\n}\n\nfunc (b *bufDecoder) skip(n int) {\n\tb.buf = b.buf[n:]\n}\n\nfunc (b *bufDecoder) bytes(x []byte) {\n\tcopy(x, b.buf)\n\tb.buf = b.buf[len(x):]\n}\n\nfunc (b *bufDecoder) u8() uint8 {\n\tx := b.buf[0]\n\tb.buf = b.buf[1:]\n\treturn x\n}\n\nfunc (b *bufDecoder) u16() uint16 {\n\tx := b.order.Uint16(b.buf)\n\tb.buf = b.buf[2:]\n\treturn x\n}\n\nfunc (b *bufDecoder) u32() uint32 {\n\tx := b.order.Uint32(b.buf)\n\tb.buf = b.buf[4:]\n\treturn x\n}\n\nfunc (b *bufDecoder) i32() int32 {\n\tx := int32(b.order.Uint32(b.buf))\n\tb.buf = b.buf[4:]\n\treturn x\n}\n\nfunc (b *bufDecoder) u64() uint64 {\n\tx := b.order.Uint64(b.buf)\n\tb.buf = b.buf[8:]\n\treturn x\n}\n\nfunc (b *bufDecoder) i64() int64 {\n\tx := int64(b.order.Uint64(b.buf))\n\tb.buf = b.buf[8:]\n\treturn x\n}\n\nfunc (b *bufDecoder) u64s(x []uint64) {\n\tfor i := range x {\n\t\tx[i] = b.order.Uint64(b.buf[i*8:])\n\t}\n\tb.buf = b.buf[len(x)*8:]\n}\n\nfunc (b *bufDecoder) u32If(cond bool) uint32 {\n\tif cond {\n\t\treturn b.u32()\n\t}\n\treturn 0\n}\n\nfunc (b *bufDecoder) i32If(cond bool) int32 {\n\tif cond {\n\t\treturn b.i32()\n\t}\n\treturn 0\n}\n\nfunc (b *bufDecoder) u64If(cond bool) uint64 {\n\tif cond {\n\t\treturn b.u64()\n\t}\n\treturn 0\n}\n\nfunc (b *bufDecoder) i64If(cond bool) int64 {\n\tif cond {\n\t\treturn b.i64()\n\t}\n\treturn 0\n}\n\nfunc (b *bufDecoder) cstring() string {\n\tfor i, c := range b.buf {\n\t\tif c == 0 {\n\t\t\tx := string(b.buf[:i])\n\t\t\tb.buf = b.buf[i+1:]\n\t\t\treturn x\n\t\t}\n\t}\n\t// TODO: Error?\n\tx := string(b.buf)\n\tb.buf = b.buf[:1]\n\treturn x\n}\n\nfunc (b *bufDecoder) lenString() string {\n\tl := b.u32()\n\tif l > uint32(len(b.buf)) {\n\t\t// TODO: Error?\n\t\tl = uint32(len(b.buf))\n\t}\n\tstr := (&bufDecoder{b.buf[:l], nil}).cstring()\n\tb.buf = b.buf[l:]\n\treturn str\n}\n\nfunc (b *bufDecoder) stringList() []string {\n\tout := []string{}\n\tcount := b.u32()\n\tfor i := uint32(0); i < count; i++ {\n\t\tout = append(out, b.lenString())\n\t}\n\treturn out\n}\n"
  },
  {
    "path": "perffile/cpumode_string.go",
    "content": "// Code generated by \"stringer -type=CPUMode\"; DO NOT EDIT.\n\npackage perffile\n\nimport \"strconv\"\n\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[CPUModeUnknown-0]\n\t_ = x[CPUModeKernel-1]\n\t_ = x[CPUModeUser-2]\n\t_ = x[CPUModeHypervisor-3]\n\t_ = x[CPUModeGuestKernel-4]\n\t_ = x[CPUModeGuestUser-5]\n}\n\nconst _CPUMode_name = \"CPUModeUnknownCPUModeKernelCPUModeUserCPUModeHypervisorCPUModeGuestKernelCPUModeGuestUser\"\n\nvar _CPUMode_index = [...]uint8{0, 14, 27, 38, 55, 73, 89}\n\nfunc (i CPUMode) String() string {\n\tif i >= CPUMode(len(_CPUMode_index)-1) {\n\t\treturn \"CPUMode(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n\treturn _CPUMode_name[_CPUMode_index[i]:_CPUMode_index[i+1]]\n}\n"
  },
  {
    "path": "perffile/cpuset.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage perffile\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// A CPUSet represents a set of CPUs by CPU index.\ntype CPUSet []int\n\nfunc parseCPUSet(str string) (CPUSet, error) {\n\tvar err error\n\tout := CPUSet{}\n\tfor _, r := range strings.Split(str, \",\") {\n\t\tvar lo, hi int\n\t\tdash := strings.Index(r, \"-\")\n\t\tif dash == -1 {\n\t\t\tlo, err = strconv.Atoi(r)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\thi = lo\n\t\t} else {\n\t\t\tlo, err = strconv.Atoi(r[:dash])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\thi, err = strconv.Atoi(r[dash+1:])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\tfor cpu := lo; cpu <= hi; cpu++ {\n\t\t\tout = append(out, cpu)\n\t\t}\n\t}\n\tsort.Ints(out)\n\ti, j := 0, 0\n\tfor ; i < len(out); i++ {\n\t\tif i != j && out[i] == out[j] {\n\t\t\tcontinue\n\t\t}\n\t\tout[j] = out[i]\n\t\tj++\n\t}\n\treturn out, nil\n}\n\nfunc (c CPUSet) String() string {\n\tif len(c) == 0 {\n\t\treturn \"\"\n\t}\n\n\tout := \"\"\n\tlo, hi := c[0], c[0]-1\n\tflush := func() {\n\t\tif lo == hi {\n\t\t\tout = fmt.Sprintf(\"%s,%d\", out, lo)\n\t\t} else {\n\t\t\tout = fmt.Sprintf(\"%s,%d-%d\", out, lo, hi)\n\t\t}\n\t}\n\tfor _, cpu := range c {\n\t\tif cpu == hi+1 {\n\t\t\thi = cpu\n\t\t} else {\n\t\t\tflush()\n\t\t\tlo, hi = cpu, cpu\n\t\t}\n\t}\n\tflush()\n\treturn out[1:]\n}\n"
  },
  {
    "path": "perffile/datasrcblock_string.go",
    "content": "// Code generated by \"bitstringer -type=DataSrcBlock\"; DO NOT EDIT\n\npackage perffile\n\nimport \"strconv\"\n\nfunc (i DataSrcBlock) String() string {\n\tif i == 0 {\n\t\treturn \"NA\"\n\t}\n\ts := \"\"\n\tif i&DataSrcBlockAddr != 0 {\n\t\ts += \"Addr|\"\n\t}\n\tif i&DataSrcBlockData != 0 {\n\t\ts += \"Data|\"\n\t}\n\ti &^= 3\n\tif i == 0 {\n\t\treturn s[:len(s)-1]\n\t}\n\treturn s + \"0x\" + strconv.FormatUint(uint64(i), 16)\n}\n"
  },
  {
    "path": "perffile/datasrchops_string.go",
    "content": "// Code generated by \"stringer -type=DataSrcHops\"; DO NOT EDIT.\n\npackage perffile\n\nimport \"strconv\"\n\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[DataSrcHopsCore-1]\n\t_ = x[DataSrcHopsNode-3]\n\t_ = x[DataSrcHopsSocket-3]\n\t_ = x[DataSrcHopesBoard-4]\n\t_ = x[DataSrcHopsNA-0]\n}\n\nconst (\n\t_DataSrcHops_name_0 = \"DataSrcHopsNADataSrcHopsCore\"\n\t_DataSrcHops_name_1 = \"DataSrcHopsNodeDataSrcHopesBoard\"\n)\n\nvar (\n\t_DataSrcHops_index_0 = [...]uint8{0, 13, 28}\n\t_DataSrcHops_index_1 = [...]uint8{0, 15, 32}\n)\n\nfunc (i DataSrcHops) String() string {\n\tswitch {\n\tcase 0 <= i && i <= 1:\n\t\treturn _DataSrcHops_name_0[_DataSrcHops_index_0[i]:_DataSrcHops_index_0[i+1]]\n\tcase 3 <= i && i <= 4:\n\t\ti -= 3\n\t\treturn _DataSrcHops_name_1[_DataSrcHops_index_1[i]:_DataSrcHops_index_1[i+1]]\n\tdefault:\n\t\treturn \"DataSrcHops(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n}\n"
  },
  {
    "path": "perffile/datasrclevel_string.go",
    "content": "// Code generated by \"bitstringer -type=DataSrcLevel\"; DO NOT EDIT\n\npackage perffile\n\nimport \"strconv\"\n\nfunc (i DataSrcLevel) String() string {\n\tif i == 0 {\n\t\treturn \"NA\"\n\t}\n\ts := \"\"\n\tif i&DataSrcLevelIO != 0 {\n\t\ts += \"IO|\"\n\t}\n\tif i&DataSrcLevelL1 != 0 {\n\t\ts += \"L1|\"\n\t}\n\tif i&DataSrcLevelL2 != 0 {\n\t\ts += \"L2|\"\n\t}\n\tif i&DataSrcLevelL3 != 0 {\n\t\ts += \"L3|\"\n\t}\n\tif i&DataSrcLevelLFB != 0 {\n\t\ts += \"LFB|\"\n\t}\n\tif i&DataSrcLevelLocalRAM != 0 {\n\t\ts += \"LocalRAM|\"\n\t}\n\tif i&DataSrcLevelRemoteCache1 != 0 {\n\t\ts += \"RemoteCache1|\"\n\t}\n\tif i&DataSrcLevelRemoteCache2 != 0 {\n\t\ts += \"RemoteCache2|\"\n\t}\n\tif i&DataSrcLevelRemoteRAM1 != 0 {\n\t\ts += \"RemoteRAM1|\"\n\t}\n\tif i&DataSrcLevelRemoteRAM2 != 0 {\n\t\ts += \"RemoteRAM2|\"\n\t}\n\tif i&DataSrcLevelUncached != 0 {\n\t\ts += \"Uncached|\"\n\t}\n\ti &^= 2047\n\tif i == 0 {\n\t\treturn s[:len(s)-1]\n\t}\n\treturn s + \"0x\" + strconv.FormatUint(uint64(i), 16)\n}\n"
  },
  {
    "path": "perffile/datasrclevelnum_string.go",
    "content": "// Code generated by \"stringer -type=DataSrcLevelNum\"; DO NOT EDIT.\n\npackage perffile\n\nimport \"strconv\"\n\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[DataSrcLevelNumL1-1]\n\t_ = x[DataSrcLevelNumL2-2]\n\t_ = x[DataSrcLevelNumL3-3]\n\t_ = x[DataSrcLevelNumL4-4]\n\t_ = x[DataSrcLevelNumAnyCache-11]\n\t_ = x[DataSrcLevelNumLFB-12]\n\t_ = x[DataSrcLevelNumRAM-13]\n\t_ = x[DataSrcLevelNumPMEM-14]\n\t_ = x[DataSrcLevelNumNA-15]\n}\n\nconst (\n\t_DataSrcLevelNum_name_0 = \"DataSrcLevelNumL1DataSrcLevelNumL2DataSrcLevelNumL3DataSrcLevelNumL4\"\n\t_DataSrcLevelNum_name_1 = \"DataSrcLevelNumAnyCacheDataSrcLevelNumLFBDataSrcLevelNumRAMDataSrcLevelNumPMEMDataSrcLevelNumNA\"\n)\n\nvar (\n\t_DataSrcLevelNum_index_0 = [...]uint8{0, 17, 34, 51, 68}\n\t_DataSrcLevelNum_index_1 = [...]uint8{0, 23, 41, 59, 78, 95}\n)\n\nfunc (i DataSrcLevelNum) String() string {\n\tswitch {\n\tcase 1 <= i && i <= 4:\n\t\ti -= 1\n\t\treturn _DataSrcLevelNum_name_0[_DataSrcLevelNum_index_0[i]:_DataSrcLevelNum_index_0[i+1]]\n\tcase 11 <= i && i <= 15:\n\t\ti -= 11\n\t\treturn _DataSrcLevelNum_name_1[_DataSrcLevelNum_index_1[i]:_DataSrcLevelNum_index_1[i+1]]\n\tdefault:\n\t\treturn \"DataSrcLevelNum(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n}\n"
  },
  {
    "path": "perffile/datasrclock_string.go",
    "content": "// Code generated by \"stringer -type=DataSrcLock\"; DO NOT EDIT.\n\npackage perffile\n\nimport \"strconv\"\n\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[DataSrcLockNA-0]\n\t_ = x[DataSrcLockUnlocked-1]\n\t_ = x[DataSrcLockLocked-2]\n}\n\nconst _DataSrcLock_name = \"DataSrcLockNADataSrcLockUnlockedDataSrcLockLocked\"\n\nvar _DataSrcLock_index = [...]uint8{0, 13, 32, 49}\n\nfunc (i DataSrcLock) String() string {\n\tif i < 0 || i >= DataSrcLock(len(_DataSrcLock_index)-1) {\n\t\treturn \"DataSrcLock(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n\treturn _DataSrcLock_name[_DataSrcLock_index[i]:_DataSrcLock_index[i+1]]\n}\n"
  },
  {
    "path": "perffile/datasrcop_string.go",
    "content": "// Code generated by \"bitstringer -type=DataSrcOp\"; DO NOT EDIT\n\npackage perffile\n\nimport \"strconv\"\n\nfunc (i DataSrcOp) String() string {\n\tif i == 0 {\n\t\treturn \"NA\"\n\t}\n\ts := \"\"\n\tif i&DataSrcOpExec != 0 {\n\t\ts += \"Exec|\"\n\t}\n\tif i&DataSrcOpLoad != 0 {\n\t\ts += \"Load|\"\n\t}\n\tif i&DataSrcOpPrefetch != 0 {\n\t\ts += \"Prefetch|\"\n\t}\n\tif i&DataSrcOpStore != 0 {\n\t\ts += \"Store|\"\n\t}\n\ti &^= 15\n\tif i == 0 {\n\t\treturn s[:len(s)-1]\n\t}\n\treturn s + \"0x\" + strconv.FormatUint(uint64(i), 16)\n}\n"
  },
  {
    "path": "perffile/datasrcsnoop_string.go",
    "content": "// Code generated by \"bitstringer -type=DataSrcSnoop\"; DO NOT EDIT\n\npackage perffile\n\nimport \"strconv\"\n\nfunc (i DataSrcSnoop) String() string {\n\tif i == 0 {\n\t\treturn \"NA\"\n\t}\n\ts := \"\"\n\tif i&DataSrcSnoopFwd != 0 {\n\t\ts += \"Fwd|\"\n\t}\n\tif i&DataSrcSnoopHit != 0 {\n\t\ts += \"Hit|\"\n\t}\n\tif i&DataSrcSnoopHitM != 0 {\n\t\ts += \"HitM|\"\n\t}\n\tif i&DataSrcSnoopMiss != 0 {\n\t\ts += \"Miss|\"\n\t}\n\tif i&DataSrcSnoopNone != 0 {\n\t\ts += \"None|\"\n\t}\n\ti &^= 31\n\tif i == 0 {\n\t\treturn s[:len(s)-1]\n\t}\n\treturn s + \"0x\" + strconv.FormatUint(uint64(i), 16)\n}\n"
  },
  {
    "path": "perffile/datasrctlb_string.go",
    "content": "// Code generated by \"bitstringer -type=DataSrcTLB\"; DO NOT EDIT\n\npackage perffile\n\nimport \"strconv\"\n\nfunc (i DataSrcTLB) String() string {\n\tif i == 0 {\n\t\treturn \"NA\"\n\t}\n\ts := \"\"\n\tif i&DataSrcTLBHardwareWalker != 0 {\n\t\ts += \"HardwareWalker|\"\n\t}\n\tif i&DataSrcTLBHit != 0 {\n\t\ts += \"Hit|\"\n\t}\n\tif i&DataSrcTLBL1 != 0 {\n\t\ts += \"L1|\"\n\t}\n\tif i&DataSrcTLBL2 != 0 {\n\t\ts += \"L2|\"\n\t}\n\tif i&DataSrcTLBMiss != 0 {\n\t\ts += \"Miss|\"\n\t}\n\tif i&DataSrcTLBOSFaultHandler != 0 {\n\t\ts += \"OSFaultHandler|\"\n\t}\n\ti &^= 63\n\tif i == 0 {\n\t\treturn s[:len(s)-1]\n\t}\n\treturn s + \"0x\" + strconv.FormatUint(uint64(i), 16)\n}\n"
  },
  {
    "path": "perffile/doc_test.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage perffile\n\nimport (\n\t\"fmt\"\n\t\"log\"\n)\n\nfunc Example() {\n\tf, err := Open(\"perf.data\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer f.Close()\n\n\trs := f.Records(RecordsTimeOrder)\n\tfor rs.Next() {\n\t\tswitch r := rs.Record.(type) {\n\t\tcase *RecordSample:\n\t\t\tfmt.Printf(\"sample: %+v\\n\", r)\n\t\t}\n\t}\n\tif err := rs.Err(); err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n"
  },
  {
    "path": "perffile/eventflags_string.go",
    "content": "// Code generated by \"bitstringer -type=EventFlags\"; DO NOT EDIT\n\npackage perffile\n\nimport \"strconv\"\n\nfunc (i EventFlags) String() string {\n\tif i == 0 {\n\t\treturn \"0\"\n\t}\n\ts := \"\"\n\tif i&EventFlagAuxOutput != 0 {\n\t\ts += \"AuxOutput|\"\n\t}\n\tif i&EventFlagBuildID != 0 {\n\t\ts += \"BuildID|\"\n\t}\n\tif i&EventFlagCGroup != 0 {\n\t\ts += \"CGroup|\"\n\t}\n\tif i&EventFlagClockID != 0 {\n\t\ts += \"ClockID|\"\n\t}\n\tif i&EventFlagComm != 0 {\n\t\ts += \"Comm|\"\n\t}\n\tif i&EventFlagCommExec != 0 {\n\t\ts += \"CommExec|\"\n\t}\n\tif i&EventFlagContextSwitch != 0 {\n\t\ts += \"ContextSwitch|\"\n\t}\n\tif i&EventFlagDisabled != 0 {\n\t\ts += \"Disabled|\"\n\t}\n\tif i&EventFlagEnableOnExec != 0 {\n\t\ts += \"EnableOnExec|\"\n\t}\n\tif i&EventFlagExcludeCallchainKernel != 0 {\n\t\ts += \"ExcludeCallchainKernel|\"\n\t}\n\tif i&EventFlagExcludeCallchainUser != 0 {\n\t\ts += \"ExcludeCallchainUser|\"\n\t}\n\tif i&EventFlagExcludeGuest != 0 {\n\t\ts += \"ExcludeGuest|\"\n\t}\n\tif i&EventFlagExcludeHost != 0 {\n\t\ts += \"ExcludeHost|\"\n\t}\n\tif i&EventFlagExcludeHypervisor != 0 {\n\t\ts += \"ExcludeHypervisor|\"\n\t}\n\tif i&EventFlagExcludeIdle != 0 {\n\t\ts += \"ExcludeIdle|\"\n\t}\n\tif i&EventFlagExcludeKernel != 0 {\n\t\ts += \"ExcludeKernel|\"\n\t}\n\tif i&EventFlagExcludeUser != 0 {\n\t\ts += \"ExcludeUser|\"\n\t}\n\tif i&EventFlagExclusive != 0 {\n\t\ts += \"Exclusive|\"\n\t}\n\tif i&EventFlagFreq != 0 {\n\t\ts += \"Freq|\"\n\t}\n\tif i&EventFlagInherit != 0 {\n\t\ts += \"Inherit|\"\n\t}\n\tif i&EventFlagInheritStat != 0 {\n\t\ts += \"InheritStat|\"\n\t}\n\tif i&EventFlagInheritThread != 0 {\n\t\ts += \"InheritThread|\"\n\t}\n\tif i&EventFlagKsymbol != 0 {\n\t\ts += \"Ksymbol|\"\n\t}\n\tif i&EventFlagMmap != 0 {\n\t\ts += \"Mmap|\"\n\t}\n\tif i&EventFlagMmapData != 0 {\n\t\ts += \"MmapData|\"\n\t}\n\tif i&EventFlagMmapInodeData != 0 {\n\t\ts += \"MmapInodeData|\"\n\t}\n\tif i&EventFlagNamespaces != 0 {\n\t\ts += \"Namespaces|\"\n\t}\n\tif i&EventFlagPinned != 0 {\n\t\ts += \"Pinned|\"\n\t}\n\tif i&EventFlagRemoveOnExec != 0 {\n\t\ts += \"RemoveOnExec|\"\n\t}\n\tif i&EventFlagSampleIDAll != 0 {\n\t\ts += \"SampleIDAll|\"\n\t}\n\tif i&EventFlagSigtrap != 0 {\n\t\ts += \"Sigtrap|\"\n\t}\n\tif i&EventFlagTask != 0 {\n\t\ts += \"Task|\"\n\t}\n\tif i&EventFlagTextPoke != 0 {\n\t\ts += \"TextPoke|\"\n\t}\n\tif i&EventFlagWakeupWatermark != 0 {\n\t\ts += \"WakeupWatermark|\"\n\t}\n\tif i&EventFlagWriteBackward != 0 {\n\t\ts += \"WriteBackward|\"\n\t}\n\ti &^= 137438855167\n\tif i == 0 {\n\t\treturn s[:len(s)-1]\n\t}\n\treturn s + \"0x\" + strconv.FormatUint(uint64(i), 16)\n}\n"
  },
  {
    "path": "perffile/eventhardwareid_string.go",
    "content": "// Code generated by \"stringer -type=EventHardwareID,EventSoftware,HWCache,HWCacheOp,HWCacheResult\"; DO NOT EDIT.\n\npackage perffile\n\nimport \"strconv\"\n\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[EventHardwareIDCPUCycles-0]\n\t_ = x[EventHardwareIDInstructions-1]\n\t_ = x[EventHardwareIDCacheReferences-2]\n\t_ = x[EventHardwareIDCacheMisses-3]\n\t_ = x[EventHardwareIDBranchInstructions-4]\n\t_ = x[EventHardwareIDBranchMisses-5]\n\t_ = x[EventHardwareIDBusCycles-6]\n\t_ = x[EventHardwareIDStalledCyclesFrontend-7]\n\t_ = x[EventHardwareIDStalledCyclesBackend-8]\n\t_ = x[EventHardwareIDRefCPUCycles-9]\n}\n\nconst _EventHardwareID_name = \"EventHardwareIDCPUCyclesEventHardwareIDInstructionsEventHardwareIDCacheReferencesEventHardwareIDCacheMissesEventHardwareIDBranchInstructionsEventHardwareIDBranchMissesEventHardwareIDBusCyclesEventHardwareIDStalledCyclesFrontendEventHardwareIDStalledCyclesBackendEventHardwareIDRefCPUCycles\"\n\nvar _EventHardwareID_index = [...]uint16{0, 24, 51, 81, 107, 140, 167, 191, 227, 262, 289}\n\nfunc (i EventHardwareID) String() string {\n\tif i >= EventHardwareID(len(_EventHardwareID_index)-1) {\n\t\treturn \"EventHardwareID(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n\treturn _EventHardwareID_name[_EventHardwareID_index[i]:_EventHardwareID_index[i+1]]\n}\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[EventSoftwareCPUClock-0]\n\t_ = x[EventSoftwareTaskClock-1]\n\t_ = x[EventSoftwarePageFaults-2]\n\t_ = x[EventSoftwareContextSwitches-3]\n\t_ = x[EventSoftwareCPUMigrations-4]\n\t_ = x[EventSoftwarePageFaultsMin-5]\n\t_ = x[EventSoftwarePageFaultsMaj-6]\n\t_ = x[EventSoftwareAlignmentFaults-7]\n\t_ = x[EventSoftwareEmulationFaults-8]\n\t_ = x[EventSoftwareDummy-9]\n\t_ = x[EventSoftwareBpfOutput-10]\n\t_ = x[EventSoftwareCGroupSwitches-11]\n}\n\nconst _EventSoftware_name = \"EventSoftwareCPUClockEventSoftwareTaskClockEventSoftwarePageFaultsEventSoftwareContextSwitchesEventSoftwareCPUMigrationsEventSoftwarePageFaultsMinEventSoftwarePageFaultsMajEventSoftwareAlignmentFaultsEventSoftwareEmulationFaultsEventSoftwareDummyEventSoftwareBpfOutputEventSoftwareCGroupSwitches\"\n\nvar _EventSoftware_index = [...]uint16{0, 21, 43, 66, 94, 120, 146, 172, 200, 228, 246, 268, 295}\n\nfunc (i EventSoftware) String() string {\n\tif i >= EventSoftware(len(_EventSoftware_index)-1) {\n\t\treturn \"EventSoftware(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n\treturn _EventSoftware_name[_EventSoftware_index[i]:_EventSoftware_index[i+1]]\n}\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[HWCacheL1D-0]\n\t_ = x[HWCacheL1I-1]\n\t_ = x[HWCacheLL-2]\n\t_ = x[HWCacheDTLB-3]\n\t_ = x[HWCacheITLB-4]\n\t_ = x[HWCacheBPU-5]\n\t_ = x[HWCacheNode-6]\n}\n\nconst _HWCache_name = \"HWCacheL1DHWCacheL1IHWCacheLLHWCacheDTLBHWCacheITLBHWCacheBPUHWCacheNode\"\n\nvar _HWCache_index = [...]uint8{0, 10, 20, 29, 40, 51, 61, 72}\n\nfunc (i HWCache) String() string {\n\tif i >= HWCache(len(_HWCache_index)-1) {\n\t\treturn \"HWCache(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n\treturn _HWCache_name[_HWCache_index[i]:_HWCache_index[i+1]]\n}\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[HWCacheOpRead-0]\n\t_ = x[HWCacheOpWrite-1]\n\t_ = x[HWCacheOpPrefetch-2]\n}\n\nconst _HWCacheOp_name = \"HWCacheOpReadHWCacheOpWriteHWCacheOpPrefetch\"\n\nvar _HWCacheOp_index = [...]uint8{0, 13, 27, 44}\n\nfunc (i HWCacheOp) String() string {\n\tif i >= HWCacheOp(len(_HWCacheOp_index)-1) {\n\t\treturn \"HWCacheOp(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n\treturn _HWCacheOp_name[_HWCacheOp_index[i]:_HWCacheOp_index[i+1]]\n}\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[HWCacheResultAccess-0]\n\t_ = x[HWCacheResultMiss-1]\n}\n\nconst _HWCacheResult_name = \"HWCacheResultAccessHWCacheResultMiss\"\n\nvar _HWCacheResult_index = [...]uint8{0, 19, 36}\n\nfunc (i HWCacheResult) String() string {\n\tif i >= HWCacheResult(len(_HWCacheResult_index)-1) {\n\t\treturn \"HWCacheResult(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n\treturn _HWCacheResult_name[_HWCacheResult_index[i]:_HWCacheResult_index[i+1]]\n}\n"
  },
  {
    "path": "perffile/eventprecision_string.go",
    "content": "// Code generated by \"stringer -type=EventPrecision\"; DO NOT EDIT.\n\npackage perffile\n\nimport \"strconv\"\n\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[EventPrecisionArbitrarySkid-0]\n\t_ = x[EventPrecisionConstantSkid-1]\n\t_ = x[EventPrecisionTryZeroSkid-2]\n\t_ = x[EventPrecisionZeroSkip-3]\n}\n\nconst _EventPrecision_name = \"EventPrecisionArbitrarySkidEventPrecisionConstantSkidEventPrecisionTryZeroSkidEventPrecisionZeroSkip\"\n\nvar _EventPrecision_index = [...]uint8{0, 27, 53, 78, 100}\n\nfunc (i EventPrecision) String() string {\n\tif i < 0 || i >= EventPrecision(len(_EventPrecision_index)-1) {\n\t\treturn \"EventPrecision(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n\treturn _EventPrecision_name[_EventPrecision_index[i]:_EventPrecision_index[i+1]]\n}\n"
  },
  {
    "path": "perffile/events.go",
    "content": "package perffile\n\n/*gendefs:C\n#include <include/uapi/linux/perf_event.h>\n*/\n\n//go:generate -command bitstringer ../cmd/bitstringer/bitstringer\n\n//go:generate stringer -type=EventHardwareID,EventSoftware,HWCache,HWCacheOp,HWCacheResult\n//go:generate bitstringer -type=BreakpointOp -strip=BreakpointOp\n\n// EventGeneric is a generic representation of a performance event.\n//\n// Any perf event can be represented by EventGeneric, but some\n// encoding is generally necessary. Hence, EventGeneric can be\n// translated back and forth between specific Event* types.\ntype EventGeneric struct {\n\t// Type specifies the major type of this event, such as\n\t// hardware event, software event, or tracepoint.\n\tType EventType\n\n\t// ID is the specific event within the class described by\n\t// Type.\n\t//\n\t// In perf_event_attr, this corresponds to either\n\t// perf_event_attr.config or, if Type == EventTypeBreakpoint,\n\t// perf_event_attr.bp_type.\n\tID uint64\n\n\t// Config gives additional configuration specific to the event\n\t// described by Type and ID.\n\t//\n\t// In perf_event_attr, this corresponds to\n\t// perf_event_attr.config1 and config2.\n\tConfig []uint64\n}\n\n// Decode decodes a generic event g into a specific event type.\nfunc (g *EventGeneric) Decode() Event {\n\tswitch g.Type {\n\tcase EventTypeHardware:\n\t\treturn EventHardware{\n\t\t\tID:        EventHardwareID(g.ID),\n\t\t\tPMUTypeID: PMUTypeID(g.ID >> 32),\n\t\t}\n\n\tcase EventTypeSoftware:\n\t\treturn EventSoftware(g.ID)\n\n\tcase EventTypeTracepoint:\n\t\treturn EventTracepoint(g.ID)\n\n\tcase EventTypeHWCache:\n\t\treturn EventHWCache{\n\t\t\tLevel:     HWCache(g.ID),\n\t\t\tOp:        HWCacheOp(g.ID >> 8),\n\t\t\tResult:    HWCacheResult(g.ID >> 16),\n\t\t\tPMUTypeID: uint32(g.ID >> 32),\n\t\t}\n\n\tcase EventTypeRaw:\n\t\treturn EventRaw(g.ID)\n\n\tcase EventTypeBreakpoint:\n\t\treturn EventBreakpoint{\n\t\t\tBreakpointOp(g.ID),\n\t\t\tg.Config[0],\n\t\t\tg.Config[1],\n\t\t}\n\t}\n\n\treturn eventUnknown{*g}\n}\n\ntype eventUnknown struct {\n\tg EventGeneric\n}\n\nfunc (e eventUnknown) Generic() EventGeneric {\n\treturn e.g\n}\n\n// EventHardware represents a hardware event.\ntype EventHardware struct {\n\tID        EventHardwareID\n\tPMUTypeID PMUTypeID // Map back to name with FileMeta.PMUMappings\n}\n\nfunc (e EventHardware) Generic() EventGeneric {\n\tid := uint64(e.ID) | uint64(e.PMUTypeID)<<32\n\treturn EventGeneric{Type: EventTypeHardware, ID: id}\n}\n\n// EventHardwareID represents a hardware event type.\n//\n// This corresponds to the perf_hw_id enum from\n// include/uapi/linux/perf_event.h\ntype EventHardwareID uint8\n\n//gendefs perf_hw_id.PERF_COUNT_HW_* EventHardwareID -omit-max\n\nconst (\n\tEventHardwareIDCPUCycles EventHardwareID = iota\n\tEventHardwareIDInstructions\n\tEventHardwareIDCacheReferences\n\tEventHardwareIDCacheMisses\n\tEventHardwareIDBranchInstructions\n\tEventHardwareIDBranchMisses\n\tEventHardwareIDBusCycles\n\tEventHardwareIDStalledCyclesFrontend\n\tEventHardwareIDStalledCyclesBackend\n\tEventHardwareIDRefCPUCycles\n)\n\n// PMUTypeID is a kernel-assigned type id assigned on PMU registration, visible\n// at /sys/bus/event_source/devices/$PMU/type.\ntype PMUTypeID uint32\n\n// EventSoftware represents a software event.\n//\n// This corresponds to the perf_sw_ids enum from\n// include/uapi/linux/perf_event.h\ntype EventSoftware uint64\n\n//gendefs perf_sw_ids.PERF_COUNT_SW_* EventSoftware -omit-max\n\nconst (\n\tEventSoftwareCPUClock EventSoftware = iota\n\tEventSoftwareTaskClock\n\tEventSoftwarePageFaults\n\tEventSoftwareContextSwitches\n\tEventSoftwareCPUMigrations\n\tEventSoftwarePageFaultsMin\n\tEventSoftwarePageFaultsMaj\n\tEventSoftwareAlignmentFaults\n\tEventSoftwareEmulationFaults\n\tEventSoftwareDummy\n\tEventSoftwareBpfOutput\n\tEventSoftwareCGroupSwitches\n)\n\nfunc (e EventSoftware) Generic() EventGeneric {\n\treturn EventGeneric{Type: EventTypeSoftware, ID: uint64(e)}\n}\n\n// EventTracepoint represents a kernel tracepoint event.\n//\n// The IDs of the tracepoint events are given by the\n// tracing/events/*/*/id files under debugfs.\ntype EventTracepoint uint64\n\nfunc (e EventTracepoint) Generic() EventGeneric {\n\treturn EventGeneric{Type: EventTypeTracepoint, ID: uint64(e)}\n}\n\n// EventHWCache represents a hardware cache event.\ntype EventHWCache struct {\n\tLevel     HWCache\n\tOp        HWCacheOp\n\tResult    HWCacheResult\n\tPMUTypeID uint32\n}\n\nfunc (e EventHWCache) Generic() EventGeneric {\n\tid := uint64(e.Level) | uint64(e.Op)<<8 | uint64(e.Result)<<16 | uint64(e.PMUTypeID)<<32\n\treturn EventGeneric{Type: EventTypeHWCache, ID: id}\n}\n\n// HWCache represents a level in the hardware cache.\n//\n// This corresponds to the perf_hw_cache_id enum from\n// include/uapi/linux/perf_event.h\ntype HWCache uint8\n\n//gendefs perf_hw_cache_id.PERF_COUNT_HW_CACHE_* HWCache -omit-max\n\nconst (\n\tHWCacheL1D HWCache = iota\n\tHWCacheL1I\n\tHWCacheLL\n\tHWCacheDTLB\n\tHWCacheITLB\n\tHWCacheBPU\n\tHWCacheNode\n)\n\n// HWCacheOp represents a type of access to a hardware cache.\n//\n// This corresponds to the perf_hw_cache_op_id enum from\n// include/uapi/linux/perf_event.h\ntype HWCacheOp uint8\n\n//gendefs perf_hw_cache_op_id.PERF_COUNT_HW_CACHE_OP_* HWCacheOp -omit-max\n\nconst (\n\tHWCacheOpRead HWCacheOp = iota\n\tHWCacheOpWrite\n\tHWCacheOpPrefetch\n)\n\n// HWCacheResult represents the result of a accessing a hardware\n// cache.\n//\n// This corresponds to the perf_hw_cache_op_result_id enum from\n// include/uapi/linux/perf_event.h\ntype HWCacheResult uint8\n\n//gendefs perf_hw_cache_op_result_id.PERF_COUNT_HW_CACHE_RESULT_* HWCacheResult -omit-max\n\nconst (\n\tHWCacheResultAccess HWCacheResult = iota\n\tHWCacheResultMiss\n)\n\n// EventRaw represents a \"raw\" hardware PMU event in a CPU-specific\n// format.\ntype EventRaw uint64\n\nfunc (e EventRaw) Generic() EventGeneric {\n\treturn EventGeneric{Type: EventTypeRaw, ID: uint64(e)}\n}\n\n// EventBreakpoint represents a breakpoint event.\n//\n// Breakpoint events are triggered by a specific type of access to an\n// address in memory.\ntype EventBreakpoint struct {\n\t// Op specifies what type of access to Addr should trigger\n\t// this event.\n\tOp BreakpointOp\n\t// Addr is the address to watch for operation Op.\n\tAddr uint64\n\t// Len is the number of bytes to watch at Addr. What sizes are\n\t// supported depends on the hardware, but it generally must be\n\t// a small power of 2.\n\tLen uint64\n}\n\nfunc (e EventBreakpoint) Generic() EventGeneric {\n\treturn EventGeneric{Type: EventTypeBreakpoint, ID: uint64(e.Op), Config: []uint64{e.Addr, e.Len}}\n}\n\n// BreakpointOp is a type of memory access that can trigger a\n// breakpoint event.\n//\n// This corresponds to the HW_BREAKPOINT_* constants from\n// include/uapi/linux/hw_breakpoint.h\ntype BreakpointOp uint32\n\nconst (\n\tBreakpointOpR  BreakpointOp = 1\n\tBreakpointOpW               = 2\n\tBreakpointOpRW              = BreakpointOpR | BreakpointOpW\n\tBreakpointOpX               = 4\n)\n"
  },
  {
    "path": "perffile/eventtype_string.go",
    "content": "// Code generated by \"stringer -type=EventType\"; DO NOT EDIT.\n\npackage perffile\n\nimport \"strconv\"\n\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[EventTypeHardware-0]\n\t_ = x[EventTypeSoftware-1]\n\t_ = x[EventTypeTracepoint-2]\n\t_ = x[EventTypeHWCache-3]\n\t_ = x[EventTypeRaw-4]\n\t_ = x[EventTypeBreakpoint-5]\n}\n\nconst _EventType_name = \"EventTypeHardwareEventTypeSoftwareEventTypeTracepointEventTypeHWCacheEventTypeRawEventTypeBreakpoint\"\n\nvar _EventType_index = [...]uint8{0, 17, 34, 53, 69, 81, 100}\n\nfunc (i EventType) String() string {\n\tif i >= EventType(len(_EventType_index)-1) {\n\t\treturn \"EventType(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n\treturn _EventType_name[_EventType_index[i]:_EventType_index[i+1]]\n}\n"
  },
  {
    "path": "perffile/format.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage perffile\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n/*gendefs:C\n#include <include/uapi/linux/perf_event.h>\n*/\n\n//go:generate -command bitstringer ../cmd/bitstringer/bitstringer\n\nconst numFeatureBits = 256\n\n// perf_file_header from tools/perf/util/header.h\ntype fileHeader struct {\n\tMagic    [8]byte\n\tSize     uint64      // Size of fileHeader on disk\n\tAttrSize uint64      // Size of fileAttr on disk\n\tAttrs    fileSection // Array of fileAttr\n\tData     fileSection // Alternating recordHeader and record\n\t_        fileSection // event_types; ignored in v2\n\n\tFeatures [numFeatureBits / 64]uint64 // Bitmap of feature\n}\n\nfunc (h *fileHeader) hasFeature(f feature) bool {\n\treturn h.Features[f/64]&(1<<(uint(f)%64)) != 0\n}\n\n// perf_file_section from tools/perf/util/header.h\ntype fileSection struct {\n\tOffset, Size uint64\n}\n\nfunc (s fileSection) sectionReader(r io.ReaderAt) *io.SectionReader {\n\treturn io.NewSectionReader(r, int64(s.Offset), int64(s.Size))\n}\n\nfunc (s fileSection) data(r io.ReaderAt) ([]byte, error) {\n\tout := make([]byte, s.Size)\n\tn, err := r.ReadAt(out, int64(s.Offset))\n\tif n == len(out) {\n\t\treturn out, nil\n\t}\n\treturn nil, err\n}\n\n// HEADER_* enum from tools/perf/util/header.h\ntype feature int\n\n// TODO: gendefs HEADER_* feature -omit HEADER_FIRST_FEATURE -omit HEADER_FEAT_BITS\n// Tricky because tools/perf/util/header.h pulls in all sorts of other junk.\n\nconst (\n\tfeatureReserved feature = iota // always cleared\n\tfeatureTracingData\n\tfeatureBuildID\n\n\tfeatureHostname\n\tfeatureOSRelease\n\tfeatureVersion\n\tfeatureArch\n\tfeatureNrCpus\n\tfeatureCPUDesc\n\tfeatureCPUID\n\tfeatureTotalMem\n\tfeatureCmdline\n\tfeatureEventDesc\n\tfeatureCPUTopology\n\tfeatureNUMATopology\n\tfeatureBranchStack\n\tfeaturePMUMappings\n\tfeatureGroupDesc\n)\n\n// perf_file_attr from tools/perf/util/header.c\ntype fileAttr struct {\n\tAttr EventAttr\n\tIDs  fileSection // array of attrID, one per core/thread\n}\n\n// eventAttrV0 is on-disk version 0 of the perf_event_attr structure.\n// Later versions extended this with additional fields, but the header\n// is always the same.\ntype eventAttrV0 struct {\n\tType                    EventType\n\tSize                    uint32\n\tConfig                  uint64\n\tSamplePeriodOrFreq      uint64\n\tSampleFormat            SampleFormat\n\tReadFormat              ReadFormat\n\tFlags                   EventFlags\n\tWakeupEventsOrWatermark uint32\n\tBPType                  uint32\n\t// BPAddrOrConfig1 can also contain kprobe_func or uprobe_path,\n\t// but these are just pointers to strings used by the\n\t// perf_event_open API, so are not meaningful in perf files.\n\tBPAddrOrConfig1 uint64\n}\n\n// eventAttrVN is the on-disk latest version of the perf_event_attr\n// structure (currently version 7).\ntype eventAttrVN struct {\n\teventAttrV0\n\n\t// ABI v1\n\t//\n\t// BPLenOrConfig2 can also contain kprobe_addr or\n\t// probe_offset, which are used in conjunction with\n\t// kprobe_func and uprobe_path (above).\n\tBPLenOrConfig2 uint64\n\n\t// ABI v2\n\tBranchSampleType BranchSampleType\n\n\t// ABI v3\n\tSampleRegsUser  uint64\n\tSampleStackUser uint32\n\tClockID         int32\n\n\t// ABI v4\n\tSampleRegsIntr uint64\n\n\t// ABI v5\n\tAuxWatermark   uint32\n\tSampleMaxStack uint16 // Max number of frame pointers in a callchain; should be < /proc/sys/kernel/perf_event_max_stack\n\tPad            uint16 // Align to uint64\n\n\t// ABI v6\n\tAuxSampleSize uint32 // Size of aux samples to include in SampleFormatAux.\n\tPad2          uint32 // Align to uint64\n\n\t// ABI v7\n\tSigData uint64 // User-provided data passed in sigcontext to SIGTRAP.\n}\n\n// TODO: Make public\ntype attrID uint64\n\n// Event describes a specific performance monitoring event.\n//\n// Events are quite general. They can be hardware events such as\n// cycles or cache misses. They can be kernel software events such as\n// page faults. They can be user or kernel trace-points, or many other\n// things. All events happen at some instant and can be counted.\ntype Event interface {\n\t// Generic returns the generic representation of this Event.\n\tGeneric() EventGeneric\n}\n\n// An EventType is a general class of performance event.\n//\n// This corresponds to the perf_type_id enum from\n// include/uapi/linux/perf_event.h\ntype EventType uint32\n\n//gendefs perf_type_id.PERF_TYPE_* EventType -omit-max\n//go:generate stringer -type=EventType\n\nconst (\n\tEventTypeHardware EventType = iota\n\tEventTypeSoftware\n\tEventTypeTracepoint\n\tEventTypeHWCache\n\tEventTypeRaw\n\tEventTypeBreakpoint\n)\n\n// An EventID combined with an EventType describes a specific event.\ntype EventID uint64\n\n// EventAttr describes an event and how that event should be recorded.\n//\n// This corresponds to the perf_event_attr struct from\n// include/uapi/linux/perf_event.h\ntype EventAttr struct {\n\t// Event describes the event that will be (or was) counted or\n\t// sampled.\n\tEvent Event\n\n\t// SamplePeriod, if non-zero, is the approximate number of\n\t// events between each sample.\n\t//\n\t// For a sampled event, SamplePeriod will be set if\n\t// Flags&EventFlagsFreq == 0. See also SampleFreq.\n\tSamplePeriod uint64\n\n\t// SampleFreq, if non-zero, is the approximate number of\n\t// samples to record per second per core. This is approximated\n\t// by dynamically adjusting the event sampling period (see\n\t// perf_calculate_period) and thus is not particularly\n\t// accurate (and even less accurate for events that don't\n\t// happen at a regular rate). If SampleFormat includes\n\t// SampleFormatPeriod, each sample includes the number of\n\t// events until the next sample on the same CPU.\n\t//\n\t// For a sampled event, SampleFreq will be set if\n\t// Flags&EventFlagsFreq != 0. See also SamplePeriod.\n\tSampleFreq uint64\n\n\t// The format of RecordSamples\n\tSampleFormat SampleFormat\n\n\t// The format of SampleRead\n\tReadFormat ReadFormat\n\n\tFlags EventFlags\n\n\t// Precise indicates the precision of instruction pointers\n\t// recorded by this event.\n\tPrecise EventPrecision\n\n\t// WakeupEvents specifies to wake up every WakeupEvents\n\t// events. Either this or WakeupWatermark will be non-zero,\n\t// depending on Flags&EventFlagWakeupWatermark.\n\tWakeupEvents uint32\n\t// WakeupWatermark specifies to wake up every WakeupWatermark\n\t// bytes.\n\tWakeupWatermark uint32\n\n\t// BranchSampleType specifies the types of branches to record\n\t// in the branch stack if SampleFormat&SampleFormatBranchStack\n\t// is set, as well as what information to record about each\n\t// branch.\n\tBranchSampleType BranchSampleType\n\n\t// SampleRegsUser is a bitmask of user-space registers\n\t// captured at each sample in RecordSample.RegsUser. The\n\t// hardware register corresponding to each bit depends on the\n\t// register ABI.\n\tSampleRegsUser uint64\n\n\t// Size of user stack to dump on samples\n\tSampleStackUser uint32\n\n\t// SampleRegsIntr is a bitmask of registers captured at each\n\t// sample in RecordSample.RegsIntr. If Precise ==\n\t// EventPrecisionArbitrarySkid, these registers are captured\n\t// at the PMU interrupt. Otherwise, these registers are\n\t// captured by the hardware when it samples an instruction.\n\tSampleRegsIntr uint64\n\n\t// AuxWatermark is the watermark for the AUX area in bytes at\n\t// which user space is woken up to collect the AUX area.\n\tAuxWatermark uint32\n\n\t// SampleMaxStack is the maximum number of frame pointers in a\n\t// callchain. Should be < /proc/sys/kernel/perf_event_max_stack.\n\tSampleMaxStack uint16\n}\n\n// A SampleFormat is a bitmask of the fields recorded by a sample.\n//\n// This corresponds to the perf_event_sample_format enum from\n// include/uapi/linux/perf_event.h\ntype SampleFormat uint64\n\n//gendefs perf_event_sample_format.PERF_SAMPLE_* SampleFormat -omit-max\n//go:generate bitstringer -type=SampleFormat -strip=SampleFormat\n\nconst (\n\tSampleFormatIP SampleFormat = 1 << iota\n\tSampleFormatTID\n\tSampleFormatTime\n\tSampleFormatAddr\n\tSampleFormatRead\n\tSampleFormatCallchain\n\tSampleFormatID\n\tSampleFormatCPU\n\tSampleFormatPeriod\n\tSampleFormatStreamID\n\tSampleFormatRaw\n\tSampleFormatBranchStack\n\tSampleFormatRegsUser\n\tSampleFormatStackUser\n\tSampleFormatWeight\n\tSampleFormatDataSrc\n\tSampleFormatIdentifier\n\tSampleFormatTransaction\n\tSampleFormatRegsIntr\n\tSampleFormatPhysAddr\n\tSampleFormatAux\n\tSampleFormatCGroup\n\tSampleFormatDataPageSize\n\tSampleFormatCodePageSize\n\tSampleFormatWeightStruct\n)\n\n// sampleIDOffset returns the byte offset of the ID field within an\n// on-disk sample record with this sample format. If there is no ID\n// field, it returns -1.\nfunc (s SampleFormat) sampleIDOffset() int {\n\t// See __perf_evsel__calc_id_pos in tools/perf/util/evsel.c.\n\n\tif s&SampleFormatIdentifier != 0 {\n\t\treturn 0\n\t}\n\tif s&SampleFormatID == 0 {\n\t\treturn -1\n\t}\n\n\toff := 0\n\tif s&SampleFormatIP != 0 {\n\t\toff += 8\n\t}\n\tif s&SampleFormatTID != 0 {\n\t\toff += 8\n\t}\n\tif s&SampleFormatTime != 0 {\n\t\toff += 8\n\t}\n\tif s&SampleFormatAddr != 0 {\n\t\toff += 8\n\t}\n\treturn off\n}\n\n// recordIDOffset returns the byte offset of the ID field of\n// non-sample records relative to the end of the on-disk sample. If\n// there is no ID field, it returns -1.\nfunc (s SampleFormat) recordIDOffset() int {\n\t// See __perf_evsel__calc_is_pos in tools/perf/util/evsel.c.\n\n\tif s&SampleFormatIdentifier != 0 {\n\t\treturn -8\n\t}\n\tif s&SampleFormatID == 0 {\n\t\treturn -1\n\t}\n\n\toff := 0\n\tif s&SampleFormatCPU != 0 {\n\t\toff -= 8\n\t}\n\tif s&SampleFormatStreamID != 0 {\n\t\toff -= 8\n\t}\n\treturn off - 8\n}\n\n// trailerBytes returns the length in the sample_id trailer for\n// non-sample records.\nfunc (s SampleFormat) trailerBytes() int {\n\ts &= SampleFormatTID | SampleFormatTime | SampleFormatID | SampleFormatStreamID | SampleFormatCPU | SampleFormatIdentifier\n\treturn 8 * weight(uint64(s))\n}\n\n// ReadFormat is a bitmask of the fields recorded in the SampleRead\n// field(s) of a sample.\n//\n// This corresponds to the perf_event_read_format enum from\n// include/uapi/linux/perf_event.h\ntype ReadFormat uint64\n\n//gendefs perf_event_read_format.PERF_FORMAT_* ReadFormat -omit-max\n//go:generate bitstringer -type=ReadFormat -strip=ReadFormat\n\nconst (\n\tReadFormatTotalTimeEnabled ReadFormat = 1 << iota\n\tReadFormatTotalTimeRunning\n\tReadFormatID\n\tReadFormatGroup\n)\n\n// EventFlags is a bitmask of boolean properties of an event.\n//\n// This corresponds to the perf_event_attr enum from\n// include/uapi/linux/perf_event.h\ntype EventFlags uint64\n\n// TODO: gendefs (need to understand skip in the middle)\n//go:generate bitstringer -type=EventFlags -strip=EventFlag\n\nconst (\n\t// Event is disabled by default\n\tEventFlagDisabled EventFlags = 1 << iota\n\t// Children inherit this event\n\tEventFlagInherit\n\t// Event must always be on the PMU\n\tEventFlagPinned\n\t// Event is only group on PMU\n\tEventFlagExclusive\n\t// Don't count events in user/kernel/hypervisor/when idle\n\tEventFlagExcludeUser\n\tEventFlagExcludeKernel\n\tEventFlagExcludeHypervisor\n\tEventFlagExcludeIdle\n\t// Include mmap data\n\tEventFlagMmap\n\t// Include comm data\n\tEventFlagComm\n\t// Use frequency, not period\n\tEventFlagFreq\n\t// Per task counts\n\tEventFlagInheritStat\n\t// Next exec enables this event\n\tEventFlagEnableOnExec\n\t// Trace fork/exit\n\tEventFlagTask\n\t// WakeupWatermark is set rather than WakeupEvents.\n\tEventFlagWakeupWatermark\n\n\t// Skip two bits here for EventFlagPreciseIPMask\n\n\t// Non-exec mmap data\n\tEventFlagMmapData EventFlags = 1 << (2 + iota)\n\t// All events have SampleField fields\n\tEventFlagSampleIDAll\n\t// Don't count events in host/guest\n\tEventFlagExcludeHost\n\tEventFlagExcludeGuest\n\t// Don't include kernel/user callchains\n\tEventFlagExcludeCallchainKernel\n\tEventFlagExcludeCallchainUser\n\t// Include inode data in mmap events\n\tEventFlagMmapInodeData\n\t// Flag comm events that are due to an exec\n\tEventFlagCommExec\n\t// Use clock specified by clockid for time fields\n\tEventFlagClockID\n\t// Record context switch data. Enables RecordTypeSwitch and\n\t// RecordTypeSwitchCPUWide events.\n\tEventFlagContextSwitch\n\t// Write ring buffer from end to beginning.\n\tEventFlagWriteBackward\n\t// Include namespaces data.\n\tEventFlagNamespaces\n\t// Include ksymbol events.\n\tEventFlagKsymbol\n\t// Generate aux records instead of events.\n\tEventFlagAuxOutput\n\t// Include cgroup events.\n\tEventFlagCGroup\n\t// Include text poke events.\n\tEventFlagTextPoke\n\t// Use build ID in mmap2 events instead of inode.\n\tEventFlagBuildID\n\t// Children only inherit if cloned with CLONE_THREAD.\n\tEventFlagInheritThread\n\t// Event is removed from task on exec.\n\tEventFlagRemoveOnExec\n\t// Send synchronous SIGTRAP on event.\n\tEventFlagSigtrap\n\n\teventFlagPreciseShift = 15\n\teventFlagPreciseMask  = 0x3 << eventFlagPreciseShift\n)\n\n// An EventPrecision indicates the precision of instruction pointers\n// recorded by an event. This can vary depending on the exact method\n// used to capture IPs.\ntype EventPrecision int\n\n//go:generate stringer -type=EventPrecision\n\nconst (\n\tEventPrecisionArbitrarySkid EventPrecision = iota\n\tEventPrecisionConstantSkid\n\tEventPrecisionTryZeroSkid\n\tEventPrecisionZeroSkip\n)\n\n// BranchSampleType is a bit-field of the types of branches to record\n// in the branch stack.\n//\n// This can include privilege levels to record, which can be different\n// from the privilege levels of the event being sampled. If none of\n// the privilege level bits are set, it defaults to the privilege\n// levels of the event.\n//\n// This corresponds to the perf_branch_sample_type enum from\n// include/uapi/linux/perf_event.h\ntype BranchSampleType uint64\n\n//gendefs perf_branch_sample_type.PERF_SAMPLE_BRANCH_* BranchSample BranchSampleType -omit-max\n//go:generate bitstringer -type=BranchSampleType -strip=BranchSample\n\nconst (\n\tBranchSampleUser   BranchSampleType = 1 << iota // User branches\n\tBranchSampleKernel                              // Kernel branches\n\tBranchSampleHV                                  // Hypervisor branches\n\n\tBranchSampleAny       // Any branch types\n\tBranchSampleAnyCall   // Any call branch\n\tBranchSampleAnyReturn // Any return branch\n\tBranchSampleIndCall   // Indirect calls\n\tBranchSampleAbortTX   // Transaction aborts\n\tBranchSampleInTX      // In transaction\n\tBranchSampleNoTX      // Not in transaction\n\tBranchSampleCond      // Conditional branches\n\n\tBranchSampleCallStack // Call/ret stack\n\tBranchSampleIndJump   // Indirect jumps\n\tBranchSampleCall      // Direct call\n\n\tBranchSampleNoFlags  // Don't set BranchRecord.Flags\n\tBranchSampleNoCycles // Don't set BranchRecord.Cycles\n\tBranchSampleTypeSave // Do set BranchRecord.Type\n\tBranchSampleHWIndex  // Do set RecordSample.BranchHWIndex\n)\n\n// perf_event_header from include/uapi/linux/perf_event.h\ntype recordHeader struct {\n\tType RecordType\n\tMisc recordMisc\n\tSize uint16\n}\n\n// A RecordType indicates the type of a record in a profile. A record\n// can either be a profiling sample or give information about changes\n// to system state, such as a process calling mmap.\ntype RecordType uint32\n\n// TODO gendefs (mix of exported and unexported)\n//go:generate stringer -type=RecordType\n\nconst (\n\tRecordTypeMmap RecordType = 1 + iota\n\tRecordTypeLost\n\tRecordTypeComm\n\tRecordTypeExit\n\tRecordTypeThrottle\n\tRecordTypeUnthrottle\n\tRecordTypeFork\n\tRecordTypeRead\n\tRecordTypeSample\n\trecordTypeMmap2 // internal extended RecordTypeMmap\n\tRecordTypeAux\n\tRecordTypeItraceStart\n\tRecordTypeLostSamples // TODO: How does this differ from RecordTypeLost?\n\tRecordTypeSwitch\n\tRecordTypeSwitchCPUWide\n\tRecordTypeNamespaces\n\tRecordTypeKsymbol\n\tRecordTypeBPFEvent\n\tRecordTypeCGroup\n\tRecordTypeTextPoke\n\tRecordTypeAuxOutputHardwareID\n\n\trecordTypeUserStart RecordType = 64\n)\n\n// perf_user_event_type in tools/perf/util/event.h\n//\n// TODO: Figure out what to do with these. Some of these are only to\n// direct parsing so they should never escape the API. Some of these\n// are only for perf.data pipes.\nconst (\n\trecordTypeAttr      RecordType = recordTypeUserStart + iota\n\trecordTypeEventType            // deprecated\n\trecordTypeTracingData\n\trecordTypeBuildID\n\trecordTypeFinishedRound\n\trecordTypeIDIndex\n\tRecordTypeAuxtraceInfo // TODO\n\tRecordTypeAuxtrace\n\tRecordTypeAuxtraceError // TODO\n\trecordTypeThreadMap\n\trecordTypeCPUMap\n\trecordTypeStatConfig\n\trecordTypeStat\n\trecordTypeStatRound\n\trecordTypeEventUpdate\n\trecordTypeTimeConv\n\trecordTypeHeaderFeature\n)\n\n// PERF_RECORD_MISC_* from include/uapi/linux/perf_event.h\ntype recordMisc uint16\n\n// TODO gendefs PERF_RECORD_MISC_* recordMisc -omit PERF_RECORD_MISC_CPUMODE_UNKNOWN -omit PERF_RECORD_MISC_KERNEL -omit PERF_RECORD_MISC_USER -omit PERF_RECORD_MISC_HYPERVISOR -omit PERF_RECORD_MISC_GUEST_KERNEL -omit PERF_RECORD_MISC_GUEST_USER\n// (macros)\n\nconst (\n\trecordMiscCPUModeMask         recordMisc = 7\n\trecordMiscProcMapParseTimeout            = 1 << 12 // /proc/PID/maps parsing was truncated by a time-out (TODO: What record is this set on?)\n\trecordMiscMmapData                       = 1 << 13 // RecordTypeMmap* events\n\trecordMiscCommExec                       = 1 << 13 // RecordTypeComm events\n\trecordMiscForkExec                       = 1 << 13 // RecordTypeFork events (perf tool internal)\n\trecordMiscSwitchOut                      = 1 << 13 // RecordTypeSwitch* events\n\n\t// recordMiscExactIP applies to RecordTypeSample records. It\n\t// indicates that the sample IP points to the actual\n\t// instruction that triggered the event.\n\trecordMiscExactIP = 1 << 14\n\n\t// recordMiscSwitchOutPreempt applies to RecordTypeSwitch*\n\t// records. It indicates that the thread was preempted in a\n\t// TASK_RUNNING state.\n\trecordMiscSwitchOutPreempt = 1 << 14\n\n\t// recordMiscMmapBuildID applies to recordTypeMmap2 records. It\n\t// indicates that the event contain build ID data rather than inode\n\t// data.\n\trecordMiscMmapBuildID = 1 << 14\n)\n\n// Record is the common interface implemented by all profile record\n// types.\ntype Record interface {\n\tType() RecordType\n\tCommon() *RecordCommon\n}\n\n// RecordCommon stores fields that are common to all record types, as\n// well as additional metadata. It is not itself a Record.\n//\n// Many fields are optional and their presence is determined by the\n// bitmask EventAttr.SampleFormat. Some record types guarantee that\n// some of these fields will be filled.\ntype RecordCommon struct {\n\t// Offset is the byte offset of this event in the perf.data\n\t// file.\n\tOffset int64\n\n\t// Format is a bit mask of SampleFormat* values that indicate\n\t// which optional fields of this record are valid.\n\tFormat SampleFormat\n\n\t// EventAttr is the event, if any, associated with this record.\n\tEventAttr *EventAttr\n\n\tPID, TID int    // if SampleFormatTID\n\tTime     uint64 // if SampleFormatTime\n\tID       attrID // if SampleFormatID or SampleFormatIdentifier\n\tStreamID uint64 // if SampleFormatStreamID\n\tCPU, Res uint32 // if SampleFormatCPU\n}\n\nfunc (r *RecordCommon) Common() *RecordCommon {\n\treturn r\n}\n\n// A RecordUnknown is a Record of unknown or unimplemented type.\ntype RecordUnknown struct {\n\trecordHeader\n\n\tRecordCommon\n\n\tData []byte\n}\n\nfunc (r *RecordUnknown) Type() RecordType {\n\treturn RecordType(r.recordHeader.Type)\n}\n\n// A RecordMmap records when a process being profiled called mmap.\n// RecordMmaps can also occur at the beginning of a profile to\n// describe the existing memory layout.\ntype RecordMmap struct {\n\t// RecordCommon.PID and .TID will always be filled\n\tRecordCommon\n\n\tData bool // from header.misc\n\n\t// Addr and Len are the virtual address of the start of this\n\t// mapping and its length in bytes.\n\tAddr, Len uint64\n\t// FileOffset is the byte offset in the mapped file of the\n\t// beginning of this mapping.\n\tFileOffset uint64\n\n\tMajor, Minor       uint32 // if !EventFlagBuildID\n\tIno, InoGeneration uint64 // if !EventFlagBuildID\n\n\tBuildID []byte // if EventFlagBuildID\n\n\tProt, Flags uint32\n\tFilename    string\n}\n\nfunc (r *RecordMmap) Type() RecordType {\n\treturn RecordTypeMmap\n}\n\n// A RecordLost records that profiling events were lost because of a\n// buffer overflow.\ntype RecordLost struct {\n\t// RecordCommon.ID and .EventAttr will always be filled\n\tRecordCommon\n\n\tNumLost uint64\n}\n\nfunc (r *RecordLost) Type() RecordType {\n\treturn RecordTypeLost\n}\n\n// A RecordComm records that a process being profiled called exec.\n// RecordComms can also occur at the beginning of a profile to\n// describe the existing set of processes.\ntype RecordComm struct {\n\t// RecordCommon.PID and .TID will always be filled\n\tRecordCommon\n\n\tExec bool // from header.misc\n\n\tComm string\n}\n\nfunc (r *RecordComm) Type() RecordType {\n\treturn RecordTypeComm\n}\n\n// A RecordExit records that a process or thread exited.\ntype RecordExit struct {\n\t// RecordCommon.PID, .TID, and .Time will always be filled\n\tRecordCommon\n\n\tPPID, PTID int\n}\n\nfunc (r *RecordExit) Type() RecordType {\n\treturn RecordTypeExit\n}\n\n// A RecordThrottle records that interrupt throttling was enabled or\n// disabled.\ntype RecordThrottle struct {\n\t// RecordCommon.Time, .ID, and .StreamID, and .EventAttr will\n\t// always be filled\n\tRecordCommon\n\n\tEnable bool\n}\n\nfunc (r *RecordThrottle) Type() RecordType {\n\treturn RecordTypeThrottle\n}\n\n// A RecordFork records that a process called clone to either fork the\n// process or create a new thread.\ntype RecordFork struct {\n\t// RecordCommon.PID, .TID, and .Time will always be filled\n\tRecordCommon\n\n\tPPID, PTID int\n}\n\nfunc (r *RecordFork) Type() RecordType {\n\treturn RecordTypeFork\n}\n\n// A RecordAux records the data was added to the AUX buffer.\ntype RecordAux struct {\n\tRecordCommon\n\n\tOffset, Size uint64\n\tFlags        AuxFlags\n\tPMUFormat    AuxPMUFormat\n}\n\nfunc (r *RecordAux) Type() RecordType {\n\treturn RecordTypeAux\n}\n\n// AuxFlags gives flags for an RecordAux event.\ntype AuxFlags uint64\n\n//TODO gendefs PERF_AUX_FLAG_* AuxFlag AuxFlags (macros)\n//go:generate bitstringer -type=AuxFlags -strip=AuxFlag\n\nconst (\n\t// Record was truncated to fit in the ring buffer.\n\tAuxFlagTruncated AuxFlags = 1 << iota\n\n\t// AUX data was collected in overwrite mode, so the AUX buffer\n\t// was treated as a circular ring buffer.\n\tAuxFlagOverwrite\n\n\t// Record contains gaps.\n\tAuxFlagPartial\n\n\t// Sample collided with another.\n\tAuxFlagCollision\n)\n\n// AuxPMUFormat is the PMU specific trace format type. Values are architecture dependent.\ntype AuxPMUFormat uint8\n\n//go:generate stringer -type=AuxPMUFormat\n\nconst (\n\t// ARM\n\tAuxPMUFormatCoresightCoresight AuxPMUFormat = 0 // ARM Coresight format CORESIGHT.\n\tAuxPMUFormatCoresightRaw       AuxPMUFormat = 1 // ARM Coresight format RAW.\n\n\tAuxPMUFormatDefault AuxPMUFormat = 0\n)\n\n// A RecordItraceStart indicates that an instruction trace started.\ntype RecordItraceStart struct {\n\t// PID and TID will always be filled in.\n\tRecordCommon\n}\n\nfunc (r *RecordItraceStart) Type() RecordType {\n\treturn RecordTypeItraceStart\n}\n\n// A RecordLostSamples records the number of dropped or lost samples.\ntype RecordLostSamples struct {\n\tRecordCommon\n\n\tLost uint64\n}\n\nfunc (r *RecordLostSamples) Type() RecordType {\n\treturn RecordTypeLostSamples\n}\n\n// A RecordSwitch records a context switch in or out of the monitored\n// process. See also RecordSwitchCPUWide.\ntype RecordSwitch struct {\n\tRecordCommon\n\n\t// Out indicates this is a switch out. Otherwise, this is a\n\t// switch in.\n\tOut bool\n}\n\nfunc (r *RecordSwitch) Type() RecordType {\n\treturn RecordTypeSwitch\n}\n\n// RecordSwitchCPUWide is a CPU-wide version of RecordSwitch.\ntype RecordSwitchCPUWide struct {\n\tRecordCommon\n\n\t// Out indicates this is a switch out. Otherwise, this is a\n\t// switch in.\n\tOut bool\n\n\t// Preempt indicates that the preempted thread was in\n\t// TASK_RUNNING state. That is, this was an involuntary\n\t// preemption.\n\tPreempt bool\n\n\t// SwitchPID and SwitchTID are the PID and TID of the process\n\t// being switched in or switched out.\n\tSwitchPID, SwitchTID int\n}\n\nfunc (r *RecordSwitchCPUWide) Type() RecordType {\n\treturn RecordTypeSwitchCPUWide\n}\n\ntype RecordNamespaces struct {\n\t// PID and TID are always filled in.\n\tRecordCommon\n\n\tNamespaces []Namespace\n}\n\nfunc (r *RecordNamespaces) Type() RecordType {\n\treturn RecordTypeNamespaces\n}\n\ntype Namespace struct {\n\tDev, Inode uint64\n}\n\n// RecordKsymbol record kernel symbol register/unregister information, for\n// dynamically loaded or JITed kernel functions.\ntype RecordKsymbol struct {\n\tRecordCommon\n\n\tAddr     uint64\n\tLen      uint32\n\tKsymType KsymbolType\n\tFlags    KsymbolFlags\n\tName     string\n}\n\nfunc (r *RecordKsymbol) Type() RecordType {\n\treturn RecordTypeKsymbol\n}\n\ntype KsymbolType uint16\n\n//gendefs perf_record_ksymbol_type.PERF_RECORD_KSYMBOL_TYPE_* KsymbolType -omit-max\n//go:generate bitstringer -type=KsymbolType -strip=KsymbolType\n\nconst (\n\tKsymbolTypeUnknown KsymbolType = iota\n\tKsymbolTypeBpf\n\tKsymbolTypeOol\n)\n\n// KsymbolFlags gives flags for a RecordKsymbol event.\ntype KsymbolFlags uint64\n\n// TODO gendefs PERF_RECORD_KSYMBOL_FLAGS_* KsymbolFlag KsymbolFlags (macros)\n//go:generate bitstringer -type=KsymbolFlags -strip=KsymbolFlag\n\nconst (\n\t// Ksymbol was unregistered.\n\tKsymbolFlagUnregister KsymbolFlags = iota\n)\n\n// RecordBPFEvent records BPF program load/unload information.\ntype RecordBPFEvent struct {\n\tRecordCommon\n\n\tEventType BPFEventType\n\tFlags     BPFEventFlags\n\tID        uint32\n\tTag       uint64\n}\n\nfunc (r *RecordBPFEvent) Type() RecordType {\n\treturn RecordTypeBPFEvent\n}\n\ntype BPFEventType uint16\n\n// gendefs perf_bpf_event_type.PERF_BPF_EVENT_* BPFEventType -omit-max\n//go:generate bitstringer -type=BPFEventType -strip=BPFEventType\n\nconst (\n\tBPFEventTypeUnknown BPFEventType = iota\n\tBPFEventTypeProgLoad\n\tBPFEventTypeProgUnload\n)\n\ntype BPFEventFlags uint16\n\n// No BPFEvent flags are defined yet.\n\n// RecordCGroup records the assosciation between a cgroup id and path.\ntype RecordCGroup struct {\n\tRecordCommon\n\n\tID   uint32\n\tPath string\n}\n\nfunc (r *RecordCGroup) Type() RecordType {\n\treturn RecordTypeCGroup\n}\n\n// RecordTextPoke records single instruction changes to the kernel text. This\n// event records the address modified and the old and new code.\ntype RecordTextPoke struct {\n\tRecordCommon\n\n\tAddr uint64\n\tOld  []byte\n\tNew  []byte\n}\n\nfunc (r *RecordTextPoke) Type() RecordType {\n\treturn RecordTypeTextPoke\n}\n\n// RecordAuxOutputHardwareID records an archtecture-specific hardware ID\n// assosciated with the aux data for this event ID.\n//\n// e.g., this is used to disambiguate different PEBS event types from each\n// other when using PEBS-via-PT.\ntype RecordAuxOutputHardwareID struct {\n\tRecordCommon\n\n\tID uint64\n}\n\nfunc (r *RecordAuxOutputHardwareID) Type() RecordType {\n\treturn RecordTypeAuxOutputHardwareID\n}\n\ntype RecordAuxtraceInfo struct {\n\tRecordCommon\n\n\tKind uint32\n\n\tPriv []uint64\n}\n\nfunc (r *RecordAuxtraceInfo) Type() RecordType {\n\treturn RecordTypeAuxtraceInfo\n}\n\ntype RecordAuxtrace struct {\n\t// TID and CPU are always filled in.\n\tRecordCommon\n\n\t// Offset is the byte offset of the aux data in the aux mmap.\n\t// Not meaningful in perf data files.\n\tOffset uint64\n\n\t// Ref is a unique identifier for this auxtrace block.\n\t//\n\t// TODO: What's the point of this? Is it cross-referenced\n\t// against something?\n\tRef uint64\n\n\t// Idx is the index of the aux mmap region of this data.\n\t// Not meaningful in perf data files.\n\tIdx uint32\n\n\t// Data is the raw auxiliary data. The encoding of this\n\t// depends on the latest RecordAuxtraceInfo.\n\tData []byte\n}\n\nfunc (r *RecordAuxtrace) Type() RecordType {\n\treturn RecordTypeAuxtrace\n}\n\n// A RecordSample records a profiling sample event.\n//\n// Typically only a subset of the fields are used. Which fields are\n// set can be determined from the bitmask\n// RecordSample.EventAttr.SampleFormat.\ntype RecordSample struct {\n\t// RecordCommon.EventAttr will always be filled.\n\t// RecordCommon.Format descibes the optional fields in this\n\t// structure, as well as the optional common fields.\n\tRecordCommon\n\n\tCPUMode CPUMode // from header.misc\n\tExactIP bool    // from header.misc\n\n\tIP   uint64 // if SampleFormatIP\n\tAddr uint64 // if SampleFormatAddr\n\n\t// Period is the number of events on this CPU until the next\n\t// sample. In frequency sampling mode, this is adjusted\n\t// dynamically based on the rate of recent events. In period\n\t// sampling mode, this is fixed.\n\tPeriod uint64 // if SampleFormatPeriod\n\n\t// SampleRead records raw event counter values. If this is an\n\t// event group, this slice will have more than one element;\n\t// otherwise, it will have one element.\n\tSampleRead []Count // if SampleFormatRead\n\n\t// Callchain gives the call stack of the sampled instruction,\n\t// starting from the sampled instruction itself. The call\n\t// chain may span several types of stacks (e.g., it may start\n\t// in a kernel stack, then transition to a user stack). Before\n\t// the first IP from each stack there will be a Callchain*\n\t// constant indicating the stack type for the following IPs.\n\tCallchain []uint64 // if SampleFormatCallchain\n\n\t// BranchHWIndex is the low level index of the raw hardware branch\n\t// record (e.g., LBR) for BranchStack[0].\n\t//\n\t// BranchStack is an abstraction of the raw hardware branch records,\n\t// and the index of the raw entry can be very useful for stitching the\n\t// stacks of multiple samples to reconstruct the call stack.\n\t//\n\t// The value is between -1 (unknown) and the max depth from\n\t// /sys/devices/cpu/caps/branches.\n\tBranchHWIndex int64 // if BranchSampleHWIndex\n\n\tBranchStack []BranchRecord // if SampleFormatBranchStack\n\n\t// RegsUserABI and RegsUser record the ABI and values of\n\t// user-space registers as of this sample. Note that these are\n\t// the current user-space registers even if this sample\n\t// occurred at a kernel PC. RegsUser[i] records the value of\n\t// the register indicated by the i-th set bit of\n\t// EventAttr.SampleRegsUser.\n\tRegsUserABI SampleRegsABI // if SampleFormatRegsUser\n\tRegsUser    []uint64      // if SampleFormatRegsUser\n\n\t// RegsIntrABI And RegsIntr record the ABI and values of\n\t// registers as of this sample. Unlike RegsUser, these can be\n\t// kernel-space registers if this sample occurs in the kernel.\n\t// RegsIntr[i] records the value of the register indicated by\n\t// the i-th set bit of EventAttr.SampleRegsIntr.\n\tRegsIntrABI SampleRegsABI // if SampleFormatRegsIntr\n\tRegsIntr    []uint64      // if SampleFormatRegsIntr\n\n\tStackUser        []byte // if SampleFormatStackUser\n\tStackUserDynSize uint64 // if SampleFormatStackUser\n\n\tWeight  uint64  // if SampleFormatWeight or SampleFormatWeightStruct\n\tWeights Weights // if SampleFormatWeightStruct\n\n\tDataSrc DataSrc // if SampleFormatDataSrc\n\n\tTransaction Transaction // if SampleFormatTransaction\n\tAbortCode   uint32      // if SampleFormatTransaction\n\n\tPhysAddr uint64 // if SampleFormatPhysAddr\n\n\tCGroup uint64 // if SampleFormatCGroup\n\n\tDataPageSize uint64 // if SampleFormatDataPageSize\n\tCodePageSize uint64 // if SampleFormatCodePageSize\n\n\tAux []byte // if SampleFormatAux\n}\n\nfunc (r *RecordSample) Type() RecordType {\n\treturn RecordTypeSample\n}\n\nfunc (r *RecordSample) String() string {\n\t// TODO: Stringers for other record types\n\tf := r.Format\n\ts := fmt.Sprintf(\"{Offset:%v Format:%v EventAttr:%p CPUMode:%v ExactIP:%v\", r.Offset, r.Format, r.EventAttr, r.CPUMode, r.ExactIP)\n\tif f&(SampleFormatID|SampleFormatIdentifier) != 0 {\n\t\ts += fmt.Sprintf(\" ID:%d\", r.ID)\n\t}\n\tif f&SampleFormatIP != 0 {\n\t\ts += fmt.Sprintf(\" IP:%#x\", r.IP)\n\t}\n\tif f&SampleFormatTID != 0 {\n\t\ts += fmt.Sprintf(\" PID:%d TID:%d\", r.PID, r.TID)\n\t}\n\tif f&SampleFormatTime != 0 {\n\t\ts += fmt.Sprintf(\" Time:%d\", r.Time)\n\t}\n\tif f&SampleFormatAddr != 0 {\n\t\ts += fmt.Sprintf(\" Addr:%#x\", r.Addr)\n\t}\n\tif f&SampleFormatStreamID != 0 {\n\t\ts += fmt.Sprintf(\" StreamID:%d\", r.StreamID)\n\t}\n\tif f&SampleFormatCPU != 0 {\n\t\ts += fmt.Sprintf(\" CPU:%d Res:%d\", r.CPU, r.Res)\n\t}\n\tif f&SampleFormatPeriod != 0 {\n\t\ts += fmt.Sprintf(\" Period:%d\", r.Period)\n\t}\n\tif f&SampleFormatRead != 0 {\n\t\ts += fmt.Sprintf(\" SampleRead:%v\", r.SampleRead)\n\t}\n\tif f&SampleFormatCallchain != 0 {\n\t\ts += fmt.Sprintf(\" Callchain:%#x\", r.Callchain)\n\t}\n\tif f&SampleFormatBranchStack != 0 {\n\t\ts += fmt.Sprintf(\" BranchStack:%v\", r.BranchStack)\n\t}\n\tif f&SampleFormatRegsUser != 0 {\n\t\ts += fmt.Sprintf(\" RegsUserABI:%v RegsUser:%v\", r.RegsUserABI, r.RegsUser)\n\t}\n\tif f&SampleFormatRegsIntr != 0 {\n\t\ts += fmt.Sprintf(\" RegsIntrABI:%v RegsIntr:%v\", r.RegsIntrABI, r.RegsIntr)\n\t}\n\tif f&SampleFormatStackUser != 0 {\n\t\ts += fmt.Sprintf(\" StackUser:[...] StackUserDynSize:%d\", r.StackUserDynSize)\n\t}\n\tif f&SampleFormatWeight != 0 {\n\t\ts += fmt.Sprintf(\" Weight:%d\", r.Weight)\n\t}\n\tif f&SampleFormatDataSrc != 0 {\n\t\ts += fmt.Sprintf(\" DataSrc:%+v\", r.DataSrc)\n\t}\n\tif f&SampleFormatTransaction != 0 {\n\t\ts += fmt.Sprintf(\" Transaction:%v AbortCode:%d\", r.Transaction, r.AbortCode)\n\t}\n\tif f&SampleFormatPhysAddr != 0 {\n\t\ts += fmt.Sprintf(\" PhysAddr:%#x\", r.PhysAddr)\n\t}\n\tif f&SampleFormatAux != 0 {\n\t\ts += fmt.Sprintf(\" Aux:%v\", r.Aux)\n\t}\n\tif f&SampleFormatCGroup != 0 {\n\t\ts += fmt.Sprintf(\" CGroup:%d\", r.CGroup)\n\t}\n\tif f&SampleFormatDataPageSize != 0 {\n\t\ts += fmt.Sprintf(\" DataPageSize:%#x\", r.DataPageSize)\n\t}\n\tif f&SampleFormatCodePageSize != 0 {\n\t\ts += fmt.Sprintf(\" CodePageSize:%#x\", r.CodePageSize)\n\t}\n\tif f&SampleFormatWeightStruct != 0 {\n\t\ts += fmt.Sprintf(\" Weights:%v\", r.Weights)\n\t}\n\treturn s + \"}\"\n}\n\n// Fields returns the list of names of valid fields in r based on\n// r.Format. This is useful for writing custom printing functions.\nfunc (r *RecordSample) Fields() []string {\n\tf := r.Format\n\tfs := []string{\"Offset\", \"Format\", \"EventAttr\", \"CPUMode\", \"ExactIP\"}\n\tif f&(SampleFormatID|SampleFormatIdentifier) != 0 {\n\t\tfs = append(fs, \"ID\")\n\t}\n\tif f&SampleFormatIP != 0 {\n\t\tfs = append(fs, \"IP\")\n\t}\n\tif f&SampleFormatTID != 0 {\n\t\tfs = append(fs, \"PID\", \"TID\")\n\t}\n\tif f&SampleFormatTime != 0 {\n\t\tfs = append(fs, \"Time\")\n\t}\n\tif f&SampleFormatAddr != 0 {\n\t\tfs = append(fs, \"Addr\")\n\t}\n\tif f&SampleFormatStreamID != 0 {\n\t\tfs = append(fs, \"StreamID\")\n\t}\n\tif f&SampleFormatCPU != 0 {\n\t\tfs = append(fs, \"CPU\", \"Res\")\n\t}\n\tif f&SampleFormatPeriod != 0 {\n\t\tfs = append(fs, \"Period\")\n\t}\n\tif f&SampleFormatRead != 0 {\n\t\tfs = append(fs, \"SampleRead\")\n\t}\n\tif f&SampleFormatCallchain != 0 {\n\t\tfs = append(fs, \"Callchain\")\n\t}\n\tif f&SampleFormatBranchStack != 0 {\n\t\tfs = append(fs, \"BranchStack\")\n\t}\n\tif f&SampleFormatRegsUser != 0 {\n\t\tfs = append(fs, \"RegsUserABI\", \"RegsUser\")\n\t}\n\tif f&SampleFormatRegsIntr != 0 {\n\t\tfs = append(fs, \"RegsIntrABI\", \"RegsIntr\")\n\t}\n\tif f&SampleFormatStackUser != 0 {\n\t\tfs = append(fs, \"StackUser\", \"StackUserDynSize\")\n\t}\n\tif f&SampleFormatWeight != 0 {\n\t\tfs = append(fs, \"Weight\")\n\t}\n\tif f&SampleFormatDataSrc != 0 {\n\t\tfs = append(fs, \"DataSrc\")\n\t}\n\tif f&SampleFormatTransaction != 0 {\n\t\tfs = append(fs, \"Transaction\", \"AbortCode\")\n\t}\n\tif f&SampleFormatPhysAddr != 0 {\n\t\tfs = append(fs, \"PhysAddr\")\n\t}\n\tif f&SampleFormatAux != 0 {\n\t\tfs = append(fs, \"Aux\")\n\t}\n\tif f&SampleFormatCGroup != 0 {\n\t\tfs = append(fs, \"CGroup\")\n\t}\n\tif f&SampleFormatDataPageSize != 0 {\n\t\tfs = append(fs, \"DataPageSize\")\n\t}\n\tif f&SampleFormatCodePageSize != 0 {\n\t\tfs = append(fs, \"CodePageSize\")\n\t}\n\tif f&SampleFormatWeightStruct != 0 {\n\t\tfs = append(fs, \"Weights\")\n\t}\n\treturn fs\n}\n\n// A CPUMode indicates the privilege level of a sample or event.\n//\n// This corresponds to PERF_RECORD_MISC_CPUMODE from\n// include/uapi/linux/perf_event.h\ntype CPUMode uint16\n\n// TODO: gendefs (need to extract from PERF_RECORD_MISC_* flags)\n//go:generate stringer -type=CPUMode\n\nconst (\n\tCPUModeUnknown CPUMode = iota\n\tCPUModeKernel\n\tCPUModeUser\n\tCPUModeHypervisor\n\tCPUModeGuestKernel\n\tCPUModeGuestUser\n)\n\n// A Count records the raw value of an event counter.\n//\n// Typically only a subset of the fields are used. Which fields are\n// set can be determined from the bitmask in the sample's\n// EventAttr.ReadFormat.\n//\n// This corresponds to perf_event_read_format from\n// include/uapi/linux/perf_event.h\ntype Count struct {\n\tValue       uint64     // Event counter value\n\tTimeEnabled uint64     // if ReadFormatTotalTimeEnabled\n\tTimeRunning uint64     // if ReadFormatTotalTimeRunning\n\tEventAttr   *EventAttr // if ReadFormatID\n}\n\n// A BranchRecord records a single branching event in a sample.\ntype BranchRecord struct {\n\tFrom, To uint64\n\tFlags    BranchFlags\n\n\tCycles uint16 // Cycle count to last branch (or 0)\n\n\t// Type is the type of branch instruction that caused this\n\t// branch. If supported, this is set by the kernel by\n\t// disassembling the branch instruction, since the binary\n\t// itself may not be available at decoding time. This is only\n\t// set if EventAttr.BranchSampleType&BranchSampleTypeSave is\n\t// set in the event.\n\tType BranchType\n}\n\ntype BranchFlags uint64\n\n//go:generate bitstringer -type=BranchFlags -strip=BranchFlag\n\nconst (\n\t// BranchFlagMispredicted indicates branch target was mispredicted.\n\tBranchFlagMispredicted BranchFlags = 1 << iota\n\n\t// BranchFlagPredicted indicates branch target was predicted.\n\t// In case predicted/mispredicted information is unavailable,\n\t// both flags will be unset.\n\tBranchFlagPredicted\n\n\t// BranchFlagInTransaction indicates the branch occurred in a\n\t// transaction.\n\tBranchFlagInTransaction\n\n\t// BranchFlagAbort indicates the branch is a transaction abort.\n\tBranchFlagAbort\n)\n\ntype BranchType uint8\n\n//gendefs PERF_BR_* BranchType -omit-max\n\nconst (\n\tBranchTypeUnknown  BranchType = iota // unknown\n\tBranchTypeCond                       // conditional\n\tBranchTypeUncond                     // unconditional\n\tBranchTypeInd                        // indirect\n\tBranchTypeCall                       // function call\n\tBranchTypeIndCall                    // indirect function call\n\tBranchTypeRet                        // function return\n\tBranchTypeSyscall                    // syscall\n\tBranchTypeSysret                     // syscall return\n\tBranchTypeCondCall                   // conditional function call\n\tBranchTypeCondRet                    // conditional function return\n\tBranchTypeEret                       // exception return\n\tBranchTypeIrq                        // interrupt\n)\n\n//gendefs perf_callchain_context.PERF_CONTEXT_* Callchain uint64 -omit-max\n\n// Special markers used in RecordSample.Callchain to mark boundaries\n// between types of stacks.\n//\n// These correspond to PERF_CONTEXT_* from\n// include/uapi/linux/perf_event.h\nconst (\n\tCallchainHV          uint64 = 0xffffffffffffffe0 // -32\n\tCallchainKernel             = 0xffffffffffffff80 // -128\n\tCallchainUser               = 0xfffffffffffffe00 // -512\n\tCallchainGuest              = 0xfffffffffffff800 // -2048\n\tCallchainGuestKernel        = 0xfffffffffffff780 // -2176\n\tCallchainGuestUser          = 0xfffffffffffff600 // -2560\n)\n\n// SampleRegsABI indicates the register ABI of a given sample for\n// architectures that support multiple ABIs.\n//\n// This corresponds to the perf_sample_regs_abi enum from\n// include/uapi/linux/perf_event.h\ntype SampleRegsABI uint64\n\n//gendefs perf_sample_regs_abi.PERF_SAMPLE_REGS_ABI_* SampleRegsABI\n//go:generate stringer -type=SampleRegsABI\n\nconst (\n\tSampleRegsABINone SampleRegsABI = iota\n\tSampleRegsABI32\n\tSampleRegsABI64\n)\n\ntype DataSrc struct {\n\tOp       DataSrcOp\n\tMiss     bool // if true, Level specifies miss, rather than hit\n\tLevel    DataSrcLevel\n\tSnoop    DataSrcSnoop\n\tLocked   DataSrcLock\n\tTLB      DataSrcTLB\n\tLevelNum DataSrcLevelNum\n\tRemote   bool\n\tBlock    DataSrcBlock\n\tHops     DataSrcHops\n}\n\ntype DataSrcOp int\n\n//go:generate bitstringer -type=DataSrcOp -strip=DataSrcOp\n\nconst (\n\tDataSrcOpLoad DataSrcOp = 1 << iota\n\tDataSrcOpStore\n\tDataSrcOpPrefetch\n\tDataSrcOpExec\n\n\tDataSrcOpNA DataSrcOp = 0\n)\n\ntype DataSrcLevel int\n\n//go:generate bitstringer -type=DataSrcLevel -strip=DataSrcLevel\n\nconst (\n\tDataSrcLevelL1  DataSrcLevel = 1 << iota\n\tDataSrcLevelLFB              // Line fill buffer\n\tDataSrcLevelL2\n\tDataSrcLevelL3\n\tDataSrcLevelLocalRAM     // Local DRAM\n\tDataSrcLevelRemoteRAM1   // Remote DRAM (1 hop)\n\tDataSrcLevelRemoteRAM2   // Remote DRAM (2 hops)\n\tDataSrcLevelRemoteCache1 // Remote cache (1 hop)\n\tDataSrcLevelRemoteCache2 // Remote cache (2 hops)\n\tDataSrcLevelIO           // I/O memory\n\tDataSrcLevelUncached\n\n\tDataSrcLevelNA DataSrcLevel = 0\n)\n\ntype DataSrcSnoop int\n\n//go:generate bitstringer -type=DataSrcSnoop -strip=DataSrcSnoop\n\nconst (\n\tDataSrcSnoopNone DataSrcSnoop = 1 << iota\n\tDataSrcSnoopHit\n\tDataSrcSnoopMiss\n\tDataSrcSnoopHitM // Snoop hit modified\n\tDataSrcSnoopFwd\n\n\tDataSrcSnoopNA DataSrcSnoop = 0\n)\n\ntype DataSrcLock int\n\n//go:generate stringer -type=DataSrcLock\n\nconst (\n\tDataSrcLockNA DataSrcLock = iota\n\tDataSrcLockUnlocked\n\tDataSrcLockLocked\n)\n\ntype DataSrcTLB int\n\n//go:generate bitstringer -type=DataSrcTLB -strip=DataSrcTLB\n\nconst (\n\tDataSrcTLBHit DataSrcTLB = 1 << iota\n\tDataSrcTLBMiss\n\tDataSrcTLBL1\n\tDataSrcTLBL2\n\tDataSrcTLBHardwareWalker\n\tDataSrcTLBOSFaultHandler\n\n\tDataSrcTLBNA DataSrcTLB = 0\n)\n\ntype DataSrcLevelNum int\n\n// TODO gendefs (macros)\n//go:generate stringer -type=DataSrcLevelNum\n\nconst (\n\tDataSrcLevelNumL1       DataSrcLevelNum = 0x01 // L1\n\tDataSrcLevelNumL2       DataSrcLevelNum = 0x02 // L2\n\tDataSrcLevelNumL3       DataSrcLevelNum = 0x03 // L3\n\tDataSrcLevelNumL4       DataSrcLevelNum = 0x04 // L4\n\tDataSrcLevelNumAnyCache DataSrcLevelNum = 0x0b // Any cache\n\tDataSrcLevelNumLFB      DataSrcLevelNum = 0x0c // LFB\n\tDataSrcLevelNumRAM      DataSrcLevelNum = 0x0d // RAM\n\tDataSrcLevelNumPMEM     DataSrcLevelNum = 0x0e // PMEM\n\tDataSrcLevelNumNA       DataSrcLevelNum = 0x0f // N/A\n)\n\ntype DataSrcBlock int\n\n//go:generate bitstringer -type=DataSrcBlock -strip=DataSrcBlock\n\nconst (\n\tDataSrcBlockData DataSrcBlock = 1 << iota // Data could not be forwarded\n\tDataSrcBlockAddr                          // Address conflict\n\n\tDataSrcBlockNA DataSrcBlock = 0\n)\n\ntype DataSrcHops int\n\n//go:generate stringer -type=DataSrcHops\n\nconst (\n\tDataSrcHopsCore   DataSrcHops = 1 // Remote core, same node\n\tDataSrcHopsNode   DataSrcHops = 3 // Remote node, same socket\n\tDataSrcHopsSocket DataSrcHops = 3 // Remote socket, same board\n\tDataSrcHopesBoard DataSrcHops = 4 // Remote board\n\n\tDataSrcHopsNA DataSrcHops = 0\n)\n\ntype Transaction int\n\n// TODO: Handle abort code mask\n\n//gendefs PERF_TXN_* Transaction -omit-max -omit PERF_TXN_ABORT_MASK -omit PERF_TXN_ABORT_SHIFT\n//go:generate bitstringer -type=Transaction -strip=Transaction\n\nconst (\n\tTransactionElision       Transaction = 1 << iota // From elision\n\tTransactionTransaction                           // From transaction\n\tTransactionSync                                  // Instruction is related\n\tTransactionAsync                                 // Instruction is not related\n\tTransactionRetry                                 // Retry possible\n\tTransactionConflict                              // Conflict abort\n\tTransactionCapacityWrite                         // Capactiy write abort\n\tTransactionCapacityRead                          // Capactiy read abort\n)\n\ntype Weights struct {\n\tVar1 uint32\n\tVar2 uint16\n\tVar3 uint16\n}\n"
  },
  {
    "path": "perffile/gendefs.sh",
    "content": "#!/bin/sh\n\nset -e\n\nif [ \"$1\" = -u ]; then\n    update=1\n    shift\nfi\n\nif [ \"$#\" != 1 ]; then\n    echo \"Usage: $0 [-u] <Linux source tree>\" 2>&1\n    exit 2\nfi\nlinux=\"$1\"\n\ngo build ../internal/gendefs\n\nprocess() {\n    ./gendefs -ccflags \"-I $linux\" $1 > .$1.tmp\n    if [ -z \"$update\" ]; then\n        diff -u $1 .$1.tmp || true\n        rm .$1.tmp\n    else\n        mv .$1.tmp $1\n    fi\n}\n\nprocess events.go\nprocess format.go\nrm gendefs\n"
  },
  {
    "path": "perffile/ksymbolflags_string.go",
    "content": "// Code generated by \"bitstringer -type=KsymbolFlags\"; DO NOT EDIT\n\npackage perffile\n\nimport \"strconv\"\n\nfunc (i KsymbolFlags) String() string {\n\tif i == 0 {\n\t\treturn \"Unregister\"\n\t}\n\ts := \"\"\n\ti &^= 0\n\tif i == 0 {\n\t\treturn s[:len(s)-1]\n\t}\n\treturn s + \"0x\" + strconv.FormatUint(uint64(i), 16)\n}\n"
  },
  {
    "path": "perffile/ksymboltype_string.go",
    "content": "// Code generated by \"bitstringer -type=KsymbolType\"; DO NOT EDIT\n\npackage perffile\n\nimport \"strconv\"\n\nfunc (i KsymbolType) String() string {\n\tif i == 0 {\n\t\treturn \"Unknown\"\n\t}\n\ts := \"\"\n\tif i&KsymbolTypeBpf != 0 {\n\t\ts += \"Bpf|\"\n\t}\n\tif i&KsymbolTypeOol != 0 {\n\t\ts += \"Ool|\"\n\t}\n\ti &^= 3\n\tif i == 0 {\n\t\treturn s[:len(s)-1]\n\t}\n\treturn s + \"0x\" + strconv.FormatUint(uint64(i), 16)\n}\n"
  },
  {
    "path": "perffile/meta.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage perffile\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n)\n\ntype FileMeta struct {\n\t// BuildIDs is the list of build IDs for processes and\n\t// libraries in this profile, or nil if unknown. Note that in\n\t// \"live mode\" (e.g., a file written by perf inject), it's\n\t// possible for build IDs to be introduced in the sample\n\t// stream itself.\n\tBuildIDs []BuildIDInfo\n\n\t// Hostname is the hostname of the machine that recorded this\n\t// profile, or \"\" if unknown.\n\tHostname string\n\n\t// OSRelease is the OS release of the machine that recorded\n\t// this profile such as \"3.13.0-62\", or \"\" if unknown.\n\tOSRelease string\n\n\t// Version is the perf version that recorded this profile such\n\t// as \"3.13.11\", or \"\" if unknown.\n\tVersion string\n\n\t// Arch is the host architecture of the machine that recorded\n\t// this profile such as \"x86_64\", or \"\" if unknown.\n\tArch string\n\n\t// CPUsOnline and CPUsAvail are the number of online and\n\t// available CPUs of the machine that recorded this profile,\n\t// or 0, 0 if unknown.\n\tCPUsOnline, CPUsAvail int\n\n\t// CPUDesc describes the CPU of the machine that recorded this\n\t// profile such as \"Intel(R) Core(TM) i7-4600U CPU @ 2.10GHz\",\n\t// or \"\" if unknown.\n\tCPUDesc string\n\n\t// CPUID describes the CPU type of the machine that recorded\n\t// this profile, or \"\" if unknown. The exact format of this\n\t// varies between architectures. On x86 architectures, it is a\n\t// comma-separated list of vendor, family, model, and\n\t// stepping, such as \"GenuineIntel,6,69,1\".\n\tCPUID string\n\n\t// TotalMem is the total memory in bytes of the machine that\n\t// recorded this profile, or 0 if unknown.\n\tTotalMem int64\n\n\t// CmdLine is the list of command line arguments perf was\n\t// invoked with, or nil if unknown.\n\tCmdLine []string\n\n\t// CoreGroups and ThreadGroups describe the CPU topology of\n\t// the machine that recorded this profile. Each CPUSet in\n\t// CoreGroups is a set of CPUs in the same package, and each\n\t// CPUSet in ThreadGroups is a set of hardware threads in the\n\t// same core. These will be nil if unkneon.\n\tCoreGroups, ThreadGroups []CPUSet\n\n\t// NUMANodes is the set of NUMA nodes in the NUMA topology of\n\t// the machine that recorded this profile, or nil if unknown.\n\tNUMANodes []NUMANode\n\n\t// PMUMappings is a map from numerical PMUTypeID to name for\n\t// event classes supported by the machine that recorded this\n\t// profile, or nil if unknown.\n\tPMUMappings map[PMUTypeID]string\n\n\t// Groups is the descriptions of each perf event group in this\n\t// profile, or nil if unknown.\n\tGroups []GroupDesc\n}\n\n// A BuildIDInfo records the mapping between a single build ID and the\n// path of an executable with that build ID.\ntype BuildIDInfo struct {\n\tCPUMode  CPUMode\n\tPID      int // Usually -1; for VM kernels\n\tBuildID  BuildID\n\tFilename string\n}\n\ntype BuildID []byte\n\nfunc (b BuildID) String() string {\n\treturn fmt.Sprintf(\"%x\", []byte(b))\n}\n\n// A NUMANode represents a single hardware NUMA node.\ntype NUMANode struct {\n\t// Node is the system identifier of this NUMA node.\n\tNode int\n\n\t// MemTotal and MemFree are the total and free number of bytes\n\t// of memory in this NUMA node.\n\tMemTotal, MemFree int64\n\n\t// CPUs is the set of CPUs in this NUMA node.\n\tCPUs CPUSet\n}\n\n// A GroupDesc describes a group of PMU events that are scheduled\n// together.\n//\n// TODO: Are Leader and NumMembers attribute IDs? If so, we should\n// probably map them to *EventAttrs to make this useful.\ntype GroupDesc struct {\n\tName       string\n\tLeader     int\n\tNumMembers int\n}\n\nvar featureParsers = map[feature]func(*FileMeta, bufDecoder) error{\n\tfeatureBuildID:      (*FileMeta).parseBuildID,\n\tfeatureHostname:     stringFeature(\"Hostname\"),\n\tfeatureOSRelease:    stringFeature(\"OSRelease\"),\n\tfeatureVersion:      stringFeature(\"Version\"),\n\tfeatureArch:         stringFeature(\"Arch\"),\n\tfeatureNrCpus:       (*FileMeta).parseNrCPUs,\n\tfeatureCPUDesc:      stringFeature(\"CPUDesc\"),\n\tfeatureCPUID:        stringFeature(\"CPUID\"),\n\tfeatureTotalMem:     (*FileMeta).parseTotalMem,\n\tfeatureCmdline:      (*FileMeta).parseCmdLine,\n\tfeatureCPUTopology:  (*FileMeta).parseCPUTopology,\n\tfeatureNUMATopology: (*FileMeta).parseNUMATopology,\n\tfeaturePMUMappings:  (*FileMeta).parsePMUMappings,\n\tfeatureGroupDesc:    (*FileMeta).parseGroupDesc,\n}\n\nfunc (m *FileMeta) parse(f feature, sec fileSection, r io.ReaderAt) error {\n\tparser := featureParsers[f]\n\tif parser == nil {\n\t\treturn nil\n\t}\n\n\t// Load the section.\n\tdata, err := sec.data(r)\n\tif err != nil {\n\t\treturn err\n\t}\n\tbd := bufDecoder{data, binary.LittleEndian}\n\n\t// Parse the section.\n\treturn parser(m, bd)\n}\n\nfunc stringFeature(name string) func(*FileMeta, bufDecoder) error {\n\treturn func(m *FileMeta, bd bufDecoder) error {\n\t\tbd.u32() // Ignore length; string is \\0-terminated\n\t\tstr := bd.cstring()\n\t\treflect.ValueOf(m).Elem().FieldByName(name).SetString(str)\n\t\treturn nil\n\t}\n}\n\nfunc (m *FileMeta) parseBuildID(bd bufDecoder) error {\n\tm.BuildIDs = make([]BuildIDInfo, 0)\n\tfor len(bd.buf) > 0 {\n\t\tvar bid BuildIDInfo\n\t\tstart := bd.buf\n\t\t// This starts with a recordHeader.\n\t\t_ = bd.u32() // type, unused\n\t\tbid.CPUMode = CPUMode(bd.u16() & uint16(recordMiscCPUModeMask))\n\t\tsize := bd.u16()\n\t\tbid.PID = int(bd.i32())\n\t\t// The build ID is 20 bytes, but padded to 8 bytes.\n\t\tbuildID := make([]byte, 24)\n\t\tbd.bytes(buildID)\n\t\tbid.BuildID = BuildID(buildID[:20])\n\t\tbid.Filename = bd.cstring()\n\t\tm.BuildIDs = append(m.BuildIDs, bid)\n\t\tbd.buf = start[size:]\n\t}\n\treturn nil\n}\n\nfunc (m *FileMeta) parseNrCPUs(bd bufDecoder) error {\n\tm.CPUsOnline, m.CPUsAvail = int(bd.u32()), int(bd.u32())\n\treturn nil\n}\n\nfunc (m *FileMeta) parseTotalMem(bd bufDecoder) error {\n\tm.TotalMem = int64(bd.u64()) * 1024\n\treturn nil\n}\n\nfunc (m *FileMeta) parseCmdLine(bd bufDecoder) error {\n\tm.CmdLine = bd.stringList()\n\treturn nil\n}\n\n// TODO: Implement featureEventDesc. This isn't useful unless we also\n// expose attribute IDs or something to make it possible to match up\n// the event descriptions with the samples. Probably we should hide\n// this as a feature section and just expose the set of events in the\n// file, augmented with the string names from this section if\n// available. As far as I can tell, the string name is the *only*\n// thing this section adds over the EventAttrs in the file header.\n\nfunc (m *FileMeta) parseCPUTopology(bd bufDecoder) error {\n\tvar err error\n\tcores, threads := bd.stringList(), bd.stringList()\n\tm.CoreGroups = make([]CPUSet, len(cores))\n\tfor i, str := range cores {\n\t\tm.CoreGroups[i], err = parseCPUSet(str)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tm.ThreadGroups = make([]CPUSet, len(threads))\n\tfor i, str := range threads {\n\t\tm.ThreadGroups[i], err = parseCPUSet(str)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (m *FileMeta) parseNUMATopology(bd bufDecoder) error {\n\tvar err error\n\tcount := bd.u32()\n\tm.NUMANodes = []NUMANode{}\n\tfor i := uint32(0); i < count; i++ {\n\t\tnode := NUMANode{\n\t\t\tNode:     int(bd.u32()),\n\t\t\tMemTotal: int64(bd.u64()) * 1024,\n\t\t\tMemFree:  int64(bd.u64()) * 1024,\n\t\t}\n\t\tnode.CPUs, err = parseCPUSet(bd.lenString())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tm.NUMANodes = append(m.NUMANodes, node)\n\t}\n\treturn nil\n}\n\nfunc (m *FileMeta) parsePMUMappings(bd bufDecoder) error {\n\tcount := bd.u32()\n\tm.PMUMappings = map[PMUTypeID]string{}\n\tfor i := uint32(0); i < count; i++ {\n\t\tm.PMUMappings[PMUTypeID(bd.u32())] = bd.lenString()\n\t}\n\treturn nil\n}\n\nfunc (m *FileMeta) parseGroupDesc(bd bufDecoder) error {\n\tcount := bd.u32()\n\tm.Groups = []GroupDesc{}\n\tfor i := uint32(0); i < count; i++ {\n\t\tm.Groups = append(m.Groups, GroupDesc{\n\t\t\tName:       bd.lenString(),\n\t\t\tLeader:     int(bd.u32()),\n\t\t\tNumMembers: int(bd.u32()),\n\t\t})\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "perffile/package.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package perffile is a parser for Linux perf.data profiles.\n//\n// Parsing a perf.data profile starts with a call to New or Open to\n// open a perf.data file. A perf.data file consists of a sequence of\n// records, which can be retrieved with File.Records, as well as\n// several metadata fields, which can be retrieved with other methods\n// of File.\npackage perffile // import \"github.com/aclements/go-perf/perffile\"\n"
  },
  {
    "path": "perffile/reader.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage perffile\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"reflect\"\n\t\"sort\"\n)\n\n// TODO: Type for file format errors.\n\n// A File is a perf.data file. It consists of a sequence of records,\n// which can be retrieved with the Records method, as well as several\n// optional metadata fields.\ntype File struct {\n\t// Meta contains the metadata for this profile, such as\n\t// information about the hardware.\n\tMeta FileMeta\n\n\t// Events lists all events that may appear in this profile.\n\tEvents []*EventAttr\n\n\tr      io.ReaderAt\n\tcloser io.Closer\n\thdr    fileHeader\n\n\tattrs    []fileAttr\n\tidToAttr map[attrID]*EventAttr\n\n\tsampleIDOffset int // byte offset of AttrID in sample\n\n\tsampleIDAll    bool // non-samples have sample_id trailer\n\trecordIDOffset int  // byte offset of AttrID in non-sample, from end\n}\n\n// New reads a \"perf.data\" file from r.\n//\n// The caller must keep r open as long as it is using the returned\n// *File.\nfunc New(r io.ReaderAt) (*File, error) {\n\t// See perf_session__open in tools/perf/util/session.c.\n\tfile := &File{r: r, Events: make([]*EventAttr, 0)}\n\n\t// Read and process the file header.\n\t//\n\t// See perf_session__read_header in tools/perf/util/header.c\n\n\tsr := io.NewSectionReader(r, 0, 1024)\n\tif err := binary.Read(sr, binary.LittleEndian, &file.hdr); err != nil {\n\t\treturn nil, err\n\t}\n\tswitch string(file.hdr.Magic[:]) {\n\tcase \"PERFILE2\":\n\t\t// Version 2, little endian.\n\t\tbreak\n\tcase \"2ELIFREP\":\n\t\t// Version 2, big endian.\n\t\t//\n\t\t// TODO: Support big endian profiles.\n\t\treturn nil, fmt.Errorf(\"big endian profiles not supported\")\n\tcase \"PERFFILE\":\n\t\t// Version 1 file.\n\t\treturn nil, fmt.Errorf(\"version 1 profiles not supported\")\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"bad or unsupported file magic %q\", string(file.hdr.Magic[:]))\n\t}\n\tif file.hdr.Size != uint64(binary.Size(&file.hdr)) {\n\t\treturn nil, fmt.Errorf(\"bad header size %d\", file.hdr.Size)\n\t}\n\n\t// hdr.Data.Size is the last thing written out by perf, so if\n\t// it's zero, we're working with a partial file.\n\tif file.hdr.Data.Size == 0 {\n\t\treturn nil, fmt.Errorf(\"truncated data file; was 'perf record' properly terminated?\")\n\t}\n\n\t// Read EventAttrs. Note that the attr size is represented in\n\t// both the file header and in each individual attr, but perf\n\t// doesn't validate the file-level attr size.\n\tif file.hdr.AttrSize == 0 {\n\t\treturn nil, fmt.Errorf(\"bad attr size 0\")\n\t}\n\tnAttrs := int(file.hdr.Attrs.Size / file.hdr.AttrSize)\n\tif nAttrs == 0 {\n\t\treturn nil, fmt.Errorf(\"no event types\")\n\t} else if nAttrs > 64*1024 {\n\t\treturn nil, fmt.Errorf(\"too many attrs or bad attr size\")\n\t}\n\tfile.attrs = make([]fileAttr, nAttrs)\n\tattrSR := file.hdr.Attrs.sectionReader(r)\n\tfor i := 0; i < nAttrs; i++ {\n\t\tif err := readFileAttr(attrSR, &file.attrs[i]); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfile.Events = append(file.Events, &file.attrs[i].Attr)\n\t}\n\n\t// Read EventAttr IDs and create ID -> EventAttr map\n\tfile.idToAttr = make(map[attrID]*EventAttr)\n\tfor _, attr := range file.attrs {\n\t\tvar ids []attrID\n\t\tif err := readSlice(attr.IDs.sectionReader(r), &ids); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfor _, id := range ids {\n\t\t\tfile.idToAttr[id] = &attr.Attr\n\t\t}\n\t}\n\n\t// Check that sample formats are consistent across all event\n\t// types and record cross-event sample format information.\n\tfirstEvent := &file.attrs[0].Attr\n\tfile.sampleIDOffset = firstEvent.SampleFormat.sampleIDOffset()\n\tfile.recordIDOffset = firstEvent.SampleFormat.recordIDOffset()\n\tfile.sampleIDAll = firstEvent.Flags&EventFlagSampleIDAll != 0\n\tif len(file.attrs) > 1 {\n\t\tif len(file.idToAttr) == 0 {\n\t\t\treturn nil, fmt.Errorf(\"file has multiple EventAttrs, but no IDs\")\n\t\t}\n\t\tfor _, attr := range file.attrs {\n\t\t\t// See perf_evlist__valid_sample_type.\n\t\t\tx := attr.Attr.SampleFormat.sampleIDOffset()\n\t\t\tif x == -1 {\n\t\t\t\treturn nil, fmt.Errorf(\"multiple events, but samples have no event ID field\")\n\t\t\t} else if file.sampleIDOffset != x {\n\t\t\t\treturn nil, fmt.Errorf(\"events have incompatible ID offsets %d and %d\", file.sampleIDOffset, x)\n\t\t\t}\n\n\t\t\tx = attr.Attr.SampleFormat.recordIDOffset()\n\t\t\tif x == -1 {\n\t\t\t\treturn nil, fmt.Errorf(\"multiple events, but records have no event ID field\")\n\t\t\t} else if file.recordIDOffset != x {\n\t\t\t\treturn nil, fmt.Errorf(\"records have incompatible ID offsets %d and %d\", file.recordIDOffset, x)\n\t\t\t}\n\n\t\t\t// See perf_evlist__valid_sample_id_all.\n\t\t\tidAll := attr.Attr.Flags&EventFlagSampleIDAll != 0\n\t\t\tif file.sampleIDAll != idAll {\n\t\t\t\treturn nil, fmt.Errorf(\"events have incompatible SampleIDAll flags\")\n\t\t\t}\n\n\t\t\t// See perf_evlist__valid_read_format.\n\t\t\tif firstEvent.ReadFormat != attr.Attr.ReadFormat {\n\t\t\t\treturn nil, fmt.Errorf(\"events have incompatible read formats\")\n\t\t\t}\n\t\t}\n\t\tif firstEvent.SampleFormat&SampleFormatRead != 0 &&\n\t\t\tfirstEvent.ReadFormat&ReadFormatID == 0 {\n\t\t\treturn nil, fmt.Errorf(\"bad event read format\")\n\t\t}\n\t}\n\n\t// Load feature sections.\n\tsr = io.NewSectionReader(r, int64(file.hdr.Data.Offset+file.hdr.Data.Size), int64(numFeatureBits*binary.Size(fileSection{})))\n\tfor bit := feature(0); bit < feature(numFeatureBits); bit++ {\n\t\tif !file.hdr.hasFeature(bit) {\n\t\t\tcontinue\n\t\t}\n\t\tsec := fileSection{}\n\t\tif err := binary.Read(sr, binary.LittleEndian, &sec); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfile.Meta.parse(bit, sec, file.r)\n\t}\n\n\treturn file, nil\n}\n\n// Open opens the named \"perf.data\" file using os.Open.\n//\n// The caller must call f.Close() on the returned file when it is\n// done.\nfunc Open(name string) (*File, error) {\n\tf, err := os.Open(name)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tff, err := New(f)\n\tif err != nil {\n\t\tf.Close()\n\t\treturn nil, err\n\t}\n\tff.closer = f\n\treturn ff, nil\n}\n\nfunc readFileAttr(sr *io.SectionReader, fa *fileAttr) error {\n\t// See read_attr in tools/perf/util/header.c.\n\n\t// Read the common prefix of all event attr versions.\n\tvar attr eventAttrVN\n\tif err := binary.Read(sr, binary.LittleEndian, &attr.eventAttrV0); err != nil {\n\t\treturn err\n\t}\n\tif attr.Size == 0 {\n\t\t// Assume ABI v0\n\t\tattr.Size = 64\n\t} else if attr.Size > uint32(binary.Size(&attr)) {\n\t\treturn fmt.Errorf(\"event attr size %d too large; more recent and unsupported format\", attr.Size)\n\t} else {\n\t\t// Read whatever's left. There are specific versions\n\t\t// of this structure, but perf doesn't try to\n\t\t// distinguish them, so neither do we.\n\t\tleft := int(attr.Size) - binary.Size(&attr.eventAttrV0)\n\t\trattr := reflect.ValueOf(&attr).Elem()\n\t\tfor i := 1; i < rattr.NumField() && left > 0; i++ {\n\t\t\tfield := rattr.Field(i).Addr().Interface()\n\t\t\terr := binary.Read(sr, binary.LittleEndian, field)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tleft -= binary.Size(field)\n\t\t}\n\t}\n\n\t// Convert on-disk perf_event_attr in to EventAttr.\n\tvar ev EventGeneric\n\tev.Type = attr.Type\n\tev.ID = attr.Config\n\tif attr.Flags&EventFlagFreq == 0 {\n\t\tfa.Attr.SamplePeriod = attr.SamplePeriodOrFreq\n\t} else {\n\t\tfa.Attr.SampleFreq = attr.SamplePeriodOrFreq\n\t}\n\tfa.Attr.SampleFormat = attr.SampleFormat\n\tfa.Attr.ReadFormat = attr.ReadFormat\n\tfa.Attr.Flags = attr.Flags &^ eventFlagPreciseMask\n\tfa.Attr.Precise = EventPrecision((attr.Flags & eventFlagPreciseMask) >> eventFlagPreciseShift)\n\tif attr.Flags&EventFlagWakeupWatermark == 0 {\n\t\tfa.Attr.WakeupEvents = attr.WakeupEventsOrWatermark\n\t} else {\n\t\tfa.Attr.WakeupWatermark = attr.WakeupEventsOrWatermark\n\t}\n\tif attr.Type == EventTypeBreakpoint {\n\t\t// For EventTypeBreakpoint, attr.Config is 0 and the\n\t\t// breakpoint type is described in BPType. We merge\n\t\t// the two.\n\t\tev.ID = uint64(attr.BPType)\n\t}\n\tev.Config = make([]uint64, 2)\n\tev.Config[0] = attr.BPAddrOrConfig1\n\tev.Config[1] = attr.BPLenOrConfig2\n\tfa.Attr.SampleRegsUser = attr.SampleRegsUser\n\tfa.Attr.SampleStackUser = attr.SampleStackUser\n\tfa.Attr.AuxWatermark = attr.AuxWatermark\n\tfa.Attr.SampleMaxStack = attr.SampleMaxStack\n\n\tfa.Attr.Event = ev.Decode()\n\n\t// Finally, read IDs fileSection, which follows the eventAttr.\n\treturn binary.Read(sr, binary.LittleEndian, &fa.IDs)\n}\n\n// Close closes the File.\n//\n// If the File was created using New directly instead of Open, Close\n// has no effect.\nfunc (f *File) Close() error {\n\tvar err error\n\tif f.closer != nil {\n\t\terr = f.closer.Close()\n\t\tf.closer = nil\n\t}\n\treturn err\n}\n\n// readSlice reads an entire section into a slice.  v must be a\n// pointer to a slice; the slice itself may be nil.  The section size\n// must be an exact multiple of the size of the element type of v.\nfunc readSlice(sr *io.SectionReader, v interface{}) error {\n\t// Figure out slice value size\n\tvt := reflect.TypeOf(v)\n\tif vt.Kind() != reflect.Ptr || vt.Elem().Kind() != reflect.Slice {\n\t\tpanic(\"v must be a pointer to a slice\")\n\t}\n\tet := vt.Elem().Elem()\n\tesize := binary.Size(reflect.Zero(et).Interface())\n\tnelem := int(sr.Size() / int64(esize))\n\tif sr.Size()%int64(esize) != 0 {\n\t\treturn fmt.Errorf(\"section size %d is not a multiple of element size %d\", sr.Size(), esize)\n\t}\n\n\t// Create slice\n\treflect.ValueOf(v).Elem().Set(reflect.MakeSlice(vt.Elem(), nelem, nelem))\n\n\t// Read in to slice\n\treturn binary.Read(sr, binary.LittleEndian, v)\n}\n\n//go:generate stringer -type=RecordsOrder\n\ntype RecordsOrder int\n\nconst (\n\t// RecordsFileOrder requests records in file order. This is\n\t// efficient because it allows streaming the records directly\n\t// from the file, but the records may not be in time-stamp or\n\t// even causal order.\n\tRecordsFileOrder RecordsOrder = iota\n\n\t// RecordsCausalOrder requests records in causal order. This\n\t// is weakly time-ordered: any two records will be in\n\t// time-stamp order *unless* those records are both\n\t// RecordSamples. This is potentially more efficient than\n\t// RecordsTimeOrder, though currently the implementation does\n\t// not distinguish.\n\tRecordsCausalOrder\n\n\t// RecordsTimeOrder requests records in time-stamp order. This\n\t// is the most expensive iteration order because it requires\n\t// buffering and/or re-reading potentially large sections of\n\t// the input file in order to sort the records.\n\tRecordsTimeOrder\n)\n\n// Records returns an iterator over the records in the profile. The\n// order argument specifies the order for iterating through the\n// records in this File. Callers should choose the least\n// resource-intensive iteration order that satisfies their needs.\nfunc (f *File) Records(order RecordsOrder) *Records {\n\tif order == RecordsCausalOrder || order == RecordsTimeOrder {\n\t\t// Sort the records by making two passes: first record\n\t\t// the offsets and time-stamps of all records, then\n\t\t// sort this by time-stamp and re-read in the new\n\t\t// offset order.\n\t\t//\n\t\t// See process_finished_round in session.c for how\n\t\t// perf does this. process_finished_round uses a\n\t\t// special flush event; however, I've never actually\n\t\t// observed in a perf.data file, so I think perf may\n\t\t// be reading and sorting the whole file looking for a\n\t\t// flush.\n\n\t\t// TODO: Optimize the first pass to decode only the\n\t\t// record length and time-stamp.\n\n\t\t// TODO: Optimize IO on the second pass by keeping\n\t\t// track of the non-monotonic boundaries and\n\t\t// performing separately buffered reads of each\n\t\t// sub-stream.\n\n\t\trs := f.Records(RecordsFileOrder)\n\t\tpos, ts := make([]int64, 0), make([]uint64, 0)\n\t\tfor rs.Next() {\n\t\t\tc := rs.Record.Common()\n\t\t\tpos = append(pos, c.Offset)\n\t\t\tts = append(ts, c.Time)\n\t\t}\n\t\tif rs.Err() != nil {\n\t\t\treturn &Records{err: rs.Err()}\n\t\t}\n\t\tsort.Stable(&timeSorter{pos, ts})\n\t\treturn &Records{f: f, sr: newBufferedSectionReader(f.hdr.Data.sectionReader(f.r)), order: pos}\n\t}\n\n\treturn &Records{f: f, sr: newBufferedSectionReader(f.hdr.Data.sectionReader(f.r))}\n}\n\ntype timeSorter struct {\n\tpos []int64\n\tts  []uint64\n}\n\nfunc (s *timeSorter) Len() int {\n\treturn len(s.pos)\n}\n\nfunc (s *timeSorter) Less(i, j int) bool {\n\treturn s.ts[i] < s.ts[j]\n}\n\nfunc (s *timeSorter) Swap(i, j int) {\n\ts.pos[i], s.pos[j] = s.pos[j], s.pos[i]\n\ts.ts[i], s.ts[j] = s.ts[j], s.ts[i]\n}\n"
  },
  {
    "path": "perffile/readformat_string.go",
    "content": "// Code generated by \"bitstringer -type=ReadFormat\"; DO NOT EDIT\n\npackage perffile\n\nimport \"strconv\"\n\nfunc (i ReadFormat) String() string {\n\tif i == 0 {\n\t\treturn \"0\"\n\t}\n\ts := \"\"\n\tif i&ReadFormatGroup != 0 {\n\t\ts += \"Group|\"\n\t}\n\tif i&ReadFormatID != 0 {\n\t\ts += \"ID|\"\n\t}\n\tif i&ReadFormatTotalTimeEnabled != 0 {\n\t\ts += \"TotalTimeEnabled|\"\n\t}\n\tif i&ReadFormatTotalTimeRunning != 0 {\n\t\ts += \"TotalTimeRunning|\"\n\t}\n\ti &^= 15\n\tif i == 0 {\n\t\treturn s[:len(s)-1]\n\t}\n\treturn s + \"0x\" + strconv.FormatUint(uint64(i), 16)\n}\n"
  },
  {
    "path": "perffile/records.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage perffile\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"io\"\n)\n\n// A Records is an iterator over the records in a \"perf.data\" file.\n// Each record will be one of the Record* types.\n//\n// Typical usage is\n//\n//\trs := file.Records()\n//\tfor rs.Next() {\n//\t  switch r := rs.Record.(type) {\n//\t  case *perffile.RecordSample:\n//\t    ...\n//\t  }\n//\t}\n//\tif rs.Err() { ... }\ntype Records struct {\n\t// The current record. The concrete type of this will be one\n\t// of the Record* types. Determine which type of record this\n\t// is using a type switch.\n\tRecord Record\n\n\tf   *File\n\tsr  *bufferedSectionReader // or *io.SectionReader\n\terr error\n\n\t// order specifies the seek order to read records in. If nil,\n\t// records are read in file order until EOF. If non-nil,\n\t// records are read in this order.\n\torder []int64\n\n\t// Read buffer.  Reused (and resized) by Next.\n\tbuf []byte\n\n\t// Cache for common record types\n\trecordMmap          RecordMmap\n\trecordComm          RecordComm\n\trecordExit          RecordExit\n\trecordFork          RecordFork\n\trecordSample        RecordSample\n\trecordAux           RecordAux\n\trecordSwitch        RecordSwitch\n\trecordSwitchCPUWide RecordSwitchCPUWide\n}\n\n// Err returns the first error encountered by Records.\nfunc (r *Records) Err() error {\n\treturn r.err\n}\n\n// Next fetches the next record into r.Record.  It returns true if\n// successful, and false if it reaches the end of the record stream or\n// encounters an error.\n//\n// The record stored in r.Record may be reused by later invocations of\n// Next, so if the caller may need the record after another call to\n// Next, it must make its own copy.\nfunc (r *Records) Next() bool {\n\t// See perf_evsel__parse_sample\n\tif r.err != nil {\n\t\treturn false\n\t}\n\n\tif r.order != nil {\n\t\tif len(r.order) == 0 {\n\t\t\treturn false\n\t\t}\n\t\tpos := r.order[0]\n\t\tr.order = r.order[1:]\n\t\t_, r.err = r.sr.Seek(pos-int64(r.f.hdr.Data.Offset), 0)\n\t\tif r.err != nil {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tvar common RecordCommon\n\toffset, _ := r.sr.Seek(0, 1)\n\tcommon.Offset = offset + int64(r.f.hdr.Data.Offset)\n\n\t// Read record header\n\tvar hdr recordHeader\n\tif err := binary.Read(r.sr, binary.LittleEndian, &hdr); err != nil {\n\t\tif err != io.EOF {\n\t\t\tr.err = err\n\t\t}\n\t\treturn false\n\t}\n\n\t// Read record data\n\trlen := int(hdr.Size - 8)\n\tif rlen > len(r.buf) {\n\t\tr.buf = make([]byte, rlen)\n\t}\n\tvar bd = &bufDecoder{r.buf[:rlen], binary.LittleEndian}\n\tif _, err := io.ReadFull(r.sr, bd.buf); err != nil {\n\t\tr.err = err\n\t\treturn false\n\t}\n\n\t// Parse common sample_id fields\n\tif r.f.sampleIDAll && hdr.Type != RecordTypeSample && hdr.Type < recordTypeUserStart {\n\t\t// mmap records in the prologue don't have eventAttrs\n\t\t// in recent perf versions, but that's okay.\n\t\t//\n\t\t// TODO: When is perf okay with missing eventAttrs?\n\t\tr.parseCommon(bd, &common, hdr.Type == RecordTypeMmap)\n\t}\n\n\t// Parse record\n\t// TODO: Don't array out-of-bounds on short records\n\tswitch hdr.Type {\n\tdefault:\n\t\t// As far as I can tell, RecordTypeRead can never\n\t\t// appear in a perf.data file.\n\t\tr.Record = &RecordUnknown{hdr, common, bd.buf}\n\n\tcase RecordTypeMmap:\n\t\tr.Record = r.parseMmap(bd, &hdr, &common, false)\n\n\tcase RecordTypeLost:\n\t\tr.Record = r.parseLost(bd, &hdr, &common)\n\n\tcase RecordTypeComm:\n\t\tr.Record = r.parseComm(bd, &hdr, &common)\n\n\tcase RecordTypeExit:\n\t\tr.Record = r.parseExit(bd, &hdr, &common)\n\n\tcase RecordTypeThrottle:\n\t\tr.Record = r.parseThrottle(bd, &hdr, &common, true)\n\n\tcase RecordTypeUnthrottle:\n\t\tr.Record = r.parseThrottle(bd, &hdr, &common, false)\n\n\tcase RecordTypeFork:\n\t\tr.Record = r.parseFork(bd, &hdr, &common)\n\n\tcase RecordTypeSample:\n\t\tr.Record = r.parseSample(bd, &hdr, &common)\n\n\tcase recordTypeMmap2:\n\t\tr.Record = r.parseMmap(bd, &hdr, &common, true)\n\n\tcase RecordTypeAux:\n\t\tr.Record = r.parseAux(bd, &hdr, &common)\n\n\tcase RecordTypeItraceStart:\n\t\tr.Record = r.parseItraceStart(bd, &hdr, &common)\n\n\tcase RecordTypeLostSamples:\n\t\tr.Record = r.parseLostSamples(bd, &hdr, &common)\n\n\tcase RecordTypeSwitch:\n\t\tr.Record = r.parseSwitch(bd, &hdr, &common)\n\n\tcase RecordTypeSwitchCPUWide:\n\t\tr.Record = r.parseSwitchCPUWide(bd, &hdr, &common)\n\n\tcase RecordTypeNamespaces:\n\t\tr.Record = r.parseNamespaces(bd, &hdr, &common)\n\n\tcase RecordTypeKsymbol:\n\t\tr.Record = r.parseKsymbol(bd, &hdr, &common)\n\n\tcase RecordTypeBPFEvent:\n\t\tr.Record = r.parseBPFEvent(bd, &hdr, &common)\n\n\tcase RecordTypeCGroup:\n\t\tr.Record = r.parseCGroup(bd, &hdr, &common)\n\n\tcase RecordTypeTextPoke:\n\t\tr.Record = r.parseTextPoke(bd, &hdr, &common)\n\n\tcase RecordTypeAuxOutputHardwareID:\n\t\tr.Record = r.parseAuxOutputHardwareID(bd, &hdr, &common)\n\n\tcase RecordTypeAuxtraceInfo:\n\t\tr.Record = r.parseAuxtraceInfo(bd, &hdr, &common)\n\n\tcase RecordTypeAuxtrace:\n\t\t// Note: This appears to be the only record type that\n\t\t// has additional payload data following it that isn't\n\t\t// included in the header size.\n\t\tr.Record = r.parseAuxtrace(bd, &hdr, &common)\n\t}\n\tif r.err != nil {\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (r *Records) getAttr(id attrID, nilOk bool) *EventAttr {\n\t// See perf_evlist__id2evsel in tools/perf/util/evlist.c.\n\n\t// If there's only one event, all records implicitly use it.\n\tif len(r.f.attrs) == 1 || id == 0 {\n\t\treturn &r.f.attrs[0].Attr\n\t}\n\t// Otherwise, look up the event by ID.\n\tif attr, ok := r.f.idToAttr[id]; ok {\n\t\treturn attr\n\t}\n\tif !nilOk {\n\t\tr.err = fmt.Errorf(\"event has unknown eventAttr ID %d\", id)\n\t}\n\treturn nil\n}\n\n// parseCommon parses the common sample_id structure in the trailer of\n// non-sample records.\nfunc (r *Records) parseCommon(bd *bufDecoder, o *RecordCommon, missingOk bool) bool {\n\t// Get EventAttr ID\n\tif r.f.recordIDOffset == -1 {\n\t\to.ID = 0\n\t} else {\n\t\to.ID = attrID(bd.order.Uint64(bd.buf[len(bd.buf)+r.f.recordIDOffset:]))\n\t}\n\to.EventAttr = r.getAttr(o.ID, missingOk && o.ID == 0)\n\tif o.EventAttr == nil {\n\t\treturn false\n\t}\n\n\t// Narrow decoder to the trailer\n\tcommonLen := o.EventAttr.SampleFormat.trailerBytes()\n\tbd = &bufDecoder{bd.buf[len(bd.buf)-commonLen:], bd.order}\n\n\t// Decode trailer\n\tt := o.EventAttr.SampleFormat\n\to.Format = t\n\to.PID = int(bd.i32If(t&SampleFormatTID != 0))\n\to.TID = int(bd.i32If(t&SampleFormatTID != 0))\n\to.Time = bd.u64If(t&SampleFormatTime != 0)\n\tbd.u64If(t&SampleFormatID != 0)\n\to.StreamID = bd.u64If(t&SampleFormatStreamID != 0)\n\to.CPU = bd.u32If(t&SampleFormatCPU != 0)\n\to.Res = bd.u32If(t&SampleFormatCPU != 0)\n\treturn true\n}\n\nfunc (r *Records) parseMmap(bd *bufDecoder, hdr *recordHeader, common *RecordCommon, v2 bool) Record {\n\to := &r.recordMmap\n\to.RecordCommon = *common\n\to.Format |= SampleFormatTID\n\n\t// Decode hdr.Misc\n\to.Data = (hdr.Misc&recordMiscMmapData != 0)\n\n\t// Decode fields. Note that perf calls the file offset\n\t// \"pgoff\", but it's actually a byte offset.\n\to.PID, o.TID = int(bd.i32()), int(bd.i32())\n\to.Addr, o.Len, o.FileOffset = bd.u64(), bd.u64(), bd.u64()\n\tif v2 {\n\t\tbuildID := (hdr.Misc&recordMiscMmapBuildID != 0)\n\t\tif buildID {\n\t\t\tbuildIDLen := int(bd.u8())\n\t\t\tif o.BuildID == nil || cap(o.BuildID) < buildIDLen {\n\t\t\t\to.BuildID = make([]byte, buildIDLen)\n\t\t\t} else {\n\t\t\t\to.BuildID = o.BuildID[:buildIDLen]\n\t\t\t}\n\t\t\tbd.skip(3)\n\t\t\tbd.bytes(o.BuildID)\n\n\t\t\to.Major, o.Minor = 0, 0\n\t\t\to.Ino, o.InoGeneration = 0, 0\n\t\t} else {\n\t\t\to.Major, o.Minor = bd.u32(), bd.u32()\n\t\t\to.Ino, o.InoGeneration = bd.u64(), bd.u64()\n\n\t\t\to.BuildID = nil\n\t\t}\n\n\t\to.Prot, o.Flags = bd.u32(), bd.u32()\n\t}\n\to.Filename = bd.cstring()\n\n\treturn o\n}\n\nfunc (r *Records) parseLost(bd *bufDecoder, hdr *recordHeader, common *RecordCommon) Record {\n\to := &RecordLost{RecordCommon: *common}\n\to.Format |= SampleFormatID\n\n\to.ID = attrID(bd.u64())\n\to.EventAttr = r.getAttr(o.ID, false)\n\to.NumLost = bd.u64()\n\n\treturn o\n}\n\nfunc (r *Records) parseComm(bd *bufDecoder, hdr *recordHeader, common *RecordCommon) Record {\n\to := &r.recordComm\n\to.RecordCommon = *common\n\to.Format |= SampleFormatTID\n\n\t// Decode hdr.Misc\n\to.Exec = (hdr.Misc&recordMiscCommExec != 0)\n\n\t// Decode fields\n\to.PID, o.TID = int(bd.i32()), int(bd.i32())\n\to.Comm = bd.cstring()\n\n\treturn o\n}\n\nfunc (r *Records) parseExit(bd *bufDecoder, hdr *recordHeader, common *RecordCommon) Record {\n\to := &r.recordExit\n\to.RecordCommon = *common\n\to.Format |= SampleFormatTID | SampleFormatTime\n\n\to.PID, o.PPID = int(bd.i32()), int(bd.i32())\n\to.TID, o.PTID = int(bd.i32()), int(bd.i32())\n\to.Time = bd.u64()\n\n\treturn o\n}\n\nfunc (r *Records) parseThrottle(bd *bufDecoder, hdr *recordHeader, common *RecordCommon, enable bool) Record {\n\to := &RecordThrottle{RecordCommon: *common, Enable: enable}\n\to.Format |= SampleFormatTime | SampleFormatID | SampleFormatStreamID\n\n\to.Time = bd.u64()\n\t// Throttle events always have an event attr ID, even if the\n\t// IDs aren't recorded.  So if we see an unknown attr ID, just\n\t// assume it's the default event.\n\tid := attrID(bd.u64())\n\tif r.f.idToAttr[id] == nil && r.f.idToAttr[0] != nil {\n\t\to.EventAttr = r.f.idToAttr[0]\n\t} else {\n\t\to.EventAttr = r.getAttr(id, false)\n\t}\n\to.StreamID = bd.u64()\n\n\treturn o\n}\n\nfunc (r *Records) parseFork(bd *bufDecoder, hdr *recordHeader, common *RecordCommon) Record {\n\to := &r.recordFork\n\to.RecordCommon = *common\n\to.Format |= SampleFormatTID | SampleFormatTime\n\n\to.PID, o.PPID = int(bd.i32()), int(bd.i32())\n\to.TID, o.PTID = int(bd.i32()), int(bd.i32())\n\to.Time = bd.u64()\n\n\treturn o\n}\n\nfunc (r *Records) parseAux(bd *bufDecoder, hdr *recordHeader, common *RecordCommon) Record {\n\to := &r.recordAux\n\to.RecordCommon = *common\n\n\to.Offset, o.Size = bd.u64(), bd.u64()\n\n\tflags := bd.u64()\n\tformat := (flags & 0xff00) >> 8\n\tflags &^= 0xff00\n\n\to.Flags = AuxFlags(flags)\n\to.PMUFormat = AuxPMUFormat(format)\n\n\treturn o\n}\n\nfunc (r *Records) parseItraceStart(bd *bufDecoder, hdr *recordHeader, common *RecordCommon) Record {\n\to := &RecordItraceStart{RecordCommon: *common}\n\to.Format |= SampleFormatTID\n\to.PID, o.TID = int(bd.i32()), int(bd.i32())\n\treturn o\n}\n\nfunc (r *Records) parseLostSamples(bd *bufDecoder, hdr *recordHeader, common *RecordCommon) Record {\n\to := &RecordLostSamples{RecordCommon: *common}\n\to.Lost = bd.u64()\n\treturn o\n}\n\nfunc (r *Records) parseSwitch(bd *bufDecoder, hdr *recordHeader, common *RecordCommon) Record {\n\to := &r.recordSwitch\n\to.RecordCommon = *common\n\to.Out = hdr.Misc&recordMiscSwitchOut != 0\n\treturn o\n}\n\nfunc (r *Records) parseSwitchCPUWide(bd *bufDecoder, hdr *recordHeader, common *RecordCommon) Record {\n\to := &r.recordSwitchCPUWide\n\to.RecordCommon = *common\n\to.SwitchPID, o.SwitchTID = int(bd.i32()), int(bd.i32())\n\to.Out = hdr.Misc&recordMiscSwitchOut != 0\n\to.Preempt = hdr.Misc&recordMiscSwitchOutPreempt != 0\n\treturn o\n}\n\nfunc (r *Records) parseNamespaces(bd *bufDecoder, hdr *recordHeader, common *RecordCommon) Record {\n\to := &RecordNamespaces{RecordCommon: *common}\n\to.Format |= SampleFormatTID\n\to.PID, o.TID = int(bd.i32()), int(bd.i32())\n\tn := bd.u64()\n\to.Namespaces = make([]Namespace, n)\n\tfor i := range o.Namespaces {\n\t\to.Namespaces[i] = Namespace{bd.u64(), bd.u64()}\n\t}\n\treturn o\n}\n\nfunc (r *Records) parseKsymbol(bd *bufDecoder, hdr *recordHeader, common *RecordCommon) Record {\n\to := &RecordKsymbol{RecordCommon: *common}\n\to.Addr, o.Len = bd.u64(), bd.u32()\n\to.KsymType = KsymbolType(bd.u16())\n\to.Flags = KsymbolFlags(bd.u64())\n\to.Name = bd.cstring()\n\n\treturn o\n}\n\nfunc (r *Records) parseBPFEvent(bd *bufDecoder, hdr *recordHeader, common *RecordCommon) Record {\n\to := &RecordBPFEvent{RecordCommon: *common}\n\to.EventType = BPFEventType(bd.u16())\n\to.Flags = BPFEventFlags(bd.u16())\n\to.ID = bd.u32()\n\to.Tag = bd.u64()\n\n\treturn o\n}\n\nfunc (r *Records) parseCGroup(bd *bufDecoder, hdr *recordHeader, common *RecordCommon) Record {\n\to := &RecordCGroup{RecordCommon: *common}\n\to.ID = bd.u32()\n\to.Path = bd.cstring()\n\n\treturn o\n}\n\nfunc (r *Records) parseTextPoke(bd *bufDecoder, hdr *recordHeader, common *RecordCommon) Record {\n\to := &RecordTextPoke{RecordCommon: *common}\n\to.Addr = bd.u64()\n\n\toldLen, newLen := bd.u16(), bd.u16()\n\n\to.Old = make([]byte, oldLen)\n\tbd.bytes(o.Old)\n\n\to.New = make([]byte, newLen)\n\tbd.bytes(o.New)\n\n\treturn o\n}\n\nfunc (r *Records) parseAuxOutputHardwareID(bd *bufDecoder, hdr *recordHeader, common *RecordCommon) Record {\n\to := &RecordAuxOutputHardwareID{RecordCommon: *common}\n\to.ID = bd.u64()\n\treturn o\n}\n\nfunc (r *Records) parseAuxtraceInfo(bd *bufDecoder, hdr *recordHeader, common *RecordCommon) Record {\n\to := &RecordAuxtraceInfo{RecordCommon: *common}\n\to.Kind = bd.u32()\n\tbd.u32() // Alignment\n\t// TODO: Decode remainder according to Kind\n\to.Priv = make([]uint64, len(bd.buf)/8)\n\tbd.u64s(o.Priv)\n\treturn o\n}\n\nfunc (r *Records) parseAuxtrace(bd *bufDecoder, hdr *recordHeader, common *RecordCommon) Record {\n\to := &RecordAuxtrace{RecordCommon: *common}\n\tsize := bd.u64()\n\to.Offset, o.Ref = bd.u64(), bd.u64()\n\to.Idx, o.TID, o.CPU = bd.u32(), int(bd.u32()), bd.u32()\n\to.Data = make([]byte, size)\n\tif _, err := io.ReadFull(r.sr, o.Data); err != nil {\n\t\tr.err = err\n\t\treturn nil\n\t}\n\treturn o\n}\n\nfunc (r *Records) parseSample(bd *bufDecoder, hdr *recordHeader, common *RecordCommon) Record {\n\to := &r.recordSample\n\to.RecordCommon = *common\n\n\t// Get sample EventAttr ID\n\tif r.f.sampleIDOffset == -1 {\n\t\to.ID = 0\n\t} else {\n\t\to.ID = attrID(bd.order.Uint64(bd.buf[r.f.sampleIDOffset:]))\n\t}\n\to.EventAttr = r.getAttr(o.ID, false)\n\tif o.EventAttr == nil {\n\t\treturn nil\n\t}\n\n\t// Decode hdr.Misc\n\to.CPUMode = CPUMode(hdr.Misc & recordMiscCPUModeMask)\n\to.ExactIP = (hdr.Misc&recordMiscExactIP != 0)\n\n\t// Decode the rest of the sample\n\tt := o.EventAttr.SampleFormat\n\to.Format = t\n\tbd.u64If(t&SampleFormatIdentifier != 0)\n\to.IP = bd.u64If(t&SampleFormatIP != 0)\n\to.PID = int(bd.i32If(t&SampleFormatTID != 0))\n\to.TID = int(bd.i32If(t&SampleFormatTID != 0))\n\to.Time = bd.u64If(t&SampleFormatTime != 0)\n\to.Addr = bd.u64If(t&SampleFormatAddr != 0)\n\tbd.u64If(t&SampleFormatID != 0)\n\to.StreamID = bd.u64If(t&SampleFormatStreamID != 0)\n\to.CPU = bd.u32If(t&SampleFormatCPU != 0)\n\to.Res = bd.u32If(t&SampleFormatCPU != 0)\n\to.Period = bd.u64If(t&SampleFormatPeriod != 0)\n\n\tif t&SampleFormatRead != 0 {\n\t\tr.parseReadFormat(bd, o.EventAttr.ReadFormat, &o.SampleRead)\n\t}\n\n\tif t&SampleFormatCallchain != 0 {\n\t\tcallchainLen := int(bd.u64())\n\t\tif o.Callchain == nil || cap(o.Callchain) < callchainLen {\n\t\t\to.Callchain = make([]uint64, callchainLen)\n\t\t} else {\n\t\t\to.Callchain = o.Callchain[:callchainLen]\n\t\t}\n\t\tbd.u64s(o.Callchain)\n\t} else {\n\t\to.Callchain = nil\n\t}\n\n\trawSize := bd.u32If(t&SampleFormatRaw != 0)\n\tbd.skip(int(rawSize))\n\n\to.BranchHWIndex = bd.i64If(o.EventAttr.BranchSampleType&BranchSampleHWIndex != 0)\n\n\tif t&SampleFormatBranchStack != 0 {\n\t\tcount := int(bd.u64())\n\t\tif o.BranchStack == nil || cap(o.BranchStack) < count {\n\t\t\to.BranchStack = make([]BranchRecord, count)\n\t\t} else {\n\t\t\to.BranchStack = o.BranchStack[:count]\n\t\t}\n\t\tfor i := range o.BranchStack {\n\t\t\tbr := &o.BranchStack[i]\n\t\t\tbr.From = bd.u64()\n\t\t\tbr.To = bd.u64()\n\t\t\tflags := bd.u64()\n\t\t\t// First 4 bits are flags\n\t\t\tbr.Flags = BranchFlags(flags & 0x0f)\n\t\t\t// Next 16 bits are cycles\n\t\t\tbr.Cycles = uint16(flags >> 4)\n\t\t\t// Next 4 bits are type\n\t\t\tbr.Type = BranchType((flags >> 20) & 0x0f)\n\t\t}\n\t}\n\n\tif t&SampleFormatRegsUser != 0 {\n\t\to.RegsUserABI = SampleRegsABI(bd.u64())\n\t\tcount := weight(o.EventAttr.SampleRegsUser)\n\t\tif o.RegsUser == nil || cap(o.RegsUser) < count {\n\t\t\to.RegsUser = make([]uint64, count)\n\t\t} else {\n\t\t\to.RegsUser = o.RegsUser[:count]\n\t\t}\n\t\tif o.RegsUserABI == SampleRegsABINone {\n\t\t\to.RegsUser = o.RegsUser[:0:0]\n\t\t} else {\n\t\t\tbd.u64s(o.RegsUser)\n\t\t}\n\t}\n\n\tif t&SampleFormatStackUser != 0 {\n\t\tsize := int(bd.u64())\n\t\tif o.StackUser == nil || cap(o.StackUser) < size {\n\t\t\to.StackUser = make([]byte, size)\n\t\t} else {\n\t\t\to.StackUser = o.StackUser[:size]\n\t\t}\n\t\tbd.bytes(o.StackUser)\n\t\to.StackUserDynSize = bd.u64()\n\t} else {\n\t\to.StackUser = nil\n\t\to.StackUserDynSize = 0\n\t}\n\n\tif t&SampleFormatWeight != 0 {\n\t\to.Weight = bd.u64()\n\t\to.Weights = Weights{}\n\t} else if t&SampleFormatWeightStruct != 0 {\n\t\t// N.B. the kernel memcpys the 64-bit union value regardless of\n\t\t// format, so on big endian systems the fields appear in the\n\t\t// opposite order. Read as a 64-bit value and extract the\n\t\t// fields to handle both little and big endian.\n\t\tweight := bd.u64()\n\t\to.Weights.Var1 = uint32(weight)\n\t\to.Weights.Var2 = uint16(weight >> 32)\n\t\to.Weights.Var3 = uint16(weight >> 48)\n\t\t// For ease of use, also put Var1 in Weight. If you\n\t\t// only care about one weight, that's the one.\n\t\to.Weight = uint64(o.Weights.Var1)\n\t}\n\n\tif t&SampleFormatDataSrc != 0 {\n\t\to.DataSrc = decodeDataSrc(bd.u64())\n\t}\n\n\ttransaction := bd.u64If(t&SampleFormatTransaction != 0)\n\to.Transaction = Transaction(transaction & 0xffffffff)\n\to.AbortCode = uint32(transaction >> 32)\n\n\tif t&SampleFormatRegsIntr != 0 {\n\t\to.RegsIntrABI = SampleRegsABI(bd.u64())\n\t\tcount := weight(o.EventAttr.SampleRegsIntr)\n\t\tif o.RegsIntr == nil || cap(o.RegsIntr) < count {\n\t\t\to.RegsIntr = make([]uint64, count)\n\t\t} else {\n\t\t\to.RegsIntr = o.RegsIntr[:count]\n\t\t}\n\t\tif o.RegsIntrABI == SampleRegsABINone {\n\t\t\to.RegsIntr = o.RegsIntr[:0:0]\n\t\t} else {\n\t\t\tbd.u64s(o.RegsIntr)\n\t\t}\n\t}\n\n\tif t&SampleFormatPhysAddr != 0 {\n\t\to.PhysAddr = bd.u64()\n\t}\n\n\tif t&SampleFormatCGroup != 0 {\n\t\to.CGroup = bd.u64()\n\t}\n\n\tif t&SampleFormatDataPageSize != 0 {\n\t\to.DataPageSize = bd.u64()\n\t}\n\n\tif t&SampleFormatCodePageSize != 0 {\n\t\to.CodePageSize = bd.u64()\n\t}\n\n\tif t&SampleFormatAux != 0 {\n\t\tauxLen := int(bd.u64())\n\t\tif o.Aux == nil || cap(o.Aux) < auxLen {\n\t\t\to.Aux = make([]byte, auxLen)\n\t\t} else {\n\t\t\to.Aux = o.Aux[:auxLen]\n\t\t}\n\t\tbd.bytes(o.Aux)\n\t} else {\n\t\to.Aux = nil\n\t}\n\n\treturn o\n}\n\nfunc (r *Records) parseReadFormat(bd *bufDecoder, f ReadFormat, out *[]Count) {\n\tn := 1\n\tif f&ReadFormatGroup != 0 {\n\t\tn = int(bd.u64())\n\t}\n\n\tif *out == nil || cap(*out) < n {\n\t\t*out = make([]Count, n)\n\t} else {\n\t\t*out = (*out)[:n]\n\t}\n\n\tif f&ReadFormatGroup == 0 {\n\t\to := &(*out)[0]\n\t\to.Value = bd.u64()\n\t\to.TimeEnabled = bd.u64If(f&ReadFormatTotalTimeEnabled != 0)\n\t\to.TimeRunning = bd.u64If(f&ReadFormatTotalTimeRunning != 0)\n\t\tif f&ReadFormatID != 0 {\n\t\t\to.EventAttr = r.getAttr(attrID(bd.u64()), false)\n\t\t} else {\n\t\t\to.EventAttr = nil\n\t\t}\n\t} else {\n\t\tfor i := range *out {\n\t\t\to := &(*out)[i]\n\t\t\to.TimeEnabled = bd.u64If(f&ReadFormatTotalTimeEnabled != 0)\n\t\t\to.TimeRunning = bd.u64If(f&ReadFormatTotalTimeRunning != 0)\n\t\t\to.Value = bd.u64()\n\t\t\tif f&ReadFormatID != 0 {\n\t\t\t\to.EventAttr = r.getAttr(attrID(bd.u64()), false)\n\t\t\t} else {\n\t\t\t\to.EventAttr = nil\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc decodeDataSrc(d uint64) (out DataSrc) {\n\t// See perf_mem_data_src in include/uapi/linux/perf_event.h\n\top := (d >> 0) & 0x1f\n\tlvl := (d >> 5) & 0x3fff\n\tsnoop := (d >> 19) & 0x1f\n\tlock := (d >> 24) & 0x3\n\tdtlb := (d >> 26) & 0x7f\n\tlevelNum := (d >> 33) & 0xf\n\tremote := (d >> 37) & 0x1\n\tsnoopX := (d >> 38) & 0x3 // two bit extension of snoop\n\tblk := (d >> 40) & 0x7\n\thops := (d >> 43) & 0x7\n\n\tif op&0x1 != 0 {\n\t\tout.Op = DataSrcOpNA\n\t} else {\n\t\tout.Op = DataSrcOp(op >> 1)\n\t}\n\n\tif lvl&0x1 != 0 {\n\t\tout.Miss, out.Level = false, DataSrcLevelNA\n\t} else {\n\t\tout.Miss = (lvl & 0x4) != 0\n\t\tout.Level = DataSrcLevel(lvl >> 3)\n\t}\n\n\tif snoop&0x1 != 0 {\n\t\tout.Snoop = DataSrcSnoopNA\n\t} else {\n\t\tout.Snoop = DataSrcSnoop(snoop >> 1)\n\t\tif snoopX&0x1 != 0 {\n\t\t\tout.Snoop |= DataSrcSnoopFwd\n\t\t}\n\t}\n\n\tif lock&0x1 != 0 {\n\t\tout.Locked = DataSrcLockNA\n\t} else if lock&0x02 != 0 {\n\t\tout.Locked = DataSrcLockLocked\n\t} else {\n\t\tout.Locked = DataSrcLockUnlocked\n\t}\n\n\tif dtlb&0x1 != 0 {\n\t\tout.TLB = DataSrcTLBNA\n\t} else {\n\t\tout.TLB = DataSrcTLB(dtlb >> 1)\n\t}\n\n\tout.LevelNum = DataSrcLevelNum(levelNum)\n\tout.Remote = remote != 0\n\n\tif blk&0x1 != 0 {\n\t\tout.Block = DataSrcBlockNA\n\t} else {\n\t\tout.Block = DataSrcBlock(blk >> 1)\n\t}\n\n\tout.Hops = DataSrcHops(hops)\n\n\treturn\n}\n\nfunc weight(x uint64) int {\n\tx -= (x >> 1) & 0x5555555555555555\n\tx = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333)\n\tx = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f\n\treturn int((x * 0x0101010101010101) >> 56)\n}\n"
  },
  {
    "path": "perffile/recordsorder_string.go",
    "content": "// Code generated by \"stringer -type=RecordsOrder\"; DO NOT EDIT.\n\npackage perffile\n\nimport \"strconv\"\n\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[RecordsFileOrder-0]\n\t_ = x[RecordsCausalOrder-1]\n\t_ = x[RecordsTimeOrder-2]\n}\n\nconst _RecordsOrder_name = \"RecordsFileOrderRecordsCausalOrderRecordsTimeOrder\"\n\nvar _RecordsOrder_index = [...]uint8{0, 16, 34, 50}\n\nfunc (i RecordsOrder) String() string {\n\tif i < 0 || i >= RecordsOrder(len(_RecordsOrder_index)-1) {\n\t\treturn \"RecordsOrder(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n\treturn _RecordsOrder_name[_RecordsOrder_index[i]:_RecordsOrder_index[i+1]]\n}\n"
  },
  {
    "path": "perffile/recordtype_string.go",
    "content": "// Code generated by \"stringer -type=RecordType\"; DO NOT EDIT.\n\npackage perffile\n\nimport \"strconv\"\n\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[RecordTypeMmap-1]\n\t_ = x[RecordTypeLost-2]\n\t_ = x[RecordTypeComm-3]\n\t_ = x[RecordTypeExit-4]\n\t_ = x[RecordTypeThrottle-5]\n\t_ = x[RecordTypeUnthrottle-6]\n\t_ = x[RecordTypeFork-7]\n\t_ = x[RecordTypeRead-8]\n\t_ = x[RecordTypeSample-9]\n\t_ = x[recordTypeMmap2-10]\n\t_ = x[RecordTypeAux-11]\n\t_ = x[RecordTypeItraceStart-12]\n\t_ = x[RecordTypeLostSamples-13]\n\t_ = x[RecordTypeSwitch-14]\n\t_ = x[RecordTypeSwitchCPUWide-15]\n\t_ = x[RecordTypeNamespaces-16]\n\t_ = x[RecordTypeKsymbol-17]\n\t_ = x[RecordTypeBPFEvent-18]\n\t_ = x[RecordTypeCGroup-19]\n\t_ = x[RecordTypeTextPoke-20]\n\t_ = x[RecordTypeAuxOutputHardwareID-21]\n\t_ = x[recordTypeUserStart-64]\n\t_ = x[recordTypeAttr-64]\n\t_ = x[recordTypeEventType-65]\n\t_ = x[recordTypeTracingData-66]\n\t_ = x[recordTypeBuildID-67]\n\t_ = x[recordTypeFinishedRound-68]\n\t_ = x[recordTypeIDIndex-69]\n\t_ = x[RecordTypeAuxtraceInfo-70]\n\t_ = x[RecordTypeAuxtrace-71]\n\t_ = x[RecordTypeAuxtraceError-72]\n\t_ = x[recordTypeThreadMap-73]\n\t_ = x[recordTypeCPUMap-74]\n\t_ = x[recordTypeStatConfig-75]\n\t_ = x[recordTypeStat-76]\n\t_ = x[recordTypeStatRound-77]\n\t_ = x[recordTypeEventUpdate-78]\n\t_ = x[recordTypeTimeConv-79]\n\t_ = x[recordTypeHeaderFeature-80]\n}\n\nconst (\n\t_RecordType_name_0 = \"RecordTypeMmapRecordTypeLostRecordTypeCommRecordTypeExitRecordTypeThrottleRecordTypeUnthrottleRecordTypeForkRecordTypeReadRecordTypeSamplerecordTypeMmap2RecordTypeAuxRecordTypeItraceStartRecordTypeLostSamplesRecordTypeSwitchRecordTypeSwitchCPUWideRecordTypeNamespacesRecordTypeKsymbolRecordTypeBPFEventRecordTypeCGroupRecordTypeTextPokeRecordTypeAuxOutputHardwareID\"\n\t_RecordType_name_1 = \"recordTypeUserStartrecordTypeEventTyperecordTypeTracingDatarecordTypeBuildIDrecordTypeFinishedRoundrecordTypeIDIndexRecordTypeAuxtraceInfoRecordTypeAuxtraceRecordTypeAuxtraceErrorrecordTypeThreadMaprecordTypeCPUMaprecordTypeStatConfigrecordTypeStatrecordTypeStatRoundrecordTypeEventUpdaterecordTypeTimeConvrecordTypeHeaderFeature\"\n)\n\nvar (\n\t_RecordType_index_0 = [...]uint16{0, 14, 28, 42, 56, 74, 94, 108, 122, 138, 153, 166, 187, 208, 224, 247, 267, 284, 302, 318, 336, 365}\n\t_RecordType_index_1 = [...]uint16{0, 19, 38, 59, 76, 99, 116, 138, 156, 179, 198, 214, 234, 248, 267, 288, 306, 329}\n)\n\nfunc (i RecordType) String() string {\n\tswitch {\n\tcase 1 <= i && i <= 21:\n\t\ti -= 1\n\t\treturn _RecordType_name_0[_RecordType_index_0[i]:_RecordType_index_0[i+1]]\n\tcase 64 <= i && i <= 80:\n\t\ti -= 64\n\t\treturn _RecordType_name_1[_RecordType_index_1[i]:_RecordType_index_1[i+1]]\n\tdefault:\n\t\treturn \"RecordType(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n}\n"
  },
  {
    "path": "perffile/sampleformat_string.go",
    "content": "// Code generated by \"bitstringer -type=SampleFormat\"; DO NOT EDIT\n\npackage perffile\n\nimport \"strconv\"\n\nfunc (i SampleFormat) String() string {\n\tif i == 0 {\n\t\treturn \"0\"\n\t}\n\ts := \"\"\n\tif i&SampleFormatAddr != 0 {\n\t\ts += \"Addr|\"\n\t}\n\tif i&SampleFormatAux != 0 {\n\t\ts += \"Aux|\"\n\t}\n\tif i&SampleFormatBranchStack != 0 {\n\t\ts += \"BranchStack|\"\n\t}\n\tif i&SampleFormatCGroup != 0 {\n\t\ts += \"CGroup|\"\n\t}\n\tif i&SampleFormatCPU != 0 {\n\t\ts += \"CPU|\"\n\t}\n\tif i&SampleFormatCallchain != 0 {\n\t\ts += \"Callchain|\"\n\t}\n\tif i&SampleFormatCodePageSize != 0 {\n\t\ts += \"CodePageSize|\"\n\t}\n\tif i&SampleFormatDataPageSize != 0 {\n\t\ts += \"DataPageSize|\"\n\t}\n\tif i&SampleFormatDataSrc != 0 {\n\t\ts += \"DataSrc|\"\n\t}\n\tif i&SampleFormatID != 0 {\n\t\ts += \"ID|\"\n\t}\n\tif i&SampleFormatIP != 0 {\n\t\ts += \"IP|\"\n\t}\n\tif i&SampleFormatIdentifier != 0 {\n\t\ts += \"Identifier|\"\n\t}\n\tif i&SampleFormatPeriod != 0 {\n\t\ts += \"Period|\"\n\t}\n\tif i&SampleFormatPhysAddr != 0 {\n\t\ts += \"PhysAddr|\"\n\t}\n\tif i&SampleFormatRaw != 0 {\n\t\ts += \"Raw|\"\n\t}\n\tif i&SampleFormatRead != 0 {\n\t\ts += \"Read|\"\n\t}\n\tif i&SampleFormatRegsIntr != 0 {\n\t\ts += \"RegsIntr|\"\n\t}\n\tif i&SampleFormatRegsUser != 0 {\n\t\ts += \"RegsUser|\"\n\t}\n\tif i&SampleFormatStackUser != 0 {\n\t\ts += \"StackUser|\"\n\t}\n\tif i&SampleFormatStreamID != 0 {\n\t\ts += \"StreamID|\"\n\t}\n\tif i&SampleFormatTID != 0 {\n\t\ts += \"TID|\"\n\t}\n\tif i&SampleFormatTime != 0 {\n\t\ts += \"Time|\"\n\t}\n\tif i&SampleFormatTransaction != 0 {\n\t\ts += \"Transaction|\"\n\t}\n\tif i&SampleFormatWeight != 0 {\n\t\ts += \"Weight|\"\n\t}\n\tif i&SampleFormatWeightStruct != 0 {\n\t\ts += \"WeightStruct|\"\n\t}\n\ti &^= 33554431\n\tif i == 0 {\n\t\treturn s[:len(s)-1]\n\t}\n\treturn s + \"0x\" + strconv.FormatUint(uint64(i), 16)\n}\n"
  },
  {
    "path": "perffile/sampleregsabi_string.go",
    "content": "// Code generated by \"stringer -type=SampleRegsABI\"; DO NOT EDIT.\n\npackage perffile\n\nimport \"strconv\"\n\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[SampleRegsABINone-0]\n\t_ = x[SampleRegsABI32-1]\n\t_ = x[SampleRegsABI64-2]\n}\n\nconst _SampleRegsABI_name = \"SampleRegsABINoneSampleRegsABI32SampleRegsABI64\"\n\nvar _SampleRegsABI_index = [...]uint8{0, 17, 32, 47}\n\nfunc (i SampleRegsABI) String() string {\n\tif i >= SampleRegsABI(len(_SampleRegsABI_index)-1) {\n\t\treturn \"SampleRegsABI(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n\treturn _SampleRegsABI_name[_SampleRegsABI_index[i]:_SampleRegsABI_index[i+1]]\n}\n"
  },
  {
    "path": "perffile/transaction_string.go",
    "content": "// Code generated by \"bitstringer -type=Transaction\"; DO NOT EDIT\n\npackage perffile\n\nimport \"strconv\"\n\nfunc (i Transaction) String() string {\n\tif i == 0 {\n\t\treturn \"0\"\n\t}\n\ts := \"\"\n\tif i&TransactionAsync != 0 {\n\t\ts += \"Async|\"\n\t}\n\tif i&TransactionCapacityRead != 0 {\n\t\ts += \"CapacityRead|\"\n\t}\n\tif i&TransactionCapacityWrite != 0 {\n\t\ts += \"CapacityWrite|\"\n\t}\n\tif i&TransactionConflict != 0 {\n\t\ts += \"Conflict|\"\n\t}\n\tif i&TransactionElision != 0 {\n\t\ts += \"Elision|\"\n\t}\n\tif i&TransactionRetry != 0 {\n\t\ts += \"Retry|\"\n\t}\n\tif i&TransactionSync != 0 {\n\t\ts += \"Sync|\"\n\t}\n\tif i&TransactionTransaction != 0 {\n\t\ts += \"Transaction|\"\n\t}\n\ti &^= 255\n\tif i == 0 {\n\t\treturn s[:len(s)-1]\n\t}\n\treturn s + \"0x\" + strconv.FormatUint(uint64(i), 16)\n}\n"
  },
  {
    "path": "perfsession/package.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package perfsession provides utilities for tracking session state\n// while processing a perf.data profile.\n//\n// The API of perfsession should be considered unstable at this point.\npackage perfsession // import \"github.com/aclements/go-perf/perfsession\"\n"
  },
  {
    "path": "perfsession/ranges.go",
    "content": "// Copyright 2019 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage perfsession\n\nimport \"sort\"\n\n// Ranges stores data associated with ranges of uint64 values and\n// supports efficient lookup.\ntype Ranges struct {\n\trs     []rangeEnt\n\tsorted bool\n}\n\ntype rangeEnt struct {\n\tlo, hi uint64\n\tval    interface{}\n}\n\n// Add inserts val for range [lo, hi).\n//\n// Add is undefined if [lo, hi) overlaps a range already in r.\nfunc (r *Ranges) Add(lo, hi uint64, val interface{}) {\n\tr.rs = append(r.rs, rangeEnt{lo, hi, val})\n\tr.sorted = false\n}\n\n// Get returns the range and the value for the range containing idx.\nfunc (r *Ranges) Get(idx uint64) (lo, hi uint64, val interface{}, ok bool) {\n\tif r == nil {\n\t\treturn 0, 0, nil, false\n\t}\n\n\trs := r.rs\n\tif !r.sorted {\n\t\tsort.Slice(rs, func(i, j int) bool {\n\t\t\treturn rs[i].lo < rs[j].lo\n\t\t})\n\t\tr.sorted = true\n\t}\n\n\ti := sort.Search(len(rs), func(i int) bool {\n\t\treturn idx < rs[i].hi\n\t})\n\tif i < len(rs) && rs[i].lo <= idx && idx < rs[i].hi {\n\t\treturn rs[i].lo, rs[i].hi, rs[i].val, true\n\t}\n\treturn 0, 0, nil, false\n}\n"
  },
  {
    "path": "perfsession/session.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage perfsession\n\nimport \"github.com/aclements/go-perf/perffile\"\n\n// TODO: Per-TID state.\n\ntype Session struct {\n\tkernel  *PIDInfo\n\tpidInfo map[int]*PIDInfo\n\n\tFile  *perffile.File\n\tExtra map[ExtraKey]interface{}\n}\n\nfunc New(f *perffile.File) *Session {\n\tkernel := &PIDInfo{\n\t\tComm:  \"[kernel]\",\n\t\tExtra: make(ForkableExtra),\n\t}\n\treturn &Session{\n\t\tkernel: kernel,\n\t\tpidInfo: map[int]*PIDInfo{\n\t\t\t// The kernel is implicitly PID -1\n\t\t\t-1: kernel,\n\t\t},\n\t\tFile:  f,\n\t\tExtra: make(map[ExtraKey]interface{}),\n\t}\n}\n\nfunc (s *Session) Update(r perffile.Record) {\n\tensurePID := func(pid int) *PIDInfo {\n\t\tpidInfo, ok := s.pidInfo[pid]\n\t\tif !ok {\n\t\t\tpidInfo = &PIDInfo{\n\t\t\t\tkernel: s.kernel,\n\t\t\t\tExtra:  make(ForkableExtra),\n\t\t\t}\n\t\t\ts.pidInfo[pid] = pidInfo\n\t\t}\n\t\treturn pidInfo\n\t}\n\n\tswitch r := r.(type) {\n\tcase *perffile.RecordComm:\n\t\tensurePID(r.PID).Comm = r.Comm\n\n\tcase *perffile.RecordExit:\n\t\tif r.PID == r.TID {\n\t\t\tdelete(s.pidInfo, r.PID)\n\t\t}\n\t\t// Otherwise this is thread exit\n\n\tcase *perffile.RecordFork:\n\t\tif r.PID == r.TID {\n\t\t\ts.pidInfo[r.PID] = ensurePID(r.PPID).fork(r.PID)\n\t\t}\n\t\t// Otherwise this is thread creation\n\n\tcase *perffile.RecordMmap:\n\t\tinfo := ensurePID(r.PID)\n\t\tinfo.munmap(r.Addr, r.Len)\n\t\tinfo.maps = append(info.maps, &Mmap{make(ForkableExtra), *r})\n\n\tcase *perffile.RecordSample:\n\t\t// Sometimes (particularly early in sample files), we\n\t\t// see kernel samples before the RecordComm.\n\t\tensurePID(r.PID)\n\t}\n}\n\nfunc (s *Session) LookupPID(pid int) *PIDInfo {\n\treturn s.pidInfo[pid]\n}\n\ntype PIDInfo struct {\n\tExtra ForkableExtra\n\n\tComm   string\n\tkernel *PIDInfo\n\tmaps   []*Mmap\n}\n\nfunc (p *PIDInfo) fork(pid int) *PIDInfo {\n\tmaps := make([]*Mmap, len(p.maps))\n\tfor i, mmap := range p.maps {\n\t\tmaps[i] = mmap.fork(pid)\n\t}\n\treturn &PIDInfo{p.Extra.Fork(pid).(ForkableExtra), p.Comm, p.kernel, maps}\n}\n\nfunc (p *PIDInfo) munmap(addr, mlen uint64) {\n\tend := addr + mlen\n\tremoved := false\n\tnmaps := p.maps\n\tfor i, mmap := range p.maps {\n\t\tif addr <= mmap.Addr {\n\t\t\tif end >= mmap.Addr+mmap.Len {\n\t\t\t\tp.maps[i] = nil\n\t\t\t\tremoved = true\n\t\t\t} else if end > mmap.Addr {\n\t\t\t\t// Remove beginning of mmap\n\t\t\t\tmmap.Len -= (end - mmap.Addr)\n\t\t\t\tmmap.Addr = end\n\t\t\t}\n\t\t} else if addr < mmap.Addr+mmap.Len {\n\t\t\tif end >= mmap.Addr+mmap.Len {\n\t\t\t\t// Remove end of mmap\n\t\t\t\tmmap.Len = addr - mmap.Addr\n\t\t\t} else {\n\t\t\t\t// Split mmap in two\n\t\t\t\tnmmap := *mmap\n\t\t\t\tnmmap.Len = end - (mmap.Addr + mmap.Len)\n\t\t\t\tnmaps = append(nmaps, &nmmap)\n\t\t\t\tmmap.Len = addr - mmap.Addr\n\t\t\t}\n\t\t}\n\t}\n\t// Fill holes\n\tif removed {\n\t\td := 0\n\t\tfor s := 0; s < len(nmaps); s++ {\n\t\t\tif nmaps[d] == nil {\n\t\t\t\tnmaps[d] = nmaps[s]\n\t\t\t}\n\t\t\tif nmaps[d] != nil {\n\t\t\t\td++\n\t\t\t}\n\t\t}\n\t\tnmaps = nmaps[:d]\n\t}\n\tp.maps = nmaps\n}\n\nfunc (p *PIDInfo) mapFind(addr uint64) *Mmap {\n\tfor _, mmap := range p.maps {\n\t\tif mmap.Addr <= addr && addr < mmap.Addr+mmap.Len {\n\t\t\treturn mmap\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (p *PIDInfo) LookupMmap(addr uint64) *Mmap {\n\tm := p.mapFind(addr)\n\tif m == nil && p.kernel != nil {\n\t\tm = p.kernel.mapFind(addr)\n\t}\n\treturn m\n}\n\ntype Mmap struct {\n\tExtra ForkableExtra\n\n\tperffile.RecordMmap\n}\n\nfunc (m *Mmap) fork(pid int) *Mmap {\n\treturn &Mmap{m.Extra.Fork(pid).(ForkableExtra), m.RecordMmap}\n}\n\ntype Forkable interface {\n\tFork(pid int) Forkable\n}\n\ntype ExtraKey *struct {\n\tprivate struct{}\n\tName    string\n}\n\nfunc NewExtraKey(name string) ExtraKey {\n\treturn ExtraKey(&struct {\n\t\tprivate struct{}\n\t\tName    string\n\t}{Name: name})\n}\n\ntype ForkableExtra map[ExtraKey]Forkable\n\nfunc (f ForkableExtra) Fork(pid int) Forkable {\n\tf2 := make(ForkableExtra, len(f))\n\tfor k, v := range f {\n\t\tf2[k] = v.Fork(pid)\n\t}\n\treturn f2\n}\n"
  },
  {
    "path": "perfsession/symbolize.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage perfsession\n\nimport (\n\t\"bufio\"\n\t\"debug/dwarf\"\n\t\"debug/elf\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"os\"\n\t\"os/user\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/ianlancetaylor/demangle\"\n)\n\ntype Symbolic struct {\n\tFuncName string\n\tLine     dwarf.LineEntry\n}\n\n// TODO: Take a PID and look up the mmap.\n\nfunc Symbolize(session *Session, mmap *Mmap, ip uint64, out *Symbolic) bool {\n\ts := getSymbolicExtra(session, mmap.Filename)\n\tif s == nil {\n\t\treturn false\n\t}\n\tf, l := s.findIP(mmap, ip)\n\tif f == nil {\n\t\tout.FuncName = \"\"\n\t} else {\n\t\tout.FuncName = f.name\n\t}\n\tif l == nil {\n\t\tout.Line = dwarf.LineEntry{}\n\t} else {\n\t\tout.Line = *l\n\t}\n\treturn true\n}\n\nvar symbolicExtraKey = NewExtraKey(\"perfsession.symbolicExtra\")\n\nvar buildIDDir = (func() string {\n\t// See set_buildid_dir in tools/perf/util/config.c.\n\tu, err := user.Current()\n\tif err != nil {\n\t\treturn \".debug\"\n\t}\n\treturn fmt.Sprintf(\"%s/.debug\", u.HomeDir)\n})()\n\nfunc getSymbolicExtra(session *Session, filename string) *symbolicExtra {\n\tvar err error\n\n\ttables, ok := session.Extra[symbolicExtraKey].(map[string]*symbolicExtra)\n\tif !ok {\n\t\ttables = make(map[string]*symbolicExtra)\n\t\tsession.Extra[symbolicExtraKey] = tables\n\t}\n\n\t// For some reason, the filename for the kernel mapping looks\n\t// like \"[kernel.kallsyms]_text\", but the build ID file name\n\t// is just \"[kernel.kallsyms]\". Match them up.\n\t//\n\t// TODO: There may be a reason the file name is different that\n\t// I don't understand. perf doesn't seem to have any special\n\t// treatment of \"_text\".\n\t//\n\t// TODO: perf works a lot harder to find kernel symbols. See\n\t// dso__find_kallsyms in tools/perf/util/symbol.c.\n\tisKallsyms := false\n\tif strings.HasPrefix(filename, \"[kernel.kallsyms]\") {\n\t\tisKallsyms = true\n\t\tfilename = \"[kernel.kallsyms]\"\n\t}\n\n\textra, ok := tables[filename]\n\tif ok {\n\t\treturn extra\n\t}\n\ttables[filename] = (*symbolicExtra)(nil)\n\n\t// See dso__data_fd in toosl/perf/util/dso.c.\n\n\t// Try build ID cache first.\n\t//\n\t// TODO: Cache filename to build ID mapping.\n\tfor _, bid := range session.File.Meta.BuildIDs {\n\t\tif bid.Filename == filename {\n\t\t\tnfilename := fmt.Sprintf(\"%s/.build-id/%.2s/%s\", buildIDDir, bid.BuildID, bid.BuildID.String()[2:])\n\t\t\tif isKallsyms {\n\t\t\t\textra, err = newKallsyms(nfilename)\n\t\t\t} else {\n\t\t\t\textra, err = newSymbolicExtra(nfilename)\n\t\t\t}\n\t\t\tif err == nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\t// Try original path.\n\tif extra == nil {\n\t\textra, err = newSymbolicExtra(filename)\n\t\tif err != nil {\n\t\t\tlog.Println(err)\n\t\t}\n\t}\n\n\ttables[filename] = extra\n\treturn extra\n}\n\nfunc newSymbolicExtra(filename string) (*symbolicExtra, error) {\n\t// Load ELF\n\telff, err := elf.Open(filename)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error loading ELF file %s: %s\", filename, err)\n\t}\n\tdefer elff.Close()\n\n\textra := &symbolicExtra{}\n\n\t// Load DWARF\n\t//\n\t// TODO: Support build IDs and debug links\n\t//\n\t// TODO: Support DWARF for relocatable objects\n\tif elff.Type == elf.ET_EXEC && (elff.Section(\".debug_info\") != nil || elff.Section(\".zdebug_info\") != nil) {\n\t\tdwarff, err := elff.DWARF()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error loading DWARF from %s: %s\", filename, err)\n\t\t}\n\n\t\textra.functab = dwarfFuncTable(dwarff)\n\t\textra.linetab = dwarfLineTable(dwarff)\n\n\t\treturn &symbolicExtra{\n\t\t\tdwarfFuncTable(dwarff),\n\t\t\tdwarfLineTable(dwarff),\n\t\t\tfalse,\n\t\t}, nil\n\t}\n\n\tif extra.functab == nil {\n\t\t// Make do with the ELF symbols.\n\t\textra.functab, extra.isReloc = elfFuncTable(filename, elff)\n\t}\n\n\treturn extra, nil\n}\n\nvar kallsymsRe = regexp.MustCompile(\"^([0-9a-fA-F]*) +(.) (.*)\")\n\nfunc newKallsyms(filename string) (*symbolicExtra, error) {\n\tf, err := os.Open(filename)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error loading kallsyms from %s: %s\", filename, err)\n\t}\n\tdefer f.Close()\n\n\t// This file is a nm-style object list. See kallsyms__parse in\n\t// tools/lib/symbol/kallsyms.c.\n\tfunctab := make([]funcRange, 0)\n\tscanner := bufio.NewScanner(f)\n\tfor scanner.Scan() {\n\t\tsubs := kallsymsRe.FindStringSubmatch(scanner.Text())\n\t\tif subs == nil {\n\t\t\tcontinue\n\t\t}\n\t\ttyp, name := subs[2][0], subs[3]\n\t\tif !(typ == 't' || typ == 'T') {\n\t\t\tcontinue\n\t\t}\n\t\taddr, _ := strconv.ParseUint(subs[1], 16, 64)\n\t\tfunctab = append(functab, funcRange{name, addr, addr, true})\n\t}\n\tif err := scanner.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tsort.Sort(funcRangeSorter(functab))\n\tsetFuncHighPCs(functab)\n\n\treturn &symbolicExtra{functab, nil, false}, nil\n}\n\ntype symbolicExtra struct {\n\tfunctab []funcRange\n\tlinetab []dwarf.LineEntry\n\n\t// isReloc indicates that lowpc/highpc in functab are ELF file\n\t// offsets rather than virtual addresses.\n\tisReloc bool\n}\n\nfunc (s *symbolicExtra) findIP(mmap *Mmap, ip uint64) (f *funcRange, l *dwarf.LineEntry) {\n\tif s.functab != nil {\n\t\tif s.isReloc {\n\t\t\t// functab is indexed by file offset.\n\t\t\tip = ip - mmap.Addr + mmap.FileOffset\n\t\t}\n\t\ti := sort.Search(len(s.functab), func(i int) bool {\n\t\t\treturn ip < s.functab[i].highpc\n\t\t})\n\t\tif i < len(s.functab) && s.functab[i].lowpc <= ip && ip < s.functab[i].highpc {\n\t\t\tf = &s.functab[i]\n\t\t\tif !f.demangled {\n\t\t\t\tf.name = demangle.Filter(f.name)\n\t\t\t\tf.demangled = true\n\t\t\t}\n\t\t}\n\t}\n\n\tif s.linetab != nil {\n\t\ti := sort.Search(len(s.linetab), func(i int) bool {\n\t\t\treturn ip < s.linetab[i].Address\n\t\t})\n\t\tif i != 0 && !s.linetab[i-1].EndSequence {\n\t\t\tl = &s.linetab[i-1]\n\t\t}\n\t}\n\n\treturn\n}\n\ntype funcRange struct {\n\tname          string\n\tlowpc, highpc uint64\n\tdemangled     bool\n}\n\nfunc dwarfFuncTable(dwarff *dwarf.Data) []funcRange {\n\t// Walk DWARF for functions\n\t// TODO: Use .debug_pubnames (not supported by dwarf package)\n\tr := dwarff.Reader()\n\tout := make([]funcRange, 0)\n\tfor {\n\t\tent, err := r.Next()\n\t\tif ent == nil || err != nil {\n\t\t\tbreak\n\t\t}\n\t\t// TODO: We should process TagInlinedSubroutine, but\n\t\t// apparently gc doesn't produce these.\n\t\t//\n\t\t// TODO: Support DW_AT_ranges.\n\ttag:\n\t\tswitch ent.Tag {\n\t\tcase dwarf.TagSubprogram:\n\t\t\tr.SkipChildren()\n\t\t\tconst AttrLinkageName dwarf.Attr = 0x6e\n\t\t\tname, ok := ent.Val(AttrLinkageName).(string)\n\t\t\tdemangled := true\n\t\t\tif !ok {\n\t\t\t\tname, ok = ent.Val(dwarf.AttrName).(string)\n\t\t\t\tdemangled = false\n\t\t\t\tif !ok {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tlowpc, ok := ent.Val(dwarf.AttrLowpc).(uint64)\n\t\t\tif !ok {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tvar highpc uint64\n\t\t\tswitch highpcx := ent.Val(dwarf.AttrHighpc).(type) {\n\t\t\tcase uint64:\n\t\t\t\thighpc = highpcx\n\t\t\tcase int64:\n\t\t\t\thighpc = lowpc + uint64(highpcx)\n\t\t\tdefault:\n\t\t\t\tbreak tag\n\t\t\t}\n\t\t\tout = append(out, funcRange{name, lowpc, highpc, demangled})\n\n\t\tcase dwarf.TagCompileUnit, dwarf.TagModule, dwarf.TagNamespace:\n\t\t\tbreak\n\n\t\tdefault:\n\t\t\tr.SkipChildren()\n\t\t}\n\t}\n\n\tsort.Sort(funcRangeSorter(out))\n\n\tif len(out) == 0 {\n\t\treturn nil\n\t}\n\treturn out\n}\n\nfunc elfFuncTable(filename string, elff *elf.File) (out []funcRange, isReloc bool) {\n\tswitch elff.Type {\n\tcase elf.ET_EXEC:\n\t\t// Symbol values are virtual addresses.\n\t\tisReloc = false\n\tcase elf.ET_DYN:\n\t\t// Symbol values are section-relative offsets. This\n\t\t// will resolve them to file offsets.\n\t\tisReloc = true\n\tdefault:\n\t\treturn nil, false\n\t}\n\n\tout = make([]funcRange, 0)\n\tsyms, err := elff.Symbols()\n\tif err != nil {\n\t\tif err != elf.ErrNoSymbols {\n\t\t\tlog.Fatalf(\"%s: %s\", filename, err)\n\t\t}\n\t\treturn nil, false\n\t}\n\tfor _, sym := range syms {\n\t\tif elf.SymType(sym.Info&0xF) != elf.STT_FUNC || sym.Section == elf.SHN_UNDEF {\n\t\t\tcontinue\n\t\t}\n\t\tlowpc := sym.Value\n\t\tif isReloc {\n\t\t\t// lowpc is a section-relative offset.\n\t\t\t// Translate it to a file offset.\n\t\t\tif int(sym.Section) >= len(elff.Sections) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tsec := elff.Sections[sym.Section]\n\t\t\tlowpc = lowpc - sec.Addr + sec.Offset\n\t\t}\n\t\tout = append(out, funcRange{sym.Name, lowpc, lowpc + sym.Size, false})\n\t}\n\n\tsort.Sort(funcRangeSorter(out))\n\tsetFuncHighPCs(out)\n\n\treturn\n}\n\ntype funcRangeSorter []funcRange\n\nfunc (s funcRangeSorter) Len() int {\n\treturn len(s)\n}\n\nfunc (s funcRangeSorter) Swap(i, j int) {\n\ts[i], s[j] = s[j], s[i]\n}\n\nfunc (s funcRangeSorter) Less(i, j int) bool {\n\treturn s[i].lowpc < s[j].lowpc\n}\n\n// setFuncHighPCs fills in missing highpc values in functab. functab\n// must be sorted.\nfunc setFuncHighPCs(functab []funcRange) {\n\t// Assign symbols highpcs if they don't have them.\n\tfor i := range functab {\n\t\tif functab[i].highpc == functab[i].lowpc {\n\t\t\tif i == len(functab)-1 {\n\t\t\t\tfunctab[i].highpc++\n\t\t\t} else {\n\t\t\t\tfunctab[i].highpc = functab[i+1].lowpc\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc dwarfLineTable(dwarff *dwarf.Data) []dwarf.LineEntry {\n\tout := make([]dwarf.LineEntry, 0)\n\n\t// Iterate over compilation units\n\tdr := dwarff.Reader()\n\tfor {\n\t\tent, err := dr.Next()\n\t\tif ent == nil || err != nil {\n\t\t\tbreak\n\t\t}\n\n\t\tif ent.Tag != dwarf.TagCompileUnit {\n\t\t\tdr.SkipChildren()\n\t\t\tcontinue\n\t\t}\n\n\t\t// Decode CU's line table\n\t\tlr, err := dwarff.LineReader(ent)\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t} else if lr == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tfor {\n\t\t\tvar lent dwarf.LineEntry\n\t\t\terr := lr.Next(&lent)\n\t\t\tif err != nil {\n\t\t\t\tif err == io.EOF {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tlog.Fatal(err)\n\t\t\t}\n\t\t\tout = append(out, lent)\n\t\t}\n\t}\n\n\tsort.Slice(out, func(i, j int) bool {\n\t\treturn out[i].Address < out[j].Address\n\t})\n\n\treturn out\n}\n"
  },
  {
    "path": "scale/interface.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage scale\n\n// A scale satisfies Interface if it maps from some input range to an\n// output interval [0, 1].\ntype Interface interface {\n\tOf(x float64) float64\n\tTicks(n int) (major, minor []float64)\n}\n"
  },
  {
    "path": "scale/linear.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage scale\n\ntype Linear struct {\n\tmin, width float64\n}\n\n// NewLinear returns a new linear scale.\nfunc NewLinear(input []float64) Linear {\n\tmin, max := minmax(input)\n\treturn Linear{min, max - min}\n}\n\nfunc (s Linear) Of(x float64) float64 {\n\treturn (x - s.min) / s.width\n}\n\nfunc (s Linear) Ticks(n int) (major, minor []float64) {\n\tmajor, minor = make([]float64, n), []float64{}\n\n\t// TODO: Pick good ticks\n\n\tfor i := range major {\n\t\tmajor[i] = float64(i)*s.width/float64(n) + s.min\n\t}\n\n\treturn\n}\n"
  },
  {
    "path": "scale/log.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage scale\n\nimport \"math\"\n\ntype Log struct {\n\tmin, max, base float64\n\tlogMin, denom  float64\n}\n\n// NewLog returns a new logarithmic scale.\n//\n// base has no effect on the scaling.  It is only used for computing\n// tick marks.\nfunc NewLog(input []float64, base float64) *Log {\n\tmin, max := minmax(input)\n\ts := &Log{min: min, max: max, base: base}\n\ts.precompute()\n\treturn s\n}\n\nfunc (s *Log) precompute() {\n\ts.logMin = math.Log(s.min)\n\ts.denom = math.Log(s.max) - s.logMin\n}\n\nfunc (s *Log) Of(x float64) float64 {\n\treturn (math.Log(x) - s.logMin) / s.denom\n}\n\n// Nice expands the domain of s to \"nice\" values of the scale, which\n// will translate into major tick marks.\n//\n// n is the maximum number of major ticks.  n must be >= 2.\nfunc (s *Log) Nice(n int) {\n\tif n < 2 {\n\t\tpanic(\"n must be >= 2\")\n\t}\n\n\t// Increase the effective base until there are <= n major ticks\n\tfor ebase := s.base; ; ebase *= s.base {\n\t\t// TODO: Allow for some round-off error\n\n\t\t// Compute major tick below s.min and above s.max\n\t\tlo := math.Pow(ebase, math.Floor(math.Log(s.min)/math.Log(ebase)))\n\t\thi := math.Pow(ebase, math.Ceil(math.Log(s.max)/math.Log(ebase)))\n\n\t\t// Compute number of ticks between lo and hi\n\t\tnticks := 1 + (math.Log(hi)-math.Log(lo))/math.Log(ebase)\n\n\t\tif nticks <= float64(n) {\n\t\t\t// Found it\n\t\t\ts.min, s.max = lo, hi\n\t\t\ts.precompute()\n\t\t\tbreak\n\t\t}\n\t}\n}\n\nfunc (s *Log) Ticks(n int) (major, minor []float64) {\n\tif n < 2 {\n\t\tpanic(\"n must be >= 2\")\n\t}\n\n\tmajor, minor = []float64{}, []float64{}\n\n\t// Increase the effective base until there are <= n major ticks\n\tebase := s.base\n\tfor ; ; ebase *= s.base {\n\t\t// Compute number of ticks between lo and hi\n\t\tnticks := 1 + (math.Log(s.max)-math.Log(s.min))/math.Log(ebase)\n\n\t\tif nticks <= float64(n) {\n\t\t\t// Found it\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Start at the major tick below s.min\n\tx := math.Pow(ebase, math.Floor(math.Log(s.min)/math.Log(ebase)))\n\tfor x <= s.max {\n\t\tfor step := 0.0; step < ebase; step += ebase / s.base {\n\t\t\tx2 := x + step*x\n\t\t\tif x2 < s.min {\n\t\t\t\tcontinue\n\t\t\t} else if x2 > s.max {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif step == 0 {\n\t\t\t\tmajor = append(major, x2)\n\t\t\t} else {\n\t\t\t\tminor = append(minor, x2)\n\t\t\t}\n\t\t}\n\n\t\tx *= ebase\n\t}\n\n\treturn\n}\n"
  },
  {
    "path": "scale/output.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage scale\n\ntype OutputScale struct {\n\tmin, max float64\n\tclamp    int\n}\n\nconst (\n\tclampCrop = iota\n\tclampNone\n\tclampClamp\n)\n\nfunc NewOutputScale(min, max float64) OutputScale {\n\treturn OutputScale{min, max, clampCrop}\n}\n\nfunc (s *OutputScale) Crop() {\n\ts.clamp = clampCrop\n}\n\nfunc (s *OutputScale) Unclamp() {\n\ts.clamp = clampNone\n}\n\nfunc (s *OutputScale) Clamp() {\n\ts.clamp = clampClamp\n}\n\nfunc (s OutputScale) Of(x float64) (float64, bool) {\n\tif s.clamp == clampCrop {\n\t\tif x < 0 || x > 1 {\n\t\t\treturn 0, false\n\t\t}\n\t} else if s.clamp == clampClamp {\n\t\tif x < 0 {\n\t\t\tx = 0\n\t\t} else if x > 1 {\n\t\t\tx = 1\n\t\t}\n\t}\n\treturn x*(s.max-s.min) + s.min, true\n}\n"
  },
  {
    "path": "scale/power.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage scale\n\nimport \"math\"\n\ntype Power struct {\n\tlin Linear\n\texp float64\n}\n\n// NewPower returns a new power scale.\nfunc NewPower(input []float64, exp float64) Power {\n\treturn Power{NewLinear(input), exp}\n}\n\nfunc (s Power) Of(x float64) float64 {\n\treturn math.Pow(s.lin.Of(x), s.exp)\n}\n\nfunc (s Power) Ticks(n int) (major, minor []float64) {\n\treturn s.lin.Ticks(n)\n}\n"
  },
  {
    "path": "scale/util.go",
    "content": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage scale\n\nfunc minmax(xs []float64) (min float64, max float64) {\n\tmin, max = xs[0], xs[0]\n\tfor _, x := range xs {\n\t\tif x < min {\n\t\t\tmin = x\n\t\t}\n\t\tif x > max {\n\t\t\tmax = x\n\t\t}\n\t}\n\treturn\n}\n"
  },
  {
    "path": "scripts/membw",
    "content": "#!/bin/zsh\n\n# Measure read/write memory bandwidth at memory controllers.\n#\n# Based on \"Intel® Xeon® Processor E5 v2 and E7 v2 Product Families\n# Uncore Performance Monitoring Reference Manual\".\n\nset -e\n\nfamily=$(grep '^cpu family' /proc/cpuinfo | awk '{print $4; exit}')\nmodel=$(grep '^model' /proc/cpuinfo | awk '{print $3; exit}')\nfm=$(printf \"%02x\" $family)_$(printf \"%02x\" $model)\n\n# TODO: This works for all E5 v2 and E7 v2. There are probably other\n# CPUIDs that apply.\nif [[ $fm != 06_3e ]]; then\n    echo \"Unsupported family/model $fm\" >&2\n    exit 1\nfi\n\n# Get iMC uncore boxes. In the E5 v2 there are four.\nimcs=($(cd -q /sys/bus/event_source/devices/; echo uncore_imc_*))\n\n# Construct the event list.\nevents=()\nfor imc in $imcs; do\n    events=($events -e $imc/event=0x04,umask=0x03/ -e $imc/event=0x04,umask=0x0c/)\ndone\n\n# Uncore events must be monitored system-wide.\noutput=$(perf stat -a $events $* 2>&1)\necho $output\n\necho $output | awk '\n/uncore_imc_.*umask=0x03/ {read += $1}\n/uncore_imc_.*umask=0x0c/ {write += $1}\n/time elapsed/ {time = $1}\nEND {\n    print (64 * read / time / 1024 / 1024) \" MiB read per second\"\n    print (64 * write / time / 1024 / 1024) \" MiB written per second\"\n}'\n"
  },
  {
    "path": "scripts/memload.py",
    "content": "#!/usr/bin/python3\n\nimport os\nimport sys\nimport subprocess\nimport operator\n\ndef gather(counters):\n    counters = list(frozenset(counters))\n    r, w = os.pipe()\n    args = [\"ocperf.py\", \"stat\", \"-x;\", \"--log-fd\", str(w)]\n    for counter in counters:\n        args.extend([\"-e\", counter])\n    args.extend(sys.argv[1:])\n    perf = subprocess.Popen(args, pass_fds=[w])\n    os.close(w)\n    r = os.fdopen(r)\n    output = r.read()\n    r.close()\n    res = perf.wait()\n    if res:\n        sys.exit(res)\n\n    #print(output, file=sys.stderr) # Debugging\n\n    # Parse output. Annoyingly, column 3 is the names, but ocperf\n    # generated names trim off modifiers, so we can't distinguish\n    # cmasks and such. Hence, we just match them up by order.\n    cmap = {}\n    for line in output.splitlines():\n        line = line.split(\"#\", 1)[0].strip()\n        if not line:\n            continue\n        row = line.split(\";\")\n\n        # TODO: What's column 2? Column 3 is name. Column 4 is run\n        # time of the counter. Column 5 is fraction of time counter\n        # was running.\n        cmap[counters[len(cmap)]] = int(row[0])\n\n    return cmap\n\ndef cpu_family_model():\n    family = model = None\n    for l in open(\"/proc/cpuinfo\").readlines():\n        if l.startswith(\"cpu family\\t\"):\n            family = int(l.split(\":\")[1])\n        if l.startswith(\"model\\t\"):\n            model = int(l.split(\":\")[1])\n        if family != None and model != None:\n            return family, model\n    print(\"failed to get CPU family and model from /proc/cpuinfo\",\n          file=sys.stderr)\n    sys.exit(1)\n\ndef main():\n    # Only Ivy Bridge for now.\n    family, model = cpu_family_model()\n    if (family, model) not in [(0x06, 0x3a), (0x06, 0x3e)]:\n        print(\"unsupported CPU model %02x_%02xH\" % (family, model),\n              file=sys.stderr)\n        sys.exit(1)\n\n    events = [\"OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD:cmask=%d\" % cmask\n              for cmask in range(1, 18)]\n    ctx = gather([\"CPU_CLK_UNHALTED.THREAD\"] + events)\n\n    # Print PDF\n    clocks = ctx[\"CPU_CLK_UNHALTED.THREAD\"]\n    for i, (ev1, ev2) in enumerate(zip(events, events[1:])):\n        print(i + 1, 100 * (ctx[ev1] - ctx[ev2]) / clocks)\n\n    if ctx[events[-1]] != 0:\n        print(\"Warning: Highest cmask has non-zero event count %d\" % ctx[events[-1]],\n              file=sys.stderr)\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "scripts/topdown.py",
    "content": "#!/usr/bin/python3\n\nimport os\nimport sys\nimport subprocess\nimport operator\n\n# TODO: Improve the quality of computed metrics using event groups.\n\ndef gather(counters):\n    counters = list(frozenset(counters))\n    r, w = os.pipe()\n    args = [\"ocperf.py\", \"stat\", \"-x;\", \"--log-fd\", str(w)]\n    for counter in counters:\n        args.extend([\"-e\", counter])\n    args.extend(sys.argv[1:])\n    perf = subprocess.Popen(args, pass_fds=[w])\n    os.close(w)\n    r = os.fdopen(r)\n    output = r.read()\n    r.close()\n    res = perf.wait()\n    if res:\n        sys.exit(res)\n\n    #print(output, file=sys.stderr) # Debugging\n\n    # Parse output. Annoyingly, column 3 is the names, but ocperf\n    # generated names trim off modifiers, so we can't distinguish\n    # cmasks and such. Hence, we just match them up by order.\n    cmap = {}\n    for line in output.splitlines():\n        line = line.split(\"#\", 1)[0].strip()\n        if not line:\n            continue\n        row = line.split(\";\")\n\n        # TODO: What's column 2? Column 3 is name. Column 4 is run\n        # time of the counter. Column 5 is fraction of time counter\n        # was running.\n        cmap[counters[len(cmap)]] = int(row[0])\n\n    return cmap\n\nclass Formula:\n    def __init__(self, children):\n        self.children = children\n\n    def eval(self, ctx):\n        raise NotImplementedError(\"eval is abstract\")\n\n    def events(self):\n        raise NotImplementedError(\"events is abstract\")\n\n    def __add__(self, o):\n        return FormulaOp(operator.add, self, o)\n\n    def __radd__(self, o):\n        return FormulaOp(operator.add, o, self)\n\n    def __sub__(self, o):\n        return FormulaOp(operator.sub, self, o)\n\n    def __rsub__(self, o):\n        return FormulaOp(operator.sub, o, self)\n\n    def __mul__(self, o):\n        return FormulaOp(operator.mul, self, o)\n\n    def __rmul__(self, o):\n        return FormulaOp(operator.mul, o, self)\n\n    def __truediv__(self, o):\n        return FormulaOp(operator.truediv, self, o)\n\n    def __rtruediv__(self, o):\n        return FormulaOp(operator.truediv, o, self)\n\nclass FormulaOp(Formula):\n    def __init__(self, op, *args):\n        super().__init__(args)\n        self.op = op\n\n    def eval(self, ctx):\n        args = [c.eval(ctx) if isinstance(c, Formula) else c\n                for c in self.children]\n        return self.op(*args)\n\n    def events(self):\n        events = []\n        for child in self.children:\n            if isinstance(child, Formula):\n                events.extend(child.events())\n        return events\n\nclass E(Formula):\n    def __init__(self, event):\n        super().__init__([])\n        self.event = event\n\n    def eval(self, ctx):\n        return ctx[self.event]\n\n    def events(self):\n        return [self.event]\n\n# Top-Down bottleneck formulas. These are mostly from Yasin 2014, \"A\n# Top-Down Method for Performance Analysis and Counters Architecture\"\n# with some more detailed metrics from pmu-tools' toplev.py.\n\nclocks = E(\"CPU_CLK_UNHALTED.THREAD\")\nissueWidth = 4\nslots = issueWidth * clocks\n\nfrontendBound = E(\"IDQ_UOPS_NOT_DELIVERED.CORE\") / slots\nfetchLatencyBound = E(\"IDQ_UOPS_NOT_DELIVERED.CORE:cmask=4\") / clocks\nfetchBandwidthBound = frontendBound - fetchLatencyBound\n\n# Fetch bandwidth breakdown from toplev.py. NOTE: These are just\n# fractions of all cycles. They don't add up to fetchBandwidthBound,\n# since they're not gated on the front end being bottlenecked.\nfe_MITE = (E(\"IDQ.ALL_MITE_CYCLES_ANY_UOPS\") - E(\"IDQ.ALL_MITE_CYCLES_4_UOPS\")) / clocks\nfe_DSB = (E(\"IDQ.ALL_DSB_CYCLES_ANY_UOPS\") - E(\"IDQ.ALL_DSB_CYCLES_4_UOPS\")) / clocks\nfe_LSD = (E(\"LSD.CYCLES_ACTIVE\") - E(\"LSD.CYCLES_4_UOPS\")) / clocks\n\nbadSpeculation = (E(\"UOPS_ISSUED.ANY\") - E(\"UOPS_RETIRED.RETIRE_SLOTS\") + 4 * E(\"INT_MISC.RECOVERY_CYCLES\")) / slots\n\nretiring = E(\"UOPS_RETIRED.RETIRE_SLOTS\") / slots\n\nmemoryBound = (E(\"CYCLE_ACTIVITY.STALLS_MEM_ANY\") + E(\"RESOURCE_STALLS.SB\")) / clocks\nnumExecutionStalls = (E(\"CYCLE_ACTIVITY.CYCLES_NO_EXECUTE\") - E(\"RS_EVENTS.EMPTY_CYCLES\") + E(\"UOPS_EXECUTED.THREAD:cmask=1\") - E(\"UOPS_EXECUTED.THREAD:cmask=2\")) / clocks\ncoreBound = numExecutionStalls - memoryBound\n\n# See https://software.intel.com/en-us/node/544440 for detailed\n# explanations of L1 bound reasons.\nl1Bound = (E(\"CYCLE_ACTIVITY.STALLS_MEM_ANY\") - E(\"CYCLE_ACTIVITY.STALLS_L1D_MISS\")) / clocks\nl1_STLBHitCost = 7\nl1_DTLBMiss = (l1_STLBHitCost * E(\"DTLB_LOAD_MISSES.STLB_HIT\") + E(\"DTLB_LOAD_MISSES.WALK_DURATION\")) / clocks\nl1_SFBCost = 13\nl1_StoreForwardBlocked = l1_SFBCost * E(\"LD_BLOCKS.STORE_FORWARD\") / clocks\nl1_LockStoreFraction = E(\"MEM_UOPS_RETIRED.LOCK_LOADS\") / E(\"MEM_UOPS_RETIRED.ALL_STORES\")\noroDemandRFOC1 = FormulaOp(min, E(\"CPU_CLK_UNHALTED.THREAD\"), E(\"OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_RFO\"))\nl1_LockLatency = l1_LockStoreFraction * oroDemandRFOC1 / clocks\n# Load spans two cache lines.\nl1_SplitLoads = 13 * E(\"LD_BLOCKS.NO_SR\") / clocks\n# Earlier load conflicts with later store on bottom 12 bits.\nl1_4KAliasCost = 7\nl1_4KAliasing = (l1_4KAliasCost * E(\"LD_BLOCKS_PARTIAL.ADDRESS_ALIAS\")) / clocks\n# L1D fill buffer limits further demand loads.\nl1_LoadMissRealLatency = E(\"L1D_PEND_MISS.PENDING\") / (E(\"MEM_LOAD_UOPS_RETIRED.L1_MISS\") + E(\"MEM_LOAD_UOPS_RETIRED.HIT_LFB\"))\nl1_FBFull = l1_LoadMissRealLatency * E(\"L1D_PEND_MISS.FB_FULL:cmask=1\") / clocks\n\nl2Bound = (E(\"CYCLE_ACTIVITY.STALLS_L1D_MISS\") - E(\"CYCLE_ACTIVITY.STALLS_L2_MISS\")) / clocks\n# toplev.py gives the following alternate formula, but the results\n# don't seem any different.\n#l2Bound = (E(\"CYCLE_ACTIVITY.STALLS_L1D_PENDING\") - E(\"CYCLE_ACTIVITY.STALLS_L2_PENDING\")) / clocks\nl3HitFraction = E(\"MEM_LOAD_UOPS_RETIRED.LLC_HIT\") / (E(\"MEM_LOAD_UOPS_RETIRED.LLC_HIT\") + 7*E(\"MEM_LOAD_UOPS_RETIRED.LLC_MISS\"))\nl3Bound = l3HitFraction * E(\"CYCLE_ACTIVITY.STALLS_L2_MISS\") / clocks\nextMemoryBound = (1 - l3HitFraction) * E(\"CYCLE_ACTIVITY.STALLS_L2_MISS\") / clocks\n\n# These formulas come from toplev.py. They're very different from the\n# Yasin paper, but are based on the same idea, and don't depend on\n# undocumented uncore counters.\nextMem_BandwidthBound = E(\"OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD:cmask=6\") / clocks\nextMem_LatencyBound = (E(\"OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_DATA_RD\") - E(\"OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD:cmask=6\")) / clocks\n\nclass Node:\n    def __init__(self, label, value, *children):\n        self.label, self.value, self.children = label, value, children\n\n    def events(self):\n        counters = []\n        if self.value is not None:\n            counters.extend(self.value.events())\n        for child in self.children:\n            counters.extend(child.events())\n        return counters\n\n    def eval(self, ctx):\n        if self.value is None:\n            return sum(child.eval(ctx) for child in self.children)\n        return self.value.eval(ctx)\n\n    def show(self, ctx, indent=0):\n        value = self.eval(ctx)\n        print(\"%-30s %6.2f%%\" % (\"  \" * indent + self.label, 100*value))\n        for child in self.children:\n            child.show(ctx, indent+1)\n\ntree = Node(\"All slots\", None,\n            Node(\"µop issued\", None,\n                 Node(\"Retires\", retiring),\n                 Node(\"Bad speculation\", badSpeculation)),\n            Node(\"No µop issued\", None,\n                 Node(\"Front end bound\", frontendBound,\n                      Node(\"Fetch latency bound\", fetchLatencyBound),\n                      Node(\"Fetch bandwidth bound\", fetchBandwidthBound,\n                           Node(\"MITE *\", fe_MITE),\n                           Node(\"DSB *\", fe_DSB),\n                           Node(\"LSD *\", fe_LSD))),\n                 Node(\"Back end bound\", None,\n                      Node(\"Core bound\", coreBound),\n                      Node(\"Memory bound\", memoryBound,\n                           Node(\"L1 bound\", l1Bound,\n                                Node(\"DTLB load miss\", l1_DTLBMiss),\n                                Node(\"Load blocked by store forwarding\", l1_StoreForwardBlocked),\n                                Node(\"Lock latency\", l1_LockLatency),\n                                Node(\"Split loads\", l1_SplitLoads),\n                                Node(\"4K aliasing\", l1_4KAliasing),\n                                Node(\"Fill buffer full\", l1_FBFull)),\n                           Node(\"L2 bound\", l2Bound),\n                           Node(\"L3 bound\", l3Bound),\n                           Node(\"Ext mem bound\", extMemoryBound,\n                                Node(\"Bandwidth *\", extMem_BandwidthBound),\n                                Node(\"Latency *\", extMem_LatencyBound))))))\n\ndef cpu_family_model():\n    family = model = None\n    for l in open(\"/proc/cpuinfo\").readlines():\n        if l.startswith(\"cpu family\\t\"):\n            family = int(l.split(\":\")[1])\n        if l.startswith(\"model\\t\"):\n            model = int(l.split(\":\")[1])\n        if family != None and model != None:\n            return family, model\n    print(\"failed to get CPU family and model from /proc/cpuinfo\",\n          file=sys.stderr)\n    sys.exit(1)\n\ndef main():\n    # Only Ivy Bridge for now.\n    family, model = cpu_family_model()\n    if (family, model) not in [(0x06, 0x3a), (0x06, 0x3e)]:\n        print(\"unsupported CPU model %02x_%02xH\" % (family, model),\n              file=sys.stderr)\n        sys.exit(1)\n\n    events = tree.events()\n    ctx = gather(events)\n    tree.show(ctx)\n\nif __name__ == \"__main__\":\n    main()\n"
  }
]