From 27ced96c8d4709eeb57aa5dde31acff7e51a8a4a Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Mon, 15 Aug 2022 17:46:59 -0400 Subject: [PATCH] [release-branch.go1.18] all: upgrade github.com/google/pprof to v0.0.0-20220729232143-a41b82acbcb1 Update the vendored copy of github.com/google/pprof to include the fix for #54105. pprof's go.mod specifies an upgrade to x/sys, thus we must also update std's x/sys to match this version. For #54105. Fixes #54464. Change-Id: I0ca4f338b3ec3e8c54a892eb684a5dd3af8d7f1b Reviewed-on: https://go-review.googlesource.com/c/go/+/423576 TryBot-Result: Gopher Robot Reviewed-by: Dmitri Shuralyov Reviewed-by: Dmitri Shuralyov Run-TryBot: Michael Pratt --- src/cmd/go.mod | 6 +- src/cmd/go.sum | 16 +- src/cmd/pprof/pprof.go | 2 +- .../github.com/google/pprof/driver/driver.go | 10 +- .../pprof/internal/binutils/binutils.go | 38 +- .../google/pprof/internal/driver/cli.go | 2 +- .../google/pprof/internal/driver/fetch.go | 6 +- .../pprof/internal/driver/html/common.css | 272 + .../pprof/internal/driver/html/common.js | 693 +++ .../internal/driver/html/flamegraph.html | 103 + .../pprof/internal/driver/html/graph.html | 16 + .../pprof/internal/driver/html/header.html | 113 + .../pprof/internal/driver/html/plaintext.html | 18 + .../pprof/internal/driver/html/source.html | 18 + .../pprof/internal/driver/html/top.html | 114 + .../google/pprof/internal/driver/settings.go | 8 +- .../google/pprof/internal/driver/tagroot.go | 11 +- .../google/pprof/internal/driver/webhtml.go | 1432 +---- .../google/pprof/internal/elfexec/elfexec.go | 6 +- .../google/pprof/internal/graph/dotgraph.go | 7 +- .../pprof/internal/measurement/measurement.go | 37 +- .../google/pprof/internal/plugin/plugin.go | 6 +- .../google/pprof/internal/report/report.go | 2 +- .../google/pprof/internal/report/source.go | 2 +- .../pprof/internal/symbolizer/symbolizer.go | 66 +- .../github.com/google/pprof/profile/encode.go | 9 + .../google/pprof/profile/legacy_profile.go | 30 +- .../github.com/google/pprof/profile/merge.go | 21 +- .../google/pprof/profile/profile.go | 9 + .../google/pprof/third_party/d3/LICENSE | 27 - .../google/pprof/third_party/d3/README.md | 119 - .../google/pprof/third_party/d3/d3.go | 4675 ----------------- .../{LICENSE => D3_FLAME_GRAPH_LICENSE} | 0 .../pprof/third_party/d3flamegraph/D3_LICENSE | 13 + .../pprof/third_party/d3flamegraph/README.md | 33 + .../d3flamegraph/d3_flame_graph.go | 976 +--- .../pprof/third_party/d3flamegraph/index.js | 13 + .../d3flamegraph/package-lock.json | 1106 ++++ .../third_party/d3flamegraph/package.json | 17 + .../pprof/third_party/d3flamegraph/update.sh | 62 + .../d3flamegraph/webpack.config.js | 13 + .../github.com/ianlancetaylor/demangle/ast.go | 52 +- .../ianlancetaylor/demangle/demangle.go | 544 +- .../ianlancetaylor/demangle/rust.go | 190 +- .../golang.org/x/sys/plan9/syscall_plan9.go | 6 +- .../golang.org/x/sys/unix/ioctl_linux.go | 23 + .../vendor/golang.org/x/sys/unix/mkerrors.sh | 6 + .../golang.org/x/sys/unix/syscall_aix.go | 6 +- .../golang.org/x/sys/unix/syscall_darwin.go | 6 +- .../x/sys/unix/syscall_dragonfly.go | 10 +- .../golang.org/x/sys/unix/syscall_freebsd.go | 6 +- .../golang.org/x/sys/unix/syscall_linux.go | 62 +- .../x/sys/unix/syscall_linux_386.go | 8 - .../x/sys/unix/syscall_linux_alarm.go | 14 + .../x/sys/unix/syscall_linux_amd64.go | 1 - .../x/sys/unix/syscall_linux_arm.go | 1 - .../x/sys/unix/syscall_linux_arm64.go | 1 - .../x/sys/unix/syscall_linux_mips64x.go | 1 - .../x/sys/unix/syscall_linux_mipsx.go | 1 - .../x/sys/unix/syscall_linux_ppc.go | 1 - .../x/sys/unix/syscall_linux_ppc64x.go | 1 - .../x/sys/unix/syscall_linux_riscv64.go | 1 - .../x/sys/unix/syscall_linux_s390x.go | 9 - .../x/sys/unix/syscall_linux_sparc64.go | 1 - .../golang.org/x/sys/unix/syscall_netbsd.go | 14 +- .../golang.org/x/sys/unix/syscall_openbsd.go | 6 +- .../golang.org/x/sys/unix/syscall_solaris.go | 12 +- .../x/sys/unix/syscall_zos_s390x.go | 6 +- .../golang.org/x/sys/unix/zerrors_linux.go | 53 +- .../x/sys/unix/zerrors_linux_386.go | 3 + .../x/sys/unix/zerrors_linux_amd64.go | 3 + .../x/sys/unix/zerrors_linux_arm.go | 3 + .../x/sys/unix/zerrors_linux_arm64.go | 3 + .../x/sys/unix/zerrors_linux_mips.go | 3 + .../x/sys/unix/zerrors_linux_mips64.go | 3 + .../x/sys/unix/zerrors_linux_mips64le.go | 3 + .../x/sys/unix/zerrors_linux_mipsle.go | 3 + .../x/sys/unix/zerrors_linux_ppc.go | 3 + .../x/sys/unix/zerrors_linux_ppc64.go | 3 + .../x/sys/unix/zerrors_linux_ppc64le.go | 3 + .../x/sys/unix/zerrors_linux_riscv64.go | 3 + .../x/sys/unix/zerrors_linux_s390x.go | 3 + .../x/sys/unix/zerrors_linux_sparc64.go | 3 + .../golang.org/x/sys/unix/zsyscall_linux.go | 20 + .../x/sys/unix/zsyscall_linux_386.go | 13 +- .../x/sys/unix/zsyscall_linux_amd64.go | 24 +- .../x/sys/unix/zsyscall_linux_arm.go | 11 - .../x/sys/unix/zsyscall_linux_arm64.go | 11 - .../x/sys/unix/zsyscall_linux_mips.go | 24 +- .../x/sys/unix/zsyscall_linux_mips64.go | 24 +- .../x/sys/unix/zsyscall_linux_mips64le.go | 11 - .../x/sys/unix/zsyscall_linux_mipsle.go | 24 +- .../x/sys/unix/zsyscall_linux_ppc.go | 24 +- .../x/sys/unix/zsyscall_linux_ppc64.go | 24 +- .../x/sys/unix/zsyscall_linux_ppc64le.go | 24 +- .../x/sys/unix/zsyscall_linux_riscv64.go | 11 - .../x/sys/unix/zsyscall_linux_s390x.go | 13 +- .../x/sys/unix/zsyscall_linux_sparc64.go | 24 +- .../x/sys/unix/zsyscall_netbsd_386.go | 12 - .../x/sys/unix/zsyscall_netbsd_amd64.go | 12 - .../x/sys/unix/zsyscall_netbsd_arm.go | 12 - .../x/sys/unix/zsyscall_netbsd_arm64.go | 12 - .../x/sys/unix/zsysnum_linux_386.go | 1 + .../x/sys/unix/zsysnum_linux_amd64.go | 1 + .../x/sys/unix/zsysnum_linux_arm.go | 1 + .../x/sys/unix/zsysnum_linux_arm64.go | 1 + .../x/sys/unix/zsysnum_linux_mips.go | 1 + .../x/sys/unix/zsysnum_linux_mips64.go | 1 + .../x/sys/unix/zsysnum_linux_mips64le.go | 1 + .../x/sys/unix/zsysnum_linux_mipsle.go | 1 + .../x/sys/unix/zsysnum_linux_ppc.go | 1 + .../x/sys/unix/zsysnum_linux_ppc64.go | 1 + .../x/sys/unix/zsysnum_linux_ppc64le.go | 1 + .../x/sys/unix/zsysnum_linux_riscv64.go | 1 + .../x/sys/unix/zsysnum_linux_s390x.go | 1 + .../x/sys/unix/zsysnum_linux_sparc64.go | 1 + .../golang.org/x/sys/unix/ztypes_linux.go | 1574 +++++- .../x/sys/unix/ztypes_linux_s390x.go | 4 +- .../golang.org/x/sys/windows/exec_windows.go | 37 +- .../x/sys/windows/syscall_windows.go | 2 + .../golang.org/x/sys/windows/types_windows.go | 43 +- .../x/sys/windows/zsyscall_windows.go | 14 + src/cmd/vendor/modules.txt | 9 +- src/go.mod | 2 +- src/go.sum | 4 +- .../golang.org/x/sys/cpu/syscall_aix_gccgo.go | 2 +- src/vendor/modules.txt | 2 +- 127 files changed, 5363 insertions(+), 7885 deletions(-) create mode 100644 src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.css create mode 100644 src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.js create mode 100644 src/cmd/vendor/github.com/google/pprof/internal/driver/html/flamegraph.html create mode 100644 src/cmd/vendor/github.com/google/pprof/internal/driver/html/graph.html create mode 100644 src/cmd/vendor/github.com/google/pprof/internal/driver/html/header.html create mode 100644 src/cmd/vendor/github.com/google/pprof/internal/driver/html/plaintext.html create mode 100644 src/cmd/vendor/github.com/google/pprof/internal/driver/html/source.html create mode 100644 src/cmd/vendor/github.com/google/pprof/internal/driver/html/top.html delete mode 100644 src/cmd/vendor/github.com/google/pprof/third_party/d3/LICENSE delete mode 100644 src/cmd/vendor/github.com/google/pprof/third_party/d3/README.md delete mode 100644 src/cmd/vendor/github.com/google/pprof/third_party/d3/d3.go rename src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/{LICENSE => D3_FLAME_GRAPH_LICENSE} (100%) create mode 100644 src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_LICENSE create mode 100644 src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/README.md create mode 100644 src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/index.js create mode 100644 src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/package-lock.json create mode 100644 src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/package.json create mode 100644 src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/update.sh create mode 100644 src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/webpack.config.js create mode 100644 src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_alarm.go diff --git a/src/cmd/go.mod b/src/cmd/go.mod index 5bd7bf9b8b..44aa3230db 100644 --- a/src/cmd/go.mod +++ b/src/cmd/go.mod @@ -3,7 +3,7 @@ module cmd go 1.18 require ( - github.com/google/pprof v0.0.0-20211104044539-f987b9c94b31 + github.com/google/pprof v0.0.0-20220729232143-a41b82acbcb1 golang.org/x/arch v0.0.0-20210923205945-b76863e36670 golang.org/x/mod v0.6.0-dev.0.20211102181907-3a5865c02020 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c @@ -12,8 +12,8 @@ require ( ) require ( - github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d // indirect + github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2 // indirect golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect - golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect + golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect ) diff --git a/src/cmd/go.sum b/src/cmd/go.sum index a8a85503a8..baad8bb507 100644 --- a/src/cmd/go.sum +++ b/src/cmd/go.sum @@ -1,10 +1,7 @@ -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/google/pprof v0.0.0-20211104044539-f987b9c94b31 h1:YvpxjnjGhf/vDEeYOysNbsrtB///PKS8lqkFNSDm1p8= -github.com/google/pprof v0.0.0-20211104044539-f987b9c94b31/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= -github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d h1:uGg2frlt3IcT7kbV6LEp5ONv4vmoO2FW4qSO+my/aoM= -github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= +github.com/google/pprof v0.0.0-20220729232143-a41b82acbcb1 h1:8pyqKJvrJqUYaKS851Ule26pwWvey6IDMiczaBLDKLQ= +github.com/google/pprof v0.0.0-20220729232143-a41b82acbcb1/go.mod h1:gSuNB+gJaOiQKLEZ+q+PK9Mq3SOzhRcw2GsGS/FhYDk= +github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2 h1:rcanfLhLDA8nozr/K289V1zcntHr3V+SHlXwzz1ZI2g= +github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M= @@ -13,9 +10,8 @@ golang.org/x/mod v0.6.0-dev.0.20211102181907-3a5865c02020 h1:HjtpZuJcnSa+yHlL4Y5 golang.org/x/mod v0.6.0-dev.0.20211102181907-3a5865c02020/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211205182925-97ca703d548d h1:FjkYO/PPp4Wi0EAUOVLxePm7qVW4r4ctbWpURyuOD0E= -golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 h1:y/woIyUBFbpQGKS0u1aHF/40WUDnek3fPOyD08H5Vng= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/tools v0.1.9-0.20220329150752-294080fd2f5a h1:IlVBSvpiWIkpqADzaiismkf1xcqsZjBDIXzO+7kZEpY= diff --git a/src/cmd/pprof/pprof.go b/src/cmd/pprof/pprof.go index e72c765adc..c073c964b4 100644 --- a/src/cmd/pprof/pprof.go +++ b/src/cmd/pprof/pprof.go @@ -149,7 +149,7 @@ type objTool struct { disasmCache map[string]*objfile.Disasm } -func (*objTool) Open(name string, start, limit, offset uint64) (driver.ObjFile, error) { +func (*objTool) Open(name string, start, limit, offset uint64, relocationSymbol string) (driver.ObjFile, error) { of, err := objfile.Open(name) if err != nil { return nil, err diff --git a/src/cmd/vendor/github.com/google/pprof/driver/driver.go b/src/cmd/vendor/github.com/google/pprof/driver/driver.go index fc05f919ba..5a8222f70a 100644 --- a/src/cmd/vendor/github.com/google/pprof/driver/driver.go +++ b/src/cmd/vendor/github.com/google/pprof/driver/driver.go @@ -137,8 +137,10 @@ type MappingSources map[string][]struct { type ObjTool interface { // Open opens the named object file. If the object is a shared // library, start/limit/offset are the addresses where it is mapped - // into memory in the address space being inspected. - Open(file string, start, limit, offset uint64) (ObjFile, error) + // into memory in the address space being inspected. If the object + // is a linux kernel, relocationSymbol is the name of the symbol + // corresponding to the start address. + Open(file string, start, limit, offset uint64, relocationSymbol string) (ObjFile, error) // Disasm disassembles the named object file, starting at // the start address and stopping at (before) the end address. @@ -232,8 +234,8 @@ type internalObjTool struct { ObjTool } -func (o *internalObjTool) Open(file string, start, limit, offset uint64) (plugin.ObjFile, error) { - f, err := o.ObjTool.Open(file, start, limit, offset) +func (o *internalObjTool) Open(file string, start, limit, offset uint64, relocationSymbol string) (plugin.ObjFile, error) { + f, err := o.ObjTool.Open(file, start, limit, offset, relocationSymbol) if err != nil { return nil, err } diff --git a/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go b/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go index e920eeb2fa..efa9167af7 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go @@ -284,7 +284,7 @@ func (bu *Binutils) Disasm(file string, start, end uint64, intelSyntax bool) ([] } // Open satisfies the plugin.ObjTool interface. -func (bu *Binutils) Open(name string, start, limit, offset uint64) (plugin.ObjFile, error) { +func (bu *Binutils) Open(name string, start, limit, offset uint64, relocationSymbol string) (plugin.ObjFile, error) { b := bu.get() // Make sure file is a supported executable. @@ -316,7 +316,7 @@ func (bu *Binutils) Open(name string, start, limit, offset uint64) (plugin.ObjFi // Match against supported file types. if elfMagic == elf.ELFMAG { - f, err := b.openELF(name, start, limit, offset) + f, err := b.openELF(name, start, limit, offset, relocationSymbol) if err != nil { return nil, fmt.Errorf("error reading ELF file %s: %v", name, err) } @@ -425,7 +425,7 @@ func (b *binrep) openMachO(name string, start, limit, offset uint64) (plugin.Obj return b.openMachOCommon(name, of, start, limit, offset) } -func (b *binrep) openELF(name string, start, limit, offset uint64) (plugin.ObjFile, error) { +func (b *binrep) openELF(name string, start, limit, offset uint64, relocationSymbol string) (plugin.ObjFile, error) { ef, err := elfOpen(name) if err != nil { return nil, fmt.Errorf("error parsing %s: %v", name, err) @@ -440,8 +440,8 @@ func (b *binrep) openELF(name string, start, limit, offset uint64) (plugin.ObjFi } var ( - stextOffset *uint64 - pageAligned = func(addr uint64) bool { return addr%4096 == 0 } + kernelOffset *uint64 + pageAligned = func(addr uint64) bool { return addr%4096 == 0 } ) if strings.Contains(name, "vmlinux") || !pageAligned(start) || !pageAligned(limit) || !pageAligned(offset) { // Reading all Symbols is expensive, and we only rarely need it so @@ -455,10 +455,18 @@ func (b *binrep) openELF(name string, start, limit, offset uint64) (plugin.ObjFi if err != nil && err != elf.ErrNoSymbols { return nil, err } + + // The kernel relocation symbol (the mapping start address) can be either + // _text or _stext. When profiles are generated by `perf`, which one was used is + // distinguished by the mapping name for the kernel image: + // '[kernel.kallsyms]_text' or '[kernel.kallsyms]_stext', respectively. If we haven't + // been able to parse it from the mapping, we default to _stext. + if relocationSymbol == "" { + relocationSymbol = "_stext" + } for _, s := range symbols { - if s.Name == "_stext" { - // The kernel may use _stext as the mapping start address. - stextOffset = &s.Value + if s.Name == relocationSymbol { + kernelOffset = &s.Value break } } @@ -469,7 +477,7 @@ func (b *binrep) openELF(name string, start, limit, offset uint64) (plugin.ObjFi // value until we have a sample address for this mapping, so that we can // correctly identify the associated program segment that is needed to compute // the base. - if _, err := elfexec.GetBase(&ef.FileHeader, elfexec.FindTextProgHeader(ef), stextOffset, start, limit, offset); err != nil { + if _, err := elfexec.GetBase(&ef.FileHeader, elfexec.FindTextProgHeader(ef), kernelOffset, start, limit, offset); err != nil { return nil, fmt.Errorf("could not identify base for %s: %v", name, err) } @@ -478,14 +486,14 @@ func (b *binrep) openELF(name string, start, limit, offset uint64) (plugin.ObjFi b: b, name: name, buildID: buildID, - m: &elfMapping{start: start, limit: limit, offset: offset, stextOffset: stextOffset}, + m: &elfMapping{start: start, limit: limit, offset: offset, kernelOffset: kernelOffset}, }}, nil } return &fileAddr2Line{file: file{ b: b, name: name, buildID: buildID, - m: &elfMapping{start: start, limit: limit, offset: offset, stextOffset: stextOffset}, + m: &elfMapping{start: start, limit: limit, offset: offset, kernelOffset: kernelOffset}, }}, nil } @@ -521,8 +529,8 @@ func (b *binrep) openPE(name string, start, limit, offset uint64) (plugin.ObjFil type elfMapping struct { // Runtime mapping parameters. start, limit, offset uint64 - // Offset of _stext symbol. Only defined for kernel images, nil otherwise. - stextOffset *uint64 + // Offset of kernel relocation symbol. Only defined for kernel images, nil otherwise. + kernelOffset *uint64 } // findProgramHeader returns the program segment that matches the current @@ -535,7 +543,7 @@ func (m *elfMapping) findProgramHeader(ef *elf.File, addr uint64) (*elf.ProgHead // it's a kernel / .ko module mapping, because with quipper address remapping // enabled, the address would be in the lower half of the address space. - if m.stextOffset != nil || m.start >= m.limit || m.limit >= (uint64(1)<<63) { + if m.kernelOffset != nil || m.start >= m.limit || m.limit >= (uint64(1)<<63) { // For the kernel, find the program segment that includes the .text section. return elfexec.FindTextProgHeader(ef), nil } @@ -601,7 +609,7 @@ func (f *file) computeBase(addr uint64) error { return fmt.Errorf("failed to find program header for file %q, ELF mapping %#v, address %x: %v", f.name, *f.m, addr, err) } - base, err := elfexec.GetBase(&ef.FileHeader, ph, f.m.stextOffset, f.m.start, f.m.limit, f.m.offset) + base, err := elfexec.GetBase(&ef.FileHeader, ph, f.m.kernelOffset, f.m.start, f.m.limit, f.m.offset) if err != nil { return err } diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go index 492400c5f3..237cc33233 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go @@ -98,7 +98,7 @@ func parseFlags(o *plugin.Options) (*source, []string, error) { // Recognize first argument as an executable or buildid override. if len(args) > 1 { arg0 := args[0] - if file, err := o.Obj.Open(arg0, 0, ^uint64(0), 0); err == nil { + if file, err := o.Obj.Open(arg0, 0, ^uint64(0), 0, ""); err == nil { file.Close() execName = arg0 args = args[1:] diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go index b8a69e87fc..0b361651bc 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go @@ -420,12 +420,14 @@ mapping: fileNames = append(fileNames, filepath.Join(path, m.File)) } for _, name := range fileNames { - if f, err := obj.Open(name, m.Start, m.Limit, m.Offset); err == nil { + if f, err := obj.Open(name, m.Start, m.Limit, m.Offset, m.KernelRelocationSymbol); err == nil { defer f.Close() fileBuildID := f.BuildID() if m.BuildID != "" && m.BuildID != fileBuildID { ui.PrintErr("Ignoring local file " + name + ": build-id mismatch (" + m.BuildID + " != " + fileBuildID + ")") } else { + // Explicitly do not update KernelRelocationSymbol -- + // the new local file name is most likely missing it. m.File = name continue mapping } @@ -449,6 +451,8 @@ mapping: if execName, buildID := s.ExecName, s.BuildID; execName != "" || buildID != "" { m := p.Mapping[0] if execName != "" { + // Explicitly do not update KernelRelocationSymbol -- + // the source override is most likely missing it. m.File = execName } if buildID != "" { diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.css b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.css new file mode 100644 index 0000000000..03755abc0e --- /dev/null +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.css @@ -0,0 +1,272 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} +html, body { + height: 100%; +} +body { + font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; + font-size: 13px; + line-height: 1.4; + display: flex; + flex-direction: column; +} +a { + color: #2a66d9; +} +.header { + display: flex; + align-items: center; + height: 44px; + min-height: 44px; + background-color: #eee; + color: #212121; + padding: 0 1rem; +} +.header > div { + margin: 0 0.125em; +} +.header .title h1 { + font-size: 1.75em; + margin-right: 1rem; + margin-bottom: 4px; +} +.header .title a { + color: #212121; + text-decoration: none; +} +.header .title a:hover { + text-decoration: underline; +} +.header .description { + width: 100%; + text-align: right; + white-space: nowrap; +} +@media screen and (max-width: 799px) { + .header input { + display: none; + } +} +#detailsbox { + display: none; + z-index: 1; + position: fixed; + top: 40px; + right: 20px; + background-color: #ffffff; + box-shadow: 0 1px 5px rgba(0,0,0,.3); + line-height: 24px; + padding: 1em; + text-align: left; +} +.header input { + background: white url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' style='pointer-events:none;display:block;width:100%25;height:100%25;fill:%23757575'%3E%3Cpath d='M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61.0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z'/%3E%3C/svg%3E") no-repeat 4px center/20px 20px; + border: 1px solid #d1d2d3; + border-radius: 2px 0 0 2px; + padding: 0.25em; + padding-left: 28px; + margin-left: 1em; + font-family: 'Roboto', 'Noto', sans-serif; + font-size: 1em; + line-height: 24px; + color: #212121; +} +.downArrow { + border-top: .36em solid #ccc; + border-left: .36em solid transparent; + border-right: .36em solid transparent; + margin-bottom: .05em; + margin-left: .5em; + transition: border-top-color 200ms; +} +.menu-item { + height: 100%; + text-transform: uppercase; + font-family: 'Roboto Medium', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; + position: relative; +} +.menu-item .menu-name:hover { + opacity: 0.75; +} +.menu-item .menu-name:hover .downArrow { + border-top-color: #666; +} +.menu-name { + height: 100%; + padding: 0 0.5em; + display: flex; + align-items: center; + justify-content: center; +} +.menu-name a { + text-decoration: none; + color: #212121; +} +.submenu { + display: none; + z-index: 1; + margin-top: -4px; + min-width: 10em; + position: absolute; + left: 0px; + background-color: white; + box-shadow: 0 1px 5px rgba(0,0,0,.3); + font-size: 100%; + text-transform: none; +} +.menu-item, .submenu { + user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -webkit-user-select: none; +} +.submenu hr { + border: 0; + border-top: 2px solid #eee; +} +.submenu a { + display: block; + padding: .5em 1em; + text-decoration: none; +} +.submenu a:hover, .submenu a.active { + color: white; + background-color: #6b82d6; +} +.submenu a.disabled { + color: gray; + pointer-events: none; +} +.menu-check-mark { + position: absolute; + left: 2px; +} +.menu-delete-btn { + position: absolute; + right: 2px; +} + +{{/* Used to disable events when a modal dialog is displayed */}} +#dialog-overlay { + display: none; + position: fixed; + left: 0px; + top: 0px; + width: 100%; + height: 100%; + background-color: rgba(1,1,1,0.1); +} + +.dialog { + {{/* Displayed centered horizontally near the top */}} + display: none; + position: fixed; + margin: 0px; + top: 60px; + left: 50%; + transform: translateX(-50%); + + z-index: 3; + font-size: 125%; + background-color: #ffffff; + box-shadow: 0 1px 5px rgba(0,0,0,.3); +} +.dialog-header { + font-size: 120%; + border-bottom: 1px solid #CCCCCC; + width: 100%; + text-align: center; + background: #EEEEEE; + user-select: none; +} +.dialog-footer { + border-top: 1px solid #CCCCCC; + width: 100%; + text-align: right; + padding: 10px; +} +.dialog-error { + margin: 10px; + color: red; +} +.dialog input { + margin: 10px; + font-size: inherit; +} +.dialog button { + margin-left: 10px; + font-size: inherit; +} +#save-dialog, #delete-dialog { + width: 50%; + max-width: 20em; +} +#delete-prompt { + padding: 10px; +} + +#content { + overflow-y: scroll; + padding: 1em; +} +#top { + overflow-y: scroll; +} +#graph { + overflow: hidden; +} +#graph svg { + width: 100%; + height: auto; + padding: 10px; +} +#content.source .filename { + margin-top: 0; + margin-bottom: 1em; + font-size: 120%; +} +#content.source pre { + margin-bottom: 3em; +} +table { + border-spacing: 0px; + width: 100%; + padding-bottom: 1em; + white-space: nowrap; +} +table thead { + font-family: 'Roboto Medium', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; +} +table tr th { + position: sticky; + top: 0; + background-color: #ddd; + text-align: right; + padding: .3em .5em; +} +table tr td { + padding: .3em .5em; + text-align: right; +} +#top table tr th:nth-child(6), +#top table tr th:nth-child(7), +#top table tr td:nth-child(6), +#top table tr td:nth-child(7) { + text-align: left; +} +#top table tr td:nth-child(6) { + width: 100%; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; +} +#flathdr1, #flathdr2, #cumhdr1, #cumhdr2, #namehdr { + cursor: ns-resize; +} +.hilite { + background-color: #ebf5fb; + font-weight: bold; +} diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.js b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.js new file mode 100644 index 0000000000..4fe3caa442 --- /dev/null +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.js @@ -0,0 +1,693 @@ +// Make svg pannable and zoomable. +// Call clickHandler(t) if a click event is caught by the pan event handlers. +function initPanAndZoom(svg, clickHandler) { + 'use strict'; + + // Current mouse/touch handling mode + const IDLE = 0; + const MOUSEPAN = 1; + const TOUCHPAN = 2; + const TOUCHZOOM = 3; + let mode = IDLE; + + // State needed to implement zooming. + let currentScale = 1.0; + const initWidth = svg.viewBox.baseVal.width; + const initHeight = svg.viewBox.baseVal.height; + + // State needed to implement panning. + let panLastX = 0; // Last event X coordinate + let panLastY = 0; // Last event Y coordinate + let moved = false; // Have we seen significant movement + let touchid = null; // Current touch identifier + + // State needed for pinch zooming + let touchid2 = null; // Second id for pinch zooming + let initGap = 1.0; // Starting gap between two touches + let initScale = 1.0; // currentScale when pinch zoom started + let centerPoint = null; // Center point for scaling + + // Convert event coordinates to svg coordinates. + function toSvg(x, y) { + const p = svg.createSVGPoint(); + p.x = x; + p.y = y; + let m = svg.getCTM(); + if (m == null) m = svg.getScreenCTM(); // Firefox workaround. + return p.matrixTransform(m.inverse()); + } + + // Change the scaling for the svg to s, keeping the point denoted + // by u (in svg coordinates]) fixed at the same screen location. + function rescale(s, u) { + // Limit to a good range. + if (s < 0.2) s = 0.2; + if (s > 10.0) s = 10.0; + + currentScale = s; + + // svg.viewBox defines the visible portion of the user coordinate + // system. So to magnify by s, divide the visible portion by s, + // which will then be stretched to fit the viewport. + const vb = svg.viewBox; + const w1 = vb.baseVal.width; + const w2 = initWidth / s; + const h1 = vb.baseVal.height; + const h2 = initHeight / s; + vb.baseVal.width = w2; + vb.baseVal.height = h2; + + // We also want to adjust vb.baseVal.x so that u.x remains at same + // screen X coordinate. In other words, want to change it from x1 to x2 + // so that: + // (u.x - x1) / w1 = (u.x - x2) / w2 + // Simplifying that, we get + // (u.x - x1) * (w2 / w1) = u.x - x2 + // x2 = u.x - (u.x - x1) * (w2 / w1) + vb.baseVal.x = u.x - (u.x - vb.baseVal.x) * (w2 / w1); + vb.baseVal.y = u.y - (u.y - vb.baseVal.y) * (h2 / h1); + } + + function handleWheel(e) { + if (e.deltaY == 0) return; + // Change scale factor by 1.1 or 1/1.1 + rescale(currentScale * (e.deltaY < 0 ? 1.1 : (1/1.1)), + toSvg(e.offsetX, e.offsetY)); + } + + function setMode(m) { + mode = m; + touchid = null; + touchid2 = null; + } + + function panStart(x, y) { + moved = false; + panLastX = x; + panLastY = y; + } + + function panMove(x, y) { + let dx = x - panLastX; + let dy = y - panLastY; + if (Math.abs(dx) <= 2 && Math.abs(dy) <= 2) return; // Ignore tiny moves + + moved = true; + panLastX = x; + panLastY = y; + + // Firefox workaround: get dimensions from parentNode. + const swidth = svg.clientWidth || svg.parentNode.clientWidth; + const sheight = svg.clientHeight || svg.parentNode.clientHeight; + + // Convert deltas from screen space to svg space. + dx *= (svg.viewBox.baseVal.width / swidth); + dy *= (svg.viewBox.baseVal.height / sheight); + + svg.viewBox.baseVal.x -= dx; + svg.viewBox.baseVal.y -= dy; + } + + function handleScanStart(e) { + if (e.button != 0) return; // Do not catch right-clicks etc. + setMode(MOUSEPAN); + panStart(e.clientX, e.clientY); + e.preventDefault(); + svg.addEventListener('mousemove', handleScanMove); + } + + function handleScanMove(e) { + if (e.buttons == 0) { + // Missed an end event, perhaps because mouse moved outside window. + setMode(IDLE); + svg.removeEventListener('mousemove', handleScanMove); + return; + } + if (mode == MOUSEPAN) panMove(e.clientX, e.clientY); + } + + function handleScanEnd(e) { + if (mode == MOUSEPAN) panMove(e.clientX, e.clientY); + setMode(IDLE); + svg.removeEventListener('mousemove', handleScanMove); + if (!moved) clickHandler(e.target); + } + + // Find touch object with specified identifier. + function findTouch(tlist, id) { + for (const t of tlist) { + if (t.identifier == id) return t; + } + return null; + } + + // Return distance between two touch points + function touchGap(t1, t2) { + const dx = t1.clientX - t2.clientX; + const dy = t1.clientY - t2.clientY; + return Math.hypot(dx, dy); + } + + function handleTouchStart(e) { + if (mode == IDLE && e.changedTouches.length == 1) { + // Start touch based panning + const t = e.changedTouches[0]; + setMode(TOUCHPAN); + touchid = t.identifier; + panStart(t.clientX, t.clientY); + e.preventDefault(); + } else if (mode == TOUCHPAN && e.touches.length == 2) { + // Start pinch zooming + setMode(TOUCHZOOM); + const t1 = e.touches[0]; + const t2 = e.touches[1]; + touchid = t1.identifier; + touchid2 = t2.identifier; + initScale = currentScale; + initGap = touchGap(t1, t2); + centerPoint = toSvg((t1.clientX + t2.clientX) / 2, + (t1.clientY + t2.clientY) / 2); + e.preventDefault(); + } + } + + function handleTouchMove(e) { + if (mode == TOUCHPAN) { + const t = findTouch(e.changedTouches, touchid); + if (t == null) return; + if (e.touches.length != 1) { + setMode(IDLE); + return; + } + panMove(t.clientX, t.clientY); + e.preventDefault(); + } else if (mode == TOUCHZOOM) { + // Get two touches; new gap; rescale to ratio. + const t1 = findTouch(e.touches, touchid); + const t2 = findTouch(e.touches, touchid2); + if (t1 == null || t2 == null) return; + const gap = touchGap(t1, t2); + rescale(initScale * gap / initGap, centerPoint); + e.preventDefault(); + } + } + + function handleTouchEnd(e) { + if (mode == TOUCHPAN) { + const t = findTouch(e.changedTouches, touchid); + if (t == null) return; + panMove(t.clientX, t.clientY); + setMode(IDLE); + e.preventDefault(); + if (!moved) clickHandler(t.target); + } else if (mode == TOUCHZOOM) { + setMode(IDLE); + e.preventDefault(); + } + } + + svg.addEventListener('mousedown', handleScanStart); + svg.addEventListener('mouseup', handleScanEnd); + svg.addEventListener('touchstart', handleTouchStart); + svg.addEventListener('touchmove', handleTouchMove); + svg.addEventListener('touchend', handleTouchEnd); + svg.addEventListener('wheel', handleWheel, true); +} + +function initMenus() { + 'use strict'; + + let activeMenu = null; + let activeMenuHdr = null; + + function cancelActiveMenu() { + if (activeMenu == null) return; + activeMenu.style.display = 'none'; + activeMenu = null; + activeMenuHdr = null; + } + + // Set click handlers on every menu header. + for (const menu of document.getElementsByClassName('submenu')) { + const hdr = menu.parentElement; + if (hdr == null) return; + if (hdr.classList.contains('disabled')) return; + function showMenu(e) { + // menu is a child of hdr, so this event can fire for clicks + // inside menu. Ignore such clicks. + if (e.target.parentElement != hdr) return; + activeMenu = menu; + activeMenuHdr = hdr; + menu.style.display = 'block'; + } + hdr.addEventListener('mousedown', showMenu); + hdr.addEventListener('touchstart', showMenu); + } + + // If there is an active menu and a down event outside, retract the menu. + for (const t of ['mousedown', 'touchstart']) { + document.addEventListener(t, (e) => { + // Note: to avoid unnecessary flicker, if the down event is inside + // the active menu header, do not retract the menu. + if (activeMenuHdr != e.target.closest('.menu-item')) { + cancelActiveMenu(); + } + }, { passive: true, capture: true }); + } + + // If there is an active menu and an up event inside, retract the menu. + document.addEventListener('mouseup', (e) => { + if (activeMenu == e.target.closest('.submenu')) { + cancelActiveMenu(); + } + }, { passive: true, capture: true }); +} + +function sendURL(method, url, done) { + fetch(url.toString(), {method: method}) + .then((response) => { done(response.ok); }) + .catch((error) => { done(false); }); +} + +// Initialize handlers for saving/loading configurations. +function initConfigManager() { + 'use strict'; + + // Initialize various elements. + function elem(id) { + const result = document.getElementById(id); + if (!result) console.warn('element ' + id + ' not found'); + return result; + } + const overlay = elem('dialog-overlay'); + const saveDialog = elem('save-dialog'); + const saveInput = elem('save-name'); + const saveError = elem('save-error'); + const delDialog = elem('delete-dialog'); + const delPrompt = elem('delete-prompt'); + const delError = elem('delete-error'); + + let currentDialog = null; + let currentDeleteTarget = null; + + function showDialog(dialog) { + if (currentDialog != null) { + overlay.style.display = 'none'; + currentDialog.style.display = 'none'; + } + currentDialog = dialog; + if (dialog != null) { + overlay.style.display = 'block'; + dialog.style.display = 'block'; + } + } + + function cancelDialog(e) { + showDialog(null); + } + + // Show dialog for saving the current config. + function showSaveDialog(e) { + saveError.innerText = ''; + showDialog(saveDialog); + saveInput.focus(); + } + + // Commit save config. + function commitSave(e) { + const name = saveInput.value; + const url = new URL(document.URL); + // Set path relative to existing path. + url.pathname = new URL('./saveconfig', document.URL).pathname; + url.searchParams.set('config', name); + saveError.innerText = ''; + sendURL('POST', url, (ok) => { + if (!ok) { + saveError.innerText = 'Save failed'; + } else { + showDialog(null); + location.reload(); // Reload to show updated config menu + } + }); + } + + function handleSaveInputKey(e) { + if (e.key === 'Enter') commitSave(e); + } + + function deleteConfig(e, elem) { + e.preventDefault(); + const config = elem.dataset.config; + delPrompt.innerText = 'Delete ' + config + '?'; + currentDeleteTarget = elem; + showDialog(delDialog); + } + + function commitDelete(e, elem) { + if (!currentDeleteTarget) return; + const config = currentDeleteTarget.dataset.config; + const url = new URL('./deleteconfig', document.URL); + url.searchParams.set('config', config); + delError.innerText = ''; + sendURL('DELETE', url, (ok) => { + if (!ok) { + delError.innerText = 'Delete failed'; + return; + } + showDialog(null); + // Remove menu entry for this config. + if (currentDeleteTarget && currentDeleteTarget.parentElement) { + currentDeleteTarget.parentElement.remove(); + } + }); + } + + // Bind event on elem to fn. + function bind(event, elem, fn) { + if (elem == null) return; + elem.addEventListener(event, fn); + if (event == 'click') { + // Also enable via touch. + elem.addEventListener('touchstart', fn); + } + } + + bind('click', elem('save-config'), showSaveDialog); + bind('click', elem('save-cancel'), cancelDialog); + bind('click', elem('save-confirm'), commitSave); + bind('keydown', saveInput, handleSaveInputKey); + + bind('click', elem('delete-cancel'), cancelDialog); + bind('click', elem('delete-confirm'), commitDelete); + + // Activate deletion button for all config entries in menu. + for (const del of Array.from(document.getElementsByClassName('menu-delete-btn'))) { + bind('click', del, (e) => { + deleteConfig(e, del); + }); + } +} + +function viewer(baseUrl, nodes) { + 'use strict'; + + // Elements + const search = document.getElementById('search'); + const graph0 = document.getElementById('graph0'); + const svg = (graph0 == null ? null : graph0.parentElement); + const toptable = document.getElementById('toptable'); + + let regexpActive = false; + let selected = new Map(); + let origFill = new Map(); + let searchAlarm = null; + let buttonsEnabled = true; + + function handleDetails(e) { + e.preventDefault(); + const detailsText = document.getElementById('detailsbox'); + if (detailsText != null) { + if (detailsText.style.display === 'block') { + detailsText.style.display = 'none'; + } else { + detailsText.style.display = 'block'; + } + } + } + + function handleKey(e) { + if (e.keyCode != 13) return; + setHrefParams(window.location, function (params) { + params.set('f', search.value); + }); + e.preventDefault(); + } + + function handleSearch() { + // Delay expensive processing so a flurry of key strokes is handled once. + if (searchAlarm != null) { + clearTimeout(searchAlarm); + } + searchAlarm = setTimeout(selectMatching, 300); + + regexpActive = true; + updateButtons(); + } + + function selectMatching() { + searchAlarm = null; + let re = null; + if (search.value != '') { + try { + re = new RegExp(search.value); + } catch (e) { + // TODO: Display error state in search box + return; + } + } + + function match(text) { + return re != null && re.test(text); + } + + // drop currently selected items that do not match re. + selected.forEach(function(v, n) { + if (!match(nodes[n])) { + unselect(n, document.getElementById('node' + n)); + } + }) + + // add matching items that are not currently selected. + if (nodes) { + for (let n = 0; n < nodes.length; n++) { + if (!selected.has(n) && match(nodes[n])) { + select(n, document.getElementById('node' + n)); + } + } + } + + updateButtons(); + } + + function toggleSvgSelect(elem) { + // Walk up to immediate child of graph0 + while (elem != null && elem.parentElement != graph0) { + elem = elem.parentElement; + } + if (!elem) return; + + // Disable regexp mode. + regexpActive = false; + + const n = nodeId(elem); + if (n < 0) return; + if (selected.has(n)) { + unselect(n, elem); + } else { + select(n, elem); + } + updateButtons(); + } + + function unselect(n, elem) { + if (elem == null) return; + selected.delete(n); + setBackground(elem, false); + } + + function select(n, elem) { + if (elem == null) return; + selected.set(n, true); + setBackground(elem, true); + } + + function nodeId(elem) { + const id = elem.id; + if (!id) return -1; + if (!id.startsWith('node')) return -1; + const n = parseInt(id.slice(4), 10); + if (isNaN(n)) return -1; + if (n < 0 || n >= nodes.length) return -1; + return n; + } + + function setBackground(elem, set) { + // Handle table row highlighting. + if (elem.nodeName == 'TR') { + elem.classList.toggle('hilite', set); + return; + } + + // Handle svg element highlighting. + const p = findPolygon(elem); + if (p != null) { + if (set) { + origFill.set(p, p.style.fill); + p.style.fill = '#ccccff'; + } else if (origFill.has(p)) { + p.style.fill = origFill.get(p); + } + } + } + + function findPolygon(elem) { + if (elem.localName == 'polygon') return elem; + for (const c of elem.children) { + const p = findPolygon(c); + if (p != null) return p; + } + return null; + } + + // convert a string to a regexp that matches that string. + function quotemeta(str) { + return str.replace(/([\\\.?+*\[\](){}|^$])/g, '\\$1'); + } + + function setSampleIndexLink(id) { + const elem = document.getElementById(id); + if (elem != null) { + setHrefParams(elem, function (params) { + params.set("si", id); + }); + } + } + + // Update id's href to reflect current selection whenever it is + // liable to be followed. + function makeSearchLinkDynamic(id) { + const elem = document.getElementById(id); + if (elem == null) return; + + // Most links copy current selection into the 'f' parameter, + // but Refine menu links are different. + let param = 'f'; + if (id == 'ignore') param = 'i'; + if (id == 'hide') param = 'h'; + if (id == 'show') param = 's'; + if (id == 'show-from') param = 'sf'; + + // We update on mouseenter so middle-click/right-click work properly. + elem.addEventListener('mouseenter', updater); + elem.addEventListener('touchstart', updater); + + function updater() { + // The selection can be in one of two modes: regexp-based or + // list-based. Construct regular expression depending on mode. + let re = regexpActive + ? search.value + : Array.from(selected.keys()).map(key => quotemeta(nodes[key])).join('|'); + + setHrefParams(elem, function (params) { + if (re != '') { + // For focus/show/show-from, forget old parameter. For others, add to re. + if (param != 'f' && param != 's' && param != 'sf' && params.has(param)) { + const old = params.get(param); + if (old != '') { + re += '|' + old; + } + } + params.set(param, re); + } else { + params.delete(param); + } + }); + } + } + + function setHrefParams(elem, paramSetter) { + let url = new URL(elem.href); + url.hash = ''; + + // Copy params from this page's URL. + const params = url.searchParams; + for (const p of new URLSearchParams(window.location.search)) { + params.set(p[0], p[1]); + } + + // Give the params to the setter to modify. + paramSetter(params); + + elem.href = url.toString(); + } + + function handleTopClick(e) { + // Walk back until we find TR and then get the Name column (index 5) + let elem = e.target; + while (elem != null && elem.nodeName != 'TR') { + elem = elem.parentElement; + } + if (elem == null || elem.children.length < 6) return; + + e.preventDefault(); + const tr = elem; + const td = elem.children[5]; + if (td.nodeName != 'TD') return; + const name = td.innerText; + const index = nodes.indexOf(name); + if (index < 0) return; + + // Disable regexp mode. + regexpActive = false; + + if (selected.has(index)) { + unselect(index, elem); + } else { + select(index, elem); + } + updateButtons(); + } + + function updateButtons() { + const enable = (search.value != '' || selected.size != 0); + if (buttonsEnabled == enable) return; + buttonsEnabled = enable; + for (const id of ['focus', 'ignore', 'hide', 'show', 'show-from']) { + const link = document.getElementById(id); + if (link != null) { + link.classList.toggle('disabled', !enable); + } + } + } + + // Initialize button states + updateButtons(); + + // Setup event handlers + initMenus(); + if (svg != null) { + initPanAndZoom(svg, toggleSvgSelect); + } + if (toptable != null) { + toptable.addEventListener('mousedown', handleTopClick); + toptable.addEventListener('touchstart', handleTopClick); + } + + const ids = ['topbtn', 'graphbtn', 'flamegraph', 'peek', 'list', 'disasm', + 'focus', 'ignore', 'hide', 'show', 'show-from']; + ids.forEach(makeSearchLinkDynamic); + + const sampleIDs = [{{range .SampleTypes}}'{{.}}', {{end}}]; + sampleIDs.forEach(setSampleIndexLink); + + // Bind action to button with specified id. + function addAction(id, action) { + const btn = document.getElementById(id); + if (btn != null) { + btn.addEventListener('click', action); + btn.addEventListener('touchstart', action); + } + } + + addAction('details', handleDetails); + initConfigManager(); + + search.addEventListener('input', handleSearch); + search.addEventListener('keydown', handleKey); + + // Give initial focus to main container so it can be scrolled using keys. + const main = document.getElementById('bodycontainer'); + if (main) { + main.focus(); + } +} diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/flamegraph.html b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/flamegraph.html new file mode 100644 index 0000000000..9866755bcd --- /dev/null +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/flamegraph.html @@ -0,0 +1,103 @@ + + + + + {{.Title}} + {{template "css" .}} + + + + + {{template "header" .}} +
+
+
+
+
+
+ {{template "script" .}} + + + + + diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/graph.html b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/graph.html new file mode 100644 index 0000000000..a113549fc4 --- /dev/null +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/graph.html @@ -0,0 +1,16 @@ + + + + + {{.Title}} + {{template "css" .}} + + + {{template "header" .}} +
+ {{.HTMLBody}} +
+ {{template "script" .}} + + + diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/header.html b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/header.html new file mode 100644 index 0000000000..66cabbbaa4 --- /dev/null +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/header.html @@ -0,0 +1,113 @@ +
+
+

