From: Anton Gladky Date: Mon, 24 Apr 2023 04:08:15 +0000 (+0100) Subject: 389-ds-base (1.4.0.21-1+deb10u1) buster-security; urgency=medium X-Git-Tag: archive/raspbian/1.4.0.21-1+rpi1+deb10u1^2~19 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=a478cb302275875710a55a32ff51903c3309e395;p=389-ds-base.git 389-ds-base (1.4.0.21-1+deb10u1) buster-security; urgency=medium * Non-maintainer upload by the LTS Security Team. * CVE-2021-4091: double free of the virtual attribute context in persistent search. * CVE-2022-0918: an unauthenticated attacker with network access to the LDAP port can cause a denial of service. * CVE-2022-0996: expired password was still allowed to access the database. * CVE-2022-2850: possible NULL pointer dereference leading to a denial of service. * CVE-2021-3652: importing an asterisk as password hashes enables successful authentication with any password, allowing attackers to access accounts with disabled passwords. * CVE-2021-3514: an authenticated attacker can crash 389-ds-base using a specially crafted query in sync_repl client, due to a NULL pointer dereference. * CVE-2019-14824:deref plugin vulnerability lets authenticated attackers access private attributes, like password hashes, using the 'search' permission. * CVE-2019-10224:vulnerability that may disclose sensitive information, including the Directory Manager password, when executing dscreate and dsconf commands in verbose mode.and dsconf commands in verbose mode and recording the terminal standard error output. * CVE-2019-3883: SSL/TLS requests do not enforce ioblocktimeout limit, leading to DoS vulnerability by hanging all workers with hanging LDAP requests. [dgit import unpatched 389-ds-base 1.4.0.21-1+deb10u1] --- a478cb302275875710a55a32ff51903c3309e395 diff --cc debian/389-ds-base-dev.install index 0000000,0000000..25880bd new file mode 100644 --- /dev/null +++ b/debian/389-ds-base-dev.install @@@ -1,0 -1,0 +1,9 @@@ ++usr/include/dirsrv/* ++usr/include/svrcore.h ++usr/lib/*/dirsrv/libldaputil.so ++usr/lib/*/dirsrv/libns-dshttpd.so ++usr/lib/*/dirsrv/libnunc-stans.so ++usr/lib/*/dirsrv/libslapd.so ++usr/lib/*/dirsrv/libsds.so ++usr/lib/*/libsvrcore.so ++usr/lib/*/pkgconfig/* diff --cc debian/389-ds-base-legacy-tools.install index 0000000,0000000..62dcd74 new file mode 100644 --- /dev/null +++ b/debian/389-ds-base-legacy-tools.install @@@ -1,0 -1,0 +1,82 @@@ ++usr/bin/cl-dump ++usr/bin/dbgen ++usr/bin/infadd ++usr/bin/ldif ++usr/bin/migratecred ++usr/bin/mmldif ++usr/bin/repl-monitor ++usr/bin/rsearch ++usr/lib/*/dirsrv/perl/ ++usr/sbin/bak2db ++usr/sbin/bak2db-online ++usr/sbin/cleanallruv ++usr/sbin/db2bak ++usr/sbin/db2bak-online ++usr/sbin/db2index ++usr/sbin/db2index-online ++usr/sbin/db2ldif ++usr/sbin/db2ldif-online ++usr/sbin/dbmon.sh ++usr/sbin/dn2rdn ++usr/sbin/fixup-linkedattrs ++usr/sbin/fixup-memberof ++usr/sbin/ldif2db ++usr/sbin/ldif2db-online ++usr/sbin/migrate-ds ++usr/sbin/monitor ++usr/sbin/ns-accountstatus ++usr/sbin/ns-activate ++usr/sbin/ns-inactivate ++usr/sbin/ns-newpwpolicy ++usr/sbin/remove-ds ++usr/sbin/restoreconfig ++usr/sbin/saveconfig ++usr/sbin/schema-reload ++usr/sbin/setup-ds ++usr/sbin/suffix2instance ++usr/sbin/syntax-validate ++usr/sbin/upgradednformat ++usr/sbin/usn-tombstone-cleanup ++usr/sbin/verify-db ++usr/share/dirsrv/properties/*.res ++usr/share/dirsrv/script-templates ++usr/share/dirsrv/updates ++usr/share/man/man1/cl-dump.1 ++usr/share/man/man1/dbgen.1 ++usr/share/man/man1/infadd.1 ++usr/share/man/man1/ldif.1 ++usr/share/man/man1/migratecred.1 ++usr/share/man/man1/mmldif.1 ++usr/share/man/man1/repl-monitor.1 ++usr/share/man/man1/rsearch.1 ++usr/share/man/man8/bak2db-online.8 ++usr/share/man/man8/bak2db.8 ++usr/share/man/man8/cleanallruv.8 ++usr/share/man/man8/db2bak-online.8 ++usr/share/man/man8/db2bak.8 ++usr/share/man/man8/db2index-online.8 ++usr/share/man/man8/db2index.8 ++usr/share/man/man8/db2ldif-online.8 ++usr/share/man/man8/db2ldif.8 ++usr/share/man/man8/dbmon.sh.8 ++usr/share/man/man8/dn2rdn.8 ++usr/share/man/man8/fixup-linkedattrs.8 ++usr/share/man/man8/fixup-memberof.8 ++usr/share/man/man8/ldif2db-online.8 ++usr/share/man/man8/ldif2db.8 ++usr/share/man/man8/migrate-ds.8 ++usr/share/man/man8/monitor.8 ++usr/share/man/man8/ns-accountstatus.8 ++usr/share/man/man8/ns-activate.8 ++usr/share/man/man8/ns-inactivate.8 ++usr/share/man/man8/ns-newpwpolicy.8 ++usr/share/man/man8/remove-ds.8 ++usr/share/man/man8/restoreconfig.8 ++usr/share/man/man8/saveconfig.8 ++usr/share/man/man8/schema-reload.8 ++usr/share/man/man8/setup-ds.8 ++usr/share/man/man8/suffix2instance.8 ++usr/share/man/man8/syntax-validate.8 ++usr/share/man/man8/upgradednformat.8 ++usr/share/man/man8/usn-tombstone-cleanup.8 ++usr/share/man/man8/verify-db.8 diff --cc debian/389-ds-base-libs.install index 0000000,0000000..ceaa364 new file mode 100644 --- /dev/null +++ b/debian/389-ds-base-libs.install @@@ -1,0 -1,0 +1,6 @@@ ++usr/lib/*/dirsrv/libldaputil.so.* ++usr/lib/*/dirsrv/libnunc-stans.so.* ++usr/lib/*/dirsrv/libns-dshttpd-*.so ++usr/lib/*/dirsrv/libsds.so.* ++usr/lib/*/dirsrv/libslapd.so.* ++usr/lib/*/libsvrcore.so.* diff --cc debian/389-ds-base-libs.lintian-overrides index 0000000,0000000..b6702fb new file mode 100644 --- /dev/null +++ b/debian/389-ds-base-libs.lintian-overrides @@@ -1,0 -1,0 +1,3 @@@ ++# these are bogus warnings, no libs shipped in a public libdir ++postinst-has-useless-call-to-ldconfig ++postrm-has-useless-call-to-ldconfig diff --cc debian/389-ds-base.default index 0000000,0000000..14beb77 new file mode 100644 --- /dev/null +++ b/debian/389-ds-base.default @@@ -1,0 -1,0 +1,6 @@@ ++# Defaults for dirsrv ++# ++# This is a POSIX shell fragment ++ ++# Enable bindnow hardening ++LD_BIND_NOW=1 diff --cc debian/389-ds-base.dirs index 0000000,0000000..f12d71e new file mode 100644 --- /dev/null +++ b/debian/389-ds-base.dirs @@@ -1,0 -1,0 +1,2 @@@ ++var/log/dirsrv ++var/lib/dirsrv diff --cc debian/389-ds-base.install index 0000000,0000000..48dc4f3 new file mode 100644 --- /dev/null +++ b/debian/389-ds-base.install @@@ -1,0 -1,0 +1,55 @@@ ++etc/default/dirsrv ++etc/default/dirsrv.systemd ++etc/dirsrv/config/ ++etc/dirsrv/schema/*.ldif ++etc/systemd/ ++lib/systemd/system/dirsrv-snmp.service ++lib/systemd/system/dirsrv.target ++lib/systemd/system/dirsrv@.service ++usr/bin/dbscan ++usr/bin/ds-logpipe ++usr/bin/ds-replcheck ++usr/bin/ldclt ++usr/bin/logconv ++usr/bin/pwdhash ++usr/bin/readnsstate ++usr/lib/*/dirsrv/plugins/*.so ++usr/lib/*/dirsrv/python/ ++usr/lib/*/ds_selinux_enabled ++usr/lib/*/ds_selinux_port_query ++usr/lib/*/ds_systemd_ask_password_acl ++usr/lib/sysctl.d/70-dirsrv.conf ++usr/sbin/dbverify ++usr/sbin/ldap-agent ++usr/sbin/ldif2ldap ++usr/sbin/ns-slapd ++usr/sbin/restart-dirsrv ++usr/sbin/start-dirsrv ++usr/sbin/status-dirsrv ++usr/sbin/stop-dirsrv ++usr/sbin/upgradedb ++usr/sbin/vlvindex ++usr/share/dirsrv/data ++usr/share/dirsrv/inf ++usr/share/dirsrv/mibs ++usr/share/dirsrv/properties/ns-slapd.properties ++usr/share/dirsrv/schema ++usr/share/gdb/auto-load/usr/sbin/ns-slapd-gdb.py ++usr/share/man/man1/dbscan.1 ++usr/share/man/man1/ds-logpipe.1 ++usr/share/man/man1/ds-replcheck.1 ++usr/share/man/man1/ldap-agent.1 ++usr/share/man/man1/ldclt.1 ++usr/share/man/man1/logconv.1 ++usr/share/man/man1/pwdhash.1 ++usr/share/man/man1/readnsstate.1 ++usr/share/man/man5/*.5 ++usr/share/man/man8/dbverify.8 ++usr/share/man/man8/ldif2ldap.8 ++usr/share/man/man8/ns-slapd.8 ++usr/share/man/man8/restart-dirsrv.8 ++usr/share/man/man8/start-dirsrv.8 ++usr/share/man/man8/status-dirsrv.8 ++usr/share/man/man8/stop-dirsrv.8 ++usr/share/man/man8/upgradedb.8 ++usr/share/man/man8/vlvindex.8 diff --cc debian/389-ds-base.links index 0000000,0000000..2f83bc6 new file mode 100644 --- /dev/null +++ b/debian/389-ds-base.links @@@ -1,0 -1,0 +1,1 @@@ ++/dev/null lib/systemd/system/dirsrv.service diff --cc debian/389-ds-base.lintian-overrides index 0000000,0000000..fbe0b92 new file mode 100644 --- /dev/null +++ b/debian/389-ds-base.lintian-overrides @@@ -1,0 -1,0 +1,4 @@@ ++# these are bogus warnings, no libs shipped in a public libdir ++unused-shlib-entry-in-control-file ++postinst-has-useless-call-to-ldconfig ++postrm-has-useless-call-to-ldconfig diff --cc debian/389-ds-base.postinst index 0000000,0000000..51a46b0 new file mode 100644 --- /dev/null +++ b/debian/389-ds-base.postinst @@@ -1,0 -1,0 +1,51 @@@ ++#!/bin/sh ++set -e ++ ++. /usr/share/debconf/confmodule ++ ++CONFIG_DIR=/etc/dirsrv ++OUT=/dev/null ++INSTANCES=`ls -d /etc/dirsrv/slapd-* 2>/dev/null | grep -v removed | sed 's/.*slapd-//'` ++ ++if [ "$1" = configure ]; then ++ # lets give them a user/group in all cases. ++ if ! getent passwd dirsrv > $OUT; then ++ adduser --quiet --system --home /var/lib/dirsrv \ ++ --disabled-password --group \ ++ --gecos "389 Directory Server user" \ ++ --no-create-home \ ++ dirsrv > $OUT ++ fi ++ ++ chown -R dirsrv:dirsrv /etc/dirsrv/ /var/log/dirsrv/ /var/lib/dirsrv/ > $OUT || true ++ chmod 750 /etc/dirsrv/ /var/log/dirsrv/ /var/lib/dirsrv/ > $OUT || true ++ ++ # needed only for upgrades from old versions, in newer ones updates are ++ # handled by ns-slapd itself ++ if dpkg --compare-versions "$2" lt "1.4.0.9"; then ++ for inst in $INSTANCES; do ++ service dirsrv@$inst stop > $OUT 2>&1 ++ done ++ ++ setup-ds -l $OUT -u -s General.UpdateMode=offline > $OUT 2>&1 ++ ++ if [ $? = 0 ]; then ++ for inst in $INSTANCES; do ++ service dirsrv@$inst start > $OUT 2>&1 ++ done ++ fi ++ fi ++fi ++ ++invoke_failure() { ++ # invoke-rc.d failed, likely because no instance has been configured yet ++ # but exit with an error if an instance is configured and the invoke failed ++ if [ -z $INSTANCES ]; then ++ echo "... because no instance has been configured yet." ++ else ++ exit 1 ++ fi ++} ++ ++ ++#DEBHELPER# diff --cc debian/389-ds-base.postrm index 0000000,0000000..0a70e0e new file mode 100644 --- /dev/null +++ b/debian/389-ds-base.postrm @@@ -1,0 -1,0 +1,16 @@@ ++#!/bin/sh ++set -e ++ ++. /usr/share/debconf/confmodule ++ ++if [ "$1" = "purge" ]; then ++ if getent group dirsrv > /dev/null; then ++ deluser --system dirsrv || true ++ fi ++ rm -f /etc/systemd/system/dirsrv.target.wants/dirsrv@*.service ++ rm -rf /etc/dirsrv ++ rm -rf /var/lib/dirsrv ++ rm -rf /var/log/dirsrv ++fi ++ ++#DEBHELPER# diff --cc debian/389-ds-base.prerm index 0000000,0000000..3e1529b new file mode 100644 --- /dev/null +++ b/debian/389-ds-base.prerm @@@ -1,0 -1,0 +1,14 @@@ ++#!/bin/sh -e ++set -e ++ ++#DEBHELPER# ++ ++if [ "$1" = "purge" ]; then ++ # remove all installed instances ++ for FILE in `ls -d $CONFDIR/slapd-* 2>/dev/null | sed -n '/\.removed$/!$'` ++ do ++ if [ -d "$FILE" ] ; then ++ remove-ds -f -i $FILE ++ fi ++ done ++fi diff --cc debian/README.Debian index 0000000,0000000..eba838e new file mode 100644 --- /dev/null +++ b/debian/README.Debian @@@ -1,0 -1,0 +1,12 @@@ ++To complete the 389 Directory Server installation just run /usr/sbin/setup-ds. ++ ++If you experience problems accessing the Directory Server, check with ++"netstat -tapen |grep 389" and verify that the server is not listening only ++to ipv6 (check for ^tcp6). In such case you will need to tweak the cn=config ++DIT with something like the following: ++ ++dn: cn=config ++changetype: modify ++add: nsslapd-listenhost ++nsslapd-listenhost: ++ diff --cc debian/changelog index 0000000,0000000..78a028f new file mode 100644 --- /dev/null +++ b/debian/changelog @@@ -1,0 -1,0 +1,851 @@@ ++389-ds-base (1.4.0.21-1+deb10u1) buster-security; urgency=medium ++ ++ * Non-maintainer upload by the LTS Security Team. ++ * CVE-2021-4091: double free of the virtual attribute context in ++ persistent search. ++ * CVE-2022-0918: an unauthenticated attacker with network access to ++ the LDAP port ++ can cause a denial of service. ++ * CVE-2022-0996: expired password was still allowed to access the database. ++ * CVE-2022-2850: possible NULL pointer dereference leading to a denial of ++ service. ++ * CVE-2021-3652: importing an asterisk as password hashes enables successful ++ authentication with any password, allowing attackers to ++ access accounts with disabled passwords. ++ * CVE-2021-3514: an authenticated attacker can crash 389-ds-base using a ++ specially crafted query in sync_repl client, due to a NULL ++ pointer dereference. ++ * CVE-2019-14824:deref plugin vulnerability lets authenticated attackers ++ access private attributes, like password hashes, using the ++ 'search' permission. ++ * CVE-2019-10224:vulnerability that may disclose sensitive information, ++ including the Directory Manager password, when executing ++ dscreate and dsconf commands in verbose mode.and dsconf ++ commands in verbose mode and recording the terminal standard ++ error output. ++ * CVE-2019-3883: SSL/TLS requests do not enforce ioblocktimeout limit, leading ++ to DoS vulnerability by hanging all workers with hanging LDAP ++ requests. ++ ++ -- Anton Gladky Mon, 24 Apr 2023 06:08:15 +0200 ++ ++389-ds-base (1.4.0.21-1) unstable; urgency=medium ++ ++ * New upstream release. ++ * Run offline upgrade only when upgrading from versions below 1.4.0.9, ++ ns-slapd itself handles upgrades in newer versions. ++ * rules: Actually install the minified javascript files. (Closes: ++ #913820) ++ ++ -- Timo Aaltonen Tue, 12 Feb 2019 16:28:15 +0200 ++ ++389-ds-base (1.4.0.20-3) unstable; urgency=medium ++ ++ * control: 389-ds-base should depend on the legacy tools for now. ++ (Closes: #919420) ++ ++ -- Timo Aaltonen Wed, 16 Jan 2019 11:30:51 +0200 ++ ++389-ds-base (1.4.0.20-2) unstable; urgency=medium ++ ++ * Upload to unstable. ++ ++ -- Timo Aaltonen Mon, 14 Jan 2019 20:03:58 +0200 ++ ++389-ds-base (1.4.0.20-1) experimental; urgency=medium ++ ++ * New upstream release. (Closes: #913821) ++ * fix-nss-path.diff: Fix includes. ++ * Build ds* manpages, add missing build-depends. ++ * Move deprecated tools in a new subpackage. ++ * control: Add python3-lib389 to 389-ds-base depends. ++ ++ -- Timo Aaltonen Sun, 13 Jan 2019 21:13:22 +0200 ++ ++389-ds-base (1.4.0.19-3) unstable; urgency=medium ++ ++ [ Jelmer Vernooij ] ++ * Use secure copyright file specification URI. ++ * Trim trailing whitespace. ++ * Use secure URI in Vcs control header. ++ ++ [ Hugh McMaster ] ++ * control: Mark 389-ds-base-libs{,-dev} M-A: same, cockpit-389-ds M-A: ++ foreign and arch:all. (Closes: #916118) ++ * Use pkg-config to detect icu. (Closes: #916115) ++ ++ -- Timo Aaltonen Wed, 02 Jan 2019 12:43:23 +0200 ++ ++389-ds-base (1.4.0.19-2) unstable; urgency=medium ++ ++ * rules: Add -latomic to LDFLAGS on archs failing to build. (Closes: ++ #910982) ++ ++ -- Timo Aaltonen Thu, 06 Dec 2018 01:06:37 +0200 ++ ++389-ds-base (1.4.0.19-1) unstable; urgency=medium ++ ++ * New upstream release. ++ * control: Make C/R backports-compatible. (Closes: #910796) ++ * use-packaged-js.diff: Dropped, packaged versions don't work. ++ (Closes: #913820) ++ * Follow upstream, and drop python3-dirsrvtests. ++ * cockpit-389-ds.install: Updated. ++ ++ -- Timo Aaltonen Mon, 03 Dec 2018 15:56:40 +0200 ++ ++389-ds-base (1.4.0.18-1) unstable; urgency=medium ++ ++ * New upstream release. ++ - CVE-2018-14624 (Closes: #907778) ++ - CVE-2018-14638 (Closes: #908859) ++ * control: Build on any arch again. ++ * perl-use-move-instead-of-rename.diff: Use copy instead of move, ++ except when restoring files in case of an error. ++ * Move the new utils (dsconf, dscreate, dsctl, dsidm) to python3- ++ lib389. ++ * control: Add python3-argcomplete to python3-lib389 depends. (Closes: ++ #910761) ++ ++ -- Timo Aaltonen Thu, 11 Oct 2018 00:56:02 +0300 ++ ++389-ds-base (1.4.0.16-1) unstable; urgency=medium ++ ++ * New upstream release. ++ * control: 389-ds-base-dev provides libsvrcore-dev. (Closes: #907140) ++ * perl-use-move-instead-of-rename.diff: Fix upgrade on systems where ++ /var is on a separate partition: (Closes: #905184) ++ ++ -- Timo Aaltonen Thu, 27 Sep 2018 22:39:34 +0300 ++ ++389-ds-base (1.4.0.15-2) unstable; urgency=medium ++ ++ * control: Build cockpit-389-ds only on 64bit and i386. ++ ++ -- Timo Aaltonen Thu, 23 Aug 2018 08:54:06 +0300 ++ ++389-ds-base (1.4.0.15-1) unstable; urgency=medium ++ ++ * New upstream release ++ - CVE-2018-10935 (Closes: #906985) ++ * control: Add libcrack2-dev to build-depends. ++ ++ -- Timo Aaltonen Thu, 23 Aug 2018 00:46:45 +0300 ++ ++389-ds-base (1.4.0.13-1) experimental; urgency=medium ++ ++ * New upstream release. ++ - CVE-2018-10850 (Closes: #903501) ++ * control: Update maintainer address. ++ * control: Upstream dropped support for non-64bit architectures, so ++ build only on supported 64bit archs (amd64, arm64, mips64el, ++ ppc64el, s390x). ++ * control: svrcore got merged here, drop it from build-depends. ++ * ftbs_lsoftotkn3.diff: Dropped, obsolete. ++ * control: Add rsync to build-depends. ++ * libs, dev, control: Add libsvrcore files, replace old package. ++ * base: Add new scripts, add python3-selinux, -semanage, -sepolicy to ++ depends. ++ * Add a package for cockpit-389-ds. ++ * rules: Clean up cruft left after build. ++ * control: Drop dh_systemd from build-depends, bump debhelper to 11. ++ * Add varions libjs packages to cockpit-389-ds Depends, add the rest ++ to d/missing-sources. ++ * copyright: Updated. (Closes: #904760) ++ * control: Modify 389-ds to depend on cockpit-389-ds and drop the old ++ GUI packages which are deprecated upstream. ++ * dont-build-new-manpages.diff: Debian doesn't have argparse-manpage, ++ so in order to not FTBFS don't build new manpages. ++ * base.install: Add man5/*. ++ ++ -- Timo Aaltonen Tue, 31 Jul 2018 23:46:17 +0300 ++ ++389-ds-base (1.3.8.2-1) unstable; urgency=medium ++ ++ * New upstream release. ++ * fix-saslpath.diff: Updated to support ppc64el and s390x. (LP: ++ #1764744) ++ * CVE-2017-15135.patch: Refreshed ++ ++ -- Timo Aaltonen Fri, 01 Jun 2018 11:21:19 +0300 ++ ++389-ds-base (1.3.7.10-1) unstable; urgency=medium ++ ++ * New upstream release. ++ - fix CVE-2018-1054 (Closes: #892124) ++ * control: Update maintainer address, freeipa-team handles this from ++ now on. Drop kklimonda from uploaders. ++ * control: Update VCS urls. ++ ++ -- Timo Aaltonen Tue, 13 Mar 2018 11:32:29 +0200 ++ ++389-ds-base (1.3.7.9-1) unstable; urgency=medium ++ ++ * New upstream release. ++ - CVE-2017-15134 (Closes: #888452) ++ * patches: Fix CVE-2017-15135. (Closes: #888451) ++ * tests: Add some debug output. ++ ++ -- Timo Aaltonen Mon, 05 Feb 2018 16:25:09 +0200 ++ ++389-ds-base (1.3.7.8-4) unstable; urgency=medium ++ ++ * tests: Drop python3-lib389 from depends, it's not used currently ++ anyway. ++ ++ -- Timo Aaltonen Thu, 21 Dec 2017 15:42:04 +0200 ++ ++389-ds-base (1.3.7.8-3) unstable; urgency=medium ++ ++ * tests/control: Depend on python3-lib389. ++ ++ -- Timo Aaltonen Wed, 20 Dec 2017 23:54:43 +0200 ++ ++389-ds-base (1.3.7.8-2) unstable; urgency=medium ++ ++ * Fix autopkgtest to be robust in the face of changed iproute2 output. ++ ++ -- Timo Aaltonen Wed, 20 Dec 2017 15:57:26 +0200 ++ ++389-ds-base (1.3.7.8-1) unstable; urgency=medium ++ ++ * New upstream release. ++ * Package python3-lib389 and python3-dirsrvtests. ++ * control: Add python3 depends to 389-ds-base, since it ships a few ++ python scripts. ++ ++ -- Timo Aaltonen Tue, 12 Dec 2017 17:32:27 +0200 ++ ++389-ds-base (1.3.7.5-1) unstable; urgency=medium ++ ++ * New upstream release. ++ * patches: ftbfs-fix.diff, reproducible-build.diff dropped (upstream) ++ others refreshed. ++ * *.install: Updated. ++ ++ -- Timo Aaltonen Wed, 04 Oct 2017 10:33:45 +0300 ++ ++389-ds-base (1.3.6.7-5) unstable; urgency=medium ++ ++ * Move all libs from base to -libs, add B/R. (Closes: #874764) ++ ++ -- Timo Aaltonen Thu, 21 Sep 2017 16:44:13 +0300 ++ ++389-ds-base (1.3.6.7-4) unstable; urgency=medium ++ ++ * control, install: Fix library/dev-link installs, add Breaks/Replaces ++ to fit, and drop obsolete B/R. ++ ++ -- Timo Aaltonen Wed, 30 Aug 2017 00:19:41 +0300 ++ ++389-ds-base (1.3.6.7-3) unstable; urgency=medium ++ ++ * ftbfs-fix.diff: Fix build. (Closes: #873120) ++ ++ -- Timo Aaltonen Mon, 28 Aug 2017 15:09:02 +0300 ++ ++389-ds-base (1.3.6.7-2) unstable; urgency=medium ++ ++ * control: Bump policy to 4.1.0, no changes. ++ * rules: Override dh_missing. ++ * control: Add libltdl-dev to build-depends. (Closes: #872979) ++ ++ -- Timo Aaltonen Thu, 24 Aug 2017 12:15:03 +0300 ++ ++389-ds-base (1.3.6.7-1) unstable; urgency=medium ++ ++ * New upstream release ++ - fix CVE-2017-7551 (Closes: #870752) ++ * fix-tests.diff: Dropped, fixed upstream. ++ ++ -- Timo Aaltonen Tue, 22 Aug 2017 16:30:11 +0300 ++ ++389-ds-base (1.3.6.5-1) experimental; urgency=medium ++ ++ * New upstream release. ++ - fix-bsd.patch, support-kfreebsd.patch, fix-48986-cve-2017-2591.diff: ++ Dropped, upstream. ++ * *.install: Updated. ++ * control: Add doxygen, libcmocka-dev, libevent-dev to build-deps. ++ * rules: Enable cmocka tests. ++ * fix-tests.diff: Fix building the tests. ++ ++ -- Timo Aaltonen Wed, 10 May 2017 09:38:30 +0300 ++ ++389-ds-base (1.3.5.17-2) unstable; urgency=medium ++ ++ * fix-upstream-49245.diff: Pull commits from upstream 1.3.5.x, which ++ remove rest of the asm code. (Closes: #862194) ++ ++ -- Timo Aaltonen Wed, 10 May 2017 09:25:03 +0300 ++ ++389-ds-base (1.3.5.17-1) unstable; urgency=medium ++ ++ * New upstream bugfix release. ++ - CVE-2017-2668 (Closes: #860125) ++ * watch: Updated. ++ ++ -- Timo Aaltonen Tue, 09 May 2017 11:06:14 +0300 ++ ++389-ds-base (1.3.5.15-2) unstable; urgency=medium ++ ++ * fix-48986-cve-2017-2591.diff: Fix upstream ticket 48986, ++ CVE-2017-2591. (Closes: #851769) ++ ++ -- Timo Aaltonen Fri, 27 Jan 2017 00:01:53 +0200 ++ ++389-ds-base (1.3.5.15-1) unstable; urgency=medium ++ ++ * New upstream release. ++ - CVE-2016-5405 (Closes: #842121) ++ ++ -- Timo Aaltonen Wed, 16 Nov 2016 11:01:00 +0200 ++ ++389-ds-base (1.3.5.14-1) unstable; urgency=medium ++ ++ * New upstream release. ++ * postrm: Remove /etc/dirsrv, /var/lib/dirsrv and /var/log/dirsrv on ++ purge. ++ * control: Bump build-dep on libsvrcore-dev to ensure it has support ++ for systemd password agent. ++ ++ -- Timo Aaltonen Fri, 28 Oct 2016 01:42:27 +0300 ++ ++389-ds-base (1.3.5.13-1) unstable; urgency=medium ++ ++ * New upstream release. ++ * control: Bump policy to 3.9.8, no changes. ++ * patches/default_user: Dropped, upstream. ++ * support-non-nss-libldap.diff: Dropped, upstream. ++ * fix-obsolete-target.diff: Updated. ++ * patches: Refreshed. ++ * control: Add libsystemd-dev to build-deps. ++ * control: Add acl to -base depends. ++ ++ -- Timo Aaltonen Wed, 12 Oct 2016 11:11:20 +0300 ++ ++389-ds-base (1.3.4.14-2) unstable; urgency=medium ++ ++ * tests: Add simple autopkgtests. ++ * postinst: Start instances after offline update. ++ * control, rules: Drop -dbg packages. ++ * control: Drop conflicts on slapd. (Closes: #822532) ++ ++ -- Timo Aaltonen Mon, 03 Oct 2016 17:53:26 +0300 ++ ++389-ds-base (1.3.4.14-1) unstable; urgency=medium ++ ++ * New upstream release. ++ * support-non-nss-libldap.diff: Refreshed. ++ ++ -- Timo Aaltonen Mon, 29 Aug 2016 10:17:41 +0300 ++ ++389-ds-base (1.3.4.9-1) unstable; urgency=medium ++ ++ * New upstream release. ++ * support-non-nss-libldap.diff: Support libldap built against gnutls. ++ (LP: #1564179) ++ ++ -- Timo Aaltonen Mon, 18 Apr 2016 18:08:14 +0300 ++ ++389-ds-base (1.3.4.8-4) unstable; urgency=medium ++ ++ * use-perl-move.diff: Dropped, 'rename' is more reliable. ++ ++ -- Timo Aaltonen Wed, 30 Mar 2016 08:38:24 +0300 ++ ++389-ds-base (1.3.4.8-3) unstable; urgency=medium ++ ++ * use-perl-move.diff: Fix 60upgradeschemafiles.pl to use File::Copy. ++ (Closes: #818578) ++ ++ -- Timo Aaltonen Fri, 18 Mar 2016 11:15:23 +0200 ++ ++389-ds-base (1.3.4.8-2) unstable; urgency=medium ++ ++ * postinst: Silence ls and adduser. ++ * Drop the init file, we depend on systemd anyway. ++ * rules: Don't enable dirsrv-snmp.service by default. ++ * postrm: Clean up /var/lib/dirsrv/scripts-* on purge. ++ * user-perl-move.diff: Use move instead of rename during upgrade. ++ (Closes: #775550) ++ ++ -- Timo Aaltonen Thu, 17 Mar 2016 08:13:38 +0200 ++ ++389-ds-base (1.3.4.8-1) unstable; urgency=medium ++ ++ * New upstream release. ++ ++ -- Timo Aaltonen Mon, 22 Feb 2016 07:58:40 +0200 ++ ++389-ds-base (1.3.4.5-2) unstable; urgency=medium ++ ++ * fix-systemctl-path.diff: Use correct path to /bin/systemctl. ++ (Closes: #779653) ++ ++ -- Timo Aaltonen Wed, 09 Dec 2015 08:31:20 +0200 ++ ++389-ds-base (1.3.4.5-1) unstable; urgency=medium ++ ++ * New upstream release. ++ * patches: Refreshed. ++ ++ -- Timo Aaltonen Wed, 09 Dec 2015 08:14:56 +0200 ++ ++389-ds-base (1.3.3.13-1) unstable; urgency=medium ++ ++ * New upstream release. ++ * control: Add systemd to 389-ds-base Depends. (Closes: #794301) ++ * postrm: Clean target.wants in postrm. ++ * reproducible-build.diff: Make builds reproducible. Thanks, Chris ++ Lamb! (Closes: #799010) ++ ++ -- Timo Aaltonen Tue, 20 Oct 2015 14:25:05 +0300 ++ ++389-ds-base (1.3.3.12-1) unstable; urgency=medium ++ ++ * New upstream release ++ - fix CVE-2015-3230 (Closes: #789202) ++ ++ -- Timo Aaltonen Wed, 24 Jun 2015 11:47:50 +0300 ++ ++389-ds-base (1.3.3.10-1) unstable; urgency=medium ++ ++ * New upstream release ++ - fix CVE-2015-1854 (Closes: #783923) ++ * postinst: Stop actual instances instead of 'dirsrv' on upgrade, and ++ use service(8) instead of invoke-rc.d. ++ ++ -- Timo Aaltonen Thu, 07 May 2015 07:58:35 +0300 ++ ++389-ds-base (1.3.3.9-1) experimental; urgency=medium ++ ++ * New upstream bugfix release. ++ - Drop cve-2014-8*.diff, upstream. ++ ++ -- Timo Aaltonen Thu, 02 Apr 2015 14:47:20 +0300 ++ ++389-ds-base (1.3.3.5-4) unstable; urgency=medium ++ ++ * Security fixes (Closes: #779909) ++ - cve-2014-8105.diff: Fix for CVE-2014-8105 ++ - cve-2014-8112.diff: Fix for CVE-2014-8112 ++ ++ -- Timo Aaltonen Mon, 09 Mar 2015 10:53:03 +0200 ++ ++389-ds-base (1.3.3.5-3) unstable; urgency=medium ++ ++ * use-bash-instead-of-sh.diff: Drop admin_scripts.diff and patch the ++ scripts to use bash instead of trying to fix bashisms. (Closes: ++ #772195) ++ ++ -- Timo Aaltonen Fri, 16 Jan 2015 15:40:23 +0200 ++ ++389-ds-base (1.3.3.5-2) unstable; urgency=medium ++ ++ * fix-saslpath.diff: Fix SASL library path. ++ ++ -- Timo Aaltonen Sat, 25 Oct 2014 01:48:34 +0300 ++ ++389-ds-base (1.3.3.5-1) unstable; urgency=medium ++ ++ * New upstream bugfix release. ++ * control: Bump policy, no changes. ++ ++ -- Timo Aaltonen Mon, 20 Oct 2014 09:57:14 +0300 ++ ++389-ds-base (1.3.3.3-1) unstable; urgency=medium ++ ++ * New upstream release. ++ * Dropped upstreamed patches, refresh others. ++ * control, rules, 389-ds-base.install: Add support for systemd. ++ * fix-obsolete-target.diff: Drop syslog.target from the service files. ++ * 389-ds-base.links: Mask the initscript so that it's not used with systemd. ++ ++ -- Timo Aaltonen Mon, 06 Oct 2014 17:13:01 +0300 ++ ++389-ds-base (1.3.2.23-2) unstable; urgency=medium ++ ++ * Team upload. ++ * Add fix-bsd.patch and support-kfreebsd.patch to fix the build failure ++ on kFreeBSD. ++ ++ -- Benjamin Drung Wed, 03 Sep 2014 15:32:22 +0200 ++ ++389-ds-base (1.3.2.23-1) unstable; urgency=medium ++ ++ * New bugfix release. ++ * watch: Update the url. ++ * control: Update Vcs-Browser url to use cgit. ++ ++ -- Timo Aaltonen Mon, 01 Sep 2014 13:32:59 +0300 ++ ++389-ds-base (1.3.2.21-1) unstable; urgency=medium ++ ++ * New upstream release. ++ - CVE-2014-3562 (Closes: #757437) ++ ++ -- Timo Aaltonen Fri, 08 Aug 2014 10:48:55 +0300 ++ ++389-ds-base (1.3.2.19-1) unstable; urgency=medium ++ ++ * New upstream release. ++ * admin_scripts.diff: Updated to fix more bashisms. ++ * watch: Update the url. ++ * Install failedbinds.py and logregex.py scripts. ++ * init: Use status from init-functions. ++ * control: Update my email. ++ ++ -- Timo Aaltonen Tue, 08 Jul 2014 15:50:11 +0300 ++ ++389-ds-base (1.3.2.9-1.1) unstable; urgency=medium ++ ++ * Non-maintainer upload. ++ * Apply fix for CVE-2014-0132, see like named patch (Closes: 741600) ++ * Fix m4-macro for libsrvcore and add missing B-D on libpci-dev ++ (Closes: #745821) ++ ++ -- Tobias Frost Fri, 25 Apr 2014 15:11:16 +0200 ++ ++389-ds-base (1.3.2.9-1) unstable; urgency=low ++ ++ * New upstream release. ++ - fixes CVE-2013-0336 (Closes: #704077) ++ - fixes CVE-2013-1897 (Closes: #704421) ++ - fixes CVE-2013-2219 (Closes: #718325) ++ - fixes CVE-2013-4283 (Closes: #721222) ++ - fixes CVE-2013-4485 (Closes: #730115) ++ * Drop fix-CVE-2013-0312.diff, upstream. ++ * rules: Add new scripts to rename. ++ * fix-sasl-path.diff: Use a triplet path to find libsasl2. (LP: ++ #1088822) ++ * admin_scripts.diff: Add patch from upstream #47511 to fix bashisms. ++ * control: Add ldap-utils to -base depends. ++ * rules, rename-online-scripts.diff: Some scripts with .pl suffix are ++ meant for an online server, so instead of overwriting the offline ++ scripts use -online suffix. ++ * rules: Enable parallel build, but limit the jobs to 1 for ++ dh_auto_install. ++ * control: Bump policy to 3.9.5, no changes. ++ * rules: Add get-orig-source target. ++ * lintian-overrides: Drop obsolete entries, add comments for the rest. ++ ++ -- Timo Aaltonen Mon, 03 Feb 2014 11:08:50 +0200 ++ ++389-ds-base (1.3.0.3-1) unstable; urgency=low ++ ++ * New upstream release. ++ * control: Bump the policy to 3.9.4, no changes. ++ * fix-CVE-2013-0312.diff: Patch to fix handling LDAPv3 control data. ++ ++ -- Timo Aaltonen Mon, 11 Mar 2013 14:23:20 +0200 ++ ++389-ds-base (1.2.11.17-1) UNRELEASED; urgency=low ++ ++ * New upstream release. ++ * watch: Add a comment about the upstream git tree. ++ * fix-cve-2012-4450.diff: Remove, upstream. ++ ++ -- Timo Aaltonen Sat, 01 Dec 2012 14:22:13 +0200 ++ ++389-ds-base (1.2.11.15-1) unstable; urgency=low ++ ++ * New upstream release. ++ * Add fix-cve-2012-4450.diff. (Closes: #688942) ++ * dirsrv.init: Fix stop() to remove the pidfile only when the process ++ is finished. (Closes: #689389) ++ * copyright: Update the source url. ++ * control: Drop quilt from build-depends, since using 3.0 (quilt) ++ * lintian-overrides: Add an override for hardening-no-fortify- ++ functions, since it's a false positive in this case. ++ * control: Drop dpkg-dev from build-depends, no need to specify it ++ directly. ++ * copyright: Add myself as a copyright holder for debian/*. ++ * 389-ds-base.prerm: Add 'set -e'. ++ * rules: drop DEB_HOST_MULTIARCH, dh9 handles it. ++ ++ -- Timo Aaltonen Wed, 03 Oct 2012 19:33:52 +0300 ++ ++389-ds-base (1.2.11.7-5) unstable; urgency=low ++ ++ * control: Drop debconf-utils and po-debconf from build-depends. ++ * control: Add libnetaddr-ip-perl and libsocket-getaddrinfo-perl to ++ 389-ds-base Depends for ipv6 support. (Closes: #682847) ++ ++ -- Timo Aaltonen Mon, 30 Jul 2012 13:12:23 +0200 ++ ++389-ds-base (1.2.11.7-4) unstable; urgency=low ++ ++ * debian/po: Remove, leftover from the template purge. (Closes: #681543) ++ ++ -- Timo Aaltonen Thu, 19 Jul 2012 23:12:01 +0300 ++ ++389-ds-base (1.2.11.7-3) unstable; urgency=low ++ ++ * 389-ds-base.config: Removed, the debconf template is no more. ++ (Closes: #680351) ++ * control: Remove duplicate 'the' from the 389-ds description. ++ ++ -- Timo Aaltonen Wed, 11 Jul 2012 11:59:36 +0300 ++ ++389-ds-base (1.2.11.7-2) unstable; urgency=low ++ ++ * control: Stop hardcoding libs to binary depends. (Closes: #679790) ++ * control: Add libnspr4-dev and libldap2-dev to 389-ds-base-dev ++ Depends. (Closes: #679742) ++ * l10n review (Closes: #679870) : ++ - Drop the debconf template, and rewrap README.Debian. ++ - control: Update the descriptions ++ ++ -- Timo Aaltonen Tue, 03 Jul 2012 17:58:20 +0300 ++ ++389-ds-base (1.2.11.7-1) unstable; urgency=low ++ ++ [ Timo Aaltonen ] ++ * New upstream release. ++ * watch: Fix the url. ++ * patches/remove_license_prompt: Dropped, included upstream. ++ * patches/default_user: Refreshed. ++ * control: Change the VCS header to point to the git repository. ++ * control: Rename last remnants of Fedora to 389. ++ * changelog, control: Be consistent with the naming; renamed the source ++ to just '389-ds-base', which matches upstream tarball naming. ++ * control: Wrap Depends. ++ * compat, control: Bump compat to 9, and debhelper build-dep to (>= 9). ++ * rules: Switch to dh. ++ * Move dirsrv.lintian to dirsrv.lintian-overrides, adjust dirsrv.install. ++ * *.dirs: Clean up. ++ * control: Build-depend on dh-autoreconf, drop duplicate bdeps. ++ * Fold dirsrv-tools into the main package. ++ * Build against libldap2-dev (>= 2.4.28). ++ * Rename binary package to 389-ds-base. ++ * -dev.install: Install the pkgconfig file. ++ * rules: Enable PIE hardening. ++ * Add a default file, currently sets LD_BIND_NOW=1. ++ * control: 'dbgen' uses old perl libs, add libperl4-corelibs-perl ++ dependency to 389-ds-base. ++ * rules: Add --fail-missing for dh_install, remove files not needed ++ and make sure to install the rest. ++ * rules, control: Fix the installation name of ds-logpipe.py, add ++ python dependency to 389-ds-base.. ++ * libns-dshttpd is internal to the server, ship it in 389-ds-base. ++ * Rename libdirsrv{-dev,0} -> 389-ds-base-{dev,libs}, includes only ++ libslapd and headers for external plugin development. ++ * control: Breaks/Replaces old libdirsrv-dev/libdirsrv0/dirsrv. ++ * Drop hyphen_used_as_minus, applied upstream. ++ * copyright: Use DEP5 format. ++ * Cherry-pick upstream commit ee320163c6 to get rid of unnecessary ++ and non-free MIB's from the tree, and build a dfsg compliant tarball. ++ * lintian-overrides: Update, create one for -libs. ++ * Fix the initscript to create the lockdir, and refactor code into separate ++ functions. ++ * Drop obsolete entries from copyright, and make it lintian clean. ++ * debian/po: Refer to the correct file after rename. ++ * control: Bump Standards-Version to 3.9.3, no changes. ++ * postinst: Drop unused 'lastversion'. ++ * patches: Add DEP3 compliant headers. ++ * rules, postinst: Add an error handler function for dh_installinit, so ++ that clean installs don't fail due to missing configuration. ++ * postinst: Run the update tool. ++ * dirsrv.init: ++ - Make the start and stop functions much simpler and LSB compliant ++ - Fix starting multiple instances ++ - Use '-b' for start-stop-daemon, since ns-slapd doesn't detach properly ++ * control: Add 389-ds metapackage. ++ * control: Change libdb4.8-dev build-depends to libdb-dev, since this version ++ supports db5.x. ++ * 389-ds-base.prerm: Add prerm script for removing installed instances on ++ purge. ++ ++ [ Krzysztof Klimonda ] ++ * dirsrv.init: ++ - return 0 code if there are no instances configured and tweak message ++ so it doesn't indicate a failure. ++ ++ -- Krzysztof Klimonda Tue, 27 Mar 2012 14:26:16 +0200 ++ ++389-directory-server (1.2.6.1-5) unstable; urgency=low ++ ++ * Removed db_stop from dirsrv.postinst ++ * Fix short description in libdirsrv0-dbg ++ ++ -- Michele Baldessari Wed, 20 Oct 2010 20:24:20 +0200 ++ ++389-directory-server (1.2.6.1-4) unstable; urgency=low ++ ++ * Make libicu dep dependent on dpkg-vendor ++ ++ -- Michele Baldessari Mon, 18 Oct 2010 21:21:52 +0200 ++ ++389-directory-server (1.2.6.1-3) unstable; urgency=low ++ ++ * Remove dirsrv user and group in postrm ++ * Clean up postrm and postinst ++ ++ -- Michele Baldessari Sun, 17 Oct 2010 21:54:08 +0200 ++ ++389-directory-server (1.2.6.1-2) unstable; urgency=low ++ ++ * Fix QUILT_STAMPFN ++ ++ -- Michele Baldessari Sun, 17 Oct 2010 15:03:34 +0200 ++ ++389-directory-server (1.2.6.1-1) unstable; urgency=low ++ ++ * New upstream ++ ++ -- Michele Baldessari Sat, 16 Oct 2010 23:08:09 +0200 ++ ++389-directory-server (1.2.6-2) unstable; urgency=low ++ ++ * Update my email address ++ ++ -- Michele Baldessari Sat, 16 Oct 2010 22:34:19 +0200 ++ ++389-directory-server (1.2.6-1) unstable; urgency=low ++ ++ * New upstream ++ * s/Fedora/389/g to clean up the branding ++ * Remove automatic configuration (breaks too often with every update) ++ * Remove dirsrv.config translation, no questions are asked anymore ++ * Fix old changelog versions with proper ~ on rc versions ++ * Update policy to 3.9.1 ++ * Improve README.Debian ++ * Depend on libicu44 ++ * Remove /var/run/dirsrv from the postinst scripts (managed by init script) ++ ++ -- Michele Baldessari Sat, 04 Sep 2010 11:58:21 +0200 ++ ++389-directory-server (1.2.6~rc7-1) unstable; urgency=low ++ ++ * New upstream ++ ++ -- Michele Baldessari Fri, 03 Sep 2010 20:06:08 +0200 ++ ++389-directory-server (1.2.6~a3-1) unstable; urgency=low ++ ++ * New upstream ++ * Rename man page remove-ds.pl in remove-ds ++ * Removed Debian.source ++ ++ -- Michele Baldessari Sun, 23 May 2010 22:12:13 +0200 ++ ++389-directory-server (1.2.6~a2-1) unstable; urgency=low ++ ++ * New upstream ++ * Removed speling_fixes patch, applied upstream ++ ++ -- Michele Baldessari Sun, 23 May 2010 13:36:25 +0200 ++ ++389-directory-server (1.2.5-1) unstable; urgency=low ++ ++ * New upstream ++ * Add libpcre3-dev Build-dep ++ * ldap-agent moved ti /usr/sbin ++ * Fix spelling errors in code and manpages ++ * Fix some lintian warnings ++ * Bump policy to 3.8.3 ++ * Ignore lintian warning pkg-has-shlibs-control-file-but-no-actual-shared-libs ++ as the shlibs file is for dirsrv plugins ++ * Upgraded deps to libicu42 and libdb4.8 ++ * Do create /var/lib/dirsrv as dirsrv user's home ++ * Added libsasl2-modules-gssapi-mit as a dependency for dirsrv (needed by ++ mandatory LDAP SASL mechs) ++ * Install all files of etc/dirsrv/config ++ * Add some missing start scripts in usr/sbin ++ * Fixed a bug in the dirsrv.init script ++ * Switch to dpkg-source 3.0 (quilt) format ++ * Bump policy to 3.8.4 ++ ++ -- Michele Baldessari Sun, 23 May 2010 12:31:24 +0200 ++ ++389-directory-server (1.2.1-0) unstable; urgency=low ++ ++ * Rename of source package (note, since this is still staging work no ++ replace or upgrade is in place) ++ * Update watch file ++ * New Upstream ++ ++ -- Michele Baldessari Fri, 12 Jun 2009 22:08:42 +0200 ++ ++fedora-directory-server (1.2.0-1) unstable; urgency=low ++ ++ * New upstream release ++ * Add missing libkrb5-dev dependency ++ * Fix section of -dbg packages ++ * Fix all "dpatch-missing-description" lintian warnings ++ ++ -- Michele Baldessari Wed, 22 Apr 2009 23:36:22 +0200 ++ ++fedora-directory-server (1.1.3-1) unstable; urgency=low ++ ++ * New upstream ++ * Added watch file ++ * Make setup-ds use dirsrv:dirsrv user/group as defaults ++ * Added VCS-* fields ++ * --enable-autobind ++ * Add ldap/servers/plugins/replication/winsync-plugin.h to libdirsrv-dev ++ ++ -- Michele Baldessari Mon, 24 Nov 2008 22:42:26 +0100 ++ ++fedora-directory-server (1.1.2-2) unstable; urgency=low ++ ++ * Fixed build+configure twice issue ++ * Added Conflicts: slapd (thanks Alessandro) ++ ++ -- Michele Baldessari Tue, 23 Sep 2008 21:12:44 +0200 ++ ++fedora-directory-server (1.1.2-1) unstable; urgency=low ++ ++ * New upstream ++ * Removed /usr/sbin PATH from postinst script ++ ++ -- Michele Baldessari Sat, 20 Sep 2008 20:10:52 +0000 ++ ++fedora-directory-server (1.1.1-0) unstable; urgency=low ++ ++ * New upstream ++ * Don't apply patch for 439829, fixed upstream ++ * Bump to policy 3.8.0 ++ * Added README.source ++ ++ -- Michele Baldessari Fri, 22 Aug 2008 00:09:40 +0200 ++ ++fedora-directory-server (1.1.0-4) unstable; urgency=low ++ ++ * dirsrv should depend on libmozilla-ldap-perl (thanks Mathias Kaufmann ++ ) ++ ++ -- Michele Baldessari Sun, 20 Jul 2008 18:41:58 +0200 ++ ++fedora-directory-server (1.1.0-3) unstable; urgency=low ++ ++ * Fix up some descriptions ++ ++ -- Michele Baldessari Sun, 25 May 2008 21:36:32 +0200 ++ ++fedora-directory-server (1.1.0-2) unstable; urgency=low ++ ++ * Silenced init warning messages when chowning pid directory ++ ++ -- Michele Baldessari Wed, 21 May 2008 23:08:32 +0200 ++ ++fedora-directory-server (1.1.0-1) unstable; urgency=low ++ ++ * Removed template lintian warning ++ * Cleaned up manpages ++ ++ -- Michele Baldessari Sun, 18 May 2008 13:39:58 +0200 ++ ++fedora-directory-server (1.1.0-0) unstable; urgency=low ++ ++ * Initial release (Closes: #497098). ++ * Fixed postinst after renaming setup-ds.pl to setup-ds ++ * Applied patch from https://bugzilla.redhat.com/show_bug.cgi?id=439829 to ++ fix segfault against late NSS versions ++ * Switched to parseable copyright format ++ * Source package is lintian clean now ++ * Added initial manpage patch ++ * Switched to dh_install ++ ++ -- Michele Baldessari Thu, 27 Mar 2008 23:56:17 +0200 diff --cc debian/cockpit-389-ds.install index 0000000,0000000..15b5a68 new file mode 100644 --- /dev/null +++ b/debian/cockpit-389-ds.install @@@ -1,0 -1,0 +1,2 @@@ ++usr/share/cockpit/389-console/ ++usr/share/metainfo/389-console/org.cockpit-project.389-console.metainfo.xml diff --cc debian/compat index 0000000,0000000..b4de394 new file mode 100644 --- /dev/null +++ b/debian/compat @@@ -1,0 -1,0 +1,1 @@@ ++11 diff --cc debian/control index 0000000,0000000..416e620 new file mode 100644 --- /dev/null +++ b/debian/control @@@ -1,0 -1,0 +1,191 @@@ ++Source: 389-ds-base ++Section: net ++Priority: optional ++Maintainer: Debian FreeIPA Team ++Uploaders: ++ Timo Aaltonen , ++Build-Depends: ++ libcmocka-dev, ++ debhelper (>= 11), ++ dh-python, ++ doxygen, ++ libbz2-dev, ++ libcrack2-dev, ++ libdb-dev, ++ libevent-dev, ++ libicu-dev, ++ libkrb5-dev, ++ libldap2-dev (>= 2.4.28), ++ libltdl-dev, ++ libnspr4-dev, ++ libnss3-dev, ++ libpam0g-dev, ++ libpci-dev, ++ libpcre3-dev, ++ libperl-dev, ++ libsasl2-dev, ++ libsnmp-dev, ++ libssl-dev, ++ libsystemd-dev, ++ pkg-config, ++ python3-all-dev, ++ python3-argcomplete, ++ python3-argparse-manpage, ++ python3-ldap, ++ python3-selinux, ++ python3-sepolicy, ++ python3-setuptools, ++ python3-six, ++ rsync, ++ zlib1g-dev, ++Standards-Version: 4.1.0 ++Vcs-Git: https://salsa.debian.org/freeipa-team/389-ds-base.git ++Vcs-Browser: https://salsa.debian.org/freeipa-team/389-ds-base.git ++Homepage: http://directory.fedoraproject.org ++ ++Package: 389-ds ++Architecture: all ++Depends: ++ 389-ds-base, ++ cockpit-389-ds, ++ ${misc:Depends}, ++Description: 389 Directory Server suite - metapackage ++ Based on the Lightweight Directory Access Protocol (LDAP), the 389 ++ Directory Server is designed to manage large directories of users and ++ resources robustly and scalably. ++ . ++ This is a metapackage depending on the LDAPv3 server and a Cockpit UI plugin ++ for administration. ++ ++Package: 389-ds-base-libs ++Section: libs ++Architecture: any ++Multi-Arch: same ++Pre-Depends: ${misc:Pre-Depends} ++Depends: ${misc:Depends}, ${shlibs:Depends} ++Breaks: 389-ds-base (<< 1.3.6.7-5), ++ 389-ds-base-dev (<< 1.3.6.7-4), ++ libsvrcore0, ++Replaces: 389-ds-base (<< 1.3.6.7-5), ++ 389-ds-base-dev (<< 1.3.6.7-4), ++ libsvrcore0, ++Description: 389 Directory Server suite - libraries ++ Based on the Lightweight Directory Access Protocol (LDAP), the 389 ++ Directory Server is designed to manage large directories of users and ++ resources robustly and scalably. ++ . ++ This package contains core libraries for the 389 Directory Server. ++ ++Package: 389-ds-base-dev ++Section: libdevel ++Architecture: any ++Multi-Arch: same ++Depends: ++ 389-ds-base-libs (= ${binary:Version}), ++ libldap2-dev, ++ libnspr4-dev, ++ ${misc:Depends}, ++ ${shlibs:Depends}, ++Breaks: 389-ds-base (<< 1.3.6.7-4), ++ libsvrcore-dev, ++Replaces: 389-ds-base (<< 1.3.6.7-4), ++ libsvrcore-dev, ++Provides: ++ libsvrcore-dev, ++Description: 389 Directory Server suite - development files ++ Based on the Lightweight Directory Access Protocol (LDAP), the 389 ++ Directory Server is designed to manage large directories of users and ++ resources robustly and scalably. ++ . ++ This package contains development headers for the core libraries ++ of the 389 Directory Server, useful for developing plugins without ++ having to install the server itself. ++ ++Package: 389-ds-base ++Architecture: any ++Pre-Depends: debconf (>= 0.5) | debconf-2.0 ++Depends: ++ 389-ds-base-libs (= ${binary:Version}), ++ 389-ds-base-legacy-tools (= ${binary:Version}), ++ adduser, ++ acl, ++ ldap-utils, ++ libperl4-corelibs-perl | perl (<< 5.12.3-7), ++ libsasl2-modules-gssapi-mit, ++ python, ++ python3-lib389, ++ python3-selinux, ++ python3-semanage, ++ python3-sepolicy, ++ systemd, ++ ${misc:Depends}, ++ ${shlibs:Depends}, ++ ${python3:Depends}, ++Description: 389 Directory Server suite - server ++ Based on the Lightweight Directory Access Protocol (LDAP), the 389 ++ Directory Server is designed to manage large directories of users and ++ resources robustly and scalably. ++ . ++ Its key features include: ++ * four-way multi-master replication; ++ * great scalability; ++ * extensive documentation; ++ * Active Directory user and group synchronization; ++ * secure authentication and transport; ++ * support for LDAPv3; ++ * graphical management console; ++ * on-line, zero downtime update of schema, configuration, and ++ in-tree Access Control Information. ++ ++Package: 389-ds-base-legacy-tools ++Architecture: any ++Depends: ++ 389-ds-base (= ${binary:Version}), ++ libmozilla-ldap-perl, ++ libnetaddr-ip-perl, ++ libperl4-corelibs-perl | perl (<< 5.12.3-7), ++ libsocket-getaddrinfo-perl, ++ ${misc:Depends}, ++ ${shlibs:Depends}, ++Conflicts: 389-ds-base (<< 1.4.0.20-1) ++Replaces: 389-ds-base (<< 1.4.0.20-1) ++Description: Legacy utilities for 389 Directory Server ++ Legacy (and deprecated) utilities for 389 Directory Server. This includes ++ the old account management and task scripts. These are deprecated in favour of ++ the dscreate, dsctl, dsconf and dsidm tools. ++ ++Package: python3-lib389 ++Architecture: all ++Depends: ${misc:Depends}, ${python3:Depends}, ++ python3-argcomplete, ++ python3-dateutil, ++ python3-ldap, ++ python3-pyasn1, ++ python3-pyasn1-modules, ++ python3-pytest, ++ python3-six, ++Conflicts: python-lib389 (<< 1.3.7.8), ++ 389-ds-base (<< 1.4.0.18-1~), ++Replaces: python-lib389 (<< 1.3.7.8), ++ 389-ds-base (<< 1.4.0.18-1~), ++Description: Python3 module for accessing and configuring the 389 Directory Server ++ This Python3 module contains tools and libraries for accessing, testing, ++ and configuring the 389 Directory Server. ++ ++Package: cockpit-389-ds ++Architecture: all ++Multi-Arch: foreign ++Depends: ${misc:Depends}, ++ cockpit, ++ libjs-bootstrap, ++ libjs-c3, ++ libjs-d3, ++ libjs-jquery-datatables, ++ libjs-jquery-datatables-extensions, ++ libjs-jquery-jstree, ++ libjs-moment, ++ python3, ++ python3-lib389, ++Description: Cockpit user interface for 389 Directory Server ++ This package includes a Cockpit UI plugin for configuring and administering ++ the 389 Directory Server. diff --cc debian/copyright index 0000000,0000000..0857600 new file mode 100644 --- /dev/null +++ b/debian/copyright @@@ -1,0 -1,0 +1,658 @@@ ++Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ ++Upstream-name: 389-ds-base ++Source: http://directory.fedoraproject.org/wiki/Source ++ ++Files: * ++Copyright: 2001 Sun Microsystems, Inc. ++ 2005 Red Hat, Inc. ++License: GPL-3+ and Other ++ ++Files: ldap/libraries/libavl/*.[ch] ldap/servers/slapd/abandon.c ++ ldap/servers/slapd/add.c ldap/servers/slapd/abandon.c ++ ldap/servers/slapd/add.c ldap/servers/slapd/bind.c ++ ldap/servers/slapd/bulk_import.c ldap/servers/slapd/compare.c ++ ldap/servers/slapd/delete.c ldap/servers/slapd/detach.c ++ ldap/servers/slapd/globals.c ldap/servers/slapd/modify.c ++ ldap/servers/slapd/modrdn.c ldap/servers/slapd/monitor.c ++ ldap/servers/slapd/search.c ldap/servers/slapd/unbind.c ++Copyright: 1993 Regents of the University of Michigan ++ 2001 Sun Microsystems, Inc. ++ 2005 Red Hat, Inc. ++License: GPL-3+ and Other ++ ++Files: ldap/servers/slapd/tools/ldaptool.h ++Copyright: 1998 Netscape Communication Corporation ++License: GPL-2+ or LGPL-2.1 or MPL-1.1 ++ ++Files: ldap/servers/slapd/tools/ldaptool-sasl.c ++ ldap/servers/slapd/tools/ldaptool-sasl.h ++Copyright: 2005 Sun Microsystems, Inc. ++License: GPL-2+ or LGPL-2.1 or MPL-1.1 ++ ++Files: m4/* ++Copyright: 2006-2017 Red Hat, Inc. ++ 2016 William Brown ++License: GPL-3+ ++ ++Files: src/svrcore/* ++Copyright: 2016 Red Hat, Inc. ++License: MPL-2.0 ++ ++Files: src/cockpit/389-console/static/bootpopup.min.js ++ debian/missing-sources/bootpopup.js ++Copyright: 2016 rigon ++License: GPL-3+ ++ ++Files: src/cockpit/389-console/static/bootstrap.min.js ++ debian/missing-sources/bootstrap.js ++Copyright: 2011-2016 Twitter, Inc. ++License: MIT ++ ++Files: src/cockpit/389-console/static/c3.min.js ++ debian/missing-sources/c3.js ++Copyright: 2013 Masayuki Tanaka ++License: MIT ++ ++Files: src/cockpit/389-console/static/d3.min.js ++ debian/missing-sources/d3.js ++Copyright: 2018 Mike Bostock ++License: BSD-3-clause ++ ++Files: src/cockpit/389-console/static/d3.min.js ++ debian/missing-sources/d3.js ++Copyright: 2018 Mike Bostock ++License: BSD-3-clause ++ ++Files: src/cockpit/389-console/static/jquery-3.3.1.min.js ++ src/cockpit/389-console/static/jquery.min.js ++ src/cockpit/389-console/static/jquery-ui.min.js ++ src/cockpit/389-console/static/moment.min.js ++ debian/missing-sources/jquery-1.12.4.js ++ debian/missing-sources/jquery-3.3.1.js ++ debian/missing-sources/jquery-ui.js ++ debian/missing-sources/moment.js ++Copyright: 2015-2018 JS Foundation and other contributors ++License: MIT ++ ++Files: src/cockpit/389-console/static/jquery.dataTables*.min.js ++ debian/missing-sources/jquery.dataTables*.js ++Copyright: 2008-2017 SpryMedia Ltd ++License: MIT ++ ++Files: src/cockpit/389-console/static/jquery.dropdown.min.js ++ debian/missing-sources/jquery.dropdown.js ++Copyright: 2018 A Beautiful Site, LLC ++License: MIT ++ ++Files: src/cockpit/389-console/static/jquery.timepicker.min.js ++ debian/missing-sources/jquery.timepicker.js ++Copyright: 2015 Jon Thornton ++License: MIT ++ ++Files: src/cockpit/389-console/static/jstree.min.js ++ debian/missing-sources/jstree.js ++Copyright: 2014 Ivan Bozhanov ++License: MIT ++ ++Files: src/cockpit/389-console/static/patternfly.min.js ++ debian/missing-sources/patternfly.js ++Copyright: 2013 Red Hat, Inc. ++License: Apache-2.0 ++ ++Files: debian/* ++Copyright: 2008 Michele Baldessari ++ 2012 Timo Aaltonen ++License: GPL-2+ or LGPL-2.1 or MPL-1.1 ++ ++License: Apache-2.0 ++ On Debian machines the full text of the Apache License 2.0 can be found in the ++ file /usr/share/common-licenses/Apache-2.0. ++ ++License: Other ++ In addition, as a special exception, Red Hat, Inc. gives You the additional ++ right to link the code of this Program with code not covered under the GNU ++ General Public License ("Non-GPL Code") and to distribute linked combinations ++ including the two, subject to the limitations in this paragraph. Non-GPL Code ++ permitted under this exception must only link to the code of this Program ++ through those well defined interfaces identified in the file named EXCEPTION ++ found in the source code files (the "Approved Interfaces"). The files of ++ Non-GPL Code may instantiate templates or use macros or inline functions from ++ the Approved Interfaces without causing the resulting work to be covered by ++ the GNU General Public License. Only Red Hat, Inc. may make changes or ++ additions to the list of Approved Interfaces. You must obey the GNU General ++ Public License in all respects for all of the Program code and other code used ++ in conjunction with the Program except the Non-GPL Code covered by this ++ exception. If you modify this file, you may extend this exception to your ++ version of the file, but you are not obligated to do so. If you do not wish to ++ provide this exception without modification, you must delete this exception ++ statement from your version and license this file solely under the GPL without ++ exception. ++ ++License: BSD-3-clause ++ 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 Dojo Foundation nor the names of its contributors ++ may be used to endorse or promote products derived from this software ++ without specific prior written permission. ++ . ++ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ++ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ++ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE ++ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ++ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ++ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ ++ ++License: GPL-2 or GPL-2+ ++ On Debian machines the full text of the GNU General Public License ++ can be found in the file /usr/share/common-licenses/GPL-2. ++ ++License: GPL-3+ ++ On Debian machines the full text of the GNU General Public License v3 ++ can be found in the file /usr/share/common-licenses/GPL-3. ++ ++License: LGPL-2.1 ++ On Debian machines the full text of the GNU General Public License ++ can be found in the file /usr/share/common-licenses/LGPL-2.1. ++ ++License: MIT ++ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and ++ associated documentation files (the "Software"), to deal in the Software without restriction, including ++ without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the ++ following conditions: ++ . ++ The above copyright notice and this permission notice shall be included in all copies or substantial ++ portions of the Software. ++ . ++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT ++ LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO ++ EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ++ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR ++ THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ ++ ++License: MPL-1.1 ++ MOZILLA PUBLIC LICENSE ++ Version 1.1 ++ . ++ --------------- ++ . ++ 1. Definitions. ++ . ++ 1.0.1. "Commercial Use" means distribution or otherwise making the ++ Covered Code available to a third party. ++ . ++ 1.1. "Contributor" means each entity that creates or contributes to ++ the creation of Modifications. ++ . ++ 1.2. "Contributor Version" means the combination of the Original ++ Code, prior Modifications used by a Contributor, and the Modifications ++ made by that particular Contributor. ++ . ++ 1.3. "Covered Code" means the Original Code or Modifications or the ++ combination of the Original Code and Modifications, in each case ++ including portions thereof. ++ . ++ 1.4. "Electronic Distribution Mechanism" means a mechanism generally ++ accepted in the software development community for the electronic ++ transfer of data. ++ . ++ 1.5. "Executable" means Covered Code in any form other than Source ++ Code. ++ . ++ 1.6. "Initial Developer" means the individual or entity identified ++ as the Initial Developer in the Source Code notice required by Exhibit ++ A. ++ . ++ 1.7. "Larger Work" means a work which combines Covered Code or ++ portions thereof with code not governed by the terms of this License. ++ . ++ 1.8. "License" means this document. ++ . ++ 1.8.1. "Licensable" means having the right to grant, to the maximum ++ extent possible, whether at the time of the initial grant or ++ subsequently acquired, any and all of the rights conveyed herein. ++ . ++ 1.9. "Modifications" means any addition to or deletion from the ++ substance or structure of either the Original Code or any previous ++ Modifications. When Covered Code is released as a series of files, a ++ Modification is: ++ A. Any addition to or deletion from the contents of a file ++ containing Original Code or previous Modifications. ++ . ++ B. Any new file that contains any part of the Original Code or ++ previous Modifications. ++ . ++ 1.10. "Original Code" means Source Code of computer software code ++ which is described in the Source Code notice required by Exhibit A as ++ Original Code, and which, at the time of its release under this ++ License is not already Covered Code governed by this License. ++ . ++ 1.10.1. "Patent Claims" means any patent claim(s), now owned or ++ hereafter acquired, including without limitation, method, process, ++ and apparatus claims, in any patent Licensable by grantor. ++ . ++ 1.11. "Source Code" means the preferred form of the Covered Code for ++ making modifications to it, including all modules it contains, plus ++ any associated interface definition files, scripts used to control ++ compilation and installation of an Executable, or source code ++ differential comparisons against either the Original Code or another ++ well known, available Covered Code of the Contributor's choice. The ++ Source Code can be in a compressed or archival form, provided the ++ appropriate decompression or de-archiving software is widely available ++ for no charge. ++ . ++ 1.12. "You" (or "Your") means an individual or a legal entity ++ exercising rights under, and complying with all of the terms of, this ++ License or a future version of this License issued under Section 6.1. ++ For legal entities, "You" includes any entity which controls, is ++ controlled by, or is under common control with You. For purposes of ++ this definition, "control" means (a) the power, direct or indirect, ++ to cause the direction or management of such entity, whether by ++ contract or otherwise, or (b) ownership of more than fifty percent ++ (50%) of the outstanding shares or beneficial ownership of such ++ entity. ++ . ++ 2. Source Code License. ++ . ++ 2.1. The Initial Developer Grant. ++ The Initial Developer hereby grants You a world-wide, royalty-free, ++ non-exclusive license, subject to third party intellectual property ++ claims: ++ (a) under intellectual property rights (other than patent or ++ trademark) Licensable by Initial Developer to use, reproduce, ++ modify, display, perform, sublicense and distribute the Original ++ Code (or portions thereof) with or without Modifications, and/or ++ as part of a Larger Work; and ++ . ++ (b) under Patents Claims infringed by the making, using or ++ selling of Original Code, to make, have made, use, practice, ++ sell, and offer for sale, and/or otherwise dispose of the ++ Original Code (or portions thereof). ++ . ++ (c) the licenses granted in this Section 2.1(a) and (b) are ++ effective on the date Initial Developer first distributes ++ Original Code under the terms of this License. ++ . ++ (d) Notwithstanding Section 2.1(b) above, no patent license is ++ granted: 1) for code that You delete from the Original Code; 2) ++ separate from the Original Code; or 3) for infringements caused ++ by: i) the modification of the Original Code or ii) the ++ combination of the Original Code with other software or devices. ++ . ++ 2.2. Contributor Grant. ++ Subject to third party intellectual property claims, each Contributor ++ hereby grants You a world-wide, royalty-free, non-exclusive license ++ . ++ (a) under intellectual property rights (other than patent or ++ trademark) Licensable by Contributor, to use, reproduce, modify, ++ display, perform, sublicense and distribute the Modifications ++ created by such Contributor (or portions thereof) either on an ++ unmodified basis, with other Modifications, as Covered Code ++ and/or as part of a Larger Work; and ++ . ++ (b) under Patent Claims infringed by the making, using, or ++ selling of Modifications made by that Contributor either alone ++ and/or in combination with its Contributor Version (or portions ++ of such combination), to make, use, sell, offer for sale, have ++ made, and/or otherwise dispose of: 1) Modifications made by that ++ Contributor (or portions thereof); and 2) the combination of ++ Modifications made by that Contributor with its Contributor ++ Version (or portions of such combination). ++ . ++ (c) the licenses granted in Sections 2.2(a) and 2.2(b) are ++ effective on the date Contributor first makes Commercial Use of ++ the Covered Code. ++ . ++ (d) Notwithstanding Section 2.2(b) above, no patent license is ++ granted: 1) for any code that Contributor has deleted from the ++ Contributor Version; 2) separate from the Contributor Version; ++ 3) for infringements caused by: i) third party modifications of ++ Contributor Version or ii) the combination of Modifications made ++ by that Contributor with other software (except as part of the ++ Contributor Version) or other devices; or 4) under Patent Claims ++ infringed by Covered Code in the absence of Modifications made by ++ that Contributor. ++ . ++ 3. Distribution Obligations. ++ . ++ 3.1. Application of License. ++ The Modifications which You create or to which You contribute are ++ governed by the terms of this License, including without limitation ++ Section 2.2. The Source Code version of Covered Code may be ++ distributed only under the terms of this License or a future version ++ of this License released under Section 6.1, and You must include a ++ copy of this License with every copy of the Source Code You ++ distribute. You may not offer or impose any terms on any Source Code ++ version that alters or restricts the applicable version of this ++ License or the recipients' rights hereunder. However, You may include ++ an additional document offering the additional rights described in ++ Section 3.5. ++ . ++ 3.2. Availability of Source Code. ++ Any Modification which You create or to which You contribute must be ++ made available in Source Code form under the terms of this License ++ either on the same media as an Executable version or via an accepted ++ Electronic Distribution Mechanism to anyone to whom you made an ++ Executable version available; and if made available via Electronic ++ Distribution Mechanism, must remain available for at least twelve (12) ++ months after the date it initially became available, or at least six ++ (6) months after a subsequent version of that particular Modification ++ has been made available to such recipients. You are responsible for ++ ensuring that the Source Code version remains available even if the ++ Electronic Distribution Mechanism is maintained by a third party. ++ . ++ 3.3. Description of Modifications. ++ You must cause all Covered Code to which You contribute to contain a ++ file documenting the changes You made to create that Covered Code and ++ the date of any change. You must include a prominent statement that ++ the Modification is derived, directly or indirectly, from Original ++ Code provided by the Initial Developer and including the name of the ++ Initial Developer in (a) the Source Code, and (b) in any notice in an ++ Executable version or related documentation in which You describe the ++ origin or ownership of the Covered Code. ++ . ++ 3.4. Intellectual Property Matters ++ (a) Third Party Claims. ++ If Contributor has knowledge that a license under a third party's ++ intellectual property rights is required to exercise the rights ++ granted by such Contributor under Sections 2.1 or 2.2, ++ Contributor must include a text file with the Source Code ++ distribution titled "LEGAL" which describes the claim and the ++ party making the claim in sufficient detail that a recipient will ++ know whom to contact. If Contributor obtains such knowledge after ++ the Modification is made available as described in Section 3.2, ++ Contributor shall promptly modify the LEGAL file in all copies ++ Contributor makes available thereafter and shall take other steps ++ (such as notifying appropriate mailing lists or newsgroups) ++ reasonably calculated to inform those who received the Covered ++ Code that new knowledge has been obtained. ++ . ++ (b) Contributor APIs. ++ If Contributor's Modifications include an application programming ++ interface and Contributor has knowledge of patent licenses which ++ are reasonably necessary to implement that API, Contributor must ++ also include this information in the LEGAL file. ++ . ++ (c) Representations. ++ Contributor represents that, except as disclosed pursuant to ++ Section 3.4(a) above, Contributor believes that Contributor's ++ Modifications are Contributor's original creation(s) and/or ++ Contributor has sufficient rights to grant the rights conveyed by ++ this License. ++ . ++ 3.5. Required Notices. ++ You must duplicate the notice in Exhibit A in each file of the Source ++ Code. If it is not possible to put such notice in a particular Source ++ Code file due to its structure, then You must include such notice in a ++ location (such as a relevant directory) where a user would be likely ++ to look for such a notice. If You created one or more Modification(s) ++ You may add your name as a Contributor to the notice described in ++ Exhibit A. You must also duplicate this License in any documentation ++ for the Source Code where You describe recipients' rights or ownership ++ rights relating to Covered Code. You may choose to offer, and to ++ charge a fee for, warranty, support, indemnity or liability ++ obligations to one or more recipients of Covered Code. However, You ++ may do so only on Your own behalf, and not on behalf of the Initial ++ Developer or any Contributor. You must make it absolutely clear than ++ any such warranty, support, indemnity or liability obligation is ++ offered by You alone, and You hereby agree to indemnify the Initial ++ Developer and every Contributor for any liability incurred by the ++ Initial Developer or such Contributor as a result of warranty, ++ support, indemnity or liability terms You offer. ++ . ++ 3.6. Distribution of Executable Versions. ++ You may distribute Covered Code in Executable form only if the ++ requirements of Section 3.1-3.5 have been met for that Covered Code, ++ and if You include a notice stating that the Source Code version of ++ the Covered Code is available under the terms of this License, ++ including a description of how and where You have fulfilled the ++ obligations of Section 3.2. The notice must be conspicuously included ++ in any notice in an Executable version, related documentation or ++ collateral in which You describe recipients' rights relating to the ++ Covered Code. You may distribute the Executable version of Covered ++ Code or ownership rights under a license of Your choice, which may ++ contain terms different from this License, provided that You are in ++ compliance with the terms of this License and that the license for the ++ Executable version does not attempt to limit or alter the recipient's ++ rights in the Source Code version from the rights set forth in this ++ License. If You distribute the Executable version under a different ++ license You must make it absolutely clear that any terms which differ ++ from this License are offered by You alone, not by the Initial ++ Developer or any Contributor. You hereby agree to indemnify the ++ Initial Developer and every Contributor for any liability incurred by ++ the Initial Developer or such Contributor as a result of any such ++ terms You offer. ++ . ++ 3.7. Larger Works. ++ You may create a Larger Work by combining Covered Code with other code ++ not governed by the terms of this License and distribute the Larger ++ Work as a single product. In such a case, You must make sure the ++ requirements of this License are fulfilled for the Covered Code. ++ . ++ 4. Inability to Comply Due to Statute or Regulation. ++ . ++ If it is impossible for You to comply with any of the terms of this ++ License with respect to some or all of the Covered Code due to ++ statute, judicial order, or regulation then You must: (a) comply with ++ the terms of this License to the maximum extent possible; and (b) ++ describe the limitations and the code they affect. Such description ++ must be included in the LEGAL file described in Section 3.4 and must ++ be included with all distributions of the Source Code. Except to the ++ extent prohibited by statute or regulation, such description must be ++ sufficiently detailed for a recipient of ordinary skill to be able to ++ understand it. ++ . ++ 5. Application of this License. ++ . ++ This License applies to code to which the Initial Developer has ++ attached the notice in Exhibit A and to related Covered Code. ++ . ++ 6. Versions of the License. ++ . ++ 6.1. New Versions. ++ Netscape Communications Corporation ("Netscape") may publish revised ++ and/or new versions of the License from time to time. Each version ++ will be given a distinguishing version number. ++ . ++ 6.2. Effect of New Versions. ++ Once Covered Code has been published under a particular version of the ++ License, You may always continue to use it under the terms of that ++ version. You may also choose to use such Covered Code under the terms ++ of any subsequent version of the License published by Netscape. No one ++ other than Netscape has the right to modify the terms applicable to ++ Covered Code created under this License. ++ . ++ 6.3. Derivative Works. ++ If You create or use a modified version of this License (which you may ++ only do in order to apply it to code which is not already Covered Code ++ governed by this License), You must (a) rename Your license so that ++ the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", ++ "MPL", "NPL" or any confusingly similar phrase do not appear in your ++ license (except to note that your license differs from this License) ++ and (b) otherwise make it clear that Your version of the license ++ contains terms which differ from the Mozilla Public License and ++ Netscape Public License. (Filling in the name of the Initial ++ Developer, Original Code or Contributor in the notice described in ++ Exhibit A shall not of themselves be deemed to be modifications of ++ this License.) ++ . ++ 7. DISCLAIMER OF WARRANTY. ++ . ++ COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, ++ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, ++ WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF ++ DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. ++ THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE ++ IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, ++ YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE ++ COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER ++ OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ++ ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. ++ . ++ 8. TERMINATION. ++ . ++ 8.1. This License and the rights granted hereunder will terminate ++ automatically if You fail to comply with terms herein and fail to cure ++ such breach within 30 days of becoming aware of the breach. All ++ sublicenses to the Covered Code which are properly granted shall ++ survive any termination of this License. Provisions which, by their ++ nature, must remain in effect beyond the termination of this License ++ shall survive. ++ . ++ 8.2. If You initiate litigation by asserting a patent infringement ++ claim (excluding declatory judgment actions) against Initial Developer ++ or a Contributor (the Initial Developer or Contributor against whom ++ You file such action is referred to as "Participant") alleging that: ++ . ++ (a) such Participant's Contributor Version directly or indirectly ++ infringes any patent, then any and all rights granted by such ++ Participant to You under Sections 2.1 and/or 2.2 of this License ++ shall, upon 60 days notice from Participant terminate prospectively, ++ unless if within 60 days after receipt of notice You either: (i) ++ agree in writing to pay Participant a mutually agreeable reasonable ++ royalty for Your past and future use of Modifications made by such ++ Participant, or (ii) withdraw Your litigation claim with respect to ++ the Contributor Version against such Participant. If within 60 days ++ of notice, a reasonable royalty and payment arrangement are not ++ mutually agreed upon in writing by the parties or the litigation claim ++ is not withdrawn, the rights granted by Participant to You under ++ Sections 2.1 and/or 2.2 automatically terminate at the expiration of ++ the 60 day notice period specified above. ++ . ++ (b) any software, hardware, or device, other than such Participant's ++ Contributor Version, directly or indirectly infringes any patent, then ++ any rights granted to You by such Participant under Sections 2.1(b) ++ and 2.2(b) are revoked effective as of the date You first made, used, ++ sold, distributed, or had made, Modifications made by that ++ Participant. ++ . ++ 8.3. If You assert a patent infringement claim against Participant ++ alleging that such Participant's Contributor Version directly or ++ indirectly infringes any patent where such claim is resolved (such as ++ by license or settlement) prior to the initiation of patent ++ infringement litigation, then the reasonable value of the licenses ++ granted by such Participant under Sections 2.1 or 2.2 shall be taken ++ into account in determining the amount or value of any payment or ++ license. ++ . ++ 8.4. In the event of termination under Sections 8.1 or 8.2 above, ++ all end user license agreements (excluding distributors and resellers) ++ which have been validly granted by You or any distributor hereunder ++ prior to termination shall survive termination. ++ . ++ 9. LIMITATION OF LIABILITY. ++ . ++ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT ++ (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL ++ DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, ++ OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ++ ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY ++ CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, ++ WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER ++ COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN ++ INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF ++ LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY ++ RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW ++ PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE ++ EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO ++ THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. ++ . ++ 10. U.S. GOVERNMENT END USERS. ++ . ++ The Covered Code is a "commercial item," as that term is defined in ++ 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer ++ software" and "commercial computer software documentation," as such ++ terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 ++ C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), ++ all U.S. Government End Users acquire Covered Code with only those ++ rights set forth herein. ++ . ++ 11. MISCELLANEOUS. ++ . ++ This License represents the complete agreement concerning subject ++ matter hereof. If any provision of this License is held to be ++ unenforceable, such provision shall be reformed only to the extent ++ necessary to make it enforceable. This License shall be governed by ++ California law provisions (except to the extent applicable law, if ++ any, provides otherwise), excluding its conflict-of-law provisions. ++ With respect to disputes in which at least one party is a citizen of, ++ or an entity chartered or registered to do business in the United ++ States of America, any litigation relating to this License shall be ++ subject to the jurisdiction of the Federal Courts of the Northern ++ District of California, with venue lying in Santa Clara County, ++ California, with the losing party responsible for costs, including ++ without limitation, court costs and reasonable attorneys' fees and ++ expenses. The application of the United Nations Convention on ++ Contracts for the International Sale of Goods is expressly excluded. ++ Any law or regulation which provides that the language of a contract ++ shall be construed against the drafter shall not apply to this ++ License. ++ . ++ 12. RESPONSIBILITY FOR CLAIMS. ++ . ++ As between Initial Developer and the Contributors, each party is ++ responsible for claims and damages arising, directly or indirectly, ++ out of its utilization of rights under this License and You agree to ++ work with Initial Developer and Contributors to distribute such ++ responsibility on an equitable basis. Nothing herein is intended or ++ shall be deemed to constitute any admission of liability. ++ . ++ 13. MULTIPLE-LICENSED CODE. ++ . ++ Initial Developer may designate portions of the Covered Code as ++ "Multiple-Licensed". "Multiple-Licensed" means that the Initial ++ Developer permits you to utilize portions of the Covered Code under ++ Your choice of the NPL or the alternative licenses, if any, specified ++ by the Initial Developer in the file described in Exhibit A. ++ . ++ EXHIBIT A -Mozilla Public License. ++ . ++ ``The contents of this file are subject to the Mozilla Public License ++ Version 1.1 (the "License"); you may not use this file except in ++ compliance with the License. You may obtain a copy of the License at ++ http://www.mozilla.org/MPL/ ++ . ++ Software distributed under the License is distributed on an "AS IS" ++ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the ++ License for the specific language governing rights and limitations ++ under the License. ++ . ++ The Original Code is ______________________________________. ++ . ++ The Initial Developer of the Original Code is ________________________. ++ Portions created by ______________________ are Copyright (C) ______ ++ _______________________. All Rights Reserved. ++ . ++ Contributor(s): ______________________________________. ++ . ++ Alternatively, the contents of this file may be used under the terms ++ of the _____ license (the "[___] License"), in which case the ++ provisions of [______] License are applicable instead of those ++ above. If you wish to allow use of your version of this file only ++ under the terms of the [____] License and not to allow others to use ++ your version of this file under the MPL, indicate your decision by ++ deleting the provisions above and replace them with the notice and ++ other provisions required by the [___] License. If you do not delete ++ the provisions above, a recipient may use your version of this file ++ under either the MPL or the [___] License." ++ . ++ [NOTE: The text of this Exhibit A may differ slightly from the text of ++ the notices in the Source Code files of the Original Code. You should ++ use the text of this Exhibit A rather than the text found in the ++ Original Code Source Code for Your Modifications.] ++ ++License: MPL-2.0 ++ On Debian machines the full text of the Mozilla Public License version 2.0 ++ can be found in the file /usr/share/common-licenses/MPL-2.0. diff --cc debian/missing-sources/bootpopup.js index 0000000,0000000..404337a new file mode 100644 --- /dev/null +++ b/debian/missing-sources/bootpopup.js @@@ -1,0 -1,0 +1,429 @@@ ++/************************************************************************** ++ * Popup dialog boxes for Bootstrap - http://www.bootpopup.tk ++ * Copyright (C) 2016 rigon ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ *************************************************************************/ ++ ++ ++/* // List of input types ++case "button": case "checkbox": case "color": case "date": case "datetime-local": ++case "email": case "file": case "hidden": case "image": case "month": case "number": ++case "password": case "radio": case "range": case "reset": case "search": ++case "submit": case "tel": case "text": case "time": case "url": case "week": */ ++var INPUT_SHORTCUT_TYPES = [ "button", "text", "submit", "color", "url", "password", ++ "hidden", "file", "number", "email", "reset", "date", "checkbox", "select", "radio" ]; ++ ++ ++function bootpopup(options) { ++ // Create a new instance if this is not ++ if(!(this instanceof bootpopup)) ++ return new bootpopup(options); ++ ++ var self = this; ++ // Create a global random ID for the form ++ this.formid = "bootpopup-form" + String(Math.random()).substr(2); ++ ++ this.options = { ++ title: document.title, ++ showclose: true, ++ size: "normal", ++ size_labels: "col-sm-4", ++ size_inputs: "col-sm-8", ++ content: [], ++ onsubmit: "close", ++ buttons: ["close"], ++ ++ before: function() {}, ++ dismiss: function() {}, ++ close: function() {}, ++ ok: function() {}, ++ cancel: function() {}, ++ yes: function() {}, ++ no: function() {}, ++ complete: function() {}, ++ submit: function(e) { ++ self.callback(self.options.onsubmit, e); ++ return false; // Cancel form submision ++ } ++ }; ++ ++ this.addOptions = function(options) { ++ var buttons = []; ++ for(var key in options) { ++ if(key in this.options) ++ this.options[key] = options[key]; ++ // If an event for a button is given, show the respective button ++ if(["close", "ok", "cancel", "yes", "no"].indexOf(key) >= 0) ++ buttons.push(key); ++ } ++ // Copy news buttons to this.options.buttons ++ if(buttons.length > 0) { ++ // Clear default buttons if new are not given ++ if(!("buttons" in options)) this.options.buttons = []; ++ buttons.forEach(function(item) { ++ if(self.options.buttons.indexOf(item) < 0) ++ self.options.buttons.push(item); ++ }); ++ } ++ // Determine what is the best action if none is given ++ if(typeof options.onsubmit !== "string") { ++ if(this.options.buttons.indexOf("close") > 0) this.options.onsubmit = "close"; ++ else if(this.options.buttons.indexOf("ok") > 0) this.options.onsubmit = "ok"; ++ else if(this.options.buttons.indexOf("yes") > 0) this.options.onsubmit = "yes"; ++ } ++ ++ return this.options; ++ }; ++ ++ this.setOptions = function(options) { ++ this.options = options; ++ return this.options; ++ }; ++ ++ this.create = function() { ++ // Option for modal dialog size ++ var classModalDialog = "modal-dialog"; ++ if(this.options.size == "large") classModalDialog += " modal-lg"; ++ if(this.options.size == "small") classModalDialog += " modal-sm"; ++ ++ // Create HTML elements for modal dialog ++ this.modal = $(''); ++ this.dialog = $('
', { class: classModalDialog, role: "document" }); ++ this.content = $(''); ++ this.dialog.append(this.content); ++ this.modal.append(this.dialog); ++ ++ // Header ++ this.header = $(''); ++ if(this.options.showclose) // Close button ++ this.header.append(''); ++ this.header.append(''); ++ this.content.append(this.header); ++ ++ // Body ++ this.body = $(''); ++ this.form = $("
", { id: this.formid, class: "form-horizontal", submit: function(e) { return self.options.submit(e); } }); ++ this.body.append(this.form); ++ this.content.append(this.body); ++ ++ // Iterate over entries ++ for(var i in this.options.content) { ++ var entry = this.options.content[i]; ++ switch(typeof entry) { ++ case "string": // HTML string ++ this.form.append(entry); ++ break; ++ case "object": ++ for(var type in entry) { ++ var attrs = entry[type]; ++ ++ // Convert functions to string to be used as callback ++ for(var attribute in attrs) ++ if(typeof attrs[attribute] === "function") ++ attrs[attribute] = "(" + attrs[attribute] + ")(this)"; ++ ++ // Check if type is a shortcut for input ++ if(INPUT_SHORTCUT_TYPES.indexOf(type) >= 0) { ++ attrs.type = type; // Add attribute for type ++ type = "input"; // Continue to input ++ } ++ ++ if(type == "input") { ++ // To avoid adding "form-control" class ++ if(attrs.type === "checkbox" && typeof attrs.class === "undefined") ++ attrs.class = ""; ++ ++ // Create a random id for the input if none provided ++ attrs.id = (typeof attrs.id === "undefined" ? "bootpopup-input" + String(Math.random()).substr(2) : attrs.id); ++ attrs.class = (typeof attrs.class === "undefined" ? "form-control" : attrs.class); ++ attrs.type = (typeof attrs.type === "undefined" ? "text" : attrs.type); ++ ++ ++ // Create input ++ var input; ++ switch(attrs.type) { ++ case "checkbox": ++ // Special case for checkbox ++ input = $('
') ++ .append($('') ++ .append($("", attrs)) ++ .append(attrs.label)); ++ ++ // Clear label to not be added as header ++ attrs.label = ""; ++ break; ++ case "select": ++ // Special case for select ++ input = $("", attrs); ++ for(var option in attrs.options) ++ input.append($("", { value: option }) ++ .append(attrs.options[option])); ++ ++ break; ++ case "radio": ++ // Special case for radios ++ input = []; ++ for(var option in attrs.options) ++ input.push($('
', attrs) ++ .append($('') ++ .append($("", { type: "radio", name: attrs.name, value: option })) ++ .append(attrs.options[option]))); ++ break; ++ default: ++ input = $("", attrs); ++ } ++ ++ // Form Group ++ var formGroup = $('
').appendTo(this.form); ++ // Label ++ $("", { for: attrs.id, class: "control-label " + this.options.size_labels, text: attrs.label }).appendTo(formGroup); ++ ++ // Input and div to control width ++ var divInput = $('
', { class: this.options.size_inputs }); ++ divInput.append(input); ++ formGroup.append(divInput); ++ } ++ else // Anything else besides input ++ this.form.append($("<" + type + ">", attrs)); // Add directly ++ } ++ break; ++ default: ++ throw "Invalid entry type"; ++ } ++ } ++ ++ // Footer ++ this.footer = $(''); ++ this.content.append(this.footer); ++ ++ for(var key in this.options.buttons) { ++ var item = this.options.buttons[key]; ++ var btnClass = ""; ++ var btnText = ""; ++ ++ switch(item) { ++ case "close": btnClass = "btn-primary"; btnText = "Close"; break; ++ case "ok": btnClass = "btn-primary"; btnText = "OK"; break; ++ case "cancel": btnClass = "btn-default"; btnText = "Cancel"; break; ++ case "yes": btnClass = "btn-primary"; btnText = "Yes"; break; ++ case "no": btnClass = "btn-default"; btnText = "No"; break; ++ } ++ ++ var button = $("", { ++ type: "button", ++ text: btnText, ++ class: "btn " + btnClass, ++ "data-dismiss": "modal", ++ "data-callback": item, ++ "data-form": this.formid, ++ ++ click: function(event) { ++ var name = $(event.target).data("callback"); ++ self.callback(name, event); ++ } ++ }); ++ this.footer.append(button); ++ ++ // Reference for buttons ++ switch(item) { ++ case "close": this.btnClose = button; break; ++ case "ok": this.btnOk = button; break; ++ case "cancel": this.btnCancel = button; break; ++ case "yes": this.btnYes = button; break; ++ case "no": this.btnNo = button; break; ++ } ++ } ++ ++ // Setup events for dismiss and complete ++ this.modal.on('hide.bs.modal', this.options.dismiss); ++ this.modal.on('hidden.bs.modal', function(e) { ++ self.options.complete(e); ++ self.modal.remove(); // Delete window after complete ++ }); ++ ++ // Don't close on backdrop click ++ if(this.options.showclose === false) ++ this.modal.attr('data-backdrop', 'static'); ++ ++ // Add window to body ++ $(document.body).append(this.modal); ++ }; ++ ++ this.show = function() { ++ // Call before event ++ this.options.before(this); ++ ++ // Fire the modal window ++ this.modal.modal(); ++ }; ++ ++ this.data = function() { ++ var keyval = {}; ++ var array = this.form.serializeArray(); ++ for(var i in array) { ++ var name = array[i].name, val = array[i].value; ++ ++ if(typeof keyval[name] === "undefined") ++ keyval[name] = val; ++ else { ++ if(!Array.isArray(keyval[name])) ++ keyval[name] = [keyval[name]]; ++ keyval[name].push(val); ++ } ++ ++ } ++ return keyval; ++ }; ++ ++ this.callback = function(name, event) { ++ var func = this.options[name]; // Get function to call ++ if(typeof func !== "function") return; ++ ++ // Perform callback ++ var array = this.form.serializeArray(); ++ var ret = func(this.data(), array, event); ++ ++ // Hide window ++ this.modal.modal("hide"); ++ return ret; ++ }; ++ ++ this.dismiss = function() { this.callback("dismiss"); }; ++ this.submit = function() { this.callback("submit"); }; ++ this.close = function() { this.callback("close"); }; ++ this.ok = function() { this.callback("ok"); }; ++ this.cancel = function() { this.callback("cancel"); }; ++ this.yes = function() { this.callback("yes"); }; ++ this.no = function() { this.callback("no"); }; ++ ++ this.addOptions(options); ++ this.create(); ++ this.show(); ++} ++ ++ ++bootpopup.alert = function(message, title, callback) { ++ if(typeof title === "function") ++ callback = title; ++ ++ if(typeof title !== "string") ++ title = document.title; ++ if(typeof callback !== "function") ++ callback = function() {}; ++ ++ return bootpopup({ ++ title: title, ++ content: [{ p: { text: message } }], ++ dismiss: function() { callback(); } ++ }); ++}; ++ ++bootpopup.confirm = function(message, title, callback) { ++ if(typeof title === "function") ++ callback = title; ++ ++ if(typeof title !== "string") ++ title = document.title; ++ if(typeof callback !== "function") ++ callback = function() {}; ++ ++ var answer = false; ++ return bootpopup({ ++ title: title, ++ showclose: false, ++ content: [{ p: { text: message } }], ++ buttons: ["no", "yes"], ++ yes: function() { answer = true; }, ++ dismiss: function() { callback(answer); } ++ }); ++}; ++ ++bootpopup.prompt = function(label, type, message, title, callback) { ++ // Callback can be in any position, except label ++ var callback_function = function() {}; ++ if(typeof type === "function") ++ callback_function = type; ++ if(typeof message === "function") ++ callback_function = message; ++ if(typeof title === "function") ++ callback_function = title; ++ if(typeof callback === "function") ++ callback_function = callback; ++ ++ // If a list of values is provided, then the parameters are shifted ++ // because type should be ignored ++ if(typeof label === "object") { ++ title = message; ++ message = type; ++ type = null; ++ } ++ ++ // Sanitize message and title ++ if(typeof message !== "string") ++ message = "Please, provide values for:"; ++ if(typeof title !== "string") ++ title = document.title; ++ ++ // Add message to the window ++ var content = [{ p: { text: message } }]; ++ ++ // If label is a list of values to be asked to input ++ if(typeof label === "object") { ++ label.forEach(function(entry) { ++ var obj = null; ++ ++ // HTML ++ if (typeof entry === "string") ++ obj = entry; ++ ++ // Input ++ if ( entry !== null && typeof entry === "object" && typeof entry.label === "string") { ++ if(typeof entry.name !== "string") // Name in lower case and dashes instead spaces ++ entry.name = entry.label.toLowerCase().replace(/\s+/g, "-"); ++ if(typeof entry.type !== "string") ++ entry.type = "text"; ++ ++ obj = { input: entry }; ++ } ++ ++ if(obj !== null) ++ content.push(obj); ++ }); ++ } ++ else { ++ if(typeof type !== "string") type = "text"; ++ content.push({ input: { type: type, name: "value", label: label } }); ++ var callback_tmp = callback_function; // Overload callback function to return "data.value" ++ callback_function = function(data) { callback_tmp(data.value); }; ++ } ++ ++ return bootpopup({ ++ title: title, ++ content: content, ++ buttons: ["cancel", "ok"], ++ ok: function(data) { ++ callback_function(data); ++ } ++ }); ++}; ++ ++/** ++ * AMD support: require.js ++ */ ++if(typeof define === "function") { ++ define(["jquery", "bootstrap"], function() { ++ return bootpopup; ++ }); ++} diff --cc debian/missing-sources/bootstrap.js index 0000000,0000000..8a2e99a new file mode 100644 --- /dev/null +++ b/debian/missing-sources/bootstrap.js @@@ -1,0 -1,0 +1,2377 @@@ ++/*! ++ * Bootstrap v3.3.7 (http://getbootstrap.com) ++ * Copyright 2011-2016 Twitter, Inc. ++ * Licensed under the MIT license ++ */ ++ ++if (typeof jQuery === 'undefined') { ++ throw new Error('Bootstrap\'s JavaScript requires jQuery') ++} ++ +++function ($) { ++ 'use strict'; ++ var version = $.fn.jquery.split(' ')[0].split('.') ++ if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) { ++ throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4') ++ } ++}(jQuery); ++ ++/* ======================================================================== ++ * Bootstrap: transition.js v3.3.7 ++ * http://getbootstrap.com/javascript/#transitions ++ * ======================================================================== ++ * Copyright 2011-2016 Twitter, Inc. ++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) ++ * ======================================================================== */ ++ ++ +++function ($) { ++ 'use strict'; ++ ++ // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) ++ // ============================================================ ++ ++ function transitionEnd() { ++ var el = document.createElement('bootstrap') ++ ++ var transEndEventNames = { ++ WebkitTransition : 'webkitTransitionEnd', ++ MozTransition : 'transitionend', ++ OTransition : 'oTransitionEnd otransitionend', ++ transition : 'transitionend' ++ } ++ ++ for (var name in transEndEventNames) { ++ if (el.style[name] !== undefined) { ++ return { end: transEndEventNames[name] } ++ } ++ } ++ ++ return false // explicit for ie8 ( ._.) ++ } ++ ++ // http://blog.alexmaccaw.com/css-transitions ++ $.fn.emulateTransitionEnd = function (duration) { ++ var called = false ++ var $el = this ++ $(this).one('bsTransitionEnd', function () { called = true }) ++ var callback = function () { if (!called) $($el).trigger($.support.transition.end) } ++ setTimeout(callback, duration) ++ return this ++ } ++ ++ $(function () { ++ $.support.transition = transitionEnd() ++ ++ if (!$.support.transition) return ++ ++ $.event.special.bsTransitionEnd = { ++ bindType: $.support.transition.end, ++ delegateType: $.support.transition.end, ++ handle: function (e) { ++ if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) ++ } ++ } ++ }) ++ ++}(jQuery); ++ ++/* ======================================================================== ++ * Bootstrap: alert.js v3.3.7 ++ * http://getbootstrap.com/javascript/#alerts ++ * ======================================================================== ++ * Copyright 2011-2016 Twitter, Inc. ++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) ++ * ======================================================================== */ ++ ++ +++function ($) { ++ 'use strict'; ++ ++ // ALERT CLASS DEFINITION ++ // ====================== ++ ++ var dismiss = '[data-dismiss="alert"]' ++ var Alert = function (el) { ++ $(el).on('click', dismiss, this.close) ++ } ++ ++ Alert.VERSION = '3.3.7' ++ ++ Alert.TRANSITION_DURATION = 150 ++ ++ Alert.prototype.close = function (e) { ++ var $this = $(this) ++ var selector = $this.attr('data-target') ++ ++ if (!selector) { ++ selector = $this.attr('href') ++ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 ++ } ++ ++ var $parent = $(selector === '#' ? [] : selector) ++ ++ if (e) e.preventDefault() ++ ++ if (!$parent.length) { ++ $parent = $this.closest('.alert') ++ } ++ ++ $parent.trigger(e = $.Event('close.bs.alert')) ++ ++ if (e.isDefaultPrevented()) return ++ ++ $parent.removeClass('in') ++ ++ function removeElement() { ++ // detach from parent, fire event then clean up data ++ $parent.detach().trigger('closed.bs.alert').remove() ++ } ++ ++ $.support.transition && $parent.hasClass('fade') ? ++ $parent ++ .one('bsTransitionEnd', removeElement) ++ .emulateTransitionEnd(Alert.TRANSITION_DURATION) : ++ removeElement() ++ } ++ ++ ++ // ALERT PLUGIN DEFINITION ++ // ======================= ++ ++ function Plugin(option) { ++ return this.each(function () { ++ var $this = $(this) ++ var data = $this.data('bs.alert') ++ ++ if (!data) $this.data('bs.alert', (data = new Alert(this))) ++ if (typeof option == 'string') data[option].call($this) ++ }) ++ } ++ ++ var old = $.fn.alert ++ ++ $.fn.alert = Plugin ++ $.fn.alert.Constructor = Alert ++ ++ ++ // ALERT NO CONFLICT ++ // ================= ++ ++ $.fn.alert.noConflict = function () { ++ $.fn.alert = old ++ return this ++ } ++ ++ ++ // ALERT DATA-API ++ // ============== ++ ++ $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) ++ ++}(jQuery); ++ ++/* ======================================================================== ++ * Bootstrap: button.js v3.3.7 ++ * http://getbootstrap.com/javascript/#buttons ++ * ======================================================================== ++ * Copyright 2011-2016 Twitter, Inc. ++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) ++ * ======================================================================== */ ++ ++ +++function ($) { ++ 'use strict'; ++ ++ // BUTTON PUBLIC CLASS DEFINITION ++ // ============================== ++ ++ var Button = function (element, options) { ++ this.$element = $(element) ++ this.options = $.extend({}, Button.DEFAULTS, options) ++ this.isLoading = false ++ } ++ ++ Button.VERSION = '3.3.7' ++ ++ Button.DEFAULTS = { ++ loadingText: 'loading...' ++ } ++ ++ Button.prototype.setState = function (state) { ++ var d = 'disabled' ++ var $el = this.$element ++ var val = $el.is('input') ? 'val' : 'html' ++ var data = $el.data() ++ ++ state += 'Text' ++ ++ if (data.resetText == null) $el.data('resetText', $el[val]()) ++ ++ // push to event loop to allow forms to submit ++ setTimeout($.proxy(function () { ++ $el[val](data[state] == null ? this.options[state] : data[state]) ++ ++ if (state == 'loadingText') { ++ this.isLoading = true ++ $el.addClass(d).attr(d, d).prop(d, true) ++ } else if (this.isLoading) { ++ this.isLoading = false ++ $el.removeClass(d).removeAttr(d).prop(d, false) ++ } ++ }, this), 0) ++ } ++ ++ Button.prototype.toggle = function () { ++ var changed = true ++ var $parent = this.$element.closest('[data-toggle="buttons"]') ++ ++ if ($parent.length) { ++ var $input = this.$element.find('input') ++ if ($input.prop('type') == 'radio') { ++ if ($input.prop('checked')) changed = false ++ $parent.find('.active').removeClass('active') ++ this.$element.addClass('active') ++ } else if ($input.prop('type') == 'checkbox') { ++ if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false ++ this.$element.toggleClass('active') ++ } ++ $input.prop('checked', this.$element.hasClass('active')) ++ if (changed) $input.trigger('change') ++ } else { ++ this.$element.attr('aria-pressed', !this.$element.hasClass('active')) ++ this.$element.toggleClass('active') ++ } ++ } ++ ++ ++ // BUTTON PLUGIN DEFINITION ++ // ======================== ++ ++ function Plugin(option) { ++ return this.each(function () { ++ var $this = $(this) ++ var data = $this.data('bs.button') ++ var options = typeof option == 'object' && option ++ ++ if (!data) $this.data('bs.button', (data = new Button(this, options))) ++ ++ if (option == 'toggle') data.toggle() ++ else if (option) data.setState(option) ++ }) ++ } ++ ++ var old = $.fn.button ++ ++ $.fn.button = Plugin ++ $.fn.button.Constructor = Button ++ ++ ++ // BUTTON NO CONFLICT ++ // ================== ++ ++ $.fn.button.noConflict = function () { ++ $.fn.button = old ++ return this ++ } ++ ++ ++ // BUTTON DATA-API ++ // =============== ++ ++ $(document) ++ .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { ++ var $btn = $(e.target).closest('.btn') ++ Plugin.call($btn, 'toggle') ++ if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) { ++ // Prevent double click on radios, and the double selections (so cancellation) on checkboxes ++ e.preventDefault() ++ // The target component still receive the focus ++ if ($btn.is('input,button')) $btn.trigger('focus') ++ else $btn.find('input:visible,button:visible').first().trigger('focus') ++ } ++ }) ++ .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { ++ $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) ++ }) ++ ++}(jQuery); ++ ++/* ======================================================================== ++ * Bootstrap: carousel.js v3.3.7 ++ * http://getbootstrap.com/javascript/#carousel ++ * ======================================================================== ++ * Copyright 2011-2016 Twitter, Inc. ++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) ++ * ======================================================================== */ ++ ++ +++function ($) { ++ 'use strict'; ++ ++ // CAROUSEL CLASS DEFINITION ++ // ========================= ++ ++ var Carousel = function (element, options) { ++ this.$element = $(element) ++ this.$indicators = this.$element.find('.carousel-indicators') ++ this.options = options ++ this.paused = null ++ this.sliding = null ++ this.interval = null ++ this.$active = null ++ this.$items = null ++ ++ this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) ++ ++ this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element ++ .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) ++ .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) ++ } ++ ++ Carousel.VERSION = '3.3.7' ++ ++ Carousel.TRANSITION_DURATION = 600 ++ ++ Carousel.DEFAULTS = { ++ interval: 5000, ++ pause: 'hover', ++ wrap: true, ++ keyboard: true ++ } ++ ++ Carousel.prototype.keydown = function (e) { ++ if (/input|textarea/i.test(e.target.tagName)) return ++ switch (e.which) { ++ case 37: this.prev(); break ++ case 39: this.next(); break ++ default: return ++ } ++ ++ e.preventDefault() ++ } ++ ++ Carousel.prototype.cycle = function (e) { ++ e || (this.paused = false) ++ ++ this.interval && clearInterval(this.interval) ++ ++ this.options.interval ++ && !this.paused ++ && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) ++ ++ return this ++ } ++ ++ Carousel.prototype.getItemIndex = function (item) { ++ this.$items = item.parent().children('.item') ++ return this.$items.index(item || this.$active) ++ } ++ ++ Carousel.prototype.getItemForDirection = function (direction, active) { ++ var activeIndex = this.getItemIndex(active) ++ var willWrap = (direction == 'prev' && activeIndex === 0) ++ || (direction == 'next' && activeIndex == (this.$items.length - 1)) ++ if (willWrap && !this.options.wrap) return active ++ var delta = direction == 'prev' ? -1 : 1 ++ var itemIndex = (activeIndex + delta) % this.$items.length ++ return this.$items.eq(itemIndex) ++ } ++ ++ Carousel.prototype.to = function (pos) { ++ var that = this ++ var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) ++ ++ if (pos > (this.$items.length - 1) || pos < 0) return ++ ++ if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" ++ if (activeIndex == pos) return this.pause().cycle() ++ ++ return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) ++ } ++ ++ Carousel.prototype.pause = function (e) { ++ e || (this.paused = true) ++ ++ if (this.$element.find('.next, .prev').length && $.support.transition) { ++ this.$element.trigger($.support.transition.end) ++ this.cycle(true) ++ } ++ ++ this.interval = clearInterval(this.interval) ++ ++ return this ++ } ++ ++ Carousel.prototype.next = function () { ++ if (this.sliding) return ++ return this.slide('next') ++ } ++ ++ Carousel.prototype.prev = function () { ++ if (this.sliding) return ++ return this.slide('prev') ++ } ++ ++ Carousel.prototype.slide = function (type, next) { ++ var $active = this.$element.find('.item.active') ++ var $next = next || this.getItemForDirection(type, $active) ++ var isCycling = this.interval ++ var direction = type == 'next' ? 'left' : 'right' ++ var that = this ++ ++ if ($next.hasClass('active')) return (this.sliding = false) ++ ++ var relatedTarget = $next[0] ++ var slideEvent = $.Event('slide.bs.carousel', { ++ relatedTarget: relatedTarget, ++ direction: direction ++ }) ++ this.$element.trigger(slideEvent) ++ if (slideEvent.isDefaultPrevented()) return ++ ++ this.sliding = true ++ ++ isCycling && this.pause() ++ ++ if (this.$indicators.length) { ++ this.$indicators.find('.active').removeClass('active') ++ var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) ++ $nextIndicator && $nextIndicator.addClass('active') ++ } ++ ++ var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" ++ if ($.support.transition && this.$element.hasClass('slide')) { ++ $next.addClass(type) ++ $next[0].offsetWidth // force reflow ++ $active.addClass(direction) ++ $next.addClass(direction) ++ $active ++ .one('bsTransitionEnd', function () { ++ $next.removeClass([type, direction].join(' ')).addClass('active') ++ $active.removeClass(['active', direction].join(' ')) ++ that.sliding = false ++ setTimeout(function () { ++ that.$element.trigger(slidEvent) ++ }, 0) ++ }) ++ .emulateTransitionEnd(Carousel.TRANSITION_DURATION) ++ } else { ++ $active.removeClass('active') ++ $next.addClass('active') ++ this.sliding = false ++ this.$element.trigger(slidEvent) ++ } ++ ++ isCycling && this.cycle() ++ ++ return this ++ } ++ ++ ++ // CAROUSEL PLUGIN DEFINITION ++ // ========================== ++ ++ function Plugin(option) { ++ return this.each(function () { ++ var $this = $(this) ++ var data = $this.data('bs.carousel') ++ var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) ++ var action = typeof option == 'string' ? option : options.slide ++ ++ if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) ++ if (typeof option == 'number') data.to(option) ++ else if (action) data[action]() ++ else if (options.interval) data.pause().cycle() ++ }) ++ } ++ ++ var old = $.fn.carousel ++ ++ $.fn.carousel = Plugin ++ $.fn.carousel.Constructor = Carousel ++ ++ ++ // CAROUSEL NO CONFLICT ++ // ==================== ++ ++ $.fn.carousel.noConflict = function () { ++ $.fn.carousel = old ++ return this ++ } ++ ++ ++ // CAROUSEL DATA-API ++ // ================= ++ ++ var clickHandler = function (e) { ++ var href ++ var $this = $(this) ++ var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 ++ if (!$target.hasClass('carousel')) return ++ var options = $.extend({}, $target.data(), $this.data()) ++ var slideIndex = $this.attr('data-slide-to') ++ if (slideIndex) options.interval = false ++ ++ Plugin.call($target, options) ++ ++ if (slideIndex) { ++ $target.data('bs.carousel').to(slideIndex) ++ } ++ ++ e.preventDefault() ++ } ++ ++ $(document) ++ .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) ++ .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) ++ ++ $(window).on('load', function () { ++ $('[data-ride="carousel"]').each(function () { ++ var $carousel = $(this) ++ Plugin.call($carousel, $carousel.data()) ++ }) ++ }) ++ ++}(jQuery); ++ ++/* ======================================================================== ++ * Bootstrap: collapse.js v3.3.7 ++ * http://getbootstrap.com/javascript/#collapse ++ * ======================================================================== ++ * Copyright 2011-2016 Twitter, Inc. ++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) ++ * ======================================================================== */ ++ ++/* jshint latedef: false */ ++ +++function ($) { ++ 'use strict'; ++ ++ // COLLAPSE PUBLIC CLASS DEFINITION ++ // ================================ ++ ++ var Collapse = function (element, options) { ++ this.$element = $(element) ++ this.options = $.extend({}, Collapse.DEFAULTS, options) ++ this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + ++ '[data-toggle="collapse"][data-target="#' + element.id + '"]') ++ this.transitioning = null ++ ++ if (this.options.parent) { ++ this.$parent = this.getParent() ++ } else { ++ this.addAriaAndCollapsedClass(this.$element, this.$trigger) ++ } ++ ++ if (this.options.toggle) this.toggle() ++ } ++ ++ Collapse.VERSION = '3.3.7' ++ ++ Collapse.TRANSITION_DURATION = 350 ++ ++ Collapse.DEFAULTS = { ++ toggle: true ++ } ++ ++ Collapse.prototype.dimension = function () { ++ var hasWidth = this.$element.hasClass('width') ++ return hasWidth ? 'width' : 'height' ++ } ++ ++ Collapse.prototype.show = function () { ++ if (this.transitioning || this.$element.hasClass('in')) return ++ ++ var activesData ++ var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') ++ ++ if (actives && actives.length) { ++ activesData = actives.data('bs.collapse') ++ if (activesData && activesData.transitioning) return ++ } ++ ++ var startEvent = $.Event('show.bs.collapse') ++ this.$element.trigger(startEvent) ++ if (startEvent.isDefaultPrevented()) return ++ ++ if (actives && actives.length) { ++ Plugin.call(actives, 'hide') ++ activesData || actives.data('bs.collapse', null) ++ } ++ ++ var dimension = this.dimension() ++ ++ this.$element ++ .removeClass('collapse') ++ .addClass('collapsing')[dimension](0) ++ .attr('aria-expanded', true) ++ ++ this.$trigger ++ .removeClass('collapsed') ++ .attr('aria-expanded', true) ++ ++ this.transitioning = 1 ++ ++ var complete = function () { ++ this.$element ++ .removeClass('collapsing') ++ .addClass('collapse in')[dimension]('') ++ this.transitioning = 0 ++ this.$element ++ .trigger('shown.bs.collapse') ++ } ++ ++ if (!$.support.transition) return complete.call(this) ++ ++ var scrollSize = $.camelCase(['scroll', dimension].join('-')) ++ ++ this.$element ++ .one('bsTransitionEnd', $.proxy(complete, this)) ++ .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) ++ } ++ ++ Collapse.prototype.hide = function () { ++ if (this.transitioning || !this.$element.hasClass('in')) return ++ ++ var startEvent = $.Event('hide.bs.collapse') ++ this.$element.trigger(startEvent) ++ if (startEvent.isDefaultPrevented()) return ++ ++ var dimension = this.dimension() ++ ++ this.$element[dimension](this.$element[dimension]())[0].offsetHeight ++ ++ this.$element ++ .addClass('collapsing') ++ .removeClass('collapse in') ++ .attr('aria-expanded', false) ++ ++ this.$trigger ++ .addClass('collapsed') ++ .attr('aria-expanded', false) ++ ++ this.transitioning = 1 ++ ++ var complete = function () { ++ this.transitioning = 0 ++ this.$element ++ .removeClass('collapsing') ++ .addClass('collapse') ++ .trigger('hidden.bs.collapse') ++ } ++ ++ if (!$.support.transition) return complete.call(this) ++ ++ this.$element ++ [dimension](0) ++ .one('bsTransitionEnd', $.proxy(complete, this)) ++ .emulateTransitionEnd(Collapse.TRANSITION_DURATION) ++ } ++ ++ Collapse.prototype.toggle = function () { ++ this[this.$element.hasClass('in') ? 'hide' : 'show']() ++ } ++ ++ Collapse.prototype.getParent = function () { ++ return $(this.options.parent) ++ .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') ++ .each($.proxy(function (i, element) { ++ var $element = $(element) ++ this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) ++ }, this)) ++ .end() ++ } ++ ++ Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { ++ var isOpen = $element.hasClass('in') ++ ++ $element.attr('aria-expanded', isOpen) ++ $trigger ++ .toggleClass('collapsed', !isOpen) ++ .attr('aria-expanded', isOpen) ++ } ++ ++ function getTargetFromTrigger($trigger) { ++ var href ++ var target = $trigger.attr('data-target') ++ || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 ++ ++ return $(target) ++ } ++ ++ ++ // COLLAPSE PLUGIN DEFINITION ++ // ========================== ++ ++ function Plugin(option) { ++ return this.each(function () { ++ var $this = $(this) ++ var data = $this.data('bs.collapse') ++ var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) ++ ++ if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false ++ if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) ++ if (typeof option == 'string') data[option]() ++ }) ++ } ++ ++ var old = $.fn.collapse ++ ++ $.fn.collapse = Plugin ++ $.fn.collapse.Constructor = Collapse ++ ++ ++ // COLLAPSE NO CONFLICT ++ // ==================== ++ ++ $.fn.collapse.noConflict = function () { ++ $.fn.collapse = old ++ return this ++ } ++ ++ ++ // COLLAPSE DATA-API ++ // ================= ++ ++ $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { ++ var $this = $(this) ++ ++ if (!$this.attr('data-target')) e.preventDefault() ++ ++ var $target = getTargetFromTrigger($this) ++ var data = $target.data('bs.collapse') ++ var option = data ? 'toggle' : $this.data() ++ ++ Plugin.call($target, option) ++ }) ++ ++}(jQuery); ++ ++/* ======================================================================== ++ * Bootstrap: dropdown.js v3.3.7 ++ * http://getbootstrap.com/javascript/#dropdowns ++ * ======================================================================== ++ * Copyright 2011-2016 Twitter, Inc. ++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) ++ * ======================================================================== */ ++ ++ +++function ($) { ++ 'use strict'; ++ ++ // DROPDOWN CLASS DEFINITION ++ // ========================= ++ ++ var backdrop = '.dropdown-backdrop' ++ var toggle = '[data-toggle="dropdown"]' ++ var Dropdown = function (element) { ++ $(element).on('click.bs.dropdown', this.toggle) ++ } ++ ++ Dropdown.VERSION = '3.3.7' ++ ++ function getParent($this) { ++ var selector = $this.attr('data-target') ++ ++ if (!selector) { ++ selector = $this.attr('href') ++ selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 ++ } ++ ++ var $parent = selector && $(selector) ++ ++ return $parent && $parent.length ? $parent : $this.parent() ++ } ++ ++ function clearMenus(e) { ++ if (e && e.which === 3) return ++ $(backdrop).remove() ++ $(toggle).each(function () { ++ var $this = $(this) ++ var $parent = getParent($this) ++ var relatedTarget = { relatedTarget: this } ++ ++ if (!$parent.hasClass('open')) return ++ ++ if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return ++ ++ $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) ++ ++ if (e.isDefaultPrevented()) return ++ ++ $this.attr('aria-expanded', 'false') ++ $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget)) ++ }) ++ } ++ ++ Dropdown.prototype.toggle = function (e) { ++ var $this = $(this) ++ ++ if ($this.is('.disabled, :disabled')) return ++ ++ var $parent = getParent($this) ++ var isActive = $parent.hasClass('open') ++ ++ clearMenus() ++ ++ if (!isActive) { ++ if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { ++ // if mobile we use a backdrop because click events don't delegate ++ $(document.createElement('div')) ++ .addClass('dropdown-backdrop') ++ .insertAfter($(this)) ++ .on('click', clearMenus) ++ } ++ ++ var relatedTarget = { relatedTarget: this } ++ $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) ++ ++ if (e.isDefaultPrevented()) return ++ ++ $this ++ .trigger('focus') ++ .attr('aria-expanded', 'true') ++ ++ $parent ++ .toggleClass('open') ++ .trigger($.Event('shown.bs.dropdown', relatedTarget)) ++ } ++ ++ return false ++ } ++ ++ Dropdown.prototype.keydown = function (e) { ++ if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return ++ ++ var $this = $(this) ++ ++ e.preventDefault() ++ e.stopPropagation() ++ ++ if ($this.is('.disabled, :disabled')) return ++ ++ var $parent = getParent($this) ++ var isActive = $parent.hasClass('open') ++ ++ if (!isActive && e.which != 27 || isActive && e.which == 27) { ++ if (e.which == 27) $parent.find(toggle).trigger('focus') ++ return $this.trigger('click') ++ } ++ ++ var desc = ' li:not(.disabled):visible a' ++ var $items = $parent.find('.dropdown-menu' + desc) ++ ++ if (!$items.length) return ++ ++ var index = $items.index(e.target) ++ ++ if (e.which == 38 && index > 0) index-- // up ++ if (e.which == 40 && index < $items.length - 1) index++ // down ++ if (!~index) index = 0 ++ ++ $items.eq(index).trigger('focus') ++ } ++ ++ ++ // DROPDOWN PLUGIN DEFINITION ++ // ========================== ++ ++ function Plugin(option) { ++ return this.each(function () { ++ var $this = $(this) ++ var data = $this.data('bs.dropdown') ++ ++ if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) ++ if (typeof option == 'string') data[option].call($this) ++ }) ++ } ++ ++ var old = $.fn.dropdown ++ ++ $.fn.dropdown = Plugin ++ $.fn.dropdown.Constructor = Dropdown ++ ++ ++ // DROPDOWN NO CONFLICT ++ // ==================== ++ ++ $.fn.dropdown.noConflict = function () { ++ $.fn.dropdown = old ++ return this ++ } ++ ++ ++ // APPLY TO STANDARD DROPDOWN ELEMENTS ++ // =================================== ++ ++ $(document) ++ .on('click.bs.dropdown.data-api', clearMenus) ++ .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) ++ .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) ++ .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) ++ .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown) ++ ++}(jQuery); ++ ++/* ======================================================================== ++ * Bootstrap: modal.js v3.3.7 ++ * http://getbootstrap.com/javascript/#modals ++ * ======================================================================== ++ * Copyright 2011-2016 Twitter, Inc. ++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) ++ * ======================================================================== */ ++ ++ +++function ($) { ++ 'use strict'; ++ ++ // MODAL CLASS DEFINITION ++ // ====================== ++ ++ var Modal = function (element, options) { ++ this.options = options ++ this.$body = $(document.body) ++ this.$element = $(element) ++ this.$dialog = this.$element.find('.modal-dialog') ++ this.$backdrop = null ++ this.isShown = null ++ this.originalBodyPad = null ++ this.scrollbarWidth = 0 ++ this.ignoreBackdropClick = false ++ ++ if (this.options.remote) { ++ this.$element ++ .find('.modal-content') ++ .load(this.options.remote, $.proxy(function () { ++ this.$element.trigger('loaded.bs.modal') ++ }, this)) ++ } ++ } ++ ++ Modal.VERSION = '3.3.7' ++ ++ Modal.TRANSITION_DURATION = 300 ++ Modal.BACKDROP_TRANSITION_DURATION = 150 ++ ++ Modal.DEFAULTS = { ++ backdrop: true, ++ keyboard: true, ++ show: true ++ } ++ ++ Modal.prototype.toggle = function (_relatedTarget) { ++ return this.isShown ? this.hide() : this.show(_relatedTarget) ++ } ++ ++ Modal.prototype.show = function (_relatedTarget) { ++ var that = this ++ var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) ++ ++ this.$element.trigger(e) ++ ++ if (this.isShown || e.isDefaultPrevented()) return ++ ++ this.isShown = true ++ ++ this.checkScrollbar() ++ this.setScrollbar() ++ this.$body.addClass('modal-open') ++ ++ this.escape() ++ this.resize() ++ ++ this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) ++ ++ this.$dialog.on('mousedown.dismiss.bs.modal', function () { ++ that.$element.one('mouseup.dismiss.bs.modal', function (e) { ++ if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true ++ }) ++ }) ++ ++ this.backdrop(function () { ++ var transition = $.support.transition && that.$element.hasClass('fade') ++ ++ if (!that.$element.parent().length) { ++ that.$element.appendTo(that.$body) // don't move modals dom position ++ } ++ ++ that.$element ++ .show() ++ .scrollTop(0) ++ ++ that.adjustDialog() ++ ++ if (transition) { ++ that.$element[0].offsetWidth // force reflow ++ } ++ ++ that.$element.addClass('in') ++ ++ that.enforceFocus() ++ ++ var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) ++ ++ transition ? ++ that.$dialog // wait for modal to slide in ++ .one('bsTransitionEnd', function () { ++ that.$element.trigger('focus').trigger(e) ++ }) ++ .emulateTransitionEnd(Modal.TRANSITION_DURATION) : ++ that.$element.trigger('focus').trigger(e) ++ }) ++ } ++ ++ Modal.prototype.hide = function (e) { ++ if (e) e.preventDefault() ++ ++ e = $.Event('hide.bs.modal') ++ ++ this.$element.trigger(e) ++ ++ if (!this.isShown || e.isDefaultPrevented()) return ++ ++ this.isShown = false ++ ++ this.escape() ++ this.resize() ++ ++ $(document).off('focusin.bs.modal') ++ ++ this.$element ++ .removeClass('in') ++ .off('click.dismiss.bs.modal') ++ .off('mouseup.dismiss.bs.modal') ++ ++ this.$dialog.off('mousedown.dismiss.bs.modal') ++ ++ $.support.transition && this.$element.hasClass('fade') ? ++ this.$element ++ .one('bsTransitionEnd', $.proxy(this.hideModal, this)) ++ .emulateTransitionEnd(Modal.TRANSITION_DURATION) : ++ this.hideModal() ++ } ++ ++ Modal.prototype.enforceFocus = function () { ++ $(document) ++ .off('focusin.bs.modal') // guard against infinite focus loop ++ .on('focusin.bs.modal', $.proxy(function (e) { ++ if (document !== e.target && ++ this.$element[0] !== e.target && ++ !this.$element.has(e.target).length) { ++ this.$element.trigger('focus') ++ } ++ }, this)) ++ } ++ ++ Modal.prototype.escape = function () { ++ if (this.isShown && this.options.keyboard) { ++ this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { ++ e.which == 27 && this.hide() ++ }, this)) ++ } else if (!this.isShown) { ++ this.$element.off('keydown.dismiss.bs.modal') ++ } ++ } ++ ++ Modal.prototype.resize = function () { ++ if (this.isShown) { ++ $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) ++ } else { ++ $(window).off('resize.bs.modal') ++ } ++ } ++ ++ Modal.prototype.hideModal = function () { ++ var that = this ++ this.$element.hide() ++ this.backdrop(function () { ++ that.$body.removeClass('modal-open') ++ that.resetAdjustments() ++ that.resetScrollbar() ++ that.$element.trigger('hidden.bs.modal') ++ }) ++ } ++ ++ Modal.prototype.removeBackdrop = function () { ++ this.$backdrop && this.$backdrop.remove() ++ this.$backdrop = null ++ } ++ ++ Modal.prototype.backdrop = function (callback) { ++ var that = this ++ var animate = this.$element.hasClass('fade') ? 'fade' : '' ++ ++ if (this.isShown && this.options.backdrop) { ++ var doAnimate = $.support.transition && animate ++ ++ this.$backdrop = $(document.createElement('div')) ++ .addClass('modal-backdrop ' + animate) ++ .appendTo(this.$body) ++ ++ this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) { ++ if (this.ignoreBackdropClick) { ++ this.ignoreBackdropClick = false ++ return ++ } ++ if (e.target !== e.currentTarget) return ++ this.options.backdrop == 'static' ++ ? this.$element[0].focus() ++ : this.hide() ++ }, this)) ++ ++ if (doAnimate) this.$backdrop[0].offsetWidth // force reflow ++ ++ this.$backdrop.addClass('in') ++ ++ if (!callback) return ++ ++ doAnimate ? ++ this.$backdrop ++ .one('bsTransitionEnd', callback) ++ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : ++ callback() ++ ++ } else if (!this.isShown && this.$backdrop) { ++ this.$backdrop.removeClass('in') ++ ++ var callbackRemove = function () { ++ that.removeBackdrop() ++ callback && callback() ++ } ++ $.support.transition && this.$element.hasClass('fade') ? ++ this.$backdrop ++ .one('bsTransitionEnd', callbackRemove) ++ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : ++ callbackRemove() ++ ++ } else if (callback) { ++ callback() ++ } ++ } ++ ++ // these following methods are used to handle overflowing modals ++ ++ Modal.prototype.handleUpdate = function () { ++ this.adjustDialog() ++ } ++ ++ Modal.prototype.adjustDialog = function () { ++ var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight ++ ++ this.$element.css({ ++ paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', ++ paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' ++ }) ++ } ++ ++ Modal.prototype.resetAdjustments = function () { ++ this.$element.css({ ++ paddingLeft: '', ++ paddingRight: '' ++ }) ++ } ++ ++ Modal.prototype.checkScrollbar = function () { ++ var fullWindowWidth = window.innerWidth ++ if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 ++ var documentElementRect = document.documentElement.getBoundingClientRect() ++ fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left) ++ } ++ this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth ++ this.scrollbarWidth = this.measureScrollbar() ++ } ++ ++ Modal.prototype.setScrollbar = function () { ++ var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) ++ this.originalBodyPad = document.body.style.paddingRight || '' ++ if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) ++ } ++ ++ Modal.prototype.resetScrollbar = function () { ++ this.$body.css('padding-right', this.originalBodyPad) ++ } ++ ++ Modal.prototype.measureScrollbar = function () { // thx walsh ++ var scrollDiv = document.createElement('div') ++ scrollDiv.className = 'modal-scrollbar-measure' ++ this.$body.append(scrollDiv) ++ var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth ++ this.$body[0].removeChild(scrollDiv) ++ return scrollbarWidth ++ } ++ ++ ++ // MODAL PLUGIN DEFINITION ++ // ======================= ++ ++ function Plugin(option, _relatedTarget) { ++ return this.each(function () { ++ var $this = $(this) ++ var data = $this.data('bs.modal') ++ var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) ++ ++ if (!data) $this.data('bs.modal', (data = new Modal(this, options))) ++ if (typeof option == 'string') data[option](_relatedTarget) ++ else if (options.show) data.show(_relatedTarget) ++ }) ++ } ++ ++ var old = $.fn.modal ++ ++ $.fn.modal = Plugin ++ $.fn.modal.Constructor = Modal ++ ++ ++ // MODAL NO CONFLICT ++ // ================= ++ ++ $.fn.modal.noConflict = function () { ++ $.fn.modal = old ++ return this ++ } ++ ++ ++ // MODAL DATA-API ++ // ============== ++ ++ $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { ++ var $this = $(this) ++ var href = $this.attr('href') ++ var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 ++ var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) ++ ++ if ($this.is('a')) e.preventDefault() ++ ++ $target.one('show.bs.modal', function (showEvent) { ++ if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown ++ $target.one('hidden.bs.modal', function () { ++ $this.is(':visible') && $this.trigger('focus') ++ }) ++ }) ++ Plugin.call($target, option, this) ++ }) ++ ++}(jQuery); ++ ++/* ======================================================================== ++ * Bootstrap: tooltip.js v3.3.7 ++ * http://getbootstrap.com/javascript/#tooltip ++ * Inspired by the original jQuery.tipsy by Jason Frame ++ * ======================================================================== ++ * Copyright 2011-2016 Twitter, Inc. ++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) ++ * ======================================================================== */ ++ ++ +++function ($) { ++ 'use strict'; ++ ++ // TOOLTIP PUBLIC CLASS DEFINITION ++ // =============================== ++ ++ var Tooltip = function (element, options) { ++ this.type = null ++ this.options = null ++ this.enabled = null ++ this.timeout = null ++ this.hoverState = null ++ this.$element = null ++ this.inState = null ++ ++ this.init('tooltip', element, options) ++ } ++ ++ Tooltip.VERSION = '3.3.7' ++ ++ Tooltip.TRANSITION_DURATION = 150 ++ ++ Tooltip.DEFAULTS = { ++ animation: true, ++ placement: 'top', ++ selector: false, ++ template: '', ++ trigger: 'hover focus', ++ title: '', ++ delay: 0, ++ html: false, ++ container: false, ++ viewport: { ++ selector: 'body', ++ padding: 0 ++ } ++ } ++ ++ Tooltip.prototype.init = function (type, element, options) { ++ this.enabled = true ++ this.type = type ++ this.$element = $(element) ++ this.options = this.getOptions(options) ++ this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport)) ++ this.inState = { click: false, hover: false, focus: false } ++ ++ if (this.$element[0] instanceof document.constructor && !this.options.selector) { ++ throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!') ++ } ++ ++ var triggers = this.options.trigger.split(' ') ++ ++ for (var i = triggers.length; i--;) { ++ var trigger = triggers[i] ++ ++ if (trigger == 'click') { ++ this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) ++ } else if (trigger != 'manual') { ++ var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' ++ var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' ++ ++ this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) ++ this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) ++ } ++ } ++ ++ this.options.selector ? ++ (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : ++ this.fixTitle() ++ } ++ ++ Tooltip.prototype.getDefaults = function () { ++ return Tooltip.DEFAULTS ++ } ++ ++ Tooltip.prototype.getOptions = function (options) { ++ options = $.extend({}, this.getDefaults(), this.$element.data(), options) ++ ++ if (options.delay && typeof options.delay == 'number') { ++ options.delay = { ++ show: options.delay, ++ hide: options.delay ++ } ++ } ++ ++ return options ++ } ++ ++ Tooltip.prototype.getDelegateOptions = function () { ++ var options = {} ++ var defaults = this.getDefaults() ++ ++ this._options && $.each(this._options, function (key, value) { ++ if (defaults[key] != value) options[key] = value ++ }) ++ ++ return options ++ } ++ ++ Tooltip.prototype.enter = function (obj) { ++ var self = obj instanceof this.constructor ? ++ obj : $(obj.currentTarget).data('bs.' + this.type) ++ ++ if (!self) { ++ self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) ++ $(obj.currentTarget).data('bs.' + this.type, self) ++ } ++ ++ if (obj instanceof $.Event) { ++ self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true ++ } ++ ++ if (self.tip().hasClass('in') || self.hoverState == 'in') { ++ self.hoverState = 'in' ++ return ++ } ++ ++ clearTimeout(self.timeout) ++ ++ self.hoverState = 'in' ++ ++ if (!self.options.delay || !self.options.delay.show) return self.show() ++ ++ self.timeout = setTimeout(function () { ++ if (self.hoverState == 'in') self.show() ++ }, self.options.delay.show) ++ } ++ ++ Tooltip.prototype.isInStateTrue = function () { ++ for (var key in this.inState) { ++ if (this.inState[key]) return true ++ } ++ ++ return false ++ } ++ ++ Tooltip.prototype.leave = function (obj) { ++ var self = obj instanceof this.constructor ? ++ obj : $(obj.currentTarget).data('bs.' + this.type) ++ ++ if (!self) { ++ self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) ++ $(obj.currentTarget).data('bs.' + this.type, self) ++ } ++ ++ if (obj instanceof $.Event) { ++ self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false ++ } ++ ++ if (self.isInStateTrue()) return ++ ++ clearTimeout(self.timeout) ++ ++ self.hoverState = 'out' ++ ++ if (!self.options.delay || !self.options.delay.hide) return self.hide() ++ ++ self.timeout = setTimeout(function () { ++ if (self.hoverState == 'out') self.hide() ++ }, self.options.delay.hide) ++ } ++ ++ Tooltip.prototype.show = function () { ++ var e = $.Event('show.bs.' + this.type) ++ ++ if (this.hasContent() && this.enabled) { ++ this.$element.trigger(e) ++ ++ var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) ++ if (e.isDefaultPrevented() || !inDom) return ++ var that = this ++ ++ var $tip = this.tip() ++ ++ var tipId = this.getUID(this.type) ++ ++ this.setContent() ++ $tip.attr('id', tipId) ++ this.$element.attr('aria-describedby', tipId) ++ ++ if (this.options.animation) $tip.addClass('fade') ++ ++ var placement = typeof this.options.placement == 'function' ? ++ this.options.placement.call(this, $tip[0], this.$element[0]) : ++ this.options.placement ++ ++ var autoToken = /\s?auto?\s?/i ++ var autoPlace = autoToken.test(placement) ++ if (autoPlace) placement = placement.replace(autoToken, '') || 'top' ++ ++ $tip ++ .detach() ++ .css({ top: 0, left: 0, display: 'block' }) ++ .addClass(placement) ++ .data('bs.' + this.type, this) ++ ++ this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) ++ this.$element.trigger('inserted.bs.' + this.type) ++ ++ var pos = this.getPosition() ++ var actualWidth = $tip[0].offsetWidth ++ var actualHeight = $tip[0].offsetHeight ++ ++ if (autoPlace) { ++ var orgPlacement = placement ++ var viewportDim = this.getPosition(this.$viewport) ++ ++ placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' : ++ placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' : ++ placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' : ++ placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' : ++ placement ++ ++ $tip ++ .removeClass(orgPlacement) ++ .addClass(placement) ++ } ++ ++ var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) ++ ++ this.applyPlacement(calculatedOffset, placement) ++ ++ var complete = function () { ++ var prevHoverState = that.hoverState ++ that.$element.trigger('shown.bs.' + that.type) ++ that.hoverState = null ++ ++ if (prevHoverState == 'out') that.leave(that) ++ } ++ ++ $.support.transition && this.$tip.hasClass('fade') ? ++ $tip ++ .one('bsTransitionEnd', complete) ++ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : ++ complete() ++ } ++ } ++ ++ Tooltip.prototype.applyPlacement = function (offset, placement) { ++ var $tip = this.tip() ++ var width = $tip[0].offsetWidth ++ var height = $tip[0].offsetHeight ++ ++ // manually read margins because getBoundingClientRect includes difference ++ var marginTop = parseInt($tip.css('margin-top'), 10) ++ var marginLeft = parseInt($tip.css('margin-left'), 10) ++ ++ // we must check for NaN for ie 8/9 ++ if (isNaN(marginTop)) marginTop = 0 ++ if (isNaN(marginLeft)) marginLeft = 0 ++ ++ offset.top += marginTop ++ offset.left += marginLeft ++ ++ // $.fn.offset doesn't round pixel values ++ // so we use setOffset directly with our own function B-0 ++ $.offset.setOffset($tip[0], $.extend({ ++ using: function (props) { ++ $tip.css({ ++ top: Math.round(props.top), ++ left: Math.round(props.left) ++ }) ++ } ++ }, offset), 0) ++ ++ $tip.addClass('in') ++ ++ // check to see if placing tip in new offset caused the tip to resize itself ++ var actualWidth = $tip[0].offsetWidth ++ var actualHeight = $tip[0].offsetHeight ++ ++ if (placement == 'top' && actualHeight != height) { ++ offset.top = offset.top + height - actualHeight ++ } ++ ++ var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) ++ ++ if (delta.left) offset.left += delta.left ++ else offset.top += delta.top ++ ++ var isVertical = /top|bottom/.test(placement) ++ var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight ++ var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' ++ ++ $tip.offset(offset) ++ this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) ++ } ++ ++ Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) { ++ this.arrow() ++ .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') ++ .css(isVertical ? 'top' : 'left', '') ++ } ++ ++ Tooltip.prototype.setContent = function () { ++ var $tip = this.tip() ++ var title = this.getTitle() ++ ++ $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) ++ $tip.removeClass('fade in top bottom left right') ++ } ++ ++ Tooltip.prototype.hide = function (callback) { ++ var that = this ++ var $tip = $(this.$tip) ++ var e = $.Event('hide.bs.' + this.type) ++ ++ function complete() { ++ if (that.hoverState != 'in') $tip.detach() ++ if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary. ++ that.$element ++ .removeAttr('aria-describedby') ++ .trigger('hidden.bs.' + that.type) ++ } ++ callback && callback() ++ } ++ ++ this.$element.trigger(e) ++ ++ if (e.isDefaultPrevented()) return ++ ++ $tip.removeClass('in') ++ ++ $.support.transition && $tip.hasClass('fade') ? ++ $tip ++ .one('bsTransitionEnd', complete) ++ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : ++ complete() ++ ++ this.hoverState = null ++ ++ return this ++ } ++ ++ Tooltip.prototype.fixTitle = function () { ++ var $e = this.$element ++ if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') { ++ $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') ++ } ++ } ++ ++ Tooltip.prototype.hasContent = function () { ++ return this.getTitle() ++ } ++ ++ Tooltip.prototype.getPosition = function ($element) { ++ $element = $element || this.$element ++ ++ var el = $element[0] ++ var isBody = el.tagName == 'BODY' ++ ++ var elRect = el.getBoundingClientRect() ++ if (elRect.width == null) { ++ // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 ++ elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) ++ } ++ var isSvg = window.SVGElement && el instanceof window.SVGElement ++ // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3. ++ // See https://github.com/twbs/bootstrap/issues/20280 ++ var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset()) ++ var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } ++ var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null ++ ++ return $.extend({}, elRect, scroll, outerDims, elOffset) ++ } ++ ++ Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { ++ return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : ++ placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : ++ placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : ++ /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } ++ ++ } ++ ++ Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { ++ var delta = { top: 0, left: 0 } ++ if (!this.$viewport) return delta ++ ++ var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 ++ var viewportDimensions = this.getPosition(this.$viewport) ++ ++ if (/right|left/.test(placement)) { ++ var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll ++ var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight ++ if (topEdgeOffset < viewportDimensions.top) { // top overflow ++ delta.top = viewportDimensions.top - topEdgeOffset ++ } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow ++ delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset ++ } ++ } else { ++ var leftEdgeOffset = pos.left - viewportPadding ++ var rightEdgeOffset = pos.left + viewportPadding + actualWidth ++ if (leftEdgeOffset < viewportDimensions.left) { // left overflow ++ delta.left = viewportDimensions.left - leftEdgeOffset ++ } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow ++ delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset ++ } ++ } ++ ++ return delta ++ } ++ ++ Tooltip.prototype.getTitle = function () { ++ var title ++ var $e = this.$element ++ var o = this.options ++ ++ title = $e.attr('data-original-title') ++ || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) ++ ++ return title ++ } ++ ++ Tooltip.prototype.getUID = function (prefix) { ++ do prefix += ~~(Math.random() * 1000000) ++ while (document.getElementById(prefix)) ++ return prefix ++ } ++ ++ Tooltip.prototype.tip = function () { ++ if (!this.$tip) { ++ this.$tip = $(this.options.template) ++ if (this.$tip.length != 1) { ++ throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!') ++ } ++ } ++ return this.$tip ++ } ++ ++ Tooltip.prototype.arrow = function () { ++ return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) ++ } ++ ++ Tooltip.prototype.enable = function () { ++ this.enabled = true ++ } ++ ++ Tooltip.prototype.disable = function () { ++ this.enabled = false ++ } ++ ++ Tooltip.prototype.toggleEnabled = function () { ++ this.enabled = !this.enabled ++ } ++ ++ Tooltip.prototype.toggle = function (e) { ++ var self = this ++ if (e) { ++ self = $(e.currentTarget).data('bs.' + this.type) ++ if (!self) { ++ self = new this.constructor(e.currentTarget, this.getDelegateOptions()) ++ $(e.currentTarget).data('bs.' + this.type, self) ++ } ++ } ++ ++ if (e) { ++ self.inState.click = !self.inState.click ++ if (self.isInStateTrue()) self.enter(self) ++ else self.leave(self) ++ } else { ++ self.tip().hasClass('in') ? self.leave(self) : self.enter(self) ++ } ++ } ++ ++ Tooltip.prototype.destroy = function () { ++ var that = this ++ clearTimeout(this.timeout) ++ this.hide(function () { ++ that.$element.off('.' + that.type).removeData('bs.' + that.type) ++ if (that.$tip) { ++ that.$tip.detach() ++ } ++ that.$tip = null ++ that.$arrow = null ++ that.$viewport = null ++ that.$element = null ++ }) ++ } ++ ++ ++ // TOOLTIP PLUGIN DEFINITION ++ // ========================= ++ ++ function Plugin(option) { ++ return this.each(function () { ++ var $this = $(this) ++ var data = $this.data('bs.tooltip') ++ var options = typeof option == 'object' && option ++ ++ if (!data && /destroy|hide/.test(option)) return ++ if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) ++ if (typeof option == 'string') data[option]() ++ }) ++ } ++ ++ var old = $.fn.tooltip ++ ++ $.fn.tooltip = Plugin ++ $.fn.tooltip.Constructor = Tooltip ++ ++ ++ // TOOLTIP NO CONFLICT ++ // =================== ++ ++ $.fn.tooltip.noConflict = function () { ++ $.fn.tooltip = old ++ return this ++ } ++ ++}(jQuery); ++ ++/* ======================================================================== ++ * Bootstrap: popover.js v3.3.7 ++ * http://getbootstrap.com/javascript/#popovers ++ * ======================================================================== ++ * Copyright 2011-2016 Twitter, Inc. ++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) ++ * ======================================================================== */ ++ ++ +++function ($) { ++ 'use strict'; ++ ++ // POPOVER PUBLIC CLASS DEFINITION ++ // =============================== ++ ++ var Popover = function (element, options) { ++ this.init('popover', element, options) ++ } ++ ++ if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') ++ ++ Popover.VERSION = '3.3.7' ++ ++ Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { ++ placement: 'right', ++ trigger: 'click', ++ content: '', ++ template: '' ++ }) ++ ++ ++ // NOTE: POPOVER EXTENDS tooltip.js ++ // ================================ ++ ++ Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) ++ ++ Popover.prototype.constructor = Popover ++ ++ Popover.prototype.getDefaults = function () { ++ return Popover.DEFAULTS ++ } ++ ++ Popover.prototype.setContent = function () { ++ var $tip = this.tip() ++ var title = this.getTitle() ++ var content = this.getContent() ++ ++ $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) ++ $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events ++ this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' ++ ](content) ++ ++ $tip.removeClass('fade top bottom left right in') ++ ++ // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do ++ // this manually by checking the contents. ++ if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() ++ } ++ ++ Popover.prototype.hasContent = function () { ++ return this.getTitle() || this.getContent() ++ } ++ ++ Popover.prototype.getContent = function () { ++ var $e = this.$element ++ var o = this.options ++ ++ return $e.attr('data-content') ++ || (typeof o.content == 'function' ? ++ o.content.call($e[0]) : ++ o.content) ++ } ++ ++ Popover.prototype.arrow = function () { ++ return (this.$arrow = this.$arrow || this.tip().find('.arrow')) ++ } ++ ++ ++ // POPOVER PLUGIN DEFINITION ++ // ========================= ++ ++ function Plugin(option) { ++ return this.each(function () { ++ var $this = $(this) ++ var data = $this.data('bs.popover') ++ var options = typeof option == 'object' && option ++ ++ if (!data && /destroy|hide/.test(option)) return ++ if (!data) $this.data('bs.popover', (data = new Popover(this, options))) ++ if (typeof option == 'string') data[option]() ++ }) ++ } ++ ++ var old = $.fn.popover ++ ++ $.fn.popover = Plugin ++ $.fn.popover.Constructor = Popover ++ ++ ++ // POPOVER NO CONFLICT ++ // =================== ++ ++ $.fn.popover.noConflict = function () { ++ $.fn.popover = old ++ return this ++ } ++ ++}(jQuery); ++ ++/* ======================================================================== ++ * Bootstrap: scrollspy.js v3.3.7 ++ * http://getbootstrap.com/javascript/#scrollspy ++ * ======================================================================== ++ * Copyright 2011-2016 Twitter, Inc. ++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) ++ * ======================================================================== */ ++ ++ +++function ($) { ++ 'use strict'; ++ ++ // SCROLLSPY CLASS DEFINITION ++ // ========================== ++ ++ function ScrollSpy(element, options) { ++ this.$body = $(document.body) ++ this.$scrollElement = $(element).is(document.body) ? $(window) : $(element) ++ this.options = $.extend({}, ScrollSpy.DEFAULTS, options) ++ this.selector = (this.options.target || '') + ' .nav li > a' ++ this.offsets = [] ++ this.targets = [] ++ this.activeTarget = null ++ this.scrollHeight = 0 ++ ++ this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this)) ++ this.refresh() ++ this.process() ++ } ++ ++ ScrollSpy.VERSION = '3.3.7' ++ ++ ScrollSpy.DEFAULTS = { ++ offset: 10 ++ } ++ ++ ScrollSpy.prototype.getScrollHeight = function () { ++ return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) ++ } ++ ++ ScrollSpy.prototype.refresh = function () { ++ var that = this ++ var offsetMethod = 'offset' ++ var offsetBase = 0 ++ ++ this.offsets = [] ++ this.targets = [] ++ this.scrollHeight = this.getScrollHeight() ++ ++ if (!$.isWindow(this.$scrollElement[0])) { ++ offsetMethod = 'position' ++ offsetBase = this.$scrollElement.scrollTop() ++ } ++ ++ this.$body ++ .find(this.selector) ++ .map(function () { ++ var $el = $(this) ++ var href = $el.data('target') || $el.attr('href') ++ var $href = /^#./.test(href) && $(href) ++ ++ return ($href ++ && $href.length ++ && $href.is(':visible') ++ && [[$href[offsetMethod]().top + offsetBase, href]]) || null ++ }) ++ .sort(function (a, b) { return a[0] - b[0] }) ++ .each(function () { ++ that.offsets.push(this[0]) ++ that.targets.push(this[1]) ++ }) ++ } ++ ++ ScrollSpy.prototype.process = function () { ++ var scrollTop = this.$scrollElement.scrollTop() + this.options.offset ++ var scrollHeight = this.getScrollHeight() ++ var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() ++ var offsets = this.offsets ++ var targets = this.targets ++ var activeTarget = this.activeTarget ++ var i ++ ++ if (this.scrollHeight != scrollHeight) { ++ this.refresh() ++ } ++ ++ if (scrollTop >= maxScroll) { ++ return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) ++ } ++ ++ if (activeTarget && scrollTop < offsets[0]) { ++ this.activeTarget = null ++ return this.clear() ++ } ++ ++ for (i = offsets.length; i--;) { ++ activeTarget != targets[i] ++ && scrollTop >= offsets[i] ++ && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) ++ && this.activate(targets[i]) ++ } ++ } ++ ++ ScrollSpy.prototype.activate = function (target) { ++ this.activeTarget = target ++ ++ this.clear() ++ ++ var selector = this.selector + ++ '[data-target="' + target + '"],' + ++ this.selector + '[href="' + target + '"]' ++ ++ var active = $(selector) ++ .parents('li') ++ .addClass('active') ++ ++ if (active.parent('.dropdown-menu').length) { ++ active = active ++ .closest('li.dropdown') ++ .addClass('active') ++ } ++ ++ active.trigger('activate.bs.scrollspy') ++ } ++ ++ ScrollSpy.prototype.clear = function () { ++ $(this.selector) ++ .parentsUntil(this.options.target, '.active') ++ .removeClass('active') ++ } ++ ++ ++ // SCROLLSPY PLUGIN DEFINITION ++ // =========================== ++ ++ function Plugin(option) { ++ return this.each(function () { ++ var $this = $(this) ++ var data = $this.data('bs.scrollspy') ++ var options = typeof option == 'object' && option ++ ++ if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) ++ if (typeof option == 'string') data[option]() ++ }) ++ } ++ ++ var old = $.fn.scrollspy ++ ++ $.fn.scrollspy = Plugin ++ $.fn.scrollspy.Constructor = ScrollSpy ++ ++ ++ // SCROLLSPY NO CONFLICT ++ // ===================== ++ ++ $.fn.scrollspy.noConflict = function () { ++ $.fn.scrollspy = old ++ return this ++ } ++ ++ ++ // SCROLLSPY DATA-API ++ // ================== ++ ++ $(window).on('load.bs.scrollspy.data-api', function () { ++ $('[data-spy="scroll"]').each(function () { ++ var $spy = $(this) ++ Plugin.call($spy, $spy.data()) ++ }) ++ }) ++ ++}(jQuery); ++ ++/* ======================================================================== ++ * Bootstrap: tab.js v3.3.7 ++ * http://getbootstrap.com/javascript/#tabs ++ * ======================================================================== ++ * Copyright 2011-2016 Twitter, Inc. ++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) ++ * ======================================================================== */ ++ ++ +++function ($) { ++ 'use strict'; ++ ++ // TAB CLASS DEFINITION ++ // ==================== ++ ++ var Tab = function (element) { ++ // jscs:disable requireDollarBeforejQueryAssignment ++ this.element = $(element) ++ // jscs:enable requireDollarBeforejQueryAssignment ++ } ++ ++ Tab.VERSION = '3.3.7' ++ ++ Tab.TRANSITION_DURATION = 150 ++ ++ Tab.prototype.show = function () { ++ var $this = this.element ++ var $ul = $this.closest('ul:not(.dropdown-menu)') ++ var selector = $this.data('target') ++ ++ if (!selector) { ++ selector = $this.attr('href') ++ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 ++ } ++ ++ if ($this.parent('li').hasClass('active')) return ++ ++ var $previous = $ul.find('.active:last a') ++ var hideEvent = $.Event('hide.bs.tab', { ++ relatedTarget: $this[0] ++ }) ++ var showEvent = $.Event('show.bs.tab', { ++ relatedTarget: $previous[0] ++ }) ++ ++ $previous.trigger(hideEvent) ++ $this.trigger(showEvent) ++ ++ if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return ++ ++ var $target = $(selector) ++ ++ this.activate($this.closest('li'), $ul) ++ this.activate($target, $target.parent(), function () { ++ $previous.trigger({ ++ type: 'hidden.bs.tab', ++ relatedTarget: $this[0] ++ }) ++ $this.trigger({ ++ type: 'shown.bs.tab', ++ relatedTarget: $previous[0] ++ }) ++ }) ++ } ++ ++ Tab.prototype.activate = function (element, container, callback) { ++ var $active = container.find('> .active') ++ var transition = callback ++ && $.support.transition ++ && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length) ++ ++ function next() { ++ $active ++ .removeClass('active') ++ .find('> .dropdown-menu > .active') ++ .removeClass('active') ++ .end() ++ .find('[data-toggle="tab"]') ++ .attr('aria-expanded', false) ++ ++ element ++ .addClass('active') ++ .find('[data-toggle="tab"]') ++ .attr('aria-expanded', true) ++ ++ if (transition) { ++ element[0].offsetWidth // reflow for transition ++ element.addClass('in') ++ } else { ++ element.removeClass('fade') ++ } ++ ++ if (element.parent('.dropdown-menu').length) { ++ element ++ .closest('li.dropdown') ++ .addClass('active') ++ .end() ++ .find('[data-toggle="tab"]') ++ .attr('aria-expanded', true) ++ } ++ ++ callback && callback() ++ } ++ ++ $active.length && transition ? ++ $active ++ .one('bsTransitionEnd', next) ++ .emulateTransitionEnd(Tab.TRANSITION_DURATION) : ++ next() ++ ++ $active.removeClass('in') ++ } ++ ++ ++ // TAB PLUGIN DEFINITION ++ // ===================== ++ ++ function Plugin(option) { ++ return this.each(function () { ++ var $this = $(this) ++ var data = $this.data('bs.tab') ++ ++ if (!data) $this.data('bs.tab', (data = new Tab(this))) ++ if (typeof option == 'string') data[option]() ++ }) ++ } ++ ++ var old = $.fn.tab ++ ++ $.fn.tab = Plugin ++ $.fn.tab.Constructor = Tab ++ ++ ++ // TAB NO CONFLICT ++ // =============== ++ ++ $.fn.tab.noConflict = function () { ++ $.fn.tab = old ++ return this ++ } ++ ++ ++ // TAB DATA-API ++ // ============ ++ ++ var clickHandler = function (e) { ++ e.preventDefault() ++ Plugin.call($(this), 'show') ++ } ++ ++ $(document) ++ .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) ++ .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) ++ ++}(jQuery); ++ ++/* ======================================================================== ++ * Bootstrap: affix.js v3.3.7 ++ * http://getbootstrap.com/javascript/#affix ++ * ======================================================================== ++ * Copyright 2011-2016 Twitter, Inc. ++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) ++ * ======================================================================== */ ++ ++ +++function ($) { ++ 'use strict'; ++ ++ // AFFIX CLASS DEFINITION ++ // ====================== ++ ++ var Affix = function (element, options) { ++ this.options = $.extend({}, Affix.DEFAULTS, options) ++ ++ this.$target = $(this.options.target) ++ .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) ++ .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) ++ ++ this.$element = $(element) ++ this.affixed = null ++ this.unpin = null ++ this.pinnedOffset = null ++ ++ this.checkPosition() ++ } ++ ++ Affix.VERSION = '3.3.7' ++ ++ Affix.RESET = 'affix affix-top affix-bottom' ++ ++ Affix.DEFAULTS = { ++ offset: 0, ++ target: window ++ } ++ ++ Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { ++ var scrollTop = this.$target.scrollTop() ++ var position = this.$element.offset() ++ var targetHeight = this.$target.height() ++ ++ if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false ++ ++ if (this.affixed == 'bottom') { ++ if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' ++ return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' ++ } ++ ++ var initializing = this.affixed == null ++ var colliderTop = initializing ? scrollTop : position.top ++ var colliderHeight = initializing ? targetHeight : height ++ ++ if (offsetTop != null && scrollTop <= offsetTop) return 'top' ++ if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' ++ ++ return false ++ } ++ ++ Affix.prototype.getPinnedOffset = function () { ++ if (this.pinnedOffset) return this.pinnedOffset ++ this.$element.removeClass(Affix.RESET).addClass('affix') ++ var scrollTop = this.$target.scrollTop() ++ var position = this.$element.offset() ++ return (this.pinnedOffset = position.top - scrollTop) ++ } ++ ++ Affix.prototype.checkPositionWithEventLoop = function () { ++ setTimeout($.proxy(this.checkPosition, this), 1) ++ } ++ ++ Affix.prototype.checkPosition = function () { ++ if (!this.$element.is(':visible')) return ++ ++ var height = this.$element.height() ++ var offset = this.options.offset ++ var offsetTop = offset.top ++ var offsetBottom = offset.bottom ++ var scrollHeight = Math.max($(document).height(), $(document.body).height()) ++ ++ if (typeof offset != 'object') offsetBottom = offsetTop = offset ++ if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) ++ if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) ++ ++ var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) ++ ++ if (this.affixed != affix) { ++ if (this.unpin != null) this.$element.css('top', '') ++ ++ var affixType = 'affix' + (affix ? '-' + affix : '') ++ var e = $.Event(affixType + '.bs.affix') ++ ++ this.$element.trigger(e) ++ ++ if (e.isDefaultPrevented()) return ++ ++ this.affixed = affix ++ this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null ++ ++ this.$element ++ .removeClass(Affix.RESET) ++ .addClass(affixType) ++ .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') ++ } ++ ++ if (affix == 'bottom') { ++ this.$element.offset({ ++ top: scrollHeight - height - offsetBottom ++ }) ++ } ++ } ++ ++ ++ // AFFIX PLUGIN DEFINITION ++ // ======================= ++ ++ function Plugin(option) { ++ return this.each(function () { ++ var $this = $(this) ++ var data = $this.data('bs.affix') ++ var options = typeof option == 'object' && option ++ ++ if (!data) $this.data('bs.affix', (data = new Affix(this, options))) ++ if (typeof option == 'string') data[option]() ++ }) ++ } ++ ++ var old = $.fn.affix ++ ++ $.fn.affix = Plugin ++ $.fn.affix.Constructor = Affix ++ ++ ++ // AFFIX NO CONFLICT ++ // ================= ++ ++ $.fn.affix.noConflict = function () { ++ $.fn.affix = old ++ return this ++ } ++ ++ ++ // AFFIX DATA-API ++ // ============== ++ ++ $(window).on('load', function () { ++ $('[data-spy="affix"]').each(function () { ++ var $spy = $(this) ++ var data = $spy.data() ++ ++ data.offset = data.offset || {} ++ ++ if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom ++ if (data.offsetTop != null) data.offset.top = data.offsetTop ++ ++ Plugin.call($spy, data) ++ }) ++ }) ++ ++}(jQuery); diff --cc debian/missing-sources/c3.js index 0000000,0000000..dcdf93b new file mode 100644 --- /dev/null +++ b/debian/missing-sources/c3.js @@@ -1,0 -1,0 +1,9519 @@@ ++/* @license C3.js v0.6.6 | (c) C3 Team and other contributors | http://c3js.org/ */ ++(function (global, factory) { ++ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : ++ typeof define === 'function' && define.amd ? define(factory) : ++ (global.c3 = factory()); ++}(this, (function () { 'use strict'; ++ ++ function ChartInternal(api) { ++ var $$ = this; ++ $$.d3 = window.d3 ? window.d3 : typeof require !== 'undefined' ? require("d3") : undefined; ++ $$.api = api; ++ $$.config = $$.getDefaultConfig(); ++ $$.data = {}; ++ $$.cache = {}; ++ $$.axes = {}; ++ } ++ ++ function Chart(config) { ++ var $$ = this.internal = new ChartInternal(this); ++ $$.loadConfig(config); ++ ++ $$.beforeInit(config); ++ $$.init(); ++ $$.afterInit(config); ++ ++ // bind "this" to nested API ++ (function bindThis(fn, target, argThis) { ++ Object.keys(fn).forEach(function (key) { ++ target[key] = fn[key].bind(argThis); ++ if (Object.keys(fn[key]).length > 0) { ++ bindThis(fn[key], target[key], argThis); ++ } ++ }); ++ })(Chart.prototype, this, this); ++ } ++ ++ function AxisInternal(component, params) { ++ var internal = this; ++ internal.component = component; ++ internal.params = params || {}; ++ ++ internal.d3 = component.d3; ++ internal.scale = internal.d3.scaleLinear(); ++ internal.range; ++ internal.orient = "bottom"; ++ internal.innerTickSize = 6; ++ internal.outerTickSize = this.params.withOuterTick ? 6 : 0; ++ internal.tickPadding = 3; ++ internal.tickValues = null; ++ internal.tickFormat; ++ internal.tickArguments; ++ ++ internal.tickOffset = 0; ++ internal.tickCulling = true; ++ internal.tickCentered; ++ internal.tickTextCharSize; ++ internal.tickTextRotate = internal.params.tickTextRotate; ++ internal.tickLength; ++ ++ internal.axis = internal.generateAxis(); ++ } ++ ++ AxisInternal.prototype.axisX = function (selection, x, tickOffset) { ++ selection.attr("transform", function (d) { ++ return "translate(" + Math.ceil(x(d) + tickOffset) + ", 0)"; ++ }); ++ }; ++ AxisInternal.prototype.axisY = function (selection, y) { ++ selection.attr("transform", function (d) { ++ return "translate(0," + Math.ceil(y(d)) + ")"; ++ }); ++ }; ++ AxisInternal.prototype.scaleExtent = function (domain) { ++ var start = domain[0], ++ stop = domain[domain.length - 1]; ++ return start < stop ? [start, stop] : [stop, start]; ++ }; ++ AxisInternal.prototype.generateTicks = function (scale) { ++ var internal = this; ++ var i, ++ domain, ++ ticks = []; ++ if (scale.ticks) { ++ return scale.ticks.apply(scale, internal.tickArguments); ++ } ++ domain = scale.domain(); ++ for (i = Math.ceil(domain[0]); i < domain[1]; i++) { ++ ticks.push(i); ++ } ++ if (ticks.length > 0 && ticks[0] > 0) { ++ ticks.unshift(ticks[0] - (ticks[1] - ticks[0])); ++ } ++ return ticks; ++ }; ++ AxisInternal.prototype.copyScale = function () { ++ var internal = this; ++ var newScale = internal.scale.copy(), ++ domain; ++ if (internal.params.isCategory) { ++ domain = internal.scale.domain(); ++ newScale.domain([domain[0], domain[1] - 1]); ++ } ++ return newScale; ++ }; ++ AxisInternal.prototype.textFormatted = function (v) { ++ var internal = this, ++ formatted = internal.tickFormat ? internal.tickFormat(v) : v; ++ return typeof formatted !== 'undefined' ? formatted : ''; ++ }; ++ AxisInternal.prototype.updateRange = function () { ++ var internal = this; ++ internal.range = internal.scale.rangeExtent ? internal.scale.rangeExtent() : internal.scaleExtent(internal.scale.range()); ++ return internal.range; ++ }; ++ AxisInternal.prototype.updateTickTextCharSize = function (tick) { ++ var internal = this; ++ if (internal.tickTextCharSize) { ++ return internal.tickTextCharSize; ++ } ++ var size = { ++ h: 11.5, ++ w: 5.5 ++ }; ++ tick.select('text').text(function (d) { ++ return internal.textFormatted(d); ++ }).each(function (d) { ++ var box = this.getBoundingClientRect(), ++ text = internal.textFormatted(d), ++ h = box.height, ++ w = text ? box.width / text.length : undefined; ++ if (h && w) { ++ size.h = h; ++ size.w = w; ++ } ++ }).text(''); ++ internal.tickTextCharSize = size; ++ return size; ++ }; ++ AxisInternal.prototype.isVertical = function () { ++ return this.orient === 'left' || this.orient === 'right'; ++ }; ++ AxisInternal.prototype.tspanData = function (d, i, scale) { ++ var internal = this; ++ var splitted = internal.params.tickMultiline ? internal.splitTickText(d, scale) : [].concat(internal.textFormatted(d)); ++ ++ if (internal.params.tickMultiline && internal.params.tickMultilineMax > 0) { ++ splitted = internal.ellipsify(splitted, internal.params.tickMultilineMax); ++ } ++ ++ return splitted.map(function (s) { ++ return { index: i, splitted: s, length: splitted.length }; ++ }); ++ }; ++ AxisInternal.prototype.splitTickText = function (d, scale) { ++ var internal = this, ++ tickText = internal.textFormatted(d), ++ maxWidth = internal.params.tickWidth, ++ subtext, ++ spaceIndex, ++ textWidth, ++ splitted = []; ++ ++ if (Object.prototype.toString.call(tickText) === "[object Array]") { ++ return tickText; ++ } ++ ++ if (!maxWidth || maxWidth <= 0) { ++ maxWidth = internal.isVertical() ? 95 : internal.params.isCategory ? Math.ceil(scale(1) - scale(0)) - 12 : 110; ++ } ++ ++ function split(splitted, text) { ++ spaceIndex = undefined; ++ for (var i = 1; i < text.length; i++) { ++ if (text.charAt(i) === ' ') { ++ spaceIndex = i; ++ } ++ subtext = text.substr(0, i + 1); ++ textWidth = internal.tickTextCharSize.w * subtext.length; ++ // if text width gets over tick width, split by space index or crrent index ++ if (maxWidth < textWidth) { ++ return split(splitted.concat(text.substr(0, spaceIndex ? spaceIndex : i)), text.slice(spaceIndex ? spaceIndex + 1 : i)); ++ } ++ } ++ return splitted.concat(text); ++ } ++ ++ return split(splitted, tickText + ""); ++ }; ++ AxisInternal.prototype.ellipsify = function (splitted, max) { ++ if (splitted.length <= max) { ++ return splitted; ++ } ++ ++ var ellipsified = splitted.slice(0, max); ++ var remaining = 3; ++ for (var i = max - 1; i >= 0; i--) { ++ var available = ellipsified[i].length; ++ ++ ellipsified[i] = ellipsified[i].substr(0, available - remaining).padEnd(available, '.'); ++ ++ remaining -= available; ++ ++ if (remaining <= 0) { ++ break; ++ } ++ } ++ ++ return ellipsified; ++ }; ++ AxisInternal.prototype.updateTickLength = function () { ++ var internal = this; ++ internal.tickLength = Math.max(internal.innerTickSize, 0) + internal.tickPadding; ++ }; ++ AxisInternal.prototype.lineY2 = function (d) { ++ var internal = this, ++ tickPosition = internal.scale(d) + (internal.tickCentered ? 0 : internal.tickOffset); ++ return internal.range[0] < tickPosition && tickPosition < internal.range[1] ? internal.innerTickSize : 0; ++ }; ++ AxisInternal.prototype.textY = function () { ++ var internal = this, ++ rotate = internal.tickTextRotate; ++ return rotate ? 11.5 - 2.5 * (rotate / 15) * (rotate > 0 ? 1 : -1) : internal.tickLength; ++ }; ++ AxisInternal.prototype.textTransform = function () { ++ var internal = this, ++ rotate = internal.tickTextRotate; ++ return rotate ? "rotate(" + rotate + ")" : ""; ++ }; ++ AxisInternal.prototype.textTextAnchor = function () { ++ var internal = this, ++ rotate = internal.tickTextRotate; ++ return rotate ? rotate > 0 ? "start" : "end" : "middle"; ++ }; ++ AxisInternal.prototype.tspanDx = function () { ++ var internal = this, ++ rotate = internal.tickTextRotate; ++ return rotate ? 8 * Math.sin(Math.PI * (rotate / 180)) : 0; ++ }; ++ AxisInternal.prototype.tspanDy = function (d, i) { ++ var internal = this, ++ dy = internal.tickTextCharSize.h; ++ if (i === 0) { ++ if (internal.isVertical()) { ++ dy = -((d.length - 1) * (internal.tickTextCharSize.h / 2) - 3); ++ } else { ++ dy = ".71em"; ++ } ++ } ++ return dy; ++ }; ++ ++ AxisInternal.prototype.generateAxis = function () { ++ var internal = this, ++ d3 = internal.d3, ++ params = internal.params; ++ function axis(g, transition) { ++ var self; ++ g.each(function () { ++ var g = axis.g = d3.select(this); ++ ++ var scale0 = this.__chart__ || internal.scale, ++ scale1 = this.__chart__ = internal.copyScale(); ++ ++ var ticksValues = internal.tickValues ? internal.tickValues : internal.generateTicks(scale1), ++ ticks = g.selectAll(".tick").data(ticksValues, scale1), ++ tickEnter = ticks.enter().insert("g", ".domain").attr("class", "tick").style("opacity", 1e-6), ++ ++ // MEMO: No exit transition. The reason is this transition affects max tick width calculation because old tick will be included in the ticks. ++ tickExit = ticks.exit().remove(), ++ tickUpdate = ticks.merge(tickEnter), ++ tickTransform, ++ tickX, ++ tickY; ++ ++ if (params.isCategory) { ++ internal.tickOffset = Math.ceil((scale1(1) - scale1(0)) / 2); ++ tickX = internal.tickCentered ? 0 : internal.tickOffset; ++ tickY = internal.tickCentered ? internal.tickOffset : 0; ++ } else { ++ internal.tickOffset = tickX = 0; ++ } ++ ++ internal.updateRange(); ++ internal.updateTickLength(); ++ internal.updateTickTextCharSize(g.select('.tick')); ++ ++ var lineUpdate = tickUpdate.select("line").merge(tickEnter.append("line")), ++ textUpdate = tickUpdate.select("text").merge(tickEnter.append("text")); ++ ++ var tspans = tickUpdate.selectAll('text').selectAll('tspan').data(function (d, i) { ++ return internal.tspanData(d, i, scale1); ++ }), ++ tspanEnter = tspans.enter().append('tspan'), ++ tspanUpdate = tspanEnter.merge(tspans).text(function (d) { ++ return d.splitted; ++ }); ++ tspans.exit().remove(); ++ ++ var path = g.selectAll(".domain").data([0]), ++ pathUpdate = path.enter().append("path").merge(path).attr("class", "domain"); ++ ++ // TODO: each attr should be one function and change its behavior by internal.orient, probably ++ switch (internal.orient) { ++ case "bottom": ++ { ++ tickTransform = internal.axisX; ++ lineUpdate.attr("x1", tickX).attr("x2", tickX).attr("y2", function (d, i) { ++ return internal.lineY2(d, i); ++ }); ++ textUpdate.attr("x", 0).attr("y", function (d, i) { ++ return internal.textY(d, i); ++ }).attr("transform", function (d, i) { ++ return internal.textTransform(d, i); ++ }).style("text-anchor", function (d, i) { ++ return internal.textTextAnchor(d, i); ++ }); ++ tspanUpdate.attr('x', 0).attr("dy", function (d, i) { ++ return internal.tspanDy(d, i); ++ }).attr('dx', function (d, i) { ++ return internal.tspanDx(d, i); ++ }); ++ pathUpdate.attr("d", "M" + internal.range[0] + "," + internal.outerTickSize + "V0H" + internal.range[1] + "V" + internal.outerTickSize); ++ break; ++ } ++ case "top": ++ { ++ // TODO: rotated tick text ++ tickTransform = internal.axisX; ++ lineUpdate.attr("x1", tickX).attr("x2", tickX).attr("y2", function (d, i) { ++ return -1 * internal.lineY2(d, i); ++ }); ++ textUpdate.attr("x", 0).attr("y", function (d, i) { ++ return -1 * internal.textY(d, i) - (params.isCategory ? 2 : internal.tickLength - 2); ++ }).attr("transform", function (d, i) { ++ return internal.textTransform(d, i); ++ }).style("text-anchor", function (d, i) { ++ return internal.textTextAnchor(d, i); ++ }); ++ tspanUpdate.attr('x', 0).attr("dy", function (d, i) { ++ return internal.tspanDy(d, i); ++ }).attr('dx', function (d, i) { ++ return internal.tspanDx(d, i); ++ }); ++ pathUpdate.attr("d", "M" + internal.range[0] + "," + -internal.outerTickSize + "V0H" + internal.range[1] + "V" + -internal.outerTickSize); ++ break; ++ } ++ case "left": ++ { ++ tickTransform = internal.axisY; ++ lineUpdate.attr("x2", -internal.innerTickSize).attr("y1", tickY).attr("y2", tickY); ++ textUpdate.attr("x", -internal.tickLength).attr("y", internal.tickOffset).style("text-anchor", "end"); ++ tspanUpdate.attr('x', -internal.tickLength).attr("dy", function (d, i) { ++ return internal.tspanDy(d, i); ++ }); ++ pathUpdate.attr("d", "M" + -internal.outerTickSize + "," + internal.range[0] + "H0V" + internal.range[1] + "H" + -internal.outerTickSize); ++ break; ++ } ++ case "right": ++ { ++ tickTransform = internal.axisY; ++ lineUpdate.attr("x2", internal.innerTickSize).attr("y1", tickY).attr("y2", tickY); ++ textUpdate.attr("x", internal.tickLength).attr("y", internal.tickOffset).style("text-anchor", "start"); ++ tspanUpdate.attr('x', internal.tickLength).attr("dy", function (d, i) { ++ return internal.tspanDy(d, i); ++ }); ++ pathUpdate.attr("d", "M" + internal.outerTickSize + "," + internal.range[0] + "H0V" + internal.range[1] + "H" + internal.outerTickSize); ++ break; ++ } ++ } ++ if (scale1.rangeBand) { ++ var x = scale1, ++ dx = x.rangeBand() / 2; ++ scale0 = scale1 = function scale1(d) { ++ return x(d) + dx; ++ }; ++ } else if (scale0.rangeBand) { ++ scale0 = scale1; ++ } else { ++ tickExit.call(tickTransform, scale1, internal.tickOffset); ++ } ++ tickEnter.call(tickTransform, scale0, internal.tickOffset); ++ self = (transition ? tickUpdate.transition(transition) : tickUpdate).style('opacity', 1).call(tickTransform, scale1, internal.tickOffset); ++ }); ++ return self; ++ } ++ axis.scale = function (x) { ++ if (!arguments.length) { ++ return internal.scale; ++ } ++ internal.scale = x; ++ return axis; ++ }; ++ axis.orient = function (x) { ++ if (!arguments.length) { ++ return internal.orient; ++ } ++ internal.orient = x in { top: 1, right: 1, bottom: 1, left: 1 } ? x + "" : "bottom"; ++ return axis; ++ }; ++ axis.tickFormat = function (format) { ++ if (!arguments.length) { ++ return internal.tickFormat; ++ } ++ internal.tickFormat = format; ++ return axis; ++ }; ++ axis.tickCentered = function (isCentered) { ++ if (!arguments.length) { ++ return internal.tickCentered; ++ } ++ internal.tickCentered = isCentered; ++ return axis; ++ }; ++ axis.tickOffset = function () { ++ return internal.tickOffset; ++ }; ++ axis.tickInterval = function () { ++ var interval, length; ++ if (params.isCategory) { ++ interval = internal.tickOffset * 2; ++ } else { ++ length = axis.g.select('path.domain').node().getTotalLength() - internal.outerTickSize * 2; ++ interval = length / axis.g.selectAll('line').size(); ++ } ++ return interval === Infinity ? 0 : interval; ++ }; ++ axis.ticks = function () { ++ if (!arguments.length) { ++ return internal.tickArguments; ++ } ++ internal.tickArguments = arguments; ++ return axis; ++ }; ++ axis.tickCulling = function (culling) { ++ if (!arguments.length) { ++ return internal.tickCulling; ++ } ++ internal.tickCulling = culling; ++ return axis; ++ }; ++ axis.tickValues = function (x) { ++ if (typeof x === 'function') { ++ internal.tickValues = function () { ++ return x(internal.scale.domain()); ++ }; ++ } else { ++ if (!arguments.length) { ++ return internal.tickValues; ++ } ++ internal.tickValues = x; ++ } ++ return axis; ++ }; ++ return axis; ++ }; ++ ++ var CLASS = { ++ target: 'c3-target', ++ chart: 'c3-chart', ++ chartLine: 'c3-chart-line', ++ chartLines: 'c3-chart-lines', ++ chartBar: 'c3-chart-bar', ++ chartBars: 'c3-chart-bars', ++ chartText: 'c3-chart-text', ++ chartTexts: 'c3-chart-texts', ++ chartArc: 'c3-chart-arc', ++ chartArcs: 'c3-chart-arcs', ++ chartArcsTitle: 'c3-chart-arcs-title', ++ chartArcsBackground: 'c3-chart-arcs-background', ++ chartArcsGaugeUnit: 'c3-chart-arcs-gauge-unit', ++ chartArcsGaugeMax: 'c3-chart-arcs-gauge-max', ++ chartArcsGaugeMin: 'c3-chart-arcs-gauge-min', ++ selectedCircle: 'c3-selected-circle', ++ selectedCircles: 'c3-selected-circles', ++ eventRect: 'c3-event-rect', ++ eventRects: 'c3-event-rects', ++ eventRectsSingle: 'c3-event-rects-single', ++ eventRectsMultiple: 'c3-event-rects-multiple', ++ zoomRect: 'c3-zoom-rect', ++ brush: 'c3-brush', ++ focused: 'c3-focused', ++ defocused: 'c3-defocused', ++ region: 'c3-region', ++ regions: 'c3-regions', ++ title: 'c3-title', ++ tooltipContainer: 'c3-tooltip-container', ++ tooltip: 'c3-tooltip', ++ tooltipName: 'c3-tooltip-name', ++ shape: 'c3-shape', ++ shapes: 'c3-shapes', ++ line: 'c3-line', ++ lines: 'c3-lines', ++ bar: 'c3-bar', ++ bars: 'c3-bars', ++ circle: 'c3-circle', ++ circles: 'c3-circles', ++ arc: 'c3-arc', ++ arcLabelLine: 'c3-arc-label-line', ++ arcs: 'c3-arcs', ++ area: 'c3-area', ++ areas: 'c3-areas', ++ empty: 'c3-empty', ++ text: 'c3-text', ++ texts: 'c3-texts', ++ gaugeValue: 'c3-gauge-value', ++ grid: 'c3-grid', ++ gridLines: 'c3-grid-lines', ++ xgrid: 'c3-xgrid', ++ xgrids: 'c3-xgrids', ++ xgridLine: 'c3-xgrid-line', ++ xgridLines: 'c3-xgrid-lines', ++ xgridFocus: 'c3-xgrid-focus', ++ ygrid: 'c3-ygrid', ++ ygrids: 'c3-ygrids', ++ ygridLine: 'c3-ygrid-line', ++ ygridLines: 'c3-ygrid-lines', ++ axis: 'c3-axis', ++ axisX: 'c3-axis-x', ++ axisXLabel: 'c3-axis-x-label', ++ axisY: 'c3-axis-y', ++ axisYLabel: 'c3-axis-y-label', ++ axisY2: 'c3-axis-y2', ++ axisY2Label: 'c3-axis-y2-label', ++ legendBackground: 'c3-legend-background', ++ legendItem: 'c3-legend-item', ++ legendItemEvent: 'c3-legend-item-event', ++ legendItemTile: 'c3-legend-item-tile', ++ legendItemHidden: 'c3-legend-item-hidden', ++ legendItemFocused: 'c3-legend-item-focused', ++ dragarea: 'c3-dragarea', ++ EXPANDED: '_expanded_', ++ SELECTED: '_selected_', ++ INCLUDED: '_included_' ++ }; ++ ++ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { ++ return typeof obj; ++ } : function (obj) { ++ return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; ++ }; ++ ++ var classCallCheck = function (instance, Constructor) { ++ if (!(instance instanceof Constructor)) { ++ throw new TypeError("Cannot call a class as a function"); ++ } ++ }; ++ ++ var defineProperty = function (obj, key, value) { ++ if (key in obj) { ++ Object.defineProperty(obj, key, { ++ value: value, ++ enumerable: true, ++ configurable: true, ++ writable: true ++ }); ++ } else { ++ obj[key] = value; ++ } ++ ++ return obj; ++ }; ++ ++ var asHalfPixel = function asHalfPixel(n) { ++ return Math.ceil(n) + 0.5; ++ }; ++ var ceil10 = function ceil10(v) { ++ return Math.ceil(v / 10) * 10; ++ }; ++ var diffDomain = function diffDomain(d) { ++ return d[1] - d[0]; ++ }; ++ var getOption = function getOption(options, key, defaultValue) { ++ return isDefined(options[key]) ? options[key] : defaultValue; ++ }; ++ var getPathBox = function getPathBox(path) { ++ var box = path.getBoundingClientRect(), ++ items = [path.pathSegList.getItem(0), path.pathSegList.getItem(1)], ++ minX = items[0].x, ++ minY = Math.min(items[0].y, items[1].y); ++ return { x: minX, y: minY, width: box.width, height: box.height }; ++ }; ++ var hasValue = function hasValue(dict, value) { ++ var found = false; ++ Object.keys(dict).forEach(function (key) { ++ if (dict[key] === value) { ++ found = true; ++ } ++ }); ++ return found; ++ }; ++ var isArray = function isArray(o) { ++ return Array.isArray(o); ++ }; ++ var isDefined = function isDefined(v) { ++ return typeof v !== 'undefined'; ++ }; ++ var isEmpty = function isEmpty(o) { ++ return typeof o === 'undefined' || o === null || isString(o) && o.length === 0 || (typeof o === 'undefined' ? 'undefined' : _typeof(o)) === 'object' && Object.keys(o).length === 0; ++ }; ++ var isFunction = function isFunction(o) { ++ return typeof o === 'function'; ++ }; ++ var isString = function isString(o) { ++ return typeof o === 'string'; ++ }; ++ var isUndefined = function isUndefined(v) { ++ return typeof v === 'undefined'; ++ }; ++ var isValue = function isValue(v) { ++ return v || v === 0; ++ }; ++ var notEmpty = function notEmpty(o) { ++ return !isEmpty(o); ++ }; ++ var sanitise = function sanitise(str) { ++ return typeof str === 'string' ? str.replace(//g, '>') : str; ++ }; ++ ++ var Axis = function Axis(owner) { ++ classCallCheck(this, Axis); ++ ++ this.owner = owner; ++ this.d3 = owner.d3; ++ this.internal = AxisInternal; ++ }; ++ ++ Axis.prototype.init = function init() { ++ var $$ = this.owner, ++ config = $$.config, ++ main = $$.main; ++ $$.axes.x = main.append("g").attr("class", CLASS.axis + ' ' + CLASS.axisX).attr("clip-path", config.axis_x_inner ? "" : $$.clipPathForXAxis).attr("transform", $$.getTranslate('x')).style("visibility", config.axis_x_show ? 'visible' : 'hidden'); ++ $$.axes.x.append("text").attr("class", CLASS.axisXLabel).attr("transform", config.axis_rotated ? "rotate(-90)" : "").style("text-anchor", this.textAnchorForXAxisLabel.bind(this)); ++ $$.axes.y = main.append("g").attr("class", CLASS.axis + ' ' + CLASS.axisY).attr("clip-path", config.axis_y_inner ? "" : $$.clipPathForYAxis).attr("transform", $$.getTranslate('y')).style("visibility", config.axis_y_show ? 'visible' : 'hidden'); ++ $$.axes.y.append("text").attr("class", CLASS.axisYLabel).attr("transform", config.axis_rotated ? "" : "rotate(-90)").style("text-anchor", this.textAnchorForYAxisLabel.bind(this)); ++ ++ $$.axes.y2 = main.append("g").attr("class", CLASS.axis + ' ' + CLASS.axisY2) ++ // clip-path? ++ .attr("transform", $$.getTranslate('y2')).style("visibility", config.axis_y2_show ? 'visible' : 'hidden'); ++ $$.axes.y2.append("text").attr("class", CLASS.axisY2Label).attr("transform", config.axis_rotated ? "" : "rotate(-90)").style("text-anchor", this.textAnchorForY2AxisLabel.bind(this)); ++ }; ++ Axis.prototype.getXAxis = function getXAxis(scale, orient, tickFormat, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) { ++ var $$ = this.owner, ++ config = $$.config, ++ axisParams = { ++ isCategory: $$.isCategorized(), ++ withOuterTick: withOuterTick, ++ tickMultiline: config.axis_x_tick_multiline, ++ tickMultilineMax: config.axis_x_tick_multiline ? Number(config.axis_x_tick_multilineMax) : 0, ++ tickWidth: config.axis_x_tick_width, ++ tickTextRotate: withoutRotateTickText ? 0 : config.axis_x_tick_rotate, ++ withoutTransition: withoutTransition ++ }, ++ axis = new this.internal(this, axisParams).axis.scale(scale).orient(orient); ++ ++ if ($$.isTimeSeries() && tickValues && typeof tickValues !== "function") { ++ tickValues = tickValues.map(function (v) { ++ return $$.parseDate(v); ++ }); ++ } ++ ++ // Set tick ++ axis.tickFormat(tickFormat).tickValues(tickValues); ++ if ($$.isCategorized()) { ++ axis.tickCentered(config.axis_x_tick_centered); ++ if (isEmpty(config.axis_x_tick_culling)) { ++ config.axis_x_tick_culling = false; ++ } ++ } ++ ++ return axis; ++ }; ++ Axis.prototype.updateXAxisTickValues = function updateXAxisTickValues(targets, axis) { ++ var $$ = this.owner, ++ config = $$.config, ++ tickValues; ++ if (config.axis_x_tick_fit || config.axis_x_tick_count) { ++ tickValues = this.generateTickValues($$.mapTargetsToUniqueXs(targets), config.axis_x_tick_count, $$.isTimeSeries()); ++ } ++ if (axis) { ++ axis.tickValues(tickValues); ++ } else { ++ $$.xAxis.tickValues(tickValues); ++ $$.subXAxis.tickValues(tickValues); ++ } ++ return tickValues; ++ }; ++ Axis.prototype.getYAxis = function getYAxis(scale, orient, tickFormat, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) { ++ var $$ = this.owner, ++ config = $$.config, ++ axisParams = { ++ withOuterTick: withOuterTick, ++ withoutTransition: withoutTransition, ++ tickTextRotate: withoutRotateTickText ? 0 : config.axis_y_tick_rotate ++ }, ++ axis = new this.internal(this, axisParams).axis.scale(scale).orient(orient).tickFormat(tickFormat); ++ if ($$.isTimeSeriesY()) { ++ axis.ticks(config.axis_y_tick_time_type, config.axis_y_tick_time_interval); ++ } else { ++ axis.tickValues(tickValues); ++ } ++ return axis; ++ }; ++ Axis.prototype.getId = function getId(id) { ++ var config = this.owner.config; ++ return id in config.data_axes ? config.data_axes[id] : 'y'; ++ }; ++ Axis.prototype.getXAxisTickFormat = function getXAxisTickFormat() { ++ // #2251 previously set any negative values to a whole number, ++ // however both should be truncated according to the users format specification ++ var $$ = this.owner, ++ config = $$.config; ++ var format = $$.isTimeSeries() ? $$.defaultAxisTimeFormat : $$.isCategorized() ? $$.categoryName : function (v) { ++ return v; ++ }; ++ ++ if (config.axis_x_tick_format) { ++ if (isFunction(config.axis_x_tick_format)) { ++ format = config.axis_x_tick_format; ++ } else if ($$.isTimeSeries()) { ++ format = function format(date) { ++ return date ? $$.axisTimeFormat(config.axis_x_tick_format)(date) : ""; ++ }; ++ } ++ } ++ return isFunction(format) ? function (v) { ++ return format.call($$, v); ++ } : format; ++ }; ++ Axis.prototype.getTickValues = function getTickValues(tickValues, axis) { ++ return tickValues ? tickValues : axis ? axis.tickValues() : undefined; ++ }; ++ Axis.prototype.getXAxisTickValues = function getXAxisTickValues() { ++ return this.getTickValues(this.owner.config.axis_x_tick_values, this.owner.xAxis); ++ }; ++ Axis.prototype.getYAxisTickValues = function getYAxisTickValues() { ++ return this.getTickValues(this.owner.config.axis_y_tick_values, this.owner.yAxis); ++ }; ++ Axis.prototype.getY2AxisTickValues = function getY2AxisTickValues() { ++ return this.getTickValues(this.owner.config.axis_y2_tick_values, this.owner.y2Axis); ++ }; ++ Axis.prototype.getLabelOptionByAxisId = function getLabelOptionByAxisId(axisId) { ++ var $$ = this.owner, ++ config = $$.config, ++ option; ++ if (axisId === 'y') { ++ option = config.axis_y_label; ++ } else if (axisId === 'y2') { ++ option = config.axis_y2_label; ++ } else if (axisId === 'x') { ++ option = config.axis_x_label; ++ } ++ return option; ++ }; ++ Axis.prototype.getLabelText = function getLabelText(axisId) { ++ var option = this.getLabelOptionByAxisId(axisId); ++ return isString(option) ? option : option ? option.text : null; ++ }; ++ Axis.prototype.setLabelText = function setLabelText(axisId, text) { ++ var $$ = this.owner, ++ config = $$.config, ++ option = this.getLabelOptionByAxisId(axisId); ++ if (isString(option)) { ++ if (axisId === 'y') { ++ config.axis_y_label = text; ++ } else if (axisId === 'y2') { ++ config.axis_y2_label = text; ++ } else if (axisId === 'x') { ++ config.axis_x_label = text; ++ } ++ } else if (option) { ++ option.text = text; ++ } ++ }; ++ Axis.prototype.getLabelPosition = function getLabelPosition(axisId, defaultPosition) { ++ var option = this.getLabelOptionByAxisId(axisId), ++ position = option && (typeof option === 'undefined' ? 'undefined' : _typeof(option)) === 'object' && option.position ? option.position : defaultPosition; ++ return { ++ isInner: position.indexOf('inner') >= 0, ++ isOuter: position.indexOf('outer') >= 0, ++ isLeft: position.indexOf('left') >= 0, ++ isCenter: position.indexOf('center') >= 0, ++ isRight: position.indexOf('right') >= 0, ++ isTop: position.indexOf('top') >= 0, ++ isMiddle: position.indexOf('middle') >= 0, ++ isBottom: position.indexOf('bottom') >= 0 ++ }; ++ }; ++ Axis.prototype.getXAxisLabelPosition = function getXAxisLabelPosition() { ++ return this.getLabelPosition('x', this.owner.config.axis_rotated ? 'inner-top' : 'inner-right'); ++ }; ++ Axis.prototype.getYAxisLabelPosition = function getYAxisLabelPosition() { ++ return this.getLabelPosition('y', this.owner.config.axis_rotated ? 'inner-right' : 'inner-top'); ++ }; ++ Axis.prototype.getY2AxisLabelPosition = function getY2AxisLabelPosition() { ++ return this.getLabelPosition('y2', this.owner.config.axis_rotated ? 'inner-right' : 'inner-top'); ++ }; ++ Axis.prototype.getLabelPositionById = function getLabelPositionById(id) { ++ return id === 'y2' ? this.getY2AxisLabelPosition() : id === 'y' ? this.getYAxisLabelPosition() : this.getXAxisLabelPosition(); ++ }; ++ Axis.prototype.textForXAxisLabel = function textForXAxisLabel() { ++ return this.getLabelText('x'); ++ }; ++ Axis.prototype.textForYAxisLabel = function textForYAxisLabel() { ++ return this.getLabelText('y'); ++ }; ++ Axis.prototype.textForY2AxisLabel = function textForY2AxisLabel() { ++ return this.getLabelText('y2'); ++ }; ++ Axis.prototype.xForAxisLabel = function xForAxisLabel(forHorizontal, position) { ++ var $$ = this.owner; ++ if (forHorizontal) { ++ return position.isLeft ? 0 : position.isCenter ? $$.width / 2 : $$.width; ++ } else { ++ return position.isBottom ? -$$.height : position.isMiddle ? -$$.height / 2 : 0; ++ } ++ }; ++ Axis.prototype.dxForAxisLabel = function dxForAxisLabel(forHorizontal, position) { ++ if (forHorizontal) { ++ return position.isLeft ? "0.5em" : position.isRight ? "-0.5em" : "0"; ++ } else { ++ return position.isTop ? "-0.5em" : position.isBottom ? "0.5em" : "0"; ++ } ++ }; ++ Axis.prototype.textAnchorForAxisLabel = function textAnchorForAxisLabel(forHorizontal, position) { ++ if (forHorizontal) { ++ return position.isLeft ? 'start' : position.isCenter ? 'middle' : 'end'; ++ } else { ++ return position.isBottom ? 'start' : position.isMiddle ? 'middle' : 'end'; ++ } ++ }; ++ Axis.prototype.xForXAxisLabel = function xForXAxisLabel() { ++ return this.xForAxisLabel(!this.owner.config.axis_rotated, this.getXAxisLabelPosition()); ++ }; ++ Axis.prototype.xForYAxisLabel = function xForYAxisLabel() { ++ return this.xForAxisLabel(this.owner.config.axis_rotated, this.getYAxisLabelPosition()); ++ }; ++ Axis.prototype.xForY2AxisLabel = function xForY2AxisLabel() { ++ return this.xForAxisLabel(this.owner.config.axis_rotated, this.getY2AxisLabelPosition()); ++ }; ++ Axis.prototype.dxForXAxisLabel = function dxForXAxisLabel() { ++ return this.dxForAxisLabel(!this.owner.config.axis_rotated, this.getXAxisLabelPosition()); ++ }; ++ Axis.prototype.dxForYAxisLabel = function dxForYAxisLabel() { ++ return this.dxForAxisLabel(this.owner.config.axis_rotated, this.getYAxisLabelPosition()); ++ }; ++ Axis.prototype.dxForY2AxisLabel = function dxForY2AxisLabel() { ++ return this.dxForAxisLabel(this.owner.config.axis_rotated, this.getY2AxisLabelPosition()); ++ }; ++ Axis.prototype.dyForXAxisLabel = function dyForXAxisLabel() { ++ var $$ = this.owner, ++ config = $$.config, ++ position = this.getXAxisLabelPosition(); ++ if (config.axis_rotated) { ++ return position.isInner ? "1.2em" : -25 - ($$.config.axis_x_inner ? 0 : this.getMaxTickWidth('x')); ++ } else { ++ return position.isInner ? "-0.5em" : config.axis_x_height ? config.axis_x_height - 10 : "3em"; ++ } ++ }; ++ Axis.prototype.dyForYAxisLabel = function dyForYAxisLabel() { ++ var $$ = this.owner, ++ position = this.getYAxisLabelPosition(); ++ if ($$.config.axis_rotated) { ++ return position.isInner ? "-0.5em" : "3em"; ++ } else { ++ return position.isInner ? "1.2em" : -10 - ($$.config.axis_y_inner ? 0 : this.getMaxTickWidth('y') + 10); ++ } ++ }; ++ Axis.prototype.dyForY2AxisLabel = function dyForY2AxisLabel() { ++ var $$ = this.owner, ++ position = this.getY2AxisLabelPosition(); ++ if ($$.config.axis_rotated) { ++ return position.isInner ? "1.2em" : "-2.2em"; ++ } else { ++ return position.isInner ? "-0.5em" : 15 + ($$.config.axis_y2_inner ? 0 : this.getMaxTickWidth('y2') + 15); ++ } ++ }; ++ Axis.prototype.textAnchorForXAxisLabel = function textAnchorForXAxisLabel() { ++ var $$ = this.owner; ++ return this.textAnchorForAxisLabel(!$$.config.axis_rotated, this.getXAxisLabelPosition()); ++ }; ++ Axis.prototype.textAnchorForYAxisLabel = function textAnchorForYAxisLabel() { ++ var $$ = this.owner; ++ return this.textAnchorForAxisLabel($$.config.axis_rotated, this.getYAxisLabelPosition()); ++ }; ++ Axis.prototype.textAnchorForY2AxisLabel = function textAnchorForY2AxisLabel() { ++ var $$ = this.owner; ++ return this.textAnchorForAxisLabel($$.config.axis_rotated, this.getY2AxisLabelPosition()); ++ }; ++ Axis.prototype.getMaxTickWidth = function getMaxTickWidth(id, withoutRecompute) { ++ var $$ = this.owner, ++ config = $$.config, ++ maxWidth = 0, ++ targetsToShow, ++ scale, ++ axis, ++ dummy, ++ svg; ++ if (withoutRecompute && $$.currentMaxTickWidths[id]) { ++ return $$.currentMaxTickWidths[id]; ++ } ++ if ($$.svg) { ++ targetsToShow = $$.filterTargetsToShow($$.data.targets); ++ if (id === 'y') { ++ scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y')); ++ axis = this.getYAxis(scale, $$.yOrient, config.axis_y_tick_format, $$.yAxisTickValues, false, true, true); ++ } else if (id === 'y2') { ++ scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2')); ++ axis = this.getYAxis(scale, $$.y2Orient, config.axis_y2_tick_format, $$.y2AxisTickValues, false, true, true); ++ } else { ++ scale = $$.x.copy().domain($$.getXDomain(targetsToShow)); ++ axis = this.getXAxis(scale, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, false, true, true); ++ this.updateXAxisTickValues(targetsToShow, axis); ++ } ++ dummy = $$.d3.select('body').append('div').classed('c3', true); ++ svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0), svg.append('g').call(axis).each(function () { ++ $$.d3.select(this).selectAll('text').each(function () { ++ var box = this.getBoundingClientRect(); ++ if (maxWidth < box.width) { ++ maxWidth = box.width; ++ } ++ }); ++ dummy.remove(); ++ }); ++ } ++ $$.currentMaxTickWidths[id] = maxWidth <= 0 ? $$.currentMaxTickWidths[id] : maxWidth; ++ return $$.currentMaxTickWidths[id]; ++ }; ++ ++ Axis.prototype.updateLabels = function updateLabels(withTransition) { ++ var $$ = this.owner; ++ var axisXLabel = $$.main.select('.' + CLASS.axisX + ' .' + CLASS.axisXLabel), ++ axisYLabel = $$.main.select('.' + CLASS.axisY + ' .' + CLASS.axisYLabel), ++ axisY2Label = $$.main.select('.' + CLASS.axisY2 + ' .' + CLASS.axisY2Label); ++ (withTransition ? axisXLabel.transition() : axisXLabel).attr("x", this.xForXAxisLabel.bind(this)).attr("dx", this.dxForXAxisLabel.bind(this)).attr("dy", this.dyForXAxisLabel.bind(this)).text(this.textForXAxisLabel.bind(this)); ++ (withTransition ? axisYLabel.transition() : axisYLabel).attr("x", this.xForYAxisLabel.bind(this)).attr("dx", this.dxForYAxisLabel.bind(this)).attr("dy", this.dyForYAxisLabel.bind(this)).text(this.textForYAxisLabel.bind(this)); ++ (withTransition ? axisY2Label.transition() : axisY2Label).attr("x", this.xForY2AxisLabel.bind(this)).attr("dx", this.dxForY2AxisLabel.bind(this)).attr("dy", this.dyForY2AxisLabel.bind(this)).text(this.textForY2AxisLabel.bind(this)); ++ }; ++ Axis.prototype.getPadding = function getPadding(padding, key, defaultValue, domainLength) { ++ var p = typeof padding === 'number' ? padding : padding[key]; ++ if (!isValue(p)) { ++ return defaultValue; ++ } ++ if (padding.unit === 'ratio') { ++ return padding[key] * domainLength; ++ } ++ // assume padding is pixels if unit is not specified ++ return this.convertPixelsToAxisPadding(p, domainLength); ++ }; ++ Axis.prototype.convertPixelsToAxisPadding = function convertPixelsToAxisPadding(pixels, domainLength) { ++ var $$ = this.owner, ++ length = $$.config.axis_rotated ? $$.width : $$.height; ++ return domainLength * (pixels / length); ++ }; ++ Axis.prototype.generateTickValues = function generateTickValues(values, tickCount, forTimeSeries) { ++ var tickValues = values, ++ targetCount, ++ start, ++ end, ++ count, ++ interval, ++ i, ++ tickValue; ++ if (tickCount) { ++ targetCount = isFunction(tickCount) ? tickCount() : tickCount; ++ // compute ticks according to tickCount ++ if (targetCount === 1) { ++ tickValues = [values[0]]; ++ } else if (targetCount === 2) { ++ tickValues = [values[0], values[values.length - 1]]; ++ } else if (targetCount > 2) { ++ count = targetCount - 2; ++ start = values[0]; ++ end = values[values.length - 1]; ++ interval = (end - start) / (count + 1); ++ // re-construct unique values ++ tickValues = [start]; ++ for (i = 0; i < count; i++) { ++ tickValue = +start + interval * (i + 1); ++ tickValues.push(forTimeSeries ? new Date(tickValue) : tickValue); ++ } ++ tickValues.push(end); ++ } ++ } ++ if (!forTimeSeries) { ++ tickValues = tickValues.sort(function (a, b) { ++ return a - b; ++ }); ++ } ++ return tickValues; ++ }; ++ Axis.prototype.generateTransitions = function generateTransitions(duration) { ++ var $$ = this.owner, ++ axes = $$.axes; ++ return { ++ axisX: duration ? axes.x.transition().duration(duration) : axes.x, ++ axisY: duration ? axes.y.transition().duration(duration) : axes.y, ++ axisY2: duration ? axes.y2.transition().duration(duration) : axes.y2, ++ axisSubX: duration ? axes.subx.transition().duration(duration) : axes.subx ++ }; ++ }; ++ Axis.prototype.redraw = function redraw(duration, isHidden) { ++ var $$ = this.owner, ++ transition = duration ? $$.d3.transition().duration(duration) : null; ++ $$.axes.x.style("opacity", isHidden ? 0 : 1).call($$.xAxis, transition); ++ $$.axes.y.style("opacity", isHidden ? 0 : 1).call($$.yAxis, transition); ++ $$.axes.y2.style("opacity", isHidden ? 0 : 1).call($$.y2Axis, transition); ++ $$.axes.subx.style("opacity", isHidden ? 0 : 1).call($$.subXAxis, transition); ++ }; ++ ++ var c3 = { ++ version: "0.6.6", ++ chart: { ++ fn: Chart.prototype, ++ internal: { ++ fn: ChartInternal.prototype, ++ axis: { ++ fn: Axis.prototype, ++ internal: { ++ fn: AxisInternal.prototype ++ } ++ } ++ } ++ }, ++ generate: function generate(config) { ++ return new Chart(config); ++ } ++ }; ++ ++ ChartInternal.prototype.beforeInit = function () { ++ // can do something ++ }; ++ ChartInternal.prototype.afterInit = function () { ++ // can do something ++ }; ++ ChartInternal.prototype.init = function () { ++ var $$ = this, ++ config = $$.config; ++ ++ $$.initParams(); ++ ++ if (config.data_url) { ++ $$.convertUrlToData(config.data_url, config.data_mimeType, config.data_headers, config.data_keys, $$.initWithData); ++ } else if (config.data_json) { ++ $$.initWithData($$.convertJsonToData(config.data_json, config.data_keys)); ++ } else if (config.data_rows) { ++ $$.initWithData($$.convertRowsToData(config.data_rows)); ++ } else if (config.data_columns) { ++ $$.initWithData($$.convertColumnsToData(config.data_columns)); ++ } else { ++ throw Error('url or json or rows or columns is required.'); ++ } ++ }; ++ ++ ChartInternal.prototype.initParams = function () { ++ var $$ = this, ++ d3 = $$.d3, ++ config = $$.config; ++ ++ // MEMO: clipId needs to be unique because it conflicts when multiple charts exist ++ $$.clipId = "c3-" + +new Date() + '-clip'; ++ $$.clipIdForXAxis = $$.clipId + '-xaxis'; ++ $$.clipIdForYAxis = $$.clipId + '-yaxis'; ++ $$.clipIdForGrid = $$.clipId + '-grid'; ++ $$.clipIdForSubchart = $$.clipId + '-subchart'; ++ $$.clipPath = $$.getClipPath($$.clipId); ++ $$.clipPathForXAxis = $$.getClipPath($$.clipIdForXAxis); ++ $$.clipPathForYAxis = $$.getClipPath($$.clipIdForYAxis); ++ $$.clipPathForGrid = $$.getClipPath($$.clipIdForGrid); ++ $$.clipPathForSubchart = $$.getClipPath($$.clipIdForSubchart); ++ ++ $$.dragStart = null; ++ $$.dragging = false; ++ $$.flowing = false; ++ $$.cancelClick = false; ++ $$.mouseover = false; ++ $$.transiting = false; ++ ++ $$.color = $$.generateColor(); ++ $$.levelColor = $$.generateLevelColor(); ++ ++ $$.dataTimeParse = (config.data_xLocaltime ? d3.timeParse : d3.utcParse)($$.config.data_xFormat); ++ $$.axisTimeFormat = config.axis_x_localtime ? d3.timeFormat : d3.utcFormat; ++ $$.defaultAxisTimeFormat = function (date) { ++ if (date.getMilliseconds()) { ++ return d3.timeFormat(".%L")(date); ++ } ++ if (date.getSeconds()) { ++ return d3.timeFormat(":%S")(date); ++ } ++ if (date.getMinutes()) { ++ return d3.timeFormat("%I:%M")(date); ++ } ++ if (date.getHours()) { ++ return d3.timeFormat("%I %p")(date); ++ } ++ if (date.getDay() && date.getDate() !== 1) { ++ return d3.timeFormat("%-m/%-d")(date); ++ } ++ if (date.getDate() !== 1) { ++ return d3.timeFormat("%-m/%-d")(date); ++ } ++ if (date.getMonth()) { ++ return d3.timeFormat("%-m/%-d")(date); ++ } ++ return d3.timeFormat("%Y/%-m/%-d")(date); ++ }; ++ $$.hiddenTargetIds = []; ++ $$.hiddenLegendIds = []; ++ $$.focusedTargetIds = []; ++ $$.defocusedTargetIds = []; ++ ++ $$.xOrient = config.axis_rotated ? config.axis_x_inner ? "right" : "left" : config.axis_x_inner ? "top" : "bottom"; ++ $$.yOrient = config.axis_rotated ? config.axis_y_inner ? "top" : "bottom" : config.axis_y_inner ? "right" : "left"; ++ $$.y2Orient = config.axis_rotated ? config.axis_y2_inner ? "bottom" : "top" : config.axis_y2_inner ? "left" : "right"; ++ $$.subXOrient = config.axis_rotated ? "left" : "bottom"; ++ ++ $$.isLegendRight = config.legend_position === 'right'; ++ $$.isLegendInset = config.legend_position === 'inset'; ++ $$.isLegendTop = config.legend_inset_anchor === 'top-left' || config.legend_inset_anchor === 'top-right'; ++ $$.isLegendLeft = config.legend_inset_anchor === 'top-left' || config.legend_inset_anchor === 'bottom-left'; ++ $$.legendStep = 0; ++ $$.legendItemWidth = 0; ++ $$.legendItemHeight = 0; ++ ++ $$.currentMaxTickWidths = { ++ x: 0, ++ y: 0, ++ y2: 0 ++ }; ++ ++ $$.rotated_padding_left = 30; ++ $$.rotated_padding_right = config.axis_rotated && !config.axis_x_show ? 0 : 30; ++ $$.rotated_padding_top = 5; ++ ++ $$.withoutFadeIn = {}; ++ ++ $$.intervalForObserveInserted = undefined; ++ ++ $$.axes.subx = d3.selectAll([]); // needs when excluding subchart.js ++ }; ++ ++ ChartInternal.prototype.initChartElements = function () { ++ if (this.initBar) { ++ this.initBar(); ++ } ++ if (this.initLine) { ++ this.initLine(); ++ } ++ if (this.initArc) { ++ this.initArc(); ++ } ++ if (this.initGauge) { ++ this.initGauge(); ++ } ++ if (this.initText) { ++ this.initText(); ++ } ++ }; ++ ++ ChartInternal.prototype.initWithData = function (data) { ++ var $$ = this, ++ d3 = $$.d3, ++ config = $$.config; ++ var defs, ++ main, ++ binding = true; ++ ++ $$.axis = new Axis($$); ++ ++ if (!config.bindto) { ++ $$.selectChart = d3.selectAll([]); ++ } else if (typeof config.bindto.node === 'function') { ++ $$.selectChart = config.bindto; ++ } else { ++ $$.selectChart = d3.select(config.bindto); ++ } ++ if ($$.selectChart.empty()) { ++ $$.selectChart = d3.select(document.createElement('div')).style('opacity', 0); ++ $$.observeInserted($$.selectChart); ++ binding = false; ++ } ++ $$.selectChart.html("").classed("c3", true); ++ ++ // Init data as targets ++ $$.data.xs = {}; ++ $$.data.targets = $$.convertDataToTargets(data); ++ ++ if (config.data_filter) { ++ $$.data.targets = $$.data.targets.filter(config.data_filter); ++ } ++ ++ // Set targets to hide if needed ++ if (config.data_hide) { ++ $$.addHiddenTargetIds(config.data_hide === true ? $$.mapToIds($$.data.targets) : config.data_hide); ++ } ++ if (config.legend_hide) { ++ $$.addHiddenLegendIds(config.legend_hide === true ? $$.mapToIds($$.data.targets) : config.legend_hide); ++ } ++ ++ // Init sizes and scales ++ $$.updateSizes(); ++ $$.updateScales(); ++ ++ // Set domains for each scale ++ $$.x.domain(d3.extent($$.getXDomain($$.data.targets))); ++ $$.y.domain($$.getYDomain($$.data.targets, 'y')); ++ $$.y2.domain($$.getYDomain($$.data.targets, 'y2')); ++ $$.subX.domain($$.x.domain()); ++ $$.subY.domain($$.y.domain()); ++ $$.subY2.domain($$.y2.domain()); ++ ++ // Save original x domain for zoom update ++ $$.orgXDomain = $$.x.domain(); ++ ++ /*-- Basic Elements --*/ ++ ++ // Define svgs ++ $$.svg = $$.selectChart.append("svg").style("overflow", "hidden").on('mouseenter', function () { ++ return config.onmouseover.call($$); ++ }).on('mouseleave', function () { ++ return config.onmouseout.call($$); ++ }); ++ ++ if ($$.config.svg_classname) { ++ $$.svg.attr('class', $$.config.svg_classname); ++ } ++ ++ // Define defs ++ defs = $$.svg.append("defs"); ++ $$.clipChart = $$.appendClip(defs, $$.clipId); ++ $$.clipXAxis = $$.appendClip(defs, $$.clipIdForXAxis); ++ $$.clipYAxis = $$.appendClip(defs, $$.clipIdForYAxis); ++ $$.clipGrid = $$.appendClip(defs, $$.clipIdForGrid); ++ $$.clipSubchart = $$.appendClip(defs, $$.clipIdForSubchart); ++ $$.updateSvgSize(); ++ ++ // Define regions ++ main = $$.main = $$.svg.append("g").attr("transform", $$.getTranslate('main')); ++ ++ if ($$.initPie) { ++ $$.initPie(); ++ } ++ if ($$.initSubchart) { ++ $$.initSubchart(); ++ } ++ if ($$.initTooltip) { ++ $$.initTooltip(); ++ } ++ if ($$.initLegend) { ++ $$.initLegend(); ++ } ++ if ($$.initTitle) { ++ $$.initTitle(); ++ } ++ if ($$.initZoom) { ++ $$.initZoom(); ++ } ++ ++ // Update selection based on size and scale ++ // TODO: currently this must be called after initLegend because of update of sizes, but it should be done in initSubchart. ++ if ($$.initSubchartBrush) { ++ $$.initSubchartBrush(); ++ } ++ ++ /*-- Main Region --*/ ++ ++ // text when empty ++ main.append("text").attr("class", CLASS.text + ' ' + CLASS.empty).attr("text-anchor", "middle") // horizontal centering of text at x position in all browsers. ++ .attr("dominant-baseline", "middle"); // vertical centering of text at y position in all browsers, except IE. ++ ++ // Regions ++ $$.initRegion(); ++ ++ // Grids ++ $$.initGrid(); ++ ++ // Define g for chart area ++ main.append('g').attr("clip-path", $$.clipPath).attr('class', CLASS.chart); ++ ++ // Grid lines ++ if (config.grid_lines_front) { ++ $$.initGridLines(); ++ } ++ ++ // Cover whole with rects for events ++ $$.initEventRect(); ++ ++ // Define g for chart ++ $$.initChartElements(); ++ ++ // Add Axis ++ $$.axis.init(); ++ ++ // Set targets ++ $$.updateTargets($$.data.targets); ++ ++ // Set default extent if defined ++ if (config.axis_x_selection) { ++ $$.brush.selectionAsValue($$.getDefaultSelection()); ++ } ++ ++ // Draw with targets ++ if (binding) { ++ $$.updateDimension(); ++ $$.config.oninit.call($$); ++ $$.redraw({ ++ withTransition: false, ++ withTransform: true, ++ withUpdateXDomain: true, ++ withUpdateOrgXDomain: true, ++ withTransitionForAxis: false ++ }); ++ } ++ ++ // Bind resize event ++ $$.bindResize(); ++ ++ // export element of the chart ++ $$.api.element = $$.selectChart.node(); ++ }; ++ ++ ChartInternal.prototype.smoothLines = function (el, type) { ++ var $$ = this; ++ if (type === 'grid') { ++ el.each(function () { ++ var g = $$.d3.select(this), ++ x1 = g.attr('x1'), ++ x2 = g.attr('x2'), ++ y1 = g.attr('y1'), ++ y2 = g.attr('y2'); ++ g.attr({ ++ 'x1': Math.ceil(x1), ++ 'x2': Math.ceil(x2), ++ 'y1': Math.ceil(y1), ++ 'y2': Math.ceil(y2) ++ }); ++ }); ++ } ++ }; ++ ++ ChartInternal.prototype.updateSizes = function () { ++ var $$ = this, ++ config = $$.config; ++ var legendHeight = $$.legend ? $$.getLegendHeight() : 0, ++ legendWidth = $$.legend ? $$.getLegendWidth() : 0, ++ legendHeightForBottom = $$.isLegendRight || $$.isLegendInset ? 0 : legendHeight, ++ hasArc = $$.hasArcType(), ++ xAxisHeight = config.axis_rotated || hasArc ? 0 : $$.getHorizontalAxisHeight('x'), ++ subchartHeight = config.subchart_show && !hasArc ? config.subchart_size_height + xAxisHeight : 0; ++ ++ $$.currentWidth = $$.getCurrentWidth(); ++ $$.currentHeight = $$.getCurrentHeight(); ++ ++ // for main ++ $$.margin = config.axis_rotated ? { ++ top: $$.getHorizontalAxisHeight('y2') + $$.getCurrentPaddingTop(), ++ right: hasArc ? 0 : $$.getCurrentPaddingRight(), ++ bottom: $$.getHorizontalAxisHeight('y') + legendHeightForBottom + $$.getCurrentPaddingBottom(), ++ left: subchartHeight + (hasArc ? 0 : $$.getCurrentPaddingLeft()) ++ } : { ++ top: 4 + $$.getCurrentPaddingTop(), // for top tick text ++ right: hasArc ? 0 : $$.getCurrentPaddingRight(), ++ bottom: xAxisHeight + subchartHeight + legendHeightForBottom + $$.getCurrentPaddingBottom(), ++ left: hasArc ? 0 : $$.getCurrentPaddingLeft() ++ }; ++ ++ // for subchart ++ $$.margin2 = config.axis_rotated ? { ++ top: $$.margin.top, ++ right: NaN, ++ bottom: 20 + legendHeightForBottom, ++ left: $$.rotated_padding_left ++ } : { ++ top: $$.currentHeight - subchartHeight - legendHeightForBottom, ++ right: NaN, ++ bottom: xAxisHeight + legendHeightForBottom, ++ left: $$.margin.left ++ }; ++ ++ // for legend ++ $$.margin3 = { ++ top: 0, ++ right: NaN, ++ bottom: 0, ++ left: 0 ++ }; ++ if ($$.updateSizeForLegend) { ++ $$.updateSizeForLegend(legendHeight, legendWidth); ++ } ++ ++ $$.width = $$.currentWidth - $$.margin.left - $$.margin.right; ++ $$.height = $$.currentHeight - $$.margin.top - $$.margin.bottom; ++ if ($$.width < 0) { ++ $$.width = 0; ++ } ++ if ($$.height < 0) { ++ $$.height = 0; ++ } ++ ++ $$.width2 = config.axis_rotated ? $$.margin.left - $$.rotated_padding_left - $$.rotated_padding_right : $$.width; ++ $$.height2 = config.axis_rotated ? $$.height : $$.currentHeight - $$.margin2.top - $$.margin2.bottom; ++ if ($$.width2 < 0) { ++ $$.width2 = 0; ++ } ++ if ($$.height2 < 0) { ++ $$.height2 = 0; ++ } ++ ++ // for arc ++ $$.arcWidth = $$.width - ($$.isLegendRight ? legendWidth + 10 : 0); ++ $$.arcHeight = $$.height - ($$.isLegendRight ? 0 : 10); ++ if ($$.hasType('gauge') && !config.gauge_fullCircle) { ++ $$.arcHeight += $$.height - $$.getGaugeLabelHeight(); ++ } ++ if ($$.updateRadius) { ++ $$.updateRadius(); ++ } ++ ++ if ($$.isLegendRight && hasArc) { ++ $$.margin3.left = $$.arcWidth / 2 + $$.radiusExpanded * 1.1; ++ } ++ }; ++ ++ ChartInternal.prototype.updateTargets = function (targets) { ++ var $$ = this; ++ ++ /*-- Main --*/ ++ ++ //-- Text --// ++ $$.updateTargetsForText(targets); ++ ++ //-- Bar --// ++ $$.updateTargetsForBar(targets); ++ ++ //-- Line --// ++ $$.updateTargetsForLine(targets); ++ ++ //-- Arc --// ++ if ($$.hasArcType() && $$.updateTargetsForArc) { ++ $$.updateTargetsForArc(targets); ++ } ++ ++ /*-- Sub --*/ ++ ++ if ($$.updateTargetsForSubchart) { ++ $$.updateTargetsForSubchart(targets); ++ } ++ ++ // Fade-in each chart ++ $$.showTargets(); ++ }; ++ ChartInternal.prototype.showTargets = function () { ++ var $$ = this; ++ $$.svg.selectAll('.' + CLASS.target).filter(function (d) { ++ return $$.isTargetToShow(d.id); ++ }).transition().duration($$.config.transition_duration).style("opacity", 1); ++ }; ++ ++ ChartInternal.prototype.redraw = function (options, transitions) { ++ var $$ = this, ++ main = $$.main, ++ d3 = $$.d3, ++ config = $$.config; ++ var areaIndices = $$.getShapeIndices($$.isAreaType), ++ barIndices = $$.getShapeIndices($$.isBarType), ++ lineIndices = $$.getShapeIndices($$.isLineType); ++ var withY, withSubchart, withTransition, withTransitionForExit, withTransitionForAxis, withTransform, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain, withLegend, withEventRect, withDimension, withUpdateXAxis; ++ var hideAxis = $$.hasArcType(); ++ var drawArea, drawBar, drawLine, xForText, yForText; ++ var duration, durationForExit, durationForAxis; ++ var transitionsToWait, waitForDraw, flow, transition; ++ var targetsToShow = $$.filterTargetsToShow($$.data.targets), ++ tickValues, ++ i, ++ intervalForCulling, ++ xDomainForZoom; ++ var xv = $$.xv.bind($$), ++ cx, ++ cy; ++ ++ options = options || {}; ++ withY = getOption(options, "withY", true); ++ withSubchart = getOption(options, "withSubchart", true); ++ withTransition = getOption(options, "withTransition", true); ++ withTransform = getOption(options, "withTransform", false); ++ withUpdateXDomain = getOption(options, "withUpdateXDomain", false); ++ withUpdateOrgXDomain = getOption(options, "withUpdateOrgXDomain", false); ++ withTrimXDomain = getOption(options, "withTrimXDomain", true); ++ withUpdateXAxis = getOption(options, "withUpdateXAxis", withUpdateXDomain); ++ withLegend = getOption(options, "withLegend", false); ++ withEventRect = getOption(options, "withEventRect", true); ++ withDimension = getOption(options, "withDimension", true); ++ withTransitionForExit = getOption(options, "withTransitionForExit", withTransition); ++ withTransitionForAxis = getOption(options, "withTransitionForAxis", withTransition); ++ ++ duration = withTransition ? config.transition_duration : 0; ++ durationForExit = withTransitionForExit ? duration : 0; ++ durationForAxis = withTransitionForAxis ? duration : 0; ++ ++ transitions = transitions || $$.axis.generateTransitions(durationForAxis); ++ ++ // update legend and transform each g ++ if (withLegend && config.legend_show) { ++ $$.updateLegend($$.mapToIds($$.data.targets), options, transitions); ++ } else if (withDimension) { ++ // need to update dimension (e.g. axis.y.tick.values) because y tick values should change ++ // no need to update axis in it because they will be updated in redraw() ++ $$.updateDimension(true); ++ } ++ ++ // MEMO: needed for grids calculation ++ if ($$.isCategorized() && targetsToShow.length === 0) { ++ $$.x.domain([0, $$.axes.x.selectAll('.tick').size()]); ++ } ++ ++ if (targetsToShow.length) { ++ $$.updateXDomain(targetsToShow, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain); ++ if (!config.axis_x_tick_values) { ++ tickValues = $$.axis.updateXAxisTickValues(targetsToShow); ++ } ++ } else { ++ $$.xAxis.tickValues([]); ++ $$.subXAxis.tickValues([]); ++ } ++ ++ if (config.zoom_rescale && !options.flow) { ++ xDomainForZoom = $$.x.orgDomain(); ++ } ++ ++ $$.y.domain($$.getYDomain(targetsToShow, 'y', xDomainForZoom)); ++ $$.y2.domain($$.getYDomain(targetsToShow, 'y2', xDomainForZoom)); ++ ++ if (!config.axis_y_tick_values && config.axis_y_tick_count) { ++ $$.yAxis.tickValues($$.axis.generateTickValues($$.y.domain(), config.axis_y_tick_count)); ++ } ++ if (!config.axis_y2_tick_values && config.axis_y2_tick_count) { ++ $$.y2Axis.tickValues($$.axis.generateTickValues($$.y2.domain(), config.axis_y2_tick_count)); ++ } ++ ++ // axes ++ $$.axis.redraw(durationForAxis, hideAxis); ++ ++ // Update axis label ++ $$.axis.updateLabels(withTransition); ++ ++ // show/hide if manual culling needed ++ if ((withUpdateXDomain || withUpdateXAxis) && targetsToShow.length) { ++ if (config.axis_x_tick_culling && tickValues) { ++ for (i = 1; i < tickValues.length; i++) { ++ if (tickValues.length / i < config.axis_x_tick_culling_max) { ++ intervalForCulling = i; ++ break; ++ } ++ } ++ $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').each(function (e) { ++ var index = tickValues.indexOf(e); ++ if (index >= 0) { ++ d3.select(this).style('display', index % intervalForCulling ? 'none' : 'block'); ++ } ++ }); ++ } else { ++ $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').style('display', 'block'); ++ } ++ } ++ ++ // setup drawer - MEMO: these must be called after axis updated ++ drawArea = $$.generateDrawArea ? $$.generateDrawArea(areaIndices, false) : undefined; ++ drawBar = $$.generateDrawBar ? $$.generateDrawBar(barIndices) : undefined; ++ drawLine = $$.generateDrawLine ? $$.generateDrawLine(lineIndices, false) : undefined; ++ xForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, true); ++ yForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, false); ++ ++ // update circleY based on updated parameters ++ $$.updateCircleY(); ++ // generate circle x/y functions depending on updated params ++ cx = ($$.config.axis_rotated ? $$.circleY : $$.circleX).bind($$); ++ cy = ($$.config.axis_rotated ? $$.circleX : $$.circleY).bind($$); ++ ++ // Update sub domain ++ if (withY) { ++ $$.subY.domain($$.getYDomain(targetsToShow, 'y')); ++ $$.subY2.domain($$.getYDomain(targetsToShow, 'y2')); ++ } ++ ++ // xgrid focus ++ $$.updateXgridFocus(); ++ ++ // Data empty label positioning and text. ++ main.select("text." + CLASS.text + '.' + CLASS.empty).attr("x", $$.width / 2).attr("y", $$.height / 2).text(config.data_empty_label_text).transition().style('opacity', targetsToShow.length ? 0 : 1); ++ ++ // event rect ++ if (withEventRect) { ++ $$.redrawEventRect(); ++ } ++ ++ // grid ++ $$.updateGrid(duration); ++ ++ // rect for regions ++ $$.updateRegion(duration); ++ ++ // bars ++ $$.updateBar(durationForExit); ++ ++ // lines, areas and cricles ++ $$.updateLine(durationForExit); ++ $$.updateArea(durationForExit); ++ $$.updateCircle(cx, cy); ++ ++ // text ++ if ($$.hasDataLabel()) { ++ $$.updateText(xForText, yForText, durationForExit); ++ } ++ ++ // title ++ if ($$.redrawTitle) { ++ $$.redrawTitle(); ++ } ++ ++ // arc ++ if ($$.redrawArc) { ++ $$.redrawArc(duration, durationForExit, withTransform); ++ } ++ ++ // subchart ++ if ($$.redrawSubchart) { ++ $$.redrawSubchart(withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices); ++ } ++ ++ // circles for select ++ main.selectAll('.' + CLASS.selectedCircles).filter($$.isBarType.bind($$)).selectAll('circle').remove(); ++ ++ if (options.flow) { ++ flow = $$.generateFlow({ ++ targets: targetsToShow, ++ flow: options.flow, ++ duration: options.flow.duration, ++ drawBar: drawBar, ++ drawLine: drawLine, ++ drawArea: drawArea, ++ cx: cx, ++ cy: cy, ++ xv: xv, ++ xForText: xForText, ++ yForText: yForText ++ }); ++ } ++ ++ if ($$.isTabVisible()) { ++ // Only use transition if tab visible. See #938. ++ if (duration) { ++ // transition should be derived from one transition ++ transition = d3.transition().duration(duration); ++ transitionsToWait = []; ++ [$$.redrawBar(drawBar, true, transition), $$.redrawLine(drawLine, true, transition), $$.redrawArea(drawArea, true, transition), $$.redrawCircle(cx, cy, true, transition), $$.redrawText(xForText, yForText, options.flow, true, transition), $$.redrawRegion(true, transition), $$.redrawGrid(true, transition)].forEach(function (transitions) { ++ transitions.forEach(function (transition) { ++ transitionsToWait.push(transition); ++ }); ++ }); ++ // Wait for end of transitions to call flow and onrendered callback ++ waitForDraw = $$.generateWait(); ++ transitionsToWait.forEach(function (t) { ++ waitForDraw.add(t); ++ }); ++ waitForDraw(function () { ++ if (flow) { ++ flow(); ++ } ++ if (config.onrendered) { ++ config.onrendered.call($$); ++ } ++ }); ++ } else { ++ $$.redrawBar(drawBar); ++ $$.redrawLine(drawLine); ++ $$.redrawArea(drawArea); ++ $$.redrawCircle(cx, cy); ++ $$.redrawText(xForText, yForText, options.flow); ++ $$.redrawRegion(); ++ $$.redrawGrid(); ++ if (flow) { ++ flow(); ++ } ++ if (config.onrendered) { ++ config.onrendered.call($$); ++ } ++ } ++ } ++ ++ // update fadein condition ++ $$.mapToIds($$.data.targets).forEach(function (id) { ++ $$.withoutFadeIn[id] = true; ++ }); ++ }; ++ ++ ChartInternal.prototype.updateAndRedraw = function (options) { ++ var $$ = this, ++ config = $$.config, ++ transitions; ++ options = options || {}; ++ // same with redraw ++ options.withTransition = getOption(options, "withTransition", true); ++ options.withTransform = getOption(options, "withTransform", false); ++ options.withLegend = getOption(options, "withLegend", false); ++ // NOT same with redraw ++ options.withUpdateXDomain = getOption(options, "withUpdateXDomain", true); ++ options.withUpdateOrgXDomain = getOption(options, "withUpdateOrgXDomain", true); ++ options.withTransitionForExit = false; ++ options.withTransitionForTransform = getOption(options, "withTransitionForTransform", options.withTransition); ++ // MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called) ++ $$.updateSizes(); ++ // MEMO: called in updateLegend in redraw if withLegend ++ if (!(options.withLegend && config.legend_show)) { ++ transitions = $$.axis.generateTransitions(options.withTransitionForAxis ? config.transition_duration : 0); ++ // Update scales ++ $$.updateScales(); ++ $$.updateSvgSize(); ++ // Update g positions ++ $$.transformAll(options.withTransitionForTransform, transitions); ++ } ++ // Draw with new sizes & scales ++ $$.redraw(options, transitions); ++ }; ++ ChartInternal.prototype.redrawWithoutRescale = function () { ++ this.redraw({ ++ withY: false, ++ withSubchart: false, ++ withEventRect: false, ++ withTransitionForAxis: false ++ }); ++ }; ++ ++ ChartInternal.prototype.isTimeSeries = function () { ++ return this.config.axis_x_type === 'timeseries'; ++ }; ++ ChartInternal.prototype.isCategorized = function () { ++ return this.config.axis_x_type.indexOf('categor') >= 0; ++ }; ++ ChartInternal.prototype.isCustomX = function () { ++ var $$ = this, ++ config = $$.config; ++ return !$$.isTimeSeries() && (config.data_x || notEmpty(config.data_xs)); ++ }; ++ ++ ChartInternal.prototype.isTimeSeriesY = function () { ++ return this.config.axis_y_type === 'timeseries'; ++ }; ++ ++ ChartInternal.prototype.getTranslate = function (target) { ++ var $$ = this, ++ config = $$.config, ++ x, ++ y; ++ if (target === 'main') { ++ x = asHalfPixel($$.margin.left); ++ y = asHalfPixel($$.margin.top); ++ } else if (target === 'context') { ++ x = asHalfPixel($$.margin2.left); ++ y = asHalfPixel($$.margin2.top); ++ } else if (target === 'legend') { ++ x = $$.margin3.left; ++ y = $$.margin3.top; ++ } else if (target === 'x') { ++ x = 0; ++ y = config.axis_rotated ? 0 : $$.height; ++ } else if (target === 'y') { ++ x = 0; ++ y = config.axis_rotated ? $$.height : 0; ++ } else if (target === 'y2') { ++ x = config.axis_rotated ? 0 : $$.width; ++ y = config.axis_rotated ? 1 : 0; ++ } else if (target === 'subx') { ++ x = 0; ++ y = config.axis_rotated ? 0 : $$.height2; ++ } else if (target === 'arc') { ++ x = $$.arcWidth / 2; ++ y = $$.arcHeight / 2 - ($$.hasType('gauge') ? 6 : 0); // to prevent wrong display of min and max label ++ } ++ return "translate(" + x + "," + y + ")"; ++ }; ++ ChartInternal.prototype.initialOpacity = function (d) { ++ return d.value !== null && this.withoutFadeIn[d.id] ? 1 : 0; ++ }; ++ ChartInternal.prototype.initialOpacityForCircle = function (d) { ++ return d.value !== null && this.withoutFadeIn[d.id] ? this.opacityForCircle(d) : 0; ++ }; ++ ChartInternal.prototype.opacityForCircle = function (d) { ++ var isPointShouldBeShown = isFunction(this.config.point_show) ? this.config.point_show(d) : this.config.point_show; ++ var opacity = isPointShouldBeShown ? 1 : 0; ++ return isValue(d.value) ? this.isScatterType(d) ? 0.5 : opacity : 0; ++ }; ++ ChartInternal.prototype.opacityForText = function () { ++ return this.hasDataLabel() ? 1 : 0; ++ }; ++ ChartInternal.prototype.xx = function (d) { ++ return d ? this.x(d.x) : null; ++ }; ++ ChartInternal.prototype.xv = function (d) { ++ var $$ = this, ++ value = d.value; ++ if ($$.isTimeSeries()) { ++ value = $$.parseDate(d.value); ++ } else if ($$.isCategorized() && typeof d.value === 'string') { ++ value = $$.config.axis_x_categories.indexOf(d.value); ++ } ++ return Math.ceil($$.x(value)); ++ }; ++ ChartInternal.prototype.yv = function (d) { ++ var $$ = this, ++ yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y; ++ return Math.ceil(yScale(d.value)); ++ }; ++ ChartInternal.prototype.subxx = function (d) { ++ return d ? this.subX(d.x) : null; ++ }; ++ ++ ChartInternal.prototype.transformMain = function (withTransition, transitions) { ++ var $$ = this, ++ xAxis, ++ yAxis, ++ y2Axis; ++ if (transitions && transitions.axisX) { ++ xAxis = transitions.axisX; ++ } else { ++ xAxis = $$.main.select('.' + CLASS.axisX); ++ if (withTransition) { ++ xAxis = xAxis.transition(); ++ } ++ } ++ if (transitions && transitions.axisY) { ++ yAxis = transitions.axisY; ++ } else { ++ yAxis = $$.main.select('.' + CLASS.axisY); ++ if (withTransition) { ++ yAxis = yAxis.transition(); ++ } ++ } ++ if (transitions && transitions.axisY2) { ++ y2Axis = transitions.axisY2; ++ } else { ++ y2Axis = $$.main.select('.' + CLASS.axisY2); ++ if (withTransition) { ++ y2Axis = y2Axis.transition(); ++ } ++ } ++ (withTransition ? $$.main.transition() : $$.main).attr("transform", $$.getTranslate('main')); ++ xAxis.attr("transform", $$.getTranslate('x')); ++ yAxis.attr("transform", $$.getTranslate('y')); ++ y2Axis.attr("transform", $$.getTranslate('y2')); ++ $$.main.select('.' + CLASS.chartArcs).attr("transform", $$.getTranslate('arc')); ++ }; ++ ChartInternal.prototype.transformAll = function (withTransition, transitions) { ++ var $$ = this; ++ $$.transformMain(withTransition, transitions); ++ if ($$.config.subchart_show) { ++ $$.transformContext(withTransition, transitions); ++ } ++ if ($$.legend) { ++ $$.transformLegend(withTransition); ++ } ++ }; ++ ++ ChartInternal.prototype.updateSvgSize = function () { ++ var $$ = this, ++ brush = $$.svg.select(".c3-brush .overlay"); ++ $$.svg.attr('width', $$.currentWidth).attr('height', $$.currentHeight); ++ $$.svg.selectAll(['#' + $$.clipId, '#' + $$.clipIdForGrid]).select('rect').attr('width', $$.width).attr('height', $$.height); ++ $$.svg.select('#' + $$.clipIdForXAxis).select('rect').attr('x', $$.getXAxisClipX.bind($$)).attr('y', $$.getXAxisClipY.bind($$)).attr('width', $$.getXAxisClipWidth.bind($$)).attr('height', $$.getXAxisClipHeight.bind($$)); ++ $$.svg.select('#' + $$.clipIdForYAxis).select('rect').attr('x', $$.getYAxisClipX.bind($$)).attr('y', $$.getYAxisClipY.bind($$)).attr('width', $$.getYAxisClipWidth.bind($$)).attr('height', $$.getYAxisClipHeight.bind($$)); ++ $$.svg.select('#' + $$.clipIdForSubchart).select('rect').attr('width', $$.width).attr('height', brush.size() ? brush.attr('height') : 0); ++ // MEMO: parent div's height will be bigger than svg when ++ $$.selectChart.style('max-height', $$.currentHeight + "px"); ++ }; ++ ++ ChartInternal.prototype.updateDimension = function (withoutAxis) { ++ var $$ = this; ++ if (!withoutAxis) { ++ if ($$.config.axis_rotated) { ++ $$.axes.x.call($$.xAxis); ++ $$.axes.subx.call($$.subXAxis); ++ } else { ++ $$.axes.y.call($$.yAxis); ++ $$.axes.y2.call($$.y2Axis); ++ } ++ } ++ $$.updateSizes(); ++ $$.updateScales(); ++ $$.updateSvgSize(); ++ $$.transformAll(false); ++ }; ++ ++ ChartInternal.prototype.observeInserted = function (selection) { ++ var $$ = this, ++ observer; ++ if (typeof MutationObserver === 'undefined') { ++ window.console.error("MutationObserver not defined."); ++ return; ++ } ++ observer = new MutationObserver(function (mutations) { ++ mutations.forEach(function (mutation) { ++ if (mutation.type === 'childList' && mutation.previousSibling) { ++ observer.disconnect(); ++ // need to wait for completion of load because size calculation requires the actual sizes determined after that completion ++ $$.intervalForObserveInserted = window.setInterval(function () { ++ // parentNode will NOT be null when completed ++ if (selection.node().parentNode) { ++ window.clearInterval($$.intervalForObserveInserted); ++ $$.updateDimension(); ++ if ($$.brush) { ++ $$.brush.update(); ++ } ++ $$.config.oninit.call($$); ++ $$.redraw({ ++ withTransform: true, ++ withUpdateXDomain: true, ++ withUpdateOrgXDomain: true, ++ withTransition: false, ++ withTransitionForTransform: false, ++ withLegend: true ++ }); ++ selection.transition().style('opacity', 1); ++ } ++ }, 10); ++ } ++ }); ++ }); ++ observer.observe(selection.node(), { ++ attributes: true, ++ childList: true, ++ characterData: true ++ }); ++ }; ++ ++ ChartInternal.prototype.bindResize = function () { ++ var $$ = this, ++ config = $$.config; ++ ++ $$.resizeFunction = $$.generateResize(); // need to call .remove ++ ++ $$.resizeFunction.add(function () { ++ config.onresize.call($$); ++ }); ++ if (config.resize_auto) { ++ $$.resizeFunction.add(function () { ++ if ($$.resizeTimeout !== undefined) { ++ window.clearTimeout($$.resizeTimeout); ++ } ++ $$.resizeTimeout = window.setTimeout(function () { ++ delete $$.resizeTimeout; ++ $$.updateAndRedraw({ ++ withUpdateXDomain: false, ++ withUpdateOrgXDomain: false, ++ withTransition: false, ++ withTransitionForTransform: false, ++ withLegend: true ++ }); ++ if ($$.brush) { ++ $$.brush.update(); ++ } ++ }, 100); ++ }); ++ } ++ $$.resizeFunction.add(function () { ++ config.onresized.call($$); ++ }); ++ ++ $$.resizeIfElementDisplayed = function () { ++ // if element not displayed skip it ++ if ($$.api == null || !$$.api.element.offsetParent) { ++ return; ++ } ++ ++ $$.resizeFunction(); ++ }; ++ ++ if (window.attachEvent) { ++ window.attachEvent('onresize', $$.resizeIfElementDisplayed); ++ } else if (window.addEventListener) { ++ window.addEventListener('resize', $$.resizeIfElementDisplayed, false); ++ } else { ++ // fallback to this, if this is a very old browser ++ var wrapper = window.onresize; ++ if (!wrapper) { ++ // create a wrapper that will call all charts ++ wrapper = $$.generateResize(); ++ } else if (!wrapper.add || !wrapper.remove) { ++ // there is already a handler registered, make sure we call it too ++ wrapper = $$.generateResize(); ++ wrapper.add(window.onresize); ++ } ++ // add this graph to the wrapper, we will be removed if the user calls destroy ++ wrapper.add($$.resizeFunction); ++ window.onresize = function () { ++ // if element not displayed skip it ++ if (!$$.api.element.offsetParent) { ++ return; ++ } ++ ++ wrapper(); ++ }; ++ } ++ }; ++ ++ ChartInternal.prototype.generateResize = function () { ++ var resizeFunctions = []; ++ ++ function callResizeFunctions() { ++ resizeFunctions.forEach(function (f) { ++ f(); ++ }); ++ } ++ callResizeFunctions.add = function (f) { ++ resizeFunctions.push(f); ++ }; ++ callResizeFunctions.remove = function (f) { ++ for (var i = 0; i < resizeFunctions.length; i++) { ++ if (resizeFunctions[i] === f) { ++ resizeFunctions.splice(i, 1); ++ break; ++ } ++ } ++ }; ++ return callResizeFunctions; ++ }; ++ ++ ChartInternal.prototype.endall = function (transition, callback) { ++ var n = 0; ++ transition.each(function () { ++ ++n; ++ }).on("end", function () { ++ if (! --n) { ++ callback.apply(this, arguments); ++ } ++ }); ++ }; ++ ChartInternal.prototype.generateWait = function () { ++ var transitionsToWait = [], ++ f = function f(callback) { ++ var timer = setInterval(function () { ++ var done = 0; ++ transitionsToWait.forEach(function (t) { ++ if (t.empty()) { ++ done += 1; ++ return; ++ } ++ try { ++ t.transition(); ++ } catch (e) { ++ done += 1; ++ } ++ }); ++ if (done === transitionsToWait.length) { ++ clearInterval(timer); ++ if (callback) { ++ callback(); ++ } ++ } ++ }, 50); ++ }; ++ f.add = function (transition) { ++ transitionsToWait.push(transition); ++ }; ++ return f; ++ }; ++ ++ ChartInternal.prototype.parseDate = function (date) { ++ var $$ = this, ++ parsedDate; ++ if (date instanceof Date) { ++ parsedDate = date; ++ } else if (typeof date === 'string') { ++ parsedDate = $$.dataTimeParse(date); ++ } else if ((typeof date === 'undefined' ? 'undefined' : _typeof(date)) === 'object') { ++ parsedDate = new Date(+date); ++ } else if (typeof date === 'number' && !isNaN(date)) { ++ parsedDate = new Date(+date); ++ } ++ if (!parsedDate || isNaN(+parsedDate)) { ++ window.console.error("Failed to parse x '" + date + "' to Date object"); ++ } ++ return parsedDate; ++ }; ++ ++ ChartInternal.prototype.isTabVisible = function () { ++ var hidden; ++ if (typeof document.hidden !== "undefined") { ++ // Opera 12.10 and Firefox 18 and later support ++ hidden = "hidden"; ++ } else if (typeof document.mozHidden !== "undefined") { ++ hidden = "mozHidden"; ++ } else if (typeof document.msHidden !== "undefined") { ++ hidden = "msHidden"; ++ } else if (typeof document.webkitHidden !== "undefined") { ++ hidden = "webkitHidden"; ++ } ++ ++ return document[hidden] ? false : true; ++ }; ++ ++ ChartInternal.prototype.getPathBox = getPathBox; ++ ChartInternal.prototype.CLASS = CLASS; ++ ++ /* jshint ignore:start */ ++ ++ // PhantomJS doesn't have support for Function.prototype.bind, which has caused confusion. Use ++ // this polyfill to avoid the confusion. ++ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Polyfill ++ ++ if (!Function.prototype.bind) { ++ Function.prototype.bind = function (oThis) { ++ if (typeof this !== 'function') { ++ // closest thing possible to the ECMAScript 5 ++ // internal IsCallable function ++ throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); ++ } ++ ++ var aArgs = Array.prototype.slice.call(arguments, 1), ++ fToBind = this, ++ fNOP = function fNOP() {}, ++ fBound = function fBound() { ++ return fToBind.apply(this instanceof fNOP ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); ++ }; ++ ++ fNOP.prototype = this.prototype; ++ fBound.prototype = new fNOP(); ++ ++ return fBound; ++ }; ++ } ++ ++ // SVGPathSeg API polyfill ++ // https://github.com/progers/pathseg ++ // ++ // This is a drop-in replacement for the SVGPathSeg and SVGPathSegList APIs that were removed from ++ // SVG2 (https://lists.w3.org/Archives/Public/www-svg/2015Jun/0044.html), including the latest spec ++ // changes which were implemented in Firefox 43 and Chrome 46. ++ ++ (function () { ++ ++ if (!("SVGPathSeg" in window)) { ++ // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg ++ window.SVGPathSeg = function (type, typeAsLetter, owningPathSegList) { ++ this.pathSegType = type; ++ this.pathSegTypeAsLetter = typeAsLetter; ++ this._owningPathSegList = owningPathSegList; ++ }; ++ ++ window.SVGPathSeg.prototype.classname = "SVGPathSeg"; ++ ++ window.SVGPathSeg.PATHSEG_UNKNOWN = 0; ++ window.SVGPathSeg.PATHSEG_CLOSEPATH = 1; ++ window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2; ++ window.SVGPathSeg.PATHSEG_MOVETO_REL = 3; ++ window.SVGPathSeg.PATHSEG_LINETO_ABS = 4; ++ window.SVGPathSeg.PATHSEG_LINETO_REL = 5; ++ window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6; ++ window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7; ++ window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8; ++ window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9; ++ window.SVGPathSeg.PATHSEG_ARC_ABS = 10; ++ window.SVGPathSeg.PATHSEG_ARC_REL = 11; ++ window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12; ++ window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13; ++ window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14; ++ window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15; ++ window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16; ++ window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17; ++ window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18; ++ window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19; ++ ++ // Notify owning PathSegList on any changes so they can be synchronized back to the path element. ++ window.SVGPathSeg.prototype._segmentChanged = function () { ++ if (this._owningPathSegList) this._owningPathSegList.segmentChanged(this); ++ }; ++ ++ window.SVGPathSegClosePath = function (owningPathSegList) { ++ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CLOSEPATH, "z", owningPathSegList); ++ }; ++ window.SVGPathSegClosePath.prototype = Object.create(window.SVGPathSeg.prototype); ++ window.SVGPathSegClosePath.prototype.toString = function () { ++ return "[object SVGPathSegClosePath]"; ++ }; ++ window.SVGPathSegClosePath.prototype._asPathString = function () { ++ return this.pathSegTypeAsLetter; ++ }; ++ window.SVGPathSegClosePath.prototype.clone = function () { ++ return new window.SVGPathSegClosePath(undefined); ++ }; ++ ++ window.SVGPathSegMovetoAbs = function (owningPathSegList, x, y) { ++ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_ABS, "M", owningPathSegList); ++ this._x = x; ++ this._y = y; ++ }; ++ window.SVGPathSegMovetoAbs.prototype = Object.create(window.SVGPathSeg.prototype); ++ window.SVGPathSegMovetoAbs.prototype.toString = function () { ++ return "[object SVGPathSegMovetoAbs]"; ++ }; ++ window.SVGPathSegMovetoAbs.prototype._asPathString = function () { ++ return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; ++ }; ++ window.SVGPathSegMovetoAbs.prototype.clone = function () { ++ return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y); ++ }; ++ Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "x", { ++ get: function get() { ++ return this._x; ++ }, ++ set: function set(x) { ++ this._x = x; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "y", { ++ get: function get() { ++ return this._y; ++ }, ++ set: function set(y) { ++ this._y = y; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ ++ window.SVGPathSegMovetoRel = function (owningPathSegList, x, y) { ++ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_REL, "m", owningPathSegList); ++ this._x = x; ++ this._y = y; ++ }; ++ window.SVGPathSegMovetoRel.prototype = Object.create(window.SVGPathSeg.prototype); ++ window.SVGPathSegMovetoRel.prototype.toString = function () { ++ return "[object SVGPathSegMovetoRel]"; ++ }; ++ window.SVGPathSegMovetoRel.prototype._asPathString = function () { ++ return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; ++ }; ++ window.SVGPathSegMovetoRel.prototype.clone = function () { ++ return new window.SVGPathSegMovetoRel(undefined, this._x, this._y); ++ }; ++ Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "x", { ++ get: function get() { ++ return this._x; ++ }, ++ set: function set(x) { ++ this._x = x; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "y", { ++ get: function get() { ++ return this._y; ++ }, ++ set: function set(y) { ++ this._y = y; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ ++ window.SVGPathSegLinetoAbs = function (owningPathSegList, x, y) { ++ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_ABS, "L", owningPathSegList); ++ this._x = x; ++ this._y = y; ++ }; ++ window.SVGPathSegLinetoAbs.prototype = Object.create(window.SVGPathSeg.prototype); ++ window.SVGPathSegLinetoAbs.prototype.toString = function () { ++ return "[object SVGPathSegLinetoAbs]"; ++ }; ++ window.SVGPathSegLinetoAbs.prototype._asPathString = function () { ++ return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; ++ }; ++ window.SVGPathSegLinetoAbs.prototype.clone = function () { ++ return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y); ++ }; ++ Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "x", { ++ get: function get() { ++ return this._x; ++ }, ++ set: function set(x) { ++ this._x = x; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "y", { ++ get: function get() { ++ return this._y; ++ }, ++ set: function set(y) { ++ this._y = y; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ ++ window.SVGPathSegLinetoRel = function (owningPathSegList, x, y) { ++ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_REL, "l", owningPathSegList); ++ this._x = x; ++ this._y = y; ++ }; ++ window.SVGPathSegLinetoRel.prototype = Object.create(window.SVGPathSeg.prototype); ++ window.SVGPathSegLinetoRel.prototype.toString = function () { ++ return "[object SVGPathSegLinetoRel]"; ++ }; ++ window.SVGPathSegLinetoRel.prototype._asPathString = function () { ++ return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; ++ }; ++ window.SVGPathSegLinetoRel.prototype.clone = function () { ++ return new window.SVGPathSegLinetoRel(undefined, this._x, this._y); ++ }; ++ Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "x", { ++ get: function get() { ++ return this._x; ++ }, ++ set: function set(x) { ++ this._x = x; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "y", { ++ get: function get() { ++ return this._y; ++ }, ++ set: function set(y) { ++ this._y = y; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ ++ window.SVGPathSegCurvetoCubicAbs = function (owningPathSegList, x, y, x1, y1, x2, y2) { ++ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, "C", owningPathSegList); ++ this._x = x; ++ this._y = y; ++ this._x1 = x1; ++ this._y1 = y1; ++ this._x2 = x2; ++ this._y2 = y2; ++ }; ++ window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(window.SVGPathSeg.prototype); ++ window.SVGPathSegCurvetoCubicAbs.prototype.toString = function () { ++ return "[object SVGPathSegCurvetoCubicAbs]"; ++ }; ++ window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function () { ++ return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; ++ }; ++ window.SVGPathSegCurvetoCubicAbs.prototype.clone = function () { ++ return new window.SVGPathSegCurvetoCubicAbs(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); ++ }; ++ Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x", { ++ get: function get() { ++ return this._x; ++ }, ++ set: function set(x) { ++ this._x = x; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y", { ++ get: function get() { ++ return this._y; ++ }, ++ set: function set(y) { ++ this._y = y; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x1", { ++ get: function get() { ++ return this._x1; ++ }, ++ set: function set(x1) { ++ this._x1 = x1; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y1", { ++ get: function get() { ++ return this._y1; ++ }, ++ set: function set(y1) { ++ this._y1 = y1; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x2", { ++ get: function get() { ++ return this._x2; ++ }, ++ set: function set(x2) { ++ this._x2 = x2; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y2", { ++ get: function get() { ++ return this._y2; ++ }, ++ set: function set(y2) { ++ this._y2 = y2; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ ++ window.SVGPathSegCurvetoCubicRel = function (owningPathSegList, x, y, x1, y1, x2, y2) { ++ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, "c", owningPathSegList); ++ this._x = x; ++ this._y = y; ++ this._x1 = x1; ++ this._y1 = y1; ++ this._x2 = x2; ++ this._y2 = y2; ++ }; ++ window.SVGPathSegCurvetoCubicRel.prototype = Object.create(window.SVGPathSeg.prototype); ++ window.SVGPathSegCurvetoCubicRel.prototype.toString = function () { ++ return "[object SVGPathSegCurvetoCubicRel]"; ++ }; ++ window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function () { ++ return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; ++ }; ++ window.SVGPathSegCurvetoCubicRel.prototype.clone = function () { ++ return new window.SVGPathSegCurvetoCubicRel(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); ++ }; ++ Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x", { ++ get: function get() { ++ return this._x; ++ }, ++ set: function set(x) { ++ this._x = x; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y", { ++ get: function get() { ++ return this._y; ++ }, ++ set: function set(y) { ++ this._y = y; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x1", { ++ get: function get() { ++ return this._x1; ++ }, ++ set: function set(x1) { ++ this._x1 = x1; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y1", { ++ get: function get() { ++ return this._y1; ++ }, ++ set: function set(y1) { ++ this._y1 = y1; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x2", { ++ get: function get() { ++ return this._x2; ++ }, ++ set: function set(x2) { ++ this._x2 = x2; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y2", { ++ get: function get() { ++ return this._y2; ++ }, ++ set: function set(y2) { ++ this._y2 = y2; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ ++ window.SVGPathSegCurvetoQuadraticAbs = function (owningPathSegList, x, y, x1, y1) { ++ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, "Q", owningPathSegList); ++ this._x = x; ++ this._y = y; ++ this._x1 = x1; ++ this._y1 = y1; ++ }; ++ window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(window.SVGPathSeg.prototype); ++ window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function () { ++ return "[object SVGPathSegCurvetoQuadraticAbs]"; ++ }; ++ window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function () { ++ return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y; ++ }; ++ window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function () { ++ return new window.SVGPathSegCurvetoQuadraticAbs(undefined, this._x, this._y, this._x1, this._y1); ++ }; ++ Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x", { ++ get: function get() { ++ return this._x; ++ }, ++ set: function set(x) { ++ this._x = x; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y", { ++ get: function get() { ++ return this._y; ++ }, ++ set: function set(y) { ++ this._y = y; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x1", { ++ get: function get() { ++ return this._x1; ++ }, ++ set: function set(x1) { ++ this._x1 = x1; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y1", { ++ get: function get() { ++ return this._y1; ++ }, ++ set: function set(y1) { ++ this._y1 = y1; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ ++ window.SVGPathSegCurvetoQuadraticRel = function (owningPathSegList, x, y, x1, y1) { ++ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, "q", owningPathSegList); ++ this._x = x; ++ this._y = y; ++ this._x1 = x1; ++ this._y1 = y1; ++ }; ++ window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(window.SVGPathSeg.prototype); ++ window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function () { ++ return "[object SVGPathSegCurvetoQuadraticRel]"; ++ }; ++ window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function () { ++ return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y; ++ }; ++ window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function () { ++ return new window.SVGPathSegCurvetoQuadraticRel(undefined, this._x, this._y, this._x1, this._y1); ++ }; ++ Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x", { ++ get: function get() { ++ return this._x; ++ }, ++ set: function set(x) { ++ this._x = x; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y", { ++ get: function get() { ++ return this._y; ++ }, ++ set: function set(y) { ++ this._y = y; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x1", { ++ get: function get() { ++ return this._x1; ++ }, ++ set: function set(x1) { ++ this._x1 = x1; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y1", { ++ get: function get() { ++ return this._y1; ++ }, ++ set: function set(y1) { ++ this._y1 = y1; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ ++ window.SVGPathSegArcAbs = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) { ++ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_ABS, "A", owningPathSegList); ++ this._x = x; ++ this._y = y; ++ this._r1 = r1; ++ this._r2 = r2; ++ this._angle = angle; ++ this._largeArcFlag = largeArcFlag; ++ this._sweepFlag = sweepFlag; ++ }; ++ window.SVGPathSegArcAbs.prototype = Object.create(window.SVGPathSeg.prototype); ++ window.SVGPathSegArcAbs.prototype.toString = function () { ++ return "[object SVGPathSegArcAbs]"; ++ }; ++ window.SVGPathSegArcAbs.prototype._asPathString = function () { ++ return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y; ++ }; ++ window.SVGPathSegArcAbs.prototype.clone = function () { ++ return new window.SVGPathSegArcAbs(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); ++ }; ++ Object.defineProperty(window.SVGPathSegArcAbs.prototype, "x", { ++ get: function get() { ++ return this._x; ++ }, ++ set: function set(x) { ++ this._x = x; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegArcAbs.prototype, "y", { ++ get: function get() { ++ return this._y; ++ }, ++ set: function set(y) { ++ this._y = y; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r1", { ++ get: function get() { ++ return this._r1; ++ }, ++ set: function set(r1) { ++ this._r1 = r1; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r2", { ++ get: function get() { ++ return this._r2; ++ }, ++ set: function set(r2) { ++ this._r2 = r2; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegArcAbs.prototype, "angle", { ++ get: function get() { ++ return this._angle; ++ }, ++ set: function set(angle) { ++ this._angle = angle; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegArcAbs.prototype, "largeArcFlag", { ++ get: function get() { ++ return this._largeArcFlag; ++ }, ++ set: function set(largeArcFlag) { ++ this._largeArcFlag = largeArcFlag; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegArcAbs.prototype, "sweepFlag", { ++ get: function get() { ++ return this._sweepFlag; ++ }, ++ set: function set(sweepFlag) { ++ this._sweepFlag = sweepFlag; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ ++ window.SVGPathSegArcRel = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) { ++ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_REL, "a", owningPathSegList); ++ this._x = x; ++ this._y = y; ++ this._r1 = r1; ++ this._r2 = r2; ++ this._angle = angle; ++ this._largeArcFlag = largeArcFlag; ++ this._sweepFlag = sweepFlag; ++ }; ++ window.SVGPathSegArcRel.prototype = Object.create(window.SVGPathSeg.prototype); ++ window.SVGPathSegArcRel.prototype.toString = function () { ++ return "[object SVGPathSegArcRel]"; ++ }; ++ window.SVGPathSegArcRel.prototype._asPathString = function () { ++ return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y; ++ }; ++ window.SVGPathSegArcRel.prototype.clone = function () { ++ return new window.SVGPathSegArcRel(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); ++ }; ++ Object.defineProperty(window.SVGPathSegArcRel.prototype, "x", { ++ get: function get() { ++ return this._x; ++ }, ++ set: function set(x) { ++ this._x = x; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegArcRel.prototype, "y", { ++ get: function get() { ++ return this._y; ++ }, ++ set: function set(y) { ++ this._y = y; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegArcRel.prototype, "r1", { ++ get: function get() { ++ return this._r1; ++ }, ++ set: function set(r1) { ++ this._r1 = r1; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegArcRel.prototype, "r2", { ++ get: function get() { ++ return this._r2; ++ }, ++ set: function set(r2) { ++ this._r2 = r2; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegArcRel.prototype, "angle", { ++ get: function get() { ++ return this._angle; ++ }, ++ set: function set(angle) { ++ this._angle = angle; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegArcRel.prototype, "largeArcFlag", { ++ get: function get() { ++ return this._largeArcFlag; ++ }, ++ set: function set(largeArcFlag) { ++ this._largeArcFlag = largeArcFlag; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegArcRel.prototype, "sweepFlag", { ++ get: function get() { ++ return this._sweepFlag; ++ }, ++ set: function set(sweepFlag) { ++ this._sweepFlag = sweepFlag; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ ++ window.SVGPathSegLinetoHorizontalAbs = function (owningPathSegList, x) { ++ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, "H", owningPathSegList); ++ this._x = x; ++ }; ++ window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(window.SVGPathSeg.prototype); ++ window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function () { ++ return "[object SVGPathSegLinetoHorizontalAbs]"; ++ }; ++ window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function () { ++ return this.pathSegTypeAsLetter + " " + this._x; ++ }; ++ window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function () { ++ return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x); ++ }; ++ Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, "x", { ++ get: function get() { ++ return this._x; ++ }, ++ set: function set(x) { ++ this._x = x; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ ++ window.SVGPathSegLinetoHorizontalRel = function (owningPathSegList, x) { ++ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, "h", owningPathSegList); ++ this._x = x; ++ }; ++ window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(window.SVGPathSeg.prototype); ++ window.SVGPathSegLinetoHorizontalRel.prototype.toString = function () { ++ return "[object SVGPathSegLinetoHorizontalRel]"; ++ }; ++ window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function () { ++ return this.pathSegTypeAsLetter + " " + this._x; ++ }; ++ window.SVGPathSegLinetoHorizontalRel.prototype.clone = function () { ++ return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x); ++ }; ++ Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, "x", { ++ get: function get() { ++ return this._x; ++ }, ++ set: function set(x) { ++ this._x = x; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ ++ window.SVGPathSegLinetoVerticalAbs = function (owningPathSegList, y) { ++ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, "V", owningPathSegList); ++ this._y = y; ++ }; ++ window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(window.SVGPathSeg.prototype); ++ window.SVGPathSegLinetoVerticalAbs.prototype.toString = function () { ++ return "[object SVGPathSegLinetoVerticalAbs]"; ++ }; ++ window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function () { ++ return this.pathSegTypeAsLetter + " " + this._y; ++ }; ++ window.SVGPathSegLinetoVerticalAbs.prototype.clone = function () { ++ return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y); ++ }; ++ Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, "y", { ++ get: function get() { ++ return this._y; ++ }, ++ set: function set(y) { ++ this._y = y; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ ++ window.SVGPathSegLinetoVerticalRel = function (owningPathSegList, y) { ++ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, "v", owningPathSegList); ++ this._y = y; ++ }; ++ window.SVGPathSegLinetoVerticalRel.prototype = Object.create(window.SVGPathSeg.prototype); ++ window.SVGPathSegLinetoVerticalRel.prototype.toString = function () { ++ return "[object SVGPathSegLinetoVerticalRel]"; ++ }; ++ window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function () { ++ return this.pathSegTypeAsLetter + " " + this._y; ++ }; ++ window.SVGPathSegLinetoVerticalRel.prototype.clone = function () { ++ return new window.SVGPathSegLinetoVerticalRel(undefined, this._y); ++ }; ++ Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, "y", { ++ get: function get() { ++ return this._y; ++ }, ++ set: function set(y) { ++ this._y = y; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ ++ window.SVGPathSegCurvetoCubicSmoothAbs = function (owningPathSegList, x, y, x2, y2) { ++ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, "S", owningPathSegList); ++ this._x = x; ++ this._y = y; ++ this._x2 = x2; ++ this._y2 = y2; ++ }; ++ window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype); ++ window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function () { ++ return "[object SVGPathSegCurvetoCubicSmoothAbs]"; ++ }; ++ window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function () { ++ return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; ++ }; ++ window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function () { ++ return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, this._x, this._y, this._x2, this._y2); ++ }; ++ Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x", { ++ get: function get() { ++ return this._x; ++ }, ++ set: function set(x) { ++ this._x = x; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y", { ++ get: function get() { ++ return this._y; ++ }, ++ set: function set(y) { ++ this._y = y; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x2", { ++ get: function get() { ++ return this._x2; ++ }, ++ set: function set(x2) { ++ this._x2 = x2; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y2", { ++ get: function get() { ++ return this._y2; ++ }, ++ set: function set(y2) { ++ this._y2 = y2; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ ++ window.SVGPathSegCurvetoCubicSmoothRel = function (owningPathSegList, x, y, x2, y2) { ++ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, "s", owningPathSegList); ++ this._x = x; ++ this._y = y; ++ this._x2 = x2; ++ this._y2 = y2; ++ }; ++ window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype); ++ window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function () { ++ return "[object SVGPathSegCurvetoCubicSmoothRel]"; ++ }; ++ window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function () { ++ return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; ++ }; ++ window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function () { ++ return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, this._x, this._y, this._x2, this._y2); ++ }; ++ Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x", { ++ get: function get() { ++ return this._x; ++ }, ++ set: function set(x) { ++ this._x = x; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y", { ++ get: function get() { ++ return this._y; ++ }, ++ set: function set(y) { ++ this._y = y; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x2", { ++ get: function get() { ++ return this._x2; ++ }, ++ set: function set(x2) { ++ this._x2 = x2; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y2", { ++ get: function get() { ++ return this._y2; ++ }, ++ set: function set(y2) { ++ this._y2 = y2; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ ++ window.SVGPathSegCurvetoQuadraticSmoothAbs = function (owningPathSegList, x, y) { ++ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, "T", owningPathSegList); ++ this._x = x; ++ this._y = y; ++ }; ++ window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype); ++ window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function () { ++ return "[object SVGPathSegCurvetoQuadraticSmoothAbs]"; ++ }; ++ window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function () { ++ return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; ++ }; ++ window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function () { ++ return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, this._x, this._y); ++ }; ++ Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "x", { ++ get: function get() { ++ return this._x; ++ }, ++ set: function set(x) { ++ this._x = x; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "y", { ++ get: function get() { ++ return this._y; ++ }, ++ set: function set(y) { ++ this._y = y; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ ++ window.SVGPathSegCurvetoQuadraticSmoothRel = function (owningPathSegList, x, y) { ++ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, "t", owningPathSegList); ++ this._x = x; ++ this._y = y; ++ }; ++ window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype); ++ window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function () { ++ return "[object SVGPathSegCurvetoQuadraticSmoothRel]"; ++ }; ++ window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function () { ++ return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; ++ }; ++ window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function () { ++ return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, this._x, this._y); ++ }; ++ Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "x", { ++ get: function get() { ++ return this._x; ++ }, ++ set: function set(x) { ++ this._x = x; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "y", { ++ get: function get() { ++ return this._y; ++ }, ++ set: function set(y) { ++ this._y = y; ++ this._segmentChanged(); ++ }, ++ enumerable: true ++ }); ++ ++ // Add createSVGPathSeg* functions to window.SVGPathElement. ++ // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-Interfacewindow.SVGPathElement. ++ window.SVGPathElement.prototype.createSVGPathSegClosePath = function () { ++ return new window.SVGPathSegClosePath(undefined); ++ }; ++ window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function (x, y) { ++ return new window.SVGPathSegMovetoAbs(undefined, x, y); ++ }; ++ window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function (x, y) { ++ return new window.SVGPathSegMovetoRel(undefined, x, y); ++ }; ++ window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function (x, y) { ++ return new window.SVGPathSegLinetoAbs(undefined, x, y); ++ }; ++ window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function (x, y) { ++ return new window.SVGPathSegLinetoRel(undefined, x, y); ++ }; ++ window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function (x, y, x1, y1, x2, y2) { ++ return new window.SVGPathSegCurvetoCubicAbs(undefined, x, y, x1, y1, x2, y2); ++ }; ++ window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function (x, y, x1, y1, x2, y2) { ++ return new window.SVGPathSegCurvetoCubicRel(undefined, x, y, x1, y1, x2, y2); ++ }; ++ window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function (x, y, x1, y1) { ++ return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1); ++ }; ++ window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function (x, y, x1, y1) { ++ return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1); ++ }; ++ window.SVGPathElement.prototype.createSVGPathSegArcAbs = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) { ++ return new window.SVGPathSegArcAbs(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag); ++ }; ++ window.SVGPathElement.prototype.createSVGPathSegArcRel = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) { ++ return new window.SVGPathSegArcRel(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag); ++ }; ++ window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function (x) { ++ return new window.SVGPathSegLinetoHorizontalAbs(undefined, x); ++ }; ++ window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function (x) { ++ return new window.SVGPathSegLinetoHorizontalRel(undefined, x); ++ }; ++ window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function (y) { ++ return new window.SVGPathSegLinetoVerticalAbs(undefined, y); ++ }; ++ window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function (y) { ++ return new window.SVGPathSegLinetoVerticalRel(undefined, y); ++ }; ++ window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function (x, y, x2, y2) { ++ return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2); ++ }; ++ window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function (x, y, x2, y2) { ++ return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2); ++ }; ++ window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function (x, y) { ++ return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y); ++ }; ++ window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function (x, y) { ++ return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y); ++ }; ++ ++ if (!("getPathSegAtLength" in window.SVGPathElement.prototype)) { ++ // Add getPathSegAtLength to SVGPathElement. ++ // Spec: https://www.w3.org/TR/SVG11/single-page.html#paths-__svg__SVGPathElement__getPathSegAtLength ++ // This polyfill requires SVGPathElement.getTotalLength to implement the distance-along-a-path algorithm. ++ window.SVGPathElement.prototype.getPathSegAtLength = function (distance) { ++ if (distance === undefined || !isFinite(distance)) throw "Invalid arguments."; ++ ++ var measurementElement = document.createElementNS("http://www.w3.org/2000/svg", "path"); ++ measurementElement.setAttribute("d", this.getAttribute("d")); ++ var lastPathSegment = measurementElement.pathSegList.numberOfItems - 1; ++ ++ // If the path is empty, return 0. ++ if (lastPathSegment <= 0) return 0; ++ ++ do { ++ measurementElement.pathSegList.removeItem(lastPathSegment); ++ if (distance > measurementElement.getTotalLength()) break; ++ lastPathSegment--; ++ } while (lastPathSegment > 0); ++ return lastPathSegment; ++ }; ++ } ++ } ++ ++ if (!("SVGPathSegList" in window)) { ++ // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList ++ window.SVGPathSegList = function (pathElement) { ++ this._pathElement = pathElement; ++ this._list = this._parsePath(this._pathElement.getAttribute("d")); ++ ++ // Use a MutationObserver to catch changes to the path's "d" attribute. ++ this._mutationObserverConfig = { ++ "attributes": true, ++ "attributeFilter": ["d"] ++ }; ++ this._pathElementMutationObserver = new MutationObserver(this._updateListFromPathMutations.bind(this)); ++ this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig); ++ }; ++ ++ window.SVGPathSegList.prototype.classname = "SVGPathSegList"; ++ ++ Object.defineProperty(window.SVGPathSegList.prototype, "numberOfItems", { ++ get: function get() { ++ this._checkPathSynchronizedToList(); ++ return this._list.length; ++ }, ++ enumerable: true ++ }); ++ ++ // Add the pathSegList accessors to window.SVGPathElement. ++ // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData ++ Object.defineProperty(window.SVGPathElement.prototype, "pathSegList", { ++ get: function get() { ++ if (!this._pathSegList) this._pathSegList = new window.SVGPathSegList(this); ++ return this._pathSegList; ++ }, ++ enumerable: true ++ }); ++ // FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList. ++ Object.defineProperty(window.SVGPathElement.prototype, "normalizedPathSegList", { ++ get: function get() { ++ return this.pathSegList; ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathElement.prototype, "animatedPathSegList", { ++ get: function get() { ++ return this.pathSegList; ++ }, ++ enumerable: true ++ }); ++ Object.defineProperty(window.SVGPathElement.prototype, "animatedNormalizedPathSegList", { ++ get: function get() { ++ return this.pathSegList; ++ }, ++ enumerable: true ++ }); ++ ++ // Process any pending mutations to the path element and update the list as needed. ++ // This should be the first call of all public functions and is needed because ++ // MutationObservers are not synchronous so we can have pending asynchronous mutations. ++ window.SVGPathSegList.prototype._checkPathSynchronizedToList = function () { ++ this._updateListFromPathMutations(this._pathElementMutationObserver.takeRecords()); ++ }; ++ ++ window.SVGPathSegList.prototype._updateListFromPathMutations = function (mutationRecords) { ++ if (!this._pathElement) return; ++ var hasPathMutations = false; ++ mutationRecords.forEach(function (record) { ++ if (record.attributeName == "d") hasPathMutations = true; ++ }); ++ if (hasPathMutations) this._list = this._parsePath(this._pathElement.getAttribute("d")); ++ }; ++ ++ // Serialize the list and update the path's 'd' attribute. ++ window.SVGPathSegList.prototype._writeListToPath = function () { ++ this._pathElementMutationObserver.disconnect(); ++ this._pathElement.setAttribute("d", window.SVGPathSegList._pathSegArrayAsString(this._list)); ++ this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig); ++ }; ++ ++ // When a path segment changes the list needs to be synchronized back to the path element. ++ window.SVGPathSegList.prototype.segmentChanged = function (pathSeg) { ++ this._writeListToPath(); ++ }; ++ ++ window.SVGPathSegList.prototype.clear = function () { ++ this._checkPathSynchronizedToList(); ++ ++ this._list.forEach(function (pathSeg) { ++ pathSeg._owningPathSegList = null; ++ }); ++ this._list = []; ++ this._writeListToPath(); ++ }; ++ ++ window.SVGPathSegList.prototype.initialize = function (newItem) { ++ this._checkPathSynchronizedToList(); ++ ++ this._list = [newItem]; ++ newItem._owningPathSegList = this; ++ this._writeListToPath(); ++ return newItem; ++ }; ++ ++ window.SVGPathSegList.prototype._checkValidIndex = function (index) { ++ if (isNaN(index) || index < 0 || index >= this.numberOfItems) throw "INDEX_SIZE_ERR"; ++ }; ++ ++ window.SVGPathSegList.prototype.getItem = function (index) { ++ this._checkPathSynchronizedToList(); ++ ++ this._checkValidIndex(index); ++ return this._list[index]; ++ }; ++ ++ window.SVGPathSegList.prototype.insertItemBefore = function (newItem, index) { ++ this._checkPathSynchronizedToList(); ++ ++ // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list. ++ if (index > this.numberOfItems) index = this.numberOfItems; ++ if (newItem._owningPathSegList) { ++ // SVG2 spec says to make a copy. ++ newItem = newItem.clone(); ++ } ++ this._list.splice(index, 0, newItem); ++ newItem._owningPathSegList = this; ++ this._writeListToPath(); ++ return newItem; ++ }; ++ ++ window.SVGPathSegList.prototype.replaceItem = function (newItem, index) { ++ this._checkPathSynchronizedToList(); ++ ++ if (newItem._owningPathSegList) { ++ // SVG2 spec says to make a copy. ++ newItem = newItem.clone(); ++ } ++ this._checkValidIndex(index); ++ this._list[index] = newItem; ++ newItem._owningPathSegList = this; ++ this._writeListToPath(); ++ return newItem; ++ }; ++ ++ window.SVGPathSegList.prototype.removeItem = function (index) { ++ this._checkPathSynchronizedToList(); ++ ++ this._checkValidIndex(index); ++ var item = this._list[index]; ++ this._list.splice(index, 1); ++ this._writeListToPath(); ++ return item; ++ }; ++ ++ window.SVGPathSegList.prototype.appendItem = function (newItem) { ++ this._checkPathSynchronizedToList(); ++ ++ if (newItem._owningPathSegList) { ++ // SVG2 spec says to make a copy. ++ newItem = newItem.clone(); ++ } ++ this._list.push(newItem); ++ newItem._owningPathSegList = this; ++ // TODO: Optimize this to just append to the existing attribute. ++ this._writeListToPath(); ++ return newItem; ++ }; ++ ++ window.SVGPathSegList._pathSegArrayAsString = function (pathSegArray) { ++ var string = ""; ++ var first = true; ++ pathSegArray.forEach(function (pathSeg) { ++ if (first) { ++ first = false; ++ string += pathSeg._asPathString(); ++ } else { ++ string += " " + pathSeg._asPathString(); ++ } ++ }); ++ return string; ++ }; ++ ++ // This closely follows SVGPathParser::parsePath from Source/core/svg/SVGPathParser.cpp. ++ window.SVGPathSegList.prototype._parsePath = function (string) { ++ if (!string || string.length == 0) return []; ++ ++ var owningPathSegList = this; ++ ++ var Builder = function Builder() { ++ this.pathSegList = []; ++ }; ++ ++ Builder.prototype.appendSegment = function (pathSeg) { ++ this.pathSegList.push(pathSeg); ++ }; ++ ++ var Source = function Source(string) { ++ this._string = string; ++ this._currentIndex = 0; ++ this._endIndex = this._string.length; ++ this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN; ++ ++ this._skipOptionalSpaces(); ++ }; ++ ++ Source.prototype._isCurrentSpace = function () { ++ var character = this._string[this._currentIndex]; ++ return character <= " " && (character == " " || character == "\n" || character == "\t" || character == "\r" || character == "\f"); ++ }; ++ ++ Source.prototype._skipOptionalSpaces = function () { ++ while (this._currentIndex < this._endIndex && this._isCurrentSpace()) { ++ this._currentIndex++; ++ }return this._currentIndex < this._endIndex; ++ }; ++ ++ Source.prototype._skipOptionalSpacesOrDelimiter = function () { ++ if (this._currentIndex < this._endIndex && !this._isCurrentSpace() && this._string.charAt(this._currentIndex) != ",") return false; ++ if (this._skipOptionalSpaces()) { ++ if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ",") { ++ this._currentIndex++; ++ this._skipOptionalSpaces(); ++ } ++ } ++ return this._currentIndex < this._endIndex; ++ }; ++ ++ Source.prototype.hasMoreData = function () { ++ return this._currentIndex < this._endIndex; ++ }; ++ ++ Source.prototype.peekSegmentType = function () { ++ var lookahead = this._string[this._currentIndex]; ++ return this._pathSegTypeFromChar(lookahead); ++ }; ++ ++ Source.prototype._pathSegTypeFromChar = function (lookahead) { ++ switch (lookahead) { ++ case "Z": ++ case "z": ++ return window.SVGPathSeg.PATHSEG_CLOSEPATH; ++ case "M": ++ return window.SVGPathSeg.PATHSEG_MOVETO_ABS; ++ case "m": ++ return window.SVGPathSeg.PATHSEG_MOVETO_REL; ++ case "L": ++ return window.SVGPathSeg.PATHSEG_LINETO_ABS; ++ case "l": ++ return window.SVGPathSeg.PATHSEG_LINETO_REL; ++ case "C": ++ return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS; ++ case "c": ++ return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL; ++ case "Q": ++ return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS; ++ case "q": ++ return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL; ++ case "A": ++ return window.SVGPathSeg.PATHSEG_ARC_ABS; ++ case "a": ++ return window.SVGPathSeg.PATHSEG_ARC_REL; ++ case "H": ++ return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS; ++ case "h": ++ return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL; ++ case "V": ++ return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS; ++ case "v": ++ return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL; ++ case "S": ++ return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS; ++ case "s": ++ return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL; ++ case "T": ++ return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS; ++ case "t": ++ return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL; ++ default: ++ return window.SVGPathSeg.PATHSEG_UNKNOWN; ++ } ++ }; ++ ++ Source.prototype._nextCommandHelper = function (lookahead, previousCommand) { ++ // Check for remaining coordinates in the current command. ++ if ((lookahead == "+" || lookahead == "-" || lookahead == "." || lookahead >= "0" && lookahead <= "9") && previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH) { ++ if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS) return window.SVGPathSeg.PATHSEG_LINETO_ABS; ++ if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL) return window.SVGPathSeg.PATHSEG_LINETO_REL; ++ return previousCommand; ++ } ++ return window.SVGPathSeg.PATHSEG_UNKNOWN; ++ }; ++ ++ Source.prototype.initialCommandIsMoveTo = function () { ++ // If the path is empty it is still valid, so return true. ++ if (!this.hasMoreData()) return true; ++ var command = this.peekSegmentType(); ++ // Path must start with moveTo. ++ return command == window.SVGPathSeg.PATHSEG_MOVETO_ABS || command == window.SVGPathSeg.PATHSEG_MOVETO_REL; ++ }; ++ ++ // Parse a number from an SVG path. This very closely follows genericParseNumber(...) from Source/core/svg/SVGParserUtilities.cpp. ++ // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-PathDataBNF ++ Source.prototype._parseNumber = function () { ++ var exponent = 0; ++ var integer = 0; ++ var frac = 1; ++ var decimal = 0; ++ var sign = 1; ++ var expsign = 1; ++ ++ var startIndex = this._currentIndex; ++ ++ this._skipOptionalSpaces(); ++ ++ // Read the sign. ++ if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "+") this._currentIndex++;else if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "-") { ++ this._currentIndex++; ++ sign = -1; ++ } ++ ++ if (this._currentIndex == this._endIndex || (this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") && this._string.charAt(this._currentIndex) != ".") ++ // The first character of a number must be one of [0-9+-.]. ++ return undefined; ++ ++ // Read the integer part, build right-to-left. ++ var startIntPartIndex = this._currentIndex; ++ while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") { ++ this._currentIndex++; ++ } // Advance to first non-digit. ++ ++ if (this._currentIndex != startIntPartIndex) { ++ var scanIntPartIndex = this._currentIndex - 1; ++ var multiplier = 1; ++ while (scanIntPartIndex >= startIntPartIndex) { ++ integer += multiplier * (this._string.charAt(scanIntPartIndex--) - "0"); ++ multiplier *= 10; ++ } ++ } ++ ++ // Read the decimals. ++ if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ".") { ++ this._currentIndex++; ++ ++ // There must be a least one digit following the . ++ if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") return undefined; ++ while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") { ++ frac *= 10; ++ decimal += (this._string.charAt(this._currentIndex) - "0") / frac; ++ this._currentIndex += 1; ++ } ++ } ++ ++ // Read the exponent part. ++ if (this._currentIndex != startIndex && this._currentIndex + 1 < this._endIndex && (this._string.charAt(this._currentIndex) == "e" || this._string.charAt(this._currentIndex) == "E") && this._string.charAt(this._currentIndex + 1) != "x" && this._string.charAt(this._currentIndex + 1) != "m") { ++ this._currentIndex++; ++ ++ // Read the sign of the exponent. ++ if (this._string.charAt(this._currentIndex) == "+") { ++ this._currentIndex++; ++ } else if (this._string.charAt(this._currentIndex) == "-") { ++ this._currentIndex++; ++ expsign = -1; ++ } ++ ++ // There must be an exponent. ++ if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") return undefined; ++ ++ while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") { ++ exponent *= 10; ++ exponent += this._string.charAt(this._currentIndex) - "0"; ++ this._currentIndex++; ++ } ++ } ++ ++ var number = integer + decimal; ++ number *= sign; ++ ++ if (exponent) number *= Math.pow(10, expsign * exponent); ++ ++ if (startIndex == this._currentIndex) return undefined; ++ ++ this._skipOptionalSpacesOrDelimiter(); ++ ++ return number; ++ }; ++ ++ Source.prototype._parseArcFlag = function () { ++ if (this._currentIndex >= this._endIndex) return undefined; ++ var flag = false; ++ var flagChar = this._string.charAt(this._currentIndex++); ++ if (flagChar == "0") flag = false;else if (flagChar == "1") flag = true;else return undefined; ++ ++ this._skipOptionalSpacesOrDelimiter(); ++ return flag; ++ }; ++ ++ Source.prototype.parseSegment = function () { ++ var lookahead = this._string[this._currentIndex]; ++ var command = this._pathSegTypeFromChar(lookahead); ++ if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) { ++ // Possibly an implicit command. Not allowed if this is the first command. ++ if (this._previousCommand == window.SVGPathSeg.PATHSEG_UNKNOWN) return null; ++ command = this._nextCommandHelper(lookahead, this._previousCommand); ++ if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) return null; ++ } else { ++ this._currentIndex++; ++ } ++ ++ this._previousCommand = command; ++ ++ switch (command) { ++ case window.SVGPathSeg.PATHSEG_MOVETO_REL: ++ return new window.SVGPathSegMovetoRel(owningPathSegList, this._parseNumber(), this._parseNumber()); ++ case window.SVGPathSeg.PATHSEG_MOVETO_ABS: ++ return new window.SVGPathSegMovetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber()); ++ case window.SVGPathSeg.PATHSEG_LINETO_REL: ++ return new window.SVGPathSegLinetoRel(owningPathSegList, this._parseNumber(), this._parseNumber()); ++ case window.SVGPathSeg.PATHSEG_LINETO_ABS: ++ return new window.SVGPathSegLinetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber()); ++ case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL: ++ return new window.SVGPathSegLinetoHorizontalRel(owningPathSegList, this._parseNumber()); ++ case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS: ++ return new window.SVGPathSegLinetoHorizontalAbs(owningPathSegList, this._parseNumber()); ++ case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL: ++ return new window.SVGPathSegLinetoVerticalRel(owningPathSegList, this._parseNumber()); ++ case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS: ++ return new window.SVGPathSegLinetoVerticalAbs(owningPathSegList, this._parseNumber()); ++ case window.SVGPathSeg.PATHSEG_CLOSEPATH: ++ this._skipOptionalSpaces(); ++ return new window.SVGPathSegClosePath(owningPathSegList); ++ case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL: ++ var points = { ++ x1: this._parseNumber(), ++ y1: this._parseNumber(), ++ x2: this._parseNumber(), ++ y2: this._parseNumber(), ++ x: this._parseNumber(), ++ y: this._parseNumber() ++ }; ++ return new window.SVGPathSegCurvetoCubicRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2); ++ case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS: ++ var points = { ++ x1: this._parseNumber(), ++ y1: this._parseNumber(), ++ x2: this._parseNumber(), ++ y2: this._parseNumber(), ++ x: this._parseNumber(), ++ y: this._parseNumber() ++ }; ++ return new window.SVGPathSegCurvetoCubicAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2); ++ case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL: ++ var points = { ++ x2: this._parseNumber(), ++ y2: this._parseNumber(), ++ x: this._parseNumber(), ++ y: this._parseNumber() ++ }; ++ return new window.SVGPathSegCurvetoCubicSmoothRel(owningPathSegList, points.x, points.y, points.x2, points.y2); ++ case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS: ++ var points = { ++ x2: this._parseNumber(), ++ y2: this._parseNumber(), ++ x: this._parseNumber(), ++ y: this._parseNumber() ++ }; ++ return new window.SVGPathSegCurvetoCubicSmoothAbs(owningPathSegList, points.x, points.y, points.x2, points.y2); ++ case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL: ++ var points = { ++ x1: this._parseNumber(), ++ y1: this._parseNumber(), ++ x: this._parseNumber(), ++ y: this._parseNumber() ++ }; ++ return new window.SVGPathSegCurvetoQuadraticRel(owningPathSegList, points.x, points.y, points.x1, points.y1); ++ case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS: ++ var points = { ++ x1: this._parseNumber(), ++ y1: this._parseNumber(), ++ x: this._parseNumber(), ++ y: this._parseNumber() ++ }; ++ return new window.SVGPathSegCurvetoQuadraticAbs(owningPathSegList, points.x, points.y, points.x1, points.y1); ++ case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL: ++ return new window.SVGPathSegCurvetoQuadraticSmoothRel(owningPathSegList, this._parseNumber(), this._parseNumber()); ++ case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS: ++ return new window.SVGPathSegCurvetoQuadraticSmoothAbs(owningPathSegList, this._parseNumber(), this._parseNumber()); ++ case window.SVGPathSeg.PATHSEG_ARC_REL: ++ var points = { ++ x1: this._parseNumber(), ++ y1: this._parseNumber(), ++ arcAngle: this._parseNumber(), ++ arcLarge: this._parseArcFlag(), ++ arcSweep: this._parseArcFlag(), ++ x: this._parseNumber(), ++ y: this._parseNumber() ++ }; ++ return new window.SVGPathSegArcRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep); ++ case window.SVGPathSeg.PATHSEG_ARC_ABS: ++ var points = { ++ x1: this._parseNumber(), ++ y1: this._parseNumber(), ++ arcAngle: this._parseNumber(), ++ arcLarge: this._parseArcFlag(), ++ arcSweep: this._parseArcFlag(), ++ x: this._parseNumber(), ++ y: this._parseNumber() ++ }; ++ return new window.SVGPathSegArcAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep); ++ default: ++ throw "Unknown path seg type."; ++ } ++ }; ++ ++ var builder = new Builder(); ++ var source = new Source(string); ++ ++ if (!source.initialCommandIsMoveTo()) return []; ++ while (source.hasMoreData()) { ++ var pathSeg = source.parseSegment(); ++ if (!pathSeg) return []; ++ builder.appendSegment(pathSeg); ++ } ++ ++ return builder.pathSegList; ++ }; ++ } ++ })(); ++ ++ // String.padEnd polyfill for IE11 ++ // ++ // https://github.com/uxitten/polyfill/blob/master/string.polyfill.js ++ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd ++ if (!String.prototype.padEnd) { ++ String.prototype.padEnd = function padEnd(targetLength, padString) { ++ targetLength = targetLength >> 0; //floor if number or convert non-number to 0; ++ padString = String(typeof padString !== 'undefined' ? padString : ' '); ++ if (this.length > targetLength) { ++ return String(this); ++ } else { ++ targetLength = targetLength - this.length; ++ if (targetLength > padString.length) { ++ padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed ++ } ++ return String(this) + padString.slice(0, targetLength); ++ } ++ }; ++ } ++ ++ /* jshint ignore:end */ ++ ++ Chart.prototype.axis = function () {}; ++ Chart.prototype.axis.labels = function (labels) { ++ var $$ = this.internal; ++ if (arguments.length) { ++ Object.keys(labels).forEach(function (axisId) { ++ $$.axis.setLabelText(axisId, labels[axisId]); ++ }); ++ $$.axis.updateLabels(); ++ } ++ // TODO: return some values? ++ }; ++ Chart.prototype.axis.max = function (max) { ++ var $$ = this.internal, ++ config = $$.config; ++ if (arguments.length) { ++ if ((typeof max === 'undefined' ? 'undefined' : _typeof(max)) === 'object') { ++ if (isValue(max.x)) { ++ config.axis_x_max = max.x; ++ } ++ if (isValue(max.y)) { ++ config.axis_y_max = max.y; ++ } ++ if (isValue(max.y2)) { ++ config.axis_y2_max = max.y2; ++ } ++ } else { ++ config.axis_y_max = config.axis_y2_max = max; ++ } ++ $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true }); ++ } else { ++ return { ++ x: config.axis_x_max, ++ y: config.axis_y_max, ++ y2: config.axis_y2_max ++ }; ++ } ++ }; ++ Chart.prototype.axis.min = function (min) { ++ var $$ = this.internal, ++ config = $$.config; ++ if (arguments.length) { ++ if ((typeof min === 'undefined' ? 'undefined' : _typeof(min)) === 'object') { ++ if (isValue(min.x)) { ++ config.axis_x_min = min.x; ++ } ++ if (isValue(min.y)) { ++ config.axis_y_min = min.y; ++ } ++ if (isValue(min.y2)) { ++ config.axis_y2_min = min.y2; ++ } ++ } else { ++ config.axis_y_min = config.axis_y2_min = min; ++ } ++ $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true }); ++ } else { ++ return { ++ x: config.axis_x_min, ++ y: config.axis_y_min, ++ y2: config.axis_y2_min ++ }; ++ } ++ }; ++ Chart.prototype.axis.range = function (range) { ++ if (arguments.length) { ++ if (isDefined(range.max)) { ++ this.axis.max(range.max); ++ } ++ if (isDefined(range.min)) { ++ this.axis.min(range.min); ++ } ++ } else { ++ return { ++ max: this.axis.max(), ++ min: this.axis.min() ++ }; ++ } ++ }; ++ ++ Chart.prototype.category = function (i, category) { ++ var $$ = this.internal, ++ config = $$.config; ++ if (arguments.length > 1) { ++ config.axis_x_categories[i] = category; ++ $$.redraw(); ++ } ++ return config.axis_x_categories[i]; ++ }; ++ Chart.prototype.categories = function (categories) { ++ var $$ = this.internal, ++ config = $$.config; ++ if (!arguments.length) { ++ return config.axis_x_categories; ++ } ++ config.axis_x_categories = categories; ++ $$.redraw(); ++ return config.axis_x_categories; ++ }; ++ ++ Chart.prototype.resize = function (size) { ++ var $$ = this.internal, ++ config = $$.config; ++ config.size_width = size ? size.width : null; ++ config.size_height = size ? size.height : null; ++ this.flush(); ++ }; ++ ++ Chart.prototype.flush = function () { ++ var $$ = this.internal; ++ $$.updateAndRedraw({ withLegend: true, withTransition: false, withTransitionForTransform: false }); ++ }; ++ ++ Chart.prototype.destroy = function () { ++ var $$ = this.internal; ++ ++ window.clearInterval($$.intervalForObserveInserted); ++ ++ if ($$.resizeTimeout !== undefined) { ++ window.clearTimeout($$.resizeTimeout); ++ } ++ ++ if (window.detachEvent) { ++ window.detachEvent('onresize', $$.resizeIfElementDisplayed); ++ } else if (window.removeEventListener) { ++ window.removeEventListener('resize', $$.resizeIfElementDisplayed); ++ } else { ++ var wrapper = window.onresize; ++ // check if no one else removed our wrapper and remove our resizeFunction from it ++ if (wrapper && wrapper.add && wrapper.remove) { ++ wrapper.remove($$.resizeFunction); ++ } ++ } ++ ++ // remove the inner resize functions ++ $$.resizeFunction.remove(); ++ ++ $$.selectChart.classed('c3', false).html(""); ++ ++ // MEMO: this is needed because the reference of some elements will not be released, then memory leak will happen. ++ Object.keys($$).forEach(function (key) { ++ $$[key] = null; ++ }); ++ ++ return null; ++ }; ++ ++ // TODO: fix ++ Chart.prototype.color = function (id) { ++ var $$ = this.internal; ++ return $$.color(id); // more patterns ++ }; ++ ++ Chart.prototype.data = function (targetIds) { ++ var targets = this.internal.data.targets; ++ return typeof targetIds === 'undefined' ? targets : targets.filter(function (t) { ++ return [].concat(targetIds).indexOf(t.id) >= 0; ++ }); ++ }; ++ Chart.prototype.data.shown = function (targetIds) { ++ return this.internal.filterTargetsToShow(this.data(targetIds)); ++ }; ++ Chart.prototype.data.values = function (targetId) { ++ var targets, ++ values = null; ++ if (targetId) { ++ targets = this.data(targetId); ++ values = targets[0] ? targets[0].values.map(function (d) { ++ return d.value; ++ }) : null; ++ } ++ return values; ++ }; ++ Chart.prototype.data.names = function (names) { ++ this.internal.clearLegendItemTextBoxCache(); ++ return this.internal.updateDataAttributes('names', names); ++ }; ++ Chart.prototype.data.colors = function (colors) { ++ return this.internal.updateDataAttributes('colors', colors); ++ }; ++ Chart.prototype.data.axes = function (axes) { ++ return this.internal.updateDataAttributes('axes', axes); ++ }; ++ ++ Chart.prototype.flow = function (args) { ++ var $$ = this.internal, ++ targets, ++ data, ++ notfoundIds = [], ++ orgDataCount = $$.getMaxDataCount(), ++ dataCount, ++ domain, ++ baseTarget, ++ baseValue, ++ length = 0, ++ tail = 0, ++ diff, ++ to; ++ ++ if (args.json) { ++ data = $$.convertJsonToData(args.json, args.keys); ++ } else if (args.rows) { ++ data = $$.convertRowsToData(args.rows); ++ } else if (args.columns) { ++ data = $$.convertColumnsToData(args.columns); ++ } else { ++ return; ++ } ++ targets = $$.convertDataToTargets(data, true); ++ ++ // Update/Add data ++ $$.data.targets.forEach(function (t) { ++ var found = false, ++ i, ++ j; ++ for (i = 0; i < targets.length; i++) { ++ if (t.id === targets[i].id) { ++ found = true; ++ ++ if (t.values[t.values.length - 1]) { ++ tail = t.values[t.values.length - 1].index + 1; ++ } ++ length = targets[i].values.length; ++ ++ for (j = 0; j < length; j++) { ++ targets[i].values[j].index = tail + j; ++ if (!$$.isTimeSeries()) { ++ targets[i].values[j].x = tail + j; ++ } ++ } ++ t.values = t.values.concat(targets[i].values); ++ ++ targets.splice(i, 1); ++ break; ++ } ++ } ++ if (!found) { ++ notfoundIds.push(t.id); ++ } ++ }); ++ ++ // Append null for not found targets ++ $$.data.targets.forEach(function (t) { ++ var i, j; ++ for (i = 0; i < notfoundIds.length; i++) { ++ if (t.id === notfoundIds[i]) { ++ tail = t.values[t.values.length - 1].index + 1; ++ for (j = 0; j < length; j++) { ++ t.values.push({ ++ id: t.id, ++ index: tail + j, ++ x: $$.isTimeSeries() ? $$.getOtherTargetX(tail + j) : tail + j, ++ value: null ++ }); ++ } ++ } ++ } ++ }); ++ ++ // Generate null values for new target ++ if ($$.data.targets.length) { ++ targets.forEach(function (t) { ++ var i, ++ missing = []; ++ for (i = $$.data.targets[0].values[0].index; i < tail; i++) { ++ missing.push({ ++ id: t.id, ++ index: i, ++ x: $$.isTimeSeries() ? $$.getOtherTargetX(i) : i, ++ value: null ++ }); ++ } ++ t.values.forEach(function (v) { ++ v.index += tail; ++ if (!$$.isTimeSeries()) { ++ v.x += tail; ++ } ++ }); ++ t.values = missing.concat(t.values); ++ }); ++ } ++ $$.data.targets = $$.data.targets.concat(targets); // add remained ++ ++ // check data count because behavior needs to change when it's only one ++ dataCount = $$.getMaxDataCount(); ++ baseTarget = $$.data.targets[0]; ++ baseValue = baseTarget.values[0]; ++ ++ // Update length to flow if needed ++ if (isDefined(args.to)) { ++ length = 0; ++ to = $$.isTimeSeries() ? $$.parseDate(args.to) : args.to; ++ baseTarget.values.forEach(function (v) { ++ if (v.x < to) { ++ length++; ++ } ++ }); ++ } else if (isDefined(args.length)) { ++ length = args.length; ++ } ++ ++ // If only one data, update the domain to flow from left edge of the chart ++ if (!orgDataCount) { ++ if ($$.isTimeSeries()) { ++ if (baseTarget.values.length > 1) { ++ diff = baseTarget.values[baseTarget.values.length - 1].x - baseValue.x; ++ } else { ++ diff = baseValue.x - $$.getXDomain($$.data.targets)[0]; ++ } ++ } else { ++ diff = 1; ++ } ++ domain = [baseValue.x - diff, baseValue.x]; ++ $$.updateXDomain(null, true, true, false, domain); ++ } else if (orgDataCount === 1) { ++ if ($$.isTimeSeries()) { ++ diff = (baseTarget.values[baseTarget.values.length - 1].x - baseValue.x) / 2; ++ domain = [new Date(+baseValue.x - diff), new Date(+baseValue.x + diff)]; ++ $$.updateXDomain(null, true, true, false, domain); ++ } ++ } ++ ++ // Set targets ++ $$.updateTargets($$.data.targets); ++ ++ // Redraw with new targets ++ $$.redraw({ ++ flow: { ++ index: baseValue.index, ++ length: length, ++ duration: isValue(args.duration) ? args.duration : $$.config.transition_duration, ++ done: args.done, ++ orgDataCount: orgDataCount ++ }, ++ withLegend: true, ++ withTransition: orgDataCount > 1, ++ withTrimXDomain: false, ++ withUpdateXAxis: true ++ }); ++ }; ++ ++ ChartInternal.prototype.generateFlow = function (args) { ++ var $$ = this, ++ config = $$.config, ++ d3 = $$.d3; ++ ++ return function () { ++ var targets = args.targets, ++ flow = args.flow, ++ drawBar = args.drawBar, ++ drawLine = args.drawLine, ++ drawArea = args.drawArea, ++ cx = args.cx, ++ cy = args.cy, ++ xv = args.xv, ++ xForText = args.xForText, ++ yForText = args.yForText, ++ duration = args.duration; ++ ++ var translateX, ++ scaleX = 1, ++ transform, ++ flowIndex = flow.index, ++ flowLength = flow.length, ++ flowStart = $$.getValueOnIndex($$.data.targets[0].values, flowIndex), ++ flowEnd = $$.getValueOnIndex($$.data.targets[0].values, flowIndex + flowLength), ++ orgDomain = $$.x.domain(), ++ domain, ++ durationForFlow = flow.duration || duration, ++ done = flow.done || function () {}, ++ wait = $$.generateWait(); ++ ++ var xgrid, xgridLines, mainRegion, mainText, mainBar, mainLine, mainArea, mainCircle; ++ ++ // set flag ++ $$.flowing = true; ++ ++ // remove head data after rendered ++ $$.data.targets.forEach(function (d) { ++ d.values.splice(0, flowLength); ++ }); ++ ++ // update x domain to generate axis elements for flow ++ domain = $$.updateXDomain(targets, true, true); ++ // update elements related to x scale ++ if ($$.updateXGrid) { ++ $$.updateXGrid(true); ++ } ++ ++ xgrid = $$.xgrid || d3.selectAll([]); // xgrid needs to be obtained after updateXGrid ++ xgridLines = $$.xgridLines || d3.selectAll([]); ++ mainRegion = $$.mainRegion || d3.selectAll([]); ++ mainText = $$.mainText || d3.selectAll([]); ++ mainBar = $$.mainBar || d3.selectAll([]); ++ mainLine = $$.mainLine || d3.selectAll([]); ++ mainArea = $$.mainArea || d3.selectAll([]); ++ mainCircle = $$.mainCircle || d3.selectAll([]); ++ ++ // generate transform to flow ++ if (!flow.orgDataCount) { ++ // if empty ++ if ($$.data.targets[0].values.length !== 1) { ++ translateX = $$.x(orgDomain[0]) - $$.x(domain[0]); ++ } else { ++ if ($$.isTimeSeries()) { ++ flowStart = $$.getValueOnIndex($$.data.targets[0].values, 0); ++ flowEnd = $$.getValueOnIndex($$.data.targets[0].values, $$.data.targets[0].values.length - 1); ++ translateX = $$.x(flowStart.x) - $$.x(flowEnd.x); ++ } else { ++ translateX = diffDomain(domain) / 2; ++ } ++ } ++ } else if (flow.orgDataCount === 1 || (flowStart && flowStart.x) === (flowEnd && flowEnd.x)) { ++ translateX = $$.x(orgDomain[0]) - $$.x(domain[0]); ++ } else { ++ if ($$.isTimeSeries()) { ++ translateX = $$.x(orgDomain[0]) - $$.x(domain[0]); ++ } else { ++ translateX = $$.x(flowStart.x) - $$.x(flowEnd.x); ++ } ++ } ++ scaleX = diffDomain(orgDomain) / diffDomain(domain); ++ transform = 'translate(' + translateX + ',0) scale(' + scaleX + ',1)'; ++ ++ $$.hideXGridFocus(); ++ ++ var flowTransition = d3.transition().ease(d3.easeLinear).duration(durationForFlow); ++ wait.add($$.xAxis($$.axes.x, flowTransition)); ++ wait.add(mainBar.transition(flowTransition).attr('transform', transform)); ++ wait.add(mainLine.transition(flowTransition).attr('transform', transform)); ++ wait.add(mainArea.transition(flowTransition).attr('transform', transform)); ++ wait.add(mainCircle.transition(flowTransition).attr('transform', transform)); ++ wait.add(mainText.transition(flowTransition).attr('transform', transform)); ++ wait.add(mainRegion.filter($$.isRegionOnX).transition(flowTransition).attr('transform', transform)); ++ wait.add(xgrid.transition(flowTransition).attr('transform', transform)); ++ wait.add(xgridLines.transition(flowTransition).attr('transform', transform)); ++ wait(function () { ++ var i, ++ shapes = [], ++ texts = []; ++ ++ // remove flowed elements ++ if (flowLength) { ++ for (i = 0; i < flowLength; i++) { ++ shapes.push('.' + CLASS.shape + '-' + (flowIndex + i)); ++ texts.push('.' + CLASS.text + '-' + (flowIndex + i)); ++ } ++ $$.svg.selectAll('.' + CLASS.shapes).selectAll(shapes).remove(); ++ $$.svg.selectAll('.' + CLASS.texts).selectAll(texts).remove(); ++ $$.svg.select('.' + CLASS.xgrid).remove(); ++ } ++ ++ // draw again for removing flowed elements and reverting attr ++ xgrid.attr('transform', null).attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style("opacity", $$.xgridAttr.opacity); ++ xgridLines.attr('transform', null); ++ xgridLines.select('line').attr("x1", config.axis_rotated ? 0 : xv).attr("x2", config.axis_rotated ? $$.width : xv); ++ xgridLines.select('text').attr("x", config.axis_rotated ? $$.width : 0).attr("y", xv); ++ mainBar.attr('transform', null).attr("d", drawBar); ++ mainLine.attr('transform', null).attr("d", drawLine); ++ mainArea.attr('transform', null).attr("d", drawArea); ++ mainCircle.attr('transform', null).attr("cx", cx).attr("cy", cy); ++ mainText.attr('transform', null).attr('x', xForText).attr('y', yForText).style('fill-opacity', $$.opacityForText.bind($$)); ++ mainRegion.attr('transform', null); ++ mainRegion.filter($$.isRegionOnX).attr("x", $$.regionX.bind($$)).attr("width", $$.regionWidth.bind($$)); ++ ++ // callback for end of flow ++ done(); ++ ++ $$.flowing = false; ++ }); ++ }; ++ }; ++ ++ Chart.prototype.focus = function (targetIds) { ++ var $$ = this.internal, ++ candidates; ++ ++ targetIds = $$.mapToTargetIds(targetIds); ++ candidates = $$.svg.selectAll($$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))), this.revert(); ++ this.defocus(); ++ candidates.classed(CLASS.focused, true).classed(CLASS.defocused, false); ++ if ($$.hasArcType()) { ++ $$.expandArc(targetIds); ++ } ++ $$.toggleFocusLegend(targetIds, true); ++ ++ $$.focusedTargetIds = targetIds; ++ $$.defocusedTargetIds = $$.defocusedTargetIds.filter(function (id) { ++ return targetIds.indexOf(id) < 0; ++ }); ++ }; ++ ++ Chart.prototype.defocus = function (targetIds) { ++ var $$ = this.internal, ++ candidates; ++ ++ targetIds = $$.mapToTargetIds(targetIds); ++ candidates = $$.svg.selectAll($$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))), candidates.classed(CLASS.focused, false).classed(CLASS.defocused, true); ++ if ($$.hasArcType()) { ++ $$.unexpandArc(targetIds); ++ } ++ $$.toggleFocusLegend(targetIds, false); ++ ++ $$.focusedTargetIds = $$.focusedTargetIds.filter(function (id) { ++ return targetIds.indexOf(id) < 0; ++ }); ++ $$.defocusedTargetIds = targetIds; ++ }; ++ ++ Chart.prototype.revert = function (targetIds) { ++ var $$ = this.internal, ++ candidates; ++ ++ targetIds = $$.mapToTargetIds(targetIds); ++ candidates = $$.svg.selectAll($$.selectorTargets(targetIds)); // should be for all targets ++ ++ candidates.classed(CLASS.focused, false).classed(CLASS.defocused, false); ++ if ($$.hasArcType()) { ++ $$.unexpandArc(targetIds); ++ } ++ if ($$.config.legend_show) { ++ $$.showLegend(targetIds.filter($$.isLegendToShow.bind($$))); ++ $$.legend.selectAll($$.selectorLegends(targetIds)).filter(function () { ++ return $$.d3.select(this).classed(CLASS.legendItemFocused); ++ }).classed(CLASS.legendItemFocused, false); ++ } ++ ++ $$.focusedTargetIds = []; ++ $$.defocusedTargetIds = []; ++ }; ++ ++ Chart.prototype.xgrids = function (grids) { ++ var $$ = this.internal, ++ config = $$.config; ++ if (!grids) { ++ return config.grid_x_lines; ++ } ++ config.grid_x_lines = grids; ++ $$.redrawWithoutRescale(); ++ return config.grid_x_lines; ++ }; ++ Chart.prototype.xgrids.add = function (grids) { ++ var $$ = this.internal; ++ return this.xgrids($$.config.grid_x_lines.concat(grids ? grids : [])); ++ }; ++ Chart.prototype.xgrids.remove = function (params) { ++ // TODO: multiple ++ var $$ = this.internal; ++ $$.removeGridLines(params, true); ++ }; ++ ++ Chart.prototype.ygrids = function (grids) { ++ var $$ = this.internal, ++ config = $$.config; ++ if (!grids) { ++ return config.grid_y_lines; ++ } ++ config.grid_y_lines = grids; ++ $$.redrawWithoutRescale(); ++ return config.grid_y_lines; ++ }; ++ Chart.prototype.ygrids.add = function (grids) { ++ var $$ = this.internal; ++ return this.ygrids($$.config.grid_y_lines.concat(grids ? grids : [])); ++ }; ++ Chart.prototype.ygrids.remove = function (params) { ++ // TODO: multiple ++ var $$ = this.internal; ++ $$.removeGridLines(params, false); ++ }; ++ ++ Chart.prototype.groups = function (groups) { ++ var $$ = this.internal, ++ config = $$.config; ++ if (isUndefined(groups)) { ++ return config.data_groups; ++ } ++ config.data_groups = groups; ++ $$.redraw(); ++ return config.data_groups; ++ }; ++ ++ Chart.prototype.legend = function () {}; ++ Chart.prototype.legend.show = function (targetIds) { ++ var $$ = this.internal; ++ $$.showLegend($$.mapToTargetIds(targetIds)); ++ $$.updateAndRedraw({ withLegend: true }); ++ }; ++ Chart.prototype.legend.hide = function (targetIds) { ++ var $$ = this.internal; ++ $$.hideLegend($$.mapToTargetIds(targetIds)); ++ $$.updateAndRedraw({ withLegend: false }); ++ }; ++ ++ Chart.prototype.load = function (args) { ++ var $$ = this.internal, ++ config = $$.config; ++ // update xs if specified ++ if (args.xs) { ++ $$.addXs(args.xs); ++ } ++ // update names if exists ++ if ('names' in args) { ++ Chart.prototype.data.names.bind(this)(args.names); ++ } ++ // update classes if exists ++ if ('classes' in args) { ++ Object.keys(args.classes).forEach(function (id) { ++ config.data_classes[id] = args.classes[id]; ++ }); ++ } ++ // update categories if exists ++ if ('categories' in args && $$.isCategorized()) { ++ config.axis_x_categories = args.categories; ++ } ++ // update axes if exists ++ if ('axes' in args) { ++ Object.keys(args.axes).forEach(function (id) { ++ config.data_axes[id] = args.axes[id]; ++ }); ++ } ++ // update colors if exists ++ if ('colors' in args) { ++ Object.keys(args.colors).forEach(function (id) { ++ config.data_colors[id] = args.colors[id]; ++ }); ++ } ++ // use cache if exists ++ if ('cacheIds' in args && $$.hasCaches(args.cacheIds)) { ++ $$.load($$.getCaches(args.cacheIds), args.done); ++ return; ++ } ++ // unload if needed ++ if ('unload' in args) { ++ // TODO: do not unload if target will load (included in url/rows/columns) ++ $$.unload($$.mapToTargetIds(typeof args.unload === 'boolean' && args.unload ? null : args.unload), function () { ++ $$.loadFromArgs(args); ++ }); ++ } else { ++ $$.loadFromArgs(args); ++ } ++ }; ++ ++ Chart.prototype.unload = function (args) { ++ var $$ = this.internal; ++ args = args || {}; ++ if (args instanceof Array) { ++ args = { ids: args }; ++ } else if (typeof args === 'string') { ++ args = { ids: [args] }; ++ } ++ $$.unload($$.mapToTargetIds(args.ids), function () { ++ $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true }); ++ if (args.done) { ++ args.done(); ++ } ++ }); ++ }; ++ ++ Chart.prototype.regions = function (regions) { ++ var $$ = this.internal, ++ config = $$.config; ++ if (!regions) { ++ return config.regions; ++ } ++ config.regions = regions; ++ $$.redrawWithoutRescale(); ++ return config.regions; ++ }; ++ Chart.prototype.regions.add = function (regions) { ++ var $$ = this.internal, ++ config = $$.config; ++ if (!regions) { ++ return config.regions; ++ } ++ config.regions = config.regions.concat(regions); ++ $$.redrawWithoutRescale(); ++ return config.regions; ++ }; ++ Chart.prototype.regions.remove = function (options) { ++ var $$ = this.internal, ++ config = $$.config, ++ duration, ++ classes, ++ regions; ++ ++ options = options || {}; ++ duration = $$.getOption(options, "duration", config.transition_duration); ++ classes = $$.getOption(options, "classes", [CLASS.region]); ++ ++ regions = $$.main.select('.' + CLASS.regions).selectAll(classes.map(function (c) { ++ return '.' + c; ++ })); ++ (duration ? regions.transition().duration(duration) : regions).style('opacity', 0).remove(); ++ ++ config.regions = config.regions.filter(function (region) { ++ var found = false; ++ if (!region['class']) { ++ return true; ++ } ++ region['class'].split(' ').forEach(function (c) { ++ if (classes.indexOf(c) >= 0) { ++ found = true; ++ } ++ }); ++ return !found; ++ }); ++ ++ return config.regions; ++ }; ++ ++ Chart.prototype.selected = function (targetId) { ++ var $$ = this.internal, ++ d3 = $$.d3; ++ return d3.merge($$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(targetId)).selectAll('.' + CLASS.shape).filter(function () { ++ return d3.select(this).classed(CLASS.SELECTED); ++ }).map(function (d) { ++ return d.map(function (d) { ++ var data = d.__data__;return data.data ? data.data : data; ++ }); ++ })); ++ }; ++ Chart.prototype.select = function (ids, indices, resetOther) { ++ var $$ = this.internal, ++ d3 = $$.d3, ++ config = $$.config; ++ if (!config.data_selection_enabled) { ++ return; ++ } ++ $$.main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).each(function (d, i) { ++ var shape = d3.select(this), ++ id = d.data ? d.data.id : d.id, ++ toggle = $$.getToggle(this, d).bind($$), ++ isTargetId = config.data_selection_grouped || !ids || ids.indexOf(id) >= 0, ++ isTargetIndex = !indices || indices.indexOf(i) >= 0, ++ isSelected = shape.classed(CLASS.SELECTED); ++ // line/area selection not supported yet ++ if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) { ++ return; ++ } ++ if (isTargetId && isTargetIndex) { ++ if (config.data_selection_isselectable(d) && !isSelected) { ++ toggle(true, shape.classed(CLASS.SELECTED, true), d, i); ++ } ++ } else if (isDefined(resetOther) && resetOther) { ++ if (isSelected) { ++ toggle(false, shape.classed(CLASS.SELECTED, false), d, i); ++ } ++ } ++ }); ++ }; ++ Chart.prototype.unselect = function (ids, indices) { ++ var $$ = this.internal, ++ d3 = $$.d3, ++ config = $$.config; ++ if (!config.data_selection_enabled) { ++ return; ++ } ++ $$.main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).each(function (d, i) { ++ var shape = d3.select(this), ++ id = d.data ? d.data.id : d.id, ++ toggle = $$.getToggle(this, d).bind($$), ++ isTargetId = config.data_selection_grouped || !ids || ids.indexOf(id) >= 0, ++ isTargetIndex = !indices || indices.indexOf(i) >= 0, ++ isSelected = shape.classed(CLASS.SELECTED); ++ // line/area selection not supported yet ++ if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) { ++ return; ++ } ++ if (isTargetId && isTargetIndex) { ++ if (config.data_selection_isselectable(d)) { ++ if (isSelected) { ++ toggle(false, shape.classed(CLASS.SELECTED, false), d, i); ++ } ++ } ++ } ++ }); ++ }; ++ ++ Chart.prototype.show = function (targetIds, options) { ++ var $$ = this.internal, ++ targets; ++ ++ targetIds = $$.mapToTargetIds(targetIds); ++ options = options || {}; ++ ++ $$.removeHiddenTargetIds(targetIds); ++ targets = $$.svg.selectAll($$.selectorTargets(targetIds)); ++ ++ targets.transition().style('display', 'initial', 'important').style('opacity', 1, 'important').call($$.endall, function () { ++ targets.style('opacity', null).style('opacity', 1); ++ }); ++ ++ if (options.withLegend) { ++ $$.showLegend(targetIds); ++ } ++ ++ $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true }); ++ }; ++ ++ Chart.prototype.hide = function (targetIds, options) { ++ var $$ = this.internal, ++ targets; ++ ++ targetIds = $$.mapToTargetIds(targetIds); ++ options = options || {}; ++ ++ $$.addHiddenTargetIds(targetIds); ++ targets = $$.svg.selectAll($$.selectorTargets(targetIds)); ++ ++ targets.transition().style('opacity', 0, 'important').call($$.endall, function () { ++ targets.style('opacity', null).style('opacity', 0); ++ targets.style('display', 'none'); ++ }); ++ ++ if (options.withLegend) { ++ $$.hideLegend(targetIds); ++ } ++ ++ $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true }); ++ }; ++ ++ Chart.prototype.toggle = function (targetIds, options) { ++ var that = this, ++ $$ = this.internal; ++ $$.mapToTargetIds(targetIds).forEach(function (targetId) { ++ $$.isTargetToShow(targetId) ? that.hide(targetId, options) : that.show(targetId, options); ++ }); ++ }; ++ ++ Chart.prototype.tooltip = function () {}; ++ Chart.prototype.tooltip.show = function (args) { ++ var $$ = this.internal, ++ targets, ++ data, ++ mouse = {}; ++ ++ // determine mouse position on the chart ++ if (args.mouse) { ++ mouse = args.mouse; ++ } else { ++ // determine focus data ++ if (args.data) { ++ data = args.data; ++ } else if (typeof args.x !== 'undefined') { ++ if (args.id) { ++ targets = $$.data.targets.filter(function (t) { ++ return t.id === args.id; ++ }); ++ } else { ++ targets = $$.data.targets; ++ } ++ data = $$.filterByX(targets, args.x).slice(0, 1)[0]; ++ } ++ mouse = data ? $$.getMousePosition(data) : null; ++ } ++ ++ // emulate mouse events to show ++ $$.dispatchEvent('mousemove', mouse); ++ ++ $$.config.tooltip_onshow.call($$, data); ++ }; ++ Chart.prototype.tooltip.hide = function () { ++ // TODO: get target data by checking the state of focus ++ this.internal.dispatchEvent('mouseout', 0); ++ ++ this.internal.config.tooltip_onhide.call(this); ++ }; ++ ++ Chart.prototype.transform = function (type, targetIds) { ++ var $$ = this.internal, ++ options = ['pie', 'donut'].indexOf(type) >= 0 ? { withTransform: true } : null; ++ $$.transformTo(targetIds, type, options); ++ }; ++ ++ ChartInternal.prototype.transformTo = function (targetIds, type, optionsForRedraw) { ++ var $$ = this, ++ withTransitionForAxis = !$$.hasArcType(), ++ options = optionsForRedraw || { withTransitionForAxis: withTransitionForAxis }; ++ options.withTransitionForTransform = false; ++ $$.transiting = false; ++ $$.setTargetType(targetIds, type); ++ $$.updateTargets($$.data.targets); // this is needed when transforming to arc ++ $$.updateAndRedraw(options); ++ }; ++ ++ Chart.prototype.x = function (x) { ++ var $$ = this.internal; ++ if (arguments.length) { ++ $$.updateTargetX($$.data.targets, x); ++ $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true }); ++ } ++ return $$.data.xs; ++ }; ++ Chart.prototype.xs = function (xs) { ++ var $$ = this.internal; ++ if (arguments.length) { ++ $$.updateTargetXs($$.data.targets, xs); ++ $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true }); ++ } ++ return $$.data.xs; ++ }; ++ ++ Chart.prototype.zoom = function (domain) { ++ var $$ = this.internal; ++ if (domain) { ++ if ($$.isTimeSeries()) { ++ domain = domain.map(function (x) { ++ return $$.parseDate(x); ++ }); ++ } ++ if ($$.config.subchart_show) { ++ $$.brush.selectionAsValue(domain, true); ++ } else { ++ $$.updateXDomain(null, true, false, false, domain); ++ $$.redraw({ withY: $$.config.zoom_rescale, withSubchart: false }); ++ } ++ $$.config.zoom_onzoom.call(this, $$.x.orgDomain()); ++ return domain; ++ } else { ++ return $$.x.domain(); ++ } ++ }; ++ Chart.prototype.zoom.enable = function (enabled) { ++ var $$ = this.internal; ++ $$.config.zoom_enabled = enabled; ++ $$.updateAndRedraw(); ++ }; ++ Chart.prototype.unzoom = function () { ++ var $$ = this.internal; ++ if ($$.config.subchart_show) { ++ $$.brush.clear(); ++ } else { ++ $$.updateXDomain(null, true, false, false, $$.subX.domain()); ++ $$.redraw({ withY: $$.config.zoom_rescale, withSubchart: false }); ++ } ++ }; ++ ++ Chart.prototype.zoom.max = function (max) { ++ var $$ = this.internal, ++ config = $$.config, ++ d3 = $$.d3; ++ if (max === 0 || max) { ++ config.zoom_x_max = d3.max([$$.orgXDomain[1], max]); ++ } else { ++ return config.zoom_x_max; ++ } ++ }; ++ ++ Chart.prototype.zoom.min = function (min) { ++ var $$ = this.internal, ++ config = $$.config, ++ d3 = $$.d3; ++ if (min === 0 || min) { ++ config.zoom_x_min = d3.min([$$.orgXDomain[0], min]); ++ } else { ++ return config.zoom_x_min; ++ } ++ }; ++ ++ Chart.prototype.zoom.range = function (range) { ++ if (arguments.length) { ++ if (isDefined(range.max)) { ++ this.domain.max(range.max); ++ } ++ if (isDefined(range.min)) { ++ this.domain.min(range.min); ++ } ++ } else { ++ return { ++ max: this.domain.max(), ++ min: this.domain.min() ++ }; ++ } ++ }; ++ ++ ChartInternal.prototype.initPie = function () { ++ var $$ = this, ++ d3 = $$.d3; ++ $$.pie = d3.pie().value(function (d) { ++ return d.values.reduce(function (a, b) { ++ return a + b.value; ++ }, 0); ++ }); ++ ++ var orderFct = $$.getOrderFunction(); ++ ++ // we need to reverse the returned order if asc or desc to have the slice in expected order. ++ if (orderFct && ($$.isOrderAsc() || $$.isOrderDesc())) { ++ var defaultSort = orderFct; ++ orderFct = function orderFct(t1, t2) { ++ return defaultSort(t1, t2) * -1; ++ }; ++ } ++ ++ $$.pie.sort(orderFct || null); ++ }; ++ ++ ChartInternal.prototype.updateRadius = function () { ++ var $$ = this, ++ config = $$.config, ++ w = config.gauge_width || config.donut_width, ++ gaugeArcWidth = $$.filterTargetsToShow($$.data.targets).length * $$.config.gauge_arcs_minWidth; ++ $$.radiusExpanded = Math.min($$.arcWidth, $$.arcHeight) / 2 * ($$.hasType('gauge') ? 0.85 : 1); ++ $$.radius = $$.radiusExpanded * 0.95; ++ $$.innerRadiusRatio = w ? ($$.radius - w) / $$.radius : 0.6; ++ $$.innerRadius = $$.hasType('donut') || $$.hasType('gauge') ? $$.radius * $$.innerRadiusRatio : 0; ++ $$.gaugeArcWidth = w ? w : gaugeArcWidth <= $$.radius - $$.innerRadius ? $$.radius - $$.innerRadius : gaugeArcWidth <= $$.radius ? gaugeArcWidth : $$.radius; ++ }; ++ ++ ChartInternal.prototype.updateArc = function () { ++ var $$ = this; ++ $$.svgArc = $$.getSvgArc(); ++ $$.svgArcExpanded = $$.getSvgArcExpanded(); ++ $$.svgArcExpandedSub = $$.getSvgArcExpanded(0.98); ++ }; ++ ++ ChartInternal.prototype.updateAngle = function (d) { ++ var $$ = this, ++ config = $$.config, ++ found = false, ++ index = 0, ++ gMin, ++ gMax, ++ gTic, ++ gValue; ++ ++ if (!config) { ++ return null; ++ } ++ ++ $$.pie($$.filterTargetsToShow($$.data.targets)).forEach(function (t) { ++ if (!found && t.data.id === d.data.id) { ++ found = true; ++ d = t; ++ d.index = index; ++ } ++ index++; ++ }); ++ if (isNaN(d.startAngle)) { ++ d.startAngle = 0; ++ } ++ if (isNaN(d.endAngle)) { ++ d.endAngle = d.startAngle; ++ } ++ if ($$.isGaugeType(d.data)) { ++ gMin = config.gauge_min; ++ gMax = config.gauge_max; ++ gTic = Math.PI * (config.gauge_fullCircle ? 2 : 1) / (gMax - gMin); ++ gValue = d.value < gMin ? 0 : d.value < gMax ? d.value - gMin : gMax - gMin; ++ d.startAngle = config.gauge_startingAngle; ++ d.endAngle = d.startAngle + gTic * gValue; ++ } ++ return found ? d : null; ++ }; ++ ++ ChartInternal.prototype.getSvgArc = function () { ++ var $$ = this, ++ hasGaugeType = $$.hasType('gauge'), ++ singleArcWidth = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length, ++ arc = $$.d3.arc().outerRadius(function (d) { ++ return hasGaugeType ? $$.radius - singleArcWidth * d.index : $$.radius; ++ }).innerRadius(function (d) { ++ return hasGaugeType ? $$.radius - singleArcWidth * (d.index + 1) : $$.innerRadius; ++ }), ++ newArc = function newArc(d, withoutUpdate) { ++ var updated; ++ if (withoutUpdate) { ++ return arc(d); ++ } // for interpolate ++ updated = $$.updateAngle(d); ++ return updated ? arc(updated) : "M 0 0"; ++ }; ++ // TODO: extends all function ++ newArc.centroid = arc.centroid; ++ return newArc; ++ }; ++ ++ ChartInternal.prototype.getSvgArcExpanded = function (rate) { ++ rate = rate || 1; ++ var $$ = this, ++ hasGaugeType = $$.hasType('gauge'), ++ singleArcWidth = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length, ++ expandWidth = Math.min($$.radiusExpanded * rate - $$.radius, singleArcWidth * 0.8 - (1 - rate) * 100), ++ arc = $$.d3.arc().outerRadius(function (d) { ++ return hasGaugeType ? $$.radius - singleArcWidth * d.index + expandWidth : $$.radiusExpanded * rate; ++ }).innerRadius(function (d) { ++ return hasGaugeType ? $$.radius - singleArcWidth * (d.index + 1) : $$.innerRadius; ++ }); ++ return function (d) { ++ var updated = $$.updateAngle(d); ++ return updated ? arc(updated) : "M 0 0"; ++ }; ++ }; ++ ++ ChartInternal.prototype.getArc = function (d, withoutUpdate, force) { ++ return force || this.isArcType(d.data) ? this.svgArc(d, withoutUpdate) : "M 0 0"; ++ }; ++ ++ ChartInternal.prototype.transformForArcLabel = function (d) { ++ var $$ = this, ++ config = $$.config, ++ updated = $$.updateAngle(d), ++ c, ++ x, ++ y, ++ h, ++ ratio, ++ translate = "", ++ hasGauge = $$.hasType('gauge'); ++ if (updated && !hasGauge) { ++ c = this.svgArc.centroid(updated); ++ x = isNaN(c[0]) ? 0 : c[0]; ++ y = isNaN(c[1]) ? 0 : c[1]; ++ h = Math.sqrt(x * x + y * y); ++ if ($$.hasType('donut') && config.donut_label_ratio) { ++ ratio = isFunction(config.donut_label_ratio) ? config.donut_label_ratio(d, $$.radius, h) : config.donut_label_ratio; ++ } else if ($$.hasType('pie') && config.pie_label_ratio) { ++ ratio = isFunction(config.pie_label_ratio) ? config.pie_label_ratio(d, $$.radius, h) : config.pie_label_ratio; ++ } else { ++ ratio = $$.radius && h ? (36 / $$.radius > 0.375 ? 1.175 - 36 / $$.radius : 0.8) * $$.radius / h : 0; ++ } ++ translate = "translate(" + x * ratio + ',' + y * ratio + ")"; ++ } else if (updated && hasGauge && $$.filterTargetsToShow($$.data.targets).length > 1) { ++ var y1 = Math.sin(updated.endAngle - Math.PI / 2); ++ x = Math.cos(updated.endAngle - Math.PI / 2) * ($$.radiusExpanded + 25); ++ y = y1 * ($$.radiusExpanded + 15 - Math.abs(y1 * 10)) + 3; ++ translate = "translate(" + x + ',' + y + ")"; ++ } ++ return translate; ++ }; ++ ++ ChartInternal.prototype.getArcRatio = function (d) { ++ var $$ = this, ++ config = $$.config, ++ whole = Math.PI * ($$.hasType('gauge') && !config.gauge_fullCircle ? 1 : 2); ++ return d ? (d.endAngle - d.startAngle) / whole : null; ++ }; ++ ++ ChartInternal.prototype.convertToArcData = function (d) { ++ return this.addName({ ++ id: d.data.id, ++ value: d.value, ++ ratio: this.getArcRatio(d), ++ index: d.index ++ }); ++ }; ++ ++ ChartInternal.prototype.textForArcLabel = function (d) { ++ var $$ = this, ++ updated, ++ value, ++ ratio, ++ id, ++ format; ++ if (!$$.shouldShowArcLabel()) { ++ return ""; ++ } ++ updated = $$.updateAngle(d); ++ value = updated ? updated.value : null; ++ ratio = $$.getArcRatio(updated); ++ id = d.data.id; ++ if (!$$.hasType('gauge') && !$$.meetsArcLabelThreshold(ratio)) { ++ return ""; ++ } ++ format = $$.getArcLabelFormat(); ++ return format ? format(value, ratio, id) : $$.defaultArcValueFormat(value, ratio); ++ }; ++ ++ ChartInternal.prototype.textForGaugeMinMax = function (value, isMax) { ++ var $$ = this, ++ format = $$.getGaugeLabelExtents(); ++ ++ return format ? format(value, isMax) : value; ++ }; ++ ++ ChartInternal.prototype.expandArc = function (targetIds) { ++ var $$ = this, ++ interval; ++ ++ // MEMO: avoid to cancel transition ++ if ($$.transiting) { ++ interval = window.setInterval(function () { ++ if (!$$.transiting) { ++ window.clearInterval(interval); ++ if ($$.legend.selectAll('.c3-legend-item-focused').size() > 0) { ++ $$.expandArc(targetIds); ++ } ++ } ++ }, 10); ++ return; ++ } ++ ++ targetIds = $$.mapToTargetIds(targetIds); ++ ++ $$.svg.selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc)).each(function (d) { ++ if (!$$.shouldExpand(d.data.id)) { ++ return; ++ } ++ $$.d3.select(this).selectAll('path').transition().duration($$.expandDuration(d.data.id)).attr("d", $$.svgArcExpanded).transition().duration($$.expandDuration(d.data.id) * 2).attr("d", $$.svgArcExpandedSub).each(function (d) { ++ if ($$.isDonutType(d.data)) ; ++ }); ++ }); ++ }; ++ ++ ChartInternal.prototype.unexpandArc = function (targetIds) { ++ var $$ = this; ++ ++ if ($$.transiting) { ++ return; ++ } ++ ++ targetIds = $$.mapToTargetIds(targetIds); ++ ++ $$.svg.selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc)).selectAll('path').transition().duration(function (d) { ++ return $$.expandDuration(d.data.id); ++ }).attr("d", $$.svgArc); ++ $$.svg.selectAll('.' + CLASS.arc); ++ }; ++ ++ ChartInternal.prototype.expandDuration = function (id) { ++ var $$ = this, ++ config = $$.config; ++ ++ if ($$.isDonutType(id)) { ++ return config.donut_expand_duration; ++ } else if ($$.isGaugeType(id)) { ++ return config.gauge_expand_duration; ++ } else if ($$.isPieType(id)) { ++ return config.pie_expand_duration; ++ } else { ++ return 50; ++ } ++ }; ++ ++ ChartInternal.prototype.shouldExpand = function (id) { ++ var $$ = this, ++ config = $$.config; ++ return $$.isDonutType(id) && config.donut_expand || $$.isGaugeType(id) && config.gauge_expand || $$.isPieType(id) && config.pie_expand; ++ }; ++ ++ ChartInternal.prototype.shouldShowArcLabel = function () { ++ var $$ = this, ++ config = $$.config, ++ shouldShow = true; ++ if ($$.hasType('donut')) { ++ shouldShow = config.donut_label_show; ++ } else if ($$.hasType('pie')) { ++ shouldShow = config.pie_label_show; ++ } ++ // when gauge, always true ++ return shouldShow; ++ }; ++ ++ ChartInternal.prototype.meetsArcLabelThreshold = function (ratio) { ++ var $$ = this, ++ config = $$.config, ++ threshold = $$.hasType('donut') ? config.donut_label_threshold : config.pie_label_threshold; ++ return ratio >= threshold; ++ }; ++ ++ ChartInternal.prototype.getArcLabelFormat = function () { ++ var $$ = this, ++ config = $$.config, ++ format = config.pie_label_format; ++ if ($$.hasType('gauge')) { ++ format = config.gauge_label_format; ++ } else if ($$.hasType('donut')) { ++ format = config.donut_label_format; ++ } ++ return format; ++ }; ++ ++ ChartInternal.prototype.getGaugeLabelExtents = function () { ++ var $$ = this, ++ config = $$.config; ++ return config.gauge_label_extents; ++ }; ++ ++ ChartInternal.prototype.getArcTitle = function () { ++ var $$ = this; ++ return $$.hasType('donut') ? $$.config.donut_title : ""; ++ }; ++ ++ ChartInternal.prototype.updateTargetsForArc = function (targets) { ++ var $$ = this, ++ main = $$.main, ++ mainPies, ++ mainPieEnter, ++ classChartArc = $$.classChartArc.bind($$), ++ classArcs = $$.classArcs.bind($$), ++ classFocus = $$.classFocus.bind($$); ++ mainPies = main.select('.' + CLASS.chartArcs).selectAll('.' + CLASS.chartArc).data($$.pie(targets)).attr("class", function (d) { ++ return classChartArc(d) + classFocus(d.data); ++ }); ++ mainPieEnter = mainPies.enter().append("g").attr("class", classChartArc); ++ mainPieEnter.append('g').attr('class', classArcs); ++ mainPieEnter.append("text").attr("dy", $$.hasType('gauge') ? "-.1em" : ".35em").style("opacity", 0).style("text-anchor", "middle").style("pointer-events", "none"); ++ // MEMO: can not keep same color..., but not bad to update color in redraw ++ //mainPieUpdate.exit().remove(); ++ }; ++ ++ ChartInternal.prototype.initArc = function () { ++ var $$ = this; ++ $$.arcs = $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartArcs).attr("transform", $$.getTranslate('arc')); ++ $$.arcs.append('text').attr('class', CLASS.chartArcsTitle).style("text-anchor", "middle").text($$.getArcTitle()); ++ }; ++ ++ ChartInternal.prototype.redrawArc = function (duration, durationForExit, withTransform) { ++ var $$ = this, ++ d3 = $$.d3, ++ config = $$.config, ++ main = $$.main, ++ arcs, ++ mainArc, ++ arcLabelLines, ++ mainArcLabelLine, ++ hasGaugeType = $$.hasType('gauge'); ++ arcs = main.selectAll('.' + CLASS.arcs).selectAll('.' + CLASS.arc).data($$.arcData.bind($$)); ++ mainArc = arcs.enter().append('path').attr("class", $$.classArc.bind($$)).style("fill", function (d) { ++ return $$.color(d.data); ++ }).style("cursor", function (d) { ++ return config.interaction_enabled && config.data_selection_isselectable(d) ? "pointer" : null; ++ }).each(function (d) { ++ if ($$.isGaugeType(d.data)) { ++ d.startAngle = d.endAngle = config.gauge_startingAngle; ++ } ++ this._current = d; ++ }).merge(arcs); ++ if (hasGaugeType) { ++ arcLabelLines = main.selectAll('.' + CLASS.arcs).selectAll('.' + CLASS.arcLabelLine).data($$.arcData.bind($$)); ++ mainArcLabelLine = arcLabelLines.enter().append('rect').attr("class", function (d) { ++ return CLASS.arcLabelLine + ' ' + CLASS.target + ' ' + CLASS.target + '-' + d.data.id; ++ }).merge(arcLabelLines); ++ ++ if ($$.filterTargetsToShow($$.data.targets).length === 1) { ++ mainArcLabelLine.style("display", "none"); ++ } else { ++ mainArcLabelLine.style("fill", function (d) { ++ return config.color_pattern.length > 0 ? $$.levelColor(d.data.values[0].value) : $$.color(d.data); ++ }).style("display", config.gauge_labelLine_show ? "" : "none").each(function (d) { ++ var lineLength = 0, ++ lineThickness = 2, ++ x = 0, ++ y = 0, ++ transform = ""; ++ if ($$.hiddenTargetIds.indexOf(d.data.id) < 0) { ++ var updated = $$.updateAngle(d), ++ innerLineLength = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length * (updated.index + 1), ++ lineAngle = updated.endAngle - Math.PI / 2, ++ arcInnerRadius = $$.radius - innerLineLength, ++ linePositioningAngle = lineAngle - (arcInnerRadius === 0 ? 0 : 1 / arcInnerRadius); ++ lineLength = $$.radiusExpanded - $$.radius + innerLineLength; ++ x = Math.cos(linePositioningAngle) * arcInnerRadius; ++ y = Math.sin(linePositioningAngle) * arcInnerRadius; ++ transform = "rotate(" + lineAngle * 180 / Math.PI + ", " + x + ", " + y + ")"; ++ } ++ d3.select(this).attr('x', x).attr('y', y).attr('width', lineLength).attr('height', lineThickness).attr('transform', transform).style("stroke-dasharray", "0, " + (lineLength + lineThickness) + ", 0"); ++ }); ++ } ++ } ++ mainArc.attr("transform", function (d) { ++ return !$$.isGaugeType(d.data) && withTransform ? "scale(0)" : ""; ++ }).on('mouseover', config.interaction_enabled ? function (d) { ++ var updated, arcData; ++ if ($$.transiting) { ++ // skip while transiting ++ return; ++ } ++ updated = $$.updateAngle(d); ++ if (updated) { ++ arcData = $$.convertToArcData(updated); ++ // transitions ++ $$.expandArc(updated.data.id); ++ $$.api.focus(updated.data.id); ++ $$.toggleFocusLegend(updated.data.id, true); ++ $$.config.data_onmouseover(arcData, this); ++ } ++ } : null).on('mousemove', config.interaction_enabled ? function (d) { ++ var updated = $$.updateAngle(d), ++ arcData, ++ selectedData; ++ if (updated) { ++ arcData = $$.convertToArcData(updated), selectedData = [arcData]; ++ $$.showTooltip(selectedData, this); ++ } ++ } : null).on('mouseout', config.interaction_enabled ? function (d) { ++ var updated, arcData; ++ if ($$.transiting) { ++ // skip while transiting ++ return; ++ } ++ updated = $$.updateAngle(d); ++ if (updated) { ++ arcData = $$.convertToArcData(updated); ++ // transitions ++ $$.unexpandArc(updated.data.id); ++ $$.api.revert(); ++ $$.revertLegend(); ++ $$.hideTooltip(); ++ $$.config.data_onmouseout(arcData, this); ++ } ++ } : null).on('click', config.interaction_enabled ? function (d, i) { ++ var updated = $$.updateAngle(d), ++ arcData; ++ if (updated) { ++ arcData = $$.convertToArcData(updated); ++ if ($$.toggleShape) { ++ $$.toggleShape(this, arcData, i); ++ } ++ $$.config.data_onclick.call($$.api, arcData, this); ++ } ++ } : null).each(function () { ++ $$.transiting = true; ++ }).transition().duration(duration).attrTween("d", function (d) { ++ var updated = $$.updateAngle(d), ++ interpolate; ++ if (!updated) { ++ return function () { ++ return "M 0 0"; ++ }; ++ } ++ // if (this._current === d) { ++ // this._current = { ++ // startAngle: Math.PI*2, ++ // endAngle: Math.PI*2, ++ // }; ++ // } ++ if (isNaN(this._current.startAngle)) { ++ this._current.startAngle = 0; ++ } ++ if (isNaN(this._current.endAngle)) { ++ this._current.endAngle = this._current.startAngle; ++ } ++ interpolate = d3.interpolate(this._current, updated); ++ this._current = interpolate(0); ++ return function (t) { ++ var interpolated = interpolate(t); ++ interpolated.data = d.data; // data.id will be updated by interporator ++ return $$.getArc(interpolated, true); ++ }; ++ }).attr("transform", withTransform ? "scale(1)" : "").style("fill", function (d) { ++ return $$.levelColor ? $$.levelColor(d.data.values[0].value) : $$.color(d.data.id); ++ }) // Where gauge reading color would receive customization. ++ .call($$.endall, function () { ++ $$.transiting = false; ++ }); ++ arcs.exit().transition().duration(durationForExit).style('opacity', 0).remove(); ++ main.selectAll('.' + CLASS.chartArc).select('text').style("opacity", 0).attr('class', function (d) { ++ return $$.isGaugeType(d.data) ? CLASS.gaugeValue : ''; ++ }).text($$.textForArcLabel.bind($$)).attr("transform", $$.transformForArcLabel.bind($$)).style('font-size', function (d) { ++ return $$.isGaugeType(d.data) && $$.filterTargetsToShow($$.data.targets).length === 1 ? Math.round($$.radius / 5) + 'px' : ''; ++ }).transition().duration(duration).style("opacity", function (d) { ++ return $$.isTargetToShow(d.data.id) && $$.isArcType(d.data) ? 1 : 0; ++ }); ++ main.select('.' + CLASS.chartArcsTitle).style("opacity", $$.hasType('donut') || hasGaugeType ? 1 : 0); ++ ++ if (hasGaugeType) { ++ var index = 0; ++ var backgroundArc = $$.arcs.select('g.' + CLASS.chartArcsBackground).selectAll('path.' + CLASS.chartArcsBackground).data($$.data.targets); ++ ++ backgroundArc.enter().append("path").attr("class", function (d, i) { ++ return CLASS.chartArcsBackground + ' ' + CLASS.chartArcsBackground + '-' + i; ++ }).merge(backgroundArc).attr("d", function (d1) { ++ if ($$.hiddenTargetIds.indexOf(d1.id) >= 0) { ++ return "M 0 0"; ++ } ++ ++ var d = { ++ data: [{ value: config.gauge_max }], ++ startAngle: config.gauge_startingAngle, ++ endAngle: -1 * config.gauge_startingAngle * (config.gauge_fullCircle ? Math.PI : 1), ++ index: index++ ++ }; ++ return $$.getArc(d, true, true); ++ }); ++ ++ backgroundArc.exit().remove(); ++ ++ $$.arcs.select('.' + CLASS.chartArcsGaugeUnit).attr("dy", ".75em").text(config.gauge_label_show ? config.gauge_units : ''); ++ $$.arcs.select('.' + CLASS.chartArcsGaugeMin).attr("dx", -1 * ($$.innerRadius + ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2)) + "px").attr("dy", "1.2em").text(config.gauge_label_show ? $$.textForGaugeMinMax(config.gauge_min, false) : ''); ++ $$.arcs.select('.' + CLASS.chartArcsGaugeMax).attr("dx", $$.innerRadius + ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2) + "px").attr("dy", "1.2em").text(config.gauge_label_show ? $$.textForGaugeMinMax(config.gauge_max, true) : ''); ++ } ++ }; ++ ChartInternal.prototype.initGauge = function () { ++ var arcs = this.arcs; ++ if (this.hasType('gauge')) { ++ arcs.append('g').attr("class", CLASS.chartArcsBackground); ++ arcs.append("text").attr("class", CLASS.chartArcsGaugeUnit).style("text-anchor", "middle").style("pointer-events", "none"); ++ arcs.append("text").attr("class", CLASS.chartArcsGaugeMin).style("text-anchor", "middle").style("pointer-events", "none"); ++ arcs.append("text").attr("class", CLASS.chartArcsGaugeMax).style("text-anchor", "middle").style("pointer-events", "none"); ++ } ++ }; ++ ChartInternal.prototype.getGaugeLabelHeight = function () { ++ return this.config.gauge_label_show ? 20 : 0; ++ }; ++ ++ ChartInternal.prototype.hasCaches = function (ids) { ++ for (var i = 0; i < ids.length; i++) { ++ if (!(ids[i] in this.cache)) { ++ return false; ++ } ++ } ++ return true; ++ }; ++ ChartInternal.prototype.addCache = function (id, target) { ++ this.cache[id] = this.cloneTarget(target); ++ }; ++ ChartInternal.prototype.getCaches = function (ids) { ++ var targets = [], ++ i; ++ for (i = 0; i < ids.length; i++) { ++ if (ids[i] in this.cache) { ++ targets.push(this.cloneTarget(this.cache[ids[i]])); ++ } ++ } ++ return targets; ++ }; ++ ++ ChartInternal.prototype.categoryName = function (i) { ++ var config = this.config; ++ return i < config.axis_x_categories.length ? config.axis_x_categories[i] : i; ++ }; ++ ++ ChartInternal.prototype.generateTargetClass = function (targetId) { ++ return targetId || targetId === 0 ? ('-' + targetId).replace(/\s/g, '-') : ''; ++ }; ++ ChartInternal.prototype.generateClass = function (prefix, targetId) { ++ return " " + prefix + " " + prefix + this.generateTargetClass(targetId); ++ }; ++ ChartInternal.prototype.classText = function (d) { ++ return this.generateClass(CLASS.text, d.index); ++ }; ++ ChartInternal.prototype.classTexts = function (d) { ++ return this.generateClass(CLASS.texts, d.id); ++ }; ++ ChartInternal.prototype.classShape = function (d) { ++ return this.generateClass(CLASS.shape, d.index); ++ }; ++ ChartInternal.prototype.classShapes = function (d) { ++ return this.generateClass(CLASS.shapes, d.id); ++ }; ++ ChartInternal.prototype.classLine = function (d) { ++ return this.classShape(d) + this.generateClass(CLASS.line, d.id); ++ }; ++ ChartInternal.prototype.classLines = function (d) { ++ return this.classShapes(d) + this.generateClass(CLASS.lines, d.id); ++ }; ++ ChartInternal.prototype.classCircle = function (d) { ++ return this.classShape(d) + this.generateClass(CLASS.circle, d.index); ++ }; ++ ChartInternal.prototype.classCircles = function (d) { ++ return this.classShapes(d) + this.generateClass(CLASS.circles, d.id); ++ }; ++ ChartInternal.prototype.classBar = function (d) { ++ return this.classShape(d) + this.generateClass(CLASS.bar, d.index); ++ }; ++ ChartInternal.prototype.classBars = function (d) { ++ return this.classShapes(d) + this.generateClass(CLASS.bars, d.id); ++ }; ++ ChartInternal.prototype.classArc = function (d) { ++ return this.classShape(d.data) + this.generateClass(CLASS.arc, d.data.id); ++ }; ++ ChartInternal.prototype.classArcs = function (d) { ++ return this.classShapes(d.data) + this.generateClass(CLASS.arcs, d.data.id); ++ }; ++ ChartInternal.prototype.classArea = function (d) { ++ return this.classShape(d) + this.generateClass(CLASS.area, d.id); ++ }; ++ ChartInternal.prototype.classAreas = function (d) { ++ return this.classShapes(d) + this.generateClass(CLASS.areas, d.id); ++ }; ++ ChartInternal.prototype.classRegion = function (d, i) { ++ return this.generateClass(CLASS.region, i) + ' ' + ('class' in d ? d['class'] : ''); ++ }; ++ ChartInternal.prototype.classEvent = function (d) { ++ return this.generateClass(CLASS.eventRect, d.index); ++ }; ++ ChartInternal.prototype.classTarget = function (id) { ++ var $$ = this; ++ var additionalClassSuffix = $$.config.data_classes[id], ++ additionalClass = ''; ++ if (additionalClassSuffix) { ++ additionalClass = ' ' + CLASS.target + '-' + additionalClassSuffix; ++ } ++ return $$.generateClass(CLASS.target, id) + additionalClass; ++ }; ++ ChartInternal.prototype.classFocus = function (d) { ++ return this.classFocused(d) + this.classDefocused(d); ++ }; ++ ChartInternal.prototype.classFocused = function (d) { ++ return ' ' + (this.focusedTargetIds.indexOf(d.id) >= 0 ? CLASS.focused : ''); ++ }; ++ ChartInternal.prototype.classDefocused = function (d) { ++ return ' ' + (this.defocusedTargetIds.indexOf(d.id) >= 0 ? CLASS.defocused : ''); ++ }; ++ ChartInternal.prototype.classChartText = function (d) { ++ return CLASS.chartText + this.classTarget(d.id); ++ }; ++ ChartInternal.prototype.classChartLine = function (d) { ++ return CLASS.chartLine + this.classTarget(d.id); ++ }; ++ ChartInternal.prototype.classChartBar = function (d) { ++ return CLASS.chartBar + this.classTarget(d.id); ++ }; ++ ChartInternal.prototype.classChartArc = function (d) { ++ return CLASS.chartArc + this.classTarget(d.data.id); ++ }; ++ ChartInternal.prototype.getTargetSelectorSuffix = function (targetId) { ++ return this.generateTargetClass(targetId).replace(/([?!@#$%^&*()_=+,.<>'":;\[\]\/|~`{}\\])/g, '\\$1'); ++ }; ++ ChartInternal.prototype.selectorTarget = function (id, prefix) { ++ return (prefix || '') + '.' + CLASS.target + this.getTargetSelectorSuffix(id); ++ }; ++ ChartInternal.prototype.selectorTargets = function (ids, prefix) { ++ var $$ = this; ++ ids = ids || []; ++ return ids.length ? ids.map(function (id) { ++ return $$.selectorTarget(id, prefix); ++ }) : null; ++ }; ++ ChartInternal.prototype.selectorLegend = function (id) { ++ return '.' + CLASS.legendItem + this.getTargetSelectorSuffix(id); ++ }; ++ ChartInternal.prototype.selectorLegends = function (ids) { ++ var $$ = this; ++ return ids && ids.length ? ids.map(function (id) { ++ return $$.selectorLegend(id); ++ }) : null; ++ }; ++ ++ ChartInternal.prototype.getClipPath = function (id) { ++ var isIE9 = window.navigator.appVersion.toLowerCase().indexOf("msie 9.") >= 0; ++ return "url(" + (isIE9 ? "" : document.URL.split('#')[0]) + "#" + id + ")"; ++ }; ++ ChartInternal.prototype.appendClip = function (parent, id) { ++ return parent.append("clipPath").attr("id", id).append("rect"); ++ }; ++ ChartInternal.prototype.getAxisClipX = function (forHorizontal) { ++ // axis line width + padding for left ++ var left = Math.max(30, this.margin.left); ++ return forHorizontal ? -(1 + left) : -(left - 1); ++ }; ++ ChartInternal.prototype.getAxisClipY = function (forHorizontal) { ++ return forHorizontal ? -20 : -this.margin.top; ++ }; ++ ChartInternal.prototype.getXAxisClipX = function () { ++ var $$ = this; ++ return $$.getAxisClipX(!$$.config.axis_rotated); ++ }; ++ ChartInternal.prototype.getXAxisClipY = function () { ++ var $$ = this; ++ return $$.getAxisClipY(!$$.config.axis_rotated); ++ }; ++ ChartInternal.prototype.getYAxisClipX = function () { ++ var $$ = this; ++ return $$.config.axis_y_inner ? -1 : $$.getAxisClipX($$.config.axis_rotated); ++ }; ++ ChartInternal.prototype.getYAxisClipY = function () { ++ var $$ = this; ++ return $$.getAxisClipY($$.config.axis_rotated); ++ }; ++ ChartInternal.prototype.getAxisClipWidth = function (forHorizontal) { ++ var $$ = this, ++ left = Math.max(30, $$.margin.left), ++ right = Math.max(30, $$.margin.right); ++ // width + axis line width + padding for left/right ++ return forHorizontal ? $$.width + 2 + left + right : $$.margin.left + 20; ++ }; ++ ChartInternal.prototype.getAxisClipHeight = function (forHorizontal) { ++ // less than 20 is not enough to show the axis label 'outer' without legend ++ return (forHorizontal ? this.margin.bottom : this.margin.top + this.height) + 20; ++ }; ++ ChartInternal.prototype.getXAxisClipWidth = function () { ++ var $$ = this; ++ return $$.getAxisClipWidth(!$$.config.axis_rotated); ++ }; ++ ChartInternal.prototype.getXAxisClipHeight = function () { ++ var $$ = this; ++ return $$.getAxisClipHeight(!$$.config.axis_rotated); ++ }; ++ ChartInternal.prototype.getYAxisClipWidth = function () { ++ var $$ = this; ++ return $$.getAxisClipWidth($$.config.axis_rotated) + ($$.config.axis_y_inner ? 20 : 0); ++ }; ++ ChartInternal.prototype.getYAxisClipHeight = function () { ++ var $$ = this; ++ return $$.getAxisClipHeight($$.config.axis_rotated); ++ }; ++ ++ ChartInternal.prototype.generateColor = function () { ++ var $$ = this, ++ config = $$.config, ++ d3 = $$.d3, ++ colors = config.data_colors, ++ pattern = notEmpty(config.color_pattern) ? config.color_pattern : d3.schemeCategory10, ++ callback = config.data_color, ++ ids = []; ++ ++ return function (d) { ++ var id = d.id || d.data && d.data.id || d, ++ color; ++ ++ // if callback function is provided ++ if (colors[id] instanceof Function) { ++ color = colors[id](d); ++ } ++ // if specified, choose that color ++ else if (colors[id]) { ++ color = colors[id]; ++ } ++ // if not specified, choose from pattern ++ else { ++ if (ids.indexOf(id) < 0) { ++ ids.push(id); ++ } ++ color = pattern[ids.indexOf(id) % pattern.length]; ++ colors[id] = color; ++ } ++ return callback instanceof Function ? callback(color, d) : color; ++ }; ++ }; ++ ChartInternal.prototype.generateLevelColor = function () { ++ var $$ = this, ++ config = $$.config, ++ colors = config.color_pattern, ++ threshold = config.color_threshold, ++ asValue = threshold.unit === 'value', ++ values = threshold.values && threshold.values.length ? threshold.values : [], ++ max = threshold.max || 100; ++ return notEmpty(config.color_threshold) ? function (value) { ++ var i, ++ v, ++ color = colors[colors.length - 1]; ++ for (i = 0; i < values.length; i++) { ++ v = asValue ? value : value * 100 / max; ++ if (v < values[i]) { ++ color = colors[i]; ++ break; ++ } ++ } ++ return color; ++ } : null; ++ }; ++ ++ ChartInternal.prototype.getDefaultConfig = function () { ++ var config = { ++ bindto: '#chart', ++ svg_classname: undefined, ++ size_width: undefined, ++ size_height: undefined, ++ padding_left: undefined, ++ padding_right: undefined, ++ padding_top: undefined, ++ padding_bottom: undefined, ++ resize_auto: true, ++ zoom_enabled: false, ++ zoom_initialRange: undefined, ++ zoom_privileged: false, ++ zoom_rescale: false, ++ zoom_onzoom: function zoom_onzoom() {}, ++ zoom_onzoomstart: function zoom_onzoomstart() {}, ++ zoom_onzoomend: function zoom_onzoomend() {}, ++ zoom_x_min: undefined, ++ zoom_x_max: undefined, ++ interaction_brighten: true, ++ interaction_enabled: true, ++ onmouseover: function onmouseover() {}, ++ onmouseout: function onmouseout() {}, ++ onresize: function onresize() {}, ++ onresized: function onresized() {}, ++ oninit: function oninit() {}, ++ onrendered: function onrendered() {}, ++ transition_duration: 350, ++ data_x: undefined, ++ data_xs: {}, ++ data_xFormat: '%Y-%m-%d', ++ data_xLocaltime: true, ++ data_xSort: true, ++ data_idConverter: function data_idConverter(id) { ++ return id; ++ }, ++ data_names: {}, ++ data_classes: {}, ++ data_groups: [], ++ data_axes: {}, ++ data_type: undefined, ++ data_types: {}, ++ data_labels: {}, ++ data_order: 'desc', ++ data_regions: {}, ++ data_color: undefined, ++ data_colors: {}, ++ data_hide: false, ++ data_filter: undefined, ++ data_selection_enabled: false, ++ data_selection_grouped: false, ++ data_selection_isselectable: function data_selection_isselectable() { ++ return true; ++ }, ++ data_selection_multiple: true, ++ data_selection_draggable: false, ++ data_onclick: function data_onclick() {}, ++ data_onmouseover: function data_onmouseover() {}, ++ data_onmouseout: function data_onmouseout() {}, ++ data_onselected: function data_onselected() {}, ++ data_onunselected: function data_onunselected() {}, ++ data_url: undefined, ++ data_headers: undefined, ++ data_json: undefined, ++ data_rows: undefined, ++ data_columns: undefined, ++ data_mimeType: undefined, ++ data_keys: undefined, ++ // configuration for no plot-able data supplied. ++ data_empty_label_text: "", ++ // subchart ++ subchart_show: false, ++ subchart_size_height: 60, ++ subchart_axis_x_show: true, ++ subchart_onbrush: function subchart_onbrush() {}, ++ // color ++ color_pattern: [], ++ color_threshold: {}, ++ // legend ++ legend_show: true, ++ legend_hide: false, ++ legend_position: 'bottom', ++ legend_inset_anchor: 'top-left', ++ legend_inset_x: 10, ++ legend_inset_y: 0, ++ legend_inset_step: undefined, ++ legend_item_onclick: undefined, ++ legend_item_onmouseover: undefined, ++ legend_item_onmouseout: undefined, ++ legend_equally: false, ++ legend_padding: 0, ++ legend_item_tile_width: 10, ++ legend_item_tile_height: 10, ++ // axis ++ axis_rotated: false, ++ axis_x_show: true, ++ axis_x_type: 'indexed', ++ axis_x_localtime: true, ++ axis_x_categories: [], ++ axis_x_tick_centered: false, ++ axis_x_tick_format: undefined, ++ axis_x_tick_culling: {}, ++ axis_x_tick_culling_max: 10, ++ axis_x_tick_count: undefined, ++ axis_x_tick_fit: true, ++ axis_x_tick_values: null, ++ axis_x_tick_rotate: 0, ++ axis_x_tick_outer: true, ++ axis_x_tick_multiline: true, ++ axis_x_tick_multilineMax: 0, ++ axis_x_tick_width: null, ++ axis_x_max: undefined, ++ axis_x_min: undefined, ++ axis_x_padding: {}, ++ axis_x_height: undefined, ++ axis_x_selection: undefined, ++ axis_x_label: {}, ++ axis_x_inner: undefined, ++ axis_y_show: true, ++ axis_y_type: undefined, ++ axis_y_max: undefined, ++ axis_y_min: undefined, ++ axis_y_inverted: false, ++ axis_y_center: undefined, ++ axis_y_inner: undefined, ++ axis_y_label: {}, ++ axis_y_tick_format: undefined, ++ axis_y_tick_outer: true, ++ axis_y_tick_values: null, ++ axis_y_tick_rotate: 0, ++ axis_y_tick_count: undefined, ++ axis_y_tick_time_type: undefined, ++ axis_y_tick_time_interval: undefined, ++ axis_y_padding: {}, ++ axis_y_default: undefined, ++ axis_y2_show: false, ++ axis_y2_max: undefined, ++ axis_y2_min: undefined, ++ axis_y2_inverted: false, ++ axis_y2_center: undefined, ++ axis_y2_inner: undefined, ++ axis_y2_label: {}, ++ axis_y2_tick_format: undefined, ++ axis_y2_tick_outer: true, ++ axis_y2_tick_values: null, ++ axis_y2_tick_count: undefined, ++ axis_y2_padding: {}, ++ axis_y2_default: undefined, ++ // grid ++ grid_x_show: false, ++ grid_x_type: 'tick', ++ grid_x_lines: [], ++ grid_y_show: false, ++ // not used ++ // grid_y_type: 'tick', ++ grid_y_lines: [], ++ grid_y_ticks: 10, ++ grid_focus_show: true, ++ grid_lines_front: true, ++ // point - point of each data ++ point_show: true, ++ point_r: 2.5, ++ point_sensitivity: 10, ++ point_focus_expand_enabled: true, ++ point_focus_expand_r: undefined, ++ point_select_r: undefined, ++ // line ++ line_connectNull: false, ++ line_step_type: 'step', ++ // bar ++ bar_width: undefined, ++ bar_width_ratio: 0.6, ++ bar_width_max: undefined, ++ bar_zerobased: true, ++ bar_space: 0, ++ // area ++ area_zerobased: true, ++ area_above: false, ++ // pie ++ pie_label_show: true, ++ pie_label_format: undefined, ++ pie_label_threshold: 0.05, ++ pie_label_ratio: undefined, ++ pie_expand: {}, ++ pie_expand_duration: 50, ++ // gauge ++ gauge_fullCircle: false, ++ gauge_label_show: true, ++ gauge_labelLine_show: true, ++ gauge_label_format: undefined, ++ gauge_min: 0, ++ gauge_max: 100, ++ gauge_startingAngle: -1 * Math.PI / 2, ++ gauge_label_extents: undefined, ++ gauge_units: undefined, ++ gauge_width: undefined, ++ gauge_arcs_minWidth: 5, ++ gauge_expand: {}, ++ gauge_expand_duration: 50, ++ // donut ++ donut_label_show: true, ++ donut_label_format: undefined, ++ donut_label_threshold: 0.05, ++ donut_label_ratio: undefined, ++ donut_width: undefined, ++ donut_title: "", ++ donut_expand: {}, ++ donut_expand_duration: 50, ++ // spline ++ spline_interpolation_type: 'cardinal', ++ // region - region to change style ++ regions: [], ++ // tooltip - show when mouseover on each data ++ tooltip_show: true, ++ tooltip_grouped: true, ++ tooltip_order: undefined, ++ tooltip_format_title: undefined, ++ tooltip_format_name: undefined, ++ tooltip_format_value: undefined, ++ tooltip_position: undefined, ++ tooltip_contents: function tooltip_contents(d, defaultTitleFormat, defaultValueFormat, color) { ++ return this.getTooltipContent ? this.getTooltipContent(d, defaultTitleFormat, defaultValueFormat, color) : ''; ++ }, ++ tooltip_init_show: false, ++ tooltip_init_x: 0, ++ tooltip_init_position: { top: '0px', left: '50px' }, ++ tooltip_onshow: function tooltip_onshow() {}, ++ tooltip_onhide: function tooltip_onhide() {}, ++ // title ++ title_text: undefined, ++ title_padding: { ++ top: 0, ++ right: 0, ++ bottom: 0, ++ left: 0 ++ }, ++ title_position: 'top-center' ++ }; ++ ++ Object.keys(this.additionalConfig).forEach(function (key) { ++ config[key] = this.additionalConfig[key]; ++ }, this); ++ ++ return config; ++ }; ++ ChartInternal.prototype.additionalConfig = {}; ++ ++ ChartInternal.prototype.loadConfig = function (config) { ++ var this_config = this.config, ++ target, ++ keys, ++ read; ++ function find() { ++ var key = keys.shift(); ++ // console.log("key =>", key, ", target =>", target); ++ if (key && target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && key in target) { ++ target = target[key]; ++ return find(); ++ } else if (!key) { ++ return target; ++ } else { ++ return undefined; ++ } ++ } ++ Object.keys(this_config).forEach(function (key) { ++ target = config; ++ keys = key.split('_'); ++ read = find(); ++ // console.log("CONFIG : ", key, read); ++ if (isDefined(read)) { ++ this_config[key] = read; ++ } ++ }); ++ }; ++ ++ ChartInternal.prototype.convertUrlToData = function (url, mimeType, headers, keys, done) { ++ var $$ = this, ++ type = mimeType ? mimeType : 'csv', ++ f, ++ converter; ++ ++ if (type === 'json') { ++ f = $$.d3.json; ++ converter = $$.convertJsonToData; ++ } else if (type === 'tsv') { ++ f = $$.d3.tsv; ++ converter = $$.convertXsvToData; ++ } else { ++ f = $$.d3.csv; ++ converter = $$.convertXsvToData; ++ } ++ ++ f(url, headers).then(function (data) { ++ done.call($$, converter.call($$, data, keys)); ++ }).catch(function (error) { ++ throw error; ++ }); ++ }; ++ ChartInternal.prototype.convertXsvToData = function (xsv) { ++ var keys = xsv.columns, ++ rows = xsv; ++ if (rows.length === 0) { ++ return { keys: keys, rows: [keys.reduce(function (row, key) { ++ return Object.assign(row, defineProperty({}, key, null)); ++ }, {})] }; ++ } else { ++ // [].concat() is to convert result into a plain array otherwise ++ // test is not happy because rows have properties. ++ return { keys: keys, rows: [].concat(xsv) }; ++ } ++ }; ++ ChartInternal.prototype.convertJsonToData = function (json, keys) { ++ var $$ = this, ++ new_rows = [], ++ targetKeys, ++ data; ++ if (keys) { ++ // when keys specified, json would be an array that includes objects ++ if (keys.x) { ++ targetKeys = keys.value.concat(keys.x); ++ $$.config.data_x = keys.x; ++ } else { ++ targetKeys = keys.value; ++ } ++ new_rows.push(targetKeys); ++ json.forEach(function (o) { ++ var new_row = []; ++ targetKeys.forEach(function (key) { ++ // convert undefined to null because undefined data will be removed in convertDataToTargets() ++ var v = $$.findValueInJson(o, key); ++ if (isUndefined(v)) { ++ v = null; ++ } ++ new_row.push(v); ++ }); ++ new_rows.push(new_row); ++ }); ++ data = $$.convertRowsToData(new_rows); ++ } else { ++ Object.keys(json).forEach(function (key) { ++ new_rows.push([key].concat(json[key])); ++ }); ++ data = $$.convertColumnsToData(new_rows); ++ } ++ return data; ++ }; ++ ChartInternal.prototype.findValueInJson = function (object, path) { ++ path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties (replace [] with .) ++ path = path.replace(/^\./, ''); // strip a leading dot ++ var pathArray = path.split('.'); ++ for (var i = 0; i < pathArray.length; ++i) { ++ var k = pathArray[i]; ++ if (k in object) { ++ object = object[k]; ++ } else { ++ return; ++ } ++ } ++ return object; ++ }; ++ ++ /** ++ * Converts the rows to normalized data. ++ * @param {any[][]} rows The row data ++ * @return {Object} ++ */ ++ ChartInternal.prototype.convertRowsToData = function (rows) { ++ var newRows = []; ++ var keys = rows[0]; ++ ++ for (var i = 1; i < rows.length; i++) { ++ var newRow = {}; ++ for (var j = 0; j < rows[i].length; j++) { ++ if (isUndefined(rows[i][j])) { ++ throw new Error("Source data is missing a component at (" + i + "," + j + ")!"); ++ } ++ newRow[keys[j]] = rows[i][j]; ++ } ++ newRows.push(newRow); ++ } ++ return { keys: keys, rows: newRows }; ++ }; ++ ++ /** ++ * Converts the columns to normalized data. ++ * @param {any[][]} columns The column data ++ * @return {Object} ++ */ ++ ChartInternal.prototype.convertColumnsToData = function (columns) { ++ var newRows = []; ++ var keys = []; ++ ++ for (var i = 0; i < columns.length; i++) { ++ var key = columns[i][0]; ++ for (var j = 1; j < columns[i].length; j++) { ++ if (isUndefined(newRows[j - 1])) { ++ newRows[j - 1] = {}; ++ } ++ if (isUndefined(columns[i][j])) { ++ throw new Error("Source data is missing a component at (" + i + "," + j + ")!"); ++ } ++ newRows[j - 1][key] = columns[i][j]; ++ } ++ keys.push(key); ++ } ++ ++ return { keys: keys, rows: newRows }; ++ }; ++ ++ /** ++ * Converts the data format into the target format. ++ * @param {!Object} data ++ * @param {!Array} data.keys Ordered list of target IDs. ++ * @param {!Array} data.rows Rows of data to convert. ++ * @param {boolean} appendXs True to append to $$.data.xs, False to replace. ++ * @return {!Array} ++ */ ++ ChartInternal.prototype.convertDataToTargets = function (data, appendXs) { ++ var $$ = this, ++ config = $$.config, ++ targets, ++ ids, ++ xs, ++ keys; ++ ++ // handles format where keys are not orderly provided ++ if (isArray(data)) { ++ keys = Object.keys(data[0]); ++ } else { ++ keys = data.keys; ++ data = data.rows; ++ } ++ ++ ids = keys.filter($$.isNotX, $$); ++ xs = keys.filter($$.isX, $$); ++ ++ // save x for update data by load when custom x and c3.x API ++ ids.forEach(function (id) { ++ var xKey = $$.getXKey(id); ++ ++ if ($$.isCustomX() || $$.isTimeSeries()) { ++ // if included in input data ++ if (xs.indexOf(xKey) >= 0) { ++ $$.data.xs[id] = (appendXs && $$.data.xs[id] ? $$.data.xs[id] : []).concat(data.map(function (d) { ++ return d[xKey]; ++ }).filter(isValue).map(function (rawX, i) { ++ return $$.generateTargetX(rawX, id, i); ++ })); ++ } ++ // if not included in input data, find from preloaded data of other id's x ++ else if (config.data_x) { ++ $$.data.xs[id] = $$.getOtherTargetXs(); ++ } ++ // if not included in input data, find from preloaded data ++ else if (notEmpty(config.data_xs)) { ++ $$.data.xs[id] = $$.getXValuesOfXKey(xKey, $$.data.targets); ++ } ++ // MEMO: if no x included, use same x of current will be used ++ } else { ++ $$.data.xs[id] = data.map(function (d, i) { ++ return i; ++ }); ++ } ++ }); ++ ++ // check x is defined ++ ids.forEach(function (id) { ++ if (!$$.data.xs[id]) { ++ throw new Error('x is not defined for id = "' + id + '".'); ++ } ++ }); ++ ++ // convert to target ++ targets = ids.map(function (id, index) { ++ var convertedId = config.data_idConverter(id); ++ return { ++ id: convertedId, ++ id_org: id, ++ values: data.map(function (d, i) { ++ var xKey = $$.getXKey(id), ++ rawX = d[xKey], ++ value = d[id] !== null && !isNaN(d[id]) ? +d[id] : null, ++ x; ++ // use x as categories if custom x and categorized ++ if ($$.isCustomX() && $$.isCategorized() && !isUndefined(rawX)) { ++ if (index === 0 && i === 0) { ++ config.axis_x_categories = []; ++ } ++ x = config.axis_x_categories.indexOf(rawX); ++ if (x === -1) { ++ x = config.axis_x_categories.length; ++ config.axis_x_categories.push(rawX); ++ } ++ } else { ++ x = $$.generateTargetX(rawX, id, i); ++ } ++ // mark as x = undefined if value is undefined and filter to remove after mapped ++ if (isUndefined(d[id]) || $$.data.xs[id].length <= i) { ++ x = undefined; ++ } ++ return { x: x, value: value, id: convertedId }; ++ }).filter(function (v) { ++ return isDefined(v.x); ++ }) ++ }; ++ }); ++ ++ // finish targets ++ targets.forEach(function (t) { ++ var i; ++ // sort values by its x ++ if (config.data_xSort) { ++ t.values = t.values.sort(function (v1, v2) { ++ var x1 = v1.x || v1.x === 0 ? v1.x : Infinity, ++ x2 = v2.x || v2.x === 0 ? v2.x : Infinity; ++ return x1 - x2; ++ }); ++ } ++ // indexing each value ++ i = 0; ++ t.values.forEach(function (v) { ++ v.index = i++; ++ }); ++ // this needs to be sorted because its index and value.index is identical ++ $$.data.xs[t.id].sort(function (v1, v2) { ++ return v1 - v2; ++ }); ++ }); ++ ++ // cache information about values ++ $$.hasNegativeValue = $$.hasNegativeValueInTargets(targets); ++ $$.hasPositiveValue = $$.hasPositiveValueInTargets(targets); ++ ++ // set target types ++ if (config.data_type) { ++ $$.setTargetType($$.mapToIds(targets).filter(function (id) { ++ return !(id in config.data_types); ++ }), config.data_type); ++ } ++ ++ // cache as original id keyed ++ targets.forEach(function (d) { ++ $$.addCache(d.id_org, d); ++ }); ++ ++ return targets; ++ }; ++ ++ ChartInternal.prototype.isX = function (key) { ++ var $$ = this, ++ config = $$.config; ++ return config.data_x && key === config.data_x || notEmpty(config.data_xs) && hasValue(config.data_xs, key); ++ }; ++ ChartInternal.prototype.isNotX = function (key) { ++ return !this.isX(key); ++ }; ++ ChartInternal.prototype.getXKey = function (id) { ++ var $$ = this, ++ config = $$.config; ++ return config.data_x ? config.data_x : notEmpty(config.data_xs) ? config.data_xs[id] : null; ++ }; ++ ChartInternal.prototype.getXValuesOfXKey = function (key, targets) { ++ var $$ = this, ++ xValues, ++ ids = targets && notEmpty(targets) ? $$.mapToIds(targets) : []; ++ ids.forEach(function (id) { ++ if ($$.getXKey(id) === key) { ++ xValues = $$.data.xs[id]; ++ } ++ }); ++ return xValues; ++ }; ++ ChartInternal.prototype.getXValue = function (id, i) { ++ var $$ = this; ++ return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i]) ? $$.data.xs[id][i] : i; ++ }; ++ ChartInternal.prototype.getOtherTargetXs = function () { ++ var $$ = this, ++ idsForX = Object.keys($$.data.xs); ++ return idsForX.length ? $$.data.xs[idsForX[0]] : null; ++ }; ++ ChartInternal.prototype.getOtherTargetX = function (index) { ++ var xs = this.getOtherTargetXs(); ++ return xs && index < xs.length ? xs[index] : null; ++ }; ++ ChartInternal.prototype.addXs = function (xs) { ++ var $$ = this; ++ Object.keys(xs).forEach(function (id) { ++ $$.config.data_xs[id] = xs[id]; ++ }); ++ }; ++ ChartInternal.prototype.addName = function (data) { ++ var $$ = this, ++ name; ++ if (data) { ++ name = $$.config.data_names[data.id]; ++ data.name = name !== undefined ? name : data.id; ++ } ++ return data; ++ }; ++ ChartInternal.prototype.getValueOnIndex = function (values, index) { ++ var valueOnIndex = values.filter(function (v) { ++ return v.index === index; ++ }); ++ return valueOnIndex.length ? valueOnIndex[0] : null; ++ }; ++ ChartInternal.prototype.updateTargetX = function (targets, x) { ++ var $$ = this; ++ targets.forEach(function (t) { ++ t.values.forEach(function (v, i) { ++ v.x = $$.generateTargetX(x[i], t.id, i); ++ }); ++ $$.data.xs[t.id] = x; ++ }); ++ }; ++ ChartInternal.prototype.updateTargetXs = function (targets, xs) { ++ var $$ = this; ++ targets.forEach(function (t) { ++ if (xs[t.id]) { ++ $$.updateTargetX([t], xs[t.id]); ++ } ++ }); ++ }; ++ ChartInternal.prototype.generateTargetX = function (rawX, id, index) { ++ var $$ = this, ++ x; ++ if ($$.isTimeSeries()) { ++ x = rawX ? $$.parseDate(rawX) : $$.parseDate($$.getXValue(id, index)); ++ } else if ($$.isCustomX() && !$$.isCategorized()) { ++ x = isValue(rawX) ? +rawX : $$.getXValue(id, index); ++ } else { ++ x = index; ++ } ++ return x; ++ }; ++ ChartInternal.prototype.cloneTarget = function (target) { ++ return { ++ id: target.id, ++ id_org: target.id_org, ++ values: target.values.map(function (d) { ++ return { ++ x: d.x, ++ value: d.value, ++ id: d.id ++ }; ++ }) ++ }; ++ }; ++ ChartInternal.prototype.getMaxDataCount = function () { ++ var $$ = this; ++ return $$.d3.max($$.data.targets, function (t) { ++ return t.values.length; ++ }); ++ }; ++ ChartInternal.prototype.mapToIds = function (targets) { ++ return targets.map(function (d) { ++ return d.id; ++ }); ++ }; ++ ChartInternal.prototype.mapToTargetIds = function (ids) { ++ var $$ = this; ++ return ids ? [].concat(ids) : $$.mapToIds($$.data.targets); ++ }; ++ ChartInternal.prototype.hasTarget = function (targets, id) { ++ var ids = this.mapToIds(targets), ++ i; ++ for (i = 0; i < ids.length; i++) { ++ if (ids[i] === id) { ++ return true; ++ } ++ } ++ return false; ++ }; ++ ChartInternal.prototype.isTargetToShow = function (targetId) { ++ return this.hiddenTargetIds.indexOf(targetId) < 0; ++ }; ++ ChartInternal.prototype.isLegendToShow = function (targetId) { ++ return this.hiddenLegendIds.indexOf(targetId) < 0; ++ }; ++ ChartInternal.prototype.filterTargetsToShow = function (targets) { ++ var $$ = this; ++ return targets.filter(function (t) { ++ return $$.isTargetToShow(t.id); ++ }); ++ }; ++ ChartInternal.prototype.mapTargetsToUniqueXs = function (targets) { ++ var $$ = this; ++ var xs = $$.d3.set($$.d3.merge(targets.map(function (t) { ++ return t.values.map(function (v) { ++ return +v.x; ++ }); ++ }))).values(); ++ xs = $$.isTimeSeries() ? xs.map(function (x) { ++ return new Date(+x); ++ }) : xs.map(function (x) { ++ return +x; ++ }); ++ return xs.sort(function (a, b) { ++ return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; ++ }); ++ }; ++ ChartInternal.prototype.addHiddenTargetIds = function (targetIds) { ++ targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds); ++ for (var i = 0; i < targetIds.length; i++) { ++ if (this.hiddenTargetIds.indexOf(targetIds[i]) < 0) { ++ this.hiddenTargetIds = this.hiddenTargetIds.concat(targetIds[i]); ++ } ++ } ++ }; ++ ChartInternal.prototype.removeHiddenTargetIds = function (targetIds) { ++ this.hiddenTargetIds = this.hiddenTargetIds.filter(function (id) { ++ return targetIds.indexOf(id) < 0; ++ }); ++ }; ++ ChartInternal.prototype.addHiddenLegendIds = function (targetIds) { ++ targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds); ++ for (var i = 0; i < targetIds.length; i++) { ++ if (this.hiddenLegendIds.indexOf(targetIds[i]) < 0) { ++ this.hiddenLegendIds = this.hiddenLegendIds.concat(targetIds[i]); ++ } ++ } ++ }; ++ ChartInternal.prototype.removeHiddenLegendIds = function (targetIds) { ++ this.hiddenLegendIds = this.hiddenLegendIds.filter(function (id) { ++ return targetIds.indexOf(id) < 0; ++ }); ++ }; ++ ChartInternal.prototype.getValuesAsIdKeyed = function (targets) { ++ var ys = {}; ++ targets.forEach(function (t) { ++ ys[t.id] = []; ++ t.values.forEach(function (v) { ++ ys[t.id].push(v.value); ++ }); ++ }); ++ return ys; ++ }; ++ ChartInternal.prototype.checkValueInTargets = function (targets, checker) { ++ var ids = Object.keys(targets), ++ i, ++ j, ++ values; ++ for (i = 0; i < ids.length; i++) { ++ values = targets[ids[i]].values; ++ for (j = 0; j < values.length; j++) { ++ if (checker(values[j].value)) { ++ return true; ++ } ++ } ++ } ++ return false; ++ }; ++ ChartInternal.prototype.hasNegativeValueInTargets = function (targets) { ++ return this.checkValueInTargets(targets, function (v) { ++ return v < 0; ++ }); ++ }; ++ ChartInternal.prototype.hasPositiveValueInTargets = function (targets) { ++ return this.checkValueInTargets(targets, function (v) { ++ return v > 0; ++ }); ++ }; ++ ChartInternal.prototype.isOrderDesc = function () { ++ var config = this.config; ++ return typeof config.data_order === 'string' && config.data_order.toLowerCase() === 'desc'; ++ }; ++ ChartInternal.prototype.isOrderAsc = function () { ++ var config = this.config; ++ return typeof config.data_order === 'string' && config.data_order.toLowerCase() === 'asc'; ++ }; ++ ChartInternal.prototype.getOrderFunction = function () { ++ var $$ = this, ++ config = $$.config, ++ orderAsc = $$.isOrderAsc(), ++ orderDesc = $$.isOrderDesc(); ++ if (orderAsc || orderDesc) { ++ var reducer = function reducer(p, c) { ++ return p + Math.abs(c.value); ++ }; ++ return function (t1, t2) { ++ var t1Sum = t1.values.reduce(reducer, 0), ++ t2Sum = t2.values.reduce(reducer, 0); ++ return orderAsc ? t2Sum - t1Sum : t1Sum - t2Sum; ++ }; ++ } else if (isFunction(config.data_order)) { ++ return config.data_order; ++ } else if (isArray(config.data_order)) { ++ var order = config.data_order; ++ return function (t1, t2) { ++ return order.indexOf(t1.id) - order.indexOf(t2.id); ++ }; ++ } ++ }; ++ ChartInternal.prototype.orderTargets = function (targets) { ++ var fct = this.getOrderFunction(); ++ if (fct) { ++ targets.sort(fct); ++ } ++ return targets; ++ }; ++ ChartInternal.prototype.filterByX = function (targets, x) { ++ return this.d3.merge(targets.map(function (t) { ++ return t.values; ++ })).filter(function (v) { ++ return v.x - x === 0; ++ }); ++ }; ++ ChartInternal.prototype.filterRemoveNull = function (data) { ++ return data.filter(function (d) { ++ return isValue(d.value); ++ }); ++ }; ++ ChartInternal.prototype.filterByXDomain = function (targets, xDomain) { ++ return targets.map(function (t) { ++ return { ++ id: t.id, ++ id_org: t.id_org, ++ values: t.values.filter(function (v) { ++ return xDomain[0] <= v.x && v.x <= xDomain[1]; ++ }) ++ }; ++ }); ++ }; ++ ChartInternal.prototype.hasDataLabel = function () { ++ var config = this.config; ++ if (typeof config.data_labels === 'boolean' && config.data_labels) { ++ return true; ++ } else if (_typeof(config.data_labels) === 'object' && notEmpty(config.data_labels)) { ++ return true; ++ } ++ return false; ++ }; ++ ChartInternal.prototype.getDataLabelLength = function (min, max, key) { ++ var $$ = this, ++ lengths = [0, 0], ++ paddingCoef = 1.3; ++ $$.selectChart.select('svg').selectAll('.dummy').data([min, max]).enter().append('text').text(function (d) { ++ return $$.dataLabelFormat(d.id)(d); ++ }).each(function (d, i) { ++ lengths[i] = this.getBoundingClientRect()[key] * paddingCoef; ++ }).remove(); ++ return lengths; ++ }; ++ ChartInternal.prototype.isNoneArc = function (d) { ++ return this.hasTarget(this.data.targets, d.id); ++ }, ChartInternal.prototype.isArc = function (d) { ++ return 'data' in d && this.hasTarget(this.data.targets, d.data.id); ++ }; ++ ChartInternal.prototype.findClosestFromTargets = function (targets, pos) { ++ var $$ = this, ++ candidates; ++ ++ // map to array of closest points of each target ++ candidates = targets.map(function (target) { ++ return $$.findClosest(target.values, pos); ++ }); ++ ++ // decide closest point and return ++ return $$.findClosest(candidates, pos); ++ }; ++ ChartInternal.prototype.findClosest = function (values, pos) { ++ var $$ = this, ++ minDist = $$.config.point_sensitivity, ++ closest; ++ ++ // find mouseovering bar ++ values.filter(function (v) { ++ return v && $$.isBarType(v.id); ++ }).forEach(function (v) { ++ var shape = $$.main.select('.' + CLASS.bars + $$.getTargetSelectorSuffix(v.id) + ' .' + CLASS.bar + '-' + v.index).node(); ++ if (!closest && $$.isWithinBar($$.d3.mouse(shape), shape)) { ++ closest = v; ++ } ++ }); ++ ++ // find closest point from non-bar ++ values.filter(function (v) { ++ return v && !$$.isBarType(v.id); ++ }).forEach(function (v) { ++ var d = $$.dist(v, pos); ++ if (d < minDist) { ++ minDist = d; ++ closest = v; ++ } ++ }); ++ ++ return closest; ++ }; ++ ChartInternal.prototype.dist = function (data, pos) { ++ var $$ = this, ++ config = $$.config, ++ xIndex = config.axis_rotated ? 1 : 0, ++ yIndex = config.axis_rotated ? 0 : 1, ++ y = $$.circleY(data, data.index), ++ x = $$.x(data.x); ++ return Math.sqrt(Math.pow(x - pos[xIndex], 2) + Math.pow(y - pos[yIndex], 2)); ++ }; ++ ChartInternal.prototype.convertValuesToStep = function (values) { ++ var converted = [].concat(values), ++ i; ++ ++ if (!this.isCategorized()) { ++ return values; ++ } ++ ++ for (i = values.length + 1; 0 < i; i--) { ++ converted[i] = converted[i - 1]; ++ } ++ ++ converted[0] = { ++ x: converted[0].x - 1, ++ value: converted[0].value, ++ id: converted[0].id ++ }; ++ converted[values.length + 1] = { ++ x: converted[values.length].x + 1, ++ value: converted[values.length].value, ++ id: converted[values.length].id ++ }; ++ ++ return converted; ++ }; ++ ChartInternal.prototype.updateDataAttributes = function (name, attrs) { ++ var $$ = this, ++ config = $$.config, ++ current = config['data_' + name]; ++ if (typeof attrs === 'undefined') { ++ return current; ++ } ++ Object.keys(attrs).forEach(function (id) { ++ current[id] = attrs[id]; ++ }); ++ $$.redraw({ ++ withLegend: true ++ }); ++ return current; ++ }; ++ ++ ChartInternal.prototype.load = function (targets, args) { ++ var $$ = this; ++ if (targets) { ++ // filter loading targets if needed ++ if (args.filter) { ++ targets = targets.filter(args.filter); ++ } ++ // set type if args.types || args.type specified ++ if (args.type || args.types) { ++ targets.forEach(function (t) { ++ var type = args.types && args.types[t.id] ? args.types[t.id] : args.type; ++ $$.setTargetType(t.id, type); ++ }); ++ } ++ // Update/Add data ++ $$.data.targets.forEach(function (d) { ++ for (var i = 0; i < targets.length; i++) { ++ if (d.id === targets[i].id) { ++ d.values = targets[i].values; ++ targets.splice(i, 1); ++ break; ++ } ++ } ++ }); ++ $$.data.targets = $$.data.targets.concat(targets); // add remained ++ } ++ ++ // Set targets ++ $$.updateTargets($$.data.targets); ++ ++ // Redraw with new targets ++ $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true }); ++ ++ if (args.done) { ++ args.done(); ++ } ++ }; ++ ChartInternal.prototype.loadFromArgs = function (args) { ++ var $$ = this; ++ if (args.data) { ++ $$.load($$.convertDataToTargets(args.data), args); ++ } else if (args.url) { ++ $$.convertUrlToData(args.url, args.mimeType, args.headers, args.keys, function (data) { ++ $$.load($$.convertDataToTargets(data), args); ++ }); ++ } else if (args.json) { ++ $$.load($$.convertDataToTargets($$.convertJsonToData(args.json, args.keys)), args); ++ } else if (args.rows) { ++ $$.load($$.convertDataToTargets($$.convertRowsToData(args.rows)), args); ++ } else if (args.columns) { ++ $$.load($$.convertDataToTargets($$.convertColumnsToData(args.columns)), args); ++ } else { ++ $$.load(null, args); ++ } ++ }; ++ ChartInternal.prototype.unload = function (targetIds, done) { ++ var $$ = this; ++ if (!done) { ++ done = function done() {}; ++ } ++ // filter existing target ++ targetIds = targetIds.filter(function (id) { ++ return $$.hasTarget($$.data.targets, id); ++ }); ++ // If no target, call done and return ++ if (!targetIds || targetIds.length === 0) { ++ done(); ++ return; ++ } ++ $$.svg.selectAll(targetIds.map(function (id) { ++ return $$.selectorTarget(id); ++ })).transition().style('opacity', 0).remove().call($$.endall, done); ++ targetIds.forEach(function (id) { ++ // Reset fadein for future load ++ $$.withoutFadeIn[id] = false; ++ // Remove target's elements ++ if ($$.legend) { ++ $$.legend.selectAll('.' + CLASS.legendItem + $$.getTargetSelectorSuffix(id)).remove(); ++ } ++ // Remove target ++ $$.data.targets = $$.data.targets.filter(function (t) { ++ return t.id !== id; ++ }); ++ }); ++ }; ++ ++ ChartInternal.prototype.getYDomainMin = function (targets) { ++ var $$ = this, ++ config = $$.config, ++ ids = $$.mapToIds(targets), ++ ys = $$.getValuesAsIdKeyed(targets), ++ j, ++ k, ++ baseId, ++ idsInGroup, ++ id, ++ hasNegativeValue; ++ if (config.data_groups.length > 0) { ++ hasNegativeValue = $$.hasNegativeValueInTargets(targets); ++ for (j = 0; j < config.data_groups.length; j++) { ++ // Determine baseId ++ idsInGroup = config.data_groups[j].filter(function (id) { ++ return ids.indexOf(id) >= 0; ++ }); ++ if (idsInGroup.length === 0) { ++ continue; ++ } ++ baseId = idsInGroup[0]; ++ // Consider negative values ++ if (hasNegativeValue && ys[baseId]) { ++ ys[baseId].forEach(function (v, i) { ++ ys[baseId][i] = v < 0 ? v : 0; ++ }); ++ } ++ // Compute min ++ for (k = 1; k < idsInGroup.length; k++) { ++ id = idsInGroup[k]; ++ if (!ys[id]) { ++ continue; ++ } ++ ys[id].forEach(function (v, i) { ++ if ($$.axis.getId(id) === $$.axis.getId(baseId) && ys[baseId] && !(hasNegativeValue && +v > 0)) { ++ ys[baseId][i] += +v; ++ } ++ }); ++ } ++ } ++ } ++ return $$.d3.min(Object.keys(ys).map(function (key) { ++ return $$.d3.min(ys[key]); ++ })); ++ }; ++ ChartInternal.prototype.getYDomainMax = function (targets) { ++ var $$ = this, ++ config = $$.config, ++ ids = $$.mapToIds(targets), ++ ys = $$.getValuesAsIdKeyed(targets), ++ j, ++ k, ++ baseId, ++ idsInGroup, ++ id, ++ hasPositiveValue; ++ if (config.data_groups.length > 0) { ++ hasPositiveValue = $$.hasPositiveValueInTargets(targets); ++ for (j = 0; j < config.data_groups.length; j++) { ++ // Determine baseId ++ idsInGroup = config.data_groups[j].filter(function (id) { ++ return ids.indexOf(id) >= 0; ++ }); ++ if (idsInGroup.length === 0) { ++ continue; ++ } ++ baseId = idsInGroup[0]; ++ // Consider positive values ++ if (hasPositiveValue && ys[baseId]) { ++ ys[baseId].forEach(function (v, i) { ++ ys[baseId][i] = v > 0 ? v : 0; ++ }); ++ } ++ // Compute max ++ for (k = 1; k < idsInGroup.length; k++) { ++ id = idsInGroup[k]; ++ if (!ys[id]) { ++ continue; ++ } ++ ys[id].forEach(function (v, i) { ++ if ($$.axis.getId(id) === $$.axis.getId(baseId) && ys[baseId] && !(hasPositiveValue && +v < 0)) { ++ ys[baseId][i] += +v; ++ } ++ }); ++ } ++ } ++ } ++ return $$.d3.max(Object.keys(ys).map(function (key) { ++ return $$.d3.max(ys[key]); ++ })); ++ }; ++ ChartInternal.prototype.getYDomain = function (targets, axisId, xDomain) { ++ var $$ = this, ++ config = $$.config, ++ targetsByAxisId = targets.filter(function (t) { ++ return $$.axis.getId(t.id) === axisId; ++ }), ++ yTargets = xDomain ? $$.filterByXDomain(targetsByAxisId, xDomain) : targetsByAxisId, ++ yMin = axisId === 'y2' ? config.axis_y2_min : config.axis_y_min, ++ yMax = axisId === 'y2' ? config.axis_y2_max : config.axis_y_max, ++ yDomainMin = $$.getYDomainMin(yTargets), ++ yDomainMax = $$.getYDomainMax(yTargets), ++ domain, ++ domainLength, ++ padding, ++ padding_top, ++ padding_bottom, ++ center = axisId === 'y2' ? config.axis_y2_center : config.axis_y_center, ++ yDomainAbs, ++ lengths, ++ diff, ++ ratio, ++ isAllPositive, ++ isAllNegative, ++ isZeroBased = $$.hasType('bar', yTargets) && config.bar_zerobased || $$.hasType('area', yTargets) && config.area_zerobased, ++ isInverted = axisId === 'y2' ? config.axis_y2_inverted : config.axis_y_inverted, ++ showHorizontalDataLabel = $$.hasDataLabel() && config.axis_rotated, ++ showVerticalDataLabel = $$.hasDataLabel() && !config.axis_rotated; ++ ++ // MEMO: avoid inverting domain unexpectedly ++ yDomainMin = isValue(yMin) ? yMin : isValue(yMax) ? yDomainMin < yMax ? yDomainMin : yMax - 10 : yDomainMin; ++ yDomainMax = isValue(yMax) ? yMax : isValue(yMin) ? yMin < yDomainMax ? yDomainMax : yMin + 10 : yDomainMax; ++ ++ if (yTargets.length === 0) { ++ // use current domain if target of axisId is none ++ return axisId === 'y2' ? $$.y2.domain() : $$.y.domain(); ++ } ++ if (isNaN(yDomainMin)) { ++ // set minimum to zero when not number ++ yDomainMin = 0; ++ } ++ if (isNaN(yDomainMax)) { ++ // set maximum to have same value as yDomainMin ++ yDomainMax = yDomainMin; ++ } ++ if (yDomainMin === yDomainMax) { ++ yDomainMin < 0 ? yDomainMax = 0 : yDomainMin = 0; ++ } ++ isAllPositive = yDomainMin >= 0 && yDomainMax >= 0; ++ isAllNegative = yDomainMin <= 0 && yDomainMax <= 0; ++ ++ // Cancel zerobased if axis_*_min / axis_*_max specified ++ if (isValue(yMin) && isAllPositive || isValue(yMax) && isAllNegative) { ++ isZeroBased = false; ++ } ++ ++ // Bar/Area chart should be 0-based if all positive|negative ++ if (isZeroBased) { ++ if (isAllPositive) { ++ yDomainMin = 0; ++ } ++ if (isAllNegative) { ++ yDomainMax = 0; ++ } ++ } ++ ++ domainLength = Math.abs(yDomainMax - yDomainMin); ++ padding = padding_top = padding_bottom = domainLength * 0.1; ++ ++ if (typeof center !== 'undefined') { ++ yDomainAbs = Math.max(Math.abs(yDomainMin), Math.abs(yDomainMax)); ++ yDomainMax = center + yDomainAbs; ++ yDomainMin = center - yDomainAbs; ++ } ++ // add padding for data label ++ if (showHorizontalDataLabel) { ++ lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'width'); ++ diff = diffDomain($$.y.range()); ++ ratio = [lengths[0] / diff, lengths[1] / diff]; ++ padding_top += domainLength * (ratio[1] / (1 - ratio[0] - ratio[1])); ++ padding_bottom += domainLength * (ratio[0] / (1 - ratio[0] - ratio[1])); ++ } else if (showVerticalDataLabel) { ++ lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'height'); ++ padding_top += $$.axis.convertPixelsToAxisPadding(lengths[1], domainLength); ++ padding_bottom += $$.axis.convertPixelsToAxisPadding(lengths[0], domainLength); ++ } ++ if (axisId === 'y' && notEmpty(config.axis_y_padding)) { ++ padding_top = $$.axis.getPadding(config.axis_y_padding, 'top', padding_top, domainLength); ++ padding_bottom = $$.axis.getPadding(config.axis_y_padding, 'bottom', padding_bottom, domainLength); ++ } ++ if (axisId === 'y2' && notEmpty(config.axis_y2_padding)) { ++ padding_top = $$.axis.getPadding(config.axis_y2_padding, 'top', padding_top, domainLength); ++ padding_bottom = $$.axis.getPadding(config.axis_y2_padding, 'bottom', padding_bottom, domainLength); ++ } ++ // Bar/Area chart should be 0-based if all positive|negative ++ if (isZeroBased) { ++ if (isAllPositive) { ++ padding_bottom = yDomainMin; ++ } ++ if (isAllNegative) { ++ padding_top = -yDomainMax; ++ } ++ } ++ domain = [yDomainMin - padding_bottom, yDomainMax + padding_top]; ++ return isInverted ? domain.reverse() : domain; ++ }; ++ ChartInternal.prototype.getXDomainMin = function (targets) { ++ var $$ = this, ++ config = $$.config; ++ return isDefined(config.axis_x_min) ? $$.isTimeSeries() ? this.parseDate(config.axis_x_min) : config.axis_x_min : $$.d3.min(targets, function (t) { ++ return $$.d3.min(t.values, function (v) { ++ return v.x; ++ }); ++ }); ++ }; ++ ChartInternal.prototype.getXDomainMax = function (targets) { ++ var $$ = this, ++ config = $$.config; ++ return isDefined(config.axis_x_max) ? $$.isTimeSeries() ? this.parseDate(config.axis_x_max) : config.axis_x_max : $$.d3.max(targets, function (t) { ++ return $$.d3.max(t.values, function (v) { ++ return v.x; ++ }); ++ }); ++ }; ++ ChartInternal.prototype.getXDomainPadding = function (domain) { ++ var $$ = this, ++ config = $$.config, ++ diff = domain[1] - domain[0], ++ maxDataCount, ++ padding, ++ paddingLeft, ++ paddingRight; ++ if ($$.isCategorized()) { ++ padding = 0; ++ } else if ($$.hasType('bar')) { ++ maxDataCount = $$.getMaxDataCount(); ++ padding = maxDataCount > 1 ? diff / (maxDataCount - 1) / 2 : 0.5; ++ } else { ++ padding = diff * 0.01; ++ } ++ if (_typeof(config.axis_x_padding) === 'object' && notEmpty(config.axis_x_padding)) { ++ paddingLeft = isValue(config.axis_x_padding.left) ? config.axis_x_padding.left : padding; ++ paddingRight = isValue(config.axis_x_padding.right) ? config.axis_x_padding.right : padding; ++ } else if (typeof config.axis_x_padding === 'number') { ++ paddingLeft = paddingRight = config.axis_x_padding; ++ } else { ++ paddingLeft = paddingRight = padding; ++ } ++ return { left: paddingLeft, right: paddingRight }; ++ }; ++ ChartInternal.prototype.getXDomain = function (targets) { ++ var $$ = this, ++ xDomain = [$$.getXDomainMin(targets), $$.getXDomainMax(targets)], ++ firstX = xDomain[0], ++ lastX = xDomain[1], ++ padding = $$.getXDomainPadding(xDomain), ++ min = 0, ++ max = 0; ++ // show center of x domain if min and max are the same ++ if (firstX - lastX === 0 && !$$.isCategorized()) { ++ if ($$.isTimeSeries()) { ++ firstX = new Date(firstX.getTime() * 0.5); ++ lastX = new Date(lastX.getTime() * 1.5); ++ } else { ++ firstX = firstX === 0 ? 1 : firstX * 0.5; ++ lastX = lastX === 0 ? -1 : lastX * 1.5; ++ } ++ } ++ if (firstX || firstX === 0) { ++ min = $$.isTimeSeries() ? new Date(firstX.getTime() - padding.left) : firstX - padding.left; ++ } ++ if (lastX || lastX === 0) { ++ max = $$.isTimeSeries() ? new Date(lastX.getTime() + padding.right) : lastX + padding.right; ++ } ++ return [min, max]; ++ }; ++ ChartInternal.prototype.updateXDomain = function (targets, withUpdateXDomain, withUpdateOrgXDomain, withTrim, domain) { ++ var $$ = this, ++ config = $$.config; ++ ++ if (withUpdateOrgXDomain) { ++ $$.x.domain(domain ? domain : $$.d3.extent($$.getXDomain(targets))); ++ $$.orgXDomain = $$.x.domain(); ++ if (config.zoom_enabled) { ++ $$.zoom.update(); ++ } ++ $$.subX.domain($$.x.domain()); ++ if ($$.brush) { ++ $$.brush.updateScale($$.subX); ++ } ++ } ++ if (withUpdateXDomain) { ++ $$.x.domain(domain ? domain : !$$.brush || $$.brush.empty() ? $$.orgXDomain : $$.brush.selectionAsValue()); ++ } ++ ++ // Trim domain when too big by zoom mousemove event ++ if (withTrim) { ++ $$.x.domain($$.trimXDomain($$.x.orgDomain())); ++ } ++ ++ return $$.x.domain(); ++ }; ++ ChartInternal.prototype.trimXDomain = function (domain) { ++ var zoomDomain = this.getZoomDomain(), ++ min = zoomDomain[0], ++ max = zoomDomain[1]; ++ if (domain[0] <= min) { ++ domain[1] = +domain[1] + (min - domain[0]); ++ domain[0] = min; ++ } ++ if (max <= domain[1]) { ++ domain[0] = +domain[0] - (domain[1] - max); ++ domain[1] = max; ++ } ++ return domain; ++ }; ++ ++ ChartInternal.prototype.drag = function (mouse) { ++ var $$ = this, ++ config = $$.config, ++ main = $$.main, ++ d3 = $$.d3; ++ var sx, sy, mx, my, minX, maxX, minY, maxY; ++ ++ if ($$.hasArcType()) { ++ return; ++ } ++ if (!config.data_selection_enabled) { ++ return; ++ } // do nothing if not selectable ++ if (!config.data_selection_multiple) { ++ return; ++ } // skip when single selection because drag is used for multiple selection ++ ++ sx = $$.dragStart[0]; ++ sy = $$.dragStart[1]; ++ mx = mouse[0]; ++ my = mouse[1]; ++ minX = Math.min(sx, mx); ++ maxX = Math.max(sx, mx); ++ minY = config.data_selection_grouped ? $$.margin.top : Math.min(sy, my); ++ maxY = config.data_selection_grouped ? $$.height : Math.max(sy, my); ++ ++ main.select('.' + CLASS.dragarea).attr('x', minX).attr('y', minY).attr('width', maxX - minX).attr('height', maxY - minY); ++ // TODO: binary search when multiple xs ++ main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).filter(function (d) { ++ return config.data_selection_isselectable(d); ++ }).each(function (d, i) { ++ var shape = d3.select(this), ++ isSelected = shape.classed(CLASS.SELECTED), ++ isIncluded = shape.classed(CLASS.INCLUDED), ++ _x, ++ _y, ++ _w, ++ _h, ++ toggle, ++ isWithin = false, ++ box; ++ if (shape.classed(CLASS.circle)) { ++ _x = shape.attr("cx") * 1; ++ _y = shape.attr("cy") * 1; ++ toggle = $$.togglePoint; ++ isWithin = minX < _x && _x < maxX && minY < _y && _y < maxY; ++ } else if (shape.classed(CLASS.bar)) { ++ box = getPathBox(this); ++ _x = box.x; ++ _y = box.y; ++ _w = box.width; ++ _h = box.height; ++ toggle = $$.togglePath; ++ isWithin = !(maxX < _x || _x + _w < minX) && !(maxY < _y || _y + _h < minY); ++ } else { ++ // line/area selection not supported yet ++ return; ++ } ++ if (isWithin ^ isIncluded) { ++ shape.classed(CLASS.INCLUDED, !isIncluded); ++ // TODO: included/unincluded callback here ++ shape.classed(CLASS.SELECTED, !isSelected); ++ toggle.call($$, !isSelected, shape, d, i); ++ } ++ }); ++ }; ++ ++ ChartInternal.prototype.dragstart = function (mouse) { ++ var $$ = this, ++ config = $$.config; ++ if ($$.hasArcType()) { ++ return; ++ } ++ if (!config.data_selection_enabled) { ++ return; ++ } // do nothing if not selectable ++ $$.dragStart = mouse; ++ $$.main.select('.' + CLASS.chart).append('rect').attr('class', CLASS.dragarea).style('opacity', 0.1); ++ $$.dragging = true; ++ }; ++ ++ ChartInternal.prototype.dragend = function () { ++ var $$ = this, ++ config = $$.config; ++ if ($$.hasArcType()) { ++ return; ++ } ++ if (!config.data_selection_enabled) { ++ return; ++ } // do nothing if not selectable ++ $$.main.select('.' + CLASS.dragarea).transition().duration(100).style('opacity', 0).remove(); ++ $$.main.selectAll('.' + CLASS.shape).classed(CLASS.INCLUDED, false); ++ $$.dragging = false; ++ }; ++ ++ ChartInternal.prototype.getYFormat = function (forArc) { ++ var $$ = this, ++ formatForY = forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.yFormat, ++ formatForY2 = forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.y2Format; ++ return function (v, ratio, id) { ++ var format = $$.axis.getId(id) === 'y2' ? formatForY2 : formatForY; ++ return format.call($$, v, ratio); ++ }; ++ }; ++ ChartInternal.prototype.yFormat = function (v) { ++ var $$ = this, ++ config = $$.config, ++ format = config.axis_y_tick_format ? config.axis_y_tick_format : $$.defaultValueFormat; ++ return format(v); ++ }; ++ ChartInternal.prototype.y2Format = function (v) { ++ var $$ = this, ++ config = $$.config, ++ format = config.axis_y2_tick_format ? config.axis_y2_tick_format : $$.defaultValueFormat; ++ return format(v); ++ }; ++ ChartInternal.prototype.defaultValueFormat = function (v) { ++ return isValue(v) ? +v : ""; ++ }; ++ ChartInternal.prototype.defaultArcValueFormat = function (v, ratio) { ++ return (ratio * 100).toFixed(1) + '%'; ++ }; ++ ChartInternal.prototype.dataLabelFormat = function (targetId) { ++ var $$ = this, ++ data_labels = $$.config.data_labels, ++ format, ++ defaultFormat = function defaultFormat(v) { ++ return isValue(v) ? +v : ""; ++ }; ++ // find format according to axis id ++ if (typeof data_labels.format === 'function') { ++ format = data_labels.format; ++ } else if (_typeof(data_labels.format) === 'object') { ++ if (data_labels.format[targetId]) { ++ format = data_labels.format[targetId] === true ? defaultFormat : data_labels.format[targetId]; ++ } else { ++ format = function format() { ++ return ''; ++ }; ++ } ++ } else { ++ format = defaultFormat; ++ } ++ return format; ++ }; ++ ++ ChartInternal.prototype.initGrid = function () { ++ var $$ = this, ++ config = $$.config, ++ d3 = $$.d3; ++ $$.grid = $$.main.append('g').attr("clip-path", $$.clipPathForGrid).attr('class', CLASS.grid); ++ if (config.grid_x_show) { ++ $$.grid.append("g").attr("class", CLASS.xgrids); ++ } ++ if (config.grid_y_show) { ++ $$.grid.append('g').attr('class', CLASS.ygrids); ++ } ++ if (config.grid_focus_show) { ++ $$.grid.append('g').attr("class", CLASS.xgridFocus).append('line').attr('class', CLASS.xgridFocus); ++ } ++ $$.xgrid = d3.selectAll([]); ++ if (!config.grid_lines_front) { ++ $$.initGridLines(); ++ } ++ }; ++ ChartInternal.prototype.initGridLines = function () { ++ var $$ = this, ++ d3 = $$.d3; ++ $$.gridLines = $$.main.append('g').attr("clip-path", $$.clipPathForGrid).attr('class', CLASS.grid + ' ' + CLASS.gridLines); ++ $$.gridLines.append('g').attr("class", CLASS.xgridLines); ++ $$.gridLines.append('g').attr('class', CLASS.ygridLines); ++ $$.xgridLines = d3.selectAll([]); ++ }; ++ ChartInternal.prototype.updateXGrid = function (withoutUpdate) { ++ var $$ = this, ++ config = $$.config, ++ d3 = $$.d3, ++ xgridData = $$.generateGridData(config.grid_x_type, $$.x), ++ tickOffset = $$.isCategorized() ? $$.xAxis.tickOffset() : 0; ++ ++ $$.xgridAttr = config.axis_rotated ? { ++ 'x1': 0, ++ 'x2': $$.width, ++ 'y1': function y1(d) { ++ return $$.x(d) - tickOffset; ++ }, ++ 'y2': function y2(d) { ++ return $$.x(d) - tickOffset; ++ } ++ } : { ++ 'x1': function x1(d) { ++ return $$.x(d) + tickOffset; ++ }, ++ 'x2': function x2(d) { ++ return $$.x(d) + tickOffset; ++ }, ++ 'y1': 0, ++ 'y2': $$.height ++ }; ++ $$.xgridAttr.opacity = function () { ++ var pos = +d3.select(this).attr(config.axis_rotated ? 'y1' : 'x1'); ++ return pos === (config.axis_rotated ? $$.height : 0) ? 0 : 1; ++ }; ++ ++ var xgrid = $$.main.select('.' + CLASS.xgrids).selectAll('.' + CLASS.xgrid).data(xgridData); ++ var xgridEnter = xgrid.enter().append('line').attr("class", CLASS.xgrid).attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style("opacity", 0); ++ $$.xgrid = xgridEnter.merge(xgrid); ++ if (!withoutUpdate) { ++ $$.xgrid.attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style("opacity", $$.xgridAttr.opacity); ++ } ++ xgrid.exit().remove(); ++ }; ++ ++ ChartInternal.prototype.updateYGrid = function () { ++ var $$ = this, ++ config = $$.config, ++ gridValues = $$.yAxis.tickValues() || $$.y.ticks(config.grid_y_ticks); ++ var ygrid = $$.main.select('.' + CLASS.ygrids).selectAll('.' + CLASS.ygrid).data(gridValues); ++ var ygridEnter = ygrid.enter().append('line') ++ // TODO: x1, x2, y1, y2, opacity need to be set here maybe ++ .attr('class', CLASS.ygrid); ++ $$.ygrid = ygridEnter.merge(ygrid); ++ $$.ygrid.attr("x1", config.axis_rotated ? $$.y : 0).attr("x2", config.axis_rotated ? $$.y : $$.width).attr("y1", config.axis_rotated ? 0 : $$.y).attr("y2", config.axis_rotated ? $$.height : $$.y); ++ ygrid.exit().remove(); ++ $$.smoothLines($$.ygrid, 'grid'); ++ }; ++ ++ ChartInternal.prototype.gridTextAnchor = function (d) { ++ return d.position ? d.position : "end"; ++ }; ++ ChartInternal.prototype.gridTextDx = function (d) { ++ return d.position === 'start' ? 4 : d.position === 'middle' ? 0 : -4; ++ }; ++ ChartInternal.prototype.xGridTextX = function (d) { ++ return d.position === 'start' ? -this.height : d.position === 'middle' ? -this.height / 2 : 0; ++ }; ++ ChartInternal.prototype.yGridTextX = function (d) { ++ return d.position === 'start' ? 0 : d.position === 'middle' ? this.width / 2 : this.width; ++ }; ++ ChartInternal.prototype.updateGrid = function (duration) { ++ var $$ = this, ++ main = $$.main, ++ config = $$.config, ++ xgridLine, ++ xgridLineEnter, ++ ygridLine, ++ ygridLineEnter, ++ xv = $$.xv.bind($$), ++ yv = $$.yv.bind($$), ++ xGridTextX = $$.xGridTextX.bind($$), ++ yGridTextX = $$.yGridTextX.bind($$); ++ ++ // hide if arc type ++ $$.grid.style('visibility', $$.hasArcType() ? 'hidden' : 'visible'); ++ ++ main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden"); ++ if (config.grid_x_show) { ++ $$.updateXGrid(); ++ } ++ xgridLine = main.select('.' + CLASS.xgridLines).selectAll('.' + CLASS.xgridLine).data(config.grid_x_lines); ++ // enter ++ xgridLineEnter = xgridLine.enter().append('g').attr("class", function (d) { ++ return CLASS.xgridLine + (d['class'] ? ' ' + d['class'] : ''); ++ }); ++ xgridLineEnter.append('line').attr("x1", config.axis_rotated ? 0 : xv).attr("x2", config.axis_rotated ? $$.width : xv).attr("y1", config.axis_rotated ? xv : 0).attr("y2", config.axis_rotated ? xv : $$.height).style("opacity", 0); ++ xgridLineEnter.append('text').attr("text-anchor", $$.gridTextAnchor).attr("transform", config.axis_rotated ? "" : "rotate(-90)").attr("x", config.axis_rotated ? yGridTextX : xGridTextX).attr("y", xv).attr('dx', $$.gridTextDx).attr('dy', -5).style("opacity", 0); ++ // udpate ++ $$.xgridLines = xgridLineEnter.merge(xgridLine); ++ // done in d3.transition() of the end of this function ++ // exit ++ xgridLine.exit().transition().duration(duration).style("opacity", 0).remove(); ++ ++ // Y-Grid ++ if (config.grid_y_show) { ++ $$.updateYGrid(); ++ } ++ ygridLine = main.select('.' + CLASS.ygridLines).selectAll('.' + CLASS.ygridLine).data(config.grid_y_lines); ++ // enter ++ ygridLineEnter = ygridLine.enter().append('g').attr("class", function (d) { ++ return CLASS.ygridLine + (d['class'] ? ' ' + d['class'] : ''); ++ }); ++ ygridLineEnter.append('line').attr("x1", config.axis_rotated ? yv : 0).attr("x2", config.axis_rotated ? yv : $$.width).attr("y1", config.axis_rotated ? 0 : yv).attr("y2", config.axis_rotated ? $$.height : yv).style("opacity", 0); ++ ygridLineEnter.append('text').attr("text-anchor", $$.gridTextAnchor).attr("transform", config.axis_rotated ? "rotate(-90)" : "").attr("x", config.axis_rotated ? xGridTextX : yGridTextX).attr("y", yv).attr('dx', $$.gridTextDx).attr('dy', -5).style("opacity", 0); ++ // update ++ $$.ygridLines = ygridLineEnter.merge(ygridLine); ++ $$.ygridLines.select('line').transition().duration(duration).attr("x1", config.axis_rotated ? yv : 0).attr("x2", config.axis_rotated ? yv : $$.width).attr("y1", config.axis_rotated ? 0 : yv).attr("y2", config.axis_rotated ? $$.height : yv).style("opacity", 1); ++ $$.ygridLines.select('text').transition().duration(duration).attr("x", config.axis_rotated ? $$.xGridTextX.bind($$) : $$.yGridTextX.bind($$)).attr("y", yv).text(function (d) { ++ return d.text; ++ }).style("opacity", 1); ++ // exit ++ ygridLine.exit().transition().duration(duration).style("opacity", 0).remove(); ++ }; ++ ChartInternal.prototype.redrawGrid = function (withTransition, transition) { ++ var $$ = this, ++ config = $$.config, ++ xv = $$.xv.bind($$), ++ lines = $$.xgridLines.select('line'), ++ texts = $$.xgridLines.select('text'); ++ return [(withTransition ? lines.transition(transition) : lines).attr("x1", config.axis_rotated ? 0 : xv).attr("x2", config.axis_rotated ? $$.width : xv).attr("y1", config.axis_rotated ? xv : 0).attr("y2", config.axis_rotated ? xv : $$.height).style("opacity", 1), (withTransition ? texts.transition(transition) : texts).attr("x", config.axis_rotated ? $$.yGridTextX.bind($$) : $$.xGridTextX.bind($$)).attr("y", xv).text(function (d) { ++ return d.text; ++ }).style("opacity", 1)]; ++ }; ++ ChartInternal.prototype.showXGridFocus = function (selectedData) { ++ var $$ = this, ++ config = $$.config, ++ dataToShow = selectedData.filter(function (d) { ++ return d && isValue(d.value); ++ }), ++ focusEl = $$.main.selectAll('line.' + CLASS.xgridFocus), ++ xx = $$.xx.bind($$); ++ if (!config.tooltip_show) { ++ return; ++ } ++ // Hide when scatter plot exists ++ if ($$.hasType('scatter') || $$.hasArcType()) { ++ return; ++ } ++ focusEl.style("visibility", "visible").data([dataToShow[0]]).attr(config.axis_rotated ? 'y1' : 'x1', xx).attr(config.axis_rotated ? 'y2' : 'x2', xx); ++ $$.smoothLines(focusEl, 'grid'); ++ }; ++ ChartInternal.prototype.hideXGridFocus = function () { ++ this.main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden"); ++ }; ++ ChartInternal.prototype.updateXgridFocus = function () { ++ var $$ = this, ++ config = $$.config; ++ $$.main.select('line.' + CLASS.xgridFocus).attr("x1", config.axis_rotated ? 0 : -10).attr("x2", config.axis_rotated ? $$.width : -10).attr("y1", config.axis_rotated ? -10 : 0).attr("y2", config.axis_rotated ? -10 : $$.height); ++ }; ++ ChartInternal.prototype.generateGridData = function (type, scale) { ++ var $$ = this, ++ gridData = [], ++ xDomain, ++ firstYear, ++ lastYear, ++ i, ++ tickNum = $$.main.select("." + CLASS.axisX).selectAll('.tick').size(); ++ if (type === 'year') { ++ xDomain = $$.getXDomain(); ++ firstYear = xDomain[0].getFullYear(); ++ lastYear = xDomain[1].getFullYear(); ++ for (i = firstYear; i <= lastYear; i++) { ++ gridData.push(new Date(i + '-01-01 00:00:00')); ++ } ++ } else { ++ gridData = scale.ticks(10); ++ if (gridData.length > tickNum) { ++ // use only int ++ gridData = gridData.filter(function (d) { ++ return ("" + d).indexOf('.') < 0; ++ }); ++ } ++ } ++ return gridData; ++ }; ++ ChartInternal.prototype.getGridFilterToRemove = function (params) { ++ return params ? function (line) { ++ var found = false; ++ [].concat(params).forEach(function (param) { ++ if ('value' in param && line.value === param.value || 'class' in param && line['class'] === param['class']) { ++ found = true; ++ } ++ }); ++ return found; ++ } : function () { ++ return true; ++ }; ++ }; ++ ChartInternal.prototype.removeGridLines = function (params, forX) { ++ var $$ = this, ++ config = $$.config, ++ toRemove = $$.getGridFilterToRemove(params), ++ toShow = function toShow(line) { ++ return !toRemove(line); ++ }, ++ classLines = forX ? CLASS.xgridLines : CLASS.ygridLines, ++ classLine = forX ? CLASS.xgridLine : CLASS.ygridLine; ++ $$.main.select('.' + classLines).selectAll('.' + classLine).filter(toRemove).transition().duration(config.transition_duration).style('opacity', 0).remove(); ++ if (forX) { ++ config.grid_x_lines = config.grid_x_lines.filter(toShow); ++ } else { ++ config.grid_y_lines = config.grid_y_lines.filter(toShow); ++ } ++ }; ++ ++ ChartInternal.prototype.initEventRect = function () { ++ var $$ = this, ++ config = $$.config; ++ ++ $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.eventRects).style('fill-opacity', 0); ++ $$.eventRect = $$.main.select('.' + CLASS.eventRects).append('rect').attr('class', CLASS.eventRect); ++ ++ // event rect handle zoom event as well ++ if (config.zoom_enabled && $$.zoom) { ++ $$.eventRect.call($$.zoom).on("dblclick.zoom", null); ++ if (config.zoom_initialRange) { ++ // WORKAROUND: Add transition to apply transform immediately when no subchart ++ $$.eventRect.transition().duration(0).call($$.zoom.transform, $$.zoomTransform(config.zoom_initialRange)); ++ } ++ } ++ }; ++ ChartInternal.prototype.redrawEventRect = function () { ++ var $$ = this, ++ d3 = $$.d3, ++ config = $$.config, ++ x, ++ y, ++ w, ++ h; ++ ++ // TODO: rotated not supported yet ++ x = 0; ++ y = 0; ++ w = $$.width; ++ h = $$.height; ++ ++ function mouseout() { ++ $$.svg.select('.' + CLASS.eventRect).style('cursor', null); ++ $$.hideXGridFocus(); ++ $$.hideTooltip(); ++ $$.unexpandCircles(); ++ $$.unexpandBars(); ++ } ++ ++ // rects for mouseover ++ $$.main.select('.' + CLASS.eventRects).style('cursor', config.zoom_enabled ? config.axis_rotated ? 'ns-resize' : 'ew-resize' : null); ++ ++ $$.eventRect.attr('x', x).attr('y', y).attr('width', w).attr('height', h).on('mouseout', config.interaction_enabled ? function () { ++ if (!config) { ++ return; ++ } // chart is destroyed ++ if ($$.hasArcType()) { ++ return; ++ } ++ mouseout(); ++ } : null).on('mousemove', config.interaction_enabled ? function () { ++ var targetsToShow, mouse, closest, sameXData, selectedData; ++ ++ if ($$.dragging) { ++ return; ++ } // do nothing when dragging ++ if ($$.hasArcType(targetsToShow)) { ++ return; ++ } ++ ++ targetsToShow = $$.filterTargetsToShow($$.data.targets); ++ mouse = d3.mouse(this); ++ closest = $$.findClosestFromTargets(targetsToShow, mouse); ++ ++ if ($$.mouseover && (!closest || closest.id !== $$.mouseover.id)) { ++ config.data_onmouseout.call($$.api, $$.mouseover); ++ $$.mouseover = undefined; ++ } ++ ++ if (!closest) { ++ mouseout(); ++ return; ++ } ++ ++ if ($$.isScatterType(closest) || !config.tooltip_grouped) { ++ sameXData = [closest]; ++ } else { ++ sameXData = $$.filterByX(targetsToShow, closest.x); ++ } ++ ++ // show tooltip when cursor is close to some point ++ selectedData = sameXData.map(function (d) { ++ return $$.addName(d); ++ }); ++ $$.showTooltip(selectedData, this); ++ ++ // expand points ++ if (config.point_focus_expand_enabled) { ++ $$.unexpandCircles(); ++ selectedData.forEach(function (d) { ++ $$.expandCircles(d.index, d.id, false); ++ }); ++ } ++ $$.expandBars(closest.index, closest.id, true); ++ ++ // Show xgrid focus line ++ $$.showXGridFocus(selectedData); ++ ++ // Show cursor as pointer if point is close to mouse position ++ if ($$.isBarType(closest.id) || $$.dist(closest, mouse) < config.point_sensitivity) { ++ $$.svg.select('.' + CLASS.eventRect).style('cursor', 'pointer'); ++ if (!$$.mouseover) { ++ config.data_onmouseover.call($$.api, closest); ++ $$.mouseover = closest; ++ } ++ } ++ } : null).on('click', config.interaction_enabled ? function () { ++ var targetsToShow, mouse, closest, sameXData; ++ if ($$.hasArcType(targetsToShow)) { ++ return; ++ } ++ ++ targetsToShow = $$.filterTargetsToShow($$.data.targets); ++ mouse = d3.mouse(this); ++ closest = $$.findClosestFromTargets(targetsToShow, mouse); ++ if (!closest) { ++ return; ++ } ++ // select if selection enabled ++ if ($$.isBarType(closest.id) || $$.dist(closest, mouse) < config.point_sensitivity) { ++ if ($$.isScatterType(closest) || !config.data_selection_grouped) { ++ sameXData = [closest]; ++ } else { ++ sameXData = $$.filterByX(targetsToShow, closest.x); ++ } ++ sameXData.forEach(function (d) { ++ $$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.shape + '-' + d.index).each(function () { ++ if (config.data_selection_grouped || $$.isWithinShape(this, d)) { ++ $$.toggleShape(this, d, d.index); ++ config.data_onclick.call($$.api, d, this); ++ } ++ }); ++ }); ++ } ++ } : null).call(config.interaction_enabled && config.data_selection_draggable && $$.drag ? d3.drag().on('drag', function () { ++ $$.drag(d3.mouse(this)); ++ }).on('start', function () { ++ $$.dragstart(d3.mouse(this)); ++ }).on('end', function () { ++ $$.dragend(); ++ }) : function () {}); ++ }; ++ ChartInternal.prototype.getMousePosition = function (data) { ++ var $$ = this; ++ return [$$.x(data.x), $$.getYScale(data.id)(data.value)]; ++ }; ++ ChartInternal.prototype.dispatchEvent = function (type, mouse) { ++ var $$ = this, ++ selector = '.' + CLASS.eventRect, ++ eventRect = $$.main.select(selector).node(), ++ box = eventRect.getBoundingClientRect(), ++ x = box.left + (mouse ? mouse[0] : 0), ++ y = box.top + (mouse ? mouse[1] : 0), ++ event = document.createEvent("MouseEvents"); ++ ++ event.initMouseEvent(type, true, true, window, 0, x, y, x, y, false, false, false, false, 0, null); ++ eventRect.dispatchEvent(event); ++ }; ++ ++ ChartInternal.prototype.initLegend = function () { ++ var $$ = this; ++ $$.legendItemTextBox = {}; ++ $$.legendHasRendered = false; ++ $$.legend = $$.svg.append("g").attr("transform", $$.getTranslate('legend')); ++ if (!$$.config.legend_show) { ++ $$.legend.style('visibility', 'hidden'); ++ $$.hiddenLegendIds = $$.mapToIds($$.data.targets); ++ return; ++ } ++ // MEMO: call here to update legend box and tranlate for all ++ // MEMO: translate will be upated by this, so transform not needed in updateLegend() ++ $$.updateLegendWithDefaults(); ++ }; ++ ChartInternal.prototype.updateLegendWithDefaults = function () { ++ var $$ = this; ++ $$.updateLegend($$.mapToIds($$.data.targets), { withTransform: false, withTransitionForTransform: false, withTransition: false }); ++ }; ++ ChartInternal.prototype.updateSizeForLegend = function (legendHeight, legendWidth) { ++ var $$ = this, ++ config = $$.config, ++ insetLegendPosition = { ++ top: $$.isLegendTop ? $$.getCurrentPaddingTop() + config.legend_inset_y + 5.5 : $$.currentHeight - legendHeight - $$.getCurrentPaddingBottom() - config.legend_inset_y, ++ left: $$.isLegendLeft ? $$.getCurrentPaddingLeft() + config.legend_inset_x + 0.5 : $$.currentWidth - legendWidth - $$.getCurrentPaddingRight() - config.legend_inset_x + 0.5 ++ }; ++ ++ $$.margin3 = { ++ top: $$.isLegendRight ? 0 : $$.isLegendInset ? insetLegendPosition.top : $$.currentHeight - legendHeight, ++ right: NaN, ++ bottom: 0, ++ left: $$.isLegendRight ? $$.currentWidth - legendWidth : $$.isLegendInset ? insetLegendPosition.left : 0 ++ }; ++ }; ++ ChartInternal.prototype.transformLegend = function (withTransition) { ++ var $$ = this; ++ (withTransition ? $$.legend.transition() : $$.legend).attr("transform", $$.getTranslate('legend')); ++ }; ++ ChartInternal.prototype.updateLegendStep = function (step) { ++ this.legendStep = step; ++ }; ++ ChartInternal.prototype.updateLegendItemWidth = function (w) { ++ this.legendItemWidth = w; ++ }; ++ ChartInternal.prototype.updateLegendItemHeight = function (h) { ++ this.legendItemHeight = h; ++ }; ++ ChartInternal.prototype.getLegendWidth = function () { ++ var $$ = this; ++ return $$.config.legend_show ? $$.isLegendRight || $$.isLegendInset ? $$.legendItemWidth * ($$.legendStep + 1) : $$.currentWidth : 0; ++ }; ++ ChartInternal.prototype.getLegendHeight = function () { ++ var $$ = this, ++ h = 0; ++ if ($$.config.legend_show) { ++ if ($$.isLegendRight) { ++ h = $$.currentHeight; ++ } else { ++ h = Math.max(20, $$.legendItemHeight) * ($$.legendStep + 1); ++ } ++ } ++ return h; ++ }; ++ ChartInternal.prototype.opacityForLegend = function (legendItem) { ++ return legendItem.classed(CLASS.legendItemHidden) ? null : 1; ++ }; ++ ChartInternal.prototype.opacityForUnfocusedLegend = function (legendItem) { ++ return legendItem.classed(CLASS.legendItemHidden) ? null : 0.3; ++ }; ++ ChartInternal.prototype.toggleFocusLegend = function (targetIds, focus) { ++ var $$ = this; ++ targetIds = $$.mapToTargetIds(targetIds); ++ $$.legend.selectAll('.' + CLASS.legendItem).filter(function (id) { ++ return targetIds.indexOf(id) >= 0; ++ }).classed(CLASS.legendItemFocused, focus).transition().duration(100).style('opacity', function () { ++ var opacity = focus ? $$.opacityForLegend : $$.opacityForUnfocusedLegend; ++ return opacity.call($$, $$.d3.select(this)); ++ }); ++ }; ++ ChartInternal.prototype.revertLegend = function () { ++ var $$ = this, ++ d3 = $$.d3; ++ $$.legend.selectAll('.' + CLASS.legendItem).classed(CLASS.legendItemFocused, false).transition().duration(100).style('opacity', function () { ++ return $$.opacityForLegend(d3.select(this)); ++ }); ++ }; ++ ChartInternal.prototype.showLegend = function (targetIds) { ++ var $$ = this, ++ config = $$.config; ++ if (!config.legend_show) { ++ config.legend_show = true; ++ $$.legend.style('visibility', 'visible'); ++ if (!$$.legendHasRendered) { ++ $$.updateLegendWithDefaults(); ++ } ++ } ++ $$.removeHiddenLegendIds(targetIds); ++ $$.legend.selectAll($$.selectorLegends(targetIds)).style('visibility', 'visible').transition().style('opacity', function () { ++ return $$.opacityForLegend($$.d3.select(this)); ++ }); ++ }; ++ ChartInternal.prototype.hideLegend = function (targetIds) { ++ var $$ = this, ++ config = $$.config; ++ if (config.legend_show && isEmpty(targetIds)) { ++ config.legend_show = false; ++ $$.legend.style('visibility', 'hidden'); ++ } ++ $$.addHiddenLegendIds(targetIds); ++ $$.legend.selectAll($$.selectorLegends(targetIds)).style('opacity', 0).style('visibility', 'hidden'); ++ }; ++ ChartInternal.prototype.clearLegendItemTextBoxCache = function () { ++ this.legendItemTextBox = {}; ++ }; ++ ChartInternal.prototype.updateLegend = function (targetIds, options, transitions) { ++ var $$ = this, ++ config = $$.config; ++ var xForLegend, xForLegendText, xForLegendRect, yForLegend, yForLegendText, yForLegendRect, x1ForLegendTile, x2ForLegendTile, yForLegendTile; ++ var paddingTop = 4, ++ paddingRight = 10, ++ maxWidth = 0, ++ maxHeight = 0, ++ posMin = 10, ++ tileWidth = config.legend_item_tile_width + 5; ++ var l, ++ totalLength = 0, ++ offsets = {}, ++ widths = {}, ++ heights = {}, ++ margins = [0], ++ steps = {}, ++ step = 0; ++ var withTransition, withTransitionForTransform; ++ var texts, rects, tiles, background; ++ ++ // Skip elements when their name is set to null ++ targetIds = targetIds.filter(function (id) { ++ return !isDefined(config.data_names[id]) || config.data_names[id] !== null; ++ }); ++ ++ options = options || {}; ++ withTransition = getOption(options, "withTransition", true); ++ withTransitionForTransform = getOption(options, "withTransitionForTransform", true); ++ ++ function getTextBox(textElement, id) { ++ if (!$$.legendItemTextBox[id]) { ++ $$.legendItemTextBox[id] = $$.getTextRect(textElement.textContent, CLASS.legendItem, textElement); ++ } ++ return $$.legendItemTextBox[id]; ++ } ++ ++ function updatePositions(textElement, id, index) { ++ var reset = index === 0, ++ isLast = index === targetIds.length - 1, ++ box = getTextBox(textElement, id), ++ itemWidth = box.width + tileWidth + (isLast && !($$.isLegendRight || $$.isLegendInset) ? 0 : paddingRight) + config.legend_padding, ++ itemHeight = box.height + paddingTop, ++ itemLength = $$.isLegendRight || $$.isLegendInset ? itemHeight : itemWidth, ++ areaLength = $$.isLegendRight || $$.isLegendInset ? $$.getLegendHeight() : $$.getLegendWidth(), ++ margin, ++ maxLength; ++ ++ // MEMO: care about condifion of step, totalLength ++ function updateValues(id, withoutStep) { ++ if (!withoutStep) { ++ margin = (areaLength - totalLength - itemLength) / 2; ++ if (margin < posMin) { ++ margin = (areaLength - itemLength) / 2; ++ totalLength = 0; ++ step++; ++ } ++ } ++ steps[id] = step; ++ margins[step] = $$.isLegendInset ? 10 : margin; ++ offsets[id] = totalLength; ++ totalLength += itemLength; ++ } ++ ++ if (reset) { ++ totalLength = 0; ++ step = 0; ++ maxWidth = 0; ++ maxHeight = 0; ++ } ++ ++ if (config.legend_show && !$$.isLegendToShow(id)) { ++ widths[id] = heights[id] = steps[id] = offsets[id] = 0; ++ return; ++ } ++ ++ widths[id] = itemWidth; ++ heights[id] = itemHeight; ++ ++ if (!maxWidth || itemWidth >= maxWidth) { ++ maxWidth = itemWidth; ++ } ++ if (!maxHeight || itemHeight >= maxHeight) { ++ maxHeight = itemHeight; ++ } ++ maxLength = $$.isLegendRight || $$.isLegendInset ? maxHeight : maxWidth; ++ ++ if (config.legend_equally) { ++ Object.keys(widths).forEach(function (id) { ++ widths[id] = maxWidth; ++ }); ++ Object.keys(heights).forEach(function (id) { ++ heights[id] = maxHeight; ++ }); ++ margin = (areaLength - maxLength * targetIds.length) / 2; ++ if (margin < posMin) { ++ totalLength = 0; ++ step = 0; ++ targetIds.forEach(function (id) { ++ updateValues(id); ++ }); ++ } else { ++ updateValues(id, true); ++ } ++ } else { ++ updateValues(id); ++ } ++ } ++ ++ if ($$.isLegendInset) { ++ step = config.legend_inset_step ? config.legend_inset_step : targetIds.length; ++ $$.updateLegendStep(step); ++ } ++ ++ if ($$.isLegendRight) { ++ xForLegend = function xForLegend(id) { ++ return maxWidth * steps[id]; ++ }; ++ yForLegend = function yForLegend(id) { ++ return margins[steps[id]] + offsets[id]; ++ }; ++ } else if ($$.isLegendInset) { ++ xForLegend = function xForLegend(id) { ++ return maxWidth * steps[id] + 10; ++ }; ++ yForLegend = function yForLegend(id) { ++ return margins[steps[id]] + offsets[id]; ++ }; ++ } else { ++ xForLegend = function xForLegend(id) { ++ return margins[steps[id]] + offsets[id]; ++ }; ++ yForLegend = function yForLegend(id) { ++ return maxHeight * steps[id]; ++ }; ++ } ++ xForLegendText = function xForLegendText(id, i) { ++ return xForLegend(id, i) + 4 + config.legend_item_tile_width; ++ }; ++ yForLegendText = function yForLegendText(id, i) { ++ return yForLegend(id, i) + 9; ++ }; ++ xForLegendRect = function xForLegendRect(id, i) { ++ return xForLegend(id, i); ++ }; ++ yForLegendRect = function yForLegendRect(id, i) { ++ return yForLegend(id, i) - 5; ++ }; ++ x1ForLegendTile = function x1ForLegendTile(id, i) { ++ return xForLegend(id, i) - 2; ++ }; ++ x2ForLegendTile = function x2ForLegendTile(id, i) { ++ return xForLegend(id, i) - 2 + config.legend_item_tile_width; ++ }; ++ yForLegendTile = function yForLegendTile(id, i) { ++ return yForLegend(id, i) + 4; ++ }; ++ ++ // Define g for legend area ++ l = $$.legend.selectAll('.' + CLASS.legendItem).data(targetIds).enter().append('g').attr('class', function (id) { ++ return $$.generateClass(CLASS.legendItem, id); ++ }).style('visibility', function (id) { ++ return $$.isLegendToShow(id) ? 'visible' : 'hidden'; ++ }).style('cursor', 'pointer').on('click', function (id) { ++ if (config.legend_item_onclick) { ++ config.legend_item_onclick.call($$, id); ++ } else { ++ if ($$.d3.event.altKey) { ++ $$.api.hide(); ++ $$.api.show(id); ++ } else { ++ $$.api.toggle(id); ++ $$.isTargetToShow(id) ? $$.api.focus(id) : $$.api.revert(); ++ } ++ } ++ }).on('mouseover', function (id) { ++ if (config.legend_item_onmouseover) { ++ config.legend_item_onmouseover.call($$, id); ++ } else { ++ $$.d3.select(this).classed(CLASS.legendItemFocused, true); ++ if (!$$.transiting && $$.isTargetToShow(id)) { ++ $$.api.focus(id); ++ } ++ } ++ }).on('mouseout', function (id) { ++ if (config.legend_item_onmouseout) { ++ config.legend_item_onmouseout.call($$, id); ++ } else { ++ $$.d3.select(this).classed(CLASS.legendItemFocused, false); ++ $$.api.revert(); ++ } ++ }); ++ l.append('text').text(function (id) { ++ return isDefined(config.data_names[id]) ? config.data_names[id] : id; ++ }).each(function (id, i) { ++ updatePositions(this, id, i); ++ }).style("pointer-events", "none").attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200).attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendText); ++ l.append('rect').attr("class", CLASS.legendItemEvent).style('fill-opacity', 0).attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendRect : -200).attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendRect); ++ l.append('line').attr('class', CLASS.legendItemTile).style('stroke', $$.color).style("pointer-events", "none").attr('x1', $$.isLegendRight || $$.isLegendInset ? x1ForLegendTile : -200).attr('y1', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile).attr('x2', $$.isLegendRight || $$.isLegendInset ? x2ForLegendTile : -200).attr('y2', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile).attr('stroke-width', config.legend_item_tile_height); ++ ++ // Set background for inset legend ++ background = $$.legend.select('.' + CLASS.legendBackground + ' rect'); ++ if ($$.isLegendInset && maxWidth > 0 && background.size() === 0) { ++ background = $$.legend.insert('g', '.' + CLASS.legendItem).attr("class", CLASS.legendBackground).append('rect'); ++ } ++ ++ texts = $$.legend.selectAll('text').data(targetIds).text(function (id) { ++ return isDefined(config.data_names[id]) ? config.data_names[id] : id; ++ }) // MEMO: needed for update ++ .each(function (id, i) { ++ updatePositions(this, id, i); ++ }); ++ (withTransition ? texts.transition() : texts).attr('x', xForLegendText).attr('y', yForLegendText); ++ ++ rects = $$.legend.selectAll('rect.' + CLASS.legendItemEvent).data(targetIds); ++ (withTransition ? rects.transition() : rects).attr('width', function (id) { ++ return widths[id]; ++ }).attr('height', function (id) { ++ return heights[id]; ++ }).attr('x', xForLegendRect).attr('y', yForLegendRect); ++ ++ tiles = $$.legend.selectAll('line.' + CLASS.legendItemTile).data(targetIds); ++ (withTransition ? tiles.transition() : tiles).style('stroke', $$.levelColor ? function (id) { ++ return $$.levelColor($$.cache[id].values[0].value); ++ } : $$.color).attr('x1', x1ForLegendTile).attr('y1', yForLegendTile).attr('x2', x2ForLegendTile).attr('y2', yForLegendTile); ++ ++ if (background) { ++ (withTransition ? background.transition() : background).attr('height', $$.getLegendHeight() - 12).attr('width', maxWidth * (step + 1) + 10); ++ } ++ ++ // toggle legend state ++ $$.legend.selectAll('.' + CLASS.legendItem).classed(CLASS.legendItemHidden, function (id) { ++ return !$$.isTargetToShow(id); ++ }); ++ ++ // Update all to reflect change of legend ++ $$.updateLegendItemWidth(maxWidth); ++ $$.updateLegendItemHeight(maxHeight); ++ $$.updateLegendStep(step); ++ // Update size and scale ++ $$.updateSizes(); ++ $$.updateScales(); ++ $$.updateSvgSize(); ++ // Update g positions ++ $$.transformAll(withTransitionForTransform, transitions); ++ $$.legendHasRendered = true; ++ }; ++ ++ ChartInternal.prototype.initRegion = function () { ++ var $$ = this; ++ $$.region = $$.main.append('g').attr("clip-path", $$.clipPath).attr("class", CLASS.regions); ++ }; ++ ChartInternal.prototype.updateRegion = function (duration) { ++ var $$ = this, ++ config = $$.config; ++ ++ // hide if arc type ++ $$.region.style('visibility', $$.hasArcType() ? 'hidden' : 'visible'); ++ ++ var mainRegion = $$.main.select('.' + CLASS.regions).selectAll('.' + CLASS.region).data(config.regions); ++ var mainRegionEnter = mainRegion.enter().append('rect').attr("x", $$.regionX.bind($$)).attr("y", $$.regionY.bind($$)).attr("width", $$.regionWidth.bind($$)).attr("height", $$.regionHeight.bind($$)).style("fill-opacity", 0); ++ $$.mainRegion = mainRegionEnter.merge(mainRegion).attr('class', $$.classRegion.bind($$)); ++ mainRegion.exit().transition().duration(duration).style("opacity", 0).remove(); ++ }; ++ ChartInternal.prototype.redrawRegion = function (withTransition, transition) { ++ var $$ = this, ++ regions = $$.mainRegion; ++ return [(withTransition ? regions.transition(transition) : regions).attr("x", $$.regionX.bind($$)).attr("y", $$.regionY.bind($$)).attr("width", $$.regionWidth.bind($$)).attr("height", $$.regionHeight.bind($$)).style("fill-opacity", function (d) { ++ return isValue(d.opacity) ? d.opacity : 0.1; ++ })]; ++ }; ++ ChartInternal.prototype.regionX = function (d) { ++ var $$ = this, ++ config = $$.config, ++ xPos, ++ yScale = d.axis === 'y' ? $$.y : $$.y2; ++ if (d.axis === 'y' || d.axis === 'y2') { ++ xPos = config.axis_rotated ? 'start' in d ? yScale(d.start) : 0 : 0; ++ } else { ++ xPos = config.axis_rotated ? 0 : 'start' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start) : 0; ++ } ++ return xPos; ++ }; ++ ChartInternal.prototype.regionY = function (d) { ++ var $$ = this, ++ config = $$.config, ++ yPos, ++ yScale = d.axis === 'y' ? $$.y : $$.y2; ++ if (d.axis === 'y' || d.axis === 'y2') { ++ yPos = config.axis_rotated ? 0 : 'end' in d ? yScale(d.end) : 0; ++ } else { ++ yPos = config.axis_rotated ? 'start' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start) : 0 : 0; ++ } ++ return yPos; ++ }; ++ ChartInternal.prototype.regionWidth = function (d) { ++ var $$ = this, ++ config = $$.config, ++ start = $$.regionX(d), ++ end, ++ yScale = d.axis === 'y' ? $$.y : $$.y2; ++ if (d.axis === 'y' || d.axis === 'y2') { ++ end = config.axis_rotated ? 'end' in d ? yScale(d.end) : $$.width : $$.width; ++ } else { ++ end = config.axis_rotated ? $$.width : 'end' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end) : $$.width; ++ } ++ return end < start ? 0 : end - start; ++ }; ++ ChartInternal.prototype.regionHeight = function (d) { ++ var $$ = this, ++ config = $$.config, ++ start = this.regionY(d), ++ end, ++ yScale = d.axis === 'y' ? $$.y : $$.y2; ++ if (d.axis === 'y' || d.axis === 'y2') { ++ end = config.axis_rotated ? $$.height : 'start' in d ? yScale(d.start) : $$.height; ++ } else { ++ end = config.axis_rotated ? 'end' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end) : $$.height : $$.height; ++ } ++ return end < start ? 0 : end - start; ++ }; ++ ChartInternal.prototype.isRegionOnX = function (d) { ++ return !d.axis || d.axis === 'x'; ++ }; ++ ++ ChartInternal.prototype.getScale = function (min, max, forTimeseries) { ++ return (forTimeseries ? this.d3.scaleTime() : this.d3.scaleLinear()).range([min, max]); ++ }; ++ ChartInternal.prototype.getX = function (min, max, domain, offset) { ++ var $$ = this, ++ scale = $$.getScale(min, max, $$.isTimeSeries()), ++ _scale = domain ? scale.domain(domain) : scale, ++ key; ++ // Define customized scale if categorized axis ++ if ($$.isCategorized()) { ++ offset = offset || function () { ++ return 0; ++ }; ++ scale = function scale(d, raw) { ++ var v = _scale(d) + offset(d); ++ return raw ? v : Math.ceil(v); ++ }; ++ } else { ++ scale = function scale(d, raw) { ++ var v = _scale(d); ++ return raw ? v : Math.ceil(v); ++ }; ++ } ++ // define functions ++ for (key in _scale) { ++ scale[key] = _scale[key]; ++ } ++ scale.orgDomain = function () { ++ return _scale.domain(); ++ }; ++ // define custom domain() for categorized axis ++ if ($$.isCategorized()) { ++ scale.domain = function (domain) { ++ if (!arguments.length) { ++ domain = this.orgDomain(); ++ return [domain[0], domain[1] + 1]; ++ } ++ _scale.domain(domain); ++ return scale; ++ }; ++ } ++ return scale; ++ }; ++ ChartInternal.prototype.getY = function (min, max, domain) { ++ var scale = this.getScale(min, max, this.isTimeSeriesY()); ++ if (domain) { ++ scale.domain(domain); ++ } ++ return scale; ++ }; ++ ChartInternal.prototype.getYScale = function (id) { ++ return this.axis.getId(id) === 'y2' ? this.y2 : this.y; ++ }; ++ ChartInternal.prototype.getSubYScale = function (id) { ++ return this.axis.getId(id) === 'y2' ? this.subY2 : this.subY; ++ }; ++ ChartInternal.prototype.updateScales = function () { ++ var $$ = this, ++ config = $$.config, ++ forInit = !$$.x; ++ // update edges ++ $$.xMin = config.axis_rotated ? 1 : 0; ++ $$.xMax = config.axis_rotated ? $$.height : $$.width; ++ $$.yMin = config.axis_rotated ? 0 : $$.height; ++ $$.yMax = config.axis_rotated ? $$.width : 1; ++ $$.subXMin = $$.xMin; ++ $$.subXMax = $$.xMax; ++ $$.subYMin = config.axis_rotated ? 0 : $$.height2; ++ $$.subYMax = config.axis_rotated ? $$.width2 : 1; ++ // update scales ++ $$.x = $$.getX($$.xMin, $$.xMax, forInit ? undefined : $$.x.orgDomain(), function () { ++ return $$.xAxis.tickOffset(); ++ }); ++ $$.y = $$.getY($$.yMin, $$.yMax, forInit ? config.axis_y_default : $$.y.domain()); ++ $$.y2 = $$.getY($$.yMin, $$.yMax, forInit ? config.axis_y2_default : $$.y2.domain()); ++ $$.subX = $$.getX($$.xMin, $$.xMax, $$.orgXDomain, function (d) { ++ return d % 1 ? 0 : $$.subXAxis.tickOffset(); ++ }); ++ $$.subY = $$.getY($$.subYMin, $$.subYMax, forInit ? config.axis_y_default : $$.subY.domain()); ++ $$.subY2 = $$.getY($$.subYMin, $$.subYMax, forInit ? config.axis_y2_default : $$.subY2.domain()); ++ // update axes ++ $$.xAxisTickFormat = $$.axis.getXAxisTickFormat(); ++ $$.xAxisTickValues = $$.axis.getXAxisTickValues(); ++ $$.yAxisTickValues = $$.axis.getYAxisTickValues(); ++ $$.y2AxisTickValues = $$.axis.getY2AxisTickValues(); ++ ++ $$.xAxis = $$.axis.getXAxis($$.x, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, config.axis_x_tick_outer); ++ $$.subXAxis = $$.axis.getXAxis($$.subX, $$.subXOrient, $$.xAxisTickFormat, $$.xAxisTickValues, config.axis_x_tick_outer); ++ $$.yAxis = $$.axis.getYAxis($$.y, $$.yOrient, config.axis_y_tick_format, $$.yAxisTickValues, config.axis_y_tick_outer); ++ $$.y2Axis = $$.axis.getYAxis($$.y2, $$.y2Orient, config.axis_y2_tick_format, $$.y2AxisTickValues, config.axis_y2_tick_outer); ++ ++ // Set initialized scales to brush and zoom ++ if (!forInit) { ++ if ($$.brush) { ++ $$.brush.updateScale($$.subX); ++ } ++ } ++ // update for arc ++ if ($$.updateArc) { ++ $$.updateArc(); ++ } ++ }; ++ ++ ChartInternal.prototype.selectPoint = function (target, d, i) { ++ var $$ = this, ++ config = $$.config, ++ cx = (config.axis_rotated ? $$.circleY : $$.circleX).bind($$), ++ cy = (config.axis_rotated ? $$.circleX : $$.circleY).bind($$), ++ r = $$.pointSelectR.bind($$); ++ config.data_onselected.call($$.api, d, target.node()); ++ // add selected-circle on low layer g ++ $$.main.select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.selectedCircle + '-' + i).data([d]).enter().append('circle').attr("class", function () { ++ return $$.generateClass(CLASS.selectedCircle, i); ++ }).attr("cx", cx).attr("cy", cy).attr("stroke", function () { ++ return $$.color(d); ++ }).attr("r", function (d) { ++ return $$.pointSelectR(d) * 1.4; ++ }).transition().duration(100).attr("r", r); ++ }; ++ ChartInternal.prototype.unselectPoint = function (target, d, i) { ++ var $$ = this; ++ $$.config.data_onunselected.call($$.api, d, target.node()); ++ // remove selected-circle from low layer g ++ $$.main.select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.selectedCircle + '-' + i).transition().duration(100).attr('r', 0).remove(); ++ }; ++ ChartInternal.prototype.togglePoint = function (selected, target, d, i) { ++ selected ? this.selectPoint(target, d, i) : this.unselectPoint(target, d, i); ++ }; ++ ChartInternal.prototype.selectPath = function (target, d) { ++ var $$ = this; ++ $$.config.data_onselected.call($$, d, target.node()); ++ if ($$.config.interaction_brighten) { ++ target.transition().duration(100).style("fill", function () { ++ return $$.d3.rgb($$.color(d)).brighter(0.75); ++ }); ++ } ++ }; ++ ChartInternal.prototype.unselectPath = function (target, d) { ++ var $$ = this; ++ $$.config.data_onunselected.call($$, d, target.node()); ++ if ($$.config.interaction_brighten) { ++ target.transition().duration(100).style("fill", function () { ++ return $$.color(d); ++ }); ++ } ++ }; ++ ChartInternal.prototype.togglePath = function (selected, target, d, i) { ++ selected ? this.selectPath(target, d, i) : this.unselectPath(target, d, i); ++ }; ++ ChartInternal.prototype.getToggle = function (that, d) { ++ var $$ = this, ++ toggle; ++ if (that.nodeName === 'circle') { ++ if ($$.isStepType(d)) { ++ // circle is hidden in step chart, so treat as within the click area ++ toggle = function toggle() {}; // TODO: how to select step chart? ++ } else { ++ toggle = $$.togglePoint; ++ } ++ } else if (that.nodeName === 'path') { ++ toggle = $$.togglePath; ++ } ++ return toggle; ++ }; ++ ChartInternal.prototype.toggleShape = function (that, d, i) { ++ var $$ = this, ++ d3 = $$.d3, ++ config = $$.config, ++ shape = d3.select(that), ++ isSelected = shape.classed(CLASS.SELECTED), ++ toggle = $$.getToggle(that, d).bind($$); ++ ++ if (config.data_selection_enabled && config.data_selection_isselectable(d)) { ++ if (!config.data_selection_multiple) { ++ $$.main.selectAll('.' + CLASS.shapes + (config.data_selection_grouped ? $$.getTargetSelectorSuffix(d.id) : "")).selectAll('.' + CLASS.shape).each(function (d, i) { ++ var shape = d3.select(this); ++ if (shape.classed(CLASS.SELECTED)) { ++ toggle(false, shape.classed(CLASS.SELECTED, false), d, i); ++ } ++ }); ++ } ++ shape.classed(CLASS.SELECTED, !isSelected); ++ toggle(!isSelected, shape, d, i); ++ } ++ }; ++ ++ ChartInternal.prototype.initBar = function () { ++ var $$ = this; ++ $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartBars); ++ }; ++ ChartInternal.prototype.updateTargetsForBar = function (targets) { ++ var $$ = this, ++ config = $$.config, ++ mainBars, ++ mainBarEnter, ++ classChartBar = $$.classChartBar.bind($$), ++ classBars = $$.classBars.bind($$), ++ classFocus = $$.classFocus.bind($$); ++ mainBars = $$.main.select('.' + CLASS.chartBars).selectAll('.' + CLASS.chartBar).data(targets).attr('class', function (d) { ++ return classChartBar(d) + classFocus(d); ++ }); ++ mainBarEnter = mainBars.enter().append('g').attr('class', classChartBar).style("pointer-events", "none"); ++ // Bars for each data ++ mainBarEnter.append('g').attr("class", classBars).style("cursor", function (d) { ++ return config.data_selection_isselectable(d) ? "pointer" : null; ++ }); ++ }; ++ ChartInternal.prototype.updateBar = function (durationForExit) { ++ var $$ = this, ++ barData = $$.barData.bind($$), ++ classBar = $$.classBar.bind($$), ++ initialOpacity = $$.initialOpacity.bind($$), ++ color = function color(d) { ++ return $$.color(d.id); ++ }; ++ var mainBar = $$.main.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar).data(barData); ++ var mainBarEnter = mainBar.enter().append('path').attr("class", classBar).style("stroke", color).style("fill", color); ++ $$.mainBar = mainBarEnter.merge(mainBar).style("opacity", initialOpacity); ++ mainBar.exit().transition().duration(durationForExit).style("opacity", 0); ++ }; ++ ChartInternal.prototype.redrawBar = function (drawBar, withTransition, transition) { ++ return [(withTransition ? this.mainBar.transition(transition) : this.mainBar).attr('d', drawBar).style("stroke", this.color).style("fill", this.color).style("opacity", 1)]; ++ }; ++ ChartInternal.prototype.getBarW = function (axis, barTargetsNum) { ++ var $$ = this, ++ config = $$.config, ++ w = typeof config.bar_width === 'number' ? config.bar_width : barTargetsNum ? axis.tickInterval() * config.bar_width_ratio / barTargetsNum : 0; ++ return config.bar_width_max && w > config.bar_width_max ? config.bar_width_max : w; ++ }; ++ ChartInternal.prototype.getBars = function (i, id) { ++ var $$ = this; ++ return (id ? $$.main.selectAll('.' + CLASS.bars + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : '')); ++ }; ++ ChartInternal.prototype.expandBars = function (i, id, reset) { ++ var $$ = this; ++ if (reset) { ++ $$.unexpandBars(); ++ } ++ $$.getBars(i, id).classed(CLASS.EXPANDED, true); ++ }; ++ ChartInternal.prototype.unexpandBars = function (i) { ++ var $$ = this; ++ $$.getBars(i).classed(CLASS.EXPANDED, false); ++ }; ++ ChartInternal.prototype.generateDrawBar = function (barIndices, isSub) { ++ var $$ = this, ++ config = $$.config, ++ getPoints = $$.generateGetBarPoints(barIndices, isSub); ++ return function (d, i) { ++ // 4 points that make a bar ++ var points = getPoints(d, i); ++ ++ // switch points if axis is rotated, not applicable for sub chart ++ var indexX = config.axis_rotated ? 1 : 0; ++ var indexY = config.axis_rotated ? 0 : 1; ++ ++ var path = 'M ' + points[0][indexX] + ',' + points[0][indexY] + ' ' + 'L' + points[1][indexX] + ',' + points[1][indexY] + ' ' + 'L' + points[2][indexX] + ',' + points[2][indexY] + ' ' + 'L' + points[3][indexX] + ',' + points[3][indexY] + ' ' + 'z'; ++ ++ return path; ++ }; ++ }; ++ ChartInternal.prototype.generateGetBarPoints = function (barIndices, isSub) { ++ var $$ = this, ++ axis = isSub ? $$.subXAxis : $$.xAxis, ++ barTargetsNum = barIndices.__max__ + 1, ++ barW = $$.getBarW(axis, barTargetsNum), ++ barX = $$.getShapeX(barW, barTargetsNum, barIndices, !!isSub), ++ barY = $$.getShapeY(!!isSub), ++ barOffset = $$.getShapeOffset($$.isBarType, barIndices, !!isSub), ++ barSpaceOffset = barW * ($$.config.bar_space / 2), ++ yScale = isSub ? $$.getSubYScale : $$.getYScale; ++ return function (d, i) { ++ var y0 = yScale.call($$, d.id)(0), ++ offset = barOffset(d, i) || y0, ++ // offset is for stacked bar chart ++ posX = barX(d), ++ posY = barY(d); ++ // fix posY not to overflow opposite quadrant ++ if ($$.config.axis_rotated) { ++ if (0 < d.value && posY < y0 || d.value < 0 && y0 < posY) { ++ posY = y0; ++ } ++ } ++ // 4 points that make a bar ++ return [[posX + barSpaceOffset, offset], [posX + barSpaceOffset, posY - (y0 - offset)], [posX + barW - barSpaceOffset, posY - (y0 - offset)], [posX + barW - barSpaceOffset, offset]]; ++ }; ++ }; ++ ChartInternal.prototype.isWithinBar = function (mouse, that) { ++ var box = that.getBoundingClientRect(), ++ seg0 = that.pathSegList.getItem(0), ++ seg1 = that.pathSegList.getItem(1), ++ x = Math.min(seg0.x, seg1.x), ++ y = Math.min(seg0.y, seg1.y), ++ w = box.width, ++ h = box.height, ++ offset = 2, ++ sx = x - offset, ++ ex = x + w + offset, ++ sy = y + h + offset, ++ ey = y - offset; ++ return sx < mouse[0] && mouse[0] < ex && ey < mouse[1] && mouse[1] < sy; ++ }; ++ ++ ChartInternal.prototype.getShapeIndices = function (typeFilter) { ++ var $$ = this, ++ config = $$.config, ++ indices = {}, ++ i = 0, ++ j, ++ k; ++ $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)).forEach(function (d) { ++ for (j = 0; j < config.data_groups.length; j++) { ++ if (config.data_groups[j].indexOf(d.id) < 0) { ++ continue; ++ } ++ for (k = 0; k < config.data_groups[j].length; k++) { ++ if (config.data_groups[j][k] in indices) { ++ indices[d.id] = indices[config.data_groups[j][k]]; ++ break; ++ } ++ } ++ } ++ if (isUndefined(indices[d.id])) { ++ indices[d.id] = i++; ++ } ++ }); ++ indices.__max__ = i - 1; ++ return indices; ++ }; ++ ChartInternal.prototype.getShapeX = function (offset, targetsNum, indices, isSub) { ++ var $$ = this, ++ scale = isSub ? $$.subX : $$.x; ++ return function (d) { ++ var index = d.id in indices ? indices[d.id] : 0; ++ return d.x || d.x === 0 ? scale(d.x) - offset * (targetsNum / 2 - index) : 0; ++ }; ++ }; ++ ChartInternal.prototype.getShapeY = function (isSub) { ++ var $$ = this; ++ return function (d) { ++ var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id); ++ return scale(d.value); ++ }; ++ }; ++ ChartInternal.prototype.getShapeOffset = function (typeFilter, indices, isSub) { ++ var $$ = this, ++ targets = $$.orderTargets($$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$))), ++ targetIds = targets.map(function (t) { ++ return t.id; ++ }); ++ return function (d, i) { ++ var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id), ++ y0 = scale(0), ++ offset = y0; ++ targets.forEach(function (t) { ++ var values = $$.isStepType(d) ? $$.convertValuesToStep(t.values) : t.values; ++ if (t.id === d.id || indices[t.id] !== indices[d.id]) { ++ return; ++ } ++ if (targetIds.indexOf(t.id) < targetIds.indexOf(d.id)) { ++ // check if the x values line up ++ if (typeof values[i] === 'undefined' || +values[i].x !== +d.x) { ++ // "+" for timeseries ++ // if not, try to find the value that does line up ++ i = -1; ++ values.forEach(function (v, j) { ++ if (v.x === d.x) { ++ i = j; ++ } ++ }); ++ } ++ if (i in values && values[i].value * d.value >= 0) { ++ offset += scale(values[i].value) - y0; ++ } ++ } ++ }); ++ return offset; ++ }; ++ }; ++ ChartInternal.prototype.isWithinShape = function (that, d) { ++ var $$ = this, ++ shape = $$.d3.select(that), ++ isWithin; ++ if (!$$.isTargetToShow(d.id)) { ++ isWithin = false; ++ } else if (that.nodeName === 'circle') { ++ isWithin = $$.isStepType(d) ? $$.isWithinStep(that, $$.getYScale(d.id)(d.value)) : $$.isWithinCircle(that, $$.pointSelectR(d) * 1.5); ++ } else if (that.nodeName === 'path') { ++ isWithin = shape.classed(CLASS.bar) ? $$.isWithinBar($$.d3.mouse(that), that) : true; ++ } ++ return isWithin; ++ }; ++ ++ ChartInternal.prototype.getInterpolate = function (d) { ++ var $$ = this, ++ d3 = $$.d3, ++ types = { ++ 'linear': d3.curveLinear, ++ 'linear-closed': d3.curveLinearClosed, ++ 'basis': d3.curveBasis, ++ 'basis-open': d3.curveBasisOpen, ++ 'basis-closed': d3.curveBasisClosed, ++ 'bundle': d3.curveBundle, ++ 'cardinal': d3.curveCardinal, ++ 'cardinal-open': d3.curveCardinalOpen, ++ 'cardinal-closed': d3.curveCardinalClosed, ++ 'monotone': d3.curveMonotoneX, ++ 'step': d3.curveStep, ++ 'step-before': d3.curveStepBefore, ++ 'step-after': d3.curveStepAfter ++ }, ++ type; ++ ++ if ($$.isSplineType(d)) { ++ type = types[$$.config.spline_interpolation_type] || types.cardinal; ++ } else if ($$.isStepType(d)) { ++ type = types[$$.config.line_step_type]; ++ } else { ++ type = types.linear; ++ } ++ return type; ++ }; ++ ++ ChartInternal.prototype.initLine = function () { ++ var $$ = this; ++ $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartLines); ++ }; ++ ChartInternal.prototype.updateTargetsForLine = function (targets) { ++ var $$ = this, ++ config = $$.config, ++ mainLines, ++ mainLineEnter, ++ classChartLine = $$.classChartLine.bind($$), ++ classLines = $$.classLines.bind($$), ++ classAreas = $$.classAreas.bind($$), ++ classCircles = $$.classCircles.bind($$), ++ classFocus = $$.classFocus.bind($$); ++ mainLines = $$.main.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine).data(targets).attr('class', function (d) { ++ return classChartLine(d) + classFocus(d); ++ }); ++ mainLineEnter = mainLines.enter().append('g').attr('class', classChartLine).style('opacity', 0).style("pointer-events", "none"); ++ // Lines for each data ++ mainLineEnter.append('g').attr("class", classLines); ++ // Areas ++ mainLineEnter.append('g').attr('class', classAreas); ++ // Circles for each data point on lines ++ mainLineEnter.append('g').attr("class", function (d) { ++ return $$.generateClass(CLASS.selectedCircles, d.id); ++ }); ++ mainLineEnter.append('g').attr("class", classCircles).style("cursor", function (d) { ++ return config.data_selection_isselectable(d) ? "pointer" : null; ++ }); ++ // Update date for selected circles ++ targets.forEach(function (t) { ++ $$.main.selectAll('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(t.id)).selectAll('.' + CLASS.selectedCircle).each(function (d) { ++ d.value = t.values[d.index].value; ++ }); ++ }); ++ // MEMO: can not keep same color... ++ //mainLineUpdate.exit().remove(); ++ }; ++ ChartInternal.prototype.updateLine = function (durationForExit) { ++ var $$ = this; ++ var mainLine = $$.main.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line).data($$.lineData.bind($$)); ++ var mainLineEnter = mainLine.enter().append('path').attr('class', $$.classLine.bind($$)).style("stroke", $$.color); ++ $$.mainLine = mainLineEnter.merge(mainLine).style("opacity", $$.initialOpacity.bind($$)).style('shape-rendering', function (d) { ++ return $$.isStepType(d) ? 'crispEdges' : ''; ++ }).attr('transform', null); ++ mainLine.exit().transition().duration(durationForExit).style('opacity', 0); ++ }; ++ ChartInternal.prototype.redrawLine = function (drawLine, withTransition, transition) { ++ return [(withTransition ? this.mainLine.transition(transition) : this.mainLine).attr("d", drawLine).style("stroke", this.color).style("opacity", 1)]; ++ }; ++ ChartInternal.prototype.generateDrawLine = function (lineIndices, isSub) { ++ var $$ = this, ++ config = $$.config, ++ line = $$.d3.line(), ++ getPoints = $$.generateGetLinePoints(lineIndices, isSub), ++ yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale, ++ xValue = function xValue(d) { ++ return (isSub ? $$.subxx : $$.xx).call($$, d); ++ }, ++ yValue = function yValue(d, i) { ++ return config.data_groups.length > 0 ? getPoints(d, i)[0][1] : yScaleGetter.call($$, d.id)(d.value); ++ }; ++ ++ line = config.axis_rotated ? line.x(yValue).y(xValue) : line.x(xValue).y(yValue); ++ if (!config.line_connectNull) { ++ line = line.defined(function (d) { ++ return d.value != null; ++ }); ++ } ++ return function (d) { ++ var values = config.line_connectNull ? $$.filterRemoveNull(d.values) : d.values, ++ x = isSub ? $$.subX : $$.x, ++ y = yScaleGetter.call($$, d.id), ++ x0 = 0, ++ y0 = 0, ++ path; ++ if ($$.isLineType(d)) { ++ if (config.data_regions[d.id]) { ++ path = $$.lineWithRegions(values, x, y, config.data_regions[d.id]); ++ } else { ++ if ($$.isStepType(d)) { ++ values = $$.convertValuesToStep(values); ++ } ++ path = line.curve($$.getInterpolate(d))(values); ++ } ++ } else { ++ if (values[0]) { ++ x0 = x(values[0].x); ++ y0 = y(values[0].value); ++ } ++ path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0; ++ } ++ return path ? path : "M 0 0"; ++ }; ++ }; ++ ChartInternal.prototype.generateGetLinePoints = function (lineIndices, isSub) { ++ // partial duplication of generateGetBarPoints ++ var $$ = this, ++ config = $$.config, ++ lineTargetsNum = lineIndices.__max__ + 1, ++ x = $$.getShapeX(0, lineTargetsNum, lineIndices, !!isSub), ++ y = $$.getShapeY(!!isSub), ++ lineOffset = $$.getShapeOffset($$.isLineType, lineIndices, !!isSub), ++ yScale = isSub ? $$.getSubYScale : $$.getYScale; ++ return function (d, i) { ++ var y0 = yScale.call($$, d.id)(0), ++ offset = lineOffset(d, i) || y0, ++ // offset is for stacked area chart ++ posX = x(d), ++ posY = y(d); ++ // fix posY not to overflow opposite quadrant ++ if (config.axis_rotated) { ++ if (0 < d.value && posY < y0 || d.value < 0 && y0 < posY) { ++ posY = y0; ++ } ++ } ++ // 1 point that marks the line position ++ return [[posX, posY - (y0 - offset)], [posX, posY - (y0 - offset)], // needed for compatibility ++ [posX, posY - (y0 - offset)], // needed for compatibility ++ [posX, posY - (y0 - offset)] // needed for compatibility ++ ]; ++ }; ++ }; ++ ++ ChartInternal.prototype.lineWithRegions = function (d, x, y, _regions) { ++ var $$ = this, ++ config = $$.config, ++ prev = -1, ++ i, ++ j, ++ s = "M", ++ sWithRegion, ++ xp, ++ yp, ++ dx, ++ dy, ++ dd, ++ diff, ++ diffx2, ++ xOffset = $$.isCategorized() ? 0.5 : 0, ++ xValue, ++ yValue, ++ regions = []; ++ ++ function isWithinRegions(x, regions) { ++ var i; ++ for (i = 0; i < regions.length; i++) { ++ if (regions[i].start < x && x <= regions[i].end) { ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ // Check start/end of regions ++ if (isDefined(_regions)) { ++ for (i = 0; i < _regions.length; i++) { ++ regions[i] = {}; ++ if (isUndefined(_regions[i].start)) { ++ regions[i].start = d[0].x; ++ } else { ++ regions[i].start = $$.isTimeSeries() ? $$.parseDate(_regions[i].start) : _regions[i].start; ++ } ++ if (isUndefined(_regions[i].end)) { ++ regions[i].end = d[d.length - 1].x; ++ } else { ++ regions[i].end = $$.isTimeSeries() ? $$.parseDate(_regions[i].end) : _regions[i].end; ++ } ++ } ++ } ++ ++ // Set scales ++ xValue = config.axis_rotated ? function (d) { ++ return y(d.value); ++ } : function (d) { ++ return x(d.x); ++ }; ++ yValue = config.axis_rotated ? function (d) { ++ return x(d.x); ++ } : function (d) { ++ return y(d.value); ++ }; ++ ++ // Define svg generator function for region ++ function generateM(points) { ++ return 'M' + points[0][0] + ' ' + points[0][1] + ' ' + points[1][0] + ' ' + points[1][1]; ++ } ++ if ($$.isTimeSeries()) { ++ sWithRegion = function sWithRegion(d0, d1, j, diff) { ++ var x0 = d0.x.getTime(), ++ x_diff = d1.x - d0.x, ++ xv0 = new Date(x0 + x_diff * j), ++ xv1 = new Date(x0 + x_diff * (j + diff)), ++ points; ++ if (config.axis_rotated) { ++ points = [[y(yp(j)), x(xv0)], [y(yp(j + diff)), x(xv1)]]; ++ } else { ++ points = [[x(xv0), y(yp(j))], [x(xv1), y(yp(j + diff))]]; ++ } ++ return generateM(points); ++ }; ++ } else { ++ sWithRegion = function sWithRegion(d0, d1, j, diff) { ++ var points; ++ if (config.axis_rotated) { ++ points = [[y(yp(j), true), x(xp(j))], [y(yp(j + diff), true), x(xp(j + diff))]]; ++ } else { ++ points = [[x(xp(j), true), y(yp(j))], [x(xp(j + diff), true), y(yp(j + diff))]]; ++ } ++ return generateM(points); ++ }; ++ } ++ ++ // Generate ++ for (i = 0; i < d.length; i++) { ++ ++ // Draw as normal ++ if (isUndefined(regions) || !isWithinRegions(d[i].x, regions)) { ++ s += " " + xValue(d[i]) + " " + yValue(d[i]); ++ } ++ // Draw with region // TODO: Fix for horizotal charts ++ else { ++ xp = $$.getScale(d[i - 1].x + xOffset, d[i].x + xOffset, $$.isTimeSeries()); ++ yp = $$.getScale(d[i - 1].value, d[i].value); ++ ++ dx = x(d[i].x) - x(d[i - 1].x); ++ dy = y(d[i].value) - y(d[i - 1].value); ++ dd = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); ++ diff = 2 / dd; ++ diffx2 = diff * 2; ++ ++ for (j = diff; j <= 1; j += diffx2) { ++ s += sWithRegion(d[i - 1], d[i], j, diff); ++ } ++ } ++ prev = d[i].x; ++ } ++ ++ return s; ++ }; ++ ++ ChartInternal.prototype.updateArea = function (durationForExit) { ++ var $$ = this, ++ d3 = $$.d3; ++ var mainArea = $$.main.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area).data($$.lineData.bind($$)); ++ var mainAreaEnter = mainArea.enter().append('path').attr("class", $$.classArea.bind($$)).style("fill", $$.color).style("opacity", function () { ++ $$.orgAreaOpacity = +d3.select(this).style('opacity');return 0; ++ }); ++ $$.mainArea = mainAreaEnter.merge(mainArea).style("opacity", $$.orgAreaOpacity); ++ mainArea.exit().transition().duration(durationForExit).style('opacity', 0); ++ }; ++ ChartInternal.prototype.redrawArea = function (drawArea, withTransition, transition) { ++ return [(withTransition ? this.mainArea.transition(transition) : this.mainArea).attr("d", drawArea).style("fill", this.color).style("opacity", this.orgAreaOpacity)]; ++ }; ++ ChartInternal.prototype.generateDrawArea = function (areaIndices, isSub) { ++ var $$ = this, ++ config = $$.config, ++ area = $$.d3.area(), ++ getPoints = $$.generateGetAreaPoints(areaIndices, isSub), ++ yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale, ++ xValue = function xValue(d) { ++ return (isSub ? $$.subxx : $$.xx).call($$, d); ++ }, ++ value0 = function value0(d, i) { ++ return config.data_groups.length > 0 ? getPoints(d, i)[0][1] : yScaleGetter.call($$, d.id)($$.getAreaBaseValue(d.id)); ++ }, ++ value1 = function value1(d, i) { ++ return config.data_groups.length > 0 ? getPoints(d, i)[1][1] : yScaleGetter.call($$, d.id)(d.value); ++ }; ++ ++ area = config.axis_rotated ? area.x0(value0).x1(value1).y(xValue) : area.x(xValue).y0(config.area_above ? 0 : value0).y1(value1); ++ if (!config.line_connectNull) { ++ area = area.defined(function (d) { ++ return d.value !== null; ++ }); ++ } ++ ++ return function (d) { ++ var values = config.line_connectNull ? $$.filterRemoveNull(d.values) : d.values, ++ x0 = 0, ++ y0 = 0, ++ path; ++ if ($$.isAreaType(d)) { ++ if ($$.isStepType(d)) { ++ values = $$.convertValuesToStep(values); ++ } ++ path = area.curve($$.getInterpolate(d))(values); ++ } else { ++ if (values[0]) { ++ x0 = $$.x(values[0].x); ++ y0 = $$.getYScale(d.id)(values[0].value); ++ } ++ path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0; ++ } ++ return path ? path : "M 0 0"; ++ }; ++ }; ++ ChartInternal.prototype.getAreaBaseValue = function () { ++ return 0; ++ }; ++ ChartInternal.prototype.generateGetAreaPoints = function (areaIndices, isSub) { ++ // partial duplication of generateGetBarPoints ++ var $$ = this, ++ config = $$.config, ++ areaTargetsNum = areaIndices.__max__ + 1, ++ x = $$.getShapeX(0, areaTargetsNum, areaIndices, !!isSub), ++ y = $$.getShapeY(!!isSub), ++ areaOffset = $$.getShapeOffset($$.isAreaType, areaIndices, !!isSub), ++ yScale = isSub ? $$.getSubYScale : $$.getYScale; ++ return function (d, i) { ++ var y0 = yScale.call($$, d.id)(0), ++ offset = areaOffset(d, i) || y0, ++ // offset is for stacked area chart ++ posX = x(d), ++ posY = y(d); ++ // fix posY not to overflow opposite quadrant ++ if (config.axis_rotated) { ++ if (0 < d.value && posY < y0 || d.value < 0 && y0 < posY) { ++ posY = y0; ++ } ++ } ++ // 1 point that marks the area position ++ return [[posX, offset], [posX, posY - (y0 - offset)], [posX, posY - (y0 - offset)], // needed for compatibility ++ [posX, offset] // needed for compatibility ++ ]; ++ }; ++ }; ++ ++ ChartInternal.prototype.updateCircle = function (cx, cy) { ++ var $$ = this; ++ var mainCircle = $$.main.selectAll('.' + CLASS.circles).selectAll('.' + CLASS.circle).data($$.lineOrScatterData.bind($$)); ++ var mainCircleEnter = mainCircle.enter().append("circle").attr("class", $$.classCircle.bind($$)).attr("cx", cx).attr("cy", cy).attr("r", $$.pointR.bind($$)).style("fill", $$.color); ++ $$.mainCircle = mainCircleEnter.merge(mainCircle).style("opacity", $$.initialOpacityForCircle.bind($$)); ++ mainCircle.exit().style("opacity", 0); ++ }; ++ ChartInternal.prototype.redrawCircle = function (cx, cy, withTransition, transition) { ++ var $$ = this, ++ selectedCircles = $$.main.selectAll('.' + CLASS.selectedCircle); ++ return [(withTransition ? $$.mainCircle.transition(transition) : $$.mainCircle).style('opacity', this.opacityForCircle.bind($$)).style("fill", $$.color).attr("cx", cx).attr("cy", cy), (withTransition ? selectedCircles.transition(transition) : selectedCircles).attr("cx", cx).attr("cy", cy)]; ++ }; ++ ChartInternal.prototype.circleX = function (d) { ++ return d.x || d.x === 0 ? this.x(d.x) : null; ++ }; ++ ChartInternal.prototype.updateCircleY = function () { ++ var $$ = this, ++ lineIndices, ++ getPoints; ++ if ($$.config.data_groups.length > 0) { ++ lineIndices = $$.getShapeIndices($$.isLineType), getPoints = $$.generateGetLinePoints(lineIndices); ++ $$.circleY = function (d, i) { ++ return getPoints(d, i)[0][1]; ++ }; ++ } else { ++ $$.circleY = function (d) { ++ return $$.getYScale(d.id)(d.value); ++ }; ++ } ++ }; ++ ChartInternal.prototype.getCircles = function (i, id) { ++ var $$ = this; ++ return (id ? $$.main.selectAll('.' + CLASS.circles + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.circle + (isValue(i) ? '-' + i : '')); ++ }; ++ ChartInternal.prototype.expandCircles = function (i, id, reset) { ++ var $$ = this, ++ r = $$.pointExpandedR.bind($$); ++ if (reset) { ++ $$.unexpandCircles(); ++ } ++ $$.getCircles(i, id).classed(CLASS.EXPANDED, true).attr('r', r); ++ }; ++ ChartInternal.prototype.unexpandCircles = function (i) { ++ var $$ = this, ++ r = $$.pointR.bind($$); ++ $$.getCircles(i).filter(function () { ++ return $$.d3.select(this).classed(CLASS.EXPANDED); ++ }).classed(CLASS.EXPANDED, false).attr('r', r); ++ }; ++ ChartInternal.prototype.pointR = function (d) { ++ var $$ = this, ++ config = $$.config; ++ return $$.isStepType(d) ? 0 : isFunction(config.point_r) ? config.point_r(d) : config.point_r; ++ }; ++ ChartInternal.prototype.pointExpandedR = function (d) { ++ var $$ = this, ++ config = $$.config; ++ if (config.point_focus_expand_enabled) { ++ return isFunction(config.point_focus_expand_r) ? config.point_focus_expand_r(d) : config.point_focus_expand_r ? config.point_focus_expand_r : $$.pointR(d) * 1.75; ++ } else { ++ return $$.pointR(d); ++ } ++ }; ++ ChartInternal.prototype.pointSelectR = function (d) { ++ var $$ = this, ++ config = $$.config; ++ return isFunction(config.point_select_r) ? config.point_select_r(d) : config.point_select_r ? config.point_select_r : $$.pointR(d) * 4; ++ }; ++ ChartInternal.prototype.isWithinCircle = function (that, r) { ++ var d3 = this.d3, ++ mouse = d3.mouse(that), ++ d3_this = d3.select(that), ++ cx = +d3_this.attr("cx"), ++ cy = +d3_this.attr("cy"); ++ return Math.sqrt(Math.pow(cx - mouse[0], 2) + Math.pow(cy - mouse[1], 2)) < r; ++ }; ++ ChartInternal.prototype.isWithinStep = function (that, y) { ++ return Math.abs(y - this.d3.mouse(that)[1]) < 30; ++ }; ++ ++ ChartInternal.prototype.getCurrentWidth = function () { ++ var $$ = this, ++ config = $$.config; ++ return config.size_width ? config.size_width : $$.getParentWidth(); ++ }; ++ ChartInternal.prototype.getCurrentHeight = function () { ++ var $$ = this, ++ config = $$.config, ++ h = config.size_height ? config.size_height : $$.getParentHeight(); ++ return h > 0 ? h : 320 / ($$.hasType('gauge') && !config.gauge_fullCircle ? 2 : 1); ++ }; ++ ChartInternal.prototype.getCurrentPaddingTop = function () { ++ var $$ = this, ++ config = $$.config, ++ padding = isValue(config.padding_top) ? config.padding_top : 0; ++ if ($$.title && $$.title.node()) { ++ padding += $$.getTitlePadding(); ++ } ++ return padding; ++ }; ++ ChartInternal.prototype.getCurrentPaddingBottom = function () { ++ var config = this.config; ++ return isValue(config.padding_bottom) ? config.padding_bottom : 0; ++ }; ++ ChartInternal.prototype.getCurrentPaddingLeft = function (withoutRecompute) { ++ var $$ = this, ++ config = $$.config; ++ if (isValue(config.padding_left)) { ++ return config.padding_left; ++ } else if (config.axis_rotated) { ++ return !config.axis_x_show || config.axis_x_inner ? 1 : Math.max(ceil10($$.getAxisWidthByAxisId('x', withoutRecompute)), 40); ++ } else if (!config.axis_y_show || config.axis_y_inner) { ++ // && !config.axis_rotated ++ return $$.axis.getYAxisLabelPosition().isOuter ? 30 : 1; ++ } else { ++ return ceil10($$.getAxisWidthByAxisId('y', withoutRecompute)); ++ } ++ }; ++ ChartInternal.prototype.getCurrentPaddingRight = function () { ++ var $$ = this, ++ config = $$.config, ++ defaultPadding = 10, ++ legendWidthOnRight = $$.isLegendRight ? $$.getLegendWidth() + 20 : 0; ++ if (isValue(config.padding_right)) { ++ return config.padding_right + 1; // 1 is needed not to hide tick line ++ } else if (config.axis_rotated) { ++ return defaultPadding + legendWidthOnRight; ++ } else if (!config.axis_y2_show || config.axis_y2_inner) { ++ // && !config.axis_rotated ++ return 2 + legendWidthOnRight + ($$.axis.getY2AxisLabelPosition().isOuter ? 20 : 0); ++ } else { ++ return ceil10($$.getAxisWidthByAxisId('y2')) + legendWidthOnRight; ++ } ++ }; ++ ++ ChartInternal.prototype.getParentRectValue = function (key) { ++ var parent = this.selectChart.node(), ++ v; ++ while (parent && parent.tagName !== 'BODY') { ++ try { ++ v = parent.getBoundingClientRect()[key]; ++ } catch (e) { ++ if (key === 'width') { ++ // In IE in certain cases getBoundingClientRect ++ // will cause an "unspecified error" ++ v = parent.offsetWidth; ++ } ++ } ++ if (v) { ++ break; ++ } ++ parent = parent.parentNode; ++ } ++ return v; ++ }; ++ ChartInternal.prototype.getParentWidth = function () { ++ return this.getParentRectValue('width'); ++ }; ++ ChartInternal.prototype.getParentHeight = function () { ++ var h = this.selectChart.style('height'); ++ return h.indexOf('px') > 0 ? +h.replace('px', '') : 0; ++ }; ++ ++ ChartInternal.prototype.getSvgLeft = function (withoutRecompute) { ++ var $$ = this, ++ config = $$.config, ++ hasLeftAxisRect = config.axis_rotated || !config.axis_rotated && !config.axis_y_inner, ++ leftAxisClass = config.axis_rotated ? CLASS.axisX : CLASS.axisY, ++ leftAxis = $$.main.select('.' + leftAxisClass).node(), ++ svgRect = leftAxis && hasLeftAxisRect ? leftAxis.getBoundingClientRect() : { right: 0 }, ++ chartRect = $$.selectChart.node().getBoundingClientRect(), ++ hasArc = $$.hasArcType(), ++ svgLeft = svgRect.right - chartRect.left - (hasArc ? 0 : $$.getCurrentPaddingLeft(withoutRecompute)); ++ return svgLeft > 0 ? svgLeft : 0; ++ }; ++ ++ ChartInternal.prototype.getAxisWidthByAxisId = function (id, withoutRecompute) { ++ var $$ = this, ++ position = $$.axis.getLabelPositionById(id); ++ return $$.axis.getMaxTickWidth(id, withoutRecompute) + (position.isInner ? 20 : 40); ++ }; ++ ChartInternal.prototype.getHorizontalAxisHeight = function (axisId) { ++ var $$ = this, ++ config = $$.config, ++ h = 30; ++ if (axisId === 'x' && !config.axis_x_show) { ++ return 8; ++ } ++ if (axisId === 'x' && config.axis_x_height) { ++ return config.axis_x_height; ++ } ++ if (axisId === 'y' && !config.axis_y_show) { ++ return config.legend_show && !$$.isLegendRight && !$$.isLegendInset ? 10 : 1; ++ } ++ if (axisId === 'y2' && !config.axis_y2_show) { ++ return $$.rotated_padding_top; ++ } ++ // Calculate x axis height when tick rotated ++ if (axisId === 'x' && !config.axis_rotated && config.axis_x_tick_rotate) { ++ h = 30 + $$.axis.getMaxTickWidth(axisId) * Math.cos(Math.PI * (90 - Math.abs(config.axis_x_tick_rotate)) / 180); ++ } ++ // Calculate y axis height when tick rotated ++ if (axisId === 'y' && config.axis_rotated && config.axis_y_tick_rotate) { ++ h = 30 + $$.axis.getMaxTickWidth(axisId) * Math.cos(Math.PI * (90 - Math.abs(config.axis_y_tick_rotate)) / 180); ++ } ++ return h + ($$.axis.getLabelPositionById(axisId).isInner ? 0 : 10) + (axisId === 'y2' ? -10 : 0); ++ }; ++ ++ ChartInternal.prototype.initBrush = function (scale) { ++ var $$ = this, ++ d3 = $$.d3; ++ // TODO: dynamically change brushY/brushX according to axis_rotated. ++ $$.brush = ($$.config.axis_rotated ? d3.brushY() : d3.brushX()).on("brush", function () { ++ var event = d3.event.sourceEvent; ++ if (event && event.type === "zoom") { ++ return; ++ } ++ $$.redrawForBrush(); ++ }).on("end", function () { ++ var event = d3.event.sourceEvent; ++ if (event && event.type === "zoom") { ++ return; ++ } ++ if ($$.brush.empty() && event && event.type !== 'end') { ++ $$.brush.clear(); ++ } ++ }); ++ $$.brush.updateExtent = function () { ++ var range = this.scale.range(), ++ extent; ++ if ($$.config.axis_rotated) { ++ extent = [[0, range[0]], [$$.width2, range[1]]]; ++ } else { ++ extent = [[range[0], 0], [range[1], $$.height2]]; ++ } ++ this.extent(extent); ++ return this; ++ }; ++ $$.brush.updateScale = function (scale) { ++ this.scale = scale; ++ return this; ++ }; ++ $$.brush.update = function (scale) { ++ this.updateScale(scale || $$.subX).updateExtent(); ++ $$.context.select('.' + CLASS.brush).call(this); ++ }; ++ $$.brush.clear = function () { ++ $$.context.select('.' + CLASS.brush).call($$.brush.move, null); ++ }; ++ $$.brush.selection = function () { ++ return d3.brushSelection($$.context.select('.' + CLASS.brush).node()); ++ }; ++ $$.brush.selectionAsValue = function (selectionAsValue, withTransition) { ++ var selection, brush; ++ if (selectionAsValue) { ++ if ($$.context) { ++ selection = [this.scale(selectionAsValue[0]), this.scale(selectionAsValue[1])]; ++ brush = $$.context.select('.' + CLASS.brush); ++ if (withTransition) { ++ brush = brush.transition(); ++ } ++ $$.brush.move(brush, selection); ++ } ++ return []; ++ } ++ selection = $$.brush.selection() || [0, 0]; ++ return [this.scale.invert(selection[0]), this.scale.invert(selection[1])]; ++ }; ++ $$.brush.empty = function () { ++ var selection = $$.brush.selection(); ++ return !selection || selection[0] === selection[1]; ++ }; ++ return $$.brush.updateScale(scale); ++ }; ++ ChartInternal.prototype.initSubchart = function () { ++ var $$ = this, ++ config = $$.config, ++ context = $$.context = $$.svg.append("g").attr("transform", $$.getTranslate('context')), ++ visibility = config.subchart_show ? 'visible' : 'hidden'; ++ ++ // set style ++ context.style('visibility', visibility); ++ ++ // Define g for chart area ++ context.append('g').attr("clip-path", $$.clipPathForSubchart).attr('class', CLASS.chart); ++ ++ // Define g for bar chart area ++ context.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartBars); ++ ++ // Define g for line chart area ++ context.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartLines); ++ ++ // Add extent rect for Brush ++ context.append("g").attr("clip-path", $$.clipPath).attr("class", CLASS.brush); ++ ++ // ATTENTION: This must be called AFTER chart added ++ // Add Axis ++ $$.axes.subx = context.append("g").attr("class", CLASS.axisX).attr("transform", $$.getTranslate('subx')).attr("clip-path", config.axis_rotated ? "" : $$.clipPathForXAxis); ++ }; ++ ChartInternal.prototype.initSubchartBrush = function () { ++ var $$ = this; ++ // Add extent rect for Brush ++ $$.initBrush($$.subX).updateExtent(); ++ $$.context.select('.' + CLASS.brush).call($$.brush); ++ }; ++ ChartInternal.prototype.updateTargetsForSubchart = function (targets) { ++ var $$ = this, ++ context = $$.context, ++ config = $$.config, ++ contextLineEnter, ++ contextLine, ++ contextBarEnter, ++ contextBar, ++ classChartBar = $$.classChartBar.bind($$), ++ classBars = $$.classBars.bind($$), ++ classChartLine = $$.classChartLine.bind($$), ++ classLines = $$.classLines.bind($$), ++ classAreas = $$.classAreas.bind($$); ++ ++ if (config.subchart_show) { ++ //-- Bar --// ++ contextBar = context.select('.' + CLASS.chartBars).selectAll('.' + CLASS.chartBar).data(targets); ++ contextBarEnter = contextBar.enter().append('g').style('opacity', 0); ++ contextBarEnter.merge(contextBar).attr('class', classChartBar); ++ // Bars for each data ++ contextBarEnter.append('g').attr("class", classBars); ++ ++ //-- Line --// ++ contextLine = context.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine).data(targets); ++ contextLineEnter = contextLine.enter().append('g').style('opacity', 0); ++ contextLineEnter.merge(contextLine).attr('class', classChartLine); ++ // Lines for each data ++ contextLineEnter.append("g").attr("class", classLines); ++ // Area ++ contextLineEnter.append("g").attr("class", classAreas); ++ ++ //-- Brush --// ++ context.selectAll('.' + CLASS.brush + ' rect').attr(config.axis_rotated ? "width" : "height", config.axis_rotated ? $$.width2 : $$.height2); ++ } ++ }; ++ ChartInternal.prototype.updateBarForSubchart = function (durationForExit) { ++ var $$ = this; ++ var contextBar = $$.context.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar).data($$.barData.bind($$)); ++ var contextBarEnter = contextBar.enter().append('path').attr("class", $$.classBar.bind($$)).style("stroke", 'none').style("fill", $$.color); ++ contextBar.exit().transition().duration(durationForExit).style('opacity', 0).remove(); ++ $$.contextBar = contextBarEnter.merge(contextBar).style("opacity", $$.initialOpacity.bind($$)); ++ }; ++ ChartInternal.prototype.redrawBarForSubchart = function (drawBarOnSub, withTransition, duration) { ++ (withTransition ? this.contextBar.transition(Math.random().toString()).duration(duration) : this.contextBar).attr('d', drawBarOnSub).style('opacity', 1); ++ }; ++ ChartInternal.prototype.updateLineForSubchart = function (durationForExit) { ++ var $$ = this; ++ var contextLine = $$.context.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line).data($$.lineData.bind($$)); ++ var contextLineEnter = contextLine.enter().append('path').attr('class', $$.classLine.bind($$)).style('stroke', $$.color); ++ contextLine.exit().transition().duration(durationForExit).style('opacity', 0).remove(); ++ $$.contextLine = contextLineEnter.merge(contextLine).style("opacity", $$.initialOpacity.bind($$)); ++ }; ++ ChartInternal.prototype.redrawLineForSubchart = function (drawLineOnSub, withTransition, duration) { ++ (withTransition ? this.contextLine.transition(Math.random().toString()).duration(duration) : this.contextLine).attr("d", drawLineOnSub).style('opacity', 1); ++ }; ++ ChartInternal.prototype.updateAreaForSubchart = function (durationForExit) { ++ var $$ = this, ++ d3 = $$.d3; ++ var contextArea = $$.context.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area).data($$.lineData.bind($$)); ++ var contextAreaEnter = contextArea.enter().append('path').attr("class", $$.classArea.bind($$)).style("fill", $$.color).style("opacity", function () { ++ $$.orgAreaOpacity = +d3.select(this).style('opacity');return 0; ++ }); ++ contextArea.exit().transition().duration(durationForExit).style('opacity', 0).remove(); ++ $$.contextArea = contextAreaEnter.merge(contextArea).style("opacity", 0); ++ }; ++ ChartInternal.prototype.redrawAreaForSubchart = function (drawAreaOnSub, withTransition, duration) { ++ (withTransition ? this.contextArea.transition(Math.random().toString()).duration(duration) : this.contextArea).attr("d", drawAreaOnSub).style("fill", this.color).style("opacity", this.orgAreaOpacity); ++ }; ++ ChartInternal.prototype.redrawSubchart = function (withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices) { ++ var $$ = this, ++ d3 = $$.d3, ++ config = $$.config, ++ drawAreaOnSub, ++ drawBarOnSub, ++ drawLineOnSub; ++ ++ $$.context.style('visibility', config.subchart_show ? 'visible' : 'hidden'); ++ ++ // subchart ++ if (config.subchart_show) { ++ // reflect main chart to extent on subchart if zoomed ++ if (d3.event && d3.event.type === 'zoom') { ++ $$.brush.selectionAsValue($$.x.orgDomain()); ++ } ++ // update subchart elements if needed ++ if (withSubchart) { ++ // extent rect ++ if (!$$.brush.empty()) { ++ $$.brush.selectionAsValue($$.x.orgDomain()); ++ } ++ // setup drawer - MEMO: this must be called after axis updated ++ drawAreaOnSub = $$.generateDrawArea(areaIndices, true); ++ drawBarOnSub = $$.generateDrawBar(barIndices, true); ++ drawLineOnSub = $$.generateDrawLine(lineIndices, true); ++ ++ $$.updateBarForSubchart(duration); ++ $$.updateLineForSubchart(duration); ++ $$.updateAreaForSubchart(duration); ++ ++ $$.redrawBarForSubchart(drawBarOnSub, duration, duration); ++ $$.redrawLineForSubchart(drawLineOnSub, duration, duration); ++ $$.redrawAreaForSubchart(drawAreaOnSub, duration, duration); ++ } ++ } ++ }; ++ ChartInternal.prototype.redrawForBrush = function () { ++ var $$ = this, ++ x = $$.x, ++ d3 = $$.d3, ++ s; ++ $$.redraw({ ++ withTransition: false, ++ withY: $$.config.zoom_rescale, ++ withSubchart: false, ++ withUpdateXDomain: true, ++ withEventRect: false, ++ withDimension: false ++ }); ++ // update zoom transation binded to event rect ++ s = d3.event.selection || $$.brush.scale.range(); ++ $$.main.select('.' + CLASS.eventRect).call($$.zoom.transform, d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0)); ++ $$.config.subchart_onbrush.call($$.api, x.orgDomain()); ++ }; ++ ChartInternal.prototype.transformContext = function (withTransition, transitions) { ++ var $$ = this, ++ subXAxis; ++ if (transitions && transitions.axisSubX) { ++ subXAxis = transitions.axisSubX; ++ } else { ++ subXAxis = $$.context.select('.' + CLASS.axisX); ++ if (withTransition) { ++ subXAxis = subXAxis.transition(); ++ } ++ } ++ $$.context.attr("transform", $$.getTranslate('context')); ++ subXAxis.attr("transform", $$.getTranslate('subx')); ++ }; ++ ChartInternal.prototype.getDefaultSelection = function () { ++ var $$ = this, ++ config = $$.config, ++ selection = isFunction(config.axis_x_selection) ? config.axis_x_selection($$.getXDomain($$.data.targets)) : config.axis_x_selection; ++ if ($$.isTimeSeries()) { ++ selection = [$$.parseDate(selection[0]), $$.parseDate(selection[1])]; ++ } ++ return selection; ++ }; ++ ++ ChartInternal.prototype.initText = function () { ++ var $$ = this; ++ $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartTexts); ++ $$.mainText = $$.d3.selectAll([]); ++ }; ++ ChartInternal.prototype.updateTargetsForText = function (targets) { ++ var $$ = this, ++ classChartText = $$.classChartText.bind($$), ++ classTexts = $$.classTexts.bind($$), ++ classFocus = $$.classFocus.bind($$); ++ var mainText = $$.main.select('.' + CLASS.chartTexts).selectAll('.' + CLASS.chartText).data(targets); ++ var mainTextEnter = mainText.enter().append('g').attr('class', classChartText).style('opacity', 0).style("pointer-events", "none"); ++ mainTextEnter.append('g').attr('class', classTexts); ++ mainTextEnter.merge(mainText).attr('class', function (d) { ++ return classChartText(d) + classFocus(d); ++ }); ++ }; ++ ChartInternal.prototype.updateText = function (xForText, yForText, durationForExit) { ++ var $$ = this, ++ config = $$.config, ++ barOrLineData = $$.barOrLineData.bind($$), ++ classText = $$.classText.bind($$); ++ var mainText = $$.main.selectAll('.' + CLASS.texts).selectAll('.' + CLASS.text).data(barOrLineData); ++ var mainTextEnter = mainText.enter().append('text').attr("class", classText).attr('text-anchor', function (d) { ++ return config.axis_rotated ? d.value < 0 ? 'end' : 'start' : 'middle'; ++ }).style("stroke", 'none').attr('x', xForText).attr('y', yForText).style("fill", function (d) { ++ return $$.color(d); ++ }).style("fill-opacity", 0); ++ $$.mainText = mainTextEnter.merge(mainText).text(function (d, i, j) { ++ return $$.dataLabelFormat(d.id)(d.value, d.id, i, j); ++ }); ++ mainText.exit().transition().duration(durationForExit).style('fill-opacity', 0).remove(); ++ }; ++ ChartInternal.prototype.redrawText = function (xForText, yForText, forFlow, withTransition, transition) { ++ return [(withTransition ? this.mainText.transition(transition) : this.mainText).attr('x', xForText).attr('y', yForText).style("fill", this.color).style("fill-opacity", forFlow ? 0 : this.opacityForText.bind(this))]; ++ }; ++ ChartInternal.prototype.getTextRect = function (text, cls, element) { ++ var dummy = this.d3.select('body').append('div').classed('c3', true), ++ svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0), ++ font = this.d3.select(element).style('font'), ++ rect; ++ svg.selectAll('.dummy').data([text]).enter().append('text').classed(cls ? cls : "", true).style('font', font).text(text).each(function () { ++ rect = this.getBoundingClientRect(); ++ }); ++ dummy.remove(); ++ return rect; ++ }; ++ ChartInternal.prototype.generateXYForText = function (areaIndices, barIndices, lineIndices, forX) { ++ var $$ = this, ++ getAreaPoints = $$.generateGetAreaPoints(areaIndices, false), ++ getBarPoints = $$.generateGetBarPoints(barIndices, false), ++ getLinePoints = $$.generateGetLinePoints(lineIndices, false), ++ getter = forX ? $$.getXForText : $$.getYForText; ++ return function (d, i) { ++ var getPoints = $$.isAreaType(d) ? getAreaPoints : $$.isBarType(d) ? getBarPoints : getLinePoints; ++ return getter.call($$, getPoints(d, i), d, this); ++ }; ++ }; ++ ChartInternal.prototype.getXForText = function (points, d, textElement) { ++ var $$ = this, ++ box = textElement.getBoundingClientRect(), ++ xPos, ++ padding; ++ if ($$.config.axis_rotated) { ++ padding = $$.isBarType(d) ? 4 : 6; ++ xPos = points[2][1] + padding * (d.value < 0 ? -1 : 1); ++ } else { ++ xPos = $$.hasType('bar') ? (points[2][0] + points[0][0]) / 2 : points[0][0]; ++ } ++ // show labels regardless of the domain if value is null ++ if (d.value === null) { ++ if (xPos > $$.width) { ++ xPos = $$.width - box.width; ++ } else if (xPos < 0) { ++ xPos = 4; ++ } ++ } ++ return xPos; ++ }; ++ ChartInternal.prototype.getYForText = function (points, d, textElement) { ++ var $$ = this, ++ box = textElement.getBoundingClientRect(), ++ yPos; ++ if ($$.config.axis_rotated) { ++ yPos = (points[0][0] + points[2][0] + box.height * 0.6) / 2; ++ } else { ++ yPos = points[2][1]; ++ if (d.value < 0 || d.value === 0 && !$$.hasPositiveValue) { ++ yPos += box.height; ++ if ($$.isBarType(d) && $$.isSafari()) { ++ yPos -= 3; ++ } else if (!$$.isBarType(d) && $$.isChrome()) { ++ yPos += 3; ++ } ++ } else { ++ yPos += $$.isBarType(d) ? -3 : -6; ++ } ++ } ++ // show labels regardless of the domain if value is null ++ if (d.value === null && !$$.config.axis_rotated) { ++ if (yPos < box.height) { ++ yPos = box.height; ++ } else if (yPos > this.height) { ++ yPos = this.height - 4; ++ } ++ } ++ return yPos; ++ }; ++ ++ ChartInternal.prototype.initTitle = function () { ++ var $$ = this; ++ $$.title = $$.svg.append("text").text($$.config.title_text).attr("class", $$.CLASS.title); ++ }; ++ ChartInternal.prototype.redrawTitle = function () { ++ var $$ = this; ++ $$.title.attr("x", $$.xForTitle.bind($$)).attr("y", $$.yForTitle.bind($$)); ++ }; ++ ChartInternal.prototype.xForTitle = function () { ++ var $$ = this, ++ config = $$.config, ++ position = config.title_position || 'left', ++ x; ++ if (position.indexOf('right') >= 0) { ++ x = $$.currentWidth - $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).width - config.title_padding.right; ++ } else if (position.indexOf('center') >= 0) { ++ x = ($$.currentWidth - $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).width) / 2; ++ } else { ++ // left ++ x = config.title_padding.left; ++ } ++ return x; ++ }; ++ ChartInternal.prototype.yForTitle = function () { ++ var $$ = this; ++ return $$.config.title_padding.top + $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).height; ++ }; ++ ChartInternal.prototype.getTitlePadding = function () { ++ var $$ = this; ++ return $$.yForTitle() + $$.config.title_padding.bottom; ++ }; ++ ++ ChartInternal.prototype.initTooltip = function () { ++ var $$ = this, ++ config = $$.config, ++ i; ++ $$.tooltip = $$.selectChart.style("position", "relative").append("div").attr('class', CLASS.tooltipContainer).style("position", "absolute").style("pointer-events", "none").style("display", "none"); ++ // Show tooltip if needed ++ if (config.tooltip_init_show) { ++ if ($$.isTimeSeries() && isString(config.tooltip_init_x)) { ++ config.tooltip_init_x = $$.parseDate(config.tooltip_init_x); ++ for (i = 0; i < $$.data.targets[0].values.length; i++) { ++ if ($$.data.targets[0].values[i].x - config.tooltip_init_x === 0) { ++ break; ++ } ++ } ++ config.tooltip_init_x = i; ++ } ++ $$.tooltip.html(config.tooltip_contents.call($$, $$.data.targets.map(function (d) { ++ return $$.addName(d.values[config.tooltip_init_x]); ++ }), $$.axis.getXAxisTickFormat(), $$.getYFormat($$.hasArcType()), $$.color)); ++ $$.tooltip.style("top", config.tooltip_init_position.top).style("left", config.tooltip_init_position.left).style("display", "block"); ++ } ++ }; ++ ChartInternal.prototype.getTooltipSortFunction = function () { ++ var $$ = this, ++ config = $$.config; ++ ++ if (config.data_groups.length === 0 || config.tooltip_order !== undefined) { ++ // if data are not grouped or if an order is specified ++ // for the tooltip values we sort them by their values ++ ++ var order = config.tooltip_order; ++ if (order === undefined) { ++ order = config.data_order; ++ } ++ ++ var valueOf = function valueOf(obj) { ++ return obj ? obj.value : null; ++ }; ++ ++ // if data are not grouped, we sort them by their value ++ if (isString(order) && order.toLowerCase() === 'asc') { ++ return function (a, b) { ++ return valueOf(a) - valueOf(b); ++ }; ++ } else if (isString(order) && order.toLowerCase() === 'desc') { ++ return function (a, b) { ++ return valueOf(b) - valueOf(a); ++ }; ++ } else if (isFunction(order)) { ++ ++ // if the function is from data_order we need ++ // to wrap the returned function in order to format ++ // the sorted value to the expected format ++ ++ var sortFunction = order; ++ ++ if (config.tooltip_order === undefined) { ++ sortFunction = function sortFunction(a, b) { ++ return order(a ? { ++ id: a.id, ++ values: [a] ++ } : null, b ? { ++ id: b.id, ++ values: [b] ++ } : null); ++ }; ++ } ++ ++ return sortFunction; ++ } else if (isArray(order)) { ++ return function (a, b) { ++ return order.indexOf(a.id) - order.indexOf(b.id); ++ }; ++ } ++ } else { ++ // if data are grouped, we follow the order of grouped targets ++ var ids = $$.orderTargets($$.data.targets).map(function (i) { ++ return i.id; ++ }); ++ ++ // if it was either asc or desc we need to invert the order ++ // returned by orderTargets ++ if ($$.isOrderAsc() || $$.isOrderDesc()) { ++ ids = ids.reverse(); ++ } ++ ++ return function (a, b) { ++ return ids.indexOf(a.id) - ids.indexOf(b.id); ++ }; ++ } ++ }; ++ ChartInternal.prototype.getTooltipContent = function (d, defaultTitleFormat, defaultValueFormat, color) { ++ var $$ = this, ++ config = $$.config, ++ titleFormat = config.tooltip_format_title || defaultTitleFormat, ++ nameFormat = config.tooltip_format_name || function (name) { ++ return name; ++ }, ++ valueFormat = config.tooltip_format_value || defaultValueFormat, ++ text, ++ i, ++ title, ++ value, ++ name, ++ bgcolor; ++ ++ var tooltipSortFunction = this.getTooltipSortFunction(); ++ if (tooltipSortFunction) { ++ d.sort(tooltipSortFunction); ++ } ++ ++ for (i = 0; i < d.length; i++) { ++ if (!(d[i] && (d[i].value || d[i].value === 0))) { ++ continue; ++ } ++ ++ if (!text) { ++ title = sanitise(titleFormat ? titleFormat(d[i].x) : d[i].x); ++ text = "" + (title || title === 0 ? "" : ""); ++ } ++ ++ value = sanitise(valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index, d)); ++ if (value !== undefined) { ++ // Skip elements when their name is set to null ++ if (d[i].name === null) { ++ continue; ++ } ++ name = sanitise(nameFormat(d[i].name, d[i].ratio, d[i].id, d[i].index)); ++ bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id); ++ ++ text += ""; ++ text += ""; ++ text += ""; ++ text += ""; ++ } ++ } ++ return text + "
" + title + "
" + name + "" + value + "
"; ++ }; ++ ChartInternal.prototype.tooltipPosition = function (dataToShow, tWidth, tHeight, element) { ++ var $$ = this, ++ config = $$.config, ++ d3 = $$.d3; ++ var svgLeft, tooltipLeft, tooltipRight, tooltipTop, chartRight; ++ var forArc = $$.hasArcType(), ++ mouse = d3.mouse(element); ++ // Determin tooltip position ++ if (forArc) { ++ tooltipLeft = ($$.width - ($$.isLegendRight ? $$.getLegendWidth() : 0)) / 2 + mouse[0]; ++ tooltipTop = ($$.hasType('gauge') ? $$.height : $$.height / 2) + mouse[1] + 20; ++ } else { ++ svgLeft = $$.getSvgLeft(true); ++ if (config.axis_rotated) { ++ tooltipLeft = svgLeft + mouse[0] + 100; ++ tooltipRight = tooltipLeft + tWidth; ++ chartRight = $$.currentWidth - $$.getCurrentPaddingRight(); ++ tooltipTop = $$.x(dataToShow[0].x) + 20; ++ } else { ++ tooltipLeft = svgLeft + $$.getCurrentPaddingLeft(true) + $$.x(dataToShow[0].x) + 20; ++ tooltipRight = tooltipLeft + tWidth; ++ chartRight = svgLeft + $$.currentWidth - $$.getCurrentPaddingRight(); ++ tooltipTop = mouse[1] + 15; ++ } ++ ++ if (tooltipRight > chartRight) { ++ // 20 is needed for Firefox to keep tooltip width ++ tooltipLeft -= tooltipRight - chartRight + 20; ++ } ++ if (tooltipTop + tHeight > $$.currentHeight) { ++ tooltipTop -= tHeight + 30; ++ } ++ } ++ if (tooltipTop < 0) { ++ tooltipTop = 0; ++ } ++ return { ++ top: tooltipTop, ++ left: tooltipLeft ++ }; ++ }; ++ ChartInternal.prototype.showTooltip = function (selectedData, element) { ++ var $$ = this, ++ config = $$.config; ++ var tWidth, tHeight, position; ++ var forArc = $$.hasArcType(), ++ dataToShow = selectedData.filter(function (d) { ++ return d && isValue(d.value); ++ }), ++ positionFunction = config.tooltip_position || ChartInternal.prototype.tooltipPosition; ++ if (dataToShow.length === 0 || !config.tooltip_show) { ++ return; ++ } ++ $$.tooltip.html(config.tooltip_contents.call($$, selectedData, $$.axis.getXAxisTickFormat(), $$.getYFormat(forArc), $$.color)).style("display", "block"); ++ ++ // Get tooltip dimensions ++ tWidth = $$.tooltip.property('offsetWidth'); ++ tHeight = $$.tooltip.property('offsetHeight'); ++ ++ position = positionFunction.call(this, dataToShow, tWidth, tHeight, element); ++ // Set tooltip ++ $$.tooltip.style("top", position.top + "px").style("left", position.left + 'px'); ++ }; ++ ChartInternal.prototype.hideTooltip = function () { ++ this.tooltip.style("display", "none"); ++ }; ++ ++ ChartInternal.prototype.setTargetType = function (targetIds, type) { ++ var $$ = this, ++ config = $$.config; ++ $$.mapToTargetIds(targetIds).forEach(function (id) { ++ $$.withoutFadeIn[id] = type === config.data_types[id]; ++ config.data_types[id] = type; ++ }); ++ if (!targetIds) { ++ config.data_type = type; ++ } ++ }; ++ ChartInternal.prototype.hasType = function (type, targets) { ++ var $$ = this, ++ types = $$.config.data_types, ++ has = false; ++ targets = targets || $$.data.targets; ++ if (targets && targets.length) { ++ targets.forEach(function (target) { ++ var t = types[target.id]; ++ if (t && t.indexOf(type) >= 0 || !t && type === 'line') { ++ has = true; ++ } ++ }); ++ } else if (Object.keys(types).length) { ++ Object.keys(types).forEach(function (id) { ++ if (types[id] === type) { ++ has = true; ++ } ++ }); ++ } else { ++ has = $$.config.data_type === type; ++ } ++ return has; ++ }; ++ ChartInternal.prototype.hasArcType = function (targets) { ++ return this.hasType('pie', targets) || this.hasType('donut', targets) || this.hasType('gauge', targets); ++ }; ++ ChartInternal.prototype.isLineType = function (d) { ++ var config = this.config, ++ id = isString(d) ? d : d.id; ++ return !config.data_types[id] || ['line', 'spline', 'area', 'area-spline', 'step', 'area-step'].indexOf(config.data_types[id]) >= 0; ++ }; ++ ChartInternal.prototype.isStepType = function (d) { ++ var id = isString(d) ? d : d.id; ++ return ['step', 'area-step'].indexOf(this.config.data_types[id]) >= 0; ++ }; ++ ChartInternal.prototype.isSplineType = function (d) { ++ var id = isString(d) ? d : d.id; ++ return ['spline', 'area-spline'].indexOf(this.config.data_types[id]) >= 0; ++ }; ++ ChartInternal.prototype.isAreaType = function (d) { ++ var id = isString(d) ? d : d.id; ++ return ['area', 'area-spline', 'area-step'].indexOf(this.config.data_types[id]) >= 0; ++ }; ++ ChartInternal.prototype.isBarType = function (d) { ++ var id = isString(d) ? d : d.id; ++ return this.config.data_types[id] === 'bar'; ++ }; ++ ChartInternal.prototype.isScatterType = function (d) { ++ var id = isString(d) ? d : d.id; ++ return this.config.data_types[id] === 'scatter'; ++ }; ++ ChartInternal.prototype.isPieType = function (d) { ++ var id = isString(d) ? d : d.id; ++ return this.config.data_types[id] === 'pie'; ++ }; ++ ChartInternal.prototype.isGaugeType = function (d) { ++ var id = isString(d) ? d : d.id; ++ return this.config.data_types[id] === 'gauge'; ++ }; ++ ChartInternal.prototype.isDonutType = function (d) { ++ var id = isString(d) ? d : d.id; ++ return this.config.data_types[id] === 'donut'; ++ }; ++ ChartInternal.prototype.isArcType = function (d) { ++ return this.isPieType(d) || this.isDonutType(d) || this.isGaugeType(d); ++ }; ++ ChartInternal.prototype.lineData = function (d) { ++ return this.isLineType(d) ? [d] : []; ++ }; ++ ChartInternal.prototype.arcData = function (d) { ++ return this.isArcType(d.data) ? [d] : []; ++ }; ++ /* not used ++ function scatterData(d) { ++ return isScatterType(d) ? d.values : []; ++ } ++ */ ++ ChartInternal.prototype.barData = function (d) { ++ return this.isBarType(d) ? d.values : []; ++ }; ++ ChartInternal.prototype.lineOrScatterData = function (d) { ++ return this.isLineType(d) || this.isScatterType(d) ? d.values : []; ++ }; ++ ChartInternal.prototype.barOrLineData = function (d) { ++ return this.isBarType(d) || this.isLineType(d) ? d.values : []; ++ }; ++ ++ ChartInternal.prototype.isSafari = function () { ++ var ua = window.navigator.userAgent; ++ return ua.indexOf('Safari') >= 0 && ua.indexOf('Chrome') < 0; ++ }; ++ ChartInternal.prototype.isChrome = function () { ++ var ua = window.navigator.userAgent; ++ return ua.indexOf('Chrome') >= 0; ++ }; ++ ++ ChartInternal.prototype.initZoom = function () { ++ var $$ = this, ++ d3 = $$.d3, ++ config = $$.config, ++ startEvent; ++ ++ $$.zoom = d3.zoom().on("start", function () { ++ var e = d3.event.sourceEvent; ++ if (e && e.type === "brush") { ++ return; ++ } ++ startEvent = e; ++ config.zoom_onzoomstart.call($$.api, e); ++ }).on("zoom", function () { ++ var e = d3.event.sourceEvent; ++ if (e && e.type === "brush") { ++ return; ++ } ++ $$.redrawForZoom.call($$); ++ }).on('end', function () { ++ var e = d3.event.sourceEvent; ++ if (e && e.type === "brush") { ++ return; ++ } ++ // if click, do nothing. otherwise, click interaction will be canceled. ++ if (e && startEvent.clientX === e.clientX && startEvent.clientY === e.clientY) { ++ return; ++ } ++ config.zoom_onzoomend.call($$.api, $$.x.orgDomain()); ++ }); ++ ++ $$.zoom.updateDomain = function () { ++ if (d3.event && d3.event.transform) { ++ $$.x.domain(d3.event.transform.rescaleX($$.subX).domain()); ++ } ++ return this; ++ }; ++ $$.zoom.updateExtent = function () { ++ this.scaleExtent([1, Infinity]).translateExtent([[0, 0], [$$.width, $$.height]]).extent([[0, 0], [$$.width, $$.height]]); ++ return this; ++ }; ++ $$.zoom.update = function () { ++ return this.updateExtent().updateDomain(); ++ }; ++ ++ return $$.zoom.updateExtent(); ++ }; ++ ChartInternal.prototype.zoomTransform = function (range) { ++ var $$ = this, ++ s = [$$.x(range[0]), $$.x(range[1])]; ++ return $$.d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0); ++ }; ++ ++ ChartInternal.prototype.getZoomDomain = function () { ++ var $$ = this, ++ config = $$.config, ++ d3 = $$.d3, ++ min = d3.min([$$.orgXDomain[0], config.zoom_x_min]), ++ max = d3.max([$$.orgXDomain[1], config.zoom_x_max]); ++ return [min, max]; ++ }; ++ ChartInternal.prototype.redrawForZoom = function () { ++ var $$ = this, ++ d3 = $$.d3, ++ config = $$.config, ++ zoom = $$.zoom, ++ x = $$.x; ++ if (!config.zoom_enabled) { ++ return; ++ } ++ if ($$.filterTargetsToShow($$.data.targets).length === 0) { ++ return; ++ } ++ ++ zoom.update(); ++ ++ if ($$.isCategorized() && x.orgDomain()[0] === $$.orgXDomain[0]) { ++ x.domain([$$.orgXDomain[0] - 1e-10, x.orgDomain()[1]]); ++ } ++ $$.redraw({ ++ withTransition: false, ++ withY: config.zoom_rescale, ++ withSubchart: false, ++ withEventRect: false, ++ withDimension: false ++ }); ++ if (d3.event.sourceEvent && d3.event.sourceEvent.type === 'mousemove') { ++ $$.cancelClick = true; ++ } ++ config.zoom_onzoom.call($$.api, x.orgDomain()); ++ }; ++ ++ return c3; ++ ++}))); diff --cc debian/missing-sources/d3.js index 0000000,0000000..e6e7e30 new file mode 100644 --- /dev/null +++ b/debian/missing-sources/d3.js @@@ -1,0 -1,0 +1,17847 @@@ ++// https://d3js.org Version 5.5.0. Copyright 2018 Mike Bostock. ++(function (global, factory) { ++ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : ++ typeof define === 'function' && define.amd ? define(['exports'], factory) : ++ (factory((global.d3 = global.d3 || {}))); ++}(this, (function (exports) { 'use strict'; ++ ++var version = "5.5.0"; ++ ++function ascending(a, b) { ++ return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; ++} ++ ++function bisector(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(f(d), x); ++ }; ++} ++ ++var ascendingBisect = bisector(ascending); ++var bisectRight = ascendingBisect.right; ++var bisectLeft = ascendingBisect.left; ++ ++function pairs(array, f) { ++ if (f == null) f = pair; ++ var i = 0, n = array.length - 1, p = array[0], pairs = new Array(n < 0 ? 0 : n); ++ while (i < n) pairs[i] = f(p, p = array[++i]); ++ return pairs; ++} ++ ++function pair(a, b) { ++ return [a, b]; ++} ++ ++function cross(values0, values1, reduce) { ++ var n0 = values0.length, ++ n1 = values1.length, ++ values = new Array(n0 * n1), ++ i0, ++ i1, ++ i, ++ value0; ++ ++ if (reduce == null) reduce = pair; ++ ++ for (i0 = i = 0; i0 < n0; ++i0) { ++ for (value0 = values0[i0], i1 = 0; i1 < n1; ++i1, ++i) { ++ values[i] = reduce(value0, values1[i1]); ++ } ++ } ++ ++ return values; ++} ++ ++function descending(a, b) { ++ return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; ++} ++ ++function number(x) { ++ return x === null ? NaN : +x; ++} ++ ++function variance(values, valueof) { ++ var n = values.length, ++ m = 0, ++ i = -1, ++ mean = 0, ++ value, ++ delta, ++ sum = 0; ++ ++ if (valueof == null) { ++ while (++i < n) { ++ if (!isNaN(value = number(values[i]))) { ++ delta = value - mean; ++ mean += delta / ++m; ++ sum += delta * (value - mean); ++ } ++ } ++ } ++ ++ else { ++ while (++i < n) { ++ if (!isNaN(value = number(valueof(values[i], i, values)))) { ++ delta = value - mean; ++ mean += delta / ++m; ++ sum += delta * (value - mean); ++ } ++ } ++ } ++ ++ if (m > 1) return sum / (m - 1); ++} ++ ++function deviation(array, f) { ++ var v = variance(array, f); ++ return v ? Math.sqrt(v) : v; ++} ++ ++function extent(values, valueof) { ++ var n = values.length, ++ i = -1, ++ value, ++ min, ++ max; ++ ++ if (valueof == null) { ++ while (++i < n) { // Find the first comparable value. ++ if ((value = values[i]) != null && value >= value) { ++ min = max = value; ++ while (++i < n) { // Compare the remaining values. ++ if ((value = values[i]) != null) { ++ if (min > value) min = value; ++ if (max < value) max = value; ++ } ++ } ++ } ++ } ++ } ++ ++ else { ++ while (++i < n) { // Find the first comparable value. ++ if ((value = valueof(values[i], i, values)) != null && value >= value) { ++ min = max = value; ++ while (++i < n) { // Compare the remaining values. ++ if ((value = valueof(values[i], i, values)) != null) { ++ if (min > value) min = value; ++ if (max < value) max = value; ++ } ++ } ++ } ++ } ++ } ++ ++ return [min, max]; ++} ++ ++var array = Array.prototype; ++ ++var slice = array.slice; ++var map = array.map; ++ ++function constant(x) { ++ return function() { ++ return x; ++ }; ++} ++ ++function identity(x) { ++ return x; ++} ++ ++function sequence(start, stop, step) { ++ start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step; ++ ++ var i = -1, ++ n = Math.max(0, Math.ceil((stop - start) / step)) | 0, ++ range = new Array(n); ++ ++ while (++i < n) { ++ range[i] = start + i * step; ++ } ++ ++ return range; ++} ++ ++var e10 = Math.sqrt(50), ++ e5 = Math.sqrt(10), ++ e2 = Math.sqrt(2); ++ ++function ticks(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; ++} ++ ++function thresholdSturges(values) { ++ return Math.ceil(Math.log(values.length) / Math.LN2) + 1; ++} ++ ++function histogram() { ++ var value = identity, ++ domain = extent, ++ threshold = thresholdSturges; ++ ++ function histogram(data) { ++ var i, ++ n = data.length, ++ x, ++ values = new Array(n); ++ ++ for (i = 0; i < n; ++i) { ++ values[i] = value(data[i], i, data); ++ } ++ ++ var xz = domain(values), ++ x0 = xz[0], ++ x1 = xz[1], ++ tz = threshold(values, x0, x1); ++ ++ // Convert number of thresholds into uniform thresholds. ++ if (!Array.isArray(tz)) { ++ tz = tickStep(x0, x1, tz); ++ tz = sequence(Math.ceil(x0 / tz) * tz, Math.floor(x1 / tz) * tz, tz); // exclusive ++ } ++ ++ // Remove any thresholds outside the domain. ++ var m = tz.length; ++ while (tz[0] <= x0) tz.shift(), --m; ++ while (tz[m - 1] > x1) tz.pop(), --m; ++ ++ var bins = new Array(m + 1), ++ bin; ++ ++ // Initialize bins. ++ for (i = 0; i <= m; ++i) { ++ bin = bins[i] = []; ++ bin.x0 = i > 0 ? tz[i - 1] : x0; ++ bin.x1 = i < m ? tz[i] : x1; ++ } ++ ++ // Assign data to bins by value, ignoring any outside the domain. ++ for (i = 0; i < n; ++i) { ++ x = values[i]; ++ if (x0 <= x && x <= x1) { ++ bins[bisectRight(tz, x, 0, m)].push(data[i]); ++ } ++ } ++ ++ return bins; ++ } ++ ++ histogram.value = function(_) { ++ return arguments.length ? (value = typeof _ === "function" ? _ : constant(_), histogram) : value; ++ }; ++ ++ histogram.domain = function(_) { ++ return arguments.length ? (domain = typeof _ === "function" ? _ : constant([_[0], _[1]]), histogram) : domain; ++ }; ++ ++ histogram.thresholds = function(_) { ++ return arguments.length ? (threshold = typeof _ === "function" ? _ : Array.isArray(_) ? constant(slice.call(_)) : constant(_), histogram) : threshold; ++ }; ++ ++ return histogram; ++} ++ ++function threshold(values, p, valueof) { ++ if (valueof == null) valueof = number; ++ if (!(n = values.length)) return; ++ if ((p = +p) <= 0 || n < 2) return +valueof(values[0], 0, values); ++ if (p >= 1) return +valueof(values[n - 1], n - 1, values); ++ var n, ++ i = (n - 1) * p, ++ i0 = Math.floor(i), ++ value0 = +valueof(values[i0], i0, values), ++ value1 = +valueof(values[i0 + 1], i0 + 1, values); ++ return value0 + (value1 - value0) * (i - i0); ++} ++ ++function freedmanDiaconis(values, min, max) { ++ values = map.call(values, number).sort(ascending); ++ return Math.ceil((max - min) / (2 * (threshold(values, 0.75) - threshold(values, 0.25)) * Math.pow(values.length, -1 / 3))); ++} ++ ++function scott(values, min, max) { ++ return Math.ceil((max - min) / (3.5 * deviation(values) * Math.pow(values.length, -1 / 3))); ++} ++ ++function max(values, valueof) { ++ var n = values.length, ++ i = -1, ++ value, ++ max; ++ ++ if (valueof == null) { ++ while (++i < n) { // Find the first comparable value. ++ if ((value = values[i]) != null && value >= value) { ++ max = value; ++ while (++i < n) { // Compare the remaining values. ++ if ((value = values[i]) != null && value > max) { ++ max = value; ++ } ++ } ++ } ++ } ++ } ++ ++ else { ++ while (++i < n) { // Find the first comparable value. ++ if ((value = valueof(values[i], i, values)) != null && value >= value) { ++ max = value; ++ while (++i < n) { // Compare the remaining values. ++ if ((value = valueof(values[i], i, values)) != null && value > max) { ++ max = value; ++ } ++ } ++ } ++ } ++ } ++ ++ return max; ++} ++ ++function mean(values, valueof) { ++ var n = values.length, ++ m = n, ++ i = -1, ++ value, ++ sum = 0; ++ ++ if (valueof == null) { ++ while (++i < n) { ++ if (!isNaN(value = number(values[i]))) sum += value; ++ else --m; ++ } ++ } ++ ++ else { ++ while (++i < n) { ++ if (!isNaN(value = number(valueof(values[i], i, values)))) sum += value; ++ else --m; ++ } ++ } ++ ++ if (m) return sum / m; ++} ++ ++function median(values, valueof) { ++ var n = values.length, ++ i = -1, ++ value, ++ numbers = []; ++ ++ if (valueof == null) { ++ while (++i < n) { ++ if (!isNaN(value = number(values[i]))) { ++ numbers.push(value); ++ } ++ } ++ } ++ ++ else { ++ while (++i < n) { ++ if (!isNaN(value = number(valueof(values[i], i, values)))) { ++ numbers.push(value); ++ } ++ } ++ } ++ ++ return threshold(numbers.sort(ascending), 0.5); ++} ++ ++function merge(arrays) { ++ var n = arrays.length, ++ m, ++ i = -1, ++ j = 0, ++ merged, ++ array; ++ ++ while (++i < n) j += arrays[i].length; ++ merged = new Array(j); ++ ++ while (--n >= 0) { ++ array = arrays[n]; ++ m = array.length; ++ while (--m >= 0) { ++ merged[--j] = array[m]; ++ } ++ } ++ ++ return merged; ++} ++ ++function min(values, valueof) { ++ var n = values.length, ++ i = -1, ++ value, ++ min; ++ ++ if (valueof == null) { ++ while (++i < n) { // Find the first comparable value. ++ if ((value = values[i]) != null && value >= value) { ++ min = value; ++ while (++i < n) { // Compare the remaining values. ++ if ((value = values[i]) != null && min > value) { ++ min = value; ++ } ++ } ++ } ++ } ++ } ++ ++ else { ++ while (++i < n) { // Find the first comparable value. ++ if ((value = valueof(values[i], i, values)) != null && value >= value) { ++ min = value; ++ while (++i < n) { // Compare the remaining values. ++ if ((value = valueof(values[i], i, values)) != null && min > value) { ++ min = value; ++ } ++ } ++ } ++ } ++ } ++ ++ return min; ++} ++ ++function permute(array, indexes) { ++ var i = indexes.length, permutes = new Array(i); ++ while (i--) permutes[i] = array[indexes[i]]; ++ return permutes; ++} ++ ++function scan(values, compare) { ++ if (!(n = values.length)) return; ++ var n, ++ i = 0, ++ j = 0, ++ xi, ++ xj = values[j]; ++ ++ if (compare == null) compare = ascending; ++ ++ while (++i < n) { ++ if (compare(xi = values[i], xj) < 0 || compare(xj, xj) !== 0) { ++ xj = xi, j = i; ++ } ++ } ++ ++ if (compare(xj, xj) === 0) return j; ++} ++ ++function shuffle(array, i0, i1) { ++ var m = (i1 == null ? array.length : i1) - (i0 = i0 == null ? 0 : +i0), ++ t, ++ i; ++ ++ while (m) { ++ i = Math.random() * m-- | 0; ++ t = array[m + i0]; ++ array[m + i0] = array[i + i0]; ++ array[i + i0] = t; ++ } ++ ++ return array; ++} ++ ++function sum(values, valueof) { ++ var n = values.length, ++ i = -1, ++ value, ++ sum = 0; ++ ++ if (valueof == null) { ++ while (++i < n) { ++ if (value = +values[i]) sum += value; // Note: zero and null are equivalent. ++ } ++ } ++ ++ else { ++ while (++i < n) { ++ if (value = +valueof(values[i], i, values)) sum += value; ++ } ++ } ++ ++ return sum; ++} ++ ++function transpose(matrix) { ++ if (!(n = matrix.length)) return []; ++ for (var i = -1, m = min(matrix, length), transpose = new Array(m); ++i < m;) { ++ for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n;) { ++ row[j] = matrix[j][i]; ++ } ++ } ++ return transpose; ++} ++ ++function length(d) { ++ return d.length; ++} ++ ++function zip() { ++ return transpose(arguments); ++} ++ ++var slice$1 = Array.prototype.slice; ++ ++function identity$1(x) { ++ return x; ++} ++ ++var top = 1, ++ right = 2, ++ bottom = 3, ++ left = 4, ++ epsilon = 1e-6; ++ ++function translateX(x) { ++ return "translate(" + (x + 0.5) + ",0)"; ++} ++ ++function translateY(y) { ++ return "translate(0," + (y + 0.5) + ")"; ++} ++ ++function number$1(scale) { ++ return function(d) { ++ return +scale(d); ++ }; ++} ++ ++function center(scale) { ++ var offset = Math.max(0, scale.bandwidth() - 1) / 2; // Adjust for 0.5px offset. ++ if (scale.round()) offset = Math.round(offset); ++ return function(d) { ++ return +scale(d) + offset; ++ }; ++} ++ ++function entering() { ++ return !this.__axis; ++} ++ ++function axis(orient, scale) { ++ var tickArguments = [], ++ tickValues = null, ++ tickFormat = null, ++ tickSizeInner = 6, ++ tickSizeOuter = 6, ++ tickPadding = 3, ++ k = orient === top || orient === left ? -1 : 1, ++ x = orient === left || orient === right ? "x" : "y", ++ transform = orient === top || orient === bottom ? translateX : translateY; ++ ++ function axis(context) { ++ var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues, ++ format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity$1) : tickFormat, ++ spacing = Math.max(tickSizeInner, 0) + tickPadding, ++ range = scale.range(), ++ range0 = +range[0] + 0.5, ++ range1 = +range[range.length - 1] + 0.5, ++ position = (scale.bandwidth ? center : number$1)(scale.copy()), ++ selection = context.selection ? context.selection() : context, ++ path = selection.selectAll(".domain").data([null]), ++ tick = selection.selectAll(".tick").data(values, scale).order(), ++ tickExit = tick.exit(), ++ tickEnter = tick.enter().append("g").attr("class", "tick"), ++ line = tick.select("line"), ++ text = tick.select("text"); ++ ++ path = path.merge(path.enter().insert("path", ".tick") ++ .attr("class", "domain") ++ .attr("stroke", "#000")); ++ ++ tick = tick.merge(tickEnter); ++ ++ line = line.merge(tickEnter.append("line") ++ .attr("stroke", "#000") ++ .attr(x + "2", k * tickSizeInner)); ++ ++ text = text.merge(tickEnter.append("text") ++ .attr("fill", "#000") ++ .attr(x, k * spacing) ++ .attr("dy", orient === top ? "0em" : orient === bottom ? "0.71em" : "0.32em")); ++ ++ if (context !== selection) { ++ path = path.transition(context); ++ tick = tick.transition(context); ++ line = line.transition(context); ++ text = text.transition(context); ++ ++ tickExit = tickExit.transition(context) ++ .attr("opacity", epsilon) ++ .attr("transform", function(d) { return isFinite(d = position(d)) ? transform(d) : this.getAttribute("transform"); }); ++ ++ tickEnter ++ .attr("opacity", epsilon) ++ .attr("transform", function(d) { var p = this.parentNode.__axis; return transform(p && isFinite(p = p(d)) ? p : position(d)); }); ++ } ++ ++ tickExit.remove(); ++ ++ path ++ .attr("d", orient === left || orient == right ++ ? "M" + k * tickSizeOuter + "," + range0 + "H0.5V" + range1 + "H" + k * tickSizeOuter ++ : "M" + range0 + "," + k * tickSizeOuter + "V0.5H" + range1 + "V" + k * tickSizeOuter); ++ ++ tick ++ .attr("opacity", 1) ++ .attr("transform", function(d) { return transform(position(d)); }); ++ ++ line ++ .attr(x + "2", k * tickSizeInner); ++ ++ text ++ .attr(x, k * spacing) ++ .text(format); ++ ++ selection.filter(entering) ++ .attr("fill", "none") ++ .attr("font-size", 10) ++ .attr("font-family", "sans-serif") ++ .attr("text-anchor", orient === right ? "start" : orient === left ? "end" : "middle"); ++ ++ selection ++ .each(function() { this.__axis = position; }); ++ } ++ ++ axis.scale = function(_) { ++ return arguments.length ? (scale = _, axis) : scale; ++ }; ++ ++ axis.ticks = function() { ++ return tickArguments = slice$1.call(arguments), axis; ++ }; ++ ++ axis.tickArguments = function(_) { ++ return arguments.length ? (tickArguments = _ == null ? [] : slice$1.call(_), axis) : tickArguments.slice(); ++ }; ++ ++ axis.tickValues = function(_) { ++ return arguments.length ? (tickValues = _ == null ? null : slice$1.call(_), axis) : tickValues && tickValues.slice(); ++ }; ++ ++ axis.tickFormat = function(_) { ++ return arguments.length ? (tickFormat = _, axis) : tickFormat; ++ }; ++ ++ axis.tickSize = function(_) { ++ return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner; ++ }; ++ ++ axis.tickSizeInner = function(_) { ++ return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner; ++ }; ++ ++ axis.tickSizeOuter = function(_) { ++ return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter; ++ }; ++ ++ axis.tickPadding = function(_) { ++ return arguments.length ? (tickPadding = +_, axis) : tickPadding; ++ }; ++ ++ return axis; ++} ++ ++function axisTop(scale) { ++ return axis(top, scale); ++} ++ ++function axisRight(scale) { ++ return axis(right, scale); ++} ++ ++function axisBottom(scale) { ++ return axis(bottom, scale); ++} ++ ++function axisLeft(scale) { ++ return axis(left, scale); ++} ++ ++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(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(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(_[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(_[t], typename.name, callback); ++ else if (callback == null) for (t in _) _[t] = set(_[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(type, name) { ++ for (var i = 0, n = type.length, c; i < n; ++i) { ++ if ((c = type[i]).name === name) { ++ return c.value; ++ } ++ } ++} ++ ++function set(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 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/" ++}; ++ ++function namespace(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); ++ }; ++} ++ ++function creator(name) { ++ var fullname = namespace(name); ++ return (fullname.local ++ ? creatorFixed ++ : creatorInherit)(fullname); ++} ++ ++function none() {} ++ ++function selector(selector) { ++ return selector == null ? none : function() { ++ return this.querySelector(selector); ++ }; ++} ++ ++function selection_select(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 []; ++} ++ ++function selectorAll(selector) { ++ return selector == null ? empty : function() { ++ return this.querySelectorAll(selector); ++ }; ++} ++ ++function selection_selectAll(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 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; ++ ++function selection_filter(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); ++} ++ ++function sparse(update) { ++ return new Array(update.length); ++} ++ ++function selection_enter() { ++ 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); } ++}; ++ ++function constant$1(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; ++ } ++ } ++} ++ ++function selection_data(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$1(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; ++} ++ ++function selection_exit() { ++ return new Selection(this._exit || this._groups.map(sparse), this._parents); ++} ++ ++function selection_merge(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); ++} ++ ++function selection_order() { ++ ++ 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; ++} ++ ++function selection_sort(compare) { ++ if (!compare) compare = ascending$1; ++ ++ 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$1(a, b) { ++ return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; ++} ++ ++function selection_call() { ++ var callback = arguments[0]; ++ arguments[0] = this; ++ callback.apply(null, arguments); ++ return this; ++} ++ ++function selection_nodes() { ++ var nodes = new Array(this.size()), i = -1; ++ this.each(function() { nodes[++i] = this; }); ++ return nodes; ++} ++ ++function selection_node() { ++ ++ 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; ++} ++ ++function selection_size() { ++ var size = 0; ++ this.each(function() { ++size; }); ++ return size; ++} ++ ++function selection_empty() { ++ return !this.node(); ++} ++ ++function selection_each(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); ++ }; ++} ++ ++function selection_attr(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)); ++} ++ ++function defaultView(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); ++ }; ++} ++ ++function selection_style(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; ++ }; ++} ++ ++function selection_property(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); ++ }; ++} ++ ++function selection_classed(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; ++ }; ++} ++ ++function selection_text(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; ++ }; ++} ++ ++function selection_html(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); ++} ++ ++function selection_raise() { ++ return this.each(raise); ++} ++ ++function lower() { ++ if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild); ++} ++ ++function selection_lower() { ++ return this.each(lower); ++} ++ ++function selection_append(name) { ++ var create = typeof name === "function" ? name : creator(name); ++ return this.select(function() { ++ return this.appendChild(create.apply(this, arguments)); ++ }); ++} ++ ++function constantNull() { ++ return null; ++} ++ ++function selection_insert(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); ++} ++ ++function selection_remove() { ++ return this.each(remove); ++} ++ ++function selection_cloneShallow() { ++ return this.parentNode.insertBefore(this.cloneNode(false), this.nextSibling); ++} ++ ++function selection_cloneDeep() { ++ return this.parentNode.insertBefore(this.cloneNode(true), this.nextSibling); ++} ++ ++function selection_clone(deep) { ++ return this.select(deep ? selection_cloneDeep : selection_cloneShallow); ++} ++ ++function selection_datum(value) { ++ return arguments.length ++ ? this.property("__data__", value) ++ : this.node().__data__; ++} ++ ++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$1(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); ++ }; ++} ++ ++function selection_on(typename, value, capture) { ++ var typenames = parseTypenames$1(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 customEvent(event1, listener, that, args) { ++ var event0 = exports.event; ++ event1.sourceEvent = exports.event; ++ exports.event = event1; ++ try { ++ return listener.apply(that, args); ++ } finally { ++ exports.event = event0; ++ } ++} ++ ++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)); ++ }; ++} ++ ++function selection_dispatch(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, ++ clone: selection_clone, ++ datum: selection_datum, ++ on: selection_on, ++ dispatch: selection_dispatch ++}; ++ ++function select(selector) { ++ return typeof selector === "string" ++ ? new Selection([[document.querySelector(selector)]], [document.documentElement]) ++ : new Selection([[selector]], root); ++} ++ ++function create(name) { ++ return select(creator(name).call(document.documentElement)); ++} ++ ++var nextId = 0; ++ ++function local() { ++ return new Local; ++} ++ ++function Local() { ++ this._ = "@" + (++nextId).toString(36); ++} ++ ++Local.prototype = local.prototype = { ++ constructor: Local, ++ get: function(node) { ++ var id = this._; ++ while (!(id in node)) if (!(node = node.parentNode)) return; ++ return node[id]; ++ }, ++ set: function(node, value) { ++ return node[this._] = value; ++ }, ++ remove: function(node) { ++ return this._ in node && delete node[this._]; ++ }, ++ toString: function() { ++ return this._; ++ } ++}; ++ ++function sourceEvent() { ++ var current = exports.event, source; ++ while (source = current.sourceEvent) current = source; ++ return current; ++} ++ ++function point(node, event) { ++ var svg = node.ownerSVGElement || node; ++ ++ if (svg.createSVGPoint) { ++ var point = svg.createSVGPoint(); ++ point.x = event.clientX, point.y = event.clientY; ++ point = point.matrixTransform(node.getScreenCTM().inverse()); ++ return [point.x, point.y]; ++ } ++ ++ var rect = node.getBoundingClientRect(); ++ return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop]; ++} ++ ++function mouse(node) { ++ var event = sourceEvent(); ++ if (event.changedTouches) event = event.changedTouches[0]; ++ return point(node, event); ++} ++ ++function selectAll(selector) { ++ return typeof selector === "string" ++ ? new Selection([document.querySelectorAll(selector)], [document.documentElement]) ++ : new Selection([selector == null ? [] : selector], root); ++} ++ ++function touch(node, touches, identifier) { ++ if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches; ++ ++ for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) { ++ if ((touch = touches[i]).identifier === identifier) { ++ return point(node, touch); ++ } ++ } ++ ++ return null; ++} ++ ++function touches(node, touches) { ++ if (touches == null) touches = sourceEvent().touches; ++ ++ for (var i = 0, n = touches ? touches.length : 0, points = new Array(n); i < n; ++i) { ++ points[i] = point(node, touches[i]); ++ } ++ ++ return points; ++} ++ ++function nopropagation() { ++ exports.event.stopImmediatePropagation(); ++} ++ ++function noevent() { ++ exports.event.preventDefault(); ++ exports.event.stopImmediatePropagation(); ++} ++ ++function dragDisable(view) { ++ var root = view.document.documentElement, ++ selection$$1 = select(view).on("dragstart.drag", noevent, true); ++ if ("onselectstart" in root) { ++ selection$$1.on("selectstart.drag", noevent, true); ++ } else { ++ root.__noselect = root.style.MozUserSelect; ++ root.style.MozUserSelect = "none"; ++ } ++} ++ ++function yesdrag(view, noclick) { ++ var root = view.document.documentElement, ++ selection$$1 = select(view).on("dragstart.drag", null); ++ if (noclick) { ++ selection$$1.on("click.drag", noevent, true); ++ setTimeout(function() { selection$$1.on("click.drag", null); }, 0); ++ } ++ if ("onselectstart" in root) { ++ selection$$1.on("selectstart.drag", null); ++ } else { ++ root.style.MozUserSelect = root.__noselect; ++ delete root.__noselect; ++ } ++} ++ ++function constant$2(x) { ++ return function() { ++ return x; ++ }; ++} ++ ++function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch) { ++ this.target = target; ++ this.type = type; ++ this.subject = subject; ++ this.identifier = id; ++ this.active = active; ++ this.x = x; ++ this.y = y; ++ this.dx = dx; ++ this.dy = dy; ++ this._ = dispatch; ++} ++ ++DragEvent.prototype.on = function() { ++ var value = this._.on.apply(this._, arguments); ++ return value === this._ ? this : value; ++}; ++ ++// Ignore right-click, since that should open the context menu. ++function defaultFilter() { ++ return !exports.event.button; ++} ++ ++function defaultContainer() { ++ return this.parentNode; ++} ++ ++function defaultSubject(d) { ++ return d == null ? {x: exports.event.x, y: exports.event.y} : d; ++} ++ ++function defaultTouchable() { ++ return "ontouchstart" in this; ++} ++ ++function drag() { ++ var filter = defaultFilter, ++ container = defaultContainer, ++ subject = defaultSubject, ++ touchable = defaultTouchable, ++ gestures = {}, ++ listeners = dispatch("start", "drag", "end"), ++ active = 0, ++ mousedownx, ++ mousedowny, ++ mousemoving, ++ touchending, ++ clickDistance2 = 0; ++ ++ function drag(selection$$1) { ++ selection$$1 ++ .on("mousedown.drag", mousedowned) ++ .filter(touchable) ++ .on("touchstart.drag", touchstarted) ++ .on("touchmove.drag", touchmoved) ++ .on("touchend.drag touchcancel.drag", touchended) ++ .style("touch-action", "none") ++ .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)"); ++ } ++ ++ function mousedowned() { ++ if (touchending || !filter.apply(this, arguments)) return; ++ var gesture = beforestart("mouse", container.apply(this, arguments), mouse, this, arguments); ++ if (!gesture) return; ++ select(exports.event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true); ++ dragDisable(exports.event.view); ++ nopropagation(); ++ mousemoving = false; ++ mousedownx = exports.event.clientX; ++ mousedowny = exports.event.clientY; ++ gesture("start"); ++ } ++ ++ function mousemoved() { ++ noevent(); ++ if (!mousemoving) { ++ var dx = exports.event.clientX - mousedownx, dy = exports.event.clientY - mousedowny; ++ mousemoving = dx * dx + dy * dy > clickDistance2; ++ } ++ gestures.mouse("drag"); ++ } ++ ++ function mouseupped() { ++ select(exports.event.view).on("mousemove.drag mouseup.drag", null); ++ yesdrag(exports.event.view, mousemoving); ++ noevent(); ++ gestures.mouse("end"); ++ } ++ ++ function touchstarted() { ++ if (!filter.apply(this, arguments)) return; ++ var touches$$1 = exports.event.changedTouches, ++ c = container.apply(this, arguments), ++ n = touches$$1.length, i, gesture; ++ ++ for (i = 0; i < n; ++i) { ++ if (gesture = beforestart(touches$$1[i].identifier, c, touch, this, arguments)) { ++ nopropagation(); ++ gesture("start"); ++ } ++ } ++ } ++ ++ function touchmoved() { ++ var touches$$1 = exports.event.changedTouches, ++ n = touches$$1.length, i, gesture; ++ ++ for (i = 0; i < n; ++i) { ++ if (gesture = gestures[touches$$1[i].identifier]) { ++ noevent(); ++ gesture("drag"); ++ } ++ } ++ } ++ ++ function touchended() { ++ var touches$$1 = exports.event.changedTouches, ++ n = touches$$1.length, i, gesture; ++ ++ if (touchending) clearTimeout(touchending); ++ touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed! ++ for (i = 0; i < n; ++i) { ++ if (gesture = gestures[touches$$1[i].identifier]) { ++ nopropagation(); ++ gesture("end"); ++ } ++ } ++ } ++ ++ function beforestart(id, container, point$$1, that, args) { ++ var p = point$$1(container, id), s, dx, dy, ++ sublisteners = listeners.copy(); ++ ++ if (!customEvent(new DragEvent(drag, "beforestart", s, id, active, p[0], p[1], 0, 0, sublisteners), function() { ++ if ((exports.event.subject = s = subject.apply(that, args)) == null) return false; ++ dx = s.x - p[0] || 0; ++ dy = s.y - p[1] || 0; ++ return true; ++ })) return; ++ ++ return function gesture(type) { ++ var p0 = p, n; ++ switch (type) { ++ case "start": gestures[id] = gesture, n = active++; break; ++ case "end": delete gestures[id], --active; // nobreak ++ case "drag": p = point$$1(container, id), n = active; break; ++ } ++ customEvent(new DragEvent(drag, type, s, id, n, p[0] + dx, p[1] + dy, p[0] - p0[0], p[1] - p0[1], sublisteners), sublisteners.apply, sublisteners, [type, that, args]); ++ }; ++ } ++ ++ drag.filter = function(_) { ++ return arguments.length ? (filter = typeof _ === "function" ? _ : constant$2(!!_), drag) : filter; ++ }; ++ ++ drag.container = function(_) { ++ return arguments.length ? (container = typeof _ === "function" ? _ : constant$2(_), drag) : container; ++ }; ++ ++ drag.subject = function(_) { ++ return arguments.length ? (subject = typeof _ === "function" ? _ : constant$2(_), drag) : subject; ++ }; ++ ++ drag.touchable = function(_) { ++ return arguments.length ? (touchable = typeof _ === "function" ? _ : constant$2(!!_), drag) : touchable; ++ }; ++ ++ drag.on = function() { ++ var value = listeners.on.apply(listeners, arguments); ++ return value === listeners ? drag : value; ++ }; ++ ++ drag.clickDistance = function(_) { ++ return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2); ++ }; ++ ++ return drag; ++} ++ ++function define(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*", ++ reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*", ++ reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*", ++ reHex3 = /^#([0-9a-f]{3})$/, ++ reHex6 = /^#([0-9a-f]{6})$/, ++ reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"), ++ reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"), ++ reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"), ++ reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"), ++ reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"), ++ 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(); ++ }, ++ hex: function() { ++ return this.rgb().hex(); ++ }, ++ 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); ++ }, ++ hex: function() { ++ return "#" + hex(this.r) + hex(this.g) + hex(this.b); ++ }, ++ 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 hex(value) { ++ value = Math.max(0, Math.min(255, Math.round(value) || 0)); ++ return (value < 16 ? "0" : "") + value.toString(16); ++} ++ ++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; ++ ++// https://beta.observablehq.com/@mbostock/lab-and-rgb ++var K = 18, ++ Xn = 0.96422, ++ Yn = 1, ++ Zn = 0.82521, ++ t0 = 4 / 29, ++ t1 = 6 / 29, ++ t2 = 3 * t1 * t1, ++ 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) { ++ if (isNaN(o.h)) return new Lab(o.l, 0, 0, o.opacity); ++ 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 r = rgb2lrgb(o.r), ++ g = rgb2lrgb(o.g), ++ b = rgb2lrgb(o.b), ++ y = xyz2lab((0.2225045 * r + 0.7168786 * g + 0.0606169 * b) / Yn), x, z; ++ if (r === g && g === b) x = z = y; else { ++ x = xyz2lab((0.4360747 * r + 0.3850649 * g + 0.1430804 * b) / Xn); ++ z = xyz2lab((0.0139322 * r + 0.0971045 * g + 0.7141733 * b) / Zn); ++ } ++ return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity); ++} ++ ++function gray(l, opacity) { ++ return new Lab(l, 0, 0, opacity == null ? 1 : 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 + K * (k == null ? 1 : k), this.a, this.b, this.opacity); ++ }, ++ darker: function(k) { ++ return new Lab(this.l - K * (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; ++ x = Xn * lab2xyz(x); ++ y = Yn * lab2xyz(y); ++ z = Zn * lab2xyz(z); ++ return new Rgb( ++ lrgb2rgb( 3.1338561 * x - 1.6168667 * y - 0.4906146 * z), ++ lrgb2rgb(-0.9787684 * x + 1.9161415 * y + 0.0334540 * z), ++ lrgb2rgb( 0.0719453 * x - 0.2289914 * y + 1.4052427 * 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 lrgb2rgb(x) { ++ return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055); ++} ++ ++function rgb2lrgb(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); ++ if (o.a === 0 && o.b === 0) return new Hcl(NaN, 0, o.l, o.opacity); ++ 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 lch(l, c, h, opacity) { ++ return arguments.length === 1 ? hclConvert(l) : new Hcl(h, c, l, opacity == null ? 1 : 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 + K * (k == null ? 1 : k), this.opacity); ++ }, ++ darker: function(k) { ++ return new Hcl(this.h, this.c, this.l - K * (k == null ? 1 : k), this.opacity); ++ }, ++ rgb: function() { ++ return labConvert(this).rgb(); ++ } ++})); ++ ++var A = -0.14861, ++ B = +1.78277, ++ C = -0.29227, ++ D = -0.90649, ++ E = +1.97294, ++ ED = E * D, ++ EB = E * B, ++ 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 ++ ); ++ } ++})); ++ ++function basis(t1, v0, v1, v2, v3) { ++ var t2 = t1 * t1, t3 = t2 * t1; ++ return ((1 - 3 * t1 + 3 * t2 - t3) * v0 ++ + (4 - 6 * t2 + 3 * t3) * v1 ++ + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2 ++ + t3 * v3) / 6; ++} ++ ++function basis$1(values) { ++ var n = values.length - 1; ++ return function(t) { ++ var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n), ++ v1 = values[i], ++ v2 = values[i + 1], ++ v0 = i > 0 ? values[i - 1] : 2 * v1 - v2, ++ v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1; ++ return basis((t - i / n) * n, v0, v1, v2, v3); ++ }; ++} ++ ++function basisClosed(values) { ++ var n = values.length; ++ return function(t) { ++ var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n), ++ v0 = values[(i + n - 1) % n], ++ v1 = values[i % n], ++ v2 = values[(i + 1) % n], ++ v3 = values[(i + 2) % n]; ++ return basis((t - i / n) * n, v0, v1, v2, v3); ++ }; ++} ++ ++function constant$3(x) { ++ return function() { ++ return x; ++ }; ++} ++ ++function linear(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(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(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); ++ ++function rgbSpline(spline) { ++ return function(colors) { ++ var n = colors.length, ++ r = new Array(n), ++ g = new Array(n), ++ b = new Array(n), ++ i, color$$1; ++ for (i = 0; i < n; ++i) { ++ color$$1 = rgb(colors[i]); ++ r[i] = color$$1.r || 0; ++ g[i] = color$$1.g || 0; ++ b[i] = color$$1.b || 0; ++ } ++ r = spline(r); ++ g = spline(g); ++ b = spline(b); ++ color$$1.opacity = 1; ++ return function(t) { ++ color$$1.r = r(t); ++ color$$1.g = g(t); ++ color$$1.b = b(t); ++ return color$$1 + ""; ++ }; ++ }; ++} ++ ++var rgbBasis = rgbSpline(basis$1); ++var rgbBasisClosed = rgbSpline(basisClosed); ++ ++function array$1(a, b) { ++ var nb = b ? b.length : 0, ++ na = a ? Math.min(nb, a.length) : 0, ++ x = new Array(na), ++ 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; ++ }; ++} ++ ++function date(a, b) { ++ var d = new Date; ++ return a = +a, b -= a, function(t) { ++ return d.setTime(a + b * t), d; ++ }; ++} ++ ++function reinterpolate(a, b) { ++ return a = +a, b -= a, function(t) { ++ return a + b * t; ++ }; ++} ++ ++function object(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, ++ reB = new RegExp(reA.source, "g"); ++ ++function zero(b) { ++ return function() { ++ return b; ++ }; ++} ++ ++function one(b) { ++ return function(t) { ++ return b(t) + ""; ++ }; ++} ++ ++function interpolateString(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: reinterpolate(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(""); ++ }); ++} ++ ++function interpolateValue(a, b) { ++ var t = typeof b, c; ++ return b == null || t === "boolean" ? constant$3(b) ++ : (t === "number" ? reinterpolate ++ : t === "string" ? ((c = color(b)) ? (b = c, interpolateRgb) : interpolateString) ++ : b instanceof color ? interpolateRgb ++ : b instanceof Date ? date ++ : Array.isArray(b) ? array$1 ++ : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object ++ : reinterpolate)(a, b); ++} ++ ++function interpolateRound(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 ++}; ++ ++function decompose(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, ++ cssRoot, ++ cssView, ++ 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: reinterpolate(xa, xb)}, {i: i - 2, x: reinterpolate(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: reinterpolate(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: reinterpolate(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: reinterpolate(xa, xb)}, {i: i - 2, x: reinterpolate(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, ++ rho2 = 2, ++ rho4 = 4, ++ epsilon2 = 1e-12; ++ ++function cosh(x) { ++ return ((x = Math.exp(x)) + 1 / x) / 2; ++} ++ ++function sinh(x) { ++ return ((x = Math.exp(x)) - 1 / x) / 2; ++} ++ ++function tanh(x) { ++ return ((x = Math.exp(2 * x)) - 1) / (x + 1); ++} ++ ++// p0 = [ux0, uy0, w0] ++// p1 = [ux1, uy1, w1] ++function interpolateZoom(p0, p1) { ++ var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ++ ux1 = p1[0], uy1 = p1[1], w1 = p1[2], ++ dx = ux1 - ux0, ++ dy = uy1 - uy0, ++ d2 = dx * dx + dy * dy, ++ i, ++ S; ++ ++ // Special case for u0 ≅ u1. ++ if (d2 < epsilon2) { ++ S = Math.log(w1 / w0) / rho; ++ i = function(t) { ++ return [ ++ ux0 + t * dx, ++ uy0 + t * dy, ++ w0 * Math.exp(rho * t * S) ++ ]; ++ }; ++ } ++ ++ // General case. ++ else { ++ var d1 = Math.sqrt(d2), ++ b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1), ++ b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1), ++ r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), ++ r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1); ++ S = (r1 - r0) / rho; ++ i = function(t) { ++ var s = t * S, ++ coshr0 = cosh(r0), ++ u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0)); ++ return [ ++ ux0 + u * dx, ++ uy0 + u * dy, ++ w0 * coshr0 / cosh(rho * s + r0) ++ ]; ++ }; ++ } ++ ++ i.duration = S * 1000; ++ ++ return i; ++} ++ ++function hsl$1(hue$$1) { ++ return function(start, end) { ++ var h = hue$$1((start = hsl(start)).h, (end = hsl(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(t); ++ start.opacity = opacity(t); ++ return start + ""; ++ }; ++ } ++} ++ ++var hsl$2 = hsl$1(hue); ++var hslLong = hsl$1(nogamma); ++ ++function lab$1(start, end) { ++ var l = nogamma((start = lab(start)).l, (end = lab(end)).l), ++ a = nogamma(start.a, end.a), ++ b = nogamma(start.b, end.b), ++ opacity = nogamma(start.opacity, end.opacity); ++ return function(t) { ++ start.l = l(t); ++ start.a = a(t); ++ start.b = b(t); ++ start.opacity = opacity(t); ++ return start + ""; ++ }; ++} ++ ++function hcl$1(hue$$1) { ++ return function(start, end) { ++ var h = hue$$1((start = hcl(start)).h, (end = hcl(end)).h), ++ c = nogamma(start.c, end.c), ++ l = nogamma(start.l, end.l), ++ opacity = nogamma(start.opacity, end.opacity); ++ return function(t) { ++ start.h = h(t); ++ start.c = c(t); ++ start.l = l(t); ++ start.opacity = opacity(t); ++ return start + ""; ++ }; ++ } ++} ++ ++var hcl$2 = hcl$1(hue); ++var hclLong = hcl$1(nogamma); ++ ++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); ++} ++ ++var cubehelix$2 = cubehelix$1(hue); ++var cubehelixLong = cubehelix$1(nogamma); ++ ++function piecewise(interpolate, values) { ++ var i = 0, n = values.length - 1, v = values[0], I = new Array(n < 0 ? 0 : n); ++ while (i < n) I[i] = interpolate(v, v = values[++i]); ++ return function(t) { ++ var i = Math.max(0, Math.min(n - 1, Math.floor(t *= n))); ++ return I[i](t - i); ++ }; ++} ++ ++function quantize(interpolator, n) { ++ var samples = new Array(n); ++ for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1)); ++ return samples; ++} ++ ++var frame = 0, // is an animation frame pending? ++ timeout = 0, // is a timeout pending? ++ interval = 0, // are any timers active? ++ pokeDelay = 1000, // how frequently we check for clock skew ++ taskHead, ++ taskTail, ++ clockLast = 0, ++ clockNow = 0, ++ clockSkew = 0, ++ clock = typeof performance === "object" && performance.now ? performance : Date, ++ 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); ++ } ++} ++ ++function timeout$1(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; ++} ++ ++function interval$1(callback, delay, time) { ++ var t = new Timer, total = delay; ++ if (delay == null) return t.restart(callback, delay, time), t; ++ delay = +delay, time = time == null ? now() : +time; ++ t.restart(function tick(elapsed) { ++ elapsed += total; ++ t.restart(tick, total += delay, time); ++ callback(elapsed); ++ }, 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; ++ ++function schedule(node, name, id, index, group, timing) { ++ var schedules = node.__transition; ++ if (!schedules) node.__transition = {}; ++ else if (id in schedules) return; ++ create$1(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 = get$1(node, id); ++ if (schedule.state > CREATED) throw new Error("too late; already scheduled"); ++ return schedule; ++} ++ ++function set$1(node, id) { ++ var schedule = get$1(node, id); ++ if (schedule.state > STARTING) throw new Error("too late; already started"); ++ return schedule; ++} ++ ++function get$1(node, id) { ++ var schedule = node.__transition; ++ if (!schedule || !(schedule = schedule[id])) throw new Error("transition not found"); ++ return schedule; ++} ++ ++function create$1(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; ++ } ++} ++ ++function interrupt(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; ++} ++ ++function selection_interrupt(name) { ++ return this.each(function() { ++ interrupt(this, name); ++ }); ++} ++ ++function tweenRemove(id, name) { ++ var tween0, tween1; ++ return function() { ++ var schedule$$1 = set$1(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$1(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; ++ }; ++} ++ ++function transition_tween(name, value) { ++ var id = this._id; ++ ++ name += ""; ++ ++ if (arguments.length < 2) { ++ var tween = get$1(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$1(this, id); ++ (schedule$$1.value || (schedule$$1.value = {}))[name] = value.apply(this, arguments); ++ }); ++ ++ return function(node) { ++ return get$1(node, id).value[name]; ++ }; ++} ++ ++function interpolate(a, b) { ++ var c; ++ return (typeof b === "number" ? reinterpolate ++ : 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); ++ }; ++} ++ ++function transition_attr(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; ++} ++ ++function transition_attrTween(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; ++ }; ++} ++ ++function transition_delay(value) { ++ var id = this._id; ++ ++ return arguments.length ++ ? this.each((typeof value === "function" ++ ? delayFunction ++ : delayConstant)(id, value)) ++ : get$1(this.node(), id).delay; ++} ++ ++function durationFunction(id, value) { ++ return function() { ++ set$1(this, id).duration = +value.apply(this, arguments); ++ }; ++} ++ ++function durationConstant(id, value) { ++ return value = +value, function() { ++ set$1(this, id).duration = value; ++ }; ++} ++ ++function transition_duration(value) { ++ var id = this._id; ++ ++ return arguments.length ++ ? this.each((typeof value === "function" ++ ? durationFunction ++ : durationConstant)(id, value)) ++ : get$1(this.node(), id).duration; ++} ++ ++function easeConstant(id, value) { ++ if (typeof value !== "function") throw new Error; ++ return function() { ++ set$1(this, id).ease = value; ++ }; ++} ++ ++function transition_ease(value) { ++ var id = this._id; ++ ++ return arguments.length ++ ? this.each(easeConstant(id, value)) ++ : get$1(this.node(), id).ease; ++} ++ ++function transition_filter(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); ++} ++ ++function transition_merge(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$1; ++ 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; ++ }; ++} ++ ++function transition_on(name, listener) { ++ var id = this._id; ++ ++ return arguments.length < 2 ++ ? get$1(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); ++ }; ++} ++ ++function transition_remove() { ++ return this.on("end.remove", removeFunction(this._id)); ++} ++ ++function transition_select(select$$1) { ++ var name = this._name, ++ id = this._id; ++ ++ if (typeof select$$1 !== "function") select$$1 = selector(select$$1); ++ ++ 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$$1.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$1(node, id)); ++ } ++ } ++ } ++ ++ return new Transition(subgroups, this._parents, name, id); ++} ++ ++function transition_selectAll(select$$1) { ++ var name = this._name, ++ id = this._id; ++ ++ if (typeof select$$1 !== "function") select$$1 = selectorAll(select$$1); ++ ++ 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$$1.call(node, node.__data__, i, group), child, inherit = get$1(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; ++ ++function transition_selection() { ++ 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); ++ }; ++} ++ ++function transition_style(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; ++} ++ ++function transition_styleTween(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; ++ }; ++} ++ ++function transition_text(value) { ++ return this.tween("text", typeof value === "function" ++ ? textFunction$1(tweenValue(this, "text", value)) ++ : textConstant$1(value == null ? "" : value + "")); ++} ++ ++function transition_transition() { ++ 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$1(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 ++}; ++ ++function linear$1(t) { ++ return +t; ++} ++ ++function quadIn(t) { ++ return t * t; ++} ++ ++function quadOut(t) { ++ return t * (2 - t); ++} ++ ++function quadInOut(t) { ++ return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2; ++} ++ ++function cubicIn(t) { ++ return t * t * t; ++} ++ ++function cubicOut(t) { ++ return --t * t * t + 1; ++} ++ ++function cubicInOut(t) { ++ return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2; ++} ++ ++var exponent = 3; ++ ++var polyIn = (function custom(e) { ++ e = +e; ++ ++ function polyIn(t) { ++ return Math.pow(t, e); ++ } ++ ++ polyIn.exponent = custom; ++ ++ return polyIn; ++})(exponent); ++ ++var polyOut = (function custom(e) { ++ e = +e; ++ ++ function polyOut(t) { ++ return 1 - Math.pow(1 - t, e); ++ } ++ ++ polyOut.exponent = custom; ++ ++ return polyOut; ++})(exponent); ++ ++var polyInOut = (function custom(e) { ++ e = +e; ++ ++ function polyInOut(t) { ++ return ((t *= 2) <= 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / 2; ++ } ++ ++ polyInOut.exponent = custom; ++ ++ return polyInOut; ++})(exponent); ++ ++var pi = Math.PI, ++ halfPi = pi / 2; ++ ++function sinIn(t) { ++ return 1 - Math.cos(t * halfPi); ++} ++ ++function sinOut(t) { ++ return Math.sin(t * halfPi); ++} ++ ++function sinInOut(t) { ++ return (1 - Math.cos(pi * t)) / 2; ++} ++ ++function expIn(t) { ++ return Math.pow(2, 10 * t - 10); ++} ++ ++function expOut(t) { ++ return 1 - Math.pow(2, -10 * t); ++} ++ ++function expInOut(t) { ++ return ((t *= 2) <= 1 ? Math.pow(2, 10 * t - 10) : 2 - Math.pow(2, 10 - 10 * t)) / 2; ++} ++ ++function circleIn(t) { ++ return 1 - Math.sqrt(1 - t * t); ++} ++ ++function circleOut(t) { ++ return Math.sqrt(1 - --t * t); ++} ++ ++function circleInOut(t) { ++ return ((t *= 2) <= 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -= 2) * t) + 1) / 2; ++} ++ ++var b1 = 4 / 11, ++ b2 = 6 / 11, ++ b3 = 8 / 11, ++ b4 = 3 / 4, ++ b5 = 9 / 11, ++ b6 = 10 / 11, ++ b7 = 15 / 16, ++ b8 = 21 / 22, ++ b9 = 63 / 64, ++ b0 = 1 / b1 / b1; ++ ++function bounceIn(t) { ++ return 1 - bounceOut(1 - t); ++} ++ ++function bounceOut(t) { ++ return (t = +t) < b1 ? b0 * t * t : t < b3 ? b0 * (t -= b2) * t + b4 : t < b6 ? b0 * (t -= b5) * t + b7 : b0 * (t -= b8) * t + b9; ++} ++ ++function bounceInOut(t) { ++ return ((t *= 2) <= 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) / 2; ++} ++ ++var overshoot = 1.70158; ++ ++var backIn = (function custom(s) { ++ s = +s; ++ ++ function backIn(t) { ++ return t * t * ((s + 1) * t - s); ++ } ++ ++ backIn.overshoot = custom; ++ ++ return backIn; ++})(overshoot); ++ ++var backOut = (function custom(s) { ++ s = +s; ++ ++ function backOut(t) { ++ return --t * t * ((s + 1) * t + s) + 1; ++ } ++ ++ backOut.overshoot = custom; ++ ++ return backOut; ++})(overshoot); ++ ++var backInOut = (function custom(s) { ++ s = +s; ++ ++ function backInOut(t) { ++ return ((t *= 2) < 1 ? t * t * ((s + 1) * t - s) : (t -= 2) * t * ((s + 1) * t + s) + 2) / 2; ++ } ++ ++ backInOut.overshoot = custom; ++ ++ return backInOut; ++})(overshoot); ++ ++var tau = 2 * Math.PI, ++ amplitude = 1, ++ period = 0.3; ++ ++var elasticIn = (function custom(a, p) { ++ var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau); ++ ++ function elasticIn(t) { ++ return a * Math.pow(2, 10 * --t) * Math.sin((s - t) / p); ++ } ++ ++ elasticIn.amplitude = function(a) { return custom(a, p * tau); }; ++ elasticIn.period = function(p) { return custom(a, p); }; ++ ++ return elasticIn; ++})(amplitude, period); ++ ++var elasticOut = (function custom(a, p) { ++ var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau); ++ ++ function elasticOut(t) { ++ return 1 - a * Math.pow(2, -10 * (t = +t)) * Math.sin((t + s) / p); ++ } ++ ++ elasticOut.amplitude = function(a) { return custom(a, p * tau); }; ++ elasticOut.period = function(p) { return custom(a, p); }; ++ ++ return elasticOut; ++})(amplitude, period); ++ ++var elasticInOut = (function custom(a, p) { ++ var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau); ++ ++ function elasticInOut(t) { ++ return ((t = t * 2 - 1) < 0 ++ ? a * Math.pow(2, 10 * t) * Math.sin((s - t) / p) ++ : 2 - a * Math.pow(2, -10 * t) * Math.sin((s + t) / p)) / 2; ++ } ++ ++ elasticInOut.amplitude = function(a) { return custom(a, p * tau); }; ++ elasticInOut.period = function(p) { return custom(a, p); }; ++ ++ return elasticInOut; ++})(amplitude, period); ++ ++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; ++} ++ ++function selection_transition(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; ++ ++var root$1 = [null]; ++ ++function active(node, name) { ++ var schedules = node.__transition, ++ schedule$$1, ++ i; ++ ++ if (schedules) { ++ name = name == null ? null : name + ""; ++ for (i in schedules) { ++ if ((schedule$$1 = schedules[i]).state > SCHEDULED && schedule$$1.name === name) { ++ return new Transition([[node]], root$1, name, +i); ++ } ++ } ++ } ++ ++ return null; ++} ++ ++function constant$4(x) { ++ return function() { ++ return x; ++ }; ++} ++ ++function BrushEvent(target, type, selection) { ++ this.target = target; ++ this.type = type; ++ this.selection = selection; ++} ++ ++function nopropagation$1() { ++ exports.event.stopImmediatePropagation(); ++} ++ ++function noevent$1() { ++ exports.event.preventDefault(); ++ exports.event.stopImmediatePropagation(); ++} ++ ++var MODE_DRAG = {name: "drag"}, ++ MODE_SPACE = {name: "space"}, ++ MODE_HANDLE = {name: "handle"}, ++ MODE_CENTER = {name: "center"}; ++ ++var X = { ++ name: "x", ++ handles: ["e", "w"].map(type), ++ input: function(x, e) { return x && [[x[0], e[0][1]], [x[1], e[1][1]]]; }, ++ output: function(xy) { return xy && [xy[0][0], xy[1][0]]; } ++}; ++ ++var Y = { ++ name: "y", ++ handles: ["n", "s"].map(type), ++ input: function(y, e) { return y && [[e[0][0], y[0]], [e[1][0], y[1]]]; }, ++ output: function(xy) { return xy && [xy[0][1], xy[1][1]]; } ++}; ++ ++var XY = { ++ name: "xy", ++ handles: ["n", "e", "s", "w", "nw", "ne", "se", "sw"].map(type), ++ input: function(xy) { return xy; }, ++ output: function(xy) { return xy; } ++}; ++ ++var cursors = { ++ overlay: "crosshair", ++ selection: "move", ++ n: "ns-resize", ++ e: "ew-resize", ++ s: "ns-resize", ++ w: "ew-resize", ++ nw: "nwse-resize", ++ ne: "nesw-resize", ++ se: "nwse-resize", ++ sw: "nesw-resize" ++}; ++ ++var flipX = { ++ e: "w", ++ w: "e", ++ nw: "ne", ++ ne: "nw", ++ se: "sw", ++ sw: "se" ++}; ++ ++var flipY = { ++ n: "s", ++ s: "n", ++ nw: "sw", ++ ne: "se", ++ se: "ne", ++ sw: "nw" ++}; ++ ++var signsX = { ++ overlay: +1, ++ selection: +1, ++ n: null, ++ e: +1, ++ s: null, ++ w: -1, ++ nw: -1, ++ ne: +1, ++ se: +1, ++ sw: -1 ++}; ++ ++var signsY = { ++ overlay: +1, ++ selection: +1, ++ n: -1, ++ e: null, ++ s: +1, ++ w: null, ++ nw: -1, ++ ne: -1, ++ se: +1, ++ sw: +1 ++}; ++ ++function type(t) { ++ return {type: t}; ++} ++ ++// Ignore right-click, since that should open the context menu. ++function defaultFilter$1() { ++ return !exports.event.button; ++} ++ ++function defaultExtent() { ++ var svg = this.ownerSVGElement || this; ++ return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]]; ++} ++ ++// Like d3.local, but with the name “__brush” rather than auto-generated. ++function local$1(node) { ++ while (!node.__brush) if (!(node = node.parentNode)) return; ++ return node.__brush; ++} ++ ++function empty$1(extent) { ++ return extent[0][0] === extent[1][0] ++ || extent[0][1] === extent[1][1]; ++} ++ ++function brushSelection(node) { ++ var state = node.__brush; ++ return state ? state.dim.output(state.selection) : null; ++} ++ ++function brushX() { ++ return brush$1(X); ++} ++ ++function brushY() { ++ return brush$1(Y); ++} ++ ++function brush() { ++ return brush$1(XY); ++} ++ ++function brush$1(dim) { ++ var extent = defaultExtent, ++ filter = defaultFilter$1, ++ listeners = dispatch(brush, "start", "brush", "end"), ++ handleSize = 6, ++ touchending; ++ ++ function brush(group) { ++ var overlay = group ++ .property("__brush", initialize) ++ .selectAll(".overlay") ++ .data([type("overlay")]); ++ ++ overlay.enter().append("rect") ++ .attr("class", "overlay") ++ .attr("pointer-events", "all") ++ .attr("cursor", cursors.overlay) ++ .merge(overlay) ++ .each(function() { ++ var extent = local$1(this).extent; ++ select(this) ++ .attr("x", extent[0][0]) ++ .attr("y", extent[0][1]) ++ .attr("width", extent[1][0] - extent[0][0]) ++ .attr("height", extent[1][1] - extent[0][1]); ++ }); ++ ++ group.selectAll(".selection") ++ .data([type("selection")]) ++ .enter().append("rect") ++ .attr("class", "selection") ++ .attr("cursor", cursors.selection) ++ .attr("fill", "#777") ++ .attr("fill-opacity", 0.3) ++ .attr("stroke", "#fff") ++ .attr("shape-rendering", "crispEdges"); ++ ++ var handle = group.selectAll(".handle") ++ .data(dim.handles, function(d) { return d.type; }); ++ ++ handle.exit().remove(); ++ ++ handle.enter().append("rect") ++ .attr("class", function(d) { return "handle handle--" + d.type; }) ++ .attr("cursor", function(d) { return cursors[d.type]; }); ++ ++ group ++ .each(redraw) ++ .attr("fill", "none") ++ .attr("pointer-events", "all") ++ .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)") ++ .on("mousedown.brush touchstart.brush", started); ++ } ++ ++ brush.move = function(group, selection$$1) { ++ if (group.selection) { ++ group ++ .on("start.brush", function() { emitter(this, arguments).beforestart().start(); }) ++ .on("interrupt.brush end.brush", function() { emitter(this, arguments).end(); }) ++ .tween("brush", function() { ++ var that = this, ++ state = that.__brush, ++ emit = emitter(that, arguments), ++ selection0 = state.selection, ++ selection1 = dim.input(typeof selection$$1 === "function" ? selection$$1.apply(this, arguments) : selection$$1, state.extent), ++ i = interpolateValue(selection0, selection1); ++ ++ function tween(t) { ++ state.selection = t === 1 && empty$1(selection1) ? null : i(t); ++ redraw.call(that); ++ emit.brush(); ++ } ++ ++ return selection0 && selection1 ? tween : tween(1); ++ }); ++ } else { ++ group ++ .each(function() { ++ var that = this, ++ args = arguments, ++ state = that.__brush, ++ selection1 = dim.input(typeof selection$$1 === "function" ? selection$$1.apply(that, args) : selection$$1, state.extent), ++ emit = emitter(that, args).beforestart(); ++ ++ interrupt(that); ++ state.selection = selection1 == null || empty$1(selection1) ? null : selection1; ++ redraw.call(that); ++ emit.start().brush().end(); ++ }); ++ } ++ }; ++ ++ function redraw() { ++ var group = select(this), ++ selection$$1 = local$1(this).selection; ++ ++ if (selection$$1) { ++ group.selectAll(".selection") ++ .style("display", null) ++ .attr("x", selection$$1[0][0]) ++ .attr("y", selection$$1[0][1]) ++ .attr("width", selection$$1[1][0] - selection$$1[0][0]) ++ .attr("height", selection$$1[1][1] - selection$$1[0][1]); ++ ++ group.selectAll(".handle") ++ .style("display", null) ++ .attr("x", function(d) { return d.type[d.type.length - 1] === "e" ? selection$$1[1][0] - handleSize / 2 : selection$$1[0][0] - handleSize / 2; }) ++ .attr("y", function(d) { return d.type[0] === "s" ? selection$$1[1][1] - handleSize / 2 : selection$$1[0][1] - handleSize / 2; }) ++ .attr("width", function(d) { return d.type === "n" || d.type === "s" ? selection$$1[1][0] - selection$$1[0][0] + handleSize : handleSize; }) ++ .attr("height", function(d) { return d.type === "e" || d.type === "w" ? selection$$1[1][1] - selection$$1[0][1] + handleSize : handleSize; }); ++ } ++ ++ else { ++ group.selectAll(".selection,.handle") ++ .style("display", "none") ++ .attr("x", null) ++ .attr("y", null) ++ .attr("width", null) ++ .attr("height", null); ++ } ++ } ++ ++ function emitter(that, args) { ++ return that.__brush.emitter || new Emitter(that, args); ++ } ++ ++ function Emitter(that, args) { ++ this.that = that; ++ this.args = args; ++ this.state = that.__brush; ++ this.active = 0; ++ } ++ ++ Emitter.prototype = { ++ beforestart: function() { ++ if (++this.active === 1) this.state.emitter = this, this.starting = true; ++ return this; ++ }, ++ start: function() { ++ if (this.starting) this.starting = false, this.emit("start"); ++ return this; ++ }, ++ brush: function() { ++ this.emit("brush"); ++ return this; ++ }, ++ end: function() { ++ if (--this.active === 0) delete this.state.emitter, this.emit("end"); ++ return this; ++ }, ++ emit: function(type) { ++ customEvent(new BrushEvent(brush, type, dim.output(this.state.selection)), listeners.apply, listeners, [type, this.that, this.args]); ++ } ++ }; ++ ++ function started() { ++ if (exports.event.touches) { if (exports.event.changedTouches.length < exports.event.touches.length) return noevent$1(); } ++ else if (touchending) return; ++ if (!filter.apply(this, arguments)) return; ++ ++ var that = this, ++ type = exports.event.target.__data__.type, ++ mode = (exports.event.metaKey ? type = "overlay" : type) === "selection" ? MODE_DRAG : (exports.event.altKey ? MODE_CENTER : MODE_HANDLE), ++ signX = dim === Y ? null : signsX[type], ++ signY = dim === X ? null : signsY[type], ++ state = local$1(that), ++ extent = state.extent, ++ selection$$1 = state.selection, ++ W = extent[0][0], w0, w1, ++ N = extent[0][1], n0, n1, ++ E = extent[1][0], e0, e1, ++ S = extent[1][1], s0, s1, ++ dx, ++ dy, ++ moving, ++ shifting = signX && signY && exports.event.shiftKey, ++ lockX, ++ lockY, ++ point0 = mouse(that), ++ point$$1 = point0, ++ emit = emitter(that, arguments).beforestart(); ++ ++ if (type === "overlay") { ++ state.selection = selection$$1 = [ ++ [w0 = dim === Y ? W : point0[0], n0 = dim === X ? N : point0[1]], ++ [e0 = dim === Y ? E : w0, s0 = dim === X ? S : n0] ++ ]; ++ } else { ++ w0 = selection$$1[0][0]; ++ n0 = selection$$1[0][1]; ++ e0 = selection$$1[1][0]; ++ s0 = selection$$1[1][1]; ++ } ++ ++ w1 = w0; ++ n1 = n0; ++ e1 = e0; ++ s1 = s0; ++ ++ var group = select(that) ++ .attr("pointer-events", "none"); ++ ++ var overlay = group.selectAll(".overlay") ++ .attr("cursor", cursors[type]); ++ ++ if (exports.event.touches) { ++ group ++ .on("touchmove.brush", moved, true) ++ .on("touchend.brush touchcancel.brush", ended, true); ++ } else { ++ var view = select(exports.event.view) ++ .on("keydown.brush", keydowned, true) ++ .on("keyup.brush", keyupped, true) ++ .on("mousemove.brush", moved, true) ++ .on("mouseup.brush", ended, true); ++ ++ dragDisable(exports.event.view); ++ } ++ ++ nopropagation$1(); ++ interrupt(that); ++ redraw.call(that); ++ emit.start(); ++ ++ function moved() { ++ var point1 = mouse(that); ++ if (shifting && !lockX && !lockY) { ++ if (Math.abs(point1[0] - point$$1[0]) > Math.abs(point1[1] - point$$1[1])) lockY = true; ++ else lockX = true; ++ } ++ point$$1 = point1; ++ moving = true; ++ noevent$1(); ++ move(); ++ } ++ ++ function move() { ++ var t; ++ ++ dx = point$$1[0] - point0[0]; ++ dy = point$$1[1] - point0[1]; ++ ++ switch (mode) { ++ case MODE_SPACE: ++ case MODE_DRAG: { ++ if (signX) dx = Math.max(W - w0, Math.min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx; ++ if (signY) dy = Math.max(N - n0, Math.min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy; ++ break; ++ } ++ case MODE_HANDLE: { ++ if (signX < 0) dx = Math.max(W - w0, Math.min(E - w0, dx)), w1 = w0 + dx, e1 = e0; ++ else if (signX > 0) dx = Math.max(W - e0, Math.min(E - e0, dx)), w1 = w0, e1 = e0 + dx; ++ if (signY < 0) dy = Math.max(N - n0, Math.min(S - n0, dy)), n1 = n0 + dy, s1 = s0; ++ else if (signY > 0) dy = Math.max(N - s0, Math.min(S - s0, dy)), n1 = n0, s1 = s0 + dy; ++ break; ++ } ++ case MODE_CENTER: { ++ if (signX) w1 = Math.max(W, Math.min(E, w0 - dx * signX)), e1 = Math.max(W, Math.min(E, e0 + dx * signX)); ++ if (signY) n1 = Math.max(N, Math.min(S, n0 - dy * signY)), s1 = Math.max(N, Math.min(S, s0 + dy * signY)); ++ break; ++ } ++ } ++ ++ if (e1 < w1) { ++ signX *= -1; ++ t = w0, w0 = e0, e0 = t; ++ t = w1, w1 = e1, e1 = t; ++ if (type in flipX) overlay.attr("cursor", cursors[type = flipX[type]]); ++ } ++ ++ if (s1 < n1) { ++ signY *= -1; ++ t = n0, n0 = s0, s0 = t; ++ t = n1, n1 = s1, s1 = t; ++ if (type in flipY) overlay.attr("cursor", cursors[type = flipY[type]]); ++ } ++ ++ if (state.selection) selection$$1 = state.selection; // May be set by brush.move! ++ if (lockX) w1 = selection$$1[0][0], e1 = selection$$1[1][0]; ++ if (lockY) n1 = selection$$1[0][1], s1 = selection$$1[1][1]; ++ ++ if (selection$$1[0][0] !== w1 ++ || selection$$1[0][1] !== n1 ++ || selection$$1[1][0] !== e1 ++ || selection$$1[1][1] !== s1) { ++ state.selection = [[w1, n1], [e1, s1]]; ++ redraw.call(that); ++ emit.brush(); ++ } ++ } ++ ++ function ended() { ++ nopropagation$1(); ++ if (exports.event.touches) { ++ if (exports.event.touches.length) return; ++ if (touchending) clearTimeout(touchending); ++ touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed! ++ group.on("touchmove.brush touchend.brush touchcancel.brush", null); ++ } else { ++ yesdrag(exports.event.view, moving); ++ view.on("keydown.brush keyup.brush mousemove.brush mouseup.brush", null); ++ } ++ group.attr("pointer-events", "all"); ++ overlay.attr("cursor", cursors.overlay); ++ if (state.selection) selection$$1 = state.selection; // May be set by brush.move (on start)! ++ if (empty$1(selection$$1)) state.selection = null, redraw.call(that); ++ emit.end(); ++ } ++ ++ function keydowned() { ++ switch (exports.event.keyCode) { ++ case 16: { // SHIFT ++ shifting = signX && signY; ++ break; ++ } ++ case 18: { // ALT ++ if (mode === MODE_HANDLE) { ++ if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX; ++ if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY; ++ mode = MODE_CENTER; ++ move(); ++ } ++ break; ++ } ++ case 32: { // SPACE; takes priority over ALT ++ if (mode === MODE_HANDLE || mode === MODE_CENTER) { ++ if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx; ++ if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy; ++ mode = MODE_SPACE; ++ overlay.attr("cursor", cursors.selection); ++ move(); ++ } ++ break; ++ } ++ default: return; ++ } ++ noevent$1(); ++ } ++ ++ function keyupped() { ++ switch (exports.event.keyCode) { ++ case 16: { // SHIFT ++ if (shifting) { ++ lockX = lockY = shifting = false; ++ move(); ++ } ++ break; ++ } ++ case 18: { // ALT ++ if (mode === MODE_CENTER) { ++ if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1; ++ if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1; ++ mode = MODE_HANDLE; ++ move(); ++ } ++ break; ++ } ++ case 32: { // SPACE ++ if (mode === MODE_SPACE) { ++ if (exports.event.altKey) { ++ if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX; ++ if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY; ++ mode = MODE_CENTER; ++ } else { ++ if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1; ++ if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1; ++ mode = MODE_HANDLE; ++ } ++ overlay.attr("cursor", cursors[type]); ++ move(); ++ } ++ break; ++ } ++ default: return; ++ } ++ noevent$1(); ++ } ++ } ++ ++ function initialize() { ++ var state = this.__brush || {selection: null}; ++ state.extent = extent.apply(this, arguments); ++ state.dim = dim; ++ return state; ++ } ++ ++ brush.extent = function(_) { ++ return arguments.length ? (extent = typeof _ === "function" ? _ : constant$4([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), brush) : extent; ++ }; ++ ++ brush.filter = function(_) { ++ return arguments.length ? (filter = typeof _ === "function" ? _ : constant$4(!!_), brush) : filter; ++ }; ++ ++ brush.handleSize = function(_) { ++ return arguments.length ? (handleSize = +_, brush) : handleSize; ++ }; ++ ++ brush.on = function() { ++ var value = listeners.on.apply(listeners, arguments); ++ return value === listeners ? brush : value; ++ }; ++ ++ return brush; ++} ++ ++var cos = Math.cos; ++var sin = Math.sin; ++var pi$1 = Math.PI; ++var halfPi$1 = pi$1 / 2; ++var tau$1 = pi$1 * 2; ++var max$1 = Math.max; ++ ++function compareValue(compare) { ++ return function(a, b) { ++ return compare( ++ a.source.value + a.target.value, ++ b.source.value + b.target.value ++ ); ++ }; ++} ++ ++function chord() { ++ var padAngle = 0, ++ sortGroups = null, ++ sortSubgroups = null, ++ sortChords = null; ++ ++ function chord(matrix) { ++ var n = matrix.length, ++ groupSums = [], ++ groupIndex = sequence(n), ++ subgroupIndex = [], ++ chords = [], ++ groups = chords.groups = new Array(n), ++ subgroups = new Array(n * n), ++ k, ++ x, ++ x0, ++ dx, ++ i, ++ j; ++ ++ // Compute the sum. ++ k = 0, i = -1; while (++i < n) { ++ x = 0, j = -1; while (++j < n) { ++ x += matrix[i][j]; ++ } ++ groupSums.push(x); ++ subgroupIndex.push(sequence(n)); ++ k += x; ++ } ++ ++ // Sort groups… ++ if (sortGroups) groupIndex.sort(function(a, b) { ++ return sortGroups(groupSums[a], groupSums[b]); ++ }); ++ ++ // Sort subgroups… ++ if (sortSubgroups) subgroupIndex.forEach(function(d, i) { ++ d.sort(function(a, b) { ++ return sortSubgroups(matrix[i][a], matrix[i][b]); ++ }); ++ }); ++ ++ // Convert the sum to scaling factor for [0, 2pi]. ++ // TODO Allow start and end angle to be specified? ++ // TODO Allow padding to be specified as percentage? ++ k = max$1(0, tau$1 - padAngle * n) / k; ++ dx = k ? padAngle : tau$1 / n; ++ ++ // Compute the start and end angle for each group and subgroup. ++ // Note: Opera has a bug reordering object literal properties! ++ x = 0, i = -1; while (++i < n) { ++ x0 = x, j = -1; while (++j < n) { ++ var di = groupIndex[i], ++ dj = subgroupIndex[di][j], ++ v = matrix[di][dj], ++ a0 = x, ++ a1 = x += v * k; ++ subgroups[dj * n + di] = { ++ index: di, ++ subindex: dj, ++ startAngle: a0, ++ endAngle: a1, ++ value: v ++ }; ++ } ++ groups[di] = { ++ index: di, ++ startAngle: x0, ++ endAngle: x, ++ value: groupSums[di] ++ }; ++ x += dx; ++ } ++ ++ // Generate chords for each (non-empty) subgroup-subgroup link. ++ i = -1; while (++i < n) { ++ j = i - 1; while (++j < n) { ++ var source = subgroups[j * n + i], ++ target = subgroups[i * n + j]; ++ if (source.value || target.value) { ++ chords.push(source.value < target.value ++ ? {source: target, target: source} ++ : {source: source, target: target}); ++ } ++ } ++ } ++ ++ return sortChords ? chords.sort(sortChords) : chords; ++ } ++ ++ chord.padAngle = function(_) { ++ return arguments.length ? (padAngle = max$1(0, _), chord) : padAngle; ++ }; ++ ++ chord.sortGroups = function(_) { ++ return arguments.length ? (sortGroups = _, chord) : sortGroups; ++ }; ++ ++ chord.sortSubgroups = function(_) { ++ return arguments.length ? (sortSubgroups = _, chord) : sortSubgroups; ++ }; ++ ++ chord.sortChords = function(_) { ++ return arguments.length ? (_ == null ? sortChords = null : (sortChords = compareValue(_))._ = _, chord) : sortChords && sortChords._; ++ }; ++ ++ return chord; ++} ++ ++var slice$2 = Array.prototype.slice; ++ ++function constant$5(x) { ++ return function() { ++ return x; ++ }; ++} ++ ++var pi$2 = Math.PI, ++ tau$2 = 2 * pi$2, ++ epsilon$1 = 1e-6, ++ tauEpsilon = tau$2 - epsilon$1; ++ ++function Path() { ++ this._x0 = this._y0 = // start of current subpath ++ this._x1 = this._y1 = null; // end of current subpath ++ this._ = ""; ++} ++ ++function path() { ++ return new Path; ++} ++ ++Path.prototype = path.prototype = { ++ constructor: Path, ++ moveTo: function(x, y) { ++ this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y); ++ }, ++ closePath: function() { ++ if (this._x1 !== null) { ++ this._x1 = this._x0, this._y1 = this._y0; ++ this._ += "Z"; ++ } ++ }, ++ lineTo: function(x, y) { ++ this._ += "L" + (this._x1 = +x) + "," + (this._y1 = +y); ++ }, ++ quadraticCurveTo: function(x1, y1, x, y) { ++ this._ += "Q" + (+x1) + "," + (+y1) + "," + (this._x1 = +x) + "," + (this._y1 = +y); ++ }, ++ bezierCurveTo: function(x1, y1, x2, y2, x, y) { ++ this._ += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y); ++ }, ++ arcTo: function(x1, y1, x2, y2, r) { ++ x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r; ++ var x0 = this._x1, ++ y0 = this._y1, ++ x21 = x2 - x1, ++ y21 = y2 - y1, ++ x01 = x0 - x1, ++ y01 = y0 - y1, ++ l01_2 = x01 * x01 + y01 * y01; ++ ++ // Is the radius negative? Error. ++ if (r < 0) throw new Error("negative radius: " + r); ++ ++ // Is this path empty? Move to (x1,y1). ++ if (this._x1 === null) { ++ this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1); ++ } ++ ++ // Or, is (x1,y1) coincident with (x0,y0)? Do nothing. ++ else if (!(l01_2 > epsilon$1)) {} ++ ++ // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear? ++ // Equivalently, is (x1,y1) coincident with (x2,y2)? ++ // Or, is the radius zero? Line to (x1,y1). ++ else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon$1) || !r) { ++ this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1); ++ } ++ ++ // Otherwise, draw an arc! ++ else { ++ var x20 = x2 - x0, ++ y20 = y2 - y0, ++ l21_2 = x21 * x21 + y21 * y21, ++ l20_2 = x20 * x20 + y20 * y20, ++ l21 = Math.sqrt(l21_2), ++ l01 = Math.sqrt(l01_2), ++ l = r * Math.tan((pi$2 - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2), ++ t01 = l / l01, ++ t21 = l / l21; ++ ++ // If the start tangent is not coincident with (x0,y0), line to. ++ if (Math.abs(t01 - 1) > epsilon$1) { ++ this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01); ++ } ++ ++ this._ += "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21); ++ } ++ }, ++ arc: function(x, y, r, a0, a1, ccw) { ++ x = +x, y = +y, r = +r; ++ var dx = r * Math.cos(a0), ++ dy = r * Math.sin(a0), ++ x0 = x + dx, ++ y0 = y + dy, ++ cw = 1 ^ ccw, ++ da = ccw ? a0 - a1 : a1 - a0; ++ ++ // Is the radius negative? Error. ++ if (r < 0) throw new Error("negative radius: " + r); ++ ++ // Is this path empty? Move to (x0,y0). ++ if (this._x1 === null) { ++ this._ += "M" + x0 + "," + y0; ++ } ++ ++ // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0). ++ else if (Math.abs(this._x1 - x0) > epsilon$1 || Math.abs(this._y1 - y0) > epsilon$1) { ++ this._ += "L" + x0 + "," + y0; ++ } ++ ++ // Is this arc empty? We’re done. ++ if (!r) return; ++ ++ // Does the angle go the wrong way? Flip the direction. ++ if (da < 0) da = da % tau$2 + tau$2; ++ ++ // Is this a complete circle? Draw two arcs to complete the circle. ++ if (da > tauEpsilon) { ++ this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0); ++ } ++ ++ // Is this arc non-empty? Draw an arc! ++ else if (da > epsilon$1) { ++ this._ += "A" + r + "," + r + ",0," + (+(da >= pi$2)) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1)); ++ } ++ }, ++ rect: function(x, y, w, h) { ++ this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z"; ++ }, ++ toString: function() { ++ return this._; ++ } ++}; ++ ++function defaultSource(d) { ++ return d.source; ++} ++ ++function defaultTarget(d) { ++ return d.target; ++} ++ ++function defaultRadius(d) { ++ return d.radius; ++} ++ ++function defaultStartAngle(d) { ++ return d.startAngle; ++} ++ ++function defaultEndAngle(d) { ++ return d.endAngle; ++} ++ ++function ribbon() { ++ var source = defaultSource, ++ target = defaultTarget, ++ radius = defaultRadius, ++ startAngle = defaultStartAngle, ++ endAngle = defaultEndAngle, ++ context = null; ++ ++ function ribbon() { ++ var buffer, ++ argv = slice$2.call(arguments), ++ s = source.apply(this, argv), ++ t = target.apply(this, argv), ++ sr = +radius.apply(this, (argv[0] = s, argv)), ++ sa0 = startAngle.apply(this, argv) - halfPi$1, ++ sa1 = endAngle.apply(this, argv) - halfPi$1, ++ sx0 = sr * cos(sa0), ++ sy0 = sr * sin(sa0), ++ tr = +radius.apply(this, (argv[0] = t, argv)), ++ ta0 = startAngle.apply(this, argv) - halfPi$1, ++ ta1 = endAngle.apply(this, argv) - halfPi$1; ++ ++ if (!context) context = buffer = path(); ++ ++ context.moveTo(sx0, sy0); ++ context.arc(0, 0, sr, sa0, sa1); ++ if (sa0 !== ta0 || sa1 !== ta1) { // TODO sr !== tr? ++ context.quadraticCurveTo(0, 0, tr * cos(ta0), tr * sin(ta0)); ++ context.arc(0, 0, tr, ta0, ta1); ++ } ++ context.quadraticCurveTo(0, 0, sx0, sy0); ++ context.closePath(); ++ ++ if (buffer) return context = null, buffer + "" || null; ++ } ++ ++ ribbon.radius = function(_) { ++ return arguments.length ? (radius = typeof _ === "function" ? _ : constant$5(+_), ribbon) : radius; ++ }; ++ ++ ribbon.startAngle = function(_) { ++ return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$5(+_), ribbon) : startAngle; ++ }; ++ ++ ribbon.endAngle = function(_) { ++ return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$5(+_), ribbon) : endAngle; ++ }; ++ ++ ribbon.source = function(_) { ++ return arguments.length ? (source = _, ribbon) : source; ++ }; ++ ++ ribbon.target = function(_) { ++ return arguments.length ? (target = _, ribbon) : target; ++ }; ++ ++ ribbon.context = function(_) { ++ return arguments.length ? (context = _ == null ? null : _, ribbon) : context; ++ }; ++ ++ return ribbon; ++} ++ ++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 nest() { ++ var keys = [], ++ sortKeys = [], ++ sortValues, ++ rollup, ++ nest; ++ ++ function apply(array, depth, createResult, setResult) { ++ if (depth >= keys.length) { ++ if (sortValues != null) array.sort(sortValues); ++ return rollup != null ? rollup(array) : array; ++ } ++ ++ var i = -1, ++ n = array.length, ++ key = keys[depth++], ++ keyValue, ++ value, ++ valuesByKey = map$1(), ++ values, ++ result = createResult(); ++ ++ while (++i < n) { ++ if (values = valuesByKey.get(keyValue = key(value = array[i]) + "")) { ++ values.push(value); ++ } else { ++ valuesByKey.set(keyValue, [value]); ++ } ++ } ++ ++ valuesByKey.each(function(values, key) { ++ setResult(result, key, apply(values, depth, createResult, setResult)); ++ }); ++ ++ return result; ++ } ++ ++ function entries(map, depth) { ++ if (++depth > keys.length) return map; ++ var array, sortKey = sortKeys[depth - 1]; ++ if (rollup != null && depth >= keys.length) array = map.entries(); ++ else array = [], map.each(function(v, k) { array.push({key: k, values: entries(v, depth)}); }); ++ return sortKey != null ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array; ++ } ++ ++ return nest = { ++ object: function(array) { return apply(array, 0, createObject, setObject); }, ++ map: function(array) { return apply(array, 0, createMap, setMap); }, ++ entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); }, ++ key: function(d) { keys.push(d); return nest; }, ++ sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; }, ++ sortValues: function(order) { sortValues = order; return nest; }, ++ rollup: function(f) { rollup = f; return nest; } ++ }; ++} ++ ++function createObject() { ++ return {}; ++} ++ ++function setObject(object, key, value) { ++ object[key] = value; ++} ++ ++function createMap() { ++ return map$1(); ++} ++ ++function setMap(map, key, value) { ++ map.set(key, value); ++} ++ ++function Set() {} ++ ++var proto = map$1.prototype; ++ ++Set.prototype = set$2.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$2(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; ++} ++ ++function keys(map) { ++ var keys = []; ++ for (var key in map) keys.push(key); ++ return keys; ++} ++ ++function values(map) { ++ var values = []; ++ for (var key in map) values.push(map[key]); ++ return values; ++} ++ ++function entries(map) { ++ var entries = []; ++ for (var key in map) entries.push({key: key, value: map[key]}); ++ return entries; ++} ++ ++var array$2 = Array.prototype; ++ ++var slice$3 = array$2.slice; ++ ++function ascending$2(a, b) { ++ return a - b; ++} ++ ++function area(ring) { ++ var i = 0, n = ring.length, area = ring[n - 1][1] * ring[0][0] - ring[n - 1][0] * ring[0][1]; ++ while (++i < n) area += ring[i - 1][1] * ring[i][0] - ring[i - 1][0] * ring[i][1]; ++ return area; ++} ++ ++function constant$6(x) { ++ return function() { ++ return x; ++ }; ++} ++ ++function contains(ring, hole) { ++ var i = -1, n = hole.length, c; ++ while (++i < n) if (c = ringContains(ring, hole[i])) return c; ++ return 0; ++} ++ ++function ringContains(ring, point) { ++ var x = point[0], y = point[1], contains = -1; ++ for (var i = 0, n = ring.length, j = n - 1; i < n; j = i++) { ++ var pi = ring[i], xi = pi[0], yi = pi[1], pj = ring[j], xj = pj[0], yj = pj[1]; ++ if (segmentContains(pi, pj, point)) return 0; ++ if (((yi > y) !== (yj > y)) && ((x < (xj - xi) * (y - yi) / (yj - yi) + xi))) contains = -contains; ++ } ++ return contains; ++} ++ ++function segmentContains(a, b, c) { ++ var i; return collinear(a, b, c) && within(a[i = +(a[0] === b[0])], c[i], b[i]); ++} ++ ++function collinear(a, b, c) { ++ return (b[0] - a[0]) * (c[1] - a[1]) === (c[0] - a[0]) * (b[1] - a[1]); ++} ++ ++function within(p, q, r) { ++ return p <= q && q <= r || r <= q && q <= p; ++} ++ ++function noop$1() {} ++ ++var cases = [ ++ [], ++ [[[1.0, 1.5], [0.5, 1.0]]], ++ [[[1.5, 1.0], [1.0, 1.5]]], ++ [[[1.5, 1.0], [0.5, 1.0]]], ++ [[[1.0, 0.5], [1.5, 1.0]]], ++ [[[1.0, 1.5], [0.5, 1.0]], [[1.0, 0.5], [1.5, 1.0]]], ++ [[[1.0, 0.5], [1.0, 1.5]]], ++ [[[1.0, 0.5], [0.5, 1.0]]], ++ [[[0.5, 1.0], [1.0, 0.5]]], ++ [[[1.0, 1.5], [1.0, 0.5]]], ++ [[[0.5, 1.0], [1.0, 0.5]], [[1.5, 1.0], [1.0, 1.5]]], ++ [[[1.5, 1.0], [1.0, 0.5]]], ++ [[[0.5, 1.0], [1.5, 1.0]]], ++ [[[1.0, 1.5], [1.5, 1.0]]], ++ [[[0.5, 1.0], [1.0, 1.5]]], ++ [] ++]; ++ ++function contours() { ++ var dx = 1, ++ dy = 1, ++ threshold$$1 = thresholdSturges, ++ smooth = smoothLinear; ++ ++ function contours(values) { ++ var tz = threshold$$1(values); ++ ++ // Convert number of thresholds into uniform thresholds. ++ if (!Array.isArray(tz)) { ++ var domain = extent(values), start = domain[0], stop = domain[1]; ++ tz = tickStep(start, stop, tz); ++ tz = sequence(Math.floor(start / tz) * tz, Math.floor(stop / tz) * tz, tz); ++ } else { ++ tz = tz.slice().sort(ascending$2); ++ } ++ ++ return tz.map(function(value) { ++ return contour(values, value); ++ }); ++ } ++ ++ // Accumulate, smooth contour rings, assign holes to exterior rings. ++ // Based on https://github.com/mbostock/shapefile/blob/v0.6.2/shp/polygon.js ++ function contour(values, value) { ++ var polygons = [], ++ holes = []; ++ ++ isorings(values, value, function(ring) { ++ smooth(ring, values, value); ++ if (area(ring) > 0) polygons.push([ring]); ++ else holes.push(ring); ++ }); ++ ++ holes.forEach(function(hole) { ++ for (var i = 0, n = polygons.length, polygon; i < n; ++i) { ++ if (contains((polygon = polygons[i])[0], hole) !== -1) { ++ polygon.push(hole); ++ return; ++ } ++ } ++ }); ++ ++ return { ++ type: "MultiPolygon", ++ value: value, ++ coordinates: polygons ++ }; ++ } ++ ++ // Marching squares with isolines stitched into rings. ++ // Based on https://github.com/topojson/topojson-client/blob/v3.0.0/src/stitch.js ++ function isorings(values, value, callback) { ++ var fragmentByStart = new Array, ++ fragmentByEnd = new Array, ++ x, y, t0, t1, t2, t3; ++ ++ // Special case for the first row (y = -1, t2 = t3 = 0). ++ x = y = -1; ++ t1 = values[0] >= value; ++ cases[t1 << 1].forEach(stitch); ++ while (++x < dx - 1) { ++ t0 = t1, t1 = values[x + 1] >= value; ++ cases[t0 | t1 << 1].forEach(stitch); ++ } ++ cases[t1 << 0].forEach(stitch); ++ ++ // General case for the intermediate rows. ++ while (++y < dy - 1) { ++ x = -1; ++ t1 = values[y * dx + dx] >= value; ++ t2 = values[y * dx] >= value; ++ cases[t1 << 1 | t2 << 2].forEach(stitch); ++ while (++x < dx - 1) { ++ t0 = t1, t1 = values[y * dx + dx + x + 1] >= value; ++ t3 = t2, t2 = values[y * dx + x + 1] >= value; ++ cases[t0 | t1 << 1 | t2 << 2 | t3 << 3].forEach(stitch); ++ } ++ cases[t1 | t2 << 3].forEach(stitch); ++ } ++ ++ // Special case for the last row (y = dy - 1, t0 = t1 = 0). ++ x = -1; ++ t2 = values[y * dx] >= value; ++ cases[t2 << 2].forEach(stitch); ++ while (++x < dx - 1) { ++ t3 = t2, t2 = values[y * dx + x + 1] >= value; ++ cases[t2 << 2 | t3 << 3].forEach(stitch); ++ } ++ cases[t2 << 3].forEach(stitch); ++ ++ function stitch(line) { ++ var start = [line[0][0] + x, line[0][1] + y], ++ end = [line[1][0] + x, line[1][1] + y], ++ startIndex = index(start), ++ endIndex = index(end), ++ f, g; ++ if (f = fragmentByEnd[startIndex]) { ++ if (g = fragmentByStart[endIndex]) { ++ delete fragmentByEnd[f.end]; ++ delete fragmentByStart[g.start]; ++ if (f === g) { ++ f.ring.push(end); ++ callback(f.ring); ++ } else { ++ fragmentByStart[f.start] = fragmentByEnd[g.end] = {start: f.start, end: g.end, ring: f.ring.concat(g.ring)}; ++ } ++ } else { ++ delete fragmentByEnd[f.end]; ++ f.ring.push(end); ++ fragmentByEnd[f.end = endIndex] = f; ++ } ++ } else if (f = fragmentByStart[endIndex]) { ++ if (g = fragmentByEnd[startIndex]) { ++ delete fragmentByStart[f.start]; ++ delete fragmentByEnd[g.end]; ++ if (f === g) { ++ f.ring.push(end); ++ callback(f.ring); ++ } else { ++ fragmentByStart[g.start] = fragmentByEnd[f.end] = {start: g.start, end: f.end, ring: g.ring.concat(f.ring)}; ++ } ++ } else { ++ delete fragmentByStart[f.start]; ++ f.ring.unshift(start); ++ fragmentByStart[f.start = startIndex] = f; ++ } ++ } else { ++ fragmentByStart[startIndex] = fragmentByEnd[endIndex] = {start: startIndex, end: endIndex, ring: [start, end]}; ++ } ++ } ++ } ++ ++ function index(point) { ++ return point[0] * 2 + point[1] * (dx + 1) * 4; ++ } ++ ++ function smoothLinear(ring, values, value) { ++ ring.forEach(function(point) { ++ var x = point[0], ++ y = point[1], ++ xt = x | 0, ++ yt = y | 0, ++ v0, ++ v1 = values[yt * dx + xt]; ++ if (x > 0 && x < dx && xt === x) { ++ v0 = values[yt * dx + xt - 1]; ++ point[0] = x + (value - v0) / (v1 - v0) - 0.5; ++ } ++ if (y > 0 && y < dy && yt === y) { ++ v0 = values[(yt - 1) * dx + xt]; ++ point[1] = y + (value - v0) / (v1 - v0) - 0.5; ++ } ++ }); ++ } ++ ++ contours.contour = contour; ++ ++ contours.size = function(_) { ++ if (!arguments.length) return [dx, dy]; ++ var _0 = Math.ceil(_[0]), _1 = Math.ceil(_[1]); ++ if (!(_0 > 0) || !(_1 > 0)) throw new Error("invalid size"); ++ return dx = _0, dy = _1, contours; ++ }; ++ ++ contours.thresholds = function(_) { ++ return arguments.length ? (threshold$$1 = typeof _ === "function" ? _ : Array.isArray(_) ? constant$6(slice$3.call(_)) : constant$6(_), contours) : threshold$$1; ++ }; ++ ++ contours.smooth = function(_) { ++ return arguments.length ? (smooth = _ ? smoothLinear : noop$1, contours) : smooth === smoothLinear; ++ }; ++ ++ return contours; ++} ++ ++// TODO Optimize edge cases. ++// TODO Optimize index calculation. ++// TODO Optimize arguments. ++function blurX(source, target, r) { ++ var n = source.width, ++ m = source.height, ++ w = (r << 1) + 1; ++ for (var j = 0; j < m; ++j) { ++ for (var i = 0, sr = 0; i < n + r; ++i) { ++ if (i < n) { ++ sr += source.data[i + j * n]; ++ } ++ if (i >= r) { ++ if (i >= w) { ++ sr -= source.data[i - w + j * n]; ++ } ++ target.data[i - r + j * n] = sr / Math.min(i + 1, n - 1 + w - i, w); ++ } ++ } ++ } ++} ++ ++// TODO Optimize edge cases. ++// TODO Optimize index calculation. ++// TODO Optimize arguments. ++function blurY(source, target, r) { ++ var n = source.width, ++ m = source.height, ++ w = (r << 1) + 1; ++ for (var i = 0; i < n; ++i) { ++ for (var j = 0, sr = 0; j < m + r; ++j) { ++ if (j < m) { ++ sr += source.data[i + j * n]; ++ } ++ if (j >= r) { ++ if (j >= w) { ++ sr -= source.data[i + (j - w) * n]; ++ } ++ target.data[i + (j - r) * n] = sr / Math.min(j + 1, m - 1 + w - j, w); ++ } ++ } ++ } ++} ++ ++function defaultX(d) { ++ return d[0]; ++} ++ ++function defaultY(d) { ++ return d[1]; ++} ++ ++function density() { ++ var x = defaultX, ++ y = defaultY, ++ dx = 960, ++ dy = 500, ++ r = 20, // blur radius ++ k = 2, // log2(grid cell size) ++ o = r * 3, // grid offset, to pad for blur ++ n = (dx + o * 2) >> k, // grid width ++ m = (dy + o * 2) >> k, // grid height ++ threshold$$1 = constant$6(20); ++ ++ function density(data) { ++ var values0 = new Float32Array(n * m), ++ values1 = new Float32Array(n * m); ++ ++ data.forEach(function(d, i, data) { ++ var xi = (x(d, i, data) + o) >> k, ++ yi = (y(d, i, data) + o) >> k; ++ if (xi >= 0 && xi < n && yi >= 0 && yi < m) { ++ ++values0[xi + yi * n]; ++ } ++ }); ++ ++ // TODO Optimize. ++ blurX({width: n, height: m, data: values0}, {width: n, height: m, data: values1}, r >> k); ++ blurY({width: n, height: m, data: values1}, {width: n, height: m, data: values0}, r >> k); ++ blurX({width: n, height: m, data: values0}, {width: n, height: m, data: values1}, r >> k); ++ blurY({width: n, height: m, data: values1}, {width: n, height: m, data: values0}, r >> k); ++ blurX({width: n, height: m, data: values0}, {width: n, height: m, data: values1}, r >> k); ++ blurY({width: n, height: m, data: values1}, {width: n, height: m, data: values0}, r >> k); ++ ++ var tz = threshold$$1(values0); ++ ++ // Convert number of thresholds into uniform thresholds. ++ if (!Array.isArray(tz)) { ++ var stop = max(values0); ++ tz = tickStep(0, stop, tz); ++ tz = sequence(0, Math.floor(stop / tz) * tz, tz); ++ tz.shift(); ++ } ++ ++ return contours() ++ .thresholds(tz) ++ .size([n, m]) ++ (values0) ++ .map(transform); ++ } ++ ++ function transform(geometry) { ++ geometry.value *= Math.pow(2, -2 * k); // Density in points per square pixel. ++ geometry.coordinates.forEach(transformPolygon); ++ return geometry; ++ } ++ ++ function transformPolygon(coordinates) { ++ coordinates.forEach(transformRing); ++ } ++ ++ function transformRing(coordinates) { ++ coordinates.forEach(transformPoint); ++ } ++ ++ // TODO Optimize. ++ function transformPoint(coordinates) { ++ coordinates[0] = coordinates[0] * Math.pow(2, k) - o; ++ coordinates[1] = coordinates[1] * Math.pow(2, k) - o; ++ } ++ ++ function resize() { ++ o = r * 3; ++ n = (dx + o * 2) >> k; ++ m = (dy + o * 2) >> k; ++ return density; ++ } ++ ++ density.x = function(_) { ++ return arguments.length ? (x = typeof _ === "function" ? _ : constant$6(+_), density) : x; ++ }; ++ ++ density.y = function(_) { ++ return arguments.length ? (y = typeof _ === "function" ? _ : constant$6(+_), density) : y; ++ }; ++ ++ density.size = function(_) { ++ if (!arguments.length) return [dx, dy]; ++ var _0 = Math.ceil(_[0]), _1 = Math.ceil(_[1]); ++ if (!(_0 >= 0) && !(_0 >= 0)) throw new Error("invalid size"); ++ return dx = _0, dy = _1, resize(); ++ }; ++ ++ density.cellSize = function(_) { ++ if (!arguments.length) return 1 << k; ++ if (!((_ = +_) >= 1)) throw new Error("invalid cell size"); ++ return k = Math.floor(Math.log(_) / Math.LN2), resize(); ++ }; ++ ++ density.thresholds = function(_) { ++ return arguments.length ? (threshold$$1 = typeof _ === "function" ? _ : Array.isArray(_) ? constant$6(slice$3.call(_)) : constant$6(_), density) : threshold$$1; ++ }; ++ ++ density.bandwidth = function(_) { ++ if (!arguments.length) return Math.sqrt(r * (r + 1)); ++ if (!((_ = +_) >= 0)) throw new Error("invalid bandwidth"); ++ return r = Math.round((Math.sqrt(4 * _ * _ + 1) - 1) / 2), resize(); ++ }; ++ ++ return density; ++} ++ ++var EOL = {}, ++ EOF = {}, ++ QUOTE = 34, ++ NEWLINE = 10, ++ RETURN = 13; ++ ++function objectConverter(columns) { ++ return new Function("d", "return {" + columns.map(function(name, i) { ++ return JSON.stringify(name) + ": d[" + i + "]"; ++ }).join(",") + "}"); ++} ++ ++function customConverter(columns, f) { ++ var object = objectConverter(columns); ++ return function(row, i) { ++ return f(object(row), i, columns); ++ }; ++} ++ ++// Compute unique columns in order of discovery. ++function inferColumns(rows) { ++ var columnSet = Object.create(null), ++ columns = []; ++ ++ rows.forEach(function(row) { ++ for (var column in row) { ++ if (!(column in columnSet)) { ++ columns.push(columnSet[column] = column); ++ } ++ } ++ }); ++ ++ return columns; ++} ++ ++function dsvFormat(delimiter) { ++ var reFormat = new RegExp("[\"" + delimiter + "\n\r]"), ++ DELIMITER = delimiter.charCodeAt(0); ++ ++ function parse(text, f) { ++ var convert, columns, rows = parseRows(text, function(row, i) { ++ if (convert) return convert(row, i - 1); ++ columns = row, convert = f ? customConverter(row, f) : objectConverter(row); ++ }); ++ rows.columns = columns || []; ++ return rows; ++ } ++ ++ function parseRows(text, f) { ++ var rows = [], // output rows ++ N = text.length, ++ I = 0, // current character index ++ n = 0, // current line number ++ t, // current token ++ eof = N <= 0, // current token followed by EOF? ++ eol = false; // current token followed by EOL? ++ ++ // Strip the trailing newline. ++ if (text.charCodeAt(N - 1) === NEWLINE) --N; ++ if (text.charCodeAt(N - 1) === RETURN) --N; ++ ++ function token() { ++ if (eof) return EOF; ++ if (eol) return eol = false, EOL; ++ ++ // Unescape quotes. ++ var i, j = I, c; ++ if (text.charCodeAt(j) === QUOTE) { ++ while (I++ < N && text.charCodeAt(I) !== QUOTE || text.charCodeAt(++I) === QUOTE); ++ if ((i = I) >= N) eof = true; ++ else if ((c = text.charCodeAt(I++)) === NEWLINE) eol = true; ++ else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; } ++ return text.slice(j + 1, i - 1).replace(/""/g, "\""); ++ } ++ ++ // Find next delimiter or newline. ++ while (I < N) { ++ if ((c = text.charCodeAt(i = I++)) === NEWLINE) eol = true; ++ else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; } ++ else if (c !== DELIMITER) continue; ++ return text.slice(j, i); ++ } ++ ++ // Return last token before EOF. ++ return eof = true, text.slice(j, N); ++ } ++ ++ while ((t = token()) !== EOF) { ++ var row = []; ++ while (t !== EOL && t !== EOF) row.push(t), t = token(); ++ if (f && (row = f(row, n++)) == null) continue; ++ rows.push(row); ++ } ++ ++ return rows; ++ } ++ ++ function format(rows, columns) { ++ if (columns == null) columns = inferColumns(rows); ++ return [columns.map(formatValue).join(delimiter)].concat(rows.map(function(row) { ++ return columns.map(function(column) { ++ return formatValue(row[column]); ++ }).join(delimiter); ++ })).join("\n"); ++ } ++ ++ function formatRows(rows) { ++ return rows.map(formatRow).join("\n"); ++ } ++ ++ function formatRow(row) { ++ return row.map(formatValue).join(delimiter); ++ } ++ ++ function formatValue(text) { ++ return text == null ? "" ++ : reFormat.test(text += "") ? "\"" + text.replace(/"/g, "\"\"") + "\"" ++ : text; ++ } ++ ++ return { ++ parse: parse, ++ parseRows: parseRows, ++ format: format, ++ formatRows: formatRows ++ }; ++} ++ ++var csv = dsvFormat(","); ++ ++var csvParse = csv.parse; ++var csvParseRows = csv.parseRows; ++var csvFormat = csv.format; ++var csvFormatRows = csv.formatRows; ++ ++var tsv = dsvFormat("\t"); ++ ++var tsvParse = tsv.parse; ++var tsvParseRows = tsv.parseRows; ++var tsvFormat = tsv.format; ++var tsvFormatRows = tsv.formatRows; ++ ++function responseBlob(response) { ++ if (!response.ok) throw new Error(response.status + " " + response.statusText); ++ return response.blob(); ++} ++ ++function blob(input, init) { ++ return fetch(input, init).then(responseBlob); ++} ++ ++function responseArrayBuffer(response) { ++ if (!response.ok) throw new Error(response.status + " " + response.statusText); ++ return response.arrayBuffer(); ++} ++ ++function buffer(input, init) { ++ return fetch(input, init).then(responseArrayBuffer); ++} ++ ++function responseText(response) { ++ if (!response.ok) throw new Error(response.status + " " + response.statusText); ++ return response.text(); ++} ++ ++function text(input, init) { ++ return fetch(input, init).then(responseText); ++} ++ ++function dsvParse(parse) { ++ return function(input, init, row) { ++ if (arguments.length === 2 && typeof init === "function") row = init, init = undefined; ++ return text(input, init).then(function(response) { ++ return parse(response, row); ++ }); ++ }; ++} ++ ++function dsv(delimiter, input, init, row) { ++ if (arguments.length === 3 && typeof init === "function") row = init, init = undefined; ++ var format = dsvFormat(delimiter); ++ return text(input, init).then(function(response) { ++ return format.parse(response, row); ++ }); ++} ++ ++var csv$1 = dsvParse(csvParse); ++var tsv$1 = dsvParse(tsvParse); ++ ++function image(input, init) { ++ return new Promise(function(resolve, reject) { ++ var image = new Image; ++ for (var key in init) image[key] = init[key]; ++ image.onerror = reject; ++ image.onload = function() { resolve(image); }; ++ image.src = input; ++ }); ++} ++ ++function responseJson(response) { ++ if (!response.ok) throw new Error(response.status + " " + response.statusText); ++ return response.json(); ++} ++ ++function json(input, init) { ++ return fetch(input, init).then(responseJson); ++} ++ ++function parser(type) { ++ return function(input, init) { ++ return text(input, init).then(function(text$$1) { ++ return (new DOMParser).parseFromString(text$$1, type); ++ }); ++ }; ++} ++ ++var xml = parser("application/xml"); ++ ++var html = parser("text/html"); ++ ++var svg = parser("image/svg+xml"); ++ ++function center$1(x, y) { ++ var nodes; ++ ++ if (x == null) x = 0; ++ if (y == null) y = 0; ++ ++ function force() { ++ var i, ++ n = nodes.length, ++ node, ++ sx = 0, ++ sy = 0; ++ ++ for (i = 0; i < n; ++i) { ++ node = nodes[i], sx += node.x, sy += node.y; ++ } ++ ++ for (sx = sx / n - x, sy = sy / n - y, i = 0; i < n; ++i) { ++ node = nodes[i], node.x -= sx, node.y -= sy; ++ } ++ } ++ ++ force.initialize = function(_) { ++ nodes = _; ++ }; ++ ++ force.x = function(_) { ++ return arguments.length ? (x = +_, force) : x; ++ }; ++ ++ force.y = function(_) { ++ return arguments.length ? (y = +_, force) : y; ++ }; ++ ++ return force; ++} ++ ++function constant$7(x) { ++ return function() { ++ return x; ++ }; ++} ++ ++function jiggle() { ++ return (Math.random() - 0.5) * 1e-6; ++} ++ ++function tree_add(d) { ++ var x = +this._x.call(null, d), ++ y = +this._y.call(null, d); ++ return add(this.cover(x, y), x, y, d); ++} ++ ++function add(tree, x, y, d) { ++ if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points ++ ++ var parent, ++ node = tree._root, ++ leaf = {data: d}, ++ x0 = tree._x0, ++ y0 = tree._y0, ++ x1 = tree._x1, ++ y1 = tree._y1, ++ xm, ++ ym, ++ xp, ++ yp, ++ right, ++ bottom, ++ i, ++ j; ++ ++ // If the tree is empty, initialize the root as a leaf. ++ if (!node) return tree._root = leaf, tree; ++ ++ // Find the existing leaf for the new point, or add it. ++ while (node.length) { ++ if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; ++ if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; ++ if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree; ++ } ++ ++ // Is the new point is exactly coincident with the existing point? ++ xp = +tree._x.call(null, node.data); ++ yp = +tree._y.call(null, node.data); ++ if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree; ++ ++ // Otherwise, split the leaf node until the old and new point are separated. ++ do { ++ parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4); ++ if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; ++ if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; ++ } while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm))); ++ return parent[j] = node, parent[i] = leaf, tree; ++} ++ ++function addAll(data) { ++ var d, i, n = data.length, ++ x, ++ y, ++ xz = new Array(n), ++ yz = new Array(n), ++ x0 = Infinity, ++ y0 = Infinity, ++ x1 = -Infinity, ++ y1 = -Infinity; ++ ++ // Compute the points and their extent. ++ for (i = 0; i < n; ++i) { ++ if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue; ++ xz[i] = x; ++ yz[i] = y; ++ if (x < x0) x0 = x; ++ if (x > x1) x1 = x; ++ if (y < y0) y0 = y; ++ if (y > y1) y1 = y; ++ } ++ ++ // If there were no (valid) points, inherit the existing extent. ++ if (x1 < x0) x0 = this._x0, x1 = this._x1; ++ if (y1 < y0) y0 = this._y0, y1 = this._y1; ++ ++ // Expand the tree to cover the new points. ++ this.cover(x0, y0).cover(x1, y1); ++ ++ // Add the new points. ++ for (i = 0; i < n; ++i) { ++ add(this, xz[i], yz[i], data[i]); ++ } ++ ++ return this; ++} ++ ++function tree_cover(x, y) { ++ if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points ++ ++ var x0 = this._x0, ++ y0 = this._y0, ++ x1 = this._x1, ++ y1 = this._y1; ++ ++ // If the quadtree has no extent, initialize them. ++ // Integer extent are necessary so that if we later double the extent, ++ // the existing quadrant boundaries don’t change due to floating point error! ++ if (isNaN(x0)) { ++ x1 = (x0 = Math.floor(x)) + 1; ++ y1 = (y0 = Math.floor(y)) + 1; ++ } ++ ++ // Otherwise, double repeatedly to cover. ++ else if (x0 > x || x > x1 || y0 > y || y > y1) { ++ var z = x1 - x0, ++ node = this._root, ++ parent, ++ i; ++ ++ switch (i = (y < (y0 + y1) / 2) << 1 | (x < (x0 + x1) / 2)) { ++ case 0: { ++ do parent = new Array(4), parent[i] = node, node = parent; ++ while (z *= 2, x1 = x0 + z, y1 = y0 + z, x > x1 || y > y1); ++ break; ++ } ++ case 1: { ++ do parent = new Array(4), parent[i] = node, node = parent; ++ while (z *= 2, x0 = x1 - z, y1 = y0 + z, x0 > x || y > y1); ++ break; ++ } ++ case 2: { ++ do parent = new Array(4), parent[i] = node, node = parent; ++ while (z *= 2, x1 = x0 + z, y0 = y1 - z, x > x1 || y0 > y); ++ break; ++ } ++ case 3: { ++ do parent = new Array(4), parent[i] = node, node = parent; ++ while (z *= 2, x0 = x1 - z, y0 = y1 - z, x0 > x || y0 > y); ++ break; ++ } ++ } ++ ++ if (this._root && this._root.length) this._root = node; ++ } ++ ++ // If the quadtree covers the point already, just return. ++ else return this; ++ ++ this._x0 = x0; ++ this._y0 = y0; ++ this._x1 = x1; ++ this._y1 = y1; ++ return this; ++} ++ ++function tree_data() { ++ var data = []; ++ this.visit(function(node) { ++ if (!node.length) do data.push(node.data); while (node = node.next) ++ }); ++ return data; ++} ++ ++function tree_extent(_) { ++ return arguments.length ++ ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1]) ++ : isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]]; ++} ++ ++function Quad(node, x0, y0, x1, y1) { ++ this.node = node; ++ this.x0 = x0; ++ this.y0 = y0; ++ this.x1 = x1; ++ this.y1 = y1; ++} ++ ++function tree_find(x, y, radius) { ++ var data, ++ x0 = this._x0, ++ y0 = this._y0, ++ x1, ++ y1, ++ x2, ++ y2, ++ x3 = this._x1, ++ y3 = this._y1, ++ quads = [], ++ node = this._root, ++ q, ++ i; ++ ++ if (node) quads.push(new Quad(node, x0, y0, x3, y3)); ++ if (radius == null) radius = Infinity; ++ else { ++ x0 = x - radius, y0 = y - radius; ++ x3 = x + radius, y3 = y + radius; ++ radius *= radius; ++ } ++ ++ while (q = quads.pop()) { ++ ++ // Stop searching if this quadrant can’t contain a closer node. ++ if (!(node = q.node) ++ || (x1 = q.x0) > x3 ++ || (y1 = q.y0) > y3 ++ || (x2 = q.x1) < x0 ++ || (y2 = q.y1) < y0) continue; ++ ++ // Bisect the current quadrant. ++ if (node.length) { ++ var xm = (x1 + x2) / 2, ++ ym = (y1 + y2) / 2; ++ ++ quads.push( ++ new Quad(node[3], xm, ym, x2, y2), ++ new Quad(node[2], x1, ym, xm, y2), ++ new Quad(node[1], xm, y1, x2, ym), ++ new Quad(node[0], x1, y1, xm, ym) ++ ); ++ ++ // Visit the closest quadrant first. ++ if (i = (y >= ym) << 1 | (x >= xm)) { ++ q = quads[quads.length - 1]; ++ quads[quads.length - 1] = quads[quads.length - 1 - i]; ++ quads[quads.length - 1 - i] = q; ++ } ++ } ++ ++ // Visit this point. (Visiting coincident points isn’t necessary!) ++ else { ++ var dx = x - +this._x.call(null, node.data), ++ dy = y - +this._y.call(null, node.data), ++ d2 = dx * dx + dy * dy; ++ if (d2 < radius) { ++ var d = Math.sqrt(radius = d2); ++ x0 = x - d, y0 = y - d; ++ x3 = x + d, y3 = y + d; ++ data = node.data; ++ } ++ } ++ } ++ ++ return data; ++} ++ ++function tree_remove(d) { ++ if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points ++ ++ var parent, ++ node = this._root, ++ retainer, ++ previous, ++ next, ++ x0 = this._x0, ++ y0 = this._y0, ++ x1 = this._x1, ++ y1 = this._y1, ++ x, ++ y, ++ xm, ++ ym, ++ right, ++ bottom, ++ i, ++ j; ++ ++ // If the tree is empty, initialize the root as a leaf. ++ if (!node) return this; ++ ++ // Find the leaf node for the point. ++ // While descending, also retain the deepest parent with a non-removed sibling. ++ if (node.length) while (true) { ++ if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; ++ if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; ++ if (!(parent = node, node = node[i = bottom << 1 | right])) return this; ++ if (!node.length) break; ++ if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i; ++ } ++ ++ // Find the point to remove. ++ while (node.data !== d) if (!(previous = node, node = node.next)) return this; ++ if (next = node.next) delete node.next; ++ ++ // If there are multiple coincident points, remove just the point. ++ if (previous) return next ? previous.next = next : delete previous.next, this; ++ ++ // If this is the root point, remove it. ++ if (!parent) return this._root = next, this; ++ ++ // Remove this leaf. ++ next ? parent[i] = next : delete parent[i]; ++ ++ // If the parent now contains exactly one leaf, collapse superfluous parents. ++ if ((node = parent[0] || parent[1] || parent[2] || parent[3]) ++ && node === (parent[3] || parent[2] || parent[1] || parent[0]) ++ && !node.length) { ++ if (retainer) retainer[j] = node; ++ else this._root = node; ++ } ++ ++ return this; ++} ++ ++function removeAll(data) { ++ for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]); ++ return this; ++} ++ ++function tree_root() { ++ return this._root; ++} ++ ++function tree_size() { ++ var size = 0; ++ this.visit(function(node) { ++ if (!node.length) do ++size; while (node = node.next) ++ }); ++ return size; ++} ++ ++function tree_visit(callback) { ++ var quads = [], q, node = this._root, child, x0, y0, x1, y1; ++ if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1)); ++ while (q = quads.pop()) { ++ if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) { ++ var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2; ++ if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1)); ++ if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1)); ++ if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym)); ++ if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym)); ++ } ++ } ++ return this; ++} ++ ++function tree_visitAfter(callback) { ++ var quads = [], next = [], q; ++ if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1)); ++ while (q = quads.pop()) { ++ var node = q.node; ++ if (node.length) { ++ var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2; ++ if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym)); ++ if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym)); ++ if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1)); ++ if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1)); ++ } ++ next.push(q); ++ } ++ while (q = next.pop()) { ++ callback(q.node, q.x0, q.y0, q.x1, q.y1); ++ } ++ return this; ++} ++ ++function defaultX$1(d) { ++ return d[0]; ++} ++ ++function tree_x(_) { ++ return arguments.length ? (this._x = _, this) : this._x; ++} ++ ++function defaultY$1(d) { ++ return d[1]; ++} ++ ++function tree_y(_) { ++ return arguments.length ? (this._y = _, this) : this._y; ++} ++ ++function quadtree(nodes, x, y) { ++ var tree = new Quadtree(x == null ? defaultX$1 : x, y == null ? defaultY$1 : y, NaN, NaN, NaN, NaN); ++ return nodes == null ? tree : tree.addAll(nodes); ++} ++ ++function Quadtree(x, y, x0, y0, x1, y1) { ++ this._x = x; ++ this._y = y; ++ this._x0 = x0; ++ this._y0 = y0; ++ this._x1 = x1; ++ this._y1 = y1; ++ this._root = undefined; ++} ++ ++function leaf_copy(leaf) { ++ var copy = {data: leaf.data}, next = copy; ++ while (leaf = leaf.next) next = next.next = {data: leaf.data}; ++ return copy; ++} ++ ++var treeProto = quadtree.prototype = Quadtree.prototype; ++ ++treeProto.copy = function() { ++ var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1), ++ node = this._root, ++ nodes, ++ child; ++ ++ if (!node) return copy; ++ ++ if (!node.length) return copy._root = leaf_copy(node), copy; ++ ++ nodes = [{source: node, target: copy._root = new Array(4)}]; ++ while (node = nodes.pop()) { ++ for (var i = 0; i < 4; ++i) { ++ if (child = node.source[i]) { ++ if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)}); ++ else node.target[i] = leaf_copy(child); ++ } ++ } ++ } ++ ++ return copy; ++}; ++ ++treeProto.add = tree_add; ++treeProto.addAll = addAll; ++treeProto.cover = tree_cover; ++treeProto.data = tree_data; ++treeProto.extent = tree_extent; ++treeProto.find = tree_find; ++treeProto.remove = tree_remove; ++treeProto.removeAll = removeAll; ++treeProto.root = tree_root; ++treeProto.size = tree_size; ++treeProto.visit = tree_visit; ++treeProto.visitAfter = tree_visitAfter; ++treeProto.x = tree_x; ++treeProto.y = tree_y; ++ ++function x(d) { ++ return d.x + d.vx; ++} ++ ++function y(d) { ++ return d.y + d.vy; ++} ++ ++function collide(radius) { ++ var nodes, ++ radii, ++ strength = 1, ++ iterations = 1; ++ ++ if (typeof radius !== "function") radius = constant$7(radius == null ? 1 : +radius); ++ ++ function force() { ++ var i, n = nodes.length, ++ tree, ++ node, ++ xi, ++ yi, ++ ri, ++ ri2; ++ ++ for (var k = 0; k < iterations; ++k) { ++ tree = quadtree(nodes, x, y).visitAfter(prepare); ++ for (i = 0; i < n; ++i) { ++ node = nodes[i]; ++ ri = radii[node.index], ri2 = ri * ri; ++ xi = node.x + node.vx; ++ yi = node.y + node.vy; ++ tree.visit(apply); ++ } ++ } ++ ++ function apply(quad, x0, y0, x1, y1) { ++ var data = quad.data, rj = quad.r, r = ri + rj; ++ if (data) { ++ if (data.index > node.index) { ++ var x = xi - data.x - data.vx, ++ y = yi - data.y - data.vy, ++ l = x * x + y * y; ++ if (l < r * r) { ++ if (x === 0) x = jiggle(), l += x * x; ++ if (y === 0) y = jiggle(), l += y * y; ++ l = (r - (l = Math.sqrt(l))) / l * strength; ++ node.vx += (x *= l) * (r = (rj *= rj) / (ri2 + rj)); ++ node.vy += (y *= l) * r; ++ data.vx -= x * (r = 1 - r); ++ data.vy -= y * r; ++ } ++ } ++ return; ++ } ++ return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r; ++ } ++ } ++ ++ function prepare(quad) { ++ if (quad.data) return quad.r = radii[quad.data.index]; ++ for (var i = quad.r = 0; i < 4; ++i) { ++ if (quad[i] && quad[i].r > quad.r) { ++ quad.r = quad[i].r; ++ } ++ } ++ } ++ ++ function initialize() { ++ if (!nodes) return; ++ var i, n = nodes.length, node; ++ radii = new Array(n); ++ for (i = 0; i < n; ++i) node = nodes[i], radii[node.index] = +radius(node, i, nodes); ++ } ++ ++ force.initialize = function(_) { ++ nodes = _; ++ initialize(); ++ }; ++ ++ force.iterations = function(_) { ++ return arguments.length ? (iterations = +_, force) : iterations; ++ }; ++ ++ force.strength = function(_) { ++ return arguments.length ? (strength = +_, force) : strength; ++ }; ++ ++ force.radius = function(_) { ++ return arguments.length ? (radius = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : radius; ++ }; ++ ++ return force; ++} ++ ++function index(d) { ++ return d.index; ++} ++ ++function find(nodeById, nodeId) { ++ var node = nodeById.get(nodeId); ++ if (!node) throw new Error("missing: " + nodeId); ++ return node; ++} ++ ++function link(links) { ++ var id = index, ++ strength = defaultStrength, ++ strengths, ++ distance = constant$7(30), ++ distances, ++ nodes, ++ count, ++ bias, ++ iterations = 1; ++ ++ if (links == null) links = []; ++ ++ function defaultStrength(link) { ++ return 1 / Math.min(count[link.source.index], count[link.target.index]); ++ } ++ ++ function force(alpha) { ++ for (var k = 0, n = links.length; k < iterations; ++k) { ++ for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) { ++ link = links[i], source = link.source, target = link.target; ++ x = target.x + target.vx - source.x - source.vx || jiggle(); ++ y = target.y + target.vy - source.y - source.vy || jiggle(); ++ l = Math.sqrt(x * x + y * y); ++ l = (l - distances[i]) / l * alpha * strengths[i]; ++ x *= l, y *= l; ++ target.vx -= x * (b = bias[i]); ++ target.vy -= y * b; ++ source.vx += x * (b = 1 - b); ++ source.vy += y * b; ++ } ++ } ++ } ++ ++ function initialize() { ++ if (!nodes) return; ++ ++ var i, ++ n = nodes.length, ++ m = links.length, ++ nodeById = map$1(nodes, id), ++ link; ++ ++ for (i = 0, count = new Array(n); i < m; ++i) { ++ link = links[i], link.index = i; ++ if (typeof link.source !== "object") link.source = find(nodeById, link.source); ++ if (typeof link.target !== "object") link.target = find(nodeById, link.target); ++ count[link.source.index] = (count[link.source.index] || 0) + 1; ++ count[link.target.index] = (count[link.target.index] || 0) + 1; ++ } ++ ++ for (i = 0, bias = new Array(m); i < m; ++i) { ++ link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]); ++ } ++ ++ strengths = new Array(m), initializeStrength(); ++ distances = new Array(m), initializeDistance(); ++ } ++ ++ function initializeStrength() { ++ if (!nodes) return; ++ ++ for (var i = 0, n = links.length; i < n; ++i) { ++ strengths[i] = +strength(links[i], i, links); ++ } ++ } ++ ++ function initializeDistance() { ++ if (!nodes) return; ++ ++ for (var i = 0, n = links.length; i < n; ++i) { ++ distances[i] = +distance(links[i], i, links); ++ } ++ } ++ ++ force.initialize = function(_) { ++ nodes = _; ++ initialize(); ++ }; ++ ++ force.links = function(_) { ++ return arguments.length ? (links = _, initialize(), force) : links; ++ }; ++ ++ force.id = function(_) { ++ return arguments.length ? (id = _, force) : id; ++ }; ++ ++ force.iterations = function(_) { ++ return arguments.length ? (iterations = +_, force) : iterations; ++ }; ++ ++ force.strength = function(_) { ++ return arguments.length ? (strength = typeof _ === "function" ? _ : constant$7(+_), initializeStrength(), force) : strength; ++ }; ++ ++ force.distance = function(_) { ++ return arguments.length ? (distance = typeof _ === "function" ? _ : constant$7(+_), initializeDistance(), force) : distance; ++ }; ++ ++ return force; ++} ++ ++function x$1(d) { ++ return d.x; ++} ++ ++function y$1(d) { ++ return d.y; ++} ++ ++var initialRadius = 10, ++ initialAngle = Math.PI * (3 - Math.sqrt(5)); ++ ++function simulation(nodes) { ++ var simulation, ++ alpha = 1, ++ alphaMin = 0.001, ++ alphaDecay = 1 - Math.pow(alphaMin, 1 / 300), ++ alphaTarget = 0, ++ velocityDecay = 0.6, ++ forces = map$1(), ++ stepper = timer(step), ++ event = dispatch("tick", "end"); ++ ++ if (nodes == null) nodes = []; ++ ++ function step() { ++ tick(); ++ event.call("tick", simulation); ++ if (alpha < alphaMin) { ++ stepper.stop(); ++ event.call("end", simulation); ++ } ++ } ++ ++ function tick() { ++ var i, n = nodes.length, node; ++ ++ alpha += (alphaTarget - alpha) * alphaDecay; ++ ++ forces.each(function(force) { ++ force(alpha); ++ }); ++ ++ for (i = 0; i < n; ++i) { ++ node = nodes[i]; ++ if (node.fx == null) node.x += node.vx *= velocityDecay; ++ else node.x = node.fx, node.vx = 0; ++ if (node.fy == null) node.y += node.vy *= velocityDecay; ++ else node.y = node.fy, node.vy = 0; ++ } ++ } ++ ++ function initializeNodes() { ++ for (var i = 0, n = nodes.length, node; i < n; ++i) { ++ node = nodes[i], node.index = i; ++ if (isNaN(node.x) || isNaN(node.y)) { ++ var radius = initialRadius * Math.sqrt(i), angle = i * initialAngle; ++ node.x = radius * Math.cos(angle); ++ node.y = radius * Math.sin(angle); ++ } ++ if (isNaN(node.vx) || isNaN(node.vy)) { ++ node.vx = node.vy = 0; ++ } ++ } ++ } ++ ++ function initializeForce(force) { ++ if (force.initialize) force.initialize(nodes); ++ return force; ++ } ++ ++ initializeNodes(); ++ ++ return simulation = { ++ tick: tick, ++ ++ restart: function() { ++ return stepper.restart(step), simulation; ++ }, ++ ++ stop: function() { ++ return stepper.stop(), simulation; ++ }, ++ ++ nodes: function(_) { ++ return arguments.length ? (nodes = _, initializeNodes(), forces.each(initializeForce), simulation) : nodes; ++ }, ++ ++ alpha: function(_) { ++ return arguments.length ? (alpha = +_, simulation) : alpha; ++ }, ++ ++ alphaMin: function(_) { ++ return arguments.length ? (alphaMin = +_, simulation) : alphaMin; ++ }, ++ ++ alphaDecay: function(_) { ++ return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay; ++ }, ++ ++ alphaTarget: function(_) { ++ return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget; ++ }, ++ ++ velocityDecay: function(_) { ++ return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay; ++ }, ++ ++ force: function(name, _) { ++ return arguments.length > 1 ? (_ == null ? forces.remove(name) : forces.set(name, initializeForce(_)), simulation) : forces.get(name); ++ }, ++ ++ find: function(x, y, radius) { ++ var i = 0, ++ n = nodes.length, ++ dx, ++ dy, ++ d2, ++ node, ++ closest; ++ ++ if (radius == null) radius = Infinity; ++ else radius *= radius; ++ ++ for (i = 0; i < n; ++i) { ++ node = nodes[i]; ++ dx = x - node.x; ++ dy = y - node.y; ++ d2 = dx * dx + dy * dy; ++ if (d2 < radius) closest = node, radius = d2; ++ } ++ ++ return closest; ++ }, ++ ++ on: function(name, _) { ++ return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name); ++ } ++ }; ++} ++ ++function manyBody() { ++ var nodes, ++ node, ++ alpha, ++ strength = constant$7(-30), ++ strengths, ++ distanceMin2 = 1, ++ distanceMax2 = Infinity, ++ theta2 = 0.81; ++ ++ function force(_) { ++ var i, n = nodes.length, tree = quadtree(nodes, x$1, y$1).visitAfter(accumulate); ++ for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply); ++ } ++ ++ function initialize() { ++ if (!nodes) return; ++ var i, n = nodes.length, node; ++ strengths = new Array(n); ++ for (i = 0; i < n; ++i) node = nodes[i], strengths[node.index] = +strength(node, i, nodes); ++ } ++ ++ function accumulate(quad) { ++ var strength = 0, q, c, weight = 0, x, y, i; ++ ++ // For internal nodes, accumulate forces from child quadrants. ++ if (quad.length) { ++ for (x = y = i = 0; i < 4; ++i) { ++ if ((q = quad[i]) && (c = Math.abs(q.value))) { ++ strength += q.value, weight += c, x += c * q.x, y += c * q.y; ++ } ++ } ++ quad.x = x / weight; ++ quad.y = y / weight; ++ } ++ ++ // For leaf nodes, accumulate forces from coincident quadrants. ++ else { ++ q = quad; ++ q.x = q.data.x; ++ q.y = q.data.y; ++ do strength += strengths[q.data.index]; ++ while (q = q.next); ++ } ++ ++ quad.value = strength; ++ } ++ ++ function apply(quad, x1, _, x2) { ++ if (!quad.value) return true; ++ ++ var x = quad.x - node.x, ++ y = quad.y - node.y, ++ w = x2 - x1, ++ l = x * x + y * y; ++ ++ // Apply the Barnes-Hut approximation if possible. ++ // Limit forces for very close nodes; randomize direction if coincident. ++ if (w * w / theta2 < l) { ++ if (l < distanceMax2) { ++ if (x === 0) x = jiggle(), l += x * x; ++ if (y === 0) y = jiggle(), l += y * y; ++ if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l); ++ node.vx += x * quad.value * alpha / l; ++ node.vy += y * quad.value * alpha / l; ++ } ++ return true; ++ } ++ ++ // Otherwise, process points directly. ++ else if (quad.length || l >= distanceMax2) return; ++ ++ // Limit forces for very close nodes; randomize direction if coincident. ++ if (quad.data !== node || quad.next) { ++ if (x === 0) x = jiggle(), l += x * x; ++ if (y === 0) y = jiggle(), l += y * y; ++ if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l); ++ } ++ ++ do if (quad.data !== node) { ++ w = strengths[quad.data.index] * alpha / l; ++ node.vx += x * w; ++ node.vy += y * w; ++ } while (quad = quad.next); ++ } ++ ++ force.initialize = function(_) { ++ nodes = _; ++ initialize(); ++ }; ++ ++ force.strength = function(_) { ++ return arguments.length ? (strength = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : strength; ++ }; ++ ++ force.distanceMin = function(_) { ++ return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2); ++ }; ++ ++ force.distanceMax = function(_) { ++ return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2); ++ }; ++ ++ force.theta = function(_) { ++ return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2); ++ }; ++ ++ return force; ++} ++ ++function radial(radius, x, y) { ++ var nodes, ++ strength = constant$7(0.1), ++ strengths, ++ radiuses; ++ ++ if (typeof radius !== "function") radius = constant$7(+radius); ++ if (x == null) x = 0; ++ if (y == null) y = 0; ++ ++ function force(alpha) { ++ for (var i = 0, n = nodes.length; i < n; ++i) { ++ var node = nodes[i], ++ dx = node.x - x || 1e-6, ++ dy = node.y - y || 1e-6, ++ r = Math.sqrt(dx * dx + dy * dy), ++ k = (radiuses[i] - r) * strengths[i] * alpha / r; ++ node.vx += dx * k; ++ node.vy += dy * k; ++ } ++ } ++ ++ function initialize() { ++ if (!nodes) return; ++ var i, n = nodes.length; ++ strengths = new Array(n); ++ radiuses = new Array(n); ++ for (i = 0; i < n; ++i) { ++ radiuses[i] = +radius(nodes[i], i, nodes); ++ strengths[i] = isNaN(radiuses[i]) ? 0 : +strength(nodes[i], i, nodes); ++ } ++ } ++ ++ force.initialize = function(_) { ++ nodes = _, initialize(); ++ }; ++ ++ force.strength = function(_) { ++ return arguments.length ? (strength = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : strength; ++ }; ++ ++ force.radius = function(_) { ++ return arguments.length ? (radius = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : radius; ++ }; ++ ++ force.x = function(_) { ++ return arguments.length ? (x = +_, force) : x; ++ }; ++ ++ force.y = function(_) { ++ return arguments.length ? (y = +_, force) : y; ++ }; ++ ++ return force; ++} ++ ++function x$2(x) { ++ var strength = constant$7(0.1), ++ nodes, ++ strengths, ++ xz; ++ ++ if (typeof x !== "function") x = constant$7(x == null ? 0 : +x); ++ ++ function force(alpha) { ++ for (var i = 0, n = nodes.length, node; i < n; ++i) { ++ node = nodes[i], node.vx += (xz[i] - node.x) * strengths[i] * alpha; ++ } ++ } ++ ++ function initialize() { ++ if (!nodes) return; ++ var i, n = nodes.length; ++ strengths = new Array(n); ++ xz = new Array(n); ++ for (i = 0; i < n; ++i) { ++ strengths[i] = isNaN(xz[i] = +x(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes); ++ } ++ } ++ ++ force.initialize = function(_) { ++ nodes = _; ++ initialize(); ++ }; ++ ++ force.strength = function(_) { ++ return arguments.length ? (strength = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : strength; ++ }; ++ ++ force.x = function(_) { ++ return arguments.length ? (x = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : x; ++ }; ++ ++ return force; ++} ++ ++function y$2(y) { ++ var strength = constant$7(0.1), ++ nodes, ++ strengths, ++ yz; ++ ++ if (typeof y !== "function") y = constant$7(y == null ? 0 : +y); ++ ++ function force(alpha) { ++ for (var i = 0, n = nodes.length, node; i < n; ++i) { ++ node = nodes[i], node.vy += (yz[i] - node.y) * strengths[i] * alpha; ++ } ++ } ++ ++ function initialize() { ++ if (!nodes) return; ++ var i, n = nodes.length; ++ strengths = new Array(n); ++ yz = new Array(n); ++ for (i = 0; i < n; ++i) { ++ strengths[i] = isNaN(yz[i] = +y(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes); ++ } ++ } ++ ++ force.initialize = function(_) { ++ nodes = _; ++ initialize(); ++ }; ++ ++ force.strength = function(_) { ++ return arguments.length ? (strength = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : strength; ++ }; ++ ++ force.y = function(_) { ++ return arguments.length ? (y = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : y; ++ }; ++ ++ return force; ++} ++ ++// 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]. ++function formatDecimal(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) ++ ]; ++} ++ ++function exponent$1(x) { ++ return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN; ++} ++ ++function formatGroup(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); ++ }; ++} ++ ++function formatNumerals(numerals) { ++ return function(value) { ++ return value.replace(/[0-9]/g, function(i) { ++ return numerals[+i]; ++ }); ++ }; ++} ++ ++// [[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; ++ this.fill = match[1] || " "; ++ this.align = match[2] || ">"; ++ this.sign = match[3] || "-"; ++ this.symbol = match[4] || ""; ++ this.zero = !!match[5]; ++ this.width = match[6] && +match[6]; ++ this.comma = !!match[7]; ++ this.precision = match[8] && +match[8].slice(1); ++ this.trim = !!match[9]; ++ this.type = match[10] || ""; ++} ++ ++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.trim ? "~" : "") ++ + this.type; ++}; ++ ++// Trims insignificant zeros, e.g., replaces 1.2000k with 1.2k. ++function formatTrim(s) { ++ out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) { ++ switch (s[i]) { ++ case ".": i0 = i1 = i; break; ++ case "0": if (i0 === 0) i0 = i; i1 = i; break; ++ default: if (i0 > 0) { if (!+s[i]) break out; i0 = 0; } break; ++ } ++ } ++ return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s; ++} ++ ++var prefixExponent; ++ ++function formatPrefixAuto(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! ++} ++ ++function formatRounded(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 = { ++ "%": 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); } ++}; ++ ++function identity$3(x) { ++ return x; ++} ++ ++var prefixes = ["y","z","a","f","p","n","\xB5","m","","k","M","G","T","P","E","Z","Y"]; ++ ++function formatLocale(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, ++ trim = specifier.trim, ++ type = specifier.type; ++ ++ // The "n" type is an alias for ",g". ++ if (type === "n") comma = true, type = "g"; ++ ++ // The "" type, and any invalid type, is an alias for ".12~g". ++ else if (!formatTypes[type]) precision == null && (precision = 12), trim = true, type = "g"; ++ ++ // If zero fill is specified, padding goes after sign and before digits. ++ if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "="; ++ ++ // 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 = /[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 ? 6 ++ : /[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); ++ ++ // Trim insignificant zeros. ++ if (trim) value = formatTrim(value); ++ ++ // 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 = (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + valueSuffix + (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$1(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; ++ ++defaultLocale({ ++ decimal: ".", ++ thousands: ",", ++ grouping: [3], ++ currency: ["$", ""] ++}); ++ ++function defaultLocale(definition) { ++ locale = formatLocale(definition); ++ exports.format = locale.format; ++ exports.formatPrefix = locale.formatPrefix; ++ return locale; ++} ++ ++function precisionFixed(step) { ++ return Math.max(0, -exponent$1(Math.abs(step))); ++} ++ ++function precisionPrefix(step, value) { ++ return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3 - exponent$1(Math.abs(step))); ++} ++ ++function precisionRound(step, max) { ++ step = Math.abs(step), max = Math.abs(max) - step; ++ return Math.max(0, exponent$1(max) - exponent$1(step)) + 1; ++} ++ ++// Adds floating point numbers with twice the normal precision. ++// Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and ++// Fast Robust Geometric Predicates, Discrete & Computational Geometry 18(3) ++// 305–363 (1997). ++// Code adapted from GeographicLib by Charles F. F. Karney, ++// http://geographiclib.sourceforge.net/ ++ ++function adder() { ++ return new Adder; ++} ++ ++function Adder() { ++ this.reset(); ++} ++ ++Adder.prototype = { ++ constructor: Adder, ++ reset: function() { ++ this.s = // rounded value ++ this.t = 0; // exact error ++ }, ++ add: function(y) { ++ add$1(temp, y, this.t); ++ add$1(this, temp.s, this.s); ++ if (this.s) this.t += temp.t; ++ else this.s = temp.t; ++ }, ++ valueOf: function() { ++ return this.s; ++ } ++}; ++ ++var temp = new Adder; ++ ++function add$1(adder, a, b) { ++ var x = adder.s = a + b, ++ bv = x - a, ++ av = x - bv; ++ adder.t = (a - av) + (b - bv); ++} ++ ++var epsilon$2 = 1e-6; ++var epsilon2$1 = 1e-12; ++var pi$3 = Math.PI; ++var halfPi$2 = pi$3 / 2; ++var quarterPi = pi$3 / 4; ++var tau$3 = pi$3 * 2; ++ ++var degrees$1 = 180 / pi$3; ++var radians = pi$3 / 180; ++ ++var abs = Math.abs; ++var atan = Math.atan; ++var atan2 = Math.atan2; ++var cos$1 = Math.cos; ++var ceil = Math.ceil; ++var exp = Math.exp; ++var log = Math.log; ++var pow = Math.pow; ++var sin$1 = Math.sin; ++var sign = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; }; ++var sqrt = Math.sqrt; ++var tan = Math.tan; ++ ++function acos(x) { ++ return x > 1 ? 0 : x < -1 ? pi$3 : Math.acos(x); ++} ++ ++function asin(x) { ++ return x > 1 ? halfPi$2 : x < -1 ? -halfPi$2 : Math.asin(x); ++} ++ ++function haversin(x) { ++ return (x = sin$1(x / 2)) * x; ++} ++ ++function noop$2() {} ++ ++function streamGeometry(geometry, stream) { ++ if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) { ++ streamGeometryType[geometry.type](geometry, stream); ++ } ++} ++ ++var streamObjectType = { ++ Feature: function(object, stream) { ++ streamGeometry(object.geometry, stream); ++ }, ++ FeatureCollection: function(object, stream) { ++ var features = object.features, i = -1, n = features.length; ++ while (++i < n) streamGeometry(features[i].geometry, stream); ++ } ++}; ++ ++var streamGeometryType = { ++ Sphere: function(object, stream) { ++ stream.sphere(); ++ }, ++ Point: function(object, stream) { ++ object = object.coordinates; ++ stream.point(object[0], object[1], object[2]); ++ }, ++ MultiPoint: function(object, stream) { ++ var coordinates = object.coordinates, i = -1, n = coordinates.length; ++ while (++i < n) object = coordinates[i], stream.point(object[0], object[1], object[2]); ++ }, ++ LineString: function(object, stream) { ++ streamLine(object.coordinates, stream, 0); ++ }, ++ MultiLineString: function(object, stream) { ++ var coordinates = object.coordinates, i = -1, n = coordinates.length; ++ while (++i < n) streamLine(coordinates[i], stream, 0); ++ }, ++ Polygon: function(object, stream) { ++ streamPolygon(object.coordinates, stream); ++ }, ++ MultiPolygon: function(object, stream) { ++ var coordinates = object.coordinates, i = -1, n = coordinates.length; ++ while (++i < n) streamPolygon(coordinates[i], stream); ++ }, ++ GeometryCollection: function(object, stream) { ++ var geometries = object.geometries, i = -1, n = geometries.length; ++ while (++i < n) streamGeometry(geometries[i], stream); ++ } ++}; ++ ++function streamLine(coordinates, stream, closed) { ++ var i = -1, n = coordinates.length - closed, coordinate; ++ stream.lineStart(); ++ while (++i < n) coordinate = coordinates[i], stream.point(coordinate[0], coordinate[1], coordinate[2]); ++ stream.lineEnd(); ++} ++ ++function streamPolygon(coordinates, stream) { ++ var i = -1, n = coordinates.length; ++ stream.polygonStart(); ++ while (++i < n) streamLine(coordinates[i], stream, 1); ++ stream.polygonEnd(); ++} ++ ++function geoStream(object, stream) { ++ if (object && streamObjectType.hasOwnProperty(object.type)) { ++ streamObjectType[object.type](object, stream); ++ } else { ++ streamGeometry(object, stream); ++ } ++} ++ ++var areaRingSum = adder(); ++ ++var areaSum = adder(), ++ lambda00, ++ phi00, ++ lambda0, ++ cosPhi0, ++ sinPhi0; ++ ++var areaStream = { ++ point: noop$2, ++ lineStart: noop$2, ++ lineEnd: noop$2, ++ polygonStart: function() { ++ areaRingSum.reset(); ++ areaStream.lineStart = areaRingStart; ++ areaStream.lineEnd = areaRingEnd; ++ }, ++ polygonEnd: function() { ++ var areaRing = +areaRingSum; ++ areaSum.add(areaRing < 0 ? tau$3 + areaRing : areaRing); ++ this.lineStart = this.lineEnd = this.point = noop$2; ++ }, ++ sphere: function() { ++ areaSum.add(tau$3); ++ } ++}; ++ ++function areaRingStart() { ++ areaStream.point = areaPointFirst; ++} ++ ++function areaRingEnd() { ++ areaPoint(lambda00, phi00); ++} ++ ++function areaPointFirst(lambda, phi) { ++ areaStream.point = areaPoint; ++ lambda00 = lambda, phi00 = phi; ++ lambda *= radians, phi *= radians; ++ lambda0 = lambda, cosPhi0 = cos$1(phi = phi / 2 + quarterPi), sinPhi0 = sin$1(phi); ++} ++ ++function areaPoint(lambda, phi) { ++ lambda *= radians, phi *= radians; ++ phi = phi / 2 + quarterPi; // half the angular distance from south pole ++ ++ // Spherical excess E for a spherical triangle with vertices: south pole, ++ // previous point, current point. Uses a formula derived from Cagnoli’s ++ // theorem. See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2). ++ var dLambda = lambda - lambda0, ++ sdLambda = dLambda >= 0 ? 1 : -1, ++ adLambda = sdLambda * dLambda, ++ cosPhi = cos$1(phi), ++ sinPhi = sin$1(phi), ++ k = sinPhi0 * sinPhi, ++ u = cosPhi0 * cosPhi + k * cos$1(adLambda), ++ v = k * sdLambda * sin$1(adLambda); ++ areaRingSum.add(atan2(v, u)); ++ ++ // Advance the previous points. ++ lambda0 = lambda, cosPhi0 = cosPhi, sinPhi0 = sinPhi; ++} ++ ++function area$1(object) { ++ areaSum.reset(); ++ geoStream(object, areaStream); ++ return areaSum * 2; ++} ++ ++function spherical(cartesian) { ++ return [atan2(cartesian[1], cartesian[0]), asin(cartesian[2])]; ++} ++ ++function cartesian(spherical) { ++ var lambda = spherical[0], phi = spherical[1], cosPhi = cos$1(phi); ++ return [cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi)]; ++} ++ ++function cartesianDot(a, b) { ++ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; ++} ++ ++function cartesianCross(a, b) { ++ return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]]; ++} ++ ++// TODO return a ++function cartesianAddInPlace(a, b) { ++ a[0] += b[0], a[1] += b[1], a[2] += b[2]; ++} ++ ++function cartesianScale(vector, k) { ++ return [vector[0] * k, vector[1] * k, vector[2] * k]; ++} ++ ++// TODO return d ++function cartesianNormalizeInPlace(d) { ++ var l = sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]); ++ d[0] /= l, d[1] /= l, d[2] /= l; ++} ++ ++var lambda0$1, phi0, lambda1, phi1, // bounds ++ lambda2, // previous lambda-coordinate ++ lambda00$1, phi00$1, // first point ++ p0, // previous 3D point ++ deltaSum = adder(), ++ ranges, ++ range; ++ ++var boundsStream = { ++ point: boundsPoint, ++ lineStart: boundsLineStart, ++ lineEnd: boundsLineEnd, ++ polygonStart: function() { ++ boundsStream.point = boundsRingPoint; ++ boundsStream.lineStart = boundsRingStart; ++ boundsStream.lineEnd = boundsRingEnd; ++ deltaSum.reset(); ++ areaStream.polygonStart(); ++ }, ++ polygonEnd: function() { ++ areaStream.polygonEnd(); ++ boundsStream.point = boundsPoint; ++ boundsStream.lineStart = boundsLineStart; ++ boundsStream.lineEnd = boundsLineEnd; ++ if (areaRingSum < 0) lambda0$1 = -(lambda1 = 180), phi0 = -(phi1 = 90); ++ else if (deltaSum > epsilon$2) phi1 = 90; ++ else if (deltaSum < -epsilon$2) phi0 = -90; ++ range[0] = lambda0$1, range[1] = lambda1; ++ } ++}; ++ ++function boundsPoint(lambda, phi) { ++ ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]); ++ if (phi < phi0) phi0 = phi; ++ if (phi > phi1) phi1 = phi; ++} ++ ++function linePoint(lambda, phi) { ++ var p = cartesian([lambda * radians, phi * radians]); ++ if (p0) { ++ var normal = cartesianCross(p0, p), ++ equatorial = [normal[1], -normal[0], 0], ++ inflection = cartesianCross(equatorial, normal); ++ cartesianNormalizeInPlace(inflection); ++ inflection = spherical(inflection); ++ var delta = lambda - lambda2, ++ sign$$1 = delta > 0 ? 1 : -1, ++ lambdai = inflection[0] * degrees$1 * sign$$1, ++ phii, ++ antimeridian = abs(delta) > 180; ++ if (antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) { ++ phii = inflection[1] * degrees$1; ++ if (phii > phi1) phi1 = phii; ++ } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) { ++ phii = -inflection[1] * degrees$1; ++ if (phii < phi0) phi0 = phii; ++ } else { ++ if (phi < phi0) phi0 = phi; ++ if (phi > phi1) phi1 = phi; ++ } ++ if (antimeridian) { ++ if (lambda < lambda2) { ++ if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda; ++ } else { ++ if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda; ++ } ++ } else { ++ if (lambda1 >= lambda0$1) { ++ if (lambda < lambda0$1) lambda0$1 = lambda; ++ if (lambda > lambda1) lambda1 = lambda; ++ } else { ++ if (lambda > lambda2) { ++ if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda; ++ } else { ++ if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda; ++ } ++ } ++ } ++ } else { ++ ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]); ++ } ++ if (phi < phi0) phi0 = phi; ++ if (phi > phi1) phi1 = phi; ++ p0 = p, lambda2 = lambda; ++} ++ ++function boundsLineStart() { ++ boundsStream.point = linePoint; ++} ++ ++function boundsLineEnd() { ++ range[0] = lambda0$1, range[1] = lambda1; ++ boundsStream.point = boundsPoint; ++ p0 = null; ++} ++ ++function boundsRingPoint(lambda, phi) { ++ if (p0) { ++ var delta = lambda - lambda2; ++ deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta); ++ } else { ++ lambda00$1 = lambda, phi00$1 = phi; ++ } ++ areaStream.point(lambda, phi); ++ linePoint(lambda, phi); ++} ++ ++function boundsRingStart() { ++ areaStream.lineStart(); ++} ++ ++function boundsRingEnd() { ++ boundsRingPoint(lambda00$1, phi00$1); ++ areaStream.lineEnd(); ++ if (abs(deltaSum) > epsilon$2) lambda0$1 = -(lambda1 = 180); ++ range[0] = lambda0$1, range[1] = lambda1; ++ p0 = null; ++} ++ ++// Finds the left-right distance between two longitudes. ++// This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want ++// the distance between ±180° to be 360°. ++function angle(lambda0, lambda1) { ++ return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1; ++} ++ ++function rangeCompare(a, b) { ++ return a[0] - b[0]; ++} ++ ++function rangeContains(range, x) { ++ return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x; ++} ++ ++function bounds(feature) { ++ var i, n, a, b, merged, deltaMax, delta; ++ ++ phi1 = lambda1 = -(lambda0$1 = phi0 = Infinity); ++ ranges = []; ++ geoStream(feature, boundsStream); ++ ++ // First, sort ranges by their minimum longitudes. ++ if (n = ranges.length) { ++ ranges.sort(rangeCompare); ++ ++ // Then, merge any ranges that overlap. ++ for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) { ++ b = ranges[i]; ++ if (rangeContains(a, b[0]) || rangeContains(a, b[1])) { ++ if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1]; ++ if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0]; ++ } else { ++ merged.push(a = b); ++ } ++ } ++ ++ // Finally, find the largest gap between the merged ranges. ++ // The final bounding box will be the inverse of this gap. ++ for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) { ++ b = merged[i]; ++ if ((delta = angle(a[1], b[0])) > deltaMax) deltaMax = delta, lambda0$1 = b[0], lambda1 = a[1]; ++ } ++ } ++ ++ ranges = range = null; ++ ++ return lambda0$1 === Infinity || phi0 === Infinity ++ ? [[NaN, NaN], [NaN, NaN]] ++ : [[lambda0$1, phi0], [lambda1, phi1]]; ++} ++ ++var W0, W1, ++ X0, Y0, Z0, ++ X1, Y1, Z1, ++ X2, Y2, Z2, ++ lambda00$2, phi00$2, // first point ++ x0, y0, z0; // previous point ++ ++var centroidStream = { ++ sphere: noop$2, ++ point: centroidPoint, ++ lineStart: centroidLineStart, ++ lineEnd: centroidLineEnd, ++ polygonStart: function() { ++ centroidStream.lineStart = centroidRingStart; ++ centroidStream.lineEnd = centroidRingEnd; ++ }, ++ polygonEnd: function() { ++ centroidStream.lineStart = centroidLineStart; ++ centroidStream.lineEnd = centroidLineEnd; ++ } ++}; ++ ++// Arithmetic mean of Cartesian vectors. ++function centroidPoint(lambda, phi) { ++ lambda *= radians, phi *= radians; ++ var cosPhi = cos$1(phi); ++ centroidPointCartesian(cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi)); ++} ++ ++function centroidPointCartesian(x, y, z) { ++ ++W0; ++ X0 += (x - X0) / W0; ++ Y0 += (y - Y0) / W0; ++ Z0 += (z - Z0) / W0; ++} ++ ++function centroidLineStart() { ++ centroidStream.point = centroidLinePointFirst; ++} ++ ++function centroidLinePointFirst(lambda, phi) { ++ lambda *= radians, phi *= radians; ++ var cosPhi = cos$1(phi); ++ x0 = cosPhi * cos$1(lambda); ++ y0 = cosPhi * sin$1(lambda); ++ z0 = sin$1(phi); ++ centroidStream.point = centroidLinePoint; ++ centroidPointCartesian(x0, y0, z0); ++} ++ ++function centroidLinePoint(lambda, phi) { ++ lambda *= radians, phi *= radians; ++ var cosPhi = cos$1(phi), ++ x = cosPhi * cos$1(lambda), ++ y = cosPhi * sin$1(lambda), ++ z = sin$1(phi), ++ w = atan2(sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z); ++ W1 += w; ++ X1 += w * (x0 + (x0 = x)); ++ Y1 += w * (y0 + (y0 = y)); ++ Z1 += w * (z0 + (z0 = z)); ++ centroidPointCartesian(x0, y0, z0); ++} ++ ++function centroidLineEnd() { ++ centroidStream.point = centroidPoint; ++} ++ ++// See J. E. Brock, The Inertia Tensor for a Spherical Triangle, ++// J. Applied Mechanics 42, 239 (1975). ++function centroidRingStart() { ++ centroidStream.point = centroidRingPointFirst; ++} ++ ++function centroidRingEnd() { ++ centroidRingPoint(lambda00$2, phi00$2); ++ centroidStream.point = centroidPoint; ++} ++ ++function centroidRingPointFirst(lambda, phi) { ++ lambda00$2 = lambda, phi00$2 = phi; ++ lambda *= radians, phi *= radians; ++ centroidStream.point = centroidRingPoint; ++ var cosPhi = cos$1(phi); ++ x0 = cosPhi * cos$1(lambda); ++ y0 = cosPhi * sin$1(lambda); ++ z0 = sin$1(phi); ++ centroidPointCartesian(x0, y0, z0); ++} ++ ++function centroidRingPoint(lambda, phi) { ++ lambda *= radians, phi *= radians; ++ var cosPhi = cos$1(phi), ++ x = cosPhi * cos$1(lambda), ++ y = cosPhi * sin$1(lambda), ++ z = sin$1(phi), ++ cx = y0 * z - z0 * y, ++ cy = z0 * x - x0 * z, ++ cz = x0 * y - y0 * x, ++ m = sqrt(cx * cx + cy * cy + cz * cz), ++ w = asin(m), // line weight = angle ++ v = m && -w / m; // area weight multiplier ++ X2 += v * cx; ++ Y2 += v * cy; ++ Z2 += v * cz; ++ W1 += w; ++ X1 += w * (x0 + (x0 = x)); ++ Y1 += w * (y0 + (y0 = y)); ++ Z1 += w * (z0 + (z0 = z)); ++ centroidPointCartesian(x0, y0, z0); ++} ++ ++function centroid(object) { ++ W0 = W1 = ++ X0 = Y0 = Z0 = ++ X1 = Y1 = Z1 = ++ X2 = Y2 = Z2 = 0; ++ geoStream(object, centroidStream); ++ ++ var x = X2, ++ y = Y2, ++ z = Z2, ++ m = x * x + y * y + z * z; ++ ++ // If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid. ++ if (m < epsilon2$1) { ++ x = X1, y = Y1, z = Z1; ++ // If the feature has zero length, fall back to arithmetic mean of point vectors. ++ if (W1 < epsilon$2) x = X0, y = Y0, z = Z0; ++ m = x * x + y * y + z * z; ++ // If the feature still has an undefined ccentroid, then return. ++ if (m < epsilon2$1) return [NaN, NaN]; ++ } ++ ++ return [atan2(y, x) * degrees$1, asin(z / sqrt(m)) * degrees$1]; ++} ++ ++function constant$8(x) { ++ return function() { ++ return x; ++ }; ++} ++ ++function compose(a, b) { ++ ++ function compose(x, y) { ++ return x = a(x, y), b(x[0], x[1]); ++ } ++ ++ if (a.invert && b.invert) compose.invert = function(x, y) { ++ return x = b.invert(x, y), x && a.invert(x[0], x[1]); ++ }; ++ ++ return compose; ++} ++ ++function rotationIdentity(lambda, phi) { ++ return [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi]; ++} ++ ++rotationIdentity.invert = rotationIdentity; ++ ++function rotateRadians(deltaLambda, deltaPhi, deltaGamma) { ++ return (deltaLambda %= tau$3) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma)) ++ : rotationLambda(deltaLambda)) ++ : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma) ++ : rotationIdentity); ++} ++ ++function forwardRotationLambda(deltaLambda) { ++ return function(lambda, phi) { ++ return lambda += deltaLambda, [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi]; ++ }; ++} ++ ++function rotationLambda(deltaLambda) { ++ var rotation = forwardRotationLambda(deltaLambda); ++ rotation.invert = forwardRotationLambda(-deltaLambda); ++ return rotation; ++} ++ ++function rotationPhiGamma(deltaPhi, deltaGamma) { ++ var cosDeltaPhi = cos$1(deltaPhi), ++ sinDeltaPhi = sin$1(deltaPhi), ++ cosDeltaGamma = cos$1(deltaGamma), ++ sinDeltaGamma = sin$1(deltaGamma); ++ ++ function rotation(lambda, phi) { ++ var cosPhi = cos$1(phi), ++ x = cos$1(lambda) * cosPhi, ++ y = sin$1(lambda) * cosPhi, ++ z = sin$1(phi), ++ k = z * cosDeltaPhi + x * sinDeltaPhi; ++ return [ ++ atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi), ++ asin(k * cosDeltaGamma + y * sinDeltaGamma) ++ ]; ++ } ++ ++ rotation.invert = function(lambda, phi) { ++ var cosPhi = cos$1(phi), ++ x = cos$1(lambda) * cosPhi, ++ y = sin$1(lambda) * cosPhi, ++ z = sin$1(phi), ++ k = z * cosDeltaGamma - y * sinDeltaGamma; ++ return [ ++ atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi), ++ asin(k * cosDeltaPhi - x * sinDeltaPhi) ++ ]; ++ }; ++ ++ return rotation; ++} ++ ++function rotation(rotate) { ++ rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0); ++ ++ function forward(coordinates) { ++ coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians); ++ return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates; ++ } ++ ++ forward.invert = function(coordinates) { ++ coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians); ++ return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates; ++ }; ++ ++ return forward; ++} ++ ++// Generates a circle centered at [0°, 0°], with a given radius and precision. ++function circleStream(stream, radius, delta, direction, t0, t1) { ++ if (!delta) return; ++ var cosRadius = cos$1(radius), ++ sinRadius = sin$1(radius), ++ step = direction * delta; ++ if (t0 == null) { ++ t0 = radius + direction * tau$3; ++ t1 = radius - step / 2; ++ } else { ++ t0 = circleRadius(cosRadius, t0); ++ t1 = circleRadius(cosRadius, t1); ++ if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau$3; ++ } ++ for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) { ++ point = spherical([cosRadius, -sinRadius * cos$1(t), -sinRadius * sin$1(t)]); ++ stream.point(point[0], point[1]); ++ } ++} ++ ++// Returns the signed angle of a cartesian point relative to [cosRadius, 0, 0]. ++function circleRadius(cosRadius, point) { ++ point = cartesian(point), point[0] -= cosRadius; ++ cartesianNormalizeInPlace(point); ++ var radius = acos(-point[1]); ++ return ((-point[2] < 0 ? -radius : radius) + tau$3 - epsilon$2) % tau$3; ++} ++ ++function circle() { ++ var center = constant$8([0, 0]), ++ radius = constant$8(90), ++ precision = constant$8(6), ++ ring, ++ rotate, ++ stream = {point: point}; ++ ++ function point(x, y) { ++ ring.push(x = rotate(x, y)); ++ x[0] *= degrees$1, x[1] *= degrees$1; ++ } ++ ++ function circle() { ++ var c = center.apply(this, arguments), ++ r = radius.apply(this, arguments) * radians, ++ p = precision.apply(this, arguments) * radians; ++ ring = []; ++ rotate = rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert; ++ circleStream(stream, r, p, 1); ++ c = {type: "Polygon", coordinates: [ring]}; ++ ring = rotate = null; ++ return c; ++ } ++ ++ circle.center = function(_) { ++ return arguments.length ? (center = typeof _ === "function" ? _ : constant$8([+_[0], +_[1]]), circle) : center; ++ }; ++ ++ circle.radius = function(_) { ++ return arguments.length ? (radius = typeof _ === "function" ? _ : constant$8(+_), circle) : radius; ++ }; ++ ++ circle.precision = function(_) { ++ return arguments.length ? (precision = typeof _ === "function" ? _ : constant$8(+_), circle) : precision; ++ }; ++ ++ return circle; ++} ++ ++function clipBuffer() { ++ var lines = [], ++ line; ++ return { ++ point: function(x, y) { ++ line.push([x, y]); ++ }, ++ lineStart: function() { ++ lines.push(line = []); ++ }, ++ lineEnd: noop$2, ++ rejoin: function() { ++ if (lines.length > 1) lines.push(lines.pop().concat(lines.shift())); ++ }, ++ result: function() { ++ var result = lines; ++ lines = []; ++ line = null; ++ return result; ++ } ++ }; ++} ++ ++function pointEqual(a, b) { ++ return abs(a[0] - b[0]) < epsilon$2 && abs(a[1] - b[1]) < epsilon$2; ++} ++ ++function Intersection(point, points, other, entry) { ++ this.x = point; ++ this.z = points; ++ this.o = other; // another intersection ++ this.e = entry; // is an entry? ++ this.v = false; // visited ++ this.n = this.p = null; // next & previous ++} ++ ++// A generalized polygon clipping algorithm: given a polygon that has been cut ++// into its visible line segments, and rejoins the segments by interpolating ++// along the clip edge. ++function clipRejoin(segments, compareIntersection, startInside, interpolate, stream) { ++ var subject = [], ++ clip = [], ++ i, ++ n; ++ ++ segments.forEach(function(segment) { ++ if ((n = segment.length - 1) <= 0) return; ++ var n, p0 = segment[0], p1 = segment[n], x; ++ ++ // If the first and last points of a segment are coincident, then treat as a ++ // closed ring. TODO if all rings are closed, then the winding order of the ++ // exterior ring should be checked. ++ if (pointEqual(p0, p1)) { ++ stream.lineStart(); ++ for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]); ++ stream.lineEnd(); ++ return; ++ } ++ ++ subject.push(x = new Intersection(p0, segment, null, true)); ++ clip.push(x.o = new Intersection(p0, null, x, false)); ++ subject.push(x = new Intersection(p1, segment, null, false)); ++ clip.push(x.o = new Intersection(p1, null, x, true)); ++ }); ++ ++ if (!subject.length) return; ++ ++ clip.sort(compareIntersection); ++ link$1(subject); ++ link$1(clip); ++ ++ for (i = 0, n = clip.length; i < n; ++i) { ++ clip[i].e = startInside = !startInside; ++ } ++ ++ var start = subject[0], ++ points, ++ point; ++ ++ while (1) { ++ // Find first unvisited intersection. ++ var current = start, ++ isSubject = true; ++ while (current.v) if ((current = current.n) === start) return; ++ points = current.z; ++ stream.lineStart(); ++ do { ++ current.v = current.o.v = true; ++ if (current.e) { ++ if (isSubject) { ++ for (i = 0, n = points.length; i < n; ++i) stream.point((point = points[i])[0], point[1]); ++ } else { ++ interpolate(current.x, current.n.x, 1, stream); ++ } ++ current = current.n; ++ } else { ++ if (isSubject) { ++ points = current.p.z; ++ for (i = points.length - 1; i >= 0; --i) stream.point((point = points[i])[0], point[1]); ++ } else { ++ interpolate(current.x, current.p.x, -1, stream); ++ } ++ current = current.p; ++ } ++ current = current.o; ++ points = current.z; ++ isSubject = !isSubject; ++ } while (!current.v); ++ stream.lineEnd(); ++ } ++} ++ ++function link$1(array) { ++ if (!(n = array.length)) return; ++ var n, ++ i = 0, ++ a = array[0], ++ b; ++ while (++i < n) { ++ a.n = b = array[i]; ++ b.p = a; ++ a = b; ++ } ++ a.n = b = array[0]; ++ b.p = a; ++} ++ ++var sum$1 = adder(); ++ ++function polygonContains(polygon, point) { ++ var lambda = point[0], ++ phi = point[1], ++ sinPhi = sin$1(phi), ++ normal = [sin$1(lambda), -cos$1(lambda), 0], ++ angle = 0, ++ winding = 0; ++ ++ sum$1.reset(); ++ ++ if (sinPhi === 1) phi = halfPi$2 + epsilon$2; ++ else if (sinPhi === -1) phi = -halfPi$2 - epsilon$2; ++ ++ for (var i = 0, n = polygon.length; i < n; ++i) { ++ if (!(m = (ring = polygon[i]).length)) continue; ++ var ring, ++ m, ++ point0 = ring[m - 1], ++ lambda0 = point0[0], ++ phi0 = point0[1] / 2 + quarterPi, ++ sinPhi0 = sin$1(phi0), ++ cosPhi0 = cos$1(phi0); ++ ++ for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) { ++ var point1 = ring[j], ++ lambda1 = point1[0], ++ phi1 = point1[1] / 2 + quarterPi, ++ sinPhi1 = sin$1(phi1), ++ cosPhi1 = cos$1(phi1), ++ delta = lambda1 - lambda0, ++ sign$$1 = delta >= 0 ? 1 : -1, ++ absDelta = sign$$1 * delta, ++ antimeridian = absDelta > pi$3, ++ k = sinPhi0 * sinPhi1; ++ ++ sum$1.add(atan2(k * sign$$1 * sin$1(absDelta), cosPhi0 * cosPhi1 + k * cos$1(absDelta))); ++ angle += antimeridian ? delta + sign$$1 * tau$3 : delta; ++ ++ // Are the longitudes either side of the point’s meridian (lambda), ++ // and are the latitudes smaller than the parallel (phi)? ++ if (antimeridian ^ lambda0 >= lambda ^ lambda1 >= lambda) { ++ var arc = cartesianCross(cartesian(point0), cartesian(point1)); ++ cartesianNormalizeInPlace(arc); ++ var intersection = cartesianCross(normal, arc); ++ cartesianNormalizeInPlace(intersection); ++ var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin(intersection[2]); ++ if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) { ++ winding += antimeridian ^ delta >= 0 ? 1 : -1; ++ } ++ } ++ } ++ } ++ ++ // First, determine whether the South pole is inside or outside: ++ // ++ // It is inside if: ++ // * the polygon winds around it in a clockwise direction. ++ // * the polygon does not (cumulatively) wind around it, but has a negative ++ // (counter-clockwise) area. ++ // ++ // Second, count the (signed) number of times a segment crosses a lambda ++ // from the point to the South pole. If it is zero, then the point is the ++ // same side as the South pole. ++ ++ return (angle < -epsilon$2 || angle < epsilon$2 && sum$1 < -epsilon$2) ^ (winding & 1); ++} ++ ++function clip(pointVisible, clipLine, interpolate, start) { ++ return function(sink) { ++ var line = clipLine(sink), ++ ringBuffer = clipBuffer(), ++ ringSink = clipLine(ringBuffer), ++ polygonStarted = false, ++ polygon, ++ segments, ++ ring; ++ ++ var clip = { ++ point: point, ++ lineStart: lineStart, ++ lineEnd: lineEnd, ++ polygonStart: function() { ++ clip.point = pointRing; ++ clip.lineStart = ringStart; ++ clip.lineEnd = ringEnd; ++ segments = []; ++ polygon = []; ++ }, ++ polygonEnd: function() { ++ clip.point = point; ++ clip.lineStart = lineStart; ++ clip.lineEnd = lineEnd; ++ segments = merge(segments); ++ var startInside = polygonContains(polygon, start); ++ if (segments.length) { ++ if (!polygonStarted) sink.polygonStart(), polygonStarted = true; ++ clipRejoin(segments, compareIntersection, startInside, interpolate, sink); ++ } else if (startInside) { ++ if (!polygonStarted) sink.polygonStart(), polygonStarted = true; ++ sink.lineStart(); ++ interpolate(null, null, 1, sink); ++ sink.lineEnd(); ++ } ++ if (polygonStarted) sink.polygonEnd(), polygonStarted = false; ++ segments = polygon = null; ++ }, ++ sphere: function() { ++ sink.polygonStart(); ++ sink.lineStart(); ++ interpolate(null, null, 1, sink); ++ sink.lineEnd(); ++ sink.polygonEnd(); ++ } ++ }; ++ ++ function point(lambda, phi) { ++ if (pointVisible(lambda, phi)) sink.point(lambda, phi); ++ } ++ ++ function pointLine(lambda, phi) { ++ line.point(lambda, phi); ++ } ++ ++ function lineStart() { ++ clip.point = pointLine; ++ line.lineStart(); ++ } ++ ++ function lineEnd() { ++ clip.point = point; ++ line.lineEnd(); ++ } ++ ++ function pointRing(lambda, phi) { ++ ring.push([lambda, phi]); ++ ringSink.point(lambda, phi); ++ } ++ ++ function ringStart() { ++ ringSink.lineStart(); ++ ring = []; ++ } ++ ++ function ringEnd() { ++ pointRing(ring[0][0], ring[0][1]); ++ ringSink.lineEnd(); ++ ++ var clean = ringSink.clean(), ++ ringSegments = ringBuffer.result(), ++ i, n = ringSegments.length, m, ++ segment, ++ point; ++ ++ ring.pop(); ++ polygon.push(ring); ++ ring = null; ++ ++ if (!n) return; ++ ++ // No intersections. ++ if (clean & 1) { ++ segment = ringSegments[0]; ++ if ((m = segment.length - 1) > 0) { ++ if (!polygonStarted) sink.polygonStart(), polygonStarted = true; ++ sink.lineStart(); ++ for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]); ++ sink.lineEnd(); ++ } ++ return; ++ } ++ ++ // Rejoin connected segments. ++ // TODO reuse ringBuffer.rejoin()? ++ if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift())); ++ ++ segments.push(ringSegments.filter(validSegment)); ++ } ++ ++ return clip; ++ }; ++} ++ ++function validSegment(segment) { ++ return segment.length > 1; ++} ++ ++// Intersections are sorted along the clip edge. For both antimeridian cutting ++// and circle clipping, the same comparison is used. ++function compareIntersection(a, b) { ++ return ((a = a.x)[0] < 0 ? a[1] - halfPi$2 - epsilon$2 : halfPi$2 - a[1]) ++ - ((b = b.x)[0] < 0 ? b[1] - halfPi$2 - epsilon$2 : halfPi$2 - b[1]); ++} ++ ++var clipAntimeridian = clip( ++ function() { return true; }, ++ clipAntimeridianLine, ++ clipAntimeridianInterpolate, ++ [-pi$3, -halfPi$2] ++); ++ ++// Takes a line and cuts into visible segments. Return values: 0 - there were ++// intersections or the line was empty; 1 - no intersections; 2 - there were ++// intersections, and the first and last segments should be rejoined. ++function clipAntimeridianLine(stream) { ++ var lambda0 = NaN, ++ phi0 = NaN, ++ sign0 = NaN, ++ clean; // no intersections ++ ++ return { ++ lineStart: function() { ++ stream.lineStart(); ++ clean = 1; ++ }, ++ point: function(lambda1, phi1) { ++ var sign1 = lambda1 > 0 ? pi$3 : -pi$3, ++ delta = abs(lambda1 - lambda0); ++ if (abs(delta - pi$3) < epsilon$2) { // line crosses a pole ++ stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi$2 : -halfPi$2); ++ stream.point(sign0, phi0); ++ stream.lineEnd(); ++ stream.lineStart(); ++ stream.point(sign1, phi0); ++ stream.point(lambda1, phi0); ++ clean = 0; ++ } else if (sign0 !== sign1 && delta >= pi$3) { // line crosses antimeridian ++ if (abs(lambda0 - sign0) < epsilon$2) lambda0 -= sign0 * epsilon$2; // handle degeneracies ++ if (abs(lambda1 - sign1) < epsilon$2) lambda1 -= sign1 * epsilon$2; ++ phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1); ++ stream.point(sign0, phi0); ++ stream.lineEnd(); ++ stream.lineStart(); ++ stream.point(sign1, phi0); ++ clean = 0; ++ } ++ stream.point(lambda0 = lambda1, phi0 = phi1); ++ sign0 = sign1; ++ }, ++ lineEnd: function() { ++ stream.lineEnd(); ++ lambda0 = phi0 = NaN; ++ }, ++ clean: function() { ++ return 2 - clean; // if intersections, rejoin first and last segments ++ } ++ }; ++} ++ ++function clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) { ++ var cosPhi0, ++ cosPhi1, ++ sinLambda0Lambda1 = sin$1(lambda0 - lambda1); ++ return abs(sinLambda0Lambda1) > epsilon$2 ++ ? atan((sin$1(phi0) * (cosPhi1 = cos$1(phi1)) * sin$1(lambda1) ++ - sin$1(phi1) * (cosPhi0 = cos$1(phi0)) * sin$1(lambda0)) ++ / (cosPhi0 * cosPhi1 * sinLambda0Lambda1)) ++ : (phi0 + phi1) / 2; ++} ++ ++function clipAntimeridianInterpolate(from, to, direction, stream) { ++ var phi; ++ if (from == null) { ++ phi = direction * halfPi$2; ++ stream.point(-pi$3, phi); ++ stream.point(0, phi); ++ stream.point(pi$3, phi); ++ stream.point(pi$3, 0); ++ stream.point(pi$3, -phi); ++ stream.point(0, -phi); ++ stream.point(-pi$3, -phi); ++ stream.point(-pi$3, 0); ++ stream.point(-pi$3, phi); ++ } else if (abs(from[0] - to[0]) > epsilon$2) { ++ var lambda = from[0] < to[0] ? pi$3 : -pi$3; ++ phi = direction * lambda / 2; ++ stream.point(-lambda, phi); ++ stream.point(0, phi); ++ stream.point(lambda, phi); ++ } else { ++ stream.point(to[0], to[1]); ++ } ++} ++ ++function clipCircle(radius) { ++ var cr = cos$1(radius), ++ delta = 6 * radians, ++ smallRadius = cr > 0, ++ notHemisphere = abs(cr) > epsilon$2; // TODO optimise for this common case ++ ++ function interpolate(from, to, direction, stream) { ++ circleStream(stream, radius, delta, direction, from, to); ++ } ++ ++ function visible(lambda, phi) { ++ return cos$1(lambda) * cos$1(phi) > cr; ++ } ++ ++ // Takes a line and cuts into visible segments. Return values used for polygon ++ // clipping: 0 - there were intersections or the line was empty; 1 - no ++ // intersections 2 - there were intersections, and the first and last segments ++ // should be rejoined. ++ function clipLine(stream) { ++ var point0, // previous point ++ c0, // code for previous point ++ v0, // visibility of previous point ++ v00, // visibility of first point ++ clean; // no intersections ++ return { ++ lineStart: function() { ++ v00 = v0 = false; ++ clean = 1; ++ }, ++ point: function(lambda, phi) { ++ var point1 = [lambda, phi], ++ point2, ++ v = visible(lambda, phi), ++ c = smallRadius ++ ? v ? 0 : code(lambda, phi) ++ : v ? code(lambda + (lambda < 0 ? pi$3 : -pi$3), phi) : 0; ++ if (!point0 && (v00 = v0 = v)) stream.lineStart(); ++ // Handle degeneracies. ++ // TODO ignore if not clipping polygons. ++ if (v !== v0) { ++ point2 = intersect(point0, point1); ++ if (!point2 || pointEqual(point0, point2) || pointEqual(point1, point2)) { ++ point1[0] += epsilon$2; ++ point1[1] += epsilon$2; ++ v = visible(point1[0], point1[1]); ++ } ++ } ++ if (v !== v0) { ++ clean = 0; ++ if (v) { ++ // outside going in ++ stream.lineStart(); ++ point2 = intersect(point1, point0); ++ stream.point(point2[0], point2[1]); ++ } else { ++ // inside going out ++ point2 = intersect(point0, point1); ++ stream.point(point2[0], point2[1]); ++ stream.lineEnd(); ++ } ++ point0 = point2; ++ } else if (notHemisphere && point0 && smallRadius ^ v) { ++ var t; ++ // If the codes for two points are different, or are both zero, ++ // and there this segment intersects with the small circle. ++ if (!(c & c0) && (t = intersect(point1, point0, true))) { ++ clean = 0; ++ if (smallRadius) { ++ stream.lineStart(); ++ stream.point(t[0][0], t[0][1]); ++ stream.point(t[1][0], t[1][1]); ++ stream.lineEnd(); ++ } else { ++ stream.point(t[1][0], t[1][1]); ++ stream.lineEnd(); ++ stream.lineStart(); ++ stream.point(t[0][0], t[0][1]); ++ } ++ } ++ } ++ if (v && (!point0 || !pointEqual(point0, point1))) { ++ stream.point(point1[0], point1[1]); ++ } ++ point0 = point1, v0 = v, c0 = c; ++ }, ++ lineEnd: function() { ++ if (v0) stream.lineEnd(); ++ point0 = null; ++ }, ++ // Rejoin first and last segments if there were intersections and the first ++ // and last points were visible. ++ clean: function() { ++ return clean | ((v00 && v0) << 1); ++ } ++ }; ++ } ++ ++ // Intersects the great circle between a and b with the clip circle. ++ function intersect(a, b, two) { ++ var pa = cartesian(a), ++ pb = cartesian(b); ++ ++ // We have two planes, n1.p = d1 and n2.p = d2. ++ // Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2). ++ var n1 = [1, 0, 0], // normal ++ n2 = cartesianCross(pa, pb), ++ n2n2 = cartesianDot(n2, n2), ++ n1n2 = n2[0], // cartesianDot(n1, n2), ++ determinant = n2n2 - n1n2 * n1n2; ++ ++ // Two polar points. ++ if (!determinant) return !two && a; ++ ++ var c1 = cr * n2n2 / determinant, ++ c2 = -cr * n1n2 / determinant, ++ n1xn2 = cartesianCross(n1, n2), ++ A = cartesianScale(n1, c1), ++ B = cartesianScale(n2, c2); ++ cartesianAddInPlace(A, B); ++ ++ // Solve |p(t)|^2 = 1. ++ var u = n1xn2, ++ w = cartesianDot(A, u), ++ uu = cartesianDot(u, u), ++ t2 = w * w - uu * (cartesianDot(A, A) - 1); ++ ++ if (t2 < 0) return; ++ ++ var t = sqrt(t2), ++ q = cartesianScale(u, (-w - t) / uu); ++ cartesianAddInPlace(q, A); ++ q = spherical(q); ++ ++ if (!two) return q; ++ ++ // Two intersection points. ++ var lambda0 = a[0], ++ lambda1 = b[0], ++ phi0 = a[1], ++ phi1 = b[1], ++ z; ++ ++ if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z; ++ ++ var delta = lambda1 - lambda0, ++ polar = abs(delta - pi$3) < epsilon$2, ++ meridian = polar || delta < epsilon$2; ++ ++ if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z; ++ ++ // Check that the first point is between a and b. ++ if (meridian ++ ? polar ++ ? phi0 + phi1 > 0 ^ q[1] < (abs(q[0] - lambda0) < epsilon$2 ? phi0 : phi1) ++ : phi0 <= q[1] && q[1] <= phi1 ++ : delta > pi$3 ^ (lambda0 <= q[0] && q[0] <= lambda1)) { ++ var q1 = cartesianScale(u, (-w + t) / uu); ++ cartesianAddInPlace(q1, A); ++ return [q, spherical(q1)]; ++ } ++ } ++ ++ // Generates a 4-bit vector representing the location of a point relative to ++ // the small circle's bounding box. ++ function code(lambda, phi) { ++ var r = smallRadius ? radius : pi$3 - radius, ++ code = 0; ++ if (lambda < -r) code |= 1; // left ++ else if (lambda > r) code |= 2; // right ++ if (phi < -r) code |= 4; // below ++ else if (phi > r) code |= 8; // above ++ return code; ++ } ++ ++ return clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi$3, radius - pi$3]); ++} ++ ++function clipLine(a, b, x0, y0, x1, y1) { ++ var ax = a[0], ++ ay = a[1], ++ bx = b[0], ++ by = b[1], ++ t0 = 0, ++ t1 = 1, ++ dx = bx - ax, ++ dy = by - ay, ++ r; ++ ++ r = x0 - ax; ++ if (!dx && r > 0) return; ++ r /= dx; ++ if (dx < 0) { ++ if (r < t0) return; ++ if (r < t1) t1 = r; ++ } else if (dx > 0) { ++ if (r > t1) return; ++ if (r > t0) t0 = r; ++ } ++ ++ r = x1 - ax; ++ if (!dx && r < 0) return; ++ r /= dx; ++ if (dx < 0) { ++ if (r > t1) return; ++ if (r > t0) t0 = r; ++ } else if (dx > 0) { ++ if (r < t0) return; ++ if (r < t1) t1 = r; ++ } ++ ++ r = y0 - ay; ++ if (!dy && r > 0) return; ++ r /= dy; ++ if (dy < 0) { ++ if (r < t0) return; ++ if (r < t1) t1 = r; ++ } else if (dy > 0) { ++ if (r > t1) return; ++ if (r > t0) t0 = r; ++ } ++ ++ r = y1 - ay; ++ if (!dy && r < 0) return; ++ r /= dy; ++ if (dy < 0) { ++ if (r > t1) return; ++ if (r > t0) t0 = r; ++ } else if (dy > 0) { ++ if (r < t0) return; ++ if (r < t1) t1 = r; ++ } ++ ++ if (t0 > 0) a[0] = ax + t0 * dx, a[1] = ay + t0 * dy; ++ if (t1 < 1) b[0] = ax + t1 * dx, b[1] = ay + t1 * dy; ++ return true; ++} ++ ++var clipMax = 1e9, clipMin = -clipMax; ++ ++// TODO Use d3-polygon’s polygonContains here for the ring check? ++// TODO Eliminate duplicate buffering in clipBuffer and polygon.push? ++ ++function clipRectangle(x0, y0, x1, y1) { ++ ++ function visible(x, y) { ++ return x0 <= x && x <= x1 && y0 <= y && y <= y1; ++ } ++ ++ function interpolate(from, to, direction, stream) { ++ var a = 0, a1 = 0; ++ if (from == null ++ || (a = corner(from, direction)) !== (a1 = corner(to, direction)) ++ || comparePoint(from, to) < 0 ^ direction > 0) { ++ do stream.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0); ++ while ((a = (a + direction + 4) % 4) !== a1); ++ } else { ++ stream.point(to[0], to[1]); ++ } ++ } ++ ++ function corner(p, direction) { ++ return abs(p[0] - x0) < epsilon$2 ? direction > 0 ? 0 : 3 ++ : abs(p[0] - x1) < epsilon$2 ? direction > 0 ? 2 : 1 ++ : abs(p[1] - y0) < epsilon$2 ? direction > 0 ? 1 : 0 ++ : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon ++ } ++ ++ function compareIntersection(a, b) { ++ return comparePoint(a.x, b.x); ++ } ++ ++ function comparePoint(a, b) { ++ var ca = corner(a, 1), ++ cb = corner(b, 1); ++ return ca !== cb ? ca - cb ++ : ca === 0 ? b[1] - a[1] ++ : ca === 1 ? a[0] - b[0] ++ : ca === 2 ? a[1] - b[1] ++ : b[0] - a[0]; ++ } ++ ++ return function(stream) { ++ var activeStream = stream, ++ bufferStream = clipBuffer(), ++ segments, ++ polygon, ++ ring, ++ x__, y__, v__, // first point ++ x_, y_, v_, // previous point ++ first, ++ clean; ++ ++ var clipStream = { ++ point: point, ++ lineStart: lineStart, ++ lineEnd: lineEnd, ++ polygonStart: polygonStart, ++ polygonEnd: polygonEnd ++ }; ++ ++ function point(x, y) { ++ if (visible(x, y)) activeStream.point(x, y); ++ } ++ ++ function polygonInside() { ++ var winding = 0; ++ ++ for (var i = 0, n = polygon.length; i < n; ++i) { ++ for (var ring = polygon[i], j = 1, m = ring.length, point = ring[0], a0, a1, b0 = point[0], b1 = point[1]; j < m; ++j) { ++ a0 = b0, a1 = b1, point = ring[j], b0 = point[0], b1 = point[1]; ++ if (a1 <= y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1) * (x0 - a0)) ++winding; } ++ else { if (b1 <= y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 - a0)) --winding; } ++ } ++ } ++ ++ return winding; ++ } ++ ++ // Buffer geometry within a polygon and then clip it en masse. ++ function polygonStart() { ++ activeStream = bufferStream, segments = [], polygon = [], clean = true; ++ } ++ ++ function polygonEnd() { ++ var startInside = polygonInside(), ++ cleanInside = clean && startInside, ++ visible = (segments = merge(segments)).length; ++ if (cleanInside || visible) { ++ stream.polygonStart(); ++ if (cleanInside) { ++ stream.lineStart(); ++ interpolate(null, null, 1, stream); ++ stream.lineEnd(); ++ } ++ if (visible) { ++ clipRejoin(segments, compareIntersection, startInside, interpolate, stream); ++ } ++ stream.polygonEnd(); ++ } ++ activeStream = stream, segments = polygon = ring = null; ++ } ++ ++ function lineStart() { ++ clipStream.point = linePoint; ++ if (polygon) polygon.push(ring = []); ++ first = true; ++ v_ = false; ++ x_ = y_ = NaN; ++ } ++ ++ // TODO rather than special-case polygons, simply handle them separately. ++ // Ideally, coincident intersection points should be jittered to avoid ++ // clipping issues. ++ function lineEnd() { ++ if (segments) { ++ linePoint(x__, y__); ++ if (v__ && v_) bufferStream.rejoin(); ++ segments.push(bufferStream.result()); ++ } ++ clipStream.point = point; ++ if (v_) activeStream.lineEnd(); ++ } ++ ++ function linePoint(x, y) { ++ var v = visible(x, y); ++ if (polygon) ring.push([x, y]); ++ if (first) { ++ x__ = x, y__ = y, v__ = v; ++ first = false; ++ if (v) { ++ activeStream.lineStart(); ++ activeStream.point(x, y); ++ } ++ } else { ++ if (v && v_) activeStream.point(x, y); ++ else { ++ var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))], ++ b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))]; ++ if (clipLine(a, b, x0, y0, x1, y1)) { ++ if (!v_) { ++ activeStream.lineStart(); ++ activeStream.point(a[0], a[1]); ++ } ++ activeStream.point(b[0], b[1]); ++ if (!v) activeStream.lineEnd(); ++ clean = false; ++ } else if (v) { ++ activeStream.lineStart(); ++ activeStream.point(x, y); ++ clean = false; ++ } ++ } ++ } ++ x_ = x, y_ = y, v_ = v; ++ } ++ ++ return clipStream; ++ }; ++} ++ ++function extent$1() { ++ var x0 = 0, ++ y0 = 0, ++ x1 = 960, ++ y1 = 500, ++ cache, ++ cacheStream, ++ clip; ++ ++ return clip = { ++ stream: function(stream) { ++ return cache && cacheStream === stream ? cache : cache = clipRectangle(x0, y0, x1, y1)(cacheStream = stream); ++ }, ++ extent: function(_) { ++ return arguments.length ? (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1], cache = cacheStream = null, clip) : [[x0, y0], [x1, y1]]; ++ } ++ }; ++} ++ ++var lengthSum = adder(), ++ lambda0$2, ++ sinPhi0$1, ++ cosPhi0$1; ++ ++var lengthStream = { ++ sphere: noop$2, ++ point: noop$2, ++ lineStart: lengthLineStart, ++ lineEnd: noop$2, ++ polygonStart: noop$2, ++ polygonEnd: noop$2 ++}; ++ ++function lengthLineStart() { ++ lengthStream.point = lengthPointFirst; ++ lengthStream.lineEnd = lengthLineEnd; ++} ++ ++function lengthLineEnd() { ++ lengthStream.point = lengthStream.lineEnd = noop$2; ++} ++ ++function lengthPointFirst(lambda, phi) { ++ lambda *= radians, phi *= radians; ++ lambda0$2 = lambda, sinPhi0$1 = sin$1(phi), cosPhi0$1 = cos$1(phi); ++ lengthStream.point = lengthPoint; ++} ++ ++function lengthPoint(lambda, phi) { ++ lambda *= radians, phi *= radians; ++ var sinPhi = sin$1(phi), ++ cosPhi = cos$1(phi), ++ delta = abs(lambda - lambda0$2), ++ cosDelta = cos$1(delta), ++ sinDelta = sin$1(delta), ++ x = cosPhi * sinDelta, ++ y = cosPhi0$1 * sinPhi - sinPhi0$1 * cosPhi * cosDelta, ++ z = sinPhi0$1 * sinPhi + cosPhi0$1 * cosPhi * cosDelta; ++ lengthSum.add(atan2(sqrt(x * x + y * y), z)); ++ lambda0$2 = lambda, sinPhi0$1 = sinPhi, cosPhi0$1 = cosPhi; ++} ++ ++function length$1(object) { ++ lengthSum.reset(); ++ geoStream(object, lengthStream); ++ return +lengthSum; ++} ++ ++var coordinates = [null, null], ++ object$1 = {type: "LineString", coordinates: coordinates}; ++ ++function distance(a, b) { ++ coordinates[0] = a; ++ coordinates[1] = b; ++ return length$1(object$1); ++} ++ ++var containsObjectType = { ++ Feature: function(object, point) { ++ return containsGeometry(object.geometry, point); ++ }, ++ FeatureCollection: function(object, point) { ++ var features = object.features, i = -1, n = features.length; ++ while (++i < n) if (containsGeometry(features[i].geometry, point)) return true; ++ return false; ++ } ++}; ++ ++var containsGeometryType = { ++ Sphere: function() { ++ return true; ++ }, ++ Point: function(object, point) { ++ return containsPoint(object.coordinates, point); ++ }, ++ MultiPoint: function(object, point) { ++ var coordinates = object.coordinates, i = -1, n = coordinates.length; ++ while (++i < n) if (containsPoint(coordinates[i], point)) return true; ++ return false; ++ }, ++ LineString: function(object, point) { ++ return containsLine(object.coordinates, point); ++ }, ++ MultiLineString: function(object, point) { ++ var coordinates = object.coordinates, i = -1, n = coordinates.length; ++ while (++i < n) if (containsLine(coordinates[i], point)) return true; ++ return false; ++ }, ++ Polygon: function(object, point) { ++ return containsPolygon(object.coordinates, point); ++ }, ++ MultiPolygon: function(object, point) { ++ var coordinates = object.coordinates, i = -1, n = coordinates.length; ++ while (++i < n) if (containsPolygon(coordinates[i], point)) return true; ++ return false; ++ }, ++ GeometryCollection: function(object, point) { ++ var geometries = object.geometries, i = -1, n = geometries.length; ++ while (++i < n) if (containsGeometry(geometries[i], point)) return true; ++ return false; ++ } ++}; ++ ++function containsGeometry(geometry, point) { ++ return geometry && containsGeometryType.hasOwnProperty(geometry.type) ++ ? containsGeometryType[geometry.type](geometry, point) ++ : false; ++} ++ ++function containsPoint(coordinates, point) { ++ return distance(coordinates, point) === 0; ++} ++ ++function containsLine(coordinates, point) { ++ var ab = distance(coordinates[0], coordinates[1]), ++ ao = distance(coordinates[0], point), ++ ob = distance(point, coordinates[1]); ++ return ao + ob <= ab + epsilon$2; ++} ++ ++function containsPolygon(coordinates, point) { ++ return !!polygonContains(coordinates.map(ringRadians), pointRadians(point)); ++} ++ ++function ringRadians(ring) { ++ return ring = ring.map(pointRadians), ring.pop(), ring; ++} ++ ++function pointRadians(point) { ++ return [point[0] * radians, point[1] * radians]; ++} ++ ++function contains$1(object, point) { ++ return (object && containsObjectType.hasOwnProperty(object.type) ++ ? containsObjectType[object.type] ++ : containsGeometry)(object, point); ++} ++ ++function graticuleX(y0, y1, dy) { ++ var y = sequence(y0, y1 - epsilon$2, dy).concat(y1); ++ return function(x) { return y.map(function(y) { return [x, y]; }); }; ++} ++ ++function graticuleY(x0, x1, dx) { ++ var x = sequence(x0, x1 - epsilon$2, dx).concat(x1); ++ return function(y) { return x.map(function(x) { return [x, y]; }); }; ++} ++ ++function graticule() { ++ var x1, x0, X1, X0, ++ y1, y0, Y1, Y0, ++ dx = 10, dy = dx, DX = 90, DY = 360, ++ x, y, X, Y, ++ precision = 2.5; ++ ++ function graticule() { ++ return {type: "MultiLineString", coordinates: lines()}; ++ } ++ ++ function lines() { ++ return sequence(ceil(X0 / DX) * DX, X1, DX).map(X) ++ .concat(sequence(ceil(Y0 / DY) * DY, Y1, DY).map(Y)) ++ .concat(sequence(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs(x % DX) > epsilon$2; }).map(x)) ++ .concat(sequence(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs(y % DY) > epsilon$2; }).map(y)); ++ } ++ ++ graticule.lines = function() { ++ return lines().map(function(coordinates) { return {type: "LineString", coordinates: coordinates}; }); ++ }; ++ ++ graticule.outline = function() { ++ return { ++ type: "Polygon", ++ coordinates: [ ++ X(X0).concat( ++ Y(Y1).slice(1), ++ X(X1).reverse().slice(1), ++ Y(Y0).reverse().slice(1)) ++ ] ++ }; ++ }; ++ ++ graticule.extent = function(_) { ++ if (!arguments.length) return graticule.extentMinor(); ++ return graticule.extentMajor(_).extentMinor(_); ++ }; ++ ++ graticule.extentMajor = function(_) { ++ if (!arguments.length) return [[X0, Y0], [X1, Y1]]; ++ X0 = +_[0][0], X1 = +_[1][0]; ++ Y0 = +_[0][1], Y1 = +_[1][1]; ++ if (X0 > X1) _ = X0, X0 = X1, X1 = _; ++ if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _; ++ return graticule.precision(precision); ++ }; ++ ++ graticule.extentMinor = function(_) { ++ if (!arguments.length) return [[x0, y0], [x1, y1]]; ++ x0 = +_[0][0], x1 = +_[1][0]; ++ y0 = +_[0][1], y1 = +_[1][1]; ++ if (x0 > x1) _ = x0, x0 = x1, x1 = _; ++ if (y0 > y1) _ = y0, y0 = y1, y1 = _; ++ return graticule.precision(precision); ++ }; ++ ++ graticule.step = function(_) { ++ if (!arguments.length) return graticule.stepMinor(); ++ return graticule.stepMajor(_).stepMinor(_); ++ }; ++ ++ graticule.stepMajor = function(_) { ++ if (!arguments.length) return [DX, DY]; ++ DX = +_[0], DY = +_[1]; ++ return graticule; ++ }; ++ ++ graticule.stepMinor = function(_) { ++ if (!arguments.length) return [dx, dy]; ++ dx = +_[0], dy = +_[1]; ++ return graticule; ++ }; ++ ++ graticule.precision = function(_) { ++ if (!arguments.length) return precision; ++ precision = +_; ++ x = graticuleX(y0, y1, 90); ++ y = graticuleY(x0, x1, precision); ++ X = graticuleX(Y0, Y1, 90); ++ Y = graticuleY(X0, X1, precision); ++ return graticule; ++ }; ++ ++ return graticule ++ .extentMajor([[-180, -90 + epsilon$2], [180, 90 - epsilon$2]]) ++ .extentMinor([[-180, -80 - epsilon$2], [180, 80 + epsilon$2]]); ++} ++ ++function graticule10() { ++ return graticule()(); ++} ++ ++function interpolate$1(a, b) { ++ var x0 = a[0] * radians, ++ y0 = a[1] * radians, ++ x1 = b[0] * radians, ++ y1 = b[1] * radians, ++ cy0 = cos$1(y0), ++ sy0 = sin$1(y0), ++ cy1 = cos$1(y1), ++ sy1 = sin$1(y1), ++ kx0 = cy0 * cos$1(x0), ++ ky0 = cy0 * sin$1(x0), ++ kx1 = cy1 * cos$1(x1), ++ ky1 = cy1 * sin$1(x1), ++ d = 2 * asin(sqrt(haversin(y1 - y0) + cy0 * cy1 * haversin(x1 - x0))), ++ k = sin$1(d); ++ ++ var interpolate = d ? function(t) { ++ var B = sin$1(t *= d) / k, ++ A = sin$1(d - t) / k, ++ x = A * kx0 + B * kx1, ++ y = A * ky0 + B * ky1, ++ z = A * sy0 + B * sy1; ++ return [ ++ atan2(y, x) * degrees$1, ++ atan2(z, sqrt(x * x + y * y)) * degrees$1 ++ ]; ++ } : function() { ++ return [x0 * degrees$1, y0 * degrees$1]; ++ }; ++ ++ interpolate.distance = d; ++ ++ return interpolate; ++} ++ ++function identity$4(x) { ++ return x; ++} ++ ++var areaSum$1 = adder(), ++ areaRingSum$1 = adder(), ++ x00, ++ y00, ++ x0$1, ++ y0$1; ++ ++var areaStream$1 = { ++ point: noop$2, ++ lineStart: noop$2, ++ lineEnd: noop$2, ++ polygonStart: function() { ++ areaStream$1.lineStart = areaRingStart$1; ++ areaStream$1.lineEnd = areaRingEnd$1; ++ }, ++ polygonEnd: function() { ++ areaStream$1.lineStart = areaStream$1.lineEnd = areaStream$1.point = noop$2; ++ areaSum$1.add(abs(areaRingSum$1)); ++ areaRingSum$1.reset(); ++ }, ++ result: function() { ++ var area = areaSum$1 / 2; ++ areaSum$1.reset(); ++ return area; ++ } ++}; ++ ++function areaRingStart$1() { ++ areaStream$1.point = areaPointFirst$1; ++} ++ ++function areaPointFirst$1(x, y) { ++ areaStream$1.point = areaPoint$1; ++ x00 = x0$1 = x, y00 = y0$1 = y; ++} ++ ++function areaPoint$1(x, y) { ++ areaRingSum$1.add(y0$1 * x - x0$1 * y); ++ x0$1 = x, y0$1 = y; ++} ++ ++function areaRingEnd$1() { ++ areaPoint$1(x00, y00); ++} ++ ++var x0$2 = Infinity, ++ y0$2 = x0$2, ++ x1 = -x0$2, ++ y1 = x1; ++ ++var boundsStream$1 = { ++ point: boundsPoint$1, ++ lineStart: noop$2, ++ lineEnd: noop$2, ++ polygonStart: noop$2, ++ polygonEnd: noop$2, ++ result: function() { ++ var bounds = [[x0$2, y0$2], [x1, y1]]; ++ x1 = y1 = -(y0$2 = x0$2 = Infinity); ++ return bounds; ++ } ++}; ++ ++function boundsPoint$1(x, y) { ++ if (x < x0$2) x0$2 = x; ++ if (x > x1) x1 = x; ++ if (y < y0$2) y0$2 = y; ++ if (y > y1) y1 = y; ++} ++ ++// TODO Enforce positive area for exterior, negative area for interior? ++ ++var X0$1 = 0, ++ Y0$1 = 0, ++ Z0$1 = 0, ++ X1$1 = 0, ++ Y1$1 = 0, ++ Z1$1 = 0, ++ X2$1 = 0, ++ Y2$1 = 0, ++ Z2$1 = 0, ++ x00$1, ++ y00$1, ++ x0$3, ++ y0$3; ++ ++var centroidStream$1 = { ++ point: centroidPoint$1, ++ lineStart: centroidLineStart$1, ++ lineEnd: centroidLineEnd$1, ++ polygonStart: function() { ++ centroidStream$1.lineStart = centroidRingStart$1; ++ centroidStream$1.lineEnd = centroidRingEnd$1; ++ }, ++ polygonEnd: function() { ++ centroidStream$1.point = centroidPoint$1; ++ centroidStream$1.lineStart = centroidLineStart$1; ++ centroidStream$1.lineEnd = centroidLineEnd$1; ++ }, ++ result: function() { ++ var centroid = Z2$1 ? [X2$1 / Z2$1, Y2$1 / Z2$1] ++ : Z1$1 ? [X1$1 / Z1$1, Y1$1 / Z1$1] ++ : Z0$1 ? [X0$1 / Z0$1, Y0$1 / Z0$1] ++ : [NaN, NaN]; ++ X0$1 = Y0$1 = Z0$1 = ++ X1$1 = Y1$1 = Z1$1 = ++ X2$1 = Y2$1 = Z2$1 = 0; ++ return centroid; ++ } ++}; ++ ++function centroidPoint$1(x, y) { ++ X0$1 += x; ++ Y0$1 += y; ++ ++Z0$1; ++} ++ ++function centroidLineStart$1() { ++ centroidStream$1.point = centroidPointFirstLine; ++} ++ ++function centroidPointFirstLine(x, y) { ++ centroidStream$1.point = centroidPointLine; ++ centroidPoint$1(x0$3 = x, y0$3 = y); ++} ++ ++function centroidPointLine(x, y) { ++ var dx = x - x0$3, dy = y - y0$3, z = sqrt(dx * dx + dy * dy); ++ X1$1 += z * (x0$3 + x) / 2; ++ Y1$1 += z * (y0$3 + y) / 2; ++ Z1$1 += z; ++ centroidPoint$1(x0$3 = x, y0$3 = y); ++} ++ ++function centroidLineEnd$1() { ++ centroidStream$1.point = centroidPoint$1; ++} ++ ++function centroidRingStart$1() { ++ centroidStream$1.point = centroidPointFirstRing; ++} ++ ++function centroidRingEnd$1() { ++ centroidPointRing(x00$1, y00$1); ++} ++ ++function centroidPointFirstRing(x, y) { ++ centroidStream$1.point = centroidPointRing; ++ centroidPoint$1(x00$1 = x0$3 = x, y00$1 = y0$3 = y); ++} ++ ++function centroidPointRing(x, y) { ++ var dx = x - x0$3, ++ dy = y - y0$3, ++ z = sqrt(dx * dx + dy * dy); ++ ++ X1$1 += z * (x0$3 + x) / 2; ++ Y1$1 += z * (y0$3 + y) / 2; ++ Z1$1 += z; ++ ++ z = y0$3 * x - x0$3 * y; ++ X2$1 += z * (x0$3 + x); ++ Y2$1 += z * (y0$3 + y); ++ Z2$1 += z * 3; ++ centroidPoint$1(x0$3 = x, y0$3 = y); ++} ++ ++function PathContext(context) { ++ this._context = context; ++} ++ ++PathContext.prototype = { ++ _radius: 4.5, ++ pointRadius: function(_) { ++ return this._radius = _, this; ++ }, ++ polygonStart: function() { ++ this._line = 0; ++ }, ++ polygonEnd: function() { ++ this._line = NaN; ++ }, ++ lineStart: function() { ++ this._point = 0; ++ }, ++ lineEnd: function() { ++ if (this._line === 0) this._context.closePath(); ++ this._point = NaN; ++ }, ++ point: function(x, y) { ++ switch (this._point) { ++ case 0: { ++ this._context.moveTo(x, y); ++ this._point = 1; ++ break; ++ } ++ case 1: { ++ this._context.lineTo(x, y); ++ break; ++ } ++ default: { ++ this._context.moveTo(x + this._radius, y); ++ this._context.arc(x, y, this._radius, 0, tau$3); ++ break; ++ } ++ } ++ }, ++ result: noop$2 ++}; ++ ++var lengthSum$1 = adder(), ++ lengthRing, ++ x00$2, ++ y00$2, ++ x0$4, ++ y0$4; ++ ++var lengthStream$1 = { ++ point: noop$2, ++ lineStart: function() { ++ lengthStream$1.point = lengthPointFirst$1; ++ }, ++ lineEnd: function() { ++ if (lengthRing) lengthPoint$1(x00$2, y00$2); ++ lengthStream$1.point = noop$2; ++ }, ++ polygonStart: function() { ++ lengthRing = true; ++ }, ++ polygonEnd: function() { ++ lengthRing = null; ++ }, ++ result: function() { ++ var length = +lengthSum$1; ++ lengthSum$1.reset(); ++ return length; ++ } ++}; ++ ++function lengthPointFirst$1(x, y) { ++ lengthStream$1.point = lengthPoint$1; ++ x00$2 = x0$4 = x, y00$2 = y0$4 = y; ++} ++ ++function lengthPoint$1(x, y) { ++ x0$4 -= x, y0$4 -= y; ++ lengthSum$1.add(sqrt(x0$4 * x0$4 + y0$4 * y0$4)); ++ x0$4 = x, y0$4 = y; ++} ++ ++function PathString() { ++ this._string = []; ++} ++ ++PathString.prototype = { ++ _radius: 4.5, ++ _circle: circle$1(4.5), ++ pointRadius: function(_) { ++ if ((_ = +_) !== this._radius) this._radius = _, this._circle = null; ++ return this; ++ }, ++ polygonStart: function() { ++ this._line = 0; ++ }, ++ polygonEnd: function() { ++ this._line = NaN; ++ }, ++ lineStart: function() { ++ this._point = 0; ++ }, ++ lineEnd: function() { ++ if (this._line === 0) this._string.push("Z"); ++ this._point = NaN; ++ }, ++ point: function(x, y) { ++ switch (this._point) { ++ case 0: { ++ this._string.push("M", x, ",", y); ++ this._point = 1; ++ break; ++ } ++ case 1: { ++ this._string.push("L", x, ",", y); ++ break; ++ } ++ default: { ++ if (this._circle == null) this._circle = circle$1(this._radius); ++ this._string.push("M", x, ",", y, this._circle); ++ break; ++ } ++ } ++ }, ++ result: function() { ++ if (this._string.length) { ++ var result = this._string.join(""); ++ this._string = []; ++ return result; ++ } else { ++ return null; ++ } ++ } ++}; ++ ++function circle$1(radius) { ++ return "m0," + radius ++ + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius ++ + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius ++ + "z"; ++} ++ ++function index$1(projection, context) { ++ var pointRadius = 4.5, ++ projectionStream, ++ contextStream; ++ ++ function path(object) { ++ if (object) { ++ if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments)); ++ geoStream(object, projectionStream(contextStream)); ++ } ++ return contextStream.result(); ++ } ++ ++ path.area = function(object) { ++ geoStream(object, projectionStream(areaStream$1)); ++ return areaStream$1.result(); ++ }; ++ ++ path.measure = function(object) { ++ geoStream(object, projectionStream(lengthStream$1)); ++ return lengthStream$1.result(); ++ }; ++ ++ path.bounds = function(object) { ++ geoStream(object, projectionStream(boundsStream$1)); ++ return boundsStream$1.result(); ++ }; ++ ++ path.centroid = function(object) { ++ geoStream(object, projectionStream(centroidStream$1)); ++ return centroidStream$1.result(); ++ }; ++ ++ path.projection = function(_) { ++ return arguments.length ? (projectionStream = _ == null ? (projection = null, identity$4) : (projection = _).stream, path) : projection; ++ }; ++ ++ path.context = function(_) { ++ if (!arguments.length) return context; ++ contextStream = _ == null ? (context = null, new PathString) : new PathContext(context = _); ++ if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius); ++ return path; ++ }; ++ ++ path.pointRadius = function(_) { ++ if (!arguments.length) return pointRadius; ++ pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_); ++ return path; ++ }; ++ ++ return path.projection(projection).context(context); ++} ++ ++function transform(methods) { ++ return { ++ stream: transformer(methods) ++ }; ++} ++ ++function transformer(methods) { ++ return function(stream) { ++ var s = new TransformStream; ++ for (var key in methods) s[key] = methods[key]; ++ s.stream = stream; ++ return s; ++ }; ++} ++ ++function TransformStream() {} ++ ++TransformStream.prototype = { ++ constructor: TransformStream, ++ point: function(x, y) { this.stream.point(x, y); }, ++ sphere: function() { this.stream.sphere(); }, ++ lineStart: function() { this.stream.lineStart(); }, ++ lineEnd: function() { this.stream.lineEnd(); }, ++ polygonStart: function() { this.stream.polygonStart(); }, ++ polygonEnd: function() { this.stream.polygonEnd(); } ++}; ++ ++function fit(projection, fitBounds, object) { ++ var clip = projection.clipExtent && projection.clipExtent(); ++ projection.scale(150).translate([0, 0]); ++ if (clip != null) projection.clipExtent(null); ++ geoStream(object, projection.stream(boundsStream$1)); ++ fitBounds(boundsStream$1.result()); ++ if (clip != null) projection.clipExtent(clip); ++ return projection; ++} ++ ++function fitExtent(projection, extent, object) { ++ return fit(projection, function(b) { ++ var w = extent[1][0] - extent[0][0], ++ h = extent[1][1] - extent[0][1], ++ k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])), ++ x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2, ++ y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2; ++ projection.scale(150 * k).translate([x, y]); ++ }, object); ++} ++ ++function fitSize(projection, size, object) { ++ return fitExtent(projection, [[0, 0], size], object); ++} ++ ++function fitWidth(projection, width, object) { ++ return fit(projection, function(b) { ++ var w = +width, ++ k = w / (b[1][0] - b[0][0]), ++ x = (w - k * (b[1][0] + b[0][0])) / 2, ++ y = -k * b[0][1]; ++ projection.scale(150 * k).translate([x, y]); ++ }, object); ++} ++ ++function fitHeight(projection, height, object) { ++ return fit(projection, function(b) { ++ var h = +height, ++ k = h / (b[1][1] - b[0][1]), ++ x = -k * b[0][0], ++ y = (h - k * (b[1][1] + b[0][1])) / 2; ++ projection.scale(150 * k).translate([x, y]); ++ }, object); ++} ++ ++var maxDepth = 16, // maximum depth of subdivision ++ cosMinDistance = cos$1(30 * radians); // cos(minimum angular distance) ++ ++function resample(project, delta2) { ++ return +delta2 ? resample$1(project, delta2) : resampleNone(project); ++} ++ ++function resampleNone(project) { ++ return transformer({ ++ point: function(x, y) { ++ x = project(x, y); ++ this.stream.point(x[0], x[1]); ++ } ++ }); ++} ++ ++function resample$1(project, delta2) { ++ ++ function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1, b1, c1, depth, stream) { ++ var dx = x1 - x0, ++ dy = y1 - y0, ++ d2 = dx * dx + dy * dy; ++ if (d2 > 4 * delta2 && depth--) { ++ var a = a0 + a1, ++ b = b0 + b1, ++ c = c0 + c1, ++ m = sqrt(a * a + b * b + c * c), ++ phi2 = asin(c /= m), ++ lambda2 = abs(abs(c) - 1) < epsilon$2 || abs(lambda0 - lambda1) < epsilon$2 ? (lambda0 + lambda1) / 2 : atan2(b, a), ++ p = project(lambda2, phi2), ++ x2 = p[0], ++ y2 = p[1], ++ dx2 = x2 - x0, ++ dy2 = y2 - y0, ++ dz = dy * dx2 - dx * dy2; ++ if (dz * dz / d2 > delta2 // perpendicular projected distance ++ || abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close to an end ++ || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance ++ resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /= m, b /= m, c, depth, stream); ++ stream.point(x2, y2); ++ resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c1, depth, stream); ++ } ++ } ++ } ++ return function(stream) { ++ var lambda00, x00, y00, a00, b00, c00, // first point ++ lambda0, x0, y0, a0, b0, c0; // previous point ++ ++ var resampleStream = { ++ point: point, ++ lineStart: lineStart, ++ lineEnd: lineEnd, ++ polygonStart: function() { stream.polygonStart(); resampleStream.lineStart = ringStart; }, ++ polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStart = lineStart; } ++ }; ++ ++ function point(x, y) { ++ x = project(x, y); ++ stream.point(x[0], x[1]); ++ } ++ ++ function lineStart() { ++ x0 = NaN; ++ resampleStream.point = linePoint; ++ stream.lineStart(); ++ } ++ ++ function linePoint(lambda, phi) { ++ var c = cartesian([lambda, phi]), p = project(lambda, phi); ++ resampleLineTo(x0, y0, lambda0, a0, b0, c0, x0 = p[0], y0 = p[1], lambda0 = lambda, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream); ++ stream.point(x0, y0); ++ } ++ ++ function lineEnd() { ++ resampleStream.point = point; ++ stream.lineEnd(); ++ } ++ ++ function ringStart() { ++ lineStart(); ++ resampleStream.point = ringPoint; ++ resampleStream.lineEnd = ringEnd; ++ } ++ ++ function ringPoint(lambda, phi) { ++ linePoint(lambda00 = lambda, phi), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0; ++ resampleStream.point = linePoint; ++ } ++ ++ function ringEnd() { ++ resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, b00, c00, maxDepth, stream); ++ resampleStream.lineEnd = lineEnd; ++ lineEnd(); ++ } ++ ++ return resampleStream; ++ }; ++} ++ ++var transformRadians = transformer({ ++ point: function(x, y) { ++ this.stream.point(x * radians, y * radians); ++ } ++}); ++ ++function transformRotate(rotate) { ++ return transformer({ ++ point: function(x, y) { ++ var r = rotate(x, y); ++ return this.stream.point(r[0], r[1]); ++ } ++ }); ++} ++ ++function scaleTranslate(k, dx, dy) { ++ function transform$$1(x, y) { ++ return [dx + k * x, dy - k * y]; ++ } ++ transform$$1.invert = function(x, y) { ++ return [(x - dx) / k, (dy - y) / k]; ++ }; ++ return transform$$1; ++} ++ ++function scaleTranslateRotate(k, dx, dy, alpha) { ++ var cosAlpha = cos$1(alpha), ++ sinAlpha = sin$1(alpha), ++ a = cosAlpha * k, ++ b = sinAlpha * k, ++ ai = cosAlpha / k, ++ bi = sinAlpha / k, ++ ci = (sinAlpha * dy - cosAlpha * dx) / k, ++ fi = (sinAlpha * dx + cosAlpha * dy) / k; ++ function transform$$1(x, y) { ++ return [a * x - b * y + dx, dy - b * x - a * y]; ++ } ++ transform$$1.invert = function(x, y) { ++ return [ai * x - bi * y + ci, fi - bi * x - ai * y]; ++ }; ++ return transform$$1; ++} ++ ++function projection(project) { ++ return projectionMutator(function() { return project; })(); ++} ++ ++function projectionMutator(projectAt) { ++ var project, ++ k = 150, // scale ++ x = 480, y = 250, // translate ++ lambda = 0, phi = 0, // center ++ deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, // pre-rotate ++ alpha = 0, // post-rotate ++ theta = null, preclip = clipAntimeridian, // pre-clip angle ++ x0 = null, y0, x1, y1, postclip = identity$4, // post-clip extent ++ delta2 = 0.5, // precision ++ projectResample, ++ projectTransform, ++ projectRotateTransform, ++ cache, ++ cacheStream; ++ ++ function projection(point) { ++ return projectRotateTransform(point[0] * radians, point[1] * radians); ++ } ++ ++ function invert(point) { ++ point = projectRotateTransform.invert(point[0], point[1]); ++ return point && [point[0] * degrees$1, point[1] * degrees$1]; ++ } ++ ++ projection.stream = function(stream) { ++ return cache && cacheStream === stream ? cache : cache = transformRadians(transformRotate(rotate)(preclip(projectResample(postclip(cacheStream = stream))))); ++ }; ++ ++ projection.preclip = function(_) { ++ return arguments.length ? (preclip = _, theta = undefined, reset()) : preclip; ++ }; ++ ++ projection.postclip = function(_) { ++ return arguments.length ? (postclip = _, x0 = y0 = x1 = y1 = null, reset()) : postclip; ++ }; ++ ++ projection.clipAngle = function(_) { ++ return arguments.length ? (preclip = +_ ? clipCircle(theta = _ * radians) : (theta = null, clipAntimeridian), reset()) : theta * degrees$1; ++ }; ++ ++ projection.clipExtent = function(_) { ++ return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$4) : clipRectangle(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]]; ++ }; ++ ++ projection.scale = function(_) { ++ return arguments.length ? (k = +_, recenter()) : k; ++ }; ++ ++ projection.translate = function(_) { ++ return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y]; ++ }; ++ ++ projection.center = function(_) { ++ return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees$1, phi * degrees$1]; ++ }; ++ ++ projection.rotate = function(_) { ++ return arguments.length ? (deltaLambda = _[0] % 360 * radians, deltaPhi = _[1] % 360 * radians, deltaGamma = _.length > 2 ? _[2] % 360 * radians : 0, recenter()) : [deltaLambda * degrees$1, deltaPhi * degrees$1, deltaGamma * degrees$1]; ++ }; ++ ++ projection.angle = function(_) { ++ return arguments.length ? (alpha = _ % 360 * radians, recenter()) : alpha * degrees$1; ++ }; ++ ++ projection.precision = function(_) { ++ return arguments.length ? (projectResample = resample(projectTransform, delta2 = _ * _), reset()) : sqrt(delta2); ++ }; ++ ++ projection.fitExtent = function(extent, object) { ++ return fitExtent(projection, extent, object); ++ }; ++ ++ projection.fitSize = function(size, object) { ++ return fitSize(projection, size, object); ++ }; ++ ++ projection.fitWidth = function(width, object) { ++ return fitWidth(projection, width, object); ++ }; ++ ++ projection.fitHeight = function(height, object) { ++ return fitHeight(projection, height, object); ++ }; ++ ++ function recenter() { ++ var center = scaleTranslateRotate(k, 0, 0, alpha).apply(null, project(lambda, phi)), ++ transform$$1 = (alpha ? scaleTranslateRotate : scaleTranslate)(k, x - center[0], y - center[1], alpha); ++ rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma); ++ projectTransform = compose(project, transform$$1); ++ projectRotateTransform = compose(rotate, projectTransform); ++ projectResample = resample(projectTransform, delta2); ++ return reset(); ++ } ++ ++ function reset() { ++ cache = cacheStream = null; ++ return projection; ++ } ++ ++ return function() { ++ project = projectAt.apply(this, arguments); ++ projection.invert = project.invert && invert; ++ return recenter(); ++ }; ++} ++ ++function conicProjection(projectAt) { ++ var phi0 = 0, ++ phi1 = pi$3 / 3, ++ m = projectionMutator(projectAt), ++ p = m(phi0, phi1); ++ ++ p.parallels = function(_) { ++ return arguments.length ? m(phi0 = _[0] * radians, phi1 = _[1] * radians) : [phi0 * degrees$1, phi1 * degrees$1]; ++ }; ++ ++ return p; ++} ++ ++function cylindricalEqualAreaRaw(phi0) { ++ var cosPhi0 = cos$1(phi0); ++ ++ function forward(lambda, phi) { ++ return [lambda * cosPhi0, sin$1(phi) / cosPhi0]; ++ } ++ ++ forward.invert = function(x, y) { ++ return [x / cosPhi0, asin(y * cosPhi0)]; ++ }; ++ ++ return forward; ++} ++ ++function conicEqualAreaRaw(y0, y1) { ++ var sy0 = sin$1(y0), n = (sy0 + sin$1(y1)) / 2; ++ ++ // Are the parallels symmetrical around the Equator? ++ if (abs(n) < epsilon$2) return cylindricalEqualAreaRaw(y0); ++ ++ var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt(c) / n; ++ ++ function project(x, y) { ++ var r = sqrt(c - 2 * n * sin$1(y)) / n; ++ return [r * sin$1(x *= n), r0 - r * cos$1(x)]; ++ } ++ ++ project.invert = function(x, y) { ++ var r0y = r0 - y; ++ return [atan2(x, abs(r0y)) / n * sign(r0y), asin((c - (x * x + r0y * r0y) * n * n) / (2 * n))]; ++ }; ++ ++ return project; ++} ++ ++function conicEqualArea() { ++ return conicProjection(conicEqualAreaRaw) ++ .scale(155.424) ++ .center([0, 33.6442]); ++} ++ ++function albers() { ++ return conicEqualArea() ++ .parallels([29.5, 45.5]) ++ .scale(1070) ++ .translate([480, 250]) ++ .rotate([96, 0]) ++ .center([-0.6, 38.7]); ++} ++ ++// The projections must have mutually exclusive clip regions on the sphere, ++// as this will avoid emitting interleaving lines and polygons. ++function multiplex(streams) { ++ var n = streams.length; ++ return { ++ point: function(x, y) { var i = -1; while (++i < n) streams[i].point(x, y); }, ++ sphere: function() { var i = -1; while (++i < n) streams[i].sphere(); }, ++ lineStart: function() { var i = -1; while (++i < n) streams[i].lineStart(); }, ++ lineEnd: function() { var i = -1; while (++i < n) streams[i].lineEnd(); }, ++ polygonStart: function() { var i = -1; while (++i < n) streams[i].polygonStart(); }, ++ polygonEnd: function() { var i = -1; while (++i < n) streams[i].polygonEnd(); } ++ }; ++} ++ ++// A composite projection for the United States, configured by default for ++// 960×500. The projection also works quite well at 960×600 if you change the ++// scale to 1285 and adjust the translate accordingly. The set of standard ++// parallels for each region comes from USGS, which is published here: ++// http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers ++function albersUsa() { ++ var cache, ++ cacheStream, ++ lower48 = albers(), lower48Point, ++ alaska = conicEqualArea().rotate([154, 0]).center([-2, 58.5]).parallels([55, 65]), alaskaPoint, // EPSG:3338 ++ hawaii = conicEqualArea().rotate([157, 0]).center([-3, 19.9]).parallels([8, 18]), hawaiiPoint, // ESRI:102007 ++ point, pointStream = {point: function(x, y) { point = [x, y]; }}; ++ ++ function albersUsa(coordinates) { ++ var x = coordinates[0], y = coordinates[1]; ++ return point = null, (lower48Point.point(x, y), point) ++ || (alaskaPoint.point(x, y), point) ++ || (hawaiiPoint.point(x, y), point); ++ } ++ ++ albersUsa.invert = function(coordinates) { ++ var k = lower48.scale(), ++ t = lower48.translate(), ++ x = (coordinates[0] - t[0]) / k, ++ y = (coordinates[1] - t[1]) / k; ++ return (y >= 0.120 && y < 0.234 && x >= -0.425 && x < -0.214 ? alaska ++ : y >= 0.166 && y < 0.234 && x >= -0.214 && x < -0.115 ? hawaii ++ : lower48).invert(coordinates); ++ }; ++ ++ albersUsa.stream = function(stream) { ++ return cache && cacheStream === stream ? cache : cache = multiplex([lower48.stream(cacheStream = stream), alaska.stream(stream), hawaii.stream(stream)]); ++ }; ++ ++ albersUsa.precision = function(_) { ++ if (!arguments.length) return lower48.precision(); ++ lower48.precision(_), alaska.precision(_), hawaii.precision(_); ++ return reset(); ++ }; ++ ++ albersUsa.scale = function(_) { ++ if (!arguments.length) return lower48.scale(); ++ lower48.scale(_), alaska.scale(_ * 0.35), hawaii.scale(_); ++ return albersUsa.translate(lower48.translate()); ++ }; ++ ++ albersUsa.translate = function(_) { ++ if (!arguments.length) return lower48.translate(); ++ var k = lower48.scale(), x = +_[0], y = +_[1]; ++ ++ lower48Point = lower48 ++ .translate(_) ++ .clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]]) ++ .stream(pointStream); ++ ++ alaskaPoint = alaska ++ .translate([x - 0.307 * k, y + 0.201 * k]) ++ .clipExtent([[x - 0.425 * k + epsilon$2, y + 0.120 * k + epsilon$2], [x - 0.214 * k - epsilon$2, y + 0.234 * k - epsilon$2]]) ++ .stream(pointStream); ++ ++ hawaiiPoint = hawaii ++ .translate([x - 0.205 * k, y + 0.212 * k]) ++ .clipExtent([[x - 0.214 * k + epsilon$2, y + 0.166 * k + epsilon$2], [x - 0.115 * k - epsilon$2, y + 0.234 * k - epsilon$2]]) ++ .stream(pointStream); ++ ++ return reset(); ++ }; ++ ++ albersUsa.fitExtent = function(extent, object) { ++ return fitExtent(albersUsa, extent, object); ++ }; ++ ++ albersUsa.fitSize = function(size, object) { ++ return fitSize(albersUsa, size, object); ++ }; ++ ++ albersUsa.fitWidth = function(width, object) { ++ return fitWidth(albersUsa, width, object); ++ }; ++ ++ albersUsa.fitHeight = function(height, object) { ++ return fitHeight(albersUsa, height, object); ++ }; ++ ++ function reset() { ++ cache = cacheStream = null; ++ return albersUsa; ++ } ++ ++ return albersUsa.scale(1070); ++} ++ ++function azimuthalRaw(scale) { ++ return function(x, y) { ++ var cx = cos$1(x), ++ cy = cos$1(y), ++ k = scale(cx * cy); ++ return [ ++ k * cy * sin$1(x), ++ k * sin$1(y) ++ ]; ++ } ++} ++ ++function azimuthalInvert(angle) { ++ return function(x, y) { ++ var z = sqrt(x * x + y * y), ++ c = angle(z), ++ sc = sin$1(c), ++ cc = cos$1(c); ++ return [ ++ atan2(x * sc, z * cc), ++ asin(z && y * sc / z) ++ ]; ++ } ++} ++ ++var azimuthalEqualAreaRaw = azimuthalRaw(function(cxcy) { ++ return sqrt(2 / (1 + cxcy)); ++}); ++ ++azimuthalEqualAreaRaw.invert = azimuthalInvert(function(z) { ++ return 2 * asin(z / 2); ++}); ++ ++function azimuthalEqualArea() { ++ return projection(azimuthalEqualAreaRaw) ++ .scale(124.75) ++ .clipAngle(180 - 1e-3); ++} ++ ++var azimuthalEquidistantRaw = azimuthalRaw(function(c) { ++ return (c = acos(c)) && c / sin$1(c); ++}); ++ ++azimuthalEquidistantRaw.invert = azimuthalInvert(function(z) { ++ return z; ++}); ++ ++function azimuthalEquidistant() { ++ return projection(azimuthalEquidistantRaw) ++ .scale(79.4188) ++ .clipAngle(180 - 1e-3); ++} ++ ++function mercatorRaw(lambda, phi) { ++ return [lambda, log(tan((halfPi$2 + phi) / 2))]; ++} ++ ++mercatorRaw.invert = function(x, y) { ++ return [x, 2 * atan(exp(y)) - halfPi$2]; ++}; ++ ++function mercator() { ++ return mercatorProjection(mercatorRaw) ++ .scale(961 / tau$3); ++} ++ ++function mercatorProjection(project) { ++ var m = projection(project), ++ center = m.center, ++ scale = m.scale, ++ translate = m.translate, ++ clipExtent = m.clipExtent, ++ x0 = null, y0, x1, y1; // clip extent ++ ++ m.scale = function(_) { ++ return arguments.length ? (scale(_), reclip()) : scale(); ++ }; ++ ++ m.translate = function(_) { ++ return arguments.length ? (translate(_), reclip()) : translate(); ++ }; ++ ++ m.center = function(_) { ++ return arguments.length ? (center(_), reclip()) : center(); ++ }; ++ ++ m.clipExtent = function(_) { ++ return arguments.length ? (_ == null ? x0 = y0 = x1 = y1 = null : (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reclip()) : x0 == null ? null : [[x0, y0], [x1, y1]]; ++ }; ++ ++ function reclip() { ++ var k = pi$3 * scale(), ++ t = m(rotation(m.rotate()).invert([0, 0])); ++ return clipExtent(x0 == null ++ ? [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]] : project === mercatorRaw ++ ? [[Math.max(t[0] - k, x0), y0], [Math.min(t[0] + k, x1), y1]] ++ : [[x0, Math.max(t[1] - k, y0)], [x1, Math.min(t[1] + k, y1)]]); ++ } ++ ++ return reclip(); ++} ++ ++function tany(y) { ++ return tan((halfPi$2 + y) / 2); ++} ++ ++function conicConformalRaw(y0, y1) { ++ var cy0 = cos$1(y0), ++ n = y0 === y1 ? sin$1(y0) : log(cy0 / cos$1(y1)) / log(tany(y1) / tany(y0)), ++ f = cy0 * pow(tany(y0), n) / n; ++ ++ if (!n) return mercatorRaw; ++ ++ function project(x, y) { ++ if (f > 0) { if (y < -halfPi$2 + epsilon$2) y = -halfPi$2 + epsilon$2; } ++ else { if (y > halfPi$2 - epsilon$2) y = halfPi$2 - epsilon$2; } ++ var r = f / pow(tany(y), n); ++ return [r * sin$1(n * x), f - r * cos$1(n * x)]; ++ } ++ ++ project.invert = function(x, y) { ++ var fy = f - y, r = sign(n) * sqrt(x * x + fy * fy); ++ return [atan2(x, abs(fy)) / n * sign(fy), 2 * atan(pow(f / r, 1 / n)) - halfPi$2]; ++ }; ++ ++ return project; ++} ++ ++function conicConformal() { ++ return conicProjection(conicConformalRaw) ++ .scale(109.5) ++ .parallels([30, 30]); ++} ++ ++function equirectangularRaw(lambda, phi) { ++ return [lambda, phi]; ++} ++ ++equirectangularRaw.invert = equirectangularRaw; ++ ++function equirectangular() { ++ return projection(equirectangularRaw) ++ .scale(152.63); ++} ++ ++function conicEquidistantRaw(y0, y1) { ++ var cy0 = cos$1(y0), ++ n = y0 === y1 ? sin$1(y0) : (cy0 - cos$1(y1)) / (y1 - y0), ++ g = cy0 / n + y0; ++ ++ if (abs(n) < epsilon$2) return equirectangularRaw; ++ ++ function project(x, y) { ++ var gy = g - y, nx = n * x; ++ return [gy * sin$1(nx), g - gy * cos$1(nx)]; ++ } ++ ++ project.invert = function(x, y) { ++ var gy = g - y; ++ return [atan2(x, abs(gy)) / n * sign(gy), g - sign(n) * sqrt(x * x + gy * gy)]; ++ }; ++ ++ return project; ++} ++ ++function conicEquidistant() { ++ return conicProjection(conicEquidistantRaw) ++ .scale(131.154) ++ .center([0, 13.9389]); ++} ++ ++function gnomonicRaw(x, y) { ++ var cy = cos$1(y), k = cos$1(x) * cy; ++ return [cy * sin$1(x) / k, sin$1(y) / k]; ++} ++ ++gnomonicRaw.invert = azimuthalInvert(atan); ++ ++function gnomonic() { ++ return projection(gnomonicRaw) ++ .scale(144.049) ++ .clipAngle(60); ++} ++ ++function scaleTranslate$1(kx, ky, tx, ty) { ++ return kx === 1 && ky === 1 && tx === 0 && ty === 0 ? identity$4 : transformer({ ++ point: function(x, y) { ++ this.stream.point(x * kx + tx, y * ky + ty); ++ } ++ }); ++} ++ ++function identity$5() { ++ var k = 1, tx = 0, ty = 0, sx = 1, sy = 1, transform$$1 = identity$4, // scale, translate and reflect ++ x0 = null, y0, x1, y1, // clip extent ++ postclip = identity$4, ++ cache, ++ cacheStream, ++ projection; ++ ++ function reset() { ++ cache = cacheStream = null; ++ return projection; ++ } ++ ++ return projection = { ++ stream: function(stream) { ++ return cache && cacheStream === stream ? cache : cache = transform$$1(postclip(cacheStream = stream)); ++ }, ++ postclip: function(_) { ++ return arguments.length ? (postclip = _, x0 = y0 = x1 = y1 = null, reset()) : postclip; ++ }, ++ clipExtent: function(_) { ++ return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$4) : clipRectangle(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]]; ++ }, ++ scale: function(_) { ++ return arguments.length ? (transform$$1 = scaleTranslate$1((k = +_) * sx, k * sy, tx, ty), reset()) : k; ++ }, ++ translate: function(_) { ++ return arguments.length ? (transform$$1 = scaleTranslate$1(k * sx, k * sy, tx = +_[0], ty = +_[1]), reset()) : [tx, ty]; ++ }, ++ reflectX: function(_) { ++ return arguments.length ? (transform$$1 = scaleTranslate$1(k * (sx = _ ? -1 : 1), k * sy, tx, ty), reset()) : sx < 0; ++ }, ++ reflectY: function(_) { ++ return arguments.length ? (transform$$1 = scaleTranslate$1(k * sx, k * (sy = _ ? -1 : 1), tx, ty), reset()) : sy < 0; ++ }, ++ fitExtent: function(extent, object) { ++ return fitExtent(projection, extent, object); ++ }, ++ fitSize: function(size, object) { ++ return fitSize(projection, size, object); ++ }, ++ fitWidth: function(width, object) { ++ return fitWidth(projection, width, object); ++ }, ++ fitHeight: function(height, object) { ++ return fitHeight(projection, height, object); ++ } ++ }; ++} ++ ++function naturalEarth1Raw(lambda, phi) { ++ var phi2 = phi * phi, phi4 = phi2 * phi2; ++ return [ ++ lambda * (0.8707 - 0.131979 * phi2 + phi4 * (-0.013791 + phi4 * (0.003971 * phi2 - 0.001529 * phi4))), ++ phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4))) ++ ]; ++} ++ ++naturalEarth1Raw.invert = function(x, y) { ++ var phi = y, i = 25, delta; ++ do { ++ var phi2 = phi * phi, phi4 = phi2 * phi2; ++ phi -= delta = (phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4))) - y) / ++ (1.007226 + phi2 * (0.015085 * 3 + phi4 * (-0.044475 * 7 + 0.028874 * 9 * phi2 - 0.005916 * 11 * phi4))); ++ } while (abs(delta) > epsilon$2 && --i > 0); ++ return [ ++ x / (0.8707 + (phi2 = phi * phi) * (-0.131979 + phi2 * (-0.013791 + phi2 * phi2 * phi2 * (0.003971 - 0.001529 * phi2)))), ++ phi ++ ]; ++}; ++ ++function naturalEarth1() { ++ return projection(naturalEarth1Raw) ++ .scale(175.295); ++} ++ ++function orthographicRaw(x, y) { ++ return [cos$1(y) * sin$1(x), sin$1(y)]; ++} ++ ++orthographicRaw.invert = azimuthalInvert(asin); ++ ++function orthographic() { ++ return projection(orthographicRaw) ++ .scale(249.5) ++ .clipAngle(90 + epsilon$2); ++} ++ ++function stereographicRaw(x, y) { ++ var cy = cos$1(y), k = 1 + cos$1(x) * cy; ++ return [cy * sin$1(x) / k, sin$1(y) / k]; ++} ++ ++stereographicRaw.invert = azimuthalInvert(function(z) { ++ return 2 * atan(z); ++}); ++ ++function stereographic() { ++ return projection(stereographicRaw) ++ .scale(250) ++ .clipAngle(142); ++} ++ ++function transverseMercatorRaw(lambda, phi) { ++ return [log(tan((halfPi$2 + phi) / 2)), -lambda]; ++} ++ ++transverseMercatorRaw.invert = function(x, y) { ++ return [-y, 2 * atan(exp(x)) - halfPi$2]; ++}; ++ ++function transverseMercator() { ++ var m = mercatorProjection(transverseMercatorRaw), ++ center = m.center, ++ rotate = m.rotate; ++ ++ m.center = function(_) { ++ return arguments.length ? center([-_[1], _[0]]) : (_ = center(), [_[1], -_[0]]); ++ }; ++ ++ m.rotate = function(_) { ++ return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 : 90]) : (_ = rotate(), [_[0], _[1], _[2] - 90]); ++ }; ++ ++ return rotate([0, 0, 90]) ++ .scale(159.155); ++} ++ ++function defaultSeparation(a, b) { ++ return a.parent === b.parent ? 1 : 2; ++} ++ ++function meanX(children) { ++ return children.reduce(meanXReduce, 0) / children.length; ++} ++ ++function meanXReduce(x, c) { ++ return x + c.x; ++} ++ ++function maxY(children) { ++ return 1 + children.reduce(maxYReduce, 0); ++} ++ ++function maxYReduce(y, c) { ++ return Math.max(y, c.y); ++} ++ ++function leafLeft(node) { ++ var children; ++ while (children = node.children) node = children[0]; ++ return node; ++} ++ ++function leafRight(node) { ++ var children; ++ while (children = node.children) node = children[children.length - 1]; ++ return node; ++} ++ ++function cluster() { ++ var separation = defaultSeparation, ++ dx = 1, ++ dy = 1, ++ nodeSize = false; ++ ++ function cluster(root) { ++ var previousNode, ++ x = 0; ++ ++ // First walk, computing the initial x & y values. ++ root.eachAfter(function(node) { ++ var children = node.children; ++ if (children) { ++ node.x = meanX(children); ++ node.y = maxY(children); ++ } else { ++ node.x = previousNode ? x += separation(node, previousNode) : 0; ++ node.y = 0; ++ previousNode = node; ++ } ++ }); ++ ++ var left = leafLeft(root), ++ right = leafRight(root), ++ x0 = left.x - separation(left, right) / 2, ++ x1 = right.x + separation(right, left) / 2; ++ ++ // Second walk, normalizing x & y to the desired size. ++ return root.eachAfter(nodeSize ? function(node) { ++ node.x = (node.x - root.x) * dx; ++ node.y = (root.y - node.y) * dy; ++ } : function(node) { ++ node.x = (node.x - x0) / (x1 - x0) * dx; ++ node.y = (1 - (root.y ? node.y / root.y : 1)) * dy; ++ }); ++ } ++ ++ cluster.separation = function(x) { ++ return arguments.length ? (separation = x, cluster) : separation; ++ }; ++ ++ cluster.size = function(x) { ++ return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? null : [dx, dy]); ++ }; ++ ++ cluster.nodeSize = function(x) { ++ return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? [dx, dy] : null); ++ }; ++ ++ return cluster; ++} ++ ++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; ++} ++ ++function node_count() { ++ return this.eachAfter(count); ++} ++ ++function node_each(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; ++} ++ ++function node_eachBefore(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; ++} ++ ++function node_eachAfter(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; ++} ++ ++function node_sum(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; ++ }); ++} ++ ++function node_sort(compare) { ++ return this.eachBefore(function(node) { ++ if (node.children) { ++ node.children.sort(compare); ++ } ++ }); ++} ++ ++function node_path(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; ++} ++ ++function node_ancestors() { ++ var node = this, nodes = [node]; ++ while (node = node.parent) { ++ nodes.push(node); ++ } ++ return nodes; ++} ++ ++function node_descendants() { ++ var nodes = []; ++ this.each(function(node) { ++ nodes.push(node); ++ }); ++ return nodes; ++} ++ ++function node_leaves() { ++ var leaves = []; ++ this.eachBefore(function(node) { ++ if (!node.children) { ++ leaves.push(node); ++ } ++ }); ++ return leaves; ++} ++ ++function node_links() { ++ 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 slice$4 = Array.prototype.slice; ++ ++function shuffle$1(array) { ++ var m = array.length, ++ t, ++ i; ++ ++ while (m) { ++ i = Math.random() * m-- | 0; ++ t = array[m]; ++ array[m] = array[i]; ++ array[i] = t; ++ } ++ ++ return array; ++} ++ ++function enclose(circles) { ++ var i = 0, n = (circles = shuffle$1(slice$4.call(circles))).length, B = [], p, e; ++ ++ while (i < n) { ++ p = circles[i]; ++ if (e && enclosesWeak(e, p)) ++i; ++ else e = encloseBasis(B = extendBasis(B, p)), i = 0; ++ } ++ ++ return e; ++} ++ ++function extendBasis(B, p) { ++ var i, j; ++ ++ if (enclosesWeakAll(p, B)) return [p]; ++ ++ // If we get here then B must have at least one element. ++ for (i = 0; i < B.length; ++i) { ++ if (enclosesNot(p, B[i]) ++ && enclosesWeakAll(encloseBasis2(B[i], p), B)) { ++ return [B[i], p]; ++ } ++ } ++ ++ // If we get here then B must have at least two elements. ++ for (i = 0; i < B.length - 1; ++i) { ++ for (j = i + 1; j < B.length; ++j) { ++ if (enclosesNot(encloseBasis2(B[i], B[j]), p) ++ && enclosesNot(encloseBasis2(B[i], p), B[j]) ++ && enclosesNot(encloseBasis2(B[j], p), B[i]) ++ && enclosesWeakAll(encloseBasis3(B[i], B[j], p), B)) { ++ return [B[i], B[j], p]; ++ } ++ } ++ } ++ ++ // If we get here then something is very wrong. ++ throw new Error; ++} ++ ++function enclosesNot(a, b) { ++ var dr = a.r - b.r, dx = b.x - a.x, dy = b.y - a.y; ++ return dr < 0 || dr * dr < dx * dx + dy * dy; ++} ++ ++function enclosesWeak(a, b) { ++ var dr = a.r - b.r + 1e-6, dx = b.x - a.x, dy = b.y - a.y; ++ return dr > 0 && dr * dr > dx * dx + dy * dy; ++} ++ ++function enclosesWeakAll(a, B) { ++ for (var i = 0; i < B.length; ++i) { ++ if (!enclosesWeak(a, B[i])) { ++ return false; ++ } ++ } ++ return true; ++} ++ ++function encloseBasis(B) { ++ switch (B.length) { ++ case 1: return encloseBasis1(B[0]); ++ case 2: return encloseBasis2(B[0], B[1]); ++ case 3: return encloseBasis3(B[0], B[1], B[2]); ++ } ++} ++ ++function encloseBasis1(a) { ++ return { ++ x: a.x, ++ y: a.y, ++ r: a.r ++ }; ++} ++ ++function encloseBasis2(a, b) { ++ var x1 = a.x, y1 = a.y, r1 = a.r, ++ x2 = b.x, y2 = b.y, r2 = b.r, ++ x21 = x2 - x1, y21 = y2 - y1, r21 = r2 - r1, ++ l = Math.sqrt(x21 * x21 + y21 * y21); ++ return { ++ x: (x1 + x2 + x21 / l * r21) / 2, ++ y: (y1 + y2 + y21 / l * r21) / 2, ++ r: (l + r1 + r2) / 2 ++ }; ++} ++ ++function encloseBasis3(a, b, c) { ++ var x1 = a.x, y1 = a.y, r1 = a.r, ++ x2 = b.x, y2 = b.y, r2 = b.r, ++ x3 = c.x, y3 = c.y, r3 = c.r, ++ a2 = x1 - x2, ++ a3 = x1 - x3, ++ b2 = y1 - y2, ++ b3 = y1 - y3, ++ c2 = r2 - r1, ++ c3 = r3 - r1, ++ d1 = x1 * x1 + y1 * y1 - r1 * r1, ++ d2 = d1 - x2 * x2 - y2 * y2 + r2 * r2, ++ d3 = d1 - x3 * x3 - y3 * y3 + r3 * r3, ++ ab = a3 * b2 - a2 * b3, ++ xa = (b2 * d3 - b3 * d2) / (ab * 2) - x1, ++ xb = (b3 * c2 - b2 * c3) / ab, ++ ya = (a3 * d2 - a2 * d3) / (ab * 2) - y1, ++ yb = (a2 * c3 - a3 * c2) / ab, ++ A = xb * xb + yb * yb - 1, ++ B = 2 * (r1 + xa * xb + ya * yb), ++ C = xa * xa + ya * ya - r1 * r1, ++ r = -(A ? (B + Math.sqrt(B * B - 4 * A * C)) / (2 * A) : C / B); ++ return { ++ x: x1 + xa + xb * r, ++ y: y1 + ya + yb * r, ++ r: r ++ }; ++} ++ ++function place(b, a, c) { ++ var dx = b.x - a.x, x, a2, ++ dy = b.y - a.y, y, b2, ++ d2 = dx * dx + dy * dy; ++ if (d2) { ++ a2 = a.r + c.r, a2 *= a2; ++ b2 = b.r + c.r, b2 *= b2; ++ if (a2 > b2) { ++ x = (d2 + b2 - a2) / (2 * d2); ++ y = Math.sqrt(Math.max(0, b2 / d2 - x * x)); ++ c.x = b.x - x * dx - y * dy; ++ c.y = b.y - x * dy + y * dx; ++ } else { ++ x = (d2 + a2 - b2) / (2 * d2); ++ y = Math.sqrt(Math.max(0, a2 / d2 - x * x)); ++ c.x = a.x + x * dx - y * dy; ++ c.y = a.y + x * dy + y * dx; ++ } ++ } else { ++ c.x = a.x + c.r; ++ c.y = a.y; ++ } ++} ++ ++function intersects(a, b) { ++ var dr = a.r + b.r - 1e-6, dx = b.x - a.x, dy = b.y - a.y; ++ return dr > 0 && dr * dr > dx * dx + dy * dy; ++} ++ ++function score(node) { ++ var a = node._, ++ b = node.next._, ++ ab = a.r + b.r, ++ dx = (a.x * b.r + b.x * a.r) / ab, ++ dy = (a.y * b.r + b.y * a.r) / ab; ++ return dx * dx + dy * dy; ++} ++ ++function Node$1(circle) { ++ this._ = circle; ++ this.next = null; ++ this.previous = null; ++} ++ ++function packEnclose(circles) { ++ if (!(n = circles.length)) return 0; ++ ++ var a, b, c, n, aa, ca, i, j, k, sj, sk; ++ ++ // Place the first circle. ++ a = circles[0], a.x = 0, a.y = 0; ++ if (!(n > 1)) return a.r; ++ ++ // Place the second circle. ++ b = circles[1], a.x = -b.r, b.x = a.r, b.y = 0; ++ if (!(n > 2)) return a.r + b.r; ++ ++ // Place the third circle. ++ place(b, a, c = circles[2]); ++ ++ // Initialize the front-chain using the first three circles a, b and c. ++ a = new Node$1(a), b = new Node$1(b), c = new Node$1(c); ++ a.next = c.previous = b; ++ b.next = a.previous = c; ++ c.next = b.previous = a; ++ ++ // Attempt to place each remaining circle… ++ pack: for (i = 3; i < n; ++i) { ++ place(a._, b._, c = circles[i]), c = new Node$1(c); ++ ++ // Find the closest intersecting circle on the front-chain, if any. ++ // “Closeness” is determined by linear distance along the front-chain. ++ // “Ahead” or “behind” is likewise determined by linear distance. ++ j = b.next, k = a.previous, sj = b._.r, sk = a._.r; ++ do { ++ if (sj <= sk) { ++ if (intersects(j._, c._)) { ++ b = j, a.next = b, b.previous = a, --i; ++ continue pack; ++ } ++ sj += j._.r, j = j.next; ++ } else { ++ if (intersects(k._, c._)) { ++ a = k, a.next = b, b.previous = a, --i; ++ continue pack; ++ } ++ sk += k._.r, k = k.previous; ++ } ++ } while (j !== k.next); ++ ++ // Success! Insert the new circle c between a and b. ++ c.previous = a, c.next = b, a.next = b.previous = b = c; ++ ++ // Compute the new closest circle pair to the centroid. ++ aa = score(a); ++ while ((c = c.next) !== b) { ++ if ((ca = score(c)) < aa) { ++ a = c, aa = ca; ++ } ++ } ++ b = a.next; ++ } ++ ++ // Compute the enclosing circle of the front chain. ++ a = [b._], c = b; while ((c = c.next) !== b) a.push(c._); c = enclose(a); ++ ++ // Translate the circles to put the enclosing circle around the origin. ++ for (i = 0; i < n; ++i) a = circles[i], a.x -= c.x, a.y -= c.y; ++ ++ return c.r; ++} ++ ++function siblings(circles) { ++ packEnclose(circles); ++ return circles; ++} ++ ++function optional(f) { ++ return f == null ? null : required(f); ++} ++ ++function required(f) { ++ if (typeof f !== "function") throw new Error; ++ return f; ++} ++ ++function constantZero() { ++ return 0; ++} ++ ++function constant$9(x) { ++ return function() { ++ return x; ++ }; ++} ++ ++function defaultRadius$1(d) { ++ return Math.sqrt(d.value); ++} ++ ++function index$2() { ++ var radius = null, ++ dx = 1, ++ dy = 1, ++ padding = constantZero; ++ ++ function pack(root) { ++ root.x = dx / 2, root.y = dy / 2; ++ if (radius) { ++ root.eachBefore(radiusLeaf(radius)) ++ .eachAfter(packChildren(padding, 0.5)) ++ .eachBefore(translateChild(1)); ++ } else { ++ root.eachBefore(radiusLeaf(defaultRadius$1)) ++ .eachAfter(packChildren(constantZero, 1)) ++ .eachAfter(packChildren(padding, root.r / Math.min(dx, dy))) ++ .eachBefore(translateChild(Math.min(dx, dy) / (2 * root.r))); ++ } ++ return root; ++ } ++ ++ pack.radius = function(x) { ++ return arguments.length ? (radius = optional(x), pack) : radius; ++ }; ++ ++ pack.size = function(x) { ++ return arguments.length ? (dx = +x[0], dy = +x[1], pack) : [dx, dy]; ++ }; ++ ++ pack.padding = function(x) { ++ return arguments.length ? (padding = typeof x === "function" ? x : constant$9(+x), pack) : padding; ++ }; ++ ++ return pack; ++} ++ ++function radiusLeaf(radius) { ++ return function(node) { ++ if (!node.children) { ++ node.r = Math.max(0, +radius(node) || 0); ++ } ++ }; ++} ++ ++function packChildren(padding, k) { ++ return function(node) { ++ if (children = node.children) { ++ var children, ++ i, ++ n = children.length, ++ r = padding(node) * k || 0, ++ e; ++ ++ if (r) for (i = 0; i < n; ++i) children[i].r += r; ++ e = packEnclose(children); ++ if (r) for (i = 0; i < n; ++i) children[i].r -= r; ++ node.r = e + r; ++ } ++ }; ++} ++ ++function translateChild(k) { ++ return function(node) { ++ var parent = node.parent; ++ node.r *= k; ++ if (parent) { ++ node.x = parent.x + k * node.x; ++ node.y = parent.y + k * node.y; ++ } ++ }; ++} ++ ++function roundNode(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); ++} ++ ++function treemapDice(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; ++ } ++} ++ ++function partition() { ++ 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 keyPrefix$1 = "$", // Protect against keys like “__proto__”. ++ preroot = {depth: -1}, ++ ambiguous = {}; ++ ++function defaultId(d) { ++ return d.id; ++} ++ ++function defaultParentId(d) { ++ return d.parentId; ++} ++ ++function stratify() { ++ var id = defaultId, ++ parentId = defaultParentId; ++ ++ function stratify(data) { ++ var d, ++ i, ++ n = data.length, ++ root, ++ parent, ++ node, ++ nodes = new Array(n), ++ nodeId, ++ nodeKey, ++ nodeByKey = {}; ++ ++ for (i = 0; i < n; ++i) { ++ d = data[i], node = nodes[i] = new Node(d); ++ if ((nodeId = id(d, i, data)) != null && (nodeId += "")) { ++ nodeKey = keyPrefix$1 + (node.id = nodeId); ++ nodeByKey[nodeKey] = nodeKey in nodeByKey ? ambiguous : node; ++ } ++ } ++ ++ for (i = 0; i < n; ++i) { ++ node = nodes[i], nodeId = parentId(data[i], i, data); ++ if (nodeId == null || !(nodeId += "")) { ++ if (root) throw new Error("multiple roots"); ++ root = node; ++ } else { ++ parent = nodeByKey[keyPrefix$1 + nodeId]; ++ if (!parent) throw new Error("missing: " + nodeId); ++ if (parent === ambiguous) throw new Error("ambiguous: " + nodeId); ++ if (parent.children) parent.children.push(node); ++ else parent.children = [node]; ++ node.parent = parent; ++ } ++ } ++ ++ if (!root) throw new Error("no root"); ++ root.parent = preroot; ++ root.eachBefore(function(node) { node.depth = node.parent.depth + 1; --n; }).eachBefore(computeHeight); ++ root.parent = null; ++ if (n > 0) throw new Error("cycle"); ++ ++ return root; ++ } ++ ++ stratify.id = function(x) { ++ return arguments.length ? (id = required(x), stratify) : id; ++ }; ++ ++ stratify.parentId = function(x) { ++ return arguments.length ? (parentId = required(x), stratify) : parentId; ++ }; ++ ++ return stratify; ++} ++ ++function defaultSeparation$1(a, b) { ++ return a.parent === b.parent ? 1 : 2; ++} ++ ++// function radialSeparation(a, b) { ++// return (a.parent === b.parent ? 1 : 2) / a.depth; ++// } ++ ++// This function is used to traverse the left contour of a subtree (or ++// subforest). It returns the successor of v on this contour. This successor is ++// either given by the leftmost child of v or by the thread of v. The function ++// returns null if and only if v is on the highest level of its subtree. ++function nextLeft(v) { ++ var children = v.children; ++ return children ? children[0] : v.t; ++} ++ ++// This function works analogously to nextLeft. ++function nextRight(v) { ++ var children = v.children; ++ return children ? children[children.length - 1] : v.t; ++} ++ ++// Shifts the current subtree rooted at w+. This is done by increasing ++// prelim(w+) and mod(w+) by shift. ++function moveSubtree(wm, wp, shift) { ++ var change = shift / (wp.i - wm.i); ++ wp.c -= change; ++ wp.s += shift; ++ wm.c += change; ++ wp.z += shift; ++ wp.m += shift; ++} ++ ++// All other shifts, applied to the smaller subtrees between w- and w+, are ++// performed by this function. To prepare the shifts, we have to adjust ++// change(w+), shift(w+), and change(w-). ++function executeShifts(v) { ++ var shift = 0, ++ change = 0, ++ children = v.children, ++ i = children.length, ++ w; ++ while (--i >= 0) { ++ w = children[i]; ++ w.z += shift; ++ w.m += shift; ++ shift += w.s + (change += w.c); ++ } ++} ++ ++// If vi-’s ancestor is a sibling of v, returns vi-’s ancestor. Otherwise, ++// returns the specified (default) ancestor. ++function nextAncestor(vim, v, ancestor) { ++ return vim.a.parent === v.parent ? vim.a : ancestor; ++} ++ ++function TreeNode(node, i) { ++ this._ = node; ++ this.parent = null; ++ this.children = null; ++ this.A = null; // default ancestor ++ this.a = this; // ancestor ++ this.z = 0; // prelim ++ this.m = 0; // mod ++ this.c = 0; // change ++ this.s = 0; // shift ++ this.t = null; // thread ++ this.i = i; // number ++} ++ ++TreeNode.prototype = Object.create(Node.prototype); ++ ++function treeRoot(root) { ++ var tree = new TreeNode(root, 0), ++ node, ++ nodes = [tree], ++ child, ++ children, ++ i, ++ n; ++ ++ while (node = nodes.pop()) { ++ if (children = node._.children) { ++ node.children = new Array(n = children.length); ++ for (i = n - 1; i >= 0; --i) { ++ nodes.push(child = node.children[i] = new TreeNode(children[i], i)); ++ child.parent = node; ++ } ++ } ++ } ++ ++ (tree.parent = new TreeNode(null, 0)).children = [tree]; ++ return tree; ++} ++ ++// Node-link tree diagram using the Reingold-Tilford "tidy" algorithm ++function tree() { ++ var separation = defaultSeparation$1, ++ dx = 1, ++ dy = 1, ++ nodeSize = null; ++ ++ function tree(root) { ++ var t = treeRoot(root); ++ ++ // Compute the layout using Buchheim et al.’s algorithm. ++ t.eachAfter(firstWalk), t.parent.m = -t.z; ++ t.eachBefore(secondWalk); ++ ++ // If a fixed node size is specified, scale x and y. ++ if (nodeSize) root.eachBefore(sizeNode); ++ ++ // If a fixed tree size is specified, scale x and y based on the extent. ++ // Compute the left-most, right-most, and depth-most nodes for extents. ++ else { ++ var left = root, ++ right = root, ++ bottom = root; ++ root.eachBefore(function(node) { ++ if (node.x < left.x) left = node; ++ if (node.x > right.x) right = node; ++ if (node.depth > bottom.depth) bottom = node; ++ }); ++ var s = left === right ? 1 : separation(left, right) / 2, ++ tx = s - left.x, ++ kx = dx / (right.x + s + tx), ++ ky = dy / (bottom.depth || 1); ++ root.eachBefore(function(node) { ++ node.x = (node.x + tx) * kx; ++ node.y = node.depth * ky; ++ }); ++ } ++ ++ return root; ++ } ++ ++ // Computes a preliminary x-coordinate for v. Before that, FIRST WALK is ++ // applied recursively to the children of v, as well as the function ++ // APPORTION. After spacing out the children by calling EXECUTE SHIFTS, the ++ // node v is placed to the midpoint of its outermost children. ++ function firstWalk(v) { ++ var children = v.children, ++ siblings = v.parent.children, ++ w = v.i ? siblings[v.i - 1] : null; ++ if (children) { ++ executeShifts(v); ++ var midpoint = (children[0].z + children[children.length - 1].z) / 2; ++ if (w) { ++ v.z = w.z + separation(v._, w._); ++ v.m = v.z - midpoint; ++ } else { ++ v.z = midpoint; ++ } ++ } else if (w) { ++ v.z = w.z + separation(v._, w._); ++ } ++ v.parent.A = apportion(v, w, v.parent.A || siblings[0]); ++ } ++ ++ // Computes all real x-coordinates by summing up the modifiers recursively. ++ function secondWalk(v) { ++ v._.x = v.z + v.parent.m; ++ v.m += v.parent.m; ++ } ++ ++ // The core of the algorithm. Here, a new subtree is combined with the ++ // previous subtrees. Threads are used to traverse the inside and outside ++ // contours of the left and right subtree up to the highest common level. The ++ // vertices used for the traversals are vi+, vi-, vo-, and vo+, where the ++ // superscript o means outside and i means inside, the subscript - means left ++ // subtree and + means right subtree. For summing up the modifiers along the ++ // contour, we use respective variables si+, si-, so-, and so+. Whenever two ++ // nodes of the inside contours conflict, we compute the left one of the ++ // greatest uncommon ancestors using the function ANCESTOR and call MOVE ++ // SUBTREE to shift the subtree and prepare the shifts of smaller subtrees. ++ // Finally, we add a new thread (if necessary). ++ function apportion(v, w, ancestor) { ++ if (w) { ++ var vip = v, ++ vop = v, ++ vim = w, ++ vom = vip.parent.children[0], ++ sip = vip.m, ++ sop = vop.m, ++ sim = vim.m, ++ som = vom.m, ++ shift; ++ while (vim = nextRight(vim), vip = nextLeft(vip), vim && vip) { ++ vom = nextLeft(vom); ++ vop = nextRight(vop); ++ vop.a = v; ++ shift = vim.z + sim - vip.z - sip + separation(vim._, vip._); ++ if (shift > 0) { ++ moveSubtree(nextAncestor(vim, v, ancestor), v, shift); ++ sip += shift; ++ sop += shift; ++ } ++ sim += vim.m; ++ sip += vip.m; ++ som += vom.m; ++ sop += vop.m; ++ } ++ if (vim && !nextRight(vop)) { ++ vop.t = vim; ++ vop.m += sim - sop; ++ } ++ if (vip && !nextLeft(vom)) { ++ vom.t = vip; ++ vom.m += sip - som; ++ ancestor = v; ++ } ++ } ++ return ancestor; ++ } ++ ++ function sizeNode(node) { ++ node.x *= dx; ++ node.y = node.depth * dy; ++ } ++ ++ tree.separation = function(x) { ++ return arguments.length ? (separation = x, tree) : separation; ++ }; ++ ++ tree.size = function(x) { ++ return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], tree) : (nodeSize ? null : [dx, dy]); ++ }; ++ ++ tree.nodeSize = function(x) { ++ return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], tree) : (nodeSize ? [dx, dy] : null); ++ }; ++ ++ return tree; ++} ++ ++function treemapSlice(parent, x0, y0, x1, y1) { ++ var nodes = parent.children, ++ node, ++ i = -1, ++ n = nodes.length, ++ k = parent.value && (y1 - y0) / parent.value; ++ ++ while (++i < n) { ++ node = nodes[i], node.x0 = x0, node.x1 = x1; ++ node.y0 = y0, node.y1 = y0 += node.value * k; ++ } ++} ++ ++var phi = (1 + Math.sqrt(5)) / 2; ++ ++function squarifyRatio(ratio, parent, x0, y0, x1, y1) { ++ var rows = [], ++ nodes = parent.children, ++ row, ++ nodeValue, ++ i0 = 0, ++ i1 = 0, ++ n = nodes.length, ++ dx, dy, ++ value = parent.value, ++ sumValue, ++ minValue, ++ maxValue, ++ newRatio, ++ minRatio, ++ alpha, ++ beta; ++ ++ while (i0 < n) { ++ dx = x1 - x0, dy = y1 - y0; ++ ++ // Find the next non-empty node. ++ do sumValue = nodes[i1++].value; while (!sumValue && i1 < n); ++ minValue = maxValue = sumValue; ++ alpha = Math.max(dy / dx, dx / dy) / (value * ratio); ++ beta = sumValue * sumValue * alpha; ++ minRatio = Math.max(maxValue / beta, beta / minValue); ++ ++ // Keep adding nodes while the aspect ratio maintains or improves. ++ for (; i1 < n; ++i1) { ++ sumValue += nodeValue = nodes[i1].value; ++ if (nodeValue < minValue) minValue = nodeValue; ++ if (nodeValue > maxValue) maxValue = nodeValue; ++ beta = sumValue * sumValue * alpha; ++ newRatio = Math.max(maxValue / beta, beta / minValue); ++ if (newRatio > minRatio) { sumValue -= nodeValue; break; } ++ minRatio = newRatio; ++ } ++ ++ // Position and record the row orientation. ++ rows.push(row = {value: sumValue, dice: dx < dy, children: nodes.slice(i0, i1)}); ++ if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1); ++ else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1); ++ value -= sumValue, i0 = i1; ++ } ++ ++ return rows; ++} ++ ++var squarify = (function custom(ratio) { ++ ++ function squarify(parent, x0, y0, x1, y1) { ++ squarifyRatio(ratio, parent, x0, y0, x1, y1); ++ } ++ ++ squarify.ratio = function(x) { ++ return custom((x = +x) > 1 ? x : 1); ++ }; ++ ++ return squarify; ++})(phi); ++ ++function index$3() { ++ var tile = squarify, ++ round = false, ++ dx = 1, ++ dy = 1, ++ paddingStack = [0], ++ paddingInner = constantZero, ++ paddingTop = constantZero, ++ paddingRight = constantZero, ++ paddingBottom = constantZero, ++ paddingLeft = constantZero; ++ ++ function treemap(root) { ++ root.x0 = ++ root.y0 = 0; ++ root.x1 = dx; ++ root.y1 = dy; ++ root.eachBefore(positionNode); ++ paddingStack = [0]; ++ if (round) root.eachBefore(roundNode); ++ return root; ++ } ++ ++ function positionNode(node) { ++ var p = paddingStack[node.depth], ++ x0 = node.x0 + p, ++ y0 = node.y0 + p, ++ x1 = node.x1 - p, ++ y1 = node.y1 - p; ++ 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; ++ if (node.children) { ++ p = paddingStack[node.depth + 1] = paddingInner(node) / 2; ++ x0 += paddingLeft(node) - p; ++ y0 += paddingTop(node) - p; ++ x1 -= paddingRight(node) - p; ++ y1 -= paddingBottom(node) - p; ++ if (x1 < x0) x0 = x1 = (x0 + x1) / 2; ++ if (y1 < y0) y0 = y1 = (y0 + y1) / 2; ++ tile(node, x0, y0, x1, y1); ++ } ++ } ++ ++ treemap.round = function(x) { ++ return arguments.length ? (round = !!x, treemap) : round; ++ }; ++ ++ treemap.size = function(x) { ++ return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy]; ++ }; ++ ++ treemap.tile = function(x) { ++ return arguments.length ? (tile = required(x), treemap) : tile; ++ }; ++ ++ treemap.padding = function(x) { ++ return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner(); ++ }; ++ ++ treemap.paddingInner = function(x) { ++ return arguments.length ? (paddingInner = typeof x === "function" ? x : constant$9(+x), treemap) : paddingInner; ++ }; ++ ++ treemap.paddingOuter = function(x) { ++ return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop(); ++ }; ++ ++ treemap.paddingTop = function(x) { ++ return arguments.length ? (paddingTop = typeof x === "function" ? x : constant$9(+x), treemap) : paddingTop; ++ }; ++ ++ treemap.paddingRight = function(x) { ++ return arguments.length ? (paddingRight = typeof x === "function" ? x : constant$9(+x), treemap) : paddingRight; ++ }; ++ ++ treemap.paddingBottom = function(x) { ++ return arguments.length ? (paddingBottom = typeof x === "function" ? x : constant$9(+x), treemap) : paddingBottom; ++ }; ++ ++ treemap.paddingLeft = function(x) { ++ return arguments.length ? (paddingLeft = typeof x === "function" ? x : constant$9(+x), treemap) : paddingLeft; ++ }; ++ ++ return treemap; ++} ++ ++function binary(parent, x0, y0, x1, y1) { ++ var nodes = parent.children, ++ i, n = nodes.length, ++ sum, sums = new Array(n + 1); ++ ++ for (sums[0] = sum = i = 0; i < n; ++i) { ++ sums[i + 1] = sum += nodes[i].value; ++ } ++ ++ partition(0, n, parent.value, x0, y0, x1, y1); ++ ++ function partition(i, j, value, x0, y0, x1, y1) { ++ if (i >= j - 1) { ++ var node = nodes[i]; ++ node.x0 = x0, node.y0 = y0; ++ node.x1 = x1, node.y1 = y1; ++ return; ++ } ++ ++ var valueOffset = sums[i], ++ valueTarget = (value / 2) + valueOffset, ++ k = i + 1, ++ hi = j - 1; ++ ++ while (k < hi) { ++ var mid = k + hi >>> 1; ++ if (sums[mid] < valueTarget) k = mid + 1; ++ else hi = mid; ++ } ++ ++ if ((valueTarget - sums[k - 1]) < (sums[k] - valueTarget) && i + 1 < k) --k; ++ ++ var valueLeft = sums[k] - valueOffset, ++ valueRight = value - valueLeft; ++ ++ if ((x1 - x0) > (y1 - y0)) { ++ var xk = (x0 * valueRight + x1 * valueLeft) / value; ++ partition(i, k, valueLeft, x0, y0, xk, y1); ++ partition(k, j, valueRight, xk, y0, x1, y1); ++ } else { ++ var yk = (y0 * valueRight + y1 * valueLeft) / value; ++ partition(i, k, valueLeft, x0, y0, x1, yk); ++ partition(k, j, valueRight, x0, yk, x1, y1); ++ } ++ } ++} ++ ++function sliceDice(parent, x0, y0, x1, y1) { ++ (parent.depth & 1 ? treemapSlice : treemapDice)(parent, x0, y0, x1, y1); ++} ++ ++var resquarify = (function custom(ratio) { ++ ++ function resquarify(parent, x0, y0, x1, y1) { ++ if ((rows = parent._squarify) && (rows.ratio === ratio)) { ++ var rows, ++ row, ++ nodes, ++ i, ++ j = -1, ++ n, ++ m = rows.length, ++ value = parent.value; ++ ++ while (++j < m) { ++ row = rows[j], nodes = row.children; ++ for (i = row.value = 0, n = nodes.length; i < n; ++i) row.value += nodes[i].value; ++ if (row.dice) treemapDice(row, x0, y0, x1, y0 += (y1 - y0) * row.value / value); ++ else treemapSlice(row, x0, y0, x0 += (x1 - x0) * row.value / value, y1); ++ value -= row.value; ++ } ++ } else { ++ parent._squarify = rows = squarifyRatio(ratio, parent, x0, y0, x1, y1); ++ rows.ratio = ratio; ++ } ++ } ++ ++ resquarify.ratio = function(x) { ++ return custom((x = +x) > 1 ? x : 1); ++ }; ++ ++ return resquarify; ++})(phi); ++ ++function area$2(polygon) { ++ var i = -1, ++ n = polygon.length, ++ a, ++ b = polygon[n - 1], ++ area = 0; ++ ++ while (++i < n) { ++ a = b; ++ b = polygon[i]; ++ area += a[1] * b[0] - a[0] * b[1]; ++ } ++ ++ return area / 2; ++} ++ ++function centroid$1(polygon) { ++ var i = -1, ++ n = polygon.length, ++ x = 0, ++ y = 0, ++ a, ++ b = polygon[n - 1], ++ c, ++ k = 0; ++ ++ while (++i < n) { ++ a = b; ++ b = polygon[i]; ++ k += c = a[0] * b[1] - b[0] * a[1]; ++ x += (a[0] + b[0]) * c; ++ y += (a[1] + b[1]) * c; ++ } ++ ++ return k *= 3, [x / k, y / k]; ++} ++ ++// Returns the 2D cross product of AB and AC vectors, i.e., the z-component of ++// the 3D cross product in a quadrant I Cartesian coordinate system (+x is ++// right, +y is up). Returns a positive value if ABC is counter-clockwise, ++// negative if clockwise, and zero if the points are collinear. ++function cross$1(a, b, c) { ++ return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]); ++} ++ ++function lexicographicOrder(a, b) { ++ return a[0] - b[0] || a[1] - b[1]; ++} ++ ++// Computes the upper convex hull per the monotone chain algorithm. ++// Assumes points.length >= 3, is sorted by x, unique in y. ++// Returns an array of indices into points in left-to-right order. ++function computeUpperHullIndexes(points) { ++ var n = points.length, ++ indexes = [0, 1], ++ size = 2; ++ ++ for (var i = 2; i < n; ++i) { ++ while (size > 1 && cross$1(points[indexes[size - 2]], points[indexes[size - 1]], points[i]) <= 0) --size; ++ indexes[size++] = i; ++ } ++ ++ return indexes.slice(0, size); // remove popped points ++} ++ ++function hull(points) { ++ if ((n = points.length) < 3) return null; ++ ++ var i, ++ n, ++ sortedPoints = new Array(n), ++ flippedPoints = new Array(n); ++ ++ for (i = 0; i < n; ++i) sortedPoints[i] = [+points[i][0], +points[i][1], i]; ++ sortedPoints.sort(lexicographicOrder); ++ for (i = 0; i < n; ++i) flippedPoints[i] = [sortedPoints[i][0], -sortedPoints[i][1]]; ++ ++ var upperIndexes = computeUpperHullIndexes(sortedPoints), ++ lowerIndexes = computeUpperHullIndexes(flippedPoints); ++ ++ // Construct the hull polygon, removing possible duplicate endpoints. ++ var skipLeft = lowerIndexes[0] === upperIndexes[0], ++ skipRight = lowerIndexes[lowerIndexes.length - 1] === upperIndexes[upperIndexes.length - 1], ++ hull = []; ++ ++ // Add upper hull in right-to-l order. ++ // Then add lower hull in left-to-right order. ++ for (i = upperIndexes.length - 1; i >= 0; --i) hull.push(points[sortedPoints[upperIndexes[i]][2]]); ++ for (i = +skipLeft; i < lowerIndexes.length - skipRight; ++i) hull.push(points[sortedPoints[lowerIndexes[i]][2]]); ++ ++ return hull; ++} ++ ++function contains$2(polygon, point) { ++ var n = polygon.length, ++ p = polygon[n - 1], ++ x = point[0], y = point[1], ++ x0 = p[0], y0 = p[1], ++ x1, y1, ++ inside = false; ++ ++ for (var i = 0; i < n; ++i) { ++ p = polygon[i], x1 = p[0], y1 = p[1]; ++ if (((y1 > y) !== (y0 > y)) && (x < (x0 - x1) * (y - y1) / (y0 - y1) + x1)) inside = !inside; ++ x0 = x1, y0 = y1; ++ } ++ ++ return inside; ++} ++ ++function length$2(polygon) { ++ var i = -1, ++ n = polygon.length, ++ b = polygon[n - 1], ++ xa, ++ ya, ++ xb = b[0], ++ yb = b[1], ++ perimeter = 0; ++ ++ while (++i < n) { ++ xa = xb; ++ ya = yb; ++ b = polygon[i]; ++ xb = b[0]; ++ yb = b[1]; ++ xa -= xb; ++ ya -= yb; ++ perimeter += Math.sqrt(xa * xa + ya * ya); ++ } ++ ++ return perimeter; ++} ++ ++function defaultSource$1() { ++ return Math.random(); ++} ++ ++var uniform = (function sourceRandomUniform(source) { ++ function randomUniform(min, max) { ++ min = min == null ? 0 : +min; ++ max = max == null ? 1 : +max; ++ if (arguments.length === 1) max = min, min = 0; ++ else max -= min; ++ return function() { ++ return source() * max + min; ++ }; ++ } ++ ++ randomUniform.source = sourceRandomUniform; ++ ++ return randomUniform; ++})(defaultSource$1); ++ ++var normal = (function sourceRandomNormal(source) { ++ function randomNormal(mu, sigma) { ++ var x, r; ++ mu = mu == null ? 0 : +mu; ++ sigma = sigma == null ? 1 : +sigma; ++ return function() { ++ var y; ++ ++ // If available, use the second previously-generated uniform random. ++ if (x != null) y = x, x = null; ++ ++ // Otherwise, generate a new x and y. ++ else do { ++ x = source() * 2 - 1; ++ y = source() * 2 - 1; ++ r = x * x + y * y; ++ } while (!r || r > 1); ++ ++ return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r); ++ }; ++ } ++ ++ randomNormal.source = sourceRandomNormal; ++ ++ return randomNormal; ++})(defaultSource$1); ++ ++var logNormal = (function sourceRandomLogNormal(source) { ++ function randomLogNormal() { ++ var randomNormal = normal.source(source).apply(this, arguments); ++ return function() { ++ return Math.exp(randomNormal()); ++ }; ++ } ++ ++ randomLogNormal.source = sourceRandomLogNormal; ++ ++ return randomLogNormal; ++})(defaultSource$1); ++ ++var irwinHall = (function sourceRandomIrwinHall(source) { ++ function randomIrwinHall(n) { ++ return function() { ++ for (var sum = 0, i = 0; i < n; ++i) sum += source(); ++ return sum; ++ }; ++ } ++ ++ randomIrwinHall.source = sourceRandomIrwinHall; ++ ++ return randomIrwinHall; ++})(defaultSource$1); ++ ++var bates = (function sourceRandomBates(source) { ++ function randomBates(n) { ++ var randomIrwinHall = irwinHall.source(source)(n); ++ return function() { ++ return randomIrwinHall() / n; ++ }; ++ } ++ ++ randomBates.source = sourceRandomBates; ++ ++ return randomBates; ++})(defaultSource$1); ++ ++var exponential$1 = (function sourceRandomExponential(source) { ++ function randomExponential(lambda) { ++ return function() { ++ return -Math.log(1 - source()) / lambda; ++ }; ++ } ++ ++ randomExponential.source = sourceRandomExponential; ++ ++ return randomExponential; ++})(defaultSource$1); ++ ++var array$3 = Array.prototype; ++ ++var map$2 = array$3.map; ++var slice$5 = array$3.slice; ++ ++var implicit = {name: "implicit"}; ++ ++function ordinal(range) { ++ var index = map$1(), ++ domain = [], ++ unknown = implicit; ++ ++ range = range == null ? [] : slice$5.call(range); ++ ++ function scale(d) { ++ var key = d + "", i = index.get(key); ++ if (!i) { ++ if (unknown !== implicit) return unknown; ++ index.set(key, i = domain.push(d)); ++ } ++ return range[(i - 1) % range.length]; ++ } ++ ++ scale.domain = function(_) { ++ if (!arguments.length) return domain.slice(); ++ domain = [], index = map$1(); ++ var i = -1, n = _.length, d, key; ++ while (++i < n) if (!index.has(key = (d = _[i]) + "")) index.set(key, domain.push(d)); ++ return scale; ++ }; ++ ++ scale.range = function(_) { ++ return arguments.length ? (range = slice$5.call(_), scale) : range.slice(); ++ }; ++ ++ scale.unknown = function(_) { ++ return arguments.length ? (unknown = _, scale) : unknown; ++ }; ++ ++ scale.copy = function() { ++ return ordinal() ++ .domain(domain) ++ .range(range) ++ .unknown(unknown); ++ }; ++ ++ return scale; ++} ++ ++function band() { ++ var scale = ordinal().unknown(undefined), ++ domain = scale.domain, ++ ordinalRange = scale.range, ++ range$$1 = [0, 1], ++ step, ++ bandwidth, ++ round = false, ++ paddingInner = 0, ++ paddingOuter = 0, ++ align = 0.5; ++ ++ delete scale.unknown; ++ ++ function rescale() { ++ var n = domain().length, ++ reverse = range$$1[1] < range$$1[0], ++ start = range$$1[reverse - 0], ++ stop = range$$1[1 - reverse]; ++ step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2); ++ if (round) step = Math.floor(step); ++ start += (stop - start - step * (n - paddingInner)) * align; ++ bandwidth = step * (1 - paddingInner); ++ if (round) start = Math.round(start), bandwidth = Math.round(bandwidth); ++ var values = sequence(n).map(function(i) { return start + step * i; }); ++ return ordinalRange(reverse ? values.reverse() : values); ++ } ++ ++ scale.domain = function(_) { ++ return arguments.length ? (domain(_), rescale()) : domain(); ++ }; ++ ++ scale.range = function(_) { ++ return arguments.length ? (range$$1 = [+_[0], +_[1]], rescale()) : range$$1.slice(); ++ }; ++ ++ scale.rangeRound = function(_) { ++ return range$$1 = [+_[0], +_[1]], round = true, rescale(); ++ }; ++ ++ scale.bandwidth = function() { ++ return bandwidth; ++ }; ++ ++ scale.step = function() { ++ return step; ++ }; ++ ++ scale.round = function(_) { ++ return arguments.length ? (round = !!_, rescale()) : round; ++ }; ++ ++ scale.padding = function(_) { ++ return arguments.length ? (paddingInner = paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingInner; ++ }; ++ ++ scale.paddingInner = function(_) { ++ return arguments.length ? (paddingInner = Math.max(0, Math.min(1, _)), rescale()) : paddingInner; ++ }; ++ ++ scale.paddingOuter = function(_) { ++ return arguments.length ? (paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingOuter; ++ }; ++ ++ scale.align = function(_) { ++ return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align; ++ }; ++ ++ scale.copy = function() { ++ return band() ++ .domain(domain()) ++ .range(range$$1) ++ .round(round) ++ .paddingInner(paddingInner) ++ .paddingOuter(paddingOuter) ++ .align(align); ++ }; ++ ++ return rescale(); ++} ++ ++function pointish(scale) { ++ var copy = scale.copy; ++ ++ scale.padding = scale.paddingOuter; ++ delete scale.paddingInner; ++ delete scale.paddingOuter; ++ ++ scale.copy = function() { ++ return pointish(copy()); ++ }; ++ ++ return scale; ++} ++ ++function point$1() { ++ return pointish(band().paddingInner(1)); ++} ++ ++function constant$10(x) { ++ return function() { ++ return x; ++ }; ++} ++ ++function number$2(x) { ++ return +x; ++} ++ ++var unit = [0, 1]; ++ ++function deinterpolateLinear(a, b) { ++ return (b -= (a = +a)) ++ ? function(x) { return (x - a) / b; } ++ : constant$10(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$$1) { ++ return function(a, b) { ++ var r = reinterpolate$$1(a = +a, b = +b); ++ return function(t) { return t <= 0 ? a : t >= 1 ? b : r(t); }; ++ }; ++} ++ ++function bimap(domain, range, deinterpolate, reinterpolate$$1) { ++ var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1]; ++ if (d1 < d0) d0 = deinterpolate(d1, d0), r0 = reinterpolate$$1(r1, r0); ++ else d0 = deinterpolate(d0, d1), r0 = reinterpolate$$1(r0, r1); ++ return function(x) { return r0(d0(x)); }; ++} ++ ++function polymap(domain, range, deinterpolate, reinterpolate$$1) { ++ 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$$1(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$$1) { ++ var domain = unit, ++ range = unit, ++ interpolate$$1 = interpolateValue, ++ clamp = false, ++ piecewise$$1, ++ output, ++ input; ++ ++ function rescale() { ++ piecewise$$1 = Math.min(domain.length, range.length) > 2 ? polymap : bimap; ++ output = input = null; ++ return scale; ++ } ++ ++ function scale(x) { ++ return (output || (output = piecewise$$1(domain, range, clamp ? deinterpolateClamp(deinterpolate) : deinterpolate, interpolate$$1)))(+x); ++ } ++ ++ scale.invert = function(y) { ++ return (input || (input = piecewise$$1(range, domain, deinterpolateLinear, clamp ? reinterpolateClamp(reinterpolate$$1) : reinterpolate$$1)))(+y); ++ }; ++ ++ scale.domain = function(_) { ++ return arguments.length ? (domain = map$2.call(_, number$2), rescale()) : domain.slice(); ++ }; ++ ++ scale.range = function(_) { ++ return arguments.length ? (range = slice$5.call(_), rescale()) : range.slice(); ++ }; ++ ++ scale.rangeRound = function(_) { ++ return range = slice$5.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(); ++} ++ ++function tickFormat(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 exports.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$2() { ++ var scale = continuous(deinterpolateLinear, reinterpolate); ++ ++ scale.copy = function() { ++ return copy(scale, linear$2()); ++ }; ++ ++ return linearish(scale); ++} ++ ++function identity$6() { ++ var domain = [0, 1]; ++ ++ function scale(x) { ++ return +x; ++ } ++ ++ scale.invert = scale; ++ ++ scale.domain = scale.range = function(_) { ++ return arguments.length ? (domain = map$2.call(_, number$2), scale) : domain.slice(); ++ }; ++ ++ scale.copy = function() { ++ return identity$6().domain(domain); ++ }; ++ ++ return linearish(scale); ++} ++ ++function nice(domain, interval) { ++ domain = domain.slice(); ++ ++ var i0 = 0, ++ i1 = domain.length - 1, ++ x0 = domain[i0], ++ x1 = domain[i1], ++ t; ++ ++ if (x1 < x0) { ++ t = i0, i0 = i1, i1 = t; ++ t = x0, x0 = x1, x1 = t; ++ } ++ ++ domain[i0] = interval.floor(x0); ++ domain[i1] = interval.ceil(x1); ++ return domain; ++} ++ ++function deinterpolate(a, b) { ++ return (b = Math.log(b / a)) ++ ? function(x) { return Math.log(x / a) / b; } ++ : constant$10(b); ++} ++ ++function reinterpolate$1(a, b) { ++ return a < 0 ++ ? function(t) { return -Math.pow(-b, t) * Math.pow(-a, 1 - t); } ++ : function(t) { return Math.pow(b, t) * Math.pow(a, 1 - t); }; ++} ++ ++function pow10(x) { ++ return isFinite(x) ? +("1e" + x) : x < 0 ? 0 : x; ++} ++ ++function powp(base) { ++ return base === 10 ? pow10 ++ : base === Math.E ? Math.exp ++ : function(x) { return Math.pow(base, x); }; ++} ++ ++function logp(base) { ++ return base === Math.E ? Math.log ++ : base === 10 && Math.log10 ++ || base === 2 && Math.log2 ++ || (base = Math.log(base), function(x) { return Math.log(x) / base; }); ++} ++ ++function reflect(f) { ++ return function(x) { ++ return -f(-x); ++ }; ++} ++ ++function log$1() { ++ var scale = continuous(deinterpolate, reinterpolate$1).domain([1, 10]), ++ domain = scale.domain, ++ base = 10, ++ logs = logp(10), ++ pows = powp(10); ++ ++ function rescale() { ++ logs = logp(base), pows = powp(base); ++ if (domain()[0] < 0) logs = reflect(logs), pows = reflect(pows); ++ return scale; ++ } ++ ++ scale.base = function(_) { ++ return arguments.length ? (base = +_, rescale()) : base; ++ }; ++ ++ scale.domain = function(_) { ++ return arguments.length ? (domain(_), rescale()) : domain(); ++ }; ++ ++ scale.ticks = function(count) { ++ var d = domain(), ++ u = d[0], ++ v = d[d.length - 1], ++ r; ++ ++ if (r = v < u) i = u, u = v, v = i; ++ ++ var i = logs(u), ++ j = logs(v), ++ p, ++ k, ++ t, ++ n = count == null ? 10 : +count, ++ z = []; ++ ++ if (!(base % 1) && j - i < n) { ++ i = Math.round(i) - 1, j = Math.round(j) + 1; ++ if (u > 0) for (; i < j; ++i) { ++ for (k = 1, p = pows(i); k < base; ++k) { ++ t = p * k; ++ if (t < u) continue; ++ if (t > v) break; ++ z.push(t); ++ } ++ } else for (; i < j; ++i) { ++ for (k = base - 1, p = pows(i); k >= 1; --k) { ++ t = p * k; ++ if (t < u) continue; ++ if (t > v) break; ++ z.push(t); ++ } ++ } ++ } else { ++ z = ticks(i, j, Math.min(j - i, n)).map(pows); ++ } ++ ++ return r ? z.reverse() : z; ++ }; ++ ++ scale.tickFormat = function(count, specifier) { ++ if (specifier == null) specifier = base === 10 ? ".0e" : ","; ++ if (typeof specifier !== "function") specifier = exports.format(specifier); ++ if (count === Infinity) return specifier; ++ if (count == null) count = 10; ++ var k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate? ++ return function(d) { ++ var i = d / pows(Math.round(logs(d))); ++ if (i * base < base - 0.5) i *= base; ++ return i <= k ? specifier(d) : ""; ++ }; ++ }; ++ ++ scale.nice = function() { ++ return domain(nice(domain(), { ++ floor: function(x) { return pows(Math.floor(logs(x))); }, ++ ceil: function(x) { return pows(Math.ceil(logs(x))); } ++ })); ++ }; ++ ++ scale.copy = function() { ++ return copy(scale, log$1().base(base)); ++ }; ++ ++ return scale; ++} ++ ++function raise$1(x, exponent) { ++ return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent); ++} ++ ++function pow$1() { ++ var exponent = 1, ++ scale = continuous(deinterpolate, reinterpolate), ++ domain = scale.domain; ++ ++ function deinterpolate(a, b) { ++ return (b = raise$1(b, exponent) - (a = raise$1(a, exponent))) ++ ? function(x) { return (raise$1(x, exponent) - a) / b; } ++ : constant$10(b); ++ } ++ ++ function reinterpolate(a, b) { ++ b = raise$1(b, exponent) - (a = raise$1(a, exponent)); ++ return function(t) { return raise$1(a + b * t, 1 / exponent); }; ++ } ++ ++ scale.exponent = function(_) { ++ return arguments.length ? (exponent = +_, domain(domain())) : exponent; ++ }; ++ ++ scale.copy = function() { ++ return copy(scale, pow$1().exponent(exponent)); ++ }; ++ ++ return linearish(scale); ++} ++ ++function sqrt$1() { ++ return pow$1().exponent(0.5); ++} ++ ++function quantile$$1() { ++ var domain = [], ++ range = [], ++ thresholds = []; ++ ++ function rescale() { ++ var i = 0, n = Math.max(1, range.length); ++ thresholds = new Array(n - 1); ++ while (++i < n) thresholds[i - 1] = threshold(domain, i / n); ++ return scale; ++ } ++ ++ function scale(x) { ++ if (!isNaN(x = +x)) return range[bisectRight(thresholds, x)]; ++ } ++ ++ scale.invertExtent = function(y) { ++ var i = range.indexOf(y); ++ return i < 0 ? [NaN, NaN] : [ ++ i > 0 ? thresholds[i - 1] : domain[0], ++ i < thresholds.length ? thresholds[i] : domain[domain.length - 1] ++ ]; ++ }; ++ ++ scale.domain = function(_) { ++ if (!arguments.length) return domain.slice(); ++ domain = []; ++ for (var i = 0, n = _.length, d; i < n; ++i) if (d = _[i], d != null && !isNaN(d = +d)) domain.push(d); ++ domain.sort(ascending); ++ return rescale(); ++ }; ++ ++ scale.range = function(_) { ++ return arguments.length ? (range = slice$5.call(_), rescale()) : range.slice(); ++ }; ++ ++ scale.quantiles = function() { ++ return thresholds.slice(); ++ }; ++ ++ scale.copy = function() { ++ return quantile$$1() ++ .domain(domain) ++ .range(range); ++ }; ++ ++ return scale; ++} ++ ++function quantize$1() { ++ var x0 = 0, ++ x1 = 1, ++ n = 1, ++ domain = [0.5], ++ range = [0, 1]; ++ ++ function scale(x) { ++ if (x <= x) return range[bisectRight(domain, x, 0, n)]; ++ } ++ ++ function rescale() { ++ var i = -1; ++ domain = new Array(n); ++ while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1); ++ return scale; ++ } ++ ++ scale.domain = function(_) { ++ return arguments.length ? (x0 = +_[0], x1 = +_[1], rescale()) : [x0, x1]; ++ }; ++ ++ scale.range = function(_) { ++ return arguments.length ? (n = (range = slice$5.call(_)).length - 1, rescale()) : range.slice(); ++ }; ++ ++ scale.invertExtent = function(y) { ++ var i = range.indexOf(y); ++ return i < 0 ? [NaN, NaN] ++ : i < 1 ? [x0, domain[0]] ++ : i >= n ? [domain[n - 1], x1] ++ : [domain[i - 1], domain[i]]; ++ }; ++ ++ scale.copy = function() { ++ return quantize$1() ++ .domain([x0, x1]) ++ .range(range); ++ }; ++ ++ return linearish(scale); ++} ++ ++function threshold$1() { ++ var domain = [0.5], ++ range = [0, 1], ++ n = 1; ++ ++ function scale(x) { ++ if (x <= x) return range[bisectRight(domain, x, 0, n)]; ++ } ++ ++ scale.domain = function(_) { ++ return arguments.length ? (domain = slice$5.call(_), n = Math.min(domain.length, range.length - 1), scale) : domain.slice(); ++ }; ++ ++ scale.range = function(_) { ++ return arguments.length ? (range = slice$5.call(_), n = Math.min(domain.length, range.length - 1), scale) : range.slice(); ++ }; ++ ++ scale.invertExtent = function(y) { ++ var i = range.indexOf(y); ++ return [domain[i - 1], domain[i]]; ++ }; ++ ++ scale.copy = function() { ++ return threshold$1() ++ .domain(domain) ++ .range(range); ++ }; ++ ++ return scale; ++} ++ ++var t0$1 = new Date, ++ 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 = [], previous; ++ 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(previous = new Date(+start)), offseti(start, step), floori(start); ++ while (previous < 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 milliseconds = millisecond.range; ++ ++var durationSecond = 1e3; ++var durationMinute = 6e4; ++var durationHour = 36e5; ++var durationDay = 864e5; ++var durationWeek = 6048e5; ++ ++var second = newInterval(function(date) { ++ date.setTime(Math.floor(date / durationSecond) * durationSecond); ++}, function(date, step) { ++ date.setTime(+date + step * durationSecond); ++}, function(start, end) { ++ return (end - start) / durationSecond; ++}, function(date) { ++ return date.getUTCSeconds(); ++}); ++var seconds = second.range; ++ ++var minute = newInterval(function(date) { ++ date.setTime(Math.floor(date / durationMinute) * durationMinute); ++}, function(date, step) { ++ date.setTime(+date + step * durationMinute); ++}, function(start, end) { ++ return (end - start) / durationMinute; ++}, function(date) { ++ return date.getMinutes(); ++}); ++var minutes = minute.range; ++ ++var hour = newInterval(function(date) { ++ var offset = date.getTimezoneOffset() * durationMinute % durationHour; ++ if (offset < 0) offset += durationHour; ++ date.setTime(Math.floor((+date - offset) / durationHour) * durationHour + offset); ++}, function(date, step) { ++ date.setTime(+date + step * durationHour); ++}, function(start, end) { ++ return (end - start) / durationHour; ++}, function(date) { ++ return date.getHours(); ++}); ++var hours = hour.range; ++ ++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) / durationDay; ++}, function(date) { ++ return date.getDate() - 1; ++}); ++var days = day.range; ++ ++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) / durationWeek; ++ }); ++} ++ ++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 sundays = sunday.range; ++var mondays = monday.range; ++var tuesdays = tuesday.range; ++var wednesdays = wednesday.range; ++var thursdays = thursday.range; ++var fridays = friday.range; ++var saturdays = saturday.range; ++ ++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 months = month.range; ++ ++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 years = year.range; ++ ++var utcMinute = newInterval(function(date) { ++ date.setUTCSeconds(0, 0); ++}, function(date, step) { ++ date.setTime(+date + step * durationMinute); ++}, function(start, end) { ++ return (end - start) / durationMinute; ++}, function(date) { ++ return date.getUTCMinutes(); ++}); ++var utcMinutes = utcMinute.range; ++ ++var utcHour = newInterval(function(date) { ++ date.setUTCMinutes(0, 0, 0); ++}, function(date, step) { ++ date.setTime(+date + step * durationHour); ++}, function(start, end) { ++ return (end - start) / durationHour; ++}, function(date) { ++ return date.getUTCHours(); ++}); ++var utcHours = utcHour.range; ++ ++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; ++}, function(date) { ++ return date.getUTCDate() - 1; ++}); ++var utcDays = utcDay.range; ++ ++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; ++ }); ++} ++ ++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 utcSundays = utcSunday.range; ++var utcMondays = utcMonday.range; ++var utcTuesdays = utcTuesday.range; ++var utcWednesdays = utcWednesday.range; ++var utcThursdays = utcThursday.range; ++var utcFridays = utcFriday.range; ++var utcSaturdays = utcSaturday.range; ++ ++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 utcMonths = utcMonth.range; ++ ++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); ++ }); ++}; ++var utcYears = utcYear.range; ++ ++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"}, ++ numberRe = /^\s*\d+/, // note: ignores next directive ++ percentRe = /^%/, ++ 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; ++ ++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); ++ exports.timeFormat = locale$1.format; ++ exports.timeParse = locale$1.parse; ++ exports.utcFormat = locale$1.utcFormat; ++ exports.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 ++ : exports.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 ++ : exports.utcParse(isoSpecifier); ++ ++var durationSecond$1 = 1000, ++ durationMinute$1 = durationSecond$1 * 60, ++ durationHour$1 = durationMinute$1 * 60, ++ durationDay$1 = durationHour$1 * 24, ++ durationWeek$1 = durationDay$1 * 7, ++ durationMonth = durationDay$1 * 30, ++ durationYear = durationDay$1 * 365; ++ ++function date$1(t) { ++ return new Date(t); ++} ++ ++function number$3(t) { ++ return t instanceof Date ? +t : +new Date(+t); ++} ++ ++function calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format) { ++ var scale = continuous(deinterpolateLinear, reinterpolate), ++ invert = scale.invert, ++ domain = scale.domain; ++ ++ var formatMillisecond = format(".%L"), ++ formatSecond = format(":%S"), ++ formatMinute = format("%I:%M"), ++ formatHour = format("%I %p"), ++ formatDay = format("%a %d"), ++ formatWeek = format("%b %d"), ++ formatMonth = format("%B"), ++ formatYear = format("%Y"); ++ ++ var tickIntervals = [ ++ [second$$1, 1, durationSecond$1], ++ [second$$1, 5, 5 * durationSecond$1], ++ [second$$1, 15, 15 * durationSecond$1], ++ [second$$1, 30, 30 * durationSecond$1], ++ [minute$$1, 1, durationMinute$1], ++ [minute$$1, 5, 5 * durationMinute$1], ++ [minute$$1, 15, 15 * durationMinute$1], ++ [minute$$1, 30, 30 * durationMinute$1], ++ [ hour$$1, 1, durationHour$1 ], ++ [ hour$$1, 3, 3 * durationHour$1 ], ++ [ hour$$1, 6, 6 * durationHour$1 ], ++ [ hour$$1, 12, 12 * durationHour$1 ], ++ [ day$$1, 1, durationDay$1 ], ++ [ day$$1, 2, 2 * durationDay$1 ], ++ [ week, 1, durationWeek$1 ], ++ [ month$$1, 1, durationMonth ], ++ [ month$$1, 3, 3 * durationMonth ], ++ [ year$$1, 1, durationYear ] ++ ]; ++ ++ function tickFormat(date$$1) { ++ return (second$$1(date$$1) < date$$1 ? formatMillisecond ++ : minute$$1(date$$1) < date$$1 ? formatSecond ++ : hour$$1(date$$1) < date$$1 ? formatMinute ++ : day$$1(date$$1) < date$$1 ? formatHour ++ : month$$1(date$$1) < date$$1 ? (week(date$$1) < date$$1 ? formatDay : formatWeek) ++ : year$$1(date$$1) < date$$1 ? formatMonth ++ : formatYear)(date$$1); ++ } ++ ++ function tickInterval(interval, start, stop, step) { ++ if (interval == null) interval = 10; ++ ++ // If a desired tick count is specified, pick a reasonable tick interval ++ // based on the extent of the domain and a rough estimate of tick size. ++ // Otherwise, assume interval is already a time interval and use it. ++ if (typeof interval === "number") { ++ var target = Math.abs(stop - start) / interval, ++ i = bisector(function(i) { return i[2]; }).right(tickIntervals, target); ++ if (i === tickIntervals.length) { ++ step = tickStep(start / durationYear, stop / durationYear, interval); ++ interval = year$$1; ++ } else if (i) { ++ i = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i]; ++ step = i[1]; ++ interval = i[0]; ++ } else { ++ step = Math.max(tickStep(start, stop, interval), 1); ++ interval = millisecond$$1; ++ } ++ } ++ ++ return step == null ? interval : interval.every(step); ++ } ++ ++ scale.invert = function(y) { ++ return new Date(invert(y)); ++ }; ++ ++ scale.domain = function(_) { ++ return arguments.length ? domain(map$2.call(_, number$3)) : domain().map(date$1); ++ }; ++ ++ scale.ticks = function(interval, step) { ++ var d = domain(), ++ t0 = d[0], ++ t1 = d[d.length - 1], ++ r = t1 < t0, ++ t; ++ if (r) t = t0, t0 = t1, t1 = t; ++ t = tickInterval(interval, t0, t1, step); ++ t = t ? t.range(t0, t1 + 1) : []; // inclusive stop ++ return r ? t.reverse() : t; ++ }; ++ ++ scale.tickFormat = function(count, specifier) { ++ return specifier == null ? tickFormat : format(specifier); ++ }; ++ ++ scale.nice = function(interval, step) { ++ var d = domain(); ++ return (interval = tickInterval(interval, d[0], d[d.length - 1], step)) ++ ? domain(nice(d, interval)) ++ : scale; ++ }; ++ ++ scale.copy = function() { ++ return copy(scale, calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format)); ++ }; ++ ++ return scale; ++} ++ ++function time() { ++ return calendar(year, month, sunday, day, hour, minute, second, millisecond, exports.timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]); ++} ++ ++function utcTime() { ++ return calendar(utcYear, utcMonth, utcSunday, utcDay, utcHour, utcMinute, second, millisecond, exports.utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]); ++} ++ ++function sequential(interpolator) { ++ var x0 = 0, ++ x1 = 1, ++ k10 = 1, ++ clamp = false; ++ ++ function scale(x) { ++ var t = (x - x0) * k10; ++ return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t); ++ } ++ ++ scale.domain = function(_) { ++ return arguments.length ? (x0 = +_[0], x1 = +_[1], k10 = x0 === x1 ? 0 : 1 / (x1 - x0), scale) : [x0, x1]; ++ }; ++ ++ scale.clamp = function(_) { ++ return arguments.length ? (clamp = !!_, scale) : clamp; ++ }; ++ ++ scale.interpolator = function(_) { ++ return arguments.length ? (interpolator = _, scale) : interpolator; ++ }; ++ ++ scale.copy = function() { ++ return sequential(interpolator).domain([x0, x1]).clamp(clamp); ++ }; ++ ++ return linearish(scale); ++} ++ ++function diverging(interpolator) { ++ var x0 = 0, ++ x1 = 0.5, ++ x2 = 1, ++ k10 = 1, ++ k21 = 1, ++ clamp = false; ++ ++ function scale(x) { ++ var t = 0.5 + ((x = +x) - x1) * (x < x1 ? k10 : k21); ++ return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t); ++ } ++ ++ scale.domain = function(_) { ++ return arguments.length ? (x0 = +_[0], x1 = +_[1], x2 = +_[2], k10 = x0 === x1 ? 0 : 0.5 / (x1 - x0), k21 = x1 === x2 ? 0 : 0.5 / (x2 - x1), scale) : [x0, x1, x2]; ++ }; ++ ++ scale.clamp = function(_) { ++ return arguments.length ? (clamp = !!_, scale) : clamp; ++ }; ++ ++ scale.interpolator = function(_) { ++ return arguments.length ? (interpolator = _, scale) : interpolator; ++ }; ++ ++ scale.copy = function() { ++ return diverging(interpolator).domain([x0, x1, x2]).clamp(clamp); ++ }; ++ ++ return linearish(scale); ++} ++ ++function colors(specifier) { ++ var n = specifier.length / 6 | 0, colors = new Array(n), i = 0; ++ while (i < n) colors[i] = "#" + specifier.slice(i * 6, ++i * 6); ++ return colors; ++} ++ ++var category10 = colors("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf"); ++ ++var Accent = colors("7fc97fbeaed4fdc086ffff99386cb0f0027fbf5b17666666"); ++ ++var Dark2 = colors("1b9e77d95f027570b3e7298a66a61ee6ab02a6761d666666"); ++ ++var Paired = colors("a6cee31f78b4b2df8a33a02cfb9a99e31a1cfdbf6fff7f00cab2d66a3d9affff99b15928"); ++ ++var Pastel1 = colors("fbb4aeb3cde3ccebc5decbe4fed9a6ffffcce5d8bdfddaecf2f2f2"); ++ ++var Pastel2 = colors("b3e2cdfdcdaccbd5e8f4cae4e6f5c9fff2aef1e2cccccccc"); ++ ++var Set1 = colors("e41a1c377eb84daf4a984ea3ff7f00ffff33a65628f781bf999999"); ++ ++var Set2 = colors("66c2a5fc8d628da0cbe78ac3a6d854ffd92fe5c494b3b3b3"); ++ ++var Set3 = colors("8dd3c7ffffb3bebadafb807280b1d3fdb462b3de69fccde5d9d9d9bc80bdccebc5ffed6f"); ++ ++function ramp(scheme) { ++ return rgbBasis(scheme[scheme.length - 1]); ++} ++ ++var scheme = new Array(3).concat( ++ "d8b365f5f5f55ab4ac", ++ "a6611adfc27d80cdc1018571", ++ "a6611adfc27df5f5f580cdc1018571", ++ "8c510ad8b365f6e8c3c7eae55ab4ac01665e", ++ "8c510ad8b365f6e8c3f5f5f5c7eae55ab4ac01665e", ++ "8c510abf812ddfc27df6e8c3c7eae580cdc135978f01665e", ++ "8c510abf812ddfc27df6e8c3f5f5f5c7eae580cdc135978f01665e", ++ "5430058c510abf812ddfc27df6e8c3c7eae580cdc135978f01665e003c30", ++ "5430058c510abf812ddfc27df6e8c3f5f5f5c7eae580cdc135978f01665e003c30" ++).map(colors); ++ ++var BrBG = ramp(scheme); ++ ++var scheme$1 = new Array(3).concat( ++ "af8dc3f7f7f77fbf7b", ++ "7b3294c2a5cfa6dba0008837", ++ "7b3294c2a5cff7f7f7a6dba0008837", ++ "762a83af8dc3e7d4e8d9f0d37fbf7b1b7837", ++ "762a83af8dc3e7d4e8f7f7f7d9f0d37fbf7b1b7837", ++ "762a839970abc2a5cfe7d4e8d9f0d3a6dba05aae611b7837", ++ "762a839970abc2a5cfe7d4e8f7f7f7d9f0d3a6dba05aae611b7837", ++ "40004b762a839970abc2a5cfe7d4e8d9f0d3a6dba05aae611b783700441b", ++ "40004b762a839970abc2a5cfe7d4e8f7f7f7d9f0d3a6dba05aae611b783700441b" ++).map(colors); ++ ++var PRGn = ramp(scheme$1); ++ ++var scheme$2 = new Array(3).concat( ++ "e9a3c9f7f7f7a1d76a", ++ "d01c8bf1b6dab8e1864dac26", ++ "d01c8bf1b6daf7f7f7b8e1864dac26", ++ "c51b7de9a3c9fde0efe6f5d0a1d76a4d9221", ++ "c51b7de9a3c9fde0eff7f7f7e6f5d0a1d76a4d9221", ++ "c51b7dde77aef1b6dafde0efe6f5d0b8e1867fbc414d9221", ++ "c51b7dde77aef1b6dafde0eff7f7f7e6f5d0b8e1867fbc414d9221", ++ "8e0152c51b7dde77aef1b6dafde0efe6f5d0b8e1867fbc414d9221276419", ++ "8e0152c51b7dde77aef1b6dafde0eff7f7f7e6f5d0b8e1867fbc414d9221276419" ++).map(colors); ++ ++var PiYG = ramp(scheme$2); ++ ++var scheme$3 = new Array(3).concat( ++ "998ec3f7f7f7f1a340", ++ "5e3c99b2abd2fdb863e66101", ++ "5e3c99b2abd2f7f7f7fdb863e66101", ++ "542788998ec3d8daebfee0b6f1a340b35806", ++ "542788998ec3d8daebf7f7f7fee0b6f1a340b35806", ++ "5427888073acb2abd2d8daebfee0b6fdb863e08214b35806", ++ "5427888073acb2abd2d8daebf7f7f7fee0b6fdb863e08214b35806", ++ "2d004b5427888073acb2abd2d8daebfee0b6fdb863e08214b358067f3b08", ++ "2d004b5427888073acb2abd2d8daebf7f7f7fee0b6fdb863e08214b358067f3b08" ++).map(colors); ++ ++var PuOr = ramp(scheme$3); ++ ++var scheme$4 = new Array(3).concat( ++ "ef8a62f7f7f767a9cf", ++ "ca0020f4a58292c5de0571b0", ++ "ca0020f4a582f7f7f792c5de0571b0", ++ "b2182bef8a62fddbc7d1e5f067a9cf2166ac", ++ "b2182bef8a62fddbc7f7f7f7d1e5f067a9cf2166ac", ++ "b2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac", ++ "b2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac", ++ "67001fb2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac053061", ++ "67001fb2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac053061" ++).map(colors); ++ ++var RdBu = ramp(scheme$4); ++ ++var scheme$5 = new Array(3).concat( ++ "ef8a62ffffff999999", ++ "ca0020f4a582bababa404040", ++ "ca0020f4a582ffffffbababa404040", ++ "b2182bef8a62fddbc7e0e0e09999994d4d4d", ++ "b2182bef8a62fddbc7ffffffe0e0e09999994d4d4d", ++ "b2182bd6604df4a582fddbc7e0e0e0bababa8787874d4d4d", ++ "b2182bd6604df4a582fddbc7ffffffe0e0e0bababa8787874d4d4d", ++ "67001fb2182bd6604df4a582fddbc7e0e0e0bababa8787874d4d4d1a1a1a", ++ "67001fb2182bd6604df4a582fddbc7ffffffe0e0e0bababa8787874d4d4d1a1a1a" ++).map(colors); ++ ++var RdGy = ramp(scheme$5); ++ ++var scheme$6 = new Array(3).concat( ++ "fc8d59ffffbf91bfdb", ++ "d7191cfdae61abd9e92c7bb6", ++ "d7191cfdae61ffffbfabd9e92c7bb6", ++ "d73027fc8d59fee090e0f3f891bfdb4575b4", ++ "d73027fc8d59fee090ffffbfe0f3f891bfdb4575b4", ++ "d73027f46d43fdae61fee090e0f3f8abd9e974add14575b4", ++ "d73027f46d43fdae61fee090ffffbfe0f3f8abd9e974add14575b4", ++ "a50026d73027f46d43fdae61fee090e0f3f8abd9e974add14575b4313695", ++ "a50026d73027f46d43fdae61fee090ffffbfe0f3f8abd9e974add14575b4313695" ++).map(colors); ++ ++var RdYlBu = ramp(scheme$6); ++ ++var scheme$7 = new Array(3).concat( ++ "fc8d59ffffbf91cf60", ++ "d7191cfdae61a6d96a1a9641", ++ "d7191cfdae61ffffbfa6d96a1a9641", ++ "d73027fc8d59fee08bd9ef8b91cf601a9850", ++ "d73027fc8d59fee08bffffbfd9ef8b91cf601a9850", ++ "d73027f46d43fdae61fee08bd9ef8ba6d96a66bd631a9850", ++ "d73027f46d43fdae61fee08bffffbfd9ef8ba6d96a66bd631a9850", ++ "a50026d73027f46d43fdae61fee08bd9ef8ba6d96a66bd631a9850006837", ++ "a50026d73027f46d43fdae61fee08bffffbfd9ef8ba6d96a66bd631a9850006837" ++).map(colors); ++ ++var RdYlGn = ramp(scheme$7); ++ ++var scheme$8 = new Array(3).concat( ++ "fc8d59ffffbf99d594", ++ "d7191cfdae61abdda42b83ba", ++ "d7191cfdae61ffffbfabdda42b83ba", ++ "d53e4ffc8d59fee08be6f59899d5943288bd", ++ "d53e4ffc8d59fee08bffffbfe6f59899d5943288bd", ++ "d53e4ff46d43fdae61fee08be6f598abdda466c2a53288bd", ++ "d53e4ff46d43fdae61fee08bffffbfe6f598abdda466c2a53288bd", ++ "9e0142d53e4ff46d43fdae61fee08be6f598abdda466c2a53288bd5e4fa2", ++ "9e0142d53e4ff46d43fdae61fee08bffffbfe6f598abdda466c2a53288bd5e4fa2" ++).map(colors); ++ ++var Spectral = ramp(scheme$8); ++ ++var scheme$9 = new Array(3).concat( ++ "e5f5f999d8c92ca25f", ++ "edf8fbb2e2e266c2a4238b45", ++ "edf8fbb2e2e266c2a42ca25f006d2c", ++ "edf8fbccece699d8c966c2a42ca25f006d2c", ++ "edf8fbccece699d8c966c2a441ae76238b45005824", ++ "f7fcfde5f5f9ccece699d8c966c2a441ae76238b45005824", ++ "f7fcfde5f5f9ccece699d8c966c2a441ae76238b45006d2c00441b" ++).map(colors); ++ ++var BuGn = ramp(scheme$9); ++ ++var scheme$10 = new Array(3).concat( ++ "e0ecf49ebcda8856a7", ++ "edf8fbb3cde38c96c688419d", ++ "edf8fbb3cde38c96c68856a7810f7c", ++ "edf8fbbfd3e69ebcda8c96c68856a7810f7c", ++ "edf8fbbfd3e69ebcda8c96c68c6bb188419d6e016b", ++ "f7fcfde0ecf4bfd3e69ebcda8c96c68c6bb188419d6e016b", ++ "f7fcfde0ecf4bfd3e69ebcda8c96c68c6bb188419d810f7c4d004b" ++).map(colors); ++ ++var BuPu = ramp(scheme$10); ++ ++var scheme$11 = new Array(3).concat( ++ "e0f3dba8ddb543a2ca", ++ "f0f9e8bae4bc7bccc42b8cbe", ++ "f0f9e8bae4bc7bccc443a2ca0868ac", ++ "f0f9e8ccebc5a8ddb57bccc443a2ca0868ac", ++ "f0f9e8ccebc5a8ddb57bccc44eb3d32b8cbe08589e", ++ "f7fcf0e0f3dbccebc5a8ddb57bccc44eb3d32b8cbe08589e", ++ "f7fcf0e0f3dbccebc5a8ddb57bccc44eb3d32b8cbe0868ac084081" ++).map(colors); ++ ++var GnBu = ramp(scheme$11); ++ ++var scheme$12 = new Array(3).concat( ++ "fee8c8fdbb84e34a33", ++ "fef0d9fdcc8afc8d59d7301f", ++ "fef0d9fdcc8afc8d59e34a33b30000", ++ "fef0d9fdd49efdbb84fc8d59e34a33b30000", ++ "fef0d9fdd49efdbb84fc8d59ef6548d7301f990000", ++ "fff7ecfee8c8fdd49efdbb84fc8d59ef6548d7301f990000", ++ "fff7ecfee8c8fdd49efdbb84fc8d59ef6548d7301fb300007f0000" ++).map(colors); ++ ++var OrRd = ramp(scheme$12); ++ ++var scheme$13 = new Array(3).concat( ++ "ece2f0a6bddb1c9099", ++ "f6eff7bdc9e167a9cf02818a", ++ "f6eff7bdc9e167a9cf1c9099016c59", ++ "f6eff7d0d1e6a6bddb67a9cf1c9099016c59", ++ "f6eff7d0d1e6a6bddb67a9cf3690c002818a016450", ++ "fff7fbece2f0d0d1e6a6bddb67a9cf3690c002818a016450", ++ "fff7fbece2f0d0d1e6a6bddb67a9cf3690c002818a016c59014636" ++).map(colors); ++ ++var PuBuGn = ramp(scheme$13); ++ ++var scheme$14 = new Array(3).concat( ++ "ece7f2a6bddb2b8cbe", ++ "f1eef6bdc9e174a9cf0570b0", ++ "f1eef6bdc9e174a9cf2b8cbe045a8d", ++ "f1eef6d0d1e6a6bddb74a9cf2b8cbe045a8d", ++ "f1eef6d0d1e6a6bddb74a9cf3690c00570b0034e7b", ++ "fff7fbece7f2d0d1e6a6bddb74a9cf3690c00570b0034e7b", ++ "fff7fbece7f2d0d1e6a6bddb74a9cf3690c00570b0045a8d023858" ++).map(colors); ++ ++var PuBu = ramp(scheme$14); ++ ++var scheme$15 = new Array(3).concat( ++ "e7e1efc994c7dd1c77", ++ "f1eef6d7b5d8df65b0ce1256", ++ "f1eef6d7b5d8df65b0dd1c77980043", ++ "f1eef6d4b9dac994c7df65b0dd1c77980043", ++ "f1eef6d4b9dac994c7df65b0e7298ace125691003f", ++ "f7f4f9e7e1efd4b9dac994c7df65b0e7298ace125691003f", ++ "f7f4f9e7e1efd4b9dac994c7df65b0e7298ace125698004367001f" ++).map(colors); ++ ++var PuRd = ramp(scheme$15); ++ ++var scheme$16 = new Array(3).concat( ++ "fde0ddfa9fb5c51b8a", ++ "feebe2fbb4b9f768a1ae017e", ++ "feebe2fbb4b9f768a1c51b8a7a0177", ++ "feebe2fcc5c0fa9fb5f768a1c51b8a7a0177", ++ "feebe2fcc5c0fa9fb5f768a1dd3497ae017e7a0177", ++ "fff7f3fde0ddfcc5c0fa9fb5f768a1dd3497ae017e7a0177", ++ "fff7f3fde0ddfcc5c0fa9fb5f768a1dd3497ae017e7a017749006a" ++).map(colors); ++ ++var RdPu = ramp(scheme$16); ++ ++var scheme$17 = new Array(3).concat( ++ "edf8b17fcdbb2c7fb8", ++ "ffffcca1dab441b6c4225ea8", ++ "ffffcca1dab441b6c42c7fb8253494", ++ "ffffccc7e9b47fcdbb41b6c42c7fb8253494", ++ "ffffccc7e9b47fcdbb41b6c41d91c0225ea80c2c84", ++ "ffffd9edf8b1c7e9b47fcdbb41b6c41d91c0225ea80c2c84", ++ "ffffd9edf8b1c7e9b47fcdbb41b6c41d91c0225ea8253494081d58" ++).map(colors); ++ ++var YlGnBu = ramp(scheme$17); ++ ++var scheme$18 = new Array(3).concat( ++ "f7fcb9addd8e31a354", ++ "ffffccc2e69978c679238443", ++ "ffffccc2e69978c67931a354006837", ++ "ffffccd9f0a3addd8e78c67931a354006837", ++ "ffffccd9f0a3addd8e78c67941ab5d238443005a32", ++ "ffffe5f7fcb9d9f0a3addd8e78c67941ab5d238443005a32", ++ "ffffe5f7fcb9d9f0a3addd8e78c67941ab5d238443006837004529" ++).map(colors); ++ ++var YlGn = ramp(scheme$18); ++ ++var scheme$19 = new Array(3).concat( ++ "fff7bcfec44fd95f0e", ++ "ffffd4fed98efe9929cc4c02", ++ "ffffd4fed98efe9929d95f0e993404", ++ "ffffd4fee391fec44ffe9929d95f0e993404", ++ "ffffd4fee391fec44ffe9929ec7014cc4c028c2d04", ++ "ffffe5fff7bcfee391fec44ffe9929ec7014cc4c028c2d04", ++ "ffffe5fff7bcfee391fec44ffe9929ec7014cc4c02993404662506" ++).map(colors); ++ ++var YlOrBr = ramp(scheme$19); ++ ++var scheme$20 = new Array(3).concat( ++ "ffeda0feb24cf03b20", ++ "ffffb2fecc5cfd8d3ce31a1c", ++ "ffffb2fecc5cfd8d3cf03b20bd0026", ++ "ffffb2fed976feb24cfd8d3cf03b20bd0026", ++ "ffffb2fed976feb24cfd8d3cfc4e2ae31a1cb10026", ++ "ffffccffeda0fed976feb24cfd8d3cfc4e2ae31a1cb10026", ++ "ffffccffeda0fed976feb24cfd8d3cfc4e2ae31a1cbd0026800026" ++).map(colors); ++ ++var YlOrRd = ramp(scheme$20); ++ ++var scheme$21 = new Array(3).concat( ++ "deebf79ecae13182bd", ++ "eff3ffbdd7e76baed62171b5", ++ "eff3ffbdd7e76baed63182bd08519c", ++ "eff3ffc6dbef9ecae16baed63182bd08519c", ++ "eff3ffc6dbef9ecae16baed64292c62171b5084594", ++ "f7fbffdeebf7c6dbef9ecae16baed64292c62171b5084594", ++ "f7fbffdeebf7c6dbef9ecae16baed64292c62171b508519c08306b" ++).map(colors); ++ ++var Blues = ramp(scheme$21); ++ ++var scheme$22 = new Array(3).concat( ++ "e5f5e0a1d99b31a354", ++ "edf8e9bae4b374c476238b45", ++ "edf8e9bae4b374c47631a354006d2c", ++ "edf8e9c7e9c0a1d99b74c47631a354006d2c", ++ "edf8e9c7e9c0a1d99b74c47641ab5d238b45005a32", ++ "f7fcf5e5f5e0c7e9c0a1d99b74c47641ab5d238b45005a32", ++ "f7fcf5e5f5e0c7e9c0a1d99b74c47641ab5d238b45006d2c00441b" ++).map(colors); ++ ++var Greens = ramp(scheme$22); ++ ++var scheme$23 = new Array(3).concat( ++ "f0f0f0bdbdbd636363", ++ "f7f7f7cccccc969696525252", ++ "f7f7f7cccccc969696636363252525", ++ "f7f7f7d9d9d9bdbdbd969696636363252525", ++ "f7f7f7d9d9d9bdbdbd969696737373525252252525", ++ "fffffff0f0f0d9d9d9bdbdbd969696737373525252252525", ++ "fffffff0f0f0d9d9d9bdbdbd969696737373525252252525000000" ++).map(colors); ++ ++var Greys = ramp(scheme$23); ++ ++var scheme$24 = new Array(3).concat( ++ "efedf5bcbddc756bb1", ++ "f2f0f7cbc9e29e9ac86a51a3", ++ "f2f0f7cbc9e29e9ac8756bb154278f", ++ "f2f0f7dadaebbcbddc9e9ac8756bb154278f", ++ "f2f0f7dadaebbcbddc9e9ac8807dba6a51a34a1486", ++ "fcfbfdefedf5dadaebbcbddc9e9ac8807dba6a51a34a1486", ++ "fcfbfdefedf5dadaebbcbddc9e9ac8807dba6a51a354278f3f007d" ++).map(colors); ++ ++var Purples = ramp(scheme$24); ++ ++var scheme$25 = new Array(3).concat( ++ "fee0d2fc9272de2d26", ++ "fee5d9fcae91fb6a4acb181d", ++ "fee5d9fcae91fb6a4ade2d26a50f15", ++ "fee5d9fcbba1fc9272fb6a4ade2d26a50f15", ++ "fee5d9fcbba1fc9272fb6a4aef3b2ccb181d99000d", ++ "fff5f0fee0d2fcbba1fc9272fb6a4aef3b2ccb181d99000d", ++ "fff5f0fee0d2fcbba1fc9272fb6a4aef3b2ccb181da50f1567000d" ++).map(colors); ++ ++var Reds = ramp(scheme$25); ++ ++var scheme$26 = new Array(3).concat( ++ "fee6cefdae6be6550d", ++ "feeddefdbe85fd8d3cd94701", ++ "feeddefdbe85fd8d3ce6550da63603", ++ "feeddefdd0a2fdae6bfd8d3ce6550da63603", ++ "feeddefdd0a2fdae6bfd8d3cf16913d948018c2d04", ++ "fff5ebfee6cefdd0a2fdae6bfd8d3cf16913d948018c2d04", ++ "fff5ebfee6cefdd0a2fdae6bfd8d3cf16913d94801a636037f2704" ++).map(colors); ++ ++var Oranges = ramp(scheme$26); ++ ++var cubehelix$3 = 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 c = cubehelix(); ++ ++function rainbow(t) { ++ if (t < 0 || t > 1) t -= Math.floor(t); ++ var ts = Math.abs(t - 0.5); ++ c.h = 360 * t - 100; ++ c.s = 1.5 - 1.5 * ts; ++ c.l = 0.8 - 0.9 * ts; ++ return c + ""; ++} ++ ++var c$1 = rgb(), ++ pi_1_3 = Math.PI / 3, ++ pi_2_3 = Math.PI * 2 / 3; ++ ++function sinebow(t) { ++ var x; ++ t = (0.5 - t) * Math.PI; ++ c$1.r = 255 * (x = Math.sin(t)) * x; ++ c$1.g = 255 * (x = Math.sin(t + pi_1_3)) * x; ++ c$1.b = 255 * (x = Math.sin(t + pi_2_3)) * x; ++ return c$1 + ""; ++} ++ ++function ramp$1(range) { ++ var n = range.length; ++ return function(t) { ++ return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))]; ++ }; ++} ++ ++var viridis = ramp$1(colors("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725")); ++ ++var magma = ramp$1(colors("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")); ++ ++var inferno = ramp$1(colors("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")); ++ ++var plasma = ramp$1(colors("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921")); ++ ++function constant$11(x) { ++ return function constant() { ++ return x; ++ }; ++} ++ ++var abs$1 = Math.abs; ++var atan2$1 = Math.atan2; ++var cos$2 = Math.cos; ++var max$2 = Math.max; ++var min$1 = Math.min; ++var sin$2 = Math.sin; ++var sqrt$2 = Math.sqrt; ++ ++var epsilon$3 = 1e-12; ++var pi$4 = Math.PI; ++var halfPi$3 = pi$4 / 2; ++var tau$4 = 2 * pi$4; ++ ++function acos$1(x) { ++ return x > 1 ? 0 : x < -1 ? pi$4 : Math.acos(x); ++} ++ ++function asin$1(x) { ++ return x >= 1 ? halfPi$3 : x <= -1 ? -halfPi$3 : Math.asin(x); ++} ++ ++function arcInnerRadius(d) { ++ return d.innerRadius; ++} ++ ++function arcOuterRadius(d) { ++ return d.outerRadius; ++} ++ ++function arcStartAngle(d) { ++ return d.startAngle; ++} ++ ++function arcEndAngle(d) { ++ return d.endAngle; ++} ++ ++function arcPadAngle(d) { ++ return d && d.padAngle; // Note: optional! ++} ++ ++function intersect(x0, y0, x1, y1, x2, y2, x3, y3) { ++ var x10 = x1 - x0, y10 = y1 - y0, ++ x32 = x3 - x2, y32 = y3 - y2, ++ t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / (y32 * x10 - x32 * y10); ++ return [x0 + t * x10, y0 + t * y10]; ++} ++ ++// Compute perpendicular offset line of length rc. ++// http://mathworld.wolfram.com/Circle-LineIntersection.html ++function cornerTangents(x0, y0, x1, y1, r1, rc, cw) { ++ var x01 = x0 - x1, ++ y01 = y0 - y1, ++ lo = (cw ? rc : -rc) / sqrt$2(x01 * x01 + y01 * y01), ++ ox = lo * y01, ++ oy = -lo * x01, ++ x11 = x0 + ox, ++ y11 = y0 + oy, ++ x10 = x1 + ox, ++ y10 = y1 + oy, ++ x00 = (x11 + x10) / 2, ++ y00 = (y11 + y10) / 2, ++ dx = x10 - x11, ++ dy = y10 - y11, ++ d2 = dx * dx + dy * dy, ++ r = r1 - rc, ++ D = x11 * y10 - x10 * y11, ++ d = (dy < 0 ? -1 : 1) * sqrt$2(max$2(0, r * r * d2 - D * D)), ++ cx0 = (D * dy - dx * d) / d2, ++ cy0 = (-D * dx - dy * d) / d2, ++ cx1 = (D * dy + dx * d) / d2, ++ cy1 = (-D * dx + dy * d) / d2, ++ dx0 = cx0 - x00, ++ dy0 = cy0 - y00, ++ dx1 = cx1 - x00, ++ dy1 = cy1 - y00; ++ ++ // Pick the closer of the two intersection points. ++ // TODO Is there a faster way to determine which intersection to use? ++ if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1; ++ ++ return { ++ cx: cx0, ++ cy: cy0, ++ x01: -ox, ++ y01: -oy, ++ x11: cx0 * (r1 / r - 1), ++ y11: cy0 * (r1 / r - 1) ++ }; ++} ++ ++function arc() { ++ var innerRadius = arcInnerRadius, ++ outerRadius = arcOuterRadius, ++ cornerRadius = constant$11(0), ++ padRadius = null, ++ startAngle = arcStartAngle, ++ endAngle = arcEndAngle, ++ padAngle = arcPadAngle, ++ context = null; ++ ++ function arc() { ++ var buffer, ++ r, ++ r0 = +innerRadius.apply(this, arguments), ++ r1 = +outerRadius.apply(this, arguments), ++ a0 = startAngle.apply(this, arguments) - halfPi$3, ++ a1 = endAngle.apply(this, arguments) - halfPi$3, ++ da = abs$1(a1 - a0), ++ cw = a1 > a0; ++ ++ if (!context) context = buffer = path(); ++ ++ // Ensure that the outer radius is always larger than the inner radius. ++ if (r1 < r0) r = r1, r1 = r0, r0 = r; ++ ++ // Is it a point? ++ if (!(r1 > epsilon$3)) context.moveTo(0, 0); ++ ++ // Or is it a circle or annulus? ++ else if (da > tau$4 - epsilon$3) { ++ context.moveTo(r1 * cos$2(a0), r1 * sin$2(a0)); ++ context.arc(0, 0, r1, a0, a1, !cw); ++ if (r0 > epsilon$3) { ++ context.moveTo(r0 * cos$2(a1), r0 * sin$2(a1)); ++ context.arc(0, 0, r0, a1, a0, cw); ++ } ++ } ++ ++ // Or is it a circular or annular sector? ++ else { ++ var a01 = a0, ++ a11 = a1, ++ a00 = a0, ++ a10 = a1, ++ da0 = da, ++ da1 = da, ++ ap = padAngle.apply(this, arguments) / 2, ++ rp = (ap > epsilon$3) && (padRadius ? +padRadius.apply(this, arguments) : sqrt$2(r0 * r0 + r1 * r1)), ++ rc = min$1(abs$1(r1 - r0) / 2, +cornerRadius.apply(this, arguments)), ++ rc0 = rc, ++ rc1 = rc, ++ t0, ++ t1; ++ ++ // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0. ++ if (rp > epsilon$3) { ++ var p0 = asin$1(rp / r0 * sin$2(ap)), ++ p1 = asin$1(rp / r1 * sin$2(ap)); ++ if ((da0 -= p0 * 2) > epsilon$3) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0; ++ else da0 = 0, a00 = a10 = (a0 + a1) / 2; ++ if ((da1 -= p1 * 2) > epsilon$3) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1; ++ else da1 = 0, a01 = a11 = (a0 + a1) / 2; ++ } ++ ++ var x01 = r1 * cos$2(a01), ++ y01 = r1 * sin$2(a01), ++ x10 = r0 * cos$2(a10), ++ y10 = r0 * sin$2(a10); ++ ++ // Apply rounded corners? ++ if (rc > epsilon$3) { ++ var x11 = r1 * cos$2(a11), ++ y11 = r1 * sin$2(a11), ++ x00 = r0 * cos$2(a00), ++ y00 = r0 * sin$2(a00); ++ ++ // Restrict the corner radius according to the sector angle. ++ if (da < pi$4) { ++ var oc = da0 > epsilon$3 ? intersect(x01, y01, x00, y00, x11, y11, x10, y10) : [x10, y10], ++ ax = x01 - oc[0], ++ ay = y01 - oc[1], ++ bx = x11 - oc[0], ++ by = y11 - oc[1], ++ kc = 1 / sin$2(acos$1((ax * bx + ay * by) / (sqrt$2(ax * ax + ay * ay) * sqrt$2(bx * bx + by * by))) / 2), ++ lc = sqrt$2(oc[0] * oc[0] + oc[1] * oc[1]); ++ rc0 = min$1(rc, (r0 - lc) / (kc - 1)); ++ rc1 = min$1(rc, (r1 - lc) / (kc + 1)); ++ } ++ } ++ ++ // Is the sector collapsed to a line? ++ if (!(da1 > epsilon$3)) context.moveTo(x01, y01); ++ ++ // Does the sector’s outer ring have rounded corners? ++ else if (rc1 > epsilon$3) { ++ t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw); ++ t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw); ++ ++ context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01); ++ ++ // Have the corners merged? ++ if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw); ++ ++ // Otherwise, draw the two corners and the ring. ++ else { ++ context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t0.y11, t0.x11), !cw); ++ context.arc(0, 0, r1, atan2$1(t0.cy + t0.y11, t0.cx + t0.x11), atan2$1(t1.cy + t1.y11, t1.cx + t1.x11), !cw); ++ context.arc(t1.cx, t1.cy, rc1, atan2$1(t1.y11, t1.x11), atan2$1(t1.y01, t1.x01), !cw); ++ } ++ } ++ ++ // Or is the outer ring just a circular arc? ++ else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw); ++ ++ // Is there no inner ring, and it’s a circular sector? ++ // Or perhaps it’s an annular sector collapsed due to padding? ++ if (!(r0 > epsilon$3) || !(da0 > epsilon$3)) context.lineTo(x10, y10); ++ ++ // Does the sector’s inner ring (or point) have rounded corners? ++ else if (rc0 > epsilon$3) { ++ t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw); ++ t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw); ++ ++ context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01); ++ ++ // Have the corners merged? ++ if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw); ++ ++ // Otherwise, draw the two corners and the ring. ++ else { ++ context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t0.y11, t0.x11), !cw); ++ context.arc(0, 0, r0, atan2$1(t0.cy + t0.y11, t0.cx + t0.x11), atan2$1(t1.cy + t1.y11, t1.cx + t1.x11), cw); ++ context.arc(t1.cx, t1.cy, rc0, atan2$1(t1.y11, t1.x11), atan2$1(t1.y01, t1.x01), !cw); ++ } ++ } ++ ++ // Or is the inner ring just a circular arc? ++ else context.arc(0, 0, r0, a10, a00, cw); ++ } ++ ++ context.closePath(); ++ ++ if (buffer) return context = null, buffer + "" || null; ++ } ++ ++ arc.centroid = function() { ++ var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2, ++ a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi$4 / 2; ++ return [cos$2(a) * r, sin$2(a) * r]; ++ }; ++ ++ arc.innerRadius = function(_) { ++ return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant$11(+_), arc) : innerRadius; ++ }; ++ ++ arc.outerRadius = function(_) { ++ return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant$11(+_), arc) : outerRadius; ++ }; ++ ++ arc.cornerRadius = function(_) { ++ return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant$11(+_), arc) : cornerRadius; ++ }; ++ ++ arc.padRadius = function(_) { ++ return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant$11(+_), arc) : padRadius; ++ }; ++ ++ arc.startAngle = function(_) { ++ return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$11(+_), arc) : startAngle; ++ }; ++ ++ arc.endAngle = function(_) { ++ return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$11(+_), arc) : endAngle; ++ }; ++ ++ arc.padAngle = function(_) { ++ return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$11(+_), arc) : padAngle; ++ }; ++ ++ arc.context = function(_) { ++ return arguments.length ? (context = _ == null ? null : _, arc) : context; ++ }; ++ ++ return arc; ++} ++ ++function Linear(context) { ++ this._context = context; ++} ++ ++Linear.prototype = { ++ areaStart: function() { ++ this._line = 0; ++ }, ++ areaEnd: function() { ++ this._line = NaN; ++ }, ++ lineStart: function() { ++ this._point = 0; ++ }, ++ lineEnd: function() { ++ if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); ++ this._line = 1 - this._line; ++ }, ++ point: function(x, y) { ++ x = +x, y = +y; ++ switch (this._point) { ++ case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; ++ case 1: this._point = 2; // proceed ++ default: this._context.lineTo(x, y); break; ++ } ++ } ++}; ++ ++function curveLinear(context) { ++ return new Linear(context); ++} ++ ++function x$3(p) { ++ return p[0]; ++} ++ ++function y$3(p) { ++ return p[1]; ++} ++ ++function line() { ++ var x$$1 = x$3, ++ y$$1 = y$3, ++ defined = constant$11(true), ++ context = null, ++ curve = curveLinear, ++ output = null; ++ ++ function line(data) { ++ var i, ++ n = data.length, ++ d, ++ defined0 = false, ++ buffer; ++ ++ if (context == null) output = curve(buffer = path()); ++ ++ for (i = 0; i <= n; ++i) { ++ if (!(i < n && defined(d = data[i], i, data)) === defined0) { ++ if (defined0 = !defined0) output.lineStart(); ++ else output.lineEnd(); ++ } ++ if (defined0) output.point(+x$$1(d, i, data), +y$$1(d, i, data)); ++ } ++ ++ if (buffer) return output = null, buffer + "" || null; ++ } ++ ++ line.x = function(_) { ++ return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$11(+_), line) : x$$1; ++ }; ++ ++ line.y = function(_) { ++ return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$11(+_), line) : y$$1; ++ }; ++ ++ line.defined = function(_) { ++ return arguments.length ? (defined = typeof _ === "function" ? _ : constant$11(!!_), line) : defined; ++ }; ++ ++ line.curve = function(_) { ++ return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve; ++ }; ++ ++ line.context = function(_) { ++ return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context; ++ }; ++ ++ return line; ++} ++ ++function area$3() { ++ var x0 = x$3, ++ x1 = null, ++ y0 = constant$11(0), ++ y1 = y$3, ++ defined = constant$11(true), ++ context = null, ++ curve = curveLinear, ++ output = null; ++ ++ function area(data) { ++ var i, ++ j, ++ k, ++ n = data.length, ++ d, ++ defined0 = false, ++ buffer, ++ x0z = new Array(n), ++ y0z = new Array(n); ++ ++ if (context == null) output = curve(buffer = path()); ++ ++ for (i = 0; i <= n; ++i) { ++ if (!(i < n && defined(d = data[i], i, data)) === defined0) { ++ if (defined0 = !defined0) { ++ j = i; ++ output.areaStart(); ++ output.lineStart(); ++ } else { ++ output.lineEnd(); ++ output.lineStart(); ++ for (k = i - 1; k >= j; --k) { ++ output.point(x0z[k], y0z[k]); ++ } ++ output.lineEnd(); ++ output.areaEnd(); ++ } ++ } ++ if (defined0) { ++ x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data); ++ output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]); ++ } ++ } ++ ++ if (buffer) return output = null, buffer + "" || null; ++ } ++ ++ function arealine() { ++ return line().defined(defined).curve(curve).context(context); ++ } ++ ++ area.x = function(_) { ++ return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$11(+_), x1 = null, area) : x0; ++ }; ++ ++ area.x0 = function(_) { ++ return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$11(+_), area) : x0; ++ }; ++ ++ area.x1 = function(_) { ++ return arguments.length ? (x1 = _ == null ? null : typeof _ === "function" ? _ : constant$11(+_), area) : x1; ++ }; ++ ++ area.y = function(_) { ++ return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$11(+_), y1 = null, area) : y0; ++ }; ++ ++ area.y0 = function(_) { ++ return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$11(+_), area) : y0; ++ }; ++ ++ area.y1 = function(_) { ++ return arguments.length ? (y1 = _ == null ? null : typeof _ === "function" ? _ : constant$11(+_), area) : y1; ++ }; ++ ++ area.lineX0 = ++ area.lineY0 = function() { ++ return arealine().x(x0).y(y0); ++ }; ++ ++ area.lineY1 = function() { ++ return arealine().x(x0).y(y1); ++ }; ++ ++ area.lineX1 = function() { ++ return arealine().x(x1).y(y0); ++ }; ++ ++ area.defined = function(_) { ++ return arguments.length ? (defined = typeof _ === "function" ? _ : constant$11(!!_), area) : defined; ++ }; ++ ++ area.curve = function(_) { ++ return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve; ++ }; ++ ++ area.context = function(_) { ++ return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context; ++ }; ++ ++ return area; ++} ++ ++function descending$1(a, b) { ++ return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; ++} ++ ++function identity$7(d) { ++ return d; ++} ++ ++function pie() { ++ var value = identity$7, ++ sortValues = descending$1, ++ sort = null, ++ startAngle = constant$11(0), ++ endAngle = constant$11(tau$4), ++ padAngle = constant$11(0); ++ ++ function pie(data) { ++ var i, ++ n = data.length, ++ j, ++ k, ++ sum = 0, ++ index = new Array(n), ++ arcs = new Array(n), ++ a0 = +startAngle.apply(this, arguments), ++ da = Math.min(tau$4, Math.max(-tau$4, endAngle.apply(this, arguments) - a0)), ++ a1, ++ p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)), ++ pa = p * (da < 0 ? -1 : 1), ++ v; ++ ++ for (i = 0; i < n; ++i) { ++ if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) { ++ sum += v; ++ } ++ } ++ ++ // Optionally sort the arcs by previously-computed values or by data. ++ if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); }); ++ else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); }); ++ ++ // Compute the arcs! They are stored in the original data's order. ++ for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) { ++ j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = { ++ data: data[j], ++ index: i, ++ value: v, ++ startAngle: a0, ++ endAngle: a1, ++ padAngle: p ++ }; ++ } ++ ++ return arcs; ++ } ++ ++ pie.value = function(_) { ++ return arguments.length ? (value = typeof _ === "function" ? _ : constant$11(+_), pie) : value; ++ }; ++ ++ pie.sortValues = function(_) { ++ return arguments.length ? (sortValues = _, sort = null, pie) : sortValues; ++ }; ++ ++ pie.sort = function(_) { ++ return arguments.length ? (sort = _, sortValues = null, pie) : sort; ++ }; ++ ++ pie.startAngle = function(_) { ++ return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$11(+_), pie) : startAngle; ++ }; ++ ++ pie.endAngle = function(_) { ++ return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$11(+_), pie) : endAngle; ++ }; ++ ++ pie.padAngle = function(_) { ++ return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$11(+_), pie) : padAngle; ++ }; ++ ++ return pie; ++} ++ ++var curveRadialLinear = curveRadial(curveLinear); ++ ++function Radial(curve) { ++ this._curve = curve; ++} ++ ++Radial.prototype = { ++ areaStart: function() { ++ this._curve.areaStart(); ++ }, ++ areaEnd: function() { ++ this._curve.areaEnd(); ++ }, ++ lineStart: function() { ++ this._curve.lineStart(); ++ }, ++ lineEnd: function() { ++ this._curve.lineEnd(); ++ }, ++ point: function(a, r) { ++ this._curve.point(r * Math.sin(a), r * -Math.cos(a)); ++ } ++}; ++ ++function curveRadial(curve) { ++ ++ function radial(context) { ++ return new Radial(curve(context)); ++ } ++ ++ radial._curve = curve; ++ ++ return radial; ++} ++ ++function lineRadial(l) { ++ var c = l.curve; ++ ++ l.angle = l.x, delete l.x; ++ l.radius = l.y, delete l.y; ++ ++ l.curve = function(_) { ++ return arguments.length ? c(curveRadial(_)) : c()._curve; ++ }; ++ ++ return l; ++} ++ ++function lineRadial$1() { ++ return lineRadial(line().curve(curveRadialLinear)); ++} ++ ++function areaRadial() { ++ var a = area$3().curve(curveRadialLinear), ++ c = a.curve, ++ x0 = a.lineX0, ++ x1 = a.lineX1, ++ y0 = a.lineY0, ++ y1 = a.lineY1; ++ ++ a.angle = a.x, delete a.x; ++ a.startAngle = a.x0, delete a.x0; ++ a.endAngle = a.x1, delete a.x1; ++ a.radius = a.y, delete a.y; ++ a.innerRadius = a.y0, delete a.y0; ++ a.outerRadius = a.y1, delete a.y1; ++ a.lineStartAngle = function() { return lineRadial(x0()); }, delete a.lineX0; ++ a.lineEndAngle = function() { return lineRadial(x1()); }, delete a.lineX1; ++ a.lineInnerRadius = function() { return lineRadial(y0()); }, delete a.lineY0; ++ a.lineOuterRadius = function() { return lineRadial(y1()); }, delete a.lineY1; ++ ++ a.curve = function(_) { ++ return arguments.length ? c(curveRadial(_)) : c()._curve; ++ }; ++ ++ return a; ++} ++ ++function pointRadial(x, y) { ++ return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)]; ++} ++ ++var slice$6 = Array.prototype.slice; ++ ++function linkSource(d) { ++ return d.source; ++} ++ ++function linkTarget(d) { ++ return d.target; ++} ++ ++function link$2(curve) { ++ var source = linkSource, ++ target = linkTarget, ++ x$$1 = x$3, ++ y$$1 = y$3, ++ context = null; ++ ++ function link() { ++ var buffer, argv = slice$6.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv); ++ if (!context) context = buffer = path(); ++ curve(context, +x$$1.apply(this, (argv[0] = s, argv)), +y$$1.apply(this, argv), +x$$1.apply(this, (argv[0] = t, argv)), +y$$1.apply(this, argv)); ++ if (buffer) return context = null, buffer + "" || null; ++ } ++ ++ link.source = function(_) { ++ return arguments.length ? (source = _, link) : source; ++ }; ++ ++ link.target = function(_) { ++ return arguments.length ? (target = _, link) : target; ++ }; ++ ++ link.x = function(_) { ++ return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$11(+_), link) : x$$1; ++ }; ++ ++ link.y = function(_) { ++ return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$11(+_), link) : y$$1; ++ }; ++ ++ link.context = function(_) { ++ return arguments.length ? (context = _ == null ? null : _, link) : context; ++ }; ++ ++ return link; ++} ++ ++function curveHorizontal(context, x0, y0, x1, y1) { ++ context.moveTo(x0, y0); ++ context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1); ++} ++ ++function curveVertical(context, x0, y0, x1, y1) { ++ context.moveTo(x0, y0); ++ context.bezierCurveTo(x0, y0 = (y0 + y1) / 2, x1, y0, x1, y1); ++} ++ ++function curveRadial$1(context, x0, y0, x1, y1) { ++ var p0 = pointRadial(x0, y0), ++ p1 = pointRadial(x0, y0 = (y0 + y1) / 2), ++ p2 = pointRadial(x1, y0), ++ p3 = pointRadial(x1, y1); ++ context.moveTo(p0[0], p0[1]); ++ context.bezierCurveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]); ++} ++ ++function linkHorizontal() { ++ return link$2(curveHorizontal); ++} ++ ++function linkVertical() { ++ return link$2(curveVertical); ++} ++ ++function linkRadial() { ++ var l = link$2(curveRadial$1); ++ l.angle = l.x, delete l.x; ++ l.radius = l.y, delete l.y; ++ return l; ++} ++ ++var circle$2 = { ++ draw: function(context, size) { ++ var r = Math.sqrt(size / pi$4); ++ context.moveTo(r, 0); ++ context.arc(0, 0, r, 0, tau$4); ++ } ++}; ++ ++var cross$2 = { ++ draw: function(context, size) { ++ var r = Math.sqrt(size / 5) / 2; ++ context.moveTo(-3 * r, -r); ++ context.lineTo(-r, -r); ++ context.lineTo(-r, -3 * r); ++ context.lineTo(r, -3 * r); ++ context.lineTo(r, -r); ++ context.lineTo(3 * r, -r); ++ context.lineTo(3 * r, r); ++ context.lineTo(r, r); ++ context.lineTo(r, 3 * r); ++ context.lineTo(-r, 3 * r); ++ context.lineTo(-r, r); ++ context.lineTo(-3 * r, r); ++ context.closePath(); ++ } ++}; ++ ++var tan30 = Math.sqrt(1 / 3), ++ tan30_2 = tan30 * 2; ++ ++var diamond = { ++ draw: function(context, size) { ++ var y = Math.sqrt(size / tan30_2), ++ x = y * tan30; ++ context.moveTo(0, -y); ++ context.lineTo(x, 0); ++ context.lineTo(0, y); ++ context.lineTo(-x, 0); ++ context.closePath(); ++ } ++}; ++ ++var ka = 0.89081309152928522810, ++ kr = Math.sin(pi$4 / 10) / Math.sin(7 * pi$4 / 10), ++ kx = Math.sin(tau$4 / 10) * kr, ++ ky = -Math.cos(tau$4 / 10) * kr; ++ ++var star = { ++ draw: function(context, size) { ++ var r = Math.sqrt(size * ka), ++ x = kx * r, ++ y = ky * r; ++ context.moveTo(0, -r); ++ context.lineTo(x, y); ++ for (var i = 1; i < 5; ++i) { ++ var a = tau$4 * i / 5, ++ c = Math.cos(a), ++ s = Math.sin(a); ++ context.lineTo(s * r, -c * r); ++ context.lineTo(c * x - s * y, s * x + c * y); ++ } ++ context.closePath(); ++ } ++}; ++ ++var square = { ++ draw: function(context, size) { ++ var w = Math.sqrt(size), ++ x = -w / 2; ++ context.rect(x, x, w, w); ++ } ++}; ++ ++var sqrt3 = Math.sqrt(3); ++ ++var triangle = { ++ draw: function(context, size) { ++ var y = -Math.sqrt(size / (sqrt3 * 3)); ++ context.moveTo(0, y * 2); ++ context.lineTo(-sqrt3 * y, -y); ++ context.lineTo(sqrt3 * y, -y); ++ context.closePath(); ++ } ++}; ++ ++var c$2 = -0.5, ++ s = Math.sqrt(3) / 2, ++ k = 1 / Math.sqrt(12), ++ a = (k / 2 + 1) * 3; ++ ++var wye = { ++ draw: function(context, size) { ++ var r = Math.sqrt(size / a), ++ x0 = r / 2, ++ y0 = r * k, ++ x1 = x0, ++ y1 = r * k + r, ++ x2 = -x1, ++ y2 = y1; ++ context.moveTo(x0, y0); ++ context.lineTo(x1, y1); ++ context.lineTo(x2, y2); ++ context.lineTo(c$2 * x0 - s * y0, s * x0 + c$2 * y0); ++ context.lineTo(c$2 * x1 - s * y1, s * x1 + c$2 * y1); ++ context.lineTo(c$2 * x2 - s * y2, s * x2 + c$2 * y2); ++ context.lineTo(c$2 * x0 + s * y0, c$2 * y0 - s * x0); ++ context.lineTo(c$2 * x1 + s * y1, c$2 * y1 - s * x1); ++ context.lineTo(c$2 * x2 + s * y2, c$2 * y2 - s * x2); ++ context.closePath(); ++ } ++}; ++ ++var symbols = [ ++ circle$2, ++ cross$2, ++ diamond, ++ square, ++ star, ++ triangle, ++ wye ++]; ++ ++function symbol() { ++ var type = constant$11(circle$2), ++ size = constant$11(64), ++ context = null; ++ ++ function symbol() { ++ var buffer; ++ if (!context) context = buffer = path(); ++ type.apply(this, arguments).draw(context, +size.apply(this, arguments)); ++ if (buffer) return context = null, buffer + "" || null; ++ } ++ ++ symbol.type = function(_) { ++ return arguments.length ? (type = typeof _ === "function" ? _ : constant$11(_), symbol) : type; ++ }; ++ ++ symbol.size = function(_) { ++ return arguments.length ? (size = typeof _ === "function" ? _ : constant$11(+_), symbol) : size; ++ }; ++ ++ symbol.context = function(_) { ++ return arguments.length ? (context = _ == null ? null : _, symbol) : context; ++ }; ++ ++ return symbol; ++} ++ ++function noop$3() {} ++ ++function point$2(that, x, y) { ++ that._context.bezierCurveTo( ++ (2 * that._x0 + that._x1) / 3, ++ (2 * that._y0 + that._y1) / 3, ++ (that._x0 + 2 * that._x1) / 3, ++ (that._y0 + 2 * that._y1) / 3, ++ (that._x0 + 4 * that._x1 + x) / 6, ++ (that._y0 + 4 * that._y1 + y) / 6 ++ ); ++} ++ ++function Basis(context) { ++ this._context = context; ++} ++ ++Basis.prototype = { ++ areaStart: function() { ++ this._line = 0; ++ }, ++ areaEnd: function() { ++ this._line = NaN; ++ }, ++ lineStart: function() { ++ this._x0 = this._x1 = ++ this._y0 = this._y1 = NaN; ++ this._point = 0; ++ }, ++ lineEnd: function() { ++ switch (this._point) { ++ case 3: point$2(this, this._x1, this._y1); // proceed ++ case 2: this._context.lineTo(this._x1, this._y1); break; ++ } ++ if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); ++ this._line = 1 - this._line; ++ }, ++ point: function(x, y) { ++ x = +x, y = +y; ++ switch (this._point) { ++ case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; ++ case 1: this._point = 2; break; ++ case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed ++ default: point$2(this, x, y); break; ++ } ++ this._x0 = this._x1, this._x1 = x; ++ this._y0 = this._y1, this._y1 = y; ++ } ++}; ++ ++function basis$2(context) { ++ return new Basis(context); ++} ++ ++function BasisClosed(context) { ++ this._context = context; ++} ++ ++BasisClosed.prototype = { ++ areaStart: noop$3, ++ areaEnd: noop$3, ++ lineStart: function() { ++ this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = ++ this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN; ++ this._point = 0; ++ }, ++ lineEnd: function() { ++ switch (this._point) { ++ case 1: { ++ this._context.moveTo(this._x2, this._y2); ++ this._context.closePath(); ++ break; ++ } ++ case 2: { ++ this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3); ++ this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3); ++ this._context.closePath(); ++ break; ++ } ++ case 3: { ++ this.point(this._x2, this._y2); ++ this.point(this._x3, this._y3); ++ this.point(this._x4, this._y4); ++ break; ++ } ++ } ++ }, ++ point: function(x, y) { ++ x = +x, y = +y; ++ switch (this._point) { ++ case 0: this._point = 1; this._x2 = x, this._y2 = y; break; ++ case 1: this._point = 2; this._x3 = x, this._y3 = y; break; ++ case 2: this._point = 3; this._x4 = x, this._y4 = y; this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6); break; ++ default: point$2(this, x, y); break; ++ } ++ this._x0 = this._x1, this._x1 = x; ++ this._y0 = this._y1, this._y1 = y; ++ } ++}; ++ ++function basisClosed$1(context) { ++ return new BasisClosed(context); ++} ++ ++function BasisOpen(context) { ++ this._context = context; ++} ++ ++BasisOpen.prototype = { ++ areaStart: function() { ++ this._line = 0; ++ }, ++ areaEnd: function() { ++ this._line = NaN; ++ }, ++ lineStart: function() { ++ this._x0 = this._x1 = ++ this._y0 = this._y1 = NaN; ++ this._point = 0; ++ }, ++ lineEnd: function() { ++ if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath(); ++ this._line = 1 - this._line; ++ }, ++ point: function(x, y) { ++ x = +x, y = +y; ++ switch (this._point) { ++ case 0: this._point = 1; break; ++ case 1: this._point = 2; break; ++ case 2: this._point = 3; var x0 = (this._x0 + 4 * this._x1 + x) / 6, y0 = (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break; ++ case 3: this._point = 4; // proceed ++ default: point$2(this, x, y); break; ++ } ++ this._x0 = this._x1, this._x1 = x; ++ this._y0 = this._y1, this._y1 = y; ++ } ++}; ++ ++function basisOpen(context) { ++ return new BasisOpen(context); ++} ++ ++function Bundle(context, beta) { ++ this._basis = new Basis(context); ++ this._beta = beta; ++} ++ ++Bundle.prototype = { ++ lineStart: function() { ++ this._x = []; ++ this._y = []; ++ this._basis.lineStart(); ++ }, ++ lineEnd: function() { ++ var x = this._x, ++ y = this._y, ++ j = x.length - 1; ++ ++ if (j > 0) { ++ var x0 = x[0], ++ y0 = y[0], ++ dx = x[j] - x0, ++ dy = y[j] - y0, ++ i = -1, ++ t; ++ ++ while (++i <= j) { ++ t = i / j; ++ this._basis.point( ++ this._beta * x[i] + (1 - this._beta) * (x0 + t * dx), ++ this._beta * y[i] + (1 - this._beta) * (y0 + t * dy) ++ ); ++ } ++ } ++ ++ this._x = this._y = null; ++ this._basis.lineEnd(); ++ }, ++ point: function(x, y) { ++ this._x.push(+x); ++ this._y.push(+y); ++ } ++}; ++ ++var bundle = (function custom(beta) { ++ ++ function bundle(context) { ++ return beta === 1 ? new Basis(context) : new Bundle(context, beta); ++ } ++ ++ bundle.beta = function(beta) { ++ return custom(+beta); ++ }; ++ ++ return bundle; ++})(0.85); ++ ++function point$3(that, x, y) { ++ that._context.bezierCurveTo( ++ that._x1 + that._k * (that._x2 - that._x0), ++ that._y1 + that._k * (that._y2 - that._y0), ++ that._x2 + that._k * (that._x1 - x), ++ that._y2 + that._k * (that._y1 - y), ++ that._x2, ++ that._y2 ++ ); ++} ++ ++function Cardinal(context, tension) { ++ this._context = context; ++ this._k = (1 - tension) / 6; ++} ++ ++Cardinal.prototype = { ++ areaStart: function() { ++ this._line = 0; ++ }, ++ areaEnd: function() { ++ this._line = NaN; ++ }, ++ lineStart: function() { ++ this._x0 = this._x1 = this._x2 = ++ this._y0 = this._y1 = this._y2 = NaN; ++ this._point = 0; ++ }, ++ lineEnd: function() { ++ switch (this._point) { ++ case 2: this._context.lineTo(this._x2, this._y2); break; ++ case 3: point$3(this, this._x1, this._y1); break; ++ } ++ if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); ++ this._line = 1 - this._line; ++ }, ++ point: function(x, y) { ++ x = +x, y = +y; ++ switch (this._point) { ++ case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; ++ case 1: this._point = 2; this._x1 = x, this._y1 = y; break; ++ case 2: this._point = 3; // proceed ++ default: point$3(this, x, y); break; ++ } ++ this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; ++ this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; ++ } ++}; ++ ++var cardinal = (function custom(tension) { ++ ++ function cardinal(context) { ++ return new Cardinal(context, tension); ++ } ++ ++ cardinal.tension = function(tension) { ++ return custom(+tension); ++ }; ++ ++ return cardinal; ++})(0); ++ ++function CardinalClosed(context, tension) { ++ this._context = context; ++ this._k = (1 - tension) / 6; ++} ++ ++CardinalClosed.prototype = { ++ areaStart: noop$3, ++ areaEnd: noop$3, ++ lineStart: function() { ++ this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 = ++ this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN; ++ this._point = 0; ++ }, ++ lineEnd: function() { ++ switch (this._point) { ++ case 1: { ++ this._context.moveTo(this._x3, this._y3); ++ this._context.closePath(); ++ break; ++ } ++ case 2: { ++ this._context.lineTo(this._x3, this._y3); ++ this._context.closePath(); ++ break; ++ } ++ case 3: { ++ this.point(this._x3, this._y3); ++ this.point(this._x4, this._y4); ++ this.point(this._x5, this._y5); ++ break; ++ } ++ } ++ }, ++ point: function(x, y) { ++ x = +x, y = +y; ++ switch (this._point) { ++ case 0: this._point = 1; this._x3 = x, this._y3 = y; break; ++ case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break; ++ case 2: this._point = 3; this._x5 = x, this._y5 = y; break; ++ default: point$3(this, x, y); break; ++ } ++ this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; ++ this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; ++ } ++}; ++ ++var cardinalClosed = (function custom(tension) { ++ ++ function cardinal$$1(context) { ++ return new CardinalClosed(context, tension); ++ } ++ ++ cardinal$$1.tension = function(tension) { ++ return custom(+tension); ++ }; ++ ++ return cardinal$$1; ++})(0); ++ ++function CardinalOpen(context, tension) { ++ this._context = context; ++ this._k = (1 - tension) / 6; ++} ++ ++CardinalOpen.prototype = { ++ areaStart: function() { ++ this._line = 0; ++ }, ++ areaEnd: function() { ++ this._line = NaN; ++ }, ++ lineStart: function() { ++ this._x0 = this._x1 = this._x2 = ++ this._y0 = this._y1 = this._y2 = NaN; ++ this._point = 0; ++ }, ++ lineEnd: function() { ++ if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath(); ++ this._line = 1 - this._line; ++ }, ++ point: function(x, y) { ++ x = +x, y = +y; ++ switch (this._point) { ++ case 0: this._point = 1; break; ++ case 1: this._point = 2; break; ++ case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break; ++ case 3: this._point = 4; // proceed ++ default: point$3(this, x, y); break; ++ } ++ this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; ++ this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; ++ } ++}; ++ ++var cardinalOpen = (function custom(tension) { ++ ++ function cardinal$$1(context) { ++ return new CardinalOpen(context, tension); ++ } ++ ++ cardinal$$1.tension = function(tension) { ++ return custom(+tension); ++ }; ++ ++ return cardinal$$1; ++})(0); ++ ++function point$4(that, x, y) { ++ var x1 = that._x1, ++ y1 = that._y1, ++ x2 = that._x2, ++ y2 = that._y2; ++ ++ if (that._l01_a > epsilon$3) { ++ var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a, ++ n = 3 * that._l01_a * (that._l01_a + that._l12_a); ++ x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n; ++ y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n; ++ } ++ ++ if (that._l23_a > epsilon$3) { ++ var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a, ++ m = 3 * that._l23_a * (that._l23_a + that._l12_a); ++ x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m; ++ y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m; ++ } ++ ++ that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2); ++} ++ ++function CatmullRom(context, alpha) { ++ this._context = context; ++ this._alpha = alpha; ++} ++ ++CatmullRom.prototype = { ++ areaStart: function() { ++ this._line = 0; ++ }, ++ areaEnd: function() { ++ this._line = NaN; ++ }, ++ lineStart: function() { ++ this._x0 = this._x1 = this._x2 = ++ this._y0 = this._y1 = this._y2 = NaN; ++ this._l01_a = this._l12_a = this._l23_a = ++ this._l01_2a = this._l12_2a = this._l23_2a = ++ this._point = 0; ++ }, ++ lineEnd: function() { ++ switch (this._point) { ++ case 2: this._context.lineTo(this._x2, this._y2); break; ++ case 3: this.point(this._x2, this._y2); break; ++ } ++ if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); ++ this._line = 1 - this._line; ++ }, ++ point: function(x, y) { ++ x = +x, y = +y; ++ ++ if (this._point) { ++ var x23 = this._x2 - x, ++ y23 = this._y2 - y; ++ this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha)); ++ } ++ ++ switch (this._point) { ++ case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; ++ case 1: this._point = 2; break; ++ case 2: this._point = 3; // proceed ++ default: point$4(this, x, y); break; ++ } ++ ++ this._l01_a = this._l12_a, this._l12_a = this._l23_a; ++ this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a; ++ this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; ++ this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; ++ } ++}; ++ ++var catmullRom = (function custom(alpha) { ++ ++ function catmullRom(context) { ++ return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0); ++ } ++ ++ catmullRom.alpha = function(alpha) { ++ return custom(+alpha); ++ }; ++ ++ return catmullRom; ++})(0.5); ++ ++function CatmullRomClosed(context, alpha) { ++ this._context = context; ++ this._alpha = alpha; ++} ++ ++CatmullRomClosed.prototype = { ++ areaStart: noop$3, ++ areaEnd: noop$3, ++ lineStart: function() { ++ this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 = ++ this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN; ++ this._l01_a = this._l12_a = this._l23_a = ++ this._l01_2a = this._l12_2a = this._l23_2a = ++ this._point = 0; ++ }, ++ lineEnd: function() { ++ switch (this._point) { ++ case 1: { ++ this._context.moveTo(this._x3, this._y3); ++ this._context.closePath(); ++ break; ++ } ++ case 2: { ++ this._context.lineTo(this._x3, this._y3); ++ this._context.closePath(); ++ break; ++ } ++ case 3: { ++ this.point(this._x3, this._y3); ++ this.point(this._x4, this._y4); ++ this.point(this._x5, this._y5); ++ break; ++ } ++ } ++ }, ++ point: function(x, y) { ++ x = +x, y = +y; ++ ++ if (this._point) { ++ var x23 = this._x2 - x, ++ y23 = this._y2 - y; ++ this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha)); ++ } ++ ++ switch (this._point) { ++ case 0: this._point = 1; this._x3 = x, this._y3 = y; break; ++ case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break; ++ case 2: this._point = 3; this._x5 = x, this._y5 = y; break; ++ default: point$4(this, x, y); break; ++ } ++ ++ this._l01_a = this._l12_a, this._l12_a = this._l23_a; ++ this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a; ++ this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; ++ this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; ++ } ++}; ++ ++var catmullRomClosed = (function custom(alpha) { ++ ++ function catmullRom$$1(context) { ++ return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0); ++ } ++ ++ catmullRom$$1.alpha = function(alpha) { ++ return custom(+alpha); ++ }; ++ ++ return catmullRom$$1; ++})(0.5); ++ ++function CatmullRomOpen(context, alpha) { ++ this._context = context; ++ this._alpha = alpha; ++} ++ ++CatmullRomOpen.prototype = { ++ areaStart: function() { ++ this._line = 0; ++ }, ++ areaEnd: function() { ++ this._line = NaN; ++ }, ++ lineStart: function() { ++ this._x0 = this._x1 = this._x2 = ++ this._y0 = this._y1 = this._y2 = NaN; ++ this._l01_a = this._l12_a = this._l23_a = ++ this._l01_2a = this._l12_2a = this._l23_2a = ++ this._point = 0; ++ }, ++ lineEnd: function() { ++ if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath(); ++ this._line = 1 - this._line; ++ }, ++ point: function(x, y) { ++ x = +x, y = +y; ++ ++ if (this._point) { ++ var x23 = this._x2 - x, ++ y23 = this._y2 - y; ++ this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha)); ++ } ++ ++ switch (this._point) { ++ case 0: this._point = 1; break; ++ case 1: this._point = 2; break; ++ case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break; ++ case 3: this._point = 4; // proceed ++ default: point$4(this, x, y); break; ++ } ++ ++ this._l01_a = this._l12_a, this._l12_a = this._l23_a; ++ this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a; ++ this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; ++ this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; ++ } ++}; ++ ++var catmullRomOpen = (function custom(alpha) { ++ ++ function catmullRom$$1(context) { ++ return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0); ++ } ++ ++ catmullRom$$1.alpha = function(alpha) { ++ return custom(+alpha); ++ }; ++ ++ return catmullRom$$1; ++})(0.5); ++ ++function LinearClosed(context) { ++ this._context = context; ++} ++ ++LinearClosed.prototype = { ++ areaStart: noop$3, ++ areaEnd: noop$3, ++ lineStart: function() { ++ this._point = 0; ++ }, ++ lineEnd: function() { ++ if (this._point) this._context.closePath(); ++ }, ++ point: function(x, y) { ++ x = +x, y = +y; ++ if (this._point) this._context.lineTo(x, y); ++ else this._point = 1, this._context.moveTo(x, y); ++ } ++}; ++ ++function linearClosed(context) { ++ return new LinearClosed(context); ++} ++ ++function sign$1(x) { ++ return x < 0 ? -1 : 1; ++} ++ ++// Calculate the slopes of the tangents (Hermite-type interpolation) based on ++// the following paper: Steffen, M. 1990. A Simple Method for Monotonic ++// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO. ++// NOV(II), P. 443, 1990. ++function slope3(that, x2, y2) { ++ var h0 = that._x1 - that._x0, ++ h1 = x2 - that._x1, ++ s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0), ++ s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0), ++ p = (s0 * h1 + s1 * h0) / (h0 + h1); ++ return (sign$1(s0) + sign$1(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0; ++} ++ ++// Calculate a one-sided slope. ++function slope2(that, t) { ++ var h = that._x1 - that._x0; ++ return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t; ++} ++ ++// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations ++// "you can express cubic Hermite interpolation in terms of cubic Bézier curves ++// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1". ++function point$5(that, t0, t1) { ++ var x0 = that._x0, ++ y0 = that._y0, ++ x1 = that._x1, ++ y1 = that._y1, ++ dx = (x1 - x0) / 3; ++ that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1); ++} ++ ++function MonotoneX(context) { ++ this._context = context; ++} ++ ++MonotoneX.prototype = { ++ areaStart: function() { ++ this._line = 0; ++ }, ++ areaEnd: function() { ++ this._line = NaN; ++ }, ++ lineStart: function() { ++ this._x0 = this._x1 = ++ this._y0 = this._y1 = ++ this._t0 = NaN; ++ this._point = 0; ++ }, ++ lineEnd: function() { ++ switch (this._point) { ++ case 2: this._context.lineTo(this._x1, this._y1); break; ++ case 3: point$5(this, this._t0, slope2(this, this._t0)); break; ++ } ++ if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); ++ this._line = 1 - this._line; ++ }, ++ point: function(x, y) { ++ var t1 = NaN; ++ ++ x = +x, y = +y; ++ if (x === this._x1 && y === this._y1) return; // Ignore coincident points. ++ switch (this._point) { ++ case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; ++ case 1: this._point = 2; break; ++ case 2: this._point = 3; point$5(this, slope2(this, t1 = slope3(this, x, y)), t1); break; ++ default: point$5(this, this._t0, t1 = slope3(this, x, y)); break; ++ } ++ ++ this._x0 = this._x1, this._x1 = x; ++ this._y0 = this._y1, this._y1 = y; ++ this._t0 = t1; ++ } ++}; ++ ++function MonotoneY(context) { ++ this._context = new ReflectContext(context); ++} ++ ++(MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) { ++ MonotoneX.prototype.point.call(this, y, x); ++}; ++ ++function ReflectContext(context) { ++ this._context = context; ++} ++ ++ReflectContext.prototype = { ++ moveTo: function(x, y) { this._context.moveTo(y, x); }, ++ closePath: function() { this._context.closePath(); }, ++ lineTo: function(x, y) { this._context.lineTo(y, x); }, ++ bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); } ++}; ++ ++function monotoneX(context) { ++ return new MonotoneX(context); ++} ++ ++function monotoneY(context) { ++ return new MonotoneY(context); ++} ++ ++function Natural(context) { ++ this._context = context; ++} ++ ++Natural.prototype = { ++ areaStart: function() { ++ this._line = 0; ++ }, ++ areaEnd: function() { ++ this._line = NaN; ++ }, ++ lineStart: function() { ++ this._x = []; ++ this._y = []; ++ }, ++ lineEnd: function() { ++ var x = this._x, ++ y = this._y, ++ n = x.length; ++ ++ if (n) { ++ this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]); ++ if (n === 2) { ++ this._context.lineTo(x[1], y[1]); ++ } else { ++ var px = controlPoints(x), ++ py = controlPoints(y); ++ for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) { ++ this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]); ++ } ++ } ++ } ++ ++ if (this._line || (this._line !== 0 && n === 1)) this._context.closePath(); ++ this._line = 1 - this._line; ++ this._x = this._y = null; ++ }, ++ point: function(x, y) { ++ this._x.push(+x); ++ this._y.push(+y); ++ } ++}; ++ ++// See https://www.particleincell.com/2012/bezier-splines/ for derivation. ++function controlPoints(x) { ++ var i, ++ n = x.length - 1, ++ m, ++ a = new Array(n), ++ b = new Array(n), ++ r = new Array(n); ++ a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1]; ++ for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1]; ++ a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n]; ++ for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1]; ++ a[n - 1] = r[n - 1] / b[n - 1]; ++ for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i]; ++ b[n - 1] = (x[n] + a[n - 1]) / 2; ++ for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1]; ++ return [a, b]; ++} ++ ++function natural(context) { ++ return new Natural(context); ++} ++ ++function Step(context, t) { ++ this._context = context; ++ this._t = t; ++} ++ ++Step.prototype = { ++ areaStart: function() { ++ this._line = 0; ++ }, ++ areaEnd: function() { ++ this._line = NaN; ++ }, ++ lineStart: function() { ++ this._x = this._y = NaN; ++ this._point = 0; ++ }, ++ lineEnd: function() { ++ if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y); ++ if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); ++ if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line; ++ }, ++ point: function(x, y) { ++ x = +x, y = +y; ++ switch (this._point) { ++ case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; ++ case 1: this._point = 2; // proceed ++ default: { ++ if (this._t <= 0) { ++ this._context.lineTo(this._x, y); ++ this._context.lineTo(x, y); ++ } else { ++ var x1 = this._x * (1 - this._t) + x * this._t; ++ this._context.lineTo(x1, this._y); ++ this._context.lineTo(x1, y); ++ } ++ break; ++ } ++ } ++ this._x = x, this._y = y; ++ } ++}; ++ ++function step(context) { ++ return new Step(context, 0.5); ++} ++ ++function stepBefore(context) { ++ return new Step(context, 0); ++} ++ ++function stepAfter(context) { ++ return new Step(context, 1); ++} ++ ++function none$1(series, order) { ++ if (!((n = series.length) > 1)) return; ++ for (var i = 1, j, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) { ++ s0 = s1, s1 = series[order[i]]; ++ for (j = 0; j < m; ++j) { ++ s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1]; ++ } ++ } ++} ++ ++function none$2(series) { ++ var n = series.length, o = new Array(n); ++ while (--n >= 0) o[n] = n; ++ return o; ++} ++ ++function stackValue(d, key) { ++ return d[key]; ++} ++ ++function stack() { ++ var keys = constant$11([]), ++ order = none$2, ++ offset = none$1, ++ value = stackValue; ++ ++ function stack(data) { ++ var kz = keys.apply(this, arguments), ++ i, ++ m = data.length, ++ n = kz.length, ++ sz = new Array(n), ++ oz; ++ ++ for (i = 0; i < n; ++i) { ++ for (var ki = kz[i], si = sz[i] = new Array(m), j = 0, sij; j < m; ++j) { ++ si[j] = sij = [0, +value(data[j], ki, j, data)]; ++ sij.data = data[j]; ++ } ++ si.key = ki; ++ } ++ ++ for (i = 0, oz = order(sz); i < n; ++i) { ++ sz[oz[i]].index = i; ++ } ++ ++ offset(sz, oz); ++ return sz; ++ } ++ ++ stack.keys = function(_) { ++ return arguments.length ? (keys = typeof _ === "function" ? _ : constant$11(slice$6.call(_)), stack) : keys; ++ }; ++ ++ stack.value = function(_) { ++ return arguments.length ? (value = typeof _ === "function" ? _ : constant$11(+_), stack) : value; ++ }; ++ ++ stack.order = function(_) { ++ return arguments.length ? (order = _ == null ? none$2 : typeof _ === "function" ? _ : constant$11(slice$6.call(_)), stack) : order; ++ }; ++ ++ stack.offset = function(_) { ++ return arguments.length ? (offset = _ == null ? none$1 : _, stack) : offset; ++ }; ++ ++ return stack; ++} ++ ++function expand(series, order) { ++ if (!((n = series.length) > 0)) return; ++ for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) { ++ for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0; ++ if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y; ++ } ++ none$1(series, order); ++} ++ ++function diverging$1(series, order) { ++ if (!((n = series.length) > 1)) return; ++ for (var i, j = 0, d, dy, yp, yn, n, m = series[order[0]].length; j < m; ++j) { ++ for (yp = yn = 0, i = 0; i < n; ++i) { ++ if ((dy = (d = series[order[i]][j])[1] - d[0]) >= 0) { ++ d[0] = yp, d[1] = yp += dy; ++ } else if (dy < 0) { ++ d[1] = yn, d[0] = yn += dy; ++ } else { ++ d[0] = yp; ++ } ++ } ++ } ++} ++ ++function silhouette(series, order) { ++ if (!((n = series.length) > 0)) return; ++ for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) { ++ for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0; ++ s0[j][1] += s0[j][0] = -y / 2; ++ } ++ none$1(series, order); ++} ++ ++function wiggle(series, order) { ++ if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return; ++ for (var y = 0, j = 1, s0, m, n; j < m; ++j) { ++ for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) { ++ var si = series[order[i]], ++ sij0 = si[j][1] || 0, ++ sij1 = si[j - 1][1] || 0, ++ s3 = (sij0 - sij1) / 2; ++ for (var k = 0; k < i; ++k) { ++ var sk = series[order[k]], ++ skj0 = sk[j][1] || 0, ++ skj1 = sk[j - 1][1] || 0; ++ s3 += skj0 - skj1; ++ } ++ s1 += sij0, s2 += s3 * sij0; ++ } ++ s0[j - 1][1] += s0[j - 1][0] = y; ++ if (s1) y -= s2 / s1; ++ } ++ s0[j - 1][1] += s0[j - 1][0] = y; ++ none$1(series, order); ++} ++ ++function ascending$3(series) { ++ var sums = series.map(sum$2); ++ return none$2(series).sort(function(a, b) { return sums[a] - sums[b]; }); ++} ++ ++function sum$2(series) { ++ var s = 0, i = -1, n = series.length, v; ++ while (++i < n) if (v = +series[i][1]) s += v; ++ return s; ++} ++ ++function descending$2(series) { ++ return ascending$3(series).reverse(); ++} ++ ++function insideOut(series) { ++ var n = series.length, ++ i, ++ j, ++ sums = series.map(sum$2), ++ order = none$2(series).sort(function(a, b) { return sums[b] - sums[a]; }), ++ top = 0, ++ bottom = 0, ++ tops = [], ++ bottoms = []; ++ ++ for (i = 0; i < n; ++i) { ++ j = order[i]; ++ if (top < bottom) { ++ top += sums[j]; ++ tops.push(j); ++ } else { ++ bottom += sums[j]; ++ bottoms.push(j); ++ } ++ } ++ ++ return bottoms.reverse().concat(tops); ++} ++ ++function reverse(series) { ++ return none$2(series).reverse(); ++} ++ ++function constant$12(x) { ++ return function() { ++ return x; ++ }; ++} ++ ++function x$4(d) { ++ return d[0]; ++} ++ ++function y$4(d) { ++ return d[1]; ++} ++ ++function RedBlackTree() { ++ this._ = null; // root node ++} ++ ++function RedBlackNode(node) { ++ node.U = // parent node ++ node.C = // color - true for red, false for black ++ node.L = // left node ++ node.R = // right node ++ node.P = // previous node ++ node.N = null; // next node ++} ++ ++RedBlackTree.prototype = { ++ constructor: RedBlackTree, ++ ++ insert: function(after, node) { ++ var parent, grandpa, uncle; ++ ++ if (after) { ++ node.P = after; ++ node.N = after.N; ++ if (after.N) after.N.P = node; ++ after.N = node; ++ if (after.R) { ++ after = after.R; ++ while (after.L) after = after.L; ++ after.L = node; ++ } else { ++ after.R = node; ++ } ++ parent = after; ++ } else if (this._) { ++ after = RedBlackFirst(this._); ++ node.P = null; ++ node.N = after; ++ after.P = after.L = node; ++ parent = after; ++ } else { ++ node.P = node.N = null; ++ this._ = node; ++ parent = null; ++ } ++ node.L = node.R = null; ++ node.U = parent; ++ node.C = true; ++ ++ after = node; ++ while (parent && parent.C) { ++ grandpa = parent.U; ++ if (parent === grandpa.L) { ++ uncle = grandpa.R; ++ if (uncle && uncle.C) { ++ parent.C = uncle.C = false; ++ grandpa.C = true; ++ after = grandpa; ++ } else { ++ if (after === parent.R) { ++ RedBlackRotateLeft(this, parent); ++ after = parent; ++ parent = after.U; ++ } ++ parent.C = false; ++ grandpa.C = true; ++ RedBlackRotateRight(this, grandpa); ++ } ++ } else { ++ uncle = grandpa.L; ++ if (uncle && uncle.C) { ++ parent.C = uncle.C = false; ++ grandpa.C = true; ++ after = grandpa; ++ } else { ++ if (after === parent.L) { ++ RedBlackRotateRight(this, parent); ++ after = parent; ++ parent = after.U; ++ } ++ parent.C = false; ++ grandpa.C = true; ++ RedBlackRotateLeft(this, grandpa); ++ } ++ } ++ parent = after.U; ++ } ++ this._.C = false; ++ }, ++ ++ remove: function(node) { ++ if (node.N) node.N.P = node.P; ++ if (node.P) node.P.N = node.N; ++ node.N = node.P = null; ++ ++ var parent = node.U, ++ sibling, ++ left = node.L, ++ right = node.R, ++ next, ++ red; ++ ++ if (!left) next = right; ++ else if (!right) next = left; ++ else next = RedBlackFirst(right); ++ ++ if (parent) { ++ if (parent.L === node) parent.L = next; ++ else parent.R = next; ++ } else { ++ this._ = next; ++ } ++ ++ if (left && right) { ++ red = next.C; ++ next.C = node.C; ++ next.L = left; ++ left.U = next; ++ if (next !== right) { ++ parent = next.U; ++ next.U = node.U; ++ node = next.R; ++ parent.L = node; ++ next.R = right; ++ right.U = next; ++ } else { ++ next.U = parent; ++ parent = next; ++ node = next.R; ++ } ++ } else { ++ red = node.C; ++ node = next; ++ } ++ ++ if (node) node.U = parent; ++ if (red) return; ++ if (node && node.C) { node.C = false; return; } ++ ++ do { ++ if (node === this._) break; ++ if (node === parent.L) { ++ sibling = parent.R; ++ if (sibling.C) { ++ sibling.C = false; ++ parent.C = true; ++ RedBlackRotateLeft(this, parent); ++ sibling = parent.R; ++ } ++ if ((sibling.L && sibling.L.C) ++ || (sibling.R && sibling.R.C)) { ++ if (!sibling.R || !sibling.R.C) { ++ sibling.L.C = false; ++ sibling.C = true; ++ RedBlackRotateRight(this, sibling); ++ sibling = parent.R; ++ } ++ sibling.C = parent.C; ++ parent.C = sibling.R.C = false; ++ RedBlackRotateLeft(this, parent); ++ node = this._; ++ break; ++ } ++ } else { ++ sibling = parent.L; ++ if (sibling.C) { ++ sibling.C = false; ++ parent.C = true; ++ RedBlackRotateRight(this, parent); ++ sibling = parent.L; ++ } ++ if ((sibling.L && sibling.L.C) ++ || (sibling.R && sibling.R.C)) { ++ if (!sibling.L || !sibling.L.C) { ++ sibling.R.C = false; ++ sibling.C = true; ++ RedBlackRotateLeft(this, sibling); ++ sibling = parent.L; ++ } ++ sibling.C = parent.C; ++ parent.C = sibling.L.C = false; ++ RedBlackRotateRight(this, parent); ++ node = this._; ++ break; ++ } ++ } ++ sibling.C = true; ++ node = parent; ++ parent = parent.U; ++ } while (!node.C); ++ ++ if (node) node.C = false; ++ } ++}; ++ ++function RedBlackRotateLeft(tree, node) { ++ var p = node, ++ q = node.R, ++ parent = p.U; ++ ++ if (parent) { ++ if (parent.L === p) parent.L = q; ++ else parent.R = q; ++ } else { ++ tree._ = q; ++ } ++ ++ q.U = parent; ++ p.U = q; ++ p.R = q.L; ++ if (p.R) p.R.U = p; ++ q.L = p; ++} ++ ++function RedBlackRotateRight(tree, node) { ++ var p = node, ++ q = node.L, ++ parent = p.U; ++ ++ if (parent) { ++ if (parent.L === p) parent.L = q; ++ else parent.R = q; ++ } else { ++ tree._ = q; ++ } ++ ++ q.U = parent; ++ p.U = q; ++ p.L = q.R; ++ if (p.L) p.L.U = p; ++ q.R = p; ++} ++ ++function RedBlackFirst(node) { ++ while (node.L) node = node.L; ++ return node; ++} ++ ++function createEdge(left, right, v0, v1) { ++ var edge = [null, null], ++ index = edges.push(edge) - 1; ++ edge.left = left; ++ edge.right = right; ++ if (v0) setEdgeEnd(edge, left, right, v0); ++ if (v1) setEdgeEnd(edge, right, left, v1); ++ cells[left.index].halfedges.push(index); ++ cells[right.index].halfedges.push(index); ++ return edge; ++} ++ ++function createBorderEdge(left, v0, v1) { ++ var edge = [v0, v1]; ++ edge.left = left; ++ return edge; ++} ++ ++function setEdgeEnd(edge, left, right, vertex) { ++ if (!edge[0] && !edge[1]) { ++ edge[0] = vertex; ++ edge.left = left; ++ edge.right = right; ++ } else if (edge.left === right) { ++ edge[1] = vertex; ++ } else { ++ edge[0] = vertex; ++ } ++} ++ ++// Liang–Barsky line clipping. ++function clipEdge(edge, x0, y0, x1, y1) { ++ var a = edge[0], ++ b = edge[1], ++ ax = a[0], ++ ay = a[1], ++ bx = b[0], ++ by = b[1], ++ t0 = 0, ++ t1 = 1, ++ dx = bx - ax, ++ dy = by - ay, ++ r; ++ ++ r = x0 - ax; ++ if (!dx && r > 0) return; ++ r /= dx; ++ if (dx < 0) { ++ if (r < t0) return; ++ if (r < t1) t1 = r; ++ } else if (dx > 0) { ++ if (r > t1) return; ++ if (r > t0) t0 = r; ++ } ++ ++ r = x1 - ax; ++ if (!dx && r < 0) return; ++ r /= dx; ++ if (dx < 0) { ++ if (r > t1) return; ++ if (r > t0) t0 = r; ++ } else if (dx > 0) { ++ if (r < t0) return; ++ if (r < t1) t1 = r; ++ } ++ ++ r = y0 - ay; ++ if (!dy && r > 0) return; ++ r /= dy; ++ if (dy < 0) { ++ if (r < t0) return; ++ if (r < t1) t1 = r; ++ } else if (dy > 0) { ++ if (r > t1) return; ++ if (r > t0) t0 = r; ++ } ++ ++ r = y1 - ay; ++ if (!dy && r < 0) return; ++ r /= dy; ++ if (dy < 0) { ++ if (r > t1) return; ++ if (r > t0) t0 = r; ++ } else if (dy > 0) { ++ if (r < t0) return; ++ if (r < t1) t1 = r; ++ } ++ ++ if (!(t0 > 0) && !(t1 < 1)) return true; // TODO Better check? ++ ++ if (t0 > 0) edge[0] = [ax + t0 * dx, ay + t0 * dy]; ++ if (t1 < 1) edge[1] = [ax + t1 * dx, ay + t1 * dy]; ++ return true; ++} ++ ++function connectEdge(edge, x0, y0, x1, y1) { ++ var v1 = edge[1]; ++ if (v1) return true; ++ ++ var v0 = edge[0], ++ left = edge.left, ++ right = edge.right, ++ lx = left[0], ++ ly = left[1], ++ rx = right[0], ++ ry = right[1], ++ fx = (lx + rx) / 2, ++ fy = (ly + ry) / 2, ++ fm, ++ fb; ++ ++ if (ry === ly) { ++ if (fx < x0 || fx >= x1) return; ++ if (lx > rx) { ++ if (!v0) v0 = [fx, y0]; ++ else if (v0[1] >= y1) return; ++ v1 = [fx, y1]; ++ } else { ++ if (!v0) v0 = [fx, y1]; ++ else if (v0[1] < y0) return; ++ v1 = [fx, y0]; ++ } ++ } else { ++ fm = (lx - rx) / (ry - ly); ++ fb = fy - fm * fx; ++ if (fm < -1 || fm > 1) { ++ if (lx > rx) { ++ if (!v0) v0 = [(y0 - fb) / fm, y0]; ++ else if (v0[1] >= y1) return; ++ v1 = [(y1 - fb) / fm, y1]; ++ } else { ++ if (!v0) v0 = [(y1 - fb) / fm, y1]; ++ else if (v0[1] < y0) return; ++ v1 = [(y0 - fb) / fm, y0]; ++ } ++ } else { ++ if (ly < ry) { ++ if (!v0) v0 = [x0, fm * x0 + fb]; ++ else if (v0[0] >= x1) return; ++ v1 = [x1, fm * x1 + fb]; ++ } else { ++ if (!v0) v0 = [x1, fm * x1 + fb]; ++ else if (v0[0] < x0) return; ++ v1 = [x0, fm * x0 + fb]; ++ } ++ } ++ } ++ ++ edge[0] = v0; ++ edge[1] = v1; ++ return true; ++} ++ ++function clipEdges(x0, y0, x1, y1) { ++ var i = edges.length, ++ edge; ++ ++ while (i--) { ++ if (!connectEdge(edge = edges[i], x0, y0, x1, y1) ++ || !clipEdge(edge, x0, y0, x1, y1) ++ || !(Math.abs(edge[0][0] - edge[1][0]) > epsilon$4 ++ || Math.abs(edge[0][1] - edge[1][1]) > epsilon$4)) { ++ delete edges[i]; ++ } ++ } ++} ++ ++function createCell(site) { ++ return cells[site.index] = { ++ site: site, ++ halfedges: [] ++ }; ++} ++ ++function cellHalfedgeAngle(cell, edge) { ++ var site = cell.site, ++ va = edge.left, ++ vb = edge.right; ++ if (site === vb) vb = va, va = site; ++ if (vb) return Math.atan2(vb[1] - va[1], vb[0] - va[0]); ++ if (site === va) va = edge[1], vb = edge[0]; ++ else va = edge[0], vb = edge[1]; ++ return Math.atan2(va[0] - vb[0], vb[1] - va[1]); ++} ++ ++function cellHalfedgeStart(cell, edge) { ++ return edge[+(edge.left !== cell.site)]; ++} ++ ++function cellHalfedgeEnd(cell, edge) { ++ return edge[+(edge.left === cell.site)]; ++} ++ ++function sortCellHalfedges() { ++ for (var i = 0, n = cells.length, cell, halfedges, j, m; i < n; ++i) { ++ if ((cell = cells[i]) && (m = (halfedges = cell.halfedges).length)) { ++ var index = new Array(m), ++ array = new Array(m); ++ for (j = 0; j < m; ++j) index[j] = j, array[j] = cellHalfedgeAngle(cell, edges[halfedges[j]]); ++ index.sort(function(i, j) { return array[j] - array[i]; }); ++ for (j = 0; j < m; ++j) array[j] = halfedges[index[j]]; ++ for (j = 0; j < m; ++j) halfedges[j] = array[j]; ++ } ++ } ++} ++ ++function clipCells(x0, y0, x1, y1) { ++ var nCells = cells.length, ++ iCell, ++ cell, ++ site, ++ iHalfedge, ++ halfedges, ++ nHalfedges, ++ start, ++ startX, ++ startY, ++ end, ++ endX, ++ endY, ++ cover = true; ++ ++ for (iCell = 0; iCell < nCells; ++iCell) { ++ if (cell = cells[iCell]) { ++ site = cell.site; ++ halfedges = cell.halfedges; ++ iHalfedge = halfedges.length; ++ ++ // Remove any dangling clipped edges. ++ while (iHalfedge--) { ++ if (!edges[halfedges[iHalfedge]]) { ++ halfedges.splice(iHalfedge, 1); ++ } ++ } ++ ++ // Insert any border edges as necessary. ++ iHalfedge = 0, nHalfedges = halfedges.length; ++ while (iHalfedge < nHalfedges) { ++ end = cellHalfedgeEnd(cell, edges[halfedges[iHalfedge]]), endX = end[0], endY = end[1]; ++ start = cellHalfedgeStart(cell, edges[halfedges[++iHalfedge % nHalfedges]]), startX = start[0], startY = start[1]; ++ if (Math.abs(endX - startX) > epsilon$4 || Math.abs(endY - startY) > epsilon$4) { ++ halfedges.splice(iHalfedge, 0, edges.push(createBorderEdge(site, end, ++ Math.abs(endX - x0) < epsilon$4 && y1 - endY > epsilon$4 ? [x0, Math.abs(startX - x0) < epsilon$4 ? startY : y1] ++ : Math.abs(endY - y1) < epsilon$4 && x1 - endX > epsilon$4 ? [Math.abs(startY - y1) < epsilon$4 ? startX : x1, y1] ++ : Math.abs(endX - x1) < epsilon$4 && endY - y0 > epsilon$4 ? [x1, Math.abs(startX - x1) < epsilon$4 ? startY : y0] ++ : Math.abs(endY - y0) < epsilon$4 && endX - x0 > epsilon$4 ? [Math.abs(startY - y0) < epsilon$4 ? startX : x0, y0] ++ : null)) - 1); ++ ++nHalfedges; ++ } ++ } ++ ++ if (nHalfedges) cover = false; ++ } ++ } ++ ++ // If there weren’t any edges, have the closest site cover the extent. ++ // It doesn’t matter which corner of the extent we measure! ++ if (cover) { ++ var dx, dy, d2, dc = Infinity; ++ ++ for (iCell = 0, cover = null; iCell < nCells; ++iCell) { ++ if (cell = cells[iCell]) { ++ site = cell.site; ++ dx = site[0] - x0; ++ dy = site[1] - y0; ++ d2 = dx * dx + dy * dy; ++ if (d2 < dc) dc = d2, cover = cell; ++ } ++ } ++ ++ if (cover) { ++ var v00 = [x0, y0], v01 = [x0, y1], v11 = [x1, y1], v10 = [x1, y0]; ++ cover.halfedges.push( ++ edges.push(createBorderEdge(site = cover.site, v00, v01)) - 1, ++ edges.push(createBorderEdge(site, v01, v11)) - 1, ++ edges.push(createBorderEdge(site, v11, v10)) - 1, ++ edges.push(createBorderEdge(site, v10, v00)) - 1 ++ ); ++ } ++ } ++ ++ // Lastly delete any cells with no edges; these were entirely clipped. ++ for (iCell = 0; iCell < nCells; ++iCell) { ++ if (cell = cells[iCell]) { ++ if (!cell.halfedges.length) { ++ delete cells[iCell]; ++ } ++ } ++ } ++} ++ ++var circlePool = []; ++ ++var firstCircle; ++ ++function Circle() { ++ RedBlackNode(this); ++ this.x = ++ this.y = ++ this.arc = ++ this.site = ++ this.cy = null; ++} ++ ++function attachCircle(arc) { ++ var lArc = arc.P, ++ rArc = arc.N; ++ ++ if (!lArc || !rArc) return; ++ ++ var lSite = lArc.site, ++ cSite = arc.site, ++ rSite = rArc.site; ++ ++ if (lSite === rSite) return; ++ ++ var bx = cSite[0], ++ by = cSite[1], ++ ax = lSite[0] - bx, ++ ay = lSite[1] - by, ++ cx = rSite[0] - bx, ++ cy = rSite[1] - by; ++ ++ var d = 2 * (ax * cy - ay * cx); ++ if (d >= -epsilon2$2) return; ++ ++ var ha = ax * ax + ay * ay, ++ hc = cx * cx + cy * cy, ++ x = (cy * ha - ay * hc) / d, ++ y = (ax * hc - cx * ha) / d; ++ ++ var circle = circlePool.pop() || new Circle; ++ circle.arc = arc; ++ circle.site = cSite; ++ circle.x = x + bx; ++ circle.y = (circle.cy = y + by) + Math.sqrt(x * x + y * y); // y bottom ++ ++ arc.circle = circle; ++ ++ var before = null, ++ node = circles._; ++ ++ while (node) { ++ if (circle.y < node.y || (circle.y === node.y && circle.x <= node.x)) { ++ if (node.L) node = node.L; ++ else { before = node.P; break; } ++ } else { ++ if (node.R) node = node.R; ++ else { before = node; break; } ++ } ++ } ++ ++ circles.insert(before, circle); ++ if (!before) firstCircle = circle; ++} ++ ++function detachCircle(arc) { ++ var circle = arc.circle; ++ if (circle) { ++ if (!circle.P) firstCircle = circle.N; ++ circles.remove(circle); ++ circlePool.push(circle); ++ RedBlackNode(circle); ++ arc.circle = null; ++ } ++} ++ ++var beachPool = []; ++ ++function Beach() { ++ RedBlackNode(this); ++ this.edge = ++ this.site = ++ this.circle = null; ++} ++ ++function createBeach(site) { ++ var beach = beachPool.pop() || new Beach; ++ beach.site = site; ++ return beach; ++} ++ ++function detachBeach(beach) { ++ detachCircle(beach); ++ beaches.remove(beach); ++ beachPool.push(beach); ++ RedBlackNode(beach); ++} ++ ++function removeBeach(beach) { ++ var circle = beach.circle, ++ x = circle.x, ++ y = circle.cy, ++ vertex = [x, y], ++ previous = beach.P, ++ next = beach.N, ++ disappearing = [beach]; ++ ++ detachBeach(beach); ++ ++ var lArc = previous; ++ while (lArc.circle ++ && Math.abs(x - lArc.circle.x) < epsilon$4 ++ && Math.abs(y - lArc.circle.cy) < epsilon$4) { ++ previous = lArc.P; ++ disappearing.unshift(lArc); ++ detachBeach(lArc); ++ lArc = previous; ++ } ++ ++ disappearing.unshift(lArc); ++ detachCircle(lArc); ++ ++ var rArc = next; ++ while (rArc.circle ++ && Math.abs(x - rArc.circle.x) < epsilon$4 ++ && Math.abs(y - rArc.circle.cy) < epsilon$4) { ++ next = rArc.N; ++ disappearing.push(rArc); ++ detachBeach(rArc); ++ rArc = next; ++ } ++ ++ disappearing.push(rArc); ++ detachCircle(rArc); ++ ++ var nArcs = disappearing.length, ++ iArc; ++ for (iArc = 1; iArc < nArcs; ++iArc) { ++ rArc = disappearing[iArc]; ++ lArc = disappearing[iArc - 1]; ++ setEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex); ++ } ++ ++ lArc = disappearing[0]; ++ rArc = disappearing[nArcs - 1]; ++ rArc.edge = createEdge(lArc.site, rArc.site, null, vertex); ++ ++ attachCircle(lArc); ++ attachCircle(rArc); ++} ++ ++function addBeach(site) { ++ var x = site[0], ++ directrix = site[1], ++ lArc, ++ rArc, ++ dxl, ++ dxr, ++ node = beaches._; ++ ++ while (node) { ++ dxl = leftBreakPoint(node, directrix) - x; ++ if (dxl > epsilon$4) node = node.L; else { ++ dxr = x - rightBreakPoint(node, directrix); ++ if (dxr > epsilon$4) { ++ if (!node.R) { ++ lArc = node; ++ break; ++ } ++ node = node.R; ++ } else { ++ if (dxl > -epsilon$4) { ++ lArc = node.P; ++ rArc = node; ++ } else if (dxr > -epsilon$4) { ++ lArc = node; ++ rArc = node.N; ++ } else { ++ lArc = rArc = node; ++ } ++ break; ++ } ++ } ++ } ++ ++ createCell(site); ++ var newArc = createBeach(site); ++ beaches.insert(lArc, newArc); ++ ++ if (!lArc && !rArc) return; ++ ++ if (lArc === rArc) { ++ detachCircle(lArc); ++ rArc = createBeach(lArc.site); ++ beaches.insert(newArc, rArc); ++ newArc.edge = rArc.edge = createEdge(lArc.site, newArc.site); ++ attachCircle(lArc); ++ attachCircle(rArc); ++ return; ++ } ++ ++ if (!rArc) { // && lArc ++ newArc.edge = createEdge(lArc.site, newArc.site); ++ return; ++ } ++ ++ // else lArc !== rArc ++ detachCircle(lArc); ++ detachCircle(rArc); ++ ++ var lSite = lArc.site, ++ ax = lSite[0], ++ ay = lSite[1], ++ bx = site[0] - ax, ++ by = site[1] - ay, ++ rSite = rArc.site, ++ cx = rSite[0] - ax, ++ cy = rSite[1] - ay, ++ d = 2 * (bx * cy - by * cx), ++ hb = bx * bx + by * by, ++ hc = cx * cx + cy * cy, ++ vertex = [(cy * hb - by * hc) / d + ax, (bx * hc - cx * hb) / d + ay]; ++ ++ setEdgeEnd(rArc.edge, lSite, rSite, vertex); ++ newArc.edge = createEdge(lSite, site, null, vertex); ++ rArc.edge = createEdge(site, rSite, null, vertex); ++ attachCircle(lArc); ++ attachCircle(rArc); ++} ++ ++function leftBreakPoint(arc, directrix) { ++ var site = arc.site, ++ rfocx = site[0], ++ rfocy = site[1], ++ pby2 = rfocy - directrix; ++ ++ if (!pby2) return rfocx; ++ ++ var lArc = arc.P; ++ if (!lArc) return -Infinity; ++ ++ site = lArc.site; ++ var lfocx = site[0], ++ lfocy = site[1], ++ plby2 = lfocy - directrix; ++ ++ if (!plby2) return lfocx; ++ ++ var hl = lfocx - rfocx, ++ aby2 = 1 / pby2 - 1 / plby2, ++ b = hl / plby2; ++ ++ if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx; ++ ++ return (rfocx + lfocx) / 2; ++} ++ ++function rightBreakPoint(arc, directrix) { ++ var rArc = arc.N; ++ if (rArc) return leftBreakPoint(rArc, directrix); ++ var site = arc.site; ++ return site[1] === directrix ? site[0] : Infinity; ++} ++ ++var epsilon$4 = 1e-6; ++var epsilon2$2 = 1e-12; ++var beaches; ++var cells; ++var circles; ++var edges; ++ ++function triangleArea(a, b, c) { ++ return (a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]); ++} ++ ++function lexicographic(a, b) { ++ return b[1] - a[1] ++ || b[0] - a[0]; ++} ++ ++function Diagram(sites, extent) { ++ var site = sites.sort(lexicographic).pop(), ++ x, ++ y, ++ circle; ++ ++ edges = []; ++ cells = new Array(sites.length); ++ beaches = new RedBlackTree; ++ circles = new RedBlackTree; ++ ++ while (true) { ++ circle = firstCircle; ++ if (site && (!circle || site[1] < circle.y || (site[1] === circle.y && site[0] < circle.x))) { ++ if (site[0] !== x || site[1] !== y) { ++ addBeach(site); ++ x = site[0], y = site[1]; ++ } ++ site = sites.pop(); ++ } else if (circle) { ++ removeBeach(circle.arc); ++ } else { ++ break; ++ } ++ } ++ ++ sortCellHalfedges(); ++ ++ if (extent) { ++ var x0 = +extent[0][0], ++ y0 = +extent[0][1], ++ x1 = +extent[1][0], ++ y1 = +extent[1][1]; ++ clipEdges(x0, y0, x1, y1); ++ clipCells(x0, y0, x1, y1); ++ } ++ ++ this.edges = edges; ++ this.cells = cells; ++ ++ beaches = ++ circles = ++ edges = ++ cells = null; ++} ++ ++Diagram.prototype = { ++ constructor: Diagram, ++ ++ polygons: function() { ++ var edges = this.edges; ++ ++ return this.cells.map(function(cell) { ++ var polygon = cell.halfedges.map(function(i) { return cellHalfedgeStart(cell, edges[i]); }); ++ polygon.data = cell.site.data; ++ return polygon; ++ }); ++ }, ++ ++ triangles: function() { ++ var triangles = [], ++ edges = this.edges; ++ ++ this.cells.forEach(function(cell, i) { ++ if (!(m = (halfedges = cell.halfedges).length)) return; ++ var site = cell.site, ++ halfedges, ++ j = -1, ++ m, ++ s0, ++ e1 = edges[halfedges[m - 1]], ++ s1 = e1.left === site ? e1.right : e1.left; ++ ++ while (++j < m) { ++ s0 = s1; ++ e1 = edges[halfedges[j]]; ++ s1 = e1.left === site ? e1.right : e1.left; ++ if (s0 && s1 && i < s0.index && i < s1.index && triangleArea(site, s0, s1) < 0) { ++ triangles.push([site.data, s0.data, s1.data]); ++ } ++ } ++ }); ++ ++ return triangles; ++ }, ++ ++ links: function() { ++ return this.edges.filter(function(edge) { ++ return edge.right; ++ }).map(function(edge) { ++ return { ++ source: edge.left.data, ++ target: edge.right.data ++ }; ++ }); ++ }, ++ ++ find: function(x, y, radius) { ++ var that = this, i0, i1 = that._found || 0, n = that.cells.length, cell; ++ ++ // Use the previously-found cell, or start with an arbitrary one. ++ while (!(cell = that.cells[i1])) if (++i1 >= n) return null; ++ var dx = x - cell.site[0], dy = y - cell.site[1], d2 = dx * dx + dy * dy; ++ ++ // Traverse the half-edges to find a closer cell, if any. ++ do { ++ cell = that.cells[i0 = i1], i1 = null; ++ cell.halfedges.forEach(function(e) { ++ var edge = that.edges[e], v = edge.left; ++ if ((v === cell.site || !v) && !(v = edge.right)) return; ++ var vx = x - v[0], vy = y - v[1], v2 = vx * vx + vy * vy; ++ if (v2 < d2) d2 = v2, i1 = v.index; ++ }); ++ } while (i1 !== null); ++ ++ that._found = i0; ++ ++ return radius == null || d2 <= radius * radius ? cell.site : null; ++ } ++}; ++ ++function voronoi() { ++ var x$$1 = x$4, ++ y$$1 = y$4, ++ extent = null; ++ ++ function voronoi(data) { ++ return new Diagram(data.map(function(d, i) { ++ var s = [Math.round(x$$1(d, i, data) / epsilon$4) * epsilon$4, Math.round(y$$1(d, i, data) / epsilon$4) * epsilon$4]; ++ s.index = i; ++ s.data = d; ++ return s; ++ }), extent); ++ } ++ ++ voronoi.polygons = function(data) { ++ return voronoi(data).polygons(); ++ }; ++ ++ voronoi.links = function(data) { ++ return voronoi(data).links(); ++ }; ++ ++ voronoi.triangles = function(data) { ++ return voronoi(data).triangles(); ++ }; ++ ++ voronoi.x = function(_) { ++ return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$12(+_), voronoi) : x$$1; ++ }; ++ ++ voronoi.y = function(_) { ++ return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$12(+_), voronoi) : y$$1; ++ }; ++ ++ voronoi.extent = function(_) { ++ return arguments.length ? (extent = _ == null ? null : [[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]], voronoi) : extent && [[extent[0][0], extent[0][1]], [extent[1][0], extent[1][1]]]; ++ }; ++ ++ voronoi.size = function(_) { ++ return arguments.length ? (extent = _ == null ? null : [[0, 0], [+_[0], +_[1]]], voronoi) : extent && [extent[1][0] - extent[0][0], extent[1][1] - extent[0][1]]; ++ }; ++ ++ return voronoi; ++} ++ ++function constant$13(x) { ++ return function() { ++ return x; ++ }; ++} ++ ++function ZoomEvent(target, type, transform) { ++ this.target = target; ++ this.type = type; ++ this.transform = transform; ++} ++ ++function Transform(k, x, y) { ++ this.k = k; ++ this.x = x; ++ this.y = y; ++} ++ ++Transform.prototype = { ++ constructor: Transform, ++ scale: function(k) { ++ return k === 1 ? this : new Transform(this.k * k, this.x, this.y); ++ }, ++ translate: function(x, y) { ++ return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y); ++ }, ++ apply: function(point) { ++ return [point[0] * this.k + this.x, point[1] * this.k + this.y]; ++ }, ++ applyX: function(x) { ++ return x * this.k + this.x; ++ }, ++ applyY: function(y) { ++ return y * this.k + this.y; ++ }, ++ invert: function(location) { ++ return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k]; ++ }, ++ invertX: function(x) { ++ return (x - this.x) / this.k; ++ }, ++ invertY: function(y) { ++ return (y - this.y) / this.k; ++ }, ++ rescaleX: function(x) { ++ return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x)); ++ }, ++ rescaleY: function(y) { ++ return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y)); ++ }, ++ toString: function() { ++ return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")"; ++ } ++}; ++ ++var identity$8 = new Transform(1, 0, 0); ++ ++transform$1.prototype = Transform.prototype; ++ ++function transform$1(node) { ++ return node.__zoom || identity$8; ++} ++ ++function nopropagation$2() { ++ exports.event.stopImmediatePropagation(); ++} ++ ++function noevent$2() { ++ exports.event.preventDefault(); ++ exports.event.stopImmediatePropagation(); ++} ++ ++// Ignore right-click, since that should open the context menu. ++function defaultFilter$2() { ++ return !exports.event.button; ++} ++ ++function defaultExtent$1() { ++ var e = this, w, h; ++ if (e instanceof SVGElement) { ++ e = e.ownerSVGElement || e; ++ w = e.width.baseVal.value; ++ h = e.height.baseVal.value; ++ } else { ++ w = e.clientWidth; ++ h = e.clientHeight; ++ } ++ return [[0, 0], [w, h]]; ++} ++ ++function defaultTransform() { ++ return this.__zoom || identity$8; ++} ++ ++function defaultWheelDelta() { ++ return -exports.event.deltaY * (exports.event.deltaMode ? 120 : 1) / 500; ++} ++ ++function defaultTouchable$1() { ++ return "ontouchstart" in this; ++} ++ ++function defaultConstrain(transform, extent, translateExtent) { ++ var dx0 = transform.invertX(extent[0][0]) - translateExtent[0][0], ++ dx1 = transform.invertX(extent[1][0]) - translateExtent[1][0], ++ dy0 = transform.invertY(extent[0][1]) - translateExtent[0][1], ++ dy1 = transform.invertY(extent[1][1]) - translateExtent[1][1]; ++ return transform.translate( ++ dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1), ++ dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1) ++ ); ++} ++ ++function zoom() { ++ var filter = defaultFilter$2, ++ extent = defaultExtent$1, ++ constrain = defaultConstrain, ++ wheelDelta = defaultWheelDelta, ++ touchable = defaultTouchable$1, ++ scaleExtent = [0, Infinity], ++ translateExtent = [[-Infinity, -Infinity], [Infinity, Infinity]], ++ duration = 250, ++ interpolate = interpolateZoom, ++ gestures = [], ++ listeners = dispatch("start", "zoom", "end"), ++ touchstarting, ++ touchending, ++ touchDelay = 500, ++ wheelDelay = 150, ++ clickDistance2 = 0; ++ ++ function zoom(selection$$1) { ++ selection$$1 ++ .property("__zoom", defaultTransform) ++ .on("wheel.zoom", wheeled) ++ .on("mousedown.zoom", mousedowned) ++ .on("dblclick.zoom", dblclicked) ++ .filter(touchable) ++ .on("touchstart.zoom", touchstarted) ++ .on("touchmove.zoom", touchmoved) ++ .on("touchend.zoom touchcancel.zoom", touchended) ++ .style("touch-action", "none") ++ .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)"); ++ } ++ ++ zoom.transform = function(collection, transform) { ++ var selection$$1 = collection.selection ? collection.selection() : collection; ++ selection$$1.property("__zoom", defaultTransform); ++ if (collection !== selection$$1) { ++ schedule(collection, transform); ++ } else { ++ selection$$1.interrupt().each(function() { ++ gesture(this, arguments) ++ .start() ++ .zoom(null, typeof transform === "function" ? transform.apply(this, arguments) : transform) ++ .end(); ++ }); ++ } ++ }; ++ ++ zoom.scaleBy = function(selection$$1, k) { ++ zoom.scaleTo(selection$$1, function() { ++ var k0 = this.__zoom.k, ++ k1 = typeof k === "function" ? k.apply(this, arguments) : k; ++ return k0 * k1; ++ }); ++ }; ++ ++ zoom.scaleTo = function(selection$$1, k) { ++ zoom.transform(selection$$1, function() { ++ var e = extent.apply(this, arguments), ++ t0 = this.__zoom, ++ p0 = centroid(e), ++ p1 = t0.invert(p0), ++ k1 = typeof k === "function" ? k.apply(this, arguments) : k; ++ return constrain(translate(scale(t0, k1), p0, p1), e, translateExtent); ++ }); ++ }; ++ ++ zoom.translateBy = function(selection$$1, x, y) { ++ zoom.transform(selection$$1, function() { ++ return constrain(this.__zoom.translate( ++ typeof x === "function" ? x.apply(this, arguments) : x, ++ typeof y === "function" ? y.apply(this, arguments) : y ++ ), extent.apply(this, arguments), translateExtent); ++ }); ++ }; ++ ++ zoom.translateTo = function(selection$$1, x, y) { ++ zoom.transform(selection$$1, function() { ++ var e = extent.apply(this, arguments), ++ t = this.__zoom, ++ p = centroid(e); ++ return constrain(identity$8.translate(p[0], p[1]).scale(t.k).translate( ++ typeof x === "function" ? -x.apply(this, arguments) : -x, ++ typeof y === "function" ? -y.apply(this, arguments) : -y ++ ), e, translateExtent); ++ }); ++ }; ++ ++ function scale(transform, k) { ++ k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], k)); ++ return k === transform.k ? transform : new Transform(k, transform.x, transform.y); ++ } ++ ++ function translate(transform, p0, p1) { ++ var x = p0[0] - p1[0] * transform.k, y = p0[1] - p1[1] * transform.k; ++ return x === transform.x && y === transform.y ? transform : new Transform(transform.k, x, y); ++ } ++ ++ function centroid(extent) { ++ return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2]; ++ } ++ ++ function schedule(transition$$1, transform, center) { ++ transition$$1 ++ .on("start.zoom", function() { gesture(this, arguments).start(); }) ++ .on("interrupt.zoom end.zoom", function() { gesture(this, arguments).end(); }) ++ .tween("zoom", function() { ++ var that = this, ++ args = arguments, ++ g = gesture(that, args), ++ e = extent.apply(that, args), ++ p = center || centroid(e), ++ w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]), ++ a = that.__zoom, ++ b = typeof transform === "function" ? transform.apply(that, args) : transform, ++ i = interpolate(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k)); ++ return function(t) { ++ if (t === 1) t = b; // Avoid rounding error on end. ++ else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); } ++ g.zoom(null, t); ++ }; ++ }); ++ } ++ ++ function gesture(that, args) { ++ for (var i = 0, n = gestures.length, g; i < n; ++i) { ++ if ((g = gestures[i]).that === that) { ++ return g; ++ } ++ } ++ return new Gesture(that, args); ++ } ++ ++ function Gesture(that, args) { ++ this.that = that; ++ this.args = args; ++ this.index = -1; ++ this.active = 0; ++ this.extent = extent.apply(that, args); ++ } ++ ++ Gesture.prototype = { ++ start: function() { ++ if (++this.active === 1) { ++ this.index = gestures.push(this) - 1; ++ this.emit("start"); ++ } ++ return this; ++ }, ++ zoom: function(key, transform) { ++ if (this.mouse && key !== "mouse") this.mouse[1] = transform.invert(this.mouse[0]); ++ if (this.touch0 && key !== "touch") this.touch0[1] = transform.invert(this.touch0[0]); ++ if (this.touch1 && key !== "touch") this.touch1[1] = transform.invert(this.touch1[0]); ++ this.that.__zoom = transform; ++ this.emit("zoom"); ++ return this; ++ }, ++ end: function() { ++ if (--this.active === 0) { ++ gestures.splice(this.index, 1); ++ this.index = -1; ++ this.emit("end"); ++ } ++ return this; ++ }, ++ emit: function(type) { ++ customEvent(new ZoomEvent(zoom, type, this.that.__zoom), listeners.apply, listeners, [type, this.that, this.args]); ++ } ++ }; ++ ++ function wheeled() { ++ if (!filter.apply(this, arguments)) return; ++ var g = gesture(this, arguments), ++ t = this.__zoom, ++ k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], t.k * Math.pow(2, wheelDelta.apply(this, arguments)))), ++ p = mouse(this); ++ ++ // If the mouse is in the same location as before, reuse it. ++ // If there were recent wheel events, reset the wheel idle timeout. ++ if (g.wheel) { ++ if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) { ++ g.mouse[1] = t.invert(g.mouse[0] = p); ++ } ++ clearTimeout(g.wheel); ++ } ++ ++ // If this wheel event won’t trigger a transform change, ignore it. ++ else if (t.k === k) return; ++ ++ // Otherwise, capture the mouse point and location at the start. ++ else { ++ g.mouse = [p, t.invert(p)]; ++ interrupt(this); ++ g.start(); ++ } ++ ++ noevent$2(); ++ g.wheel = setTimeout(wheelidled, wheelDelay); ++ g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent, translateExtent)); ++ ++ function wheelidled() { ++ g.wheel = null; ++ g.end(); ++ } ++ } ++ ++ function mousedowned() { ++ if (touchending || !filter.apply(this, arguments)) return; ++ var g = gesture(this, arguments), ++ v = select(exports.event.view).on("mousemove.zoom", mousemoved, true).on("mouseup.zoom", mouseupped, true), ++ p = mouse(this), ++ x0 = exports.event.clientX, ++ y0 = exports.event.clientY; ++ ++ dragDisable(exports.event.view); ++ nopropagation$2(); ++ g.mouse = [p, this.__zoom.invert(p)]; ++ interrupt(this); ++ g.start(); ++ ++ function mousemoved() { ++ noevent$2(); ++ if (!g.moved) { ++ var dx = exports.event.clientX - x0, dy = exports.event.clientY - y0; ++ g.moved = dx * dx + dy * dy > clickDistance2; ++ } ++ g.zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = mouse(g.that), g.mouse[1]), g.extent, translateExtent)); ++ } ++ ++ function mouseupped() { ++ v.on("mousemove.zoom mouseup.zoom", null); ++ yesdrag(exports.event.view, g.moved); ++ noevent$2(); ++ g.end(); ++ } ++ } ++ ++ function dblclicked() { ++ if (!filter.apply(this, arguments)) return; ++ var t0 = this.__zoom, ++ p0 = mouse(this), ++ p1 = t0.invert(p0), ++ k1 = t0.k * (exports.event.shiftKey ? 0.5 : 2), ++ t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, arguments), translateExtent); ++ ++ noevent$2(); ++ if (duration > 0) select(this).transition().duration(duration).call(schedule, t1, p0); ++ else select(this).call(zoom.transform, t1); ++ } ++ ++ function touchstarted() { ++ if (!filter.apply(this, arguments)) return; ++ var g = gesture(this, arguments), ++ touches$$1 = exports.event.changedTouches, ++ started, ++ n = touches$$1.length, i, t, p; ++ ++ nopropagation$2(); ++ for (i = 0; i < n; ++i) { ++ t = touches$$1[i], p = touch(this, touches$$1, t.identifier); ++ p = [p, this.__zoom.invert(p), t.identifier]; ++ if (!g.touch0) g.touch0 = p, started = true; ++ else if (!g.touch1) g.touch1 = p; ++ } ++ ++ // If this is a dbltap, reroute to the (optional) dblclick.zoom handler. ++ if (touchstarting) { ++ touchstarting = clearTimeout(touchstarting); ++ if (!g.touch1) { ++ g.end(); ++ p = select(this).on("dblclick.zoom"); ++ if (p) p.apply(this, arguments); ++ return; ++ } ++ } ++ ++ if (started) { ++ touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay); ++ interrupt(this); ++ g.start(); ++ } ++ } ++ ++ function touchmoved() { ++ var g = gesture(this, arguments), ++ touches$$1 = exports.event.changedTouches, ++ n = touches$$1.length, i, t, p, l; ++ ++ noevent$2(); ++ if (touchstarting) touchstarting = clearTimeout(touchstarting); ++ for (i = 0; i < n; ++i) { ++ t = touches$$1[i], p = touch(this, touches$$1, t.identifier); ++ if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p; ++ else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p; ++ } ++ t = g.that.__zoom; ++ if (g.touch1) { ++ var p0 = g.touch0[0], l0 = g.touch0[1], ++ p1 = g.touch1[0], l1 = g.touch1[1], ++ dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp, ++ dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl; ++ t = scale(t, Math.sqrt(dp / dl)); ++ p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2]; ++ l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2]; ++ } ++ else if (g.touch0) p = g.touch0[0], l = g.touch0[1]; ++ else return; ++ g.zoom("touch", constrain(translate(t, p, l), g.extent, translateExtent)); ++ } ++ ++ function touchended() { ++ var g = gesture(this, arguments), ++ touches$$1 = exports.event.changedTouches, ++ n = touches$$1.length, i, t; ++ ++ nopropagation$2(); ++ if (touchending) clearTimeout(touchending); ++ touchending = setTimeout(function() { touchending = null; }, touchDelay); ++ for (i = 0; i < n; ++i) { ++ t = touches$$1[i]; ++ if (g.touch0 && g.touch0[2] === t.identifier) delete g.touch0; ++ else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1; ++ } ++ if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1; ++ if (g.touch0) g.touch0[1] = this.__zoom.invert(g.touch0[0]); ++ else g.end(); ++ } ++ ++ zoom.wheelDelta = function(_) { ++ return arguments.length ? (wheelDelta = typeof _ === "function" ? _ : constant$13(+_), zoom) : wheelDelta; ++ }; ++ ++ zoom.filter = function(_) { ++ return arguments.length ? (filter = typeof _ === "function" ? _ : constant$13(!!_), zoom) : filter; ++ }; ++ ++ zoom.touchable = function(_) { ++ return arguments.length ? (touchable = typeof _ === "function" ? _ : constant$13(!!_), zoom) : touchable; ++ }; ++ ++ zoom.extent = function(_) { ++ return arguments.length ? (extent = typeof _ === "function" ? _ : constant$13([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent; ++ }; ++ ++ zoom.scaleExtent = function(_) { ++ return arguments.length ? (scaleExtent[0] = +_[0], scaleExtent[1] = +_[1], zoom) : [scaleExtent[0], scaleExtent[1]]; ++ }; ++ ++ zoom.translateExtent = function(_) { ++ return arguments.length ? (translateExtent[0][0] = +_[0][0], translateExtent[1][0] = +_[1][0], translateExtent[0][1] = +_[0][1], translateExtent[1][1] = +_[1][1], zoom) : [[translateExtent[0][0], translateExtent[0][1]], [translateExtent[1][0], translateExtent[1][1]]]; ++ }; ++ ++ zoom.constrain = function(_) { ++ return arguments.length ? (constrain = _, zoom) : constrain; ++ }; ++ ++ zoom.duration = function(_) { ++ return arguments.length ? (duration = +_, zoom) : duration; ++ }; ++ ++ zoom.interpolate = function(_) { ++ return arguments.length ? (interpolate = _, zoom) : interpolate; ++ }; ++ ++ zoom.on = function() { ++ var value = listeners.on.apply(listeners, arguments); ++ return value === listeners ? zoom : value; ++ }; ++ ++ zoom.clickDistance = function(_) { ++ return arguments.length ? (clickDistance2 = (_ = +_) * _, zoom) : Math.sqrt(clickDistance2); ++ }; ++ ++ return zoom; ++} ++ ++exports.version = version; ++exports.bisect = bisectRight; ++exports.bisectRight = bisectRight; ++exports.bisectLeft = bisectLeft; ++exports.ascending = ascending; ++exports.bisector = bisector; ++exports.cross = cross; ++exports.descending = descending; ++exports.deviation = deviation; ++exports.extent = extent; ++exports.histogram = histogram; ++exports.thresholdFreedmanDiaconis = freedmanDiaconis; ++exports.thresholdScott = scott; ++exports.thresholdSturges = thresholdSturges; ++exports.max = max; ++exports.mean = mean; ++exports.median = median; ++exports.merge = merge; ++exports.min = min; ++exports.pairs = pairs; ++exports.permute = permute; ++exports.quantile = threshold; ++exports.range = sequence; ++exports.scan = scan; ++exports.shuffle = shuffle; ++exports.sum = sum; ++exports.ticks = ticks; ++exports.tickIncrement = tickIncrement; ++exports.tickStep = tickStep; ++exports.transpose = transpose; ++exports.variance = variance; ++exports.zip = zip; ++exports.axisTop = axisTop; ++exports.axisRight = axisRight; ++exports.axisBottom = axisBottom; ++exports.axisLeft = axisLeft; ++exports.brush = brush; ++exports.brushX = brushX; ++exports.brushY = brushY; ++exports.brushSelection = brushSelection; ++exports.chord = chord; ++exports.ribbon = ribbon; ++exports.nest = nest; ++exports.set = set$2; ++exports.map = map$1; ++exports.keys = keys; ++exports.values = values; ++exports.entries = entries; ++exports.color = color; ++exports.rgb = rgb; ++exports.hsl = hsl; ++exports.lab = lab; ++exports.hcl = hcl; ++exports.lch = lch; ++exports.gray = gray; ++exports.cubehelix = cubehelix; ++exports.contours = contours; ++exports.contourDensity = density; ++exports.dispatch = dispatch; ++exports.drag = drag; ++exports.dragDisable = dragDisable; ++exports.dragEnable = yesdrag; ++exports.dsvFormat = dsvFormat; ++exports.csvParse = csvParse; ++exports.csvParseRows = csvParseRows; ++exports.csvFormat = csvFormat; ++exports.csvFormatRows = csvFormatRows; ++exports.tsvParse = tsvParse; ++exports.tsvParseRows = tsvParseRows; ++exports.tsvFormat = tsvFormat; ++exports.tsvFormatRows = tsvFormatRows; ++exports.easeLinear = linear$1; ++exports.easeQuad = quadInOut; ++exports.easeQuadIn = quadIn; ++exports.easeQuadOut = quadOut; ++exports.easeQuadInOut = quadInOut; ++exports.easeCubic = cubicInOut; ++exports.easeCubicIn = cubicIn; ++exports.easeCubicOut = cubicOut; ++exports.easeCubicInOut = cubicInOut; ++exports.easePoly = polyInOut; ++exports.easePolyIn = polyIn; ++exports.easePolyOut = polyOut; ++exports.easePolyInOut = polyInOut; ++exports.easeSin = sinInOut; ++exports.easeSinIn = sinIn; ++exports.easeSinOut = sinOut; ++exports.easeSinInOut = sinInOut; ++exports.easeExp = expInOut; ++exports.easeExpIn = expIn; ++exports.easeExpOut = expOut; ++exports.easeExpInOut = expInOut; ++exports.easeCircle = circleInOut; ++exports.easeCircleIn = circleIn; ++exports.easeCircleOut = circleOut; ++exports.easeCircleInOut = circleInOut; ++exports.easeBounce = bounceOut; ++exports.easeBounceIn = bounceIn; ++exports.easeBounceOut = bounceOut; ++exports.easeBounceInOut = bounceInOut; ++exports.easeBack = backInOut; ++exports.easeBackIn = backIn; ++exports.easeBackOut = backOut; ++exports.easeBackInOut = backInOut; ++exports.easeElastic = elasticOut; ++exports.easeElasticIn = elasticIn; ++exports.easeElasticOut = elasticOut; ++exports.easeElasticInOut = elasticInOut; ++exports.blob = blob; ++exports.buffer = buffer; ++exports.dsv = dsv; ++exports.csv = csv$1; ++exports.tsv = tsv$1; ++exports.image = image; ++exports.json = json; ++exports.text = text; ++exports.xml = xml; ++exports.html = html; ++exports.svg = svg; ++exports.forceCenter = center$1; ++exports.forceCollide = collide; ++exports.forceLink = link; ++exports.forceManyBody = manyBody; ++exports.forceRadial = radial; ++exports.forceSimulation = simulation; ++exports.forceX = x$2; ++exports.forceY = y$2; ++exports.formatDefaultLocale = defaultLocale; ++exports.formatLocale = formatLocale; ++exports.formatSpecifier = formatSpecifier; ++exports.precisionFixed = precisionFixed; ++exports.precisionPrefix = precisionPrefix; ++exports.precisionRound = precisionRound; ++exports.geoArea = area$1; ++exports.geoBounds = bounds; ++exports.geoCentroid = centroid; ++exports.geoCircle = circle; ++exports.geoClipAntimeridian = clipAntimeridian; ++exports.geoClipCircle = clipCircle; ++exports.geoClipExtent = extent$1; ++exports.geoClipRectangle = clipRectangle; ++exports.geoContains = contains$1; ++exports.geoDistance = distance; ++exports.geoGraticule = graticule; ++exports.geoGraticule10 = graticule10; ++exports.geoInterpolate = interpolate$1; ++exports.geoLength = length$1; ++exports.geoPath = index$1; ++exports.geoAlbers = albers; ++exports.geoAlbersUsa = albersUsa; ++exports.geoAzimuthalEqualArea = azimuthalEqualArea; ++exports.geoAzimuthalEqualAreaRaw = azimuthalEqualAreaRaw; ++exports.geoAzimuthalEquidistant = azimuthalEquidistant; ++exports.geoAzimuthalEquidistantRaw = azimuthalEquidistantRaw; ++exports.geoConicConformal = conicConformal; ++exports.geoConicConformalRaw = conicConformalRaw; ++exports.geoConicEqualArea = conicEqualArea; ++exports.geoConicEqualAreaRaw = conicEqualAreaRaw; ++exports.geoConicEquidistant = conicEquidistant; ++exports.geoConicEquidistantRaw = conicEquidistantRaw; ++exports.geoEquirectangular = equirectangular; ++exports.geoEquirectangularRaw = equirectangularRaw; ++exports.geoGnomonic = gnomonic; ++exports.geoGnomonicRaw = gnomonicRaw; ++exports.geoIdentity = identity$5; ++exports.geoProjection = projection; ++exports.geoProjectionMutator = projectionMutator; ++exports.geoMercator = mercator; ++exports.geoMercatorRaw = mercatorRaw; ++exports.geoNaturalEarth1 = naturalEarth1; ++exports.geoNaturalEarth1Raw = naturalEarth1Raw; ++exports.geoOrthographic = orthographic; ++exports.geoOrthographicRaw = orthographicRaw; ++exports.geoStereographic = stereographic; ++exports.geoStereographicRaw = stereographicRaw; ++exports.geoTransverseMercator = transverseMercator; ++exports.geoTransverseMercatorRaw = transverseMercatorRaw; ++exports.geoRotation = rotation; ++exports.geoStream = geoStream; ++exports.geoTransform = transform; ++exports.cluster = cluster; ++exports.hierarchy = hierarchy; ++exports.pack = index$2; ++exports.packSiblings = siblings; ++exports.packEnclose = enclose; ++exports.partition = partition; ++exports.stratify = stratify; ++exports.tree = tree; ++exports.treemap = index$3; ++exports.treemapBinary = binary; ++exports.treemapDice = treemapDice; ++exports.treemapSlice = treemapSlice; ++exports.treemapSliceDice = sliceDice; ++exports.treemapSquarify = squarify; ++exports.treemapResquarify = resquarify; ++exports.interpolate = interpolateValue; ++exports.interpolateArray = array$1; ++exports.interpolateBasis = basis$1; ++exports.interpolateBasisClosed = basisClosed; ++exports.interpolateDate = date; ++exports.interpolateNumber = reinterpolate; ++exports.interpolateObject = object; ++exports.interpolateRound = interpolateRound; ++exports.interpolateString = interpolateString; ++exports.interpolateTransformCss = interpolateTransformCss; ++exports.interpolateTransformSvg = interpolateTransformSvg; ++exports.interpolateZoom = interpolateZoom; ++exports.interpolateRgb = interpolateRgb; ++exports.interpolateRgbBasis = rgbBasis; ++exports.interpolateRgbBasisClosed = rgbBasisClosed; ++exports.interpolateHsl = hsl$2; ++exports.interpolateHslLong = hslLong; ++exports.interpolateLab = lab$1; ++exports.interpolateHcl = hcl$2; ++exports.interpolateHclLong = hclLong; ++exports.interpolateCubehelix = cubehelix$2; ++exports.interpolateCubehelixLong = cubehelixLong; ++exports.piecewise = piecewise; ++exports.quantize = quantize; ++exports.path = path; ++exports.polygonArea = area$2; ++exports.polygonCentroid = centroid$1; ++exports.polygonHull = hull; ++exports.polygonContains = contains$2; ++exports.polygonLength = length$2; ++exports.quadtree = quadtree; ++exports.randomUniform = uniform; ++exports.randomNormal = normal; ++exports.randomLogNormal = logNormal; ++exports.randomBates = bates; ++exports.randomIrwinHall = irwinHall; ++exports.randomExponential = exponential$1; ++exports.scaleBand = band; ++exports.scalePoint = point$1; ++exports.scaleIdentity = identity$6; ++exports.scaleLinear = linear$2; ++exports.scaleLog = log$1; ++exports.scaleOrdinal = ordinal; ++exports.scaleImplicit = implicit; ++exports.scalePow = pow$1; ++exports.scaleSqrt = sqrt$1; ++exports.scaleQuantile = quantile$$1; ++exports.scaleQuantize = quantize$1; ++exports.scaleThreshold = threshold$1; ++exports.scaleTime = time; ++exports.scaleUtc = utcTime; ++exports.scaleSequential = sequential; ++exports.scaleDiverging = diverging; ++exports.schemeCategory10 = category10; ++exports.schemeAccent = Accent; ++exports.schemeDark2 = Dark2; ++exports.schemePaired = Paired; ++exports.schemePastel1 = Pastel1; ++exports.schemePastel2 = Pastel2; ++exports.schemeSet1 = Set1; ++exports.schemeSet2 = Set2; ++exports.schemeSet3 = Set3; ++exports.interpolateBrBG = BrBG; ++exports.schemeBrBG = scheme; ++exports.interpolatePRGn = PRGn; ++exports.schemePRGn = scheme$1; ++exports.interpolatePiYG = PiYG; ++exports.schemePiYG = scheme$2; ++exports.interpolatePuOr = PuOr; ++exports.schemePuOr = scheme$3; ++exports.interpolateRdBu = RdBu; ++exports.schemeRdBu = scheme$4; ++exports.interpolateRdGy = RdGy; ++exports.schemeRdGy = scheme$5; ++exports.interpolateRdYlBu = RdYlBu; ++exports.schemeRdYlBu = scheme$6; ++exports.interpolateRdYlGn = RdYlGn; ++exports.schemeRdYlGn = scheme$7; ++exports.interpolateSpectral = Spectral; ++exports.schemeSpectral = scheme$8; ++exports.interpolateBuGn = BuGn; ++exports.schemeBuGn = scheme$9; ++exports.interpolateBuPu = BuPu; ++exports.schemeBuPu = scheme$10; ++exports.interpolateGnBu = GnBu; ++exports.schemeGnBu = scheme$11; ++exports.interpolateOrRd = OrRd; ++exports.schemeOrRd = scheme$12; ++exports.interpolatePuBuGn = PuBuGn; ++exports.schemePuBuGn = scheme$13; ++exports.interpolatePuBu = PuBu; ++exports.schemePuBu = scheme$14; ++exports.interpolatePuRd = PuRd; ++exports.schemePuRd = scheme$15; ++exports.interpolateRdPu = RdPu; ++exports.schemeRdPu = scheme$16; ++exports.interpolateYlGnBu = YlGnBu; ++exports.schemeYlGnBu = scheme$17; ++exports.interpolateYlGn = YlGn; ++exports.schemeYlGn = scheme$18; ++exports.interpolateYlOrBr = YlOrBr; ++exports.schemeYlOrBr = scheme$19; ++exports.interpolateYlOrRd = YlOrRd; ++exports.schemeYlOrRd = scheme$20; ++exports.interpolateBlues = Blues; ++exports.schemeBlues = scheme$21; ++exports.interpolateGreens = Greens; ++exports.schemeGreens = scheme$22; ++exports.interpolateGreys = Greys; ++exports.schemeGreys = scheme$23; ++exports.interpolatePurples = Purples; ++exports.schemePurples = scheme$24; ++exports.interpolateReds = Reds; ++exports.schemeReds = scheme$25; ++exports.interpolateOranges = Oranges; ++exports.schemeOranges = scheme$26; ++exports.interpolateCubehelixDefault = cubehelix$3; ++exports.interpolateRainbow = rainbow; ++exports.interpolateWarm = warm; ++exports.interpolateCool = cool; ++exports.interpolateSinebow = sinebow; ++exports.interpolateViridis = viridis; ++exports.interpolateMagma = magma; ++exports.interpolateInferno = inferno; ++exports.interpolatePlasma = plasma; ++exports.create = create; ++exports.creator = creator; ++exports.local = local; ++exports.matcher = matcher$1; ++exports.mouse = mouse; ++exports.namespace = namespace; ++exports.namespaces = namespaces; ++exports.clientPoint = point; ++exports.select = select; ++exports.selectAll = selectAll; ++exports.selection = selection; ++exports.selector = selector; ++exports.selectorAll = selectorAll; ++exports.style = styleValue; ++exports.touch = touch; ++exports.touches = touches; ++exports.window = defaultView; ++exports.customEvent = customEvent; ++exports.arc = arc; ++exports.area = area$3; ++exports.line = line; ++exports.pie = pie; ++exports.areaRadial = areaRadial; ++exports.radialArea = areaRadial; ++exports.lineRadial = lineRadial$1; ++exports.radialLine = lineRadial$1; ++exports.pointRadial = pointRadial; ++exports.linkHorizontal = linkHorizontal; ++exports.linkVertical = linkVertical; ++exports.linkRadial = linkRadial; ++exports.symbol = symbol; ++exports.symbols = symbols; ++exports.symbolCircle = circle$2; ++exports.symbolCross = cross$2; ++exports.symbolDiamond = diamond; ++exports.symbolSquare = square; ++exports.symbolStar = star; ++exports.symbolTriangle = triangle; ++exports.symbolWye = wye; ++exports.curveBasisClosed = basisClosed$1; ++exports.curveBasisOpen = basisOpen; ++exports.curveBasis = basis$2; ++exports.curveBundle = bundle; ++exports.curveCardinalClosed = cardinalClosed; ++exports.curveCardinalOpen = cardinalOpen; ++exports.curveCardinal = cardinal; ++exports.curveCatmullRomClosed = catmullRomClosed; ++exports.curveCatmullRomOpen = catmullRomOpen; ++exports.curveCatmullRom = catmullRom; ++exports.curveLinearClosed = linearClosed; ++exports.curveLinear = curveLinear; ++exports.curveMonotoneX = monotoneX; ++exports.curveMonotoneY = monotoneY; ++exports.curveNatural = natural; ++exports.curveStep = step; ++exports.curveStepAfter = stepAfter; ++exports.curveStepBefore = stepBefore; ++exports.stack = stack; ++exports.stackOffsetExpand = expand; ++exports.stackOffsetDiverging = diverging$1; ++exports.stackOffsetNone = none$1; ++exports.stackOffsetSilhouette = silhouette; ++exports.stackOffsetWiggle = wiggle; ++exports.stackOrderAscending = ascending$3; ++exports.stackOrderDescending = descending$2; ++exports.stackOrderInsideOut = insideOut; ++exports.stackOrderNone = none$2; ++exports.stackOrderReverse = reverse; ++exports.timeInterval = newInterval; ++exports.timeMillisecond = millisecond; ++exports.timeMilliseconds = milliseconds; ++exports.utcMillisecond = millisecond; ++exports.utcMilliseconds = milliseconds; ++exports.timeSecond = second; ++exports.timeSeconds = seconds; ++exports.utcSecond = second; ++exports.utcSeconds = seconds; ++exports.timeMinute = minute; ++exports.timeMinutes = minutes; ++exports.timeHour = hour; ++exports.timeHours = hours; ++exports.timeDay = day; ++exports.timeDays = days; ++exports.timeWeek = sunday; ++exports.timeWeeks = sundays; ++exports.timeSunday = sunday; ++exports.timeSundays = sundays; ++exports.timeMonday = monday; ++exports.timeMondays = mondays; ++exports.timeTuesday = tuesday; ++exports.timeTuesdays = tuesdays; ++exports.timeWednesday = wednesday; ++exports.timeWednesdays = wednesdays; ++exports.timeThursday = thursday; ++exports.timeThursdays = thursdays; ++exports.timeFriday = friday; ++exports.timeFridays = fridays; ++exports.timeSaturday = saturday; ++exports.timeSaturdays = saturdays; ++exports.timeMonth = month; ++exports.timeMonths = months; ++exports.timeYear = year; ++exports.timeYears = years; ++exports.utcMinute = utcMinute; ++exports.utcMinutes = utcMinutes; ++exports.utcHour = utcHour; ++exports.utcHours = utcHours; ++exports.utcDay = utcDay; ++exports.utcDays = utcDays; ++exports.utcWeek = utcSunday; ++exports.utcWeeks = utcSundays; ++exports.utcSunday = utcSunday; ++exports.utcSundays = utcSundays; ++exports.utcMonday = utcMonday; ++exports.utcMondays = utcMondays; ++exports.utcTuesday = utcTuesday; ++exports.utcTuesdays = utcTuesdays; ++exports.utcWednesday = utcWednesday; ++exports.utcWednesdays = utcWednesdays; ++exports.utcThursday = utcThursday; ++exports.utcThursdays = utcThursdays; ++exports.utcFriday = utcFriday; ++exports.utcFridays = utcFridays; ++exports.utcSaturday = utcSaturday; ++exports.utcSaturdays = utcSaturdays; ++exports.utcMonth = utcMonth; ++exports.utcMonths = utcMonths; ++exports.utcYear = utcYear; ++exports.utcYears = utcYears; ++exports.timeFormatDefaultLocale = defaultLocale$1; ++exports.timeFormatLocale = formatLocale$1; ++exports.isoFormat = formatIso; ++exports.isoParse = parseIso; ++exports.now = now; ++exports.timer = timer; ++exports.timerFlush = timerFlush; ++exports.timeout = timeout$1; ++exports.interval = interval$1; ++exports.transition = transition; ++exports.active = active; ++exports.interrupt = interrupt; ++exports.voronoi = voronoi; ++exports.zoom = zoom; ++exports.zoomTransform = transform$1; ++exports.zoomIdentity = identity$8; ++ ++Object.defineProperty(exports, '__esModule', { value: true }); ++ ++}))); diff --cc debian/missing-sources/jquery-1.12.4.js index 0000000,0000000..7fc60fc new file mode 100644 --- /dev/null +++ b/debian/missing-sources/jquery-1.12.4.js @@@ -1,0 -1,0 +1,11008 @@@ ++/*! ++ * jQuery JavaScript Library v1.12.4 ++ * http://jquery.com/ ++ * ++ * Includes Sizzle.js ++ * http://sizzlejs.com/ ++ * ++ * Copyright jQuery Foundation and other contributors ++ * Released under the MIT license ++ * http://jquery.org/license ++ * ++ * Date: 2016-05-20T17:17Z ++ */ ++ ++(function( global, factory ) { ++ ++ if ( typeof module === "object" && typeof module.exports === "object" ) { ++ // For CommonJS and CommonJS-like environments where a proper `window` ++ // is present, execute the factory and get jQuery. ++ // For environments that do not have a `window` with a `document` ++ // (such as Node.js), expose a factory as module.exports. ++ // This accentuates the need for the creation of a real `window`. ++ // e.g. var jQuery = require("jquery")(window); ++ // See ticket #14549 for more info. ++ module.exports = global.document ? ++ factory( global, true ) : ++ function( w ) { ++ if ( !w.document ) { ++ throw new Error( "jQuery requires a window with a document" ); ++ } ++ return factory( w ); ++ }; ++ } else { ++ factory( global ); ++ } ++ ++// Pass this if window is not defined yet ++}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { ++ ++// Support: Firefox 18+ ++// Can't be in strict mode, several libs including ASP.NET trace ++// the stack via arguments.caller.callee and Firefox dies if ++// you try to trace through "use strict" call chains. (#13335) ++//"use strict"; ++var deletedIds = []; ++ ++var document = window.document; ++ ++var slice = deletedIds.slice; ++ ++var concat = deletedIds.concat; ++ ++var push = deletedIds.push; ++ ++var indexOf = deletedIds.indexOf; ++ ++var class2type = {}; ++ ++var toString = class2type.toString; ++ ++var hasOwn = class2type.hasOwnProperty; ++ ++var support = {}; ++ ++ ++ ++var ++ version = "1.12.4", ++ ++ // Define a local copy of jQuery ++ jQuery = function( selector, context ) { ++ ++ // The jQuery object is actually just the init constructor 'enhanced' ++ // Need init if jQuery is called (just allow error to be thrown if not included) ++ return new jQuery.fn.init( selector, context ); ++ }, ++ ++ // Support: Android<4.1, IE<9 ++ // Make sure we trim BOM and NBSP ++ rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ++ ++ // Matches dashed string for camelizing ++ rmsPrefix = /^-ms-/, ++ rdashAlpha = /-([\da-z])/gi, ++ ++ // Used by jQuery.camelCase as callback to replace() ++ fcamelCase = function( all, letter ) { ++ return letter.toUpperCase(); ++ }; ++ ++jQuery.fn = jQuery.prototype = { ++ ++ // The current version of jQuery being used ++ jquery: version, ++ ++ constructor: jQuery, ++ ++ // Start with an empty selector ++ selector: "", ++ ++ // The default length of a jQuery object is 0 ++ length: 0, ++ ++ toArray: function() { ++ return slice.call( this ); ++ }, ++ ++ // Get the Nth element in the matched element set OR ++ // Get the whole matched element set as a clean array ++ get: function( num ) { ++ return num != null ? ++ ++ // Return just the one element from the set ++ ( num < 0 ? this[ num + this.length ] : this[ num ] ) : ++ ++ // Return all the elements in a clean array ++ slice.call( this ); ++ }, ++ ++ // Take an array of elements and push it onto the stack ++ // (returning the new matched element set) ++ pushStack: function( elems ) { ++ ++ // Build a new jQuery matched element set ++ var ret = jQuery.merge( this.constructor(), elems ); ++ ++ // Add the old object onto the stack (as a reference) ++ ret.prevObject = this; ++ ret.context = this.context; ++ ++ // Return the newly-formed element set ++ return ret; ++ }, ++ ++ // Execute a callback for every element in the matched set. ++ each: function( callback ) { ++ return jQuery.each( this, callback ); ++ }, ++ ++ map: function( callback ) { ++ return this.pushStack( jQuery.map( this, function( elem, i ) { ++ return callback.call( elem, i, elem ); ++ } ) ); ++ }, ++ ++ slice: function() { ++ return this.pushStack( slice.apply( this, arguments ) ); ++ }, ++ ++ first: function() { ++ return this.eq( 0 ); ++ }, ++ ++ last: function() { ++ return this.eq( -1 ); ++ }, ++ ++ eq: function( i ) { ++ var len = this.length, ++ j = +i + ( i < 0 ? len : 0 ); ++ return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); ++ }, ++ ++ end: function() { ++ return this.prevObject || this.constructor(); ++ }, ++ ++ // For internal use only. ++ // Behaves like an Array's method, not like a jQuery method. ++ push: push, ++ sort: deletedIds.sort, ++ splice: deletedIds.splice ++}; ++ ++jQuery.extend = jQuery.fn.extend = function() { ++ var src, copyIsArray, copy, name, options, clone, ++ target = arguments[ 0 ] || {}, ++ i = 1, ++ length = arguments.length, ++ deep = false; ++ ++ // Handle a deep copy situation ++ if ( typeof target === "boolean" ) { ++ deep = target; ++ ++ // skip the boolean and the target ++ target = arguments[ i ] || {}; ++ i++; ++ } ++ ++ // Handle case when target is a string or something (possible in deep copy) ++ if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { ++ target = {}; ++ } ++ ++ // extend jQuery itself if only one argument is passed ++ if ( i === length ) { ++ target = this; ++ i--; ++ } ++ ++ for ( ; i < length; i++ ) { ++ ++ // Only deal with non-null/undefined values ++ if ( ( options = arguments[ i ] ) != null ) { ++ ++ // Extend the base object ++ for ( name in options ) { ++ src = target[ name ]; ++ copy = options[ name ]; ++ ++ // Prevent never-ending loop ++ if ( target === copy ) { ++ continue; ++ } ++ ++ // Recurse if we're merging plain objects or arrays ++ if ( deep && copy && ( jQuery.isPlainObject( copy ) || ++ ( copyIsArray = jQuery.isArray( copy ) ) ) ) { ++ ++ if ( copyIsArray ) { ++ copyIsArray = false; ++ clone = src && jQuery.isArray( src ) ? src : []; ++ ++ } else { ++ clone = src && jQuery.isPlainObject( src ) ? src : {}; ++ } ++ ++ // Never move original objects, clone them ++ target[ name ] = jQuery.extend( deep, clone, copy ); ++ ++ // Don't bring in undefined values ++ } else if ( copy !== undefined ) { ++ target[ name ] = copy; ++ } ++ } ++ } ++ } ++ ++ // Return the modified object ++ return target; ++}; ++ ++jQuery.extend( { ++ ++ // Unique for each copy of jQuery on the page ++ expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), ++ ++ // Assume jQuery is ready without the ready module ++ isReady: true, ++ ++ error: function( msg ) { ++ throw new Error( msg ); ++ }, ++ ++ noop: function() {}, ++ ++ // See test/unit/core.js for details concerning isFunction. ++ // Since version 1.3, DOM methods and functions like alert ++ // aren't supported. They return false on IE (#2968). ++ isFunction: function( obj ) { ++ return jQuery.type( obj ) === "function"; ++ }, ++ ++ isArray: Array.isArray || function( obj ) { ++ return jQuery.type( obj ) === "array"; ++ }, ++ ++ isWindow: function( obj ) { ++ /* jshint eqeqeq: false */ ++ return obj != null && obj == obj.window; ++ }, ++ ++ isNumeric: function( obj ) { ++ ++ // parseFloat NaNs numeric-cast false positives (null|true|false|"") ++ // ...but misinterprets leading-number strings, particularly hex literals ("0x...") ++ // subtraction forces infinities to NaN ++ // adding 1 corrects loss of precision from parseFloat (#15100) ++ var realStringObj = obj && obj.toString(); ++ return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0; ++ }, ++ ++ isEmptyObject: function( obj ) { ++ var name; ++ for ( name in obj ) { ++ return false; ++ } ++ return true; ++ }, ++ ++ isPlainObject: function( obj ) { ++ var key; ++ ++ // Must be an Object. ++ // Because of IE, we also have to check the presence of the constructor property. ++ // Make sure that DOM nodes and window objects don't pass through, as well ++ if ( !obj || jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { ++ return false; ++ } ++ ++ try { ++ ++ // Not own constructor property must be Object ++ if ( obj.constructor && ++ !hasOwn.call( obj, "constructor" ) && ++ !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { ++ return false; ++ } ++ } catch ( e ) { ++ ++ // IE8,9 Will throw exceptions on certain host objects #9897 ++ return false; ++ } ++ ++ // Support: IE<9 ++ // Handle iteration over inherited properties before own properties. ++ if ( !support.ownFirst ) { ++ for ( key in obj ) { ++ return hasOwn.call( obj, key ); ++ } ++ } ++ ++ // Own properties are enumerated firstly, so to speed up, ++ // if last one is own, then all properties are own. ++ for ( key in obj ) {} ++ ++ return key === undefined || hasOwn.call( obj, key ); ++ }, ++ ++ type: function( obj ) { ++ if ( obj == null ) { ++ return obj + ""; ++ } ++ return typeof obj === "object" || typeof obj === "function" ? ++ class2type[ toString.call( obj ) ] || "object" : ++ typeof obj; ++ }, ++ ++ // Workarounds based on findings by Jim Driscoll ++ // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context ++ globalEval: function( data ) { ++ if ( data && jQuery.trim( data ) ) { ++ ++ // We use execScript on Internet Explorer ++ // We use an anonymous function so that context is window ++ // rather than jQuery in Firefox ++ ( window.execScript || function( data ) { ++ window[ "eval" ].call( window, data ); // jscs:ignore requireDotNotation ++ } )( data ); ++ } ++ }, ++ ++ // Convert dashed to camelCase; used by the css and data modules ++ // Microsoft forgot to hump their vendor prefix (#9572) ++ camelCase: function( string ) { ++ return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); ++ }, ++ ++ nodeName: function( elem, name ) { ++ return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); ++ }, ++ ++ each: function( obj, callback ) { ++ var length, i = 0; ++ ++ if ( isArrayLike( obj ) ) { ++ length = obj.length; ++ for ( ; i < length; i++ ) { ++ if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { ++ break; ++ } ++ } ++ } else { ++ for ( i in obj ) { ++ if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { ++ break; ++ } ++ } ++ } ++ ++ return obj; ++ }, ++ ++ // Support: Android<4.1, IE<9 ++ trim: function( text ) { ++ return text == null ? ++ "" : ++ ( text + "" ).replace( rtrim, "" ); ++ }, ++ ++ // results is for internal usage only ++ makeArray: function( arr, results ) { ++ var ret = results || []; ++ ++ if ( arr != null ) { ++ if ( isArrayLike( Object( arr ) ) ) { ++ jQuery.merge( ret, ++ typeof arr === "string" ? ++ [ arr ] : arr ++ ); ++ } else { ++ push.call( ret, arr ); ++ } ++ } ++ ++ return ret; ++ }, ++ ++ inArray: function( elem, arr, i ) { ++ var len; ++ ++ if ( arr ) { ++ if ( indexOf ) { ++ return indexOf.call( arr, elem, i ); ++ } ++ ++ len = arr.length; ++ i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; ++ ++ for ( ; i < len; i++ ) { ++ ++ // Skip accessing in sparse arrays ++ if ( i in arr && arr[ i ] === elem ) { ++ return i; ++ } ++ } ++ } ++ ++ return -1; ++ }, ++ ++ merge: function( first, second ) { ++ var len = +second.length, ++ j = 0, ++ i = first.length; ++ ++ while ( j < len ) { ++ first[ i++ ] = second[ j++ ]; ++ } ++ ++ // Support: IE<9 ++ // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists) ++ if ( len !== len ) { ++ while ( second[ j ] !== undefined ) { ++ first[ i++ ] = second[ j++ ]; ++ } ++ } ++ ++ first.length = i; ++ ++ return first; ++ }, ++ ++ grep: function( elems, callback, invert ) { ++ var callbackInverse, ++ matches = [], ++ i = 0, ++ length = elems.length, ++ callbackExpect = !invert; ++ ++ // Go through the array, only saving the items ++ // that pass the validator function ++ for ( ; i < length; i++ ) { ++ callbackInverse = !callback( elems[ i ], i ); ++ if ( callbackInverse !== callbackExpect ) { ++ matches.push( elems[ i ] ); ++ } ++ } ++ ++ return matches; ++ }, ++ ++ // arg is for internal usage only ++ map: function( elems, callback, arg ) { ++ var length, value, ++ i = 0, ++ ret = []; ++ ++ // Go through the array, translating each of the items to their new values ++ if ( isArrayLike( elems ) ) { ++ length = elems.length; ++ for ( ; i < length; i++ ) { ++ value = callback( elems[ i ], i, arg ); ++ ++ if ( value != null ) { ++ ret.push( value ); ++ } ++ } ++ ++ // Go through every key on the object, ++ } else { ++ for ( i in elems ) { ++ value = callback( elems[ i ], i, arg ); ++ ++ if ( value != null ) { ++ ret.push( value ); ++ } ++ } ++ } ++ ++ // Flatten any nested arrays ++ return concat.apply( [], ret ); ++ }, ++ ++ // A global GUID counter for objects ++ guid: 1, ++ ++ // Bind a function to a context, optionally partially applying any ++ // arguments. ++ proxy: function( fn, context ) { ++ var args, proxy, tmp; ++ ++ if ( typeof context === "string" ) { ++ tmp = fn[ context ]; ++ context = fn; ++ fn = tmp; ++ } ++ ++ // Quick check to determine if target is callable, in the spec ++ // this throws a TypeError, but we will just return undefined. ++ if ( !jQuery.isFunction( fn ) ) { ++ return undefined; ++ } ++ ++ // Simulated bind ++ args = slice.call( arguments, 2 ); ++ proxy = function() { ++ return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); ++ }; ++ ++ // Set the guid of unique handler to the same of original handler, so it can be removed ++ proxy.guid = fn.guid = fn.guid || jQuery.guid++; ++ ++ return proxy; ++ }, ++ ++ now: function() { ++ return +( new Date() ); ++ }, ++ ++ // jQuery.support is not used in Core but other projects attach their ++ // properties to it so it needs to exist. ++ support: support ++} ); ++ ++// JSHint would error on this code due to the Symbol not being defined in ES5. ++// Defining this global in .jshintrc would create a danger of using the global ++// unguarded in another place, it seems safer to just disable JSHint for these ++// three lines. ++/* jshint ignore: start */ ++if ( typeof Symbol === "function" ) { ++ jQuery.fn[ Symbol.iterator ] = deletedIds[ Symbol.iterator ]; ++} ++/* jshint ignore: end */ ++ ++// Populate the class2type map ++jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), ++function( i, name ) { ++ class2type[ "[object " + name + "]" ] = name.toLowerCase(); ++} ); ++ ++function isArrayLike( obj ) { ++ ++ // Support: iOS 8.2 (not reproducible in simulator) ++ // `in` check used to prevent JIT error (gh-2145) ++ // hasOwn isn't used here due to false negatives ++ // regarding Nodelist length in IE ++ var length = !!obj && "length" in obj && obj.length, ++ type = jQuery.type( obj ); ++ ++ if ( type === "function" || jQuery.isWindow( obj ) ) { ++ return false; ++ } ++ ++ return type === "array" || length === 0 || ++ typeof length === "number" && length > 0 && ( length - 1 ) in obj; ++} ++var Sizzle = ++/*! ++ * Sizzle CSS Selector Engine v2.2.1 ++ * http://sizzlejs.com/ ++ * ++ * Copyright jQuery Foundation and other contributors ++ * Released under the MIT license ++ * http://jquery.org/license ++ * ++ * Date: 2015-10-17 ++ */ ++(function( window ) { ++ ++var i, ++ support, ++ Expr, ++ getText, ++ isXML, ++ tokenize, ++ compile, ++ select, ++ outermostContext, ++ sortInput, ++ hasDuplicate, ++ ++ // Local document vars ++ setDocument, ++ document, ++ docElem, ++ documentIsHTML, ++ rbuggyQSA, ++ rbuggyMatches, ++ matches, ++ contains, ++ ++ // Instance-specific data ++ expando = "sizzle" + 1 * new Date(), ++ preferredDoc = window.document, ++ dirruns = 0, ++ done = 0, ++ classCache = createCache(), ++ tokenCache = createCache(), ++ compilerCache = createCache(), ++ sortOrder = function( a, b ) { ++ if ( a === b ) { ++ hasDuplicate = true; ++ } ++ return 0; ++ }, ++ ++ // General-purpose constants ++ MAX_NEGATIVE = 1 << 31, ++ ++ // Instance methods ++ hasOwn = ({}).hasOwnProperty, ++ arr = [], ++ pop = arr.pop, ++ push_native = arr.push, ++ push = arr.push, ++ slice = arr.slice, ++ // Use a stripped-down indexOf as it's faster than native ++ // http://jsperf.com/thor-indexof-vs-for/5 ++ indexOf = function( list, elem ) { ++ var i = 0, ++ len = list.length; ++ for ( ; i < len; i++ ) { ++ if ( list[i] === elem ) { ++ return i; ++ } ++ } ++ return -1; ++ }, ++ ++ booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", ++ ++ // Regular expressions ++ ++ // http://www.w3.org/TR/css3-selectors/#whitespace ++ whitespace = "[\\x20\\t\\r\\n\\f]", ++ ++ // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier ++ identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", ++ ++ // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors ++ attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + ++ // Operator (capture 2) ++ "*([*^$|!~]?=)" + whitespace + ++ // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" ++ "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + ++ "*\\]", ++ ++ pseudos = ":(" + identifier + ")(?:\\((" + ++ // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: ++ // 1. quoted (capture 3; capture 4 or capture 5) ++ "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + ++ // 2. simple (capture 6) ++ "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + ++ // 3. anything else (capture 2) ++ ".*" + ++ ")\\)|)", ++ ++ // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter ++ rwhitespace = new RegExp( whitespace + "+", "g" ), ++ rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), ++ ++ rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), ++ rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), ++ ++ rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), ++ ++ rpseudo = new RegExp( pseudos ), ++ ridentifier = new RegExp( "^" + identifier + "$" ), ++ ++ matchExpr = { ++ "ID": new RegExp( "^#(" + identifier + ")" ), ++ "CLASS": new RegExp( "^\\.(" + identifier + ")" ), ++ "TAG": new RegExp( "^(" + identifier + "|[*])" ), ++ "ATTR": new RegExp( "^" + attributes ), ++ "PSEUDO": new RegExp( "^" + pseudos ), ++ "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + ++ "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + ++ "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), ++ "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), ++ // For use in libraries implementing .is() ++ // We use this for POS matching in `select` ++ "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + ++ whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) ++ }, ++ ++ rinputs = /^(?:input|select|textarea|button)$/i, ++ rheader = /^h\d$/i, ++ ++ rnative = /^[^{]+\{\s*\[native \w/, ++ ++ // Easily-parseable/retrievable ID or TAG or CLASS selectors ++ rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, ++ ++ rsibling = /[+~]/, ++ rescape = /'|\\/g, ++ ++ // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters ++ runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), ++ funescape = function( _, escaped, escapedWhitespace ) { ++ var high = "0x" + escaped - 0x10000; ++ // NaN means non-codepoint ++ // Support: Firefox<24 ++ // Workaround erroneous numeric interpretation of +"0x" ++ return high !== high || escapedWhitespace ? ++ escaped : ++ high < 0 ? ++ // BMP codepoint ++ String.fromCharCode( high + 0x10000 ) : ++ // Supplemental Plane codepoint (surrogate pair) ++ String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); ++ }, ++ ++ // Used for iframes ++ // See setDocument() ++ // Removing the function wrapper causes a "Permission Denied" ++ // error in IE ++ unloadHandler = function() { ++ setDocument(); ++ }; ++ ++// Optimize for push.apply( _, NodeList ) ++try { ++ push.apply( ++ (arr = slice.call( preferredDoc.childNodes )), ++ preferredDoc.childNodes ++ ); ++ // Support: Android<4.0 ++ // Detect silently failing push.apply ++ arr[ preferredDoc.childNodes.length ].nodeType; ++} catch ( e ) { ++ push = { apply: arr.length ? ++ ++ // Leverage slice if possible ++ function( target, els ) { ++ push_native.apply( target, slice.call(els) ); ++ } : ++ ++ // Support: IE<9 ++ // Otherwise append directly ++ function( target, els ) { ++ var j = target.length, ++ i = 0; ++ // Can't trust NodeList.length ++ while ( (target[j++] = els[i++]) ) {} ++ target.length = j - 1; ++ } ++ }; ++} ++ ++function Sizzle( selector, context, results, seed ) { ++ var m, i, elem, nid, nidselect, match, groups, newSelector, ++ newContext = context && context.ownerDocument, ++ ++ // nodeType defaults to 9, since context defaults to document ++ nodeType = context ? context.nodeType : 9; ++ ++ results = results || []; ++ ++ // Return early from calls with invalid selector or context ++ if ( typeof selector !== "string" || !selector || ++ nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { ++ ++ return results; ++ } ++ ++ // Try to shortcut find operations (as opposed to filters) in HTML documents ++ if ( !seed ) { ++ ++ if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { ++ setDocument( context ); ++ } ++ context = context || document; ++ ++ if ( documentIsHTML ) { ++ ++ // If the selector is sufficiently simple, try using a "get*By*" DOM method ++ // (excepting DocumentFragment context, where the methods don't exist) ++ if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { ++ ++ // ID selector ++ if ( (m = match[1]) ) { ++ ++ // Document context ++ if ( nodeType === 9 ) { ++ if ( (elem = context.getElementById( m )) ) { ++ ++ // Support: IE, Opera, Webkit ++ // TODO: identify versions ++ // getElementById can match elements by name instead of ID ++ if ( elem.id === m ) { ++ results.push( elem ); ++ return results; ++ } ++ } else { ++ return results; ++ } ++ ++ // Element context ++ } else { ++ ++ // Support: IE, Opera, Webkit ++ // TODO: identify versions ++ // getElementById can match elements by name instead of ID ++ if ( newContext && (elem = newContext.getElementById( m )) && ++ contains( context, elem ) && ++ elem.id === m ) { ++ ++ results.push( elem ); ++ return results; ++ } ++ } ++ ++ // Type selector ++ } else if ( match[2] ) { ++ push.apply( results, context.getElementsByTagName( selector ) ); ++ return results; ++ ++ // Class selector ++ } else if ( (m = match[3]) && support.getElementsByClassName && ++ context.getElementsByClassName ) { ++ ++ push.apply( results, context.getElementsByClassName( m ) ); ++ return results; ++ } ++ } ++ ++ // Take advantage of querySelectorAll ++ if ( support.qsa && ++ !compilerCache[ selector + " " ] && ++ (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { ++ ++ if ( nodeType !== 1 ) { ++ newContext = context; ++ newSelector = selector; ++ ++ // qSA looks outside Element context, which is not what we want ++ // Thanks to Andrew Dupont for this workaround technique ++ // Support: IE <=8 ++ // Exclude object elements ++ } else if ( context.nodeName.toLowerCase() !== "object" ) { ++ ++ // Capture the context ID, setting it first if necessary ++ if ( (nid = context.getAttribute( "id" )) ) { ++ nid = nid.replace( rescape, "\\$&" ); ++ } else { ++ context.setAttribute( "id", (nid = expando) ); ++ } ++ ++ // Prefix every selector in the list ++ groups = tokenize( selector ); ++ i = groups.length; ++ nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']"; ++ while ( i-- ) { ++ groups[i] = nidselect + " " + toSelector( groups[i] ); ++ } ++ newSelector = groups.join( "," ); ++ ++ // Expand context for sibling selectors ++ newContext = rsibling.test( selector ) && testContext( context.parentNode ) || ++ context; ++ } ++ ++ if ( newSelector ) { ++ try { ++ push.apply( results, ++ newContext.querySelectorAll( newSelector ) ++ ); ++ return results; ++ } catch ( qsaError ) { ++ } finally { ++ if ( nid === expando ) { ++ context.removeAttribute( "id" ); ++ } ++ } ++ } ++ } ++ } ++ } ++ ++ // All others ++ return select( selector.replace( rtrim, "$1" ), context, results, seed ); ++} ++ ++/** ++ * Create key-value caches of limited size ++ * @returns {function(string, object)} Returns the Object data after storing it on itself with ++ * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) ++ * deleting the oldest entry ++ */ ++function createCache() { ++ var keys = []; ++ ++ function cache( key, value ) { ++ // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) ++ if ( keys.push( key + " " ) > Expr.cacheLength ) { ++ // Only keep the most recent entries ++ delete cache[ keys.shift() ]; ++ } ++ return (cache[ key + " " ] = value); ++ } ++ return cache; ++} ++ ++/** ++ * Mark a function for special use by Sizzle ++ * @param {Function} fn The function to mark ++ */ ++function markFunction( fn ) { ++ fn[ expando ] = true; ++ return fn; ++} ++ ++/** ++ * Support testing using an element ++ * @param {Function} fn Passed the created div and expects a boolean result ++ */ ++function assert( fn ) { ++ var div = document.createElement("div"); ++ ++ try { ++ return !!fn( div ); ++ } catch (e) { ++ return false; ++ } finally { ++ // Remove from its parent by default ++ if ( div.parentNode ) { ++ div.parentNode.removeChild( div ); ++ } ++ // release memory in IE ++ div = null; ++ } ++} ++ ++/** ++ * Adds the same handler for all of the specified attrs ++ * @param {String} attrs Pipe-separated list of attributes ++ * @param {Function} handler The method that will be applied ++ */ ++function addHandle( attrs, handler ) { ++ var arr = attrs.split("|"), ++ i = arr.length; ++ ++ while ( i-- ) { ++ Expr.attrHandle[ arr[i] ] = handler; ++ } ++} ++ ++/** ++ * Checks document order of two siblings ++ * @param {Element} a ++ * @param {Element} b ++ * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b ++ */ ++function siblingCheck( a, b ) { ++ var cur = b && a, ++ diff = cur && a.nodeType === 1 && b.nodeType === 1 && ++ ( ~b.sourceIndex || MAX_NEGATIVE ) - ++ ( ~a.sourceIndex || MAX_NEGATIVE ); ++ ++ // Use IE sourceIndex if available on both nodes ++ if ( diff ) { ++ return diff; ++ } ++ ++ // Check if b follows a ++ if ( cur ) { ++ while ( (cur = cur.nextSibling) ) { ++ if ( cur === b ) { ++ return -1; ++ } ++ } ++ } ++ ++ return a ? 1 : -1; ++} ++ ++/** ++ * Returns a function to use in pseudos for input types ++ * @param {String} type ++ */ ++function createInputPseudo( type ) { ++ return function( elem ) { ++ var name = elem.nodeName.toLowerCase(); ++ return name === "input" && elem.type === type; ++ }; ++} ++ ++/** ++ * Returns a function to use in pseudos for buttons ++ * @param {String} type ++ */ ++function createButtonPseudo( type ) { ++ return function( elem ) { ++ var name = elem.nodeName.toLowerCase(); ++ return (name === "input" || name === "button") && elem.type === type; ++ }; ++} ++ ++/** ++ * Returns a function to use in pseudos for positionals ++ * @param {Function} fn ++ */ ++function createPositionalPseudo( fn ) { ++ return markFunction(function( argument ) { ++ argument = +argument; ++ return markFunction(function( seed, matches ) { ++ var j, ++ matchIndexes = fn( [], seed.length, argument ), ++ i = matchIndexes.length; ++ ++ // Match elements found at the specified indexes ++ while ( i-- ) { ++ if ( seed[ (j = matchIndexes[i]) ] ) { ++ seed[j] = !(matches[j] = seed[j]); ++ } ++ } ++ }); ++ }); ++} ++ ++/** ++ * Checks a node for validity as a Sizzle context ++ * @param {Element|Object=} context ++ * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value ++ */ ++function testContext( context ) { ++ return context && typeof context.getElementsByTagName !== "undefined" && context; ++} ++ ++// Expose support vars for convenience ++support = Sizzle.support = {}; ++ ++/** ++ * Detects XML nodes ++ * @param {Element|Object} elem An element or a document ++ * @returns {Boolean} True iff elem is a non-HTML XML node ++ */ ++isXML = Sizzle.isXML = function( elem ) { ++ // documentElement is verified for cases where it doesn't yet exist ++ // (such as loading iframes in IE - #4833) ++ var documentElement = elem && (elem.ownerDocument || elem).documentElement; ++ return documentElement ? documentElement.nodeName !== "HTML" : false; ++}; ++ ++/** ++ * Sets document-related variables once based on the current document ++ * @param {Element|Object} [doc] An element or document object to use to set the document ++ * @returns {Object} Returns the current document ++ */ ++setDocument = Sizzle.setDocument = function( node ) { ++ var hasCompare, parent, ++ doc = node ? node.ownerDocument || node : preferredDoc; ++ ++ // Return early if doc is invalid or already selected ++ if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { ++ return document; ++ } ++ ++ // Update global variables ++ document = doc; ++ docElem = document.documentElement; ++ documentIsHTML = !isXML( document ); ++ ++ // Support: IE 9-11, Edge ++ // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) ++ if ( (parent = document.defaultView) && parent.top !== parent ) { ++ // Support: IE 11 ++ if ( parent.addEventListener ) { ++ parent.addEventListener( "unload", unloadHandler, false ); ++ ++ // Support: IE 9 - 10 only ++ } else if ( parent.attachEvent ) { ++ parent.attachEvent( "onunload", unloadHandler ); ++ } ++ } ++ ++ /* Attributes ++ ---------------------------------------------------------------------- */ ++ ++ // Support: IE<8 ++ // Verify that getAttribute really returns attributes and not properties ++ // (excepting IE8 booleans) ++ support.attributes = assert(function( div ) { ++ div.className = "i"; ++ return !div.getAttribute("className"); ++ }); ++ ++ /* getElement(s)By* ++ ---------------------------------------------------------------------- */ ++ ++ // Check if getElementsByTagName("*") returns only elements ++ support.getElementsByTagName = assert(function( div ) { ++ div.appendChild( document.createComment("") ); ++ return !div.getElementsByTagName("*").length; ++ }); ++ ++ // Support: IE<9 ++ support.getElementsByClassName = rnative.test( document.getElementsByClassName ); ++ ++ // Support: IE<10 ++ // Check if getElementById returns elements by name ++ // The broken getElementById methods don't pick up programatically-set names, ++ // so use a roundabout getElementsByName test ++ support.getById = assert(function( div ) { ++ docElem.appendChild( div ).id = expando; ++ return !document.getElementsByName || !document.getElementsByName( expando ).length; ++ }); ++ ++ // ID find and filter ++ if ( support.getById ) { ++ Expr.find["ID"] = function( id, context ) { ++ if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { ++ var m = context.getElementById( id ); ++ return m ? [ m ] : []; ++ } ++ }; ++ Expr.filter["ID"] = function( id ) { ++ var attrId = id.replace( runescape, funescape ); ++ return function( elem ) { ++ return elem.getAttribute("id") === attrId; ++ }; ++ }; ++ } else { ++ // Support: IE6/7 ++ // getElementById is not reliable as a find shortcut ++ delete Expr.find["ID"]; ++ ++ Expr.filter["ID"] = function( id ) { ++ var attrId = id.replace( runescape, funescape ); ++ return function( elem ) { ++ var node = typeof elem.getAttributeNode !== "undefined" && ++ elem.getAttributeNode("id"); ++ return node && node.value === attrId; ++ }; ++ }; ++ } ++ ++ // Tag ++ Expr.find["TAG"] = support.getElementsByTagName ? ++ function( tag, context ) { ++ if ( typeof context.getElementsByTagName !== "undefined" ) { ++ return context.getElementsByTagName( tag ); ++ ++ // DocumentFragment nodes don't have gEBTN ++ } else if ( support.qsa ) { ++ return context.querySelectorAll( tag ); ++ } ++ } : ++ ++ function( tag, context ) { ++ var elem, ++ tmp = [], ++ i = 0, ++ // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too ++ results = context.getElementsByTagName( tag ); ++ ++ // Filter out possible comments ++ if ( tag === "*" ) { ++ while ( (elem = results[i++]) ) { ++ if ( elem.nodeType === 1 ) { ++ tmp.push( elem ); ++ } ++ } ++ ++ return tmp; ++ } ++ return results; ++ }; ++ ++ // Class ++ Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { ++ if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { ++ return context.getElementsByClassName( className ); ++ } ++ }; ++ ++ /* QSA/matchesSelector ++ ---------------------------------------------------------------------- */ ++ ++ // QSA and matchesSelector support ++ ++ // matchesSelector(:active) reports false when true (IE9/Opera 11.5) ++ rbuggyMatches = []; ++ ++ // qSa(:focus) reports false when true (Chrome 21) ++ // We allow this because of a bug in IE8/9 that throws an error ++ // whenever `document.activeElement` is accessed on an iframe ++ // So, we allow :focus to pass through QSA all the time to avoid the IE error ++ // See http://bugs.jquery.com/ticket/13378 ++ rbuggyQSA = []; ++ ++ if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { ++ // Build QSA regex ++ // Regex strategy adopted from Diego Perini ++ assert(function( div ) { ++ // Select is set to empty string on purpose ++ // This is to test IE's treatment of not explicitly ++ // setting a boolean content attribute, ++ // since its presence should be enough ++ // http://bugs.jquery.com/ticket/12359 ++ docElem.appendChild( div ).innerHTML = "" + ++ ""; ++ ++ // Support: IE8, Opera 11-12.16 ++ // Nothing should be selected when empty strings follow ^= or $= or *= ++ // The test attribute must be unknown in Opera but "safe" for WinRT ++ // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section ++ if ( div.querySelectorAll("[msallowcapture^='']").length ) { ++ rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); ++ } ++ ++ // Support: IE8 ++ // Boolean attributes and "value" are not treated correctly ++ if ( !div.querySelectorAll("[selected]").length ) { ++ rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); ++ } ++ ++ // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ ++ if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { ++ rbuggyQSA.push("~="); ++ } ++ ++ // Webkit/Opera - :checked should return selected option elements ++ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked ++ // IE8 throws error here and will not see later tests ++ if ( !div.querySelectorAll(":checked").length ) { ++ rbuggyQSA.push(":checked"); ++ } ++ ++ // Support: Safari 8+, iOS 8+ ++ // https://bugs.webkit.org/show_bug.cgi?id=136851 ++ // In-page `selector#id sibing-combinator selector` fails ++ if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { ++ rbuggyQSA.push(".#.+[+~]"); ++ } ++ }); ++ ++ assert(function( div ) { ++ // Support: Windows 8 Native Apps ++ // The type and name attributes are restricted during .innerHTML assignment ++ var input = document.createElement("input"); ++ input.setAttribute( "type", "hidden" ); ++ div.appendChild( input ).setAttribute( "name", "D" ); ++ ++ // Support: IE8 ++ // Enforce case-sensitivity of name attribute ++ if ( div.querySelectorAll("[name=d]").length ) { ++ rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); ++ } ++ ++ // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) ++ // IE8 throws error here and will not see later tests ++ if ( !div.querySelectorAll(":enabled").length ) { ++ rbuggyQSA.push( ":enabled", ":disabled" ); ++ } ++ ++ // Opera 10-11 does not throw on post-comma invalid pseudos ++ div.querySelectorAll("*,:x"); ++ rbuggyQSA.push(",.*:"); ++ }); ++ } ++ ++ if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || ++ docElem.webkitMatchesSelector || ++ docElem.mozMatchesSelector || ++ docElem.oMatchesSelector || ++ docElem.msMatchesSelector) )) ) { ++ ++ assert(function( div ) { ++ // Check to see if it's possible to do matchesSelector ++ // on a disconnected node (IE 9) ++ support.disconnectedMatch = matches.call( div, "div" ); ++ ++ // This should fail with an exception ++ // Gecko does not error, returns false instead ++ matches.call( div, "[s!='']:x" ); ++ rbuggyMatches.push( "!=", pseudos ); ++ }); ++ } ++ ++ rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); ++ rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); ++ ++ /* Contains ++ ---------------------------------------------------------------------- */ ++ hasCompare = rnative.test( docElem.compareDocumentPosition ); ++ ++ // Element contains another ++ // Purposefully self-exclusive ++ // As in, an element does not contain itself ++ contains = hasCompare || rnative.test( docElem.contains ) ? ++ function( a, b ) { ++ var adown = a.nodeType === 9 ? a.documentElement : a, ++ bup = b && b.parentNode; ++ return a === bup || !!( bup && bup.nodeType === 1 && ( ++ adown.contains ? ++ adown.contains( bup ) : ++ a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 ++ )); ++ } : ++ function( a, b ) { ++ if ( b ) { ++ while ( (b = b.parentNode) ) { ++ if ( b === a ) { ++ return true; ++ } ++ } ++ } ++ return false; ++ }; ++ ++ /* Sorting ++ ---------------------------------------------------------------------- */ ++ ++ // Document order sorting ++ sortOrder = hasCompare ? ++ function( a, b ) { ++ ++ // Flag for duplicate removal ++ if ( a === b ) { ++ hasDuplicate = true; ++ return 0; ++ } ++ ++ // Sort on method existence if only one input has compareDocumentPosition ++ var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; ++ if ( compare ) { ++ return compare; ++ } ++ ++ // Calculate position if both inputs belong to the same document ++ compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? ++ a.compareDocumentPosition( b ) : ++ ++ // Otherwise we know they are disconnected ++ 1; ++ ++ // Disconnected nodes ++ if ( compare & 1 || ++ (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { ++ ++ // Choose the first element that is related to our preferred document ++ if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { ++ return -1; ++ } ++ if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { ++ return 1; ++ } ++ ++ // Maintain original order ++ return sortInput ? ++ ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : ++ 0; ++ } ++ ++ return compare & 4 ? -1 : 1; ++ } : ++ function( a, b ) { ++ // Exit early if the nodes are identical ++ if ( a === b ) { ++ hasDuplicate = true; ++ return 0; ++ } ++ ++ var cur, ++ i = 0, ++ aup = a.parentNode, ++ bup = b.parentNode, ++ ap = [ a ], ++ bp = [ b ]; ++ ++ // Parentless nodes are either documents or disconnected ++ if ( !aup || !bup ) { ++ return a === document ? -1 : ++ b === document ? 1 : ++ aup ? -1 : ++ bup ? 1 : ++ sortInput ? ++ ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : ++ 0; ++ ++ // If the nodes are siblings, we can do a quick check ++ } else if ( aup === bup ) { ++ return siblingCheck( a, b ); ++ } ++ ++ // Otherwise we need full lists of their ancestors for comparison ++ cur = a; ++ while ( (cur = cur.parentNode) ) { ++ ap.unshift( cur ); ++ } ++ cur = b; ++ while ( (cur = cur.parentNode) ) { ++ bp.unshift( cur ); ++ } ++ ++ // Walk down the tree looking for a discrepancy ++ while ( ap[i] === bp[i] ) { ++ i++; ++ } ++ ++ return i ? ++ // Do a sibling check if the nodes have a common ancestor ++ siblingCheck( ap[i], bp[i] ) : ++ ++ // Otherwise nodes in our document sort first ++ ap[i] === preferredDoc ? -1 : ++ bp[i] === preferredDoc ? 1 : ++ 0; ++ }; ++ ++ return document; ++}; ++ ++Sizzle.matches = function( expr, elements ) { ++ return Sizzle( expr, null, null, elements ); ++}; ++ ++Sizzle.matchesSelector = function( elem, expr ) { ++ // Set document vars if needed ++ if ( ( elem.ownerDocument || elem ) !== document ) { ++ setDocument( elem ); ++ } ++ ++ // Make sure that attribute selectors are quoted ++ expr = expr.replace( rattributeQuotes, "='$1']" ); ++ ++ if ( support.matchesSelector && documentIsHTML && ++ !compilerCache[ expr + " " ] && ++ ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && ++ ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { ++ ++ try { ++ var ret = matches.call( elem, expr ); ++ ++ // IE 9's matchesSelector returns false on disconnected nodes ++ if ( ret || support.disconnectedMatch || ++ // As well, disconnected nodes are said to be in a document ++ // fragment in IE 9 ++ elem.document && elem.document.nodeType !== 11 ) { ++ return ret; ++ } ++ } catch (e) {} ++ } ++ ++ return Sizzle( expr, document, null, [ elem ] ).length > 0; ++}; ++ ++Sizzle.contains = function( context, elem ) { ++ // Set document vars if needed ++ if ( ( context.ownerDocument || context ) !== document ) { ++ setDocument( context ); ++ } ++ return contains( context, elem ); ++}; ++ ++Sizzle.attr = function( elem, name ) { ++ // Set document vars if needed ++ if ( ( elem.ownerDocument || elem ) !== document ) { ++ setDocument( elem ); ++ } ++ ++ var fn = Expr.attrHandle[ name.toLowerCase() ], ++ // Don't get fooled by Object.prototype properties (jQuery #13807) ++ val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? ++ fn( elem, name, !documentIsHTML ) : ++ undefined; ++ ++ return val !== undefined ? ++ val : ++ support.attributes || !documentIsHTML ? ++ elem.getAttribute( name ) : ++ (val = elem.getAttributeNode(name)) && val.specified ? ++ val.value : ++ null; ++}; ++ ++Sizzle.error = function( msg ) { ++ throw new Error( "Syntax error, unrecognized expression: " + msg ); ++}; ++ ++/** ++ * Document sorting and removing duplicates ++ * @param {ArrayLike} results ++ */ ++Sizzle.uniqueSort = function( results ) { ++ var elem, ++ duplicates = [], ++ j = 0, ++ i = 0; ++ ++ // Unless we *know* we can detect duplicates, assume their presence ++ hasDuplicate = !support.detectDuplicates; ++ sortInput = !support.sortStable && results.slice( 0 ); ++ results.sort( sortOrder ); ++ ++ if ( hasDuplicate ) { ++ while ( (elem = results[i++]) ) { ++ if ( elem === results[ i ] ) { ++ j = duplicates.push( i ); ++ } ++ } ++ while ( j-- ) { ++ results.splice( duplicates[ j ], 1 ); ++ } ++ } ++ ++ // Clear input after sorting to release objects ++ // See https://github.com/jquery/sizzle/pull/225 ++ sortInput = null; ++ ++ return results; ++}; ++ ++/** ++ * Utility function for retrieving the text value of an array of DOM nodes ++ * @param {Array|Element} elem ++ */ ++getText = Sizzle.getText = function( elem ) { ++ var node, ++ ret = "", ++ i = 0, ++ nodeType = elem.nodeType; ++ ++ if ( !nodeType ) { ++ // If no nodeType, this is expected to be an array ++ while ( (node = elem[i++]) ) { ++ // Do not traverse comment nodes ++ ret += getText( node ); ++ } ++ } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { ++ // Use textContent for elements ++ // innerText usage removed for consistency of new lines (jQuery #11153) ++ if ( typeof elem.textContent === "string" ) { ++ return elem.textContent; ++ } else { ++ // Traverse its children ++ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { ++ ret += getText( elem ); ++ } ++ } ++ } else if ( nodeType === 3 || nodeType === 4 ) { ++ return elem.nodeValue; ++ } ++ // Do not include comment or processing instruction nodes ++ ++ return ret; ++}; ++ ++Expr = Sizzle.selectors = { ++ ++ // Can be adjusted by the user ++ cacheLength: 50, ++ ++ createPseudo: markFunction, ++ ++ match: matchExpr, ++ ++ attrHandle: {}, ++ ++ find: {}, ++ ++ relative: { ++ ">": { dir: "parentNode", first: true }, ++ " ": { dir: "parentNode" }, ++ "+": { dir: "previousSibling", first: true }, ++ "~": { dir: "previousSibling" } ++ }, ++ ++ preFilter: { ++ "ATTR": function( match ) { ++ match[1] = match[1].replace( runescape, funescape ); ++ ++ // Move the given value to match[3] whether quoted or unquoted ++ match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); ++ ++ if ( match[2] === "~=" ) { ++ match[3] = " " + match[3] + " "; ++ } ++ ++ return match.slice( 0, 4 ); ++ }, ++ ++ "CHILD": function( match ) { ++ /* matches from matchExpr["CHILD"] ++ 1 type (only|nth|...) ++ 2 what (child|of-type) ++ 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) ++ 4 xn-component of xn+y argument ([+-]?\d*n|) ++ 5 sign of xn-component ++ 6 x of xn-component ++ 7 sign of y-component ++ 8 y of y-component ++ */ ++ match[1] = match[1].toLowerCase(); ++ ++ if ( match[1].slice( 0, 3 ) === "nth" ) { ++ // nth-* requires argument ++ if ( !match[3] ) { ++ Sizzle.error( match[0] ); ++ } ++ ++ // numeric x and y parameters for Expr.filter.CHILD ++ // remember that false/true cast respectively to 0/1 ++ match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); ++ match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); ++ ++ // other types prohibit arguments ++ } else if ( match[3] ) { ++ Sizzle.error( match[0] ); ++ } ++ ++ return match; ++ }, ++ ++ "PSEUDO": function( match ) { ++ var excess, ++ unquoted = !match[6] && match[2]; ++ ++ if ( matchExpr["CHILD"].test( match[0] ) ) { ++ return null; ++ } ++ ++ // Accept quoted arguments as-is ++ if ( match[3] ) { ++ match[2] = match[4] || match[5] || ""; ++ ++ // Strip excess characters from unquoted arguments ++ } else if ( unquoted && rpseudo.test( unquoted ) && ++ // Get excess from tokenize (recursively) ++ (excess = tokenize( unquoted, true )) && ++ // advance to the next closing parenthesis ++ (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { ++ ++ // excess is a negative index ++ match[0] = match[0].slice( 0, excess ); ++ match[2] = unquoted.slice( 0, excess ); ++ } ++ ++ // Return only captures needed by the pseudo filter method (type and argument) ++ return match.slice( 0, 3 ); ++ } ++ }, ++ ++ filter: { ++ ++ "TAG": function( nodeNameSelector ) { ++ var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); ++ return nodeNameSelector === "*" ? ++ function() { return true; } : ++ function( elem ) { ++ return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; ++ }; ++ }, ++ ++ "CLASS": function( className ) { ++ var pattern = classCache[ className + " " ]; ++ ++ return pattern || ++ (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && ++ classCache( className, function( elem ) { ++ return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); ++ }); ++ }, ++ ++ "ATTR": function( name, operator, check ) { ++ return function( elem ) { ++ var result = Sizzle.attr( elem, name ); ++ ++ if ( result == null ) { ++ return operator === "!="; ++ } ++ if ( !operator ) { ++ return true; ++ } ++ ++ result += ""; ++ ++ return operator === "=" ? result === check : ++ operator === "!=" ? result !== check : ++ operator === "^=" ? check && result.indexOf( check ) === 0 : ++ operator === "*=" ? check && result.indexOf( check ) > -1 : ++ operator === "$=" ? check && result.slice( -check.length ) === check : ++ operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : ++ operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : ++ false; ++ }; ++ }, ++ ++ "CHILD": function( type, what, argument, first, last ) { ++ var simple = type.slice( 0, 3 ) !== "nth", ++ forward = type.slice( -4 ) !== "last", ++ ofType = what === "of-type"; ++ ++ return first === 1 && last === 0 ? ++ ++ // Shortcut for :nth-*(n) ++ function( elem ) { ++ return !!elem.parentNode; ++ } : ++ ++ function( elem, context, xml ) { ++ var cache, uniqueCache, outerCache, node, nodeIndex, start, ++ dir = simple !== forward ? "nextSibling" : "previousSibling", ++ parent = elem.parentNode, ++ name = ofType && elem.nodeName.toLowerCase(), ++ useCache = !xml && !ofType, ++ diff = false; ++ ++ if ( parent ) { ++ ++ // :(first|last|only)-(child|of-type) ++ if ( simple ) { ++ while ( dir ) { ++ node = elem; ++ while ( (node = node[ dir ]) ) { ++ if ( ofType ? ++ node.nodeName.toLowerCase() === name : ++ node.nodeType === 1 ) { ++ ++ return false; ++ } ++ } ++ // Reverse direction for :only-* (if we haven't yet done so) ++ start = dir = type === "only" && !start && "nextSibling"; ++ } ++ return true; ++ } ++ ++ start = [ forward ? parent.firstChild : parent.lastChild ]; ++ ++ // non-xml :nth-child(...) stores cache data on `parent` ++ if ( forward && useCache ) { ++ ++ // Seek `elem` from a previously-cached index ++ ++ // ...in a gzip-friendly way ++ node = parent; ++ outerCache = node[ expando ] || (node[ expando ] = {}); ++ ++ // Support: IE <9 only ++ // Defend against cloned attroperties (jQuery gh-1709) ++ uniqueCache = outerCache[ node.uniqueID ] || ++ (outerCache[ node.uniqueID ] = {}); ++ ++ cache = uniqueCache[ type ] || []; ++ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; ++ diff = nodeIndex && cache[ 2 ]; ++ node = nodeIndex && parent.childNodes[ nodeIndex ]; ++ ++ while ( (node = ++nodeIndex && node && node[ dir ] || ++ ++ // Fallback to seeking `elem` from the start ++ (diff = nodeIndex = 0) || start.pop()) ) { ++ ++ // When found, cache indexes on `parent` and break ++ if ( node.nodeType === 1 && ++diff && node === elem ) { ++ uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; ++ break; ++ } ++ } ++ ++ } else { ++ // Use previously-cached element index if available ++ if ( useCache ) { ++ // ...in a gzip-friendly way ++ node = elem; ++ outerCache = node[ expando ] || (node[ expando ] = {}); ++ ++ // Support: IE <9 only ++ // Defend against cloned attroperties (jQuery gh-1709) ++ uniqueCache = outerCache[ node.uniqueID ] || ++ (outerCache[ node.uniqueID ] = {}); ++ ++ cache = uniqueCache[ type ] || []; ++ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; ++ diff = nodeIndex; ++ } ++ ++ // xml :nth-child(...) ++ // or :nth-last-child(...) or :nth(-last)?-of-type(...) ++ if ( diff === false ) { ++ // Use the same loop as above to seek `elem` from the start ++ while ( (node = ++nodeIndex && node && node[ dir ] || ++ (diff = nodeIndex = 0) || start.pop()) ) { ++ ++ if ( ( ofType ? ++ node.nodeName.toLowerCase() === name : ++ node.nodeType === 1 ) && ++ ++diff ) { ++ ++ // Cache the index of each encountered element ++ if ( useCache ) { ++ outerCache = node[ expando ] || (node[ expando ] = {}); ++ ++ // Support: IE <9 only ++ // Defend against cloned attroperties (jQuery gh-1709) ++ uniqueCache = outerCache[ node.uniqueID ] || ++ (outerCache[ node.uniqueID ] = {}); ++ ++ uniqueCache[ type ] = [ dirruns, diff ]; ++ } ++ ++ if ( node === elem ) { ++ break; ++ } ++ } ++ } ++ } ++ } ++ ++ // Incorporate the offset, then check against cycle size ++ diff -= last; ++ return diff === first || ( diff % first === 0 && diff / first >= 0 ); ++ } ++ }; ++ }, ++ ++ "PSEUDO": function( pseudo, argument ) { ++ // pseudo-class names are case-insensitive ++ // http://www.w3.org/TR/selectors/#pseudo-classes ++ // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters ++ // Remember that setFilters inherits from pseudos ++ var args, ++ fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || ++ Sizzle.error( "unsupported pseudo: " + pseudo ); ++ ++ // The user may use createPseudo to indicate that ++ // arguments are needed to create the filter function ++ // just as Sizzle does ++ if ( fn[ expando ] ) { ++ return fn( argument ); ++ } ++ ++ // But maintain support for old signatures ++ if ( fn.length > 1 ) { ++ args = [ pseudo, pseudo, "", argument ]; ++ return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? ++ markFunction(function( seed, matches ) { ++ var idx, ++ matched = fn( seed, argument ), ++ i = matched.length; ++ while ( i-- ) { ++ idx = indexOf( seed, matched[i] ); ++ seed[ idx ] = !( matches[ idx ] = matched[i] ); ++ } ++ }) : ++ function( elem ) { ++ return fn( elem, 0, args ); ++ }; ++ } ++ ++ return fn; ++ } ++ }, ++ ++ pseudos: { ++ // Potentially complex pseudos ++ "not": markFunction(function( selector ) { ++ // Trim the selector passed to compile ++ // to avoid treating leading and trailing ++ // spaces as combinators ++ var input = [], ++ results = [], ++ matcher = compile( selector.replace( rtrim, "$1" ) ); ++ ++ return matcher[ expando ] ? ++ markFunction(function( seed, matches, context, xml ) { ++ var elem, ++ unmatched = matcher( seed, null, xml, [] ), ++ i = seed.length; ++ ++ // Match elements unmatched by `matcher` ++ while ( i-- ) { ++ if ( (elem = unmatched[i]) ) { ++ seed[i] = !(matches[i] = elem); ++ } ++ } ++ }) : ++ function( elem, context, xml ) { ++ input[0] = elem; ++ matcher( input, null, xml, results ); ++ // Don't keep the element (issue #299) ++ input[0] = null; ++ return !results.pop(); ++ }; ++ }), ++ ++ "has": markFunction(function( selector ) { ++ return function( elem ) { ++ return Sizzle( selector, elem ).length > 0; ++ }; ++ }), ++ ++ "contains": markFunction(function( text ) { ++ text = text.replace( runescape, funescape ); ++ return function( elem ) { ++ return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; ++ }; ++ }), ++ ++ // "Whether an element is represented by a :lang() selector ++ // is based solely on the element's language value ++ // being equal to the identifier C, ++ // or beginning with the identifier C immediately followed by "-". ++ // The matching of C against the element's language value is performed case-insensitively. ++ // The identifier C does not have to be a valid language name." ++ // http://www.w3.org/TR/selectors/#lang-pseudo ++ "lang": markFunction( function( lang ) { ++ // lang value must be a valid identifier ++ if ( !ridentifier.test(lang || "") ) { ++ Sizzle.error( "unsupported lang: " + lang ); ++ } ++ lang = lang.replace( runescape, funescape ).toLowerCase(); ++ return function( elem ) { ++ var elemLang; ++ do { ++ if ( (elemLang = documentIsHTML ? ++ elem.lang : ++ elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { ++ ++ elemLang = elemLang.toLowerCase(); ++ return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; ++ } ++ } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); ++ return false; ++ }; ++ }), ++ ++ // Miscellaneous ++ "target": function( elem ) { ++ var hash = window.location && window.location.hash; ++ return hash && hash.slice( 1 ) === elem.id; ++ }, ++ ++ "root": function( elem ) { ++ return elem === docElem; ++ }, ++ ++ "focus": function( elem ) { ++ return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); ++ }, ++ ++ // Boolean properties ++ "enabled": function( elem ) { ++ return elem.disabled === false; ++ }, ++ ++ "disabled": function( elem ) { ++ return elem.disabled === true; ++ }, ++ ++ "checked": function( elem ) { ++ // In CSS3, :checked should return both checked and selected elements ++ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked ++ var nodeName = elem.nodeName.toLowerCase(); ++ return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); ++ }, ++ ++ "selected": function( elem ) { ++ // Accessing this property makes selected-by-default ++ // options in Safari work properly ++ if ( elem.parentNode ) { ++ elem.parentNode.selectedIndex; ++ } ++ ++ return elem.selected === true; ++ }, ++ ++ // Contents ++ "empty": function( elem ) { ++ // http://www.w3.org/TR/selectors/#empty-pseudo ++ // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), ++ // but not by others (comment: 8; processing instruction: 7; etc.) ++ // nodeType < 6 works because attributes (2) do not appear as children ++ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { ++ if ( elem.nodeType < 6 ) { ++ return false; ++ } ++ } ++ return true; ++ }, ++ ++ "parent": function( elem ) { ++ return !Expr.pseudos["empty"]( elem ); ++ }, ++ ++ // Element/input types ++ "header": function( elem ) { ++ return rheader.test( elem.nodeName ); ++ }, ++ ++ "input": function( elem ) { ++ return rinputs.test( elem.nodeName ); ++ }, ++ ++ "button": function( elem ) { ++ var name = elem.nodeName.toLowerCase(); ++ return name === "input" && elem.type === "button" || name === "button"; ++ }, ++ ++ "text": function( elem ) { ++ var attr; ++ return elem.nodeName.toLowerCase() === "input" && ++ elem.type === "text" && ++ ++ // Support: IE<8 ++ // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" ++ ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); ++ }, ++ ++ // Position-in-collection ++ "first": createPositionalPseudo(function() { ++ return [ 0 ]; ++ }), ++ ++ "last": createPositionalPseudo(function( matchIndexes, length ) { ++ return [ length - 1 ]; ++ }), ++ ++ "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { ++ return [ argument < 0 ? argument + length : argument ]; ++ }), ++ ++ "even": createPositionalPseudo(function( matchIndexes, length ) { ++ var i = 0; ++ for ( ; i < length; i += 2 ) { ++ matchIndexes.push( i ); ++ } ++ return matchIndexes; ++ }), ++ ++ "odd": createPositionalPseudo(function( matchIndexes, length ) { ++ var i = 1; ++ for ( ; i < length; i += 2 ) { ++ matchIndexes.push( i ); ++ } ++ return matchIndexes; ++ }), ++ ++ "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { ++ var i = argument < 0 ? argument + length : argument; ++ for ( ; --i >= 0; ) { ++ matchIndexes.push( i ); ++ } ++ return matchIndexes; ++ }), ++ ++ "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { ++ var i = argument < 0 ? argument + length : argument; ++ for ( ; ++i < length; ) { ++ matchIndexes.push( i ); ++ } ++ return matchIndexes; ++ }) ++ } ++}; ++ ++Expr.pseudos["nth"] = Expr.pseudos["eq"]; ++ ++// Add button/input type pseudos ++for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { ++ Expr.pseudos[ i ] = createInputPseudo( i ); ++} ++for ( i in { submit: true, reset: true } ) { ++ Expr.pseudos[ i ] = createButtonPseudo( i ); ++} ++ ++// Easy API for creating new setFilters ++function setFilters() {} ++setFilters.prototype = Expr.filters = Expr.pseudos; ++Expr.setFilters = new setFilters(); ++ ++tokenize = Sizzle.tokenize = function( selector, parseOnly ) { ++ var matched, match, tokens, type, ++ soFar, groups, preFilters, ++ cached = tokenCache[ selector + " " ]; ++ ++ if ( cached ) { ++ return parseOnly ? 0 : cached.slice( 0 ); ++ } ++ ++ soFar = selector; ++ groups = []; ++ preFilters = Expr.preFilter; ++ ++ while ( soFar ) { ++ ++ // Comma and first run ++ if ( !matched || (match = rcomma.exec( soFar )) ) { ++ if ( match ) { ++ // Don't consume trailing commas as valid ++ soFar = soFar.slice( match[0].length ) || soFar; ++ } ++ groups.push( (tokens = []) ); ++ } ++ ++ matched = false; ++ ++ // Combinators ++ if ( (match = rcombinators.exec( soFar )) ) { ++ matched = match.shift(); ++ tokens.push({ ++ value: matched, ++ // Cast descendant combinators to space ++ type: match[0].replace( rtrim, " " ) ++ }); ++ soFar = soFar.slice( matched.length ); ++ } ++ ++ // Filters ++ for ( type in Expr.filter ) { ++ if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || ++ (match = preFilters[ type ]( match ))) ) { ++ matched = match.shift(); ++ tokens.push({ ++ value: matched, ++ type: type, ++ matches: match ++ }); ++ soFar = soFar.slice( matched.length ); ++ } ++ } ++ ++ if ( !matched ) { ++ break; ++ } ++ } ++ ++ // Return the length of the invalid excess ++ // if we're just parsing ++ // Otherwise, throw an error or return tokens ++ return parseOnly ? ++ soFar.length : ++ soFar ? ++ Sizzle.error( selector ) : ++ // Cache the tokens ++ tokenCache( selector, groups ).slice( 0 ); ++}; ++ ++function toSelector( tokens ) { ++ var i = 0, ++ len = tokens.length, ++ selector = ""; ++ for ( ; i < len; i++ ) { ++ selector += tokens[i].value; ++ } ++ return selector; ++} ++ ++function addCombinator( matcher, combinator, base ) { ++ var dir = combinator.dir, ++ checkNonElements = base && dir === "parentNode", ++ doneName = done++; ++ ++ return combinator.first ? ++ // Check against closest ancestor/preceding element ++ function( elem, context, xml ) { ++ while ( (elem = elem[ dir ]) ) { ++ if ( elem.nodeType === 1 || checkNonElements ) { ++ return matcher( elem, context, xml ); ++ } ++ } ++ } : ++ ++ // Check against all ancestor/preceding elements ++ function( elem, context, xml ) { ++ var oldCache, uniqueCache, outerCache, ++ newCache = [ dirruns, doneName ]; ++ ++ // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching ++ if ( xml ) { ++ while ( (elem = elem[ dir ]) ) { ++ if ( elem.nodeType === 1 || checkNonElements ) { ++ if ( matcher( elem, context, xml ) ) { ++ return true; ++ } ++ } ++ } ++ } else { ++ while ( (elem = elem[ dir ]) ) { ++ if ( elem.nodeType === 1 || checkNonElements ) { ++ outerCache = elem[ expando ] || (elem[ expando ] = {}); ++ ++ // Support: IE <9 only ++ // Defend against cloned attroperties (jQuery gh-1709) ++ uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); ++ ++ if ( (oldCache = uniqueCache[ dir ]) && ++ oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { ++ ++ // Assign to newCache so results back-propagate to previous elements ++ return (newCache[ 2 ] = oldCache[ 2 ]); ++ } else { ++ // Reuse newcache so results back-propagate to previous elements ++ uniqueCache[ dir ] = newCache; ++ ++ // A match means we're done; a fail means we have to keep checking ++ if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { ++ return true; ++ } ++ } ++ } ++ } ++ } ++ }; ++} ++ ++function elementMatcher( matchers ) { ++ return matchers.length > 1 ? ++ function( elem, context, xml ) { ++ var i = matchers.length; ++ while ( i-- ) { ++ if ( !matchers[i]( elem, context, xml ) ) { ++ return false; ++ } ++ } ++ return true; ++ } : ++ matchers[0]; ++} ++ ++function multipleContexts( selector, contexts, results ) { ++ var i = 0, ++ len = contexts.length; ++ for ( ; i < len; i++ ) { ++ Sizzle( selector, contexts[i], results ); ++ } ++ return results; ++} ++ ++function condense( unmatched, map, filter, context, xml ) { ++ var elem, ++ newUnmatched = [], ++ i = 0, ++ len = unmatched.length, ++ mapped = map != null; ++ ++ for ( ; i < len; i++ ) { ++ if ( (elem = unmatched[i]) ) { ++ if ( !filter || filter( elem, context, xml ) ) { ++ newUnmatched.push( elem ); ++ if ( mapped ) { ++ map.push( i ); ++ } ++ } ++ } ++ } ++ ++ return newUnmatched; ++} ++ ++function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { ++ if ( postFilter && !postFilter[ expando ] ) { ++ postFilter = setMatcher( postFilter ); ++ } ++ if ( postFinder && !postFinder[ expando ] ) { ++ postFinder = setMatcher( postFinder, postSelector ); ++ } ++ return markFunction(function( seed, results, context, xml ) { ++ var temp, i, elem, ++ preMap = [], ++ postMap = [], ++ preexisting = results.length, ++ ++ // Get initial elements from seed or context ++ elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), ++ ++ // Prefilter to get matcher input, preserving a map for seed-results synchronization ++ matcherIn = preFilter && ( seed || !selector ) ? ++ condense( elems, preMap, preFilter, context, xml ) : ++ elems, ++ ++ matcherOut = matcher ? ++ // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, ++ postFinder || ( seed ? preFilter : preexisting || postFilter ) ? ++ ++ // ...intermediate processing is necessary ++ [] : ++ ++ // ...otherwise use results directly ++ results : ++ matcherIn; ++ ++ // Find primary matches ++ if ( matcher ) { ++ matcher( matcherIn, matcherOut, context, xml ); ++ } ++ ++ // Apply postFilter ++ if ( postFilter ) { ++ temp = condense( matcherOut, postMap ); ++ postFilter( temp, [], context, xml ); ++ ++ // Un-match failing elements by moving them back to matcherIn ++ i = temp.length; ++ while ( i-- ) { ++ if ( (elem = temp[i]) ) { ++ matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); ++ } ++ } ++ } ++ ++ if ( seed ) { ++ if ( postFinder || preFilter ) { ++ if ( postFinder ) { ++ // Get the final matcherOut by condensing this intermediate into postFinder contexts ++ temp = []; ++ i = matcherOut.length; ++ while ( i-- ) { ++ if ( (elem = matcherOut[i]) ) { ++ // Restore matcherIn since elem is not yet a final match ++ temp.push( (matcherIn[i] = elem) ); ++ } ++ } ++ postFinder( null, (matcherOut = []), temp, xml ); ++ } ++ ++ // Move matched elements from seed to results to keep them synchronized ++ i = matcherOut.length; ++ while ( i-- ) { ++ if ( (elem = matcherOut[i]) && ++ (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { ++ ++ seed[temp] = !(results[temp] = elem); ++ } ++ } ++ } ++ ++ // Add elements to results, through postFinder if defined ++ } else { ++ matcherOut = condense( ++ matcherOut === results ? ++ matcherOut.splice( preexisting, matcherOut.length ) : ++ matcherOut ++ ); ++ if ( postFinder ) { ++ postFinder( null, results, matcherOut, xml ); ++ } else { ++ push.apply( results, matcherOut ); ++ } ++ } ++ }); ++} ++ ++function matcherFromTokens( tokens ) { ++ var checkContext, matcher, j, ++ len = tokens.length, ++ leadingRelative = Expr.relative[ tokens[0].type ], ++ implicitRelative = leadingRelative || Expr.relative[" "], ++ i = leadingRelative ? 1 : 0, ++ ++ // The foundational matcher ensures that elements are reachable from top-level context(s) ++ matchContext = addCombinator( function( elem ) { ++ return elem === checkContext; ++ }, implicitRelative, true ), ++ matchAnyContext = addCombinator( function( elem ) { ++ return indexOf( checkContext, elem ) > -1; ++ }, implicitRelative, true ), ++ matchers = [ function( elem, context, xml ) { ++ var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( ++ (checkContext = context).nodeType ? ++ matchContext( elem, context, xml ) : ++ matchAnyContext( elem, context, xml ) ); ++ // Avoid hanging onto element (issue #299) ++ checkContext = null; ++ return ret; ++ } ]; ++ ++ for ( ; i < len; i++ ) { ++ if ( (matcher = Expr.relative[ tokens[i].type ]) ) { ++ matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; ++ } else { ++ matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); ++ ++ // Return special upon seeing a positional matcher ++ if ( matcher[ expando ] ) { ++ // Find the next relative operator (if any) for proper handling ++ j = ++i; ++ for ( ; j < len; j++ ) { ++ if ( Expr.relative[ tokens[j].type ] ) { ++ break; ++ } ++ } ++ return setMatcher( ++ i > 1 && elementMatcher( matchers ), ++ i > 1 && toSelector( ++ // If the preceding token was a descendant combinator, insert an implicit any-element `*` ++ tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) ++ ).replace( rtrim, "$1" ), ++ matcher, ++ i < j && matcherFromTokens( tokens.slice( i, j ) ), ++ j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), ++ j < len && toSelector( tokens ) ++ ); ++ } ++ matchers.push( matcher ); ++ } ++ } ++ ++ return elementMatcher( matchers ); ++} ++ ++function matcherFromGroupMatchers( elementMatchers, setMatchers ) { ++ var bySet = setMatchers.length > 0, ++ byElement = elementMatchers.length > 0, ++ superMatcher = function( seed, context, xml, results, outermost ) { ++ var elem, j, matcher, ++ matchedCount = 0, ++ i = "0", ++ unmatched = seed && [], ++ setMatched = [], ++ contextBackup = outermostContext, ++ // We must always have either seed elements or outermost context ++ elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), ++ // Use integer dirruns iff this is the outermost matcher ++ dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), ++ len = elems.length; ++ ++ if ( outermost ) { ++ outermostContext = context === document || context || outermost; ++ } ++ ++ // Add elements passing elementMatchers directly to results ++ // Support: IE<9, Safari ++ // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id ++ for ( ; i !== len && (elem = elems[i]) != null; i++ ) { ++ if ( byElement && elem ) { ++ j = 0; ++ if ( !context && elem.ownerDocument !== document ) { ++ setDocument( elem ); ++ xml = !documentIsHTML; ++ } ++ while ( (matcher = elementMatchers[j++]) ) { ++ if ( matcher( elem, context || document, xml) ) { ++ results.push( elem ); ++ break; ++ } ++ } ++ if ( outermost ) { ++ dirruns = dirrunsUnique; ++ } ++ } ++ ++ // Track unmatched elements for set filters ++ if ( bySet ) { ++ // They will have gone through all possible matchers ++ if ( (elem = !matcher && elem) ) { ++ matchedCount--; ++ } ++ ++ // Lengthen the array for every element, matched or not ++ if ( seed ) { ++ unmatched.push( elem ); ++ } ++ } ++ } ++ ++ // `i` is now the count of elements visited above, and adding it to `matchedCount` ++ // makes the latter nonnegative. ++ matchedCount += i; ++ ++ // Apply set filters to unmatched elements ++ // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` ++ // equals `i`), unless we didn't visit _any_ elements in the above loop because we have ++ // no element matchers and no seed. ++ // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that ++ // case, which will result in a "00" `matchedCount` that differs from `i` but is also ++ // numerically zero. ++ if ( bySet && i !== matchedCount ) { ++ j = 0; ++ while ( (matcher = setMatchers[j++]) ) { ++ matcher( unmatched, setMatched, context, xml ); ++ } ++ ++ if ( seed ) { ++ // Reintegrate element matches to eliminate the need for sorting ++ if ( matchedCount > 0 ) { ++ while ( i-- ) { ++ if ( !(unmatched[i] || setMatched[i]) ) { ++ setMatched[i] = pop.call( results ); ++ } ++ } ++ } ++ ++ // Discard index placeholder values to get only actual matches ++ setMatched = condense( setMatched ); ++ } ++ ++ // Add matches to results ++ push.apply( results, setMatched ); ++ ++ // Seedless set matches succeeding multiple successful matchers stipulate sorting ++ if ( outermost && !seed && setMatched.length > 0 && ++ ( matchedCount + setMatchers.length ) > 1 ) { ++ ++ Sizzle.uniqueSort( results ); ++ } ++ } ++ ++ // Override manipulation of globals by nested matchers ++ if ( outermost ) { ++ dirruns = dirrunsUnique; ++ outermostContext = contextBackup; ++ } ++ ++ return unmatched; ++ }; ++ ++ return bySet ? ++ markFunction( superMatcher ) : ++ superMatcher; ++} ++ ++compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { ++ var i, ++ setMatchers = [], ++ elementMatchers = [], ++ cached = compilerCache[ selector + " " ]; ++ ++ if ( !cached ) { ++ // Generate a function of recursive functions that can be used to check each element ++ if ( !match ) { ++ match = tokenize( selector ); ++ } ++ i = match.length; ++ while ( i-- ) { ++ cached = matcherFromTokens( match[i] ); ++ if ( cached[ expando ] ) { ++ setMatchers.push( cached ); ++ } else { ++ elementMatchers.push( cached ); ++ } ++ } ++ ++ // Cache the compiled function ++ cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); ++ ++ // Save selector and tokenization ++ cached.selector = selector; ++ } ++ return cached; ++}; ++ ++/** ++ * A low-level selection function that works with Sizzle's compiled ++ * selector functions ++ * @param {String|Function} selector A selector or a pre-compiled ++ * selector function built with Sizzle.compile ++ * @param {Element} context ++ * @param {Array} [results] ++ * @param {Array} [seed] A set of elements to match against ++ */ ++select = Sizzle.select = function( selector, context, results, seed ) { ++ var i, tokens, token, type, find, ++ compiled = typeof selector === "function" && selector, ++ match = !seed && tokenize( (selector = compiled.selector || selector) ); ++ ++ results = results || []; ++ ++ // Try to minimize operations if there is only one selector in the list and no seed ++ // (the latter of which guarantees us context) ++ if ( match.length === 1 ) { ++ ++ // Reduce context if the leading compound selector is an ID ++ tokens = match[0] = match[0].slice( 0 ); ++ if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && ++ support.getById && context.nodeType === 9 && documentIsHTML && ++ Expr.relative[ tokens[1].type ] ) { ++ ++ context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; ++ if ( !context ) { ++ return results; ++ ++ // Precompiled matchers will still verify ancestry, so step up a level ++ } else if ( compiled ) { ++ context = context.parentNode; ++ } ++ ++ selector = selector.slice( tokens.shift().value.length ); ++ } ++ ++ // Fetch a seed set for right-to-left matching ++ i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; ++ while ( i-- ) { ++ token = tokens[i]; ++ ++ // Abort if we hit a combinator ++ if ( Expr.relative[ (type = token.type) ] ) { ++ break; ++ } ++ if ( (find = Expr.find[ type ]) ) { ++ // Search, expanding context for leading sibling combinators ++ if ( (seed = find( ++ token.matches[0].replace( runescape, funescape ), ++ rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context ++ )) ) { ++ ++ // If seed is empty or no tokens remain, we can return early ++ tokens.splice( i, 1 ); ++ selector = seed.length && toSelector( tokens ); ++ if ( !selector ) { ++ push.apply( results, seed ); ++ return results; ++ } ++ ++ break; ++ } ++ } ++ } ++ } ++ ++ // Compile and execute a filtering function if one is not provided ++ // Provide `match` to avoid retokenization if we modified the selector above ++ ( compiled || compile( selector, match ) )( ++ seed, ++ context, ++ !documentIsHTML, ++ results, ++ !context || rsibling.test( selector ) && testContext( context.parentNode ) || context ++ ); ++ return results; ++}; ++ ++// One-time assignments ++ ++// Sort stability ++support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; ++ ++// Support: Chrome 14-35+ ++// Always assume duplicates if they aren't passed to the comparison function ++support.detectDuplicates = !!hasDuplicate; ++ ++// Initialize against the default document ++setDocument(); ++ ++// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) ++// Detached nodes confoundingly follow *each other* ++support.sortDetached = assert(function( div1 ) { ++ // Should return 1, but returns 4 (following) ++ return div1.compareDocumentPosition( document.createElement("div") ) & 1; ++}); ++ ++// Support: IE<8 ++// Prevent attribute/property "interpolation" ++// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx ++if ( !assert(function( div ) { ++ div.innerHTML = ""; ++ return div.firstChild.getAttribute("href") === "#" ; ++}) ) { ++ addHandle( "type|href|height|width", function( elem, name, isXML ) { ++ if ( !isXML ) { ++ return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); ++ } ++ }); ++} ++ ++// Support: IE<9 ++// Use defaultValue in place of getAttribute("value") ++if ( !support.attributes || !assert(function( div ) { ++ div.innerHTML = ""; ++ div.firstChild.setAttribute( "value", "" ); ++ return div.firstChild.getAttribute( "value" ) === ""; ++}) ) { ++ addHandle( "value", function( elem, name, isXML ) { ++ if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { ++ return elem.defaultValue; ++ } ++ }); ++} ++ ++// Support: IE<9 ++// Use getAttributeNode to fetch booleans when getAttribute lies ++if ( !assert(function( div ) { ++ return div.getAttribute("disabled") == null; ++}) ) { ++ addHandle( booleans, function( elem, name, isXML ) { ++ var val; ++ if ( !isXML ) { ++ return elem[ name ] === true ? name.toLowerCase() : ++ (val = elem.getAttributeNode( name )) && val.specified ? ++ val.value : ++ null; ++ } ++ }); ++} ++ ++return Sizzle; ++ ++})( window ); ++ ++ ++ ++jQuery.find = Sizzle; ++jQuery.expr = Sizzle.selectors; ++jQuery.expr[ ":" ] = jQuery.expr.pseudos; ++jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; ++jQuery.text = Sizzle.getText; ++jQuery.isXMLDoc = Sizzle.isXML; ++jQuery.contains = Sizzle.contains; ++ ++ ++ ++var dir = function( elem, dir, until ) { ++ var matched = [], ++ truncate = until !== undefined; ++ ++ while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { ++ if ( elem.nodeType === 1 ) { ++ if ( truncate && jQuery( elem ).is( until ) ) { ++ break; ++ } ++ matched.push( elem ); ++ } ++ } ++ return matched; ++}; ++ ++ ++var siblings = function( n, elem ) { ++ var matched = []; ++ ++ for ( ; n; n = n.nextSibling ) { ++ if ( n.nodeType === 1 && n !== elem ) { ++ matched.push( n ); ++ } ++ } ++ ++ return matched; ++}; ++ ++ ++var rneedsContext = jQuery.expr.match.needsContext; ++ ++var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ ); ++ ++ ++ ++var risSimple = /^.[^:#\[\.,]*$/; ++ ++// Implement the identical functionality for filter and not ++function winnow( elements, qualifier, not ) { ++ if ( jQuery.isFunction( qualifier ) ) { ++ return jQuery.grep( elements, function( elem, i ) { ++ /* jshint -W018 */ ++ return !!qualifier.call( elem, i, elem ) !== not; ++ } ); ++ ++ } ++ ++ if ( qualifier.nodeType ) { ++ return jQuery.grep( elements, function( elem ) { ++ return ( elem === qualifier ) !== not; ++ } ); ++ ++ } ++ ++ if ( typeof qualifier === "string" ) { ++ if ( risSimple.test( qualifier ) ) { ++ return jQuery.filter( qualifier, elements, not ); ++ } ++ ++ qualifier = jQuery.filter( qualifier, elements ); ++ } ++ ++ return jQuery.grep( elements, function( elem ) { ++ return ( jQuery.inArray( elem, qualifier ) > -1 ) !== not; ++ } ); ++} ++ ++jQuery.filter = function( expr, elems, not ) { ++ var elem = elems[ 0 ]; ++ ++ if ( not ) { ++ expr = ":not(" + expr + ")"; ++ } ++ ++ return elems.length === 1 && elem.nodeType === 1 ? ++ jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : ++ jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { ++ return elem.nodeType === 1; ++ } ) ); ++}; ++ ++jQuery.fn.extend( { ++ find: function( selector ) { ++ var i, ++ ret = [], ++ self = this, ++ len = self.length; ++ ++ if ( typeof selector !== "string" ) { ++ return this.pushStack( jQuery( selector ).filter( function() { ++ for ( i = 0; i < len; i++ ) { ++ if ( jQuery.contains( self[ i ], this ) ) { ++ return true; ++ } ++ } ++ } ) ); ++ } ++ ++ for ( i = 0; i < len; i++ ) { ++ jQuery.find( selector, self[ i ], ret ); ++ } ++ ++ // Needed because $( selector, context ) becomes $( context ).find( selector ) ++ ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); ++ ret.selector = this.selector ? this.selector + " " + selector : selector; ++ return ret; ++ }, ++ filter: function( selector ) { ++ return this.pushStack( winnow( this, selector || [], false ) ); ++ }, ++ not: function( selector ) { ++ return this.pushStack( winnow( this, selector || [], true ) ); ++ }, ++ is: function( selector ) { ++ return !!winnow( ++ this, ++ ++ // If this is a positional/relative selector, check membership in the returned set ++ // so $("p:first").is("p:last") won't return true for a doc with two "p". ++ typeof selector === "string" && rneedsContext.test( selector ) ? ++ jQuery( selector ) : ++ selector || [], ++ false ++ ).length; ++ } ++} ); ++ ++ ++// Initialize a jQuery object ++ ++ ++// A central reference to the root jQuery(document) ++var rootjQuery, ++ ++ // A simple way to check for HTML strings ++ // Prioritize #id over to avoid XSS via location.hash (#9521) ++ // Strict HTML recognition (#11290: must start with <) ++ rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, ++ ++ init = jQuery.fn.init = function( selector, context, root ) { ++ var match, elem; ++ ++ // HANDLE: $(""), $(null), $(undefined), $(false) ++ if ( !selector ) { ++ return this; ++ } ++ ++ // init accepts an alternate rootjQuery ++ // so migrate can support jQuery.sub (gh-2101) ++ root = root || rootjQuery; ++ ++ // Handle HTML strings ++ if ( typeof selector === "string" ) { ++ if ( selector.charAt( 0 ) === "<" && ++ selector.charAt( selector.length - 1 ) === ">" && ++ selector.length >= 3 ) { ++ ++ // Assume that strings that start and end with <> are HTML and skip the regex check ++ match = [ null, selector, null ]; ++ ++ } else { ++ match = rquickExpr.exec( selector ); ++ } ++ ++ // Match html or make sure no context is specified for #id ++ if ( match && ( match[ 1 ] || !context ) ) { ++ ++ // HANDLE: $(html) -> $(array) ++ if ( match[ 1 ] ) { ++ context = context instanceof jQuery ? context[ 0 ] : context; ++ ++ // scripts is true for back-compat ++ // Intentionally let the error be thrown if parseHTML is not present ++ jQuery.merge( this, jQuery.parseHTML( ++ match[ 1 ], ++ context && context.nodeType ? context.ownerDocument || context : document, ++ true ++ ) ); ++ ++ // HANDLE: $(html, props) ++ if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { ++ for ( match in context ) { ++ ++ // Properties of context are called as methods if possible ++ if ( jQuery.isFunction( this[ match ] ) ) { ++ this[ match ]( context[ match ] ); ++ ++ // ...and otherwise set as attributes ++ } else { ++ this.attr( match, context[ match ] ); ++ } ++ } ++ } ++ ++ return this; ++ ++ // HANDLE: $(#id) ++ } else { ++ elem = document.getElementById( match[ 2 ] ); ++ ++ // Check parentNode to catch when Blackberry 4.6 returns ++ // nodes that are no longer in the document #6963 ++ if ( elem && elem.parentNode ) { ++ ++ // Handle the case where IE and Opera return items ++ // by name instead of ID ++ if ( elem.id !== match[ 2 ] ) { ++ return rootjQuery.find( selector ); ++ } ++ ++ // Otherwise, we inject the element directly into the jQuery object ++ this.length = 1; ++ this[ 0 ] = elem; ++ } ++ ++ this.context = document; ++ this.selector = selector; ++ return this; ++ } ++ ++ // HANDLE: $(expr, $(...)) ++ } else if ( !context || context.jquery ) { ++ return ( context || root ).find( selector ); ++ ++ // HANDLE: $(expr, context) ++ // (which is just equivalent to: $(context).find(expr) ++ } else { ++ return this.constructor( context ).find( selector ); ++ } ++ ++ // HANDLE: $(DOMElement) ++ } else if ( selector.nodeType ) { ++ this.context = this[ 0 ] = selector; ++ this.length = 1; ++ return this; ++ ++ // HANDLE: $(function) ++ // Shortcut for document ready ++ } else if ( jQuery.isFunction( selector ) ) { ++ return typeof root.ready !== "undefined" ? ++ root.ready( selector ) : ++ ++ // Execute immediately if ready is not present ++ selector( jQuery ); ++ } ++ ++ if ( selector.selector !== undefined ) { ++ this.selector = selector.selector; ++ this.context = selector.context; ++ } ++ ++ return jQuery.makeArray( selector, this ); ++ }; ++ ++// Give the init function the jQuery prototype for later instantiation ++init.prototype = jQuery.fn; ++ ++// Initialize central reference ++rootjQuery = jQuery( document ); ++ ++ ++var rparentsprev = /^(?:parents|prev(?:Until|All))/, ++ ++ // methods guaranteed to produce a unique set when starting from a unique set ++ guaranteedUnique = { ++ children: true, ++ contents: true, ++ next: true, ++ prev: true ++ }; ++ ++jQuery.fn.extend( { ++ has: function( target ) { ++ var i, ++ targets = jQuery( target, this ), ++ len = targets.length; ++ ++ return this.filter( function() { ++ for ( i = 0; i < len; i++ ) { ++ if ( jQuery.contains( this, targets[ i ] ) ) { ++ return true; ++ } ++ } ++ } ); ++ }, ++ ++ closest: function( selectors, context ) { ++ var cur, ++ i = 0, ++ l = this.length, ++ matched = [], ++ pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? ++ jQuery( selectors, context || this.context ) : ++ 0; ++ ++ for ( ; i < l; i++ ) { ++ for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { ++ ++ // Always skip document fragments ++ if ( cur.nodeType < 11 && ( pos ? ++ pos.index( cur ) > -1 : ++ ++ // Don't pass non-elements to Sizzle ++ cur.nodeType === 1 && ++ jQuery.find.matchesSelector( cur, selectors ) ) ) { ++ ++ matched.push( cur ); ++ break; ++ } ++ } ++ } ++ ++ return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); ++ }, ++ ++ // Determine the position of an element within ++ // the matched set of elements ++ index: function( elem ) { ++ ++ // No argument, return index in parent ++ if ( !elem ) { ++ return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; ++ } ++ ++ // index in selector ++ if ( typeof elem === "string" ) { ++ return jQuery.inArray( this[ 0 ], jQuery( elem ) ); ++ } ++ ++ // Locate the position of the desired element ++ return jQuery.inArray( ++ ++ // If it receives a jQuery object, the first element is used ++ elem.jquery ? elem[ 0 ] : elem, this ); ++ }, ++ ++ add: function( selector, context ) { ++ return this.pushStack( ++ jQuery.uniqueSort( ++ jQuery.merge( this.get(), jQuery( selector, context ) ) ++ ) ++ ); ++ }, ++ ++ addBack: function( selector ) { ++ return this.add( selector == null ? ++ this.prevObject : this.prevObject.filter( selector ) ++ ); ++ } ++} ); ++ ++function sibling( cur, dir ) { ++ do { ++ cur = cur[ dir ]; ++ } while ( cur && cur.nodeType !== 1 ); ++ ++ return cur; ++} ++ ++jQuery.each( { ++ parent: function( elem ) { ++ var parent = elem.parentNode; ++ return parent && parent.nodeType !== 11 ? parent : null; ++ }, ++ parents: function( elem ) { ++ return dir( elem, "parentNode" ); ++ }, ++ parentsUntil: function( elem, i, until ) { ++ return dir( elem, "parentNode", until ); ++ }, ++ next: function( elem ) { ++ return sibling( elem, "nextSibling" ); ++ }, ++ prev: function( elem ) { ++ return sibling( elem, "previousSibling" ); ++ }, ++ nextAll: function( elem ) { ++ return dir( elem, "nextSibling" ); ++ }, ++ prevAll: function( elem ) { ++ return dir( elem, "previousSibling" ); ++ }, ++ nextUntil: function( elem, i, until ) { ++ return dir( elem, "nextSibling", until ); ++ }, ++ prevUntil: function( elem, i, until ) { ++ return dir( elem, "previousSibling", until ); ++ }, ++ siblings: function( elem ) { ++ return siblings( ( elem.parentNode || {} ).firstChild, elem ); ++ }, ++ children: function( elem ) { ++ return siblings( elem.firstChild ); ++ }, ++ contents: function( elem ) { ++ return jQuery.nodeName( elem, "iframe" ) ? ++ elem.contentDocument || elem.contentWindow.document : ++ jQuery.merge( [], elem.childNodes ); ++ } ++}, function( name, fn ) { ++ jQuery.fn[ name ] = function( until, selector ) { ++ var ret = jQuery.map( this, fn, until ); ++ ++ if ( name.slice( -5 ) !== "Until" ) { ++ selector = until; ++ } ++ ++ if ( selector && typeof selector === "string" ) { ++ ret = jQuery.filter( selector, ret ); ++ } ++ ++ if ( this.length > 1 ) { ++ ++ // Remove duplicates ++ if ( !guaranteedUnique[ name ] ) { ++ ret = jQuery.uniqueSort( ret ); ++ } ++ ++ // Reverse order for parents* and prev-derivatives ++ if ( rparentsprev.test( name ) ) { ++ ret = ret.reverse(); ++ } ++ } ++ ++ return this.pushStack( ret ); ++ }; ++} ); ++var rnotwhite = ( /\S+/g ); ++ ++ ++ ++// Convert String-formatted options into Object-formatted ones ++function createOptions( options ) { ++ var object = {}; ++ jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { ++ object[ flag ] = true; ++ } ); ++ return object; ++} ++ ++/* ++ * Create a callback list using the following parameters: ++ * ++ * options: an optional list of space-separated options that will change how ++ * the callback list behaves or a more traditional option object ++ * ++ * By default a callback list will act like an event callback list and can be ++ * "fired" multiple times. ++ * ++ * Possible options: ++ * ++ * once: will ensure the callback list can only be fired once (like a Deferred) ++ * ++ * memory: will keep track of previous values and will call any callback added ++ * after the list has been fired right away with the latest "memorized" ++ * values (like a Deferred) ++ * ++ * unique: will ensure a callback can only be added once (no duplicate in the list) ++ * ++ * stopOnFalse: interrupt callings when a callback returns false ++ * ++ */ ++jQuery.Callbacks = function( options ) { ++ ++ // Convert options from String-formatted to Object-formatted if needed ++ // (we check in cache first) ++ options = typeof options === "string" ? ++ createOptions( options ) : ++ jQuery.extend( {}, options ); ++ ++ var // Flag to know if list is currently firing ++ firing, ++ ++ // Last fire value for non-forgettable lists ++ memory, ++ ++ // Flag to know if list was already fired ++ fired, ++ ++ // Flag to prevent firing ++ locked, ++ ++ // Actual callback list ++ list = [], ++ ++ // Queue of execution data for repeatable lists ++ queue = [], ++ ++ // Index of currently firing callback (modified by add/remove as needed) ++ firingIndex = -1, ++ ++ // Fire callbacks ++ fire = function() { ++ ++ // Enforce single-firing ++ locked = options.once; ++ ++ // Execute callbacks for all pending executions, ++ // respecting firingIndex overrides and runtime changes ++ fired = firing = true; ++ for ( ; queue.length; firingIndex = -1 ) { ++ memory = queue.shift(); ++ while ( ++firingIndex < list.length ) { ++ ++ // Run callback and check for early termination ++ if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && ++ options.stopOnFalse ) { ++ ++ // Jump to end and forget the data so .add doesn't re-fire ++ firingIndex = list.length; ++ memory = false; ++ } ++ } ++ } ++ ++ // Forget the data if we're done with it ++ if ( !options.memory ) { ++ memory = false; ++ } ++ ++ firing = false; ++ ++ // Clean up if we're done firing for good ++ if ( locked ) { ++ ++ // Keep an empty list if we have data for future add calls ++ if ( memory ) { ++ list = []; ++ ++ // Otherwise, this object is spent ++ } else { ++ list = ""; ++ } ++ } ++ }, ++ ++ // Actual Callbacks object ++ self = { ++ ++ // Add a callback or a collection of callbacks to the list ++ add: function() { ++ if ( list ) { ++ ++ // If we have memory from a past run, we should fire after adding ++ if ( memory && !firing ) { ++ firingIndex = list.length - 1; ++ queue.push( memory ); ++ } ++ ++ ( function add( args ) { ++ jQuery.each( args, function( _, arg ) { ++ if ( jQuery.isFunction( arg ) ) { ++ if ( !options.unique || !self.has( arg ) ) { ++ list.push( arg ); ++ } ++ } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) { ++ ++ // Inspect recursively ++ add( arg ); ++ } ++ } ); ++ } )( arguments ); ++ ++ if ( memory && !firing ) { ++ fire(); ++ } ++ } ++ return this; ++ }, ++ ++ // Remove a callback from the list ++ remove: function() { ++ jQuery.each( arguments, function( _, arg ) { ++ var index; ++ while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { ++ list.splice( index, 1 ); ++ ++ // Handle firing indexes ++ if ( index <= firingIndex ) { ++ firingIndex--; ++ } ++ } ++ } ); ++ return this; ++ }, ++ ++ // Check if a given callback is in the list. ++ // If no argument is given, return whether or not list has callbacks attached. ++ has: function( fn ) { ++ return fn ? ++ jQuery.inArray( fn, list ) > -1 : ++ list.length > 0; ++ }, ++ ++ // Remove all callbacks from the list ++ empty: function() { ++ if ( list ) { ++ list = []; ++ } ++ return this; ++ }, ++ ++ // Disable .fire and .add ++ // Abort any current/pending executions ++ // Clear all callbacks and values ++ disable: function() { ++ locked = queue = []; ++ list = memory = ""; ++ return this; ++ }, ++ disabled: function() { ++ return !list; ++ }, ++ ++ // Disable .fire ++ // Also disable .add unless we have memory (since it would have no effect) ++ // Abort any pending executions ++ lock: function() { ++ locked = true; ++ if ( !memory ) { ++ self.disable(); ++ } ++ return this; ++ }, ++ locked: function() { ++ return !!locked; ++ }, ++ ++ // Call all callbacks with the given context and arguments ++ fireWith: function( context, args ) { ++ if ( !locked ) { ++ args = args || []; ++ args = [ context, args.slice ? args.slice() : args ]; ++ queue.push( args ); ++ if ( !firing ) { ++ fire(); ++ } ++ } ++ return this; ++ }, ++ ++ // Call all the callbacks with the given arguments ++ fire: function() { ++ self.fireWith( this, arguments ); ++ return this; ++ }, ++ ++ // To know if the callbacks have already been called at least once ++ fired: function() { ++ return !!fired; ++ } ++ }; ++ ++ return self; ++}; ++ ++ ++jQuery.extend( { ++ ++ Deferred: function( func ) { ++ var tuples = [ ++ ++ // action, add listener, listener list, final state ++ [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ], ++ [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ], ++ [ "notify", "progress", jQuery.Callbacks( "memory" ) ] ++ ], ++ state = "pending", ++ promise = { ++ state: function() { ++ return state; ++ }, ++ always: function() { ++ deferred.done( arguments ).fail( arguments ); ++ return this; ++ }, ++ then: function( /* fnDone, fnFail, fnProgress */ ) { ++ var fns = arguments; ++ return jQuery.Deferred( function( newDefer ) { ++ jQuery.each( tuples, function( i, tuple ) { ++ var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; ++ ++ // deferred[ done | fail | progress ] for forwarding actions to newDefer ++ deferred[ tuple[ 1 ] ]( function() { ++ var returned = fn && fn.apply( this, arguments ); ++ if ( returned && jQuery.isFunction( returned.promise ) ) { ++ returned.promise() ++ .progress( newDefer.notify ) ++ .done( newDefer.resolve ) ++ .fail( newDefer.reject ); ++ } else { ++ newDefer[ tuple[ 0 ] + "With" ]( ++ this === promise ? newDefer.promise() : this, ++ fn ? [ returned ] : arguments ++ ); ++ } ++ } ); ++ } ); ++ fns = null; ++ } ).promise(); ++ }, ++ ++ // Get a promise for this deferred ++ // If obj is provided, the promise aspect is added to the object ++ promise: function( obj ) { ++ return obj != null ? jQuery.extend( obj, promise ) : promise; ++ } ++ }, ++ deferred = {}; ++ ++ // Keep pipe for back-compat ++ promise.pipe = promise.then; ++ ++ // Add list-specific methods ++ jQuery.each( tuples, function( i, tuple ) { ++ var list = tuple[ 2 ], ++ stateString = tuple[ 3 ]; ++ ++ // promise[ done | fail | progress ] = list.add ++ promise[ tuple[ 1 ] ] = list.add; ++ ++ // Handle state ++ if ( stateString ) { ++ list.add( function() { ++ ++ // state = [ resolved | rejected ] ++ state = stateString; ++ ++ // [ reject_list | resolve_list ].disable; progress_list.lock ++ }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); ++ } ++ ++ // deferred[ resolve | reject | notify ] ++ deferred[ tuple[ 0 ] ] = function() { ++ deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments ); ++ return this; ++ }; ++ deferred[ tuple[ 0 ] + "With" ] = list.fireWith; ++ } ); ++ ++ // Make the deferred a promise ++ promise.promise( deferred ); ++ ++ // Call given func if any ++ if ( func ) { ++ func.call( deferred, deferred ); ++ } ++ ++ // All done! ++ return deferred; ++ }, ++ ++ // Deferred helper ++ when: function( subordinate /* , ..., subordinateN */ ) { ++ var i = 0, ++ resolveValues = slice.call( arguments ), ++ length = resolveValues.length, ++ ++ // the count of uncompleted subordinates ++ remaining = length !== 1 || ++ ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, ++ ++ // the master Deferred. ++ // If resolveValues consist of only a single Deferred, just use that. ++ deferred = remaining === 1 ? subordinate : jQuery.Deferred(), ++ ++ // Update function for both resolve and progress values ++ updateFunc = function( i, contexts, values ) { ++ return function( value ) { ++ contexts[ i ] = this; ++ values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; ++ if ( values === progressValues ) { ++ deferred.notifyWith( contexts, values ); ++ ++ } else if ( !( --remaining ) ) { ++ deferred.resolveWith( contexts, values ); ++ } ++ }; ++ }, ++ ++ progressValues, progressContexts, resolveContexts; ++ ++ // add listeners to Deferred subordinates; treat others as resolved ++ if ( length > 1 ) { ++ progressValues = new Array( length ); ++ progressContexts = new Array( length ); ++ resolveContexts = new Array( length ); ++ for ( ; i < length; i++ ) { ++ if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { ++ resolveValues[ i ].promise() ++ .progress( updateFunc( i, progressContexts, progressValues ) ) ++ .done( updateFunc( i, resolveContexts, resolveValues ) ) ++ .fail( deferred.reject ); ++ } else { ++ --remaining; ++ } ++ } ++ } ++ ++ // if we're not waiting on anything, resolve the master ++ if ( !remaining ) { ++ deferred.resolveWith( resolveContexts, resolveValues ); ++ } ++ ++ return deferred.promise(); ++ } ++} ); ++ ++ ++// The deferred used on DOM ready ++var readyList; ++ ++jQuery.fn.ready = function( fn ) { ++ ++ // Add the callback ++ jQuery.ready.promise().done( fn ); ++ ++ return this; ++}; ++ ++jQuery.extend( { ++ ++ // Is the DOM ready to be used? Set to true once it occurs. ++ isReady: false, ++ ++ // A counter to track how many items to wait for before ++ // the ready event fires. See #6781 ++ readyWait: 1, ++ ++ // Hold (or release) the ready event ++ holdReady: function( hold ) { ++ if ( hold ) { ++ jQuery.readyWait++; ++ } else { ++ jQuery.ready( true ); ++ } ++ }, ++ ++ // Handle when the DOM is ready ++ ready: function( wait ) { ++ ++ // Abort if there are pending holds or we're already ready ++ if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { ++ return; ++ } ++ ++ // Remember that the DOM is ready ++ jQuery.isReady = true; ++ ++ // If a normal DOM Ready event fired, decrement, and wait if need be ++ if ( wait !== true && --jQuery.readyWait > 0 ) { ++ return; ++ } ++ ++ // If there are functions bound, to execute ++ readyList.resolveWith( document, [ jQuery ] ); ++ ++ // Trigger any bound ready events ++ if ( jQuery.fn.triggerHandler ) { ++ jQuery( document ).triggerHandler( "ready" ); ++ jQuery( document ).off( "ready" ); ++ } ++ } ++} ); ++ ++/** ++ * Clean-up method for dom ready events ++ */ ++function detach() { ++ if ( document.addEventListener ) { ++ document.removeEventListener( "DOMContentLoaded", completed ); ++ window.removeEventListener( "load", completed ); ++ ++ } else { ++ document.detachEvent( "onreadystatechange", completed ); ++ window.detachEvent( "onload", completed ); ++ } ++} ++ ++/** ++ * The ready event handler and self cleanup method ++ */ ++function completed() { ++ ++ // readyState === "complete" is good enough for us to call the dom ready in oldIE ++ if ( document.addEventListener || ++ window.event.type === "load" || ++ document.readyState === "complete" ) { ++ ++ detach(); ++ jQuery.ready(); ++ } ++} ++ ++jQuery.ready.promise = function( obj ) { ++ if ( !readyList ) { ++ ++ readyList = jQuery.Deferred(); ++ ++ // Catch cases where $(document).ready() is called ++ // after the browser event has already occurred. ++ // Support: IE6-10 ++ // Older IE sometimes signals "interactive" too soon ++ if ( document.readyState === "complete" || ++ ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { ++ ++ // Handle it asynchronously to allow scripts the opportunity to delay ready ++ window.setTimeout( jQuery.ready ); ++ ++ // Standards-based browsers support DOMContentLoaded ++ } else if ( document.addEventListener ) { ++ ++ // Use the handy event callback ++ document.addEventListener( "DOMContentLoaded", completed ); ++ ++ // A fallback to window.onload, that will always work ++ window.addEventListener( "load", completed ); ++ ++ // If IE event model is used ++ } else { ++ ++ // Ensure firing before onload, maybe late but safe also for iframes ++ document.attachEvent( "onreadystatechange", completed ); ++ ++ // A fallback to window.onload, that will always work ++ window.attachEvent( "onload", completed ); ++ ++ // If IE and not a frame ++ // continually check to see if the document is ready ++ var top = false; ++ ++ try { ++ top = window.frameElement == null && document.documentElement; ++ } catch ( e ) {} ++ ++ if ( top && top.doScroll ) { ++ ( function doScrollCheck() { ++ if ( !jQuery.isReady ) { ++ ++ try { ++ ++ // Use the trick by Diego Perini ++ // http://javascript.nwbox.com/IEContentLoaded/ ++ top.doScroll( "left" ); ++ } catch ( e ) { ++ return window.setTimeout( doScrollCheck, 50 ); ++ } ++ ++ // detach all dom ready events ++ detach(); ++ ++ // and execute any waiting functions ++ jQuery.ready(); ++ } ++ } )(); ++ } ++ } ++ } ++ return readyList.promise( obj ); ++}; ++ ++// Kick off the DOM ready check even if the user does not ++jQuery.ready.promise(); ++ ++ ++ ++ ++// Support: IE<9 ++// Iteration over object's inherited properties before its own ++var i; ++for ( i in jQuery( support ) ) { ++ break; ++} ++support.ownFirst = i === "0"; ++ ++// Note: most support tests are defined in their respective modules. ++// false until the test is run ++support.inlineBlockNeedsLayout = false; ++ ++// Execute ASAP in case we need to set body.style.zoom ++jQuery( function() { ++ ++ // Minified: var a,b,c,d ++ var val, div, body, container; ++ ++ body = document.getElementsByTagName( "body" )[ 0 ]; ++ if ( !body || !body.style ) { ++ ++ // Return for frameset docs that don't have a body ++ return; ++ } ++ ++ // Setup ++ div = document.createElement( "div" ); ++ container = document.createElement( "div" ); ++ container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; ++ body.appendChild( container ).appendChild( div ); ++ ++ if ( typeof div.style.zoom !== "undefined" ) { ++ ++ // Support: IE<8 ++ // Check if natively block-level elements act like inline-block ++ // elements when setting their display to 'inline' and giving ++ // them layout ++ div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1"; ++ ++ support.inlineBlockNeedsLayout = val = div.offsetWidth === 3; ++ if ( val ) { ++ ++ // Prevent IE 6 from affecting layout for positioned elements #11048 ++ // Prevent IE from shrinking the body in IE 7 mode #12869 ++ // Support: IE<8 ++ body.style.zoom = 1; ++ } ++ } ++ ++ body.removeChild( container ); ++} ); ++ ++ ++( function() { ++ var div = document.createElement( "div" ); ++ ++ // Support: IE<9 ++ support.deleteExpando = true; ++ try { ++ delete div.test; ++ } catch ( e ) { ++ support.deleteExpando = false; ++ } ++ ++ // Null elements to avoid leaks in IE. ++ div = null; ++} )(); ++var acceptData = function( elem ) { ++ var noData = jQuery.noData[ ( elem.nodeName + " " ).toLowerCase() ], ++ nodeType = +elem.nodeType || 1; ++ ++ // Do not set data on non-element DOM nodes because it will not be cleared (#8335). ++ return nodeType !== 1 && nodeType !== 9 ? ++ false : ++ ++ // Nodes accept data unless otherwise specified; rejection can be conditional ++ !noData || noData !== true && elem.getAttribute( "classid" ) === noData; ++}; ++ ++ ++ ++ ++var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, ++ rmultiDash = /([A-Z])/g; ++ ++function dataAttr( elem, key, data ) { ++ ++ // If nothing was found internally, try to fetch any ++ // data from the HTML5 data-* attribute ++ if ( data === undefined && elem.nodeType === 1 ) { ++ ++ var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); ++ ++ data = elem.getAttribute( name ); ++ ++ if ( typeof data === "string" ) { ++ try { ++ data = data === "true" ? true : ++ data === "false" ? false : ++ data === "null" ? null : ++ ++ // Only convert to a number if it doesn't change the string ++ +data + "" === data ? +data : ++ rbrace.test( data ) ? jQuery.parseJSON( data ) : ++ data; ++ } catch ( e ) {} ++ ++ // Make sure we set the data so it isn't changed later ++ jQuery.data( elem, key, data ); ++ ++ } else { ++ data = undefined; ++ } ++ } ++ ++ return data; ++} ++ ++// checks a cache object for emptiness ++function isEmptyDataObject( obj ) { ++ var name; ++ for ( name in obj ) { ++ ++ // if the public data object is empty, the private is still empty ++ if ( name === "data" && jQuery.isEmptyObject( obj[ name ] ) ) { ++ continue; ++ } ++ if ( name !== "toJSON" ) { ++ return false; ++ } ++ } ++ ++ return true; ++} ++ ++function internalData( elem, name, data, pvt /* Internal Use Only */ ) { ++ if ( !acceptData( elem ) ) { ++ return; ++ } ++ ++ var ret, thisCache, ++ internalKey = jQuery.expando, ++ ++ // We have to handle DOM nodes and JS objects differently because IE6-7 ++ // can't GC object references properly across the DOM-JS boundary ++ isNode = elem.nodeType, ++ ++ // Only DOM nodes need the global jQuery cache; JS object data is ++ // attached directly to the object so GC can occur automatically ++ cache = isNode ? jQuery.cache : elem, ++ ++ // Only defining an ID for JS objects if its cache already exists allows ++ // the code to shortcut on the same path as a DOM node with no cache ++ id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; ++ ++ // Avoid doing any more work than we need to when trying to get data on an ++ // object that has no data at all ++ if ( ( !id || !cache[ id ] || ( !pvt && !cache[ id ].data ) ) && ++ data === undefined && typeof name === "string" ) { ++ return; ++ } ++ ++ if ( !id ) { ++ ++ // Only DOM nodes need a new unique ID for each element since their data ++ // ends up in the global cache ++ if ( isNode ) { ++ id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++; ++ } else { ++ id = internalKey; ++ } ++ } ++ ++ if ( !cache[ id ] ) { ++ ++ // Avoid exposing jQuery metadata on plain JS objects when the object ++ // is serialized using JSON.stringify ++ cache[ id ] = isNode ? {} : { toJSON: jQuery.noop }; ++ } ++ ++ // An object can be passed to jQuery.data instead of a key/value pair; this gets ++ // shallow copied over onto the existing cache ++ if ( typeof name === "object" || typeof name === "function" ) { ++ if ( pvt ) { ++ cache[ id ] = jQuery.extend( cache[ id ], name ); ++ } else { ++ cache[ id ].data = jQuery.extend( cache[ id ].data, name ); ++ } ++ } ++ ++ thisCache = cache[ id ]; ++ ++ // jQuery data() is stored in a separate object inside the object's internal data ++ // cache in order to avoid key collisions between internal data and user-defined ++ // data. ++ if ( !pvt ) { ++ if ( !thisCache.data ) { ++ thisCache.data = {}; ++ } ++ ++ thisCache = thisCache.data; ++ } ++ ++ if ( data !== undefined ) { ++ thisCache[ jQuery.camelCase( name ) ] = data; ++ } ++ ++ // Check for both converted-to-camel and non-converted data property names ++ // If a data property was specified ++ if ( typeof name === "string" ) { ++ ++ // First Try to find as-is property data ++ ret = thisCache[ name ]; ++ ++ // Test for null|undefined property data ++ if ( ret == null ) { ++ ++ // Try to find the camelCased property ++ ret = thisCache[ jQuery.camelCase( name ) ]; ++ } ++ } else { ++ ret = thisCache; ++ } ++ ++ return ret; ++} ++ ++function internalRemoveData( elem, name, pvt ) { ++ if ( !acceptData( elem ) ) { ++ return; ++ } ++ ++ var thisCache, i, ++ isNode = elem.nodeType, ++ ++ // See jQuery.data for more information ++ cache = isNode ? jQuery.cache : elem, ++ id = isNode ? elem[ jQuery.expando ] : jQuery.expando; ++ ++ // If there is already no cache entry for this object, there is no ++ // purpose in continuing ++ if ( !cache[ id ] ) { ++ return; ++ } ++ ++ if ( name ) { ++ ++ thisCache = pvt ? cache[ id ] : cache[ id ].data; ++ ++ if ( thisCache ) { ++ ++ // Support array or space separated string names for data keys ++ if ( !jQuery.isArray( name ) ) { ++ ++ // try the string as a key before any manipulation ++ if ( name in thisCache ) { ++ name = [ name ]; ++ } else { ++ ++ // split the camel cased version by spaces unless a key with the spaces exists ++ name = jQuery.camelCase( name ); ++ if ( name in thisCache ) { ++ name = [ name ]; ++ } else { ++ name = name.split( " " ); ++ } ++ } ++ } else { ++ ++ // If "name" is an array of keys... ++ // When data is initially created, via ("key", "val") signature, ++ // keys will be converted to camelCase. ++ // Since there is no way to tell _how_ a key was added, remove ++ // both plain key and camelCase key. #12786 ++ // This will only penalize the array argument path. ++ name = name.concat( jQuery.map( name, jQuery.camelCase ) ); ++ } ++ ++ i = name.length; ++ while ( i-- ) { ++ delete thisCache[ name[ i ] ]; ++ } ++ ++ // If there is no data left in the cache, we want to continue ++ // and let the cache object itself get destroyed ++ if ( pvt ? !isEmptyDataObject( thisCache ) : !jQuery.isEmptyObject( thisCache ) ) { ++ return; ++ } ++ } ++ } ++ ++ // See jQuery.data for more information ++ if ( !pvt ) { ++ delete cache[ id ].data; ++ ++ // Don't destroy the parent cache unless the internal data object ++ // had been the only thing left in it ++ if ( !isEmptyDataObject( cache[ id ] ) ) { ++ return; ++ } ++ } ++ ++ // Destroy the cache ++ if ( isNode ) { ++ jQuery.cleanData( [ elem ], true ); ++ ++ // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) ++ /* jshint eqeqeq: false */ ++ } else if ( support.deleteExpando || cache != cache.window ) { ++ /* jshint eqeqeq: true */ ++ delete cache[ id ]; ++ ++ // When all else fails, undefined ++ } else { ++ cache[ id ] = undefined; ++ } ++} ++ ++jQuery.extend( { ++ cache: {}, ++ ++ // The following elements (space-suffixed to avoid Object.prototype collisions) ++ // throw uncatchable exceptions if you attempt to set expando properties ++ noData: { ++ "applet ": true, ++ "embed ": true, ++ ++ // ...but Flash objects (which have this classid) *can* handle expandos ++ "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ++ }, ++ ++ hasData: function( elem ) { ++ elem = elem.nodeType ? jQuery.cache[ elem[ jQuery.expando ] ] : elem[ jQuery.expando ]; ++ return !!elem && !isEmptyDataObject( elem ); ++ }, ++ ++ data: function( elem, name, data ) { ++ return internalData( elem, name, data ); ++ }, ++ ++ removeData: function( elem, name ) { ++ return internalRemoveData( elem, name ); ++ }, ++ ++ // For internal use only. ++ _data: function( elem, name, data ) { ++ return internalData( elem, name, data, true ); ++ }, ++ ++ _removeData: function( elem, name ) { ++ return internalRemoveData( elem, name, true ); ++ } ++} ); ++ ++jQuery.fn.extend( { ++ data: function( key, value ) { ++ var i, name, data, ++ elem = this[ 0 ], ++ attrs = elem && elem.attributes; ++ ++ // Special expections of .data basically thwart jQuery.access, ++ // so implement the relevant behavior ourselves ++ ++ // Gets all values ++ if ( key === undefined ) { ++ if ( this.length ) { ++ data = jQuery.data( elem ); ++ ++ if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { ++ i = attrs.length; ++ while ( i-- ) { ++ ++ // Support: IE11+ ++ // The attrs elements can be null (#14894) ++ if ( attrs[ i ] ) { ++ name = attrs[ i ].name; ++ if ( name.indexOf( "data-" ) === 0 ) { ++ name = jQuery.camelCase( name.slice( 5 ) ); ++ dataAttr( elem, name, data[ name ] ); ++ } ++ } ++ } ++ jQuery._data( elem, "parsedAttrs", true ); ++ } ++ } ++ ++ return data; ++ } ++ ++ // Sets multiple values ++ if ( typeof key === "object" ) { ++ return this.each( function() { ++ jQuery.data( this, key ); ++ } ); ++ } ++ ++ return arguments.length > 1 ? ++ ++ // Sets one value ++ this.each( function() { ++ jQuery.data( this, key, value ); ++ } ) : ++ ++ // Gets one value ++ // Try to fetch any internally stored data first ++ elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined; ++ }, ++ ++ removeData: function( key ) { ++ return this.each( function() { ++ jQuery.removeData( this, key ); ++ } ); ++ } ++} ); ++ ++ ++jQuery.extend( { ++ queue: function( elem, type, data ) { ++ var queue; ++ ++ if ( elem ) { ++ type = ( type || "fx" ) + "queue"; ++ queue = jQuery._data( elem, type ); ++ ++ // Speed up dequeue by getting out quickly if this is just a lookup ++ if ( data ) { ++ if ( !queue || jQuery.isArray( data ) ) { ++ queue = jQuery._data( elem, type, jQuery.makeArray( data ) ); ++ } else { ++ queue.push( data ); ++ } ++ } ++ return queue || []; ++ } ++ }, ++ ++ dequeue: function( elem, type ) { ++ type = type || "fx"; ++ ++ var queue = jQuery.queue( elem, type ), ++ startLength = queue.length, ++ fn = queue.shift(), ++ hooks = jQuery._queueHooks( elem, type ), ++ next = function() { ++ jQuery.dequeue( elem, type ); ++ }; ++ ++ // If the fx queue is dequeued, always remove the progress sentinel ++ if ( fn === "inprogress" ) { ++ fn = queue.shift(); ++ startLength--; ++ } ++ ++ if ( fn ) { ++ ++ // Add a progress sentinel to prevent the fx queue from being ++ // automatically dequeued ++ if ( type === "fx" ) { ++ queue.unshift( "inprogress" ); ++ } ++ ++ // clear up the last queue stop function ++ delete hooks.stop; ++ fn.call( elem, next, hooks ); ++ } ++ ++ if ( !startLength && hooks ) { ++ hooks.empty.fire(); ++ } ++ }, ++ ++ // not intended for public consumption - generates a queueHooks object, ++ // or returns the current one ++ _queueHooks: function( elem, type ) { ++ var key = type + "queueHooks"; ++ return jQuery._data( elem, key ) || jQuery._data( elem, key, { ++ empty: jQuery.Callbacks( "once memory" ).add( function() { ++ jQuery._removeData( elem, type + "queue" ); ++ jQuery._removeData( elem, key ); ++ } ) ++ } ); ++ } ++} ); ++ ++jQuery.fn.extend( { ++ queue: function( type, data ) { ++ var setter = 2; ++ ++ if ( typeof type !== "string" ) { ++ data = type; ++ type = "fx"; ++ setter--; ++ } ++ ++ if ( arguments.length < setter ) { ++ return jQuery.queue( this[ 0 ], type ); ++ } ++ ++ return data === undefined ? ++ this : ++ this.each( function() { ++ var queue = jQuery.queue( this, type, data ); ++ ++ // ensure a hooks for this queue ++ jQuery._queueHooks( this, type ); ++ ++ if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { ++ jQuery.dequeue( this, type ); ++ } ++ } ); ++ }, ++ dequeue: function( type ) { ++ return this.each( function() { ++ jQuery.dequeue( this, type ); ++ } ); ++ }, ++ clearQueue: function( type ) { ++ return this.queue( type || "fx", [] ); ++ }, ++ ++ // Get a promise resolved when queues of a certain type ++ // are emptied (fx is the type by default) ++ promise: function( type, obj ) { ++ var tmp, ++ count = 1, ++ defer = jQuery.Deferred(), ++ elements = this, ++ i = this.length, ++ resolve = function() { ++ if ( !( --count ) ) { ++ defer.resolveWith( elements, [ elements ] ); ++ } ++ }; ++ ++ if ( typeof type !== "string" ) { ++ obj = type; ++ type = undefined; ++ } ++ type = type || "fx"; ++ ++ while ( i-- ) { ++ tmp = jQuery._data( elements[ i ], type + "queueHooks" ); ++ if ( tmp && tmp.empty ) { ++ count++; ++ tmp.empty.add( resolve ); ++ } ++ } ++ resolve(); ++ return defer.promise( obj ); ++ } ++} ); ++ ++ ++( function() { ++ var shrinkWrapBlocksVal; ++ ++ support.shrinkWrapBlocks = function() { ++ if ( shrinkWrapBlocksVal != null ) { ++ return shrinkWrapBlocksVal; ++ } ++ ++ // Will be changed later if needed. ++ shrinkWrapBlocksVal = false; ++ ++ // Minified: var b,c,d ++ var div, body, container; ++ ++ body = document.getElementsByTagName( "body" )[ 0 ]; ++ if ( !body || !body.style ) { ++ ++ // Test fired too early or in an unsupported environment, exit. ++ return; ++ } ++ ++ // Setup ++ div = document.createElement( "div" ); ++ container = document.createElement( "div" ); ++ container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; ++ body.appendChild( container ).appendChild( div ); ++ ++ // Support: IE6 ++ // Check if elements with layout shrink-wrap their children ++ if ( typeof div.style.zoom !== "undefined" ) { ++ ++ // Reset CSS: box-sizing; display; margin; border ++ div.style.cssText = ++ ++ // Support: Firefox<29, Android 2.3 ++ // Vendor-prefix box-sizing ++ "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + ++ "box-sizing:content-box;display:block;margin:0;border:0;" + ++ "padding:1px;width:1px;zoom:1"; ++ div.appendChild( document.createElement( "div" ) ).style.width = "5px"; ++ shrinkWrapBlocksVal = div.offsetWidth !== 3; ++ } ++ ++ body.removeChild( container ); ++ ++ return shrinkWrapBlocksVal; ++ }; ++ ++} )(); ++var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; ++ ++var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); ++ ++ ++var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; ++ ++var isHidden = function( elem, el ) { ++ ++ // isHidden might be called from jQuery#filter function; ++ // in that case, element will be second argument ++ elem = el || elem; ++ return jQuery.css( elem, "display" ) === "none" || ++ !jQuery.contains( elem.ownerDocument, elem ); ++ }; ++ ++ ++ ++function adjustCSS( elem, prop, valueParts, tween ) { ++ var adjusted, ++ scale = 1, ++ maxIterations = 20, ++ currentValue = tween ? ++ function() { return tween.cur(); } : ++ function() { return jQuery.css( elem, prop, "" ); }, ++ initial = currentValue(), ++ unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), ++ ++ // Starting value computation is required for potential unit mismatches ++ initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && ++ rcssNum.exec( jQuery.css( elem, prop ) ); ++ ++ if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { ++ ++ // Trust units reported by jQuery.css ++ unit = unit || initialInUnit[ 3 ]; ++ ++ // Make sure we update the tween properties later on ++ valueParts = valueParts || []; ++ ++ // Iteratively approximate from a nonzero starting point ++ initialInUnit = +initial || 1; ++ ++ do { ++ ++ // If previous iteration zeroed out, double until we get *something*. ++ // Use string for doubling so we don't accidentally see scale as unchanged below ++ scale = scale || ".5"; ++ ++ // Adjust and apply ++ initialInUnit = initialInUnit / scale; ++ jQuery.style( elem, prop, initialInUnit + unit ); ++ ++ // Update scale, tolerating zero or NaN from tween.cur() ++ // Break the loop if scale is unchanged or perfect, or if we've just had enough. ++ } while ( ++ scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations ++ ); ++ } ++ ++ if ( valueParts ) { ++ initialInUnit = +initialInUnit || +initial || 0; ++ ++ // Apply relative offset (+=/-=) if specified ++ adjusted = valueParts[ 1 ] ? ++ initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : ++ +valueParts[ 2 ]; ++ if ( tween ) { ++ tween.unit = unit; ++ tween.start = initialInUnit; ++ tween.end = adjusted; ++ } ++ } ++ return adjusted; ++} ++ ++ ++// Multifunctional method to get and set values of a collection ++// The value/s can optionally be executed if it's a function ++var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { ++ var i = 0, ++ length = elems.length, ++ bulk = key == null; ++ ++ // Sets many values ++ if ( jQuery.type( key ) === "object" ) { ++ chainable = true; ++ for ( i in key ) { ++ access( elems, fn, i, key[ i ], true, emptyGet, raw ); ++ } ++ ++ // Sets one value ++ } else if ( value !== undefined ) { ++ chainable = true; ++ ++ if ( !jQuery.isFunction( value ) ) { ++ raw = true; ++ } ++ ++ if ( bulk ) { ++ ++ // Bulk operations run against the entire set ++ if ( raw ) { ++ fn.call( elems, value ); ++ fn = null; ++ ++ // ...except when executing function values ++ } else { ++ bulk = fn; ++ fn = function( elem, key, value ) { ++ return bulk.call( jQuery( elem ), value ); ++ }; ++ } ++ } ++ ++ if ( fn ) { ++ for ( ; i < length; i++ ) { ++ fn( ++ elems[ i ], ++ key, ++ raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) ) ++ ); ++ } ++ } ++ } ++ ++ return chainable ? ++ elems : ++ ++ // Gets ++ bulk ? ++ fn.call( elems ) : ++ length ? fn( elems[ 0 ], key ) : emptyGet; ++}; ++var rcheckableType = ( /^(?:checkbox|radio)$/i ); ++ ++var rtagName = ( /<([\w:-]+)/ ); ++ ++var rscriptType = ( /^$|\/(?:java|ecma)script/i ); ++ ++var rleadingWhitespace = ( /^\s+/ ); ++ ++var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|" + ++ "details|dialog|figcaption|figure|footer|header|hgroup|main|" + ++ "mark|meter|nav|output|picture|progress|section|summary|template|time|video"; ++ ++ ++ ++function createSafeFragment( document ) { ++ var list = nodeNames.split( "|" ), ++ safeFrag = document.createDocumentFragment(); ++ ++ if ( safeFrag.createElement ) { ++ while ( list.length ) { ++ safeFrag.createElement( ++ list.pop() ++ ); ++ } ++ } ++ return safeFrag; ++} ++ ++ ++( function() { ++ var div = document.createElement( "div" ), ++ fragment = document.createDocumentFragment(), ++ input = document.createElement( "input" ); ++ ++ // Setup ++ div.innerHTML = "
a"; ++ ++ // IE strips leading whitespace when .innerHTML is used ++ support.leadingWhitespace = div.firstChild.nodeType === 3; ++ ++ // Make sure that tbody elements aren't automatically inserted ++ // IE will insert them into empty tables ++ support.tbody = !div.getElementsByTagName( "tbody" ).length; ++ ++ // Make sure that link elements get serialized correctly by innerHTML ++ // This requires a wrapper element in IE ++ support.htmlSerialize = !!div.getElementsByTagName( "link" ).length; ++ ++ // Makes sure cloning an html5 element does not cause problems ++ // Where outerHTML is undefined, this still works ++ support.html5Clone = ++ document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav>"; ++ ++ // Check if a disconnected checkbox will retain its checked ++ // value of true after appended to the DOM (IE6/7) ++ input.type = "checkbox"; ++ input.checked = true; ++ fragment.appendChild( input ); ++ support.appendChecked = input.checked; ++ ++ // Make sure textarea (and checkbox) defaultValue is properly cloned ++ // Support: IE6-IE11+ ++ div.innerHTML = ""; ++ support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; ++ ++ // #11217 - WebKit loses check when the name is after the checked attribute ++ fragment.appendChild( div ); ++ ++ // Support: Windows Web Apps (WWA) ++ // `name` and `type` must use .setAttribute for WWA (#14901) ++ input = document.createElement( "input" ); ++ input.setAttribute( "type", "radio" ); ++ input.setAttribute( "checked", "checked" ); ++ input.setAttribute( "name", "t" ); ++ ++ div.appendChild( input ); ++ ++ // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 ++ // old WebKit doesn't clone checked state correctly in fragments ++ support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; ++ ++ // Support: IE<9 ++ // Cloned elements keep attachEvent handlers, we use addEventListener on IE9+ ++ support.noCloneEvent = !!div.addEventListener; ++ ++ // Support: IE<9 ++ // Since attributes and properties are the same in IE, ++ // cleanData must set properties to undefined rather than use removeAttribute ++ div[ jQuery.expando ] = 1; ++ support.attributes = !div.getAttribute( jQuery.expando ); ++} )(); ++ ++ ++// We have to close these tags to support XHTML (#13200) ++var wrapMap = { ++ option: [ 1, "" ], ++ legend: [ 1, "
", "
" ], ++ area: [ 1, "", "" ], ++ ++ // Support: IE8 ++ param: [ 1, "", "" ], ++ thead: [ 1, "", "
" ], ++ tr: [ 2, "", "
" ], ++ col: [ 2, "", "
" ], ++ td: [ 3, "", "
" ], ++ ++ // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, ++ // unless wrapped in a div with non-breaking characters in front of it. ++ _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ] ++}; ++ ++// Support: IE8-IE9 ++wrapMap.optgroup = wrapMap.option; ++ ++wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; ++wrapMap.th = wrapMap.td; ++ ++ ++function getAll( context, tag ) { ++ var elems, elem, ++ i = 0, ++ found = typeof context.getElementsByTagName !== "undefined" ? ++ context.getElementsByTagName( tag || "*" ) : ++ typeof context.querySelectorAll !== "undefined" ? ++ context.querySelectorAll( tag || "*" ) : ++ undefined; ++ ++ if ( !found ) { ++ for ( found = [], elems = context.childNodes || context; ++ ( elem = elems[ i ] ) != null; ++ i++ ++ ) { ++ if ( !tag || jQuery.nodeName( elem, tag ) ) { ++ found.push( elem ); ++ } else { ++ jQuery.merge( found, getAll( elem, tag ) ); ++ } ++ } ++ } ++ ++ return tag === undefined || tag && jQuery.nodeName( context, tag ) ? ++ jQuery.merge( [ context ], found ) : ++ found; ++} ++ ++ ++// Mark scripts as having already been evaluated ++function setGlobalEval( elems, refElements ) { ++ var elem, ++ i = 0; ++ for ( ; ( elem = elems[ i ] ) != null; i++ ) { ++ jQuery._data( ++ elem, ++ "globalEval", ++ !refElements || jQuery._data( refElements[ i ], "globalEval" ) ++ ); ++ } ++} ++ ++ ++var rhtml = /<|&#?\w+;/, ++ rtbody = / from table fragments ++ if ( !support.tbody ) { ++ ++ // String was a , *may* have spurious ++ elem = tag === "table" && !rtbody.test( elem ) ? ++ tmp.firstChild : ++ ++ // String was a bare or ++ wrap[ 1 ] === "
" && !rtbody.test( elem ) ? ++ tmp : ++ 0; ++ ++ j = elem && elem.childNodes.length; ++ while ( j-- ) { ++ if ( jQuery.nodeName( ( tbody = elem.childNodes[ j ] ), "tbody" ) && ++ !tbody.childNodes.length ) { ++ ++ elem.removeChild( tbody ); ++ } ++ } ++ } ++ ++ jQuery.merge( nodes, tmp.childNodes ); ++ ++ // Fix #12392 for WebKit and IE > 9 ++ tmp.textContent = ""; ++ ++ // Fix #12392 for oldIE ++ while ( tmp.firstChild ) { ++ tmp.removeChild( tmp.firstChild ); ++ } ++ ++ // Remember the top-level container for proper cleanup ++ tmp = safe.lastChild; ++ } ++ } ++ } ++ ++ // Fix #11356: Clear elements from fragment ++ if ( tmp ) { ++ safe.removeChild( tmp ); ++ } ++ ++ // Reset defaultChecked for any radios and checkboxes ++ // about to be appended to the DOM in IE 6/7 (#8060) ++ if ( !support.appendChecked ) { ++ jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); ++ } ++ ++ i = 0; ++ while ( ( elem = nodes[ i++ ] ) ) { ++ ++ // Skip elements already in the context collection (trac-4087) ++ if ( selection && jQuery.inArray( elem, selection ) > -1 ) { ++ if ( ignored ) { ++ ignored.push( elem ); ++ } ++ ++ continue; ++ } ++ ++ contains = jQuery.contains( elem.ownerDocument, elem ); ++ ++ // Append to fragment ++ tmp = getAll( safe.appendChild( elem ), "script" ); ++ ++ // Preserve script evaluation history ++ if ( contains ) { ++ setGlobalEval( tmp ); ++ } ++ ++ // Capture executables ++ if ( scripts ) { ++ j = 0; ++ while ( ( elem = tmp[ j++ ] ) ) { ++ if ( rscriptType.test( elem.type || "" ) ) { ++ scripts.push( elem ); ++ } ++ } ++ } ++ } ++ ++ tmp = null; ++ ++ return safe; ++} ++ ++ ++( function() { ++ var i, eventName, ++ div = document.createElement( "div" ); ++ ++ // Support: IE<9 (lack submit/change bubble), Firefox (lack focus(in | out) events) ++ for ( i in { submit: true, change: true, focusin: true } ) { ++ eventName = "on" + i; ++ ++ if ( !( support[ i ] = eventName in window ) ) { ++ ++ // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) ++ div.setAttribute( eventName, "t" ); ++ support[ i ] = div.attributes[ eventName ].expando === false; ++ } ++ } ++ ++ // Null elements to avoid leaks in IE. ++ div = null; ++} )(); ++ ++ ++var rformElems = /^(?:input|select|textarea)$/i, ++ rkeyEvent = /^key/, ++ rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, ++ rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, ++ rtypenamespace = /^([^.]*)(?:\.(.+)|)/; ++ ++function returnTrue() { ++ return true; ++} ++ ++function returnFalse() { ++ return false; ++} ++ ++// Support: IE9 ++// See #13393 for more info ++function safeActiveElement() { ++ try { ++ return document.activeElement; ++ } catch ( err ) { } ++} ++ ++function on( elem, types, selector, data, fn, one ) { ++ var origFn, type; ++ ++ // Types can be a map of types/handlers ++ if ( typeof types === "object" ) { ++ ++ // ( types-Object, selector, data ) ++ if ( typeof selector !== "string" ) { ++ ++ // ( types-Object, data ) ++ data = data || selector; ++ selector = undefined; ++ } ++ for ( type in types ) { ++ on( elem, type, selector, data, types[ type ], one ); ++ } ++ return elem; ++ } ++ ++ if ( data == null && fn == null ) { ++ ++ // ( types, fn ) ++ fn = selector; ++ data = selector = undefined; ++ } else if ( fn == null ) { ++ if ( typeof selector === "string" ) { ++ ++ // ( types, selector, fn ) ++ fn = data; ++ data = undefined; ++ } else { ++ ++ // ( types, data, fn ) ++ fn = data; ++ data = selector; ++ selector = undefined; ++ } ++ } ++ if ( fn === false ) { ++ fn = returnFalse; ++ } else if ( !fn ) { ++ return elem; ++ } ++ ++ if ( one === 1 ) { ++ origFn = fn; ++ fn = function( event ) { ++ ++ // Can use an empty set, since event contains the info ++ jQuery().off( event ); ++ return origFn.apply( this, arguments ); ++ }; ++ ++ // Use same guid so caller can remove using origFn ++ fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); ++ } ++ return elem.each( function() { ++ jQuery.event.add( this, types, fn, data, selector ); ++ } ); ++} ++ ++/* ++ * Helper functions for managing events -- not part of the public interface. ++ * Props to Dean Edwards' addEvent library for many of the ideas. ++ */ ++jQuery.event = { ++ ++ global: {}, ++ ++ add: function( elem, types, handler, data, selector ) { ++ var tmp, events, t, handleObjIn, ++ special, eventHandle, handleObj, ++ handlers, type, namespaces, origType, ++ elemData = jQuery._data( elem ); ++ ++ // Don't attach events to noData or text/comment nodes (but allow plain objects) ++ if ( !elemData ) { ++ return; ++ } ++ ++ // Caller can pass in an object of custom data in lieu of the handler ++ if ( handler.handler ) { ++ handleObjIn = handler; ++ handler = handleObjIn.handler; ++ selector = handleObjIn.selector; ++ } ++ ++ // Make sure that the handler has a unique ID, used to find/remove it later ++ if ( !handler.guid ) { ++ handler.guid = jQuery.guid++; ++ } ++ ++ // Init the element's event structure and main handler, if this is the first ++ if ( !( events = elemData.events ) ) { ++ events = elemData.events = {}; ++ } ++ if ( !( eventHandle = elemData.handle ) ) { ++ eventHandle = elemData.handle = function( e ) { ++ ++ // Discard the second event of a jQuery.event.trigger() and ++ // when an event is called after a page has unloaded ++ return typeof jQuery !== "undefined" && ++ ( !e || jQuery.event.triggered !== e.type ) ? ++ jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : ++ undefined; ++ }; ++ ++ // Add elem as a property of the handle fn to prevent a memory leak ++ // with IE non-native events ++ eventHandle.elem = elem; ++ } ++ ++ // Handle multiple events separated by a space ++ types = ( types || "" ).match( rnotwhite ) || [ "" ]; ++ t = types.length; ++ while ( t-- ) { ++ tmp = rtypenamespace.exec( types[ t ] ) || []; ++ type = origType = tmp[ 1 ]; ++ namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); ++ ++ // There *must* be a type, no attaching namespace-only handlers ++ if ( !type ) { ++ continue; ++ } ++ ++ // If event changes its type, use the special event handlers for the changed type ++ special = jQuery.event.special[ type ] || {}; ++ ++ // If selector defined, determine special event api type, otherwise given type ++ type = ( selector ? special.delegateType : special.bindType ) || type; ++ ++ // Update special based on newly reset type ++ special = jQuery.event.special[ type ] || {}; ++ ++ // handleObj is passed to all event handlers ++ handleObj = jQuery.extend( { ++ type: type, ++ origType: origType, ++ data: data, ++ handler: handler, ++ guid: handler.guid, ++ selector: selector, ++ needsContext: selector && jQuery.expr.match.needsContext.test( selector ), ++ namespace: namespaces.join( "." ) ++ }, handleObjIn ); ++ ++ // Init the event handler queue if we're the first ++ if ( !( handlers = events[ type ] ) ) { ++ handlers = events[ type ] = []; ++ handlers.delegateCount = 0; ++ ++ // Only use addEventListener/attachEvent if the special events handler returns false ++ if ( !special.setup || ++ special.setup.call( elem, data, namespaces, eventHandle ) === false ) { ++ ++ // Bind the global event handler to the element ++ if ( elem.addEventListener ) { ++ elem.addEventListener( type, eventHandle, false ); ++ ++ } else if ( elem.attachEvent ) { ++ elem.attachEvent( "on" + type, eventHandle ); ++ } ++ } ++ } ++ ++ if ( special.add ) { ++ special.add.call( elem, handleObj ); ++ ++ if ( !handleObj.handler.guid ) { ++ handleObj.handler.guid = handler.guid; ++ } ++ } ++ ++ // Add to the element's handler list, delegates in front ++ if ( selector ) { ++ handlers.splice( handlers.delegateCount++, 0, handleObj ); ++ } else { ++ handlers.push( handleObj ); ++ } ++ ++ // Keep track of which events have ever been used, for event optimization ++ jQuery.event.global[ type ] = true; ++ } ++ ++ // Nullify elem to prevent memory leaks in IE ++ elem = null; ++ }, ++ ++ // Detach an event or set of events from an element ++ remove: function( elem, types, handler, selector, mappedTypes ) { ++ var j, handleObj, tmp, ++ origCount, t, events, ++ special, handlers, type, ++ namespaces, origType, ++ elemData = jQuery.hasData( elem ) && jQuery._data( elem ); ++ ++ if ( !elemData || !( events = elemData.events ) ) { ++ return; ++ } ++ ++ // Once for each type.namespace in types; type may be omitted ++ types = ( types || "" ).match( rnotwhite ) || [ "" ]; ++ t = types.length; ++ while ( t-- ) { ++ tmp = rtypenamespace.exec( types[ t ] ) || []; ++ type = origType = tmp[ 1 ]; ++ namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); ++ ++ // Unbind all events (on this namespace, if provided) for the element ++ if ( !type ) { ++ for ( type in events ) { ++ jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); ++ } ++ continue; ++ } ++ ++ special = jQuery.event.special[ type ] || {}; ++ type = ( selector ? special.delegateType : special.bindType ) || type; ++ handlers = events[ type ] || []; ++ tmp = tmp[ 2 ] && ++ new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); ++ ++ // Remove matching events ++ origCount = j = handlers.length; ++ while ( j-- ) { ++ handleObj = handlers[ j ]; ++ ++ if ( ( mappedTypes || origType === handleObj.origType ) && ++ ( !handler || handler.guid === handleObj.guid ) && ++ ( !tmp || tmp.test( handleObj.namespace ) ) && ++ ( !selector || selector === handleObj.selector || ++ selector === "**" && handleObj.selector ) ) { ++ handlers.splice( j, 1 ); ++ ++ if ( handleObj.selector ) { ++ handlers.delegateCount--; ++ } ++ if ( special.remove ) { ++ special.remove.call( elem, handleObj ); ++ } ++ } ++ } ++ ++ // Remove generic event handler if we removed something and no more handlers exist ++ // (avoids potential for endless recursion during removal of special event handlers) ++ if ( origCount && !handlers.length ) { ++ if ( !special.teardown || ++ special.teardown.call( elem, namespaces, elemData.handle ) === false ) { ++ ++ jQuery.removeEvent( elem, type, elemData.handle ); ++ } ++ ++ delete events[ type ]; ++ } ++ } ++ ++ // Remove the expando if it's no longer used ++ if ( jQuery.isEmptyObject( events ) ) { ++ delete elemData.handle; ++ ++ // removeData also checks for emptiness and clears the expando if empty ++ // so use it instead of delete ++ jQuery._removeData( elem, "events" ); ++ } ++ }, ++ ++ trigger: function( event, data, elem, onlyHandlers ) { ++ var handle, ontype, cur, ++ bubbleType, special, tmp, i, ++ eventPath = [ elem || document ], ++ type = hasOwn.call( event, "type" ) ? event.type : event, ++ namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; ++ ++ cur = tmp = elem = elem || document; ++ ++ // Don't do events on text and comment nodes ++ if ( elem.nodeType === 3 || elem.nodeType === 8 ) { ++ return; ++ } ++ ++ // focus/blur morphs to focusin/out; ensure we're not firing them right now ++ if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { ++ return; ++ } ++ ++ if ( type.indexOf( "." ) > -1 ) { ++ ++ // Namespaced trigger; create a regexp to match event type in handle() ++ namespaces = type.split( "." ); ++ type = namespaces.shift(); ++ namespaces.sort(); ++ } ++ ontype = type.indexOf( ":" ) < 0 && "on" + type; ++ ++ // Caller can pass in a jQuery.Event object, Object, or just an event type string ++ event = event[ jQuery.expando ] ? ++ event : ++ new jQuery.Event( type, typeof event === "object" && event ); ++ ++ // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) ++ event.isTrigger = onlyHandlers ? 2 : 3; ++ event.namespace = namespaces.join( "." ); ++ event.rnamespace = event.namespace ? ++ new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : ++ null; ++ ++ // Clean up the event in case it is being reused ++ event.result = undefined; ++ if ( !event.target ) { ++ event.target = elem; ++ } ++ ++ // Clone any incoming data and prepend the event, creating the handler arg list ++ data = data == null ? ++ [ event ] : ++ jQuery.makeArray( data, [ event ] ); ++ ++ // Allow special events to draw outside the lines ++ special = jQuery.event.special[ type ] || {}; ++ if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { ++ return; ++ } ++ ++ // Determine event propagation path in advance, per W3C events spec (#9951) ++ // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) ++ if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { ++ ++ bubbleType = special.delegateType || type; ++ if ( !rfocusMorph.test( bubbleType + type ) ) { ++ cur = cur.parentNode; ++ } ++ for ( ; cur; cur = cur.parentNode ) { ++ eventPath.push( cur ); ++ tmp = cur; ++ } ++ ++ // Only add window if we got to document (e.g., not plain obj or detached DOM) ++ if ( tmp === ( elem.ownerDocument || document ) ) { ++ eventPath.push( tmp.defaultView || tmp.parentWindow || window ); ++ } ++ } ++ ++ // Fire handlers on the event path ++ i = 0; ++ while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { ++ ++ event.type = i > 1 ? ++ bubbleType : ++ special.bindType || type; ++ ++ // jQuery handler ++ handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && ++ jQuery._data( cur, "handle" ); ++ ++ if ( handle ) { ++ handle.apply( cur, data ); ++ } ++ ++ // Native handler ++ handle = ontype && cur[ ontype ]; ++ if ( handle && handle.apply && acceptData( cur ) ) { ++ event.result = handle.apply( cur, data ); ++ if ( event.result === false ) { ++ event.preventDefault(); ++ } ++ } ++ } ++ event.type = type; ++ ++ // If nobody prevented the default action, do it now ++ if ( !onlyHandlers && !event.isDefaultPrevented() ) { ++ ++ if ( ++ ( !special._default || ++ special._default.apply( eventPath.pop(), data ) === false ++ ) && acceptData( elem ) ++ ) { ++ ++ // Call a native DOM method on the target with the same name name as the event. ++ // Can't use an .isFunction() check here because IE6/7 fails that test. ++ // Don't do default actions on window, that's where global variables be (#6170) ++ if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { ++ ++ // Don't re-trigger an onFOO event when we call its FOO() method ++ tmp = elem[ ontype ]; ++ ++ if ( tmp ) { ++ elem[ ontype ] = null; ++ } ++ ++ // Prevent re-triggering of the same event, since we already bubbled it above ++ jQuery.event.triggered = type; ++ try { ++ elem[ type ](); ++ } catch ( e ) { ++ ++ // IE<9 dies on focus/blur to hidden element (#1486,#12518) ++ // only reproducible on winXP IE8 native, not IE9 in IE8 mode ++ } ++ jQuery.event.triggered = undefined; ++ ++ if ( tmp ) { ++ elem[ ontype ] = tmp; ++ } ++ } ++ } ++ } ++ ++ return event.result; ++ }, ++ ++ dispatch: function( event ) { ++ ++ // Make a writable jQuery.Event from the native event object ++ event = jQuery.event.fix( event ); ++ ++ var i, j, ret, matched, handleObj, ++ handlerQueue = [], ++ args = slice.call( arguments ), ++ handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], ++ special = jQuery.event.special[ event.type ] || {}; ++ ++ // Use the fix-ed jQuery.Event rather than the (read-only) native event ++ args[ 0 ] = event; ++ event.delegateTarget = this; ++ ++ // Call the preDispatch hook for the mapped type, and let it bail if desired ++ if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { ++ return; ++ } ++ ++ // Determine handlers ++ handlerQueue = jQuery.event.handlers.call( this, event, handlers ); ++ ++ // Run delegates first; they may want to stop propagation beneath us ++ i = 0; ++ while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { ++ event.currentTarget = matched.elem; ++ ++ j = 0; ++ while ( ( handleObj = matched.handlers[ j++ ] ) && ++ !event.isImmediatePropagationStopped() ) { ++ ++ // Triggered event must either 1) have no namespace, or 2) have namespace(s) ++ // a subset or equal to those in the bound event (both can have no namespace). ++ if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { ++ ++ event.handleObj = handleObj; ++ event.data = handleObj.data; ++ ++ ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || ++ handleObj.handler ).apply( matched.elem, args ); ++ ++ if ( ret !== undefined ) { ++ if ( ( event.result = ret ) === false ) { ++ event.preventDefault(); ++ event.stopPropagation(); ++ } ++ } ++ } ++ } ++ } ++ ++ // Call the postDispatch hook for the mapped type ++ if ( special.postDispatch ) { ++ special.postDispatch.call( this, event ); ++ } ++ ++ return event.result; ++ }, ++ ++ handlers: function( event, handlers ) { ++ var i, matches, sel, handleObj, ++ handlerQueue = [], ++ delegateCount = handlers.delegateCount, ++ cur = event.target; ++ ++ // Support (at least): Chrome, IE9 ++ // Find delegate handlers ++ // Black-hole SVG instance trees (#13180) ++ // ++ // Support: Firefox<=42+ ++ // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343) ++ if ( delegateCount && cur.nodeType && ++ ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) { ++ ++ /* jshint eqeqeq: false */ ++ for ( ; cur != this; cur = cur.parentNode || this ) { ++ /* jshint eqeqeq: true */ ++ ++ // Don't check non-elements (#13208) ++ // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) ++ if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) { ++ matches = []; ++ for ( i = 0; i < delegateCount; i++ ) { ++ handleObj = handlers[ i ]; ++ ++ // Don't conflict with Object.prototype properties (#13203) ++ sel = handleObj.selector + " "; ++ ++ if ( matches[ sel ] === undefined ) { ++ matches[ sel ] = handleObj.needsContext ? ++ jQuery( sel, this ).index( cur ) > -1 : ++ jQuery.find( sel, this, null, [ cur ] ).length; ++ } ++ if ( matches[ sel ] ) { ++ matches.push( handleObj ); ++ } ++ } ++ if ( matches.length ) { ++ handlerQueue.push( { elem: cur, handlers: matches } ); ++ } ++ } ++ } ++ } ++ ++ // Add the remaining (directly-bound) handlers ++ if ( delegateCount < handlers.length ) { ++ handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } ); ++ } ++ ++ return handlerQueue; ++ }, ++ ++ fix: function( event ) { ++ if ( event[ jQuery.expando ] ) { ++ return event; ++ } ++ ++ // Create a writable copy of the event object and normalize some properties ++ var i, prop, copy, ++ type = event.type, ++ originalEvent = event, ++ fixHook = this.fixHooks[ type ]; ++ ++ if ( !fixHook ) { ++ this.fixHooks[ type ] = fixHook = ++ rmouseEvent.test( type ) ? this.mouseHooks : ++ rkeyEvent.test( type ) ? this.keyHooks : ++ {}; ++ } ++ copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; ++ ++ event = new jQuery.Event( originalEvent ); ++ ++ i = copy.length; ++ while ( i-- ) { ++ prop = copy[ i ]; ++ event[ prop ] = originalEvent[ prop ]; ++ } ++ ++ // Support: IE<9 ++ // Fix target property (#1925) ++ if ( !event.target ) { ++ event.target = originalEvent.srcElement || document; ++ } ++ ++ // Support: Safari 6-8+ ++ // Target should not be a text node (#504, #13143) ++ if ( event.target.nodeType === 3 ) { ++ event.target = event.target.parentNode; ++ } ++ ++ // Support: IE<9 ++ // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) ++ event.metaKey = !!event.metaKey; ++ ++ return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; ++ }, ++ ++ // Includes some event props shared by KeyEvent and MouseEvent ++ props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " + ++ "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ), ++ ++ fixHooks: {}, ++ ++ keyHooks: { ++ props: "char charCode key keyCode".split( " " ), ++ filter: function( event, original ) { ++ ++ // Add which for key events ++ if ( event.which == null ) { ++ event.which = original.charCode != null ? original.charCode : original.keyCode; ++ } ++ ++ return event; ++ } ++ }, ++ ++ mouseHooks: { ++ props: ( "button buttons clientX clientY fromElement offsetX offsetY " + ++ "pageX pageY screenX screenY toElement" ).split( " " ), ++ filter: function( event, original ) { ++ var body, eventDoc, doc, ++ button = original.button, ++ fromElement = original.fromElement; ++ ++ // Calculate pageX/Y if missing and clientX/Y available ++ if ( event.pageX == null && original.clientX != null ) { ++ eventDoc = event.target.ownerDocument || document; ++ doc = eventDoc.documentElement; ++ body = eventDoc.body; ++ ++ event.pageX = original.clientX + ++ ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ++ ( doc && doc.clientLeft || body && body.clientLeft || 0 ); ++ event.pageY = original.clientY + ++ ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ++ ( doc && doc.clientTop || body && body.clientTop || 0 ); ++ } ++ ++ // Add relatedTarget, if necessary ++ if ( !event.relatedTarget && fromElement ) { ++ event.relatedTarget = fromElement === event.target ? ++ original.toElement : ++ fromElement; ++ } ++ ++ // Add which for click: 1 === left; 2 === middle; 3 === right ++ // Note: button is not normalized, so don't use it ++ if ( !event.which && button !== undefined ) { ++ event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); ++ } ++ ++ return event; ++ } ++ }, ++ ++ special: { ++ load: { ++ ++ // Prevent triggered image.load events from bubbling to window.load ++ noBubble: true ++ }, ++ focus: { ++ ++ // Fire native event if possible so blur/focus sequence is correct ++ trigger: function() { ++ if ( this !== safeActiveElement() && this.focus ) { ++ try { ++ this.focus(); ++ return false; ++ } catch ( e ) { ++ ++ // Support: IE<9 ++ // If we error on focus to hidden element (#1486, #12518), ++ // let .trigger() run the handlers ++ } ++ } ++ }, ++ delegateType: "focusin" ++ }, ++ blur: { ++ trigger: function() { ++ if ( this === safeActiveElement() && this.blur ) { ++ this.blur(); ++ return false; ++ } ++ }, ++ delegateType: "focusout" ++ }, ++ click: { ++ ++ // For checkbox, fire native event so checked state will be right ++ trigger: function() { ++ if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { ++ this.click(); ++ return false; ++ } ++ }, ++ ++ // For cross-browser consistency, don't fire native .click() on links ++ _default: function( event ) { ++ return jQuery.nodeName( event.target, "a" ); ++ } ++ }, ++ ++ beforeunload: { ++ postDispatch: function( event ) { ++ ++ // Support: Firefox 20+ ++ // Firefox doesn't alert if the returnValue field is not set. ++ if ( event.result !== undefined && event.originalEvent ) { ++ event.originalEvent.returnValue = event.result; ++ } ++ } ++ } ++ }, ++ ++ // Piggyback on a donor event to simulate a different one ++ simulate: function( type, elem, event ) { ++ var e = jQuery.extend( ++ new jQuery.Event(), ++ event, ++ { ++ type: type, ++ isSimulated: true ++ ++ // Previously, `originalEvent: {}` was set here, so stopPropagation call ++ // would not be triggered on donor event, since in our own ++ // jQuery.event.stopPropagation function we had a check for existence of ++ // originalEvent.stopPropagation method, so, consequently it would be a noop. ++ // ++ // Guard for simulated events was moved to jQuery.event.stopPropagation function ++ // since `originalEvent` should point to the original event for the ++ // constancy with other events and for more focused logic ++ } ++ ); ++ ++ jQuery.event.trigger( e, null, elem ); ++ ++ if ( e.isDefaultPrevented() ) { ++ event.preventDefault(); ++ } ++ } ++}; ++ ++jQuery.removeEvent = document.removeEventListener ? ++ function( elem, type, handle ) { ++ ++ // This "if" is needed for plain objects ++ if ( elem.removeEventListener ) { ++ elem.removeEventListener( type, handle ); ++ } ++ } : ++ function( elem, type, handle ) { ++ var name = "on" + type; ++ ++ if ( elem.detachEvent ) { ++ ++ // #8545, #7054, preventing memory leaks for custom events in IE6-8 ++ // detachEvent needed property on element, by name of that event, ++ // to properly expose it to GC ++ if ( typeof elem[ name ] === "undefined" ) { ++ elem[ name ] = null; ++ } ++ ++ elem.detachEvent( name, handle ); ++ } ++ }; ++ ++jQuery.Event = function( src, props ) { ++ ++ // Allow instantiation without the 'new' keyword ++ if ( !( this instanceof jQuery.Event ) ) { ++ return new jQuery.Event( src, props ); ++ } ++ ++ // Event object ++ if ( src && src.type ) { ++ this.originalEvent = src; ++ this.type = src.type; ++ ++ // Events bubbling up the document may have been marked as prevented ++ // by a handler lower down the tree; reflect the correct value. ++ this.isDefaultPrevented = src.defaultPrevented || ++ src.defaultPrevented === undefined && ++ ++ // Support: IE < 9, Android < 4.0 ++ src.returnValue === false ? ++ returnTrue : ++ returnFalse; ++ ++ // Event type ++ } else { ++ this.type = src; ++ } ++ ++ // Put explicitly provided properties onto the event object ++ if ( props ) { ++ jQuery.extend( this, props ); ++ } ++ ++ // Create a timestamp if incoming event doesn't have one ++ this.timeStamp = src && src.timeStamp || jQuery.now(); ++ ++ // Mark it as fixed ++ this[ jQuery.expando ] = true; ++}; ++ ++// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding ++// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html ++jQuery.Event.prototype = { ++ constructor: jQuery.Event, ++ isDefaultPrevented: returnFalse, ++ isPropagationStopped: returnFalse, ++ isImmediatePropagationStopped: returnFalse, ++ ++ preventDefault: function() { ++ var e = this.originalEvent; ++ ++ this.isDefaultPrevented = returnTrue; ++ if ( !e ) { ++ return; ++ } ++ ++ // If preventDefault exists, run it on the original event ++ if ( e.preventDefault ) { ++ e.preventDefault(); ++ ++ // Support: IE ++ // Otherwise set the returnValue property of the original event to false ++ } else { ++ e.returnValue = false; ++ } ++ }, ++ stopPropagation: function() { ++ var e = this.originalEvent; ++ ++ this.isPropagationStopped = returnTrue; ++ ++ if ( !e || this.isSimulated ) { ++ return; ++ } ++ ++ // If stopPropagation exists, run it on the original event ++ if ( e.stopPropagation ) { ++ e.stopPropagation(); ++ } ++ ++ // Support: IE ++ // Set the cancelBubble property of the original event to true ++ e.cancelBubble = true; ++ }, ++ stopImmediatePropagation: function() { ++ var e = this.originalEvent; ++ ++ this.isImmediatePropagationStopped = returnTrue; ++ ++ if ( e && e.stopImmediatePropagation ) { ++ e.stopImmediatePropagation(); ++ } ++ ++ this.stopPropagation(); ++ } ++}; ++ ++// Create mouseenter/leave events using mouseover/out and event-time checks ++// so that event delegation works in jQuery. ++// Do the same for pointerenter/pointerleave and pointerover/pointerout ++// ++// Support: Safari 7 only ++// Safari sends mouseenter too often; see: ++// https://code.google.com/p/chromium/issues/detail?id=470258 ++// for the description of the bug (it existed in older Chrome versions as well). ++jQuery.each( { ++ mouseenter: "mouseover", ++ mouseleave: "mouseout", ++ pointerenter: "pointerover", ++ pointerleave: "pointerout" ++}, function( orig, fix ) { ++ jQuery.event.special[ orig ] = { ++ delegateType: fix, ++ bindType: fix, ++ ++ handle: function( event ) { ++ var ret, ++ target = this, ++ related = event.relatedTarget, ++ handleObj = event.handleObj; ++ ++ // For mouseenter/leave call the handler if related is outside the target. ++ // NB: No relatedTarget if the mouse left/entered the browser window ++ if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { ++ event.type = handleObj.origType; ++ ret = handleObj.handler.apply( this, arguments ); ++ event.type = fix; ++ } ++ return ret; ++ } ++ }; ++} ); ++ ++// IE submit delegation ++if ( !support.submit ) { ++ ++ jQuery.event.special.submit = { ++ setup: function() { ++ ++ // Only need this for delegated form submit events ++ if ( jQuery.nodeName( this, "form" ) ) { ++ return false; ++ } ++ ++ // Lazy-add a submit handler when a descendant form may potentially be submitted ++ jQuery.event.add( this, "click._submit keypress._submit", function( e ) { ++ ++ // Node name check avoids a VML-related crash in IE (#9807) ++ var elem = e.target, ++ form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? ++ ++ // Support: IE <=8 ++ // We use jQuery.prop instead of elem.form ++ // to allow fixing the IE8 delegated submit issue (gh-2332) ++ // by 3rd party polyfills/workarounds. ++ jQuery.prop( elem, "form" ) : ++ undefined; ++ ++ if ( form && !jQuery._data( form, "submit" ) ) { ++ jQuery.event.add( form, "submit._submit", function( event ) { ++ event._submitBubble = true; ++ } ); ++ jQuery._data( form, "submit", true ); ++ } ++ } ); ++ ++ // return undefined since we don't need an event listener ++ }, ++ ++ postDispatch: function( event ) { ++ ++ // If form was submitted by the user, bubble the event up the tree ++ if ( event._submitBubble ) { ++ delete event._submitBubble; ++ if ( this.parentNode && !event.isTrigger ) { ++ jQuery.event.simulate( "submit", this.parentNode, event ); ++ } ++ } ++ }, ++ ++ teardown: function() { ++ ++ // Only need this for delegated form submit events ++ if ( jQuery.nodeName( this, "form" ) ) { ++ return false; ++ } ++ ++ // Remove delegated handlers; cleanData eventually reaps submit handlers attached above ++ jQuery.event.remove( this, "._submit" ); ++ } ++ }; ++} ++ ++// IE change delegation and checkbox/radio fix ++if ( !support.change ) { ++ ++ jQuery.event.special.change = { ++ ++ setup: function() { ++ ++ if ( rformElems.test( this.nodeName ) ) { ++ ++ // IE doesn't fire change on a check/radio until blur; trigger it on click ++ // after a propertychange. Eat the blur-change in special.change.handle. ++ // This still fires onchange a second time for check/radio after blur. ++ if ( this.type === "checkbox" || this.type === "radio" ) { ++ jQuery.event.add( this, "propertychange._change", function( event ) { ++ if ( event.originalEvent.propertyName === "checked" ) { ++ this._justChanged = true; ++ } ++ } ); ++ jQuery.event.add( this, "click._change", function( event ) { ++ if ( this._justChanged && !event.isTrigger ) { ++ this._justChanged = false; ++ } ++ ++ // Allow triggered, simulated change events (#11500) ++ jQuery.event.simulate( "change", this, event ); ++ } ); ++ } ++ return false; ++ } ++ ++ // Delegated event; lazy-add a change handler on descendant inputs ++ jQuery.event.add( this, "beforeactivate._change", function( e ) { ++ var elem = e.target; ++ ++ if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "change" ) ) { ++ jQuery.event.add( elem, "change._change", function( event ) { ++ if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { ++ jQuery.event.simulate( "change", this.parentNode, event ); ++ } ++ } ); ++ jQuery._data( elem, "change", true ); ++ } ++ } ); ++ }, ++ ++ handle: function( event ) { ++ var elem = event.target; ++ ++ // Swallow native change events from checkbox/radio, we already triggered them above ++ if ( this !== elem || event.isSimulated || event.isTrigger || ++ ( elem.type !== "radio" && elem.type !== "checkbox" ) ) { ++ ++ return event.handleObj.handler.apply( this, arguments ); ++ } ++ }, ++ ++ teardown: function() { ++ jQuery.event.remove( this, "._change" ); ++ ++ return !rformElems.test( this.nodeName ); ++ } ++ }; ++} ++ ++// Support: Firefox ++// Firefox doesn't have focus(in | out) events ++// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 ++// ++// Support: Chrome, Safari ++// focus(in | out) events fire after focus & blur events, ++// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order ++// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857 ++if ( !support.focusin ) { ++ jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { ++ ++ // Attach a single capturing handler on the document while someone wants focusin/focusout ++ var handler = function( event ) { ++ jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); ++ }; ++ ++ jQuery.event.special[ fix ] = { ++ setup: function() { ++ var doc = this.ownerDocument || this, ++ attaches = jQuery._data( doc, fix ); ++ ++ if ( !attaches ) { ++ doc.addEventListener( orig, handler, true ); ++ } ++ jQuery._data( doc, fix, ( attaches || 0 ) + 1 ); ++ }, ++ teardown: function() { ++ var doc = this.ownerDocument || this, ++ attaches = jQuery._data( doc, fix ) - 1; ++ ++ if ( !attaches ) { ++ doc.removeEventListener( orig, handler, true ); ++ jQuery._removeData( doc, fix ); ++ } else { ++ jQuery._data( doc, fix, attaches ); ++ } ++ } ++ }; ++ } ); ++} ++ ++jQuery.fn.extend( { ++ ++ on: function( types, selector, data, fn ) { ++ return on( this, types, selector, data, fn ); ++ }, ++ one: function( types, selector, data, fn ) { ++ return on( this, types, selector, data, fn, 1 ); ++ }, ++ off: function( types, selector, fn ) { ++ var handleObj, type; ++ if ( types && types.preventDefault && types.handleObj ) { ++ ++ // ( event ) dispatched jQuery.Event ++ handleObj = types.handleObj; ++ jQuery( types.delegateTarget ).off( ++ handleObj.namespace ? ++ handleObj.origType + "." + handleObj.namespace : ++ handleObj.origType, ++ handleObj.selector, ++ handleObj.handler ++ ); ++ return this; ++ } ++ if ( typeof types === "object" ) { ++ ++ // ( types-object [, selector] ) ++ for ( type in types ) { ++ this.off( type, selector, types[ type ] ); ++ } ++ return this; ++ } ++ if ( selector === false || typeof selector === "function" ) { ++ ++ // ( types [, fn] ) ++ fn = selector; ++ selector = undefined; ++ } ++ if ( fn === false ) { ++ fn = returnFalse; ++ } ++ return this.each( function() { ++ jQuery.event.remove( this, types, fn, selector ); ++ } ); ++ }, ++ ++ trigger: function( type, data ) { ++ return this.each( function() { ++ jQuery.event.trigger( type, data, this ); ++ } ); ++ }, ++ triggerHandler: function( type, data ) { ++ var elem = this[ 0 ]; ++ if ( elem ) { ++ return jQuery.event.trigger( type, data, elem, true ); ++ } ++ } ++} ); ++ ++ ++var rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, ++ rnoshimcache = new RegExp( "<(?:" + nodeNames + ")[\\s/>]", "i" ), ++ rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi, ++ ++ // Support: IE 10-11, Edge 10240+ ++ // In IE/Edge using regex groups here causes severe slowdowns. ++ // See https://connect.microsoft.com/IE/feedback/details/1736512/ ++ rnoInnerhtml = /\s*$/g, ++ safeFragment = createSafeFragment( document ), ++ fragmentDiv = safeFragment.appendChild( document.createElement( "div" ) ); ++ ++// Support: IE<8 ++// Manipulating tables requires a tbody ++function manipulationTarget( elem, content ) { ++ return jQuery.nodeName( elem, "table" ) && ++ jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? ++ ++ elem.getElementsByTagName( "tbody" )[ 0 ] || ++ elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) : ++ elem; ++} ++ ++// Replace/restore the type attribute of script elements for safe DOM manipulation ++function disableScript( elem ) { ++ elem.type = ( jQuery.find.attr( elem, "type" ) !== null ) + "/" + elem.type; ++ return elem; ++} ++function restoreScript( elem ) { ++ var match = rscriptTypeMasked.exec( elem.type ); ++ if ( match ) { ++ elem.type = match[ 1 ]; ++ } else { ++ elem.removeAttribute( "type" ); ++ } ++ return elem; ++} ++ ++function cloneCopyEvent( src, dest ) { ++ if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { ++ return; ++ } ++ ++ var type, i, l, ++ oldData = jQuery._data( src ), ++ curData = jQuery._data( dest, oldData ), ++ events = oldData.events; ++ ++ if ( events ) { ++ delete curData.handle; ++ curData.events = {}; ++ ++ for ( type in events ) { ++ for ( i = 0, l = events[ type ].length; i < l; i++ ) { ++ jQuery.event.add( dest, type, events[ type ][ i ] ); ++ } ++ } ++ } ++ ++ // make the cloned public data object a copy from the original ++ if ( curData.data ) { ++ curData.data = jQuery.extend( {}, curData.data ); ++ } ++} ++ ++function fixCloneNodeIssues( src, dest ) { ++ var nodeName, e, data; ++ ++ // We do not need to do anything for non-Elements ++ if ( dest.nodeType !== 1 ) { ++ return; ++ } ++ ++ nodeName = dest.nodeName.toLowerCase(); ++ ++ // IE6-8 copies events bound via attachEvent when using cloneNode. ++ if ( !support.noCloneEvent && dest[ jQuery.expando ] ) { ++ data = jQuery._data( dest ); ++ ++ for ( e in data.events ) { ++ jQuery.removeEvent( dest, e, data.handle ); ++ } ++ ++ // Event data gets referenced instead of copied if the expando gets copied too ++ dest.removeAttribute( jQuery.expando ); ++ } ++ ++ // IE blanks contents when cloning scripts, and tries to evaluate newly-set text ++ if ( nodeName === "script" && dest.text !== src.text ) { ++ disableScript( dest ).text = src.text; ++ restoreScript( dest ); ++ ++ // IE6-10 improperly clones children of object elements using classid. ++ // IE10 throws NoModificationAllowedError if parent is null, #12132. ++ } else if ( nodeName === "object" ) { ++ if ( dest.parentNode ) { ++ dest.outerHTML = src.outerHTML; ++ } ++ ++ // This path appears unavoidable for IE9. When cloning an object ++ // element in IE9, the outerHTML strategy above is not sufficient. ++ // If the src has innerHTML and the destination does not, ++ // copy the src.innerHTML into the dest.innerHTML. #10324 ++ if ( support.html5Clone && ( src.innerHTML && !jQuery.trim( dest.innerHTML ) ) ) { ++ dest.innerHTML = src.innerHTML; ++ } ++ ++ } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { ++ ++ // IE6-8 fails to persist the checked state of a cloned checkbox ++ // or radio button. Worse, IE6-7 fail to give the cloned element ++ // a checked appearance if the defaultChecked value isn't also set ++ ++ dest.defaultChecked = dest.checked = src.checked; ++ ++ // IE6-7 get confused and end up setting the value of a cloned ++ // checkbox/radio button to an empty string instead of "on" ++ if ( dest.value !== src.value ) { ++ dest.value = src.value; ++ } ++ ++ // IE6-8 fails to return the selected option to the default selected ++ // state when cloning options ++ } else if ( nodeName === "option" ) { ++ dest.defaultSelected = dest.selected = src.defaultSelected; ++ ++ // IE6-8 fails to set the defaultValue to the correct value when ++ // cloning other types of input fields ++ } else if ( nodeName === "input" || nodeName === "textarea" ) { ++ dest.defaultValue = src.defaultValue; ++ } ++} ++ ++function domManip( collection, args, callback, ignored ) { ++ ++ // Flatten any nested arrays ++ args = concat.apply( [], args ); ++ ++ var first, node, hasScripts, ++ scripts, doc, fragment, ++ i = 0, ++ l = collection.length, ++ iNoClone = l - 1, ++ value = args[ 0 ], ++ isFunction = jQuery.isFunction( value ); ++ ++ // We can't cloneNode fragments that contain checked, in WebKit ++ if ( isFunction || ++ ( l > 1 && typeof value === "string" && ++ !support.checkClone && rchecked.test( value ) ) ) { ++ return collection.each( function( index ) { ++ var self = collection.eq( index ); ++ if ( isFunction ) { ++ args[ 0 ] = value.call( this, index, self.html() ); ++ } ++ domManip( self, args, callback, ignored ); ++ } ); ++ } ++ ++ if ( l ) { ++ fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); ++ first = fragment.firstChild; ++ ++ if ( fragment.childNodes.length === 1 ) { ++ fragment = first; ++ } ++ ++ // Require either new content or an interest in ignored elements to invoke the callback ++ if ( first || ignored ) { ++ scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); ++ hasScripts = scripts.length; ++ ++ // Use the original fragment for the last item ++ // instead of the first because it can end up ++ // being emptied incorrectly in certain situations (#8070). ++ for ( ; i < l; i++ ) { ++ node = fragment; ++ ++ if ( i !== iNoClone ) { ++ node = jQuery.clone( node, true, true ); ++ ++ // Keep references to cloned scripts for later restoration ++ if ( hasScripts ) { ++ ++ // Support: Android<4.1, PhantomJS<2 ++ // push.apply(_, arraylike) throws on ancient WebKit ++ jQuery.merge( scripts, getAll( node, "script" ) ); ++ } ++ } ++ ++ callback.call( collection[ i ], node, i ); ++ } ++ ++ if ( hasScripts ) { ++ doc = scripts[ scripts.length - 1 ].ownerDocument; ++ ++ // Reenable scripts ++ jQuery.map( scripts, restoreScript ); ++ ++ // Evaluate executable scripts on first document insertion ++ for ( i = 0; i < hasScripts; i++ ) { ++ node = scripts[ i ]; ++ if ( rscriptType.test( node.type || "" ) && ++ !jQuery._data( node, "globalEval" ) && ++ jQuery.contains( doc, node ) ) { ++ ++ if ( node.src ) { ++ ++ // Optional AJAX dependency, but won't run scripts if not present ++ if ( jQuery._evalUrl ) { ++ jQuery._evalUrl( node.src ); ++ } ++ } else { ++ jQuery.globalEval( ++ ( node.text || node.textContent || node.innerHTML || "" ) ++ .replace( rcleanScript, "" ) ++ ); ++ } ++ } ++ } ++ } ++ ++ // Fix #11809: Avoid leaking memory ++ fragment = first = null; ++ } ++ } ++ ++ return collection; ++} ++ ++function remove( elem, selector, keepData ) { ++ var node, ++ elems = selector ? jQuery.filter( selector, elem ) : elem, ++ i = 0; ++ ++ for ( ; ( node = elems[ i ] ) != null; i++ ) { ++ ++ if ( !keepData && node.nodeType === 1 ) { ++ jQuery.cleanData( getAll( node ) ); ++ } ++ ++ if ( node.parentNode ) { ++ if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { ++ setGlobalEval( getAll( node, "script" ) ); ++ } ++ node.parentNode.removeChild( node ); ++ } ++ } ++ ++ return elem; ++} ++ ++jQuery.extend( { ++ htmlPrefilter: function( html ) { ++ return html.replace( rxhtmlTag, "<$1>" ); ++ }, ++ ++ clone: function( elem, dataAndEvents, deepDataAndEvents ) { ++ var destElements, node, clone, i, srcElements, ++ inPage = jQuery.contains( elem.ownerDocument, elem ); ++ ++ if ( support.html5Clone || jQuery.isXMLDoc( elem ) || ++ !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { ++ ++ clone = elem.cloneNode( true ); ++ ++ // IE<=8 does not properly clone detached, unknown element nodes ++ } else { ++ fragmentDiv.innerHTML = elem.outerHTML; ++ fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); ++ } ++ ++ if ( ( !support.noCloneEvent || !support.noCloneChecked ) && ++ ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) { ++ ++ // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 ++ destElements = getAll( clone ); ++ srcElements = getAll( elem ); ++ ++ // Fix all IE cloning issues ++ for ( i = 0; ( node = srcElements[ i ] ) != null; ++i ) { ++ ++ // Ensure that the destination node is not null; Fixes #9587 ++ if ( destElements[ i ] ) { ++ fixCloneNodeIssues( node, destElements[ i ] ); ++ } ++ } ++ } ++ ++ // Copy the events from the original to the clone ++ if ( dataAndEvents ) { ++ if ( deepDataAndEvents ) { ++ srcElements = srcElements || getAll( elem ); ++ destElements = destElements || getAll( clone ); ++ ++ for ( i = 0; ( node = srcElements[ i ] ) != null; i++ ) { ++ cloneCopyEvent( node, destElements[ i ] ); ++ } ++ } else { ++ cloneCopyEvent( elem, clone ); ++ } ++ } ++ ++ // Preserve script evaluation history ++ destElements = getAll( clone, "script" ); ++ if ( destElements.length > 0 ) { ++ setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); ++ } ++ ++ destElements = srcElements = node = null; ++ ++ // Return the cloned set ++ return clone; ++ }, ++ ++ cleanData: function( elems, /* internal */ forceAcceptData ) { ++ var elem, type, id, data, ++ i = 0, ++ internalKey = jQuery.expando, ++ cache = jQuery.cache, ++ attributes = support.attributes, ++ special = jQuery.event.special; ++ ++ for ( ; ( elem = elems[ i ] ) != null; i++ ) { ++ if ( forceAcceptData || acceptData( elem ) ) { ++ ++ id = elem[ internalKey ]; ++ data = id && cache[ id ]; ++ ++ if ( data ) { ++ if ( data.events ) { ++ for ( type in data.events ) { ++ if ( special[ type ] ) { ++ jQuery.event.remove( elem, type ); ++ ++ // This is a shortcut to avoid jQuery.event.remove's overhead ++ } else { ++ jQuery.removeEvent( elem, type, data.handle ); ++ } ++ } ++ } ++ ++ // Remove cache only if it was not already removed by jQuery.event.remove ++ if ( cache[ id ] ) { ++ ++ delete cache[ id ]; ++ ++ // Support: IE<9 ++ // IE does not allow us to delete expando properties from nodes ++ // IE creates expando attributes along with the property ++ // IE does not have a removeAttribute function on Document nodes ++ if ( !attributes && typeof elem.removeAttribute !== "undefined" ) { ++ elem.removeAttribute( internalKey ); ++ ++ // Webkit & Blink performance suffers when deleting properties ++ // from DOM nodes, so set to undefined instead ++ // https://code.google.com/p/chromium/issues/detail?id=378607 ++ } else { ++ elem[ internalKey ] = undefined; ++ } ++ ++ deletedIds.push( id ); ++ } ++ } ++ } ++ } ++ } ++} ); ++ ++jQuery.fn.extend( { ++ ++ // Keep domManip exposed until 3.0 (gh-2225) ++ domManip: domManip, ++ ++ detach: function( selector ) { ++ return remove( this, selector, true ); ++ }, ++ ++ remove: function( selector ) { ++ return remove( this, selector ); ++ }, ++ ++ text: function( value ) { ++ return access( this, function( value ) { ++ return value === undefined ? ++ jQuery.text( this ) : ++ this.empty().append( ++ ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value ) ++ ); ++ }, null, value, arguments.length ); ++ }, ++ ++ append: function() { ++ return domManip( this, arguments, function( elem ) { ++ if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { ++ var target = manipulationTarget( this, elem ); ++ target.appendChild( elem ); ++ } ++ } ); ++ }, ++ ++ prepend: function() { ++ return domManip( this, arguments, function( elem ) { ++ if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { ++ var target = manipulationTarget( this, elem ); ++ target.insertBefore( elem, target.firstChild ); ++ } ++ } ); ++ }, ++ ++ before: function() { ++ return domManip( this, arguments, function( elem ) { ++ if ( this.parentNode ) { ++ this.parentNode.insertBefore( elem, this ); ++ } ++ } ); ++ }, ++ ++ after: function() { ++ return domManip( this, arguments, function( elem ) { ++ if ( this.parentNode ) { ++ this.parentNode.insertBefore( elem, this.nextSibling ); ++ } ++ } ); ++ }, ++ ++ empty: function() { ++ var elem, ++ i = 0; ++ ++ for ( ; ( elem = this[ i ] ) != null; i++ ) { ++ ++ // Remove element nodes and prevent memory leaks ++ if ( elem.nodeType === 1 ) { ++ jQuery.cleanData( getAll( elem, false ) ); ++ } ++ ++ // Remove any remaining nodes ++ while ( elem.firstChild ) { ++ elem.removeChild( elem.firstChild ); ++ } ++ ++ // If this is a select, ensure that it displays empty (#12336) ++ // Support: IE<9 ++ if ( elem.options && jQuery.nodeName( elem, "select" ) ) { ++ elem.options.length = 0; ++ } ++ } ++ ++ return this; ++ }, ++ ++ clone: function( dataAndEvents, deepDataAndEvents ) { ++ dataAndEvents = dataAndEvents == null ? false : dataAndEvents; ++ deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; ++ ++ return this.map( function() { ++ return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); ++ } ); ++ }, ++ ++ html: function( value ) { ++ return access( this, function( value ) { ++ var elem = this[ 0 ] || {}, ++ i = 0, ++ l = this.length; ++ ++ if ( value === undefined ) { ++ return elem.nodeType === 1 ? ++ elem.innerHTML.replace( rinlinejQuery, "" ) : ++ undefined; ++ } ++ ++ // See if we can take a shortcut and just use innerHTML ++ if ( typeof value === "string" && !rnoInnerhtml.test( value ) && ++ ( support.htmlSerialize || !rnoshimcache.test( value ) ) && ++ ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && ++ !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { ++ ++ value = jQuery.htmlPrefilter( value ); ++ ++ try { ++ for ( ; i < l; i++ ) { ++ ++ // Remove element nodes and prevent memory leaks ++ elem = this[ i ] || {}; ++ if ( elem.nodeType === 1 ) { ++ jQuery.cleanData( getAll( elem, false ) ); ++ elem.innerHTML = value; ++ } ++ } ++ ++ elem = 0; ++ ++ // If using innerHTML throws an exception, use the fallback method ++ } catch ( e ) {} ++ } ++ ++ if ( elem ) { ++ this.empty().append( value ); ++ } ++ }, null, value, arguments.length ); ++ }, ++ ++ replaceWith: function() { ++ var ignored = []; ++ ++ // Make the changes, replacing each non-ignored context element with the new content ++ return domManip( this, arguments, function( elem ) { ++ var parent = this.parentNode; ++ ++ if ( jQuery.inArray( this, ignored ) < 0 ) { ++ jQuery.cleanData( getAll( this ) ); ++ if ( parent ) { ++ parent.replaceChild( elem, this ); ++ } ++ } ++ ++ // Force callback invocation ++ }, ignored ); ++ } ++} ); ++ ++jQuery.each( { ++ appendTo: "append", ++ prependTo: "prepend", ++ insertBefore: "before", ++ insertAfter: "after", ++ replaceAll: "replaceWith" ++}, function( name, original ) { ++ jQuery.fn[ name ] = function( selector ) { ++ var elems, ++ i = 0, ++ ret = [], ++ insert = jQuery( selector ), ++ last = insert.length - 1; ++ ++ for ( ; i <= last; i++ ) { ++ elems = i === last ? this : this.clone( true ); ++ jQuery( insert[ i ] )[ original ]( elems ); ++ ++ // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() ++ push.apply( ret, elems.get() ); ++ } ++ ++ return this.pushStack( ret ); ++ }; ++} ); ++ ++ ++var iframe, ++ elemdisplay = { ++ ++ // Support: Firefox ++ // We have to pre-define these values for FF (#10227) ++ HTML: "block", ++ BODY: "block" ++ }; ++ ++/** ++ * Retrieve the actual display of a element ++ * @param {String} name nodeName of the element ++ * @param {Object} doc Document object ++ */ ++ ++// Called only from within defaultDisplay ++function actualDisplay( name, doc ) { ++ var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), ++ ++ display = jQuery.css( elem[ 0 ], "display" ); ++ ++ // We don't have any data stored on the element, ++ // so use "detach" method as fast way to get rid of the element ++ elem.detach(); ++ ++ return display; ++} ++ ++/** ++ * Try to determine the default display value of an element ++ * @param {String} nodeName ++ */ ++function defaultDisplay( nodeName ) { ++ var doc = document, ++ display = elemdisplay[ nodeName ]; ++ ++ if ( !display ) { ++ display = actualDisplay( nodeName, doc ); ++ ++ // If the simple way fails, read from inside an iframe ++ if ( display === "none" || !display ) { ++ ++ // Use the already-created iframe if possible ++ iframe = ( iframe || jQuery( "