pprof

+
+ + + + {{$sampleLen := len .SampleTypes}} + {{if gt $sampleLen 1}} + + {{end}} + + + + + + + +
+ +
+ +
+ {{.Title}} +
+ {{range .Legend}}
{{.}}
{{end}} +
+
+
+ +
+ +
+
Save options as
+ + {{range .Configs}}{{if .UserConfig}} + + +
+ +
+
Delete config
+
+ +
+ +
{{range .Errors}}
{{.}}
{{end}}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/plaintext.html b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/plaintext.html new file mode 100644 index 0000000000..9791cc7718 --- /dev/null +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/plaintext.html @@ -0,0 +1,18 @@ + + + + + {{.Title}} + {{template "css" .}} + + + {{template "header" .}} +
+
+      {{.TextBody}}
+    
+
+ {{template "script" .}} + + + diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/source.html b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/source.html new file mode 100644 index 0000000000..3212bee4a0 --- /dev/null +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/source.html @@ -0,0 +1,18 @@ + + + + + {{.Title}} + {{template "css" .}} + {{template "weblistcss" .}} + {{template "weblistjs" .}} + + + {{template "header" .}} +
+ {{.HTMLBody}} +
+ {{template "script" .}} + + + diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/top.html b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/top.html new file mode 100644 index 0000000000..86d9fcbdb0 --- /dev/null +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/top.html @@ -0,0 +1,114 @@ + + + + + {{.Title}} + {{template "css" .}} + + + + {{template "header" .}} +
+ + + + + + + + + + + + + +
FlatFlat%Sum%CumCum%NameInlined?
+
+ {{template "script" .}} + + + diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/settings.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/settings.go index f72314b185..1e9154c5f5 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/settings.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/settings.go @@ -79,7 +79,7 @@ type configMenuEntry struct { } // configMenu returns a list of items to add to a menu in the web UI. -func configMenu(fname string, url url.URL) []configMenuEntry { +func configMenu(fname string, u url.URL) []configMenuEntry { // Start with system configs. configs := []namedConfig{{Name: "Default", config: defaultConfig()}} if settings, err := readSettings(fname); err == nil { @@ -91,13 +91,15 @@ func configMenu(fname string, url url.URL) []configMenuEntry { result := make([]configMenuEntry, len(configs)) lastMatch := -1 for i, cfg := range configs { - dst, changed := cfg.config.makeURL(url) + dst, changed := cfg.config.makeURL(u) if !changed { lastMatch = i } + // Use a relative URL to work in presence of stripping/redirects in webui.go. + rel := &url.URL{RawQuery: dst.RawQuery, ForceQuery: true} result[i] = configMenuEntry{ Name: cfg.Name, - URL: dst.String(), + URL: rel.String(), UserConfig: (i != 0), } } diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/tagroot.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/tagroot.go index c2cdfa455e..c43d599982 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/tagroot.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/tagroot.go @@ -113,12 +113,17 @@ func formatLabelValues(s *profile.Sample, k string, outputUnit string) []string values = append(values, s.Label[k]...) numLabels := s.NumLabel[k] numUnits := s.NumUnit[k] - if len(numLabels) != len(numUnits) { + if len(numLabels) != len(numUnits) && len(numUnits) != 0 { return values } for i, numLabel := range numLabels { - unit := numUnits[i] - values = append(values, measurement.ScaledLabel(numLabel, unit, outputUnit)) + var value string + if len(numUnits) != 0 { + value = measurement.ScaledLabel(numLabel, numUnits[i], outputUnit) + } else { + value = measurement.ScaledLabel(numLabel, "", "") + } + values = append(values, value) } return values } diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go index b9c73271b8..94f32e3755 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go @@ -15,1400 +15,54 @@ package driver import ( + "embed" + "fmt" "html/template" + "os" - "github.com/google/pprof/third_party/d3" "github.com/google/pprof/third_party/d3flamegraph" ) +//go:embed html +var embeddedFiles embed.FS + // addTemplates adds a set of template definitions to templates. func addTemplates(templates *template.Template) { - template.Must(templates.Parse(`{{define "d3script"}}` + d3.JSSource + `{{end}}`)) - template.Must(templates.Parse(`{{define "d3flamegraphscript"}}` + d3flamegraph.JSSource + `{{end}}`)) - template.Must(templates.Parse(`{{define "d3flamegraphcss"}}` + d3flamegraph.CSSSource + `{{end}}`)) - template.Must(templates.Parse(` -{{define "css"}} - -{{end}} - -{{define "header"}} -
-
-

pprof

-
- - - - {{$sampleLen := len .SampleTypes}} - {{if gt $sampleLen 1}} - - {{end}} - - - - - - - -
- -
- -
- {{.Title}} -
- {{range .Legend}}
{{.}}
{{end}} -
-
-
- -
- -
-
Save options as
- - {{range .Configs}}{{if .UserConfig}} - - -
- -
-
Delete config
-
- -
- -
{{range .Errors}}
{{.}}
{{end}}
-{{end}} - -{{define "graph" -}} - - - - - {{.Title}} - {{template "css" .}} - - - {{template "header" .}} -
- {{.HTMLBody}} -
- {{template "script" .}} - - - -{{end}} - -{{define "script"}} - -{{end}} - -{{define "top" -}} - - - - - {{.Title}} - {{template "css" .}} - - - - {{template "header" .}} -
- - - - - - - - - - - - - -
FlatFlat%Sum%CumCum%NameInlined?
-
- {{template "script" .}} - - - -{{end}} - -{{define "sourcelisting" -}} - - - - - {{.Title}} - {{template "css" .}} - {{template "weblistcss" .}} - {{template "weblistjs" .}} - - - {{template "header" .}} -
- {{.HTMLBody}} -
- {{template "script" .}} - - - -{{end}} - -{{define "plaintext" -}} - - - - - {{.Title}} - {{template "css" .}} - - - {{template "header" .}} -
-
-      {{.TextBody}}
-    
-
- {{template "script" .}} - - - -{{end}} - -{{define "flamegraph" -}} - - - - - {{.Title}} - {{template "css" .}} - - - - - {{template "header" .}} -
-
-
-
-
-
- {{template "script" .}} - - - - - - -{{end}} -`)) + // Load specified file. + loadFile := func(fname string) string { + data, err := embeddedFiles.ReadFile(fname) + if err != nil { + fmt.Fprintf(os.Stderr, "internal/driver: embedded file %q not found\n", + fname) + os.Exit(1) + } + return string(data) + } + loadCSS := func(fname string) string { + return `` + "\n" + } + loadJS := func(fname string) string { + return `` + "\n" + } + + // Define a named template with specified contents. + def := func(name, contents string) { + sub := template.New(name) + template.Must(sub.Parse(contents)) + template.Must(templates.AddParseTree(name, sub.Tree)) + } + + // Pre-packaged third-party files. + def("d3flamegraphscript", d3flamegraph.JSSource) + def("d3flamegraphcss", d3flamegraph.CSSSource) + + // Embeded files. + def("css", loadCSS("html/common.css")) + def("header", loadFile("html/header.html")) + def("graph", loadFile("html/graph.html")) + def("script", loadJS("html/common.js")) + def("top", loadFile("html/top.html")) + def("sourcelisting", loadFile("html/source.html")) + def("plaintext", loadFile("html/plaintext.html")) + def("flamegraph", loadFile("html/flamegraph.html")) } diff --git a/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec.go b/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec.go index 6447092d3d..718481b078 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec.go @@ -165,9 +165,9 @@ func GetBuildID(binary io.ReaderAt) ([]byte, error) { return nil, nil } -// kernelBase caluclates the base for kernel mappings, which usually require +// kernelBase calculates the base for kernel mappings, which usually require // special handling. For kernel mappings, tools (like perf) use the address of -// the kernel relocation symbol (_text or _stext) as the mmap start. Additionaly, +// the kernel relocation symbol (_text or _stext) as the mmap start. Additionally, // for obfuscation, ChromeOS profiles have the kernel image remapped to the 0-th page. func kernelBase(loadSegment *elf.ProgHeader, stextOffset *uint64, start, limit, offset uint64) (uint64, bool) { const ( @@ -217,7 +217,7 @@ func kernelBase(loadSegment *elf.ProgHeader, stextOffset *uint64, start, limit, // GetBase determines the base address to subtract from virtual // address to get symbol table address. For an executable, the base // is 0. Otherwise, it's a shared library, and the base is the -// address where the mapping starts. The kernel needs special hanldling. +// address where the mapping starts. The kernel needs special handling. func GetBase(fh *elf.FileHeader, loadSegment *elf.ProgHeader, stextOffset *uint64, start, limit, offset uint64) (uint64, error) { if start == 0 && offset == 0 && (limit == ^uint64(0) || limit == 0) { diff --git a/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go b/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go index 8008675248..09d40fd2c9 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go @@ -126,7 +126,7 @@ func (b *builder) addLegend() { return } title := labels[0] - fmt.Fprintf(b, `subgraph cluster_L { "%s" [shape=box fontsize=16`, title) + fmt.Fprintf(b, `subgraph cluster_L { "%s" [shape=box fontsize=16`, escapeForDot(title)) fmt.Fprintf(b, ` label="%s\l"`, strings.Join(escapeAllForDot(labels), `\l`)) if b.config.LegendURL != "" { fmt.Fprintf(b, ` URL="%s" target="_blank"`, b.config.LegendURL) @@ -385,6 +385,9 @@ func multilinePrintableName(info *NodeInfo) string { infoCopy := *info infoCopy.Name = escapeForDot(ShortenFunctionName(infoCopy.Name)) infoCopy.Name = strings.Replace(infoCopy.Name, "::", `\n`, -1) + // Go type parameters are reported as "[...]" by Go pprof profiles. + // Keep this ellipsis rather than replacing with newlines below. + infoCopy.Name = strings.Replace(infoCopy.Name, "[...]", "[…]", -1) infoCopy.Name = strings.Replace(infoCopy.Name, ".", `\n`, -1) if infoCopy.File != "" { infoCopy.File = filepath.Base(infoCopy.File) @@ -485,7 +488,7 @@ func escapeAllForDot(in []string) []string { // escapeForDot escapes double quotes and backslashes, and replaces Graphviz's // "center" character (\n) with a left-justified character. -// See https://graphviz.org/doc/info/attrs.html#k:escString for more info. +// See https://graphviz.org/docs/attr-types/escString/ for more info. func escapeForDot(str string) string { return strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(str, `\`, `\\`), `"`, `\"`), "\n", `\l`) } diff --git a/src/cmd/vendor/github.com/google/pprof/internal/measurement/measurement.go b/src/cmd/vendor/github.com/google/pprof/internal/measurement/measurement.go index 53325740a3..b5fcfbc3e4 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/measurement/measurement.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/measurement/measurement.go @@ -110,10 +110,15 @@ func compatibleValueTypes(v1, v2 *profile.ValueType) bool { return false } - return v1.Unit == v2.Unit || - (timeUnits.sniffUnit(v1.Unit) != nil && timeUnits.sniffUnit(v2.Unit) != nil) || - (memoryUnits.sniffUnit(v1.Unit) != nil && memoryUnits.sniffUnit(v2.Unit) != nil) || - (gcuUnits.sniffUnit(v1.Unit) != nil && gcuUnits.sniffUnit(v2.Unit) != nil) + if v1.Unit == v2.Unit { + return true + } + for _, ut := range unitTypes { + if ut.sniffUnit(v1.Unit) != nil && ut.sniffUnit(v2.Unit) != nil { + return true + } + } + return false } // Scale a measurement from an unit to a different unit and returns @@ -125,14 +130,10 @@ func Scale(value int64, fromUnit, toUnit string) (float64, string) { v, u := Scale(-value, fromUnit, toUnit) return -v, u } - if m, u, ok := memoryUnits.convertUnit(value, fromUnit, toUnit); ok { - return m, u - } - if t, u, ok := timeUnits.convertUnit(value, fromUnit, toUnit); ok { - return t, u - } - if g, u, ok := gcuUnits.convertUnit(value, fromUnit, toUnit); ok { - return g, u + for _, ut := range unitTypes { + if v, u, ok := ut.convertUnit(value, fromUnit, toUnit); ok { + return v, u + } } // Skip non-interesting units. switch toUnit { @@ -257,7 +258,7 @@ func (ut unitType) convertUnit(value int64, fromUnitStr, toUnitStr string) (floa return v / toUnit.factor, toUnit.canonicalName, true } -var memoryUnits = unitType{ +var unitTypes = []unitType{{ units: []unit{ {"B", []string{"b", "byte"}, 1}, {"kB", []string{"kb", "kbyte", "kilobyte"}, float64(1 << 10)}, @@ -267,9 +268,7 @@ var memoryUnits = unitType{ {"PB", []string{"pb", "pbyte", "petabyte"}, float64(1 << 50)}, }, defaultUnit: unit{"B", []string{"b", "byte"}, 1}, -} - -var timeUnits = unitType{ +}, { units: []unit{ {"ns", []string{"ns", "nanosecond"}, float64(time.Nanosecond)}, {"us", []string{"μs", "us", "microsecond"}, float64(time.Microsecond)}, @@ -278,9 +277,7 @@ var timeUnits = unitType{ {"hrs", []string{"hour", "hr"}, float64(time.Hour)}, }, defaultUnit: unit{"s", []string{}, float64(time.Second)}, -} - -var gcuUnits = unitType{ +}, { units: []unit{ {"n*GCU", []string{"nanogcu"}, 1e-9}, {"u*GCU", []string{"microgcu"}, 1e-6}, @@ -293,4 +290,4 @@ var gcuUnits = unitType{ {"P*GCU", []string{"petagcu"}, 1e15}, }, defaultUnit: unit{"GCU", []string{}, 1.0}, -} +}} diff --git a/src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go b/src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go index a57a0b20a9..98eb1dd817 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go @@ -109,8 +109,10 @@ type MappingSources map[string][]struct { type ObjTool interface { // Open opens the named object file. If the object is a shared // library, start/limit/offset are the addresses where it is mapped - // into memory in the address space being inspected. - Open(file string, start, limit, offset uint64) (ObjFile, error) + // into memory in the address space being inspected. If the object + // is a linux kernel, relocationSymbol is the name of the symbol + // corresponding to the start address. + Open(file string, start, limit, offset uint64, relocationSymbol string) (ObjFile, error) // Disasm disassembles the named object file, starting at // the start address and stopping at (before) the end address. diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/report.go b/src/cmd/vendor/github.com/google/pprof/internal/report/report.go index e2fb00314c..36ddf2e934 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/report/report.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/report/report.go @@ -526,7 +526,7 @@ func symbolsFromBinaries(prof *profile.Profile, g *graph.Graph, rx *regexp.Regex } } - f, err := obj.Open(m.File, m.Start, m.Limit, m.Offset) + f, err := obj.Open(m.File, m.Start, m.Limit, m.Offset, m.KernelRelocationSymbol) if err != nil { fmt.Printf("%v\n", err) continue diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/source.go b/src/cmd/vendor/github.com/google/pprof/internal/report/source.go index 33d04c591d..d8b4395265 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/report/source.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/report/source.go @@ -744,7 +744,7 @@ func (sp *sourcePrinter) objectFile(m *profile.Mapping) plugin.ObjFile { if object, ok := sp.objects[m.File]; ok { return object // May be nil if we detected an error earlier. } - object, err := sp.objectTool.Open(m.File, m.Start, m.Limit, m.Offset) + object, err := sp.objectTool.Open(m.File, m.Start, m.Limit, m.Offset, m.KernelRelocationSymbol) if err != nil { object = nil } diff --git a/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer.go b/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer.go index d741e7ad7f..d243b800a9 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer.go @@ -205,49 +205,64 @@ func Demangle(prof *profile.Profile, force bool, demanglerMode string) { } } - var options []demangle.Option + options := demanglerModeToOptions(demanglerMode) + for _, fn := range prof.Function { + demangleSingleFunction(fn, options) + } +} + +func demanglerModeToOptions(demanglerMode string) []demangle.Option { switch demanglerMode { case "": // demangled, simplified: no parameters, no templates, no return type - options = []demangle.Option{demangle.NoParams, demangle.NoTemplateParams} + return []demangle.Option{demangle.NoParams, demangle.NoTemplateParams} case "templates": // demangled, simplified: no parameters, no return type - options = []demangle.Option{demangle.NoParams} + return []demangle.Option{demangle.NoParams} case "full": - options = []demangle.Option{demangle.NoClones} + return []demangle.Option{demangle.NoClones} case "none": // no demangling - return + return []demangle.Option{} } + panic(fmt.Sprintf("unknown demanglerMode %s", demanglerMode)) +} + +func demangleSingleFunction(fn *profile.Function, options []demangle.Option) { + if fn.Name != "" && fn.SystemName != fn.Name { + return // Already demangled. + } // Copy the options because they may be updated by the call. o := make([]demangle.Option, len(options)) - for _, fn := range prof.Function { - if fn.Name != "" && fn.SystemName != fn.Name { - continue // Already demangled. - } - copy(o, options) - if demangled := demangle.Filter(fn.SystemName, o...); demangled != fn.SystemName { - fn.Name = demangled - continue - } - // Could not demangle. Apply heuristics in case the name is - // already demangled. - name := fn.SystemName - if looksLikeDemangledCPlusPlus(name) { - if demanglerMode == "" || demanglerMode == "templates" { + copy(o, options) + if demangled := demangle.Filter(fn.SystemName, o...); demangled != fn.SystemName { + fn.Name = demangled + return + } + // Could not demangle. Apply heuristics in case the name is + // already demangled. + name := fn.SystemName + if looksLikeDemangledCPlusPlus(name) { + for _, o := range options { + switch o { + case demangle.NoParams: name = removeMatching(name, '(', ')') - } - if demanglerMode == "" { + case demangle.NoTemplateParams: name = removeMatching(name, '<', '>') } } - fn.Name = name } + fn.Name = name } // looksLikeDemangledCPlusPlus is a heuristic to decide if a name is // the result of demangling C++. If so, further heuristics will be // applied to simplify the name. func looksLikeDemangledCPlusPlus(demangled string) bool { - if strings.Contains(demangled, ".<") { // Skip java names of the form "class." + // Skip java names of the form "class.". + if strings.Contains(demangled, ".<") { + return false + } + // Skip Go names of the form "foo.(*Bar[...]).Method". + if strings.Contains(demangled, "]).") { return false } return strings.ContainsAny(demangled, "<>[]") || strings.Contains(demangled, "::") @@ -325,7 +340,10 @@ func newMapping(prof *profile.Profile, obj plugin.ObjTool, ui plugin.UI, force b } name := filepath.Base(m.File) - f, err := obj.Open(m.File, m.Start, m.Limit, m.Offset) + if m.BuildID != "" { + name += fmt.Sprintf(" (build ID %s)", m.BuildID) + } + f, err := obj.Open(m.File, m.Start, m.Limit, m.Offset, m.KernelRelocationSymbol) if err != nil { ui.PrintErr("Local symbolization failed for ", name, ": ", err) missingBinaries = true diff --git a/src/cmd/vendor/github.com/google/pprof/profile/encode.go b/src/cmd/vendor/github.com/google/pprof/profile/encode.go index ab7f03ae26..96aa271e54 100644 --- a/src/cmd/vendor/github.com/google/pprof/profile/encode.go +++ b/src/cmd/vendor/github.com/google/pprof/profile/encode.go @@ -17,6 +17,7 @@ package profile import ( "errors" "sort" + "strings" ) func (p *Profile) decoder() []decoder { @@ -252,6 +253,14 @@ func (p *Profile) postDecode() error { } else { mappings[m.ID] = m } + + // If this a main linux kernel mapping with a relocation symbol suffix + // ("[kernel.kallsyms]_text"), extract said suffix. + // It is fairly hacky to handle at this level, but the alternatives appear even worse. + if strings.HasPrefix(m.File, "[kernel.kallsyms]") { + m.KernelRelocationSymbol = strings.ReplaceAll(m.File, "[kernel.kallsyms]", "") + } + } functions := make(map[uint64]*Function, len(p.Function)) diff --git a/src/cmd/vendor/github.com/google/pprof/profile/legacy_profile.go b/src/cmd/vendor/github.com/google/pprof/profile/legacy_profile.go index 0c8f3bb5b7..9ba9a77c92 100644 --- a/src/cmd/vendor/github.com/google/pprof/profile/legacy_profile.go +++ b/src/cmd/vendor/github.com/google/pprof/profile/legacy_profile.go @@ -295,11 +295,12 @@ func get64b(b []byte) (uint64, []byte) { // // The general format for profilez samples is a sequence of words in // binary format. The first words are a header with the following data: -// 1st word -- 0 -// 2nd word -- 3 -// 3rd word -- 0 if a c++ application, 1 if a java application. -// 4th word -- Sampling period (in microseconds). -// 5th word -- Padding. +// +// 1st word -- 0 +// 2nd word -- 3 +// 3rd word -- 0 if a c++ application, 1 if a java application. +// 4th word -- Sampling period (in microseconds). +// 5th word -- Padding. func parseCPU(b []byte) (*Profile, error) { var parse func([]byte) (uint64, []byte) var n1, n2, n3, n4, n5 uint64 @@ -403,15 +404,18 @@ func cleanupDuplicateLocations(p *Profile) { // // profilez samples are a repeated sequence of stack frames of the // form: -// 1st word -- The number of times this stack was encountered. -// 2nd word -- The size of the stack (StackSize). -// 3rd word -- The first address on the stack. -// ... -// StackSize + 2 -- The last address on the stack +// +// 1st word -- The number of times this stack was encountered. +// 2nd word -- The size of the stack (StackSize). +// 3rd word -- The first address on the stack. +// ... +// StackSize + 2 -- The last address on the stack +// // The last stack trace is of the form: -// 1st word -- 0 -// 2nd word -- 1 -// 3rd word -- 0 +// +// 1st word -- 0 +// 2nd word -- 1 +// 3rd word -- 0 // // Addresses from stack traces may point to the next instruction after // each call. Optionally adjust by -1 to land somewhere on the actual diff --git a/src/cmd/vendor/github.com/google/pprof/profile/merge.go b/src/cmd/vendor/github.com/google/pprof/profile/merge.go index 9978e7330e..6fcd11de19 100644 --- a/src/cmd/vendor/github.com/google/pprof/profile/merge.go +++ b/src/cmd/vendor/github.com/google/pprof/profile/merge.go @@ -303,16 +303,17 @@ func (pm *profileMerger) mapMapping(src *Mapping) mapInfo { return mi } m := &Mapping{ - ID: uint64(len(pm.p.Mapping) + 1), - Start: src.Start, - Limit: src.Limit, - Offset: src.Offset, - File: src.File, - BuildID: src.BuildID, - HasFunctions: src.HasFunctions, - HasFilenames: src.HasFilenames, - HasLineNumbers: src.HasLineNumbers, - HasInlineFrames: src.HasInlineFrames, + ID: uint64(len(pm.p.Mapping) + 1), + Start: src.Start, + Limit: src.Limit, + Offset: src.Offset, + File: src.File, + KernelRelocationSymbol: src.KernelRelocationSymbol, + BuildID: src.BuildID, + HasFunctions: src.HasFunctions, + HasFilenames: src.HasFilenames, + HasLineNumbers: src.HasLineNumbers, + HasInlineFrames: src.HasInlineFrames, } pm.p.Mapping = append(pm.p.Mapping, m) diff --git a/src/cmd/vendor/github.com/google/pprof/profile/profile.go b/src/cmd/vendor/github.com/google/pprof/profile/profile.go index 2590c8ddb4..5a3807f978 100644 --- a/src/cmd/vendor/github.com/google/pprof/profile/profile.go +++ b/src/cmd/vendor/github.com/google/pprof/profile/profile.go @@ -106,6 +106,15 @@ type Mapping struct { fileX int64 buildIDX int64 + + // Name of the kernel relocation symbol ("_text" or "_stext"), extracted from File. + // For linux kernel mappings generated by some tools, correct symbolization depends + // on knowing which of the two possible relocation symbols was used for `Start`. + // This is given to us as a suffix in `File` (e.g. "[kernel.kallsyms]_stext"). + // + // Note, this public field is not persisted in the proto. For the purposes of + // copying / merging / hashing profiles, it is considered subsumed by `File`. + KernelRelocationSymbol string } // Location corresponds to Profile.Location diff --git a/src/cmd/vendor/github.com/google/pprof/third_party/d3/LICENSE b/src/cmd/vendor/github.com/google/pprof/third_party/d3/LICENSE deleted file mode 100644 index 1d9d875edb..0000000000 --- a/src/cmd/vendor/github.com/google/pprof/third_party/d3/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright 2010-2017 Mike Bostock -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the author nor the names of contributors may be used to - endorse or promote products derived from this software without specific prior - written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/cmd/vendor/github.com/google/pprof/third_party/d3/README.md b/src/cmd/vendor/github.com/google/pprof/third_party/d3/README.md deleted file mode 100644 index 53e6eb61eb..0000000000 --- a/src/cmd/vendor/github.com/google/pprof/third_party/d3/README.md +++ /dev/null @@ -1,119 +0,0 @@ -# Building a customized D3.js bundle - -The D3.js version distributed with pprof is customized to only include the modules required by pprof. - -## Dependencies - -First, it's necessary to pull all bundle dependencies. We will use a JavaScript package manager, [npm](https://www.npmjs.com/), to accomplish that. npm dependencies are declared in a `package.json` file, so create one with the following configuration: - -```js -{ - "name": "d3-pprof", - "version": "1.0.0", - "description": "A d3.js bundle for pprof.", - "scripts": { - "prepare": "rollup -c && uglifyjs d3.js -c -m -o d3.min.js" - }, - "license": "Apache-2.0", - "devDependencies": { - "d3-selection": "1.1.0", - "d3-hierarchy": "1.1.5", - "d3-scale": "1.0.6", - "d3-format": "1.2.0", - "d3-ease": "1.0.3", - "d3-array": "1.2.1", - "d3-collection": "1.0.4", - "d3-transition": "1.1.0", - "rollup": "0.51.8", - "rollup-plugin-node-resolve": "3", - "uglify-js": "3.1.10" - } -} -``` - -Besides the bundle dependencies, the `package.json` file also specifies a script called `prepare`, which will be executed to create the bundle after `Rollup` is installed. - -## Bundler - -The simplest way of creating a custom bundle is to use a bundler, such as [Rollup](https://rollupjs.org/) or [Webpack](https://webpack.js.org/). Rollup will be used in this example. - -First, create a `rollup.config.js` file, containing the configuration Rollup should use to build the bundle. - -```js -import node from "rollup-plugin-node-resolve"; - -export default { - input: "index.js", - output: { - format: "umd", - file: "d3.js" - }, - name: "d3", - plugins: [node()], - sourcemap: false -}; -``` - -Then create an `index.js` file containing all the functions that need to be exported in the bundle. - -```js -export { - select, - selection, - event, -} from "d3-selection"; - -export { - hierarchy, - partition, -} from "d3-hierarchy"; - -export { - scaleLinear, -} from "d3-scale"; - -export { - format, -} from "d3-format"; - -export { - easeCubic, -} from "d3-ease"; - -export { - ascending, -} from "d3-array"; - -export { - map, -} from "d3-collection"; - -export { - transition, -} from "d3-transition"; -``` - -## Building - -Once all files were created, execute the following commands to pull all dependencies and build the bundle. - -``` -% npm install -% npm run prepare -``` - -This will create two files, `d3.js` and `d3.min.js`, the custom D3.js bundle and its minified version respectively. - -# References - -## D3 Custom Bundle - -A demonstration of building a custom D3 4.0 bundle using ES2015 modules and Rollup. - -[bl.ocks.org/mbostock/bb09af4c39c79cffcde4](https://bl.ocks.org/mbostock/bb09af4c39c79cffcde4) - -## d3-pprof - -A repository containing all previously mentioned configuration files and the generated custom bundle. - -[github.com/spiermar/d3-pprof](https://github.com/spiermar/d3-pprof) \ No newline at end of file diff --git a/src/cmd/vendor/github.com/google/pprof/third_party/d3/d3.go b/src/cmd/vendor/github.com/google/pprof/third_party/d3/d3.go deleted file mode 100644 index 7d217c71bf..0000000000 --- a/src/cmd/vendor/github.com/google/pprof/third_party/d3/d3.go +++ /dev/null @@ -1,4675 +0,0 @@ -// D3.js is a JavaScript library for manipulating documents based on data. -// https://github.com/d3/d3 -// See LICENSE file for license details -// Custom build for pprof (https://github.com/spiermar/d3-pprof) - -package d3 - -// JSSource returns the d3.js file -const JSSource = ` -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : - typeof define === 'function' && define.amd ? define(['exports'], factory) : - (factory((global.d3 = {}))); -}(this, (function (exports) { 'use strict'; - -var xhtml = "http://www.w3.org/1999/xhtml"; - -var namespaces = { - svg: "http://www.w3.org/2000/svg", - xhtml: xhtml, - xlink: "http://www.w3.org/1999/xlink", - xml: "http://www.w3.org/XML/1998/namespace", - xmlns: "http://www.w3.org/2000/xmlns/" -}; - -var namespace = function(name) { - var prefix = name += "", i = prefix.indexOf(":"); - if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1); - return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name; -}; - -function creatorInherit(name) { - return function() { - var document = this.ownerDocument, - uri = this.namespaceURI; - return uri === xhtml && document.documentElement.namespaceURI === xhtml - ? document.createElement(name) - : document.createElementNS(uri, name); - }; -} - -function creatorFixed(fullname) { - return function() { - return this.ownerDocument.createElementNS(fullname.space, fullname.local); - }; -} - -var creator = function(name) { - var fullname = namespace(name); - return (fullname.local - ? creatorFixed - : creatorInherit)(fullname); -}; - -var matcher = function(selector) { - return function() { - return this.matches(selector); - }; -}; - -if (typeof document !== "undefined") { - var element = document.documentElement; - if (!element.matches) { - var vendorMatches = element.webkitMatchesSelector - || element.msMatchesSelector - || element.mozMatchesSelector - || element.oMatchesSelector; - matcher = function(selector) { - return function() { - return vendorMatches.call(this, selector); - }; - }; - } -} - -var matcher$1 = matcher; - -var filterEvents = {}; - -exports.event = null; - -if (typeof document !== "undefined") { - var element$1 = document.documentElement; - if (!("onmouseenter" in element$1)) { - filterEvents = {mouseenter: "mouseover", mouseleave: "mouseout"}; - } -} - -function filterContextListener(listener, index, group) { - listener = contextListener(listener, index, group); - return function(event) { - var related = event.relatedTarget; - if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) { - listener.call(this, event); - } - }; -} - -function contextListener(listener, index, group) { - return function(event1) { - var event0 = exports.event; // Events can be reentrant (e.g., focus). - exports.event = event1; - try { - listener.call(this, this.__data__, index, group); - } finally { - exports.event = event0; - } - }; -} - -function parseTypenames(typenames) { - return typenames.trim().split(/^|\s+/).map(function(t) { - var name = "", i = t.indexOf("."); - if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); - return {type: t, name: name}; - }); -} - -function onRemove(typename) { - return function() { - var on = this.__on; - if (!on) return; - for (var j = 0, i = -1, m = on.length, o; j < m; ++j) { - if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) { - this.removeEventListener(o.type, o.listener, o.capture); - } else { - on[++i] = o; - } - } - if (++i) on.length = i; - else delete this.__on; - }; -} - -function onAdd(typename, value, capture) { - var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener; - return function(d, i, group) { - var on = this.__on, o, listener = wrap(value, i, group); - if (on) for (var j = 0, m = on.length; j < m; ++j) { - if ((o = on[j]).type === typename.type && o.name === typename.name) { - this.removeEventListener(o.type, o.listener, o.capture); - this.addEventListener(o.type, o.listener = listener, o.capture = capture); - o.value = value; - return; - } - } - this.addEventListener(typename.type, listener, capture); - o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture}; - if (!on) this.__on = [o]; - else on.push(o); - }; -} - -var selection_on = function(typename, value, capture) { - var typenames = parseTypenames(typename + ""), i, n = typenames.length, t; - - if (arguments.length < 2) { - var on = this.node().__on; - if (on) for (var j = 0, m = on.length, o; j < m; ++j) { - for (i = 0, o = on[j]; i < n; ++i) { - if ((t = typenames[i]).type === o.type && t.name === o.name) { - return o.value; - } - } - } - return; - } - - on = value ? onAdd : onRemove; - if (capture == null) capture = false; - for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture)); - return this; -}; - -function none() {} - -var selector = function(selector) { - return selector == null ? none : function() { - return this.querySelector(selector); - }; -}; - -var selection_select = function(select) { - if (typeof select !== "function") select = selector(select); - - for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) { - if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) { - if ("__data__" in node) subnode.__data__ = node.__data__; - subgroup[i] = subnode; - } - } - } - - return new Selection(subgroups, this._parents); -}; - -function empty() { - return []; -} - -var selectorAll = function(selector) { - return selector == null ? empty : function() { - return this.querySelectorAll(selector); - }; -}; - -var selection_selectAll = function(select) { - if (typeof select !== "function") select = selectorAll(select); - - for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { - if (node = group[i]) { - subgroups.push(select.call(node, node.__data__, i, group)); - parents.push(node); - } - } - } - - return new Selection(subgroups, parents); -}; - -var selection_filter = function(match) { - if (typeof match !== "function") match = matcher$1(match); - - for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) { - if ((node = group[i]) && match.call(node, node.__data__, i, group)) { - subgroup.push(node); - } - } - } - - return new Selection(subgroups, this._parents); -}; - -var sparse = function(update) { - return new Array(update.length); -}; - -var selection_enter = function() { - return new Selection(this._enter || this._groups.map(sparse), this._parents); -}; - -function EnterNode(parent, datum) { - this.ownerDocument = parent.ownerDocument; - this.namespaceURI = parent.namespaceURI; - this._next = null; - this._parent = parent; - this.__data__ = datum; -} - -EnterNode.prototype = { - constructor: EnterNode, - appendChild: function(child) { return this._parent.insertBefore(child, this._next); }, - insertBefore: function(child, next) { return this._parent.insertBefore(child, next); }, - querySelector: function(selector) { return this._parent.querySelector(selector); }, - querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); } -}; - -var constant = function(x) { - return function() { - return x; - }; -}; - -var keyPrefix = "$"; // Protect against keys like “__proto__”. - -function bindIndex(parent, group, enter, update, exit, data) { - var i = 0, - node, - groupLength = group.length, - dataLength = data.length; - - // Put any non-null nodes that fit into update. - // Put any null nodes into enter. - // Put any remaining data into enter. - for (; i < dataLength; ++i) { - if (node = group[i]) { - node.__data__ = data[i]; - update[i] = node; - } else { - enter[i] = new EnterNode(parent, data[i]); - } - } - - // Put any non-null nodes that don’t fit into exit. - for (; i < groupLength; ++i) { - if (node = group[i]) { - exit[i] = node; - } - } -} - -function bindKey(parent, group, enter, update, exit, data, key) { - var i, - node, - nodeByKeyValue = {}, - groupLength = group.length, - dataLength = data.length, - keyValues = new Array(groupLength), - keyValue; - - // Compute the key for each node. - // If multiple nodes have the same key, the duplicates are added to exit. - for (i = 0; i < groupLength; ++i) { - if (node = group[i]) { - keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group); - if (keyValue in nodeByKeyValue) { - exit[i] = node; - } else { - nodeByKeyValue[keyValue] = node; - } - } - } - - // Compute the key for each datum. - // If there a node associated with this key, join and add it to update. - // If there is not (or the key is a duplicate), add it to enter. - for (i = 0; i < dataLength; ++i) { - keyValue = keyPrefix + key.call(parent, data[i], i, data); - if (node = nodeByKeyValue[keyValue]) { - update[i] = node; - node.__data__ = data[i]; - nodeByKeyValue[keyValue] = null; - } else { - enter[i] = new EnterNode(parent, data[i]); - } - } - - // Add any remaining nodes that were not bound to data to exit. - for (i = 0; i < groupLength; ++i) { - if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) { - exit[i] = node; - } - } -} - -var selection_data = function(value, key) { - if (!value) { - data = new Array(this.size()), j = -1; - this.each(function(d) { data[++j] = d; }); - return data; - } - - var bind = key ? bindKey : bindIndex, - parents = this._parents, - groups = this._groups; - - if (typeof value !== "function") value = constant(value); - - for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) { - var parent = parents[j], - group = groups[j], - groupLength = group.length, - data = value.call(parent, parent && parent.__data__, j, parents), - dataLength = data.length, - enterGroup = enter[j] = new Array(dataLength), - updateGroup = update[j] = new Array(dataLength), - exitGroup = exit[j] = new Array(groupLength); - - bind(parent, group, enterGroup, updateGroup, exitGroup, data, key); - - // Now connect the enter nodes to their following update node, such that - // appendChild can insert the materialized enter node before this node, - // rather than at the end of the parent node. - for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) { - if (previous = enterGroup[i0]) { - if (i0 >= i1) i1 = i0 + 1; - while (!(next = updateGroup[i1]) && ++i1 < dataLength); - previous._next = next || null; - } - } - } - - update = new Selection(update, parents); - update._enter = enter; - update._exit = exit; - return update; -}; - -var selection_exit = function() { - return new Selection(this._exit || this._groups.map(sparse), this._parents); -}; - -var selection_merge = function(selection$$1) { - - for (var groups0 = this._groups, groups1 = selection$$1._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { - for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { - if (node = group0[i] || group1[i]) { - merge[i] = node; - } - } - } - - for (; j < m0; ++j) { - merges[j] = groups0[j]; - } - - return new Selection(merges, this._parents); -}; - -var selection_order = function() { - - for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) { - for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) { - if (node = group[i]) { - if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next); - next = node; - } - } - } - - return this; -}; - -var selection_sort = function(compare) { - if (!compare) compare = ascending; - - function compareNode(a, b) { - return a && b ? compare(a.__data__, b.__data__) : !a - !b; - } - - for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) { - if (node = group[i]) { - sortgroup[i] = node; - } - } - sortgroup.sort(compareNode); - } - - return new Selection(sortgroups, this._parents).order(); -}; - -function ascending(a, b) { - return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; -} - -var selection_call = function() { - var callback = arguments[0]; - arguments[0] = this; - callback.apply(null, arguments); - return this; -}; - -var selection_nodes = function() { - var nodes = new Array(this.size()), i = -1; - this.each(function() { nodes[++i] = this; }); - return nodes; -}; - -var selection_node = function() { - - for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { - for (var group = groups[j], i = 0, n = group.length; i < n; ++i) { - var node = group[i]; - if (node) return node; - } - } - - return null; -}; - -var selection_size = function() { - var size = 0; - this.each(function() { ++size; }); - return size; -}; - -var selection_empty = function() { - return !this.node(); -}; - -var selection_each = function(callback) { - - for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { - for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) { - if (node = group[i]) callback.call(node, node.__data__, i, group); - } - } - - return this; -}; - -function attrRemove(name) { - return function() { - this.removeAttribute(name); - }; -} - -function attrRemoveNS(fullname) { - return function() { - this.removeAttributeNS(fullname.space, fullname.local); - }; -} - -function attrConstant(name, value) { - return function() { - this.setAttribute(name, value); - }; -} - -function attrConstantNS(fullname, value) { - return function() { - this.setAttributeNS(fullname.space, fullname.local, value); - }; -} - -function attrFunction(name, value) { - return function() { - var v = value.apply(this, arguments); - if (v == null) this.removeAttribute(name); - else this.setAttribute(name, v); - }; -} - -function attrFunctionNS(fullname, value) { - return function() { - var v = value.apply(this, arguments); - if (v == null) this.removeAttributeNS(fullname.space, fullname.local); - else this.setAttributeNS(fullname.space, fullname.local, v); - }; -} - -var selection_attr = function(name, value) { - var fullname = namespace(name); - - if (arguments.length < 2) { - var node = this.node(); - return fullname.local - ? node.getAttributeNS(fullname.space, fullname.local) - : node.getAttribute(fullname); - } - - return this.each((value == null - ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function" - ? (fullname.local ? attrFunctionNS : attrFunction) - : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value)); -}; - -var defaultView = function(node) { - return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node - || (node.document && node) // node is a Window - || node.defaultView; // node is a Document -}; - -function styleRemove(name) { - return function() { - this.style.removeProperty(name); - }; -} - -function styleConstant(name, value, priority) { - return function() { - this.style.setProperty(name, value, priority); - }; -} - -function styleFunction(name, value, priority) { - return function() { - var v = value.apply(this, arguments); - if (v == null) this.style.removeProperty(name); - else this.style.setProperty(name, v, priority); - }; -} - -var selection_style = function(name, value, priority) { - return arguments.length > 1 - ? this.each((value == null - ? styleRemove : typeof value === "function" - ? styleFunction - : styleConstant)(name, value, priority == null ? "" : priority)) - : styleValue(this.node(), name); -}; - -function styleValue(node, name) { - return node.style.getPropertyValue(name) - || defaultView(node).getComputedStyle(node, null).getPropertyValue(name); -} - -function propertyRemove(name) { - return function() { - delete this[name]; - }; -} - -function propertyConstant(name, value) { - return function() { - this[name] = value; - }; -} - -function propertyFunction(name, value) { - return function() { - var v = value.apply(this, arguments); - if (v == null) delete this[name]; - else this[name] = v; - }; -} - -var selection_property = function(name, value) { - return arguments.length > 1 - ? this.each((value == null - ? propertyRemove : typeof value === "function" - ? propertyFunction - : propertyConstant)(name, value)) - : this.node()[name]; -}; - -function classArray(string) { - return string.trim().split(/^|\s+/); -} - -function classList(node) { - return node.classList || new ClassList(node); -} - -function ClassList(node) { - this._node = node; - this._names = classArray(node.getAttribute("class") || ""); -} - -ClassList.prototype = { - add: function(name) { - var i = this._names.indexOf(name); - if (i < 0) { - this._names.push(name); - this._node.setAttribute("class", this._names.join(" ")); - } - }, - remove: function(name) { - var i = this._names.indexOf(name); - if (i >= 0) { - this._names.splice(i, 1); - this._node.setAttribute("class", this._names.join(" ")); - } - }, - contains: function(name) { - return this._names.indexOf(name) >= 0; - } -}; - -function classedAdd(node, names) { - var list = classList(node), i = -1, n = names.length; - while (++i < n) list.add(names[i]); -} - -function classedRemove(node, names) { - var list = classList(node), i = -1, n = names.length; - while (++i < n) list.remove(names[i]); -} - -function classedTrue(names) { - return function() { - classedAdd(this, names); - }; -} - -function classedFalse(names) { - return function() { - classedRemove(this, names); - }; -} - -function classedFunction(names, value) { - return function() { - (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names); - }; -} - -var selection_classed = function(name, value) { - var names = classArray(name + ""); - - if (arguments.length < 2) { - var list = classList(this.node()), i = -1, n = names.length; - while (++i < n) if (!list.contains(names[i])) return false; - return true; - } - - return this.each((typeof value === "function" - ? classedFunction : value - ? classedTrue - : classedFalse)(names, value)); -}; - -function textRemove() { - this.textContent = ""; -} - -function textConstant(value) { - return function() { - this.textContent = value; - }; -} - -function textFunction(value) { - return function() { - var v = value.apply(this, arguments); - this.textContent = v == null ? "" : v; - }; -} - -var selection_text = function(value) { - return arguments.length - ? this.each(value == null - ? textRemove : (typeof value === "function" - ? textFunction - : textConstant)(value)) - : this.node().textContent; -}; - -function htmlRemove() { - this.innerHTML = ""; -} - -function htmlConstant(value) { - return function() { - this.innerHTML = value; - }; -} - -function htmlFunction(value) { - return function() { - var v = value.apply(this, arguments); - this.innerHTML = v == null ? "" : v; - }; -} - -var selection_html = function(value) { - return arguments.length - ? this.each(value == null - ? htmlRemove : (typeof value === "function" - ? htmlFunction - : htmlConstant)(value)) - : this.node().innerHTML; -}; - -function raise() { - if (this.nextSibling) this.parentNode.appendChild(this); -} - -var selection_raise = function() { - return this.each(raise); -}; - -function lower() { - if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild); -} - -var selection_lower = function() { - return this.each(lower); -}; - -var selection_append = function(name) { - var create = typeof name === "function" ? name : creator(name); - return this.select(function() { - return this.appendChild(create.apply(this, arguments)); - }); -}; - -function constantNull() { - return null; -} - -var selection_insert = function(name, before) { - var create = typeof name === "function" ? name : creator(name), - select = before == null ? constantNull : typeof before === "function" ? before : selector(before); - return this.select(function() { - return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null); - }); -}; - -function remove() { - var parent = this.parentNode; - if (parent) parent.removeChild(this); -} - -var selection_remove = function() { - return this.each(remove); -}; - -var selection_datum = function(value) { - return arguments.length - ? this.property("__data__", value) - : this.node().__data__; -}; - -function dispatchEvent(node, type, params) { - var window = defaultView(node), - event = window.CustomEvent; - - if (typeof event === "function") { - event = new event(type, params); - } else { - event = window.document.createEvent("Event"); - if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail; - else event.initEvent(type, false, false); - } - - node.dispatchEvent(event); -} - -function dispatchConstant(type, params) { - return function() { - return dispatchEvent(this, type, params); - }; -} - -function dispatchFunction(type, params) { - return function() { - return dispatchEvent(this, type, params.apply(this, arguments)); - }; -} - -var selection_dispatch = function(type, params) { - return this.each((typeof params === "function" - ? dispatchFunction - : dispatchConstant)(type, params)); -}; - -var root = [null]; - -function Selection(groups, parents) { - this._groups = groups; - this._parents = parents; -} - -function selection() { - return new Selection([[document.documentElement]], root); -} - -Selection.prototype = selection.prototype = { - constructor: Selection, - select: selection_select, - selectAll: selection_selectAll, - filter: selection_filter, - data: selection_data, - enter: selection_enter, - exit: selection_exit, - merge: selection_merge, - order: selection_order, - sort: selection_sort, - call: selection_call, - nodes: selection_nodes, - node: selection_node, - size: selection_size, - empty: selection_empty, - each: selection_each, - attr: selection_attr, - style: selection_style, - property: selection_property, - classed: selection_classed, - text: selection_text, - html: selection_html, - raise: selection_raise, - lower: selection_lower, - append: selection_append, - insert: selection_insert, - remove: selection_remove, - datum: selection_datum, - on: selection_on, - dispatch: selection_dispatch -}; - -var select = function(selector) { - return typeof selector === "string" - ? new Selection([[document.querySelector(selector)]], [document.documentElement]) - : new Selection([[selector]], root); -}; - -function count(node) { - var sum = 0, - children = node.children, - i = children && children.length; - if (!i) sum = 1; - else while (--i >= 0) sum += children[i].value; - node.value = sum; -} - -var node_count = function() { - return this.eachAfter(count); -}; - -var node_each = function(callback) { - var node = this, current, next = [node], children, i, n; - do { - current = next.reverse(), next = []; - while (node = current.pop()) { - callback(node), children = node.children; - if (children) for (i = 0, n = children.length; i < n; ++i) { - next.push(children[i]); - } - } - } while (next.length); - return this; -}; - -var node_eachBefore = function(callback) { - var node = this, nodes = [node], children, i; - while (node = nodes.pop()) { - callback(node), children = node.children; - if (children) for (i = children.length - 1; i >= 0; --i) { - nodes.push(children[i]); - } - } - return this; -}; - -var node_eachAfter = function(callback) { - var node = this, nodes = [node], next = [], children, i, n; - while (node = nodes.pop()) { - next.push(node), children = node.children; - if (children) for (i = 0, n = children.length; i < n; ++i) { - nodes.push(children[i]); - } - } - while (node = next.pop()) { - callback(node); - } - return this; -}; - -var node_sum = function(value) { - return this.eachAfter(function(node) { - var sum = +value(node.data) || 0, - children = node.children, - i = children && children.length; - while (--i >= 0) sum += children[i].value; - node.value = sum; - }); -}; - -var node_sort = function(compare) { - return this.eachBefore(function(node) { - if (node.children) { - node.children.sort(compare); - } - }); -}; - -var node_path = function(end) { - var start = this, - ancestor = leastCommonAncestor(start, end), - nodes = [start]; - while (start !== ancestor) { - start = start.parent; - nodes.push(start); - } - var k = nodes.length; - while (end !== ancestor) { - nodes.splice(k, 0, end); - end = end.parent; - } - return nodes; -}; - -function leastCommonAncestor(a, b) { - if (a === b) return a; - var aNodes = a.ancestors(), - bNodes = b.ancestors(), - c = null; - a = aNodes.pop(); - b = bNodes.pop(); - while (a === b) { - c = a; - a = aNodes.pop(); - b = bNodes.pop(); - } - return c; -} - -var node_ancestors = function() { - var node = this, nodes = [node]; - while (node = node.parent) { - nodes.push(node); - } - return nodes; -}; - -var node_descendants = function() { - var nodes = []; - this.each(function(node) { - nodes.push(node); - }); - return nodes; -}; - -var node_leaves = function() { - var leaves = []; - this.eachBefore(function(node) { - if (!node.children) { - leaves.push(node); - } - }); - return leaves; -}; - -var node_links = function() { - var root = this, links = []; - root.each(function(node) { - if (node !== root) { // Don’t include the root’s parent, if any. - links.push({source: node.parent, target: node}); - } - }); - return links; -}; - -function hierarchy(data, children) { - var root = new Node(data), - valued = +data.value && (root.value = data.value), - node, - nodes = [root], - child, - childs, - i, - n; - - if (children == null) children = defaultChildren; - - while (node = nodes.pop()) { - if (valued) node.value = +node.data.value; - if ((childs = children(node.data)) && (n = childs.length)) { - node.children = new Array(n); - for (i = n - 1; i >= 0; --i) { - nodes.push(child = node.children[i] = new Node(childs[i])); - child.parent = node; - child.depth = node.depth + 1; - } - } - } - - return root.eachBefore(computeHeight); -} - -function node_copy() { - return hierarchy(this).eachBefore(copyData); -} - -function defaultChildren(d) { - return d.children; -} - -function copyData(node) { - node.data = node.data.data; -} - -function computeHeight(node) { - var height = 0; - do node.height = height; - while ((node = node.parent) && (node.height < ++height)); -} - -function Node(data) { - this.data = data; - this.depth = - this.height = 0; - this.parent = null; -} - -Node.prototype = hierarchy.prototype = { - constructor: Node, - count: node_count, - each: node_each, - eachAfter: node_eachAfter, - eachBefore: node_eachBefore, - sum: node_sum, - sort: node_sort, - path: node_path, - ancestors: node_ancestors, - descendants: node_descendants, - leaves: node_leaves, - links: node_links, - copy: node_copy -}; - -var roundNode = function(node) { - node.x0 = Math.round(node.x0); - node.y0 = Math.round(node.y0); - node.x1 = Math.round(node.x1); - node.y1 = Math.round(node.y1); -}; - -var treemapDice = function(parent, x0, y0, x1, y1) { - var nodes = parent.children, - node, - i = -1, - n = nodes.length, - k = parent.value && (x1 - x0) / parent.value; - - while (++i < n) { - node = nodes[i], node.y0 = y0, node.y1 = y1; - node.x0 = x0, node.x1 = x0 += node.value * k; - } -}; - -var partition = function() { - var dx = 1, - dy = 1, - padding = 0, - round = false; - - function partition(root) { - var n = root.height + 1; - root.x0 = - root.y0 = padding; - root.x1 = dx; - root.y1 = dy / n; - root.eachBefore(positionNode(dy, n)); - if (round) root.eachBefore(roundNode); - return root; - } - - function positionNode(dy, n) { - return function(node) { - if (node.children) { - treemapDice(node, node.x0, dy * (node.depth + 1) / n, node.x1, dy * (node.depth + 2) / n); - } - var x0 = node.x0, - y0 = node.y0, - x1 = node.x1 - padding, - y1 = node.y1 - padding; - if (x1 < x0) x0 = x1 = (x0 + x1) / 2; - if (y1 < y0) y0 = y1 = (y0 + y1) / 2; - node.x0 = x0; - node.y0 = y0; - node.x1 = x1; - node.y1 = y1; - }; - } - - partition.round = function(x) { - return arguments.length ? (round = !!x, partition) : round; - }; - - partition.size = function(x) { - return arguments.length ? (dx = +x[0], dy = +x[1], partition) : [dx, dy]; - }; - - partition.padding = function(x) { - return arguments.length ? (padding = +x, partition) : padding; - }; - - return partition; -}; - -var ascending$1 = function(a, b) { - return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; -}; - -var bisector = function(compare) { - if (compare.length === 1) compare = ascendingComparator(compare); - return { - left: function(a, x, lo, hi) { - if (lo == null) lo = 0; - if (hi == null) hi = a.length; - while (lo < hi) { - var mid = lo + hi >>> 1; - if (compare(a[mid], x) < 0) lo = mid + 1; - else hi = mid; - } - return lo; - }, - right: function(a, x, lo, hi) { - if (lo == null) lo = 0; - if (hi == null) hi = a.length; - while (lo < hi) { - var mid = lo + hi >>> 1; - if (compare(a[mid], x) > 0) hi = mid; - else lo = mid + 1; - } - return lo; - } - }; -}; - -function ascendingComparator(f) { - return function(d, x) { - return ascending$1(f(d), x); - }; -} - -var ascendingBisect = bisector(ascending$1); -var bisectRight = ascendingBisect.right; - -var e10 = Math.sqrt(50); -var e5 = Math.sqrt(10); -var e2 = Math.sqrt(2); - -var ticks = function(start, stop, count) { - var reverse, - i = -1, - n, - ticks, - step; - - stop = +stop, start = +start, count = +count; - if (start === stop && count > 0) return [start]; - if (reverse = stop < start) n = start, start = stop, stop = n; - if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return []; - - if (step > 0) { - start = Math.ceil(start / step); - stop = Math.floor(stop / step); - ticks = new Array(n = Math.ceil(stop - start + 1)); - while (++i < n) ticks[i] = (start + i) * step; - } else { - start = Math.floor(start * step); - stop = Math.ceil(stop * step); - ticks = new Array(n = Math.ceil(start - stop + 1)); - while (++i < n) ticks[i] = (start - i) / step; - } - - if (reverse) ticks.reverse(); - - return ticks; -}; - -function tickIncrement(start, stop, count) { - var step = (stop - start) / Math.max(0, count), - power = Math.floor(Math.log(step) / Math.LN10), - error = step / Math.pow(10, power); - return power >= 0 - ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power) - : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1); -} - -function tickStep(start, stop, count) { - var step0 = Math.abs(stop - start) / Math.max(0, count), - step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)), - error = step0 / step1; - if (error >= e10) step1 *= 10; - else if (error >= e5) step1 *= 5; - else if (error >= e2) step1 *= 2; - return stop < start ? -step1 : step1; -} - -var prefix = "$"; - -function Map() {} - -Map.prototype = map$1.prototype = { - constructor: Map, - has: function(key) { - return (prefix + key) in this; - }, - get: function(key) { - return this[prefix + key]; - }, - set: function(key, value) { - this[prefix + key] = value; - return this; - }, - remove: function(key) { - var property = prefix + key; - return property in this && delete this[property]; - }, - clear: function() { - for (var property in this) if (property[0] === prefix) delete this[property]; - }, - keys: function() { - var keys = []; - for (var property in this) if (property[0] === prefix) keys.push(property.slice(1)); - return keys; - }, - values: function() { - var values = []; - for (var property in this) if (property[0] === prefix) values.push(this[property]); - return values; - }, - entries: function() { - var entries = []; - for (var property in this) if (property[0] === prefix) entries.push({key: property.slice(1), value: this[property]}); - return entries; - }, - size: function() { - var size = 0; - for (var property in this) if (property[0] === prefix) ++size; - return size; - }, - empty: function() { - for (var property in this) if (property[0] === prefix) return false; - return true; - }, - each: function(f) { - for (var property in this) if (property[0] === prefix) f(this[property], property.slice(1), this); - } -}; - -function map$1(object, f) { - var map = new Map; - - // Copy constructor. - if (object instanceof Map) object.each(function(value, key) { map.set(key, value); }); - - // Index array by numeric index or specified key function. - else if (Array.isArray(object)) { - var i = -1, - n = object.length, - o; - - if (f == null) while (++i < n) map.set(i, object[i]); - else while (++i < n) map.set(f(o = object[i], i, object), o); - } - - // Convert object to map. - else if (object) for (var key in object) map.set(key, object[key]); - - return map; -} - -function Set() {} - -var proto = map$1.prototype; - -Set.prototype = set.prototype = { - constructor: Set, - has: proto.has, - add: function(value) { - value += ""; - this[prefix + value] = value; - return this; - }, - remove: proto.remove, - clear: proto.clear, - values: proto.keys, - size: proto.size, - empty: proto.empty, - each: proto.each -}; - -function set(object, f) { - var set = new Set; - - // Copy constructor. - if (object instanceof Set) object.each(function(value) { set.add(value); }); - - // Otherwise, assume it’s an array. - else if (object) { - var i = -1, n = object.length; - if (f == null) while (++i < n) set.add(object[i]); - else while (++i < n) set.add(f(object[i], i, object)); - } - - return set; -} - -var array$1 = Array.prototype; - -var map$3 = array$1.map; -var slice$2 = array$1.slice; - -var define = function(constructor, factory, prototype) { - constructor.prototype = factory.prototype = prototype; - prototype.constructor = constructor; -}; - -function extend(parent, definition) { - var prototype = Object.create(parent.prototype); - for (var key in definition) prototype[key] = definition[key]; - return prototype; -} - -function Color() {} - -var darker = 0.7; -var brighter = 1 / darker; - -var reI = "\\s*([+-]?\\d+)\\s*"; -var reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*"; -var reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*"; -var reHex3 = /^#([0-9a-f]{3})$/; -var reHex6 = /^#([0-9a-f]{6})$/; -var reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"); -var reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"); -var reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"); -var reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"); -var reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"); -var reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$"); - -var named = { - aliceblue: 0xf0f8ff, - antiquewhite: 0xfaebd7, - aqua: 0x00ffff, - aquamarine: 0x7fffd4, - azure: 0xf0ffff, - beige: 0xf5f5dc, - bisque: 0xffe4c4, - black: 0x000000, - blanchedalmond: 0xffebcd, - blue: 0x0000ff, - blueviolet: 0x8a2be2, - brown: 0xa52a2a, - burlywood: 0xdeb887, - cadetblue: 0x5f9ea0, - chartreuse: 0x7fff00, - chocolate: 0xd2691e, - coral: 0xff7f50, - cornflowerblue: 0x6495ed, - cornsilk: 0xfff8dc, - crimson: 0xdc143c, - cyan: 0x00ffff, - darkblue: 0x00008b, - darkcyan: 0x008b8b, - darkgoldenrod: 0xb8860b, - darkgray: 0xa9a9a9, - darkgreen: 0x006400, - darkgrey: 0xa9a9a9, - darkkhaki: 0xbdb76b, - darkmagenta: 0x8b008b, - darkolivegreen: 0x556b2f, - darkorange: 0xff8c00, - darkorchid: 0x9932cc, - darkred: 0x8b0000, - darksalmon: 0xe9967a, - darkseagreen: 0x8fbc8f, - darkslateblue: 0x483d8b, - darkslategray: 0x2f4f4f, - darkslategrey: 0x2f4f4f, - darkturquoise: 0x00ced1, - darkviolet: 0x9400d3, - deeppink: 0xff1493, - deepskyblue: 0x00bfff, - dimgray: 0x696969, - dimgrey: 0x696969, - dodgerblue: 0x1e90ff, - firebrick: 0xb22222, - floralwhite: 0xfffaf0, - forestgreen: 0x228b22, - fuchsia: 0xff00ff, - gainsboro: 0xdcdcdc, - ghostwhite: 0xf8f8ff, - gold: 0xffd700, - goldenrod: 0xdaa520, - gray: 0x808080, - green: 0x008000, - greenyellow: 0xadff2f, - grey: 0x808080, - honeydew: 0xf0fff0, - hotpink: 0xff69b4, - indianred: 0xcd5c5c, - indigo: 0x4b0082, - ivory: 0xfffff0, - khaki: 0xf0e68c, - lavender: 0xe6e6fa, - lavenderblush: 0xfff0f5, - lawngreen: 0x7cfc00, - lemonchiffon: 0xfffacd, - lightblue: 0xadd8e6, - lightcoral: 0xf08080, - lightcyan: 0xe0ffff, - lightgoldenrodyellow: 0xfafad2, - lightgray: 0xd3d3d3, - lightgreen: 0x90ee90, - lightgrey: 0xd3d3d3, - lightpink: 0xffb6c1, - lightsalmon: 0xffa07a, - lightseagreen: 0x20b2aa, - lightskyblue: 0x87cefa, - lightslategray: 0x778899, - lightslategrey: 0x778899, - lightsteelblue: 0xb0c4de, - lightyellow: 0xffffe0, - lime: 0x00ff00, - limegreen: 0x32cd32, - linen: 0xfaf0e6, - magenta: 0xff00ff, - maroon: 0x800000, - mediumaquamarine: 0x66cdaa, - mediumblue: 0x0000cd, - mediumorchid: 0xba55d3, - mediumpurple: 0x9370db, - mediumseagreen: 0x3cb371, - mediumslateblue: 0x7b68ee, - mediumspringgreen: 0x00fa9a, - mediumturquoise: 0x48d1cc, - mediumvioletred: 0xc71585, - midnightblue: 0x191970, - mintcream: 0xf5fffa, - mistyrose: 0xffe4e1, - moccasin: 0xffe4b5, - navajowhite: 0xffdead, - navy: 0x000080, - oldlace: 0xfdf5e6, - olive: 0x808000, - olivedrab: 0x6b8e23, - orange: 0xffa500, - orangered: 0xff4500, - orchid: 0xda70d6, - palegoldenrod: 0xeee8aa, - palegreen: 0x98fb98, - paleturquoise: 0xafeeee, - palevioletred: 0xdb7093, - papayawhip: 0xffefd5, - peachpuff: 0xffdab9, - peru: 0xcd853f, - pink: 0xffc0cb, - plum: 0xdda0dd, - powderblue: 0xb0e0e6, - purple: 0x800080, - rebeccapurple: 0x663399, - red: 0xff0000, - rosybrown: 0xbc8f8f, - royalblue: 0x4169e1, - saddlebrown: 0x8b4513, - salmon: 0xfa8072, - sandybrown: 0xf4a460, - seagreen: 0x2e8b57, - seashell: 0xfff5ee, - sienna: 0xa0522d, - silver: 0xc0c0c0, - skyblue: 0x87ceeb, - slateblue: 0x6a5acd, - slategray: 0x708090, - slategrey: 0x708090, - snow: 0xfffafa, - springgreen: 0x00ff7f, - steelblue: 0x4682b4, - tan: 0xd2b48c, - teal: 0x008080, - thistle: 0xd8bfd8, - tomato: 0xff6347, - turquoise: 0x40e0d0, - violet: 0xee82ee, - wheat: 0xf5deb3, - white: 0xffffff, - whitesmoke: 0xf5f5f5, - yellow: 0xffff00, - yellowgreen: 0x9acd32 -}; - -define(Color, color, { - displayable: function() { - return this.rgb().displayable(); - }, - toString: function() { - return this.rgb() + ""; - } -}); - -function color(format) { - var m; - format = (format + "").trim().toLowerCase(); - return (m = reHex3.exec(format)) ? (m = parseInt(m[1], 16), new Rgb((m >> 8 & 0xf) | (m >> 4 & 0x0f0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1)) // #f00 - : (m = reHex6.exec(format)) ? rgbn(parseInt(m[1], 16)) // #ff0000 - : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0) - : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%) - : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1) - : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1) - : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%) - : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1) - : named.hasOwnProperty(format) ? rgbn(named[format]) - : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) - : null; -} - -function rgbn(n) { - return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1); -} - -function rgba(r, g, b, a) { - if (a <= 0) r = g = b = NaN; - return new Rgb(r, g, b, a); -} - -function rgbConvert(o) { - if (!(o instanceof Color)) o = color(o); - if (!o) return new Rgb; - o = o.rgb(); - return new Rgb(o.r, o.g, o.b, o.opacity); -} - -function rgb(r, g, b, opacity) { - return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity); -} - -function Rgb(r, g, b, opacity) { - this.r = +r; - this.g = +g; - this.b = +b; - this.opacity = +opacity; -} - -define(Rgb, rgb, extend(Color, { - brighter: function(k) { - k = k == null ? brighter : Math.pow(brighter, k); - return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); - }, - darker: function(k) { - k = k == null ? darker : Math.pow(darker, k); - return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); - }, - rgb: function() { - return this; - }, - displayable: function() { - return (0 <= this.r && this.r <= 255) - && (0 <= this.g && this.g <= 255) - && (0 <= this.b && this.b <= 255) - && (0 <= this.opacity && this.opacity <= 1); - }, - toString: function() { - var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); - return (a === 1 ? "rgb(" : "rgba(") - + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", " - + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", " - + Math.max(0, Math.min(255, Math.round(this.b) || 0)) - + (a === 1 ? ")" : ", " + a + ")"); - } -})); - -function hsla(h, s, l, a) { - if (a <= 0) h = s = l = NaN; - else if (l <= 0 || l >= 1) h = s = NaN; - else if (s <= 0) h = NaN; - return new Hsl(h, s, l, a); -} - -function hslConvert(o) { - if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity); - if (!(o instanceof Color)) o = color(o); - if (!o) return new Hsl; - if (o instanceof Hsl) return o; - o = o.rgb(); - var r = o.r / 255, - g = o.g / 255, - b = o.b / 255, - min = Math.min(r, g, b), - max = Math.max(r, g, b), - h = NaN, - s = max - min, - l = (max + min) / 2; - if (s) { - if (r === max) h = (g - b) / s + (g < b) * 6; - else if (g === max) h = (b - r) / s + 2; - else h = (r - g) / s + 4; - s /= l < 0.5 ? max + min : 2 - max - min; - h *= 60; - } else { - s = l > 0 && l < 1 ? 0 : h; - } - return new Hsl(h, s, l, o.opacity); -} - -function hsl(h, s, l, opacity) { - return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity); -} - -function Hsl(h, s, l, opacity) { - this.h = +h; - this.s = +s; - this.l = +l; - this.opacity = +opacity; -} - -define(Hsl, hsl, extend(Color, { - brighter: function(k) { - k = k == null ? brighter : Math.pow(brighter, k); - return new Hsl(this.h, this.s, this.l * k, this.opacity); - }, - darker: function(k) { - k = k == null ? darker : Math.pow(darker, k); - return new Hsl(this.h, this.s, this.l * k, this.opacity); - }, - rgb: function() { - var h = this.h % 360 + (this.h < 0) * 360, - s = isNaN(h) || isNaN(this.s) ? 0 : this.s, - l = this.l, - m2 = l + (l < 0.5 ? l : 1 - l) * s, - m1 = 2 * l - m2; - return new Rgb( - hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2), - hsl2rgb(h, m1, m2), - hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2), - this.opacity - ); - }, - displayable: function() { - return (0 <= this.s && this.s <= 1 || isNaN(this.s)) - && (0 <= this.l && this.l <= 1) - && (0 <= this.opacity && this.opacity <= 1); - } -})); - -/* From FvD 13.37, CSS Color Module Level 3 */ -function hsl2rgb(h, m1, m2) { - return (h < 60 ? m1 + (m2 - m1) * h / 60 - : h < 180 ? m2 - : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60 - : m1) * 255; -} - -var deg2rad = Math.PI / 180; -var rad2deg = 180 / Math.PI; - -var Kn = 18; -var Xn = 0.950470; -var Yn = 1; -var Zn = 1.088830; -var t0 = 4 / 29; -var t1 = 6 / 29; -var t2 = 3 * t1 * t1; -var t3 = t1 * t1 * t1; - -function labConvert(o) { - if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity); - if (o instanceof Hcl) { - var h = o.h * deg2rad; - return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity); - } - if (!(o instanceof Rgb)) o = rgbConvert(o); - var b = rgb2xyz(o.r), - a = rgb2xyz(o.g), - l = rgb2xyz(o.b), - x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn), - y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.0721750 * l) / Yn), - z = xyz2lab((0.0193339 * b + 0.1191920 * a + 0.9503041 * l) / Zn); - return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity); -} - -function lab(l, a, b, opacity) { - return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity); -} - -function Lab(l, a, b, opacity) { - this.l = +l; - this.a = +a; - this.b = +b; - this.opacity = +opacity; -} - -define(Lab, lab, extend(Color, { - brighter: function(k) { - return new Lab(this.l + Kn * (k == null ? 1 : k), this.a, this.b, this.opacity); - }, - darker: function(k) { - return new Lab(this.l - Kn * (k == null ? 1 : k), this.a, this.b, this.opacity); - }, - rgb: function() { - var y = (this.l + 16) / 116, - x = isNaN(this.a) ? y : y + this.a / 500, - z = isNaN(this.b) ? y : y - this.b / 200; - y = Yn * lab2xyz(y); - x = Xn * lab2xyz(x); - z = Zn * lab2xyz(z); - return new Rgb( - xyz2rgb( 3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB - xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z), - xyz2rgb( 0.0556434 * x - 0.2040259 * y + 1.0572252 * z), - this.opacity - ); - } -})); - -function xyz2lab(t) { - return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0; -} - -function lab2xyz(t) { - return t > t1 ? t * t * t : t2 * (t - t0); -} - -function xyz2rgb(x) { - return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055); -} - -function rgb2xyz(x) { - return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4); -} - -function hclConvert(o) { - if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity); - if (!(o instanceof Lab)) o = labConvert(o); - var h = Math.atan2(o.b, o.a) * rad2deg; - return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity); -} - -function hcl(h, c, l, opacity) { - return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity); -} - -function Hcl(h, c, l, opacity) { - this.h = +h; - this.c = +c; - this.l = +l; - this.opacity = +opacity; -} - -define(Hcl, hcl, extend(Color, { - brighter: function(k) { - return new Hcl(this.h, this.c, this.l + Kn * (k == null ? 1 : k), this.opacity); - }, - darker: function(k) { - return new Hcl(this.h, this.c, this.l - Kn * (k == null ? 1 : k), this.opacity); - }, - rgb: function() { - return labConvert(this).rgb(); - } -})); - -var A = -0.14861; -var B = +1.78277; -var C = -0.29227; -var D = -0.90649; -var E = +1.97294; -var ED = E * D; -var EB = E * B; -var BC_DA = B * C - D * A; - -function cubehelixConvert(o) { - if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity); - if (!(o instanceof Rgb)) o = rgbConvert(o); - var r = o.r / 255, - g = o.g / 255, - b = o.b / 255, - l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB), - bl = b - l, - k = (E * (g - l) - C * bl) / D, - s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1 - h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN; - return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity); -} - -function cubehelix(h, s, l, opacity) { - return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity); -} - -function Cubehelix(h, s, l, opacity) { - this.h = +h; - this.s = +s; - this.l = +l; - this.opacity = +opacity; -} - -define(Cubehelix, cubehelix, extend(Color, { - brighter: function(k) { - k = k == null ? brighter : Math.pow(brighter, k); - return new Cubehelix(this.h, this.s, this.l * k, this.opacity); - }, - darker: function(k) { - k = k == null ? darker : Math.pow(darker, k); - return new Cubehelix(this.h, this.s, this.l * k, this.opacity); - }, - rgb: function() { - var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad, - l = +this.l, - a = isNaN(this.s) ? 0 : this.s * l * (1 - l), - cosh = Math.cos(h), - sinh = Math.sin(h); - return new Rgb( - 255 * (l + a * (A * cosh + B * sinh)), - 255 * (l + a * (C * cosh + D * sinh)), - 255 * (l + a * (E * cosh)), - this.opacity - ); - } -})); - -var constant$3 = function(x) { - return function() { - return x; - }; -}; - -function linear$1(a, d) { - return function(t) { - return a + t * d; - }; -} - -function exponential(a, b, y) { - return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) { - return Math.pow(a + t * b, y); - }; -} - -function hue(a, b) { - var d = b - a; - return d ? linear$1(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant$3(isNaN(a) ? b : a); -} - -function gamma(y) { - return (y = +y) === 1 ? nogamma : function(a, b) { - return b - a ? exponential(a, b, y) : constant$3(isNaN(a) ? b : a); - }; -} - -function nogamma(a, b) { - var d = b - a; - return d ? linear$1(a, d) : constant$3(isNaN(a) ? b : a); -} - -var interpolateRgb = (function rgbGamma(y) { - var color$$1 = gamma(y); - - function rgb$$1(start, end) { - var r = color$$1((start = rgb(start)).r, (end = rgb(end)).r), - g = color$$1(start.g, end.g), - b = color$$1(start.b, end.b), - opacity = nogamma(start.opacity, end.opacity); - return function(t) { - start.r = r(t); - start.g = g(t); - start.b = b(t); - start.opacity = opacity(t); - return start + ""; - }; - } - - rgb$$1.gamma = rgbGamma; - - return rgb$$1; -})(1); - -var array$2 = function(a, b) { - var nb = b ? b.length : 0, - na = a ? Math.min(nb, a.length) : 0, - x = new Array(nb), - c = new Array(nb), - i; - - for (i = 0; i < na; ++i) x[i] = interpolateValue(a[i], b[i]); - for (; i < nb; ++i) c[i] = b[i]; - - return function(t) { - for (i = 0; i < na; ++i) c[i] = x[i](t); - return c; - }; -}; - -var date = function(a, b) { - var d = new Date; - return a = +a, b -= a, function(t) { - return d.setTime(a + b * t), d; - }; -}; - -var interpolateNumber = function(a, b) { - return a = +a, b -= a, function(t) { - return a + b * t; - }; -}; - -var object = function(a, b) { - var i = {}, - c = {}, - k; - - if (a === null || typeof a !== "object") a = {}; - if (b === null || typeof b !== "object") b = {}; - - for (k in b) { - if (k in a) { - i[k] = interpolateValue(a[k], b[k]); - } else { - c[k] = b[k]; - } - } - - return function(t) { - for (k in i) c[k] = i[k](t); - return c; - }; -}; - -var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g; -var reB = new RegExp(reA.source, "g"); - -function zero(b) { - return function() { - return b; - }; -} - -function one(b) { - return function(t) { - return b(t) + ""; - }; -} - -var interpolateString = function(a, b) { - var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b - am, // current match in a - bm, // current match in b - bs, // string preceding current number in b, if any - i = -1, // index in s - s = [], // string constants and placeholders - q = []; // number interpolators - - // Coerce inputs to strings. - a = a + "", b = b + ""; - - // Interpolate pairs of numbers in a & b. - while ((am = reA.exec(a)) - && (bm = reB.exec(b))) { - if ((bs = bm.index) > bi) { // a string precedes the next number in b - bs = b.slice(bi, bs); - if (s[i]) s[i] += bs; // coalesce with previous string - else s[++i] = bs; - } - if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match - if (s[i]) s[i] += bm; // coalesce with previous string - else s[++i] = bm; - } else { // interpolate non-matching numbers - s[++i] = null; - q.push({i: i, x: interpolateNumber(am, bm)}); - } - bi = reB.lastIndex; - } - - // Add remains of b. - if (bi < b.length) { - bs = b.slice(bi); - if (s[i]) s[i] += bs; // coalesce with previous string - else s[++i] = bs; - } - - // Special optimization for only a single match. - // Otherwise, interpolate each of the numbers and rejoin the string. - return s.length < 2 ? (q[0] - ? one(q[0].x) - : zero(b)) - : (b = q.length, function(t) { - for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }); -}; - -var interpolateValue = function(a, b) { - var t = typeof b, c; - return b == null || t === "boolean" ? constant$3(b) - : (t === "number" ? interpolateNumber - : t === "string" ? ((c = color(b)) ? (b = c, interpolateRgb) : interpolateString) - : b instanceof color ? interpolateRgb - : b instanceof Date ? date - : Array.isArray(b) ? array$2 - : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object - : interpolateNumber)(a, b); -}; - -var interpolateRound = function(a, b) { - return a = +a, b -= a, function(t) { - return Math.round(a + b * t); - }; -}; - -var degrees = 180 / Math.PI; - -var identity$2 = { - translateX: 0, - translateY: 0, - rotate: 0, - skewX: 0, - scaleX: 1, - scaleY: 1 -}; - -var decompose = function(a, b, c, d, e, f) { - var scaleX, scaleY, skewX; - if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX; - if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX; - if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY; - if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX; - return { - translateX: e, - translateY: f, - rotate: Math.atan2(b, a) * degrees, - skewX: Math.atan(skewX) * degrees, - scaleX: scaleX, - scaleY: scaleY - }; -}; - -var cssNode; -var cssRoot; -var cssView; -var svgNode; - -function parseCss(value) { - if (value === "none") return identity$2; - if (!cssNode) cssNode = document.createElement("DIV"), cssRoot = document.documentElement, cssView = document.defaultView; - cssNode.style.transform = value; - value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue("transform"); - cssRoot.removeChild(cssNode); - value = value.slice(7, -1).split(","); - return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]); -} - -function parseSvg(value) { - if (value == null) return identity$2; - if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g"); - svgNode.setAttribute("transform", value); - if (!(value = svgNode.transform.baseVal.consolidate())) return identity$2; - value = value.matrix; - return decompose(value.a, value.b, value.c, value.d, value.e, value.f); -} - -function interpolateTransform(parse, pxComma, pxParen, degParen) { - - function pop(s) { - return s.length ? s.pop() + " " : ""; - } - - function translate(xa, ya, xb, yb, s, q) { - if (xa !== xb || ya !== yb) { - var i = s.push("translate(", null, pxComma, null, pxParen); - q.push({i: i - 4, x: interpolateNumber(xa, xb)}, {i: i - 2, x: interpolateNumber(ya, yb)}); - } else if (xb || yb) { - s.push("translate(" + xb + pxComma + yb + pxParen); - } - } - - function rotate(a, b, s, q) { - if (a !== b) { - if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path - q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: interpolateNumber(a, b)}); - } else if (b) { - s.push(pop(s) + "rotate(" + b + degParen); - } - } - - function skewX(a, b, s, q) { - if (a !== b) { - q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: interpolateNumber(a, b)}); - } else if (b) { - s.push(pop(s) + "skewX(" + b + degParen); - } - } - - function scale(xa, ya, xb, yb, s, q) { - if (xa !== xb || ya !== yb) { - var i = s.push(pop(s) + "scale(", null, ",", null, ")"); - q.push({i: i - 4, x: interpolateNumber(xa, xb)}, {i: i - 2, x: interpolateNumber(ya, yb)}); - } else if (xb !== 1 || yb !== 1) { - s.push(pop(s) + "scale(" + xb + "," + yb + ")"); - } - } - - return function(a, b) { - var s = [], // string constants and placeholders - q = []; // number interpolators - a = parse(a), b = parse(b); - translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q); - rotate(a.rotate, b.rotate, s, q); - skewX(a.skewX, b.skewX, s, q); - scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q); - a = b = null; // gc - return function(t) { - var i = -1, n = q.length, o; - while (++i < n) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }; - }; -} - -var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)"); -var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")"); - -var rho = Math.SQRT2; - -function cubehelix$1(hue$$1) { - return (function cubehelixGamma(y) { - y = +y; - - function cubehelix$$1(start, end) { - var h = hue$$1((start = cubehelix(start)).h, (end = cubehelix(end)).h), - s = nogamma(start.s, end.s), - l = nogamma(start.l, end.l), - opacity = nogamma(start.opacity, end.opacity); - return function(t) { - start.h = h(t); - start.s = s(t); - start.l = l(Math.pow(t, y)); - start.opacity = opacity(t); - return start + ""; - }; - } - - cubehelix$$1.gamma = cubehelixGamma; - - return cubehelix$$1; - })(1); -} - -cubehelix$1(hue); -var cubehelixLong = cubehelix$1(nogamma); - -var constant$4 = function(x) { - return function() { - return x; - }; -}; - -var number$1 = function(x) { - return +x; -}; - -var unit = [0, 1]; - -function deinterpolateLinear(a, b) { - return (b -= (a = +a)) - ? function(x) { return (x - a) / b; } - : constant$4(b); -} - -function deinterpolateClamp(deinterpolate) { - return function(a, b) { - var d = deinterpolate(a = +a, b = +b); - return function(x) { return x <= a ? 0 : x >= b ? 1 : d(x); }; - }; -} - -function reinterpolateClamp(reinterpolate) { - return function(a, b) { - var r = reinterpolate(a = +a, b = +b); - return function(t) { return t <= 0 ? a : t >= 1 ? b : r(t); }; - }; -} - -function bimap(domain, range, deinterpolate, reinterpolate) { - var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1]; - if (d1 < d0) d0 = deinterpolate(d1, d0), r0 = reinterpolate(r1, r0); - else d0 = deinterpolate(d0, d1), r0 = reinterpolate(r0, r1); - return function(x) { return r0(d0(x)); }; -} - -function polymap(domain, range, deinterpolate, reinterpolate) { - var j = Math.min(domain.length, range.length) - 1, - d = new Array(j), - r = new Array(j), - i = -1; - - // Reverse descending domains. - if (domain[j] < domain[0]) { - domain = domain.slice().reverse(); - range = range.slice().reverse(); - } - - while (++i < j) { - d[i] = deinterpolate(domain[i], domain[i + 1]); - r[i] = reinterpolate(range[i], range[i + 1]); - } - - return function(x) { - var i = bisectRight(domain, x, 1, j) - 1; - return r[i](d[i](x)); - }; -} - -function copy(source, target) { - return target - .domain(source.domain()) - .range(source.range()) - .interpolate(source.interpolate()) - .clamp(source.clamp()); -} - -// deinterpolate(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1]. -// reinterpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding domain value x in [a,b]. -function continuous(deinterpolate, reinterpolate) { - var domain = unit, - range = unit, - interpolate$$1 = interpolateValue, - clamp = false, - piecewise, - output, - input; - - function rescale() { - piecewise = Math.min(domain.length, range.length) > 2 ? polymap : bimap; - output = input = null; - return scale; - } - - function scale(x) { - return (output || (output = piecewise(domain, range, clamp ? deinterpolateClamp(deinterpolate) : deinterpolate, interpolate$$1)))(+x); - } - - scale.invert = function(y) { - return (input || (input = piecewise(range, domain, deinterpolateLinear, clamp ? reinterpolateClamp(reinterpolate) : reinterpolate)))(+y); - }; - - scale.domain = function(_) { - return arguments.length ? (domain = map$3.call(_, number$1), rescale()) : domain.slice(); - }; - - scale.range = function(_) { - return arguments.length ? (range = slice$2.call(_), rescale()) : range.slice(); - }; - - scale.rangeRound = function(_) { - return range = slice$2.call(_), interpolate$$1 = interpolateRound, rescale(); - }; - - scale.clamp = function(_) { - return arguments.length ? (clamp = !!_, rescale()) : clamp; - }; - - scale.interpolate = function(_) { - return arguments.length ? (interpolate$$1 = _, rescale()) : interpolate$$1; - }; - - return rescale(); -} - -// Computes the decimal coefficient and exponent of the specified number x with -// significant digits p, where x is positive and p is in [1, 21] or undefined. -// For example, formatDecimal(1.23) returns ["123", 0]. -var formatDecimal = function(x, p) { - if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity - var i, coefficient = x.slice(0, i); - - // The string returned by toExponential either has the form \d\.\d+e[-+]\d+ - // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3). - return [ - coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient, - +x.slice(i + 1) - ]; -}; - -var exponent = function(x) { - return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN; -}; - -var formatGroup = function(grouping, thousands) { - return function(value, width) { - var i = value.length, - t = [], - j = 0, - g = grouping[0], - length = 0; - - while (i > 0 && g > 0) { - if (length + g + 1 > width) g = Math.max(1, width - length); - t.push(value.substring(i -= g, i + g)); - if ((length += g + 1) > width) break; - g = grouping[j = (j + 1) % grouping.length]; - } - - return t.reverse().join(thousands); - }; -}; - -var formatNumerals = function(numerals) { - return function(value) { - return value.replace(/[0-9]/g, function(i) { - return numerals[+i]; - }); - }; -}; - -var formatDefault = function(x, p) { - x = x.toPrecision(p); - - out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) { - switch (x[i]) { - case ".": i0 = i1 = i; break; - case "0": if (i0 === 0) i0 = i; i1 = i; break; - case "e": break out; - default: if (i0 > 0) i0 = 0; break; - } - } - - return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x; -}; - -var prefixExponent; - -var formatPrefixAuto = function(x, p) { - var d = formatDecimal(x, p); - if (!d) return x + ""; - var coefficient = d[0], - exponent = d[1], - i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1, - n = coefficient.length; - return i === n ? coefficient - : i > n ? coefficient + new Array(i - n + 1).join("0") - : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i) - : "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y! -}; - -var formatRounded = function(x, p) { - var d = formatDecimal(x, p); - if (!d) return x + ""; - var coefficient = d[0], - exponent = d[1]; - return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient - : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1) - : coefficient + new Array(exponent - coefficient.length + 2).join("0"); -}; - -var formatTypes = { - "": formatDefault, - "%": function(x, p) { return (x * 100).toFixed(p); }, - "b": function(x) { return Math.round(x).toString(2); }, - "c": function(x) { return x + ""; }, - "d": function(x) { return Math.round(x).toString(10); }, - "e": function(x, p) { return x.toExponential(p); }, - "f": function(x, p) { return x.toFixed(p); }, - "g": function(x, p) { return x.toPrecision(p); }, - "o": function(x) { return Math.round(x).toString(8); }, - "p": function(x, p) { return formatRounded(x * 100, p); }, - "r": formatRounded, - "s": formatPrefixAuto, - "X": function(x) { return Math.round(x).toString(16).toUpperCase(); }, - "x": function(x) { return Math.round(x).toString(16); } -}; - -// [[fill]align][sign][symbol][0][width][,][.precision][type] -var re = /^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i; - -function formatSpecifier(specifier) { - return new FormatSpecifier(specifier); -} - -formatSpecifier.prototype = FormatSpecifier.prototype; // instanceof - -function FormatSpecifier(specifier) { - if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier); - - var match, - fill = match[1] || " ", - align = match[2] || ">", - sign = match[3] || "-", - symbol = match[4] || "", - zero = !!match[5], - width = match[6] && +match[6], - comma = !!match[7], - precision = match[8] && +match[8].slice(1), - type = match[9] || ""; - - // The "n" type is an alias for ",g". - if (type === "n") comma = true, type = "g"; - - // Map invalid types to the default format. - else if (!formatTypes[type]) type = ""; - - // If zero fill is specified, padding goes after sign and before digits. - if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "="; - - this.fill = fill; - this.align = align; - this.sign = sign; - this.symbol = symbol; - this.zero = zero; - this.width = width; - this.comma = comma; - this.precision = precision; - this.type = type; -} - -FormatSpecifier.prototype.toString = function() { - return this.fill - + this.align - + this.sign - + this.symbol - + (this.zero ? "0" : "") - + (this.width == null ? "" : Math.max(1, this.width | 0)) - + (this.comma ? "," : "") - + (this.precision == null ? "" : "." + Math.max(0, this.precision | 0)) - + this.type; -}; - -var identity$3 = function(x) { - return x; -}; - -var prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"]; - -var formatLocale = function(locale) { - var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity$3, - currency = locale.currency, - decimal = locale.decimal, - numerals = locale.numerals ? formatNumerals(locale.numerals) : identity$3, - percent = locale.percent || "%"; - - function newFormat(specifier) { - specifier = formatSpecifier(specifier); - - var fill = specifier.fill, - align = specifier.align, - sign = specifier.sign, - symbol = specifier.symbol, - zero = specifier.zero, - width = specifier.width, - comma = specifier.comma, - precision = specifier.precision, - type = specifier.type; - - // Compute the prefix and suffix. - // For SI-prefix, the suffix is lazily computed. - var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "", - suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? percent : ""; - - // What format function should we use? - // Is this an integer type? - // Can this type generate exponential notation? - var formatType = formatTypes[type], - maybeSuffix = !type || /[defgprs%]/.test(type); - - // Set the default precision if not specified, - // or clamp the specified precision to the supported range. - // For significant precision, it must be in [1, 21]. - // For fixed precision, it must be in [0, 20]. - precision = precision == null ? (type ? 6 : 12) - : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision)) - : Math.max(0, Math.min(20, precision)); - - function format(value) { - var valuePrefix = prefix, - valueSuffix = suffix, - i, n, c; - - if (type === "c") { - valueSuffix = formatType(value) + valueSuffix; - value = ""; - } else { - value = +value; - - // Perform the initial formatting. - var valueNegative = value < 0; - value = formatType(Math.abs(value), precision); - - // If a negative value rounds to zero during formatting, treat as positive. - if (valueNegative && +value === 0) valueNegative = false; - - // Compute the prefix and suffix. - valuePrefix = (valueNegative ? (sign === "(" ? sign : "-") : sign === "-" || sign === "(" ? "" : sign) + valuePrefix; - valueSuffix = valueSuffix + (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + (valueNegative && sign === "(" ? ")" : ""); - - // Break the formatted value into the integer “value” part that can be - // grouped, and fractional or exponential “suffix” part that is not. - if (maybeSuffix) { - i = -1, n = value.length; - while (++i < n) { - if (c = value.charCodeAt(i), 48 > c || c > 57) { - valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix; - value = value.slice(0, i); - break; - } - } - } - } - - // If the fill character is not "0", grouping is applied before padding. - if (comma && !zero) value = group(value, Infinity); - - // Compute the padding. - var length = valuePrefix.length + value.length + valueSuffix.length, - padding = length < width ? new Array(width - length + 1).join(fill) : ""; - - // If the fill character is "0", grouping is applied after padding. - if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = ""; - - // Reconstruct the final output based on the desired alignment. - switch (align) { - case "<": value = valuePrefix + value + valueSuffix + padding; break; - case "=": value = valuePrefix + padding + value + valueSuffix; break; - case "^": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break; - default: value = padding + valuePrefix + value + valueSuffix; break; - } - - return numerals(value); - } - - format.toString = function() { - return specifier + ""; - }; - - return format; - } - - function formatPrefix(specifier, value) { - var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)), - e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3, - k = Math.pow(10, -e), - prefix = prefixes[8 + e / 3]; - return function(value) { - return f(k * value) + prefix; - }; - } - - return { - format: newFormat, - formatPrefix: formatPrefix - }; -}; - -var locale; - -var formatPrefix; - -defaultLocale({ - decimal: ".", - thousands: ",", - grouping: [3], - currency: ["$", ""] -}); - -function defaultLocale(definition) { - locale = formatLocale(definition); - exports.format = locale.format; - formatPrefix = locale.formatPrefix; - return locale; -} - -var precisionFixed = function(step) { - return Math.max(0, -exponent(Math.abs(step))); -}; - -var precisionPrefix = function(step, value) { - return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step))); -}; - -var precisionRound = function(step, max) { - step = Math.abs(step), max = Math.abs(max) - step; - return Math.max(0, exponent(max) - exponent(step)) + 1; -}; - -var tickFormat = function(domain, count, specifier) { - var start = domain[0], - stop = domain[domain.length - 1], - step = tickStep(start, stop, count == null ? 10 : count), - precision; - specifier = formatSpecifier(specifier == null ? ",f" : specifier); - switch (specifier.type) { - case "s": { - var value = Math.max(Math.abs(start), Math.abs(stop)); - if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision; - return formatPrefix(specifier, value); - } - case "": - case "e": - case "g": - case "p": - case "r": { - if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e"); - break; - } - case "f": - case "%": { - if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2; - break; - } - } - return exports.format(specifier); -}; - -function linearish(scale) { - var domain = scale.domain; - - scale.ticks = function(count) { - var d = domain(); - return ticks(d[0], d[d.length - 1], count == null ? 10 : count); - }; - - scale.tickFormat = function(count, specifier) { - return tickFormat(domain(), count, specifier); - }; - - scale.nice = function(count) { - if (count == null) count = 10; - - var d = domain(), - i0 = 0, - i1 = d.length - 1, - start = d[i0], - stop = d[i1], - step; - - if (stop < start) { - step = start, start = stop, stop = step; - step = i0, i0 = i1, i1 = step; - } - - step = tickIncrement(start, stop, count); - - if (step > 0) { - start = Math.floor(start / step) * step; - stop = Math.ceil(stop / step) * step; - step = tickIncrement(start, stop, count); - } else if (step < 0) { - start = Math.ceil(start * step) / step; - stop = Math.floor(stop * step) / step; - step = tickIncrement(start, stop, count); - } - - if (step > 0) { - d[i0] = Math.floor(start / step) * step; - d[i1] = Math.ceil(stop / step) * step; - domain(d); - } else if (step < 0) { - d[i0] = Math.ceil(start * step) / step; - d[i1] = Math.floor(stop * step) / step; - domain(d); - } - - return scale; - }; - - return scale; -} - -function linear() { - var scale = continuous(deinterpolateLinear, interpolateNumber); - - scale.copy = function() { - return copy(scale, linear()); - }; - - return linearish(scale); -} - -var t0$1 = new Date; -var t1$1 = new Date; - -function newInterval(floori, offseti, count, field) { - - function interval(date) { - return floori(date = new Date(+date)), date; - } - - interval.floor = interval; - - interval.ceil = function(date) { - return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date; - }; - - interval.round = function(date) { - var d0 = interval(date), - d1 = interval.ceil(date); - return date - d0 < d1 - date ? d0 : d1; - }; - - interval.offset = function(date, step) { - return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date; - }; - - interval.range = function(start, stop, step) { - var range = []; - start = interval.ceil(start); - step = step == null ? 1 : Math.floor(step); - if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date - do range.push(new Date(+start)); while (offseti(start, step), floori(start), start < stop) - return range; - }; - - interval.filter = function(test) { - return newInterval(function(date) { - if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1); - }, function(date, step) { - if (date >= date) { - if (step < 0) while (++step <= 0) { - while (offseti(date, -1), !test(date)) {} // eslint-disable-line no-empty - } else while (--step >= 0) { - while (offseti(date, +1), !test(date)) {} // eslint-disable-line no-empty - } - } - }); - }; - - if (count) { - interval.count = function(start, end) { - t0$1.setTime(+start), t1$1.setTime(+end); - floori(t0$1), floori(t1$1); - return Math.floor(count(t0$1, t1$1)); - }; - - interval.every = function(step) { - step = Math.floor(step); - return !isFinite(step) || !(step > 0) ? null - : !(step > 1) ? interval - : interval.filter(field - ? function(d) { return field(d) % step === 0; } - : function(d) { return interval.count(0, d) % step === 0; }); - }; - } - - return interval; -} - -var millisecond = newInterval(function() { - // noop -}, function(date, step) { - date.setTime(+date + step); -}, function(start, end) { - return end - start; -}); - -// An optimized implementation for this simple case. -millisecond.every = function(k) { - k = Math.floor(k); - if (!isFinite(k) || !(k > 0)) return null; - if (!(k > 1)) return millisecond; - return newInterval(function(date) { - date.setTime(Math.floor(date / k) * k); - }, function(date, step) { - date.setTime(+date + step * k); - }, function(start, end) { - return (end - start) / k; - }); -}; - -var durationSecond$1 = 1e3; -var durationMinute$1 = 6e4; -var durationHour$1 = 36e5; -var durationDay$1 = 864e5; -var durationWeek$1 = 6048e5; - -var second = newInterval(function(date) { - date.setTime(Math.floor(date / durationSecond$1) * durationSecond$1); -}, function(date, step) { - date.setTime(+date + step * durationSecond$1); -}, function(start, end) { - return (end - start) / durationSecond$1; -}, function(date) { - return date.getUTCSeconds(); -}); - -var minute = newInterval(function(date) { - date.setTime(Math.floor(date / durationMinute$1) * durationMinute$1); -}, function(date, step) { - date.setTime(+date + step * durationMinute$1); -}, function(start, end) { - return (end - start) / durationMinute$1; -}, function(date) { - return date.getMinutes(); -}); - -var hour = newInterval(function(date) { - var offset = date.getTimezoneOffset() * durationMinute$1 % durationHour$1; - if (offset < 0) offset += durationHour$1; - date.setTime(Math.floor((+date - offset) / durationHour$1) * durationHour$1 + offset); -}, function(date, step) { - date.setTime(+date + step * durationHour$1); -}, function(start, end) { - return (end - start) / durationHour$1; -}, function(date) { - return date.getHours(); -}); - -var day = newInterval(function(date) { - date.setHours(0, 0, 0, 0); -}, function(date, step) { - date.setDate(date.getDate() + step); -}, function(start, end) { - return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute$1) / durationDay$1; -}, function(date) { - return date.getDate() - 1; -}); - -function weekday(i) { - return newInterval(function(date) { - date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7); - date.setHours(0, 0, 0, 0); - }, function(date, step) { - date.setDate(date.getDate() + step * 7); - }, function(start, end) { - return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute$1) / durationWeek$1; - }); -} - -var sunday = weekday(0); -var monday = weekday(1); -var tuesday = weekday(2); -var wednesday = weekday(3); -var thursday = weekday(4); -var friday = weekday(5); -var saturday = weekday(6); - -var month = newInterval(function(date) { - date.setDate(1); - date.setHours(0, 0, 0, 0); -}, function(date, step) { - date.setMonth(date.getMonth() + step); -}, function(start, end) { - return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12; -}, function(date) { - return date.getMonth(); -}); - -var year = newInterval(function(date) { - date.setMonth(0, 1); - date.setHours(0, 0, 0, 0); -}, function(date, step) { - date.setFullYear(date.getFullYear() + step); -}, function(start, end) { - return end.getFullYear() - start.getFullYear(); -}, function(date) { - return date.getFullYear(); -}); - -// An optimized implementation for this simple case. -year.every = function(k) { - return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) { - date.setFullYear(Math.floor(date.getFullYear() / k) * k); - date.setMonth(0, 1); - date.setHours(0, 0, 0, 0); - }, function(date, step) { - date.setFullYear(date.getFullYear() + step * k); - }); -}; - -var utcMinute = newInterval(function(date) { - date.setUTCSeconds(0, 0); -}, function(date, step) { - date.setTime(+date + step * durationMinute$1); -}, function(start, end) { - return (end - start) / durationMinute$1; -}, function(date) { - return date.getUTCMinutes(); -}); - -var utcHour = newInterval(function(date) { - date.setUTCMinutes(0, 0, 0); -}, function(date, step) { - date.setTime(+date + step * durationHour$1); -}, function(start, end) { - return (end - start) / durationHour$1; -}, function(date) { - return date.getUTCHours(); -}); - -var utcDay = newInterval(function(date) { - date.setUTCHours(0, 0, 0, 0); -}, function(date, step) { - date.setUTCDate(date.getUTCDate() + step); -}, function(start, end) { - return (end - start) / durationDay$1; -}, function(date) { - return date.getUTCDate() - 1; -}); - -function utcWeekday(i) { - return newInterval(function(date) { - date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7); - date.setUTCHours(0, 0, 0, 0); - }, function(date, step) { - date.setUTCDate(date.getUTCDate() + step * 7); - }, function(start, end) { - return (end - start) / durationWeek$1; - }); -} - -var utcSunday = utcWeekday(0); -var utcMonday = utcWeekday(1); -var utcTuesday = utcWeekday(2); -var utcWednesday = utcWeekday(3); -var utcThursday = utcWeekday(4); -var utcFriday = utcWeekday(5); -var utcSaturday = utcWeekday(6); - -var utcMonth = newInterval(function(date) { - date.setUTCDate(1); - date.setUTCHours(0, 0, 0, 0); -}, function(date, step) { - date.setUTCMonth(date.getUTCMonth() + step); -}, function(start, end) { - return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12; -}, function(date) { - return date.getUTCMonth(); -}); - -var utcYear = newInterval(function(date) { - date.setUTCMonth(0, 1); - date.setUTCHours(0, 0, 0, 0); -}, function(date, step) { - date.setUTCFullYear(date.getUTCFullYear() + step); -}, function(start, end) { - return end.getUTCFullYear() - start.getUTCFullYear(); -}, function(date) { - return date.getUTCFullYear(); -}); - -// An optimized implementation for this simple case. -utcYear.every = function(k) { - return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) { - date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k); - date.setUTCMonth(0, 1); - date.setUTCHours(0, 0, 0, 0); - }, function(date, step) { - date.setUTCFullYear(date.getUTCFullYear() + step * k); - }); -}; - -function localDate(d) { - if (0 <= d.y && d.y < 100) { - var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L); - date.setFullYear(d.y); - return date; - } - return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L); -} - -function utcDate(d) { - if (0 <= d.y && d.y < 100) { - var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L)); - date.setUTCFullYear(d.y); - return date; - } - return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L)); -} - -function newYear(y) { - return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0}; -} - -function formatLocale$1(locale) { - var locale_dateTime = locale.dateTime, - locale_date = locale.date, - locale_time = locale.time, - locale_periods = locale.periods, - locale_weekdays = locale.days, - locale_shortWeekdays = locale.shortDays, - locale_months = locale.months, - locale_shortMonths = locale.shortMonths; - - var periodRe = formatRe(locale_periods), - periodLookup = formatLookup(locale_periods), - weekdayRe = formatRe(locale_weekdays), - weekdayLookup = formatLookup(locale_weekdays), - shortWeekdayRe = formatRe(locale_shortWeekdays), - shortWeekdayLookup = formatLookup(locale_shortWeekdays), - monthRe = formatRe(locale_months), - monthLookup = formatLookup(locale_months), - shortMonthRe = formatRe(locale_shortMonths), - shortMonthLookup = formatLookup(locale_shortMonths); - - var formats = { - "a": formatShortWeekday, - "A": formatWeekday, - "b": formatShortMonth, - "B": formatMonth, - "c": null, - "d": formatDayOfMonth, - "e": formatDayOfMonth, - "f": formatMicroseconds, - "H": formatHour24, - "I": formatHour12, - "j": formatDayOfYear, - "L": formatMilliseconds, - "m": formatMonthNumber, - "M": formatMinutes, - "p": formatPeriod, - "Q": formatUnixTimestamp, - "s": formatUnixTimestampSeconds, - "S": formatSeconds, - "u": formatWeekdayNumberMonday, - "U": formatWeekNumberSunday, - "V": formatWeekNumberISO, - "w": formatWeekdayNumberSunday, - "W": formatWeekNumberMonday, - "x": null, - "X": null, - "y": formatYear, - "Y": formatFullYear, - "Z": formatZone, - "%": formatLiteralPercent - }; - - var utcFormats = { - "a": formatUTCShortWeekday, - "A": formatUTCWeekday, - "b": formatUTCShortMonth, - "B": formatUTCMonth, - "c": null, - "d": formatUTCDayOfMonth, - "e": formatUTCDayOfMonth, - "f": formatUTCMicroseconds, - "H": formatUTCHour24, - "I": formatUTCHour12, - "j": formatUTCDayOfYear, - "L": formatUTCMilliseconds, - "m": formatUTCMonthNumber, - "M": formatUTCMinutes, - "p": formatUTCPeriod, - "Q": formatUnixTimestamp, - "s": formatUnixTimestampSeconds, - "S": formatUTCSeconds, - "u": formatUTCWeekdayNumberMonday, - "U": formatUTCWeekNumberSunday, - "V": formatUTCWeekNumberISO, - "w": formatUTCWeekdayNumberSunday, - "W": formatUTCWeekNumberMonday, - "x": null, - "X": null, - "y": formatUTCYear, - "Y": formatUTCFullYear, - "Z": formatUTCZone, - "%": formatLiteralPercent - }; - - var parses = { - "a": parseShortWeekday, - "A": parseWeekday, - "b": parseShortMonth, - "B": parseMonth, - "c": parseLocaleDateTime, - "d": parseDayOfMonth, - "e": parseDayOfMonth, - "f": parseMicroseconds, - "H": parseHour24, - "I": parseHour24, - "j": parseDayOfYear, - "L": parseMilliseconds, - "m": parseMonthNumber, - "M": parseMinutes, - "p": parsePeriod, - "Q": parseUnixTimestamp, - "s": parseUnixTimestampSeconds, - "S": parseSeconds, - "u": parseWeekdayNumberMonday, - "U": parseWeekNumberSunday, - "V": parseWeekNumberISO, - "w": parseWeekdayNumberSunday, - "W": parseWeekNumberMonday, - "x": parseLocaleDate, - "X": parseLocaleTime, - "y": parseYear, - "Y": parseFullYear, - "Z": parseZone, - "%": parseLiteralPercent - }; - - // These recursive directive definitions must be deferred. - formats.x = newFormat(locale_date, formats); - formats.X = newFormat(locale_time, formats); - formats.c = newFormat(locale_dateTime, formats); - utcFormats.x = newFormat(locale_date, utcFormats); - utcFormats.X = newFormat(locale_time, utcFormats); - utcFormats.c = newFormat(locale_dateTime, utcFormats); - - function newFormat(specifier, formats) { - return function(date) { - var string = [], - i = -1, - j = 0, - n = specifier.length, - c, - pad, - format; - - if (!(date instanceof Date)) date = new Date(+date); - - while (++i < n) { - if (specifier.charCodeAt(i) === 37) { - string.push(specifier.slice(j, i)); - if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i); - else pad = c === "e" ? " " : "0"; - if (format = formats[c]) c = format(date, pad); - string.push(c); - j = i + 1; - } - } - - string.push(specifier.slice(j, i)); - return string.join(""); - }; - } - - function newParse(specifier, newDate) { - return function(string) { - var d = newYear(1900), - i = parseSpecifier(d, specifier, string += "", 0), - week, day$$1; - if (i != string.length) return null; - - // If a UNIX timestamp is specified, return it. - if ("Q" in d) return new Date(d.Q); - - // The am-pm flag is 0 for AM, and 1 for PM. - if ("p" in d) d.H = d.H % 12 + d.p * 12; - - // Convert day-of-week and week-of-year to day-of-year. - if ("V" in d) { - if (d.V < 1 || d.V > 53) return null; - if (!("w" in d)) d.w = 1; - if ("Z" in d) { - week = utcDate(newYear(d.y)), day$$1 = week.getUTCDay(); - week = day$$1 > 4 || day$$1 === 0 ? utcMonday.ceil(week) : utcMonday(week); - week = utcDay.offset(week, (d.V - 1) * 7); - d.y = week.getUTCFullYear(); - d.m = week.getUTCMonth(); - d.d = week.getUTCDate() + (d.w + 6) % 7; - } else { - week = newDate(newYear(d.y)), day$$1 = week.getDay(); - week = day$$1 > 4 || day$$1 === 0 ? monday.ceil(week) : monday(week); - week = day.offset(week, (d.V - 1) * 7); - d.y = week.getFullYear(); - d.m = week.getMonth(); - d.d = week.getDate() + (d.w + 6) % 7; - } - } else if ("W" in d || "U" in d) { - if (!("w" in d)) d.w = "u" in d ? d.u % 7 : "W" in d ? 1 : 0; - day$$1 = "Z" in d ? utcDate(newYear(d.y)).getUTCDay() : newDate(newYear(d.y)).getDay(); - d.m = 0; - d.d = "W" in d ? (d.w + 6) % 7 + d.W * 7 - (day$$1 + 5) % 7 : d.w + d.U * 7 - (day$$1 + 6) % 7; - } - - // If a time zone is specified, all fields are interpreted as UTC and then - // offset according to the specified time zone. - if ("Z" in d) { - d.H += d.Z / 100 | 0; - d.M += d.Z % 100; - return utcDate(d); - } - - // Otherwise, all fields are in local time. - return newDate(d); - }; - } - - function parseSpecifier(d, specifier, string, j) { - var i = 0, - n = specifier.length, - m = string.length, - c, - parse; - - while (i < n) { - if (j >= m) return -1; - c = specifier.charCodeAt(i++); - if (c === 37) { - c = specifier.charAt(i++); - parse = parses[c in pads ? specifier.charAt(i++) : c]; - if (!parse || ((j = parse(d, string, j)) < 0)) return -1; - } else if (c != string.charCodeAt(j++)) { - return -1; - } - } - - return j; - } - - function parsePeriod(d, string, i) { - var n = periodRe.exec(string.slice(i)); - return n ? (d.p = periodLookup[n[0].toLowerCase()], i + n[0].length) : -1; - } - - function parseShortWeekday(d, string, i) { - var n = shortWeekdayRe.exec(string.slice(i)); - return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1; - } - - function parseWeekday(d, string, i) { - var n = weekdayRe.exec(string.slice(i)); - return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1; - } - - function parseShortMonth(d, string, i) { - var n = shortMonthRe.exec(string.slice(i)); - return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1; - } - - function parseMonth(d, string, i) { - var n = monthRe.exec(string.slice(i)); - return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1; - } - - function parseLocaleDateTime(d, string, i) { - return parseSpecifier(d, locale_dateTime, string, i); - } - - function parseLocaleDate(d, string, i) { - return parseSpecifier(d, locale_date, string, i); - } - - function parseLocaleTime(d, string, i) { - return parseSpecifier(d, locale_time, string, i); - } - - function formatShortWeekday(d) { - return locale_shortWeekdays[d.getDay()]; - } - - function formatWeekday(d) { - return locale_weekdays[d.getDay()]; - } - - function formatShortMonth(d) { - return locale_shortMonths[d.getMonth()]; - } - - function formatMonth(d) { - return locale_months[d.getMonth()]; - } - - function formatPeriod(d) { - return locale_periods[+(d.getHours() >= 12)]; - } - - function formatUTCShortWeekday(d) { - return locale_shortWeekdays[d.getUTCDay()]; - } - - function formatUTCWeekday(d) { - return locale_weekdays[d.getUTCDay()]; - } - - function formatUTCShortMonth(d) { - return locale_shortMonths[d.getUTCMonth()]; - } - - function formatUTCMonth(d) { - return locale_months[d.getUTCMonth()]; - } - - function formatUTCPeriod(d) { - return locale_periods[+(d.getUTCHours() >= 12)]; - } - - return { - format: function(specifier) { - var f = newFormat(specifier += "", formats); - f.toString = function() { return specifier; }; - return f; - }, - parse: function(specifier) { - var p = newParse(specifier += "", localDate); - p.toString = function() { return specifier; }; - return p; - }, - utcFormat: function(specifier) { - var f = newFormat(specifier += "", utcFormats); - f.toString = function() { return specifier; }; - return f; - }, - utcParse: function(specifier) { - var p = newParse(specifier, utcDate); - p.toString = function() { return specifier; }; - return p; - } - }; -} - -var pads = {"-": "", "_": " ", "0": "0"}; -var numberRe = /^\s*\d+/; -var percentRe = /^%/; -var requoteRe = /[\\^$*+?|[\]().{}]/g; - -function pad(value, fill, width) { - var sign = value < 0 ? "-" : "", - string = (sign ? -value : value) + "", - length = string.length; - return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); -} - -function requote(s) { - return s.replace(requoteRe, "\\$&"); -} - -function formatRe(names) { - return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i"); -} - -function formatLookup(names) { - var map = {}, i = -1, n = names.length; - while (++i < n) map[names[i].toLowerCase()] = i; - return map; -} - -function parseWeekdayNumberSunday(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 1)); - return n ? (d.w = +n[0], i + n[0].length) : -1; -} - -function parseWeekdayNumberMonday(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 1)); - return n ? (d.u = +n[0], i + n[0].length) : -1; -} - -function parseWeekNumberSunday(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 2)); - return n ? (d.U = +n[0], i + n[0].length) : -1; -} - -function parseWeekNumberISO(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 2)); - return n ? (d.V = +n[0], i + n[0].length) : -1; -} - -function parseWeekNumberMonday(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 2)); - return n ? (d.W = +n[0], i + n[0].length) : -1; -} - -function parseFullYear(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 4)); - return n ? (d.y = +n[0], i + n[0].length) : -1; -} - -function parseYear(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 2)); - return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1; -} - -function parseZone(d, string, i) { - var n = /^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(string.slice(i, i + 6)); - return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || "00")), i + n[0].length) : -1; -} - -function parseMonthNumber(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 2)); - return n ? (d.m = n[0] - 1, i + n[0].length) : -1; -} - -function parseDayOfMonth(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 2)); - return n ? (d.d = +n[0], i + n[0].length) : -1; -} - -function parseDayOfYear(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 3)); - return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1; -} - -function parseHour24(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 2)); - return n ? (d.H = +n[0], i + n[0].length) : -1; -} - -function parseMinutes(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 2)); - return n ? (d.M = +n[0], i + n[0].length) : -1; -} - -function parseSeconds(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 2)); - return n ? (d.S = +n[0], i + n[0].length) : -1; -} - -function parseMilliseconds(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 3)); - return n ? (d.L = +n[0], i + n[0].length) : -1; -} - -function parseMicroseconds(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 6)); - return n ? (d.L = Math.floor(n[0] / 1000), i + n[0].length) : -1; -} - -function parseLiteralPercent(d, string, i) { - var n = percentRe.exec(string.slice(i, i + 1)); - return n ? i + n[0].length : -1; -} - -function parseUnixTimestamp(d, string, i) { - var n = numberRe.exec(string.slice(i)); - return n ? (d.Q = +n[0], i + n[0].length) : -1; -} - -function parseUnixTimestampSeconds(d, string, i) { - var n = numberRe.exec(string.slice(i)); - return n ? (d.Q = (+n[0]) * 1000, i + n[0].length) : -1; -} - -function formatDayOfMonth(d, p) { - return pad(d.getDate(), p, 2); -} - -function formatHour24(d, p) { - return pad(d.getHours(), p, 2); -} - -function formatHour12(d, p) { - return pad(d.getHours() % 12 || 12, p, 2); -} - -function formatDayOfYear(d, p) { - return pad(1 + day.count(year(d), d), p, 3); -} - -function formatMilliseconds(d, p) { - return pad(d.getMilliseconds(), p, 3); -} - -function formatMicroseconds(d, p) { - return formatMilliseconds(d, p) + "000"; -} - -function formatMonthNumber(d, p) { - return pad(d.getMonth() + 1, p, 2); -} - -function formatMinutes(d, p) { - return pad(d.getMinutes(), p, 2); -} - -function formatSeconds(d, p) { - return pad(d.getSeconds(), p, 2); -} - -function formatWeekdayNumberMonday(d) { - var day$$1 = d.getDay(); - return day$$1 === 0 ? 7 : day$$1; -} - -function formatWeekNumberSunday(d, p) { - return pad(sunday.count(year(d), d), p, 2); -} - -function formatWeekNumberISO(d, p) { - var day$$1 = d.getDay(); - d = (day$$1 >= 4 || day$$1 === 0) ? thursday(d) : thursday.ceil(d); - return pad(thursday.count(year(d), d) + (year(d).getDay() === 4), p, 2); -} - -function formatWeekdayNumberSunday(d) { - return d.getDay(); -} - -function formatWeekNumberMonday(d, p) { - return pad(monday.count(year(d), d), p, 2); -} - -function formatYear(d, p) { - return pad(d.getFullYear() % 100, p, 2); -} - -function formatFullYear(d, p) { - return pad(d.getFullYear() % 10000, p, 4); -} - -function formatZone(d) { - var z = d.getTimezoneOffset(); - return (z > 0 ? "-" : (z *= -1, "+")) - + pad(z / 60 | 0, "0", 2) - + pad(z % 60, "0", 2); -} - -function formatUTCDayOfMonth(d, p) { - return pad(d.getUTCDate(), p, 2); -} - -function formatUTCHour24(d, p) { - return pad(d.getUTCHours(), p, 2); -} - -function formatUTCHour12(d, p) { - return pad(d.getUTCHours() % 12 || 12, p, 2); -} - -function formatUTCDayOfYear(d, p) { - return pad(1 + utcDay.count(utcYear(d), d), p, 3); -} - -function formatUTCMilliseconds(d, p) { - return pad(d.getUTCMilliseconds(), p, 3); -} - -function formatUTCMicroseconds(d, p) { - return formatUTCMilliseconds(d, p) + "000"; -} - -function formatUTCMonthNumber(d, p) { - return pad(d.getUTCMonth() + 1, p, 2); -} - -function formatUTCMinutes(d, p) { - return pad(d.getUTCMinutes(), p, 2); -} - -function formatUTCSeconds(d, p) { - return pad(d.getUTCSeconds(), p, 2); -} - -function formatUTCWeekdayNumberMonday(d) { - var dow = d.getUTCDay(); - return dow === 0 ? 7 : dow; -} - -function formatUTCWeekNumberSunday(d, p) { - return pad(utcSunday.count(utcYear(d), d), p, 2); -} - -function formatUTCWeekNumberISO(d, p) { - var day$$1 = d.getUTCDay(); - d = (day$$1 >= 4 || day$$1 === 0) ? utcThursday(d) : utcThursday.ceil(d); - return pad(utcThursday.count(utcYear(d), d) + (utcYear(d).getUTCDay() === 4), p, 2); -} - -function formatUTCWeekdayNumberSunday(d) { - return d.getUTCDay(); -} - -function formatUTCWeekNumberMonday(d, p) { - return pad(utcMonday.count(utcYear(d), d), p, 2); -} - -function formatUTCYear(d, p) { - return pad(d.getUTCFullYear() % 100, p, 2); -} - -function formatUTCFullYear(d, p) { - return pad(d.getUTCFullYear() % 10000, p, 4); -} - -function formatUTCZone() { - return "+0000"; -} - -function formatLiteralPercent() { - return "%"; -} - -function formatUnixTimestamp(d) { - return +d; -} - -function formatUnixTimestampSeconds(d) { - return Math.floor(+d / 1000); -} - -var locale$1; -var timeFormat; -var timeParse; -var utcFormat; -var utcParse; - -defaultLocale$1({ - dateTime: "%x, %X", - date: "%-m/%-d/%Y", - time: "%-I:%M:%S %p", - periods: ["AM", "PM"], - days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], - shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], - months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], - shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] -}); - -function defaultLocale$1(definition) { - locale$1 = formatLocale$1(definition); - timeFormat = locale$1.format; - timeParse = locale$1.parse; - utcFormat = locale$1.utcFormat; - utcParse = locale$1.utcParse; - return locale$1; -} - -var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ"; - -function formatIsoNative(date) { - return date.toISOString(); -} - -var formatIso = Date.prototype.toISOString - ? formatIsoNative - : utcFormat(isoSpecifier); - -function parseIsoNative(string) { - var date = new Date(string); - return isNaN(date) ? null : date; -} - -var parseIso = +new Date("2000-01-01T00:00:00.000Z") - ? parseIsoNative - : utcParse(isoSpecifier); - -var colors = function(s) { - return s.match(/.{6}/g).map(function(x) { - return "#" + x; - }); -}; - -colors("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf"); - -colors("393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6"); - -colors("3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9"); - -colors("1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5"); - -cubehelixLong(cubehelix(300, 0.5, 0.0), cubehelix(-240, 0.5, 1.0)); - -var warm = cubehelixLong(cubehelix(-100, 0.75, 0.35), cubehelix(80, 1.50, 0.8)); - -var cool = cubehelixLong(cubehelix(260, 0.75, 0.35), cubehelix(80, 1.50, 0.8)); - -var rainbow = cubehelix(); - -function ramp(range) { - var n = range.length; - return function(t) { - return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))]; - }; -} - -ramp(colors("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725")); - -var magma = ramp(colors("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")); - -var inferno = ramp(colors("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")); - -var plasma = ramp(colors("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921")); - -function cubicInOut(t) { - return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2; -} - -var pi = Math.PI; - -var tau = 2 * Math.PI; - -var noop = {value: function() {}}; - -function dispatch() { - for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) { - if (!(t = arguments[i] + "") || (t in _)) throw new Error("illegal type: " + t); - _[t] = []; - } - return new Dispatch(_); -} - -function Dispatch(_) { - this._ = _; -} - -function parseTypenames$1(typenames, types) { - return typenames.trim().split(/^|\s+/).map(function(t) { - var name = "", i = t.indexOf("."); - if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); - if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t); - return {type: t, name: name}; - }); -} - -Dispatch.prototype = dispatch.prototype = { - constructor: Dispatch, - on: function(typename, callback) { - var _ = this._, - T = parseTypenames$1(typename + "", _), - t, - i = -1, - n = T.length; - - // If no callback was specified, return the callback of the given type and name. - if (arguments.length < 2) { - while (++i < n) if ((t = (typename = T[i]).type) && (t = get$1(_[t], typename.name))) return t; - return; - } - - // If a type was specified, set the callback for the given type and name. - // Otherwise, if a null callback was specified, remove callbacks of the given name. - if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback); - while (++i < n) { - if (t = (typename = T[i]).type) _[t] = set$3(_[t], typename.name, callback); - else if (callback == null) for (t in _) _[t] = set$3(_[t], typename.name, null); - } - - return this; - }, - copy: function() { - var copy = {}, _ = this._; - for (var t in _) copy[t] = _[t].slice(); - return new Dispatch(copy); - }, - call: function(type, that) { - if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2]; - if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); - for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); - }, - apply: function(type, that, args) { - if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); - for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); - } -}; - -function get$1(type, name) { - for (var i = 0, n = type.length, c; i < n; ++i) { - if ((c = type[i]).name === name) { - return c.value; - } - } -} - -function set$3(type, name, callback) { - for (var i = 0, n = type.length; i < n; ++i) { - if (type[i].name === name) { - type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1)); - break; - } - } - if (callback != null) type.push({name: name, value: callback}); - return type; -} - -var frame = 0; -var timeout = 0; -var interval = 0; -var pokeDelay = 1000; -var taskHead; -var taskTail; -var clockLast = 0; -var clockNow = 0; -var clockSkew = 0; -var clock = typeof performance === "object" && performance.now ? performance : Date; -var setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); }; - -function now() { - return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew); -} - -function clearNow() { - clockNow = 0; -} - -function Timer() { - this._call = - this._time = - this._next = null; -} - -Timer.prototype = timer.prototype = { - constructor: Timer, - restart: function(callback, delay, time) { - if (typeof callback !== "function") throw new TypeError("callback is not a function"); - time = (time == null ? now() : +time) + (delay == null ? 0 : +delay); - if (!this._next && taskTail !== this) { - if (taskTail) taskTail._next = this; - else taskHead = this; - taskTail = this; - } - this._call = callback; - this._time = time; - sleep(); - }, - stop: function() { - if (this._call) { - this._call = null; - this._time = Infinity; - sleep(); - } - } -}; - -function timer(callback, delay, time) { - var t = new Timer; - t.restart(callback, delay, time); - return t; -} - -function timerFlush() { - now(); // Get the current time, if not already set. - ++frame; // Pretend we’ve set an alarm, if we haven’t already. - var t = taskHead, e; - while (t) { - if ((e = clockNow - t._time) >= 0) t._call.call(null, e); - t = t._next; - } - --frame; -} - -function wake() { - clockNow = (clockLast = clock.now()) + clockSkew; - frame = timeout = 0; - try { - timerFlush(); - } finally { - frame = 0; - nap(); - clockNow = 0; - } -} - -function poke() { - var now = clock.now(), delay = now - clockLast; - if (delay > pokeDelay) clockSkew -= delay, clockLast = now; -} - -function nap() { - var t0, t1 = taskHead, t2, time = Infinity; - while (t1) { - if (t1._call) { - if (time > t1._time) time = t1._time; - t0 = t1, t1 = t1._next; - } else { - t2 = t1._next, t1._next = null; - t1 = t0 ? t0._next = t2 : taskHead = t2; - } - } - taskTail = t0; - sleep(time); -} - -function sleep(time) { - if (frame) return; // Soonest alarm already set, or will be. - if (timeout) timeout = clearTimeout(timeout); - var delay = time - clockNow; // Strictly less than if we recomputed clockNow. - if (delay > 24) { - if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew); - if (interval) interval = clearInterval(interval); - } else { - if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay); - frame = 1, setFrame(wake); - } -} - -var timeout$1 = function(callback, delay, time) { - var t = new Timer; - delay = delay == null ? 0 : +delay; - t.restart(function(elapsed) { - t.stop(); - callback(elapsed + delay); - }, delay, time); - return t; -}; - -var emptyOn = dispatch("start", "end", "interrupt"); -var emptyTween = []; - -var CREATED = 0; -var SCHEDULED = 1; -var STARTING = 2; -var STARTED = 3; -var RUNNING = 4; -var ENDING = 5; -var ENDED = 6; - -var schedule = function(node, name, id, index, group, timing) { - var schedules = node.__transition; - if (!schedules) node.__transition = {}; - else if (id in schedules) return; - create(node, id, { - name: name, - index: index, // For context during callback. - group: group, // For context during callback. - on: emptyOn, - tween: emptyTween, - time: timing.time, - delay: timing.delay, - duration: timing.duration, - ease: timing.ease, - timer: null, - state: CREATED - }); -}; - -function init(node, id) { - var schedule = node.__transition; - if (!schedule || !(schedule = schedule[id]) || schedule.state > CREATED) throw new Error("too late"); - return schedule; -} - -function set$2(node, id) { - var schedule = node.__transition; - if (!schedule || !(schedule = schedule[id]) || schedule.state > STARTING) throw new Error("too late"); - return schedule; -} - -function get(node, id) { - var schedule = node.__transition; - if (!schedule || !(schedule = schedule[id])) throw new Error("too late"); - return schedule; -} - -function create(node, id, self) { - var schedules = node.__transition, - tween; - - // Initialize the self timer when the transition is created. - // Note the actual delay is not known until the first callback! - schedules[id] = self; - self.timer = timer(schedule, 0, self.time); - - function schedule(elapsed) { - self.state = SCHEDULED; - self.timer.restart(start, self.delay, self.time); - - // If the elapsed delay is less than our first sleep, start immediately. - if (self.delay <= elapsed) start(elapsed - self.delay); - } - - function start(elapsed) { - var i, j, n, o; - - // If the state is not SCHEDULED, then we previously errored on start. - if (self.state !== SCHEDULED) return stop(); - - for (i in schedules) { - o = schedules[i]; - if (o.name !== self.name) continue; - - // While this element already has a starting transition during this frame, - // defer starting an interrupting transition until that transition has a - // chance to tick (and possibly end); see d3/d3-transition#54! - if (o.state === STARTED) return timeout$1(start); - - // Interrupt the active transition, if any. - // Dispatch the interrupt event. - if (o.state === RUNNING) { - o.state = ENDED; - o.timer.stop(); - o.on.call("interrupt", node, node.__data__, o.index, o.group); - delete schedules[i]; - } - - // Cancel any pre-empted transitions. No interrupt event is dispatched - // because the cancelled transitions never started. Note that this also - // removes this transition from the pending list! - else if (+i < id) { - o.state = ENDED; - o.timer.stop(); - delete schedules[i]; - } - } - - // Defer the first tick to end of the current frame; see d3/d3#1576. - // Note the transition may be canceled after start and before the first tick! - // Note this must be scheduled before the start event; see d3/d3-transition#16! - // Assuming this is successful, subsequent callbacks go straight to tick. - timeout$1(function() { - if (self.state === STARTED) { - self.state = RUNNING; - self.timer.restart(tick, self.delay, self.time); - tick(elapsed); - } - }); - - // Dispatch the start event. - // Note this must be done before the tween are initialized. - self.state = STARTING; - self.on.call("start", node, node.__data__, self.index, self.group); - if (self.state !== STARTING) return; // interrupted - self.state = STARTED; - - // Initialize the tween, deleting null tween. - tween = new Array(n = self.tween.length); - for (i = 0, j = -1; i < n; ++i) { - if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) { - tween[++j] = o; - } - } - tween.length = j + 1; - } - - function tick(elapsed) { - var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1), - i = -1, - n = tween.length; - - while (++i < n) { - tween[i].call(null, t); - } - - // Dispatch the end event. - if (self.state === ENDING) { - self.on.call("end", node, node.__data__, self.index, self.group); - stop(); - } - } - - function stop() { - self.state = ENDED; - self.timer.stop(); - delete schedules[id]; - for (var i in schedules) return; // eslint-disable-line no-unused-vars - delete node.__transition; - } -} - -var interrupt = function(node, name) { - var schedules = node.__transition, - schedule$$1, - active, - empty = true, - i; - - if (!schedules) return; - - name = name == null ? null : name + ""; - - for (i in schedules) { - if ((schedule$$1 = schedules[i]).name !== name) { empty = false; continue; } - active = schedule$$1.state > STARTING && schedule$$1.state < ENDING; - schedule$$1.state = ENDED; - schedule$$1.timer.stop(); - if (active) schedule$$1.on.call("interrupt", node, node.__data__, schedule$$1.index, schedule$$1.group); - delete schedules[i]; - } - - if (empty) delete node.__transition; -}; - -var selection_interrupt = function(name) { - return this.each(function() { - interrupt(this, name); - }); -}; - -function tweenRemove(id, name) { - var tween0, tween1; - return function() { - var schedule$$1 = set$2(this, id), - tween = schedule$$1.tween; - - // If this node shared tween with the previous node, - // just assign the updated shared tween and we’re done! - // Otherwise, copy-on-write. - if (tween !== tween0) { - tween1 = tween0 = tween; - for (var i = 0, n = tween1.length; i < n; ++i) { - if (tween1[i].name === name) { - tween1 = tween1.slice(); - tween1.splice(i, 1); - break; - } - } - } - - schedule$$1.tween = tween1; - }; -} - -function tweenFunction(id, name, value) { - var tween0, tween1; - if (typeof value !== "function") throw new Error; - return function() { - var schedule$$1 = set$2(this, id), - tween = schedule$$1.tween; - - // If this node shared tween with the previous node, - // just assign the updated shared tween and we’re done! - // Otherwise, copy-on-write. - if (tween !== tween0) { - tween1 = (tween0 = tween).slice(); - for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) { - if (tween1[i].name === name) { - tween1[i] = t; - break; - } - } - if (i === n) tween1.push(t); - } - - schedule$$1.tween = tween1; - }; -} - -var transition_tween = function(name, value) { - var id = this._id; - - name += ""; - - if (arguments.length < 2) { - var tween = get(this.node(), id).tween; - for (var i = 0, n = tween.length, t; i < n; ++i) { - if ((t = tween[i]).name === name) { - return t.value; - } - } - return null; - } - - return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value)); -}; - -function tweenValue(transition, name, value) { - var id = transition._id; - - transition.each(function() { - var schedule$$1 = set$2(this, id); - (schedule$$1.value || (schedule$$1.value = {}))[name] = value.apply(this, arguments); - }); - - return function(node) { - return get(node, id).value[name]; - }; -} - -var interpolate = function(a, b) { - var c; - return (typeof b === "number" ? interpolateNumber - : b instanceof color ? interpolateRgb - : (c = color(b)) ? (b = c, interpolateRgb) - : interpolateString)(a, b); -}; - -function attrRemove$1(name) { - return function() { - this.removeAttribute(name); - }; -} - -function attrRemoveNS$1(fullname) { - return function() { - this.removeAttributeNS(fullname.space, fullname.local); - }; -} - -function attrConstant$1(name, interpolate$$1, value1) { - var value00, - interpolate0; - return function() { - var value0 = this.getAttribute(name); - return value0 === value1 ? null - : value0 === value00 ? interpolate0 - : interpolate0 = interpolate$$1(value00 = value0, value1); - }; -} - -function attrConstantNS$1(fullname, interpolate$$1, value1) { - var value00, - interpolate0; - return function() { - var value0 = this.getAttributeNS(fullname.space, fullname.local); - return value0 === value1 ? null - : value0 === value00 ? interpolate0 - : interpolate0 = interpolate$$1(value00 = value0, value1); - }; -} - -function attrFunction$1(name, interpolate$$1, value) { - var value00, - value10, - interpolate0; - return function() { - var value0, value1 = value(this); - if (value1 == null) return void this.removeAttribute(name); - value0 = this.getAttribute(name); - return value0 === value1 ? null - : value0 === value00 && value1 === value10 ? interpolate0 - : interpolate0 = interpolate$$1(value00 = value0, value10 = value1); - }; -} - -function attrFunctionNS$1(fullname, interpolate$$1, value) { - var value00, - value10, - interpolate0; - return function() { - var value0, value1 = value(this); - if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local); - value0 = this.getAttributeNS(fullname.space, fullname.local); - return value0 === value1 ? null - : value0 === value00 && value1 === value10 ? interpolate0 - : interpolate0 = interpolate$$1(value00 = value0, value10 = value1); - }; -} - -var transition_attr = function(name, value) { - var fullname = namespace(name), i = fullname === "transform" ? interpolateTransformSvg : interpolate; - return this.attrTween(name, typeof value === "function" - ? (fullname.local ? attrFunctionNS$1 : attrFunction$1)(fullname, i, tweenValue(this, "attr." + name, value)) - : value == null ? (fullname.local ? attrRemoveNS$1 : attrRemove$1)(fullname) - : (fullname.local ? attrConstantNS$1 : attrConstant$1)(fullname, i, value + "")); -}; - -function attrTweenNS(fullname, value) { - function tween() { - var node = this, i = value.apply(node, arguments); - return i && function(t) { - node.setAttributeNS(fullname.space, fullname.local, i(t)); - }; - } - tween._value = value; - return tween; -} - -function attrTween(name, value) { - function tween() { - var node = this, i = value.apply(node, arguments); - return i && function(t) { - node.setAttribute(name, i(t)); - }; - } - tween._value = value; - return tween; -} - -var transition_attrTween = function(name, value) { - var key = "attr." + name; - if (arguments.length < 2) return (key = this.tween(key)) && key._value; - if (value == null) return this.tween(key, null); - if (typeof value !== "function") throw new Error; - var fullname = namespace(name); - return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value)); -}; - -function delayFunction(id, value) { - return function() { - init(this, id).delay = +value.apply(this, arguments); - }; -} - -function delayConstant(id, value) { - return value = +value, function() { - init(this, id).delay = value; - }; -} - -var transition_delay = function(value) { - var id = this._id; - - return arguments.length - ? this.each((typeof value === "function" - ? delayFunction - : delayConstant)(id, value)) - : get(this.node(), id).delay; -}; - -function durationFunction(id, value) { - return function() { - set$2(this, id).duration = +value.apply(this, arguments); - }; -} - -function durationConstant(id, value) { - return value = +value, function() { - set$2(this, id).duration = value; - }; -} - -var transition_duration = function(value) { - var id = this._id; - - return arguments.length - ? this.each((typeof value === "function" - ? durationFunction - : durationConstant)(id, value)) - : get(this.node(), id).duration; -}; - -function easeConstant(id, value) { - if (typeof value !== "function") throw new Error; - return function() { - set$2(this, id).ease = value; - }; -} - -var transition_ease = function(value) { - var id = this._id; - - return arguments.length - ? this.each(easeConstant(id, value)) - : get(this.node(), id).ease; -}; - -var transition_filter = function(match) { - if (typeof match !== "function") match = matcher$1(match); - - for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) { - if ((node = group[i]) && match.call(node, node.__data__, i, group)) { - subgroup.push(node); - } - } - } - - return new Transition(subgroups, this._parents, this._name, this._id); -}; - -var transition_merge = function(transition$$1) { - if (transition$$1._id !== this._id) throw new Error; - - for (var groups0 = this._groups, groups1 = transition$$1._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { - for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { - if (node = group0[i] || group1[i]) { - merge[i] = node; - } - } - } - - for (; j < m0; ++j) { - merges[j] = groups0[j]; - } - - return new Transition(merges, this._parents, this._name, this._id); -}; - -function start(name) { - return (name + "").trim().split(/^|\s+/).every(function(t) { - var i = t.indexOf("."); - if (i >= 0) t = t.slice(0, i); - return !t || t === "start"; - }); -} - -function onFunction(id, name, listener) { - var on0, on1, sit = start(name) ? init : set$2; - return function() { - var schedule$$1 = sit(this, id), - on = schedule$$1.on; - - // If this node shared a dispatch with the previous node, - // just assign the updated shared dispatch and we’re done! - // Otherwise, copy-on-write. - if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener); - - schedule$$1.on = on1; - }; -} - -var transition_on = function(name, listener) { - var id = this._id; - - return arguments.length < 2 - ? get(this.node(), id).on.on(name) - : this.each(onFunction(id, name, listener)); -}; - -function removeFunction(id) { - return function() { - var parent = this.parentNode; - for (var i in this.__transition) if (+i !== id) return; - if (parent) parent.removeChild(this); - }; -} - -var transition_remove = function() { - return this.on("end.remove", removeFunction(this._id)); -}; - -var transition_select = function(select) { - var name = this._name, - id = this._id; - - if (typeof select !== "function") select = selector(select); - - for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) { - if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) { - if ("__data__" in node) subnode.__data__ = node.__data__; - subgroup[i] = subnode; - schedule(subgroup[i], name, id, i, subgroup, get(node, id)); - } - } - } - - return new Transition(subgroups, this._parents, name, id); -}; - -var transition_selectAll = function(select) { - var name = this._name, - id = this._id; - - if (typeof select !== "function") select = selectorAll(select); - - for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { - if (node = group[i]) { - for (var children = select.call(node, node.__data__, i, group), child, inherit = get(node, id), k = 0, l = children.length; k < l; ++k) { - if (child = children[k]) { - schedule(child, name, id, k, children, inherit); - } - } - subgroups.push(children); - parents.push(node); - } - } - } - - return new Transition(subgroups, parents, name, id); -}; - -var Selection$1 = selection.prototype.constructor; - -var transition_selection = function() { - return new Selection$1(this._groups, this._parents); -}; - -function styleRemove$1(name, interpolate$$1) { - var value00, - value10, - interpolate0; - return function() { - var value0 = styleValue(this, name), - value1 = (this.style.removeProperty(name), styleValue(this, name)); - return value0 === value1 ? null - : value0 === value00 && value1 === value10 ? interpolate0 - : interpolate0 = interpolate$$1(value00 = value0, value10 = value1); - }; -} - -function styleRemoveEnd(name) { - return function() { - this.style.removeProperty(name); - }; -} - -function styleConstant$1(name, interpolate$$1, value1) { - var value00, - interpolate0; - return function() { - var value0 = styleValue(this, name); - return value0 === value1 ? null - : value0 === value00 ? interpolate0 - : interpolate0 = interpolate$$1(value00 = value0, value1); - }; -} - -function styleFunction$1(name, interpolate$$1, value) { - var value00, - value10, - interpolate0; - return function() { - var value0 = styleValue(this, name), - value1 = value(this); - if (value1 == null) value1 = (this.style.removeProperty(name), styleValue(this, name)); - return value0 === value1 ? null - : value0 === value00 && value1 === value10 ? interpolate0 - : interpolate0 = interpolate$$1(value00 = value0, value10 = value1); - }; -} - -var transition_style = function(name, value, priority) { - var i = (name += "") === "transform" ? interpolateTransformCss : interpolate; - return value == null ? this - .styleTween(name, styleRemove$1(name, i)) - .on("end.style." + name, styleRemoveEnd(name)) - : this.styleTween(name, typeof value === "function" - ? styleFunction$1(name, i, tweenValue(this, "style." + name, value)) - : styleConstant$1(name, i, value + ""), priority); -}; - -function styleTween(name, value, priority) { - function tween() { - var node = this, i = value.apply(node, arguments); - return i && function(t) { - node.style.setProperty(name, i(t), priority); - }; - } - tween._value = value; - return tween; -} - -var transition_styleTween = function(name, value, priority) { - var key = "style." + (name += ""); - if (arguments.length < 2) return (key = this.tween(key)) && key._value; - if (value == null) return this.tween(key, null); - if (typeof value !== "function") throw new Error; - return this.tween(key, styleTween(name, value, priority == null ? "" : priority)); -}; - -function textConstant$1(value) { - return function() { - this.textContent = value; - }; -} - -function textFunction$1(value) { - return function() { - var value1 = value(this); - this.textContent = value1 == null ? "" : value1; - }; -} - -var transition_text = function(value) { - return this.tween("text", typeof value === "function" - ? textFunction$1(tweenValue(this, "text", value)) - : textConstant$1(value == null ? "" : value + "")); -}; - -var transition_transition = function() { - var name = this._name, - id0 = this._id, - id1 = newId(); - - for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { - if (node = group[i]) { - var inherit = get(node, id0); - schedule(node, name, id1, i, group, { - time: inherit.time + inherit.delay + inherit.duration, - delay: 0, - duration: inherit.duration, - ease: inherit.ease - }); - } - } - } - - return new Transition(groups, this._parents, name, id1); -}; - -var id = 0; - -function Transition(groups, parents, name, id) { - this._groups = groups; - this._parents = parents; - this._name = name; - this._id = id; -} - -function transition(name) { - return selection().transition(name); -} - -function newId() { - return ++id; -} - -var selection_prototype = selection.prototype; - -Transition.prototype = transition.prototype = { - constructor: Transition, - select: transition_select, - selectAll: transition_selectAll, - filter: transition_filter, - merge: transition_merge, - selection: transition_selection, - transition: transition_transition, - call: selection_prototype.call, - nodes: selection_prototype.nodes, - node: selection_prototype.node, - size: selection_prototype.size, - empty: selection_prototype.empty, - each: selection_prototype.each, - on: transition_on, - attr: transition_attr, - attrTween: transition_attrTween, - style: transition_style, - styleTween: transition_styleTween, - text: transition_text, - remove: transition_remove, - tween: transition_tween, - delay: transition_delay, - duration: transition_duration, - ease: transition_ease -}; - -var defaultTiming = { - time: null, // Set on use. - delay: 0, - duration: 250, - ease: cubicInOut -}; - -function inherit(node, id) { - var timing; - while (!(timing = node.__transition) || !(timing = timing[id])) { - if (!(node = node.parentNode)) { - return defaultTiming.time = now(), defaultTiming; - } - } - return timing; -} - -var selection_transition = function(name) { - var id, - timing; - - if (name instanceof Transition) { - id = name._id, name = name._name; - } else { - id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + ""; - } - - for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { - if (node = group[i]) { - schedule(node, name, id, i, group, timing || inherit(node, id)); - } - } - } - - return new Transition(groups, this._parents, name, id); -}; - -selection.prototype.interrupt = selection_interrupt; -selection.prototype.transition = selection_transition; - -exports.select = select; -exports.selection = selection; -exports.hierarchy = hierarchy; -exports.partition = partition; -exports.scaleLinear = linear; -exports.easeCubic = cubicInOut; -exports.ascending = ascending$1; -exports.map = map$1; -exports.transition = transition; - -Object.defineProperty(exports, '__esModule', { value: true }); - -}))); -` diff --git a/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/LICENSE b/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_FLAME_GRAPH_LICENSE similarity index 100% rename from src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/LICENSE rename to src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_FLAME_GRAPH_LICENSE diff --git a/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_LICENSE b/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_LICENSE new file mode 100644 index 0000000000..b0145150fd --- /dev/null +++ b/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_LICENSE @@ -0,0 +1,13 @@ +Copyright 2010-2021 Mike Bostock + +Permission to use, copy, modify, and/or distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. diff --git a/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/README.md b/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/README.md new file mode 100644 index 0000000000..eb84b68007 --- /dev/null +++ b/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/README.md @@ -0,0 +1,33 @@ +# Building a customized D3.js bundle + +The D3.js version distributed with pprof is customized to only include the +modules required by pprof. + +## Dependencies + +- Install [npm](https://www.npmjs.com). + +## Building + +- Run `update.sh` to: + - Download npm package dependencies (declared in `package.json` and `package-lock.json`) + - Create a d3.js bundle containing the JavScript of d3 and d3-flame-graph (by running `webpack`) + +This will `d3_flame_graph.go`, the minified custom D3.js bundle as Go source code. + +# References / Appendix + +## D3 Custom Bundle + +A demonstration of building a custom D3 4.0 bundle using ES2015 modules and Rollup. + +[bl.ocks.org/mbostock/bb09af4c39c79cffcde4](https://bl.ocks.org/mbostock/bb09af4c39c79cffcde4) + +## Old version of d3-pprof + +A previous version of d3-flame-graph bundled for pprof used Rollup instead of +Webpack. This has now been migrated directly into this directory. + +The repository configuring Rollup was here: + +[github.com/spiermar/d3-pprof](https://github.com/spiermar/d3-pprof) diff --git a/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/d3_flame_graph.go b/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/d3_flame_graph.go index 58a7fb4c40..7e27941995 100644 --- a/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/d3_flame_graph.go +++ b/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/d3_flame_graph.go @@ -1,915 +1,17 @@ -// A D3.js plugin that produces flame graphs from hierarchical data. +// D3.js is a JavaScript library for manipulating documents based on data. +// https://github.com/d3/d3 +// See D3_LICENSE file for license details + +// d3-flame-graph is a D3.js plugin that produces flame graphs from hierarchical data. // https://github.com/spiermar/d3-flame-graph -// Version 2.0.0-alpha4 -// See LICENSE file for license details +// See D3_FLAME_GRAPH_LICENSE file for license details package d3flamegraph -// JSSource returns the d3-flamegraph.js file +// JSSource returns the d3 and d3-flame-graph JavaScript bundle const JSSource = ` -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3')) : - typeof define === 'function' && define.amd ? define(['exports', 'd3'], factory) : - (factory((global.d3 = global.d3 || {}),global.d3)); -}(this, (function (exports,d3) { 'use strict'; - -var d3__default = 'default' in d3 ? d3['default'] : d3; - -var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - - - - - -function createCommonjsModule(fn, module) { - return module = { exports: {} }, fn(module, module.exports), module.exports; -} - -var d3Tip = createCommonjsModule(function (module) { -// d3.tip -// Copyright (c) 2013 Justin Palmer -// -// Tooltips for d3.js SVG visualizations - -(function (root, factory) { - if (typeof undefined === 'function' && undefined.amd) { - // AMD. Register as an anonymous module with d3 as a dependency. - undefined(['d3'], factory); - } else if ('object' === 'object' && module.exports) { - // CommonJS - var d3$$1 = d3__default; - module.exports = factory(d3$$1); - } else { - // Browser global. - root.d3.tip = factory(root.d3); - } -}(commonjsGlobal, function (d3$$1) { - - // Public - contructs a new tooltip - // - // Returns a tip - return function() { - var direction = d3_tip_direction, - offset = d3_tip_offset, - html = d3_tip_html, - node = initNode(), - svg = null, - point = null, - target = null; - - function tip(vis) { - svg = getSVGNode(vis); - point = svg.createSVGPoint(); - document.body.appendChild(node); - } - - // Public - show the tooltip on the screen - // - // Returns a tip - tip.show = function() { - var args = Array.prototype.slice.call(arguments); - if(args[args.length - 1] instanceof SVGElement) target = args.pop(); - - var content = html.apply(this, args), - poffset = offset.apply(this, args), - dir = direction.apply(this, args), - nodel = getNodeEl(), - i = directions.length, - coords, - scrollTop = document.documentElement.scrollTop || document.body.scrollTop, - scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft; - - nodel.html(content) - .style('opacity', 1).style('pointer-events', 'all'); - - while(i--) nodel.classed(directions[i], false); - coords = direction_callbacks.get(dir).apply(this); - nodel.classed(dir, true) - .style('top', (coords.top + poffset[0]) + scrollTop + 'px') - .style('left', (coords.left + poffset[1]) + scrollLeft + 'px'); - - return tip; - }; - - // Public - hide the tooltip - // - // Returns a tip - tip.hide = function() { - var nodel = getNodeEl(); - nodel.style('opacity', 0).style('pointer-events', 'none'); - return tip - }; - - // Public: Proxy attr calls to the d3 tip container. Sets or gets attribute value. - // - // n - name of the attribute - // v - value of the attribute - // - // Returns tip or attribute value - tip.attr = function(n, v) { - if (arguments.length < 2 && typeof n === 'string') { - return getNodeEl().attr(n) - } else { - var args = Array.prototype.slice.call(arguments); - d3$$1.selection.prototype.attr.apply(getNodeEl(), args); - } - - return tip - }; - - // Public: Proxy style calls to the d3 tip container. Sets or gets a style value. - // - // n - name of the property - // v - value of the property - // - // Returns tip or style property value - tip.style = function(n, v) { - if (arguments.length < 2 && typeof n === 'string') { - return getNodeEl().style(n) - } else { - var args = Array.prototype.slice.call(arguments); - d3$$1.selection.prototype.style.apply(getNodeEl(), args); - } - - return tip - }; - - // Public: Set or get the direction of the tooltip - // - // v - One of n(north), s(south), e(east), or w(west), nw(northwest), - // sw(southwest), ne(northeast) or se(southeast) - // - // Returns tip or direction - tip.direction = function(v) { - if (!arguments.length) return direction - direction = v == null ? v : functor(v); - - return tip - }; - - // Public: Sets or gets the offset of the tip - // - // v - Array of [x, y] offset - // - // Returns offset or - tip.offset = function(v) { - if (!arguments.length) return offset - offset = v == null ? v : functor(v); - - return tip - }; - - // Public: sets or gets the html value of the tooltip - // - // v - String value of the tip - // - // Returns html value or tip - tip.html = function(v) { - if (!arguments.length) return html - html = v == null ? v : functor(v); - - return tip - }; - - // Public: destroys the tooltip and removes it from the DOM - // - // Returns a tip - tip.destroy = function() { - if(node) { - getNodeEl().remove(); - node = null; - } - return tip; - }; - - function d3_tip_direction() { return 'n' } - function d3_tip_offset() { return [0, 0] } - function d3_tip_html() { return ' ' } - - var direction_callbacks = d3$$1.map({ - n: direction_n, - s: direction_s, - e: direction_e, - w: direction_w, - nw: direction_nw, - ne: direction_ne, - sw: direction_sw, - se: direction_se - }), - - directions = direction_callbacks.keys(); - - function direction_n() { - var bbox = getScreenBBox(); - return { - top: bbox.n.y - node.offsetHeight, - left: bbox.n.x - node.offsetWidth / 2 - } - } - - function direction_s() { - var bbox = getScreenBBox(); - return { - top: bbox.s.y, - left: bbox.s.x - node.offsetWidth / 2 - } - } - - function direction_e() { - var bbox = getScreenBBox(); - return { - top: bbox.e.y - node.offsetHeight / 2, - left: bbox.e.x - } - } - - function direction_w() { - var bbox = getScreenBBox(); - return { - top: bbox.w.y - node.offsetHeight / 2, - left: bbox.w.x - node.offsetWidth - } - } - - function direction_nw() { - var bbox = getScreenBBox(); - return { - top: bbox.nw.y - node.offsetHeight, - left: bbox.nw.x - node.offsetWidth - } - } - - function direction_ne() { - var bbox = getScreenBBox(); - return { - top: bbox.ne.y - node.offsetHeight, - left: bbox.ne.x - } - } - - function direction_sw() { - var bbox = getScreenBBox(); - return { - top: bbox.sw.y, - left: bbox.sw.x - node.offsetWidth - } - } - - function direction_se() { - var bbox = getScreenBBox(); - return { - top: bbox.se.y, - left: bbox.e.x - } - } - - function initNode() { - var node = d3$$1.select(document.createElement('div')); - node.style('position', 'absolute').style('top', 0).style('opacity', 0) - .style('pointer-events', 'none').style('box-sizing', 'border-box'); - - return node.node() - } - - function getSVGNode(el) { - el = el.node(); - if(el.tagName.toLowerCase() === 'svg') - return el - - return el.ownerSVGElement - } - - function getNodeEl() { - if(node === null) { - node = initNode(); - // re-add node to DOM - document.body.appendChild(node); - } - return d3$$1.select(node); - } - - // Private - gets the screen coordinates of a shape - // - // Given a shape on the screen, will return an SVGPoint for the directions - // n(north), s(south), e(east), w(west), ne(northeast), se(southeast), nw(northwest), - // sw(southwest). - // - // +-+-+ - // | | - // + + - // | | - // +-+-+ - // - // Returns an Object {n, s, e, w, nw, sw, ne, se} - function getScreenBBox() { - var targetel = target || d3$$1.event.target; - - while ('undefined' === typeof targetel.getScreenCTM && 'undefined' === targetel.parentNode) { - targetel = targetel.parentNode; - } - - var bbox = {}, - matrix = targetel.getScreenCTM(), - tbbox = targetel.getBBox(), - width = tbbox.width, - height = tbbox.height, - x = tbbox.x, - y = tbbox.y; - - point.x = x; - point.y = y; - bbox.nw = point.matrixTransform(matrix); - point.x += width; - bbox.ne = point.matrixTransform(matrix); - point.y += height; - bbox.se = point.matrixTransform(matrix); - point.x -= width; - bbox.sw = point.matrixTransform(matrix); - point.y -= height / 2; - bbox.w = point.matrixTransform(matrix); - point.x += width; - bbox.e = point.matrixTransform(matrix); - point.x -= width / 2; - point.y -= height / 2; - bbox.n = point.matrixTransform(matrix); - point.y += height; - bbox.s = point.matrixTransform(matrix); - - return bbox - } - - // Private - replace D3JS 3.X d3.functor() function - function functor(v) { - return typeof v === "function" ? v : function() { - return v - } - } - - return tip - }; - -})); -}); - -var flamegraph = function () { - var w = 960; // graph width - var h = null; // graph height - var c = 18; // cell height - var selection = null; // selection - var tooltip = true; // enable tooltip - var title = ''; // graph title - var transitionDuration = 750; - var transitionEase = d3.easeCubic; // tooltip offset - var sort = false; - var inverted = false; // invert the graph direction - var clickHandler = null; - var minFrameSize = 0; - var details = null; - - var tip = d3Tip() - .direction('s') - .offset([8, 0]) - .attr('class', 'd3-flame-graph-tip') - .html(function (d) { return label(d) }); - - var svg; - - function name (d) { - return d.data.n || d.data.name - } - - function libtype (d) { - return d.data.l || d.data.libtype - } - - function children (d) { - return d.c || d.children - } - - function value (d) { - return d.v || d.value - } - - var label = function (d) { - return name(d) + ' (' + d3.format('.3f')(100 * (d.x1 - d.x0), 3) + '%, ' + value(d) + ' samples)' - }; - - function setDetails (t) { - if (details) { details.innerHTML = t; } - } - - var colorMapper = function (d) { - return d.highlight ? '#E600E6' : colorHash(name(d), libtype(d)) - }; - - function generateHash (name) { - // Return a vector (0.0->1.0) that is a hash of the input string. - // The hash is computed to favor early characters over later ones, so - // that strings with similar starts have similar vectors. Only the first - // 6 characters are considered. - const MAX_CHAR = 6; - - var hash = 0; - var maxHash = 0; - var weight = 1; - var mod = 10; - - if (name) { - for (var i = 0; i < name.length; i++) { - if (i > MAX_CHAR) { break } - hash += weight * (name.charCodeAt(i) % mod); - maxHash += weight * (mod - 1); - weight *= 0.70; - } - if (maxHash > 0) { hash = hash / maxHash; } - } - return hash - } - - function colorHash (name, libtype) { - // Return a color for the given name and library type. The library type - // selects the hue, and the name is hashed to a color in that hue. - - var r; - var g; - var b; - - // Select hue. Order is important. - var hue; - if (typeof libtype === 'undefined' || libtype === '') { - // default when libtype is not in use - hue = 'warm'; - } else { - hue = 'red'; - if (name.match(/::/)) { - hue = 'yellow'; - } - if (libtype === 'kernel') { - hue = 'orange'; - } else if (libtype === 'jit') { - hue = 'green'; - } else if (libtype === 'inlined') { - hue = 'aqua'; - } - } - - // calculate hash - var vector = 0; - if (name) { - var nameArr = name.split('` + "`" + `'); - if (nameArr.length > 1) { - name = nameArr[nameArr.length - 1]; // drop module name if present - } - name = name.split('(')[0]; // drop extra info - vector = generateHash(name); - } - - // calculate color - if (hue === 'red') { - r = 200 + Math.round(55 * vector); - g = 50 + Math.round(80 * vector); - b = g; - } else if (hue === 'orange') { - r = 190 + Math.round(65 * vector); - g = 90 + Math.round(65 * vector); - b = 0; - } else if (hue === 'yellow') { - r = 175 + Math.round(55 * vector); - g = r; - b = 50 + Math.round(20 * vector); - } else if (hue === 'green') { - r = 50 + Math.round(60 * vector); - g = 200 + Math.round(55 * vector); - b = r; - } else if (hue === 'aqua') { - r = 50 + Math.round(60 * vector); - g = 165 + Math.round(55 * vector); - b = g; - } else { - // original warm palette - r = 200 + Math.round(55 * vector); - g = 0 + Math.round(230 * (1 - vector)); - b = 0 + Math.round(55 * (1 - vector)); - } - - return 'rgb(' + r + ',' + g + ',' + b + ')' - } - - function hide (d) { - d.data.hide = true; - if (children(d)) { - children(d).forEach(hide); - } - } - - function show (d) { - d.data.fade = false; - d.data.hide = false; - if (children(d)) { - children(d).forEach(show); - } - } - - function getSiblings (d) { - var siblings = []; - if (d.parent) { - var me = d.parent.children.indexOf(d); - siblings = d.parent.children.slice(0); - siblings.splice(me, 1); - } - return siblings - } - - function hideSiblings (d) { - var siblings = getSiblings(d); - siblings.forEach(function (s) { - hide(s); - }); - if (d.parent) { - hideSiblings(d.parent); - } - } - function fadeAncestors (d) { - if (d.parent) { - d.parent.data.fade = true; - fadeAncestors(d.parent); - } - } - - // function getRoot (d) { - // if (d.parent) { - // return getRoot(d.parent) - // } - // return d - // } - - function zoom (d) { - tip.hide(d); - hideSiblings(d); - show(d); - fadeAncestors(d); - update(); - if (typeof clickHandler === 'function') { - clickHandler(d); - } - } - - function searchTree (d, term) { - var re = new RegExp(term); - var searchResults = []; - - function searchInner (d) { - var label = name(d); - - if (children(d)) { - children(d).forEach(function (child) { - searchInner(child); - }); - } - - if (label.match(re)) { - d.highlight = true; - searchResults.push(d); - } else { - d.highlight = false; - } - } - - searchInner(d); - return searchResults - } - - function clear (d) { - d.highlight = false; - if (children(d)) { - children(d).forEach(function (child) { - clear(child); - }); - } - } - - function doSort (a, b) { - if (typeof sort === 'function') { - return sort(a, b) - } else if (sort) { - return d3.ascending(name(a), name(b)) - } - } - - var p = d3.partition(); - - function filterNodes (root) { - var nodeList = root.descendants(); - if (minFrameSize > 0) { - var kx = w / (root.x1 - root.x0); - nodeList = nodeList.filter(function (el) { - return ((el.x1 - el.x0) * kx) > minFrameSize - }); - } - return nodeList - } - - function update () { - selection.each(function (root) { - var x = d3.scaleLinear().range([0, w]); - var y = d3.scaleLinear().range([0, c]); - - if (sort) root.sort(doSort); - root.sum(function (d) { - if (d.fade || d.hide) { - return 0 - } - // The node's self value is its total value minus all children. - var v = value(d); - if (children(d)) { - var c = children(d); - for (var i = 0; i < c.length; i++) { - v -= value(c[i]); - } - } - return v - }); - p(root); - - var kx = w / (root.x1 - root.x0); - function width (d) { return (d.x1 - d.x0) * kx } - - var descendants = filterNodes(root); - var g = d3.select(this).select('svg').selectAll('g').data(descendants, function (d) { return d.id }); - - g.transition() - .duration(transitionDuration) - .ease(transitionEase) - .attr('transform', function (d) { return 'translate(' + x(d.x0) + ',' + (inverted ? y(d.depth) : (h - y(d.depth) - c)) + ')' }); - - g.select('rect') - .attr('width', width); - - var node = g.enter() - .append('svg:g') - .attr('transform', function (d) { return 'translate(' + x(d.x0) + ',' + (inverted ? y(d.depth) : (h - y(d.depth) - c)) + ')' }); - - node.append('svg:rect') - .transition() - .delay(transitionDuration / 2) - .attr('width', width); - - if (!tooltip) { node.append('svg:title'); } - - node.append('foreignObject') - .append('xhtml:div'); - - // Now we have to re-select to see the new elements (why?). - g = d3.select(this).select('svg').selectAll('g').data(descendants, function (d) { return d.id }); - - g.attr('width', width) - .attr('height', function (d) { return c }) - .attr('name', function (d) { return name(d) }) - .attr('class', function (d) { return d.data.fade ? 'frame fade' : 'frame' }); - - g.select('rect') - .attr('height', function (d) { return c }) - .attr('fill', function (d) { return colorMapper(d) }); - - if (!tooltip) { - g.select('title') - .text(label); - } - - g.select('foreignObject') - .attr('width', width) - .attr('height', function (d) { return c }) - .select('div') - .attr('class', 'd3-flame-graph-label') - .style('display', function (d) { return (width(d) < 35) ? 'none' : 'block' }) - .transition() - .delay(transitionDuration) - .text(name); - - g.on('click', zoom); - - g.exit() - .remove(); - - g.on('mouseover', function (d) { - if (tooltip) tip.show(d, this); - setDetails(label(d)); - }).on('mouseout', function (d) { - if (tooltip) tip.hide(d); - setDetails(''); - }); - }); - } - - function merge (data, samples) { - samples.forEach(function (sample) { - var node = data.find(function (element) { - return (element.name === sample.name) - }); - - if (node) { - if (node.original) { - node.original += sample.value; - } else { - node.value += sample.value; - } - if (sample.children) { - if (!node.children) { - node.children = []; - } - merge(node.children, sample.children); - } - } else { - data.push(sample); - } - }); - } - - function s4 () { - return Math.floor((1 + Math.random()) * 0x10000) - .toString(16) - .substring(1) - } - - function injectIds (node) { - node.id = s4() + '-' + s4() + '-' + '-' + s4() + '-' + s4(); - var children = node.c || node.children || []; - for (var i = 0; i < children.length; i++) { - injectIds(children[i]); - } - } - - function chart (s) { - var root = d3.hierarchy( - s.datum(), function (d) { return children(d) } - ); - injectIds(root); - selection = s.datum(root); - - if (!arguments.length) return chart - - if (!h) { - h = (root.height + 2) * c; - } - - selection.each(function (data) { - if (!svg) { - svg = d3.select(this) - .append('svg:svg') - .attr('width', w) - .attr('height', h) - .attr('class', 'partition d3-flame-graph') - .call(tip); - - svg.append('svg:text') - .attr('class', 'title') - .attr('text-anchor', 'middle') - .attr('y', '25') - .attr('x', w / 2) - .attr('fill', '#808080') - .text(title); - } - }); - - // first draw - update(); - } - - chart.height = function (_) { - if (!arguments.length) { return h } - h = _; - return chart - }; - - chart.width = function (_) { - if (!arguments.length) { return w } - w = _; - return chart - }; - - chart.cellHeight = function (_) { - if (!arguments.length) { return c } - c = _; - return chart - }; - - chart.tooltip = function (_) { - if (!arguments.length) { return tooltip } - if (typeof _ === 'function') { - tip = _; - } - tooltip = !!_; - return chart - }; - - chart.title = function (_) { - if (!arguments.length) { return title } - title = _; - return chart - }; - - chart.transitionDuration = function (_) { - if (!arguments.length) { return transitionDuration } - transitionDuration = _; - return chart - }; - - chart.transitionEase = function (_) { - if (!arguments.length) { return transitionEase } - transitionEase = _; - return chart - }; - - chart.sort = function (_) { - if (!arguments.length) { return sort } - sort = _; - return chart - }; - - chart.inverted = function (_) { - if (!arguments.length) { return inverted } - inverted = _; - return chart - }; - - chart.label = function (_) { - if (!arguments.length) { return label } - label = _; - return chart - }; - - chart.search = function (term) { - var searchResults = []; - selection.each(function (data) { - searchResults = searchTree(data, term); - update(); - }); - return searchResults - }; - - chart.clear = function () { - selection.each(function (data) { - clear(data); - update(); - }); - }; - - chart.zoomTo = function (d) { - zoom(d); - }; - - chart.resetZoom = function () { - selection.each(function (data) { - zoom(data); // zoom to root - }); - }; - - chart.onClick = function (_) { - if (!arguments.length) { - return clickHandler - } - clickHandler = _; - return chart - }; - - chart.merge = function (samples) { - var newRoot; // Need to re-create hierarchy after data changes. - selection.each(function (root) { - merge([root.data], [samples]); - newRoot = d3.hierarchy(root.data, function (d) { return children(d) }); - injectIds(newRoot); - }); - selection = selection.datum(newRoot); - update(); - }; - - chart.color = function (_) { - if (!arguments.length) { return colorMapper } - colorMapper = _; - return chart - }; - - chart.minFrameSize = function (_) { - if (!arguments.length) { return minFrameSize } - minFrameSize = _; - return chart - }; - - chart.details = function (_) { - if (!arguments.length) { return details } - details = _; - return chart - }; - - return chart -}; - -exports.flamegraph = flamegraph; - -Object.defineProperty(exports, '__esModule', { value: true }); - -}))); +!function(t,n){if("object"==typeof exports&&"object"==typeof module)module.exports=n();else if("function"==typeof define&&define.amd)define([],n);else{var e=n();for(var r in e)("object"==typeof exports?exports:t)[r]=e[r]}}(self,(function(){return(()=>{"use strict";var t={d:(n,e)=>{for(var r in e)t.o(e,r)&&!t.o(n,r)&&Object.defineProperty(n,r,{enumerable:!0,get:e[r]})},o:(t,n)=>Object.prototype.hasOwnProperty.call(t,n),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},n={};function e(){}function r(t){return null==t?e:function(){return this.querySelector(t)}}function i(t){return null==t?[]:Array.isArray(t)?t:Array.from(t)}function o(){return[]}function u(t){return function(n){return n.matches(t)}}t.r(n),t.d(n,{flamegraph:()=>ji,select:()=>pt});var a=Array.prototype.find;function l(){return this.firstElementChild}var s=Array.prototype.filter;function c(){return Array.from(this.children)}function f(t){return new Array(t.length)}function h(t,n){this.ownerDocument=t.ownerDocument,this.namespaceURI=t.namespaceURI,this._next=null,this._parent=t,this.__data__=n}function p(t){return function(){return t}}function d(t,n,e,r,i,o){for(var u,a=0,l=n.length,s=o.length;an?1:t>=n?0:NaN}h.prototype={constructor:h,appendChild:function(t){return this._parent.insertBefore(t,this._next)},insertBefore:function(t,n){return this._parent.insertBefore(t,n)},querySelector:function(t){return this._parent.querySelector(t)},querySelectorAll:function(t){return this._parent.querySelectorAll(t)}};var _="http://www.w3.org/1999/xhtml";const w={svg:"http://www.w3.org/2000/svg",xhtml:_,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function b(t){var n=t+="",e=n.indexOf(":");return e>=0&&"xmlns"!==(n=t.slice(0,e))&&(t=t.slice(e+1)),w.hasOwnProperty(n)?{space:w[n],local:t}:t}function x(t){return function(){this.removeAttribute(t)}}function M(t){return function(){this.removeAttributeNS(t.space,t.local)}}function A(t,n){return function(){this.setAttribute(t,n)}}function N(t,n){return function(){this.setAttributeNS(t.space,t.local,n)}}function E(t,n){return function(){var e=n.apply(this,arguments);null==e?this.removeAttribute(t):this.setAttribute(t,e)}}function k(t,n){return function(){var e=n.apply(this,arguments);null==e?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,e)}}function S(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView}function C(t){return function(){this.style.removeProperty(t)}}function P(t,n,e){return function(){this.style.setProperty(t,n,e)}}function j(t,n,e){return function(){var r=n.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,e)}}function q(t,n){return t.style.getPropertyValue(n)||S(t).getComputedStyle(t,null).getPropertyValue(n)}function O(t){return function(){delete this[t]}}function L(t,n){return function(){this[t]=n}}function T(t,n){return function(){var e=n.apply(this,arguments);null==e?delete this[t]:this[t]=e}}function B(t){return t.trim().split(/^|\s+/)}function D(t){return t.classList||new H(t)}function H(t){this._node=t,this._names=B(t.getAttribute("class")||"")}function R(t,n){for(var e=D(t),r=-1,i=n.length;++r=0&&(n=t.slice(e+1),t=t.slice(0,e)),{type:t,name:n}}))}function ut(t){return function(){var n=this.__on;if(n){for(var e,r=0,i=-1,o=n.length;r=0&&(this._names.splice(n,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};var ft=[null];function ht(t,n){this._groups=t,this._parents=n}function pt(t){return"string"==typeof t?new ht([[document.querySelector(t)]],[document.documentElement]):new ht([[t]],ft)}function dt(){}function gt(t){return null==t?dt:function(){return this.querySelector(t)}}function vt(t){return null==t?[]:Array.isArray(t)?t:Array.from(t)}function yt(){return[]}function mt(t){return null==t?yt:function(){return this.querySelectorAll(t)}}function _t(t){return function(){return this.matches(t)}}function wt(t){return function(n){return n.matches(t)}}ht.prototype=function(){return new ht([[document.documentElement]],ft)}.prototype={constructor:ht,select:function(t){"function"!=typeof t&&(t=r(t));for(var n=this._groups,e=n.length,i=new Array(e),o=0;o=E&&(E=N+1);!(A=b[E])&&++E<_;);M._next=A||null}}return(u=new ht(u,r))._enter=a,u._exit=l,u},enter:function(){return new ht(this._enter||this._groups.map(f),this._parents)},exit:function(){return new ht(this._exit||this._groups.map(f),this._parents)},join:function(t,n,e){var r=this.enter(),i=this,o=this.exit();return"function"==typeof t?(r=t(r))&&(r=r.selection()):r=r.append(t+""),null!=n&&(i=n(i))&&(i=i.selection()),null==e?o.remove():e(o),r&&i?r.merge(i).order():i},merge:function(t){for(var n=t.selection?t.selection():t,e=this._groups,r=n._groups,i=e.length,o=r.length,u=Math.min(i,o),a=new Array(i),l=0;l=0;)(r=i[o])&&(u&&4^r.compareDocumentPosition(u)&&u.parentNode.insertBefore(r,u),u=r);return this},sort:function(t){function n(n,e){return n&&e?t(n.__data__,e.__data__):!n-!e}t||(t=m);for(var e=this._groups,r=e.length,i=new Array(r),o=0;o1?this.each((null==n?C:"function"==typeof n?j:P)(t,n,null==e?"":e)):q(this.node(),t)},property:function(t,n){return arguments.length>1?this.each((null==n?O:"function"==typeof n?T:L)(t,n)):this.node()[t]},classed:function(t,n){var e=B(t+"");if(arguments.length<2){for(var r=D(this.node()),i=-1,o=e.length;++in?1:t>=n?0:NaN}Et.prototype={constructor:Et,appendChild:function(t){return this._parent.insertBefore(t,this._next)},insertBefore:function(t,n){return this._parent.insertBefore(t,n)},querySelector:function(t){return this._parent.querySelector(t)},querySelectorAll:function(t){return this._parent.querySelectorAll(t)}};var Ot="http://www.w3.org/1999/xhtml";const Lt={svg:"http://www.w3.org/2000/svg",xhtml:Ot,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function Tt(t){var n=t+="",e=n.indexOf(":");return e>=0&&"xmlns"!==(n=t.slice(0,e))&&(t=t.slice(e+1)),Lt.hasOwnProperty(n)?{space:Lt[n],local:t}:t}function Bt(t){return function(){this.removeAttribute(t)}}function Dt(t){return function(){this.removeAttributeNS(t.space,t.local)}}function Ht(t,n){return function(){this.setAttribute(t,n)}}function Rt(t,n){return function(){this.setAttributeNS(t.space,t.local,n)}}function Vt(t,n){return function(){var e=n.apply(this,arguments);null==e?this.removeAttribute(t):this.setAttribute(t,e)}}function Xt(t,n){return function(){var e=n.apply(this,arguments);null==e?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,e)}}function zt(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView}function It(t){return function(){this.style.removeProperty(t)}}function $t(t,n,e){return function(){this.style.setProperty(t,n,e)}}function Ut(t,n,e){return function(){var r=n.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,e)}}function Yt(t,n){return t.style.getPropertyValue(n)||zt(t).getComputedStyle(t,null).getPropertyValue(n)}function Ft(t){return function(){delete this[t]}}function Zt(t,n){return function(){this[t]=n}}function Gt(t,n){return function(){var e=n.apply(this,arguments);null==e?delete this[t]:this[t]=e}}function Jt(t){return t.trim().split(/^|\s+/)}function Kt(t){return t.classList||new Qt(t)}function Qt(t){this._node=t,this._names=Jt(t.getAttribute("class")||"")}function Wt(t,n){for(var e=Kt(t),r=-1,i=n.length;++r=0&&(n=t.slice(e+1),t=t.slice(0,e)),{type:t,name:n}}))}function bn(t){return function(){var n=this.__on;if(n){for(var e,r=0,i=-1,o=n.length;r=0&&(this._names.splice(n,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};var En=[null];function kn(t,n){this._groups=t,this._parents=n}function Sn(){return new kn([[document.documentElement]],En)}kn.prototype=Sn.prototype={constructor:kn,select:function(t){"function"!=typeof t&&(t=gt(t));for(var n=this._groups,e=n.length,r=new Array(e),i=0;i=b&&(b=w+1);!(_=v[b])&&++b=0;)(r=i[o])&&(u&&4^r.compareDocumentPosition(u)&&u.parentNode.insertBefore(r,u),u=r);return this},sort:function(t){function n(n,e){return n&&e?t(n.__data__,e.__data__):!n-!e}t||(t=qt);for(var e=this._groups,r=e.length,i=new Array(r),o=0;o1?this.each((null==n?It:"function"==typeof n?Ut:$t)(t,n,null==e?"":e)):Yt(this.node(),t)},property:function(t,n){return arguments.length>1?this.each((null==n?Ft:"function"==typeof n?Gt:Zt)(t,n)):this.node()[t]},classed:function(t,n){var e=Jt(t+"");if(arguments.length<2){for(var r=Kt(this.node()),i=-1,o=e.length;++i1?r[0]+r.slice(2):r,+t.slice(e+1)]}function qn(t){return(t=jn(Math.abs(t)))?t[1]:NaN}var On,Ln=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function Tn(t){if(!(n=Ln.exec(t)))throw new Error("invalid format: "+t);var n;return new Bn({fill:n[1],align:n[2],sign:n[3],symbol:n[4],zero:n[5],width:n[6],comma:n[7],precision:n[8]&&n[8].slice(1),trim:n[9],type:n[10]})}function Bn(t){this.fill=void 0===t.fill?" ":t.fill+"",this.align=void 0===t.align?">":t.align+"",this.sign=void 0===t.sign?"-":t.sign+"",this.symbol=void 0===t.symbol?"":t.symbol+"",this.zero=!!t.zero,this.width=void 0===t.width?void 0:+t.width,this.comma=!!t.comma,this.precision=void 0===t.precision?void 0:+t.precision,this.trim=!!t.trim,this.type=void 0===t.type?"":t.type+""}function Dn(t,n){var e=jn(t,n);if(!e)return t+"";var r=e[0],i=e[1];return i<0?"0."+new Array(-i).join("0")+r:r.length>i+1?r.slice(0,i+1)+"."+r.slice(i+1):r+new Array(i-r.length+2).join("0")}Tn.prototype=Bn.prototype,Bn.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};const Hn={"%":(t,n)=>(100*t).toFixed(n),b:t=>Math.round(t).toString(2),c:t=>t+"",d:function(t){return Math.abs(t=Math.round(t))>=1e21?t.toLocaleString("en").replace(/,/g,""):t.toString(10)},e:(t,n)=>t.toExponential(n),f:(t,n)=>t.toFixed(n),g:(t,n)=>t.toPrecision(n),o:t=>Math.round(t).toString(8),p:(t,n)=>Dn(100*t,n),r:Dn,s:function(t,n){var e=jn(t,n);if(!e)return t+"";var r=e[0],i=e[1],o=i-(On=3*Math.max(-8,Math.min(8,Math.floor(i/3))))+1,u=r.length;return o===u?r:o>u?r+new Array(o-u+1).join("0"):o>0?r.slice(0,o)+"."+r.slice(o):"0."+new Array(1-o).join("0")+jn(t,Math.max(0,n+o-1))[0]},X:t=>Math.round(t).toString(16).toUpperCase(),x:t=>Math.round(t).toString(16)};function Rn(t){return t}var Vn,Xn,zn,In=Array.prototype.map,$n=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function Un(t,n){return null==t||null==n?NaN:tn?1:t>=n?0:NaN}function Yn(t){t.x0=Math.round(t.x0),t.y0=Math.round(t.y0),t.x1=Math.round(t.x1),t.y1=Math.round(t.y1)}function Fn(t){var n=0,e=t.children,r=e&&e.length;if(r)for(;--r>=0;)n+=e[r].value;else n=1;t.value=n}function Zn(t,n){t instanceof Map?(t=[void 0,t],void 0===n&&(n=Jn)):void 0===n&&(n=Gn);for(var e,r,i,o,u,a=new Wn(t),l=[a];e=l.pop();)if((i=n(e.data))&&(u=(i=Array.from(i)).length))for(e.children=i,o=u-1;o>=0;--o)l.push(r=i[o]=new Wn(i[o])),r.parent=e,r.depth=e.depth+1;return a.eachBefore(Qn)}function Gn(t){return t.children}function Jn(t){return Array.isArray(t)?t[1]:null}function Kn(t){void 0!==t.data.value&&(t.value=t.data.value),t.data=t.data.data}function Qn(t){var n=0;do{t.height=n}while((t=t.parent)&&t.height<++n)}function Wn(t){this.data=t,this.depth=this.height=0,this.parent=null}Vn=function(t){var n,e,r=void 0===t.grouping||void 0===t.thousands?Rn:(n=In.call(t.grouping,Number),e=t.thousands+"",function(t,r){for(var i=t.length,o=[],u=0,a=n[0],l=0;i>0&&a>0&&(l+a+1>r&&(a=Math.max(1,r-l)),o.push(t.substring(i-=a,i+a)),!((l+=a+1)>r));)a=n[u=(u+1)%n.length];return o.reverse().join(e)}),i=void 0===t.currency?"":t.currency[0]+"",o=void 0===t.currency?"":t.currency[1]+"",u=void 0===t.decimal?".":t.decimal+"",a=void 0===t.numerals?Rn:function(t){return function(n){return n.replace(/[0-9]/g,(function(n){return t[+n]}))}}(In.call(t.numerals,String)),l=void 0===t.percent?"%":t.percent+"",s=void 0===t.minus?"−":t.minus+"",c=void 0===t.nan?"NaN":t.nan+"";function f(t){var n=(t=Tn(t)).fill,e=t.align,f=t.sign,h=t.symbol,p=t.zero,d=t.width,g=t.comma,v=t.precision,y=t.trim,m=t.type;"n"===m?(g=!0,m="g"):Hn[m]||(void 0===v&&(v=12),y=!0,m="g"),(p||"0"===n&&"="===e)&&(p=!0,n="0",e="=");var _="$"===h?i:"#"===h&&/[boxX]/.test(m)?"0"+m.toLowerCase():"",w="$"===h?o:/[%p]/.test(m)?l:"",b=Hn[m],x=/[defgprs%]/.test(m);function M(t){var i,o,l,h=_,M=w;if("c"===m)M=b(t)+M,t="";else{var A=(t=+t)<0||1/t<0;if(t=isNaN(t)?c:b(Math.abs(t),v),y&&(t=function(t){t:for(var n,e=t.length,r=1,i=-1;r0&&(i=0)}return i>0?t.slice(0,i)+t.slice(n+1):t}(t)),A&&0==+t&&"+"!==f&&(A=!1),h=(A?"("===f?f:s:"-"===f||"("===f?"":f)+h,M=("s"===m?$n[8+On/3]:"")+M+(A&&"("===f?")":""),x)for(i=-1,o=t.length;++i(l=t.charCodeAt(i))||l>57){M=(46===l?u+t.slice(i+1):t.slice(i))+M,t=t.slice(0,i);break}}g&&!p&&(t=r(t,1/0));var N=h.length+t.length+M.length,E=N>1)+h+t+M+E.slice(N);break;default:t=E+h+t+M}return a(t)}return v=void 0===v?6:/[gprs]/.test(m)?Math.max(1,Math.min(21,v)):Math.max(0,Math.min(20,v)),M.toString=function(){return t+""},M}return{format:f,formatPrefix:function(t,n){var e=f(((t=Tn(t)).type="f",t)),r=3*Math.max(-8,Math.min(8,Math.floor(qn(n)/3))),i=Math.pow(10,-r),o=$n[8+r/3];return function(t){return e(i*t)+o}}}}({thousands:",",grouping:[3],currency:["$",""]}),Xn=Vn.format,zn=Vn.formatPrefix,Wn.prototype=Zn.prototype={constructor:Wn,count:function(){return this.eachAfter(Fn)},each:function(t,n){let e=-1;for(const r of this)t.call(n,r,++e,this);return this},eachAfter:function(t,n){for(var e,r,i,o=this,u=[o],a=[],l=-1;o=u.pop();)if(a.push(o),e=o.children)for(r=0,i=e.length;r=0;--r)o.push(e[r]);return this},find:function(t,n){let e=-1;for(const r of this)if(t.call(n,r,++e,this))return r},sum:function(t){return this.eachAfter((function(n){for(var e=+t(n.data)||0,r=n.children,i=r&&r.length;--i>=0;)e+=r[i].value;n.value=e}))},sort:function(t){return this.eachBefore((function(n){n.children&&n.children.sort(t)}))},path:function(t){for(var n=this,e=function(t,n){if(t===n)return t;var e=t.ancestors(),r=n.ancestors(),i=null;for(t=e.pop(),n=r.pop();t===n;)i=t,t=e.pop(),n=r.pop();return i}(n,t),r=[n];n!==e;)n=n.parent,r.push(n);for(var i=r.length;t!==e;)r.splice(i,0,t),t=t.parent;return r},ancestors:function(){for(var t=this,n=[t];t=t.parent;)n.push(t);return n},descendants:function(){return Array.from(this)},leaves:function(){var t=[];return this.eachBefore((function(n){n.children||t.push(n)})),t},links:function(){var t=this,n=[];return t.each((function(e){e!==t&&n.push({source:e.parent,target:e})})),n},copy:function(){return Zn(this).eachBefore(Kn)},[Symbol.iterator]:function*(){var t,n,e,r,i=this,o=[i];do{for(t=o.reverse(),o=[];i=t.pop();)if(yield i,n=i.children)for(e=0,r=n.length;e=0?(o>=te?10:o>=ne?5:o>=ee?2:1)*Math.pow(10,i):-Math.pow(10,-i)/(o>=te?10:o>=ne?5:o>=ee?2:1)}function ie(t){let n=t,e=t,r=t;function i(t,n,i=0,o=t.length){if(i>>1;r(t[e],n)<0?i=e+1:o=e}while(it(n)-e,e=Un,r=(n,e)=>Un(t(n),e)),{left:i,center:function(t,e,r=0,o=t.length){const u=i(t,e,r,o-1);return u>r&&n(t[u-1],e)>-n(t[u],e)?u-1:u},right:function(t,n,i=0,o=t.length){if(i>>1;r(t[e],n)<=0?i=e+1:o=e}while(i>8&15|n>>4&240,n>>4&15|240&n,(15&n)<<4|15&n,1):8===e?Se(n>>24&255,n>>16&255,n>>8&255,(255&n)/255):4===e?Se(n>>12&15|n>>8&240,n>>8&15|n>>4&240,n>>4&15|240&n,((15&n)<<4|15&n)/255):null):(n=ye.exec(t))?new je(n[1],n[2],n[3],1):(n=me.exec(t))?new je(255*n[1]/100,255*n[2]/100,255*n[3]/100,1):(n=_e.exec(t))?Se(n[1],n[2],n[3],n[4]):(n=we.exec(t))?Se(255*n[1]/100,255*n[2]/100,255*n[3]/100,n[4]):(n=be.exec(t))?Te(n[1],n[2]/100,n[3]/100,1):(n=xe.exec(t))?Te(n[1],n[2]/100,n[3]/100,n[4]):Me.hasOwnProperty(t)?ke(Me[t]):"transparent"===t?new je(NaN,NaN,NaN,0):null}function ke(t){return new je(t>>16&255,t>>8&255,255&t,1)}function Se(t,n,e,r){return r<=0&&(t=n=e=NaN),new je(t,n,e,r)}function Ce(t){return t instanceof ce||(t=Ee(t)),t?new je((t=t.rgb()).r,t.g,t.b,t.opacity):new je}function Pe(t,n,e,r){return 1===arguments.length?Ce(t):new je(t,n,e,null==r?1:r)}function je(t,n,e,r){this.r=+t,this.g=+n,this.b=+e,this.opacity=+r}function qe(){return"#"+Le(this.r)+Le(this.g)+Le(this.b)}function Oe(){var t=this.opacity;return(1===(t=isNaN(t)?1:Math.max(0,Math.min(1,t)))?"rgb(":"rgba(")+Math.max(0,Math.min(255,Math.round(this.r)||0))+", "+Math.max(0,Math.min(255,Math.round(this.g)||0))+", "+Math.max(0,Math.min(255,Math.round(this.b)||0))+(1===t?")":", "+t+")")}function Le(t){return((t=Math.max(0,Math.min(255,Math.round(t)||0)))<16?"0":"")+t.toString(16)}function Te(t,n,e,r){return r<=0?t=n=e=NaN:e<=0||e>=1?t=n=NaN:n<=0&&(t=NaN),new De(t,n,e,r)}function Be(t){if(t instanceof De)return new De(t.h,t.s,t.l,t.opacity);if(t instanceof ce||(t=Ee(t)),!t)return new De;if(t instanceof De)return t;var n=(t=t.rgb()).r/255,e=t.g/255,r=t.b/255,i=Math.min(n,e,r),o=Math.max(n,e,r),u=NaN,a=o-i,l=(o+i)/2;return a?(u=n===o?(e-r)/a+6*(e0&&l<1?0:u,new De(u,a,l,t.opacity)}function De(t,n,e,r){this.h=+t,this.s=+n,this.l=+e,this.opacity=+r}function He(t,n,e){return 255*(t<60?n+(e-n)*t/60:t<180?e:t<240?n+(e-n)*(240-t)/60:n)}function Re(t,n,e,r,i){var o=t*t,u=o*t;return((1-3*t+3*o-u)*n+(4-6*o+3*u)*e+(1+3*t+3*o-3*u)*r+u*i)/6}function Ve(t){return function(){return t}}function Xe(t,n){var e=n-t;return e?function(t,n){return function(e){return t+e*n}}(t,e):Ve(isNaN(t)?n:t)}le(ce,Ee,{copy:function(t){return Object.assign(new this.constructor,this,t)},displayable:function(){return this.rgb().displayable()},hex:Ae,formatHex:Ae,formatHsl:function(){return Be(this).formatHsl()},formatRgb:Ne,toString:Ne}),le(je,Pe,se(ce,{brighter:function(t){return t=null==t?he:Math.pow(he,t),new je(this.r*t,this.g*t,this.b*t,this.opacity)},darker:function(t){return t=null==t?fe:Math.pow(fe,t),new je(this.r*t,this.g*t,this.b*t,this.opacity)},rgb:function(){return this},displayable:function(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:qe,formatHex:qe,formatRgb:Oe,toString:Oe})),le(De,(function(t,n,e,r){return 1===arguments.length?Be(t):new De(t,n,e,null==r?1:r)}),se(ce,{brighter:function(t){return t=null==t?he:Math.pow(he,t),new De(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=null==t?fe:Math.pow(fe,t),new De(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=this.h%360+360*(this.h<0),n=isNaN(t)||isNaN(this.s)?0:this.s,e=this.l,r=e+(e<.5?e:1-e)*n,i=2*e-r;return new je(He(t>=240?t-240:t+120,i,r),He(t,i,r),He(t<120?t+240:t-120,i,r),this.opacity)},displayable:function(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl:function(){var t=this.opacity;return(1===(t=isNaN(t)?1:Math.max(0,Math.min(1,t)))?"hsl(":"hsla(")+(this.h||0)+", "+100*(this.s||0)+"%, "+100*(this.l||0)+"%"+(1===t?")":", "+t+")")}}));const ze=function t(n){var e=function(t){return 1==(t=+t)?Xe:function(n,e){return e-n?function(t,n,e){return t=Math.pow(t,e),n=Math.pow(n,e)-t,e=1/e,function(r){return Math.pow(t+r*n,e)}}(n,e,t):Ve(isNaN(n)?e:n)}}(n);function r(t,n){var r=e((t=Pe(t)).r,(n=Pe(n)).r),i=e(t.g,n.g),o=e(t.b,n.b),u=Xe(t.opacity,n.opacity);return function(n){return t.r=r(n),t.g=i(n),t.b=o(n),t.opacity=u(n),t+""}}return r.gamma=t,r}(1);function Ie(t){return function(n){var e,r,i=n.length,o=new Array(i),u=new Array(i),a=new Array(i);for(e=0;e=1?(e=1,n-1):Math.floor(e*n),i=t[r],o=t[r+1],u=r>0?t[r-1]:2*i-o,a=ro&&(i=n.slice(o,i),a[u]?a[u]+=i:a[++u]=i),(e=e[0])===(r=r[0])?a[u]?a[u]+=r:a[++u]=r:(a[++u]=null,l.push({i:u,x:Ye(e,r)})),o=Ge.lastIndex;return on&&(e=t,t=n,n=e),s=function(e){return Math.max(t,Math.min(n,e))}),r=l>2?or:ir,i=o=null,f}function f(n){return null==n||isNaN(n=+n)?e:(i||(i=r(u.map(t),a,l)))(t(s(n)))}return f.invert=function(e){return s(n((o||(o=r(a,u.map(t),Ye)))(e)))},f.domain=function(t){return arguments.length?(u=Array.from(t,tr),c()):u.slice()},f.range=function(t){return arguments.length?(a=Array.from(t),c()):a.slice()},f.rangeRound=function(t){return a=Array.from(t),l=We,c()},f.clamp=function(t){return arguments.length?(s=!!t||er,c()):s!==er},f.interpolate=function(t){return arguments.length?(l=t,c()):l},f.unknown=function(t){return arguments.length?(e=t,f):e},function(e,r){return t=e,n=r,c()}}()(er,er)}function lr(t,n){switch(arguments.length){case 0:break;case 1:this.range(t);break;default:this.range(n).domain(t)}return this}function sr(t){var n=t.domain;return t.ticks=function(t){var e=n();return function(t,n,e){var r,i,o,u,a=-1;if(e=+e,(t=+t)==(n=+n)&&e>0)return[t];if((r=n0){let e=Math.round(t/u),r=Math.round(n/u);for(e*un&&--r,o=new Array(i=r-e+1);++an&&--r,o=new Array(i=r-e+1);++a=te?i*=10:o>=ne?i*=5:o>=ee&&(i*=2),n0;){if((i=re(l,s,e))===r)return o[u]=l,o[a]=s,n(o);if(i>0)l=Math.floor(l/i)*i,s=Math.ceil(s/i)*i;else{if(!(i<0))break;l=Math.ceil(l*i)/i,s=Math.floor(s*i)/i}r=i}return t},t}function cr(){var t=ar();return t.copy=function(){return ur(t,cr())},lr.apply(t,arguments),sr(t)}function fr(t){return((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2}var hr={value:()=>{}};function pr(){for(var t,n=0,e=arguments.length,r={};n=0&&(e=t.slice(r+1),t=t.slice(0,r)),t&&!n.hasOwnProperty(t))throw new Error("unknown type: "+t);return{type:t,name:e}}))}function vr(t,n){for(var e,r=0,i=t.length;r0)for(var e,r,i=new Array(e),o=0;o=0&&n._call.call(null,t),n=n._next;--br}()}finally{br=0,function(){for(var t,n,e=_r,r=1/0;e;)e._call?(r>e._time&&(r=e._time),t=e,e=e._next):(n=e._next,e._next=null,e=t?t._next=n:_r=n);wr=t,Tr(r)}(),Nr=0}}function Lr(){var t=kr.now(),n=t-Ar;n>1e3&&(Er-=n,Ar=t)}function Tr(t){br||(xr&&(xr=clearTimeout(xr)),t-Nr>24?(t<1/0&&(xr=setTimeout(Or,t-kr.now()-Er)),Mr&&(Mr=clearInterval(Mr))):(Mr||(Ar=kr.now(),Mr=setInterval(Lr,1e3)),br=1,Sr(Or)))}function Br(t,n,e){var r=new jr;return n=null==n?0:+n,r.restart((function(e){r.stop(),t(e+n)}),n,e),r}jr.prototype=qr.prototype={constructor:jr,restart:function(t,n,e){if("function"!=typeof t)throw new TypeError("callback is not a function");e=(null==e?Cr():+e)+(null==n?0:+n),this._next||wr===this||(wr?wr._next=this:_r=this,wr=this),this._call=t,this._time=e,Tr()},stop:function(){this._call&&(this._call=null,this._time=1/0,Tr())}};var Dr=mr("start","end","cancel","interrupt"),Hr=[];function Rr(t,n,e,r,i,o){var u=t.__transition;if(u){if(e in u)return}else t.__transition={};!function(t,n,e){var r,i=t.__transition;function o(l){var s,c,f,h;if(1!==e.state)return a();for(s in i)if((h=i[s]).name===e.name){if(3===h.state)return Br(o);4===h.state?(h.state=6,h.timer.stop(),h.on.call("interrupt",t,t.__data__,h.index,h.group),delete i[s]):+s0)throw new Error("too late; already scheduled");return e}function Xr(t,n){var e=zr(t,n);if(e.state>3)throw new Error("too late; already running");return e}function zr(t,n){var e=t.__transition;if(!e||!(e=e[n]))throw new Error("transition not found");return e}var Ir,$r,Ur,Yr,Fr=180/Math.PI,Zr={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function Gr(t,n,e,r,i,o){var u,a,l;return(u=Math.sqrt(t*t+n*n))&&(t/=u,n/=u),(l=t*e+n*r)&&(e-=t*l,r-=n*l),(a=Math.sqrt(e*e+r*r))&&(e/=a,r/=a,l/=a),t*r180?n+=360:n-t>180&&(t+=360),o.push({i:e.push(i(e)+"rotate(",null,r)-2,x:Ye(t,n)})):n&&e.push(i(e)+"rotate("+n+r)}(o.rotate,u.rotate,a,l),function(t,n,e,o){t!==n?o.push({i:e.push(i(e)+"skewX(",null,r)-2,x:Ye(t,n)}):n&&e.push(i(e)+"skewX("+n+r)}(o.skewX,u.skewX,a,l),function(t,n,e,r,o,u){if(t!==e||n!==r){var a=o.push(i(o)+"scale(",null,",",null,")");u.push({i:a-4,x:Ye(t,e)},{i:a-2,x:Ye(n,r)})}else 1===e&&1===r||o.push(i(o)+"scale("+e+","+r+")")}(o.scaleX,o.scaleY,u.scaleX,u.scaleY,a,l),o=u=null,function(t){for(var n,e=-1,r=l.length;++e=0&&(t=t.slice(0,n)),!t||"start"===t}))}(n)?Vr:Xr;return function(){var u=o(this,t),a=u.on;a!==r&&(i=(r=a).copy()).on(n,e),u.on=i}}var _i=Cn.prototype.constructor;function wi(t){return function(){this.style.removeProperty(t)}}function bi(t,n,e){return function(r){this.style.setProperty(t,n.call(this,r),e)}}function xi(t,n,e){var r,i;function o(){var o=n.apply(this,arguments);return o!==i&&(r=(i=o)&&bi(t,o,e)),r}return o._value=n,o}function Mi(t){return function(n){this.textContent=t.call(this,n)}}function Ai(t){var n,e;function r(){var r=t.apply(this,arguments);return r!==e&&(n=(e=r)&&Mi(r)),n}return r._value=t,r}var Ni=0;function Ei(t,n,e,r){this._groups=t,this._parents=n,this._name=e,this._id=r}function ki(){return++Ni}var Si=Cn.prototype;Ei.prototype=function(t){return Cn().transition(t)}.prototype={constructor:Ei,select:function(t){var n=this._name,e=this._id;"function"!=typeof t&&(t=gt(t));for(var r=this._groups,i=r.length,o=new Array(i),u=0;u{p&&(p.textContent="search: "+n+" of "+e+" total samples ( "+Xn(".3f")(n/e*100,3)+"%)")},d()};const k=E;let S=(t,n,e=!1)=>{if(!n)return!1;let r=b(t);e&&(n=n.toLowerCase(),r=r.toLowerCase());const i=new RegExp(n);return void 0!==r&&r&&r.match(i)};const C=S;let P=function(t){p&&(t?p.textContent=t:"function"==typeof d?d():p.textContent="")};const j=P;let q=function(t){return b(t)+" ("+Xn(".3f")(100*(t.x1-t.x0),3)+"%, "+x(t)+" samples)"},O=function(t){return t.highlight?"#E600E6":function(t,n){let e=w||"warm";w||void 0===n||""===n||(e="red",void 0!==t&&t&&t.match(/::/)&&(e="yellow"),"kernel"===n?e="orange":"jit"===n?e="green":"inlined"===n&&(e="aqua"));const r=function(t){let n=0;if(t){const e=t.split("` + "`" + `");e.length>1&&(t=e[e.length-1]),n=function(t){let n=0,e=0,r=1;if(t){for(let i=0;i6);i++)n+=r*(t.charCodeAt(i)%10),e+=9*r,r*=.7;e>0&&(n/=e)}return n}(t=t.split("(")[0])}return n}(t);return function(t,n){let e,r,i;return"red"===t?(e=200+Math.round(55*n),r=50+Math.round(80*n),i=r):"orange"===t?(e=190+Math.round(65*n),r=90+Math.round(65*n),i=0):"yellow"===t?(e=175+Math.round(55*n),r=e,i=50+Math.round(20*n)):"green"===t?(e=50+Math.round(60*n),r=200+Math.round(55*n),i=e):"pastelgreen"===t?(e=163+Math.round(75*n),r=195+Math.round(49*n),i=72+Math.round(149*n)):"blue"===t?(e=91+Math.round(126*n),r=156+Math.round(76*n),i=221+Math.round(26*n)):"aqua"===t?(e=50+Math.round(60*n),r=165+Math.round(55*n),i=r):"cold"===t?(e=0+Math.round(55*(1-n)),r=0+Math.round(230*(1-n)),i=200+Math.round(55*n)):(e=200+Math.round(55*n),r=0+Math.round(230*(1-n)),i=0+Math.round(55*(1-n))),"rgb("+e+","+r+","+i+")"}(e,r)}(b(t),A(t))};const L=O;function T(t){t.data.fade=!1,t.data.hide=!1,t.children&&t.children.forEach(T)}function B(t){t.parent&&(t.parent.data.fade=!0,B(t.parent))}function D(t){if(i&&i.hide(),function(t){let n,e,r,i=t,o=i.parent;for(;o;){for(n=o.children,e=n.length;e--;)r=n[e],r!==i&&(r.data.hide=!0);i=o,o=i.parent}}(t),T(t),B(t),z(),y){const n=Pn(this).select("svg")._groups[0][0].parentNode.offsetTop,r=(window.innerHeight-n)/e,i=(t.height-r+10)*e;window.scrollTo({top:n+i,left:0,behavior:"smooth"})}"function"==typeof c&&c(t)}function H(t,n){if(t.id===n)return t;{const e=M(t);if(e)for(let t=0;t0){const r=t/(n.x1-n.x0);e=e.filter((function(t){return(t.x1-t.x0)*r>h}))}return e}(r),y=Pn(this).select("svg");y.attr("width",t);let _=y.selectAll("g").data(g,(function(t){return t.id}));if(!n||v){const t=Math.max.apply(null,g.map((function(t){return t.depth})));n=(t+3)*e,n{D(n)})),_.exit().remove(),_.on("mouseover",(function(t,n){i&&i.show(n,this),P(q(n)),"function"==typeof f&&f(n)})).on("mouseout",(function(){i&&i.hide(),P(null)}))}))}function I(t,n){n.forEach((function(n){const e=t.find((function(t){return t.name===n.name}));e?(e.value+=n.value,n.children&&(e.children||(e.children=[]),I(e.children,n.children))):t.push(n)}))}function $(t){let n,e,r,i,o,u,a,l;const s=[],c=[],f=[],h=!g;let p=t.data;for(p.hide?(t.value=0,e=t.children,e&&f.push(e)):(t.value=p.fade?0:x(p),s.push(t));n=s.pop();)if(e=n.children,e&&(o=e.length)){for(i=0;o--;)a=e[o],p=a.data,p.hide?(a.value=0,r=a.children,r&&f.push(r)):(p.fade?a.value=0:(l=x(p),a.value=l,i+=l),s.push(a));h&&n.value&&(n.value-=i),c.push(e)}for(o=c.length;o--;){for(e=c[o],i=0,u=e.length;u--;)i+=e[u].value;e[0].parent.value+=i}for(;f.length;)for(e=f.pop(),u=e.length;u--;)a=e[u],a.value=0,r=a.children,r&&f.push(r)}function U(){r.datum((t=>{if("Node"!==t.constructor.name){const n=Zn(t,M);return function(t){let n=0;!function(t,n){n(t);let e=t.children;if(e){const t=[e];let r,i,o;for(;t.length;)for(e=t.pop(),r=e.length;r--;)i=e[r],n(i),o=i.children,o&&t.push(o)}}(t,(function(t){t.id=n++}))}(n),$(n),n.originalValue=n.value,_&&n.eachAfter((t=>{let n=N(t);const e=t.children;let r=e&&e.length;for(;--r>=0;)n+=e[r].delta;t.delta=n})),n}}))}function Y(e){if(!arguments.length)return Y;r=e,U(),r.each((function(e){if(0===Pn(this).select("svg").size()){const e=Pn(this).append("svg:svg").attr("width",t).attr("class","partition d3-flame-graph");n&&(n(I([n.data],[t]),n.data))),U(),z(),Y):Y},Y.update=function(t){return r?(t&&(r.datum(t),U()),z(),Y):Y},Y.destroy=function(){return r?(i&&(i.hide(),"function"==typeof i.destroy&&i.destroy()),r.selectAll("svg").remove(),Y):Y},Y.setColorMapper=function(t){return arguments.length?(O=n=>{const e=L(n);return t(n,e)},Y):(O=L,Y)},Y.color=Y.setColorMapper,Y.setColorHue=function(t){return arguments.length?(w=t,Y):(w=null,Y)},Y.minFrameSize=function(t){return arguments.length?(h=t,Y):h},Y.setDetailsElement=function(t){return arguments.length?(p=t,Y):p},Y.details=Y.setDetailsElement,Y.selfValue=function(t){return arguments.length?(g=t,Y):g},Y.resetHeightOnZoom=function(t){return arguments.length?(v=t,Y):v},Y.scrollOnZoom=function(t){return arguments.length?(y=t,Y):y},Y.getName=function(t){return arguments.length?(b=t,Y):b},Y.getValue=function(t){return arguments.length?(x=t,Y):x},Y.getChildren=function(t){return arguments.length?(M=t,Y):M},Y.getLibtype=function(t){return arguments.length?(A=t,Y):A},Y.getDelta=function(t){return arguments.length?(N=t,Y):N},Y.setSearchHandler=function(t){return arguments.length?(E=t,Y):(E=k,Y)},Y.setDetailsHandler=function(t){return arguments.length?(P=t,Y):(P=j,Y)},Y.setSearchMatch=function(t){return arguments.length?(S=t,Y):(S=C,Y)},Y}return Cn.prototype.interrupt=function(t){return this.each((function(){!function(t,n){var e,r,i,o=t.__transition,u=!0;if(o){for(i in n=null==n?null:n+"",o)(e=o[i]).name===n?(r=e.state>2&&e.state<5,e.state=6,e.timer.stop(),e.on.call(r?"interrupt":"cancel",t,t.__data__,e.index,e.group),delete o[i]):u=!1;u&&delete t.__transition}}(this,t)}))},Cn.prototype.transition=function(t){var n,e;t instanceof Ei?(n=t._id,t=t._name):(n=ki(),(e=Ci).time=Cr(),t=null==t?null:t+"");for(var r=this._groups,i=r.length,o=0;o d3_flame_graph.go +// D3.js is a JavaScript library for manipulating documents based on data. +// https://github.com/d3/d3 +// See D3_LICENSE file for license details + +// d3-flame-graph is a D3.js plugin that produces flame graphs from hierarchical data. +// https://github.com/spiermar/d3-flame-graph +// See D3_FLAME_GRAPH_LICENSE file for license details + +package d3flamegraph + +// JSSource returns the d3 and d3-flame-graph JavaScript bundle +const JSSource = \` + +$d3_js +\` + +// CSSSource returns the $D3FLAMEGRAPH_CSS file +const CSSSource = \` +$d3_css +\` + +EOF + gofmt -w d3_flame_graph.go +} + +get_licenses() { + cp node_modules/d3-selection/LICENSE D3_LICENSE + cp node_modules/d3-flame-graph/LICENSE D3_FLAME_GRAPH_LICENSE +} + +get_licenses +generate_d3_flame_graph_go diff --git a/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/webpack.config.js b/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/webpack.config.js new file mode 100644 index 0000000000..71239d9e96 --- /dev/null +++ b/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/webpack.config.js @@ -0,0 +1,13 @@ +// Minimal webpack config to package a minified JS bundle (including +// dependencies) for execution in a