From bb50acdcb8073654ea667b8c0272e335bd43f844 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 14 Apr 2022 20:12:14 +0200 Subject: Merging upstream version 1.34.0. Signed-off-by: Daniel Baumann --- .dockerignore | 7 +- .github/CODEOWNERS | 60 +- .github/PULL_REQUEST_TEMPLATE.md | 30 +- .github/data/build-matrix.json | 98 - .github/data/distros.yml | 155 + .github/dockerfiles/Dockerfile.build_test | 2 +- .github/labeler.yml | 106 +- .github/scripts/docker-test.sh | 4 +- .github/scripts/prepare-release-base.sh | 177 + .github/scripts/run_install_with_dist_file.sh | 2 +- .github/workflows/build.yml | 283 +- .github/workflows/checks.yml | 21 +- .github/workflows/cloud_regression.yml | 53 + .github/workflows/coverity.yml | 14 +- .github/workflows/dashboard-pr.yml | 24 +- .github/workflows/docker.yml | 86 +- .github/workflows/docs.yml | 4 +- .github/workflows/labeler.yml | 2 +- .github/workflows/packaging.yml | 268 +- .github/workflows/release.yml | 207 + .github/workflows/repoconfig-packages.yml | 118 +- .github/workflows/review.yml | 14 +- .github/workflows/tests.yml | 8 +- .github/workflows/trigger-learn-update.yml | 37 + .gitignore | 4 + .travis.yml | 89 - BREAKING_CHANGES.md | 2 +- BUILD.md | 2 +- CHANGELOG.md | 529 +- CMakeLists.txt | 75 +- Makefile.am | 64 +- README.md | 7 - REDISTRIBUTED.md | 2 +- aclk/README.md | 2 +- aclk/aclk.c | 361 +- aclk/aclk_api.c | 5 + aclk/aclk_query.c | 81 +- aclk/aclk_query.h | 4 + aclk/aclk_query_queue.c | 35 - aclk/aclk_query_queue.h | 5 +- aclk/aclk_rx_msgs.c | 16 +- aclk/aclk_rx_msgs.h | 3 +- aclk/aclk_stats.c | 114 +- aclk/aclk_stats.h | 15 +- aclk/aclk_tx_msgs.c | 68 +- aclk/aclk_tx_msgs.h | 1 + aclk/aclk_util.c | 3 +- aclk/aclk_util.h | 15 +- aclk/https_client.c | 2 +- backends/Makefile.am | 22 - backends/README.md | 236 - backends/TIMESCALE.md | 57 - backends/WALKTHROUGH.md | 258 - backends/aws_kinesis/Makefile.am | 12 - backends/aws_kinesis/README.md | 53 - backends/aws_kinesis/aws_kinesis.c | 94 - backends/aws_kinesis/aws_kinesis.conf | 10 - backends/aws_kinesis/aws_kinesis.h | 14 - backends/aws_kinesis/aws_kinesis_put_record.cc | 87 - backends/aws_kinesis/aws_kinesis_put_record.h | 25 - backends/backends.c | 1247 ---- backends/backends.h | 98 - backends/graphite/Makefile.am | 4 - backends/graphite/graphite.c | 90 - backends/graphite/graphite.h | 35 - backends/json/Makefile.am | 4 - backends/json/json.c | 152 - backends/json/json.h | 34 - backends/mongodb/Makefile.am | 8 - backends/mongodb/README.md | 41 - backends/mongodb/mongodb.c | 189 - backends/mongodb/mongodb.conf | 12 - backends/mongodb/mongodb.h | 16 - backends/nc-backend.sh | 158 - backends/opentsdb/Makefile.am | 4 - backends/opentsdb/README.md | 38 - backends/opentsdb/opentsdb.c | 205 - backends/opentsdb/opentsdb.h | 58 - backends/prometheus/Makefile.am | 12 - backends/prometheus/README.md | 457 -- backends/prometheus/backend_prometheus.c | 797 --- backends/prometheus/backend_prometheus.h | 37 - backends/prometheus/remote_write/Makefile.am | 14 - backends/prometheus/remote_write/README.md | 41 - backends/prometheus/remote_write/remote_write.cc | 120 - backends/prometheus/remote_write/remote_write.h | 30 - .../prometheus/remote_write/remote_write.proto | 29 - build/m4/ax_pthread.m4 | 468 +- build_external/README.md | 2 +- .../scenarios/aclk-testing/agent_netdata.conf | 17 - claim/README.md | 71 +- claim/claim.c | 8 +- claim/netdata-claim.sh.in | 12 +- cli/README.md | 2 +- collectors/COLLECTORS.md | 9 +- collectors/README.md | 8 +- collectors/REFERENCE.md | 1 - collectors/all.h | 2 + collectors/apps.plugin/README.md | 2 +- collectors/apps.plugin/apps_groups.conf | 13 + collectors/apps.plugin/apps_plugin.c | 91 +- collectors/cgroups.plugin/README.md | 2 +- collectors/cgroups.plugin/sys_fs_cgroup.c | 448 +- collectors/charts.d.plugin/README.md | 2 +- collectors/charts.d.plugin/ap/README.md | 2 +- collectors/charts.d.plugin/apcupsd/README.md | 2 +- .../charts.d.plugin/apcupsd/apcupsd.chart.sh | 2 +- collectors/charts.d.plugin/example/README.md | 2 +- collectors/charts.d.plugin/libreswan/README.md | 2 +- collectors/charts.d.plugin/nut/README.md | 2 +- collectors/charts.d.plugin/opensips/README.md | 2 +- collectors/charts.d.plugin/sensors/README.md | 2 +- .../charts.d.plugin/sensors/sensors.chart.sh | 28 +- collectors/checks.plugin/README.md | 2 +- collectors/cups.plugin/README.md | 2 +- collectors/cups.plugin/cups_plugin.c | 16 +- collectors/diskspace.plugin/README.md | 2 +- collectors/diskspace.plugin/plugin_diskspace.c | 4 +- collectors/ebpf.plugin/README.md | 1101 ++-- collectors/ebpf.plugin/ebpf.c | 128 +- collectors/ebpf.plugin/ebpf.d/mount.conf | 13 +- collectors/ebpf.plugin/ebpf.d/network.conf | 12 + collectors/ebpf.plugin/ebpf.d/shm.conf | 14 +- collectors/ebpf.plugin/ebpf.d/sync.conf | 13 +- collectors/ebpf.plugin/ebpf.h | 4 + collectors/ebpf.plugin/ebpf_apps.c | 2 +- collectors/ebpf.plugin/ebpf_apps.h | 4 + collectors/ebpf.plugin/ebpf_cachestat.c | 40 +- collectors/ebpf.plugin/ebpf_cgroup.c | 2 +- collectors/ebpf.plugin/ebpf_dcstat.c | 34 +- collectors/ebpf.plugin/ebpf_mount.c | 238 +- collectors/ebpf.plugin/ebpf_mount.h | 8 + collectors/ebpf.plugin/ebpf_oomkill.c | 4 +- collectors/ebpf.plugin/ebpf_oomkill.h | 3 + collectors/ebpf.plugin/ebpf_shm.c | 243 +- collectors/ebpf.plugin/ebpf_shm.h | 1 + collectors/ebpf.plugin/ebpf_socket.c | 743 ++- collectors/ebpf.plugin/ebpf_socket.h | 85 +- collectors/ebpf.plugin/ebpf_swap.c | 2 +- collectors/ebpf.plugin/ebpf_sync.c | 205 +- collectors/ebpf.plugin/ebpf_sync.h | 24 +- collectors/ebpf.plugin/ebpf_vfs.c | 36 +- collectors/ebpf.plugin/ebpf_vfs.h | 12 + collectors/fping.plugin/README.md | 2 +- collectors/freebsd.plugin/README.md | 2 +- collectors/freeipmi.plugin/README.md | 2 +- collectors/idlejitter.plugin/README.md | 2 +- collectors/ioping.plugin/README.md | 2 +- collectors/ioping.plugin/ioping.plugin.in | 18 +- collectors/macos.plugin/README.md | 2 +- collectors/macos.plugin/macos_fw.c | 13 +- collectors/macos.plugin/macos_sysctl.c | 7 +- collectors/nfacct.plugin/README.md | 4 +- collectors/node.d.plugin/Makefile.am | 4 - collectors/node.d.plugin/README.md | 2 +- collectors/node.d.plugin/fronius/Makefile.inc | 13 - collectors/node.d.plugin/fronius/README.md | 135 - collectors/node.d.plugin/fronius/fronius.node.js | 400 -- collectors/node.d.plugin/named/Makefile.inc | 13 - collectors/node.d.plugin/named/README.md | 348 -- collectors/node.d.plugin/named/named.node.js | 610 -- collectors/node.d.plugin/node.d.conf | 6 - collectors/node.d.plugin/sma_webbox/Makefile.inc | 13 - collectors/node.d.plugin/sma_webbox/README.md | 33 - .../node.d.plugin/sma_webbox/sma_webbox.node.js | 239 - collectors/node.d.plugin/snmp/README.md | 2 +- .../node.d.plugin/stiebeleltron/Makefile.inc | 13 - collectors/node.d.plugin/stiebeleltron/README.md | 525 -- .../stiebeleltron/stiebeleltron.node.js | 197 - collectors/perf.plugin/README.md | 2 +- collectors/plugins.d/README.md | 6 +- collectors/plugins.d/plugins_d.c | 2 +- collectors/plugins.d/plugins_d.h | 1 + collectors/plugins.d/pluginsd_parser.c | 7 +- collectors/proc.plugin/README.md | 2 +- collectors/proc.plugin/proc_interrupts.c | 2 +- collectors/proc.plugin/proc_net_dev.c | 87 +- collectors/proc.plugin/proc_net_softnet_stat.c | 2 +- collectors/proc.plugin/proc_softirqs.c | 2 +- collectors/proc.plugin/sys_fs_btrfs.c | 8 +- collectors/python.d.plugin/README.md | 4 +- collectors/python.d.plugin/adaptec_raid/README.md | 2 +- collectors/python.d.plugin/alarms/README.md | 2 - collectors/python.d.plugin/am2320/README.md | 1 - collectors/python.d.plugin/anomalies/README.md | 1 - collectors/python.d.plugin/apache/README.md | 2 +- collectors/python.d.plugin/beanstalk/README.md | 2 +- .../python.d.plugin/beanstalk/beanstalk.conf | 2 +- collectors/python.d.plugin/bind_rndc/README.md | 2 +- collectors/python.d.plugin/boinc/README.md | 2 +- collectors/python.d.plugin/ceph/README.md | 2 +- collectors/python.d.plugin/changefinder/README.md | 1 - collectors/python.d.plugin/chrony/README.md | 2 +- collectors/python.d.plugin/couchdb/README.md | 2 +- .../python.d.plugin/dns_query_time/README.md | 2 +- collectors/python.d.plugin/dnsdist/README.md | 2 +- collectors/python.d.plugin/dockerd/README.md | 2 +- collectors/python.d.plugin/dovecot/README.md | 2 +- collectors/python.d.plugin/elasticsearch/README.md | 2 +- collectors/python.d.plugin/energid/README.md | 2 +- collectors/python.d.plugin/example/README.md | 2 +- collectors/python.d.plugin/exim/README.md | 2 +- collectors/python.d.plugin/fail2ban/README.md | 2 +- collectors/python.d.plugin/freeradius/README.md | 2 +- collectors/python.d.plugin/gearman/README.md | 1 - collectors/python.d.plugin/go_expvar/README.md | 2 +- collectors/python.d.plugin/haproxy/README.md | 2 +- collectors/python.d.plugin/hddtemp/README.md | 2 +- collectors/python.d.plugin/hpssa/README.md | 1 - collectors/python.d.plugin/hpssa/hpssa.chart.py | 3 +- collectors/python.d.plugin/httpcheck/README.md | 2 +- .../python.d.plugin/httpcheck/httpcheck.conf | 2 +- collectors/python.d.plugin/icecast/README.md | 2 +- collectors/python.d.plugin/ipfs/README.md | 2 +- collectors/python.d.plugin/isc_dhcpd/README.md | 2 +- collectors/python.d.plugin/litespeed/README.md | 2 +- collectors/python.d.plugin/logind/README.md | 2 +- collectors/python.d.plugin/megacli/README.md | 2 +- collectors/python.d.plugin/memcached/README.md | 2 +- collectors/python.d.plugin/mongodb/README.md | 2 +- collectors/python.d.plugin/monit/README.md | 2 +- collectors/python.d.plugin/mysql/README.md | 2 +- collectors/python.d.plugin/nginx/README.md | 2 +- collectors/python.d.plugin/nginx_plus/README.md | 2 +- collectors/python.d.plugin/nsd/README.md | 2 +- collectors/python.d.plugin/ntpd/README.md | 2 +- collectors/python.d.plugin/nvidia_smi/README.md | 2 +- .../python.d.plugin/nvidia_smi/nvidia_smi.chart.py | 11 +- collectors/python.d.plugin/openldap/README.md | 2 +- collectors/python.d.plugin/oracledb/README.md | 2 +- .../python.d.plugin/ovpn_status_log/README.md | 2 +- collectors/python.d.plugin/phpfpm/README.md | 2 +- collectors/python.d.plugin/portcheck/README.md | 2 +- .../python.d.plugin/portcheck/portcheck.conf | 2 +- collectors/python.d.plugin/postfix/README.md | 2 +- collectors/python.d.plugin/postgres/README.md | 2 +- collectors/python.d.plugin/powerdns/README.md | 2 +- collectors/python.d.plugin/proxysql/README.md | 2 +- collectors/python.d.plugin/puppet/README.md | 2 +- .../python.d.plugin/python_modules/bases/charts.py | 2 +- collectors/python.d.plugin/rabbitmq/README.md | 2 +- collectors/python.d.plugin/redis/README.md | 2 +- collectors/python.d.plugin/rethinkdbs/README.md | 2 +- collectors/python.d.plugin/retroshare/README.md | 2 +- collectors/python.d.plugin/riakkv/README.md | 2 - collectors/python.d.plugin/samba/README.md | 2 +- collectors/python.d.plugin/sensors/README.md | 2 +- .../python.d.plugin/sensors/sensors.chart.py | 15 +- collectors/python.d.plugin/smartd_log/README.md | 2 +- collectors/python.d.plugin/spigotmc/README.md | 2 +- collectors/python.d.plugin/springboot/README.md | 2 +- collectors/python.d.plugin/squid/README.md | 2 +- collectors/python.d.plugin/tomcat/README.md | 2 +- collectors/python.d.plugin/tor/README.md | 2 +- collectors/python.d.plugin/traefik/README.md | 2 +- collectors/python.d.plugin/uwsgi/README.md | 2 +- collectors/python.d.plugin/varnish/README.md | 2 +- collectors/python.d.plugin/w1sensor/README.md | 2 +- collectors/python.d.plugin/web_log/README.md | 2 +- collectors/slabinfo.plugin/README.md | 2 +- collectors/statsd.plugin/Makefile.am | 1 + collectors/statsd.plugin/README.md | 6 +- collectors/statsd.plugin/asterisk.conf | 208 + collectors/statsd.plugin/asterisk.md | 61 + collectors/tc.plugin/README.md | 2 +- collectors/timex.plugin/README.md | 16 +- collectors/timex.plugin/plugin_timex.c | 74 +- collectors/xenstat.plugin/README.md | 2 +- configure.ac | 186 +- contrib/README.md | 2 +- contrib/debian/compat | 2 +- contrib/debian/netdata.postinst | 3 +- contrib/debian/rules | 20 +- contrib/sles11/README.md | 17 - contrib/sles11/alarm-notify-basic.bash3.sh | 755 --- contrib/sles11/netdata-alarms-bash3.patch | 10 - contrib/sles11/netdata-automake-no-dist-xz.patch | 13 - contrib/sles11/netdata-python-plugin-sles11.patch | 28 - contrib/sles11/netdata.init | 65 - coverity-scan.sh | 18 +- daemon/README.md | 61 +- daemon/analytics.c | 28 +- daemon/anonymous-statistics.sh.in | 6 +- daemon/buildinfo.c | 174 +- daemon/buildinfo.h | 8 +- daemon/commands.c | 8 +- daemon/common.h | 4 +- daemon/config/README.md | 89 +- daemon/daemon.c | 30 +- daemon/get-kubernetes-labels.sh.in | 21 +- daemon/global_statistics.c | 12 +- daemon/main.c | 53 +- daemon/service.c | 5 + daemon/static_threads.c | 19 +- daemon/static_threads_linux.c | 9 - daemon/system-info.sh | 91 +- daemon/unit_test.c | 44 +- daemon/unit_test.h | 1 + database/README.md | 2 +- database/engine/README.md | 2 +- database/engine/datafile.c | 1 + database/engine/journalfile.c | 3 +- database/rrd.c | 3 +- database/rrd.h | 29 +- database/rrdcalctemplate.c | 3 + database/rrddim.c | 66 +- database/rrdhost.c | 142 +- database/rrdset.c | 140 +- database/sqlite/sqlite_aclk.c | 15 +- database/sqlite/sqlite_aclk.h | 2 + database/sqlite/sqlite_aclk_alert.c | 128 +- database/sqlite/sqlite_aclk_alert.h | 10 + database/sqlite/sqlite_aclk_chart.c | 601 +- database/sqlite/sqlite_aclk_chart.h | 27 +- database/sqlite/sqlite_aclk_node.c | 30 +- database/sqlite/sqlite_functions.c | 167 +- database/sqlite/sqlite_functions.h | 2 + database/sqlite/sqlite_health.c | 7 +- database/sqlite/sqlite_health.h | 2 +- diagrams/data_structures/README.md | 2 +- docs/Add-more-charts-to-netdata.md | 2 - docs/Demo-Sites.md | 2 +- docs/Donations-netdata-has-received.md | 2 +- docs/README.md | 2 +- docs/Running-behind-apache.md | 2 +- docs/Running-behind-caddy.md | 2 +- docs/Running-behind-haproxy.md | 6 +- docs/Running-behind-lighttpd.md | 2 +- docs/Running-behind-nginx.md | 2 +- docs/a-github-star-is-important.md | 2 +- docs/agent-cloud.md | 2 - docs/anonymous-statistics.md | 14 +- docs/collect/application-metrics.md | 2 +- docs/collect/container-metrics.md | 2 +- docs/collect/enable-configure.md | 2 +- docs/collect/how-collectors-work.md | 2 +- docs/collect/system-metrics.md | 2 +- docs/configure/nodes.md | 2 +- docs/contributing/contributing-documentation.md | 2 +- docs/contributing/style-guide.md | 2 +- docs/export/enable-connector.md | 2 +- docs/export/external-databases.md | 3 +- docs/guides/collect-apache-nginx-web-logs.md | 2 +- docs/guides/collect-unbound-metrics.md | 2 +- docs/guides/deploy/ansible.md | 2 +- .../export/export-netdata-metrics-graphite.md | 2 +- docs/guides/longer-metrics-storage.md | 2 +- docs/guides/monitor-cockroachdb.md | 2 +- docs/guides/monitor-hadoop-cluster.md | 2 +- docs/guides/monitor/anomaly-detection-python.md | 4 +- docs/guides/monitor/dimension-templates.md | 2 +- docs/guides/monitor/kubernetes-k8s-netdata.md | 2 +- docs/guides/monitor/lamp-stack.md | 1 - docs/guides/monitor/pi-hole-raspberry-pi.md | 2 +- docs/guides/monitor/process.md | 2 +- .../monitor/raspberry-pi-anomaly-detection.md | 2 +- docs/guides/monitor/statsd.md | 2 +- docs/guides/monitor/stop-notifications-alarms.md | 2 +- docs/guides/monitor/visualize-monitor-anomalies.md | 2 +- docs/guides/python-collector.md | 2 +- docs/guides/step-by-step/step-00.md | 2 +- docs/guides/step-by-step/step-01.md | 2 +- docs/guides/step-by-step/step-02.md | 2 +- docs/guides/step-by-step/step-03.md | 2 +- docs/guides/step-by-step/step-04.md | 2 +- docs/guides/step-by-step/step-05.md | 2 +- docs/guides/step-by-step/step-06.md | 2 +- docs/guides/step-by-step/step-07.md | 2 +- docs/guides/step-by-step/step-08.md | 2 +- docs/guides/step-by-step/step-09.md | 2 +- docs/guides/step-by-step/step-10.md | 4 +- docs/guides/step-by-step/step-99.md | 4 +- .../monitor-debug-applications-ebpf.md | 2 +- docs/guides/using-host-labels.md | 4 +- docs/monitor/configure-alarms.md | 2 +- docs/monitor/enable-notifications.md | 2 +- docs/monitor/view-active-alarms.md | 2 +- docs/netdata-for-IoT.md | 2 +- docs/netdata-security.md | 4 +- docs/overview/netdata-monitoring-stack.md | 2 +- docs/overview/what-is-netdata.md | 2 +- docs/overview/why-netdata.md | 2 +- docs/quickstart/infrastructure.md | 2 +- docs/quickstart/single-node.md | 2 +- docs/store/change-metrics-storage.md | 2 +- docs/store/distributed-data-architecture.md | 2 +- docs/visualize/create-dashboards.md | 2 +- docs/visualize/interact-dashboards-charts.md | 2 +- docs/visualize/overview-infrastructure.md | 2 +- docs/why-netdata/1s-granularity.md | 2 +- docs/why-netdata/README.md | 2 +- docs/why-netdata/immediate-results.md | 2 +- docs/why-netdata/meaningful-presentation.md | 2 +- docs/why-netdata/unlimited-metrics.md | 2 +- exporting/README.md | 14 +- exporting/TIMESCALE.md | 4 +- exporting/WALKTHROUGH.md | 2 +- exporting/aws_kinesis/README.md | 2 +- exporting/aws_kinesis/aws_kinesis.c | 4 +- exporting/check_filters.c | 18 +- exporting/exporting_engine.h | 9 +- exporting/graphite/README.md | 2 +- exporting/json/README.md | 2 +- exporting/mongodb/README.md | 2 +- exporting/mongodb/mongodb.c | 2 +- exporting/nc-exporting.sh | 44 +- exporting/opentsdb/README.md | 2 +- exporting/process_data.c | 4 +- exporting/prometheus/README.md | 2 +- exporting/prometheus/prometheus.c | 10 +- exporting/prometheus/remote_write/README.md | 2 +- exporting/prometheus/remote_write/remote_write.c | 2 +- exporting/pubsub/README.md | 2 +- exporting/pubsub/pubsub.c | 2 +- exporting/read_config.c | 39 +- exporting/send_data.c | 2 +- exporting/tests/test_exporting_engine.c | 9 +- health/Makefile.am | 4 +- health/QUICKSTART.md | 6 +- health/README.md | 2 +- health/REFERENCE.md | 13 +- health/health.c | 70 +- health/health.d/backend.conf | 42 - health/health.d/cgroups.conf | 37 + health/health.d/fronius.conf | 14 - health/health.d/ioping.conf | 10 +- health/health.d/net.conf | 8 +- health/health.d/nut.conf | 47 + health/health.d/stiebeleltron.conf | 14 - health/health.d/tcp_resets.conf | 2 +- health/health.d/timex.conf | 2 +- health/health.h | 1 + health/health_config.c | 27 +- health/notifications/README.md | 2 +- health/notifications/alerta/README.md | 2 +- health/notifications/awssns/README.md | 48 +- health/notifications/custom/README.md | 2 +- health/notifications/discord/README.md | 2 +- health/notifications/dynatrace/README.md | 2 - health/notifications/email/README.md | 2 +- health/notifications/flock/README.md | 2 +- health/notifications/hangouts/README.md | 2 +- health/notifications/irc/README.md | 2 +- health/notifications/kavenegar/README.md | 2 +- health/notifications/matrix/README.md | 2 +- health/notifications/messagebird/README.md | 2 +- health/notifications/msteams/README.md | 2 +- health/notifications/opsgenie/README.md | 2 +- health/notifications/prowl/README.md | 2 - health/notifications/pushbullet/README.md | 2 +- health/notifications/pushover/README.md | 2 +- health/notifications/rocketchat/README.md | 2 +- health/notifications/slack/README.md | 2 +- health/notifications/smstools3/README.md | 2 +- health/notifications/stackpulse/README.md | 2 +- health/notifications/syslog/README.md | 2 +- health/notifications/telegram/README.md | 2 +- health/notifications/twilio/README.md | 2 +- health/notifications/web/README.md | 2 +- libnetdata/README.md | 2 +- libnetdata/adaptive_resortable_list/README.md | 2 +- libnetdata/avl/README.md | 2 +- libnetdata/buffer/README.md | 3 +- libnetdata/buffer/buffer.c | 42 +- libnetdata/circular_buffer/README.md | 2 - libnetdata/clocks/README.md | 2 +- libnetdata/config/README.md | 2 +- libnetdata/config/appconfig.c | 7 +- libnetdata/config/appconfig.h | 1 - libnetdata/dictionary/README.md | 2 +- libnetdata/ebpf/README.md | 2 +- libnetdata/ebpf/ebpf.c | 268 +- libnetdata/ebpf/ebpf.h | 45 +- libnetdata/eval/README.md | 2 +- libnetdata/json/README.md | 2 +- libnetdata/libnetdata.h | 15 +- libnetdata/locks/README.md | 2 +- libnetdata/log/README.md | 2 +- libnetdata/log/log.h | 2 +- libnetdata/os.h | 7 + libnetdata/popen/README.md | 2 +- libnetdata/procfile/README.md | 2 +- libnetdata/procfile/procfile.h | 3 + libnetdata/simple_pattern/README.md | 2 +- libnetdata/socket/README.md | 2 +- libnetdata/statistical/README.md | 2 +- libnetdata/storage_number/README.md | 2 +- libnetdata/threads/README.md | 2 +- libnetdata/threads/threads.c | 1 + libnetdata/url/README.md | 2 +- ml/Config.cc | 20 +- ml/Config.h | 6 + ml/Dimension.cc | 15 +- ml/Dimension.h | 49 +- ml/Host.cc | 222 +- ml/Host.h | 44 +- ml/README.md | 14 +- ml/kmeans/SamplesBuffer.cc | 6 + ml/kmeans/SamplesBuffer.h | 7 +- ml/ml-dummy.c | 24 + ml/ml.cc | 81 +- ml/ml.h | 17 + ml/notebooks/README.md | 5 + .../netdata_anomaly_detection_deepdive.ipynb | 1712 ++++++ netdata-installer.sh | 301 +- netdata.spec.in | 36 +- package-lock.json | 6320 -------------------- package.json | 57 - packaging/bundle-ebpf-co-re.sh | 9 + packaging/bundle-libbpf.sh | 1 + packaging/bundle-protobuf.sh | 16 + packaging/current_libbpf.checksums | 2 +- packaging/current_libbpf.version | 2 +- packaging/docker/Dockerfile | 8 +- packaging/docker/README.md | 2 +- packaging/docker/run.sh | 26 +- packaging/ebpf-co-re.checksums | 1 + packaging/ebpf-co-re.version | 1 + packaging/ebpf.checksums | 6 +- packaging/ebpf.version | 2 +- packaging/go.d.checksums | 32 +- packaging/go.d.version | 2 +- packaging/installer/README.md | 21 +- packaging/installer/REINSTALL.md | 2 +- packaging/installer/UNINSTALL.md | 2 +- packaging/installer/UPDATE.md | 104 +- packaging/installer/dependencies/alpine.sh | 1 + packaging/installer/dependencies/centos.sh | 3 +- packaging/installer/dependencies/debian.sh | 1 + packaging/installer/dependencies/fedora.sh | 3 +- packaging/installer/dependencies/ol.sh | 1 + packaging/installer/dependencies/opensuse.sh | 1 + packaging/installer/dependencies/rockylinux.sh | 1 + packaging/installer/dependencies/ubuntu.sh | 1 + packaging/installer/functions.sh | 83 +- packaging/installer/install-required-packages.sh | 26 +- packaging/installer/kickstart.sh | 619 +- packaging/installer/methods/cloud-providers.md | 2 +- packaging/installer/methods/freebsd.md | 15 +- packaging/installer/methods/freenas.md | 2 +- packaging/installer/methods/kickstart.md | 32 +- packaging/installer/methods/kubernetes.md | 2 +- packaging/installer/methods/macos.md | 8 +- packaging/installer/methods/manual.md | 2 +- packaging/installer/methods/offline.md | 2 - packaging/installer/methods/pfsense.md | 2 +- packaging/installer/methods/source.md | 2 +- packaging/installer/methods/synology.md | 6 +- packaging/installer/netdata-uninstaller.sh | 293 +- packaging/installer/netdata-updater.sh | 336 +- packaging/libbpf.checksums | 2 +- packaging/libbpf.version | 2 +- packaging/maintainers/README.md | 2 +- packaging/makeself/README.md | 2 +- packaging/makeself/build-static.sh | 16 +- packaging/makeself/build.sh | 19 +- packaging/makeself/install-alpine-packages.sh | 3 + packaging/makeself/install-or-update.sh | 18 +- packaging/makeself/jobs/50-bash-5.1.16.install.sh | 41 + packaging/makeself/jobs/50-bash-5.1.8.install.sh | 41 - packaging/makeself/jobs/50-curl-7.78.0.install.sh | 54 - packaging/makeself/jobs/50-curl-7.82.0.install.sh | 54 + packaging/makeself/jobs/50-fping-5.0.install.sh | 37 - packaging/makeself/jobs/50-fping-5.1.install.sh | 37 + packaging/makeself/jobs/99-makeself.install.sh | 5 +- packaging/makeself/makeself-help-header.txt | 4 +- packaging/makeself/makeself-license.txt | 2 +- packaging/makeself/openssl.version | 2 +- packaging/protobuf.checksums | 2 +- packaging/protobuf.version | 2 +- packaging/repoconfig/netdata-edge.repo.centos | 2 + packaging/repoconfig/netdata-edge.repo.fedora | 2 + packaging/repoconfig/netdata-edge.repo.ol | 2 + packaging/repoconfig/netdata-repo.spec | 4 + packaging/repoconfig/netdata.repo.centos | 2 + packaging/repoconfig/netdata.repo.fedora | 2 + packaging/repoconfig/netdata.repo.ol | 2 + packaging/version | 2 +- parser/README.md | 2 - registry/README.md | 2 +- streaming/README.md | 51 +- streaming/compression.c | 36 +- streaming/rrdpush.c | 11 +- streaming/rrdpush.h | 2 +- streaming/sender.c | 62 +- streaming/stream.conf | 6 +- system/netdata.conf | 10 - system/netdata.service.in | 12 +- system/netdata.service.v235.in | 10 +- tests/Makefile.am | 10 - tests/README.md | 148 - .../alarm_repetition/netdata.conf_with_repetition | 2 - .../netdata.conf_without_repetition | 2 - tests/backends/prometheus-avg-oldunits.txt | 148 - tests/backends/prometheus-avg.txt | 148 - tests/backends/prometheus-raw.txt | 156 - tests/backends/prometheus.bats | 31 - tests/exporting/prometheus-avg-oldunits.txt | 148 + tests/exporting/prometheus-avg.txt | 148 + tests/exporting/prometheus-raw.txt | 156 + tests/exporting/prometheus.bats | 31 + tests/health_mgmtapi/README.md | 2 +- tests/node.d/fronius.chart.spec.js | 162 - tests/node.d/fronius.parse.spec.js | 333 -- tests/node.d/fronius.process.spec.js | 75 - tests/node.d/fronius.validation.spec.js | 155 - tests/web/easypiechart.chart.spec.js | 39 - tests/web/easypiechart.percentage.spec.js | 142 - .../web/fixtures/easypiechart.chart.fixture1.html | 6 - tests/web/karma.conf.js | 110 - tests/web/lib/jasmine-jquery.js | 841 --- web/README.md | 2 - web/api/README.md | 2 +- web/api/badges/README.md | 2 +- web/api/badges/web_buffer_svg.c | 2 +- web/api/exporters/README.md | 2 +- web/api/exporters/allmetrics.c | 8 +- web/api/exporters/prometheus/README.md | 2 +- web/api/exporters/shell/README.md | 2 +- web/api/formatters/README.md | 2 +- web/api/formatters/csv/README.md | 2 +- web/api/formatters/json/README.md | 2 +- web/api/formatters/rrd2json.c | 33 +- web/api/formatters/rrd2json.h | 3 + web/api/formatters/ssv/README.md | 2 +- web/api/formatters/ssv/ssv.c | 4 +- web/api/formatters/ssv/ssv.h | 2 +- web/api/formatters/value/README.md | 2 +- web/api/formatters/value/value.c | 6 +- web/api/formatters/value/value.h | 2 +- web/api/health/README.md | 2 +- web/api/netdata-swagger.json | 66 +- web/api/netdata-swagger.yaml | 55 +- web/api/queries/README.md | 2 +- web/api/queries/average/README.md | 2 +- web/api/queries/des/README.md | 2 +- web/api/queries/incremental_sum/README.md | 2 +- web/api/queries/max/README.md | 2 +- web/api/queries/median/README.md | 2 +- web/api/queries/min/README.md | 2 +- web/api/queries/query.c | 49 +- web/api/queries/rrdr.h | 3 +- web/api/queries/ses/README.md | 2 +- web/api/queries/stddev/README.md | 2 +- web/api/queries/sum/README.md | 2 +- web/api/tests/valid_urls.c | 4 +- web/api/tests/web_api.c | 4 +- web/api/web_api_v1.c | 88 +- web/api/web_api_v1.h | 1 + web/gui/README.md | 2 - web/gui/confluence/README.md | 2 +- web/gui/custom/README.md | 3 +- web/gui/dashboard/Makefile.am | 56 +- web/gui/dashboard/asset-manifest.json | 64 +- web/gui/dashboard/index.html | 4 +- ...he-manifest.34ebb83b69a8a6741865723124721c81.js | 190 + ...he-manifest.55bf0765e4092267255469aff90b2f26.js | 190 - web/gui/dashboard/service-worker.js | 2 +- .../dashboard/static/css/main.102ce44c.chunk.css | 2 + .../static/css/main.102ce44c.chunk.css.map | 1 + .../dashboard/static/css/main.a46a34fa.chunk.css | 2 - .../static/css/main.a46a34fa.chunk.css.map | 1 - web/gui/dashboard/static/js/10.44d9d40b.chunk.js | 2 + .../dashboard/static/js/10.44d9d40b.chunk.js.map | 1 + web/gui/dashboard/static/js/10.eb10af4d.chunk.js | 2 - .../dashboard/static/js/10.eb10af4d.chunk.js.map | 1 - web/gui/dashboard/static/js/2.d50fa4b3.chunk.js | 3 + .../static/js/2.d50fa4b3.chunk.js.LICENSE | 260 + .../dashboard/static/js/2.d50fa4b3.chunk.js.map | 1 + web/gui/dashboard/static/js/2.da522cd4.chunk.js | 3 - .../static/js/2.da522cd4.chunk.js.LICENSE | 260 - .../dashboard/static/js/2.da522cd4.chunk.js.map | 1 - web/gui/dashboard/static/js/3.6267b47a.chunk.js | 2 - .../dashboard/static/js/3.6267b47a.chunk.js.map | 1 - web/gui/dashboard/static/js/3.d49f0857.chunk.js | 2 + .../dashboard/static/js/3.d49f0857.chunk.js.map | 1 + web/gui/dashboard/static/js/4.89bcbd92.chunk.js | 2 - .../dashboard/static/js/4.89bcbd92.chunk.js.map | 1 - web/gui/dashboard/static/js/4.8b70c754.chunk.js | 2 + .../dashboard/static/js/4.8b70c754.chunk.js.map | 1 + web/gui/dashboard/static/js/5.29dab1cd.chunk.js | 3 + .../static/js/5.29dab1cd.chunk.js.LICENSE | 3 + .../dashboard/static/js/5.29dab1cd.chunk.js.map | 1 + web/gui/dashboard/static/js/5.8d493428.chunk.js | 3 - .../static/js/5.8d493428.chunk.js.LICENSE | 3 - .../dashboard/static/js/5.8d493428.chunk.js.map | 1 - web/gui/dashboard/static/js/6.7b15cdf3.chunk.js | 2 + .../dashboard/static/js/6.7b15cdf3.chunk.js.map | 1 + web/gui/dashboard/static/js/6.fd3732fc.chunk.js | 2 - .../dashboard/static/js/6.fd3732fc.chunk.js.map | 1 - web/gui/dashboard/static/js/7.c4cdb9f0.chunk.js | 2 - .../dashboard/static/js/7.c4cdb9f0.chunk.js.map | 1 - web/gui/dashboard/static/js/7.cf6bc66f.chunk.js | 2 + .../dashboard/static/js/7.cf6bc66f.chunk.js.map | 1 + web/gui/dashboard/static/js/8.11ff05e7.chunk.js | 2 - .../dashboard/static/js/8.11ff05e7.chunk.js.map | 1 - web/gui/dashboard/static/js/8.b1a4b595.chunk.js | 2 + .../dashboard/static/js/8.b1a4b595.chunk.js.map | 1 + web/gui/dashboard/static/js/9.50358509.chunk.js | 2 + .../dashboard/static/js/9.50358509.chunk.js.map | 1 + web/gui/dashboard/static/js/9.84b7c771.chunk.js | 2 - .../dashboard/static/js/9.84b7c771.chunk.js.map | 1 - web/gui/dashboard/static/js/main.485cc284.chunk.js | 3 + .../static/js/main.485cc284.chunk.js.LICENSE | 8 + .../dashboard/static/js/main.485cc284.chunk.js.map | 1 + web/gui/dashboard/static/js/main.e3f3d31b.chunk.js | 3 - .../static/js/main.e3f3d31b.chunk.js.LICENSE | 8 - .../dashboard/static/js/main.e3f3d31b.chunk.js.map | 1 - .../dashboard/static/js/runtime-main.b352aa47.js | 2 + .../static/js/runtime-main.b352aa47.js.map | 1 + .../dashboard/static/js/runtime-main.ec4d2459.js | 2 - .../static/js/runtime-main.ec4d2459.js.map | 1 - web/gui/dashboard_info.js | 1208 ++-- web/server/README.md | 4 +- web/server/static/README.md | 2 +- web/server/static/static-threaded.c | 2 +- web/server/web_client.c | 83 +- web/server/web_client.h | 3 - 718 files changed, 14231 insertions(+), 22668 deletions(-) delete mode 100644 .github/data/build-matrix.json create mode 100644 .github/data/distros.yml create mode 100755 .github/scripts/prepare-release-base.sh create mode 100644 .github/workflows/cloud_regression.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/trigger-learn-update.yml delete mode 100644 backends/Makefile.am delete mode 100644 backends/README.md delete mode 100644 backends/TIMESCALE.md delete mode 100644 backends/WALKTHROUGH.md delete mode 100644 backends/aws_kinesis/Makefile.am delete mode 100644 backends/aws_kinesis/README.md delete mode 100644 backends/aws_kinesis/aws_kinesis.c delete mode 100644 backends/aws_kinesis/aws_kinesis.conf delete mode 100644 backends/aws_kinesis/aws_kinesis.h delete mode 100644 backends/aws_kinesis/aws_kinesis_put_record.cc delete mode 100644 backends/aws_kinesis/aws_kinesis_put_record.h delete mode 100644 backends/backends.c delete mode 100644 backends/backends.h delete mode 100644 backends/graphite/Makefile.am delete mode 100644 backends/graphite/graphite.c delete mode 100644 backends/graphite/graphite.h delete mode 100644 backends/json/Makefile.am delete mode 100644 backends/json/json.c delete mode 100644 backends/json/json.h delete mode 100644 backends/mongodb/Makefile.am delete mode 100644 backends/mongodb/README.md delete mode 100644 backends/mongodb/mongodb.c delete mode 100644 backends/mongodb/mongodb.conf delete mode 100644 backends/mongodb/mongodb.h delete mode 100755 backends/nc-backend.sh delete mode 100644 backends/opentsdb/Makefile.am delete mode 100644 backends/opentsdb/README.md delete mode 100644 backends/opentsdb/opentsdb.c delete mode 100644 backends/opentsdb/opentsdb.h delete mode 100644 backends/prometheus/Makefile.am delete mode 100644 backends/prometheus/README.md delete mode 100644 backends/prometheus/backend_prometheus.c delete mode 100644 backends/prometheus/backend_prometheus.h delete mode 100644 backends/prometheus/remote_write/Makefile.am delete mode 100644 backends/prometheus/remote_write/README.md delete mode 100644 backends/prometheus/remote_write/remote_write.cc delete mode 100644 backends/prometheus/remote_write/remote_write.h delete mode 100644 backends/prometheus/remote_write/remote_write.proto delete mode 100644 collectors/node.d.plugin/fronius/Makefile.inc delete mode 100644 collectors/node.d.plugin/fronius/README.md delete mode 100644 collectors/node.d.plugin/fronius/fronius.node.js delete mode 100644 collectors/node.d.plugin/named/Makefile.inc delete mode 100644 collectors/node.d.plugin/named/README.md delete mode 100644 collectors/node.d.plugin/named/named.node.js delete mode 100644 collectors/node.d.plugin/sma_webbox/Makefile.inc delete mode 100644 collectors/node.d.plugin/sma_webbox/README.md delete mode 100644 collectors/node.d.plugin/sma_webbox/sma_webbox.node.js delete mode 100644 collectors/node.d.plugin/stiebeleltron/Makefile.inc delete mode 100644 collectors/node.d.plugin/stiebeleltron/README.md delete mode 100644 collectors/node.d.plugin/stiebeleltron/stiebeleltron.node.js create mode 100644 collectors/statsd.plugin/asterisk.conf create mode 100644 collectors/statsd.plugin/asterisk.md delete mode 100644 contrib/sles11/README.md delete mode 100755 contrib/sles11/alarm-notify-basic.bash3.sh delete mode 100644 contrib/sles11/netdata-alarms-bash3.patch delete mode 100644 contrib/sles11/netdata-automake-no-dist-xz.patch delete mode 100644 contrib/sles11/netdata-python-plugin-sles11.patch delete mode 100755 contrib/sles11/netdata.init delete mode 100644 health/health.d/backend.conf delete mode 100644 health/health.d/fronius.conf create mode 100644 health/health.d/nut.conf delete mode 100644 health/health.d/stiebeleltron.conf create mode 100644 ml/notebooks/README.md create mode 100644 ml/notebooks/netdata_anomaly_detection_deepdive.ipynb delete mode 100644 package-lock.json delete mode 100644 package.json create mode 100755 packaging/bundle-ebpf-co-re.sh create mode 100755 packaging/bundle-protobuf.sh create mode 100644 packaging/ebpf-co-re.checksums create mode 100644 packaging/ebpf-co-re.version create mode 100755 packaging/makeself/jobs/50-bash-5.1.16.install.sh delete mode 100755 packaging/makeself/jobs/50-bash-5.1.8.install.sh delete mode 100755 packaging/makeself/jobs/50-curl-7.78.0.install.sh create mode 100755 packaging/makeself/jobs/50-curl-7.82.0.install.sh delete mode 100755 packaging/makeself/jobs/50-fping-5.0.install.sh create mode 100755 packaging/makeself/jobs/50-fping-5.1.install.sh delete mode 100644 tests/README.md delete mode 100644 tests/backends/prometheus-avg-oldunits.txt delete mode 100644 tests/backends/prometheus-avg.txt delete mode 100644 tests/backends/prometheus-raw.txt delete mode 100755 tests/backends/prometheus.bats create mode 100644 tests/exporting/prometheus-avg-oldunits.txt create mode 100644 tests/exporting/prometheus-avg.txt create mode 100644 tests/exporting/prometheus-raw.txt create mode 100755 tests/exporting/prometheus.bats delete mode 100644 tests/node.d/fronius.chart.spec.js delete mode 100644 tests/node.d/fronius.parse.spec.js delete mode 100644 tests/node.d/fronius.process.spec.js delete mode 100644 tests/node.d/fronius.validation.spec.js delete mode 100644 tests/web/easypiechart.chart.spec.js delete mode 100644 tests/web/easypiechart.percentage.spec.js delete mode 100644 tests/web/fixtures/easypiechart.chart.fixture1.html delete mode 100644 tests/web/karma.conf.js delete mode 100644 tests/web/lib/jasmine-jquery.js create mode 100644 web/gui/dashboard/precache-manifest.34ebb83b69a8a6741865723124721c81.js delete mode 100644 web/gui/dashboard/precache-manifest.55bf0765e4092267255469aff90b2f26.js create mode 100644 web/gui/dashboard/static/css/main.102ce44c.chunk.css create mode 100644 web/gui/dashboard/static/css/main.102ce44c.chunk.css.map delete mode 100644 web/gui/dashboard/static/css/main.a46a34fa.chunk.css delete mode 100644 web/gui/dashboard/static/css/main.a46a34fa.chunk.css.map create mode 100644 web/gui/dashboard/static/js/10.44d9d40b.chunk.js create mode 100644 web/gui/dashboard/static/js/10.44d9d40b.chunk.js.map delete mode 100644 web/gui/dashboard/static/js/10.eb10af4d.chunk.js delete mode 100644 web/gui/dashboard/static/js/10.eb10af4d.chunk.js.map create mode 100644 web/gui/dashboard/static/js/2.d50fa4b3.chunk.js create mode 100644 web/gui/dashboard/static/js/2.d50fa4b3.chunk.js.LICENSE create mode 100644 web/gui/dashboard/static/js/2.d50fa4b3.chunk.js.map delete mode 100644 web/gui/dashboard/static/js/2.da522cd4.chunk.js delete mode 100644 web/gui/dashboard/static/js/2.da522cd4.chunk.js.LICENSE delete mode 100644 web/gui/dashboard/static/js/2.da522cd4.chunk.js.map delete mode 100644 web/gui/dashboard/static/js/3.6267b47a.chunk.js delete mode 100644 web/gui/dashboard/static/js/3.6267b47a.chunk.js.map create mode 100644 web/gui/dashboard/static/js/3.d49f0857.chunk.js create mode 100644 web/gui/dashboard/static/js/3.d49f0857.chunk.js.map delete mode 100644 web/gui/dashboard/static/js/4.89bcbd92.chunk.js delete mode 100644 web/gui/dashboard/static/js/4.89bcbd92.chunk.js.map create mode 100644 web/gui/dashboard/static/js/4.8b70c754.chunk.js create mode 100644 web/gui/dashboard/static/js/4.8b70c754.chunk.js.map create mode 100644 web/gui/dashboard/static/js/5.29dab1cd.chunk.js create mode 100644 web/gui/dashboard/static/js/5.29dab1cd.chunk.js.LICENSE create mode 100644 web/gui/dashboard/static/js/5.29dab1cd.chunk.js.map delete mode 100644 web/gui/dashboard/static/js/5.8d493428.chunk.js delete mode 100644 web/gui/dashboard/static/js/5.8d493428.chunk.js.LICENSE delete mode 100644 web/gui/dashboard/static/js/5.8d493428.chunk.js.map create mode 100644 web/gui/dashboard/static/js/6.7b15cdf3.chunk.js create mode 100644 web/gui/dashboard/static/js/6.7b15cdf3.chunk.js.map delete mode 100644 web/gui/dashboard/static/js/6.fd3732fc.chunk.js delete mode 100644 web/gui/dashboard/static/js/6.fd3732fc.chunk.js.map delete mode 100644 web/gui/dashboard/static/js/7.c4cdb9f0.chunk.js delete mode 100644 web/gui/dashboard/static/js/7.c4cdb9f0.chunk.js.map create mode 100644 web/gui/dashboard/static/js/7.cf6bc66f.chunk.js create mode 100644 web/gui/dashboard/static/js/7.cf6bc66f.chunk.js.map delete mode 100644 web/gui/dashboard/static/js/8.11ff05e7.chunk.js delete mode 100644 web/gui/dashboard/static/js/8.11ff05e7.chunk.js.map create mode 100644 web/gui/dashboard/static/js/8.b1a4b595.chunk.js create mode 100644 web/gui/dashboard/static/js/8.b1a4b595.chunk.js.map create mode 100644 web/gui/dashboard/static/js/9.50358509.chunk.js create mode 100644 web/gui/dashboard/static/js/9.50358509.chunk.js.map delete mode 100644 web/gui/dashboard/static/js/9.84b7c771.chunk.js delete mode 100644 web/gui/dashboard/static/js/9.84b7c771.chunk.js.map create mode 100644 web/gui/dashboard/static/js/main.485cc284.chunk.js create mode 100644 web/gui/dashboard/static/js/main.485cc284.chunk.js.LICENSE create mode 100644 web/gui/dashboard/static/js/main.485cc284.chunk.js.map delete mode 100644 web/gui/dashboard/static/js/main.e3f3d31b.chunk.js delete mode 100644 web/gui/dashboard/static/js/main.e3f3d31b.chunk.js.LICENSE delete mode 100644 web/gui/dashboard/static/js/main.e3f3d31b.chunk.js.map create mode 100644 web/gui/dashboard/static/js/runtime-main.b352aa47.js create mode 100644 web/gui/dashboard/static/js/runtime-main.b352aa47.js.map delete mode 100644 web/gui/dashboard/static/js/runtime-main.ec4d2459.js delete mode 100644 web/gui/dashboard/static/js/runtime-main.ec4d2459.js.map diff --git a/.dockerignore b/.dockerignore index 3e4e48b0b..60ea3668f 120000 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1,6 @@ -.gitignore \ No newline at end of file +.gitignore + +# Jupyter notebook checkpoints +.ipynb_checkpoints +# Jupyter notebooks +.ipynb \ No newline at end of file diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9aae48d57..fb371e4f7 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -5,63 +5,55 @@ * @Ferroin # Ownership by directory structure -.travis/ @Ferroin @iigorkarpov @maneamarius @kaskavel @vkalintiris -.github/ @Ferroin @iigorkarpov @maneamarius @kaskavel @vkalintiris +.travis/ @Ferroin @iigorkarpov @maneamarius +.github/ @Ferroin @iigorkarpov @maneamarius aclk/ @stelfrag @underhood -backends/ @thiagoftsm @vlvkobal -backends/graphite/ @thiagoftsm @vlvkobal -backends/json/ @thiagoftsm @vlvkobal -backends/opentsdb/ @thiagoftsm @vlvkobal -backends/prometheus/ @vlvkobal @thiagoftsm build/ @Ferroin @iigorkarpov @maneamarius -contrib/debian @Ferroin @iigorkarpov @maneamarius @vkalintiris -collectors/ @vlvkobal -collectors/charts.d.plugin/ @ilyam8 @Ferroin -collectors/freebsd.plugin/ @vlvkobal @thiagoftsm +contrib/debian @Ferroin @iigorkarpov @maneamarius +collectors/ @vlvkobal @surajnpn collectors/ebpf.plugin/ @thiagoftsm @vlvkobal -collectors/macos.plugin/ @vlvkobal @thiagoftsm +collectors/charts.d.plugin/ @ilyam8 @surajnpn @Ferroin +collectors/freebsd.plugin/ @vlvkobal @thiagoftsm @surajnpn +collectors/macos.plugin/ @vlvkobal @thiagoftsm @surajnpn collectors/node.d.plugin/ @jacekkolasa -collectors/node.d.plugin/fronius/ @ccremer collectors/node.d.plugin/snmp/ @jacekkolasa -collectors/node.d.plugin/stiebeleltron/ @ccremer collectors/python.d.plugin/ @ilyam8 collectors/cups.plugin/ @simonnagl @vlvkobal @thiagoftsm exporting/ @vlvkobal @thiagoftsm -daemon/ @thiagoftsm +daemon/ @thiagoftsm @vkalintiris database/ @thiagoftsm @vkalintiris docs/ @DShreve2 @kickoke health/ @thiagoftsm @vlvkobal @vkalintiris health/health.d/ @thiagoftsm @vlvkobal health/notifications/ @Ferroin @thiagoftsm ml/ @andrewm4894 @vkalintiris -libnetdata/ @thiagofsm -packaging/ @Ferroin @iigorkarpov @maneamarius @vkalintiris +libnetdata/ @thiagoftsm @vkalintiris +packaging/ @Ferroin @iigorkarpov @maneamarius registry/ @jacekkolasa streaming/ @thiagoftsm @vlvkobal -system/ @Ferroin @iigorkarpov @maneamarius @vkalintiris -tests/ @Ferroin @iigorkarpov @maneamarius @kaskavel @vkalintiris +system/ @Ferroin @iigorkarpov @maneamarius +tests/ @Ferroin @iigorkarpov @maneamarius @vkalintiris web/ @thiagoftsm @vlvkobal @vkalintiris web/gui/ @jacekkolasa # Ownership by filetype (overwrites ownership by directory) -*.am @Ferroin @iigorkarpov @maneamarius @vkalintiris +*.am @Ferroin @iigorkarpov @maneamarius *.md @DShreve2 @kickoke -Dockerfile* @Ferroin @iigorkarpov @maneamarius @vkalintiris +Dockerfile* @Ferroin @iigorkarpov @maneamarius # Ownership of specific files .gitignore @Ferroin @iigorkarpov @maneamarius @vkalintiris -.travis.yml @Ferroin @iigorkarpov @maneamarius @kaskavel @vkalintiris -.lgtm.yml @Ferroin @iigorkarpov @maneamarius @vkalintiris -.eslintrc @Ferroin @iigorkarpov @maneamarius @vkalintiris -.eslintignore @Ferroin @iigorkarpov @maneamarius @vkalintiris -.csslintrc @Ferroin @iigorkarpov @maneamarius @vkalintiris -.codeclimate.yml @Ferroin @iigorkarpov @maneamarius @vkalintiris -.codacy.yml @Ferroin @iigorkarpov @maneamarius @vkalintiris -.yamllint.yml @Ferroin @iigorkarpov @maneamarius @vkalintiris -netdata.spec.in @Ferroin @iigorkarpov @maneamarius @vkalintiris -netdata-installer.sh @Ferroin @iigorkarpov @maneamarius @vkalintiris -package.json @jacekkolasa @Ferroin @iigorkarpov @maneamarius @vkalintiris -packaging/version @netdatabot @Ferroin @iigorkarpov @maneamarius @vkalintiris +.travis.yml @Ferroin @iigorkarpov @maneamarius +.lgtm.yml @Ferroin @iigorkarpov @maneamarius +.eslintrc @Ferroin @iigorkarpov @maneamarius +.eslintignore @Ferroin @iigorkarpov @maneamarius +.csslintrc @Ferroin @iigorkarpov @maneamarius +.codeclimate.yml @Ferroin @iigorkarpov @maneamarius +.codacy.yml @Ferroin @iigorkarpov @maneamarius +.yamllint.yml @Ferroin @iigorkarpov @maneamarius +netdata.spec.in @Ferroin @iigorkarpov @maneamarius +netdata-installer.sh @Ferroin @iigorkarpov @maneamarius +packaging/version @netdatabot @Ferroin @iigorkarpov @maneamarius LICENSE.md @DShreve2 @Ferroin @vkalintiris -CHANGELOG.md @netdatabot @Ferroin @iigorkarpov @maneamarius @vkalintiris +CHANGELOG.md @netdatabot @Ferroin @iigorkarpov @maneamarius diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 74f9918e2..829d8e647 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,23 +1,27 @@ +##### Summary -##### Summary - ##### Test Plan - ##### Additional Information + + +
For users: How does this change affect me? + +
diff --git a/.github/data/build-matrix.json b/.github/data/build-matrix.json deleted file mode 100644 index 6ceb9fa54..000000000 --- a/.github/data/build-matrix.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "include": [ - { - "distro": "alpine:edge", - "artifact_key": "alpine-edge", - "pre": "apk add -U bash", - "rmjsonc": "apk del json-c-dev" - }, - { - "distro": "alpine:3.14", - "artifact_key": "alpine-3.14", - "pre": "apk add -U bash", - "rmjsonc": "apk del json-c-dev" - }, - { - "distro": "alpine:3.13", - "artifact_key": "alpine-3.13", - "pre": "apk add -U bash", - "rmjsonc": "apk del json-c-dev" - }, - { - "distro": "alpine:3.12", - "artifact_key": "alpine-3.12", - "pre": "apk add -U bash", - "rmjsonc": "apk del json-c-dev" - }, - { - "distro": "archlinux:latest", - "artifact_key": "archlinux", - "pre": "pacman --noconfirm -Syu && pacman --noconfirm -Sy grep libffi" - }, - { - "distro": "centos:7", - "artifact_key": "centos7" - }, - { - "distro": "rockylinux/rockylinux:8", - "artifact_key": "rockylinux8", - "rmjsonc": "dnf remove -y json-c-devel" - }, - { - "distro": "debian:11", - "artifact_key": "debian11", - "pre": "apt-get update", - "rmjsonc": "apt-get remove -y libjson-c-dev" - }, - { - "distro": "debian:10", - "artifact_key": "debian10", - "pre": "apt-get update", - "rmjsonc": "apt-get remove -y libjson-c-dev" - }, - { - "distro": "debian:9", - "artifact_key": "debian9", - "pre": "apt-get update", - "rmjsonc": "apt-get remove -y libjson-c-dev" - }, - { - "distro": "fedora:35", - "artifact_key": "fedora35", - "rmjsonc": "dnf remove -y json-c-devel" - }, - { - "distro": "fedora:34", - "artifact_key": "fedora34", - "rmjsonc": "dnf remove -y json-c-devel" - }, - { - "distro": "opensuse/leap:15.3", - "artifact_key": "opensuse15.3", - "rmjsonc": "zypper rm -y libjson-c-devel" - }, - { - "distro": "oraclelinux:8", - "artifact_key": "oraclelinux8", - "rmjsonc": "dnf remove -y json-c-devel" - }, - { - "distro": "ubuntu:21.10", - "artifact_key": "ubuntu21.10", - "pre": "rm -f /etc/apt/apt.conf.d/docker && apt-get update", - "rmjsonc": "apt-get remove -y libjson-c-dev" - }, - { - "distro": "ubuntu:20.04", - "artifact_key": "ubuntu20.04", - "pre": "apt-get update", - "rmjsonc": "apt-get remove -y libjson-c-dev" - }, - { - "distro": "ubuntu:18.04", - "artifact_key": "ubuntu18.04", - "pre": "apt-get update", - "rmjsonc": "apt-get remove -y libjson-c-dev" - } - ] -} diff --git a/.github/data/distros.yml b/.github/data/distros.yml new file mode 100644 index 000000000..8d58f4d23 --- /dev/null +++ b/.github/data/distros.yml @@ -0,0 +1,155 @@ +# This defines the full set of distros we run CI on. +--- +platform_map: # map packaging architectures to docker platforms + i386: linux/i386 + amd64: linux/amd64 + armhf: linux/arm/v7 + arm64: linux/arm64/v8 +include: + - &alpine + distro: alpine + version: edge + env_prep: | + apk add -U bash + jsonc_removal: | + apk del json-c-dev + - <<: *alpine + version: "3.15" + - <<: *alpine + version: "3.14" + - <<: *alpine + version: "3.13" + - <<: *alpine + version: "3.12" + + - distro: archlinux + version: latest + env_prep: | + pacman --noconfirm -Syu && pacman --noconfirm -Sy grep libffi + + - distro: rockylinux + version: "8" + base_image: rockylinux/rockylinux + jsonc_removal: | + dnf remove -y json-c-devel + packages: + type: rpm + repo_distro: el/8 + arches: + - amd64 + - arm64 + - distro: centos + version: "7" + packages: + type: rpm + repo_distro: el/7 + arches: + - amd64 + + - &debian + distro: debian + version: "11" + env_prep: | + apt-get update + jsonc_removal: | + apt-get purge -y libjson-c-dev + packages: &debian_packages + type: deb + repo_distro: debian/bullseye + arches: + - i386 + - amd64 + - armhf + - arm64 + - <<: *debian + version: "10" + packages: + <<: *debian_packages + repo_distro: debian/buster + - <<: *debian + version: "9" + packages: + <<: *debian_packages + repo_distro: debian/stretch + + - &fedora + distro: fedora + version: "36" + jsonc_removal: | + dnf remove -y json-c-devel + packages: &fedora_packages + type: rpm + repo_distro: fedora/36 + arches: + - amd64 + - armhf + - arm64 + - <<: *fedora + version: "35" + packages: + <<: *fedora_packages + repo_distro: fedora/35 + - <<: *fedora + version: "34" + packages: + <<: *fedora_packages + repo_distro: fedora/34 + + - &opensuse + distro: opensuse + version: "15.3" + base_image: opensuse/leap + jsonc_removal: | + zypper rm -y libjson-c-devel + packages: + type: rpm + repo_distro: opensuse/15.3 + arches: + - amd64 + - arm64 + + - distro: oraclelinux + version: "8" + jsonc_removal: | + dnf remove -y json-c-devel + packages: + type: rpm + repo_distro: ol/8 + arches: + - amd64 + - arm64 + + - &ubuntu + distro: ubuntu + version: "22.04" + env_prep: | + rm -f /etc/apt/apt.conf.d/docker && apt-get update + jsonc_removal: | + apt-get remove -y libjson-c-dev + packages: &ubuntu_packages + type: deb + repo_distro: ubuntu/jammy + arches: + - amd64 + - armhf + - arm64 + - <<: *ubuntu + version: "21.10" + packages: + <<: *ubuntu_packages + repo_distro: ubuntu/impish + - <<: *ubuntu + version: "20.04" + packages: + <<: *ubuntu_packages + repo_distro: ubuntu/focal + - <<: *ubuntu + version: "18.04" + packages: + <<: *ubuntu_packages + repo_distro: ubuntu/bionic + arches: + - i386 + - amd64 + - armhf + - arm64 diff --git a/.github/dockerfiles/Dockerfile.build_test b/.github/dockerfiles/Dockerfile.build_test index 50cfdee06..c275d61d6 100644 --- a/.github/dockerfiles/Dockerfile.build_test +++ b/.github/dockerfiles/Dockerfile.build_test @@ -6,7 +6,7 @@ ARG PRE ENV PRE=${PRE} ARG RMJSONC ENV RMJSONC=${RMJSONC} -ENV DO_NOT_TRACK=1 +ENV DISABLE_TELEMETRY=1 ENV GITHUB_ACTIONS=true RUN echo "${PRE}" > /prep-cmd.sh && \ diff --git a/.github/labeler.yml b/.github/labeler.yml index 4c0d857de..d576b937d 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -15,10 +15,6 @@ ACLK: - aclk/**/* - mqtt_websockets -area/backends: - - backends/* - - backends/**/* - area/claim: - claim/* @@ -42,10 +38,6 @@ area/ci: - .github/* - .github/**/* -area/collectors: - - collectors/* - - collectors/**/* - area/daemon: - daemon/* - daemon/**/* @@ -60,16 +52,106 @@ area/docs: - diagrams/* - diagrams/**/* -area/external/python: - - collectors/python.d.plugin/* - - collectors/python.d.plugin/**/* +# -----------------collectors---------------------- + +area/collectors: + - collectors/* + - collectors/**/* + +collectors/plugins.d: + - collectors/plugins.d/* + - collectors/plugins.d/**/* + +collectors/apps: + - collectors/apps.plugin/* + - collectors/apps.plugin/**/* + +collectors/cgroups: + - collectors/cgroups.plugin/* + - collectors/cgroups.plugin/**/* -area/external: +collectors/charts.d: - collectors/charts.d.plugin/* - collectors/charts.d.plugin/**/* + +collectors/cups: + - collectors/cups.plugin/* + - collectors/cups.plugin/**/* + +collectors/diskspace: + - collectors/diskspace.plugin/* + - collectors/diskspace.plugin/**/* + +collectors/ebpf: + - collectors/ebpf.plugin/* + - collectors/ebpf.plugin/**/* + +collectors/fping: + - collectors/fping.plugin/* + - collectors/fping.plugin/**/* + +collectors/freebsd: + - collectors/freebsd.plugin/* + - collectors/freebsd.plugin/**/* + +collectors/freeipmi: + - collectors/freeipmi.plugin/* + - collectors/freeipmi.plugin/**/* + +collectors/idlejitter: + - collectors/idlejitter.plugin/* + - collectors/idlejitter.plugin/**/* + +collectors/ioping: + - collectors/ioping.plugin/* + - collectors/ioping.plugin/**/* + +collectors/macos: + - collectors/macos.plugin/* + - collectors/macos.plugin/**/* + +collectors/nfacct: + - collectors/nfacct.plugin/* + - collectors/nfacct.plugin/**/* + +collectors/node.d: - collectors/node.d.plugin/* - collectors/node.d.plugin/**/* +collectors/perf: + - collectors/perf.plugin/* + - collectors/perf.plugin/**/* + +collectors/proc: + - collectors/proc.plugin/* + - collectors/proc.plugin/**/* + +collectors/python.d: + - collectors/python.d.plugin/* + - collectors/python.d.plugin/**/* + +collectors/slabinfo: + - collectors/slabinfo.plugin/* + - collectors/slabinfo.plugin/**/* + +collectors/statsd: + - collectors/statsd.plugin/* + - collectors/statsd.plugin/**/* + +collectors/tc: + - collectors/tc.plugin/* + - collectors/tc.plugin/**/* + +collectors/timex: + - collectors/timex.plugin/* + - collectors/timex.plugin/**/* + +collectors/xenstat: + - collectors/xenstat.plugin/* + - collectors/xenstat.plugin/**/* + +# ----------------/collectors---------------------- + area/health: - health/* - health/**/* diff --git a/.github/scripts/docker-test.sh b/.github/scripts/docker-test.sh index 795711b1a..22821d17e 100755 --- a/.github/scripts/docker-test.sh +++ b/.github/scripts/docker-test.sh @@ -33,7 +33,9 @@ wait_for() { printf "OK\n" } -apt-get update && apt-get upgrade -y && apt get install -y netcat +if [ -z "$(command -v nc 2>/dev/null)" ] && [ -z "$(command -v netcat 2>/dev/null)" ]; then + sudo apt-get update && sudo apt-get upgrade -y && sudo apt-get install -y netcat +fi docker run -d --name=netdata \ -p 19999:19999 \ diff --git a/.github/scripts/prepare-release-base.sh b/.github/scripts/prepare-release-base.sh new file mode 100755 index 000000000..cb6be8e7c --- /dev/null +++ b/.github/scripts/prepare-release-base.sh @@ -0,0 +1,177 @@ +#!/bin/sh + +set -e + +REPO="${1}" +EVENT_NAME="${2}" +EVENT_TYPE="${3}" +EVENT_VERSION="${4}" + +############################################################## +# Version validation functions + +check_version_format() { + if ! echo "${EVENT_VERSION}" | grep -qE '^v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+$'; then + echo "::error::The supplied version (${EVENT_VERSION}) is not a valid version string." + return 1 + fi +} + +patch_is_zero() { + if ! echo "${EVENT_VERSION}" | grep -qE '^v[[:digit:]]+\.[[:digit:]]+\.0$'; then + echo "::error::The patch number for a ${EVENT_TYPE} build must be 0." + return 1 + fi +} + +minor_is_zero() { + if ! echo "${EVENT_VERSION}" | grep -qE '^v[[:digit:]]+\.0'; then + echo "::error::The minor version number for a ${EVENT_TYPE} build must be 0." + return 1 + fi +} + +major_matches() { + current_major="$(cut -f 1 -d '-' packaging/version | cut -f 1 -d '.' | cut -f 2 -d 'v')" + target_major="$(echo "${EVENT_VERSION}" | cut -f 1 -d '.' | cut -f 2 -d 'v')" + + if [ "${target_major}" != "${current_major}" ]; then + echo "::error::Major version mismatch, expected ${current_major} but got ${target_major}." + return 1 + fi +} + +minor_matches() { + current_minor="$(cut -f 1 -d '-' packaging/version | cut -f 2 -d '.')" + target_minor="$(echo "${EVENT_VERSION}" | cut -f 2 -d '.')" + + if [ "${target_minor}" != "${current_minor}" ]; then + echo "::error::Minor version mismatch, expected ${current_minor} but got ${target_minor}." + return 1 + fi +} + +check_for_existing_tag() { + if git tag | grep -qE "^${EVENT_VERSION}$"; then + echo "::error::A tag for version ${EVENT_VERSION} already exists." + return 1 + fi +} + +check_newer_major_version() { + current="$(cut -f 1 -d '-' packaging/version | cut -f 1 -d '.' | cut -f 2 -d 'v')" + target="$(echo "${EVENT_VERSION}" | cut -f 1 -d '.' | cut -f 2 -d 'v')" + + if [ "${target}" -le "${current}" ]; then + echo "::error::Version ${EVENT_VERSION} is not newer than the current version." + return 1 + fi +} + +check_newer_minor_version() { + current="$(cut -f 1 -d '-' packaging/version | cut -f 2 -d '.')" + target="$(echo "${EVENT_VERSION}" | cut -f 2 -d '.')" + + if [ "${target}" -le "${current}" ]; then + echo "::error::Version ${EVENT_VERSION} is not newer than the current version." + return 1 + fi +} + +check_newer_patch_version() { + current="$(cut -f 1 -d '-' packaging/version | cut -f 3 -d '.')" + target="$(echo "${EVENT_VERSION}" | cut -f 3 -d '.')" + + if [ "${target}" -le "${current}" ]; then + echo "::error::Version ${EVENT_VERSION} is not newer than the current version." + return 1 + fi +} + +############################################################## +# Core logic + +git config user.name "netdatabot" +git config user.email "bot@netdata.cloud" + +if [ "${REPO}" != "netdata/netdata" ]; then + echo "::notice::Not running in the netdata/netdata repository, not queueing a release build." + echo "::set-output name=run::false" +elif [ "${EVENT_NAME}" = 'schedule' ] || [ "${EVENT_TYPE}" = 'nightly' ]; then + echo "::notice::Preparing a nightly release build." + LAST_TAG=$(git describe --abbrev=0 --tags) + COMMITS_SINCE_RELEASE=$(git rev-list "${LAST_TAG}"..HEAD --count) + NEW_VERSION="${LAST_TAG}-$((COMMITS_SINCE_RELEASE + 1))-nightly" + LAST_VERSION_COMMIT="$(git rev-list -1 HEAD packaging/version)" + HEAD_COMMIT="$(git rev-parse HEAD)" + if [ "${EVENT_NAME}" = 'schedule' ] && [ "${LAST_VERSION_COMMIT}" = "${HEAD_COMMIT}" ] && grep -qE '.*-nightly$' packaging/version; then + echo "::notice::No commits since last nightly build, not publishing a new nightly build." + echo "::set-output name=run::false" + else + echo "${NEW_VERSION}" > packaging/version || exit 1 + echo "::set-output name=run::true" + echo "::set-output name=message::Update changelog and version for nightly build: ${NEW_VERSION}." + echo "::set-output name=ref::master" + echo "::set-output name=type::nightly" + echo "::set-output name=branch::master" + echo "::set-output name=version::nightly" + fi +elif [ "${EVENT_TYPE}" = 'patch' ] && [ "${EVENT_VERSION}" != "nightly" ]; then + echo "::notice::Preparing a patch release build." + check_version_format || exit 1 + check_for_existing_tag || exit 1 + branch_name="$(echo "${EVENT_VERSION}" | cut -f 1-2 -d '.')" + if [ -z "$(git branch --list "${branch_name}")" ]; then + echo "::error::Could not find a branch for the ${branch_name}.x release series." + exit 1 + fi + git checkout "${branch_name}" + minor_matches || exit 1 + major_matches || exit 1 + check_newer_patch_number || exit 1 + echo "${EVENT_VERSION}" > packaging/version || exit 1 + echo "::set-output name=run::true" + echo "::set-output name=message::Patch release ${EVENT_VERSION}." + echo "::set-output name=ref::${EVENT_VERSION}" + echo "::set-output name=type::release" + echo "::set-output name=branch::${branch_name}" + echo "::set-output name=version::$(tr -d 'v' < packaging/version)" +elif [ "${EVENT_TYPE}" = 'minor' ] && [ "${EVENT_VERSION}" != "nightly" ]; then + echo "::notice::Preparing a minor release build." + check_version_format || exit 1 + patch_is_zero || exit 1 + major_matches || exit 1 + check_newer_minor_version || exit 1 + check_for_existing_tag || exit 1 + branch_name="$(echo "${EVENT_VERSION}" | cut -f 1-2 -d '.')" + if [ -n "$(git branch --list "${branch_name}")" ]; then + echo "::error::A branch named ${branch_name} already exists in the repository." + exit 1 + fi + git branch "${branch_name}" + git checkout "${branch_name}" + echo "${EVENT_VERSION}" > packaging/version || exit 1 + echo "::set-output name=run::true" + echo "::set-output name=message::Minor release ${EVENT_VERSION}." + echo "::set-output name=ref::${EVENT_VERSION}" + echo "::set-output name=type::release" + echo "::set-output name=branch::${branch_name}" + echo "::set-output name=version::$(tr -d 'v' < packaging/version)" +elif [ "${EVENT_TYPE}" = 'major' ] && [ "${EVENT_VERSION}" != "nightly" ]; then + echo "::notice::Preparing a major release build." + check_version_format || exit 1 + minor_is_zero || exit 1 + patch_is_zero || exit 1 + check_newer_major_version || exit 1 + check_for_existing_tag || exit 1 + echo "${EVENT_VERSION}" > packaging/version || exit 1 + echo "::set-output name=run::true" + echo "::set-output name=message::Major release ${EVENT_VERSION}" + echo "::set-output name=ref::${EVENT_VERSION}" + echo "::set-output name=type::release" + echo "::set-output name=branch::master" + echo "::set-output name=version::$(tr -d 'v' < packaging/version)" +else + echo '::error::Unrecognized release type or invalid version.' + exit 1 +fi diff --git a/.github/scripts/run_install_with_dist_file.sh b/.github/scripts/run_install_with_dist_file.sh index 18cf80927..83559f267 100755 --- a/.github/scripts/run_install_with_dist_file.sh +++ b/.github/scripts/run_install_with_dist_file.sh @@ -29,7 +29,7 @@ printf >&2 "Entering %s and starting docker run ..." "${distdir}" pushd "${distdir}" || exit 1 docker run \ - -e DO_NOT_TRACK=1 \ + -e DISABLE_TELEMETRY=1 \ -v "${PWD}:/netdata" \ -w /netdata \ "ubuntu:latest" \ diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index abf08c2ea..caa49e290 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,7 +17,7 @@ on: default: nightly required: true concurrency: # This keeps multiple instances of the job from running concurrently for the same ref and event type. - group: release-${{ github.ref }}-${{ github.event_name }} + group: build-${{ github.ref }}-${{ github.event_name }} cancel-in-progress: true jobs: build-dist: # Build the distribution tarball and store it as an artifact. @@ -27,11 +27,13 @@ jobs: distfile: ${{ steps.build.outputs.distfile }} steps: - name: Checkout - uses: actions/checkout@v2 + id: checkout + uses: actions/checkout@v3 with: fetch-depth: 0 submodules: recursive - name: Mark Stable + id: channel if: github.event_name == 'workflow_dispatch' && github.event.inputs.type != 'nightly' run: | sed -i 's/^RELEASE_CHANNEL="nightly" *#/RELEASE_CHANNEL="stable" #/' netdata-installer.sh @@ -52,7 +54,8 @@ jobs: echo "::set-output name=distfile::$(find . -name 'netdata-*.tar.gz')" cp netdata-*.tar.gz artifacts/ - name: Store - uses: actions/upload-artifact@v2 + id: store + uses: actions/upload-artifact@v3 with: name: dist-tarball path: artifacts/*.tar.gz @@ -63,9 +66,14 @@ jobs: SLACK_COLOR: 'danger' SLACK_FOOTER: '' SLACK_ICON_EMOJI: ':github-actions:' - SLACK_TITLE: 'Distribution tarball build failed:' + SLACK_TITLE: 'Distribution tarball creation failed:' SLACK_USERNAME: 'GitHub Actions' - SLACK_MESSAGE: "Distribution tarball build failed." + SLACK_MESSAGE: |- + ${{ github.repository }}: Failed to create source tarball for distribution. + Checkout: ${{ steps.checkout.outcome }} + Mark stable: ${{ steps.channel.outcome }} + Build: ${{ steps.build.outcome }} + Store: ${{ steps.store.outcome }} SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} if: >- ${{ @@ -86,18 +94,22 @@ jobs: - 'ppc64le' steps: - name: Checkout - uses: actions/checkout@v2 + id: checkout + uses: actions/checkout@v3 with: fetch-depth: 0 submodules: recursive - name: Mark Stable + id: channel if: github.event_name == 'workflow_dispatch' && github.event.inputs.type != 'nightly' run: | sed -i 's/^RELEASE_CHANNEL="nightly" *#/RELEASE_CHANNEL="stable" #/' netdata-installer.sh packaging/makeself/install-or-update.sh - name: Build + id: build run: .github/scripts/build-static.sh ${{ matrix.arch }} - name: Store - uses: actions/upload-artifact@v2 + id: store + uses: actions/upload-artifact@v3 with: name: static-archive path: artifacts/*.gz.run @@ -108,9 +120,14 @@ jobs: SLACK_COLOR: 'danger' SLACK_FOOTER: '' SLACK_ICON_EMOJI: ':github-actions:' - SLACK_TITLE: 'Static build for ${{ matrix.arch }} failed:' + SLACK_TITLE: 'Static build failed:' SLACK_USERNAME: 'GitHub Actions' - SLACK_MESSAGE: "Static build for ${{ matrix.arch }} failed." + SLACK_MESSAGE: |- + ${{ github.repository }}: Failed to create static installer archive for ${{ matrix.arch }}. + Checkout: ${{ steps.checkout.outcome }} + Mark stable: ${{ steps.channel.outcome }} + Build: ${{ steps.build.outcome }} + Store: ${{ steps.store.outcome }} SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} if: >- ${{ @@ -126,33 +143,112 @@ jobs: matrix: ${{ steps.set-matrix.outputs.matrix }} steps: - name: Checkout - uses: actions/checkout@v2 + id: checkout + uses: actions/checkout@v3 - name: Prepare tools + id: prepare run: | - sudo apt-get update && sudo apt-get install -y jq + sudo apt-get update && sudo apt-get install -y python3-ruamel.yaml - name: Read build matrix id: set-matrix + shell: python3 {0} run: | - TASKS="$(jq -c . .github/data/build-matrix.json)" - echo "Generated Matrix: $TASKS" - echo "::set-output name=matrix::$TASKS" + from ruamel.yaml import YAML + import json + yaml = YAML(typ='safe') + with open('.github/data/distros.yml') as f: + data = yaml.load(f) + del data['platform_map'] + for i, v in enumerate(data['include']): + data['include'][i]['artifact_key'] = data['include'][i]['distro'] + str(data['include'][i]['version']).replace('.', '') + if 'packages' in data['include'][i]: + del data['include'][i]['packages'] + if 'base_image' in data['include'][i]: + data['include'][i]['distro'] = data['include'][i]['base_image'] + del data['include'][i]['base_image'] + data['include'][i]['distro'] = ':'.join([data['include'][i]['distro'], str(data['include'][i]['version'])]) + del data['include'][i]['version'] + matrix = json.dumps(data, sort_keys=True) + print('Generated Matrix: ' + matrix) + print('::set-output name=matrix::' + matrix) + - name: Failure Notification + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_COLOR: 'danger' + SLACK_FOOTER: '' + SLACK_ICON_EMOJI: ':github-actions:' + SLACK_TITLE: 'Build matrix preparation failed:' + SLACK_USERNAME: 'GitHub Actions' + SLACK_MESSAGE: |- + ${{ github.repository }}: Failed to prepare build matrix for build checks. + Checkout: ${{ steps.checkout.outcome }} + Prepare tools: ${{ steps.prepare.outcome }} + Read build matrix: ${{ steps.set-matrix.outcome }} + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} + if: >- + ${{ + failure() + && startsWith(github.ref, 'refs/heads/master') + && github.event_name != 'pull_request' + }} prepare-test-images: # Prepare the test environments for our build checks. This also checks dependency handling code for each tested environment. name: Prepare Test Environments runs-on: ubuntu-latest needs: - matrix + env: + RETRY_DELAY: 300 strategy: # Unlike the actal build tests, this completes _very_ fast (average of about 3 minutes for each job), so we # just run everything in parallel instead lof limiting job concurrency. fail-fast: false matrix: ${{ fromJson(needs.matrix.outputs.matrix) }} steps: - - name: Git clone repository - uses: actions/checkout@v2 + - name: Checkout + id: checkout + uses: actions/checkout@v3 - name: Setup Buildx + id: buildx uses: docker/setup-buildx-action@v1 - name: Build test environment + id: build1 + uses: docker/build-push-action@v2 + continue-on-error: true # We retry 3 times at 5 minute intervals if there is a failure here. + with: + push: false + load: false + file: .github/dockerfiles/Dockerfile.build_test + build-args: | + BASE=${{ matrix.distro }} + PRE=${{ matrix.env_prep }} + RMJSONC=${{ matrix.jsonc_removal }} + outputs: type=oci,dest=/tmp/image.tar + tags: test:${{ matrix.artifact_key }} + - name: Retry delay + if: ${{ steps.build1.outcome }} == 'failure' + run: sleep "${RETRY_DELAY}" + - name: Build test environment (attempt 2) + if: ${{ steps.build1.outcome }} == 'failure' + id: build2 + uses: docker/build-push-action@v2 + continue-on-error: true # We retry 3 times at 5 minute intervals if there is a failure here. + with: + push: false + load: false + file: .github/dockerfiles/Dockerfile.build_test + build-args: | + BASE=${{ matrix.distro }} + PRE=${{ matrix.env_prep }} + RMJSONC=${{ matrix.jsonc_removal }} + outputs: type=oci,dest=/tmp/image.tar + tags: test:${{ matrix.artifact_key }} + - name: Retry delay + if: ${{ steps.build1.outcome }} == 'failure' && ${{ steps.build2.outcome }} == 'failure' + run: sleep "${RETRY_DELAY}" + - name: Build test environment (attempt 3) + if: ${{ steps.build1.outcome }} == 'failure' && ${{ steps.build2.outcome }} == 'failure' + id: build3 uses: docker/build-push-action@v2 with: push: false @@ -160,12 +256,13 @@ jobs: file: .github/dockerfiles/Dockerfile.build_test build-args: | BASE=${{ matrix.distro }} - PRE=${{ matrix.pre }} - RMJSONC=${{ matrix.rmjsonc }} + PRE=${{ matrix.env_prep }} + RMJSONC=${{ matrix.jsonc_removal }} outputs: type=oci,dest=/tmp/image.tar tags: test:${{ matrix.artifact_key }} - name: Upload image artifact - uses: actions/upload-artifact@v2 + id: upload + uses: actions/upload-artifact@v3 with: name: ${{ matrix.artifact_key }}-test-env path: /tmp/image.tar @@ -178,7 +275,14 @@ jobs: SLACK_ICON_EMOJI: ':github-actions:' SLACK_TITLE: 'Test environment preparation for ${{ matrix.distro }} failed:' SLACK_USERNAME: 'GitHub Actions' - SLACK_MESSAGE: "Test environment preparation for ${{ matrix.distro }} failed." + SLACK_MESSAGE: |- + ${{ github.repository }}: Test environment preparation for ${{ matrix.distro }} failed. + Checkout: ${{ steps.checkout.outcome }} + Set up Buildx: ${{ steps.buildx.outcome }} + Build test environment: ${{ steps.build1.outcome }} + Build test environment (attempt 2): ${{ steps.build2.outcome }} + Build test environment (attempt 3): ${{ steps.build3.outcome }} + Upload: ${{ steps.upload.outcome }} SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} if: >- ${{ @@ -198,12 +302,14 @@ jobs: max-parallel: 8 matrix: ${{ fromJson(needs.matrix.outputs.matrix) }} steps: - - name: Git clone repository - uses: actions/checkout@v2 + - name: Checkout + id: checkout + uses: actions/checkout@v3 with: submodules: recursive - name: Fetch test environment - uses: actions/download-artifact@v2 + id: fetch + uses: actions/download-artifact@v3 with: name: ${{ matrix.artifact_key }}-test-env - name: Load test environment @@ -212,19 +318,23 @@ jobs: docker load --input image.tar | tee image-info.txt echo "::set-output name=image::$(cut -d ':' -f 3 image-info.txt)" - name: Regular build on ${{ matrix.distro }} + id: build-basic run: | docker run --security-opt seccomp=unconfined -w /netdata sha256:${{ steps.load.outputs.image }} \ /bin/sh -c 'autoreconf -ivf && ./configure && make -j2' - name: netdata-installer on ${{ matrix.distro }}, disable cloud + id: build-no-cloud run: | docker run --security-opt seccomp=unconfined -w /netdata sha256:${{ steps.load.outputs.image }} \ /bin/sh -c './netdata-installer.sh --dont-wait --dont-start-it --disable-cloud' - name: netdata-installer on ${{ matrix.distro }}, require cloud + id: build-cloud run: | docker run --security-opt seccomp=unconfined -w /netdata sha256:${{ steps.load.outputs.image }} \ /bin/sh -c './netdata-installer.sh --dont-wait --dont-start-it --require-cloud' - name: netdata-installer on ${{ matrix.distro }}, require cloud, no JSON-C - if: matrix.rmjsonc != '' + id: build-no-jsonc + if: matrix.jsonc_removal != '' run: | docker run --security-opt seccomp=unconfined -w /netdata sha256:${{ steps.load.outputs.image }} \ /bin/sh -c '/rmjsonc.sh && ./netdata-installer.sh --dont-wait --dont-start-it --require-cloud' @@ -236,7 +346,15 @@ jobs: SLACK_ICON_EMOJI: ':github-actions:' SLACK_TITLE: 'Build tests for ${{ matrix.distro }} failed:' SLACK_USERNAME: 'GitHub Actions' - SLACK_MESSAGE: "Build tests for ${{ matrix.distro }} failed." + SLACK_MESSAGE: |- + ${{ github.repository }}: Build tests for ${{ matrix.distro }} failed. + Checkout: ${{ steps.checkout.outcome }} + Fetch test environment: ${{ steps.fetch.outcome }} + Load test environment: ${{ steps.load.outcome }} + Regular build: ${{ steps.build-basic.outcome }} + netdata-installer, disable cloud: ${{ steps.build-no-cloud.outcome }} + netdata-installer, require cloud: ${{ steps.build-cloud.outcome }} + netdata-installer, no JSON-C: ${{ steps.build-no-jsonc.outcome }} SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} if: >- ${{ @@ -265,13 +383,16 @@ jobs: - ${{ github.workspace }}:/usr/local/apache2/htdocs/ steps: - name: Checkout - uses: actions/checkout@v2 + id: checkout + uses: actions/checkout@v3 - name: Fetch dist tarball artifacts - uses: actions/download-artifact@v2 + id: fetch-tarball + uses: actions/download-artifact@v3 with: name: dist-tarball path: dist-tarball - name: Prepare artifact directory + id: prepare run: | mkdir -p artifacts || exit 1 echo "9999.0.0-0" > artifacts/latest-version.txt || exit 1 @@ -281,7 +402,8 @@ jobs: sha256sum -b ./* > "sha256sums.txt" || exit 1 cat sha256sums.txt - name: Fetch test environment - uses: actions/download-artifact@v2 + id: fetch-test-environment + uses: actions/download-artifact@v3 with: name: ${{ matrix.artifact_key }}-test-env - name: Load test environment @@ -290,8 +412,9 @@ jobs: docker load --input image.tar | tee image-info.txt echo "::set-output name=image::$(cut -d ':' -f 3 image-info.txt)" - name: Install netdata and run the updater on ${{ matrix.distro }} + id: updater-check run: | - docker run --security-opt seccomp=unconfined -e DO_NOT_TRACK=1 --network host -w /netdata sha256:${{ steps.load.outputs.image }} \ + docker run --security-opt seccomp=unconfined -e DISABLE_TELEMETRY=1 --network host -w /netdata sha256:${{ steps.load.outputs.image }} \ /netdata/.github/scripts/run-updater-check.sh - name: Failure Notification uses: rtCamp/action-slack-notify@v2 @@ -301,7 +424,14 @@ jobs: SLACK_ICON_EMOJI: ':github-actions:' SLACK_TITLE: 'Updater checks for ${{ matrix.distro }} failed:' SLACK_USERNAME: 'GitHub Actions' - SLACK_MESSAGE: "Updater checks for ${{ matrix.distro }} failed." + SLACK_MESSAGE: |- + ${{ github.repository }}: Updater checks for ${{ matrix.distro }} failed. + Checkout: ${{ steps.checkout.outcome }} + Fetch dist tarball: ${{ steps.fetch-tarball.outcome }} + Prepare artifact directory: ${{ steps.prepare.outcome }} + Fetch test environment: ${{ steps.fetch-test-environment.outcome }} + Load test environment: ${{ steps.load.outcome }} + Updater check: ${{ steps.updater-check.outcome }} SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} if: >- ${{ @@ -318,20 +448,25 @@ jobs: - build-static steps: - name: Checkout - uses: actions/checkout@v2 + id: checkout + uses: actions/checkout@v3 - name: Prepare Environment + id: prepare run: mkdir -p artifacts - name: Retrieve Dist Tarball - uses: actions/download-artifact@v2 + id: fetch-dist + uses: actions/download-artifact@v3 with: name: dist-tarball path: dist-tarball - name: Retrieve Static Build Artifacts - uses: actions/download-artifact@v2 + id: fetch-static + uses: actions/download-artifact@v3 with: name: static-archive path: static-archive - name: Prepare Artifacts + id: consolidate working-directory: ./artifacts/ run: | mv ../dist-tarball/* . || exit 1 @@ -341,7 +476,8 @@ jobs: sha256sum -b ./* > sha256sums.txt || exit 1 cat sha256sums.txt - name: Store Artifacts - uses: actions/upload-artifact@v2 + id: store + uses: actions/upload-artifact@v3 with: name: final-artifacts path: artifacts/* @@ -354,7 +490,14 @@ jobs: SLACK_ICON_EMOJI: ':github-actions:' SLACK_TITLE: 'Failed to prepare release artifacts for upload:' SLACK_USERNAME: 'GitHub Actions' - SLACK_MESSAGE: "Failed to prepare release artifacts for upload." + SLACK_MESSAGE: |- + ${{ github.repository }}: Failed to prepare release artifacts for upload. + CHeckout: ${{ steps.checkout.outcome }} + Prepare environment: ${{ steps.prepare.outcome }} + Fetch dist tarball: ${{ steps.fetch-dist.outcome }} + Fetch static builds: ${{ steps.fetch-static.outcome }} + Consolidate artifacts: ${{ steps.consolidate.outcome }} + Store: ${{ steps.store.outcome }} SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} if: >- ${{ @@ -377,13 +520,16 @@ jobs: - ${{ github.workspace }}:/usr/local/apache2/htdocs/ steps: - name: Checkout - uses: actions/checkout@v2 + id: checkout + uses: actions/checkout@v3 - name: Fetch artifacts - uses: actions/download-artifact@v2 + id: fetch + uses: actions/download-artifact@v3 with: name: final-artifacts path: artifacts - name: Verify that artifacts work with installer + id: verify env: NETDATA_TARBALL_BASEURL: http://localhost:8080/artifacts run: packaging/installer/kickstart.sh --build-only --dont-start-it --disable-telemetry --dont-wait @@ -395,7 +541,11 @@ jobs: SLACK_ICON_EMOJI: ':github-actions:' SLACK_TITLE: 'Artifact verification for source tarball failed.' SLACK_USERNAME: 'GitHub Actions' - SLACK_MESSAGE: "Artifact verification for source tarball failed." + SLACK_MESSAGE: |- + ${{ github.repository }}: Artifact verification for source tarball failed. + Checkout: ${{ steps.checkout.outcome }} + Fetch artifacts: ${{ steps.fetch.outcome }} + Verify artifacts: ${{ steps.verify.outcome }} SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} if: >- ${{ @@ -418,13 +568,16 @@ jobs: - ${{ github.workspace }}:/usr/local/apache2/htdocs/ steps: - name: Checkout - uses: actions/checkout@v2 + id: checkout + uses: actions/checkout@v3 - name: Fetch artifacts - uses: actions/download-artifact@v2 + id: fetch-artifacts + uses: actions/download-artifact@v3 with: name: final-artifacts path: artifacts - name: Verify that artifacts work with installer + id: verify env: NETDATA_TARBALL_BASEURL: http://localhost:8080/artifacts run: packaging/installer/kickstart.sh --static-only --dont-start-it --disable-telemetry @@ -436,7 +589,11 @@ jobs: SLACK_ICON_EMOJI: ':github-actions:' SLACK_TITLE: 'Artifact verification for static build failed.' SLACK_USERNAME: 'GitHub Actions' - SLACK_MESSAGE: "Artifact verification for static build failed." + SLACK_MESSAGE: |- + ${{ github.repository }}: Artifact verification for static build failed. + Checkout: ${{ steps.checkout.outcome }} + Fetch artifacts: ${{ steps.fetch-artifacts.outcome }} + Verify artifacts: ${{ steps.verify.outcome }} SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} if: >- ${{ @@ -456,18 +613,21 @@ jobs: - artifact-verification-static steps: - name: Retrieve Artifacts - uses: actions/download-artifact@v2 + id: fetch + uses: actions/download-artifact@v3 with: name: final-artifacts path: final-artifacts - name: Setup Gcloud - uses: google-github-actions/setup-gcloud@v0.5.0 + id: gcloud + uses: google-github-actions/setup-gcloud@v0.6.0 with: project_id: ${{ secrets.GCP_NIGHTLY_STORAGE_PROJECT }} service_account_key: ${{ secrets.GCP_STORAGE_SERVICE_ACCOUNT_KEY }} export_default_credentials: true - name: Upload Artifacts - uses: google-github-actions/upload-cloud-storage@v0.5.0 + id: upload + uses: google-github-actions/upload-cloud-storage@v0.9.0 with: destination: ${{ secrets.GCP_NIGHTLY_STORAGE_BUCKET }} gzip: false @@ -481,7 +641,11 @@ jobs: SLACK_ICON_EMOJI: ':github-actions:' SLACK_TITLE: 'Failed to upload nightly release artifacts:' SLACK_USERNAME: 'GitHub Actions' - SLACK_MESSAGE: "Failed to upload nightly release artifacts." + SLACK_MESSAGE: |- + ${{ github.repository }}: Failed to upload nightly release artifacts. + Fetch artifacts: ${{ steps.fetch.outcome }} + Setup GCloud: ${{ steps.gcloud.outcome }} + Upload artifacts: ${{ steps.upload.outcome }} SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} if: >- ${{ @@ -501,13 +665,16 @@ jobs: - artifact-verification-static steps: - name: Checkout - uses: actions/checkout@v2 + id: checkout + uses: actions/checkout@v3 - name: Retrieve Artifacts - uses: actions/download-artifact@v2 + id: fetch + uses: actions/download-artifact@v3 with: name: final-artifacts path: final-artifacts - name: Create Release + id: create-release uses: ncipollo/release-action@v1 with: allowUpdates: false @@ -524,11 +691,29 @@ jobs: SLACK_ICON_EMOJI: ':github-actions:' SLACK_TITLE: 'Failed to draft release:' SLACK_USERNAME: 'GitHub Actions' - SLACK_MESSAGE: "Failed to draft release." + SLACK_MESSAGE: |- + ${{ github.repository }}: Failed to create draft release or attach artifacts. + Checkout: ${{ steps.checkout.outcome }} + Fetch artifacts: ${{ steps.fetch.outcome }} + Create draft release: ${{ steps.create-release.outcome }} SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} if: >- ${{ failure() - && startsWith(github.ref, 'refs/heads/master') + && github.event_name == 'workflow_dispatch' + }} + - name: Success Notification + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_COLOR: 'good' + SLACK_FOOTER: '' + SLACK_ICON_EMOJI: ':github-actions:' + SLACK_TITLE: 'Created agent draft release:' + SLACK_USERNAME: 'GitHub Actions' + SLACK_MESSAGE: "${{ github.repository }}: ${{ steps.create-release.outputs.html_url }}" + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} + if: >- + ${{ + success() && github.event_name == 'workflow_dispatch' }} diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index bc746f9ac..5f9a9c8c6 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -6,30 +6,17 @@ on: - master pull_request: null env: - DO_NOT_TRACK: 1 + DISABLE_TELEMETRY: 1 concurrency: group: checks-${{ github.ref }} cancel-in-progress: true jobs: - checksum-checks: - name: Checksums - runs-on: ubuntu-latest - steps: - - name: Git clone repository - uses: actions/checkout@v2 - with: - submodules: recursive - - name: Run checksum checks on kickstart files - env: - LOCAL_ONLY: "true" - run: | - ./tests/installer/checksums.sh libressl-checks: name: LibreSSL runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive - name: Build @@ -47,7 +34,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive - name: Build @@ -58,7 +45,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive - name: Prepare environment diff --git a/.github/workflows/cloud_regression.yml b/.github/workflows/cloud_regression.yml new file mode 100644 index 000000000..03b12c157 --- /dev/null +++ b/.github/workflows/cloud_regression.yml @@ -0,0 +1,53 @@ +name: Trigger Cloud Regression E2E Tests +on: + push: + branches: [master] + paths: + - 'CMakeLists.txt' + - '**.c' + - '**.cc' + - '**.cpp' + - '**.h' + - 'mqtt_websockets/**' + - 'aclk/aclk-schemas/**' +jobs: + trigger_cloud_regression_tests: + runs-on: ubuntu-latest + steps: + - name: Evaluate workflow dispatch parameters + env: + PR_REPO_NAME: ${{ github.event.pull_request.head.repo.full_name }} + PR_BRANCH_NAME: ${{ github.event.pull_request.head.ref }} + PR_COMMIT_HASH: ${{ github.event.pull_request.head.sha }} + id: output-workflow-dispatch-params + run: | + if [ ${{ github.event_name }} == 'pull_request_target' ]; then + NETDATA_CUSTOM_REPO="$PR_REPO_NAME" + NETDATA_CUSTOM_BRANCH="$PR_BRANCH_NAME" + NETDATA_CUSTOM_PR_NUMBER="${{ github.event.number }}" + NETDATA_CUSTOM_COMMIT_HASH="$PR_COMMIT_HASH" + elif [ ${{ github.event_name }} == 'push' ]; then + NETDATA_CUSTOM_REPO="netdata/netdata" + NETDATA_CUSTOM_BRANCH="master" + NETDATA_CUSTOM_PR_NUMBER="" + NETDATA_CUSTOM_COMMIT_HASH="${{ github.sha }}" + fi + echo "::set-output name=netdata_repo::${NETDATA_CUSTOM_REPO}" + echo "::set-output name=netdata_branch::${NETDATA_CUSTOM_BRANCH}" + echo "::set-output name=netdata_pr_number::${NETDATA_CUSTOM_PR_NUMBER}" + echo "::set-output name=netdata_commit_hash::${NETDATA_CUSTOM_COMMIT_HASH}" + + - name: Trigger Cloud Regression + uses: aurelien-baudet/workflow-dispatch@v2 + with: + repo: netdata/test-automation + ref: refs/heads/master + workflow: regression.yml + token: ${{ secrets.NETDATABOT_GITHUB_TOKEN }} + inputs: '{ "netdata_branch": "${{ steps.output-workflow-dispatch-params.outputs.netdata_branch }}", + "netdata_repo": "${{ steps.output-workflow-dispatch-params.outputs.netdata_repo }}", + "netdata_pr_number": "${{ steps.output-workflow-dispatch-params.outputs.netdata_pr_number }}", + "netdata_branch_commit_hash": "${{ steps.output-workflow-dispatch-params.outputs.netdata_commit_hash }}", + "custom_netdata_image": "true" + }' + wait-for-completion: false diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index c9e25ebf9..9d1119a82 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -9,7 +9,7 @@ on: - .github/workflows/coverity.yml - coverity-scan.sh env: - DO_NOT_TRACK: 1 + DISABLE_TELEMETRY: 1 concurrency: group: coverity-${{ github.ref }} cancel-in-progress: true @@ -19,10 +19,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 + id: checkout with: submodules: recursive - name: Prepare environment + id: prepare env: DEBIAN_FRONTEND: 'noninteractive' run: | @@ -33,12 +35,13 @@ jobs: libprotoc-dev libssl-dev protobuf-compiler \ libnetfilter-acct-dev - name: Run coverity-scan + id: run env: REPOSITORY: 'netdata/netdata' COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }} COVERITY_SCAN_SUBMIT_MAIL: ${{ secrets.COVERITY_SCAN_SUBMIT_MAIL }} run: | - ./coverity-scan.sh --with-install + bash -x ./coverity-scan.sh --with-install - name: Failure Notification uses: rtCamp/action-slack-notify@v2 env: @@ -47,6 +50,11 @@ jobs: SLACK_ICON_EMOJI: ':github-actions:' SLACK_TITLE: 'Coverity run failed:' SLACK_USERNAME: 'GitHub Actions' + SLACK_MESSAGE: |- + ${{ github.repository }}: Coverity failed to run correctly. + Checkout: ${{ steps.checkout.outcome }} + Environment preparation: ${{ steps.prepare.outcome }} + Coverity run: ${{ steps.run.outcome }} SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} if: ${{ failure() diff --git a/.github/workflows/dashboard-pr.yml b/.github/workflows/dashboard-pr.yml index 711cf1e1f..c99f98919 100644 --- a/.github/workflows/dashboard-pr.yml +++ b/.github/workflows/dashboard-pr.yml @@ -12,7 +12,7 @@ on: required: true env: - DO_NOT_TRACK: 1 + DISABLE_TELEMETRY: 1 jobs: dashboard-pr: @@ -20,12 +20,15 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + id: checkout + uses: actions/checkout@v3 - name: Update Files + id: update run: | web/gui/bundle_dashboard.py ${{ github.event.inputs.dashboard_version }} - name: Create Pull Request - uses: peter-evans/create-pull-request@v3 + id: pr + uses: peter-evans/create-pull-request@v4 with: title: 'Update dashboard to version ${{ github.event.inputs.dashboard_version }}.' body: 'See https://github.com/netdata/dashboard/releases/tag/${{ github.event.inputs.dashboard_version }} for changes.' @@ -34,3 +37,18 @@ jobs: delete-branch: true commit-message: 'Update dashboard to version ${{ github.event.inputs.dashboard_version }}.' token: ${{ secrets.NETDATABOT_GITHUB_TOKEN }} + - name: Failure Notification + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_COLOR: 'danger' + SLACK_FOOTER: '' + SLACK_ICON_EMOJI: ':github-actions:' + SLACK_TITLE: 'Dashboard update PR creation failed:' + SLACK_USERNAME: 'GitHub Actions' + SLACK_MESSAGE: |- + ${{ github.repository }}: Failed to create PR to update dashboard code to newest release. + Checkout: ${{ steps.checkout.outcome }} + Update files: ${{ steps.update.outcome }} + Create PR: ${{ steps.pr.outcome }} + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} + if: failure() diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index f8a1d6855..5a45b0f98 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -8,11 +8,11 @@ on: workflow_dispatch: inputs: version: - name: Version Tag + description: Version Tag default: nightly required: true env: - DO_NOT_TRACK: 1 + DISABLE_TELEMETRY: 1 concurrency: group: docker-${{ github.ref }}-${{ github.event_name }} cancel-in-progress: true @@ -22,19 +22,44 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + id: checkout + uses: actions/checkout@v3 with: submodules: recursive - name: Setup Buildx + id: prepare uses: docker/setup-buildx-action@v1 - name: Test Build + id: build uses: docker/build-push-action@v2 with: load: true push: false tags: netdata/netdata:test - name: Test Image + id: test run: .github/scripts/docker-test.sh + - name: Failure Notification + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_COLOR: 'danger' + SLACK_FOOTER: '' + SLACK_ICON_EMOJI: ':github-actions:' + SLACK_TITLE: 'Docker runtime testing failed:' + SLACK_USERNAME: 'GitHub Actions' + SLACK_MESSAGE: |- + ${{ github.repository }}: Building or testing Docker image for linux/amd64 failed. + CHeckout: ${{ steps.checkout.outcome }} + Setup buildx: ${{ steps.prepare.outcome }} + Build image: ${{ steps.build.outcome }} + Test image: ${{ steps.test.outcome }} + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} + if: >- + ${{ + failure() + && github.event_name != 'pull_request' + && startsWith(github.ref, 'refs/heads/master') + }} docker-ci: if: github.event_name != 'workflow_dispatch' @@ -50,21 +75,46 @@ jobs: - linux/ppc64le steps: - name: Checkout - uses: actions/checkout@v2 + id: checkout + uses: actions/checkout@v3 with: submodules: recursive - name: Setup QEMU + id: qemu if: matrix.platforms != 'linux/i386' uses: docker/setup-qemu-action@v1 - name: Setup Buildx + id: buildx uses: docker/setup-buildx-action@v1 - name: Build + id: build uses: docker/build-push-action@v2 with: platforms: ${{ matrix.platforms }} load: false push: false tags: netdata/netdata:test + - name: Failure Notification + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_COLOR: 'danger' + SLACK_FOOTER: '' + SLACK_ICON_EMOJI: ':github-actions:' + SLACK_TITLE: 'Docker build testing failed:' + SLACK_USERNAME: 'GitHub Actions' + SLACK_MESSAGE: |- + ${{ github.repository }}: Building Docker image for ${{ matrix.platforms }} failed. + CHeckout: ${{ steps.checkout.outcome }} + Setup QEMU: ${{ steps.qemu.outcome }} + Setup buildx: ${{ steps.buildx.outcome }} + Build image: ${{ steps.build.outcome }} + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} + if: >- + ${{ + failure() + && github.event_name != 'pull_request' + && startsWith(github.ref, 'refs/heads/master') + }} docker-publish: if: github.event_name == 'workflow_dispatch' @@ -73,30 +123,39 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + id: checkout + uses: actions/checkout@v3 with: submodules: recursive - name: Determine which tags to use + id: release-tags if: github.event.inputs.version != 'nightly' run: | - echo "tags=netdata/netdata:latest,netdata/netdata:stable,$(.github/scripts/gen-docker-tags.py ${{ github.event.inputs.version }})" >> $GITHUB_ENV + echo "tags=netdata/netdata:latest,netdata/netdata:stable,$(.github/scripts/gen-docker-tags.py ${{ github.event.inputs.version }})" \ + >> "${GITHUB_ENV}" - name: Determine which tags to use + id: nightly-tags if: github.event.inputs.version == 'nightly' run: | - echo "tags=netdata/netdata:latest,netdata/netdata:edge" >> $GITHUB_ENV + echo "tags=netdata/netdata:latest,netdata/netdata:edge" >> "${GITHUB_ENV}" - name: Mark image as official + id: env if: github.repository == 'netdata/netdata' - run: echo "OFFICIAL_IMAGE=true" >> $GITHUB_ENV + run: echo "OFFICIAL_IMAGE=true" >> "${GITHUB_ENV}" - name: Setup QEMU + id: qemu uses: docker/setup-qemu-action@v1 - name: Setup Buildx + id: buildx uses: docker/setup-buildx-action@v1 - name: Docker Hub Login + id: login uses: docker/login-action@v1 with: username: ${{ secrets.DOCKER_HUB_USERNAME }} password: ${{ secrets.DOCKER_HUB_PASSWORD }} - name: Docker Build + id: build uses: docker/build-push-action@v2 with: platforms: linux/amd64,linux/i386,linux/arm/v7,linux/arm64,linux/ppc64le @@ -111,7 +170,16 @@ jobs: SLACK_ICON_EMOJI: ':github-actions:' SLACK_TITLE: 'Docker Build failed:' SLACK_USERNAME: 'GitHub Actions' - SLACK_MESSAGE: "Docker image build failed." + SLACK_MESSAGE: |- + ${{ github.repository }}: Failed to build or publish Docker images. + CHeckout: ${{ steps.checkout.outcome }} + Generate release tags: ${{ steps.release-tags.outcome }} + Generate nightly tags: ${{ steps.nightly-tags.outcome }} + Setup environment: ${{ steps.env.outcome }} + Setup QEMU: ${{ steps.qemu.outcome }} + Setup buildx: ${{ steps.buildx.outcome }} + Authenticate against DockerHub: ${{ steps.login.outcome }} + Build and publish images: ${{ steps.build.outcome }} SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} if: >- ${{ diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 73bcc8773..69fda40c3 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -10,14 +10,14 @@ on: paths: - '**.md' env: - DO_NOT_TRACK: 1 + DISABLE_TELEMETRY: 1 jobs: markdown-link-check: name: Broken Links runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive - name: Run link check diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index a4937a9db..0854080a7 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -5,7 +5,7 @@ on: schedule: - cron: '*/10 * * * *' env: - DO_NOT_TRACK: 1 + DISABLE_TELEMETRY: 1 jobs: labeler: runs-on: ubuntu-latest diff --git a/.github/workflows/packaging.yml b/.github/workflows/packaging.yml index 38a78731b..dbf334d59 100644 --- a/.github/workflows/packaging.yml +++ b/.github/workflows/packaging.yml @@ -6,164 +6,235 @@ on: branches: - master - develop + push: + branches: + - master workflow_dispatch: inputs: type: - name: Package build type + description: Package build type default: devel required: true version: - name: Package version + description: Package version required: false env: - DO_NOT_TRACK: 1 + DISABLE_TELEMETRY: 1 + REPO_PREFIX: netdata/netdata concurrency: group: packages-${{ github.ref }}-${{ github.event_name }} cancel-in-progress: true jobs: + matrix: + name: Prepare Build Matrix + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - name: Checkout + id: checkout + uses: actions/checkout@v3 + - name: Prepare tools + id: prepare + run: | + sudo apt-get update && sudo apt-get install -y python3-ruamel.yaml + - name: Read build matrix + id: set-matrix + shell: python3 {0} + run: | + from ruamel.yaml import YAML + import json + import re + FULL_CI_REGEX = '/actions run full ci' + ALWAYS_RUN_ARCHES = ["amd64"] + PR_BODY = """${{ github.event.pull_request.body }}""" + yaml = YAML(typ='safe') + entries = list() + run_limited = False + + with open('.github/data/distros.yml') as f: + data = yaml.load(f) + + if "${{ github.event_name }}" == "pull_request" and re.search(FULL_CI_REGEX, PR_BODY, re.I) is None: + run_limited = True + + for i, v in enumerate(data['include']): + if 'packages' in data['include'][i]: + for arch in data['include'][i]['packages']['arches']: + if arch in ALWAYS_RUN_ARCHES or not run_limited: + entries.append({ + 'distro': data['include'][i]['distro'], + 'version': data['include'][i]['version'], + 'pkgclouddistro': data['include'][i]['packages']['repo_distro'], + 'format': data['include'][i]['packages']['type'], + 'base_image': data['include'][i]['base_image'] if 'base_image' in data['include'][i] else data['include'][i]['distro'], + 'platform': data['platform_map'][arch], + 'arch': arch + }) + + entries.sort(key=lambda k: (k['arch'], k['distro'], k['version'])) + matrix = json.dumps({'include': entries}, sort_keys=True) + print('Generated Matrix: ' + matrix) + print('::set-output name=matrix::' + matrix) + - name: Failure Notification + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_COLOR: 'danger' + SLACK_ICON_EMOJI: ':github-actions:' + SLACK_TITLE: 'Package Build matrix generation failed:' + SLACK_USERNAME: 'GitHub Actions' + SLACK_MESSAGE: |- + ${{ github.repository }}: Failed to generate build matrix for package build. + Checkout: ${{ steps.checkout.outcome }} + Prepare Tools: ${{ steps.prepare.outcome }} + Read Build Matrix: ${{ steps.set-matrix.outcome }} + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} + if: >- + ${{ + failure() + && github.event_name != 'pull_request' + && startsWith(github.ref, 'refs/heads/master') + }} + + version-check: + name: Version check + runs-on: ubuntu-latest + outputs: + repo: ${{ steps.check-version.outputs.repo }} + version: ${{ steps.check-version.outputs.version }} + retention: ${{ steps.check-version.outputs.retention }} + steps: + - name: Checkout + id: checkout + uses: actions/checkout@v3 + - name: Check Version + id: check-version + run: | + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + case "${{ github.event.inputs.type }}" in + "release") + echo "::set-output name=repo::${REPO_PREFIX}" + echo "::set-output name=version::${{ github.event.inputs.version }}" + echo "::set-output name=retention::365" + ;; + "nightly") + echo "::set-output name=repo::${REPO_PREFIX}-edge" + echo "::set-output name=version::$(tr -d 'v' < packaging/version)" + echo "::set-output name=retention::30" + ;; + *) + echo "::set-output name=repo::${REPO_PREFIX}-devel" + echo "::set-output name=version::0.${GITHUB_SHA}" + echo "::set-output name=retention::30" + ;; + esac + else + echo "::set-output name=version::$(cut -d'-' -f 1 packaging/version | tr -d 'v')" + echo "::set-output name=retention::0" + fi + - name: Failure Notification + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_COLOR: 'danger' + SLACK_ICON_EMOJI: ':github-actions:' + SLACK_TITLE: 'Package Build version check failed:' + SLACK_USERNAME: 'GitHub Actions' + SLACK_MESSAGE: |- + ${{ github.repository }}: Failed to generate version information for package build. + Checkout: ${{ steps.checkout.outcome }} + Check Version: ${{ steps.check-version.outcome }} + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} + if: >- + ${{ + failure() + && github.event_name != 'pull_request' + && startsWith(github.ref, 'refs/heads/master') + }} + build: name: Build runs-on: ubuntu-latest env: DOCKER_CLI_EXPERIMENTAL: enabled + needs: + - matrix + - version-check strategy: - matrix: - include: - - {distro: debian, version: "9", pkgclouddistro: debian/stretch, format: deb, base_image: debian, platform: linux/amd64, arch: amd64} - - {distro: debian, version: "9", pkgclouddistro: debian/stretch, format: deb, base_image: debian, platform: linux/i386, arch: i386} - - {distro: debian, version: "9", pkgclouddistro: debian/stretch, format: deb, base_image: debian, platform: linux/arm/v7, arch: armhf} - - {distro: debian, version: "9", pkgclouddistro: debian/stretch, format: deb, base_image: debian, platform: linux/arm64/v8, arch: arm64} - - {distro: debian, version: "10", pkgclouddistro: debian/buster, format: deb, base_image: debian, platform: linux/amd64, arch: amd64} - - {distro: debian, version: "10", pkgclouddistro: debian/buster, format: deb, base_image: debian, platform: linux/i386, arch: i386} - - {distro: debian, version: "10", pkgclouddistro: debian/buster, format: deb, base_image: debian, platform: linux/arm/v7, arch: armhf} - - {distro: debian, version: "10", pkgclouddistro: debian/buster, format: deb, base_image: debian, platform: linux/arm64/v8, arch: arm64} - - {distro: debian, version: "11", pkgclouddistro: debian/bullseye, format: deb, base_image: debian, platform: linux/amd64, arch: amd64, alias: bullseye} - - {distro: debian, version: "11", pkgclouddistro: debian/bullseye, format: deb, base_image: debian, platform: linux/i386, arch: i386, alias: bullseye} - - {distro: debian, version: "11", pkgclouddistro: debian/bullseye, format: deb, base_image: debian, platform: linux/arm/v7, arch: armhf, alias: bullseye} - - {distro: debian, version: "11", pkgclouddistro: debian/bullseye, format: deb, base_image: debian, platform: linux/arm64/v8, arch: arm64, alias: bullseye} - - {distro: ubuntu, version: "18.04", pkgclouddistro: ubuntu/bionic, format: deb, base_image: ubuntu, platform: linux/amd64, arch: amd64} - - {distro: ubuntu, version: "18.04", pkgclouddistro: ubuntu/bionic, format: deb, base_image: ubuntu, platform: linux/i386, arch: i386} - - {distro: ubuntu, version: "18.04", pkgclouddistro: ubuntu/bionic, format: deb, base_image: ubuntu, platform: linux/arm/v7, arch: armhf} - - {distro: ubuntu, version: "18.04", pkgclouddistro: ubuntu/bionic, format: deb, base_image: ubuntu, platform: linux/arm64/v8, arch: arm64} - - {distro: ubuntu, version: "20.04", pkgclouddistro: ubuntu/focal, format: deb, base_image: ubuntu, platform: linux/amd64, arch: amd64} - - {distro: ubuntu, version: "20.04", pkgclouddistro: ubuntu/focal, format: deb, base_image: ubuntu, platform: linux/arm/v7, arch: armhf} - - {distro: ubuntu, version: "20.04", pkgclouddistro: ubuntu/focal, format: deb, base_image: ubuntu, platform: linux/arm64/v8, arch: arm64} - - {distro: ubuntu, version: "21.10", pkgclouddistro: ubuntu/impish, format: deb, base_image: ubuntu, platform: linux/amd64, arch: amd64} - - {distro: ubuntu, version: "21.10", pkgclouddistro: ubuntu/impish, format: deb, base_image: ubuntu, platform: linux/arm/v7, arch: armhf} - - {distro: ubuntu, version: "21.10", pkgclouddistro: ubuntu/impish, format: deb, base_image: ubuntu, platform: linux/arm64/v8, arch: arm64} - - {distro: centos, version: "7", pkgclouddistro: el/7, format: rpm, base_image: centos, platform: linux/amd64, arch: amd64} - - {distro: rockylinux, version: "8", pkgclouddistro: el/8, format: rpm, base_image: rockylinux/rockylinux, platform: linux/amd64, arch: amd64} - - {distro: rockylinux, version: "8", pkgclouddistro: el/8, format: rpm, base_image: rockylinux/rockylinux, platform: linux/arm64/v8, arch: arm64} - - {distro: fedora, version: "34", pkgclouddistro: fedora/34, format: rpm, base_image: fedora, platform: linux/amd64, arch: amd64} - - {distro: fedora, version: "34", pkgclouddistro: fedora/34, format: rpm, base_image: fedora, platform: linux/arm/v7, arch: armhf} - - {distro: fedora, version: "34", pkgclouddistro: fedora/34, format: rpm, base_image: fedora, platform: linux/arm64/v8, arch: arm64} - - {distro: fedora, version: "35", pkgclouddistro: fedora/35, format: rpm, base_image: fedora, platform: linux/amd64, arch: amd64} - - {distro: fedora, version: "35", pkgclouddistro: fedora/35, format: rpm, base_image: fedora, platform: linux/arm/v7, arch: armhf} - - {distro: fedora, version: "35", pkgclouddistro: fedora/35, format: rpm, base_image: fedora, platform: linux/arm64/v8, arch: arm64} - - {distro: opensuse, version: "15.3", pkgclouddistro: opensuse/15.3, format: rpm, base_image: opensuse/leap, platform: linux/amd64, arch: amd64} - - {distro: opensuse, version: "15.3", pkgclouddistro: opensuse/15.3, format: rpm, base_image: opensuse/leap, platform: linux/arm64/v8, arch: arm64} - - {distro: oraclelinux, version: "8", pkgclouddistro: ol/8, format: rpm, base_image: oraclelinux, platform: linux/amd64, arch: amd64} - - {distro: oraclelinux, version: "8", pkgclouddistro: ol/8, format: rpm, base_image: oraclelinux, platform: linux/arm64/v8, arch: arm64} + matrix: ${{ fromJson(needs.matrix.outputs.matrix) }} # We intentiaonally disable the fail-fast behavior so that a # build failure for one version doesn't prevent us from publishing # successfully built and tested packages for another version. fail-fast: false max-parallel: 8 steps: - - name: Checkout PR # Checkout the PR if it's a PR. - if: github.event_name == 'pull_request' - uses: actions/checkout@v2 - with: - fetch-depth: 0 # We need full history for versioning - submodules: recursive - - name: Checkout Tag # Otherwise check out the tag that triggered this. - if: github.event_name == 'workflow_dispatch' - uses: actions/checkout@v2 + - name: Checkout + id: checkout + uses: actions/checkout@v3 with: - ref: ${{ github.event.ref }} fetch-depth: 0 # We need full history for versioning submodules: recursive - - name: Check Base Branch - run: | - if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then - echo "runtype=${{ github.event.inputs.type }}" >> $GITHUB_ENV - case "${{ github.event.inputs.type }}" in - "release") - echo "repo=${{ secrets.PACKAGE_CLOUD_REPO }}" >> $GITHUB_ENV - echo "pkg_version=${{ github.event.inputs.version }}" >> $GITHUB_ENV - echo "pkg_retention_days=365" >> $GITHUB_ENV - ;; - "nightly") - echo "repo=${{ secrets.PACKAGE_CLOUD_REPO }}-edge" >> $GITHUB_ENV - echo "pkg_version=${{ github.event.inputs.version }}" >> $GITHUB_ENV - echo "pkg_retention_days=30" >> $GITHUB_ENV - ;; - *) - echo "repo=${{ secrets.PACKAGE_CLOUD_REPO }}-devel" >> $GITHUB_ENV - echo "pkg_version=0.${GITHUB_SHA}" >> $GITHUB_ENV - echo "pkg_retention_days=30" >> $GITHUB_ENV - ;; - esac - else - echo "runtype=test" >> $GITHUB_ENV - echo "pkg_version=$(cut -d'-' -f 1 packaging/version | sed -e 's/^v//')" >> $GITHUB_ENV - fi - name: Setup QEMU + id: qemu if: matrix.platform != 'linux/amd64' && matrix.platform != 'linux/i386' uses: docker/setup-qemu-action@v1 - name: Prepare Docker Environment + id: docker-config shell: bash run: | echo '{"cgroup-parent": "/actions_job", "experimental": true}' | sudo tee /etc/docker/daemon.json 2>/dev/null sudo service docker restart - - name: Set Base Image Version - shell: bash - run: | - if [ -z "${{ matrix.alias }}" ] ; then - echo "version=${{ matrix.version }}" >> $GITHUB_ENV - else - echo "version=${{ matrix.alias }}" >> $GITHUB_ENV - fi - - name: Fetch base image + - name: Fetch images + id: fetch-images uses: nick-invision/retry@v2 with: max_attempts: 3 retry_wait_seconds: 30 timeout_seconds: 900 command: | - docker pull --platform ${{ matrix.platform }} ${{ matrix.base_image }}:${{ env.version }} + docker pull --platform ${{ matrix.platform }} ${{ matrix.base_image }}:${{ matrix.version }} docker pull --platform ${{ matrix.platform }} netdata/package-builders:${{ matrix.distro }}${{ matrix.version }} - name: Build Packages + id: build shell: bash run: | - docker run --security-opt seccomp=unconfined -e DO_NOT_TRACK=1 -e VERSION=${{ env.pkg_version }} --platform=${{ matrix.platform }} -v $PWD:/netdata netdata/package-builders:${{ matrix.distro }}${{ matrix.version }} + docker run --security-opt seccomp=unconfined -e DISABLE_TELEMETRY=1 -e VERSION=${{ needs.version-check.outputs.version }} \ + --platform=${{ matrix.platform }} -v "$PWD":/netdata netdata/package-builders:${{ matrix.distro }}${{ matrix.version }} - name: Test Packages + id: test shell: bash run: | - docker run --security-opt seccomp=unconfined -e DO_NOT_TRACK=1 -e DISTRO=${{ matrix.distro }} -e VERSION=${{ env.pkg_version }} -e DISTRO_VERSION=${{ env.version }} --platform=${{ matrix.platform }} -v $PWD:/netdata ${{ matrix.base_image }}:${{ env.version }} /netdata/.github/scripts/pkg-test.sh + docker run --security-opt seccomp=unconfined -e DISABLE_TELEMETRY=1 -e DISTRO=${{ matrix.distro }} \ + -e VERSION=${{ needs.version-check.outputs.version }} -e DISTRO_VERSION=${{ matrix.version }} \ + --platform=${{ matrix.platform }} -v "$PWD":/netdata ${{ matrix.base_image }}:${{ matrix.version }} \ + /netdata/.github/scripts/pkg-test.sh - name: Save Packages - uses: actions/upload-artifact@v2 + id: artifacts + continue-on-error: true + uses: actions/upload-artifact@v3 with: name: ${{ matrix.distro }}-${{ matrix.version }}-${{ matrix.arch }}-packages path: ${{ github.workspace }}/artifacts/* - name: Upload to PackageCloud + id: upload if: github.event_name == 'workflow_dispatch' shell: bash env: PKG_CLOUD_TOKEN: ${{ secrets.PACKAGE_CLOUD_API_KEY }} run: | - echo "Packages to upload:\n$(ls artifacts/*.${{ matrix.format }})" + printf "Packages to upload:\n%s" "$(ls artifacts/*.${{ matrix.format }})" for pkgfile in artifacts/*.${{ matrix.format }} ; do - .github/scripts/package_cloud_wrapper.sh yank ${{ env.repo }}/${{ matrix.pkgclouddistro }} $(basename ${pkgfile}) || true - .github/scripts/package_cloud_wrapper.sh push ${{ env.repo }}/${{ matrix.pkgclouddistro }} ${pkgfile} + .github/scripts/package_cloud_wrapper.sh yank ${{ needs.version-check.outputs.repo }}/${{ matrix.pkgclouddistro }} \ + "$(basename "${pkgfile}")" || true + .github/scripts/package_cloud_wrapper.sh push ${{ needs.version-check.outputs.repo }}/${{ matrix.pkgclouddistro }} "${pkgfile}" done - name: Clean + id: cleanup if: github.event_name == 'workflow_dispatch' shell: bash env: - REPO: ${{ env.repo }} + REPO: ${{ needs.version-check.outputs.repo }} PKG_CLOUD_TOKEN: ${{ secrets.PACKAGE_CLOUD_API_KEY }} - PACKAGE_CLOUD_RETENTION_DAYS: ${{ env.pkg_retention_days }} + PACKAGE_CLOUD_RETENTION_DAYS: ${{ needs.version-check.outputs.retention }} run: .github/scripts/old_package_purging.sh - name: Failure Notification uses: rtCamp/action-slack-notify@v2 @@ -172,7 +243,16 @@ jobs: SLACK_ICON_EMOJI: ':github-actions:' SLACK_TITLE: 'Package Build failed:' SLACK_USERNAME: 'GitHub Actions' - SLACK_MESSAGE: "${{ matrix.pkgclouddistro }} ${{ matrix.version }} package build for ${{ matrix.arch }} failed." + SLACK_MESSAGE: |- + ${{ github.repository }}: ${{ matrix.pkgclouddistro }} ${{ matrix.version }} package build for ${{ matrix.arch }} failed. + Checkout: ${{ steps.checkout.outcome }} + Setup QEMU: ${{ steps.qemu.outcome }} + Setup Docker: ${{ steps.docker-config.outcome }} + Fetch images: ${{ steps.fetch-images.outcome }} + Build: ${{ steps.build.outcome }} + Test: ${{ steps.test.outcome }} + Publish: ${{ steps.upload.outcome }} + Cleanup: ${{ steps.cleanup.outcome }} SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} if: >- ${{ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..248e45e07 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,207 @@ +--- +# Workflow for triggering a release. +name: Release +on: + schedule: + - cron: '0 0 * * *' + workflow_dispatch: # Dispatch runs build and validate, then push to the appropriate storage location. + inputs: + type: + description: Build Type + default: nightly + required: true + version: + description: Version Tag + default: nightly + required: true +concurrency: # This keeps multiple instances of the job from running concurrently for the same ref and event type. + group: release-${{ github.ref }}-${{ github.event_name }} + cancel-in-progress: true +jobs: + update-changelogs: + name: Update changelog + runs-on: ubuntu-latest + outputs: + ref: ${{ steps.target.outputs.ref }} + version: ${{ steps.target.outputs.version }} + type: ${{ steps.target.outputs.type }} + run: ${{ steps.target.outputs.run }} + steps: + - name: Checkout + id: checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + submodules: recursive + token: ${{ secrets.NETDATABOT_GITHUB_TOKEN }} + - name: Prepare base ref + id: target + run: >- + .github/scripts/prepare-release-base.sh \ + ${{ github.repository }} \ + ${{ github.event_name }} \ + ${{ github.event.inputs.type }} \ + ${{ github.event.inputs.version }} + - name: Generate Nightly Changleog + id: nightly-changelog + if: steps.target.outputs.run == 'true' && steps.target.outputs.type == 'nightly' + uses: heinrichreimer/github-changelog-generator-action@v2.3 + with: + bugLabels: IGNOREBUGS + excludeLabels: "stale,duplicate,question,invalid,wontfix,discussion,no changelog" + issues: false + sinceTag: v1.10.0 + token: ${{ secrets.NETDATABOT_GITHUB_TOKEN }} + unreleasedLabel: "**Next release**" + verbose: true + maxIssues: 500 + - name: Generate Release Changelog + id: release-changelog + if: steps.target.outputs.run == 'true' && steps.target.outputs.type != 'nightly' + uses: heinrichreimer/github-changelog-generator-action@v2.3 + with: + bugLabels: IGNOREBUGS + excludeLabels: "stale,duplicate,question,invalid,wontfix,discussion,no changelog" + futureRelease: ${{ github.event.inputs.version }} + issues: false + sinceTag: v1.10.0 + token: ${{ secrets.NETDATABOT_GITHUB_TOKEN }} + unreleasedLabel: "**Next release**" + verbose: true + maxIssues: 500 + - name: Commit Changes + id: commit + if: steps.target.outputs.run == 'true' + env: + GITHUB_TOKEN: ${{ secrets.NETDATABOT_GITHUB_TOKEN }} + run: | + git config user.name "netdatabot" + git config user.email "bot@netdata.cloud" + git add packaging/version CHANGELOG.md + git commit -m "[ci skip] ${{ steps.target.outputs.message }}" + if [ "${{ steps.target.outputs.type }}" != "nightly" ]; then + git tag ${{ github.event.inputs.version }} + fi + git push --follow-tags origin ${{ steps.target.outputs.branch }} + - name: Failure Notification + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_COLOR: 'danger' + SLACK_FOOTER: '' + SLACK_ICON_EMOJI: ':github-actions:' + SLACK_TITLE: 'Failed to prepare changelog:' + SLACK_USERNAME: 'GitHub Actions' + SLACK_MESSAGE: |- + ${{ github.repository }}: Failed to prepare changelog. + Checkout: ${{ steps.checkout.outcome }} + Prepare base ref: ${{ steps.target.outcome }} + Generate nightly changelog: ${{ steps.nightly-changelog.outcome }} + Generate release changelog: ${{ steps.release-changelog.outcome }} + Commit changes: ${{ steps.commit.outcome }} + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} + if: failure() + + trigger-artifacts: + name: Trigger artifact builds + runs-on: ubuntu-latest + needs: update-changelogs + if: ${{ needs.update-changelogs.outputs.run }} == 'true' + steps: + - name: Checkout + id: checkout + uses: actions/checkout@v2 + with: + ref: ${{ needs.update-changelogs.outputs.ref }} + - name: Trigger build + id: trigger + uses: benc-uk/workflow-dispatch@v1 + with: + token: ${{ secrets.NETDATABOT_GITHUB_TOKEN }} + repo: ${{ github.repository }} + workflow: Build + ref: ${{ needs.update-changelogs.outputs.ref }} + inputs: '{"version": "${{ needs.update-changelogs.outputs.version }}", "type": "${{ needs.update-changelogs.outputs.type }}"}' + - name: Failure Notification + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_COLOR: 'danger' + SLACK_FOOTER: '' + SLACK_ICON_EMOJI: ':github-actions:' + SLACK_TITLE: 'Failed to trigger ${{ needs.update-changelogs.outputs.type }} artifact builds:' + SLACK_USERNAME: 'GitHub Actions' + SLACK_MESSAGE: |- + ${{ github.repository }}: Failed to trigger ${{ needs.update-changelogs.outputs.type }} artifact builds. + Checkout: ${{ steps.checkout.outcome }} + Trigger build: ${{ steps.trigger.outcome }} + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} + if: failure() + + trigger-docker: + name: Trigger docker builds + runs-on: ubuntu-latest + needs: update-changelogs + if: ${{ needs.update-changelogs.outputs.run }} == 'true' + steps: + - name: Checkout + id: checkout + uses: actions/checkout@v2 + with: + ref: ${{ needs.update-changelogs.outputs.ref }} + - name: Trigger build + id: trigger + uses: benc-uk/workflow-dispatch@v1 + with: + token: ${{ secrets.NETDATABOT_GITHUB_TOKEN }} + repo: ${{ github.repository }} + workflow: Docker + ref: ${{ needs.update-changelogs.outputs.ref }} + inputs: '{"version": "${{ needs.update-changelogs.outputs.version }}"}' + - name: Failure Notification + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_COLOR: 'danger' + SLACK_FOOTER: '' + SLACK_ICON_EMOJI: ':github-actions:' + SLACK_TITLE: 'Failed to trigger ${{ needs.update-changelogs.outputs.type }} Docker builds:' + SLACK_USERNAME: 'GitHub Actions' + SLACK_MESSAGE: |- + ${{ github.repository }}: Failed to trigger ${{ needs.update-changelogs.outputs.type }} Docker builds. + Checkout: ${{ steps.checkout.outcome }} + Trigger build: ${{ steps.trigger.outcome }} + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} + if: failure() + + trigger-packages: + name: Trigger package builds + runs-on: ubuntu-latest + needs: update-changelogs + if: ${{ needs.update-changelogs.outputs.run }} == 'true' + steps: + - name: Checkout + id: checkout + uses: actions/checkout@v2 + with: + ref: ${{ needs.update-changelogs.outputs.ref }} + - name: Trigger build + id: trigger + uses: benc-uk/workflow-dispatch@v1 + with: + token: ${{ secrets.NETDATABOT_GITHUB_TOKEN }} + repo: ${{ github.repository }} + workflow: Packages + ref: ${{ needs.update-changelogs.outputs.ref }} + inputs: '{"version": "${{ needs.update-changelogs.outputs.version }}", "type": "${{ needs.update-changelogs.outputs.type }}"}' + - name: Failure Notification + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_COLOR: 'danger' + SLACK_FOOTER: '' + SLACK_ICON_EMOJI: ':github-actions:' + SLACK_TITLE: 'Failed to trigger ${{ needs.update-changelogs.outputs.type }} package builds:' + SLACK_USERNAME: 'GitHub Actions' + SLACK_MESSAGE: |- + ${{ github.repository }}: Failed to trigger ${{ needs.update-changelogs.outputs.type }} package builds. + Checkout: ${{ steps.checkout.outcome }} + Trigger build: ${{ steps.trigger.outcome }} + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} + if: failure() diff --git a/.github/workflows/repoconfig-packages.yml b/.github/workflows/repoconfig-packages.yml index b8d0ff67c..b0600cc0b 100644 --- a/.github/workflows/repoconfig-packages.yml +++ b/.github/workflows/repoconfig-packages.yml @@ -14,30 +14,80 @@ on: - packaging/repoconfig/** - .github/workflows/repoconfig-packages.yml env: - DO_NOT_TRACK: 1 + DISABLE_TELEMETRY: 1 + REPO_PREFIX: netdata/netdata jobs: + matrix: + name: Prepare Build Matrix + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - name: Checkout + id: checkout + uses: actions/checkout@v3 + - name: Prepare tools + id: prepare + run: | + sudo apt-get update && sudo apt-get install -y python3-ruamel.yaml + - name: Read build matrix + id: set-matrix + shell: python3 {0} + run: | + from ruamel.yaml import YAML + import json + yaml = YAML(typ='safe') + entries = list() + + with open('.github/data/distros.yml') as f: + data = yaml.load(f) + + for i, v in enumerate(data['include']): + if 'packages' in data['include'][i]: + entries.append({ + 'distro': data['include'][i]['distro'], + 'version': data['include'][i]['version'], + 'pkgclouddistro': data['include'][i]['packages']['repo_distro'], + 'format': data['include'][i]['packages']['type'], + 'base_image': data['include'][i]['base_image'] if 'base_image' in data['include'][i] else data['include'][i]['distro'], + 'platform': data['platform_map']['amd64'], + 'arch': 'amd64' + }) + + entries.sort(key=lambda k: (k['arch'], k['distro'], k['version'])) + matrix = json.dumps({'include': entries}, sort_keys=True) + print('Generated Matrix: ' + matrix) + print('::set-output name=matrix::' + matrix) + - name: Failure Notification + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_COLOR: 'danger' + SLACK_ICON_EMOJI: ':github-actions:' + SLACK_TITLE: 'Repository Package Build matrix generation failed:' + SLACK_USERNAME: 'GitHub Actions' + SLACK_MESSAGE: |- + ${{ github.repository }}: Failed to generate build matrix for repository package build. + Checkout: ${{ steps.checkout.outcome }} + Prepare Tools: ${{ steps.prepare.outcome }} + Read Build Matrix: ${{ steps.set-matrix.outcome }} + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} + if: >- + ${{ + failure() + && github.event_name != 'pull_request' + && startsWith(github.ref, 'refs/heads/master') + }} + build: name: Build runs-on: ubuntu-latest env: - DO_NOT_TRACK: 1 + DISABLE_TELEMETRY: 1 DOCKER_CLI_EXPERIMENTAL: enabled + needs: + - matrix strategy: - # This needs to be kept in sync with the matrix in packaging.yml, but should only include the AMD64 lines. - matrix: - include: - - {distro: debian, version: "9", pkgclouddistro: debian/stretch, format: deb, base_image: debian, platform: linux/amd64, arch: amd64} - - {distro: debian, version: "10", pkgclouddistro: debian/buster, format: deb, base_image: debian, platform: linux/amd64, arch: amd64} - - {distro: debian, version: "11", pkgclouddistro: debian/bullseye, format: deb, base_image: debian, platform: linux/amd64, arch: amd64} - - {distro: ubuntu, version: "18.04", pkgclouddistro: ubuntu/bionic, format: deb, base_image: ubuntu, platform: linux/amd64, arch: amd64} - - {distro: ubuntu, version: "20.04", pkgclouddistro: ubuntu/focal, format: deb, base_image: ubuntu, platform: linux/amd64, arch: amd64} - - {distro: ubuntu, version: "21.10", pkgclouddistro: ubuntu/impish, format: deb, base_image: ubuntu, platform: linux/amd64, arch: amd64} - - {distro: centos, version: "7", pkgclouddistro: el/7, format: rpm, base_image: centos, platform: linux/amd64, arch: amd64} - - {distro: rockylinux, version: "8", pkgclouddistro: el/8, format: rpm, base_image: rockylinux/rockylinux, platform: linux/amd64, arch: amd64} - - {distro: fedora, version: "34", pkgclouddistro: fedora/34, format: rpm, base_image: fedora, platform: linux/amd64, arch: amd64} - - {distro: fedora, version: "35", pkgclouddistro: fedora/35, format: rpm, base_image: fedora, platform: linux/amd64, arch: amd64} - - {distro: opensuse, version: "15.3", pkgclouddistro: opensuse/15.3, format: rpm, base_image: opensuse/leap, platform: linux/amd64, arch: amd64} - - {distro: oraclelinux, version: "8", pkgclouddistro: ol/8, format: rpm, base_image: oraclelinux, platform: linux/amd64, arch: amd64} + matrix: ${{ fromJson(needs.matrix.outputs.matrix) }} # We intentiaonally disable the fail-fast behavior so that a # build failure for one version doesn't prevent us from publishing # successfully built and tested packages for another version. @@ -45,9 +95,11 @@ jobs: max-parallel: 8 steps: - name: Checkout - uses: actions/checkout@v2 + id: checkout + uses: actions/checkout@v3 # Unlike normally, we do not need a deep clone or submodules for this. - name: Fetch base image + id: fetch-images uses: nick-invision/retry@v2 with: max_attempts: 3 @@ -55,25 +107,30 @@ jobs: timeout_seconds: 900 command: docker pull --platform ${{ matrix.platform }} ${{ matrix.base_image }}:${{ matrix.version }} - name: Build Packages + id: build shell: bash run: | - docker run --security-opt seccomp=unconfined -e DO_NOT_TRACK=1 --platform ${{ matrix.platform }} \ - -v $PWD:/netdata ${{ matrix.base_image }}:${{ matrix.version }} \ + docker run --security-opt seccomp=unconfined -e DISABLE_TELEMETRY=1 --platform ${{ matrix.platform }} \ + -v "$PWD":/netdata ${{ matrix.base_image }}:${{ matrix.version }} \ /netdata/packaging/repoconfig/build-${{ matrix.format }}.sh - name: Upload Packages + id: publish if: github.event_name != 'pull_request' && github.repository == 'netdata/netdata' shell: bash env: PKG_CLOUD_TOKEN: ${{ secrets.PACKAGE_CLOUD_API_KEY }} run: | - echo "Packages to upload:\n$(ls artifacts/*.${{ matrix.format }})" + printf "Packages to upload:\n%s" "$(ls artifacts/*.${{ matrix.format }})" for pkgfile in artifacts/*.${{ matrix.format }} ; do - .github/scripts/package_cloud_wrapper.sh yank ${{ secrets.PACKAGE_CLOUD_REPO }}/${{ matrix.pkgclouddistro }} $(basename ${pkgfile}) || true - .github/scripts/package_cloud_wrapper.sh push ${{ secrets.PACKAGE_CLOUD_REPO }}/${{ matrix.pkgclouddistro }} ${pkgfile} - .github/scripts/package_cloud_wrapper.sh yank ${{ secrets.PACKAGE_CLOUD_REPO }}-edge/${{ matrix.pkgclouddistro }} $(basename ${pkgfile}) || true - .github/scripts/package_cloud_wrapper.sh push ${{ secrets.PACKAGE_CLOUD_REPO }}-edge/${{ matrix.pkgclouddistro }} ${pkgfile} - .github/scripts/package_cloud_wrapper.sh yank ${{ secrets.PACKAGE_CLOUD_REPO }}-repoconfig/${{ matrix.pkgclouddistro }} $(basename ${pkgfile}) || true - .github/scripts/package_cloud_wrapper.sh push ${{ secrets.PACKAGE_CLOUD_REPO }}-repoconfig/${{ matrix.pkgclouddistro }} ${pkgfile} + .github/scripts/package_cloud_wrapper.sh yank "${REPO_PREFIX}/${{ matrix.pkgclouddistro }}" \ + "$(basename "${pkgfile}")" || true + .github/scripts/package_cloud_wrapper.sh push "${REPO_PREFIX}/${{ matrix.pkgclouddistro }}" "${pkgfile}" + .github/scripts/package_cloud_wrapper.sh yank "${REPO_PREFIX}-edge/${{ matrix.pkgclouddistro }}" \ + "$(basename "${pkgfile}")" || true + .github/scripts/package_cloud_wrapper.sh push "${REPO_PREFIX}-edge/${{ matrix.pkgclouddistro }}" "${pkgfile}" + .github/scripts/package_cloud_wrapper.sh yank "${REPO_PREFIX}-repoconfig/${{ matrix.pkgclouddistro }}" \ + "$(basename "${pkgfile}")" || true + .github/scripts/package_cloud_wrapper.sh push "${REPO_PREFIX}-repoconfig/${{ matrix.pkgclouddistro }}" "${pkgfile}" done - name: Failure Notification if: ${{ failure() }} @@ -84,5 +141,10 @@ jobs: SLACK_ICON_EMOJI: ':github-actions:' SLACK_TITLE: 'Repository Package Build failed:' SLACK_USERNAME: 'GitHub Actions' - SLACK_MESSAGE: "${{ matrix.pkgclouddistro }} ${{ matrix.version }} repository package build failed." + SLACK_MESSAGE: |- + ${{ github.repository }}: ${{ matrix.pkgclouddistro }} ${{ matrix.version }} repository package build failed. + Checkout: ${{ steps.checkout.outcome }} + Fetch images: ${{ steps.fetch-images.outcome }} + Build: ${{ steps.build.outcome }} + Publish: ${{ steps.publish.outcome }} SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} diff --git a/.github/workflows/review.yml b/.github/workflows/review.yml index b6ee6fcf7..f631b929a 100644 --- a/.github/workflows/review.yml +++ b/.github/workflows/review.yml @@ -4,7 +4,7 @@ name: Review on: pull_request: null env: - DO_NOT_TRACK: 1 + DISABLE_TELEMETRY: 1 concurrency: group: review-${{ github.ref }} cancel-in-progress: true @@ -20,7 +20,7 @@ jobs: yamllint: ${{ steps.yamllint.outputs.run }} steps: - name: Clone repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive fetch-depth: 0 @@ -77,7 +77,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Git clone repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive fetch-depth: 0 @@ -94,7 +94,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Git clone repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive fetch-depth: 0 @@ -114,7 +114,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Git clone repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 - name: Run hadolint @@ -130,7 +130,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Git clone repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive fetch-depth: 0 @@ -150,7 +150,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Git clone repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive fetch-depth: 0 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 20c6f7b8c..7e53c4979 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -15,7 +15,7 @@ on: - '**.c' - '**.h' env: - DO_NOT_TRACK: 1 + DISABLE_TELEMETRY: 1 concurrency: group: tests-${{ github.ref }} cancel-in-progress: true @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive - name: Prepare environment @@ -45,7 +45,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive - name: Prepare environment @@ -90,7 +90,7 @@ jobs: find . -type f -name '*.log' -exec cp {} ../logs/ \; popd || exit 1 - name: Upload Artifacts - uses: actions/upload-artifact@v2.2.4 + uses: actions/upload-artifact@v3 if: always() with: name: logs diff --git a/.github/workflows/trigger-learn-update.yml b/.github/workflows/trigger-learn-update.yml new file mode 100644 index 000000000..3d39ebabc --- /dev/null +++ b/.github/workflows/trigger-learn-update.yml @@ -0,0 +1,37 @@ +--- +name: Trigger Netdata Learn documentation update +on: + push: + branches: + - master + paths: + - "**.mdx?" + - "packaging/installer/kickstart.sh" +concurrency: + group: learn-trigger-${{ github.ref }} + cancel-in-progress: true +jobs: + trigger-ingest: + name: Trigger Netdata Learn ingest workflow. + if: github.repository == 'netdata/netdata' + runs-on: ubuntu-latest + steps: + - name: Trigger Netdata Learn ingest workflow. + uses: benc-uk/workflow-dispatch@v1 + with: + token: ${{ secrets.NETDATABOT_GITHUB_TOKEN }} + repo: netdata/learn + workflow: Ingest + ref: refs/heads/master + - name: Failure Notification + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_COLOR: 'danger' + SLACK_FOOTER: '' + SLACK_ICON_EMOJI: ':github-actions:' + SLACK_TITLE: 'Triggering Netdata Learn documentation update failed:' + SLACK_USERNAME: 'GitHub Actions' + SLACK_MESSAGE: |- + ${{ github.repository }}: Failed to trigger Netdata Learn documentation update workflow. + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} + if: failure() diff --git a/.gitignore b/.gitignore index cd4896f98..ab19032c9 100644 --- a/.gitignore +++ b/.gitignore @@ -72,6 +72,7 @@ cgroup-network ebpf.plugin collectors/ebpf.plugin/reset_netdata_trace.sh !ebpf.plugin/ +collectors/ebpf.plugin/includes/ # protoc generated files *.pb.cc @@ -226,3 +227,6 @@ Session.*.vim # Special exceptions !packaging/repoconfig/Makefile + +# Jupyter notebook checkpoints +.ipynb_checkpoints diff --git a/.travis.yml b/.travis.yml index 32ee455e5..838799f8f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,26 +51,6 @@ stages: - name: Build process if: commit_message =~ /^((?!\[Package (amd64|arm64|i386) (DEB|RPM)( .*)?\]).)*$/ - # Nightly operations - - name: Nightly operations - if: branch = master AND type = cron AND env(RUN_NIGHTLY) = yes - - - name: Nightly release - if: branch = master AND type = cron AND env(RUN_NIGHTLY) = yes - - # Scheduled releases - - name: Support activities on main branch - if: branch = master AND type != pull_request AND type != cron AND repo = netdata/netdata - - # We don't run on release candidates - - name: Publish for release - if: >- - branch = master - AND type != pull_request - AND type != cron - AND tag !~ /(-rc)/ - AND commit_message =~ /\[netdata (release candidate|(major|minor|patch) release)\]/ - # Define stage implementation details # @@ -86,72 +66,3 @@ jobs: script: fakeroot ./netdata-installer.sh --install $HOME --dont-wait --dont-start-it --enable-plugin-nfacct --enable-plugin-freeipmi --disable-lto env: CFLAGS='-O1 -Wall -Wextra -Wformat-signedness -fstack-protector-all -fno-common -DNETDATA_INTERNAL_CHECKS=1 -D_FORTIFY_SOURCE=2 -DNETDATA_VERIFY_LOCKS=1' after_failure: post_message "TRAVIS_MESSAGE" " standard netdata build is failing (Still dont know which one, will improve soon)" - - - stage: Support activities on main branch - name: Generate changelog for release (only on special and tagged commit msg) - before_script: post_message "TRAVIS_MESSAGE" "Support activities on main branch initiated" "${NOTIF_CHANNEL}" - script: - - echo "GIT Branch:" && git branch - - echo "Last commit:" && git log -1 - - echo "GIT Describe:" && git describe - - echo "packaging/version:" && cat packaging/version - - if [[ -z "${GIT_TAG}" ]]; then echo "Running set tag for release" && set_tag_for_release; fi; - - .travis/generate_changelog_and_tag_release.sh - after_failure: post_message "TRAVIS_MESSAGE" " Changelog generation and tag of release, failed" - git: - depth: false - if: commit_message =~ /\[netdata (release candidate|(major|minor|patch) release)\]/ AND tag !~ /(-rc)/ OR (env(GIT_TAG) IS present AND NOT env(GIT_TAG) IS blank) - - # We only publish if a TAG has been set during packaging - - stage: Publish for release - name: Trigger release build and draft release creation - script: - - git checkout "${TRAVIS_BRANCH}" && export BUILD_VERSION="$(cat packaging/version)" - - .travis/trigger_artifact_build.sh "${GITHUB_TOKEN}" "${BUILD_VERSION}" "release" - after_failure: post_message "TRAVIS_MESSAGE" " Failed to trigger release artifact build during nightly release" "${NOTIF_CHANNEL}" - - - name: Trigger Docker image build and publish - script: - - git checkout "${TRAVIS_BRANCH}" && export BUILD_VERSION="$(cat packaging/version | cut -d'-' -f1)" - - .travis/trigger_docker_build.sh "${GITHUB_TOKEN}" "${BUILD_VERSION}" - after_failure: post_message "TRAVIS_MESSAGE" " Failed to trigger docker build during release" "${NOTIF_CHANNEL}" - - - name: Trigger DEB and RPM package build - script: - - git checkout "${TRAVIS_BRANCH}" && export BUILD_VERSION="$(cat packaging/version | sed 's/^v//' | cut -d'-' -f1)" - - .travis/trigger_package_build.sh "${GITHUB_TOKEN}" "${BUILD_VERSION}" "release" - after_failure: post_message "TRAVIS_MESSAGE" " Failed to trigger deb and rpm package build during release" "${NOTIF_CHANNEL}" - - - # This is the nightly pre-execution step (Jobs, preparatory steps for nightly, etc) - - stage: Nightly operations - name: Kickstart files integrity testing (extended) - script: ./tests/installer/checksums.sh - - # This is generating the changelog for nightly release and publish it - - name: Generate nightly changelog - script: - - ".travis/nightlies.sh" - - ".travis/check_changelog_last_modification.sh" - after_failure: post_message "TRAVIS_MESSAGE" " Nightly changelog generation failed" - git: - depth: false - - # This is the nightly execution step - # - - stage: Nightly release - name: Trigger nightly artifact build and upload - script: - - git checkout "${TRAVIS_BRANCH}" && export BUILD_VERSION="$(cat packaging/version)" - - .travis/trigger_artifact_build.sh "${GITHUB_TOKEN}" "${BUILD_VERSION}" "nightly" - after_failure: post_message "TRAVIS_MESSAGE" " Failed to trigger release artifact build during nightly release" "${NOTIF_CHANNEL}" - - - name: Trigger Docker image build and publish - script: .travis/trigger_docker_build.sh "${GITHUB_TOKEN}" "nightly" - after_failure: post_message "TRAVIS_MESSAGE" " Failed to trigger docker build during nightly release" "${NOTIF_CHANNEL}" - - - name: Trigger DEB and RPM package build - script: - - git checkout "${TRAVIS_BRANCH}" && export BUILD_VERSION="$(cat packaging/version | sed 's/^v//')" - - .travis/trigger_package_build.sh "${GITHUB_TOKEN}" "${BUILD_VERSION}" "nightly" - after_failure: post_message "TRAVIS_MESSAGE" " Failed to trigger deb and rpm package build during nightly release" "${NOTIF_CHANNEL}" diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md index 20d055621..3399cb61f 100644 --- a/BREAKING_CHANGES.md +++ b/BREAKING_CHANGES.md @@ -8,4 +8,4 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/BREAKING_CHANGES - remove deprecated bash modules (`apache`, `cpu_apps`, `cpufreq`, `exim`, `hddtemp`, `load_average`, `mem_apps`, `mysql`, `nginx`, `phpfpm`, `postfix`, `squid`, `tomcat`) [[#7962](https://github.com/netdata/netdata/pull/7962)] -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2BREAKING_CHANGES&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/BUILD.md b/BUILD.md index 049c86d3f..83f7e9945 100644 --- a/BUILD.md +++ b/BUILD.md @@ -362,4 +362,4 @@ Some smaller miscellaneous suggestions: * [header checks in CMake](https://stackoverflow.com/questions/647892/how-to-check-header-files-and-library-functions-in-cmake-like-it-is-done-in-auto) * [how to write platform checks](https://gitlab.kitware.com/cmake/community/wikis/doc/tutorials/How-To-Write-Platform-Checks) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2FBUILD&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/CHANGELOG.md b/CHANGELOG.md index e303b54d6..7916bf83a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,258 @@ # Changelog +## [v1.34.0](https://github.com/netdata/netdata/tree/v1.34.0) (2022-04-14) + +[Full Changelog](https://github.com/netdata/netdata/compare/v1.33.1...v1.34.0) + +**Merged pull requests:** + +- Cancel anomaly detection threads before joining. [\#12681](https://github.com/netdata/netdata/pull/12681) ([vkalintiris](https://github.com/vkalintiris)) +- Update dashboard to version v2.25.0. [\#12680](https://github.com/netdata/netdata/pull/12680) ([netdatabot](https://github.com/netdatabot)) +- Delete ML-related data of a host in the proper order. [\#12672](https://github.com/netdata/netdata/pull/12672) ([vkalintiris](https://github.com/vkalintiris)) +- fix\(ebpf.plugin\): add missing chart context for cgroups charts [\#12671](https://github.com/netdata/netdata/pull/12671) ([ilyam8](https://github.com/ilyam8)) +- Remove on pull\_request trigger [\#12670](https://github.com/netdata/netdata/pull/12670) ([dimko](https://github.com/dimko)) +- \[Stream compression Docs\] - Enabled by default [\#12669](https://github.com/netdata/netdata/pull/12669) ([odynik](https://github.com/odynik)) +- Update dashboard to version v2.24.0. [\#12668](https://github.com/netdata/netdata/pull/12668) ([netdatabot](https://github.com/netdatabot)) +- Show error when clock synchronization state is unavailable [\#12667](https://github.com/netdata/netdata/pull/12667) ([vlvkobal](https://github.com/vlvkobal)) +- Dashboard network title [\#12665](https://github.com/netdata/netdata/pull/12665) ([thiagoftsm](https://github.com/thiagoftsm)) +- bump go.d.plugin version to v0.32.2 [\#12663](https://github.com/netdata/netdata/pull/12663) ([ilyam8](https://github.com/ilyam8)) +- Properly limit repository configuration dependencies. [\#12661](https://github.com/netdata/netdata/pull/12661) ([Ferroin](https://github.com/Ferroin)) +- Show --build-only instead of --only-build [\#12657](https://github.com/netdata/netdata/pull/12657) ([MrZammler](https://github.com/MrZammler)) +- Update dashboard to version v2.22.6. [\#12653](https://github.com/netdata/netdata/pull/12653) ([netdatabot](https://github.com/netdatabot)) +- Add a chart label filter parameter in context data queries [\#12652](https://github.com/netdata/netdata/pull/12652) ([stelfrag](https://github.com/stelfrag)) +- Add a timeout parameter to data queries [\#12649](https://github.com/netdata/netdata/pull/12649) ([stelfrag](https://github.com/stelfrag)) +- fix: remove instance-specific information from chart titles [\#12644](https://github.com/netdata/netdata/pull/12644) ([ilyam8](https://github.com/ilyam8)) +- feat: add k8s\_cluster\_name host tag \(GKE only\) [\#12638](https://github.com/netdata/netdata/pull/12638) ([ilyam8](https://github.com/ilyam8)) +- Summarize encountered errors and warnings at end of kickstart script run. [\#12636](https://github.com/netdata/netdata/pull/12636) ([Ferroin](https://github.com/Ferroin)) +- Add eBPF CO-RE version and checksum files to distfile list. [\#12627](https://github.com/netdata/netdata/pull/12627) ([Ferroin](https://github.com/Ferroin)) +- Fix ACLK shutdown [\#12625](https://github.com/netdata/netdata/pull/12625) ([underhood](https://github.com/underhood)) +- Don't do fatal on error writing the health api management key. [\#12623](https://github.com/netdata/netdata/pull/12623) ([MrZammler](https://github.com/MrZammler)) +- fix\(cgroups.plugin\): set CPU prev usage before first usage. [\#12622](https://github.com/netdata/netdata/pull/12622) ([ilyam8](https://github.com/ilyam8)) +- eBPF update dashboard [\#12617](https://github.com/netdata/netdata/pull/12617) ([thiagoftsm](https://github.com/thiagoftsm)) +- fix print: command not found issue [\#12615](https://github.com/netdata/netdata/pull/12615) ([maneamarius](https://github.com/maneamarius)) +- feat: add support for cloud providers info to /api/v1/info [\#12613](https://github.com/netdata/netdata/pull/12613) ([ilyam8](https://github.com/ilyam8)) +- Fix training/prediction stats charts context. [\#12610](https://github.com/netdata/netdata/pull/12610) ([vkalintiris](https://github.com/vkalintiris)) +- Fix a compilation warning [\#12608](https://github.com/netdata/netdata/pull/12608) ([vlvkobal](https://github.com/vlvkobal)) +- Update dashboard to version v2.22.3. [\#12607](https://github.com/netdata/netdata/pull/12607) ([netdatabot](https://github.com/netdatabot)) +- Enable streaming of anomaly\_detection.\* charts [\#12606](https://github.com/netdata/netdata/pull/12606) ([vkalintiris](https://github.com/vkalintiris)) +- Better check for IOMainPort on MacOS [\#12600](https://github.com/netdata/netdata/pull/12600) ([vlvkobal](https://github.com/vlvkobal)) +- Fix coverity issues [\#12598](https://github.com/netdata/netdata/pull/12598) ([vkalintiris](https://github.com/vkalintiris)) +- chore: make logs less noisy on child reconnect [\#12594](https://github.com/netdata/netdata/pull/12594) ([ilyam8](https://github.com/ilyam8)) +- feat\(cgroups.plugin\): add CPU throttling charts [\#12591](https://github.com/netdata/netdata/pull/12591) ([ilyam8](https://github.com/ilyam8)) +- Fix ebpf exit [\#12590](https://github.com/netdata/netdata/pull/12590) ([thiagoftsm](https://github.com/thiagoftsm)) +- feat\(collectors\): update go.d.plugin version to v0.32.1 [\#12586](https://github.com/netdata/netdata/pull/12586) ([ilyam8](https://github.com/ilyam8)) +- Check if libatomic can be linked [\#12583](https://github.com/netdata/netdata/pull/12583) ([MrZammler](https://github.com/MrZammler)) +- Update links to documentation \(eBPF\) [\#12581](https://github.com/netdata/netdata/pull/12581) ([thiagoftsm](https://github.com/thiagoftsm)) +- fix: re-add setuid bit to ioping after installing Debian package [\#12580](https://github.com/netdata/netdata/pull/12580) ([ilyam8](https://github.com/ilyam8)) +- Kickstart improved messaging [\#12577](https://github.com/netdata/netdata/pull/12577) ([Ferroin](https://github.com/Ferroin)) +- add some new ml params to README [\#12575](https://github.com/netdata/netdata/pull/12575) ([andrewm4894](https://github.com/andrewm4894)) +- Update ML-related charts [\#12574](https://github.com/netdata/netdata/pull/12574) ([vkalintiris](https://github.com/vkalintiris)) +- update anonymous-statistics readme for PH Cloud [\#12571](https://github.com/netdata/netdata/pull/12571) ([andrewm4894](https://github.com/andrewm4894)) +- Respect dimension hidden option when executing a query [\#12570](https://github.com/netdata/netdata/pull/12570) ([stelfrag](https://github.com/stelfrag)) +- \[Agent crash on api/v1/info call\] - fixes \#12559 [\#12565](https://github.com/netdata/netdata/pull/12565) ([erdem2000](https://github.com/erdem2000)) +- Fix temporary directory handling for dependency handling script in updater. [\#12562](https://github.com/netdata/netdata/pull/12562) ([Ferroin](https://github.com/Ferroin)) +- feat\(netdata-updater\): add the script name when logging [\#12557](https://github.com/netdata/netdata/pull/12557) ([ilyam8](https://github.com/ilyam8)) +- Fix Build on MacOS [\#12554](https://github.com/netdata/netdata/pull/12554) ([underhood](https://github.com/underhood)) +- Unblock cgroup version detection with systemd [\#12553](https://github.com/netdata/netdata/pull/12553) ([vlvkobal](https://github.com/vlvkobal)) +- fix FreeBSD bundled protobuf build if system one is present [\#12552](https://github.com/netdata/netdata/pull/12552) ([underhood](https://github.com/underhood)) +- fix: use `/proc/cpuinfo` for CPU freq detection as a last resort [\#12550](https://github.com/netdata/netdata/pull/12550) ([ilyam8](https://github.com/ilyam8)) +- add --reinstall-clean flag for kickstart.sh and update documentation [\#12548](https://github.com/netdata/netdata/pull/12548) ([maneamarius](https://github.com/maneamarius)) +- Don't send alert events without wc-\>host [\#12547](https://github.com/netdata/netdata/pull/12547) ([MrZammler](https://github.com/MrZammler)) +- reduce min `dbengine anomaly rate every` 60s-\>30s [\#12543](https://github.com/netdata/netdata/pull/12543) ([andrewm4894](https://github.com/andrewm4894)) +- Explicitly use debhelper to enable systemd service [\#12542](https://github.com/netdata/netdata/pull/12542) ([ralphm](https://github.com/ralphm)) +- Allocate buffer and release on callback when executing agent CLI commands [\#12540](https://github.com/netdata/netdata/pull/12540) ([stelfrag](https://github.com/stelfrag)) +- Make sure registered static threads are unique. [\#12538](https://github.com/netdata/netdata/pull/12538) ([vkalintiris](https://github.com/vkalintiris)) +- packaging: upgrage protocol buffer version to 3.19.4 [\#12537](https://github.com/netdata/netdata/pull/12537) ([surajnpn](https://github.com/surajnpn)) +- feat\(collectors\): update go.d.plugin version to v0.32.0 [\#12536](https://github.com/netdata/netdata/pull/12536) ([ilyam8](https://github.com/ilyam8)) +- Improve ACLK sync logging [\#12534](https://github.com/netdata/netdata/pull/12534) ([stelfrag](https://github.com/stelfrag)) +- Socket connections \(eBPF\) and bug fix [\#12532](https://github.com/netdata/netdata/pull/12532) ([thiagoftsm](https://github.com/thiagoftsm)) +- fix: use internal defaults for sched policy/oom score in native packages [\#12529](https://github.com/netdata/netdata/pull/12529) ([ilyam8](https://github.com/ilyam8)) +- docs: fix unresolved file references [\#12528](https://github.com/netdata/netdata/pull/12528) ([ilyam8](https://github.com/ilyam8)) +- fix\(kickstart.sh\): use `$ROOTCMD` when setting auto updates [\#12526](https://github.com/netdata/netdata/pull/12526) ([ilyam8](https://github.com/ilyam8)) +- fix\(netdata-updater\): properly handle update for debian packages [\#12524](https://github.com/netdata/netdata/pull/12524) ([ilyam8](https://github.com/ilyam8)) +- fix centos gpg key issue [\#12519](https://github.com/netdata/netdata/pull/12519) ([maneamarius](https://github.com/maneamarius)) +- fix: Netdata segfault because of 2 timex.plugin threads [\#12512](https://github.com/netdata/netdata/pull/12512) ([ilyam8](https://github.com/ilyam8)) +- Fix memory leaks on Netdata exit [\#12511](https://github.com/netdata/netdata/pull/12511) ([vlvkobal](https://github.com/vlvkobal)) +- fix centos7 gpg key issue [\#12506](https://github.com/netdata/netdata/pull/12506) ([maneamarius](https://github.com/maneamarius)) +- Use live charts to count the total number of dimensions. [\#12504](https://github.com/netdata/netdata/pull/12504) ([vkalintiris](https://github.com/vkalintiris)) +- Update ebpf doc [\#12503](https://github.com/netdata/netdata/pull/12503) ([thiagoftsm](https://github.com/thiagoftsm)) +- feat\(collectors/timex.plugin\): add clock status chart [\#12501](https://github.com/netdata/netdata/pull/12501) ([ilyam8](https://github.com/ilyam8)) +- PR template: Include user information section [\#12499](https://github.com/netdata/netdata/pull/12499) ([kickoke](https://github.com/kickoke)) +- add `locust` to `apps_groups.conf` [\#12498](https://github.com/netdata/netdata/pull/12498) ([andrewm4894](https://github.com/andrewm4894)) +- Properly skip running the updater in kickstart dry-run mode. [\#12497](https://github.com/netdata/netdata/pull/12497) ([Ferroin](https://github.com/Ferroin)) +- Adjust timex.plugin information to be less cryptic [\#12495](https://github.com/netdata/netdata/pull/12495) ([DanTheMediocre](https://github.com/DanTheMediocre)) +- ML-related changes to address issue/discussion comments. [\#12494](https://github.com/netdata/netdata/pull/12494) ([vkalintiris](https://github.com/vkalintiris)) +- fix: open fd 3 before first use in the netdata-updater.sh script [\#12491](https://github.com/netdata/netdata/pull/12491) ([ilyam8](https://github.com/ilyam8)) +- timex: this plugin enables timex plugin for non-linux systems [\#12489](https://github.com/netdata/netdata/pull/12489) ([surajnpn](https://github.com/surajnpn)) +- Bump the debhelper compat level to 10 in our DEB packaging code. [\#12488](https://github.com/netdata/netdata/pull/12488) ([Ferroin](https://github.com/Ferroin)) +- Properly recognize Almalinux as an RHEL clone. [\#12487](https://github.com/netdata/netdata/pull/12487) ([Ferroin](https://github.com/Ferroin)) +- minor - fix configure output of eBPF [\#12471](https://github.com/netdata/netdata/pull/12471) ([underhood](https://github.com/underhood)) +- Don't send an alert snapshot with snapshot\_id 0 [\#12469](https://github.com/netdata/netdata/pull/12469) ([MrZammler](https://github.com/MrZammler)) +- Update ebpf dashboard [\#12467](https://github.com/netdata/netdata/pull/12467) ([thiagoftsm](https://github.com/thiagoftsm)) +- docs\(collectors/python.d\): remove mention of compatibility with py2/py3 [\#12465](https://github.com/netdata/netdata/pull/12465) ([ilyam8](https://github.com/ilyam8)) +- feat\(collectors/cgroups\): prefer `blkio.*_recursive` when available [\#12462](https://github.com/netdata/netdata/pull/12462) ([ilyam8](https://github.com/ilyam8)) +- Updated static build components to latest versions. [\#12461](https://github.com/netdata/netdata/pull/12461) ([ktsaou](https://github.com/ktsaou)) +- Implement fine-grained errors to cloud queries [\#12460](https://github.com/netdata/netdata/pull/12460) ([underhood](https://github.com/underhood)) +- Extend aclk-state [\#12458](https://github.com/netdata/netdata/pull/12458) ([underhood](https://github.com/underhood)) +- Add support for passing extra claiming options when claiming with Docker. [\#12457](https://github.com/netdata/netdata/pull/12457) ([Ferroin](https://github.com/Ferroin)) +- Update dashboard to version v2.21.8. [\#12455](https://github.com/netdata/netdata/pull/12455) ([netdatabot](https://github.com/netdatabot)) +- fix\(collectors/cgroups\): use different context for cgroup network charts [\#12454](https://github.com/netdata/netdata/pull/12454) ([ilyam8](https://github.com/ilyam8)) +- Initialize foreach alarms of dimensions in health thread. [\#12452](https://github.com/netdata/netdata/pull/12452) ([vkalintiris](https://github.com/vkalintiris)) +- Fix issue with charts not properly synchronized with the cloud [\#12451](https://github.com/netdata/netdata/pull/12451) ([stelfrag](https://github.com/stelfrag)) +- Add delay on missing priv\_key [\#12450](https://github.com/netdata/netdata/pull/12450) ([underhood](https://github.com/underhood)) +- fix unclaimed agents [\#12449](https://github.com/netdata/netdata/pull/12449) ([underhood](https://github.com/underhood)) +- apps.plugin: fix for plugin sending unnecessary data in freebsd [\#12446](https://github.com/netdata/netdata/pull/12446) ([surajnpn](https://github.com/surajnpn)) +- fix\(cups.plugin\): add `cups` prefix to chart context [\#12444](https://github.com/netdata/netdata/pull/12444) ([ilyam8](https://github.com/ilyam8)) +- Skip `foreach` alarms for dimensions of anomaly rate chart. [\#12441](https://github.com/netdata/netdata/pull/12441) ([vkalintiris](https://github.com/vkalintiris)) +- fix: CPU frequency detection of FreeBSD [\#12440](https://github.com/netdata/netdata/pull/12440) ([ilyam8](https://github.com/ilyam8)) +- fix install type in netdata-uninstaller.sh [\#12438](https://github.com/netdata/netdata/pull/12438) ([maneamarius](https://github.com/maneamarius)) +- fix\(kickstart.sh\): prefer shasum over sha256sum [\#12429](https://github.com/netdata/netdata/pull/12429) ([ilyam8](https://github.com/ilyam8)) +- Docs: Fix broken link [\#12428](https://github.com/netdata/netdata/pull/12428) ([kickoke](https://github.com/kickoke)) +- Fix OS name for older agent versions streaming to a parent [\#12425](https://github.com/netdata/netdata/pull/12425) ([stelfrag](https://github.com/stelfrag)) +- fix: ensure claim\_id is always sent lowercase as string [\#12423](https://github.com/netdata/netdata/pull/12423) ([underhood](https://github.com/underhood)) +- fix: lowercase uuidgen [\#12422](https://github.com/netdata/netdata/pull/12422) ([ilyam8](https://github.com/ilyam8)) +- fix: add a delay between starting Netdata and checking pids [\#12420](https://github.com/netdata/netdata/pull/12420) ([ilyam8](https://github.com/ilyam8)) +- fix\(charts.d.plugin\): fix recursion in apcupsd\_check and enable it again [\#12418](https://github.com/netdata/netdata/pull/12418) ([ilyam8](https://github.com/ilyam8)) +- Add content for eBPF documentation [\#12417](https://github.com/netdata/netdata/pull/12417) ([thiagoftsm](https://github.com/thiagoftsm)) +- fix: temporarily disable charts.d apcupsd collectors [\#12415](https://github.com/netdata/netdata/pull/12415) ([ilyam8](https://github.com/ilyam8)) +- Add additional link to badges doc [\#12412](https://github.com/netdata/netdata/pull/12412) ([Steve8291](https://github.com/Steve8291)) +- chore: remove contrib/sles11 [\#12410](https://github.com/netdata/netdata/pull/12410) ([ilyam8](https://github.com/ilyam8)) +- Update dashboard to version v2.21.3. [\#12407](https://github.com/netdata/netdata/pull/12407) ([netdatabot](https://github.com/netdatabot)) +- chore: remove "web files" options leftovers [\#12403](https://github.com/netdata/netdata/pull/12403) ([ilyam8](https://github.com/ilyam8)) +- Allow updates without environment files in some cases. [\#12400](https://github.com/netdata/netdata/pull/12400) ([Ferroin](https://github.com/Ferroin)) +- Reorder functions properly in updater script. [\#12399](https://github.com/netdata/netdata/pull/12399) ([Ferroin](https://github.com/Ferroin)) +- Fix crash when netdatacli command output too long [\#12393](https://github.com/netdata/netdata/pull/12393) ([underhood](https://github.com/underhood)) +- Dont check host health enabled if host is null [\#12392](https://github.com/netdata/netdata/pull/12392) ([MrZammler](https://github.com/MrZammler)) +- Update build/m4/ax\_pthread.m4 [\#12390](https://github.com/netdata/netdata/pull/12390) ([vkalintiris](https://github.com/vkalintiris)) +- Delay removed event for 60 seconds after the chart's last collected time [\#12388](https://github.com/netdata/netdata/pull/12388) ([MrZammler](https://github.com/MrZammler)) +- Remove unecessary error report for proc and sys files [\#12385](https://github.com/netdata/netdata/pull/12385) ([thiagoftsm](https://github.com/thiagoftsm)) +- feat\(statsd.plugin\): add Asterisk configuration file with synthetic charts [\#12381](https://github.com/netdata/netdata/pull/12381) ([ilyam8](https://github.com/ilyam8)) +- fix: handle double host prefix when Netdata running in a podman container [\#12380](https://github.com/netdata/netdata/pull/12380) ([ilyam8](https://github.com/ilyam8)) +- fix\(ebpf.plugin\): remove pid file on exit [\#12379](https://github.com/netdata/netdata/pull/12379) ([thiagoftsm](https://github.com/thiagoftsm)) +- fix: shellcheck warnings in docker run.sh [\#12377](https://github.com/netdata/netdata/pull/12377) ([ilyam8](https://github.com/ilyam8)) +- Fix version handling issues in release workflow. [\#12375](https://github.com/netdata/netdata/pull/12375) ([Ferroin](https://github.com/Ferroin)) +- Update Agent version in the Swagger API [\#12374](https://github.com/netdata/netdata/pull/12374) ([tkatsoulas](https://github.com/tkatsoulas)) +- Fix handling of checks for newer updater script on update. [\#12367](https://github.com/netdata/netdata/pull/12367) ([Ferroin](https://github.com/Ferroin)) +- configure.ac: Unconditionally link against libatomic [\#12366](https://github.com/netdata/netdata/pull/12366) ([AlexGhiti](https://github.com/AlexGhiti)) +- Fix handling of pushing commits for release process. [\#12359](https://github.com/netdata/netdata/pull/12359) ([Ferroin](https://github.com/Ferroin)) +- Fix chart synchronization with the cloud [\#12356](https://github.com/netdata/netdata/pull/12356) ([stelfrag](https://github.com/stelfrag)) +- minor - fix analytics\_build\_info [\#12354](https://github.com/netdata/netdata/pull/12354) ([underhood](https://github.com/underhood)) +- Docs fix: Add missing frontmatter [\#12353](https://github.com/netdata/netdata/pull/12353) ([kickoke](https://github.com/kickoke)) +- fix\(health\): make ioping\_disk\_latency alarm less sensitive [\#12351](https://github.com/netdata/netdata/pull/12351) ([ilyam8](https://github.com/ilyam8)) +- Trigger cloud intergration workflow for PRs and pushes against master [\#12349](https://github.com/netdata/netdata/pull/12349) ([dimko](https://github.com/dimko)) +- Improve agent to cloud synchronization performance [\#12348](https://github.com/netdata/netdata/pull/12348) ([stelfrag](https://github.com/stelfrag)) +- Prepend context in anomaly rate dimension id. [\#12342](https://github.com/netdata/netdata/pull/12342) ([vkalintiris](https://github.com/vkalintiris)) +- Redirect dependency handling script output to logfile when running from the updater. [\#12341](https://github.com/netdata/netdata/pull/12341) ([Ferroin](https://github.com/Ferroin)) +- Remove owner check from webserver [\#12339](https://github.com/netdata/netdata/pull/12339) ([thiagoftsm](https://github.com/thiagoftsm)) +- fix: container virtualization detection with systemd-detect-virt [\#12338](https://github.com/netdata/netdata/pull/12338) ([ilyam8](https://github.com/ilyam8)) +- fix: use default "bind to" in native packages [\#12336](https://github.com/netdata/netdata/pull/12336) ([ilyam8](https://github.com/ilyam8)) +- Use the built agent version for Netdata static build archive name. [\#12335](https://github.com/netdata/netdata/pull/12335) ([Ferroin](https://github.com/Ferroin)) +- Set repo priority in YUM/DNF repository configuration. [\#12332](https://github.com/netdata/netdata/pull/12332) ([Ferroin](https://github.com/Ferroin)) +- Add latency dimension [\#12329](https://github.com/netdata/netdata/pull/12329) ([Steve8291](https://github.com/Steve8291)) +- Remove check for config file in stock conf dir [\#12327](https://github.com/netdata/netdata/pull/12327) ([Steve8291](https://github.com/Steve8291)) +- fix underscore in libnetfilter-acct-dev package [\#12326](https://github.com/netdata/netdata/pull/12326) ([Steve8291](https://github.com/Steve8291)) +- fix: returning 0 for CPU frequency when unknown [\#12323](https://github.com/netdata/netdata/pull/12323) ([ilyam8](https://github.com/ilyam8)) +- Add a dry run mode to the kickstart script. [\#12322](https://github.com/netdata/netdata/pull/12322) ([Ferroin](https://github.com/Ferroin)) +- fix\(health\): adjust 10s\_ipv4\_tcp\_resets\_sent warn trigger [\#12320](https://github.com/netdata/netdata/pull/12320) ([ilyam8](https://github.com/ilyam8)) +- CO-RE and syscalls [\#12318](https://github.com/netdata/netdata/pull/12318) ([thiagoftsm](https://github.com/thiagoftsm)) +- Fix 'connect' typo anomaly-detection-python.md [\#12317](https://github.com/netdata/netdata/pull/12317) ([DanTheMediocre](https://github.com/DanTheMediocre)) +- Add ml notebooks [\#12313](https://github.com/netdata/netdata/pull/12313) ([andrewm4894](https://github.com/andrewm4894)) +- Provide better handling of config files in Docker containers. [\#12310](https://github.com/netdata/netdata/pull/12310) ([Ferroin](https://github.com/Ferroin)) +- Replace write with read locks [\#12309](https://github.com/netdata/netdata/pull/12309) ([MrZammler](https://github.com/MrZammler)) +- adds node\_id into mirrored\_hosts list [\#12307](https://github.com/netdata/netdata/pull/12307) ([underhood](https://github.com/underhood)) +- fix: CPU frequency detection for some containers [\#12306](https://github.com/netdata/netdata/pull/12306) ([ilyam8](https://github.com/ilyam8)) +- introduce new chart for process states metrics [\#12305](https://github.com/netdata/netdata/pull/12305) ([surajnpn](https://github.com/surajnpn)) +- fix uninstall using kickstart flag [\#12304](https://github.com/netdata/netdata/pull/12304) ([maneamarius](https://github.com/maneamarius)) +- Workflow to trigger cloud regression e2e tests [\#12299](https://github.com/netdata/netdata/pull/12299) ([dimko](https://github.com/dimko)) +- Fixing stderr output when testing tmpdir [\#12298](https://github.com/netdata/netdata/pull/12298) ([godismyjudge95](https://github.com/godismyjudge95)) +- chore: remove unused variable in the system-info script [\#12297](https://github.com/netdata/netdata/pull/12297) ([ilyam8](https://github.com/ilyam8)) +- Switch to using netdata-updater.sh to toggle auto updates on and off when installing. [\#12296](https://github.com/netdata/netdata/pull/12296) ([Ferroin](https://github.com/Ferroin)) +- Pull in build dependencies when updating a locally built install. [\#12294](https://github.com/netdata/netdata/pull/12294) ([Ferroin](https://github.com/Ferroin)) +- fix: cpu system info detection on macOS [\#12293](https://github.com/netdata/netdata/pull/12293) ([ilyam8](https://github.com/ilyam8)) +- Only store alert hashes when iterated from localhost [\#12292](https://github.com/netdata/netdata/pull/12292) ([MrZammler](https://github.com/MrZammler)) +- fix\(kickstart\): use correct syntax for claiming extra parameters [\#12289](https://github.com/netdata/netdata/pull/12289) ([ilyam8](https://github.com/ilyam8)) +- feat\(health\): add charts.d/nut alarms [\#12285](https://github.com/netdata/netdata/pull/12285) ([ilyam8](https://github.com/ilyam8)) +- Adjust cloud dimension update frequency [\#12284](https://github.com/netdata/netdata/pull/12284) ([stelfrag](https://github.com/stelfrag)) +- Fix incorrect install type on some older nightly installs. [\#12282](https://github.com/netdata/netdata/pull/12282) ([Ferroin](https://github.com/Ferroin)) +- Timex: make offset rrd independently configurable [\#12281](https://github.com/netdata/netdata/pull/12281) ([d--j](https://github.com/d--j)) +- add host labels \_aclk\_ng\_new\_cloud\_protocol [\#12278](https://github.com/netdata/netdata/pull/12278) ([underhood](https://github.com/underhood)) +- Use the new error mechanism in case host not found [\#12277](https://github.com/netdata/netdata/pull/12277) ([underhood](https://github.com/underhood)) +- Add proper handling for legacy kickstart install detection. [\#12273](https://github.com/netdata/netdata/pull/12273) ([Ferroin](https://github.com/Ferroin)) +- Fixed typos in docs/Running-behind-haproxy.md [\#12272](https://github.com/netdata/netdata/pull/12272) ([RatishT](https://github.com/RatishT)) +- Change default OOM score and scheduling policy to behave more sanely. [\#12271](https://github.com/netdata/netdata/pull/12271) ([Ferroin](https://github.com/Ferroin)) +- Add Ubuntu 22.04 to CI and package builds. [\#12269](https://github.com/netdata/netdata/pull/12269) ([Ferroin](https://github.com/Ferroin)) +- Add Fedora 36 to CI and package builds. [\#12268](https://github.com/netdata/netdata/pull/12268) ([Ferroin](https://github.com/Ferroin)) +- Null terminate decoded\_query\_string if there are no url parameters. [\#12266](https://github.com/netdata/netdata/pull/12266) ([MrZammler](https://github.com/MrZammler)) +- delete package.json [\#12265](https://github.com/netdata/netdata/pull/12265) ([ilyam8](https://github.com/ilyam8)) +- Docs: Fix typo in step-10.md [\#12263](https://github.com/netdata/netdata/pull/12263) ([tnagorran](https://github.com/tnagorran)) +- Set a version number for the metadata database to better handle future data migrations [\#12249](https://github.com/netdata/netdata/pull/12249) ([stelfrag](https://github.com/stelfrag)) +- Revise claiming error message in kickstart script. [\#12248](https://github.com/netdata/netdata/pull/12248) ([Ferroin](https://github.com/Ferroin)) +- Add a check to make sure internal chart state is initialized [\#12244](https://github.com/netdata/netdata/pull/12244) ([stelfrag](https://github.com/stelfrag)) +- eBPF installation fixes [\#12242](https://github.com/netdata/netdata/pull/12242) ([thiagoftsm](https://github.com/thiagoftsm)) +- Add a fix to correctly register child nodes to the cloud via a parent [\#12241](https://github.com/netdata/netdata/pull/12241) ([stelfrag](https://github.com/stelfrag)) +- Fix builds where HAVE\_C\_\_\_ATOMIC is not defined. [\#12240](https://github.com/netdata/netdata/pull/12240) ([vkalintiris](https://github.com/vkalintiris)) +- Adds more info to aclk-state API call [\#12231](https://github.com/netdata/netdata/pull/12231) ([underhood](https://github.com/underhood)) +- minor - remove dead code [\#12230](https://github.com/netdata/netdata/pull/12230) ([underhood](https://github.com/underhood)) +- Fix node information send to the cloud for older agent versions [\#12223](https://github.com/netdata/netdata/pull/12223) ([stelfrag](https://github.com/stelfrag)) +- Fixed typo in docs/guides/monitor/anomaly-detection-python.md file [\#12220](https://github.com/netdata/netdata/pull/12220) ([MariosMarinos](https://github.com/MariosMarinos)) +- \[makeself\] Fix license URL [\#12219](https://github.com/netdata/netdata/pull/12219) ([Daniel15](https://github.com/Daniel15)) +- Update github's code owners configuration. [\#12213](https://github.com/netdata/netdata/pull/12213) ([vkalintiris](https://github.com/vkalintiris)) +- Skip training of constant metrics. [\#12212](https://github.com/netdata/netdata/pull/12212) ([vkalintiris](https://github.com/vkalintiris)) +- Add -W keepopenfds option. [\#12211](https://github.com/netdata/netdata/pull/12211) ([vkalintiris](https://github.com/vkalintiris)) +- Skip info field in protobuf alerts messages if it doesn't exist. [\#12210](https://github.com/netdata/netdata/pull/12210) ([MrZammler](https://github.com/MrZammler)) +- Remove chart specific configuration from netdata.conf except enabled [\#12209](https://github.com/netdata/netdata/pull/12209) ([stelfrag](https://github.com/stelfrag)) +- Fix two small typos in documentation [\#12208](https://github.com/netdata/netdata/pull/12208) ([xrgman](https://github.com/xrgman)) +- Fix `hpssa` parse error [\#12206](https://github.com/netdata/netdata/pull/12206) ([wooyey](https://github.com/wooyey)) +- Add support to the updater to toggle auto-updates on and off. [\#12202](https://github.com/netdata/netdata/pull/12202) ([Ferroin](https://github.com/Ferroin)) +- Improve cleaning up of orphan hosts [\#12201](https://github.com/netdata/netdata/pull/12201) ([stelfrag](https://github.com/stelfrag)) +- Fix detection of existing installs. [\#12199](https://github.com/netdata/netdata/pull/12199) ([Ferroin](https://github.com/Ferroin)) +- Store dimension hidden option in the metadata db [\#12196](https://github.com/netdata/netdata/pull/12196) ([stelfrag](https://github.com/stelfrag)) +- make netdata-uninstaller.sh POSIX compatibility and add --uninstall flag… [\#12195](https://github.com/netdata/netdata/pull/12195) ([maneamarius](https://github.com/maneamarius)) +- docs: document the issue with seccomp and claiming [\#12192](https://github.com/netdata/netdata/pull/12192) ([ilyam8](https://github.com/ilyam8)) +- fix\(docs\): unresolved file references [\#12191](https://github.com/netdata/netdata/pull/12191) ([ilyam8](https://github.com/ilyam8)) +- Update libs code [\#12190](https://github.com/netdata/netdata/pull/12190) ([thiagoftsm](https://github.com/thiagoftsm)) +- fix\(python.d/nvidia\_smi\): use uid when can't find the username [\#12184](https://github.com/netdata/netdata/pull/12184) ([ilyam8](https://github.com/ilyam8)) +- Fix typos [\#12183](https://github.com/netdata/netdata/pull/12183) ([rex4539](https://github.com/rex4539)) +- Revert "Overhaul handling of auto-updates in the installer code. \(\#12076 [\#12182](https://github.com/netdata/netdata/pull/12182) ([Ferroin](https://github.com/Ferroin)) +- Add warning about broken Docker hosts in container entrypoint. [\#12175](https://github.com/netdata/netdata/pull/12175) ([Ferroin](https://github.com/Ferroin)) +- tidy up the installer script usage message [\#12171](https://github.com/netdata/netdata/pull/12171) ([petecooper](https://github.com/petecooper)) +- Remove check for ACLK\_NG and PROMETHEUS\_WRITE in order to assume PROTOBUF [\#12168](https://github.com/netdata/netdata/pull/12168) ([MrZammler](https://github.com/MrZammler)) +- Bundle protobuf on CentOS 7 and earlier. [\#12167](https://github.com/netdata/netdata/pull/12167) ([Ferroin](https://github.com/Ferroin)) +- add `stress-ng` and `gremlin` to apps\_groups.conf [\#12165](https://github.com/netdata/netdata/pull/12165) ([andrewm4894](https://github.com/andrewm4894)) +- Fix alerts to raise correctly when the delay and repeat parameters are used together. [\#12164](https://github.com/netdata/netdata/pull/12164) ([erdem2000](https://github.com/erdem2000)) +- fix: claiming with wget [\#12163](https://github.com/netdata/netdata/pull/12163) ([ilyam8](https://github.com/ilyam8)) +- fix: CPU frequency calculation in system-info.sh [\#12162](https://github.com/netdata/netdata/pull/12162) ([ilyam8](https://github.com/ilyam8)) +- Docs fix: Claim nodes in the kickstart script [\#12161](https://github.com/netdata/netdata/pull/12161) ([kickoke](https://github.com/kickoke)) +- Update packaging CI to only run a limited set of jobs on PRs. [\#12156](https://github.com/netdata/netdata/pull/12156) ([Ferroin](https://github.com/Ferroin)) +- kickstart.sh: fix quoting for globbing [\#12148](https://github.com/netdata/netdata/pull/12148) ([fayak](https://github.com/fayak)) +- Remove backends subsystem [\#12146](https://github.com/netdata/netdata/pull/12146) ([vlvkobal](https://github.com/vlvkobal)) +- Removed Google Analytics from the docs [\#12145](https://github.com/netdata/netdata/pull/12145) ([kickoke](https://github.com/kickoke)) +- Docs: Improved kickstart's cloud installation docs [\#12143](https://github.com/netdata/netdata/pull/12143) ([kickoke](https://github.com/kickoke)) +- Documentation: Fixed broken links [\#12142](https://github.com/netdata/netdata/pull/12142) ([kickoke](https://github.com/kickoke)) +- Fix typo in ZFS ARC Cache size info [\#12138](https://github.com/netdata/netdata/pull/12138) ([dvdmuckle](https://github.com/dvdmuckle)) +- Fix data query option allow\_past to correctly work in memory mode ram and save [\#12136](https://github.com/netdata/netdata/pull/12136) ([stelfrag](https://github.com/stelfrag)) +- Improve messaging around unknown install handling in kickstart script. [\#12134](https://github.com/netdata/netdata/pull/12134) ([Ferroin](https://github.com/Ferroin)) +- Fix the format=array output in context queries [\#12129](https://github.com/netdata/netdata/pull/12129) ([stelfrag](https://github.com/stelfrag)) +- rename DO\_NOT\_TRACK to DISABLE\_TELEMETRY [\#12126](https://github.com/netdata/netdata/pull/12126) ([ilyam8](https://github.com/ilyam8)) +- Bump follow-redirects from 1.14.7 to 1.14.8 [\#12124](https://github.com/netdata/netdata/pull/12124) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump karma from 6.0.2 to 6.3.14 [\#12116](https://github.com/netdata/netdata/pull/12116) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Track anomaly rates with DBEngine. [\#12083](https://github.com/netdata/netdata/pull/12083) ([vkalintiris](https://github.com/vkalintiris)) +- Fix compilation warnings on macOS [\#12082](https://github.com/netdata/netdata/pull/12082) ([vlvkobal](https://github.com/vlvkobal)) +- feat\(apps.plugin\): group Apple Filing Protocol daemons into `afp` group [\#12078](https://github.com/netdata/netdata/pull/12078) ([ilyam8](https://github.com/ilyam8)) +- Overhaul handling of auto-updates in the installer code. [\#12076](https://github.com/netdata/netdata/pull/12076) ([Ferroin](https://github.com/Ferroin)) +- Add serial numbers to chart names [\#12067](https://github.com/netdata/netdata/pull/12067) ([vlvkobal](https://github.com/vlvkobal)) +- Add handling for claiming non-standard install types with kickstart. [\#12064](https://github.com/netdata/netdata/pull/12064) ([Ferroin](https://github.com/Ferroin)) +- remove deprecated node.d modules [\#12047](https://github.com/netdata/netdata/pull/12047) ([ilyam8](https://github.com/ilyam8)) +- Remove SIZEOF\_VOIDP and ENVIRONMENT{32,64} macros. [\#12046](https://github.com/netdata/netdata/pull/12046) ([vkalintiris](https://github.com/vkalintiris)) +- Remove unused NETDATA\_NO\_ATOMIC\_INSTRUCTIONS macro [\#12045](https://github.com/netdata/netdata/pull/12045) ([vkalintiris](https://github.com/vkalintiris)) +- Remove NETDATA\_WITH\_UUID def because it's not used anywhere. [\#12044](https://github.com/netdata/netdata/pull/12044) ([vkalintiris](https://github.com/vkalintiris)) +- inform cloud about inability to satisfy request [\#12041](https://github.com/netdata/netdata/pull/12041) ([underhood](https://github.com/underhood)) +- adds install method to /api/v1/info as label [\#12040](https://github.com/netdata/netdata/pull/12040) ([underhood](https://github.com/underhood)) +- Stream compression - Deactivate compression at runtime in case of a compressor buffer overflow [\#12037](https://github.com/netdata/netdata/pull/12037) ([odynik](https://github.com/odynik)) +- Adds all query types to aclk\_processed\_query\_type [\#12036](https://github.com/netdata/netdata/pull/12036) ([underhood](https://github.com/underhood)) +- Create a removed alert event if chart goes obsolete [\#12021](https://github.com/netdata/netdata/pull/12021) ([MrZammler](https://github.com/MrZammler)) +- minor - remove ACLK\_NEWARCH\_DEVMODE [\#12018](https://github.com/netdata/netdata/pull/12018) ([underhood](https://github.com/underhood)) + ## [v1.33.1](https://github.com/netdata/netdata/tree/v1.33.1) (2022-02-14) [Full Changelog](https://github.com/netdata/netdata/compare/v1.33.0...v1.33.1) @@ -33,10 +286,6 @@ - Fix compilation errors for OpenSSL on macOS [\#12048](https://github.com/netdata/netdata/pull/12048) ([vlvkobal](https://github.com/vlvkobal)) - Updated the docs to match new install script [\#12042](https://github.com/netdata/netdata/pull/12042) ([kickoke](https://github.com/kickoke)) - Fix handling of removed packages with leftover config files in package check. [\#12033](https://github.com/netdata/netdata/pull/12033) ([Ferroin](https://github.com/Ferroin)) -- update existing OS dependencies scripts and add scripts for fedora an… [\#11963](https://github.com/netdata/netdata/pull/11963) ([maneamarius](https://github.com/maneamarius)) -- Posix [\#11961](https://github.com/netdata/netdata/pull/11961) ([maneamarius](https://github.com/maneamarius)) -- Updated formatting issues and copy [\#11944](https://github.com/netdata/netdata/pull/11944) ([kickoke](https://github.com/kickoke)) -- Replace CentOS 8 with RockyLinux 8 in CI and package builds. [\#11801](https://github.com/netdata/netdata/pull/11801) ([Ferroin](https://github.com/Ferroin)) ## [v1.33.0](https://github.com/netdata/netdata/tree/v1.33.0) (2022-01-26) @@ -55,89 +304,6 @@ - Add install type info to `-W buildinfo` output. [\#12010](https://github.com/netdata/netdata/pull/12010) ([Ferroin](https://github.com/Ferroin)) - Remove internal dbengine header from spawn/spawn\_client.c [\#12009](https://github.com/netdata/netdata/pull/12009) ([vkalintiris](https://github.com/vkalintiris)) - Fix typo in the dashboard\_info.js spigot part [\#12008](https://github.com/netdata/netdata/pull/12008) ([lokerhp](https://github.com/lokerhp)) -- Add support for NVME disks with blkext driver [\#12007](https://github.com/netdata/netdata/pull/12007) ([ralphm](https://github.com/ralphm)) -- Fix cleanup from a failed DEB install. [\#12006](https://github.com/netdata/netdata/pull/12006) ([Ferroin](https://github.com/Ferroin)) -- update go.d.plugin version to v0.31.2 [\#12005](https://github.com/netdata/netdata/pull/12005) ([ilyam8](https://github.com/ilyam8)) -- Fix handling of static archive selection for installs. [\#12004](https://github.com/netdata/netdata/pull/12004) ([Ferroin](https://github.com/Ferroin)) -- fix\(python.d.plugin\): prefer python3 if available [\#12001](https://github.com/netdata/netdata/pull/12001) ([ilyam8](https://github.com/ilyam8)) -- Fixing redirects [\#12000](https://github.com/netdata/netdata/pull/12000) ([kickoke](https://github.com/kickoke)) -- Fix install prefix handling for claiming code in new kickstart script. [\#11999](https://github.com/netdata/netdata/pull/11999) ([Ferroin](https://github.com/Ferroin)) -- Add alternative install command for macOS. [\#11997](https://github.com/netdata/netdata/pull/11997) ([Ferroin](https://github.com/Ferroin)) -- Fix queue removed alerts [\#11996](https://github.com/netdata/netdata/pull/11996) ([MrZammler](https://github.com/MrZammler)) -- update go.d.plugin version to v0.31.1 [\#11995](https://github.com/netdata/netdata/pull/11995) ([ilyam8](https://github.com/ilyam8)) -- Fix ib counters [\#11994](https://github.com/netdata/netdata/pull/11994) ([Saruspete](https://github.com/Saruspete)) -- eBPF plugin CO-RE and monitoring [\#11992](https://github.com/netdata/netdata/pull/11992) ([thiagoftsm](https://github.com/thiagoftsm)) -- Included link to charts.d example [\#11990](https://github.com/netdata/netdata/pull/11990) ([kickoke](https://github.com/kickoke)) -- Refined the python example for clarity [\#11989](https://github.com/netdata/netdata/pull/11989) ([kickoke](https://github.com/kickoke)) -- fix\(updater\): checksum validation for static build [\#11986](https://github.com/netdata/netdata/pull/11986) ([ilyam8](https://github.com/ilyam8)) -- fix\(python.d\): ignore decoding errors in ExecutableService [\#11979](https://github.com/netdata/netdata/pull/11979) ([ilyam8](https://github.com/ilyam8)) -- Deleted duplicate getting started doc [\#11978](https://github.com/netdata/netdata/pull/11978) ([kickoke](https://github.com/kickoke)) -- Bump lodash from 4.17.19 to 4.17.21 [\#11976](https://github.com/netdata/netdata/pull/11976) ([dependabot[bot]](https://github.com/apps/dependabot)) -- Better handle creation of UUID for claiming. [\#11974](https://github.com/netdata/netdata/pull/11974) ([Ferroin](https://github.com/Ferroin)) -- Fixes coverity 374746 [\#11973](https://github.com/netdata/netdata/pull/11973) ([MrZammler](https://github.com/MrZammler)) -- Bump follow-redirects from 1.13.2 to 1.14.7 [\#11972](https://github.com/netdata/netdata/pull/11972) ([dependabot[bot]](https://github.com/apps/dependabot)) -- Use libnetdata/required\_dummies.h in collectors. [\#11971](https://github.com/netdata/netdata/pull/11971) ([vkalintiris](https://github.com/vkalintiris)) -- Fixes Wrong Chart Description [\#11970](https://github.com/netdata/netdata/pull/11970) ([underhood](https://github.com/underhood)) -- Bump engine.io from 4.1.0 to 4.1.2 [\#11968](https://github.com/netdata/netdata/pull/11968) ([dependabot[bot]](https://github.com/apps/dependabot)) -- Do not use dbengine headers when dbengine is disabled. [\#11967](https://github.com/netdata/netdata/pull/11967) ([vkalintiris](https://github.com/vkalintiris)) -- Perform a host metadata update on child reconnection [\#11965](https://github.com/netdata/netdata/pull/11965) ([stelfrag](https://github.com/stelfrag)) -- Remove bitfields from rrdhost. [\#11964](https://github.com/netdata/netdata/pull/11964) ([vkalintiris](https://github.com/vkalintiris)) -- Update libmongoc CMake config [\#11962](https://github.com/netdata/netdata/pull/11962) ([vlvkobal](https://github.com/vlvkobal)) -- Find host and pass host-\>health\_enabled to cloud AlarmLogHealth message [\#11960](https://github.com/netdata/netdata/pull/11960) ([MrZammler](https://github.com/MrZammler)) -- Updated SNMP v3 documentation [\#11959](https://github.com/netdata/netdata/pull/11959) ([kickoke](https://github.com/kickoke)) -- Add a missing capability for the perf plugin [\#11958](https://github.com/netdata/netdata/pull/11958) ([vlvkobal](https://github.com/vlvkobal)) -- python.d/nvidia\_smi: add bar1 chart [\#11956](https://github.com/netdata/netdata/pull/11956) ([pbouchez](https://github.com/pbouchez)) -- Compute platform-specific list of static\_threads at runtime. [\#11955](https://github.com/netdata/netdata/pull/11955) ([vkalintiris](https://github.com/vkalintiris)) -- fix\(nfacct.plugin\): Netfilter accounting charts priority [\#11952](https://github.com/netdata/netdata/pull/11952) ([ilyam8](https://github.com/ilyam8)) -- fix\(nfacct.plugin\): Netfilter accounting data collection [\#11951](https://github.com/netdata/netdata/pull/11951) ([ilyam8](https://github.com/ilyam8)) -- fix: add a note that netfilter's `new` and `ignore` counters are removed in the latest kernel [\#11950](https://github.com/netdata/netdata/pull/11950) ([ilyam8](https://github.com/ilyam8)) -- Fix a broken link in dashboard\_info.js [\#11948](https://github.com/netdata/netdata/pull/11948) ([Ancairon](https://github.com/Ancairon)) -- fix retrieving service commands without failure [\#11947](https://github.com/netdata/netdata/pull/11947) ([maneamarius](https://github.com/maneamarius)) -- Fix yum config-manager check [\#11945](https://github.com/netdata/netdata/pull/11945) ([lgrn](https://github.com/lgrn)) -- Fixed formatting [\#11943](https://github.com/netdata/netdata/pull/11943) ([kickoke](https://github.com/kickoke)) -- Fix error in configure.ac [\#11937](https://github.com/netdata/netdata/pull/11937) ([underhood](https://github.com/underhood)) -- Update dashboard to version v2.20.15. [\#11934](https://github.com/netdata/netdata/pull/11934) ([netdatabot](https://github.com/netdatabot)) -- Blocking publish and in flight buffer regrowth [\#11932](https://github.com/netdata/netdata/pull/11932) ([underhood](https://github.com/underhood)) -- Try to find worker config thread from inactive threads for new architecture [\#11928](https://github.com/netdata/netdata/pull/11928) ([MrZammler](https://github.com/MrZammler)) -- Handle re-claim while the agent is running in new architecture [\#11924](https://github.com/netdata/netdata/pull/11924) ([MrZammler](https://github.com/MrZammler)) -- fix\(claim\): set URL\_BASE only if `-url` parameter value is not null [\#11919](https://github.com/netdata/netdata/pull/11919) ([ilyam8](https://github.com/ilyam8)) -- Include libatomic again to allow protobuf to resolve [\#11917](https://github.com/netdata/netdata/pull/11917) ([MrZammler](https://github.com/MrZammler)) -- Send ML feature information with UpdateNodeInfo. [\#11913](https://github.com/netdata/netdata/pull/11913) ([vkalintiris](https://github.com/vkalintiris)) -- Don’t verify optional dependencies in build test environments in CI. [\#11910](https://github.com/netdata/netdata/pull/11910) ([Ferroin](https://github.com/Ferroin)) -- fix getting latest release tag [\#11908](https://github.com/netdata/netdata/pull/11908) ([maneamarius](https://github.com/maneamarius)) -- Added "==" to the list of expression operators [\#11905](https://github.com/netdata/netdata/pull/11905) ([laned130](https://github.com/laned130)) -- fix\(docs\): unresolved file references [\#11903](https://github.com/netdata/netdata/pull/11903) ([ilyam8](https://github.com/ilyam8)) -- Fix slight errors [\#11902](https://github.com/netdata/netdata/pull/11902) ([ardabbour](https://github.com/ardabbour)) -- Fix time\_t format [\#11897](https://github.com/netdata/netdata/pull/11897) ([vlvkobal](https://github.com/vlvkobal)) -- Fix handling of agent restart on update. [\#11887](https://github.com/netdata/netdata/pull/11887) ([Ferroin](https://github.com/Ferroin)) -- Provide runtime ml info from a new endpoint. [\#11886](https://github.com/netdata/netdata/pull/11886) ([vkalintiris](https://github.com/vkalintiris)) -- fix permissions of plugins that may be built [\#11877](https://github.com/netdata/netdata/pull/11877) ([boxjan](https://github.com/boxjan)) -- Use absolute features when doing training/prediction. [\#11876](https://github.com/netdata/netdata/pull/11876) ([vkalintiris](https://github.com/vkalintiris)) -- Update dependencies for the pubsub exporting connector [\#11872](https://github.com/netdata/netdata/pull/11872) ([vlvkobal](https://github.com/vlvkobal)) -- Fix the code that checks for available updates. [\#11870](https://github.com/netdata/netdata/pull/11870) ([Ferroin](https://github.com/Ferroin)) -- Don't check for symbols in libaws-cpp-sdk-core [\#11867](https://github.com/netdata/netdata/pull/11867) ([vlvkobal](https://github.com/vlvkobal)) -- ACLK-NG remove 'cmd' switch by message type [\#11866](https://github.com/netdata/netdata/pull/11866) ([underhood](https://github.com/underhood)) -- Update libbpf [\#11865](https://github.com/netdata/netdata/pull/11865) ([thiagoftsm](https://github.com/thiagoftsm)) -- Fix cmake build [\#11862](https://github.com/netdata/netdata/pull/11862) ([vlvkobal](https://github.com/vlvkobal)) -- chore: update community link of alert notifications [\#11860](https://github.com/netdata/netdata/pull/11860) ([burbuli8ra](https://github.com/burbuli8ra)) -- nvidia\_smi\_chart.py : fixed username for not-local users [\#11858](https://github.com/netdata/netdata/pull/11858) ([scatenag](https://github.com/scatenag)) -- Remove Ubuntu 21.04 from CI and packaging. [\#11851](https://github.com/netdata/netdata/pull/11851) ([Ferroin](https://github.com/Ferroin)) -- Allow PushBullet notifications to be sent to PushBullet channels [\#11850](https://github.com/netdata/netdata/pull/11850) ([sourcecodes2](https://github.com/sourcecodes2)) -- Fix compilation warnings [\#11846](https://github.com/netdata/netdata/pull/11846) ([vlvkobal](https://github.com/vlvkobal)) -- Send the cloud protocol used to posthog [\#11842](https://github.com/netdata/netdata/pull/11842) ([MrZammler](https://github.com/MrZammler)) -- Removes ACLK Legacy [\#11841](https://github.com/netdata/netdata/pull/11841) ([underhood](https://github.com/underhood)) -- Fix cachestat on kernel 5.15.x \(eBPF\) [\#11833](https://github.com/netdata/netdata/pull/11833) ([thiagoftsm](https://github.com/thiagoftsm)) -- feat\(python.d/fail2ban\): add "Failed attempts" chart, cleanup [\#11825](https://github.com/netdata/netdata/pull/11825) ([ilyam8](https://github.com/ilyam8)) -- Add code for LZ4 streaming data compression [\#11821](https://github.com/netdata/netdata/pull/11821) ([avstrakhov](https://github.com/avstrakhov)) -- Postgres: mat. views considered as tables in table size/count chart [\#11816](https://github.com/netdata/netdata/pull/11816) ([NikolayS](https://github.com/NikolayS)) -- Postgres: use block\_size instead of 8\*1024 [\#11815](https://github.com/netdata/netdata/pull/11815) ([NikolayS](https://github.com/NikolayS)) -- Optimize rx msg name resolution [\#11811](https://github.com/netdata/netdata/pull/11811) ([underhood](https://github.com/underhood)) -- Ignore clangd cache directory. [\#11803](https://github.com/netdata/netdata/pull/11803) ([vkalintiris](https://github.com/vkalintiris)) -- fix tps decode, add memory usage chart [\#11797](https://github.com/netdata/netdata/pull/11797) ([neotf](https://github.com/neotf)) -- Add localhost hostname to the edit\_command [\#11793](https://github.com/netdata/netdata/pull/11793) ([MrZammler](https://github.com/MrZammler)) -- Initial release of new kickstart script. [\#11764](https://github.com/netdata/netdata/pull/11764) ([Ferroin](https://github.com/Ferroin)) -- Add support to updater for updating native DEB/RPM installs with our official packages. [\#11753](https://github.com/netdata/netdata/pull/11753) ([Ferroin](https://github.com/Ferroin)) -- add note with link to guide for using on Pi [\#11605](https://github.com/netdata/netdata/pull/11605) ([andrewm4894](https://github.com/andrewm4894)) ## [1.32.1](https://github.com/netdata/netdata/tree/1.32.1) (2021-12-14) @@ -147,193 +313,10 @@ [Full Changelog](https://github.com/netdata/netdata/compare/v1.32.0...v1.32.1) -**Merged pull requests:** - -- Clean up anomaly-detection guide docs [\#11901](https://github.com/netdata/netdata/pull/11901) ([andrewm4894](https://github.com/andrewm4894)) -- Use the chart id instead of chart name in response to incoming cloud context queries [\#11898](https://github.com/netdata/netdata/pull/11898) ([stelfrag](https://github.com/stelfrag)) -- Moved data privacy section into a separate topic [\#11889](https://github.com/netdata/netdata/pull/11889) ([kickoke](https://github.com/kickoke)) -- Fixed formatting issues. [\#11888](https://github.com/netdata/netdata/pull/11888) ([kickoke](https://github.com/kickoke)) -- Fix postdrop handling for systemd systems. [\#11885](https://github.com/netdata/netdata/pull/11885) ([Ferroin](https://github.com/Ferroin)) -- Minor ACLK docu updates [\#11882](https://github.com/netdata/netdata/pull/11882) ([underhood](https://github.com/underhood)) -- Adds Swagger docs for new `/api/v1/aclk` endpoint [\#11881](https://github.com/netdata/netdata/pull/11881) ([underhood](https://github.com/underhood)) -- fix\(updater\): don't produce output when static update succeeded [\#11879](https://github.com/netdata/netdata/pull/11879) ([ilyam8](https://github.com/ilyam8)) -- fix\(updater\): fix exit code when updating static install && updater script [\#11873](https://github.com/netdata/netdata/pull/11873) ([ilyam8](https://github.com/ilyam8)) -- add z score alarm example [\#11871](https://github.com/netdata/netdata/pull/11871) ([andrewm4894](https://github.com/andrewm4894)) -- fix\(health\): used\_swap alarm calc [\#11868](https://github.com/netdata/netdata/pull/11868) ([ilyam8](https://github.com/ilyam8)) -- Initialize enabled parameter to 1 in AlarmLogHealth message [\#11856](https://github.com/netdata/netdata/pull/11856) ([MrZammler](https://github.com/MrZammler)) -- Explicitly conflict with distro netdata DEB packages. [\#11855](https://github.com/netdata/netdata/pull/11855) ([Ferroin](https://github.com/Ferroin)) -- fixed username for not-local users [\#11854](https://github.com/netdata/netdata/pull/11854) ([scatenag](https://github.com/scatenag)) -- fix static build, curl will be staict binary; extra args can be transfer [\#11852](https://github.com/netdata/netdata/pull/11852) ([boxjan](https://github.com/boxjan)) -- Create ML README.md [\#11848](https://github.com/netdata/netdata/pull/11848) ([andrewm4894](https://github.com/andrewm4894)) -- Fix token name in release draft workflow. [\#11847](https://github.com/netdata/netdata/pull/11847) ([Ferroin](https://github.com/Ferroin)) -- Bump static builds to use Alpine 3.15 as a base. [\#11836](https://github.com/netdata/netdata/pull/11836) ([Ferroin](https://github.com/Ferroin)) -- Detect whether libatomic should be linked in when using CXX linker. [\#11818](https://github.com/netdata/netdata/pull/11818) ([vkalintiris](https://github.com/vkalintiris)) -- Make netdata-updater.sh POSIX compliant. [\#11755](https://github.com/netdata/netdata/pull/11755) ([Ferroin](https://github.com/Ferroin)) -- Remove Fedora 33 from CI. [\#11640](https://github.com/netdata/netdata/pull/11640) ([Ferroin](https://github.com/Ferroin)) -- Remove OpenSUSE Leap 15.2 from CI. [\#11600](https://github.com/netdata/netdata/pull/11600) ([Ferroin](https://github.com/Ferroin)) - ## [v1.32.0](https://github.com/netdata/netdata/tree/v1.32.0) (2021-11-30) [Full Changelog](https://github.com/netdata/netdata/compare/v1.31.0...v1.32.0) -**Merged pull requests:** - -- fix\(health\): `pihole\_blocklist\_gravity\_file` and `pihole\_status` info lines [\#11844](https://github.com/netdata/netdata/pull/11844) ([ilyam8](https://github.com/ilyam8)) -- Optional proto support fix [\#11840](https://github.com/netdata/netdata/pull/11840) ([underhood](https://github.com/underhood)) -- feat\(apps.plugin\): add consul to apps\_groups.conf [\#11839](https://github.com/netdata/netdata/pull/11839) ([ilyam8](https://github.com/ilyam8)) -- Add a note about pkg-config file location for freeipmi [\#11831](https://github.com/netdata/netdata/pull/11831) ([vlvkobal](https://github.com/vlvkobal)) -- Remove pihole\_blocked\_queries alert [\#11829](https://github.com/netdata/netdata/pull/11829) ([Ancairon](https://github.com/Ancairon)) -- Add commands to check and fix database corruption [\#11828](https://github.com/netdata/netdata/pull/11828) ([stelfrag](https://github.com/stelfrag)) -- Set NETDATA\_CONTAINER\_OS\_DETECTION properly [\#11827](https://github.com/netdata/netdata/pull/11827) ([MrZammler](https://github.com/MrZammler)) -- feat\(apps.plugin\): add aws to apps\_groups.conf [\#11826](https://github.com/netdata/netdata/pull/11826) ([ilyam8](https://github.com/ilyam8)) -- Updating ansible steps for clarity [\#11823](https://github.com/netdata/netdata/pull/11823) ([kickoke](https://github.com/kickoke)) -- Don't use wc struct if it might not exist [\#11820](https://github.com/netdata/netdata/pull/11820) ([MrZammler](https://github.com/MrZammler)) -- specify pip3 when installing git-semver package [\#11817](https://github.com/netdata/netdata/pull/11817) ([maneamarius](https://github.com/maneamarius)) -- Cleanup compilation warnings [\#11810](https://github.com/netdata/netdata/pull/11810) ([stelfrag](https://github.com/stelfrag)) -- Fix coverity issues [\#11809](https://github.com/netdata/netdata/pull/11809) ([stelfrag](https://github.com/stelfrag)) -- Fix broken link in charts.mdx [\#11808](https://github.com/netdata/netdata/pull/11808) ([DShreve2](https://github.com/DShreve2)) -- Always queue alerts to aclk\_alert [\#11806](https://github.com/netdata/netdata/pull/11806) ([MrZammler](https://github.com/MrZammler)) -- Use two digits after the decimal point for the anomaly rate. [\#11804](https://github.com/netdata/netdata/pull/11804) ([vkalintiris](https://github.com/vkalintiris)) -- Add POWER8+ static builds. [\#11802](https://github.com/netdata/netdata/pull/11802) ([Ferroin](https://github.com/Ferroin)) -- Update libbpf [\#11800](https://github.com/netdata/netdata/pull/11800) ([thiagoftsm](https://github.com/thiagoftsm)) -- Assorted cleanups to static builds. [\#11798](https://github.com/netdata/netdata/pull/11798) ([Ferroin](https://github.com/Ferroin)) -- Use the proper format specifier when logging configuration options. [\#11795](https://github.com/netdata/netdata/pull/11795) ([vkalintiris](https://github.com/vkalintiris)) -- Verify checksums of makeself deps. [\#11791](https://github.com/netdata/netdata/pull/11791) ([vkalintiris](https://github.com/vkalintiris)) -- packaging: update go.d.plugin version to v0.31.0 [\#11789](https://github.com/netdata/netdata/pull/11789) ([ilyam8](https://github.com/ilyam8)) -- Add some logging for cloud new architecture to access.log [\#11788](https://github.com/netdata/netdata/pull/11788) ([MrZammler](https://github.com/MrZammler)) -- Simple fix for the data API query [\#11787](https://github.com/netdata/netdata/pull/11787) ([vlvkobal](https://github.com/vlvkobal)) -- Use correct hop count if host is already in memory [\#11785](https://github.com/netdata/netdata/pull/11785) ([stelfrag](https://github.com/stelfrag)) -- Fix proc/interrupts parser [\#11783](https://github.com/netdata/netdata/pull/11783) ([maximethebault](https://github.com/maximethebault)) -- Fix typos [\#11782](https://github.com/netdata/netdata/pull/11782) ([rex4539](https://github.com/rex4539)) -- add nightly release version to readme [\#11780](https://github.com/netdata/netdata/pull/11780) ([andrewm4894](https://github.com/andrewm4894)) -- Delete from aclk alerts table if ack'ed from cloud one day ago [\#11779](https://github.com/netdata/netdata/pull/11779) ([MrZammler](https://github.com/MrZammler)) -- Add Oracle Linux 8 to CI and package builds. [\#11776](https://github.com/netdata/netdata/pull/11776) ([Ferroin](https://github.com/Ferroin)) -- Temporary fix for cgroup renaming [\#11775](https://github.com/netdata/netdata/pull/11775) ([vlvkobal](https://github.com/vlvkobal)) -- Remove feature flag for ACLK new cloud architecture [\#11774](https://github.com/netdata/netdata/pull/11774) ([stelfrag](https://github.com/stelfrag)) -- Fix link to new charts. [\#11773](https://github.com/netdata/netdata/pull/11773) ([DShreve2](https://github.com/DShreve2)) -- Update netdata-security.md [\#11772](https://github.com/netdata/netdata/pull/11772) ([jlbriston](https://github.com/jlbriston)) -- Skip sending hidden dimensions via ACLK [\#11770](https://github.com/netdata/netdata/pull/11770) ([stelfrag](https://github.com/stelfrag)) -- Insert alert into aclk\_alert directly instead of queuing it [\#11769](https://github.com/netdata/netdata/pull/11769) ([MrZammler](https://github.com/MrZammler)) -- Fix host hop count reported to the cloud [\#11768](https://github.com/netdata/netdata/pull/11768) ([stelfrag](https://github.com/stelfrag)) -- Show stats for protected mount points in diskspace plugin [\#11767](https://github.com/netdata/netdata/pull/11767) ([vlvkobal](https://github.com/vlvkobal)) -- Adding parenthesis [\#11766](https://github.com/netdata/netdata/pull/11766) ([ShimonOhayon](https://github.com/ShimonOhayon)) -- fix log if D\_ACLK is used [\#11763](https://github.com/netdata/netdata/pull/11763) ([underhood](https://github.com/underhood)) -- Don't interrupt popcorn timer for children [\#11758](https://github.com/netdata/netdata/pull/11758) ([underhood](https://github.com/underhood)) -- fix \(cgroups.plugin\): containers name resolution for crio/containerd cri [\#11756](https://github.com/netdata/netdata/pull/11756) ([ilyam8](https://github.com/ilyam8)) -- Add SSL\_MODE\_ENABLE\_PARTIAL\_WRITE to netdata\_srv\_ctx [\#11754](https://github.com/netdata/netdata/pull/11754) ([MrZammler](https://github.com/MrZammler)) -- Update eBPF documenation \(Filesystem and HardIRQ\) [\#11752](https://github.com/netdata/netdata/pull/11752) ([UmanShahzad](https://github.com/UmanShahzad)) -- Adds exit points between env and OTP [\#11751](https://github.com/netdata/netdata/pull/11751) ([underhood](https://github.com/underhood)) -- Teach GH about ML label and its code owners. [\#11750](https://github.com/netdata/netdata/pull/11750) ([vkalintiris](https://github.com/vkalintiris)) -- Update enable-streaming.mdx [\#11747](https://github.com/netdata/netdata/pull/11747) ([caleno](https://github.com/caleno)) -- Minor improvement to CPU number function regarding macOS. [\#11746](https://github.com/netdata/netdata/pull/11746) ([iigorkarpov](https://github.com/iigorkarpov)) -- minor - popocorn no more [\#11745](https://github.com/netdata/netdata/pull/11745) ([underhood](https://github.com/underhood)) -- Update dashboard to version v2.20.11. [\#11743](https://github.com/netdata/netdata/pull/11743) ([netdatabot](https://github.com/netdatabot)) -- Update eBPF documentation [\#11741](https://github.com/netdata/netdata/pull/11741) ([thiagoftsm](https://github.com/thiagoftsm)) -- Change comma possition in v1/info if ml-info is missing [\#11739](https://github.com/netdata/netdata/pull/11739) ([MrZammler](https://github.com/MrZammler)) -- Disable C++ warnings from dlib library. [\#11738](https://github.com/netdata/netdata/pull/11738) ([vkalintiris](https://github.com/vkalintiris)) -- Fix typo in aclk\_query.c [\#11737](https://github.com/netdata/netdata/pull/11737) ([eltociear](https://github.com/eltociear)) -- Fix online chart in NG not updated properly [\#11734](https://github.com/netdata/netdata/pull/11734) ([underhood](https://github.com/underhood)) -- Add command for new health entity file. [\#11733](https://github.com/netdata/netdata/pull/11733) ([DShreve2](https://github.com/DShreve2)) -- Removing dated contact suggestion. [\#11732](https://github.com/netdata/netdata/pull/11732) ([DShreve2](https://github.com/DShreve2)) -- Fix Link to New Charts [\#11729](https://github.com/netdata/netdata/pull/11729) ([DShreve2](https://github.com/DShreve2)) -- Fix Header Link.md [\#11728](https://github.com/netdata/netdata/pull/11728) ([DShreve2](https://github.com/DShreve2)) -- Implements cloud initiated disconnect command [\#11723](https://github.com/netdata/netdata/pull/11723) ([underhood](https://github.com/underhood)) -- Adding \(eBPF\) to submenu [\#11721](https://github.com/netdata/netdata/pull/11721) ([thiagoftsm](https://github.com/thiagoftsm)) -- Fix coverity CID \#373610 [\#11719](https://github.com/netdata/netdata/pull/11719) ([MrZammler](https://github.com/MrZammler)) -- add sensors to charts.d.conf and add a note how to enable it [\#11715](https://github.com/netdata/netdata/pull/11715) ([ilyam8](https://github.com/ilyam8)) -- Add Cloud sign-up link to README.md [\#11714](https://github.com/netdata/netdata/pull/11714) ([DShreve2](https://github.com/DShreve2)) -- Updating Docker Node Instructions for Clarity [\#11713](https://github.com/netdata/netdata/pull/11713) ([DShreve2](https://github.com/DShreve2)) -- Update jQuery Dependency [\#11710](https://github.com/netdata/netdata/pull/11710) ([rupokify](https://github.com/rupokify)) -- Bring eBPF to static binaries [\#11709](https://github.com/netdata/netdata/pull/11709) ([thiagoftsm](https://github.com/thiagoftsm)) -- Fix kickstart.md Installation Guide Links [\#11708](https://github.com/netdata/netdata/pull/11708) ([DShreve2](https://github.com/DShreve2)) -- Queue removed alerts to cloud for new architecture [\#11704](https://github.com/netdata/netdata/pull/11704) ([MrZammler](https://github.com/MrZammler)) -- Ebpf doc [\#11703](https://github.com/netdata/netdata/pull/11703) ([thiagoftsm](https://github.com/thiagoftsm)) -- Charts 2.0 - fix broken link [\#11701](https://github.com/netdata/netdata/pull/11701) ([hugovalente-pm](https://github.com/hugovalente-pm)) -- postgres collector: Fix crash the wal query if wal-file was removed concurrently [\#11697](https://github.com/netdata/netdata/pull/11697) ([unhandled-exception](https://github.com/unhandled-exception)) -- Fix handling of disabling telemetry in static installs. [\#11689](https://github.com/netdata/netdata/pull/11689) ([Ferroin](https://github.com/Ferroin)) -- fix "lsns: unknown column" logging in cgroup-network-helper script [\#11687](https://github.com/netdata/netdata/pull/11687) ([ilyam8](https://github.com/ilyam8)) -- Fix coverity issues 373612 & 373611 [\#11684](https://github.com/netdata/netdata/pull/11684) ([MrZammler](https://github.com/MrZammler)) -- eBPF mdflush [\#11681](https://github.com/netdata/netdata/pull/11681) ([UmanShahzad](https://github.com/UmanShahzad)) -- New eBPF and libbpf releases [\#11680](https://github.com/netdata/netdata/pull/11680) ([thiagoftsm](https://github.com/thiagoftsm)) -- Mark g++ for freebsd as NOTREQUIRED [\#11678](https://github.com/netdata/netdata/pull/11678) ([MrZammler](https://github.com/MrZammler)) -- Fix warnings from -Wformat-truncation=2 [\#11676](https://github.com/netdata/netdata/pull/11676) ([MrZammler](https://github.com/MrZammler)) -- Stream chart labels [\#11675](https://github.com/netdata/netdata/pull/11675) ([MrZammler](https://github.com/MrZammler)) -- Update pfsense.md [\#11674](https://github.com/netdata/netdata/pull/11674) ([78Star](https://github.com/78Star)) -- fix swap\_used alarm calc [\#11672](https://github.com/netdata/netdata/pull/11672) ([ilyam8](https://github.com/ilyam8)) -- Fix line arguments \(eBPF\) [\#11670](https://github.com/netdata/netdata/pull/11670) ([thiagoftsm](https://github.com/thiagoftsm)) -- Add snapshot message for cloud new architecture [\#11664](https://github.com/netdata/netdata/pull/11664) ([MrZammler](https://github.com/MrZammler)) -- Fix interval usage and reduce I/O [\#11662](https://github.com/netdata/netdata/pull/11662) ([thiagoftsm](https://github.com/thiagoftsm)) -- Update dashboard to version v2.20.9. [\#11661](https://github.com/netdata/netdata/pull/11661) ([netdatabot](https://github.com/netdatabot)) -- Optimize static build and update various dependencies. [\#11660](https://github.com/netdata/netdata/pull/11660) ([Ferroin](https://github.com/Ferroin)) -- Sanely handle installing on systems with limited RAM. [\#11658](https://github.com/netdata/netdata/pull/11658) ([Ferroin](https://github.com/Ferroin)) -- Mark unmaintained tests as expected failures. [\#11657](https://github.com/netdata/netdata/pull/11657) ([vkalintiris](https://github.com/vkalintiris)) -- Fix build issue related to legacy aclk and new arch code [\#11655](https://github.com/netdata/netdata/pull/11655) ([MrZammler](https://github.com/MrZammler)) -- minor - fixes typo in URL when calling env [\#11651](https://github.com/netdata/netdata/pull/11651) ([underhood](https://github.com/underhood)) -- Fix false poll timeout [\#11650](https://github.com/netdata/netdata/pull/11650) ([underhood](https://github.com/underhood)) -- Use submodules in Clang build checks. [\#11649](https://github.com/netdata/netdata/pull/11649) ([Ferroin](https://github.com/Ferroin)) -- Fix chart config overflow [\#11645](https://github.com/netdata/netdata/pull/11645) ([stelfrag](https://github.com/stelfrag)) -- Explicitly opt out of LTO in RPM builds. [\#11644](https://github.com/netdata/netdata/pull/11644) ([Ferroin](https://github.com/Ferroin)) -- eBPF process \(collector improvements\) [\#11643](https://github.com/netdata/netdata/pull/11643) ([thiagoftsm](https://github.com/thiagoftsm)) -- eBPF cgroup integration [\#11642](https://github.com/netdata/netdata/pull/11642) ([thiagoftsm](https://github.com/thiagoftsm)) -- Add Fedora 35 to CI. [\#11641](https://github.com/netdata/netdata/pull/11641) ([Ferroin](https://github.com/Ferroin)) -- various fixes and updates for dashboard info [\#11639](https://github.com/netdata/netdata/pull/11639) ([ilyam8](https://github.com/ilyam8)) -- Fix an overflow when unsigned integer subtracted [\#11638](https://github.com/netdata/netdata/pull/11638) ([vlvkobal](https://github.com/vlvkobal)) -- add note for the new release of charts on the cloud [\#11637](https://github.com/netdata/netdata/pull/11637) ([hugovalente-pm](https://github.com/hugovalente-pm)) -- add timex.plugin charts info [\#11635](https://github.com/netdata/netdata/pull/11635) ([ilyam8](https://github.com/ilyam8)) -- Add protobuf to `-W buildinfo` output. [\#11634](https://github.com/netdata/netdata/pull/11634) ([Ferroin](https://github.com/Ferroin)) -- Revert "Update alarms info" [\#11633](https://github.com/netdata/netdata/pull/11633) ([ilyam8](https://github.com/ilyam8)) -- Fix nfsd RPC metrics and remove unused nfsd charts and metrics [\#11632](https://github.com/netdata/netdata/pull/11632) ([vlvkobal](https://github.com/vlvkobal)) -- add proc zfs charts info [\#11630](https://github.com/netdata/netdata/pull/11630) ([ilyam8](https://github.com/ilyam8)) -- Update dashboard to version v2.20.7. [\#11629](https://github.com/netdata/netdata/pull/11629) ([netdatabot](https://github.com/netdatabot)) -- add sys\_class\_infiniband charts info [\#11628](https://github.com/netdata/netdata/pull/11628) ([ilyam8](https://github.com/ilyam8)) -- add proc\_pagetypeinfo charts info [\#11627](https://github.com/netdata/netdata/pull/11627) ([ilyam8](https://github.com/ilyam8)) -- add proc\_net\_wireless charts info [\#11626](https://github.com/netdata/netdata/pull/11626) ([ilyam8](https://github.com/ilyam8)) -- add proc\_net\_rpc\_nfs and nfsd charts info [\#11625](https://github.com/netdata/netdata/pull/11625) ([ilyam8](https://github.com/ilyam8)) -- fix proc nfsd "proc4ops" chart family [\#11623](https://github.com/netdata/netdata/pull/11623) ([ilyam8](https://github.com/ilyam8)) -- Initialize struct with zeroes [\#11621](https://github.com/netdata/netdata/pull/11621) ([MrZammler](https://github.com/MrZammler)) -- add sys\_class\_power\_supply charts info [\#11619](https://github.com/netdata/netdata/pull/11619) ([ilyam8](https://github.com/ilyam8)) -- add cgroups.plugin systemd units charts info [\#11618](https://github.com/netdata/netdata/pull/11618) ([ilyam8](https://github.com/ilyam8)) -- Fix swap size calculation for cgroups [\#11617](https://github.com/netdata/netdata/pull/11617) ([vlvkobal](https://github.com/vlvkobal)) -- Fix RSS memory counter for systemd services [\#11616](https://github.com/netdata/netdata/pull/11616) ([vlvkobal](https://github.com/vlvkobal)) -- Add @iigorkarpov to CODEOWNERS. [\#11614](https://github.com/netdata/netdata/pull/11614) ([Ferroin](https://github.com/Ferroin)) -- Adds new alarm status protocol messages [\#11612](https://github.com/netdata/netdata/pull/11612) ([underhood](https://github.com/underhood)) -- eBPF and cgroup \(process, file descriptor, VFS, directory cache and OOMkill\) [\#11611](https://github.com/netdata/netdata/pull/11611) ([thiagoftsm](https://github.com/thiagoftsm)) -- apps: disable reporting min/avg/max group uptime by default [\#11609](https://github.com/netdata/netdata/pull/11609) ([ilyam8](https://github.com/ilyam8)) -- fix https client [\#11608](https://github.com/netdata/netdata/pull/11608) ([underhood](https://github.com/underhood)) -- add cgroups.plugin charts descriptions [\#11607](https://github.com/netdata/netdata/pull/11607) ([ilyam8](https://github.com/ilyam8)) -- Add flag to mark containers as created from official images in analytics. [\#11606](https://github.com/netdata/netdata/pull/11606) ([Ferroin](https://github.com/Ferroin)) -- Update optional parameters for upcoming installer. [\#11604](https://github.com/netdata/netdata/pull/11604) ([DShreve2](https://github.com/DShreve2)) -- add apps.plugin charts descriptions [\#11601](https://github.com/netdata/netdata/pull/11601) ([ilyam8](https://github.com/ilyam8)) -- add proc\_vmstat charts info [\#11597](https://github.com/netdata/netdata/pull/11597) ([ilyam8](https://github.com/ilyam8)) -- fix varnish VBE parsing [\#11596](https://github.com/netdata/netdata/pull/11596) ([ilyam8](https://github.com/ilyam8)) -- add sys\_kernel\_mm\_ksm charts info [\#11595](https://github.com/netdata/netdata/pull/11595) ([ilyam8](https://github.com/ilyam8)) -- Update dashboard to version v2.20.2. [\#11593](https://github.com/netdata/netdata/pull/11593) ([netdatabot](https://github.com/netdatabot)) -- Add POWER8+ support to our official Docker images. [\#11592](https://github.com/netdata/netdata/pull/11592) ([Ferroin](https://github.com/Ferroin)) -- add sys\_devices\_system\_edac\_mc charts info [\#11589](https://github.com/netdata/netdata/pull/11589) ([ilyam8](https://github.com/ilyam8)) -- Adds local webserver API/v1 call "aclk" [\#11588](https://github.com/netdata/netdata/pull/11588) ([underhood](https://github.com/underhood)) -- Makes New Cloud architecture optional for ACLK-NG [\#11587](https://github.com/netdata/netdata/pull/11587) ([underhood](https://github.com/underhood)) -- add proc\_stat charts info [\#11586](https://github.com/netdata/netdata/pull/11586) ([ilyam8](https://github.com/ilyam8)) -- Add Ubuntu 21.10 to CI. [\#11585](https://github.com/netdata/netdata/pull/11585) ([Ferroin](https://github.com/Ferroin)) -- Remove unused synproxy chart [\#11582](https://github.com/netdata/netdata/pull/11582) ([vlvkobal](https://github.com/vlvkobal)) -- add proc\_net\_stat\_synproxy charts info [\#11581](https://github.com/netdata/netdata/pull/11581) ([ilyam8](https://github.com/ilyam8)) -- Sorting the Postgres cluster databases in the postgres collector [\#11580](https://github.com/netdata/netdata/pull/11580) ([unhandled-exception](https://github.com/unhandled-exception)) -- Enable additional functionality for the new cloud architecture [\#11579](https://github.com/netdata/netdata/pull/11579) ([stelfrag](https://github.com/stelfrag)) -- Fix CID 339027 and reverse arguments [\#11578](https://github.com/netdata/netdata/pull/11578) ([thiagoftsm](https://github.com/thiagoftsm)) -- add proc\_softirqs charts info [\#11577](https://github.com/netdata/netdata/pull/11577) ([ilyam8](https://github.com/ilyam8)) -- add proc\_net\_stat\_conntrack charts info [\#11576](https://github.com/netdata/netdata/pull/11576) ([ilyam8](https://github.com/ilyam8)) -- Free analytics data when analytics thread stops [\#11575](https://github.com/netdata/netdata/pull/11575) ([MrZammler](https://github.com/MrZammler)) -- add missing privilege to fix MySQL slave reporting [\#11574](https://github.com/netdata/netdata/pull/11574) ([steffenweber](https://github.com/steffenweber)) -- Integrate eBPF and cgroup \(consumer side\) [\#11573](https://github.com/netdata/netdata/pull/11573) ([thiagoftsm](https://github.com/thiagoftsm)) -- add proc\_uptime charts info [\#11569](https://github.com/netdata/netdata/pull/11569) ([ilyam8](https://github.com/ilyam8)) -- add proc\_net\_sockstat and sockstat6 charts info [\#11567](https://github.com/netdata/netdata/pull/11567) ([ilyam8](https://github.com/ilyam8)) -- Disable eBPF compilation in different platforms [\#11566](https://github.com/netdata/netdata/pull/11566) ([thiagoftsm](https://github.com/thiagoftsm)) -- add proc\_net\_snmp6 charts info [\#11565](https://github.com/netdata/netdata/pull/11565) ([ilyam8](https://github.com/ilyam8)) -- eBPF Shared Memory system call tracking [\#11560](https://github.com/netdata/netdata/pull/11560) ([UmanShahzad](https://github.com/UmanShahzad)) -- Add shared memory to cgroup [\#11559](https://github.com/netdata/netdata/pull/11559) ([thiagoftsm](https://github.com/thiagoftsm)) -- End of support for Ubuntu 16.04 [\#11556](https://github.com/netdata/netdata/pull/11556) ([Ferroin](https://github.com/Ferroin)) -- Add alert message support for ACLK new architecture [\#11552](https://github.com/netdata/netdata/pull/11552) ([MrZammler](https://github.com/MrZammler)) -- Anomaly Detection MVP [\#11548](https://github.com/netdata/netdata/pull/11548) ([vkalintiris](https://github.com/vkalintiris)) - ## [v1.31.0](https://github.com/netdata/netdata/tree/v1.31.0) (2021-05-19) [Full Changelog](https://github.com/netdata/netdata/compare/v1.30.1...v1.31.0) @@ -396,7 +379,11 @@ ## [v1.23.2](https://github.com/netdata/netdata/tree/v1.23.2) (2020-07-16) -[Full Changelog](https://github.com/netdata/netdata/compare/v1.23.1...v1.23.2) +[Full Changelog](https://github.com/netdata/netdata/compare/v1.23.1_infiniband...v1.23.2) + +## [v1.23.1_infiniband](https://github.com/netdata/netdata/tree/v1.23.1_infiniband) (2020-07-03) + +[Full Changelog](https://github.com/netdata/netdata/compare/v1.23.1...v1.23.1_infiniband) ## [v1.23.1](https://github.com/netdata/netdata/tree/v1.23.1) (2020-07-01) diff --git a/CMakeLists.txt b/CMakeLists.txt index f8705f2ed..f3df9feff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -745,19 +745,6 @@ set(STREAMING_PLUGIN_FILES streaming/sender.c ) -set(BACKENDS_PLUGIN_FILES - backends/backends.c - backends/backends.h - backends/graphite/graphite.c - backends/graphite/graphite.h - backends/json/json.c - backends/json/json.h - backends/opentsdb/opentsdb.c - backends/opentsdb/opentsdb.h - backends/prometheus/backend_prometheus.c - backends/prometheus/backend_prometheus.h - ) - set(CLAIM_PLUGIN_FILES claim/claim.c claim/claim.h @@ -884,23 +871,6 @@ set(MONGODB_EXPORTING_FILES exporting/mongodb/mongodb.h ) -set(KINESIS_BACKEND_FILES - backends/aws_kinesis/aws_kinesis.c - backends/aws_kinesis/aws_kinesis.h - backends/aws_kinesis/aws_kinesis_put_record.cc - backends/aws_kinesis/aws_kinesis_put_record.h - ) - -set(PROMETHEUS_REMOTE_WRITE_BACKEND_FILES - backends/prometheus/remote_write/remote_write.cc - backends/prometheus/remote_write/remote_write.h - ) - -set(MONGODB_BACKEND_FILES - backends/mongodb/mongodb.c - backends/mongodb/mongodb.h - ) - set(DAEMON_FILES daemon/buildinfo.c daemon/buildinfo.h @@ -960,7 +930,6 @@ set(NETDATA_FILES collectors/all.h ${DAEMON_FILES} ${API_PLUGIN_FILES} - ${BACKENDS_PLUGIN_FILES} ${EXPORTING_ENGINE_FILES} ${CHECKS_PLUGIN_FILES} ${HEALTH_PLUGIN_FILES} @@ -997,25 +966,25 @@ add_definitions( ) # ----------------------------------------------------------------------------- -# kinesis backend +# kinesis exporting connector IF(KINESIS_LIBRARIES AND AWS_CORE_LIBRARIES AND HAVE_AWS_EVENT_STREAM AND HAVE_AWS_COMMON AND HAVE_AWS_CHECKSUMS AND CRYPTO_LIBRARIES AND SSL_LIBRARIES AND CURL_LIBRARIES) - SET(ENABLE_BACKEND_KINESIS True) + SET(ENABLE_EXPORTING_KINESIS True) ELSE() - SET(ENABLE_BACKEND_KINESIS False) + SET(ENABLE_EXPORTING_KINESIS False) ENDIF() -IF(ENABLE_BACKEND_KINESIS) - message(STATUS "kinesis backend: enabled") - list(APPEND NETDATA_FILES ${KINESIS_BACKEND_FILES} ${KINESIS_EXPORTING_FILES}) +IF(ENABLE_EXPORTING_KINESIS) + message(STATUS "kinesis exporting: enabled") + list(APPEND NETDATA_FILES ${KINESIS_EXPORTING_FILES}) list(APPEND NETDATA_COMMON_LIBRARIES ${KINESIS_LIBRARIES} ${AWS_CORE_LIBRARIES} ${CRYPTO_LIBRARIES} ${SSL_LIBRARIES} ${CURL_LIBRARIES}) list(APPEND NETDATA_COMMON_INCLUDE_DIRS ${KINESIS_INCLUDE_DIRS} ${AWS_CORE_INCLUDE_DIRS} ${CRYPTO_INCLUDE_DIRS} ${SSL_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS}) list(APPEND NETDATA_COMMON_CFLAGS ${CRYPTO_CFLAGS_OTHER} ${SSL_CFLAGS_OTHER} ${CURL_CFLAGS_OTHER}) ELSE() - message(STATUS "kinesis backend: disabled (requires AWS SDK for C++)") + message(STATUS "kinesis exporting: disabled (requires AWS SDK for C++)") ENDIF() # ----------------------------------------------------------------------------- @@ -1038,16 +1007,16 @@ ELSE() ENDIF() # ----------------------------------------------------------------------------- -# prometheus remote write backend +# prometheus remote write exporting connector IF(PROTOBUF_LIBRARIES AND SNAPPY_LIBRARIES) - SET(ENABLE_BACKEND_PROMETHEUS_REMOTE_WRITE True) + SET(ENABLE_EXPORTING_PROMETHEUS_REMOTE_WRITE True) ELSE() - SET(ENABLE_BACKEND_PROMETHEUS_REMOTE_WRITE False) + SET(ENABLE_EXPORTING_PROMETHEUS_REMOTE_WRITE False) ENDIF() -IF(ENABLE_BACKEND_PROMETHEUS_REMOTE_WRITE) - message(STATUS "prometheus remote write backend: enabled") +IF(ENABLE_EXPORTING_PROMETHEUS_REMOTE_WRITE) + message(STATUS "prometheus remote write exporting: enabled") find_package(Protobuf REQUIRED) @@ -1083,26 +1052,26 @@ IF(ENABLE_BACKEND_PROMETHEUS_REMOTE_WRITE) protobuf_remote_write_generate_cpp(PROTO_SRCS PROTO_HDRS exporting/prometheus/remote_write/remote_write.proto) - list(APPEND NETDATA_FILES ${PROMETHEUS_REMOTE_WRITE_BACKEND_FILES} ${PROMETHEUS_REMOTE_WRITE_EXPORTING_FILES} ${PROTO_SRCS} ${PROTO_HDRS}) + list(APPEND NETDATA_FILES ${PROMETHEUS_REMOTE_WRITE_EXPORTING_FILES} ${PROTO_SRCS} ${PROTO_HDRS}) list(APPEND NETDATA_COMMON_LIBRARIES ${PROTOBUF_LIBRARIES} ${SNAPPY_LIBRARIES}) list(APPEND NETDATA_COMMON_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIRS} ${SNAPPY_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR}) list(APPEND NETDATA_COMMON_CFLAGS ${PROTOBUF_CFLAGS_OTHER} ${SNAPPY_CFLAGS_OTHER}) ELSE() - message(STATUS "prometheus remote write backend: disabled (requires protobuf and snappy libraries)") + message(STATUS "prometheus remote write exporting: disabled (requires protobuf and snappy libraries)") ENDIF() # ----------------------------------------------------------------------------- -# mongodb backend +# mongodb exporting connector IF(MONGOC_LIBRARIES) - message(STATUS "mongodb backend: enabled") + message(STATUS "mongodb exporting: enabled") - list(APPEND NETDATA_FILES ${MONGODB_BACKEND_FILES} ${MONGODB_EXPORTING_FILES}) + list(APPEND NETDATA_FILES ${MONGODB_EXPORTING_FILES}) list(APPEND NETDATA_COMMON_LIBRARIES ${MONGOC_LIBRARIES}) list(APPEND NETDATA_COMMON_INCLUDE_DIRS ${MONGOC_INCLUDE_DIRS}) list(APPEND NETDATA_COMMON_CFLAGS ${MONGOC_CFLAGS_OTHER}) ELSE() - message(STATUS "mongodb backend: disabled (requires mongoc library)") + message(STATUS "mongodb exporting: disabled (requires mongoc library)") ENDIF() set(NETDATA_COMMON_LIBRARIES ${NETDATA_COMMON_LIBRARIES} m ${CMAKE_THREAD_LIBS_INIT}) @@ -1165,6 +1134,7 @@ list(APPEND NETDATA_COMMON_LIBRARIES ${PROTOBUF_LIBRARIES}) list(APPEND NETDATA_COMMON_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIRS}) list(APPEND NETDATA_COMMON_CFLAGS ${PROTOBUF_CFLAGS_OTHER}) list(APPEND NETDATA_FILES ${ACLK_ALWAYS_BUILD}) +list(APPEND NETDATA_FILES ${TIMEX_PLUGIN_FILES}) list(APPEND NETDATA_FILES ${ACLK_FILES} ${ACLK_PROTO_BUILT_SRCS} ${ACLK_PROTO_BUILT_HDRS}) list(APPEND NETDATA_FILES ${ACLK_COMMON_FILES}) include_directories(BEFORE ${CMAKE_SOURCE_DIR}/aclk/aclk-schemas) @@ -1182,7 +1152,6 @@ IF(LINUX) add_executable(netdata config.h ${NETDATA_FILES} ${CGROUPS_PLUGIN_FILES} ${DISKSPACE_PLUGIN_FILES} - ${TIMEX_PLUGIN_FILES} ${PROC_PLUGIN_FILES} ${TC_PLUGIN_FILES} ) @@ -1223,7 +1192,7 @@ ELSEIF(MACOS) ENDIF() -IF(ENABLE_BACKEND_KINESIS OR ENABLE_EXPORTING_PUBSUB OR ENABLE_BACKEND_PROMETHEUS_REMOTE_WRITE) +IF(ENABLE_EXPORTING_KINESIS OR ENABLE_EXPORTING_PUBSUB OR ENABLE_EXPORTING_PROMETHEUS_REMOTE_WRITE) set_property(TARGET netdata PROPERTY CXX_STANDARD 11) set_property(TARGET netdata PROPERTY CMAKE_CXX_STANDARD_REQUIRED ON) ENDIF() @@ -1397,7 +1366,7 @@ if(BUILD_TESTING) set(KINESIS_LINK_OPTIONS) set(PUBSUB_LINK_OPTIONS) set(MONGODB_LINK_OPTIONS) -if(ENABLE_BACKEND_PROMETHEUS_REMOTE_WRITE) +if(ENABLE_EXPORTING_PROMETHEUS_REMOTE_WRITE) list(APPEND EXPORTING_ENGINE_FILES ${PROMETHEUS_REMOTE_WRITE_EXPORTING_FILES} ${PROTO_SRCS} ${PROTO_HDRS}) list( APPEND PROMETHEUS_REMOTE_WRITE_LINK_OPTIONS @@ -1407,7 +1376,7 @@ if(ENABLE_BACKEND_PROMETHEUS_REMOTE_WRITE) -Wl,--wrap=add_metric ) endif() -if(ENABLE_BACKEND_KINESIS) +if(ENABLE_EXPORTING_KINESIS) list(APPEND EXPORTING_ENGINE_FILES ${KINESIS_EXPORTING_FILES}) list( APPEND KINESIS_LINK_OPTIONS diff --git a/Makefile.am b/Makefile.am index c41e8db24..0aa4d639e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -60,13 +60,15 @@ dist_noinst_DATA = \ mqtt_websockets \ netdata.cppcheck \ netdata.spec \ - package.json \ packaging/bundle-ebpf.sh \ + packaging/bundle-ebpf-co-re.sh \ packaging/bundle-judy.sh \ packaging/bundle-libbpf.sh \ packaging/check-kernel-config.sh \ packaging/ebpf.checksums \ packaging/ebpf.version \ + packaging/ebpf-co-re.checksums \ + packaging/ebpf-co-re.version \ packaging/go.d.checksums \ packaging/go.d.version \ packaging/installer/README.md \ @@ -99,7 +101,6 @@ dist_noinst_SCRIPTS = \ # Compile netdata binaries SUBDIRS += \ - backends \ collectors \ daemon \ database \ @@ -580,19 +581,6 @@ WEB_PLUGIN_FILES = \ web/server/static/static-threaded.h \ $(NULL) -BACKENDS_PLUGIN_FILES = \ - backends/backends.c \ - backends/backends.h \ - backends/graphite/graphite.c \ - backends/graphite/graphite.h \ - backends/json/json.c \ - backends/json/json.h \ - backends/opentsdb/opentsdb.c \ - backends/opentsdb/opentsdb.h \ - backends/prometheus/backend_prometheus.c \ - backends/prometheus/backend_prometheus.h \ - $(NULL) - CLAIM_FILES = \ claim/claim.c \ claim/claim.h \ @@ -831,23 +819,6 @@ MONGODB_EXPORTING_FILES = \ exporting/mongodb/mongodb.h \ $(NULL) -KINESIS_BACKEND_FILES = \ - backends/aws_kinesis/aws_kinesis.c \ - backends/aws_kinesis/aws_kinesis.h \ - backends/aws_kinesis/aws_kinesis_put_record.cc \ - backends/aws_kinesis/aws_kinesis_put_record.h \ - $(NULL) - -PROMETHEUS_REMOTE_WRITE_BACKEND_FILES = \ - backends/prometheus/remote_write/remote_write.cc \ - backends/prometheus/remote_write/remote_write.h \ - $(NULL) - -MONGODB_BACKEND_FILES = \ - backends/mongodb/mongodb.c \ - backends/mongodb/mongodb.h \ - $(NULL) - DAEMON_FILES = \ daemon/buildinfo.c \ daemon/buildinfo.h \ @@ -877,7 +848,6 @@ NETDATA_FILES = \ $(DAEMON_FILES) \ $(LIBNETDATA_FILES) \ $(API_PLUGIN_FILES) \ - $(BACKENDS_PLUGIN_FILES) \ $(EXPORTING_ENGINE_FILES) \ $(CHECKS_PLUGIN_FILES) \ $(HEALTH_PLUGIN_FILES) \ @@ -896,6 +866,7 @@ NETDATA_FILES = \ $(ACLK_COMMON_FILES) \ $(ACLK_FILES) \ $(SPAWN_PLUGIN_FILES) \ + $(TIMEX_PLUGIN_FILES) \ $(NULL) if FREEBSD @@ -917,7 +888,6 @@ if LINUX daemon/static_threads_linux.c \ $(CGROUPS_PLUGIN_FILES) \ $(DISKSPACE_PLUGIN_FILES) \ - $(TIMEX_PLUGIN_FILES) \ $(PROC_PLUGIN_FILES) \ $(TC_PLUGIN_FILES) \ $(NULL) @@ -1065,8 +1035,8 @@ if ENABLE_PLUGIN_SLABINFO $(NULL) endif -if ENABLE_BACKEND_KINESIS - netdata_SOURCES += $(KINESIS_BACKEND_FILES) $(KINESIS_EXPORTING_FILES) +if ENABLE_EXPORTING_KINESIS + netdata_SOURCES += $(KINESIS_EXPORTING_FILES) netdata_LDADD += $(OPTIONAL_KINESIS_LIBS) endif @@ -1075,17 +1045,17 @@ if ENABLE_EXPORTING_PUBSUB netdata_LDADD += $(OPTIONAL_PUBSUB_LIBS) endif -if ENABLE_BACKEND_PROMETHEUS_REMOTE_WRITE - netdata_SOURCES += $(PROMETHEUS_REMOTE_WRITE_BACKEND_FILES) $(PROMETHEUS_REMOTE_WRITE_EXPORTING_FILES) +if ENABLE_EXPORTING_PROMETHEUS_REMOTE_WRITE + netdata_SOURCES += $(PROMETHEUS_REMOTE_WRITE_EXPORTING_FILES) netdata_LDADD += $(OPTIONAL_PROMETHEUS_REMOTE_WRITE_LIBS) \ $(OPTIONAL_PROTOBUF_LIBS) \ $(NULL) - BACKEND_PROMETHEUS_BUILT_SOURCES = \ + EXPORTING_PROMETHEUS_BUILT_SOURCES = \ exporting/prometheus/remote_write/remote_write.pb.cc \ exporting/prometheus/remote_write/remote_write.pb.h \ $(NULL) - BUILT_SOURCES += $(BACKEND_PROMETHEUS_BUILT_SOURCES) - nodist_netdata_SOURCES += $(BACKEND_PROMETHEUS_BUILT_SOURCES) + BUILT_SOURCES += $(EXPORTING_PROMETHEUS_BUILT_SOURCES) + nodist_netdata_SOURCES += $(EXPORTING_PROMETHEUS_BUILT_SOURCES) exporting/prometheus/remote_write/remote_write.pb.cc \ exporting/prometheus/remote_write/remote_write.pb.h: exporting/prometheus/remote_write/remote_write.proto @@ -1093,8 +1063,8 @@ exporting/prometheus/remote_write/remote_write.pb.h: exporting/prometheus/remote endif -if ENABLE_BACKEND_MONGODB - netdata_SOURCES += $(MONGODB_BACKEND_FILES) $(MONGODB_EXPORTING_FILES) +if ENABLE_EXPORTING_MONGODB + netdata_SOURCES += $(MONGODB_EXPORTING_FILES) netdata_LDADD += $(OPTIONAL_MONGOC_LIBS) endif @@ -1217,7 +1187,7 @@ if ENABLE_UNITTESTS $(TEST_LDFLAGS) \ $(NULL) exporting_tests_exporting_engine_testdriver_LDADD = $(NETDATA_COMMON_LIBS) $(TEST_LIBS) -if ENABLE_BACKEND_PROMETHEUS_REMOTE_WRITE +if ENABLE_EXPORTING_PROMETHEUS_REMOTE_WRITE exporting_tests_exporting_engine_testdriver_SOURCES += $(PROMETHEUS_REMOTE_WRITE_EXPORTING_FILES) exporting_tests_exporting_engine_testdriver_LDADD += \ $(OPTIONAL_PROMETHEUS_REMOTE_WRITE_LIBS) \ @@ -1229,9 +1199,9 @@ if ENABLE_BACKEND_PROMETHEUS_REMOTE_WRITE -Wl,--wrap=add_label \ -Wl,--wrap=add_metric \ $(NULL) - nodist_exporting_tests_exporting_engine_testdriver_SOURCES = $(BACKEND_PROMETHEUS_BUILT_SOURCES) + nodist_exporting_tests_exporting_engine_testdriver_SOURCES = $(EXPORTING_PROMETHEUS_BUILT_SOURCES) endif -if ENABLE_BACKEND_KINESIS +if ENABLE_EXPORTING_KINESIS exporting_tests_exporting_engine_testdriver_SOURCES += $(KINESIS_EXPORTING_FILES) exporting_tests_exporting_engine_testdriver_LDADD += $(OPTIONAL_KINESIS_LIBS) exporting_tests_exporting_engine_testdriver_LDFLAGS += \ @@ -1251,7 +1221,7 @@ if ENABLE_EXPORTING_PUBSUB -Wl,--wrap=pubsub_get_result \ $(NULL) endif -if ENABLE_BACKEND_MONGODB +if ENABLE_EXPORTING_MONGODB exporting_tests_exporting_engine_testdriver_SOURCES += $(MONGODB_EXPORTING_FILES) exporting_tests_exporting_engine_testdriver_LDADD += $(OPTIONAL_MONGOC_LIBS) exporting_tests_exporting_engine_testdriver_LDFLAGS += \ diff --git a/README.md b/README.md index 89075092a..b979e6084 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ Build status CII Best Practices License: GPL v3+ - analytics
Code Climate Codacy @@ -35,12 +34,6 @@ People get addicted to Netdata. Once you use it on your systems, there's no goin ![Users who are addicted to Netdata](https://user-images.githubusercontent.com/1153921/96495792-2e881380-11fd-11eb-85a3-53d3a84dcb29.png) -> **[Latest release](https://github.com/netdata/netdata/releases/latest): v1.31.0, May 19, 2021** -> -> The v1.31.0 release of Netdata comes with re-packaged and redesigned elements of the dashboard to help you focus on -> your metrics, even more Linux kernel insights via eBPF, on-node machine learning to help you find anomalies, and much -> more. - ## Menu - [Features](#features) diff --git a/REDISTRIBUTED.md b/REDISTRIBUTED.md index fb256b5fc..0b62d54b5 100644 --- a/REDISTRIBUTED.md +++ b/REDISTRIBUTED.md @@ -180,4 +180,4 @@ connectivity is not available. Copyright 2015, Benedikt Schmitt [Unlicense License](https://unlicense.org/) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2FREDISTRIBUTED&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/aclk/README.md b/aclk/README.md index 870314be4..09c0d2920 100644 --- a/aclk/README.md +++ b/aclk/README.md @@ -134,4 +134,4 @@ If you changed the runtime setting in your `var/lib/netdata/cloud.d/cloud.conf` Restart your Agent and [connect your node](/claim/README.md#how-to-connect-a-node). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Faclk%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/aclk/aclk.c b/aclk/aclk.c index c25b7df68..599b9a093 100644 --- a/aclk/aclk.c +++ b/aclk/aclk.c @@ -24,8 +24,16 @@ #define ACLK_STABLE_TIMEOUT 3 // Minimum delay to mark AGENT as stable int aclk_pubacks_per_conn = 0; // How many PubAcks we got since MQTT conn est. +int aclk_rcvd_cloud_msgs = 0; +int aclk_connection_counter = 0; int disconnect_req = 0; +time_t last_conn_time_mqtt = 0; +time_t last_conn_time_appl = 0; +time_t last_disconnect_time = 0; +time_t next_connection_attempt = 0; +float last_backoff_value = 0; + int aclk_alert_reloaded = 1; //1 on startup, and again on health_reload time_t aclk_block_until = 0; @@ -43,8 +51,6 @@ struct aclk_shared_state aclk_shared_state = { .mqtt_shutdown_msg_rcvd = 0 }; -//ENDTODO - static RSA *aclk_private_key = NULL; static int load_private_key() { @@ -123,7 +129,7 @@ static int wait_till_agent_claimed(void) * @param aclk_hostname points to location where string pointer to hostname will be set * @param aclk_port port to int where port will be saved * - * @return If non 0 returned irrecoverable error happened and ACLK should be terminated + * @return If non 0 returned irrecoverable error happened (or netdata_exit) and ACLK should be terminated */ static int wait_till_agent_claim_ready() { @@ -144,20 +150,20 @@ static int wait_till_agent_claim_ready() // TODO make it without malloc/free memset(&url, 0, sizeof(url_t)); if (url_parse(cloud_base_url, &url)) { - error("Agent is claimed but the configuration is invalid, please fix"); + error("Agent is claimed but the URL in configuration key \"cloud base url\" is invalid, please fix"); url_t_destroy(&url); sleep(5); continue; } url_t_destroy(&url); - if (!load_private_key()) { - sleep(5); - break; - } + if (!load_private_key()) + return 0; + + sleep(5); } - return 0; + return 1; } void aclk_mqtt_wss_log_cb(mqtt_wss_log_type_t log_type, const char* str) @@ -266,6 +272,7 @@ static void msg_callback_new_protocol(const char *topic, const void *msg, size_t } static inline void msg_callback(const char *topic, const void *msg, size_t msglen, int qos) { + aclk_rcvd_cloud_msgs++; if (aclk_use_new_cloud_arch) msg_callback_new_protocol(topic, msg, msglen, qos); else @@ -275,8 +282,10 @@ static inline void msg_callback(const char *topic, const void *msg, size_t msgle static void puback_callback(uint16_t packet_id) { - if (++aclk_pubacks_per_conn == ACLK_PUBACKS_CONN_STABLE) + if (++aclk_pubacks_per_conn == ACLK_PUBACKS_CONN_STABLE) { + last_conn_time_appl = now_realtime_sec(); aclk_tbeb_reset(); + } #ifdef NETDATA_INTERNAL_CHECKS aclk_stats_msg_puback(packet_id); @@ -402,6 +411,8 @@ static inline void mqtt_connected_actions(mqtt_wss_client client) aclk_stats_upd_online(1); aclk_connected = 1; aclk_pubacks_per_conn = 0; + aclk_rcvd_cloud_msgs = 0; + aclk_connection_counter++; #ifdef ENABLE_NEW_CLOUD_PROTOCOL if (!aclk_use_new_cloud_arch) { @@ -480,6 +491,7 @@ void aclk_graceful_disconnect(mqtt_wss_client client) info("ACLK link is down"); log_access("ACLK DISCONNECTED"); aclk_stats_upd_online(0); + last_disconnect_time = now_realtime_sec(); aclk_connected = 0; info("Attempting to gracefully shutdown the MQTT/WSS connection"); @@ -521,6 +533,9 @@ static unsigned long aclk_reconnect_delay() { static int aclk_block_till_recon_allowed() { unsigned long recon_delay = aclk_reconnect_delay(); + next_connection_attempt = now_realtime_sec() + (recon_delay / MSEC_PER_SEC); + last_backoff_value = (float)recon_delay / MSEC_PER_SEC; + info("Wait before attempting to reconnect in %.3f seconds\n", recon_delay / (float)MSEC_PER_SEC); // we want to wake up from time to time to check netdata_exit while (recon_delay) @@ -613,12 +628,7 @@ static int aclk_attempt_to_connect(mqtt_wss_client client) .drop_on_publish_fail = 1 }; -#if defined(ENABLE_NEW_CLOUD_PROTOCOL) && defined(ACLK_NEWARCH_DEVMODE) - aclk_use_new_cloud_arch = 1; - info("Switching ACLK to new protobuf protocol. Due to #define ACLK_NEWARCH_DEVMODE."); -#else aclk_use_new_cloud_arch = 0; -#endif #ifndef ACLK_DISABLE_CHALLENGE if (aclk_env) { @@ -638,20 +648,19 @@ static int aclk_attempt_to_connect(mqtt_wss_client client) if (netdata_exit) return 1; -#ifndef ACLK_NEWARCH_DEVMODE if (aclk_env->encoding == ACLK_ENC_PROTO) { #ifndef ENABLE_NEW_CLOUD_PROTOCOL error("Cloud requested New Cloud Protocol to be used but this agent cannot support it!"); continue; -#endif +#else if (!aclk_env_has_capa("proto")) { error ("Can't encoding=proto without at least \"proto\" capability."); continue; } info("Switching ACLK to new protobuf protocol. Due to /env response."); aclk_use_new_cloud_arch = 1; - } #endif + } memset(&auth_url, 0, sizeof(url_t)); if (url_parse(aclk_env->auth_endpoint, &auth_url)) { @@ -728,6 +737,7 @@ static int aclk_attempt_to_connect(mqtt_wss_client client) json_object_put(lwt); if (!ret) { + last_conn_time_mqtt = now_realtime_sec(); info("ACLK connection successfully established"); log_access("ACLK CONNECTED"); mqtt_connected_actions(client); @@ -767,8 +777,9 @@ void *aclk_main(void *ptr) return NULL; } + unsigned int proto_hdl_cnt; #ifdef ENABLE_NEW_CLOUD_PROTOCOL - aclk_init_rx_msg_handlers(); + proto_hdl_cnt = aclk_init_rx_msg_handlers(); #endif // This thread is unusual in that it cannot be cancelled by cancel_main_threads() @@ -808,6 +819,7 @@ void *aclk_main(void *ptr) stats_thread = callocz(1, sizeof(struct aclk_stats_thread)); stats_thread->thread = mallocz(sizeof(netdata_thread_t)); stats_thread->query_thread_count = query_threads.count; + aclk_stats_thread_prepare(query_threads.count, proto_hdl_cnt); netdata_thread_create( stats_thread->thread, ACLK_STATS_THREAD_NAME, NETDATA_THREAD_OPTION_JOINABLE, aclk_stats_main_thread, stats_thread); @@ -843,6 +855,7 @@ void *aclk_main(void *ptr) if (handle_connection(mqttwss_client)) { aclk_stats_upd_online(0); + last_disconnect_time = now_realtime_sec(); aclk_connected = 0; log_access("ACLK DISCONNECTED"); } @@ -1092,6 +1105,7 @@ void aclk_send_node_instances() uuid_unparse_lower(list->node_id, (char*)query->data.node_update.node_id); query->data.node_update.queryable = 1; query->data.node_update.session_id = aclk_session_newarch; + freez(list->hostname); info("Queuing status update for node=%s, live=%d, hops=%d",(char*)query->data.node_update.node_id, list->live, list->hops); @@ -1121,53 +1135,257 @@ void aclk_send_bin_msg(char *msg, size_t msg_len, enum aclk_topics subtopic, con aclk_send_bin_message_subtopic_pid(mqttwss_client, msg, msg_len, subtopic, msgname); } +#ifdef ENABLE_NEW_CLOUD_PROTOCOL +static void fill_alert_status_for_host(BUFFER *wb, RRDHOST *host) +{ + struct proto_alert_status status; + memset(&status, 0, sizeof(status)); + if (get_proto_alert_status(host, &status)) { + buffer_strcat(wb, "\nFailed to get alert streaming status for this host"); + return; + } + buffer_sprintf(wb, + "\n\t\tUpdates: %d" + "\n\t\tBatch ID: %"PRIu64 + "\n\t\tLast Acked Seq ID: %"PRIu64 + "\n\t\tPending Min Seq ID: %"PRIu64 + "\n\t\tPending Max Seq ID: %"PRIu64 + "\n\t\tLast Submitted Seq ID: %"PRIu64, + status.alert_updates, + status.alerts_batch_id, + status.last_acked_sequence_id, + status.pending_min_sequence_id, + status.pending_max_sequence_id, + status.last_submitted_sequence_id + ); +} + +static void fill_chart_status_for_host(BUFFER *wb, RRDHOST *host) +{ + struct aclk_chart_sync_stats *stats = aclk_get_chart_sync_stats(host); + if (!stats) { + buffer_strcat(wb, "\n\t\tFailed to get alert streaming status for this host"); + return; + } + buffer_sprintf(wb, + "\n\t\tUpdates: %d" + "\n\t\tBatch ID: %"PRIu64 + "\n\t\tMin Seq ID: %"PRIu64 + "\n\t\tMax Seq ID: %"PRIu64 + "\n\t\tPending Min Seq ID: %"PRIu64 + "\n\t\tPending Max Seq ID: %"PRIu64 + "\n\t\tSent Min Seq ID: %"PRIu64 + "\n\t\tSent Max Seq ID: %"PRIu64 + "\n\t\tAcked Min Seq ID: %"PRIu64 + "\n\t\tAcked Max Seq ID: %"PRIu64, + stats->updates, + stats->batch_id, + stats->min_seqid, + stats->max_seqid, + stats->min_seqid_pend, + stats->max_seqid_pend, + stats->min_seqid_sent, + stats->max_seqid_sent, + stats->min_seqid_ack, + stats->max_seqid_ack + ); + freez(stats); +} +#endif + char *ng_aclk_state(void) { BUFFER *wb = buffer_create(1024); + struct tm *tmptr, tmbuf; char *ret; buffer_strcat(wb, "ACLK Available: Yes\n" - "ACLK Implementation: Next Generation\n" + "ACLK Version: 2\n" #ifdef ENABLE_NEW_CLOUD_PROTOCOL - "New Cloud Protocol Support: Yes\n" + "Protocols Supported: Legacy, Protobuf\n" #else - "New Cloud Protocol Support: No\n" + "Protocols Supported: Legacy\n" #endif - "Claimed: " ); + buffer_sprintf(wb, "Protocol Used: %s\nClaimed: ", aclk_use_new_cloud_arch ? "Protobuf" : "Legacy"); char *agent_id = is_agent_claimed(); if (agent_id == NULL) buffer_strcat(wb, "No\n"); else { - buffer_sprintf(wb, "Yes\nClaimed Id: %s\n", agent_id); + char *cloud_base_url = appconfig_get(&cloud_config, CONFIG_SECTION_GLOBAL, "cloud base url", NULL); + buffer_sprintf(wb, "Yes\nClaimed Id: %s\nCloud URL: %s\n", agent_id, cloud_base_url ? cloud_base_url : "null"); freez(agent_id); } - buffer_sprintf(wb, "Online: %s\nUsed Cloud Protocol: %s", aclk_connected ? "Yes" : "No", aclk_use_new_cloud_arch ? "New" : "Legacy"); + buffer_sprintf(wb, "Online: %s\nReconnect count: %d\nBanned By Cloud: %s\n", aclk_connected ? "Yes" : "No", aclk_connection_counter > 0 ? (aclk_connection_counter - 1) : 0, aclk_disable_runtime ? "Yes" : "No"); + if (last_conn_time_mqtt && (tmptr = localtime_r(&last_conn_time_mqtt, &tmbuf)) ) { + char timebuf[26]; + strftime(timebuf, 26, "%Y-%m-%d %H:%M:%S", tmptr); + buffer_sprintf(wb, "Last Connection Time: %s\n", timebuf); + } + if (last_conn_time_appl && (tmptr = localtime_r(&last_conn_time_appl, &tmbuf)) ) { + char timebuf[26]; + strftime(timebuf, 26, "%Y-%m-%d %H:%M:%S", tmptr); + buffer_sprintf(wb, "Last Connection Time + %d PUBACKs received: %s\n", ACLK_PUBACKS_CONN_STABLE, timebuf); + } + if (last_disconnect_time && (tmptr = localtime_r(&last_disconnect_time, &tmbuf)) ) { + char timebuf[26]; + strftime(timebuf, 26, "%Y-%m-%d %H:%M:%S", tmptr); + buffer_sprintf(wb, "Last Disconnect Time: %s\n", timebuf); + } + if (!aclk_connected && next_connection_attempt && (tmptr = localtime_r(&next_connection_attempt, &tmbuf)) ) { + char timebuf[26]; + strftime(timebuf, 26, "%Y-%m-%d %H:%M:%S", tmptr); + buffer_sprintf(wb, "Next Connection Attempt At: %s\nLast Backoff: %.3f", timebuf, last_backoff_value); + } + + if (aclk_connected) { + buffer_sprintf(wb, "Received Cloud MQTT Messages: %d\nMQTT Messages Confirmed by Remote Broker (PUBACKs): %d", aclk_rcvd_cloud_msgs, aclk_pubacks_per_conn); + +#ifdef ENABLE_NEW_CLOUD_PROTOCOL + RRDHOST *host; + rrd_rdlock(); + rrdhost_foreach_read(host) { + buffer_sprintf(wb, "\n\n> Node Instance for mGUID: \"%s\" hostname \"%s\"\n", host->machine_guid, host->hostname); + + buffer_strcat(wb, "\tClaimed ID: "); + rrdhost_aclk_state_lock(host); + if (host->aclk_state.claimed_id) + buffer_strcat(wb, host->aclk_state.claimed_id); + else + buffer_strcat(wb, "null"); + rrdhost_aclk_state_unlock(host); + + + if (host->node_id == NULL || uuid_is_null(*host->node_id)) { + buffer_strcat(wb, "\n\tNode ID: null\n"); + } else { + char node_id[GUID_LEN + 1]; + uuid_unparse_lower(*host->node_id, node_id); + buffer_sprintf(wb, "\n\tNode ID: %s\n", node_id); + } + + buffer_sprintf(wb, "\tStreaming Hops: %d\n\tRelationship: %s", host->system_info->hops, host == localhost ? "self" : "child"); + + if (host != localhost) + buffer_sprintf(wb, "\n\tStreaming Connection Live: %s", host->receiver ? "true" : "false"); + + buffer_strcat(wb, "\n\tAlert Streaming Status:"); + fill_alert_status_for_host(wb, host); + + buffer_strcat(wb, "\n\tChart Streaming Status:"); + fill_chart_status_for_host(wb, host); + } + rrd_unlock(); +#endif + } ret = strdupz(buffer_tostring(wb)); buffer_free(wb); return ret; } +#ifdef ENABLE_NEW_CLOUD_PROTOCOL +static void fill_alert_status_for_host_json(json_object *obj, RRDHOST *host) +{ + struct proto_alert_status status; + memset(&status, 0, sizeof(status)); + if (get_proto_alert_status(host, &status)) + return; + + json_object *tmp = json_object_new_int(status.alert_updates); + json_object_object_add(obj, "updates", tmp); + + tmp = json_object_new_int(status.alerts_batch_id); + json_object_object_add(obj, "batch-id", tmp); + + tmp = json_object_new_int(status.last_acked_sequence_id); + json_object_object_add(obj, "last-acked-seq-id", tmp); + + tmp = json_object_new_int(status.pending_min_sequence_id); + json_object_object_add(obj, "pending-min-seq-id", tmp); + + tmp = json_object_new_int(status.pending_max_sequence_id); + json_object_object_add(obj, "pending-max-seq-id", tmp); + + tmp = json_object_new_int(status.last_submitted_sequence_id); + json_object_object_add(obj, "last-submitted-seq-id", tmp); +} + +static void fill_chart_status_for_host_json(json_object *obj, RRDHOST *host) +{ + struct aclk_chart_sync_stats *stats = aclk_get_chart_sync_stats(host); + if (!stats) + return; + + json_object *tmp = json_object_new_int(stats->updates); + json_object_object_add(obj, "updates", tmp); + + tmp = json_object_new_int(stats->batch_id); + json_object_object_add(obj, "batch-id", tmp); + + tmp = json_object_new_int(stats->min_seqid); + json_object_object_add(obj, "min-seq-id", tmp); + + tmp = json_object_new_int(stats->max_seqid); + json_object_object_add(obj, "max-seq-id", tmp); + + tmp = json_object_new_int(stats->min_seqid_pend); + json_object_object_add(obj, "pending-min-seq-id", tmp); + + tmp = json_object_new_int(stats->max_seqid_pend); + json_object_object_add(obj, "pending-max-seq-id", tmp); + + tmp = json_object_new_int(stats->min_seqid_sent); + json_object_object_add(obj, "sent-min-seq-id", tmp); + + tmp = json_object_new_int(stats->max_seqid_sent); + json_object_object_add(obj, "sent-max-seq-id", tmp); + + tmp = json_object_new_int(stats->min_seqid_ack); + json_object_object_add(obj, "acked-min-seq-id", tmp); + + tmp = json_object_new_int(stats->max_seqid_ack); + json_object_object_add(obj, "acked-max-seq-id", tmp); + + freez(stats); +} +#endif + +static json_object *timestamp_to_json(const time_t *t) +{ + struct tm *tmptr, tmbuf; + if (*t && (tmptr = gmtime_r(t, &tmbuf)) ) { + char timebuf[26]; + strftime(timebuf, 26, "%Y-%m-%d %H:%M:%S", tmptr); + return json_object_new_string(timebuf); + } + return NULL; +} + char *ng_aclk_state_json(void) { - json_object *tmp, *msg = json_object_new_object(); + json_object *tmp, *grp, *msg = json_object_new_object(); tmp = json_object_new_boolean(1); json_object_object_add(msg, "aclk-available", tmp); - tmp = json_object_new_string("Next Generation"); - json_object_object_add(msg, "aclk-implementation", tmp); + tmp = json_object_new_int(2); + json_object_object_add(msg, "aclk-version", tmp); + grp = json_object_new_array(); #ifdef ENABLE_NEW_CLOUD_PROTOCOL - tmp = json_object_new_boolean(1); + tmp = json_object_new_string("Legacy"); + json_object_array_add(grp, tmp); + tmp = json_object_new_string("Protobuf"); + json_object_array_add(grp, tmp); #else - tmp = json_object_new_boolean(0); + tmp = json_object_new_string("Legacy"); + json_object_array_add(grp, tmp); #endif - json_object_object_add(msg, "new-cloud-protocol-supported", tmp); + json_object_object_add(msg, "protocols-supported", grp); char *agent_id = is_agent_claimed(); tmp = json_object_new_boolean(agent_id != NULL); @@ -1180,12 +1398,91 @@ char *ng_aclk_state_json(void) tmp = NULL; json_object_object_add(msg, "claimed-id", tmp); + char *cloud_base_url = appconfig_get(&cloud_config, CONFIG_SECTION_GLOBAL, "cloud base url", NULL); + tmp = cloud_base_url ? json_object_new_string(cloud_base_url) : NULL; + json_object_object_add(msg, "cloud-url", tmp); + tmp = json_object_new_boolean(aclk_connected); json_object_object_add(msg, "online", tmp); - tmp = json_object_new_string(aclk_use_new_cloud_arch ? "New" : "Legacy"); + tmp = json_object_new_string(aclk_use_new_cloud_arch ? "Protobuf" : "Legacy"); json_object_object_add(msg, "used-cloud-protocol", tmp); + tmp = json_object_new_int(aclk_rcvd_cloud_msgs); + json_object_object_add(msg, "received-app-layer-msgs", tmp); + + tmp = json_object_new_int(aclk_pubacks_per_conn); + json_object_object_add(msg, "received-mqtt-pubacks", tmp); + + tmp = json_object_new_int(aclk_connection_counter > 0 ? (aclk_connection_counter - 1) : 0); + json_object_object_add(msg, "reconnect-count", tmp); + + json_object_object_add(msg, "last-connect-time-utc", timestamp_to_json(&last_conn_time_mqtt)); + json_object_object_add(msg, "last-connect-time-puback-utc", timestamp_to_json(&last_conn_time_appl)); + json_object_object_add(msg, "last-disconnect-time-utc", timestamp_to_json(&last_disconnect_time)); + json_object_object_add(msg, "next-connection-attempt-utc", !aclk_connected ? timestamp_to_json(&next_connection_attempt) : NULL); + tmp = NULL; + if (!aclk_connected && last_backoff_value) + tmp = json_object_new_double(last_backoff_value); + json_object_object_add(msg, "last-backoff-value", tmp); + + tmp = json_object_new_boolean(aclk_disable_runtime); + json_object_object_add(msg, "banned-by-cloud", tmp); + +#ifdef ENABLE_NEW_CLOUD_PROTOCOL + grp = json_object_new_array(); + + RRDHOST *host; + rrd_rdlock(); + rrdhost_foreach_read(host) { + json_object *nodeinstance = json_object_new_object(); + + tmp = json_object_new_string(host->hostname); + json_object_object_add(nodeinstance, "hostname", tmp); + + tmp = json_object_new_string(host->machine_guid); + json_object_object_add(nodeinstance, "mguid", tmp); + + rrdhost_aclk_state_lock(host); + if (host->aclk_state.claimed_id) { + tmp = json_object_new_string(host->aclk_state.claimed_id); + json_object_object_add(nodeinstance, "claimed_id", tmp); + } else + json_object_object_add(nodeinstance, "claimed_id", NULL); + rrdhost_aclk_state_unlock(host); + + if (host->node_id == NULL || uuid_is_null(*host->node_id)) { + json_object_object_add(nodeinstance, "node-id", NULL); + } else { + char node_id[GUID_LEN + 1]; + uuid_unparse_lower(*host->node_id, node_id); + tmp = json_object_new_string(node_id); + json_object_object_add(nodeinstance, "node-id", tmp); + } + + tmp = json_object_new_int(host->system_info->hops); + json_object_object_add(nodeinstance, "streaming-hops", tmp); + + tmp = json_object_new_string(host == localhost ? "self" : "child"); + json_object_object_add(nodeinstance, "relationship", tmp); + + tmp = json_object_new_boolean((host->receiver || host == localhost)); + json_object_object_add(nodeinstance, "streaming-online", tmp); + + tmp = json_object_new_object(); + fill_alert_status_for_host_json(tmp, host); + json_object_object_add(nodeinstance, "alert-sync-status", tmp); + + tmp = json_object_new_object(); + fill_chart_status_for_host_json(tmp, host); + json_object_object_add(nodeinstance, "chart-sync-status", tmp); + + json_object_array_add(grp, nodeinstance); + } + rrd_unlock(); + json_object_object_add(msg, "node-instances", grp); +#endif + char *str = strdupz(json_object_to_json_string_ext(msg, JSON_C_TO_STRING_PLAIN)); json_object_put(msg); return str; diff --git a/aclk/aclk_api.c b/aclk/aclk_api.c index 172cf2982..766f78053 100644 --- a/aclk/aclk_api.c +++ b/aclk/aclk_api.c @@ -70,6 +70,11 @@ struct label *add_aclk_host_labels(struct label *label) { label = add_label_to_list(label, "_aclk_impl", "Next Generation", LABEL_SOURCE_AUTO); label = add_label_to_list(label, "_aclk_proxy", proxy_str, LABEL_SOURCE_AUTO); +#ifdef ENABLE_NEW_CLOUD_PROTOCOL + label = add_label_to_list(label, "_aclk_ng_new_cloud_protocol", "true", LABEL_SOURCE_AUTO); +#else + label = add_label_to_list(label, "_aclk_ng_new_cloud_protocol", "false", LABEL_SOURCE_AUTO); +#endif #endif return label; } diff --git a/aclk/aclk_query.c b/aclk/aclk_query.c index 001c1ba02..ae5659310 100644 --- a/aclk/aclk_query.c +++ b/aclk/aclk_query.c @@ -2,7 +2,6 @@ #include "aclk_query.h" #include "aclk_stats.h" -#include "aclk_query_queue.h" #include "aclk_tx_msgs.h" #define ACLK_QUERY_THREAD_NAME "ACLK_Query" @@ -59,6 +58,13 @@ static RRDHOST *node_id_2_rrdhost(const char *node_id) { int res; uuid_t node_id_bin, host_id_bin; + + rrd_rdlock(); + RRDHOST *host = find_host_by_node_id((char *) node_id); + rrd_unlock(); + if (host) + return host; + char host_id[UUID_STR_LEN]; if (uuid_parse(node_id, node_id_bin)) { error("Couldn't parse UUID %s", node_id); @@ -99,26 +105,34 @@ static int http_api_v2(struct aclk_query_thread *query_thr, aclk_query_t query) w->cookie2[0] = 0; // Simulate web_client_create_on_fd() w->acl = 0x1f; + buffer_strcat(log_buffer, query->data.http_api_v2.query); + size_t size = 0; + size_t sent = 0; + w->tv_in = query->created_tv; + now_realtime_timeval(&w->tv_ready); + if (!strncmp(query->data.http_api_v2.query, NODE_ID_QUERY, strlen(NODE_ID_QUERY))) { char *node_uuid = query->data.http_api_v2.query + strlen(NODE_ID_QUERY); char nodeid[UUID_STR_LEN]; if (strlen(node_uuid) < (UUID_STR_LEN - 1)) { - error("URL requests node_id but there is not enough chars following"); + error_report(CLOUD_EMSG_MALFORMED_NODE_ID); retval = 1; + w->response.code = 404; + aclk_http_msg_v2_err(query_thr->client, query->callback_topic, query->msg_id, w->response.code, CLOUD_EC_MALFORMED_NODE_ID, CLOUD_EMSG_MALFORMED_NODE_ID, NULL, 0); goto cleanup; } strncpyz(nodeid, node_uuid, UUID_STR_LEN - 1); query_host = node_id_2_rrdhost(nodeid); if (!query_host) { - error("Host with node_id \"%s\" not found! Query Ignored!", node_uuid); + error_report("Host with node_id \"%s\" not found! Returning 404 to Cloud!", nodeid); retval = 1; + w->response.code = 404; + aclk_http_msg_v2_err(query_thr->client, query->callback_topic, query->msg_id, w->response.code, CLOUD_EC_NODE_NOT_FOUND, CLOUD_EMSG_NODE_NOT_FOUND, NULL, 0); goto cleanup; } } - buffer_strcat(log_buffer, query->data.http_api_v2.query); - char *mysep = strchr(query->data.http_api_v2.query, '?'); if (mysep) { url_decode_r(w->decoded_query_string, mysep, NETDATA_WEB_REQUEST_URL_SIZE + 1); @@ -136,11 +150,9 @@ static int http_api_v2(struct aclk_query_thread *query_thr, aclk_query_t query) } // execute the query - w->tv_in = query->created_tv; - now_realtime_timeval(&w->tv_ready); t = aclk_web_api_v1_request(query_host, w, mysep ? mysep + 1 : "noop"); - size_t size = (w->mode == WEB_CLIENT_MODE_FILECOPY) ? w->response.rlen : w->response.data->len; - size_t sent = size; + size = (w->mode == WEB_CLIENT_MODE_FILECOPY) ? w->response.rlen : w->response.data->len; + sent = size; #ifdef NETDATA_WITH_ZLIB // check if gzip encoding can and should be used @@ -174,6 +186,8 @@ static int http_api_v2(struct aclk_query_thread *query_thr, aclk_query_t query) else error("Unknown error during zlib compression."); retval = 1; + w->response.code = 500; + aclk_http_msg_v2_err(query_thr->client, query->callback_topic, query->msg_id, w->response.code, CLOUD_EC_ZLIB_ERROR, CLOUD_EMSG_ZLIB_ERROR, NULL, 0); goto cleanup; } int bytes_to_cpy = NETDATA_WEB_RESPONSE_ZLIB_CHUNK_SIZE - w->response.zstream.avail_out; @@ -214,8 +228,9 @@ static int http_api_v2(struct aclk_query_thread *query_thr, aclk_query_t query) // send msg. aclk_http_msg_v2(query_thr->client, query->callback_topic, query->msg_id, t, query->created, w->response.code, local_buffer->buffer, local_buffer->len); - // log. struct timeval tv; + +cleanup: now_realtime_timeval(&tv); log_access("%llu: %d '[ACLK]:%d' '%s' (sent/all = %zu/%zu bytes %0.0f%%, prep/sent/total = %0.2f/%0.2f/%0.2f ms) %d '%s'", w->id @@ -232,7 +247,6 @@ static int http_api_v2(struct aclk_query_thread *query_thr, aclk_query_t query) , strip_control_characters((char *)buffer_tostring(log_buffer)) ); -cleanup: #ifdef NETDATA_WITH_ZLIB if(w->response.zinitialized) deflateEnd(&w->response.zstream); @@ -287,27 +301,37 @@ static int send_bin_msg(struct aclk_query_thread *query_thr, aclk_query_t query) #endif aclk_query_handler aclk_query_handlers[] = { - { .type = HTTP_API_V2, .name = "http api request v2", .fnc = http_api_v2 }, - { .type = ALARM_STATE_UPDATE, .name = "alarm state update", .fnc = alarm_state_update_query }, - { .type = METADATA_INFO, .name = "info metadata", .fnc = info_metadata }, - { .type = METADATA_ALARMS, .name = "alarms metadata", .fnc = alarms_metadata }, - { .type = CHART_NEW, .name = "chart new", .fnc = chart_query }, - { .type = CHART_DEL, .name = "chart delete", .fnc = info_metadata }, + { .type = HTTP_API_V2, .name = "http_api_request_v2", .fnc = http_api_v2 }, + { .type = ALARM_STATE_UPDATE, .name = "alarm_state_update", .fnc = alarm_state_update_query }, + { .type = METADATA_INFO, .name = "info_metadata", .fnc = info_metadata }, + { .type = METADATA_ALARMS, .name = "alarms_metadata", .fnc = alarms_metadata }, + { .type = CHART_NEW, .name = "chart_new", .fnc = chart_query }, + { .type = CHART_DEL, .name = "chart_delete", .fnc = info_metadata }, #ifdef ENABLE_NEW_CLOUD_PROTOCOL - { .type = REGISTER_NODE, .name = "register node", .fnc = register_node }, - { .type = NODE_STATE_UPDATE, .name = "node state update", .fnc = node_state_update }, - { .type = CHART_DIMS_UPDATE, .name = "chart and dim update bin", .fnc = send_bin_msg }, - { .type = CHART_CONFIG_UPDATED, .name = "chart config updated", .fnc = send_bin_msg }, - { .type = CHART_RESET, .name = "reset chart messages", .fnc = send_bin_msg }, - { .type = RETENTION_UPDATED, .name = "update retention info", .fnc = send_bin_msg }, - { .type = UPDATE_NODE_INFO, .name = "update node info", .fnc = send_bin_msg }, - { .type = ALARM_LOG_HEALTH, .name = "alarm log health", .fnc = send_bin_msg }, - { .type = ALARM_PROVIDE_CFG, .name = "provide alarm config", .fnc = send_bin_msg }, - { .type = ALARM_SNAPSHOT, .name = "alarm snapshot", .fnc = send_bin_msg }, + { .type = REGISTER_NODE, .name = "register_node", .fnc = register_node }, + { .type = NODE_STATE_UPDATE, .name = "node_state_update", .fnc = node_state_update }, + { .type = CHART_DIMS_UPDATE, .name = "chart_and_dim_update", .fnc = send_bin_msg }, + { .type = CHART_CONFIG_UPDATED, .name = "chart_config_updated", .fnc = send_bin_msg }, + { .type = CHART_RESET, .name = "reset_chart_messages", .fnc = send_bin_msg }, + { .type = RETENTION_UPDATED, .name = "update_retention_info", .fnc = send_bin_msg }, + { .type = UPDATE_NODE_INFO, .name = "update_node_info", .fnc = send_bin_msg }, + { .type = ALARM_LOG_HEALTH, .name = "alarm_log_health", .fnc = send_bin_msg }, + { .type = ALARM_PROVIDE_CFG, .name = "provide_alarm_config", .fnc = send_bin_msg }, + { .type = ALARM_SNAPSHOT, .name = "alarm_snapshot", .fnc = send_bin_msg }, #endif { .type = UNKNOWN, .name = NULL, .fnc = NULL } }; +const char *aclk_query_get_name(aclk_query_type_t qt) +{ + aclk_query_handler *ptr = aclk_query_handlers; + while (ptr->type != UNKNOWN) { + if (ptr->type == qt) + return ptr->name; + ptr++; + } + return "unknown"; +} static void aclk_query_process_msg(struct aclk_query_thread *query_thr, aclk_query_t query) { @@ -315,13 +339,14 @@ static void aclk_query_process_msg(struct aclk_query_thread *query_thr, aclk_que if (aclk_query_handlers[i].type == query->type) { debug(D_ACLK, "Processing Queued Message of type: \"%s\"", aclk_query_handlers[i].name); aclk_query_handlers[i].fnc(query_thr, query); - aclk_query_free(query); if (aclk_stats_enabled) { ACLK_STATS_LOCK; aclk_metrics_per_sample.queries_dispatched++; aclk_queries_per_thread[query_thr->idx]++; + aclk_metrics_per_sample.queries_per_type[query->type]++; ACLK_STATS_UNLOCK; } + aclk_query_free(query); return; } } diff --git a/aclk/aclk_query.h b/aclk/aclk_query.h index 43741fb32..f86754a2a 100644 --- a/aclk/aclk_query.h +++ b/aclk/aclk_query.h @@ -7,6 +7,8 @@ #include "mqtt_wss_client.h" +#include "aclk_query_queue.h" + extern pthread_cond_t query_cond_wait; extern pthread_mutex_t query_lock_wait; #define QUERY_THREAD_WAKEUP pthread_cond_signal(&query_cond_wait) @@ -29,4 +31,6 @@ struct aclk_query_threads { void aclk_query_threads_start(struct aclk_query_threads *query_threads, mqtt_wss_client client); void aclk_query_threads_cleanup(struct aclk_query_threads *query_threads); +const char *aclk_query_get_name(aclk_query_type_t qt); + #endif //NETDATA_AGENT_CLOUD_LINK_H diff --git a/aclk/aclk_query_queue.c b/aclk/aclk_query_queue.c index fe7ee123c..74a899226 100644 --- a/aclk/aclk_query_queue.c +++ b/aclk/aclk_query_queue.c @@ -45,49 +45,14 @@ static inline int _aclk_queue_query(aclk_query_t query) } -// Gets a pointer to the metric associated with a particular query type. -// NULL if the query type has no associated metric. -static inline volatile uint32_t *aclk_stats_qmetric_for_qtype(aclk_query_type_t qtype) { - switch (qtype) { - case HTTP_API_V2: - return &aclk_metrics_per_sample.query_type_http; - case ALARM_STATE_UPDATE: - return &aclk_metrics_per_sample.query_type_alarm_upd; - case METADATA_INFO: - return &aclk_metrics_per_sample.query_type_metadata_info; - case METADATA_ALARMS: - return &aclk_metrics_per_sample.query_type_metadata_alarms; - case CHART_NEW: - return &aclk_metrics_per_sample.query_type_chart_new; - case CHART_DEL: - return &aclk_metrics_per_sample.query_type_chart_del; - case REGISTER_NODE: - return &aclk_metrics_per_sample.query_type_register_node; - case NODE_STATE_UPDATE: - return &aclk_metrics_per_sample.query_type_node_upd; - default: - return NULL; - } -} - int aclk_queue_query(aclk_query_t query) { int ret = _aclk_queue_query(query); if (!ret) { - // local cache of query type before we wake up query thread, which may - // free the query in a race. - aclk_query_type_t qtype = query->type; QUERY_THREAD_WAKEUP; - if (aclk_stats_enabled) { - // get target query type metric before lock so we keep lock for - // minimal time. - volatile uint32_t *metric = aclk_stats_qmetric_for_qtype(qtype); - ACLK_STATS_LOCK; aclk_metrics_per_sample.queries_queued++; - if (metric) - *metric += 1; ACLK_STATS_UNLOCK; } } diff --git a/aclk/aclk_query_queue.h b/aclk/aclk_query_queue.h index db6354433..88976f9eb 100644 --- a/aclk/aclk_query_queue.h +++ b/aclk/aclk_query_queue.h @@ -10,7 +10,7 @@ #include "aclk_util.h" typedef enum { - UNKNOWN, + UNKNOWN = 0, METADATA_INFO, METADATA_ALARMS, HTTP_API_V2, @@ -26,7 +26,8 @@ typedef enum { UPDATE_NODE_INFO, ALARM_LOG_HEALTH, ALARM_PROVIDE_CFG, - ALARM_SNAPSHOT + ALARM_SNAPSHOT, + ACLK_QUERY_TYPE_COUNT // always keep this as last } aclk_query_type_t; struct aclk_query_metadata { diff --git a/aclk/aclk_rx_msgs.c b/aclk/aclk_rx_msgs.c index ecb2b4179..1f2cb27ef 100644 --- a/aclk/aclk_rx_msgs.c +++ b/aclk/aclk_rx_msgs.c @@ -457,9 +457,15 @@ new_cloud_rx_msg_t *find_rx_handler_by_hash(simple_hash_t hash) return NULL; } -void aclk_init_rx_msg_handlers(void) +const char *rx_handler_get_name(size_t i) { - for (int i = 0; rx_msgs[i].fnc; i++) { + return rx_msgs[i].name; +} + +unsigned int aclk_init_rx_msg_handlers(void) +{ + int i; + for (i = 0; rx_msgs[i].fnc; i++) { simple_hash_t hash = simple_hash(rx_msgs[i].name); new_cloud_rx_msg_t *hdl = find_rx_handler_by_hash(hash); if (unlikely(hdl)) { @@ -469,6 +475,7 @@ void aclk_init_rx_msg_handlers(void) } rx_msgs[i].name_hash = hash; } + return i; } void aclk_handle_new_cloud_msg(const char *message_type, const char *msg, size_t msg_len) @@ -489,6 +496,11 @@ void aclk_handle_new_cloud_msg(const char *message_type, const char *msg, size_t } return; } + if (aclk_stats_enabled) { + ACLK_STATS_LOCK; + aclk_proto_rx_msgs_sample[msg_descriptor-rx_msgs]++; + ACLK_STATS_UNLOCK; + } if (msg_descriptor->fnc(msg, msg_len)) { error("Error processing message of type '%s'", message_type); if (aclk_stats_enabled) { diff --git a/aclk/aclk_rx_msgs.h b/aclk/aclk_rx_msgs.h index 38243a4c9..00f88c6a8 100644 --- a/aclk/aclk_rx_msgs.h +++ b/aclk/aclk_rx_msgs.h @@ -11,7 +11,8 @@ int aclk_handle_cloud_cmd_message(char *payload); #ifdef ENABLE_NEW_CLOUD_PROTOCOL -void aclk_init_rx_msg_handlers(void); +const char *rx_handler_get_name(size_t i); +unsigned int aclk_init_rx_msg_handlers(void); void aclk_handle_new_cloud_msg(const char *message_type, const char *msg, size_t msg_len); #endif diff --git a/aclk/aclk_stats.c b/aclk/aclk_stats.c index a7d4a4709..a9f0a923c 100644 --- a/aclk/aclk_stats.c +++ b/aclk/aclk_stats.c @@ -2,9 +2,18 @@ #include "aclk_stats.h" +#include "aclk_query.h" + netdata_mutex_t aclk_stats_mutex = NETDATA_MUTEX_INITIALIZER; -int query_thread_count; +struct { + int query_thread_count; +#ifdef ENABLE_NEW_CLOUD_PROTOCOL + unsigned int proto_hdl_cnt; + uint32_t *aclk_proto_rx_msgs_sample; + RRDDIM **rx_msg_dims; +#endif +} aclk_stats_cfg; // there is only 1 stats thread at a time // data ACLK stats need per query thread struct aclk_qt_data { @@ -13,6 +22,7 @@ struct aclk_qt_data { uint32_t *aclk_queries_per_thread = NULL; uint32_t *aclk_queries_per_thread_sample = NULL; +uint32_t *aclk_proto_rx_msgs_sample = NULL; struct aclk_metrics aclk_metrics = { .online = 0, @@ -113,39 +123,21 @@ static void aclk_stats_cloud_req(struct aclk_metrics_per_sample *per_sample) static void aclk_stats_cloud_req_type(struct aclk_metrics_per_sample *per_sample) { static RRDSET *st = NULL; - static RRDDIM *rd_type_http = NULL; - static RRDDIM *rd_type_alarm_upd = NULL; - static RRDDIM *rd_type_metadata_info = NULL; - static RRDDIM *rd_type_metadata_alarms = NULL; - static RRDDIM *rd_type_chart_new = NULL; - static RRDDIM *rd_type_chart_del = NULL; - static RRDDIM *rd_type_register_node = NULL; - static RRDDIM *rd_type_node_upd = NULL; + static RRDDIM *dims[ACLK_QUERY_TYPE_COUNT]; if (unlikely(!st)) { st = rrdset_create_localhost( "netdata", "aclk_processed_query_type", NULL, "aclk", NULL, "Query thread commands processed by their type", "cmd/s", "netdata", "stats", 200006, localhost->rrd_update_every, RRDSET_TYPE_STACKED); - rd_type_http = rrddim_add(st, "http", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE); - rd_type_alarm_upd = rrddim_add(st, "alarm update", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE); - rd_type_metadata_info = rrddim_add(st, "info metadata", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE); - rd_type_metadata_alarms = rrddim_add(st, "alarms metadata", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE); - rd_type_chart_new = rrddim_add(st, "chart new", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE); - rd_type_chart_del = rrddim_add(st, "chart delete", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE); - rd_type_register_node = rrddim_add(st, "register node", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE); - rd_type_node_upd = rrddim_add(st, "node update", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE); + for (int i = 0; i < ACLK_QUERY_TYPE_COUNT; i++) + dims[i] = rrddim_add(st, aclk_query_get_name(i), NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE); + } else rrdset_next(st); - rrddim_set_by_pointer(st, rd_type_http, per_sample->query_type_http); - rrddim_set_by_pointer(st, rd_type_alarm_upd, per_sample->query_type_alarm_upd); - rrddim_set_by_pointer(st, rd_type_metadata_info, per_sample->query_type_metadata_info); - rrddim_set_by_pointer(st, rd_type_metadata_alarms, per_sample->query_type_metadata_alarms); - rrddim_set_by_pointer(st, rd_type_chart_new, per_sample->query_type_chart_new); - rrddim_set_by_pointer(st, rd_type_chart_del, per_sample->query_type_chart_del); - rrddim_set_by_pointer(st, rd_type_register_node, per_sample->query_type_register_node); - rrddim_set_by_pointer(st, rd_type_node_upd, per_sample->query_type_node_upd); + for (int i = 0; i < ACLK_QUERY_TYPE_COUNT; i++) + rrddim_set_by_pointer(st, dims[i], per_sample->queries_per_type[i]); rrdset_done(st); } @@ -202,7 +194,7 @@ static void aclk_stats_query_threads(uint32_t *queries_per_thread) "netdata", "aclk_query_threads", NULL, "aclk", NULL, "Queries Processed Per Thread", "req/s", "netdata", "stats", 200009, localhost->rrd_update_every, RRDSET_TYPE_STACKED); - for (int i = 0; i < query_thread_count; i++) { + for (int i = 0; i < aclk_stats_cfg.query_thread_count; i++) { if (snprintfz(dim_name, MAX_DIM_NAME, "Query %d", i) < 0) error("snprintf encoding error"); aclk_qt_data[i].dim = rrddim_add(st, dim_name, NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE); @@ -210,7 +202,7 @@ static void aclk_stats_query_threads(uint32_t *queries_per_thread) } else rrdset_next(st); - for (int i = 0; i < query_thread_count; i++) { + for (int i = 0; i < aclk_stats_cfg.query_thread_count; i++) { rrddim_set_by_pointer(st, aclk_qt_data[i].dim, queries_per_thread[i]); } @@ -245,8 +237,57 @@ static void aclk_stats_query_time(struct aclk_metrics_per_sample *per_sample) rrdset_done(st); } +#ifdef ENABLE_NEW_CLOUD_PROTOCOL +const char *rx_handler_get_name(size_t i); +static void aclk_stats_newproto_rx(uint32_t *rx_msgs_sample) +{ + static RRDSET *st = NULL; + + if (unlikely(!st)) { + st = rrdset_create_localhost( + "netdata", "aclk_protobuf_rx_types", NULL, "aclk", NULL, "Received new cloud architecture messages by their type.", "msg/s", + "netdata", "stats", 200010, localhost->rrd_update_every, RRDSET_TYPE_STACKED); + + for (unsigned int i = 0; i < aclk_stats_cfg.proto_hdl_cnt; i++) { + aclk_stats_cfg.rx_msg_dims[i] = rrddim_add(st, rx_handler_get_name(i), NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE); + } + } else + rrdset_next(st); + + for (unsigned int i = 0; i < aclk_stats_cfg.proto_hdl_cnt; i++) + rrddim_set_by_pointer(st, aclk_stats_cfg.rx_msg_dims[i], rx_msgs_sample[i]); + + rrdset_done(st); +} +#endif + +void aclk_stats_thread_prepare(int query_thread_count, unsigned int proto_hdl_cnt) +{ +#ifndef ENABLE_NEW_CLOUD_PROTOCOL + UNUSED(proto_hdl_cnt); +#endif + + aclk_qt_data = callocz(query_thread_count, sizeof(struct aclk_qt_data)); + aclk_queries_per_thread = callocz(query_thread_count, sizeof(uint32_t)); + aclk_queries_per_thread_sample = callocz(query_thread_count, sizeof(uint32_t)); + + memset(&aclk_metrics_per_sample, 0, sizeof(struct aclk_metrics_per_sample)); + +#ifdef ENABLE_NEW_CLOUD_PROTOCOL + aclk_stats_cfg.proto_hdl_cnt = proto_hdl_cnt; + aclk_stats_cfg.aclk_proto_rx_msgs_sample = callocz(proto_hdl_cnt, sizeof(*aclk_proto_rx_msgs_sample)); + aclk_proto_rx_msgs_sample = callocz(proto_hdl_cnt, sizeof(*aclk_proto_rx_msgs_sample)); + aclk_stats_cfg.rx_msg_dims = callocz(proto_hdl_cnt, sizeof(RRDDIM*)); +#endif +} + void aclk_stats_thread_cleanup() { +#ifdef ENABLE_NEW_CLOUD_PROTOCOL + freez(aclk_stats_cfg.rx_msg_dims); + freez(aclk_proto_rx_msgs_sample); + freez(aclk_stats_cfg.aclk_proto_rx_msgs_sample); +#endif freez(aclk_qt_data); freez(aclk_queries_per_thread); freez(aclk_queries_per_thread_sample); @@ -256,17 +297,12 @@ void *aclk_stats_main_thread(void *ptr) { struct aclk_stats_thread *args = ptr; - query_thread_count = args->query_thread_count; - aclk_qt_data = callocz(query_thread_count, sizeof(struct aclk_qt_data)); - aclk_queries_per_thread = callocz(query_thread_count, sizeof(uint32_t)); - aclk_queries_per_thread_sample = callocz(query_thread_count, sizeof(uint32_t)); + aclk_stats_cfg.query_thread_count = args->query_thread_count; heartbeat_t hb; heartbeat_init(&hb); usec_t step_ut = localhost->rrd_update_every * USEC_PER_SEC; - memset(&aclk_metrics_per_sample, 0, sizeof(struct aclk_metrics_per_sample)); - struct aclk_metrics_per_sample per_sample; struct aclk_metrics permanent; @@ -282,11 +318,15 @@ void *aclk_stats_main_thread(void *ptr) // to not hold lock longer than necessary, especially not to hold it // during database rrd* operations memcpy(&per_sample, &aclk_metrics_per_sample, sizeof(struct aclk_metrics_per_sample)); +#ifdef ENABLE_NEW_CLOUD_PROTOCOL + memcpy(aclk_stats_cfg.aclk_proto_rx_msgs_sample, aclk_proto_rx_msgs_sample, sizeof(*aclk_proto_rx_msgs_sample) * aclk_stats_cfg.proto_hdl_cnt); + memset(aclk_proto_rx_msgs_sample, 0, sizeof(*aclk_proto_rx_msgs_sample) * aclk_stats_cfg.proto_hdl_cnt); +#endif memcpy(&permanent, &aclk_metrics, sizeof(struct aclk_metrics)); memset(&aclk_metrics_per_sample, 0, sizeof(struct aclk_metrics_per_sample)); - memcpy(aclk_queries_per_thread_sample, aclk_queries_per_thread, sizeof(uint32_t) * query_thread_count); - memset(aclk_queries_per_thread, 0, sizeof(uint32_t) * query_thread_count); + memcpy(aclk_queries_per_thread_sample, aclk_queries_per_thread, sizeof(uint32_t) * aclk_stats_cfg.query_thread_count); + memset(aclk_queries_per_thread, 0, sizeof(uint32_t) * aclk_stats_cfg.query_thread_count); ACLK_STATS_UNLOCK; aclk_stats_collect(&per_sample, &permanent); @@ -302,6 +342,10 @@ void *aclk_stats_main_thread(void *ptr) aclk_stats_query_threads(aclk_queries_per_thread_sample); aclk_stats_query_time(&per_sample); + +#ifdef ENABLE_NEW_CLOUD_PROTOCOL + aclk_stats_newproto_rx(aclk_stats_cfg.aclk_proto_rx_msgs_sample); +#endif } return 0; diff --git a/aclk/aclk_stats.h b/aclk/aclk_stats.h index 3cc6a0cb0..4f2894798 100644 --- a/aclk/aclk_stats.h +++ b/aclk/aclk_stats.h @@ -5,6 +5,7 @@ #include "daemon/common.h" #include "libnetdata/libnetdata.h" +#include "aclk_query_queue.h" #define ACLK_STATS_THREAD_NAME "ACLK_Stats" @@ -49,14 +50,7 @@ extern struct aclk_metrics_per_sample { volatile uint32_t cloud_req_err; // query types. - volatile uint32_t query_type_http; - volatile uint32_t query_type_alarm_upd; - volatile uint32_t query_type_metadata_info; - volatile uint32_t query_type_metadata_alarms; - volatile uint32_t query_type_chart_new; - volatile uint32_t query_type_chart_del; - volatile uint32_t query_type_register_node; - volatile uint32_t query_type_node_upd; + volatile uint32_t queries_per_type[ACLK_QUERY_TYPE_COUNT]; // HTTP-specific request types. volatile uint32_t cloud_req_http_by_type[ACLK_STATS_CLOUD_HTTP_REQ_TYPE_CNT]; @@ -66,9 +60,14 @@ extern struct aclk_metrics_per_sample { volatile uint32_t cloud_q_process_max; } aclk_metrics_per_sample; +#ifdef ENABLE_NEW_CLOUD_PROTOCOL +extern uint32_t *aclk_proto_rx_msgs_sample; +#endif + extern uint32_t *aclk_queries_per_thread; void *aclk_stats_main_thread(void *ptr); +void aclk_stats_thread_prepare(int query_thread_count, unsigned int proto_hdl_cnt); void aclk_stats_thread_cleanup(); void aclk_stats_upd_online(int online); diff --git a/aclk/aclk_tx_msgs.c b/aclk/aclk_tx_msgs.c index 74fc19c72..185f5d796 100644 --- a/aclk/aclk_tx_msgs.c +++ b/aclk/aclk_tx_msgs.c @@ -116,28 +116,30 @@ static void aclk_send_message_topic(mqtt_wss_client client, json_object *msg, co #define TOPIC_MAX_LEN 512 #define V2_BIN_PAYLOAD_SEPARATOR "\x0D\x0A\x0D\x0A" -static void aclk_send_message_with_bin_payload(mqtt_wss_client client, json_object *msg, const char *topic, const void *payload, size_t payload_len) +static int aclk_send_message_with_bin_payload(mqtt_wss_client client, json_object *msg, const char *topic, const void *payload, size_t payload_len) { uint16_t packet_id; const char *str; - char *full_msg; - int len; + char *full_msg = NULL; + int len, rc; if (unlikely(!topic || topic[0] != '/')) { error ("Full topic required!"); - return; + return 500; } str = json_object_to_json_string_ext(msg, JSON_C_TO_STRING_PLAIN); len = strlen(str); - full_msg = mallocz(len + strlen(V2_BIN_PAYLOAD_SEPARATOR) + payload_len); + if (payload_len) { + full_msg = mallocz(len + strlen(V2_BIN_PAYLOAD_SEPARATOR) + payload_len); - memcpy(full_msg, str, len); - memcpy(&full_msg[len], V2_BIN_PAYLOAD_SEPARATOR, strlen(V2_BIN_PAYLOAD_SEPARATOR)); - len += strlen(V2_BIN_PAYLOAD_SEPARATOR); - memcpy(&full_msg[len], payload, payload_len); - len += payload_len; + memcpy(full_msg, str, len); + memcpy(&full_msg[len], V2_BIN_PAYLOAD_SEPARATOR, strlen(V2_BIN_PAYLOAD_SEPARATOR)); + len += strlen(V2_BIN_PAYLOAD_SEPARATOR); + memcpy(&full_msg[len], payload, payload_len); + len += payload_len; + } /* TODO #ifdef ACLK_LOG_CONVERSATION_DIR @@ -147,15 +149,22 @@ static void aclk_send_message_with_bin_payload(mqtt_wss_client client, json_obje json_object_to_file_ext(filename, msg, JSON_C_TO_STRING_PRETTY); #endif */ - int rc = mqtt_wss_publish_pid_block(client, topic, full_msg, len, MQTT_WSS_PUB_QOS1, &packet_id, 5000); - if (rc == MQTT_WSS_ERR_BLOCK_TIMEOUT) + rc = mqtt_wss_publish_pid_block(client, topic, payload_len ? full_msg : str, len, MQTT_WSS_PUB_QOS1, &packet_id, 5000); + if (rc == MQTT_WSS_ERR_BLOCK_TIMEOUT) { error("Timeout sending binpacked message"); - if (rc == MQTT_WSS_ERR_TX_BUF_TOO_SMALL) + freez(full_msg); + return 503; + } + if (rc == MQTT_WSS_ERR_TX_BUF_TOO_SMALL) { error("Message is bigger than allowed maximum"); + freez(full_msg); + return 403; + } #ifdef NETDATA_INTERNAL_CHECKS aclk_stats_msg_published(packet_id); #endif freez(full_msg); + return 0; } /* @@ -316,6 +325,25 @@ void aclk_send_alarm_metadata(mqtt_wss_client client, int metadata_submitted) buffer_free(local_buffer); } +void aclk_http_msg_v2_err(mqtt_wss_client client, const char *topic, const char *msg_id, int http_code, int ec, const char* emsg, const char *payload, size_t payload_len) +{ + json_object *tmp, *msg; + msg = create_hdr("http", msg_id, 0, 0, 2); + tmp = json_object_new_int(http_code); + json_object_object_add(msg, "http-code", tmp); + + tmp = json_object_new_int(ec); + json_object_object_add(msg, "error-code", tmp); + + tmp = json_object_new_string(emsg); + json_object_object_add(msg, "error-description", tmp); + + if (aclk_send_message_with_bin_payload(client, msg, topic, payload, payload_len)) { + error("Failed to send cancelation message for http reply"); + } + json_object_put(msg); +} + void aclk_http_msg_v2(mqtt_wss_client client, const char *topic, const char *msg_id, usec_t t_exec, usec_t created, int http_code, const char *payload, size_t payload_len) { json_object *tmp, *msg; @@ -331,8 +359,20 @@ void aclk_http_msg_v2(mqtt_wss_client client, const char *topic, const char *msg tmp = json_object_new_int(http_code); json_object_object_add(msg, "http-code", tmp); - aclk_send_message_with_bin_payload(client, msg, topic, payload, payload_len); + int rc = aclk_send_message_with_bin_payload(client, msg, topic, payload, payload_len); json_object_put(msg); + + switch (rc) { + case 403: + aclk_http_msg_v2_err(client, topic, msg_id, rc, CLOUD_EC_REQ_REPLY_TOO_BIG, CLOUD_EMSG_REQ_REPLY_TOO_BIG, payload, payload_len); + break; + case 500: + aclk_http_msg_v2_err(client, topic, msg_id, rc, CLOUD_EC_FAIL_TOPIC, CLOUD_EMSG_FAIL_TOPIC, payload, payload_len); + break; + case 503: + aclk_http_msg_v2_err(client, topic, msg_id, rc, CLOUD_EC_SND_TIMEOUT, CLOUD_EMSG_SND_TIMEOUT, payload, payload_len); + break; + } } void aclk_chart_msg(mqtt_wss_client client, RRDHOST *host, const char *chart) diff --git a/aclk/aclk_tx_msgs.h b/aclk/aclk_tx_msgs.h index da29a4a32..402f13fb6 100644 --- a/aclk/aclk_tx_msgs.h +++ b/aclk/aclk_tx_msgs.h @@ -14,6 +14,7 @@ uint16_t aclk_send_bin_message_subtopic_pid(mqtt_wss_client client, char *msg, s void aclk_send_info_metadata(mqtt_wss_client client, int metadata_submitted, RRDHOST *host); void aclk_send_alarm_metadata(mqtt_wss_client client, int metadata_submitted); +void aclk_http_msg_v2_err(mqtt_wss_client client, const char *topic, const char *msg_id, int http_code, int ec, const char* emsg, const char *payload, size_t payload_len); void aclk_http_msg_v2(mqtt_wss_client client, const char *topic, const char *msg_id, usec_t t_exec, usec_t created, int http_code, const char *payload, size_t payload_len); void aclk_chart_msg(mqtt_wss_client client, RRDHOST *host, const char *chart); diff --git a/aclk/aclk_util.c b/aclk/aclk_util.c index ee8fcaf94..5576a865a 100644 --- a/aclk/aclk_util.c +++ b/aclk/aclk_util.c @@ -41,6 +41,7 @@ void aclk_env_t_destroy(aclk_env_t *env) { for (size_t i = 0; i < env->transport_count; i++) { if(env->transports[i]) { aclk_transport_desc_t_destroy(env->transports[i]); + freez(env->transports[i]); env->transports[i] = NULL; } } @@ -64,7 +65,7 @@ int aclk_env_has_capa(const char *capa) #ifdef ACLK_LOG_CONVERSATION_DIR volatile int aclk_conversation_log_counter = 0; -#if !defined(HAVE_C___ATOMIC) || defined(NETDATA_NO_ATOMIC_INSTRUCTIONS) +#if !defined(HAVE_C___ATOMIC) netdata_mutex_t aclk_conversation_log_mutex = NETDATA_MUTEX_INITIALIZER; int aclk_get_conv_log_next() { diff --git a/aclk/aclk_util.h b/aclk/aclk_util.h index 4d8744e7f..7a7202076 100644 --- a/aclk/aclk_util.h +++ b/aclk/aclk_util.h @@ -5,6 +5,19 @@ #include "libnetdata/libnetdata.h" #include "mqtt_wss_client.h" +#define CLOUD_EC_MALFORMED_NODE_ID 1 +#define CLOUD_EMSG_MALFORMED_NODE_ID "URL requests node_id but there is not enough chars following (for it to be valid uuid)." +#define CLOUD_EC_NODE_NOT_FOUND 2 +#define CLOUD_EMSG_NODE_NOT_FOUND "Node with requested node_id not found" +#define CLOUD_EC_ZLIB_ERROR 3 +#define CLOUD_EMSG_ZLIB_ERROR "Error during zlib compression" +#define CLOUD_EC_REQ_REPLY_TOO_BIG 4 +#define CLOUD_EMSG_REQ_REPLY_TOO_BIG "Request reply produces message bigger than allowed maximum" +#define CLOUD_EC_FAIL_TOPIC 5 +#define CLOUD_EMSG_FAIL_TOPIC "Internal Topic Error" +#define CLOUD_EC_SND_TIMEOUT 6 +#define CLOUD_EMSG_SND_TIMEOUT "Timeout sending binpacked message" + // Helper stuff which should not have any further inside ACLK dependency // and are supposed not to be needed outside of ACLK extern int aclk_use_new_cloud_arch; @@ -86,7 +99,7 @@ void free_topic_cache(void); #ifdef ACLK_LOG_CONVERSATION_DIR extern volatile int aclk_conversation_log_counter; -#if defined(HAVE_C___ATOMIC) && !defined(NETDATA_NO_ATOMIC_INSTRUCTIONS) +#if defined(HAVE_C___ATOMIC) #define ACLK_GET_CONV_LOG_NEXT() __atomic_fetch_add(&aclk_conversation_log_counter, 1, __ATOMIC_SEQ_CST) #else extern netdata_mutex_t aclk_conversation_log_mutex; diff --git a/aclk/https_client.c b/aclk/https_client.c index 470c3fdf3..1a32f833f 100644 --- a/aclk/https_client.c +++ b/aclk/https_client.c @@ -587,7 +587,7 @@ void https_req_response_init(https_req_response_t *res) { res->payload_size = 0; } -static inline char *min_non_null(char *a, char *b) { +static inline char *UNUSED_FUNCTION(min_non_null)(char *a, char *b) { if (!a) return b; if (!b) diff --git a/backends/Makefile.am b/backends/Makefile.am deleted file mode 100644 index dace0132a..000000000 --- a/backends/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later - -AUTOMAKE_OPTIONS = subdir-objects -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in - -SUBDIRS = \ - graphite \ - json \ - opentsdb \ - prometheus \ - aws_kinesis \ - mongodb \ - $(NULL) - -dist_noinst_DATA = \ - README.md \ - WALKTHROUGH.md \ - $(NULL) - -dist_noinst_SCRIPTS = \ - nc-backend.sh \ - $(NULL) diff --git a/backends/README.md b/backends/README.md deleted file mode 100644 index 8d53fd664..000000000 --- a/backends/README.md +++ /dev/null @@ -1,236 +0,0 @@ - - -# Metrics long term archiving - -> ⚠️ The backends system is now deprecated in favor of the [exporting engine](/exporting/README.md). - -Netdata supports backends for archiving the metrics, or providing long term dashboards, using Grafana or other tools, -like this: - -![image](https://cloud.githubusercontent.com/assets/2662304/20649711/29f182ba-b4ce-11e6-97c8-ab2c0ab59833.png) - -Since Netdata collects thousands of metrics per server per second, which would easily congest any backend server when -several Netdata servers are sending data to it, Netdata allows sending metrics at a lower frequency, by resampling them. - -So, although Netdata collects metrics every second, it can send to the backend servers averages or sums every X seconds -(though, it can send them per second if you need it to). - -## features - -1. Supported backends - - - **graphite** (`plaintext interface`, used by **Graphite**, **InfluxDB**, **KairosDB**, **Blueflood**, - **ElasticSearch** via logstash tcp input and the graphite codec, etc) - - metrics are sent to the backend server as `prefix.hostname.chart.dimension`. `prefix` is configured below, - `hostname` is the hostname of the machine (can also be configured). - - - **opentsdb** (`telnet or HTTP interfaces`, used by **OpenTSDB**, **InfluxDB**, **KairosDB**, etc) - - metrics are sent to opentsdb as `prefix.chart.dimension` with tag `host=hostname`. - - - **json** document DBs - - metrics are sent to a document db, `JSON` formatted. - - - **prometheus** is described at [prometheus page](/backends/prometheus/README.md) since it pulls data from - Netdata. - - - **prometheus remote write** (a binary snappy-compressed protocol buffer encoding over HTTP used by - **Elasticsearch**, **Gnocchi**, **Graphite**, **InfluxDB**, **Kafka**, **OpenTSDB**, **PostgreSQL/TimescaleDB**, - **Splunk**, **VictoriaMetrics**, and a lot of other [storage - providers](https://prometheus.io/docs/operating/integrations/#remote-endpoints-and-storage)) - - metrics are labeled in the format, which is used by Netdata for the [plaintext prometheus - protocol](/backends/prometheus/README.md). Notes on using the remote write backend are [here](/backends/prometheus/remote_write/README.md). - - - **TimescaleDB** via [community-built connector](/backends/TIMESCALE.md) that takes JSON streams from a Netdata - client and writes them to a TimescaleDB table. - - - **AWS Kinesis Data Streams** - - metrics are sent to the service in `JSON` format. - - - **MongoDB** - - metrics are sent to the database in `JSON` format. - -2. Only one backend may be active at a time. - -3. Netdata can filter metrics (at the chart level), to send only a subset of the collected metrics. - -4. Netdata supports three modes of operation for all backends: - - - `as-collected` sends to backends the metrics as they are collected, in the units they are collected. So, - counters are sent as counters and gauges are sent as gauges, much like all data collectors do. For example, to - calculate CPU utilization in this format, you need to know how to convert kernel ticks to percentage. - - - `average` sends to backends normalized metrics from the Netdata database. In this mode, all metrics are sent as - gauges, in the units Netdata uses. This abstracts data collection and simplifies visualization, but you will not - be able to copy and paste queries from other sources to convert units. For example, CPU utilization percentage - is calculated by Netdata, so Netdata will convert ticks to percentage and send the average percentage to the - backend. - - - `sum` or `volume`: the sum of the interpolated values shown on the Netdata graphs is sent to the backend. So, if - Netdata is configured to send data to the backend every 10 seconds, the sum of the 10 values shown on the - Netdata charts will be used. - - Time-series databases suggest to collect the raw values (`as-collected`). If you plan to invest on building your - monitoring around a time-series database and you already know (or you will invest in learning) how to convert units - and normalize the metrics in Grafana or other visualization tools, we suggest to use `as-collected`. - - If, on the other hand, you just need long term archiving of Netdata metrics and you plan to mainly work with - Netdata, we suggest to use `average`. It decouples visualization from data collection, so it will generally be a lot - simpler. Furthermore, if you use `average`, the charts shown in the back-end will match exactly what you see in - Netdata, which is not necessarily true for the other modes of operation. - -5. This code is smart enough, not to slow down Netdata, independently of the speed of the backend server. - -## configuration - -In `/etc/netdata/netdata.conf` you should have something like this (if not download the latest version of `netdata.conf` -from your Netdata): - -```conf -[backend] - enabled = yes | no - type = graphite | opentsdb:telnet | opentsdb:http | opentsdb:https | prometheus_remote_write | json | kinesis | mongodb - host tags = list of TAG=VALUE - destination = space separated list of [PROTOCOL:]HOST[:PORT] - the first working will be used, or a region for kinesis - data source = average | sum | as collected - prefix = Netdata - hostname = my-name - update every = 10 - buffer on failures = 10 - timeout ms = 20000 - send charts matching = * - send hosts matching = localhost * - send names instead of ids = yes -``` - -- `enabled = yes | no`, enables or disables sending data to a backend - -- `type = graphite | opentsdb:telnet | opentsdb:http | opentsdb:https | json | kinesis | mongodb`, selects the backend - type - -- `destination = host1 host2 host3 ...`, accepts **a space separated list** of hostnames, IPs (IPv4 and IPv6) and - ports to connect to. Netdata will use the **first available** to send the metrics. - - The format of each item in this list, is: `[PROTOCOL:]IP[:PORT]`. - - `PROTOCOL` can be `udp` or `tcp`. `tcp` is the default and only supported by the current backends. - - `IP` can be `XX.XX.XX.XX` (IPv4), or `[XX:XX...XX:XX]` (IPv6). For IPv6 you can to enclose the IP in `[]` to - separate it from the port. - - `PORT` can be a number of a service name. If omitted, the default port for the backend will be used - (graphite = 2003, opentsdb = 4242). - - Example IPv4: - -```conf - destination = 10.11.14.2:4242 10.11.14.3:4242 10.11.14.4:4242 -``` - - Example IPv6 and IPv4 together: - -```conf - destination = [ffff:...:0001]:2003 10.11.12.1:2003 -``` - - When multiple servers are defined, Netdata will try the next one when the first one fails. This allows you to - load-balance different servers: give your backend servers in different order on each Netdata. - - Netdata also ships `nc-backend.sh`, a script that can be used as a fallback backend to save the - metrics to disk and push them to the time-series database when it becomes available again. It can also be used to - monitor / trace / debug the metrics Netdata generates. - - For kinesis backend `destination` should be set to an AWS region (for example, `us-east-1`). - - The MongoDB backend doesn't use the `destination` option for its configuration. It uses the `mongodb.conf` - [configuration file](/backends/mongodb/README.md) instead. - -- `data source = as collected`, or `data source = average`, or `data source = sum`, selects the kind of data that will - be sent to the backend. - -- `hostname = my-name`, is the hostname to be used for sending data to the backend server. By default this is - `[global].hostname`. - -- `prefix = Netdata`, is the prefix to add to all metrics. - -- `update every = 10`, is the number of seconds between sending data to the backend. Netdata will add some randomness - to this number, to prevent stressing the backend server when many Netdata servers send data to the same backend. - This randomness does not affect the quality of the data, only the time they are sent. - -- `buffer on failures = 10`, is the number of iterations (each iteration is `[backend].update every` seconds) to - buffer data, when the backend is not available. If the backend fails to receive the data after that many failures, - data loss on the backend is expected (Netdata will also log it). - -- `timeout ms = 20000`, is the timeout in milliseconds to wait for the backend server to process the data. By default - this is `2 * update_every * 1000`. - -- `send hosts matching = localhost *` includes one or more space separated patterns, using `*` as wildcard (any number - of times within each pattern). The patterns are checked against the hostname (the localhost is always checked as - `localhost`), allowing us to filter which hosts will be sent to the backend when this Netdata is a central Netdata - aggregating multiple hosts. A pattern starting with `!` gives a negative match. So to match all hosts named `*db*` - except hosts containing `*child*`, use `!*child* *db*` (so, the order is important: the first pattern - matching the hostname will be used - positive or negative). - -- `send charts matching = *` includes one or more space separated patterns, using `*` as wildcard (any number of times - within each pattern). The patterns are checked against both chart id and chart name. A pattern starting with `!` - gives a negative match. So to match all charts named `apps.*` except charts ending in `*reads`, use `!*reads - apps.*` (so, the order is important: the first pattern matching the chart id or the chart name will be used - - positive or negative). - -- `send names instead of ids = yes | no` controls the metric names Netdata should send to backend. Netdata supports - names and IDs for charts and dimensions. Usually IDs are unique identifiers as read by the system and names are - human friendly labels (also unique). Most charts and metrics have the same ID and name, but in several cases they - are different: disks with device-mapper, interrupts, QoS classes, statsd synthetic charts, etc. - -- `host tags = list of TAG=VALUE` defines tags that should be appended on all metrics for the given host. These are - currently only sent to graphite, json, opentsdb and prometheus. Please use the appropriate format for each - time-series db. For example opentsdb likes them like `TAG1=VALUE1 TAG2=VALUE2`, but prometheus like `tag1="value1", - tag2="value2"`. Host tags are mirrored with database replication (streaming of metrics between Netdata servers). - - Starting from Netdata v1.20 the host tags are parsed in accordance with a configured backend type and stored as - host labels so that they can be reused in API responses and exporting connectors. The parsing is supported for - graphite, json, opentsdb, and prometheus (default) backend types. You can check how the host tags were parsed using - the /api/v1/info API call. - -## monitoring operation - -Netdata provides 5 charts: - -1. **Buffered metrics**, the number of metrics Netdata added to the buffer for dispatching them to the - backend server. - -2. **Buffered data size**, the amount of data (in KB) Netdata added the buffer. - -3. ~~**Backend latency**, the time the backend server needed to process the data Netdata sent. If there was a - re-connection involved, this includes the connection time.~~ (this chart has been removed, because it only measures - the time Netdata needs to give the data to the O/S - since the backend servers do not ack the reception, Netdata - does not have any means to measure this properly). - -4. **Backend operations**, the number of operations performed by Netdata. - -5. **Backend thread CPU usage**, the CPU resources consumed by the Netdata thread, that is responsible for sending the - metrics to the backend server. - -![image](https://cloud.githubusercontent.com/assets/2662304/20463536/eb196084-af3d-11e6-8ee5-ddbd3b4d8449.png) - -## alarms - -Netdata adds 4 alarms: - -1. `backend_last_buffering`, number of seconds since the last successful buffering of backend data -2. `backend_metrics_sent`, percentage of metrics sent to the backend server -3. `backend_metrics_lost`, number of metrics lost due to repeating failures to contact the backend server -4. ~~`backend_slow`, the percentage of time between iterations needed by the backend time to process the data sent by - Netdata~~ (this was misleading and has been removed). - -![image](https://cloud.githubusercontent.com/assets/2662304/20463779/a46ed1c2-af43-11e6-91a5-07ca4533cac3.png) - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fbackends%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) diff --git a/backends/TIMESCALE.md b/backends/TIMESCALE.md deleted file mode 100644 index 05a3c3b47..000000000 --- a/backends/TIMESCALE.md +++ /dev/null @@ -1,57 +0,0 @@ - - -# Writing metrics to TimescaleDB - -Thanks to Netdata's community of developers and system administrators, and Mahlon Smith -([GitHub](https://github.com/mahlonsmith)/[Website](http://www.martini.nu/)) in particular, Netdata now supports -archiving metrics directly to TimescaleDB. - -What's TimescaleDB? Here's how their team defines the project on their [GitHub page](https://github.com/timescale/timescaledb): - -> TimescaleDB is an open-source database designed to make SQL scalable for time-series data. It is engineered up from -> PostgreSQL, providing automatic partitioning across time and space (partitioning key), as well as full SQL support. - -## Quickstart - -To get started archiving metrics to TimescaleDB right away, check out Mahlon's [`netdata-timescale-relay` -repository](https://github.com/mahlonsmith/netdata-timescale-relay) on GitHub. - -This small program takes JSON streams from a Netdata client and writes them to a PostgreSQL (aka TimescaleDB) table. -You'll run this program in parallel with Netdata, and after a short [configuration -process](https://github.com/mahlonsmith/netdata-timescale-relay#configuration), your metrics should start populating -TimescaleDB. - -Finally, another member of Netdata's community has built a project that quickly launches Netdata, TimescaleDB, and -Grafana in easy-to-manage Docker containers. Rune Juhl Jacobsen's -[project](https://github.com/runejuhl/grafana-timescaledb) uses a `Makefile` to create everything, which makes it -perfect for testing and experimentation. - -## Netdata↔TimescaleDB in action - -Aside from creating incredible contributions to Netdata, Mahlon works at [LAIKA](https://www.laika.com/), an -Oregon-based animation studio that's helped create acclaimed films like _Coraline_ and _Kubo and the Two Strings_. - -As part of his work to maintain the company's infrastructure of render farms, workstations, and virtual machines, he's -using Netdata, `netdata-timescale-relay`, and TimescaleDB to store Netdata metrics alongside other data from other -sources. - -> LAIKA is a long-time PostgreSQL user and added TimescaleDB to their infrastructure in 2018 to help manage and store -> their IT metrics and time-series data. So far, the tool has been in production at LAIKA for over a year and helps them -> with their use case of time-based logging, where they record over 8 million metrics an hour for netdata content alone. - -By archiving Netdata metrics to a backend like TimescaleDB, LAIKA can consolidate metrics data from distributed machines -efficiently. Mahlon can then correlate Netdata metrics with other sources directly in TimescaleDB. - -And, because LAIKA will soon be storing years worth of Netdata metrics data in TimescaleDB, they can analyze long-term -metrics as their films move from concept to final cut. - -Read the full blog post from LAIKA at the [TimescaleDB -blog](https://blog.timescale.com/blog/writing-it-metrics-from-netdata-to-timescaledb/amp/). - -Thank you to Mahlon, Rune, TimescaleDB, and the members of the Netdata community that requested and then built this -backend connection between Netdata and TimescaleDB! - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fbackends%2FTIMESCALE&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) diff --git a/backends/WALKTHROUGH.md b/backends/WALKTHROUGH.md deleted file mode 100644 index bb38e7c1c..000000000 --- a/backends/WALKTHROUGH.md +++ /dev/null @@ -1,258 +0,0 @@ - - -# Netdata, Prometheus, Grafana stack - -## Intro - -In this article I will walk you through the basics of getting Netdata, Prometheus and Grafana all working together and -monitoring your application servers. This article will be using docker on your local workstation. We will be working -with docker in an ad-hoc way, launching containers that run ‘/bin/bash’ and attaching a TTY to them. I use docker here -in a purely academic fashion and do not condone running Netdata in a container. I pick this method so individuals -without cloud accounts or access to VMs can try this out and for it’s speed of deployment. - -## Why Netdata, Prometheus, and Grafana - -Some time ago I was introduced to Netdata by a coworker. We were attempting to troubleshoot python code which seemed to -be bottlenecked. I was instantly impressed by the amount of metrics Netdata exposes to you. I quickly added Netdata to -my set of go-to tools when troubleshooting systems performance. - -Some time ago, even later, I was introduced to Prometheus. Prometheus is a monitoring application which flips the normal -architecture around and polls rest endpoints for its metrics. This architectural change greatly simplifies and decreases -the time necessary to begin monitoring your applications. Compared to current monitoring solutions the time spent on -designing the infrastructure is greatly reduced. Running a single Prometheus server per application becomes feasible -with the help of Grafana. - -Grafana has been the go to graphing tool for… some time now. It’s awesome, anyone that has used it knows it’s awesome. -We can point Grafana at Prometheus and use Prometheus as a data source. This allows a pretty simple overall monitoring -architecture: Install Netdata on your application servers, point Prometheus at Netdata, and then point Grafana at -Prometheus. - -I’m omitting an important ingredient in this stack in order to keep this tutorial simple and that is service discovery. -My personal preference is to use Consul. Prometheus can plug into consul and automatically begin to scrape new hosts -that register a Netdata client with Consul. - -At the end of this tutorial you will understand how each technology fits together to create a modern monitoring stack. -This stack will offer you visibility into your application and systems performance. - -## Getting Started - Netdata - -To begin let’s create our container which we will install Netdata on. We need to run a container, forward the necessary -port that Netdata listens on, and attach a tty so we can interact with the bash shell on the container. But before we do -this we want name resolution between the two containers to work. In order to accomplish this we will create a -user-defined network and attach both containers to this network. The first command we should run is: - -```sh -docker network create --driver bridge netdata-tutorial -``` - -With this user-defined network created we can now launch our container we will install Netdata on and point it to this -network. - -```sh -docker run -it --name netdata --hostname netdata --network=netdata-tutorial -p 19999:19999 centos:latest '/bin/bash' -``` - -This command creates an interactive tty session (-it), gives the container both a name in relation to the docker daemon -and a hostname (this is so you know what container is which when working in the shells and docker maps hostname -resolution to this container), forwards the local port 19999 to the container’s port 19999 (-p 19999:19999), sets the -command to run (/bin/bash) and then chooses the base container images (centos:latest). After running this you should be -sitting inside the shell of the container. - -After we have entered the shell we can install Netdata. This process could not be easier. If you take a look at [this -link](/packaging/installer/README.md), the Netdata devs give us several one-liners to install Netdata. I have not had -any issues with these one liners and their bootstrapping scripts so far (If you guys run into anything do share). Run -the following command in your container. - -```sh -bash <(curl -Ss https://my-netdata.io/kickstart.sh) --dont-wait -``` - -After the install completes you should be able to hit the Netdata dashboard at (replace -localhost if you’re doing this on a VM or have the docker container hosted on a machine not on your local system). If -this is your first time using Netdata I suggest you take a look around. The amount of time I’ve spent digging through -/proc and calculating my own metrics has been greatly reduced by this tool. Take it all in. - -Next I want to draw your attention to a particular endpoint. Navigate to - In your browser. This is the endpoint which -publishes all the metrics in a format which Prometheus understands. Let’s take a look at one of these metrics. -`netdata_system_cpu_percentage_average{chart="system.cpu",family="cpu",dimension="system"} 0.0831255 1501271696000` This -metric is representing several things which I will go in more details in the section on prometheus. For now understand -that this metric: `netdata_system_cpu_percentage_average` has several labels: (chart, family, dimension). This -corresponds with the first cpu chart you see on the Netdata dashboard. - -![](https://github.com/ldelossa/NetdataTutorial/raw/master/Screen%20Shot%202017-07-28%20at%204.00.45%20PM.png) - -This CHART is called ‘system.cpu’, The FAMILY is cpu, and the DIMENSION we are observing is “system”. You can begin to -draw links between the charts in Netdata to the prometheus metrics format in this manner. - -## Prometheus - -We will be installing prometheus in a container for purpose of demonstration. While prometheus does have an official -container I would like to walk through the install process and setup on a fresh container. This will allow anyone -reading to migrate this tutorial to a VM or Server of any sort. - -Let’s start another container in the same fashion as we did the Netdata container. - -```sh -docker run -it --name prometheus --hostname prometheus ---network=netdata-tutorial -p 9090:9090 centos:latest '/bin/bash' -``` - -This should drop you into a shell once again. Once there quickly install your favorite editor as we will be editing -files later in this tutorial. - -```sh -yum install vim -y -``` - -Prometheus provides a tarball of their latest stable versions [here](https://prometheus.io/download/). - -Let’s download the latest version and install into your container. - -```sh -cd /tmp && curl -s https://api.github.com/repos/prometheus/prometheus/releases/latest \ -| grep "browser_download_url.*linux-amd64.tar.gz" \ -| cut -d '"' -f 4 \ -| wget -qi - - -mkdir /opt/prometheus - -sudo tar -xvf /tmp/prometheus-*linux-amd64.tar.gz -C /opt/prometheus --strip=1 -``` - -This should get prometheus installed into the container. Let’s test that we can run prometheus and connect to it’s web -interface. - -```sh -/opt/prometheus/prometheus -``` - -Now attempt to go to . You should be presented with the prometheus homepage. This is a good -point to talk about Prometheus’s data model which can be viewed here: -As explained we have two key elements in Prometheus metrics. We have the ‘metric’ and its ‘labels’. Labels allow for -granularity between metrics. Let’s use our previous example to further explain. - -```conf -netdata_system_cpu_percentage_average{chart="system.cpu",family="cpu",dimension="system"} 0.0831255 1501271696000 -``` - -Here our metric is ‘netdata_system_cpu_percentage_average’ and our labels are ‘chart’, ‘family’, and ‘dimension. The -last two values constitute the actual metric value for the metric type (gauge, counter, etc…). We can begin graphing -system metrics with this information, but first we need to hook up Prometheus to poll Netdata stats. - -Let’s move our attention to Prometheus’s configuration. Prometheus gets it config from the file located (in our example) -at `/opt/prometheus/prometheus.yml`. I won’t spend an extensive amount of time going over the configuration values -documented here: . We will be adding a new“job” under the -“scrape_configs”. Let’s make the “scrape_configs” section look like this (we can use the dns name Netdata due to the -custom user-defined network we created in docker beforehand). - -```yaml -scrape_configs: - # The job name is added as a label `job=` to any timeseries scraped from this config. - - job_name: 'prometheus' - - # metrics_path defaults to '/metrics' - # scheme defaults to 'http'. - - static_configs: - - targets: ['localhost:9090'] - - - job_name: 'netdata' - - metrics_path: /api/v1/allmetrics - params: - format: [ prometheus ] - - static_configs: - - targets: ['netdata:19999'] -``` - -Let’s start prometheus once again by running `/opt/prometheus/prometheus`. If we now navigate to prometheus at -‘ we should see our target being successfully scraped. If we now go back to the -Prometheus’s homepage and begin to type ‘netdata\_’ Prometheus should auto complete metrics it is now scraping. - -![](https://github.com/ldelossa/NetdataTutorial/raw/master/Screen%20Shot%202017-07-28%20at%205.13.43%20PM.png) - -Let’s now start exploring how we can graph some metrics. Back in our Netdata container lets get the CPU spinning with a -pointless busy loop. On the shell do the following: - -```sh -[root@netdata /]# while true; do echo "HOT HOT HOT CPU"; done -``` - -Our Netdata cpu graph should be showing some activity. Let’s represent this in Prometheus. In order to do this let’s -keep our metrics page open for reference: We are -setting out to graph the data in the CPU chart so let’s search for “system.cpu”in the metrics page above. We come across -a section of metrics with the first comments `# COMMENT homogeneous chart "system.cpu", context "system.cpu", family -"cpu", units "percentage"` Followed by the metrics. This is a good start now let us drill down to the specific metric we -would like to graph. - -```conf -# COMMENT -netdata_system_cpu_percentage_average: dimension "system", value is percentage, gauge, dt 1501275951 to 1501275951 inclusive -netdata_system_cpu_percentage_average{chart="system.cpu",family="cpu",dimension="system"} 0.0000000 1501275951000 -``` - -Here we learn that the metric name we care about is‘netdata_system_cpu_percentage_average’ so throw this into Prometheus -and see what we get. We should see something similar to this (I shut off my busy loop) - -![](https://github.com/ldelossa/NetdataTutorial/raw/master/Screen%20Shot%202017-07-28%20at%205.47.53%20PM.png) - -This is a good step toward what we want. Also make note that Prometheus will tag on an ‘instance’ label for us which -corresponds to our statically defined job in the configuration file. This allows us to tailor our queries to specific -instances. Now we need to isolate the dimension we want in our query. To do this let us refine the query slightly. Let’s -query the dimension also. Place this into our query text box. -`netdata_system_cpu_percentage_average{dimension="system"}` We now wind up with the following graph. - -![](https://github.com/ldelossa/NetdataTutorial/raw/master/Screen%20Shot%202017-07-28%20at%205.54.40%20PM.png) - -Awesome, this is exactly what we wanted. If you haven’t caught on yet we can emulate entire charts from Netdata by using -the `chart` dimension. If you’d like you can combine the ‘chart’ and ‘instance’ dimension to create per-instance charts. -Let’s give this a try: `netdata_system_cpu_percentage_average{chart="system.cpu", instance="netdata:19999"}` - -This is the basics of using Prometheus to query Netdata. I’d advise everyone at this point to read [this -page](/backends/prometheus/README.md#using-netdata-with-prometheus). The key point here is that Netdata can export metrics from -its internal DB or can send metrics “as-collected” by specifying the ‘source=as-collected’ url parameter like so. - If you choose to use -this method you will need to use Prometheus's set of functions here: to -obtain useful metrics as you are now dealing with raw counters from the system. For example you will have to use the -`irate()` function over a counter to get that metric's rate per second. If your graphing needs are met by using the -metrics returned by Netdata's internal database (not specifying any source= url parameter) then use that. If you find -limitations then consider re-writing your queries using the raw data and using Prometheus functions to get the desired -chart. - -## Grafana - -Finally we make it to grafana. This is the easiest part in my opinion. This time we will actually run the official -grafana docker container as all configuration we need to do is done via the GUI. Let’s run the following command: - -```sh -docker run -i -p 3000:3000 --network=netdata-tutorial grafana/grafana -``` - -This will get grafana running at ‘ Let’s go there and - -login using the credentials Admin:Admin. - -The first thing we want to do is click ‘Add data source’. Let’s make it look like the following screenshot - -![](https://github.com/ldelossa/NetdataTutorial/raw/master/Screen%20Shot%202017-07-28%20at%206.36.55%20PM.png) - -With this completed let’s graph! Create a new Dashboard by clicking on the top left Grafana Icon and create a new graph -in that dashboard. Fill in the query like we did above and save. - -![](https://github.com/ldelossa/NetdataTutorial/raw/master/Screen%20Shot%202017-07-28%20at%206.39.38%20PM.png) - -## Conclusion - -There you have it, a complete systems monitoring stack which is very easy to deploy. From here I would begin to -understand how Prometheus and a service discovery mechanism such as Consul can play together nicely. My current prod -deployments automatically register Netdata services into Consul and Prometheus automatically begins to scrape them. Once -achieved you do not have to think about the monitoring system until Prometheus cannot keep up with your scale. Once this -happens there are options presented in the Prometheus documentation for solving this. Hope this was helpful, happy -monitoring. - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fbackends%2FWALKTHROUGH&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) diff --git a/backends/aws_kinesis/Makefile.am b/backends/aws_kinesis/Makefile.am deleted file mode 100644 index 1fec72c1f..000000000 --- a/backends/aws_kinesis/Makefile.am +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later - -AUTOMAKE_OPTIONS = subdir-objects -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in - -dist_noinst_DATA = \ - README.md \ - $(NULL) - -dist_libconfig_DATA = \ - aws_kinesis.conf \ - $(NULL) diff --git a/backends/aws_kinesis/README.md b/backends/aws_kinesis/README.md deleted file mode 100644 index a2b682517..000000000 --- a/backends/aws_kinesis/README.md +++ /dev/null @@ -1,53 +0,0 @@ - - -# Using Netdata with AWS Kinesis Data Streams - -## Prerequisites - -To use AWS Kinesis as a backend AWS SDK for C++ should be -[installed](https://docs.aws.amazon.com/en_us/sdk-for-cpp/v1/developer-guide/setup.html) first. `libcrypto`, `libssl`, -and `libcurl` are also required to compile Netdata with Kinesis support enabled. Next, Netdata should be re-installed -from the source. The installer will detect that the required libraries are now available. - -If the AWS SDK for C++ is being installed from source, it is useful to set `-DBUILD_ONLY="kinesis"`. Otherwise, the -building process could take a very long time. Take a note, that the default installation path for the libraries is -`/usr/local/lib64`. Many Linux distributions don't include this path as the default one for a library search, so it is -advisable to use the following options to `cmake` while building the AWS SDK: - -```sh -cmake -DCMAKE_INSTALL_LIBDIR=/usr/lib -DCMAKE_INSTALL_INCLUDEDIR=/usr/include -DBUILD_SHARED_LIBS=OFF -DBUILD_ONLY=kinesis -``` - -## Configuration - -To enable data sending to the kinesis backend set the following options in `netdata.conf`: - -```conf -[backend] - enabled = yes - type = kinesis - destination = us-east-1 -``` - -set the `destination` option to an AWS region. - -In the Netdata configuration directory run `./edit-config aws_kinesis.conf` and set AWS credentials and stream name: - -```yaml -# AWS credentials -aws_access_key_id = your_access_key_id -aws_secret_access_key = your_secret_access_key - -# destination stream -stream name = your_stream_name -``` - -Alternatively, AWS credentials can be set for the `netdata` user using AWS SDK for C++ [standard methods](https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/credentials.html). - -A partition key for every record is computed automatically by Netdata with the purpose to distribute records across -available shards evenly. - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fbackends%2Faws_kinesis%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) diff --git a/backends/aws_kinesis/aws_kinesis.c b/backends/aws_kinesis/aws_kinesis.c deleted file mode 100644 index b1ea47862..000000000 --- a/backends/aws_kinesis/aws_kinesis.c +++ /dev/null @@ -1,94 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -#define BACKENDS_INTERNALS -#include "aws_kinesis.h" - -#define CONFIG_FILE_LINE_MAX ((CONFIG_MAX_NAME + CONFIG_MAX_VALUE + 1024) * 2) - -// ---------------------------------------------------------------------------- -// kinesis backend - -// read the aws_kinesis.conf file -int read_kinesis_conf(const char *path, char **access_key_id_p, char **secret_access_key_p, char **stream_name_p) -{ - char *access_key_id = *access_key_id_p; - char *secret_access_key = *secret_access_key_p; - char *stream_name = *stream_name_p; - - if(unlikely(access_key_id)) freez(access_key_id); - if(unlikely(secret_access_key)) freez(secret_access_key); - if(unlikely(stream_name)) freez(stream_name); - access_key_id = NULL; - secret_access_key = NULL; - stream_name = NULL; - - int line = 0; - - char filename[FILENAME_MAX + 1]; - snprintfz(filename, FILENAME_MAX, "%s/aws_kinesis.conf", path); - - char buffer[CONFIG_FILE_LINE_MAX + 1], *s; - - debug(D_BACKEND, "BACKEND: opening config file '%s'", filename); - - FILE *fp = fopen(filename, "r"); - if(!fp) { - return 1; - } - - while(fgets(buffer, CONFIG_FILE_LINE_MAX, fp) != NULL) { - buffer[CONFIG_FILE_LINE_MAX] = '\0'; - line++; - - s = trim(buffer); - if(!s || *s == '#') { - debug(D_BACKEND, "BACKEND: ignoring line %d of file '%s', it is empty.", line, filename); - continue; - } - - char *name = s; - char *value = strchr(s, '='); - if(unlikely(!value)) { - error("BACKEND: ignoring line %d ('%s') of file '%s', there is no = in it.", line, s, filename); - continue; - } - *value = '\0'; - value++; - - name = trim(name); - value = trim(value); - - if(unlikely(!name || *name == '#')) { - error("BACKEND: ignoring line %d of file '%s', name is empty.", line, filename); - continue; - } - - if(!value) - value = ""; - else - value = strip_quotes(value); - - if(name[0] == 'a' && name[4] == 'a' && !strcmp(name, "aws_access_key_id")) { - access_key_id = strdupz(value); - } - else if(name[0] == 'a' && name[4] == 's' && !strcmp(name, "aws_secret_access_key")) { - secret_access_key = strdupz(value); - } - else if(name[0] == 's' && !strcmp(name, "stream name")) { - stream_name = strdupz(value); - } - } - - fclose(fp); - - if(unlikely(!stream_name || !*stream_name)) { - error("BACKEND: stream name is a mandatory Kinesis parameter but it is not configured"); - return 1; - } - - *access_key_id_p = access_key_id; - *secret_access_key_p = secret_access_key; - *stream_name_p = stream_name; - - return 0; -} diff --git a/backends/aws_kinesis/aws_kinesis.conf b/backends/aws_kinesis/aws_kinesis.conf deleted file mode 100644 index cc54b5fa2..000000000 --- a/backends/aws_kinesis/aws_kinesis.conf +++ /dev/null @@ -1,10 +0,0 @@ -# AWS Kinesis Data Streams backend configuration -# -# All options in this file are mandatory - -# AWS credentials -aws_access_key_id = -aws_secret_access_key = - -# destination stream -stream name = \ No newline at end of file diff --git a/backends/aws_kinesis/aws_kinesis.h b/backends/aws_kinesis/aws_kinesis.h deleted file mode 100644 index 50a4631c5..000000000 --- a/backends/aws_kinesis/aws_kinesis.h +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -#ifndef NETDATA_BACKEND_KINESIS_H -#define NETDATA_BACKEND_KINESIS_H - -#include "backends/backends.h" -#include "aws_kinesis_put_record.h" - -#define KINESIS_PARTITION_KEY_MAX 256 -#define KINESIS_RECORD_MAX 1024 * 1024 - -extern int read_kinesis_conf(const char *path, char **auth_key_id_p, char **secure_key_p, char **stream_name_p); - -#endif //NETDATA_BACKEND_KINESIS_H diff --git a/backends/aws_kinesis/aws_kinesis_put_record.cc b/backends/aws_kinesis/aws_kinesis_put_record.cc deleted file mode 100644 index a8ba4aaca..000000000 --- a/backends/aws_kinesis/aws_kinesis_put_record.cc +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -#include -#include -#include -#include -#include -#include -#include "aws_kinesis_put_record.h" - -using namespace Aws; - -static SDKOptions options; - -static Kinesis::KinesisClient *client; - -struct request_outcome { - Kinesis::Model::PutRecordOutcomeCallable future_outcome; - size_t data_len; -}; - -static Vector request_outcomes; - -void backends_kinesis_init(const char *region, const char *access_key_id, const char *secret_key, const long timeout) { - InitAPI(options); - - Client::ClientConfiguration config; - - config.region = region; - config.requestTimeoutMs = timeout; - config.connectTimeoutMs = timeout; - - if(access_key_id && *access_key_id && secret_key && *secret_key) { - client = New("client", Auth::AWSCredentials(access_key_id, secret_key), config); - } else { - client = New("client", config); - } -} - -void backends_kinesis_shutdown() { - Delete(client); - - ShutdownAPI(options); -} - -int backends_kinesis_put_record(const char *stream_name, const char *partition_key, - const char *data, size_t data_len) { - Kinesis::Model::PutRecordRequest request; - - request.SetStreamName(stream_name); - request.SetPartitionKey(partition_key); - request.SetData(Utils::ByteBuffer((unsigned char*) data, data_len)); - - request_outcomes.push_back({client->PutRecordCallable(request), data_len}); - - return 0; -} - -int backends_kinesis_get_result(char *error_message, size_t *sent_bytes, size_t *lost_bytes) { - Kinesis::Model::PutRecordOutcome outcome; - *sent_bytes = 0; - *lost_bytes = 0; - - for(auto request_outcome = request_outcomes.begin(); request_outcome != request_outcomes.end(); ) { - std::future_status status = request_outcome->future_outcome.wait_for(std::chrono::microseconds(100)); - - if(status == std::future_status::ready || status == std::future_status::deferred) { - outcome = request_outcome->future_outcome.get(); - *sent_bytes += request_outcome->data_len; - - if(!outcome.IsSuccess()) { - *lost_bytes += request_outcome->data_len; - outcome.GetError().GetMessage().copy(error_message, ERROR_LINE_MAX); - } - - request_outcomes.erase(request_outcome); - } else { - ++request_outcome; - } - } - - if(*lost_bytes) { - return 1; - } - - return 0; -} \ No newline at end of file diff --git a/backends/aws_kinesis/aws_kinesis_put_record.h b/backends/aws_kinesis/aws_kinesis_put_record.h deleted file mode 100644 index fa3d03459..000000000 --- a/backends/aws_kinesis/aws_kinesis_put_record.h +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -#ifndef NETDATA_BACKEND_KINESIS_PUT_RECORD_H -#define NETDATA_BACKEND_KINESIS_PUT_RECORD_H - -#define ERROR_LINE_MAX 1023 - -#ifdef __cplusplus -extern "C" { -#endif - -void backends_kinesis_init(const char *region, const char *access_key_id, const char *secret_key, const long timeout); - -void backends_kinesis_shutdown(); - -int backends_kinesis_put_record(const char *stream_name, const char *partition_key, - const char *data, size_t data_len); - -int backends_kinesis_get_result(char *error_message, size_t *sent_bytes, size_t *lost_bytes); - -#ifdef __cplusplus -} -#endif - -#endif //NETDATA_BACKEND_KINESIS_PUT_RECORD_H diff --git a/backends/backends.c b/backends/backends.c deleted file mode 100644 index dca21ef1c..000000000 --- a/backends/backends.c +++ /dev/null @@ -1,1247 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -#define BACKENDS_INTERNALS -#include "backends.h" - -// ---------------------------------------------------------------------------- -// How backends work in netdata: -// -// 1. There is an independent thread that runs at the required interval -// (for example, once every 10 seconds) -// -// 2. Every time it wakes, it calls the backend formatting functions to build -// a buffer of data. This is a very fast, memory only operation. -// -// 3. If the buffer already includes data, the new data are appended. -// If the buffer becomes too big, because the data cannot be sent, a -// log is written and the buffer is discarded. -// -// 4. Then it tries to send all the data. It blocks until all the data are sent -// or the socket returns an error. -// If the time required for this is above the interval, it starts skipping -// intervals, but the calculated values include the entire database, without -// gaps (it remembers the timestamps and continues from where it stopped). -// -// 5. repeats the above forever. -// - -const char *global_backend_prefix = "netdata"; -const char *global_backend_send_charts_matching = "*"; -int global_backend_update_every = 10; -BACKEND_OPTIONS global_backend_options = BACKEND_SOURCE_DATA_AVERAGE | BACKEND_OPTION_SEND_NAMES; -const char *global_backend_source = NULL; - -// ---------------------------------------------------------------------------- -// helper functions for backends - -size_t backend_name_copy(char *d, const char *s, size_t usable) { - size_t n; - - for(n = 0; *s && n < usable ; d++, s++, n++) { - char c = *s; - - if(c != '.' && !isalnum(c)) *d = '_'; - else *d = c; - } - *d = '\0'; - - return n; -} - -// calculate the SUM or AVERAGE of a dimension, for any timeframe -// may return NAN if the database does not have any value in the give timeframe - -calculated_number backend_calculate_value_from_stored_data( - RRDSET *st // the chart - , RRDDIM *rd // the dimension - , time_t after // the start timestamp - , time_t before // the end timestamp - , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap - , time_t *first_timestamp // the first point of the database used in this response - , time_t *last_timestamp // the timestamp that should be reported to backend -) { - RRDHOST *host = st->rrdhost; - (void)host; - - // find the edges of the rrd database for this chart - time_t first_t = rd->state->query_ops.oldest_time(rd); - time_t last_t = rd->state->query_ops.latest_time(rd); - time_t update_every = st->update_every; - struct rrddim_query_handle handle; - storage_number n; - - // step back a little, to make sure we have complete data collection - // for all metrics - after -= update_every * 2; - before -= update_every * 2; - - // align the time-frame - after = after - (after % update_every); - before = before - (before % update_every); - - // for before, loose another iteration - // the latest point will be reported the next time - before -= update_every; - - if(unlikely(after > before)) - // this can happen when update_every > before - after - after = before; - - if(unlikely(after < first_t)) - after = first_t; - - if(unlikely(before > last_t)) - before = last_t; - - if(unlikely(before < first_t || after > last_t)) { - // the chart has not been updated in the wanted timeframe - debug(D_BACKEND, "BACKEND: %s.%s.%s: aligned timeframe %lu to %lu is outside the chart's database range %lu to %lu", - host->hostname, st->id, rd->id, - (unsigned long)after, (unsigned long)before, - (unsigned long)first_t, (unsigned long)last_t - ); - return NAN; - } - - *first_timestamp = after; - *last_timestamp = before; - - size_t counter = 0; - calculated_number sum = 0; - -/* - long start_at_slot = rrdset_time2slot(st, before), - stop_at_slot = rrdset_time2slot(st, after), - slot, stop_now = 0; - - for(slot = start_at_slot; !stop_now ; slot--) { - - if(unlikely(slot < 0)) slot = st->entries - 1; - if(unlikely(slot == stop_at_slot)) stop_now = 1; - - storage_number n = rd->values[slot]; - - if(unlikely(!does_storage_number_exist(n))) { - // not collected - continue; - } - - calculated_number value = unpack_storage_number(n); - sum += value; - - counter++; - } -*/ - for(rd->state->query_ops.init(rd, &handle, after, before) ; !rd->state->query_ops.is_finished(&handle) ; ) { - time_t curr_t; - n = rd->state->query_ops.next_metric(&handle, &curr_t); - - if(unlikely(!does_storage_number_exist(n))) { - // not collected - continue; - } - - calculated_number value = unpack_storage_number(n); - sum += value; - - counter++; - } - rd->state->query_ops.finalize(&handle); - if(unlikely(!counter)) { - debug(D_BACKEND, "BACKEND: %s.%s.%s: no values stored in database for range %lu to %lu", - host->hostname, st->id, rd->id, - (unsigned long)after, (unsigned long)before - ); - return NAN; - } - - if(unlikely(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_SUM)) - return sum; - - return sum / (calculated_number)counter; -} - - -// discard a response received by a backend -// after logging a simple of it to error.log - -int discard_response(BUFFER *b, const char *backend) { - char sample[1024]; - const char *s = buffer_tostring(b); - char *d = sample, *e = &sample[sizeof(sample) - 1]; - - for(; *s && d < e ;s++) { - char c = *s; - if(unlikely(!isprint(c))) c = ' '; - *d++ = c; - } - *d = '\0'; - - info("BACKEND: received %zu bytes from %s backend. Ignoring them. Sample: '%s'", buffer_strlen(b), backend, sample); - buffer_flush(b); - return 0; -} - - -// ---------------------------------------------------------------------------- -// the backend thread - -static SIMPLE_PATTERN *charts_pattern = NULL; -static SIMPLE_PATTERN *hosts_pattern = NULL; - -inline int backends_can_send_rrdset(BACKEND_OPTIONS backend_options, RRDSET *st) { - RRDHOST *host = st->rrdhost; - (void)host; - - if(unlikely(rrdset_flag_check(st, RRDSET_FLAG_BACKEND_IGNORE))) - return 0; - - if(unlikely(!rrdset_flag_check(st, RRDSET_FLAG_BACKEND_SEND))) { - // we have not checked this chart - if(simple_pattern_matches(charts_pattern, st->id) || simple_pattern_matches(charts_pattern, st->name)) - rrdset_flag_set(st, RRDSET_FLAG_BACKEND_SEND); - else { - rrdset_flag_set(st, RRDSET_FLAG_BACKEND_IGNORE); - debug(D_BACKEND, "BACKEND: not sending chart '%s' of host '%s', because it is disabled for backends.", st->id, host->hostname); - return 0; - } - } - - if(unlikely(!rrdset_is_available_for_exporting_and_alarms(st))) { - debug(D_BACKEND, "BACKEND: not sending chart '%s' of host '%s', because it is not available for backends.", st->id, host->hostname); - return 0; - } - - if(unlikely(st->rrd_memory_mode == RRD_MEMORY_MODE_NONE && !(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED))) { - debug(D_BACKEND, "BACKEND: not sending chart '%s' of host '%s' because its memory mode is '%s' and the backend requires database access.", st->id, host->hostname, rrd_memory_mode_name(host->rrd_memory_mode)); - return 0; - } - - return 1; -} - -inline BACKEND_OPTIONS backend_parse_data_source(const char *source, BACKEND_OPTIONS backend_options) { - if(!strcmp(source, "raw") || !strcmp(source, "as collected") || !strcmp(source, "as-collected") || !strcmp(source, "as_collected") || !strcmp(source, "ascollected")) { - backend_options |= BACKEND_SOURCE_DATA_AS_COLLECTED; - backend_options &= ~(BACKEND_OPTIONS_SOURCE_BITS ^ BACKEND_SOURCE_DATA_AS_COLLECTED); - } - else if(!strcmp(source, "average")) { - backend_options |= BACKEND_SOURCE_DATA_AVERAGE; - backend_options &= ~(BACKEND_OPTIONS_SOURCE_BITS ^ BACKEND_SOURCE_DATA_AVERAGE); - } - else if(!strcmp(source, "sum") || !strcmp(source, "volume")) { - backend_options |= BACKEND_SOURCE_DATA_SUM; - backend_options &= ~(BACKEND_OPTIONS_SOURCE_BITS ^ BACKEND_SOURCE_DATA_SUM); - } - else { - error("BACKEND: invalid data source method '%s'.", source); - } - - return backend_options; -} - -static void backends_main_cleanup(void *ptr) { - struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr; - static_thread->enabled = NETDATA_MAIN_THREAD_EXITING; - - info("cleaning up..."); - - static_thread->enabled = NETDATA_MAIN_THREAD_EXITED; -} - -/** - * Set Kinesis variables - * - * Set the variables necessary to work with this specific backend. - * - * @param default_port the default port of the backend - * @param brc function called to check the result. - * @param brf function called to format the message to the backend - */ -void backend_set_kinesis_variables(int *default_port, - backend_response_checker_t brc, - backend_request_formatter_t brf) -{ - (void)default_port; -#ifndef HAVE_KINESIS - (void)brc; - (void)brf; -#endif - -#if HAVE_KINESIS - *brc = process_json_response; - if (BACKEND_OPTIONS_DATA_SOURCE(global_backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED) - *brf = backends_format_dimension_collected_json_plaintext; - else - *brf = backends_format_dimension_stored_json_plaintext; -#endif -} - -/** - * Set Prometheus variables - * - * Set the variables necessary to work with this specific backend. - * - * @param default_port the default port of the backend - * @param brc function called to check the result. - * @param brf function called to format the message to the backend - */ -void backend_set_prometheus_variables(int *default_port, - backend_response_checker_t brc, - backend_request_formatter_t brf) -{ - (void)default_port; - (void)brf; -#ifndef ENABLE_PROMETHEUS_REMOTE_WRITE - (void)brc; -#endif - -#if ENABLE_PROMETHEUS_REMOTE_WRITE - *brc = backends_process_prometheus_remote_write_response; -#endif /* ENABLE_PROMETHEUS_REMOTE_WRITE */ -} - -/** - * Set MongoDB variables - * - * Set the variables necessary to work with this specific backend. - * - * @param default_port the default port of the backend - * @param brc function called to check the result. - * @param brf function called to format the message to the backend - */ -void backend_set_mongodb_variables(int *default_port, - backend_response_checker_t brc, - backend_request_formatter_t brf) -{ - (void)default_port; -#ifndef HAVE_MONGOC - (void)brc; - (void)brf; -#endif - -#if HAVE_MONGOC - *brc = process_json_response; - if(BACKEND_OPTIONS_DATA_SOURCE(global_backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED) - *brf = backends_format_dimension_collected_json_plaintext; - else - *brf = backends_format_dimension_stored_json_plaintext; -#endif -} - -/** - * Set JSON variables - * - * Set the variables necessary to work with this specific backend. - * - * @param default_port the default port of the backend - * @param brc function called to check the result. - * @param brf function called to format the message to the backend - */ -void backend_set_json_variables(int *default_port, - backend_response_checker_t brc, - backend_request_formatter_t brf) -{ - *default_port = 5448; - *brc = process_json_response; - - if (BACKEND_OPTIONS_DATA_SOURCE(global_backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED) - *brf = backends_format_dimension_collected_json_plaintext; - else - *brf = backends_format_dimension_stored_json_plaintext; -} - -/** - * Set OpenTSDB HTTP variables - * - * Set the variables necessary to work with this specific backend. - * - * @param default_port the default port of the backend - * @param brc function called to check the result. - * @param brf function called to format the message to the backend - */ -void backend_set_opentsdb_http_variables(int *default_port, - backend_response_checker_t brc, - backend_request_formatter_t brf) -{ - *default_port = 4242; - *brc = process_opentsdb_response; - - if(BACKEND_OPTIONS_DATA_SOURCE(global_backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED) - *brf = backends_format_dimension_collected_opentsdb_http; - else - *brf = backends_format_dimension_stored_opentsdb_http; - -} - -/** - * Set OpenTSDB Telnet variables - * - * Set the variables necessary to work with this specific backend. - * - * @param default_port the default port of the backend - * @param brc function called to check the result. - * @param brf function called to format the message to the backend - */ -void backend_set_opentsdb_telnet_variables(int *default_port, - backend_response_checker_t brc, - backend_request_formatter_t brf) -{ - *default_port = 4242; - *brc = process_opentsdb_response; - - if(BACKEND_OPTIONS_DATA_SOURCE(global_backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED) - *brf = backends_format_dimension_collected_opentsdb_telnet; - else - *brf = backends_format_dimension_stored_opentsdb_telnet; -} - -/** - * Set Graphite variables - * - * Set the variables necessary to work with this specific backend. - * - * @param default_port the default port of the backend - * @param brc function called to check the result. - * @param brf function called to format the message to the backend - */ -void backend_set_graphite_variables(int *default_port, - backend_response_checker_t brc, - backend_request_formatter_t brf) -{ - *default_port = 2003; - *brc = process_graphite_response; - - if(BACKEND_OPTIONS_DATA_SOURCE(global_backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED) - *brf = backends_format_dimension_collected_graphite_plaintext; - else - *brf = backends_format_dimension_stored_graphite_plaintext; -} - -/** - * Select Type - * - * Select the backend type based in the user input - * - * @param type is the string that defines the backend type - * - * @return It returns the backend id. - */ -BACKEND_TYPE backend_select_type(const char *type) { - if(!strcmp(type, "graphite") || !strcmp(type, "graphite:plaintext")) { - return BACKEND_TYPE_GRAPHITE; - } - else if(!strcmp(type, "opentsdb") || !strcmp(type, "opentsdb:telnet")) { - return BACKEND_TYPE_OPENTSDB_USING_TELNET; - } - else if(!strcmp(type, "opentsdb:http") || !strcmp(type, "opentsdb:https")) { - return BACKEND_TYPE_OPENTSDB_USING_HTTP; - } - else if (!strcmp(type, "json") || !strcmp(type, "json:plaintext")) { - return BACKEND_TYPE_JSON; - } - else if (!strcmp(type, "prometheus_remote_write")) { - return BACKEND_TYPE_PROMETHEUS_REMOTE_WRITE; - } - else if (!strcmp(type, "kinesis") || !strcmp(type, "kinesis:plaintext")) { - return BACKEND_TYPE_KINESIS; - } - else if (!strcmp(type, "mongodb") || !strcmp(type, "mongodb:plaintext")) { - return BACKEND_TYPE_MONGODB; - } - - return BACKEND_TYPE_UNKNOWN; -} - -/** - * Backend main - * - * The main thread used to control the backends. - * - * @param ptr a pointer to netdata_static_structure. - * - * @return It always return NULL. - */ -void *backends_main(void *ptr) { - netdata_thread_cleanup_push(backends_main_cleanup, ptr); - - int default_port = 0; - int sock = -1; - BUFFER *b = buffer_create(1), *response = buffer_create(1); - int (*backend_request_formatter)(BUFFER *, const char *, RRDHOST *, const char *, RRDSET *, RRDDIM *, time_t, time_t, BACKEND_OPTIONS) = NULL; - int (*backend_response_checker)(BUFFER *) = NULL; - -#if HAVE_KINESIS - int do_kinesis = 0; - char *kinesis_auth_key_id = NULL, *kinesis_secure_key = NULL, *kinesis_stream_name = NULL; -#endif - -#if ENABLE_PROMETHEUS_REMOTE_WRITE - int do_prometheus_remote_write = 0; - BUFFER *http_request_header = NULL; -#endif - -#if HAVE_MONGOC - int do_mongodb = 0; - char *mongodb_uri = NULL; - char *mongodb_database = NULL; - char *mongodb_collection = NULL; - - // set the default socket timeout in ms - int32_t mongodb_default_socket_timeout = (int32_t)(global_backend_update_every >= 2)?(global_backend_update_every * MSEC_PER_SEC - 500):1000; - -#endif - -#ifdef ENABLE_HTTPS - struct netdata_ssl opentsdb_ssl = {NULL , NETDATA_SSL_START}; -#endif - - // ------------------------------------------------------------------------ - // collect configuration options - - struct timeval timeout = { - .tv_sec = 0, - .tv_usec = 0 - }; - int enabled = config_get_boolean(CONFIG_SECTION_BACKEND, "enabled", 0); - const char *source = config_get(CONFIG_SECTION_BACKEND, "data source", "average"); - const char *type = config_get(CONFIG_SECTION_BACKEND, "type", "graphite"); - const char *destination = config_get(CONFIG_SECTION_BACKEND, "destination", "localhost"); - global_backend_prefix = config_get(CONFIG_SECTION_BACKEND, "prefix", "netdata"); - const char *hostname = config_get(CONFIG_SECTION_BACKEND, "hostname", localhost->hostname); - global_backend_update_every = (int)config_get_number(CONFIG_SECTION_BACKEND, "update every", global_backend_update_every); - int buffer_on_failures = (int)config_get_number(CONFIG_SECTION_BACKEND, "buffer on failures", 10); - long timeoutms = config_get_number(CONFIG_SECTION_BACKEND, "timeout ms", global_backend_update_every * 2 * 1000); - - if(config_get_boolean(CONFIG_SECTION_BACKEND, "send names instead of ids", (global_backend_options & BACKEND_OPTION_SEND_NAMES))) - global_backend_options |= BACKEND_OPTION_SEND_NAMES; - else - global_backend_options &= ~BACKEND_OPTION_SEND_NAMES; - - charts_pattern = simple_pattern_create( - global_backend_send_charts_matching = config_get(CONFIG_SECTION_BACKEND, "send charts matching", "*"), - NULL, - SIMPLE_PATTERN_EXACT); - hosts_pattern = simple_pattern_create(config_get(CONFIG_SECTION_BACKEND, "send hosts matching", "localhost *"), NULL, SIMPLE_PATTERN_EXACT); - -#if ENABLE_PROMETHEUS_REMOTE_WRITE - const char *remote_write_path = config_get(CONFIG_SECTION_BACKEND, "remote write URL path", "/receive"); -#endif - - // ------------------------------------------------------------------------ - // validate configuration options - // and prepare for sending data to our backend - - global_backend_options = backend_parse_data_source(source, global_backend_options); - global_backend_source = source; - - if(timeoutms < 1) { - error("BACKEND: invalid timeout %ld ms given. Assuming %d ms.", timeoutms, global_backend_update_every * 2 * 1000); - timeoutms = global_backend_update_every * 2 * 1000; - } - timeout.tv_sec = (timeoutms * 1000) / 1000000; - timeout.tv_usec = (timeoutms * 1000) % 1000000; - - if(!enabled || global_backend_update_every < 1) - goto cleanup; - - // ------------------------------------------------------------------------ - // select the backend type - BACKEND_TYPE work_type = backend_select_type(type); - if (work_type == BACKEND_TYPE_UNKNOWN) { - error("BACKEND: Unknown backend type '%s'", type); - goto cleanup; - } - - switch (work_type) { - case BACKEND_TYPE_OPENTSDB_USING_HTTP: { -#ifdef ENABLE_HTTPS - if (!strcmp(type, "opentsdb:https")) { - security_start_ssl(NETDATA_SSL_CONTEXT_EXPORTING); - } -#endif - backend_set_opentsdb_http_variables(&default_port,&backend_response_checker,&backend_request_formatter); - break; - } - case BACKEND_TYPE_PROMETHEUS_REMOTE_WRITE: { -#if ENABLE_PROMETHEUS_REMOTE_WRITE - do_prometheus_remote_write = 1; - - http_request_header = buffer_create(1); - backends_init_write_request(); -#else - error("BACKEND: Prometheus remote write support isn't compiled"); -#endif // ENABLE_PROMETHEUS_REMOTE_WRITE - backend_set_prometheus_variables(&default_port,&backend_response_checker,&backend_request_formatter); - break; - } - case BACKEND_TYPE_KINESIS: { -#if HAVE_KINESIS - do_kinesis = 1; - - if(unlikely(read_kinesis_conf(netdata_configured_user_config_dir, &kinesis_auth_key_id, &kinesis_secure_key, &kinesis_stream_name))) { - error("BACKEND: kinesis backend type is set but cannot read its configuration from %s/aws_kinesis.conf", netdata_configured_user_config_dir); - goto cleanup; - } - - backends_kinesis_init(destination, kinesis_auth_key_id, kinesis_secure_key, timeout.tv_sec * 1000 + timeout.tv_usec / 1000); -#else - error("BACKEND: AWS Kinesis support isn't compiled"); -#endif // HAVE_KINESIS - backend_set_kinesis_variables(&default_port,&backend_response_checker,&backend_request_formatter); - break; - } - case BACKEND_TYPE_MONGODB: { -#if HAVE_MONGOC - if(unlikely(read_mongodb_conf(netdata_configured_user_config_dir, - &mongodb_uri, - &mongodb_database, - &mongodb_collection))) { - error("BACKEND: mongodb backend type is set but cannot read its configuration from %s/mongodb.conf", - netdata_configured_user_config_dir); - goto cleanup; - } - - if(likely(!backends_mongodb_init(mongodb_uri, mongodb_database, mongodb_collection, mongodb_default_socket_timeout))) { - backend_set_mongodb_variables(&default_port, &backend_response_checker, &backend_request_formatter); - do_mongodb = 1; - } - else { - error("BACKEND: cannot initialize MongoDB backend"); - goto cleanup; - } -#else - error("BACKEND: MongoDB support isn't compiled"); -#endif // HAVE_MONGOC - break; - } - case BACKEND_TYPE_GRAPHITE: { - backend_set_graphite_variables(&default_port,&backend_response_checker,&backend_request_formatter); - break; - } - case BACKEND_TYPE_OPENTSDB_USING_TELNET: { - backend_set_opentsdb_telnet_variables(&default_port,&backend_response_checker,&backend_request_formatter); - break; - } - case BACKEND_TYPE_JSON: { - backend_set_json_variables(&default_port,&backend_response_checker,&backend_request_formatter); - break; - } - case BACKEND_TYPE_UNKNOWN: { - break; - } - default: { - break; - } - } - -#if ENABLE_PROMETHEUS_REMOTE_WRITE - if((backend_request_formatter == NULL && !do_prometheus_remote_write) || backend_response_checker == NULL) { -#else - if(backend_request_formatter == NULL || backend_response_checker == NULL) { -#endif - error("BACKEND: backend is misconfigured - disabling it."); - goto cleanup; - } - - -// ------------------------------------------------------------------------ -// prepare the charts for monitoring the backend operation - - struct rusage thread; - - collected_number - chart_buffered_metrics = 0, - chart_lost_metrics = 0, - chart_sent_metrics = 0, - chart_buffered_bytes = 0, - chart_received_bytes = 0, - chart_sent_bytes = 0, - chart_receptions = 0, - chart_transmission_successes = 0, - chart_transmission_failures = 0, - chart_data_lost_events = 0, - chart_lost_bytes = 0, - chart_backend_reconnects = 0; - // chart_backend_latency = 0; - - RRDSET *chart_metrics = rrdset_create_localhost("netdata", "backend_metrics", NULL, "backend", NULL, "Netdata Buffered Metrics", "metrics", "backends", NULL, 130600, global_backend_update_every, RRDSET_TYPE_LINE); - rrddim_add(chart_metrics, "buffered", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); - rrddim_add(chart_metrics, "lost", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); - rrddim_add(chart_metrics, "sent", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); - - RRDSET *chart_bytes = rrdset_create_localhost("netdata", "backend_bytes", NULL, "backend", NULL, "Netdata Backend Data Size", "KiB", "backends", NULL, 130610, global_backend_update_every, RRDSET_TYPE_AREA); - rrddim_add(chart_bytes, "buffered", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE); - rrddim_add(chart_bytes, "lost", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE); - rrddim_add(chart_bytes, "sent", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE); - rrddim_add(chart_bytes, "received", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE); - - RRDSET *chart_ops = rrdset_create_localhost("netdata", "backend_ops", NULL, "backend", NULL, "Netdata Backend Operations", "operations", "backends", NULL, 130630, global_backend_update_every, RRDSET_TYPE_LINE); - rrddim_add(chart_ops, "write", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); - rrddim_add(chart_ops, "discard", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); - rrddim_add(chart_ops, "reconnect", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); - rrddim_add(chart_ops, "failure", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); - rrddim_add(chart_ops, "read", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); - - /* - * this is misleading - we can only measure the time we need to send data - * this time is not related to the time required for the data to travel to - * the backend database and the time that server needed to process them - * - * issue #1432 and https://www.softlab.ntua.gr/facilities/documentation/unix/unix-socket-faq/unix-socket-faq-2.html - * - RRDSET *chart_latency = rrdset_create_localhost("netdata", "backend_latency", NULL, "backend", NULL, "Netdata Backend Latency", "ms", "backends", NULL, 130620, global_backend_update_every, RRDSET_TYPE_AREA); - rrddim_add(chart_latency, "latency", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE); - */ - - RRDSET *chart_rusage = rrdset_create_localhost("netdata", "backend_thread_cpu", NULL, "backend", NULL, "Netdata Backend Thread CPU usage", "milliseconds/s", "backends", NULL, 130630, global_backend_update_every, RRDSET_TYPE_STACKED); - rrddim_add(chart_rusage, "user", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL); - rrddim_add(chart_rusage, "system", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL); - - - // ------------------------------------------------------------------------ - // prepare the backend main loop - - info("BACKEND: configured ('%s' on '%s' sending '%s' data, every %d seconds, as host '%s', with prefix '%s')", type, destination, source, global_backend_update_every, hostname, global_backend_prefix); - send_statistics("BACKEND_START", "OK", type); - - usec_t step_ut = global_backend_update_every * USEC_PER_SEC; - time_t after = now_realtime_sec(); - int failures = 0; - heartbeat_t hb; - heartbeat_init(&hb); - - while(!netdata_exit) { - - // ------------------------------------------------------------------------ - // Wait for the next iteration point. - - heartbeat_next(&hb, step_ut); - time_t before = now_realtime_sec(); - debug(D_BACKEND, "BACKEND: preparing buffer for timeframe %lu to %lu", (unsigned long)after, (unsigned long)before); - - // ------------------------------------------------------------------------ - // add to the buffer the data we need to send to the backend - - netdata_thread_disable_cancelability(); - - size_t count_hosts = 0; - size_t count_charts_total = 0; - size_t count_dims_total = 0; - -#if ENABLE_PROMETHEUS_REMOTE_WRITE - if(do_prometheus_remote_write) - backends_clear_write_request(); -#endif - rrd_rdlock(); - RRDHOST *host; - rrdhost_foreach_read(host) { - if(unlikely(!rrdhost_flag_check(host, RRDHOST_FLAG_BACKEND_SEND|RRDHOST_FLAG_BACKEND_DONT_SEND))) { - char *name = (host == localhost)?"localhost":host->hostname; - if (!hosts_pattern || simple_pattern_matches(hosts_pattern, name)) { - rrdhost_flag_set(host, RRDHOST_FLAG_BACKEND_SEND); - info("enabled backend for host '%s'", name); - } - else { - rrdhost_flag_set(host, RRDHOST_FLAG_BACKEND_DONT_SEND); - info("disabled backend for host '%s'", name); - } - } - - if(unlikely(!rrdhost_flag_check(host, RRDHOST_FLAG_BACKEND_SEND))) - continue; - - rrdhost_rdlock(host); - - count_hosts++; - size_t count_charts = 0; - size_t count_dims = 0; - size_t count_dims_skipped = 0; - - const char *__hostname = (host == localhost)?hostname:host->hostname; - -#if ENABLE_PROMETHEUS_REMOTE_WRITE - if(do_prometheus_remote_write) { - backends_rrd_stats_remote_write_allmetrics_prometheus( - host - , __hostname - , global_backend_prefix - , global_backend_options - , after - , before - , &count_charts - , &count_dims - , &count_dims_skipped - ); - chart_buffered_metrics += count_dims; - } - else -#endif - { - RRDSET *st; - rrdset_foreach_read(st, host) { - if(likely(backends_can_send_rrdset(global_backend_options, st))) { - rrdset_rdlock(st); - - count_charts++; - - RRDDIM *rd; - rrddim_foreach_read(rd, st) { - if (likely(rd->last_collected_time.tv_sec >= after)) { - chart_buffered_metrics += backend_request_formatter(b, global_backend_prefix, host, __hostname, st, rd, after, before, global_backend_options); - count_dims++; - } - else { - debug(D_BACKEND, "BACKEND: not sending dimension '%s' of chart '%s' from host '%s', its last data collection (%lu) is not within our timeframe (%lu to %lu)", rd->id, st->id, __hostname, (unsigned long)rd->last_collected_time.tv_sec, (unsigned long)after, (unsigned long)before); - count_dims_skipped++; - } - } - - rrdset_unlock(st); - } - } - } - - debug(D_BACKEND, "BACKEND: sending host '%s', metrics of %zu dimensions, of %zu charts. Skipped %zu dimensions.", __hostname, count_dims, count_charts, count_dims_skipped); - count_charts_total += count_charts; - count_dims_total += count_dims; - - rrdhost_unlock(host); - } - rrd_unlock(); - - netdata_thread_enable_cancelability(); - - debug(D_BACKEND, "BACKEND: buffer has %zu bytes, added metrics for %zu dimensions, of %zu charts, from %zu hosts", buffer_strlen(b), count_dims_total, count_charts_total, count_hosts); - - // ------------------------------------------------------------------------ - - chart_buffered_bytes = (collected_number)buffer_strlen(b); - - // reset the monitoring chart counters - chart_received_bytes = - chart_sent_bytes = - chart_sent_metrics = - chart_lost_metrics = - chart_receptions = - chart_transmission_successes = - chart_transmission_failures = - chart_data_lost_events = - chart_lost_bytes = - chart_backend_reconnects = 0; - // chart_backend_latency = 0; - - if(unlikely(netdata_exit)) break; - - //fprintf(stderr, "\nBACKEND BEGIN:\n%s\nBACKEND END\n", buffer_tostring(b)); - //fprintf(stderr, "after = %lu, before = %lu\n", after, before); - - // prepare for the next iteration - // to add incrementally data to buffer - after = before; - -#if HAVE_KINESIS - if(do_kinesis) { - unsigned long long partition_key_seq = 0; - - size_t buffer_len = buffer_strlen(b); - size_t sent = 0; - - while(sent < buffer_len) { - char partition_key[KINESIS_PARTITION_KEY_MAX + 1]; - snprintf(partition_key, KINESIS_PARTITION_KEY_MAX, "netdata_%llu", partition_key_seq++); - size_t partition_key_len = strnlen(partition_key, KINESIS_PARTITION_KEY_MAX); - - const char *first_char = buffer_tostring(b) + sent; - - size_t record_len = 0; - - // split buffer into chunks of maximum allowed size - if(buffer_len - sent < KINESIS_RECORD_MAX - partition_key_len) { - record_len = buffer_len - sent; - } - else { - record_len = KINESIS_RECORD_MAX - partition_key_len; - while(*(first_char + record_len) != '\n' && record_len) record_len--; - } - - char error_message[ERROR_LINE_MAX + 1] = ""; - - debug(D_BACKEND, "BACKEND: backends_kinesis_put_record(): dest = %s, id = %s, key = %s, stream = %s, partition_key = %s, \ - buffer = %zu, record = %zu", destination, kinesis_auth_key_id, kinesis_secure_key, kinesis_stream_name, - partition_key, buffer_len, record_len); - - backends_kinesis_put_record(kinesis_stream_name, partition_key, first_char, record_len); - - sent += record_len; - chart_transmission_successes++; - - size_t sent_bytes = 0, lost_bytes = 0; - - if(unlikely(backends_kinesis_get_result(error_message, &sent_bytes, &lost_bytes))) { - // oops! we couldn't send (all or some of the) data - error("BACKEND: %s", error_message); - error("BACKEND: failed to write data to database backend '%s'. Willing to write %zu bytes, wrote %zu bytes.", - destination, sent_bytes, sent_bytes - lost_bytes); - - chart_transmission_failures++; - chart_data_lost_events++; - chart_lost_bytes += lost_bytes; - - // estimate the number of lost metrics - chart_lost_metrics += (collected_number)(chart_buffered_metrics - * (buffer_len && (lost_bytes > buffer_len) ? (double)lost_bytes / buffer_len : 1)); - - break; - } - else { - chart_receptions++; - } - - if(unlikely(netdata_exit)) break; - } - - chart_sent_bytes += sent; - if(likely(sent == buffer_len)) - chart_sent_metrics = chart_buffered_metrics; - - buffer_flush(b); - } else -#endif /* HAVE_KINESIS */ - -#if HAVE_MONGOC - if(do_mongodb) { - size_t buffer_len = buffer_strlen(b); - size_t sent = 0; - - while(sent < buffer_len) { - const char *first_char = buffer_tostring(b); - - debug(D_BACKEND, "BACKEND: backends_mongodb_insert(): uri = %s, database = %s, collection = %s, \ - buffer = %zu", mongodb_uri, mongodb_database, mongodb_collection, buffer_len); - - if(likely(!backends_mongodb_insert((char *)first_char, (size_t)chart_buffered_metrics))) { - sent += buffer_len; - chart_transmission_successes++; - chart_receptions++; - } - else { - // oops! we couldn't send (all or some of the) data - error("BACKEND: failed to write data to database backend '%s'. Willing to write %zu bytes, wrote %zu bytes.", - mongodb_uri, buffer_len, 0UL); - - chart_transmission_failures++; - chart_data_lost_events++; - chart_lost_bytes += buffer_len; - - // estimate the number of lost metrics - chart_lost_metrics += (collected_number)chart_buffered_metrics; - - break; - } - - if(unlikely(netdata_exit)) break; - } - - chart_sent_bytes += sent; - if(likely(sent == buffer_len)) - chart_sent_metrics = chart_buffered_metrics; - - buffer_flush(b); - } else -#endif /* HAVE_MONGOC */ - - { - - // ------------------------------------------------------------------------ - // if we are connected, receive a response, without blocking - - if(likely(sock != -1)) { - errno = 0; - - // loop through to collect all data - while(sock != -1 && errno != EWOULDBLOCK) { - buffer_need_bytes(response, 4096); - - ssize_t r; -#ifdef ENABLE_HTTPS - if(opentsdb_ssl.conn && !opentsdb_ssl.flags) { - r = SSL_read(opentsdb_ssl.conn, &response->buffer[response->len], response->size - response->len); - } else { - r = recv(sock, &response->buffer[response->len], response->size - response->len, MSG_DONTWAIT); - } -#else - r = recv(sock, &response->buffer[response->len], response->size - response->len, MSG_DONTWAIT); -#endif - if(likely(r > 0)) { - // we received some data - response->len += r; - chart_received_bytes += r; - chart_receptions++; - } - else if(r == 0) { - error("BACKEND: '%s' closed the socket", destination); - close(sock); - sock = -1; - } - else { - // failed to receive data - if(errno != EAGAIN && errno != EWOULDBLOCK) { - error("BACKEND: cannot receive data from backend '%s'.", destination); - } - } - } - - // if we received data, process them - if(buffer_strlen(response)) - backend_response_checker(response); - } - - // ------------------------------------------------------------------------ - // if we are not connected, connect to a backend server - - if(unlikely(sock == -1)) { - // usec_t start_ut = now_monotonic_usec(); - size_t reconnects = 0; - - sock = connect_to_one_of(destination, default_port, &timeout, &reconnects, NULL, 0); -#ifdef ENABLE_HTTPS - if(sock != -1) { - if(netdata_exporting_ctx) { - if(!opentsdb_ssl.conn) { - opentsdb_ssl.conn = SSL_new(netdata_exporting_ctx); - if(!opentsdb_ssl.conn) { - error("Failed to allocate SSL structure %d.", sock); - opentsdb_ssl.flags = NETDATA_SSL_NO_HANDSHAKE; - } - } else { - SSL_clear(opentsdb_ssl.conn); - } - } - - if(opentsdb_ssl.conn) { - if(SSL_set_fd(opentsdb_ssl.conn, sock) != 1) { - error("Failed to set the socket to the SSL on socket fd %d.", host->rrdpush_sender_socket); - opentsdb_ssl.flags = NETDATA_SSL_NO_HANDSHAKE; - } else { - opentsdb_ssl.flags = NETDATA_SSL_HANDSHAKE_COMPLETE; - SSL_set_connect_state(opentsdb_ssl.conn); - int err = SSL_connect(opentsdb_ssl.conn); - if (err != 1) { - err = SSL_get_error(opentsdb_ssl.conn, err); - error("SSL cannot connect with the server: %s ", ERR_error_string((long)SSL_get_error(opentsdb_ssl.conn, err), NULL)); - opentsdb_ssl.flags = NETDATA_SSL_NO_HANDSHAKE; - } //TODO: check certificate here - } - } - } -#endif - chart_backend_reconnects += reconnects; - // chart_backend_latency += now_monotonic_usec() - start_ut; - } - - if(unlikely(netdata_exit)) break; - - // ------------------------------------------------------------------------ - // if we are connected, send our buffer to the backend server - - if(likely(sock != -1)) { - size_t len = buffer_strlen(b); - // usec_t start_ut = now_monotonic_usec(); - int flags = 0; - #ifdef MSG_NOSIGNAL - flags += MSG_NOSIGNAL; - #endif - -#if ENABLE_PROMETHEUS_REMOTE_WRITE - if(do_prometheus_remote_write) { - size_t data_size = backends_get_write_request_size(); - - if(unlikely(!data_size)) { - error("BACKEND: write request size is out of range"); - continue; - } - - buffer_flush(b); - buffer_need_bytes(b, data_size); - if(unlikely(backends_pack_write_request(b->buffer, &data_size))) { - error("BACKEND: cannot pack write request"); - continue; - } - b->len = data_size; - chart_buffered_bytes = (collected_number)buffer_strlen(b); - - buffer_flush(http_request_header); - buffer_sprintf(http_request_header, - "POST %s HTTP/1.1\r\n" - "Host: %s\r\n" - "Accept: */*\r\n" - "Content-Length: %zu\r\n" - "Content-Type: application/x-www-form-urlencoded\r\n\r\n", - remote_write_path, - destination, - data_size - ); - - len = buffer_strlen(http_request_header); - send(sock, buffer_tostring(http_request_header), len, flags); - - len = data_size; - } -#endif - - ssize_t written; -#ifdef ENABLE_HTTPS - if(opentsdb_ssl.conn && !opentsdb_ssl.flags) { - written = SSL_write(opentsdb_ssl.conn, buffer_tostring(b), len); - } else { - written = send(sock, buffer_tostring(b), len, flags); - } -#else - written = send(sock, buffer_tostring(b), len, flags); -#endif - - // chart_backend_latency += now_monotonic_usec() - start_ut; - if(written != -1 && (size_t)written == len) { - // we sent the data successfully - chart_transmission_successes++; - chart_sent_bytes += written; - chart_sent_metrics = chart_buffered_metrics; - - // reset the failures count - failures = 0; - - // empty the buffer - buffer_flush(b); - } - else { - // oops! we couldn't send (all or some of the) data - error("BACKEND: failed to write data to database backend '%s'. Willing to write %zu bytes, wrote %zd bytes. Will re-connect.", destination, len, written); - chart_transmission_failures++; - - if(written != -1) - chart_sent_bytes += written; - - // increment the counter we check for data loss - failures++; - - // close the socket - we will re-open it next time - close(sock); - sock = -1; - } - } - else { - error("BACKEND: failed to update database backend '%s'", destination); - chart_transmission_failures++; - - // increment the counter we check for data loss - failures++; - } - } - - -#if ENABLE_PROMETHEUS_REMOTE_WRITE - if(do_prometheus_remote_write && failures) { - (void) buffer_on_failures; - failures = 0; - chart_lost_bytes = chart_buffered_bytes = backends_get_write_request_size(); // estimated write request size - chart_data_lost_events++; - chart_lost_metrics = chart_buffered_metrics; - } else -#endif - if(failures > buffer_on_failures) { - // too bad! we are going to lose data - chart_lost_bytes += buffer_strlen(b); - error("BACKEND: reached %d backend failures. Flushing buffers to protect this host - this results in data loss on back-end server '%s'", failures, destination); - buffer_flush(b); - failures = 0; - chart_data_lost_events++; - chart_lost_metrics = chart_buffered_metrics; - } - - if(unlikely(netdata_exit)) break; - - // ------------------------------------------------------------------------ - // update the monitoring charts - - if(likely(chart_ops->counter_done)) rrdset_next(chart_ops); - rrddim_set(chart_ops, "read", chart_receptions); - rrddim_set(chart_ops, "write", chart_transmission_successes); - rrddim_set(chart_ops, "discard", chart_data_lost_events); - rrddim_set(chart_ops, "failure", chart_transmission_failures); - rrddim_set(chart_ops, "reconnect", chart_backend_reconnects); - rrdset_done(chart_ops); - - if(likely(chart_metrics->counter_done)) rrdset_next(chart_metrics); - rrddim_set(chart_metrics, "buffered", chart_buffered_metrics); - rrddim_set(chart_metrics, "lost", chart_lost_metrics); - rrddim_set(chart_metrics, "sent", chart_sent_metrics); - rrdset_done(chart_metrics); - - if(likely(chart_bytes->counter_done)) rrdset_next(chart_bytes); - rrddim_set(chart_bytes, "buffered", chart_buffered_bytes); - rrddim_set(chart_bytes, "lost", chart_lost_bytes); - rrddim_set(chart_bytes, "sent", chart_sent_bytes); - rrddim_set(chart_bytes, "received", chart_received_bytes); - rrdset_done(chart_bytes); - - /* - if(likely(chart_latency->counter_done)) rrdset_next(chart_latency); - rrddim_set(chart_latency, "latency", chart_backend_latency); - rrdset_done(chart_latency); - */ - - getrusage(RUSAGE_THREAD, &thread); - if(likely(chart_rusage->counter_done)) rrdset_next(chart_rusage); - rrddim_set(chart_rusage, "user", thread.ru_utime.tv_sec * 1000000ULL + thread.ru_utime.tv_usec); - rrddim_set(chart_rusage, "system", thread.ru_stime.tv_sec * 1000000ULL + thread.ru_stime.tv_usec); - rrdset_done(chart_rusage); - - if(likely(buffer_strlen(b) == 0)) - chart_buffered_metrics = 0; - - if(unlikely(netdata_exit)) break; - } - -cleanup: -#if HAVE_KINESIS - if(do_kinesis) { - backends_kinesis_shutdown(); - freez(kinesis_auth_key_id); - freez(kinesis_secure_key); - freez(kinesis_stream_name); - } -#endif - -#if ENABLE_PROMETHEUS_REMOTE_WRITE - buffer_free(http_request_header); - if(do_prometheus_remote_write) - backends_protocol_buffers_shutdown(); -#endif - -#if HAVE_MONGOC - if(do_mongodb) { - backends_mongodb_cleanup(); - freez(mongodb_uri); - freez(mongodb_database); - freez(mongodb_collection); - } -#endif - - if(sock != -1) - close(sock); - - buffer_free(b); - buffer_free(response); - -#ifdef ENABLE_HTTPS - if(netdata_exporting_ctx) { - if(opentsdb_ssl.conn) { - SSL_free(opentsdb_ssl.conn); - } - } -#endif - - netdata_thread_cleanup_pop(1); - return NULL; -} diff --git a/backends/backends.h b/backends/backends.h deleted file mode 100644 index 77c58c9e4..000000000 --- a/backends/backends.h +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -#ifndef NETDATA_BACKENDS_H -#define NETDATA_BACKENDS_H 1 - -#include "daemon/common.h" - -typedef enum backend_options { - BACKEND_OPTION_NONE = 0, - - BACKEND_SOURCE_DATA_AS_COLLECTED = (1 << 0), - BACKEND_SOURCE_DATA_AVERAGE = (1 << 1), - BACKEND_SOURCE_DATA_SUM = (1 << 2), - - BACKEND_OPTION_SEND_NAMES = (1 << 16) -} BACKEND_OPTIONS; - -typedef enum backend_types { - BACKEND_TYPE_UNKNOWN, // Invalid type - BACKEND_TYPE_GRAPHITE, // Send plain text to Graphite - BACKEND_TYPE_OPENTSDB_USING_TELNET, // Send data to OpenTSDB using telnet API - BACKEND_TYPE_OPENTSDB_USING_HTTP, // Send data to OpenTSDB using HTTP API - BACKEND_TYPE_JSON, // Stores the data using JSON. - BACKEND_TYPE_PROMETHEUS_REMOTE_WRITE, // The user selected to use Prometheus backend - BACKEND_TYPE_KINESIS, // Send message to AWS Kinesis - BACKEND_TYPE_MONGODB, // Send data to MongoDB collection - BACKEND_TYPE_NUM // Number of backend types -} BACKEND_TYPE; - -typedef int (**backend_response_checker_t)(BUFFER *); -typedef int (**backend_request_formatter_t)(BUFFER *, const char *, RRDHOST *, const char *, RRDSET *, RRDDIM *, time_t, time_t, BACKEND_OPTIONS); - -#define BACKEND_OPTIONS_SOURCE_BITS (BACKEND_SOURCE_DATA_AS_COLLECTED|BACKEND_SOURCE_DATA_AVERAGE|BACKEND_SOURCE_DATA_SUM) -#define BACKEND_OPTIONS_DATA_SOURCE(backend_options) (backend_options & BACKEND_OPTIONS_SOURCE_BITS) - -extern int global_backend_update_every; -extern BACKEND_OPTIONS global_backend_options; -extern const char *global_backend_source; -extern const char *global_backend_prefix; -extern const char *global_backend_send_charts_matching; - -extern void *backends_main(void *ptr); -BACKEND_TYPE backend_select_type(const char *type); - -extern BACKEND_OPTIONS backend_parse_data_source(const char *source, BACKEND_OPTIONS backend_options); - -#ifdef BACKENDS_INTERNALS - -extern int backends_can_send_rrdset(BACKEND_OPTIONS backend_options, RRDSET *st); -extern calculated_number backend_calculate_value_from_stored_data( - RRDSET *st // the chart - , RRDDIM *rd // the dimension - , time_t after // the start timestamp - , time_t before // the end timestamp - , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap - , time_t *first_timestamp // the timestamp of the first point used in this response - , time_t *last_timestamp // the timestamp that should be reported to backend -); - -extern size_t backend_name_copy(char *d, const char *s, size_t usable); -extern int discard_response(BUFFER *b, const char *backend); - -static inline char *strip_quotes(char *str) { - if(*str == '"' || *str == '\'') { - char *s; - - str++; - - s = str; - while(*s) s++; - if(s != str) s--; - - if(*s == '"' || *s == '\'') *s = '\0'; - } - - return str; -} - -#endif // BACKENDS_INTERNALS - -#include "backends/prometheus/backend_prometheus.h" -#include "backends/graphite/graphite.h" -#include "backends/json/json.h" -#include "backends/opentsdb/opentsdb.h" - -#if HAVE_KINESIS -#include "backends/aws_kinesis/aws_kinesis.h" -#endif - -#if ENABLE_PROMETHEUS_REMOTE_WRITE -#include "backends/prometheus/remote_write/remote_write.h" -#endif - -#if HAVE_MONGOC -#include "backends/mongodb/mongodb.h" -#endif - -#endif /* NETDATA_BACKENDS_H */ diff --git a/backends/graphite/Makefile.am b/backends/graphite/Makefile.am deleted file mode 100644 index babdcf0df..000000000 --- a/backends/graphite/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later - -AUTOMAKE_OPTIONS = subdir-objects -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in diff --git a/backends/graphite/graphite.c b/backends/graphite/graphite.c deleted file mode 100644 index f75a93a0f..000000000 --- a/backends/graphite/graphite.c +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -#define BACKENDS_INTERNALS -#include "graphite.h" - -// ---------------------------------------------------------------------------- -// graphite backend - -int backends_format_dimension_collected_graphite_plaintext( - BUFFER *b // the buffer to write data to - , const char *prefix // the prefix to use - , RRDHOST *host // the host this chart comes from - , const char *hostname // the hostname (to override host->hostname) - , RRDSET *st // the chart - , RRDDIM *rd // the dimension - , time_t after // the start timestamp - , time_t before // the end timestamp - , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap -) { - (void)host; - (void)after; - (void)before; - - char chart_name[RRD_ID_LENGTH_MAX + 1]; - char dimension_name[RRD_ID_LENGTH_MAX + 1]; - backend_name_copy(chart_name, (backend_options & BACKEND_OPTION_SEND_NAMES && st->name)?st->name:st->id, RRD_ID_LENGTH_MAX); - backend_name_copy(dimension_name, (backend_options & BACKEND_OPTION_SEND_NAMES && rd->name)?rd->name:rd->id, RRD_ID_LENGTH_MAX); - - buffer_sprintf( - b - , "%s.%s.%s.%s%s%s " COLLECTED_NUMBER_FORMAT " %llu\n" - , prefix - , hostname - , chart_name - , dimension_name - , (host->tags)?";":"" - , (host->tags)?host->tags:"" - , rd->last_collected_value - , (unsigned long long)rd->last_collected_time.tv_sec - ); - - return 1; -} - -int backends_format_dimension_stored_graphite_plaintext( - BUFFER *b // the buffer to write data to - , const char *prefix // the prefix to use - , RRDHOST *host // the host this chart comes from - , const char *hostname // the hostname (to override host->hostname) - , RRDSET *st // the chart - , RRDDIM *rd // the dimension - , time_t after // the start timestamp - , time_t before // the end timestamp - , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap -) { - (void)host; - - char chart_name[RRD_ID_LENGTH_MAX + 1]; - char dimension_name[RRD_ID_LENGTH_MAX + 1]; - backend_name_copy(chart_name, (backend_options & BACKEND_OPTION_SEND_NAMES && st->name)?st->name:st->id, RRD_ID_LENGTH_MAX); - backend_name_copy(dimension_name, (backend_options & BACKEND_OPTION_SEND_NAMES && rd->name)?rd->name:rd->id, RRD_ID_LENGTH_MAX); - - time_t first_t = after, last_t = before; - calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, backend_options, &first_t, &last_t); - - if(!isnan(value)) { - - buffer_sprintf( - b - , "%s.%s.%s.%s%s%s " CALCULATED_NUMBER_FORMAT " %llu\n" - , prefix - , hostname - , chart_name - , dimension_name - , (host->tags)?";":"" - , (host->tags)?host->tags:"" - , value - , (unsigned long long) last_t - ); - - return 1; - } - return 0; -} - -int process_graphite_response(BUFFER *b) { - return discard_response(b, "graphite"); -} - - diff --git a/backends/graphite/graphite.h b/backends/graphite/graphite.h deleted file mode 100644 index 498a7fcdf..000000000 --- a/backends/graphite/graphite.h +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - - -#ifndef NETDATA_BACKEND_GRAPHITE_H -#define NETDATA_BACKEND_GRAPHITE_H - -#include "backends/backends.h" - -extern int backends_format_dimension_collected_graphite_plaintext( - BUFFER *b // the buffer to write data to - , const char *prefix // the prefix to use - , RRDHOST *host // the host this chart comes from - , const char *hostname // the hostname (to override host->hostname) - , RRDSET *st // the chart - , RRDDIM *rd // the dimension - , time_t after // the start timestamp - , time_t before // the end timestamp - , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap -); - -extern int backends_format_dimension_stored_graphite_plaintext( - BUFFER *b // the buffer to write data to - , const char *prefix // the prefix to use - , RRDHOST *host // the host this chart comes from - , const char *hostname // the hostname (to override host->hostname) - , RRDSET *st // the chart - , RRDDIM *rd // the dimension - , time_t after // the start timestamp - , time_t before // the end timestamp - , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap -); - -extern int process_graphite_response(BUFFER *b); - -#endif //NETDATA_BACKEND_GRAPHITE_H diff --git a/backends/json/Makefile.am b/backends/json/Makefile.am deleted file mode 100644 index babdcf0df..000000000 --- a/backends/json/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later - -AUTOMAKE_OPTIONS = subdir-objects -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in diff --git a/backends/json/json.c b/backends/json/json.c deleted file mode 100644 index 0c7cc738f..000000000 --- a/backends/json/json.c +++ /dev/null @@ -1,152 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -#define BACKENDS_INTERNALS -#include "json.h" - -// ---------------------------------------------------------------------------- -// json backend - -int backends_format_dimension_collected_json_plaintext( - BUFFER *b // the buffer to write data to - , const char *prefix // the prefix to use - , RRDHOST *host // the host this chart comes from - , const char *hostname // the hostname (to override host->hostname) - , RRDSET *st // the chart - , RRDDIM *rd // the dimension - , time_t after // the start timestamp - , time_t before // the end timestamp - , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap -) { - (void)host; - (void)after; - (void)before; - (void)backend_options; - - const char *tags_pre = "", *tags_post = "", *tags = host->tags; - if(!tags) tags = ""; - - if(*tags) { - if(*tags == '{' || *tags == '[' || *tags == '"') { - tags_pre = "\"host_tags\":"; - tags_post = ","; - } - else { - tags_pre = "\"host_tags\":\""; - tags_post = "\","; - } - } - - buffer_sprintf(b, "{" - "\"prefix\":\"%s\"," - "\"hostname\":\"%s\"," - "%s%s%s" - - "\"chart_id\":\"%s\"," - "\"chart_name\":\"%s\"," - "\"chart_family\":\"%s\"," - "\"chart_context\": \"%s\"," - "\"chart_type\":\"%s\"," - "\"units\": \"%s\"," - - "\"id\":\"%s\"," - "\"name\":\"%s\"," - "\"value\":" COLLECTED_NUMBER_FORMAT "," - - "\"timestamp\": %llu}\n", - prefix, - hostname, - tags_pre, tags, tags_post, - - st->id, - st->name, - st->family, - st->context, - st->type, - st->units, - - rd->id, - rd->name, - rd->last_collected_value, - - (unsigned long long) rd->last_collected_time.tv_sec - ); - - return 1; -} - -int backends_format_dimension_stored_json_plaintext( - BUFFER *b // the buffer to write data to - , const char *prefix // the prefix to use - , RRDHOST *host // the host this chart comes from - , const char *hostname // the hostname (to override host->hostname) - , RRDSET *st // the chart - , RRDDIM *rd // the dimension - , time_t after // the start timestamp - , time_t before // the end timestamp - , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap -) { - (void)host; - - time_t first_t = after, last_t = before; - calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, backend_options, &first_t, &last_t); - - if(!isnan(value)) { - const char *tags_pre = "", *tags_post = "", *tags = host->tags; - if(!tags) tags = ""; - - if(*tags) { - if(*tags == '{' || *tags == '[' || *tags == '"') { - tags_pre = "\"host_tags\":"; - tags_post = ","; - } - else { - tags_pre = "\"host_tags\":\""; - tags_post = "\","; - } - } - - buffer_sprintf(b, "{" - "\"prefix\":\"%s\"," - "\"hostname\":\"%s\"," - "%s%s%s" - - "\"chart_id\":\"%s\"," - "\"chart_name\":\"%s\"," - "\"chart_family\":\"%s\"," - "\"chart_context\": \"%s\"," - "\"chart_type\":\"%s\"," - "\"units\": \"%s\"," - - "\"id\":\"%s\"," - "\"name\":\"%s\"," - "\"value\":" CALCULATED_NUMBER_FORMAT "," - - "\"timestamp\": %llu}\n", - prefix, - hostname, - tags_pre, tags, tags_post, - - st->id, - st->name, - st->family, - st->context, - st->type, - st->units, - - rd->id, - rd->name, - value, - - (unsigned long long) last_t - ); - - return 1; - } - return 0; -} - -int process_json_response(BUFFER *b) { - return discard_response(b, "json"); -} - - diff --git a/backends/json/json.h b/backends/json/json.h deleted file mode 100644 index 78ac37609..000000000 --- a/backends/json/json.h +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -#ifndef NETDATA_BACKEND_JSON_H -#define NETDATA_BACKEND_JSON_H - -#include "backends/backends.h" - -extern int backends_format_dimension_collected_json_plaintext( - BUFFER *b // the buffer to write data to - , const char *prefix // the prefix to use - , RRDHOST *host // the host this chart comes from - , const char *hostname // the hostname (to override host->hostname) - , RRDSET *st // the chart - , RRDDIM *rd // the dimension - , time_t after // the start timestamp - , time_t before // the end timestamp - , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap -); - -extern int backends_format_dimension_stored_json_plaintext( - BUFFER *b // the buffer to write data to - , const char *prefix // the prefix to use - , RRDHOST *host // the host this chart comes from - , const char *hostname // the hostname (to override host->hostname) - , RRDSET *st // the chart - , RRDDIM *rd // the dimension - , time_t after // the start timestamp - , time_t before // the end timestamp - , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap -); - -extern int process_json_response(BUFFER *b); - -#endif //NETDATA_BACKEND_JSON_H diff --git a/backends/mongodb/Makefile.am b/backends/mongodb/Makefile.am deleted file mode 100644 index 161784b8f..000000000 --- a/backends/mongodb/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later - -AUTOMAKE_OPTIONS = subdir-objects -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in - -dist_noinst_DATA = \ - README.md \ - $(NULL) diff --git a/backends/mongodb/README.md b/backends/mongodb/README.md deleted file mode 100644 index 7c7996e1b..000000000 --- a/backends/mongodb/README.md +++ /dev/null @@ -1,41 +0,0 @@ - - -# MongoDB backend - -## Prerequisites - -To use MongoDB as a backend, `libmongoc` 1.7.0 or higher should be -[installed](http://mongoc.org/libmongoc/current/installing.html) first. Next, Netdata should be re-installed from the -source. The installer will detect that the required libraries are now available. - -## Configuration - -To enable data sending to the MongoDB backend set the following options in `netdata.conf`: - -```conf -[backend] - enabled = yes - type = mongodb -``` - -In the Netdata configuration directory run `./edit-config mongodb.conf` and set [MongoDB -URI](https://docs.mongodb.com/manual/reference/connection-string/), database name, and collection name: - -```yaml -# URI -uri = mongodb:// - -# database name -database = your_database_name - -# collection name -collection = your_collection_name -``` - -The default socket timeout depends on the backend update interval. The timeout is 500 ms shorter than the interval (but -not less than 1000 ms). You can alter the timeout using the `sockettimeoutms` MongoDB URI option. - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fbackends%2Fmongodb%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) diff --git a/backends/mongodb/mongodb.c b/backends/mongodb/mongodb.c deleted file mode 100644 index d0527a723..000000000 --- a/backends/mongodb/mongodb.c +++ /dev/null @@ -1,189 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -#define BACKENDS_INTERNALS -#include "mongodb.h" -#include - -#define CONFIG_FILE_LINE_MAX ((CONFIG_MAX_NAME + CONFIG_MAX_VALUE + 1024) * 2) - -static mongoc_client_t *mongodb_client; -static mongoc_collection_t *mongodb_collection; - -int backends_mongodb_init(const char *uri_string, - const char *database_string, - const char *collection_string, - int32_t default_socket_timeout) { - mongoc_uri_t *uri; - bson_error_t error; - - mongoc_init(); - - uri = mongoc_uri_new_with_error(uri_string, &error); - if(unlikely(!uri)) { - error("BACKEND: failed to parse URI: %s. Error message: %s", uri_string, error.message); - return 1; - } - - int32_t socket_timeout = mongoc_uri_get_option_as_int32(uri, MONGOC_URI_SOCKETTIMEOUTMS, default_socket_timeout); - if(!mongoc_uri_set_option_as_int32(uri, MONGOC_URI_SOCKETTIMEOUTMS, socket_timeout)) { - error("BACKEND: failed to set %s to the value %d", MONGOC_URI_SOCKETTIMEOUTMS, socket_timeout); - return 1; - }; - - mongodb_client = mongoc_client_new_from_uri(uri); - if(unlikely(!mongodb_client)) { - error("BACKEND: failed to create a new client"); - return 1; - } - - if(!mongoc_client_set_appname(mongodb_client, "netdata")) { - error("BACKEND: failed to set client appname"); - }; - - mongodb_collection = mongoc_client_get_collection(mongodb_client, database_string, collection_string); - - mongoc_uri_destroy(uri); - - return 0; -} - -void backends_free_bson(bson_t **insert, size_t n_documents) { - size_t i; - - for(i = 0; i < n_documents; i++) - bson_destroy(insert[i]); - - free(insert); -} - -int backends_mongodb_insert(char *data, size_t n_metrics) { - bson_t **insert = calloc(n_metrics, sizeof(bson_t *)); - bson_error_t error; - char *start = data, *end = data; - size_t n_documents = 0; - - while(*end && n_documents <= n_metrics) { - while(*end && *end != '\n') end++; - - if(likely(*end)) { - *end = '\0'; - end++; - } - else { - break; - } - - insert[n_documents] = bson_new_from_json((const uint8_t *)start, -1, &error); - - if(unlikely(!insert[n_documents])) { - error("BACKEND: %s", error.message); - backends_free_bson(insert, n_documents); - return 1; - } - - start = end; - - n_documents++; - } - - if(unlikely(!mongoc_collection_insert_many(mongodb_collection, (const bson_t **)insert, n_documents, NULL, NULL, &error))) { - error("BACKEND: %s", error.message); - backends_free_bson(insert, n_documents); - return 1; - } - - backends_free_bson(insert, n_documents); - - return 0; -} - -void backends_mongodb_cleanup() { - mongoc_collection_destroy(mongodb_collection); - mongoc_client_destroy(mongodb_client); - mongoc_cleanup(); - - return; -} - -int read_mongodb_conf(const char *path, char **uri_p, char **database_p, char **collection_p) { - char *uri = *uri_p; - char *database = *database_p; - char *collection = *collection_p; - - if(unlikely(uri)) freez(uri); - if(unlikely(database)) freez(database); - if(unlikely(collection)) freez(collection); - uri = NULL; - database = NULL; - collection = NULL; - - int line = 0; - - char filename[FILENAME_MAX + 1]; - snprintfz(filename, FILENAME_MAX, "%s/mongodb.conf", path); - - char buffer[CONFIG_FILE_LINE_MAX + 1], *s; - - debug(D_BACKEND, "BACKEND: opening config file '%s'", filename); - - FILE *fp = fopen(filename, "r"); - if(!fp) { - return 1; - } - - while(fgets(buffer, CONFIG_FILE_LINE_MAX, fp) != NULL) { - buffer[CONFIG_FILE_LINE_MAX] = '\0'; - line++; - - s = trim(buffer); - if(!s || *s == '#') { - debug(D_BACKEND, "BACKEND: ignoring line %d of file '%s', it is empty.", line, filename); - continue; - } - - char *name = s; - char *value = strchr(s, '='); - if(unlikely(!value)) { - error("BACKEND: ignoring line %d ('%s') of file '%s', there is no = in it.", line, s, filename); - continue; - } - *value = '\0'; - value++; - - name = trim(name); - value = trim(value); - - if(unlikely(!name || *name == '#')) { - error("BACKEND: ignoring line %d of file '%s', name is empty.", line, filename); - continue; - } - - if(!value) - value = ""; - else - value = strip_quotes(value); - - if(name[0] == 'u' && !strcmp(name, "uri")) { - uri = strdupz(value); - } - else if(name[0] == 'd' && !strcmp(name, "database")) { - database = strdupz(value); - } - else if(name[0] == 'c' && !strcmp(name, "collection")) { - collection = strdupz(value); - } - } - - fclose(fp); - - if(unlikely(!collection || !*collection)) { - error("BACKEND: collection name is a mandatory MongoDB parameter, but it is not configured"); - return 1; - } - - *uri_p = uri; - *database_p = database; - *collection_p = collection; - - return 0; -} diff --git a/backends/mongodb/mongodb.conf b/backends/mongodb/mongodb.conf deleted file mode 100644 index 11ea6efb2..000000000 --- a/backends/mongodb/mongodb.conf +++ /dev/null @@ -1,12 +0,0 @@ -# MongoDB backend configuration -# -# All options in this file are mandatory - -# URI -uri = - -# database name -database = - -# collection name -collection = diff --git a/backends/mongodb/mongodb.h b/backends/mongodb/mongodb.h deleted file mode 100644 index cae9b093e..000000000 --- a/backends/mongodb/mongodb.h +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -#ifndef NETDATA_BACKEND_MONGODB_H -#define NETDATA_BACKEND_MONGODB_H - -#include "backends/backends.h" - -extern int backends_mongodb_init(const char *uri_string, const char *database_string, const char *collection_string, const int32_t socket_timeout); - -extern int backends_mongodb_insert(char *data, size_t n_metrics); - -extern void backends_mongodb_cleanup(); - -extern int read_mongodb_conf(const char *path, char **uri_p, char **database_p, char **collection_p); - -#endif //NETDATA_BACKEND_MONGODB_H diff --git a/backends/nc-backend.sh b/backends/nc-backend.sh deleted file mode 100755 index 65704b98f..000000000 --- a/backends/nc-backend.sh +++ /dev/null @@ -1,158 +0,0 @@ -#!/usr/bin/env bash - -# SPDX-License-Identifier: GPL-3.0-or-later - -# This is a simple backend database proxy, written in BASH, using the nc command. -# Run the script without any parameters for help. - -MODE="${1}" -MY_PORT="${2}" -BACKEND_HOST="${3}" -BACKEND_PORT="${4}" -FILE="${NETDATA_NC_BACKEND_DIR-/tmp}/netdata-nc-backend-${MY_PORT}" - -log() { - logger --stderr --id=$$ --tag "netdata-nc-backend" "${*}" -} - -mync() { - local ret - - log "Running: nc ${*}" - nc "${@}" - ret=$? - - log "nc stopped with return code ${ret}." - - return ${ret} -} - -listen_save_replay_forever() { - local file="${1}" port="${2}" real_backend_host="${3}" real_backend_port="${4}" ret delay=1 started ended - - while true - do - log "Starting nc to listen on port ${port} and save metrics to ${file}" - - started=$(date +%s) - mync -l -p "${port}" | tee -a -p --output-error=exit "${file}" - ended=$(date +%s) - - if [ -s "${file}" ] - then - if [ ! -z "${real_backend_host}" ] && [ ! -z "${real_backend_port}" ] - then - log "Attempting to send the metrics to the real backend at ${real_backend_host}:${real_backend_port}" - - mync "${real_backend_host}" "${real_backend_port}" <"${file}" - ret=$? - - if [ ${ret} -eq 0 ] - then - log "Successfully sent the metrics to ${real_backend_host}:${real_backend_port}" - mv "${file}" "${file}.old" - touch "${file}" - else - log "Failed to send the metrics to ${real_backend_host}:${real_backend_port} (nc returned ${ret}) - appending more data to ${file}" - fi - else - log "No backend configured - appending more data to ${file}" - fi - fi - - # prevent a CPU hungry infinite loop - # if nc cannot listen to port - if [ $((ended - started)) -lt 5 ] - then - log "nc has been stopped too fast." - delay=30 - else - delay=1 - fi - - log "Waiting ${delay} seconds before listening again for data." - sleep ${delay} - done -} - -if [ "${MODE}" = "start" ] - then - - # start the listener, in exclusive mode - # only one can use the same file/port at a time - { - flock -n 9 - # shellcheck disable=SC2181 - if [ $? -ne 0 ] - then - log "Cannot get exclusive lock on file ${FILE}.lock - Am I running multiple times?" - exit 2 - fi - - # save our PID to the lock file - echo "$$" >"${FILE}.lock" - - listen_save_replay_forever "${FILE}" "${MY_PORT}" "${BACKEND_HOST}" "${BACKEND_PORT}" - ret=$? - - log "listener exited." - exit ${ret} - - } 9>>"${FILE}.lock" - - # we can only get here if ${FILE}.lock cannot be created - log "Cannot create file ${FILE}." - exit 3 - -elif [ "${MODE}" = "stop" ] - then - - { - flock -n 9 - # shellcheck disable=SC2181 - if [ $? -ne 0 ] - then - pid=$(<"${FILE}".lock) - log "Killing process ${pid}..." - kill -TERM "-${pid}" - exit 0 - fi - - log "File ${FILE}.lock has been locked by me but it shouldn't. Is a collector running?" - exit 4 - - } 9<"${FILE}.lock" - - log "File ${FILE}.lock does not exist. Is a collector running?" - exit 5 - -else - - cat < - -# OpenTSDB with HTTP - -Netdata can easily communicate with OpenTSDB using HTTP API. To enable this channel, set the following options in your -`netdata.conf`: - -```conf -[backend] - type = opentsdb:http - destination = localhost:4242 -``` - -In this example, OpenTSDB is running with its default port, which is `4242`. If you run OpenTSDB on a different port, -change the `destination = localhost:4242` line accordingly. - -## HTTPS - -As of [v1.16.0](https://github.com/netdata/netdata/releases/tag/v1.16.0), Netdata can send metrics to OpenTSDB using -TLS/SSL. Unfortunately, OpenTDSB does not support encrypted connections, so you will have to configure a reverse proxy -to enable HTTPS communication between Netdata and OpenTSDB. You can set up a reverse proxy with -[Nginx](/docs/Running-behind-nginx.md). - -After your proxy is configured, make the following changes to `netdata.conf`: - -```conf -[backend] - type = opentsdb:https - destination = localhost:8082 -``` - -In this example, we used the port `8082` for our reverse proxy. If your reverse proxy listens on a different port, -change the `destination = localhost:8082` line accordingly. - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fbackends%2Fopentsdb%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]() diff --git a/backends/opentsdb/opentsdb.c b/backends/opentsdb/opentsdb.c deleted file mode 100644 index 965b4c092..000000000 --- a/backends/opentsdb/opentsdb.c +++ /dev/null @@ -1,205 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -#define BACKENDS_INTERNALS -#include "opentsdb.h" - -// ---------------------------------------------------------------------------- -// opentsdb backend - -int backends_format_dimension_collected_opentsdb_telnet( - BUFFER *b // the buffer to write data to - , const char *prefix // the prefix to use - , RRDHOST *host // the host this chart comes from - , const char *hostname // the hostname (to override host->hostname) - , RRDSET *st // the chart - , RRDDIM *rd // the dimension - , time_t after // the start timestamp - , time_t before // the end timestamp - , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap -) { - (void)host; - (void)after; - (void)before; - - char chart_name[RRD_ID_LENGTH_MAX + 1]; - char dimension_name[RRD_ID_LENGTH_MAX + 1]; - backend_name_copy(chart_name, (backend_options & BACKEND_OPTION_SEND_NAMES && st->name)?st->name:st->id, RRD_ID_LENGTH_MAX); - backend_name_copy(dimension_name, (backend_options & BACKEND_OPTION_SEND_NAMES && rd->name)?rd->name:rd->id, RRD_ID_LENGTH_MAX); - - buffer_sprintf( - b - , "put %s.%s.%s %llu " COLLECTED_NUMBER_FORMAT " host=%s%s%s\n" - , prefix - , chart_name - , dimension_name - , (unsigned long long)rd->last_collected_time.tv_sec - , rd->last_collected_value - , hostname - , (host->tags)?" ":"" - , (host->tags)?host->tags:"" - ); - - return 1; -} - -int backends_format_dimension_stored_opentsdb_telnet( - BUFFER *b // the buffer to write data to - , const char *prefix // the prefix to use - , RRDHOST *host // the host this chart comes from - , const char *hostname // the hostname (to override host->hostname) - , RRDSET *st // the chart - , RRDDIM *rd // the dimension - , time_t after // the start timestamp - , time_t before // the end timestamp - , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap -) { - (void)host; - - time_t first_t = after, last_t = before; - calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, backend_options, &first_t, &last_t); - - char chart_name[RRD_ID_LENGTH_MAX + 1]; - char dimension_name[RRD_ID_LENGTH_MAX + 1]; - backend_name_copy(chart_name, (backend_options & BACKEND_OPTION_SEND_NAMES && st->name)?st->name:st->id, RRD_ID_LENGTH_MAX); - backend_name_copy(dimension_name, (backend_options & BACKEND_OPTION_SEND_NAMES && rd->name)?rd->name:rd->id, RRD_ID_LENGTH_MAX); - - if(!isnan(value)) { - - buffer_sprintf( - b - , "put %s.%s.%s %llu " CALCULATED_NUMBER_FORMAT " host=%s%s%s\n" - , prefix - , chart_name - , dimension_name - , (unsigned long long) last_t - , value - , hostname - , (host->tags)?" ":"" - , (host->tags)?host->tags:"" - ); - - return 1; - } - - return 0; -} - -int process_opentsdb_response(BUFFER *b) { - return discard_response(b, "opentsdb"); -} - -static inline void opentsdb_build_message(BUFFER *b, char *message, const char *hostname, int length) { - buffer_sprintf( - b - , "POST /api/put HTTP/1.1\r\n" - "Host: %s\r\n" - "Content-Type: application/json\r\n" - "Content-Length: %d\r\n" - "\r\n" - "%s" - , hostname - , length - , message - ); -} - -int backends_format_dimension_collected_opentsdb_http( - BUFFER *b // the buffer to write data to - , const char *prefix // the prefix to use - , RRDHOST *host // the host this chart comes from - , const char *hostname // the hostname (to override host->hostname) - , RRDSET *st // the chart - , RRDDIM *rd // the dimension - , time_t after // the start timestamp - , time_t before // the end timestamp - , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap -) { - (void)host; - (void)after; - (void)before; - - char message[1024]; - char chart_name[RRD_ID_LENGTH_MAX + 1]; - char dimension_name[RRD_ID_LENGTH_MAX + 1]; - backend_name_copy(chart_name, (backend_options & BACKEND_OPTION_SEND_NAMES && st->name)?st->name:st->id, RRD_ID_LENGTH_MAX); - backend_name_copy(dimension_name, (backend_options & BACKEND_OPTION_SEND_NAMES && rd->name)?rd->name:rd->id, RRD_ID_LENGTH_MAX); - - int length = snprintfz(message - , sizeof(message) - , "{" - " \"metric\": \"%s.%s.%s\"," - " \"timestamp\": %llu," - " \"value\": "COLLECTED_NUMBER_FORMAT "," - " \"tags\": {" - " \"host\": \"%s%s%s\"" - " }" - "}" - , prefix - , chart_name - , dimension_name - , (unsigned long long)rd->last_collected_time.tv_sec - , rd->last_collected_value - , hostname - , (host->tags)?" ":"" - , (host->tags)?host->tags:"" - ); - - if(length > 0) { - opentsdb_build_message(b, message, hostname, length); - } - - return 1; -} - -int backends_format_dimension_stored_opentsdb_http( - BUFFER *b // the buffer to write data to - , const char *prefix // the prefix to use - , RRDHOST *host // the host this chart comes from - , const char *hostname // the hostname (to override host->hostname) - , RRDSET *st // the chart - , RRDDIM *rd // the dimension - , time_t after // the start timestamp - , time_t before // the end timestamp - , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap -) { - (void)host; - - time_t first_t = after, last_t = before; - calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, backend_options, &first_t, &last_t); - - if(!isnan(value)) { - char chart_name[RRD_ID_LENGTH_MAX + 1]; - char dimension_name[RRD_ID_LENGTH_MAX + 1]; - backend_name_copy(chart_name, (backend_options & BACKEND_OPTION_SEND_NAMES && st->name)?st->name:st->id, RRD_ID_LENGTH_MAX); - backend_name_copy(dimension_name, (backend_options & BACKEND_OPTION_SEND_NAMES && rd->name)?rd->name:rd->id, RRD_ID_LENGTH_MAX); - - char message[1024]; - int length = snprintfz(message - , sizeof(message) - , "{" - " \"metric\": \"%s.%s.%s\"," - " \"timestamp\": %llu," - " \"value\": "CALCULATED_NUMBER_FORMAT "," - " \"tags\": {" - " \"host\": \"%s%s%s\"" - " }" - "}" - , prefix - , chart_name - , dimension_name - , (unsigned long long)last_t - , value - , hostname - , (host->tags)?" ":"" - , (host->tags)?host->tags:"" - ); - - if(length > 0) { - opentsdb_build_message(b, message, hostname, length); - } - - return 1; - } - - return 0; -} diff --git a/backends/opentsdb/opentsdb.h b/backends/opentsdb/opentsdb.h deleted file mode 100644 index 87d9c5cd7..000000000 --- a/backends/opentsdb/opentsdb.h +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -#ifndef NETDATA_BACKEND_OPENTSDB_H -#define NETDATA_BACKEND_OPENTSDB_H - -#include "backends/backends.h" - -extern int backends_format_dimension_collected_opentsdb_telnet( - BUFFER *b // the buffer to write data to - , const char *prefix // the prefix to use - , RRDHOST *host // the host this chart comes from - , const char *hostname // the hostname (to override host->hostname) - , RRDSET *st // the chart - , RRDDIM *rd // the dimension - , time_t after // the start timestamp - , time_t before // the end timestamp - , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap -); - -extern int backends_format_dimension_stored_opentsdb_telnet( - BUFFER *b // the buffer to write data to - , const char *prefix // the prefix to use - , RRDHOST *host // the host this chart comes from - , const char *hostname // the hostname (to override host->hostname) - , RRDSET *st // the chart - , RRDDIM *rd // the dimension - , time_t after // the start timestamp - , time_t before // the end timestamp - , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap -); - -extern int process_opentsdb_response(BUFFER *b); - -int backends_format_dimension_collected_opentsdb_http( - BUFFER *b // the buffer to write data to - , const char *prefix // the prefix to use - , RRDHOST *host // the host this chart comes from - , const char *hostname // the hostname (to override host->hostname) - , RRDSET *st // the chart - , RRDDIM *rd // the dimension - , time_t after // the start timestamp - , time_t before // the end timestamp - , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap -); - -int backends_format_dimension_stored_opentsdb_http( - BUFFER *b // the buffer to write data to - , const char *prefix // the prefix to use - , RRDHOST *host // the host this chart comes from - , const char *hostname // the hostname (to override host->hostname) - , RRDSET *st // the chart - , RRDDIM *rd // the dimension - , time_t after // the start timestamp - , time_t before // the end timestamp - , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap -); - -#endif //NETDATA_BACKEND_OPENTSDB_H diff --git a/backends/prometheus/Makefile.am b/backends/prometheus/Makefile.am deleted file mode 100644 index 334fca81c..000000000 --- a/backends/prometheus/Makefile.am +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later - -AUTOMAKE_OPTIONS = subdir-objects -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in - -SUBDIRS = \ - remote_write \ - $(NULL) - -dist_noinst_DATA = \ - README.md \ - $(NULL) diff --git a/backends/prometheus/README.md b/backends/prometheus/README.md deleted file mode 100644 index a0460d1d8..000000000 --- a/backends/prometheus/README.md +++ /dev/null @@ -1,457 +0,0 @@ - - -# Using Netdata with Prometheus - -> IMPORTANT: the format Netdata sends metrics to prometheus has changed since Netdata v1.7. The new prometheus backend -> for Netdata supports a lot more features and is aligned to the development of the rest of the Netdata backends. - -Prometheus is a distributed monitoring system which offers a very simple setup along with a robust data model. Recently -Netdata added support for Prometheus. I'm going to quickly show you how to install both Netdata and prometheus on the -same server. We can then use grafana pointed at Prometheus to obtain long term metrics Netdata offers. I'm assuming we -are starting at a fresh ubuntu shell (whether you'd like to follow along in a VM or a cloud instance is up to you). - -## Installing Netdata and prometheus - -### Installing Netdata - -There are number of ways to install Netdata according to [Installation](/packaging/installer/README.md). The suggested way -of installing the latest Netdata and keep it upgrade automatically. Using one line installation: - -```sh -bash <(curl -Ss https://my-netdata.io/kickstart.sh) -``` - -At this point we should have Netdata listening on port 19999. Attempt to take your browser here: - -```sh -http://your.netdata.ip:19999 -``` - -_(replace `your.netdata.ip` with the IP or hostname of the server running Netdata)_ - -### Installing Prometheus - -In order to install prometheus we are going to introduce our own systemd startup script along with an example of -prometheus.yaml configuration. Prometheus needs to be pointed to your server at a specific target url for it to scrape -Netdata's api. Prometheus is always a pull model meaning Netdata is the passive client within this architecture. -Prometheus always initiates the connection with Netdata. - -#### Download Prometheus - -```sh -cd /tmp && curl -s https://api.github.com/repos/prometheus/prometheus/releases/latest \ -| grep "browser_download_url.*linux-amd64.tar.gz" \ -| cut -d '"' -f 4 \ -| wget -qi - -``` - -#### Create prometheus system user - -```sh -sudo useradd -r prometheus -``` - -#### Create prometheus directory - -```sh -sudo mkdir /opt/prometheus -sudo chown prometheus:prometheus /opt/prometheus -``` - -#### Untar prometheus directory - -```sh -sudo tar -xvf /tmp/prometheus-*linux-amd64.tar.gz -C /opt/prometheus --strip=1 -``` - -#### Install prometheus.yml - -We will use the following `prometheus.yml` file. Save it at `/opt/prometheus/prometheus.yml`. - -Make sure to replace `your.netdata.ip` with the IP or hostname of the host running Netdata. - -```yaml -# my global config -global: - scrape_interval: 5s # Set the scrape interval to every 5 seconds. Default is every 1 minute. - evaluation_interval: 5s # Evaluate rules every 5 seconds. The default is every 1 minute. - # scrape_timeout is set to the global default (10s). - - # Attach these labels to any time series or alerts when communicating with - # external systems (federation, remote storage, Alertmanager). - external_labels: - monitor: 'codelab-monitor' - -# Load rules once and periodically evaluate them according to the global 'evaluation_interval'. -rule_files: - # - "first.rules" - # - "second.rules" - -# A scrape configuration containing exactly one endpoint to scrape: -# Here it's Prometheus itself. -scrape_configs: - # The job name is added as a label `job=` to any timeseries scraped from this config. - - job_name: 'prometheus' - - # metrics_path defaults to '/metrics' - # scheme defaults to 'http'. - - static_configs: - - targets: ['0.0.0.0:9090'] - - - job_name: 'netdata-scrape' - - metrics_path: '/api/v1/allmetrics' - params: - # format: prometheus | prometheus_all_hosts - # You can use `prometheus_all_hosts` if you want Prometheus to set the `instance` to your hostname instead of IP - format: [prometheus] - # - # source: as-collected | raw | average | sum | volume - # default is: average - #source: [as-collected] - # - # server name for this prometheus - the default is the client IP - # for Netdata to uniquely identify it - #server: ['prometheus1'] - honor_labels: true - - static_configs: - - targets: ['{your.netdata.ip}:19999'] -``` - -#### Install nodes.yml - -The following is completely optional, it will enable Prometheus to generate alerts from some Netdata sources. Tweak the -values to your own needs. We will use the following `nodes.yml` file below. Save it at `/opt/prometheus/nodes.yml`, and -add a _- "nodes.yml"_ entry under the _rule_files:_ section in the example prometheus.yml file above. - -```yaml -groups: - - name: nodes - - rules: - - alert: node_high_cpu_usage_70 - expr: sum(sum_over_time(netdata_system_cpu_percentage_average{dimension=~"(user|system|softirq|irq|guest)"}[10m])) by (job) / sum(count_over_time(netdata_system_cpu_percentage_average{dimension="idle"}[10m])) by (job) > 70 - for: 1m - annotations: - description: '{{ $labels.job }} on ''{{ $labels.job }}'' CPU usage is at {{ humanize $value }}%.' - summary: CPU alert for container node '{{ $labels.job }}' - - - alert: node_high_memory_usage_70 - expr: 100 / sum(netdata_system_ram_MB_average) by (job) - * sum(netdata_system_ram_MB_average{dimension=~"free|cached"}) by (job) < 30 - for: 1m - annotations: - description: '{{ $labels.job }} memory usage is {{ humanize $value}}%.' - summary: Memory alert for container node '{{ $labels.job }}' - - - alert: node_low_root_filesystem_space_20 - expr: 100 / sum(netdata_disk_space_GB_average{family="/"}) by (job) - * sum(netdata_disk_space_GB_average{family="/",dimension=~"avail|cached"}) by (job) < 20 - for: 1m - annotations: - description: '{{ $labels.job }} root filesystem space is {{ humanize $value}}%.' - summary: Root filesystem alert for container node '{{ $labels.job }}' - - - alert: node_root_filesystem_fill_rate_6h - expr: predict_linear(netdata_disk_space_GB_average{family="/",dimension=~"avail|cached"}[1h], 6 * 3600) < 0 - for: 1h - labels: - severity: critical - annotations: - description: Container node {{ $labels.job }} root filesystem is going to fill up in 6h. - summary: Disk fill alert for Swarm node '{{ $labels.job }}' -``` - -#### Install prometheus.service - -Save this service file as `/etc/systemd/system/prometheus.service`: - -```sh -[Unit] -Description=Prometheus Server -AssertPathExists=/opt/prometheus - -[Service] -Type=simple -WorkingDirectory=/opt/prometheus -User=prometheus -Group=prometheus -ExecStart=/opt/prometheus/prometheus --config.file=/opt/prometheus/prometheus.yml --log.level=info -ExecReload=/bin/kill -SIGHUP $MAINPID -ExecStop=/bin/kill -SIGINT $MAINPID - -[Install] -WantedBy=multi-user.target -``` - -##### Start Prometheus - -```sh -sudo systemctl start prometheus -sudo systemctl enable prometheus -``` - -Prometheus should now start and listen on port 9090. Attempt to head there with your browser. - -If everything is working correctly when you fetch `http://your.prometheus.ip:9090` you will see a 'Status' tab. Click -this and click on 'targets' We should see the Netdata host as a scraped target. - ---- - -## Netdata support for prometheus - -> IMPORTANT: the format Netdata sends metrics to prometheus has changed since Netdata v1.6. The new format allows easier -> queries for metrics and supports both `as collected` and normalized metrics. - -Before explaining the changes, we have to understand the key differences between Netdata and prometheus. - -### understanding Netdata metrics - -#### charts - -Each chart in Netdata has several properties (common to all its metrics): - -- `chart_id` - uniquely identifies a chart. - -- `chart_name` - a more human friendly name for `chart_id`, also unique. - -- `context` - this is the template of the chart. All disk I/O charts have the same context, all mysql requests charts - have the same context, etc. This is used for alarm templates to match all the charts they should be attached to. - -- `family` groups a set of charts together. It is used as the submenu of the dashboard. - -- `units` is the units for all the metrics attached to the chart. - -#### dimensions - -Then each Netdata chart contains metrics called `dimensions`. All the dimensions of a chart have the same units of -measurement, and are contextually in the same category (ie. the metrics for disk bandwidth are `read` and `write` and -they are both in the same chart). - -### Netdata data source - -Netdata can send metrics to prometheus from 3 data sources: - -- `as collected` or `raw` - this data source sends the metrics to prometheus as they are collected. No conversion is - done by Netdata. The latest value for each metric is just given to prometheus. This is the most preferred method by - prometheus, but it is also the harder to work with. To work with this data source, you will need to understand how - to get meaningful values out of them. - - The format of the metrics is: `CONTEXT{chart="CHART",family="FAMILY",dimension="DIMENSION"}`. - - If the metric is a counter (`incremental` in Netdata lingo), `_total` is appended the context. - - Unlike prometheus, Netdata allows each dimension of a chart to have a different algorithm and conversion constants - (`multiplier` and `divisor`). In this case, that the dimensions of a charts are heterogeneous, Netdata will use this - format: `CONTEXT_DIMENSION{chart="CHART",family="FAMILY"}` - -- `average` - this data source uses the Netdata database to send the metrics to prometheus as they are presented on - the Netdata dashboard. So, all the metrics are sent as gauges, at the units they are presented in the Netdata - dashboard charts. This is the easiest to work with. - - The format of the metrics is: `CONTEXT_UNITS_average{chart="CHART",family="FAMILY",dimension="DIMENSION"}`. - - When this source is used, Netdata keeps track of the last access time for each prometheus server fetching the - metrics. This last access time is used at the subsequent queries of the same prometheus server to identify the - time-frame the `average` will be calculated. - - So, no matter how frequently prometheus scrapes Netdata, it will get all the database data. - To identify each prometheus server, Netdata uses by default the IP of the client fetching the metrics. - - If there are multiple prometheus servers fetching data from the same Netdata, using the same IP, each prometheus - server can append `server=NAME` to the URL. Netdata will use this `NAME` to uniquely identify the prometheus server. - -- `sum` or `volume`, is like `average` but instead of averaging the values, it sums them. - - The format of the metrics is: `CONTEXT_UNITS_sum{chart="CHART",family="FAMILY",dimension="DIMENSION"}`. All the - other operations are the same with `average`. - - To change the data source to `sum` or `as-collected` you need to provide the `source` parameter in the request URL. - e.g.: `http://your.netdata.ip:19999/api/v1/allmetrics?format=prometheus&help=yes&source=as-collected` - - Keep in mind that early versions of Netdata were sending the metrics as: `CHART_DIMENSION{}`. - -### Querying Metrics - -Fetch with your web browser this URL: - -`http://your.netdata.ip:19999/api/v1/allmetrics?format=prometheus&help=yes` - -_(replace `your.netdata.ip` with the ip or hostname of your Netdata server)_ - -Netdata will respond with all the metrics it sends to prometheus. - -If you search that page for `"system.cpu"` you will find all the metrics Netdata is exporting to prometheus for this -chart. `system.cpu` is the chart name on the Netdata dashboard (on the Netdata dashboard all charts have a text heading -such as : `Total CPU utilization (system.cpu)`. What we are interested here in the chart name: `system.cpu`). - -Searching for `"system.cpu"` reveals: - -```sh -# COMMENT homogeneous chart "system.cpu", context "system.cpu", family "cpu", units "percentage" -# COMMENT netdata_system_cpu_percentage_average: dimension "guest_nice", value is percentage, gauge, dt 1500066653 to 1500066662 inclusive -netdata_system_cpu_percentage_average{chart="system.cpu",family="cpu",dimension="guest_nice"} 0.0000000 1500066662000 -# COMMENT netdata_system_cpu_percentage_average: dimension "guest", value is percentage, gauge, dt 1500066653 to 1500066662 inclusive -netdata_system_cpu_percentage_average{chart="system.cpu",family="cpu",dimension="guest"} 1.7837326 1500066662000 -# COMMENT netdata_system_cpu_percentage_average: dimension "steal", value is percentage, gauge, dt 1500066653 to 1500066662 inclusive -netdata_system_cpu_percentage_average{chart="system.cpu",family="cpu",dimension="steal"} 0.0000000 1500066662000 -# COMMENT netdata_system_cpu_percentage_average: dimension "softirq", value is percentage, gauge, dt 1500066653 to 1500066662 inclusive -netdata_system_cpu_percentage_average{chart="system.cpu",family="cpu",dimension="softirq"} 0.5275442 1500066662000 -# COMMENT netdata_system_cpu_percentage_average: dimension "irq", value is percentage, gauge, dt 1500066653 to 1500066662 inclusive -netdata_system_cpu_percentage_average{chart="system.cpu",family="cpu",dimension="irq"} 0.2260836 1500066662000 -# COMMENT netdata_system_cpu_percentage_average: dimension "user", value is percentage, gauge, dt 1500066653 to 1500066662 inclusive -netdata_system_cpu_percentage_average{chart="system.cpu",family="cpu",dimension="user"} 2.3362762 1500066662000 -# COMMENT netdata_system_cpu_percentage_average: dimension "system", value is percentage, gauge, dt 1500066653 to 1500066662 inclusive -netdata_system_cpu_percentage_average{chart="system.cpu",family="cpu",dimension="system"} 1.7961062 1500066662000 -# COMMENT netdata_system_cpu_percentage_average: dimension "nice", value is percentage, gauge, dt 1500066653 to 1500066662 inclusive -netdata_system_cpu_percentage_average{chart="system.cpu",family="cpu",dimension="nice"} 0.0000000 1500066662000 -# COMMENT netdata_system_cpu_percentage_average: dimension "iowait", value is percentage, gauge, dt 1500066653 to 1500066662 inclusive -netdata_system_cpu_percentage_average{chart="system.cpu",family="cpu",dimension="iowait"} 0.9671802 1500066662000 -# COMMENT netdata_system_cpu_percentage_average: dimension "idle", value is percentage, gauge, dt 1500066653 to 1500066662 inclusive -netdata_system_cpu_percentage_average{chart="system.cpu",family="cpu",dimension="idle"} 92.3630770 1500066662000 -``` - -_(Netdata response for `system.cpu` with source=`average`)_ - -In `average` or `sum` data sources, all values are normalized and are reported to prometheus as gauges. Now, use the -'expression' text form in prometheus. Begin to type the metrics we are looking for: `netdata_system_cpu`. You should see -that the text form begins to auto-fill as prometheus knows about this metric. - -If the data source was `as collected`, the response would be: - -```sh -# COMMENT homogeneous chart "system.cpu", context "system.cpu", family "cpu", units "percentage" -# COMMENT netdata_system_cpu_total: chart "system.cpu", context "system.cpu", family "cpu", dimension "guest_nice", value * 1 / 1 delta gives percentage (counter) -netdata_system_cpu_total{chart="system.cpu",family="cpu",dimension="guest_nice"} 0 1500066716438 -# COMMENT netdata_system_cpu_total: chart "system.cpu", context "system.cpu", family "cpu", dimension "guest", value * 1 / 1 delta gives percentage (counter) -netdata_system_cpu_total{chart="system.cpu",family="cpu",dimension="guest"} 63945 1500066716438 -# COMMENT netdata_system_cpu_total: chart "system.cpu", context "system.cpu", family "cpu", dimension "steal", value * 1 / 1 delta gives percentage (counter) -netdata_system_cpu_total{chart="system.cpu",family="cpu",dimension="steal"} 0 1500066716438 -# COMMENT netdata_system_cpu_total: chart "system.cpu", context "system.cpu", family "cpu", dimension "softirq", value * 1 / 1 delta gives percentage (counter) -netdata_system_cpu_total{chart="system.cpu",family="cpu",dimension="softirq"} 8295 1500066716438 -# COMMENT netdata_system_cpu_total: chart "system.cpu", context "system.cpu", family "cpu", dimension "irq", value * 1 / 1 delta gives percentage (counter) -netdata_system_cpu_total{chart="system.cpu",family="cpu",dimension="irq"} 4079 1500066716438 -# COMMENT netdata_system_cpu_total: chart "system.cpu", context "system.cpu", family "cpu", dimension "user", value * 1 / 1 delta gives percentage (counter) -netdata_system_cpu_total{chart="system.cpu",family="cpu",dimension="user"} 116488 1500066716438 -# COMMENT netdata_system_cpu_total: chart "system.cpu", context "system.cpu", family "cpu", dimension "system", value * 1 / 1 delta gives percentage (counter) -netdata_system_cpu_total{chart="system.cpu",family="cpu",dimension="system"} 35084 1500066716438 -# COMMENT netdata_system_cpu_total: chart "system.cpu", context "system.cpu", family "cpu", dimension "nice", value * 1 / 1 delta gives percentage (counter) -netdata_system_cpu_total{chart="system.cpu",family="cpu",dimension="nice"} 505 1500066716438 -# COMMENT netdata_system_cpu_total: chart "system.cpu", context "system.cpu", family "cpu", dimension "iowait", value * 1 / 1 delta gives percentage (counter) -netdata_system_cpu_total{chart="system.cpu",family="cpu",dimension="iowait"} 23314 1500066716438 -# COMMENT netdata_system_cpu_total: chart "system.cpu", context "system.cpu", family "cpu", dimension "idle", value * 1 / 1 delta gives percentage (counter) -netdata_system_cpu_total{chart="system.cpu",family="cpu",dimension="idle"} 918470 1500066716438 -``` - -_(Netdata response for `system.cpu` with source=`as-collected`)_ - -For more information check prometheus documentation. - -### Streaming data from upstream hosts - -The `format=prometheus` parameter only exports the host's Netdata metrics. If you are using the parent-child -functionality of Netdata this ignores any upstream hosts - so you should consider using the below in your -**prometheus.yml**: - -```yaml - metrics_path: '/api/v1/allmetrics' - params: - format: [prometheus_all_hosts] - honor_labels: true -``` - -This will report all upstream host data, and `honor_labels` will make Prometheus take note of the instance names -provided. - -### Timestamps - -To pass the metrics through prometheus pushgateway, Netdata supports the option `×tamps=no` to send the metrics -without timestamps. - -## Netdata host variables - -Netdata collects various system configuration metrics, like the max number of TCP sockets supported, the max number of -files allowed system-wide, various IPC sizes, etc. These metrics are not exposed to prometheus by default. - -To expose them, append `variables=yes` to the Netdata URL. - -### TYPE and HELP - -To save bandwidth, and because prometheus does not use them anyway, `# TYPE` and `# HELP` lines are suppressed. If -wanted they can be re-enabled via `types=yes` and `help=yes`, e.g. -`/api/v1/allmetrics?format=prometheus&types=yes&help=yes` - -Note that if enabled, the `# TYPE` and `# HELP` lines are repeated for every occurrence of a metric, which goes against the Prometheus documentation's [specification for these lines](https://github.com/prometheus/docs/blob/master/content/docs/instrumenting/exposition_formats.md#comments-help-text-and-type-information). - -### Names and IDs - -Netdata supports names and IDs for charts and dimensions. Usually IDs are unique identifiers as read by the system and -names are human friendly labels (also unique). - -Most charts and metrics have the same ID and name, but in several cases they are different: disks with device-mapper, -interrupts, QoS classes, statsd synthetic charts, etc. - -The default is controlled in `netdata.conf`: - -```conf -[backend] - send names instead of ids = yes | no -``` - -You can overwrite it from prometheus, by appending to the URL: - -- `&names=no` to get IDs (the old behaviour) -- `&names=yes` to get names - -### Filtering metrics sent to prometheus - -Netdata can filter the metrics it sends to prometheus with this setting: - -```conf -[backend] - send charts matching = * -``` - -This settings accepts a space separated list of patterns to match the **charts** to be sent to prometheus. Each pattern -can use `*` as wildcard, any number of times (e.g `*a*b*c*` is valid). Patterns starting with `!` give a negative match -(e.g `!*.bad users.* groups.*` will send all the users and groups except `bad` user and `bad` group). The order is -important: the first match (positive or negative) left to right, is used. - -### Changing the prefix of Netdata metrics - -Netdata sends all metrics prefixed with `netdata_`. You can change this in `netdata.conf`, like this: - -```conf -[backend] - prefix = netdata -``` - -It can also be changed from the URL, by appending `&prefix=netdata`. - -### Metric Units - -The default source `average` adds the unit of measurement to the name of each metric (e.g. `_KiB_persec`). To hide the -units and get the same metric names as with the other sources, append to the URL `&hideunits=yes`. - -The units were standardized in v1.12, with the effect of changing the metric names. To get the metric names as they were -before v1.12, append to the URL `&oldunits=yes` - -### Accuracy of `average` and `sum` data sources - -When the data source is set to `average` or `sum`, Netdata remembers the last access of each client accessing prometheus -metrics and uses this last access time to respond with the `average` or `sum` of all the entries in the database since -that. This means that prometheus servers are not losing data when they access Netdata with data source = `average` or -`sum`. - -To uniquely identify each prometheus server, Netdata uses the IP of the client accessing the metrics. If however the IP -is not good enough for identifying a single prometheus server (e.g. when prometheus servers are accessing Netdata -through a web proxy, or when multiple prometheus servers are NATed to a single IP), each prometheus may append -`&server=NAME` to the URL. This `NAME` is used by Netdata to uniquely identify each prometheus server and keep track of -its last access time. - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fbackends%2Fprometheus%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) diff --git a/backends/prometheus/backend_prometheus.c b/backends/prometheus/backend_prometheus.c deleted file mode 100644 index 1fb3fd42c..000000000 --- a/backends/prometheus/backend_prometheus.c +++ /dev/null @@ -1,797 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -#define BACKENDS_INTERNALS -#include "backend_prometheus.h" - -// ---------------------------------------------------------------------------- -// PROMETHEUS -// /api/v1/allmetrics?format=prometheus and /api/v1/allmetrics?format=prometheus_all_hosts - -static struct prometheus_server { - const char *server; - uint32_t hash; - RRDHOST *host; - time_t last_access; - struct prometheus_server *next; -} *prometheus_server_root = NULL; - -static inline time_t prometheus_server_last_access(const char *server, RRDHOST *host, time_t now) { - static netdata_mutex_t prometheus_server_root_mutex = NETDATA_MUTEX_INITIALIZER; - - uint32_t hash = simple_hash(server); - - netdata_mutex_lock(&prometheus_server_root_mutex); - - struct prometheus_server *ps; - for(ps = prometheus_server_root; ps ;ps = ps->next) { - if (host == ps->host && hash == ps->hash && !strcmp(server, ps->server)) { - time_t last = ps->last_access; - ps->last_access = now; - netdata_mutex_unlock(&prometheus_server_root_mutex); - return last; - } - } - - ps = callocz(1, sizeof(struct prometheus_server)); - ps->server = strdupz(server); - ps->hash = hash; - ps->host = host; - ps->last_access = now; - ps->next = prometheus_server_root; - prometheus_server_root = ps; - - netdata_mutex_unlock(&prometheus_server_root_mutex); - return 0; -} - -static inline size_t backends_prometheus_name_copy(char *d, const char *s, size_t usable) { - size_t n; - - for(n = 0; *s && n < usable ; d++, s++, n++) { - register char c = *s; - - if(!isalnum(c)) *d = '_'; - else *d = c; - } - *d = '\0'; - - return n; -} - -static inline size_t backends_prometheus_label_copy(char *d, const char *s, size_t usable) { - size_t n; - - // make sure we can escape one character without overflowing the buffer - usable--; - - for(n = 0; *s && n < usable ; d++, s++, n++) { - register char c = *s; - - if(unlikely(c == '"' || c == '\\' || c == '\n')) { - *d++ = '\\'; - n++; - } - *d = c; - } - *d = '\0'; - - return n; -} - -static inline char *backends_prometheus_units_copy(char *d, const char *s, size_t usable, int showoldunits) { - const char *sorig = s; - char *ret = d; - size_t n; - - // Fix for issue 5227 - if (unlikely(showoldunits)) { - static struct { - const char *newunit; - uint32_t hash; - const char *oldunit; - } units[] = { - {"KiB/s", 0, "kilobytes/s"} - , {"MiB/s", 0, "MB/s"} - , {"GiB/s", 0, "GB/s"} - , {"KiB" , 0, "KB"} - , {"MiB" , 0, "MB"} - , {"GiB" , 0, "GB"} - , {"inodes" , 0, "Inodes"} - , {"percentage" , 0, "percent"} - , {"faults/s" , 0, "page faults/s"} - , {"KiB/operation", 0, "kilobytes per operation"} - , {"milliseconds/operation", 0, "ms per operation"} - , {NULL, 0, NULL} - }; - static int initialized = 0; - int i; - - if(unlikely(!initialized)) { - for (i = 0; units[i].newunit; i++) - units[i].hash = simple_hash(units[i].newunit); - initialized = 1; - } - - uint32_t hash = simple_hash(s); - for(i = 0; units[i].newunit ; i++) { - if(unlikely(hash == units[i].hash && !strcmp(s, units[i].newunit))) { - // info("matched extension for filename '%s': '%s'", filename, last_dot); - s=units[i].oldunit; - sorig = s; - break; - } - } - } - *d++ = '_'; - for(n = 1; *s && n < usable ; d++, s++, n++) { - register char c = *s; - - if(!isalnum(c)) *d = '_'; - else *d = c; - } - - if(n == 2 && sorig[0] == '%') { - n = 0; - d = ret; - s = "_percent"; - for( ; *s && n < usable ; n++) *d++ = *s++; - } - else if(n > 3 && sorig[n-3] == '/' && sorig[n-2] == 's') { - n = n - 2; - d -= 2; - s = "_persec"; - for( ; *s && n < usable ; n++) *d++ = *s++; - } - - *d = '\0'; - - return ret; -} - - -#define PROMETHEUS_ELEMENT_MAX 256 -#define PROMETHEUS_LABELS_MAX 1024 -#define PROMETHEUS_VARIABLE_MAX 256 - -#define PROMETHEUS_LABELS_MAX_NUMBER 128 - -struct host_variables_callback_options { - RRDHOST *host; - BUFFER *wb; - BACKEND_OPTIONS backend_options; - BACKENDS_PROMETHEUS_OUTPUT_OPTIONS output_options; - const char *prefix; - const char *labels; - time_t now; - int host_header_printed; - char name[PROMETHEUS_VARIABLE_MAX+1]; -}; - -static int print_host_variables(RRDVAR *rv, void *data) { - struct host_variables_callback_options *opts = data; - - if(rv->options & (RRDVAR_OPTION_CUSTOM_HOST_VAR|RRDVAR_OPTION_CUSTOM_CHART_VAR)) { - if(!opts->host_header_printed) { - opts->host_header_printed = 1; - - if(opts->output_options & BACKENDS_PROMETHEUS_OUTPUT_HELP) { - buffer_sprintf(opts->wb, "\n# COMMENT global host and chart variables\n"); - } - } - - calculated_number value = rrdvar2number(rv); - if(isnan(value) || isinf(value)) { - if(opts->output_options & BACKENDS_PROMETHEUS_OUTPUT_HELP) - buffer_sprintf(opts->wb, "# COMMENT variable \"%s\" is %s. Skipped.\n", rv->name, (isnan(value))?"NAN":"INF"); - - return 0; - } - - char *label_pre = ""; - char *label_post = ""; - if(opts->labels && *opts->labels) { - label_pre = "{"; - label_post = "}"; - } - - backends_prometheus_name_copy(opts->name, rv->name, sizeof(opts->name)); - - if(opts->output_options & BACKENDS_PROMETHEUS_OUTPUT_TIMESTAMPS) - buffer_sprintf(opts->wb - , "%s_%s%s%s%s " CALCULATED_NUMBER_FORMAT " %llu\n" - , opts->prefix - , opts->name - , label_pre - , opts->labels - , label_post - , value - , opts->now * 1000ULL - ); - else - buffer_sprintf(opts->wb, "%s_%s%s%s%s " CALCULATED_NUMBER_FORMAT "\n" - , opts->prefix - , opts->name - , label_pre - , opts->labels - , label_post - , value - ); - - return 1; - } - - return 0; -} - -static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER *wb, const char *prefix, BACKEND_OPTIONS backend_options, time_t after, time_t before, int allhosts, BACKENDS_PROMETHEUS_OUTPUT_OPTIONS output_options) { - rrdhost_rdlock(host); - - char hostname[PROMETHEUS_ELEMENT_MAX + 1]; - backends_prometheus_label_copy(hostname, host->hostname, PROMETHEUS_ELEMENT_MAX); - - char labels[PROMETHEUS_LABELS_MAX + 1] = ""; - if(allhosts) { - if(output_options & BACKENDS_PROMETHEUS_OUTPUT_TIMESTAMPS) - buffer_sprintf(wb, "netdata_info{instance=\"%s\",application=\"%s\",version=\"%s\"} 1 %llu\n", hostname, host->program_name, host->program_version, now_realtime_usec() / USEC_PER_MS); - else - buffer_sprintf(wb, "netdata_info{instance=\"%s\",application=\"%s\",version=\"%s\"} 1\n", hostname, host->program_name, host->program_version); - - if(host->tags && *(host->tags)) { - if(output_options & BACKENDS_PROMETHEUS_OUTPUT_TIMESTAMPS) { - buffer_sprintf(wb, "netdata_host_tags_info{instance=\"%s\",%s} 1 %llu\n", hostname, host->tags, now_realtime_usec() / USEC_PER_MS); - - // deprecated, exists only for compatibility with older queries - buffer_sprintf(wb, "netdata_host_tags{instance=\"%s\",%s} 1 %llu\n", hostname, host->tags, now_realtime_usec() / USEC_PER_MS); - } - else { - buffer_sprintf(wb, "netdata_host_tags_info{instance=\"%s\",%s} 1\n", hostname, host->tags); - - // deprecated, exists only for compatibility with older queries - buffer_sprintf(wb, "netdata_host_tags{instance=\"%s\",%s} 1\n", hostname, host->tags); - } - - } - - snprintfz(labels, PROMETHEUS_LABELS_MAX, ",instance=\"%s\"", hostname); - } - else { - if(output_options & BACKENDS_PROMETHEUS_OUTPUT_TIMESTAMPS) - buffer_sprintf(wb, "netdata_info{instance=\"%s\",application=\"%s\",version=\"%s\"} 1 %llu\n", hostname, host->program_name, host->program_version, now_realtime_usec() / USEC_PER_MS); - else - buffer_sprintf(wb, "netdata_info{instance=\"%s\",application=\"%s\",version=\"%s\"} 1\n", hostname, host->program_name, host->program_version); - - if(host->tags && *(host->tags)) { - if(output_options & BACKENDS_PROMETHEUS_OUTPUT_TIMESTAMPS) { - buffer_sprintf(wb, "netdata_host_tags_info{%s} 1 %llu\n", host->tags, now_realtime_usec() / USEC_PER_MS); - - // deprecated, exists only for compatibility with older queries - buffer_sprintf(wb, "netdata_host_tags{%s} 1 %llu\n", host->tags, now_realtime_usec() / USEC_PER_MS); - } - else { - buffer_sprintf(wb, "netdata_host_tags_info{%s} 1\n", host->tags); - - // deprecated, exists only for compatibility with older queries - buffer_sprintf(wb, "netdata_host_tags{%s} 1\n", host->tags); - } - } - } - - // send custom variables set for the host - if(output_options & BACKENDS_PROMETHEUS_OUTPUT_VARIABLES){ - struct host_variables_callback_options opts = { - .host = host, - .wb = wb, - .labels = (labels[0] == ',')?&labels[1]:labels, - .backend_options = backend_options, - .output_options = output_options, - .prefix = prefix, - .now = now_realtime_sec(), - .host_header_printed = 0 - }; - foreach_host_variable_callback(host, print_host_variables, &opts); - } - - // for each chart - RRDSET *st; - rrdset_foreach_read(st, host) { - char chart[PROMETHEUS_ELEMENT_MAX + 1]; - char context[PROMETHEUS_ELEMENT_MAX + 1]; - char family[PROMETHEUS_ELEMENT_MAX + 1]; - char units[PROMETHEUS_ELEMENT_MAX + 1] = ""; - - backends_prometheus_label_copy(chart, (output_options & BACKENDS_PROMETHEUS_OUTPUT_NAMES && st->name)?st->name:st->id, PROMETHEUS_ELEMENT_MAX); - backends_prometheus_label_copy(family, st->family, PROMETHEUS_ELEMENT_MAX); - backends_prometheus_name_copy(context, st->context, PROMETHEUS_ELEMENT_MAX); - - if(likely(backends_can_send_rrdset(backend_options, st))) { - rrdset_rdlock(st); - - int as_collected = (BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED); - int homogeneous = 1; - if(as_collected) { - if(rrdset_flag_check(st, RRDSET_FLAG_HOMOGENEOUS_CHECK)) - rrdset_update_heterogeneous_flag(st); - - if(rrdset_flag_check(st, RRDSET_FLAG_HETEROGENEOUS)) - homogeneous = 0; - } - else { - if(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_AVERAGE && !(output_options & BACKENDS_PROMETHEUS_OUTPUT_HIDEUNITS)) - backends_prometheus_units_copy(units, st->units, PROMETHEUS_ELEMENT_MAX, output_options & BACKENDS_PROMETHEUS_OUTPUT_OLDUNITS); - } - - if(unlikely(output_options & BACKENDS_PROMETHEUS_OUTPUT_HELP)) - buffer_sprintf(wb, "\n# COMMENT %s chart \"%s\", context \"%s\", family \"%s\", units \"%s\"\n" - , (homogeneous)?"homogeneous":"heterogeneous" - , (output_options & BACKENDS_PROMETHEUS_OUTPUT_NAMES && st->name) ? st->name : st->id - , st->context - , st->family - , st->units - ); - - // for each dimension - RRDDIM *rd; - rrddim_foreach_read(rd, st) { - if(rd->collections_counter && !rrddim_flag_check(rd, RRDDIM_FLAG_OBSOLETE)) { - char dimension[PROMETHEUS_ELEMENT_MAX + 1]; - char *suffix = ""; - - if (as_collected) { - // we need as-collected / raw data - - if(unlikely(rd->last_collected_time.tv_sec < after)) - continue; - - const char *t = "gauge", *h = "gives"; - if(rd->algorithm == RRD_ALGORITHM_INCREMENTAL || - rd->algorithm == RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL) { - t = "counter"; - h = "delta gives"; - suffix = "_total"; - } - - if(homogeneous) { - // all the dimensions of the chart, has the same algorithm, multiplier and divisor - // we add all dimensions as labels - - backends_prometheus_label_copy(dimension, (output_options & BACKENDS_PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX); - - if(unlikely(output_options & BACKENDS_PROMETHEUS_OUTPUT_HELP)) - buffer_sprintf(wb - , "# COMMENT %s_%s%s: chart \"%s\", context \"%s\", family \"%s\", dimension \"%s\", value * " COLLECTED_NUMBER_FORMAT " / " COLLECTED_NUMBER_FORMAT " %s %s (%s)\n" - , prefix - , context - , suffix - , (output_options & BACKENDS_PROMETHEUS_OUTPUT_NAMES && st->name) ? st->name : st->id - , st->context - , st->family - , (output_options & BACKENDS_PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id - , rd->multiplier - , rd->divisor - , h - , st->units - , t - ); - - if(unlikely(output_options & BACKENDS_PROMETHEUS_OUTPUT_TYPES)) - buffer_sprintf(wb, "# TYPE %s_%s%s %s\n" - , prefix - , context - , suffix - , t - ); - - if(output_options & BACKENDS_PROMETHEUS_OUTPUT_TIMESTAMPS) - buffer_sprintf(wb - , "%s_%s%s{chart=\"%s\",family=\"%s\",dimension=\"%s\"%s} " COLLECTED_NUMBER_FORMAT " %llu\n" - , prefix - , context - , suffix - , chart - , family - , dimension - , labels - , rd->last_collected_value - , timeval_msec(&rd->last_collected_time) - ); - else - buffer_sprintf(wb - , "%s_%s%s{chart=\"%s\",family=\"%s\",dimension=\"%s\"%s} " COLLECTED_NUMBER_FORMAT "\n" - , prefix - , context - , suffix - , chart - , family - , dimension - , labels - , rd->last_collected_value - ); - } - else { - // the dimensions of the chart, do not have the same algorithm, multiplier or divisor - // we create a metric per dimension - - backends_prometheus_name_copy(dimension, (output_options & BACKENDS_PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX); - - if(unlikely(output_options & BACKENDS_PROMETHEUS_OUTPUT_HELP)) - buffer_sprintf(wb - , "# COMMENT %s_%s_%s%s: chart \"%s\", context \"%s\", family \"%s\", dimension \"%s\", value * " COLLECTED_NUMBER_FORMAT " / " COLLECTED_NUMBER_FORMAT " %s %s (%s)\n" - , prefix - , context - , dimension - , suffix - , (output_options & BACKENDS_PROMETHEUS_OUTPUT_NAMES && st->name) ? st->name : st->id - , st->context - , st->family - , (output_options & BACKENDS_PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id - , rd->multiplier - , rd->divisor - , h - , st->units - , t - ); - - if(unlikely(output_options & BACKENDS_PROMETHEUS_OUTPUT_TYPES)) - buffer_sprintf(wb, "# TYPE %s_%s_%s%s %s\n" - , prefix - , context - , dimension - , suffix - , t - ); - - if(output_options & BACKENDS_PROMETHEUS_OUTPUT_TIMESTAMPS) - buffer_sprintf(wb - , "%s_%s_%s%s{chart=\"%s\",family=\"%s\"%s} " COLLECTED_NUMBER_FORMAT " %llu\n" - , prefix - , context - , dimension - , suffix - , chart - , family - , labels - , rd->last_collected_value - , timeval_msec(&rd->last_collected_time) - ); - else - buffer_sprintf(wb - , "%s_%s_%s%s{chart=\"%s\",family=\"%s\"%s} " COLLECTED_NUMBER_FORMAT "\n" - , prefix - , context - , dimension - , suffix - , chart - , family - , labels - , rd->last_collected_value - ); - } - } - else { - // we need average or sum of the data - - time_t first_t = after, last_t = before; - calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, backend_options, &first_t, &last_t); - - if(!isnan(value) && !isinf(value)) { - - if(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_AVERAGE) - suffix = "_average"; - else if(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_SUM) - suffix = "_sum"; - - backends_prometheus_label_copy(dimension, (output_options & BACKENDS_PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX); - - if (unlikely(output_options & BACKENDS_PROMETHEUS_OUTPUT_HELP)) - buffer_sprintf(wb, "# COMMENT %s_%s%s%s: dimension \"%s\", value is %s, gauge, dt %llu to %llu inclusive\n" - , prefix - , context - , units - , suffix - , (output_options & BACKENDS_PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id - , st->units - , (unsigned long long)first_t - , (unsigned long long)last_t - ); - - if (unlikely(output_options & BACKENDS_PROMETHEUS_OUTPUT_TYPES)) - buffer_sprintf(wb, "# TYPE %s_%s%s%s gauge\n" - , prefix - , context - , units - , suffix - ); - - if(output_options & BACKENDS_PROMETHEUS_OUTPUT_TIMESTAMPS) - buffer_sprintf(wb, "%s_%s%s%s{chart=\"%s\",family=\"%s\",dimension=\"%s\"%s} " CALCULATED_NUMBER_FORMAT " %llu\n" - , prefix - , context - , units - , suffix - , chart - , family - , dimension - , labels - , value - , last_t * MSEC_PER_SEC - ); - else - buffer_sprintf(wb, "%s_%s%s%s{chart=\"%s\",family=\"%s\",dimension=\"%s\"%s} " CALCULATED_NUMBER_FORMAT "\n" - , prefix - , context - , units - , suffix - , chart - , family - , dimension - , labels - , value - ); - } - } - } - } - - rrdset_unlock(st); - } - } - - rrdhost_unlock(host); -} - -#if ENABLE_PROMETHEUS_REMOTE_WRITE -inline static void remote_write_split_words(char *str, char **words, int max_words) { - char *s = str; - int i = 0; - - while(*s && i < max_words - 1) { - while(*s && isspace(*s)) s++; // skip spaces to the beginning of a tag name - - if(*s) - words[i] = s; - - while(*s && !isspace(*s) && *s != '=') s++; // find the end of the tag name - - if(*s != '=') { - words[i] = NULL; - break; - } - *s = '\0'; - s++; - i++; - - while(*s && isspace(*s)) s++; // skip spaces to the beginning of a tag value - - if(*s && *s == '"') s++; // strip an opening quote - if(*s) - words[i] = s; - - while(*s && !isspace(*s) && *s != ',') s++; // find the end of the tag value - - if(*s && *s != ',') { - words[i] = NULL; - break; - } - if(s != words[i] && *(s - 1) == '"') *(s - 1) = '\0'; // strip a closing quote - if(*s != '\0') { - *s = '\0'; - s++; - i++; - } - } -} - -void backends_rrd_stats_remote_write_allmetrics_prometheus( - RRDHOST *host - , const char *__hostname - , const char *prefix - , BACKEND_OPTIONS backend_options - , time_t after - , time_t before - , size_t *count_charts - , size_t *count_dims - , size_t *count_dims_skipped -) { - char hostname[PROMETHEUS_ELEMENT_MAX + 1]; - backends_prometheus_label_copy(hostname, __hostname, PROMETHEUS_ELEMENT_MAX); - - backends_add_host_info("netdata_info", hostname, host->program_name, host->program_version, now_realtime_usec() / USEC_PER_MS); - - if(host->tags && *(host->tags)) { - char tags[PROMETHEUS_LABELS_MAX + 1]; - strncpy(tags, host->tags, PROMETHEUS_LABELS_MAX); - char *words[PROMETHEUS_LABELS_MAX_NUMBER] = {NULL}; - int i; - - remote_write_split_words(tags, words, PROMETHEUS_LABELS_MAX_NUMBER); - - backends_add_host_info("netdata_host_tags_info", hostname, NULL, NULL, now_realtime_usec() / USEC_PER_MS); - - for(i = 0; words[i] != NULL && words[i + 1] != NULL && (i + 1) < PROMETHEUS_LABELS_MAX_NUMBER; i += 2) { - backends_add_tag(words[i], words[i + 1]); - } - } - - // for each chart - RRDSET *st; - rrdset_foreach_read(st, host) { - char chart[PROMETHEUS_ELEMENT_MAX + 1]; - char context[PROMETHEUS_ELEMENT_MAX + 1]; - char family[PROMETHEUS_ELEMENT_MAX + 1]; - char units[PROMETHEUS_ELEMENT_MAX + 1] = ""; - - backends_prometheus_label_copy(chart, (backend_options & BACKEND_OPTION_SEND_NAMES && st->name)?st->name:st->id, PROMETHEUS_ELEMENT_MAX); - backends_prometheus_label_copy(family, st->family, PROMETHEUS_ELEMENT_MAX); - backends_prometheus_name_copy(context, st->context, PROMETHEUS_ELEMENT_MAX); - - if(likely(backends_can_send_rrdset(backend_options, st))) { - rrdset_rdlock(st); - - (*count_charts)++; - - int as_collected = (BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED); - int homogeneous = 1; - if(as_collected) { - if(rrdset_flag_check(st, RRDSET_FLAG_HOMOGENEOUS_CHECK)) - rrdset_update_heterogeneous_flag(st); - - if(rrdset_flag_check(st, RRDSET_FLAG_HETEROGENEOUS)) - homogeneous = 0; - } - else { - if(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_AVERAGE) - backends_prometheus_units_copy(units, st->units, PROMETHEUS_ELEMENT_MAX, 0); - } - - // for each dimension - RRDDIM *rd; - rrddim_foreach_read(rd, st) { - if(rd->collections_counter && !rrddim_flag_check(rd, RRDDIM_FLAG_OBSOLETE)) { - char name[PROMETHEUS_LABELS_MAX + 1]; - char dimension[PROMETHEUS_ELEMENT_MAX + 1]; - char *suffix = ""; - - if (as_collected) { - // we need as-collected / raw data - - if(unlikely(rd->last_collected_time.tv_sec < after)) { - debug(D_BACKEND, "BACKEND: not sending dimension '%s' of chart '%s' from host '%s', its last data collection (%lu) is not within our timeframe (%lu to %lu)", rd->id, st->id, __hostname, (unsigned long)rd->last_collected_time.tv_sec, (unsigned long)after, (unsigned long)before); - (*count_dims_skipped)++; - continue; - } - - if(homogeneous) { - // all the dimensions of the chart, has the same algorithm, multiplier and divisor - // we add all dimensions as labels - - backends_prometheus_label_copy(dimension, (backend_options & BACKEND_OPTION_SEND_NAMES && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX); - snprintf(name, PROMETHEUS_LABELS_MAX, "%s_%s%s", prefix, context, suffix); - - backends_add_metric(name, chart, family, dimension, hostname, rd->last_collected_value, timeval_msec(&rd->last_collected_time)); - (*count_dims)++; - } - else { - // the dimensions of the chart, do not have the same algorithm, multiplier or divisor - // we create a metric per dimension - - backends_prometheus_name_copy(dimension, (backend_options & BACKEND_OPTION_SEND_NAMES && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX); - snprintf(name, PROMETHEUS_LABELS_MAX, "%s_%s_%s%s", prefix, context, dimension, suffix); - - backends_add_metric(name, chart, family, NULL, hostname, rd->last_collected_value, timeval_msec(&rd->last_collected_time)); - (*count_dims)++; - } - } - else { - // we need average or sum of the data - - time_t first_t = after, last_t = before; - calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, backend_options, &first_t, &last_t); - - if(!isnan(value) && !isinf(value)) { - - if(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_AVERAGE) - suffix = "_average"; - else if(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_SUM) - suffix = "_sum"; - - backends_prometheus_label_copy(dimension, (backend_options & BACKEND_OPTION_SEND_NAMES && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX); - snprintf(name, PROMETHEUS_LABELS_MAX, "%s_%s%s%s", prefix, context, units, suffix); - - backends_add_metric(name, chart, family, dimension, hostname, value, last_t * MSEC_PER_SEC); - (*count_dims)++; - } - } - } - } - - rrdset_unlock(st); - } - } -} -#endif /* ENABLE_PROMETHEUS_REMOTE_WRITE */ - -static inline time_t prometheus_preparation(RRDHOST *host, BUFFER *wb, BACKEND_OPTIONS backend_options, const char *server, time_t now, BACKENDS_PROMETHEUS_OUTPUT_OPTIONS output_options) { - if(!server || !*server) server = "default"; - - time_t after = prometheus_server_last_access(server, host, now); - - int first_seen = 0; - if(!after) { - after = now - global_backend_update_every; - first_seen = 1; - } - - if(after > now) { - // oops! this should never happen - after = now - global_backend_update_every; - } - - if(output_options & BACKENDS_PROMETHEUS_OUTPUT_HELP) { - char *mode; - if(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED) - mode = "as collected"; - else if(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_AVERAGE) - mode = "average"; - else if(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_SUM) - mode = "sum"; - else - mode = "unknown"; - - buffer_sprintf(wb, "# COMMENT netdata \"%s\" to %sprometheus \"%s\", source \"%s\", last seen %lu %s, time range %lu to %lu\n\n" - , host->hostname - , (first_seen)?"FIRST SEEN ":"" - , server - , mode - , (unsigned long)((first_seen)?0:(now - after)) - , (first_seen)?"never":"seconds ago" - , (unsigned long)after, (unsigned long)now - ); - } - - return after; -} - -void backends_rrd_stats_api_v1_charts_allmetrics_prometheus_single_host(RRDHOST *host, BUFFER *wb, const char *server, const char *prefix, BACKEND_OPTIONS backend_options, BACKENDS_PROMETHEUS_OUTPUT_OPTIONS output_options) { - time_t before = now_realtime_sec(); - - // we start at the point we had stopped before - time_t after = prometheus_preparation(host, wb, backend_options, server, before, output_options); - - rrd_stats_api_v1_charts_allmetrics_prometheus(host, wb, prefix, backend_options, after, before, 0, output_options); -} - -void backends_rrd_stats_api_v1_charts_allmetrics_prometheus_all_hosts(RRDHOST *host, BUFFER *wb, const char *server, const char *prefix, BACKEND_OPTIONS backend_options, BACKENDS_PROMETHEUS_OUTPUT_OPTIONS output_options) { - time_t before = now_realtime_sec(); - - // we start at the point we had stopped before - time_t after = prometheus_preparation(host, wb, backend_options, server, before, output_options); - - rrd_rdlock(); - rrdhost_foreach_read(host) { - rrd_stats_api_v1_charts_allmetrics_prometheus(host, wb, prefix, backend_options, after, before, 1, output_options); - } - rrd_unlock(); -} - -#if ENABLE_PROMETHEUS_REMOTE_WRITE -int backends_process_prometheus_remote_write_response(BUFFER *b) { - if(unlikely(!b)) return 1; - - const char *s = buffer_tostring(b); - int len = buffer_strlen(b); - - // do nothing with HTTP responses 200 or 204 - - while(!isspace(*s) && len) { - s++; - len--; - } - s++; - len--; - - if(likely(len > 4 && (!strncmp(s, "200 ", 4) || !strncmp(s, "204 ", 4)))) - return 0; - else - return discard_response(b, "prometheus remote write"); -} -#endif diff --git a/backends/prometheus/backend_prometheus.h b/backends/prometheus/backend_prometheus.h deleted file mode 100644 index 8c14ddc26..000000000 --- a/backends/prometheus/backend_prometheus.h +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -#ifndef NETDATA_BACKEND_PROMETHEUS_H -#define NETDATA_BACKEND_PROMETHEUS_H 1 - -#include "backends/backends.h" - -typedef enum backends_prometheus_output_flags { - BACKENDS_PROMETHEUS_OUTPUT_NONE = 0, - BACKENDS_PROMETHEUS_OUTPUT_HELP = (1 << 0), - BACKENDS_PROMETHEUS_OUTPUT_TYPES = (1 << 1), - BACKENDS_PROMETHEUS_OUTPUT_NAMES = (1 << 2), - BACKENDS_PROMETHEUS_OUTPUT_TIMESTAMPS = (1 << 3), - BACKENDS_PROMETHEUS_OUTPUT_VARIABLES = (1 << 4), - BACKENDS_PROMETHEUS_OUTPUT_OLDUNITS = (1 << 5), - BACKENDS_PROMETHEUS_OUTPUT_HIDEUNITS = (1 << 6) -} BACKENDS_PROMETHEUS_OUTPUT_OPTIONS; - -extern void backends_rrd_stats_api_v1_charts_allmetrics_prometheus_single_host(RRDHOST *host, BUFFER *wb, const char *server, const char *prefix, BACKEND_OPTIONS backend_options, BACKENDS_PROMETHEUS_OUTPUT_OPTIONS output_options); -extern void backends_rrd_stats_api_v1_charts_allmetrics_prometheus_all_hosts(RRDHOST *host, BUFFER *wb, const char *server, const char *prefix, BACKEND_OPTIONS backend_options, BACKENDS_PROMETHEUS_OUTPUT_OPTIONS output_options); - -#if ENABLE_PROMETHEUS_REMOTE_WRITE -extern void backends_rrd_stats_remote_write_allmetrics_prometheus( - RRDHOST *host - , const char *__hostname - , const char *prefix - , BACKEND_OPTIONS backend_options - , time_t after - , time_t before - , size_t *count_charts - , size_t *count_dims - , size_t *count_dims_skipped -); -extern int backends_process_prometheus_remote_write_response(BUFFER *b); -#endif - -#endif //NETDATA_BACKEND_PROMETHEUS_H diff --git a/backends/prometheus/remote_write/Makefile.am b/backends/prometheus/remote_write/Makefile.am deleted file mode 100644 index d049ef48c..000000000 --- a/backends/prometheus/remote_write/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later - -AUTOMAKE_OPTIONS = subdir-objects -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in - -CLEANFILES = \ - remote_write.pb.cc \ - remote_write.pb.h \ - $(NULL) - -dist_noinst_DATA = \ - remote_write.proto \ - README.md \ - $(NULL) diff --git a/backends/prometheus/remote_write/README.md b/backends/prometheus/remote_write/README.md deleted file mode 100644 index b83575e10..000000000 --- a/backends/prometheus/remote_write/README.md +++ /dev/null @@ -1,41 +0,0 @@ - - -# Prometheus remote write backend - -## Prerequisites - -To use the prometheus remote write API with [storage -providers](https://prometheus.io/docs/operating/integrations/#remote-endpoints-and-storage) -[protobuf](https://developers.google.com/protocol-buffers/) and [snappy](https://github.com/google/snappy) libraries -should be installed first. Next, Netdata should be re-installed from the source. The installer will detect that the -required libraries and utilities are now available. - -## Configuration - -An additional option in the backend configuration section is available for the remote write backend: - -```conf -[backend] - remote write URL path = /receive -``` - -The default value is `/receive`. `remote write URL path` is used to set an endpoint path for the remote write protocol. -For example, if your endpoint is `http://example.domain:example_port/storage/read` you should set - -```conf -[backend] - destination = example.domain:example_port - remote write URL path = /storage/read -``` - -`buffered` and `lost` dimensions in the Netdata Backend Data Size operation monitoring chart estimate uncompressed -buffer size on failures. - -## Notes - -The remote write backend does not support `buffer on failures` - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fbackends%2Fprometheus%2Fremote_write%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) diff --git a/backends/prometheus/remote_write/remote_write.cc b/backends/prometheus/remote_write/remote_write.cc deleted file mode 100644 index b919cffad..000000000 --- a/backends/prometheus/remote_write/remote_write.cc +++ /dev/null @@ -1,120 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -#include -#include "exporting/prometheus/remote_write/remote_write.pb.h" -#include "remote_write.h" - -using namespace prometheus; - -static google::protobuf::Arena arena; -static WriteRequest *write_request; - -void backends_init_write_request() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - write_request = google::protobuf::Arena::CreateMessage(&arena); -} - -void backends_clear_write_request() { - write_request->clear_timeseries(); -} - -void backends_add_host_info(const char *name, const char *instance, const char *application, const char *version, const int64_t timestamp) { - TimeSeries *timeseries; - Sample *sample; - Label *label; - - timeseries = write_request->add_timeseries(); - - label = timeseries->add_labels(); - label->set_name("__name__"); - label->set_value(name); - - label = timeseries->add_labels(); - label->set_name("instance"); - label->set_value(instance); - - if(application) { - label = timeseries->add_labels(); - label->set_name("application"); - label->set_value(application); - } - - if(version) { - label = timeseries->add_labels(); - label->set_name("version"); - label->set_value(version); - } - - sample = timeseries->add_samples(); - sample->set_value(1); - sample->set_timestamp(timestamp); -} - -// adds tag to the last created timeseries -void backends_add_tag(char *tag, char *value) { - TimeSeries *timeseries; - Label *label; - - timeseries = write_request->mutable_timeseries(write_request->timeseries_size() - 1); - - label = timeseries->add_labels(); - label->set_name(tag); - label->set_value(value); -} - -void backends_add_metric(const char *name, const char *chart, const char *family, const char *dimension, const char *instance, const double value, const int64_t timestamp) { - TimeSeries *timeseries; - Sample *sample; - Label *label; - - timeseries = write_request->add_timeseries(); - - label = timeseries->add_labels(); - label->set_name("__name__"); - label->set_value(name); - - label = timeseries->add_labels(); - label->set_name("chart"); - label->set_value(chart); - - label = timeseries->add_labels(); - label->set_name("family"); - label->set_value(family); - - if(dimension) { - label = timeseries->add_labels(); - label->set_name("dimension"); - label->set_value(dimension); - } - - label = timeseries->add_labels(); - label->set_name("instance"); - label->set_value(instance); - - sample = timeseries->add_samples(); - sample->set_value(value); - sample->set_timestamp(timestamp); -} - -size_t backends_get_write_request_size(){ -#if GOOGLE_PROTOBUF_VERSION < 3001000 - size_t size = (size_t)snappy::MaxCompressedLength(write_request->ByteSize()); -#else - size_t size = (size_t)snappy::MaxCompressedLength(write_request->ByteSizeLong()); -#endif - - return (size < INT_MAX)?size:0; -} - -int backends_pack_write_request(char *buffer, size_t *size) { - std::string uncompressed_write_request; - if(write_request->SerializeToString(&uncompressed_write_request) == false) return 1; - - snappy::RawCompress(uncompressed_write_request.data(), uncompressed_write_request.size(), buffer, size); - - return 0; -} - -void backends_protocol_buffers_shutdown() { - google::protobuf::ShutdownProtobufLibrary(); -} diff --git a/backends/prometheus/remote_write/remote_write.h b/backends/prometheus/remote_write/remote_write.h deleted file mode 100644 index 1307d7281..000000000 --- a/backends/prometheus/remote_write/remote_write.h +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -#ifndef NETDATA_BACKEND_PROMETHEUS_REMOTE_WRITE_H -#define NETDATA_BACKEND_PROMETHEUS_REMOTE_WRITE_H - -#ifdef __cplusplus -extern "C" { -#endif - -void backends_init_write_request(); - -void backends_clear_write_request(); - -void backends_add_host_info(const char *name, const char *instance, const char *application, const char *version, const int64_t timestamp); - -void backends_add_tag(char *tag, char *value); - -void backends_add_metric(const char *name, const char *chart, const char *family, const char *dimension, const char *instance, const double value, const int64_t timestamp); - -size_t backends_get_write_request_size(); - -int backends_pack_write_request(char *buffer, size_t *size); - -void backends_protocol_buffers_shutdown(); - -#ifdef __cplusplus -} -#endif - -#endif //NETDATA_BACKEND_PROMETHEUS_REMOTE_WRITE_H diff --git a/backends/prometheus/remote_write/remote_write.proto b/backends/prometheus/remote_write/remote_write.proto deleted file mode 100644 index dfde254e1..000000000 --- a/backends/prometheus/remote_write/remote_write.proto +++ /dev/null @@ -1,29 +0,0 @@ -syntax = "proto3"; -package prometheus; - -option cc_enable_arenas = true; - -import "google/protobuf/descriptor.proto"; - -message WriteRequest { - repeated TimeSeries timeseries = 1 [(nullable) = false]; -} - -message TimeSeries { - repeated Label labels = 1 [(nullable) = false]; - repeated Sample samples = 2 [(nullable) = false]; -} - -message Label { - string name = 1; - string value = 2; -} - -message Sample { - double value = 1; - int64 timestamp = 2; -} - -extend google.protobuf.FieldOptions { - bool nullable = 65001; -} diff --git a/build/m4/ax_pthread.m4 b/build/m4/ax_pthread.m4 index ba9ac28a5..9f35d1391 100644 --- a/build/m4/ax_pthread.m4 +++ b/build/m4/ax_pthread.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_pthread.html +# https://www.gnu.org/software/autoconf-archive/ax_pthread.html # =========================================================================== # # SYNOPSIS @@ -14,24 +14,28 @@ # flags that are needed. (The user can also force certain compiler # flags/libs to be tested by setting these environment variables.) # -# Also sets PTHREAD_CC to any special C compiler that is needed for -# multi-threaded programs (defaults to the value of CC otherwise). (This -# is necessary on AIX to use the special cc_r compiler alias.) +# Also sets PTHREAD_CC and PTHREAD_CXX to any special C compiler that is +# needed for multi-threaded programs (defaults to the value of CC +# respectively CXX otherwise). (This is necessary on e.g. AIX to use the +# special cc_r/CC_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, -# but also link it with them as well. e.g. you should link with +# but also to link with them as well. For example, you might link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# $PTHREAD_CXX $CXXFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # -# If you are only building threads programs, you may wish to use these +# If you are only building threaded programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS" # CC="$PTHREAD_CC" +# CXX="$PTHREAD_CXX" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant -# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name -# (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to +# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the # PTHREAD_PRIO_INHERIT symbol is defined when compiling with @@ -55,38 +59,69 @@ # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2011 Daniel Richard G. +# Copyright (c) 2019 Marc Stevens # -# SPDX-License-Identifier: GPL-3.0-or-later +# 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 . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. -#serial 21 +#serial 31 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_PROG_SED]) AC_LANG_PUSH([C]) ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h -# requires special compiler flags (e.g. on True64 or Sequent). +# requires special compiler flags (e.g. on Tru64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: -if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then - save_CFLAGS="$CFLAGS" +if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then + ax_pthread_save_CC="$CC" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) + AS_IF([test "x$PTHREAD_CXX" != "x"], [CXX="$PTHREAD_CXX"]) CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" - AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) - AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes]) + AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) + AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) AC_MSG_RESULT([$ax_pthread_ok]) - if test x"$ax_pthread_ok" = xno; then + if test "x$ax_pthread_ok" = "xno"; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" + CC="$ax_pthread_save_CC" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" fi # We must check for the threads library under a number of different @@ -94,12 +129,14 @@ fi # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). -# Create a list of thread flags to try. Items starting with a "-" are -# C compiler flags, and other items are library names, except for "none" -# which indicates that we try without any flags at all, and "pthread-config" -# which is a program returning the flags for the Pth emulation library. +# Create a list of thread flags to try. Items with a "," contain both +# C compiler flags (before ",") and linker flags (after ","). Other items +# starting with a "-" are C compiler flags, and remaining items are +# library names, except for "none" which indicates that we try without +# any flags at all, and "pthread-config" which is a program returning +# the flags for the Pth emulation library. -ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" +ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: @@ -108,82 +145,163 @@ ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mt # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) -# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) -# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) -# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) -# -pthreads: Solaris/gcc -# -mthreads: Mingw32/gcc, Lynx/gcc +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 +# (Note: HP C rejects this with "bad form for `-t' option") +# -pthreads: Solaris/gcc (Note: HP C also rejects) # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it -# doesn't hurt to check since this sometimes defines pthreads too; -# also defines -D_REENTRANT) -# ... -mt is also the pthreads flag for HP/aCC +# doesn't hurt to check since this sometimes defines pthreads and +# -D_REENTRANT too), HP C (must be checked before -lpthread, which +# is present but should not be used directly; and before -mthreads, +# because the compiler interprets this as "-mt" + "-hreads") +# -mthreads: Mingw32/gcc, Lynx/gcc # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) -case ${host_os} in +case $host_os in + + freebsd*) + + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) + + ax_pthread_flags="-kthread lthread $ax_pthread_flags" + ;; + + hpux*) + + # From the cc(1) man page: "[-mt] Sets various -D flags to enable + # multi-threading and also sets -lpthread." + + ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" + ;; + + openedition*) + + # IBM z/OS requires a feature-test macro to be defined in order to + # enable POSIX threads at all, so give the user a hint if this is + # not set. (We don't define these ourselves, as they can affect + # other portions of the system API in unpredictable ways.) + + AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], + [ +# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) + AX_PTHREAD_ZOS_MISSING +# endif + ], + [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) + ;; + solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based - # tests will erroneously succeed. (We need to link with -pthreads/-mt/ - # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather - # a function called by this macro, so we could check for that, but - # who knows whether they'll stub that too in a future libc.) So, - # we'll just look for -pthreads and -lpthread first: + # tests will erroneously succeed. (N.B.: The stubs are missing + # pthread_cleanup_push, or rather a function called by this macro, + # so we could check for that, but who knows whether they'll stub + # that too in a future libc.) So we'll check first for the + # standard Solaris way of linking pthreads (-mt -lpthread). + + ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags" + ;; +esac + +# Are we compiling with Clang? + +AC_CACHE_CHECK([whether $CC is Clang], + [ax_cv_PTHREAD_CLANG], + [ax_cv_PTHREAD_CLANG=no + # Note that Autoconf sets GCC=yes for Clang as well as GCC + if test "x$GCC" = "xyes"; then + AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], + [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +# if defined(__clang__) && defined(__llvm__) + AX_PTHREAD_CC_IS_CLANG +# endif + ], + [ax_cv_PTHREAD_CLANG=yes]) + fi + ]) +ax_pthread_clang="$ax_cv_PTHREAD_CLANG" + + +# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) + +# Note that for GCC and Clang -pthread generally implies -lpthread, +# except when -nostdlib is passed. +# This is problematic using libtool to build C++ shared libraries with pthread: +# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460 +# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333 +# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555 +# To solve this, first try -pthread together with -lpthread for GCC + +AS_IF([test "x$GCC" = "xyes"], + [ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"]) - ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" +# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first + +AS_IF([test "x$ax_pthread_clang" = "xyes"], + [ax_pthread_flags="-pthread,-lpthread -pthread"]) + + +# The presence of a feature test macro requesting re-entrant function +# definitions is, on some systems, a strong hint that pthreads support is +# correctly enabled + +case $host_os in + darwin* | hpux* | linux* | osf* | solaris*) + ax_pthread_check_macro="_REENTRANT" ;; - darwin*) - ax_pthread_flags="-pthread $ax_pthread_flags" + aix*) + ax_pthread_check_macro="_THREAD_SAFE" ;; -esac -# Clang doesn't consider unrecognized options an error unless we specify -# -Werror. We throw in some extra Clang-specific options to ensure that -# this doesn't happen for GCC, which also accepts -Werror. + *) + ax_pthread_check_macro="--" + ;; +esac +AS_IF([test "x$ax_pthread_check_macro" = "x--"], + [ax_pthread_check_cond=0], + [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) -AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags]) -save_CFLAGS="$CFLAGS" -ax_pthread_extra_flags="-Werror" -CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument" -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])], - [AC_MSG_RESULT([yes])], - [ax_pthread_extra_flags= - AC_MSG_RESULT([no])]) -CFLAGS="$save_CFLAGS" -if test x"$ax_pthread_ok" = xno; then -for flag in $ax_pthread_flags; do +if test "x$ax_pthread_ok" = "xno"; then +for ax_pthread_try_flag in $ax_pthread_flags; do - case $flag in + case $ax_pthread_try_flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; + *,*) + PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"` + PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"` + AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"]) + ;; + -*) - AC_MSG_CHECKING([whether pthreads work with $flag]) - PTHREAD_CFLAGS="$flag" + AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) + PTHREAD_CFLAGS="$ax_pthread_try_flag" ;; pthread-config) AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) - if test x"$ax_pthread_config" = xno; then continue; fi + AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) - AC_MSG_CHECKING([for the pthreads library -l$flag]) - PTHREAD_LIBS="-l$flag" + AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) + PTHREAD_LIBS="-l$ax_pthread_try_flag" ;; esac - save_LIBS="$LIBS" - save_CFLAGS="$CFLAGS" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we @@ -194,8 +312,18 @@ for flag in $ax_pthread_flags; do # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include - static void routine(void *a) { a = 0; } +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif + static void *some_global = NULL; + static void routine(void *a) + { + /* To avoid any unused-parameter or + unused-but-set-parameter warning. */ + some_global = a; + } static void *start_routine(void *a) { return a; }], [pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); @@ -203,101 +331,187 @@ for flag in $ax_pthread_flags; do pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */])], - [ax_pthread_ok=yes], - []) + [ax_pthread_ok=yes], + []) - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" AC_MSG_RESULT([$ax_pthread_ok]) - if test "x$ax_pthread_ok" = xyes; then - break; - fi + AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi + +# Clang needs special handling, because older versions handle the -pthread +# option in a rather... idiosyncratic way + +if test "x$ax_pthread_clang" = "xyes"; then + + # Clang takes -pthread; it has never supported any other flag + + # (Note 1: This will need to be revisited if a system that Clang + # supports has POSIX threads in a separate library. This tends not + # to be the way of modern systems, but it's conceivable.) + + # (Note 2: On some systems, notably Darwin, -pthread is not needed + # to get POSIX threads support; the API is always present and + # active. We could reasonably leave PTHREAD_CFLAGS empty. But + # -pthread does define _REENTRANT, and while the Darwin headers + # ignore this macro, third-party headers might not.) + + # However, older versions of Clang make a point of warning the user + # that, in an invocation where only linking and no compilation is + # taking place, the -pthread option has no effect ("argument unused + # during compilation"). They expect -pthread to be passed in only + # when source code is being compiled. + # + # Problem is, this is at odds with the way Automake and most other + # C build frameworks function, which is that the same flags used in + # compilation (CFLAGS) are also used in linking. Many systems + # supported by AX_PTHREAD require exactly this for POSIX threads + # support, and in fact it is often not straightforward to specify a + # flag that is used only in the compilation phase and not in + # linking. Such a scenario is extremely rare in practice. + # + # Even though use of the -pthread flag in linking would only print + # a warning, this can be a nuisance for well-run software projects + # that build with -Werror. So if the active version of Clang has + # this misfeature, we search for an option to squash it. + + AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown + # Create an alternate version of $ac_link that compiles and + # links in two steps (.c -> .o, .o -> exe) instead of one + # (.c -> exe), because the warning occurs only in the second + # step + ax_pthread_save_ac_link="$ac_link" + ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' + ax_pthread_link_step=`AS_ECHO(["$ac_link"]) | sed "$ax_pthread_sed"` + ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" + ax_pthread_save_CFLAGS="$CFLAGS" + for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do + AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) + CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" + ac_link="$ax_pthread_save_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [ac_link="$ax_pthread_2step_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [break]) + ]) + done + ac_link="$ax_pthread_save_ac_link" + CFLAGS="$ax_pthread_save_CFLAGS" + AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" + ]) + + case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in + no | unknown) ;; + *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; + esac + +fi # $ax_pthread_clang = yes + + + # Various other checks: -if test "x$ax_pthread_ok" = xyes; then - save_LIBS="$LIBS" - LIBS="$PTHREAD_LIBS $LIBS" - save_CFLAGS="$CFLAGS" +if test "x$ax_pthread_ok" = "xyes"; then + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. - AC_MSG_CHECKING([for joinable pthread attribute]) - attr_name=unknown - for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], - [int attr = $attr; return attr /* ; */])], - [attr_name=$attr; break], - []) - done - AC_MSG_RESULT([$attr_name]) - if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then - AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name], - [Define to necessary symbol if this constant - uses a non-standard name on your system.]) - fi - - AC_MSG_CHECKING([if more special flags are required for pthreads]) - flag=no - case ${host_os} in - aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; - osf* | hpux*) flag="-D_REENTRANT";; - solaris*) - if test "$GCC" = "yes"; then - flag="-D_REENTRANT" - else - # TODO: What about Clang on Solaris? - flag="-mt -D_REENTRANT" - fi - ;; - esac - AC_MSG_RESULT([$flag]) - if test "x$flag" != xno; then - PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" - fi + AC_CACHE_CHECK([for joinable pthread attribute], + [ax_cv_PTHREAD_JOINABLE_ATTR], + [ax_cv_PTHREAD_JOINABLE_ATTR=unknown + for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [int attr = $ax_pthread_attr; return attr /* ; */])], + [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], + []) + done + ]) + AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ + test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ + test "x$ax_pthread_joinable_attr_defined" != "xyes"], + [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], + [$ax_cv_PTHREAD_JOINABLE_ATTR], + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + ax_pthread_joinable_attr_defined=yes + ]) + + AC_CACHE_CHECK([whether more special flags are required for pthreads], + [ax_cv_PTHREAD_SPECIAL_FLAGS], + [ax_cv_PTHREAD_SPECIAL_FLAGS=no + case $host_os in + solaris*) + ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" + ;; + esac + ]) + AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ + test "x$ax_pthread_special_flags_added" != "xyes"], + [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" + ax_pthread_special_flags_added=yes]) AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], - [ax_cv_PTHREAD_PRIO_INHERIT], [ - AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], - [[int i = PTHREAD_PRIO_INHERIT;]])], - [ax_cv_PTHREAD_PRIO_INHERIT=yes], - [ax_cv_PTHREAD_PRIO_INHERIT=no]) + [ax_cv_PTHREAD_PRIO_INHERIT], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[int i = PTHREAD_PRIO_INHERIT; + return i;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) ]) - AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], - [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ + test "x$ax_pthread_prio_inherit_defined" != "xyes"], + [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) + ax_pthread_prio_inherit_defined=yes + ]) - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" # More AIX lossage: compile with *_r variant - if test "x$GCC" != xyes; then + if test "x$GCC" != "xyes"; then case $host_os in aix*) AS_CASE(["x/$CC"], - [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], - [#handle absolute path differently from PATH based program lookup - AS_CASE(["x$CC"], - [x/*], - [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], - [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) + [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], + [#handle absolute path differently from PATH based program lookup + AS_CASE(["x$CC"], + [x/*], + [ + AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"]) + AS_IF([test "x${CXX}" != "x"], [AS_IF([AS_EXECUTABLE_P([${CXX}_r])],[PTHREAD_CXX="${CXX}_r"])]) + ], + [ + AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC]) + AS_IF([test "x${CXX}" != "x"], [AC_CHECK_PROGS([PTHREAD_CXX],[${CXX}_r],[$CXX])]) + ] + ) + ]) ;; esac fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" +test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX" AC_SUBST([PTHREAD_LIBS]) AC_SUBST([PTHREAD_CFLAGS]) AC_SUBST([PTHREAD_CC]) +AC_SUBST([PTHREAD_CXX]) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: -if test x"$ax_pthread_ok" = xyes; then +if test "x$ax_pthread_ok" = "xyes"; then ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) : else diff --git a/build_external/README.md b/build_external/README.md index 6a1e30a57..d68e4d0f1 100644 --- a/build_external/README.md +++ b/build_external/README.md @@ -125,4 +125,4 @@ Notes: * There is not yet a good way to configure the target agent container from the docker-compose command line. * Several other containers should be in this compose (a paho client, tshark etc). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fbuild_external%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]() + diff --git a/build_external/scenarios/aclk-testing/agent_netdata.conf b/build_external/scenarios/aclk-testing/agent_netdata.conf index 774005f76..7a2803c21 100644 --- a/build_external/scenarios/aclk-testing/agent_netdata.conf +++ b/build_external/scenarios/aclk-testing/agent_netdata.conf @@ -60,8 +60,6 @@ # listen backlog = 4096 # default port = 19999 # bind to = * - # web files owner = netdata - # web files group = netdata # disconnect idle clients after seconds = 60 # timeout for first request = 60 # accept a streaming request every seconds = 0 @@ -140,21 +138,6 @@ [cloud] # cloud base url = https://netdata.cloud -[backend] - # host tags = - # enabled = no - # data source = average - # type = graphite - # destination = localhost - # prefix = netdata - # hostname = b073e16793c4 - # update every = 10 - # buffer on failures = 10 - # timeout ms = 20000 - # send names instead of ids = yes - # send charts matching = * - # send hosts matching = localhost * - [statsd] # enabled = yes # update every (flushInterval) = 1 diff --git a/claim/README.md b/claim/README.md index 30f5a85f1..d694990d3 100644 --- a/claim/README.md +++ b/claim/README.md @@ -116,6 +116,67 @@ For the connection process to work, the contents of `/var/lib/netdata` _must_ be restarts using a persistent volume. See our [recommended `docker run` and Docker Compose examples](/packaging/docker/README.md#create-a-new-netdata-agent-container) for details. +#### Known issues on older hosts with seccomp enabled + +The nodes running on the following hosts **cannot be claimed**: + +- `libseccomp` version less than v2.3.3. +- Docker version less than v18.04.0-ce. +- The kernel is configured with CONFIG_SECCOMP enabled. + +To check if your kernel supports `seccomp`: + +```cmd +# grep CONFIG_SECCOMP= /boot/config-$(uname -r) 2>/dev/null || zgrep CONFIG_SECCOMP /proc/config.gz 2>/dev/null +CONFIG_SECCOMP=y +``` + +To resolve the issue, do one of the following actions: + +- Update to a newer version of Docker and `libseccomp` (recommended). +- Create a custom profile and pass it for the container. +- Run [without the default seccomp profile](https://docs.docker.com/engine/security/seccomp/#run-without-the-default-seccomp-profile) (unsafe, not recommended). + +
+See how to create a custom profile + +1. Download the moby default seccomp profile and change `defaultAction` to `SCMP_ACT_TRACE` on line 2. + + ```cmd + sudo wget https://raw.githubusercontent.com/moby/moby/master/profiles/seccomp/default.json -O /etc/docker/seccomp.json + sudo sed -i '2s/SCMP_ACT_ERRNO/SCMP_ACT_TRACE/' /etc/docker/seccomp.json + ``` + +2. Specify the new policy for the container explicitly. + + - When using `docker run`: + + ```cmd + docker run -d --name=netdata \ + --security-opt=seccomp=/etc/docker/seccomp.json \ + ... + ``` + + - When using `docker-compose`: + + > :warning: The security_opt option is ignored when deploying a stack in swarm mode. + + ```yaml + version: '3' + services: + netdata: + security_opt: + - seccomp:/etc/docker/seccomp.json + ... + ``` + + - When using `docker stack deploy`: + + Change the default profile globally by adding `--seccomp-profile=/etc/docker/seccomp.json` to the options passed to + dockerd on startup. + +
+ #### Using environment variables The Netdata Docker container looks for the following environment variables on startup: @@ -308,7 +369,7 @@ If you run the kickstart script and get the following error `Existing install ap If you are using an unsupported package, such as a third-party `.deb`/`.rpm` package provided by your distribution, please remove that package and reinstall using our [recommended kickstart -script](/docs/get-started.mdx#install-on-linux-with-one-line-installer-recommended). +script](/docs/get-started.mdx#install-on-linux-with-one-line-installer). #### kickstart: Failed to write new machine GUID @@ -328,7 +389,7 @@ Netdata to `/opt/netdata`, use `/opt/netdata/bin/netdata-claim.sh` to run the cl If you are using an unsupported package, such as a third-party `.deb`/`.rpm` package provided by your distribution, please remove that package and reinstall using our [recommended kickstart -script](/docs/get-started.mdx#install-on-linux-with-one-line-installer-recommended). +script](/docs/get-started.mdx#install-on-linux-with-one-line-installer). #### Connecting on older distributions (Ubuntu 14.04, Debian 8, CentOS 6) @@ -460,8 +521,8 @@ using the [ACLK](/aclk/README.md). The best way to install Netdata and connect your nodes to Netdata Cloud is with our automatic one-line installation script, [kickstart](/packaging/installer/README.md#automatic-one-line-installation-script). This script will install the Netdata Agent, in case it isn't already installed, and connect your node to Netdata Cloud. -This works with: -* all Linux distributions, see [Netdata distribution support matrix](https://learn.netdata.cloud/docs/agent/packaging/distributions) +This works with: +* most Linux distributions, see [Netdata's platform support policy](/packaging/PLATFORM_SUPPORT.md) * macOS For details on how to run this script please check [How to connect a node](#how-to-connect-a-node) and choose your environment. @@ -548,4 +609,4 @@ Rooms you added that node to. The user can also put the Cloud endpoint's full certificate chain in `cloud.d/cloud_fullchain.pem` so that the Agent can trust the endpoint if necessary. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fclaim%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/claim/claim.c b/claim/claim.c index c919fa3bd..9c7e97e9e 100644 --- a/claim/claim.c +++ b/claim/claim.c @@ -161,7 +161,11 @@ void load_claiming_state(void) freez(claimed_id); claimed_id = NULL; } - localhost->aclk_state.claimed_id = claimed_id; + + if(claimed_id) { + localhost->aclk_state.claimed_id = mallocz(UUID_STR_LEN); + uuid_unparse_lower(uuid, localhost->aclk_state.claimed_id); + } invalidate_node_instances(&localhost->host_uuid, claimed_id ? &uuid : NULL); store_claim_id(&localhost->host_uuid, claimed_id ? &uuid : NULL); @@ -172,6 +176,8 @@ void load_claiming_state(void) return; } + freez(claimed_id); + info("File '%s' was found. Setting state to AGENT_CLAIMED.", filename); netdata_cloud_setting = appconfig_get_boolean(&cloud_config, CONFIG_SECTION_GLOBAL, "enabled", 1); #endif diff --git a/claim/netdata-claim.sh.in b/claim/netdata-claim.sh.in index 9f04de0da..73f016623 100755 --- a/claim/netdata-claim.sh.in +++ b/claim/netdata-claim.sh.in @@ -152,7 +152,7 @@ gen_id() { local id if command -v uuidgen > /dev/null 2>&1; then - id="$(uuidgen)" + id="$(uuidgen | tr '[:upper:]' '[:lower:]')" elif [ -r /proc/sys/kernel/random/uuid ]; then id="$(cat /proc/sys/kernel/random/uuid)" else @@ -199,7 +199,7 @@ do case $arg in -token=*) TOKEN=${arg:7} ;; -url=*) [ -n "${arg:5}" ] && URL_BASE=${arg:5} ;; - -id=*) ID=${arg:4} ;; + -id=*) ID=$(echo "${arg:4}" | tr '[:upper:]' '[:lower:]');; -rooms=*) ROOMS=${arg:7} ;; -hostname=*) HOSTNAME=${arg:10} ;; -verbose) VERBOSE=1 ;; @@ -296,7 +296,7 @@ if [ "${URLTOOL}" = "curl" ] ; then URLCOMMAND="${URLCOMMAND} -x \"${PROXY}\"" fi else - URLCOMMAND="wget -T 15 -O - -q --save-headers --content-on-error=on --method=PUT \ + URLCOMMAND="wget -T 15 -O - -q --server-response --content-on-error=on --method=PUT \ --body-file=\"${CLAIMING_DIR}/tmpin.txt\"" if [ "${NOPROXY}" = "yes" ] ; then URLCOMMAND="${URLCOMMAND} --no-proxy" @@ -326,7 +326,11 @@ if [ "${VERBOSE}" == 1 ]; then fi attempt_contact () { - eval "${URLCOMMAND} \"${TARGET_URL}\"" >"${CLAIMING_DIR}/tmpout.txt" + if [ "${URLTOOL}" = "curl" ] ; then + eval "${URLCOMMAND} \"${TARGET_URL}\"" >"${CLAIMING_DIR}/tmpout.txt" + else + eval "${URLCOMMAND} \"${TARGET_URL}\"" >"${CLAIMING_DIR}/tmpout.txt" 2>&1 + fi URLCOMMAND_EXIT_CODE=$? if [ "${URLTOOL}" = "wget" ] && [ "${URLCOMMAND_EXIT_CODE}" -eq 8 ] ; then # We consider the server issuing an error response a successful attempt at communicating diff --git a/cli/README.md b/cli/README.md index 6eb121be5..75a90b08a 100644 --- a/cli/README.md +++ b/cli/README.md @@ -37,4 +37,4 @@ aclk-state [json] Those commands are the same that can be sent to netdata via [signals](/daemon/README.md#command-line-options). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcli%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/COLLECTORS.md b/collectors/COLLECTORS.md index 19790c424..6b95228f9 100644 --- a/collectors/COLLECTORS.md +++ b/collectors/COLLECTORS.md @@ -219,8 +219,6 @@ configure any of these collectors according to your setup and infrastructure. accounting statistics from the `status server` using the `radclient` tool. - [Libreswan](/collectors/charts.d.plugin/libreswan/README.md): Collect bytes-in, bytes-out, and uptime metrics. - [Icecast](/collectors/python.d.plugin/icecast/README.md): Monitor the number of listeners for active sources. -- [ISC BIND](/collectors/node.d.plugin/named/README.md): Collect nameserver summary performance statistics via a web - interface (`statistics-channels` feature). - [ISC Bind (RDNC)](/collectors/python.d.plugin/bind_rndc/README.md): Collect nameserver summary performance statistics using the `rndc` tool. - [ISC DHCP (Go)](https://learn.netdata.cloud/docs/agent/collectors/go.d.plugin/modules/isc_dhcpd): Reads a @@ -267,13 +265,8 @@ configure any of these collectors according to your setup and infrastructure. blockchain indexes, memory usage, network usage, and transactions of wallet instances. - [Energi Core (Python)](/collectors/python.d.plugin/energid/README.md): Monitor blockchain, memory, network, and unspent transactions statistics. -- [Fronius Symo](/collectors/node.d.plugin/fronius/README.md): Collect power, consumption, autonomy, energy, and inverter - statistics. - [UPS/PDU](/collectors/charts.d.plugin/nut/README.md): Read the status of UPS/PDU devices using the `upsc` tool. -- [SMA Sunny WebBox](/collectors/node.d.plugin/sma_webbox/README.md): Collect power statistics. - [SNMP devices](/collectors/node.d.plugin/snmp/README.md): Gather data using the SNMP protocol. -- [Stiebel Eltron ISG](/collectors/node.d.plugin/stiebeleltron/README.md): Collect metrics from heat pump and hot - water installations. - [1-Wire sensors](/collectors/python.d.plugin/w1sensor/README.md): Monitor sensor temperature. ### Search @@ -540,4 +533,4 @@ default. To use a third-party collector, visit their GitHub/documentation page a - [charts.d example](charts.d.plugin/example/README.md): An example `charts.d` collector. - [python.d example](python.d.plugin/example/README.md): An example `python.d` collector. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2FCOLLECTORS&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/README.md b/collectors/README.md index e9cce42b3..3b76e1624 100644 --- a/collectors/README.md +++ b/collectors/README.md @@ -40,10 +40,8 @@ our [collectors' configuration reference](/collectors/REFERENCE.md). **[Dashboards](/web/README.md)**: Visualize your newly-collect metrics in real-time using Netdata's [built-in dashboard](/web/gui/README.md). -**[Backends](/backends/README.md)**: Extend our built-in [database engine](/database/engine/README.md), which supports -long-term metrics storage, by archiving metrics to like Graphite, Prometheus, MongoDB, TimescaleDB, and more. +**[Exporting](/exporting/README.md)**: Extend our built-in [database engine](/database/engine/README.md), which supports +long-term metrics storage, by archiving metrics to external databases like Graphite, Prometheus, MongoDB, TimescaleDB, and more. +It can export metrics to multiple databases simultaneously. -**[Exporting](/exporting/README.md)**: An experimental refactoring of our backends system with a modular system and -support for exporting metrics to multiple systems simultaneously. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) diff --git a/collectors/REFERENCE.md b/collectors/REFERENCE.md index fc9ed366d..bd267c5c6 100644 --- a/collectors/REFERENCE.md +++ b/collectors/REFERENCE.md @@ -179,4 +179,3 @@ through this, is to examine what other similar plugins do. You can add custom collectors by following the [external plugins documentation](/collectors/plugins.d/README.md). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2REFERENCE&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]() diff --git a/collectors/all.h b/collectors/all.h index 100a6b090..61f3c01bf 100644 --- a/collectors/all.h +++ b/collectors/all.h @@ -30,6 +30,7 @@ #define NETDATA_CHART_PRIO_SYSTEM_IP 501 #define NETDATA_CHART_PRIO_SYSTEM_IPV6 502 #define NETDATA_CHART_PRIO_SYSTEM_PROCESSES 600 +#define NETDATA_CHART_PRIO_SYSTEM_PROCESS_STATES 601 #define NETDATA_CHART_PRIO_SYSTEM_FORKS 700 #define NETDATA_CHART_PRIO_SYSTEM_ACTIVE_PROCESSES 750 #define NETDATA_CHART_PRIO_SYSTEM_CTXT 800 @@ -43,6 +44,7 @@ #define NETDATA_CHART_PRIO_SYSTEM_ENTROPY 1000 #define NETDATA_CHART_PRIO_SYSTEM_UPTIME 1000 #define NETDATA_CHART_PRIO_CLOCK_SYNC_STATE 1100 +#define NETDATA_CHART_PRIO_CLOCK_STATUS 1105 #define NETDATA_CHART_PRIO_CLOCK_SYNC_OFFSET 1110 #define NETDATA_CHART_PRIO_SYSTEM_IPC_MSQ_QUEUES 1200 // freebsd only #define NETDATA_CHART_PRIO_SYSTEM_IPC_MSQ_MESSAGES 1201 diff --git a/collectors/apps.plugin/README.md b/collectors/apps.plugin/README.md index a85c07898..76821695a 100644 --- a/collectors/apps.plugin/README.md +++ b/collectors/apps.plugin/README.md @@ -396,4 +396,4 @@ if you sum the CPU utilization of all processes, you might have more CPU time th total cpu time of the system. Netdata solves this, by adapting the per process cpu utilization to the total of the system. [Netdata adds charts that document this normalization](https://london.my-netdata.io/default.html#menu_netdata_submenu_apps_plugin). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fapps.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/apps.plugin/apps_groups.conf b/collectors/apps.plugin/apps_groups.conf index a36cae50b..f4824cd9d 100644 --- a/collectors/apps.plugin/apps_groups.conf +++ b/collectors/apps.plugin/apps_groups.conf @@ -169,6 +169,7 @@ nfs: rpcbind rpc.* nfs* zfs: spl_* z_* txg_* zil_* arc_* l2arc* btrfs: btrfs* iscsi: iscsid iscsi_eh +afp: netatalk afpd cnid_dbd cnid_metad # ----------------------------------------------------------------------------- # kubernetes @@ -338,3 +339,15 @@ filecoin: lotus* lotus-miner* lotus-worker* solana: solana* web3: *hardhat* *ganache* *truffle* *brownie* *waffle* terra: terra* mantle* + +# ----------------------------------------------------------------------------- +# chaos engineering tools + +stress: stress stress-ng* +gremlin: gremlin* + +# ----------------------------------------------------------------------------- +# load testing tools + +locust: locust + diff --git a/collectors/apps.plugin/apps_plugin.c b/collectors/apps.plugin/apps_plugin.c index 5555f157b..6924b2bf4 100644 --- a/collectors/apps.plugin/apps_plugin.c +++ b/collectors/apps.plugin/apps_plugin.c @@ -6,6 +6,7 @@ * Released under GPL v3+ */ +#include "collectors/all.h" #include "libnetdata/libnetdata.h" #include "libnetdata/required_dummies.h" @@ -107,6 +108,25 @@ static int static char *user_config_dir = CONFIG_DIR; static char *stock_config_dir = LIBCONFIG_DIR; +// some variables for keeping track of processes count by states +typedef enum { + PROC_STATUS_RUNNING = 0, + PROC_STATUS_SLEEPING_D, // uninterruptible sleep + PROC_STATUS_SLEEPING, // interruptible sleep + PROC_STATUS_ZOMBIE, + PROC_STATUS_STOPPED, + PROC_STATUS_END, //place holder for ending enum fields +} proc_state; + +static proc_state proc_state_count[PROC_STATUS_END]; +static const char *proc_states[] = { + [PROC_STATUS_RUNNING] = "running", + [PROC_STATUS_SLEEPING] = "sleeping_interruptible", + [PROC_STATUS_SLEEPING_D] = "sleeping_uninterruptible", + [PROC_STATUS_ZOMBIE] = "zombie", + [PROC_STATUS_STOPPED] = "stopped", + }; + // ---------------------------------------------------------------------------- // internal flags // handled in code (automatically set) @@ -286,7 +306,7 @@ struct pid_stat { uint32_t log_thrown; - // char state; + char state; int32_t ppid; // int32_t pgrp; // int32_t session; @@ -1234,6 +1254,28 @@ void arl_callback_status_rssshmem(const char *name, uint32_t hash, const char *v } #endif // !__FreeBSD__ +static void update_proc_state_count(char proc_state) { + switch (proc_state) { + case 'S': + proc_state_count[PROC_STATUS_SLEEPING] += 1; + break; + case 'R': + proc_state_count[PROC_STATUS_RUNNING] += 1; + break; + case 'D': + proc_state_count[PROC_STATUS_SLEEPING_D] += 1; + break; + case 'Z': + proc_state_count[PROC_STATUS_ZOMBIE] += 1; + break; + case 'T': + proc_state_count[PROC_STATUS_STOPPED] += 1; + break; + default: + break; + } +} + static inline int read_proc_pid_status(struct pid_stat *p, void *ptr) { p->status_vmsize = 0; p->status_vmrss = 0; @@ -1268,6 +1310,7 @@ static inline int read_proc_pid_status(struct pid_stat *p, void *ptr) { arl_expect_custom(p->status_arl, "VmSwap", arl_callback_status_vmswap, &arl_ptr); } + if(unlikely(!p->status_filename)) { char filename[FILENAME_MAX + 1]; snprintfz(filename, FILENAME_MAX, "%s/proc/%d/status", netdata_configured_host_prefix, p->pid); @@ -1313,7 +1356,6 @@ static inline int read_proc_pid_stat(struct pid_stat *p, void *ptr) { #ifdef __FreeBSD__ struct kinfo_proc *proc_info = (struct kinfo_proc *)ptr; - if (unlikely(proc_info->ki_tdflags & TDF_IDLETD)) goto cleanup; #else @@ -1348,7 +1390,7 @@ static inline int read_proc_pid_stat(struct pid_stat *p, void *ptr) { #else // p->pid = str2pid_t(procfile_lineword(ff, 0, 0)); char *comm = procfile_lineword(ff, 0, 1); - // p->state = *(procfile_lineword(ff, 0, 2)); + p->state = *(procfile_lineword(ff, 0, 2)); p->ppid = (int32_t)str2pid_t(procfile_lineword(ff, 0, 3)); // p->pgrp = (int32_t)str2pid_t(procfile_lineword(ff, 0, 4)); // p->session = (int32_t)str2pid_t(procfile_lineword(ff, 0, 5)); @@ -1356,7 +1398,6 @@ static inline int read_proc_pid_stat(struct pid_stat *p, void *ptr) { // p->tpgid = (int32_t)str2pid_t(procfile_lineword(ff, 0, 7)); // p->flags = str2uint64_t(procfile_lineword(ff, 0, 8)); #endif - if(strcmp(p->comm, comm) != 0) { if(unlikely(debug_enabled)) { if(p->comm[0]) @@ -1454,7 +1495,7 @@ static inline int read_proc_pid_stat(struct pid_stat *p, void *ptr) { p->cstime = 0; p->cgtime = 0; } - + update_proc_state_count(p->state); return 1; cleanup: @@ -2534,6 +2575,8 @@ static inline int collect_data_for_pid(pid_t pid, void *ptr) { static int collect_data_for_all_processes(void) { struct pid_stat *p = NULL; + // clear process state counter + memset(proc_state_count, 0, sizeof proc_state_count); #ifdef __FreeBSD__ int i, procnum; @@ -2608,8 +2651,9 @@ static int collect_data_for_all_processes(void) { // we forward read all running processes // collect_data_for_pid() is smart enough, // not to read the same pid twice per iteration - for(slc = 0; slc < all_pids_count; slc++) + for(slc = 0; slc < all_pids_count; slc++) { collect_data_for_pid(all_pids_sortlist[slc], NULL); + } } #endif } @@ -2666,7 +2710,6 @@ static int collect_data_for_all_processes(void) { // we do this by collecting the ownership of process // if we manage to get the ownership, the process still runs process_exited_processes(); - return 1; } @@ -3470,14 +3513,14 @@ static void send_collected_data_to_netdata(struct target *root, const char *type send_BEGIN(type, "threads", dt); for (w = root; w ; w = w->next) { - if(unlikely(w->exposed && w->processes)) + if(unlikely(w->exposed)) send_SET(w->name, w->num_threads); } send_END(); send_BEGIN(type, "processes", dt); for (w = root; w ; w = w->next) { - if(unlikely(w->exposed && w->processes)) + if(unlikely(w->exposed)) send_SET(w->name, w->processes); } send_END(); @@ -3640,7 +3683,7 @@ static void send_charts_updates_to_netdata(struct target *root, const char *type debug_log_int("%s just added - regenerating charts.", w->name); } } - + // nothing more to show if(!newly_added && show_guest_time == show_guest_time_old) return; @@ -3806,6 +3849,29 @@ static void send_charts_updates_to_netdata(struct target *root, const char *type } } +static void send_proc_states_count(usec_t dt) +{ + static bool chart_added = false; + // create chart for count of processes in different states + if (!chart_added) { + fprintf( + stdout, + "CHART system.processes_state '' 'System Processes State' 'processes' processes system.processes_state line %d %d\n", + NETDATA_CHART_PRIO_SYSTEM_PROCESS_STATES, + update_every); + for (proc_state i = PROC_STATUS_RUNNING; i < PROC_STATUS_END; i++) { + fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", proc_states[i]); + } + chart_added = true; + } + + // send process state count + send_BEGIN("system", "processes_state", dt); + for (proc_state i = PROC_STATUS_RUNNING; i < PROC_STATUS_END; i++) { + send_SET(proc_states[i], proc_state_count[i]); + } + send_END(); +} // ---------------------------------------------------------------------------- // parse command line arguments @@ -4182,9 +4248,12 @@ int main(int argc, char **argv) { send_resource_usage_to_netdata(dt); +#ifndef __FreeBSD__ + send_proc_states_count(dt); +#endif + // this is smart enough to show only newly added apps, when needed send_charts_updates_to_netdata(apps_groups_root_target, "apps", "Apps"); - if(likely(enable_users_charts)) send_charts_updates_to_netdata(users_root_target, "users", "Users"); diff --git a/collectors/cgroups.plugin/README.md b/collectors/cgroups.plugin/README.md index 86776d6e0..d74ef000e 100644 --- a/collectors/cgroups.plugin/README.md +++ b/collectors/cgroups.plugin/README.md @@ -284,4 +284,4 @@ So, when a network interface or container stops, Netdata might log a few errors Network interfaces are monitored by means of the [proc plugin](/collectors/proc.plugin/README.md#monitored-network-interface-metrics). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fcgroups.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/cgroups.plugin/sys_fs_cgroup.c b/collectors/cgroups.plugin/sys_fs_cgroup.c index 92aa22c77..8efb68cf0 100644 --- a/collectors/cgroups.plugin/sys_fs_cgroup.c +++ b/collectors/cgroups.plugin/sys_fs_cgroup.c @@ -13,6 +13,7 @@ static long system_page_size = 4096; // system will be queried via sysconf() in static int cgroup_enable_cpuacct_stat = CONFIG_BOOLEAN_AUTO; static int cgroup_enable_cpuacct_usage = CONFIG_BOOLEAN_AUTO; +static int cgroup_enable_cpuacct_cpu_throttling = CONFIG_BOOLEAN_YES; static int cgroup_enable_memory = CONFIG_BOOLEAN_AUTO; static int cgroup_enable_detailed_memory = CONFIG_BOOLEAN_AUTO; static int cgroup_enable_memory_failcnt = CONFIG_BOOLEAN_AUTO; @@ -72,6 +73,12 @@ static uint32_t Read_hash = 0; static uint32_t Write_hash = 0; static uint32_t user_hash = 0; static uint32_t system_hash = 0; +static uint32_t user_usec_hash = 0; +static uint32_t system_usec_hash = 0; +static uint32_t nr_periods_hash = 0; +static uint32_t nr_throttled_hash = 0; +static uint32_t throttled_time_hash = 0; +static uint32_t throttled_usec_hash = 0; enum cgroups_type { CGROUPS_AUTODETECT_FAIL, CGROUPS_V1, CGROUPS_V2 }; @@ -116,21 +123,41 @@ static enum cgroups_systemd_setting cgroups_detect_systemd(const char *exec) if (!f) return retval; - while (fgets(buf, MAXSIZE_PROC_CMDLINE, f) != NULL) { - if ((begin = strstr(buf, SYSTEMD_HIERARCHY_STRING))) { - end = begin = begin + strlen(SYSTEMD_HIERARCHY_STRING); - if (!*begin) - break; - while (isalpha(*end)) - end++; - *end = 0; - for (int i = 0; cgroups_systemd_options[i].name; i++) { - if (!strcmp(begin, cgroups_systemd_options[i].name)) { - retval = cgroups_systemd_options[i].setting; + fd_set rfds; + struct timeval timeout; + int fd = fileno(f); + int ret = -1; + + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + timeout.tv_sec = 3; + timeout.tv_usec = 0; + + if (fd != -1) { + ret = select(fd + 1, &rfds, NULL, NULL, &timeout); + } + + if (ret == -1) { + error("Failed to get the output of \"%s\"", exec); + } else if (ret == 0) { + info("Cannot get the output of \"%s\" within %"PRId64" seconds", exec, (int64_t)timeout.tv_sec); + } else { + while (fgets(buf, MAXSIZE_PROC_CMDLINE, f) != NULL) { + if ((begin = strstr(buf, SYSTEMD_HIERARCHY_STRING))) { + end = begin = begin + strlen(SYSTEMD_HIERARCHY_STRING); + if (!*begin) break; + while (isalpha(*end)) + end++; + *end = 0; + for (int i = 0; cgroups_systemd_options[i].name; i++) { + if (!strcmp(begin, cgroups_systemd_options[i].name)) { + retval = cgroups_systemd_options[i].setting; + break; + } } + break; } - break; } } @@ -213,6 +240,14 @@ static enum cgroups_type cgroups_try_detect_version() return CGROUPS_V2; } +void set_cgroup_base_path(char *filename, char *path) { + if (strncmp(netdata_configured_host_prefix, path, strlen(netdata_configured_host_prefix)) == 0) { + snprintfz(filename, FILENAME_MAX, "%s", path); + } else { + snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, path); + } +} + void read_cgroup_plugin_configuration() { system_page_size = sysconf(_SC_PAGESIZE); @@ -220,6 +255,12 @@ void read_cgroup_plugin_configuration() { Write_hash = simple_hash("Write"); user_hash = simple_hash("user"); system_hash = simple_hash("system"); + user_usec_hash = simple_hash("user_usec"); + system_usec_hash = simple_hash("system_usec"); + nr_periods_hash = simple_hash("nr_periods"); + nr_throttled_hash = simple_hash("nr_throttled"); + throttled_time_hash = simple_hash("throttled_time"); + throttled_usec_hash = simple_hash("throttled_usec"); cgroup_update_every = (int)config_get_number("plugin:cgroups", "update every", localhost->rrd_update_every); if(cgroup_update_every < localhost->rrd_update_every) @@ -241,6 +282,7 @@ void read_cgroup_plugin_configuration() { cgroup_enable_cpuacct_stat = config_get_boolean_ondemand("plugin:cgroups", "enable cpuacct stat (total CPU)", cgroup_enable_cpuacct_stat); cgroup_enable_cpuacct_usage = config_get_boolean_ondemand("plugin:cgroups", "enable cpuacct usage (per core CPU)", cgroup_enable_cpuacct_usage); + cgroup_enable_cpuacct_cpu_throttling = config_get_boolean_ondemand("plugin:cgroups", "enable cpuacct cpu throttling", cgroup_enable_cpuacct_cpu_throttling); cgroup_enable_memory = config_get_boolean_ondemand("plugin:cgroups", "enable memory", cgroup_enable_memory); cgroup_enable_detailed_memory = config_get_boolean_ondemand("plugin:cgroups", "enable detailed memory", cgroup_enable_detailed_memory); @@ -285,7 +327,7 @@ void read_cgroup_plugin_configuration() { s = "/sys/fs/cgroup/cpuacct"; } else s = mi->mount_point; - snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, s); + set_cgroup_base_path(filename, s); cgroup_cpuacct_base = config_get("plugin:cgroups", "path to /sys/fs/cgroup/cpuacct", filename); mi = mountinfo_find_by_filesystem_super_option(root, "cgroup", "cpuset"); @@ -295,7 +337,7 @@ void read_cgroup_plugin_configuration() { s = "/sys/fs/cgroup/cpuset"; } else s = mi->mount_point; - snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, s); + set_cgroup_base_path(filename, s); cgroup_cpuset_base = config_get("plugin:cgroups", "path to /sys/fs/cgroup/cpuset", filename); mi = mountinfo_find_by_filesystem_super_option(root, "cgroup", "blkio"); @@ -305,7 +347,7 @@ void read_cgroup_plugin_configuration() { s = "/sys/fs/cgroup/blkio"; } else s = mi->mount_point; - snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, s); + set_cgroup_base_path(filename, s); cgroup_blkio_base = config_get("plugin:cgroups", "path to /sys/fs/cgroup/blkio", filename); mi = mountinfo_find_by_filesystem_super_option(root, "cgroup", "memory"); @@ -315,7 +357,7 @@ void read_cgroup_plugin_configuration() { s = "/sys/fs/cgroup/memory"; } else s = mi->mount_point; - snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, s); + set_cgroup_base_path(filename, s); cgroup_memory_base = config_get("plugin:cgroups", "path to /sys/fs/cgroup/memory", filename); mi = mountinfo_find_by_filesystem_super_option(root, "cgroup", "devices"); @@ -325,7 +367,7 @@ void read_cgroup_plugin_configuration() { s = "/sys/fs/cgroup/devices"; } else s = mi->mount_point; - snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, s); + set_cgroup_base_path(filename, s); cgroup_devices_base = config_get("plugin:cgroups", "path to /sys/fs/cgroup/devices", filename); } else { @@ -357,7 +399,7 @@ void read_cgroup_plugin_configuration() { s = "/sys/fs/cgroup"; } else s = mi->mount_point; - snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, s); + set_cgroup_base_path(filename, s); cgroup_unified_base = config_get("plugin:cgroups", "path to unified cgroups", filename); debug(D_CGROUP, "using cgroup root: '%s'", cgroup_unified_base); } @@ -395,7 +437,7 @@ void read_cgroup_plugin_configuration() { " !*.user " " !/ " " !/docker " - " !/libvirt " + " !*/libvirt " " !/lxc " " !/lxc/*/* " // #1397 #2649 " !/lxc.monitor* " @@ -630,12 +672,12 @@ struct memory { // https://www.kernel.org/doc/Documentation/cgroup-v1/cpuacct.txt struct cpuacct_stat { int updated; - int enabled; // CONFIG_BOOLEAN_YES or CONFIG_BOOLEAN_AUTO + int enabled; // CONFIG_BOOLEAN_YES or CONFIG_BOOLEAN_AUTO char *filename; - unsigned long long user; - unsigned long long system; + unsigned long long user; // v1, v2(user_usec) + unsigned long long system; // v1, v2(system_usec) }; // https://www.kernel.org/doc/Documentation/cgroup-v1/cpuacct.txt @@ -649,6 +691,20 @@ struct cpuacct_usage { unsigned long long *cpu_percpu; }; +// represents cpuacct/cpu.stat, for v2 'cpuacct_stat' is used for 'user_usec', 'system_usec' +struct cpuacct_cpu_throttling { + int updated; + int enabled; // CONFIG_BOOLEAN_YES or CONFIG_BOOLEAN_AUTO + + char *filename; + + unsigned long long nr_periods; + unsigned long long nr_throttled; + unsigned long long throttled_time; + + unsigned long long nr_throttled_perc; +}; + struct cgroup_network_interface { const char *host_device; const char *container_device; @@ -677,6 +733,7 @@ struct cgroup { struct cpuacct_stat cpuacct_stat; struct cpuacct_usage cpuacct_usage; + struct cpuacct_cpu_throttling cpuacct_cpu_throttling; struct memory memory; @@ -699,6 +756,9 @@ struct cgroup { RRDSET *st_cpu; RRDSET *st_cpu_limit; RRDSET *st_cpu_per_core; + RRDSET *st_cpu_nr_throttled; + RRDSET *st_cpu_throttled_time; + RRDSET *st_mem; RRDSET *st_mem_utilization; RRDSET *st_writeback; @@ -707,6 +767,7 @@ struct cgroup { RRDSET *st_mem_usage; RRDSET *st_mem_usage_limit; RRDSET *st_mem_failcnt; + RRDSET *st_io; RRDSET *st_serviced_ops; RRDSET *st_throttle_io; @@ -781,6 +842,22 @@ struct discovery_thread { int exited; } discovery_thread; +// ---------------------------------------------------------------------------- + +static unsigned long long calc_delta(unsigned long long curr, unsigned long long prev) { + if (prev > curr) { + return 0; + } + return curr - prev; +} + +static unsigned long long calc_percentage(unsigned long long value, unsigned long long total) { + if (total == 0) { + return 0; + } + return (calculated_number)value / (calculated_number)total * 100; +} + // ---------------------------------------------------------------------------- // read values from /sys @@ -829,40 +906,126 @@ static inline void cgroup_read_cpuacct_stat(struct cpuacct_stat *cp) { } } -static inline void cgroup2_read_cpuacct_stat(struct cpuacct_stat *cp) { +static inline void cgroup_read_cpuacct_cpu_stat(struct cpuacct_cpu_throttling *cp) { + if (unlikely(!cp->filename)) { + return; + } + static procfile *ff = NULL; + ff = procfile_reopen(ff, cp->filename, NULL, PROCFILE_FLAG_DEFAULT); + if (unlikely(!ff)) { + cp->updated = 0; + cgroups_check = 1; + return; + } - if(likely(cp->filename)) { - ff = procfile_reopen(ff, cp->filename, NULL, PROCFILE_FLAG_DEFAULT); - if(unlikely(!ff)) { - cp->updated = 0; - cgroups_check = 1; - return; - } + ff = procfile_readall(ff); + if (unlikely(!ff)) { + cp->updated = 0; + cgroups_check = 1; + return; + } - ff = procfile_readall(ff); - if(unlikely(!ff)) { - cp->updated = 0; - cgroups_check = 1; - return; + unsigned long lines = procfile_lines(ff); + if (unlikely(lines < 3)) { + error("CGROUP: file '%s' should have 3 lines.", cp->filename); + cp->updated = 0; + return; + } + + unsigned long long nr_periods_last = cp->nr_periods; + unsigned long long nr_throttled_last = cp->nr_throttled; + + for (unsigned long i = 0; i < lines; i++) { + char *s = procfile_lineword(ff, i, 0); + uint32_t hash = simple_hash(s); + + if (unlikely(hash == nr_periods_hash && !strcmp(s, "nr_periods"))) { + cp->nr_periods = str2ull(procfile_lineword(ff, i, 1)); + } else if (unlikely(hash == nr_throttled_hash && !strcmp(s, "nr_throttled"))) { + cp->nr_throttled = str2ull(procfile_lineword(ff, i, 1)); + } else if (unlikely(hash == throttled_time_hash && !strcmp(s, "throttled_time"))) { + cp->throttled_time = str2ull(procfile_lineword(ff, i, 1)); } + } + cp->nr_throttled_perc = + calc_percentage(calc_delta(cp->nr_throttled, nr_throttled_last), calc_delta(cp->nr_periods, nr_periods_last)); - unsigned long lines = procfile_lines(ff); + cp->updated = 1; - if(unlikely(lines < 3)) { - error("CGROUP: file '%s' should have 3+ lines.", cp->filename); - cp->updated = 0; - return; + if (unlikely(cp->enabled == CONFIG_BOOLEAN_AUTO)) { + if (likely( + cp->nr_periods || cp->nr_throttled || cp->throttled_time || + netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES)) { + cp->enabled = CONFIG_BOOLEAN_YES; } + } +} - cp->user = str2ull(procfile_lineword(ff, 1, 1)); - cp->system = str2ull(procfile_lineword(ff, 2, 1)); +static inline void cgroup2_read_cpuacct_cpu_stat(struct cpuacct_stat *cp, struct cpuacct_cpu_throttling *cpt) { + static procfile *ff = NULL; + if (unlikely(!cp->filename)) { + return; + } - cp->updated = 1; + ff = procfile_reopen(ff, cp->filename, NULL, PROCFILE_FLAG_DEFAULT); + if (unlikely(!ff)) { + cp->updated = 0; + cgroups_check = 1; + return; + } - if(unlikely(cp->enabled == CONFIG_BOOLEAN_AUTO && - (cp->user || cp->system || netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) + ff = procfile_readall(ff); + if (unlikely(!ff)) { + cp->updated = 0; + cgroups_check = 1; + return; + } + + unsigned long lines = procfile_lines(ff); + + if (unlikely(lines < 3)) { + error("CGROUP: file '%s' should have at least 3 lines.", cp->filename); + cp->updated = 0; + return; + } + + unsigned long long nr_periods_last = cpt->nr_periods; + unsigned long long nr_throttled_last = cpt->nr_throttled; + + for (unsigned long i = 0; i < lines; i++) { + char *s = procfile_lineword(ff, i, 0); + uint32_t hash = simple_hash(s); + + if (unlikely(hash == user_usec_hash && !strcmp(s, "user_usec"))) { + cp->user = str2ull(procfile_lineword(ff, i, 1)); + } else if (unlikely(hash == system_usec_hash && !strcmp(s, "system_usec"))) { + cp->system = str2ull(procfile_lineword(ff, i, 1)); + } else if (unlikely(hash == nr_periods_hash && !strcmp(s, "nr_periods"))) { + cpt->nr_periods = str2ull(procfile_lineword(ff, i, 1)); + } else if (unlikely(hash == nr_throttled_hash && !strcmp(s, "nr_throttled"))) { + cpt->nr_throttled = str2ull(procfile_lineword(ff, i, 1)); + } else if (unlikely(hash == throttled_usec_hash && !strcmp(s, "throttled_usec"))) { + cpt->throttled_time = str2ull(procfile_lineword(ff, i, 1)) * 1000; // usec -> ns + } + } + cpt->nr_throttled_perc = + calc_percentage(calc_delta(cpt->nr_throttled, nr_throttled_last), calc_delta(cpt->nr_periods, nr_periods_last)); + + cp->updated = 1; + cpt->updated = 1; + + if (unlikely(cp->enabled == CONFIG_BOOLEAN_AUTO)) { + if (likely(cp->user || cp->system || netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES)) { cp->enabled = CONFIG_BOOLEAN_YES; + } + } + if (unlikely(cpt->enabled == CONFIG_BOOLEAN_AUTO)) { + if (likely( + cpt->nr_periods || cpt->nr_throttled || cpt->throttled_time || + netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES)) { + cpt->enabled = CONFIG_BOOLEAN_YES; + } } } @@ -1236,6 +1399,7 @@ static inline void cgroup_read(struct cgroup *cg) { if(!(cg->options & CGROUP_OPTIONS_IS_UNIFIED)) { cgroup_read_cpuacct_stat(&cg->cpuacct_stat); cgroup_read_cpuacct_usage(&cg->cpuacct_usage); + cgroup_read_cpuacct_cpu_stat(&cg->cpuacct_cpu_throttling); cgroup_read_memory(&cg->memory, 0); cgroup_read_blkio(&cg->io_service_bytes); cgroup_read_blkio(&cg->io_serviced); @@ -1248,7 +1412,7 @@ static inline void cgroup_read(struct cgroup *cg) { //TODO: io_service_bytes and io_serviced use same file merge into 1 function cgroup2_read_blkio(&cg->io_service_bytes, 0); cgroup2_read_blkio(&cg->io_serviced, 4); - cgroup2_read_cpuacct_stat(&cg->cpuacct_stat); + cgroup2_read_cpuacct_cpu_stat(&cg->cpuacct_stat, &cg->cpuacct_cpu_throttling); cgroup2_read_pressure(&cg->cpu_pressure); cgroup2_read_pressure(&cg->io_pressure); cgroup2_read_pressure(&cg->memory_pressure); @@ -1599,6 +1763,8 @@ static inline void cgroup_free(struct cgroup *cg) { if(cg->st_cpu) rrdset_is_obsolete(cg->st_cpu); if(cg->st_cpu_limit) rrdset_is_obsolete(cg->st_cpu_limit); if(cg->st_cpu_per_core) rrdset_is_obsolete(cg->st_cpu_per_core); + if(cg->st_cpu_nr_throttled) rrdset_is_obsolete(cg->st_cpu_nr_throttled); + if(cg->st_cpu_throttled_time) rrdset_is_obsolete(cg->st_cpu_throttled_time); if(cg->st_mem) rrdset_is_obsolete(cg->st_mem); if(cg->st_writeback) rrdset_is_obsolete(cg->st_writeback); if(cg->st_mem_activity) rrdset_is_obsolete(cg->st_mem_activity); @@ -1626,6 +1792,7 @@ static inline void cgroup_free(struct cgroup *cg) { freez(cg->cpuacct_stat.filename); freez(cg->cpuacct_usage.filename); + freez(cg->cpuacct_cpu_throttling.filename); arl_free(cg->memory.arl_base); freez(cg->memory.filename_detailed); @@ -1842,6 +2009,16 @@ static inline void update_filenames() else debug(D_CGROUP, "cpuacct.usage_percpu file for cgroup '%s': '%s' does not exist.", cg->id, filename); } + if(unlikely(cgroup_enable_cpuacct_cpu_throttling && !cg->cpuacct_cpu_throttling.filename && !(cg->options & CGROUP_OPTIONS_SYSTEM_SLICE_SERVICE))) { + snprintfz(filename, FILENAME_MAX, "%s%s/cpu.stat", cgroup_cpuacct_base, cg->id); + if(likely(stat(filename, &buf) != -1)) { + cg->cpuacct_cpu_throttling.filename = strdupz(filename); + cg->cpuacct_cpu_throttling.enabled = cgroup_enable_cpuacct_cpu_throttling; + debug(D_CGROUP, "cpu.stat filename for cgroup '%s': '%s'", cg->id, cg->cpuacct_cpu_throttling.filename); + } + else + debug(D_CGROUP, "cpu.stat file for cgroup '%s': '%s' does not exist.", cg->id, filename); + } if(unlikely((cgroup_enable_detailed_memory || cgroup_used_memory) && !cg->memory.filename_detailed && (cgroup_used_memory || cgroup_enable_systemd_services_detailed_memory || !(cg->options & CGROUP_OPTIONS_SYSTEM_SLICE_SERVICE)))) { snprintfz(filename, FILENAME_MAX, "%s%s/memory.stat", cgroup_memory_base, cg->id); @@ -1892,69 +2069,118 @@ static inline void update_filenames() } if(unlikely(cgroup_enable_blkio_io && !cg->io_service_bytes.filename)) { - snprintfz(filename, FILENAME_MAX, "%s%s/blkio.io_service_bytes", cgroup_blkio_base, cg->id); - if(likely(stat(filename, &buf) != -1)) { + snprintfz(filename, FILENAME_MAX, "%s%s/blkio.io_service_bytes_recursive", cgroup_blkio_base, cg->id); + if (unlikely(stat(filename, &buf) != -1)) { cg->io_service_bytes.filename = strdupz(filename); cg->io_service_bytes.enabled = cgroup_enable_blkio_io; - debug(D_CGROUP, "io_service_bytes filename for cgroup '%s': '%s'", cg->id, cg->io_service_bytes.filename); + debug(D_CGROUP, "blkio.io_service_bytes_recursive filename for cgroup '%s': '%s'", cg->id, cg->io_service_bytes.filename); + } else { + debug(D_CGROUP, "blkio.io_service_bytes_recursive file for cgroup '%s': '%s' does not exist.", cg->id, filename); + snprintfz(filename, FILENAME_MAX, "%s%s/blkio.io_service_bytes", cgroup_blkio_base, cg->id); + if (likely(stat(filename, &buf) != -1)) { + cg->io_service_bytes.filename = strdupz(filename); + cg->io_service_bytes.enabled = cgroup_enable_blkio_io; + debug(D_CGROUP, "blkio.io_service_bytes filename for cgroup '%s': '%s'", cg->id, cg->io_service_bytes.filename); + } else { + debug(D_CGROUP, "blkio.io_service_bytes file for cgroup '%s': '%s' does not exist.", cg->id, filename); + } } - else - debug(D_CGROUP, "io_service_bytes file for cgroup '%s': '%s' does not exist.", cg->id, filename); } - if(unlikely(cgroup_enable_blkio_ops && !cg->io_serviced.filename)) { - snprintfz(filename, FILENAME_MAX, "%s%s/blkio.io_serviced", cgroup_blkio_base, cg->id); - if(likely(stat(filename, &buf) != -1)) { + if (unlikely(cgroup_enable_blkio_ops && !cg->io_serviced.filename)) { + snprintfz(filename, FILENAME_MAX, "%s%s/blkio.io_serviced_recursive", cgroup_blkio_base, cg->id); + if (unlikely(stat(filename, &buf) != -1)) { cg->io_serviced.filename = strdupz(filename); cg->io_serviced.enabled = cgroup_enable_blkio_ops; - debug(D_CGROUP, "io_serviced filename for cgroup '%s': '%s'", cg->id, cg->io_serviced.filename); + debug(D_CGROUP, "blkio.io_serviced_recursive filename for cgroup '%s': '%s'", cg->id, cg->io_serviced.filename); + } else { + debug(D_CGROUP, "blkio.io_serviced_recursive file for cgroup '%s': '%s' does not exist.", cg->id, filename); + snprintfz(filename, FILENAME_MAX, "%s%s/blkio.io_serviced", cgroup_blkio_base, cg->id); + if (likely(stat(filename, &buf) != -1)) { + cg->io_serviced.filename = strdupz(filename); + cg->io_serviced.enabled = cgroup_enable_blkio_ops; + debug(D_CGROUP, "blkio.io_serviced filename for cgroup '%s': '%s'", cg->id, cg->io_serviced.filename); + } else { + debug(D_CGROUP, "blkio.io_serviced file for cgroup '%s': '%s' does not exist.", cg->id, filename); + } } - else - debug(D_CGROUP, "io_serviced file for cgroup '%s': '%s' does not exist.", cg->id, filename); } - if(unlikely(cgroup_enable_blkio_throttle_io && !cg->throttle_io_service_bytes.filename)) { - snprintfz(filename, FILENAME_MAX, "%s%s/blkio.throttle.io_service_bytes", cgroup_blkio_base, cg->id); - if(likely(stat(filename, &buf) != -1)) { + if (unlikely(cgroup_enable_blkio_throttle_io && !cg->throttle_io_service_bytes.filename)) { + snprintfz(filename, FILENAME_MAX, "%s%s/blkio.throttle.io_service_bytes_recursive", cgroup_blkio_base, cg->id); + if (unlikely(stat(filename, &buf) != -1)) { cg->throttle_io_service_bytes.filename = strdupz(filename); cg->throttle_io_service_bytes.enabled = cgroup_enable_blkio_throttle_io; - debug(D_CGROUP, "throttle_io_service_bytes filename for cgroup '%s': '%s'", cg->id, cg->throttle_io_service_bytes.filename); + debug(D_CGROUP,"blkio.throttle.io_service_bytes_recursive filename for cgroup '%s': '%s'", cg->id, cg->throttle_io_service_bytes.filename); + } else { + debug(D_CGROUP, "blkio.throttle.io_service_bytes_recursive file for cgroup '%s': '%s' does not exist.", cg->id, filename); + snprintfz( + filename, FILENAME_MAX, "%s%s/blkio.throttle.io_service_bytes", cgroup_blkio_base, cg->id); + if (likely(stat(filename, &buf) != -1)) { + cg->throttle_io_service_bytes.filename = strdupz(filename); + cg->throttle_io_service_bytes.enabled = cgroup_enable_blkio_throttle_io; + debug(D_CGROUP, "blkio.throttle.io_service_bytes filename for cgroup '%s': '%s'", cg->id, cg->throttle_io_service_bytes.filename); + } else { + debug(D_CGROUP, "blkio.throttle.io_service_bytes file for cgroup '%s': '%s' does not exist.", cg->id, filename); + } } - else - debug(D_CGROUP, "throttle_io_service_bytes file for cgroup '%s': '%s' does not exist.", cg->id, filename); } - if(unlikely(cgroup_enable_blkio_throttle_ops && !cg->throttle_io_serviced.filename)) { - snprintfz(filename, FILENAME_MAX, "%s%s/blkio.throttle.io_serviced", cgroup_blkio_base, cg->id); - if(likely(stat(filename, &buf) != -1)) { + if (unlikely(cgroup_enable_blkio_throttle_ops && !cg->throttle_io_serviced.filename)) { + snprintfz(filename, FILENAME_MAX, "%s%s/blkio.throttle.io_serviced_recursive", cgroup_blkio_base, cg->id); + if (unlikely(stat(filename, &buf) != -1)) { cg->throttle_io_serviced.filename = strdupz(filename); cg->throttle_io_serviced.enabled = cgroup_enable_blkio_throttle_ops; - debug(D_CGROUP, "throttle_io_serviced filename for cgroup '%s': '%s'", cg->id, cg->throttle_io_serviced.filename); + debug(D_CGROUP, "blkio.throttle.io_serviced_recursive filename for cgroup '%s': '%s'", cg->id, cg->throttle_io_serviced.filename); + } else { + debug(D_CGROUP, "blkio.throttle.io_serviced_recursive file for cgroup '%s': '%s' does not exist.", cg->id, filename); + snprintfz(filename, FILENAME_MAX, "%s%s/blkio.throttle.io_serviced", cgroup_blkio_base, cg->id); + if (likely(stat(filename, &buf) != -1)) { + cg->throttle_io_serviced.filename = strdupz(filename); + cg->throttle_io_serviced.enabled = cgroup_enable_blkio_throttle_ops; + debug(D_CGROUP, "blkio.throttle.io_serviced filename for cgroup '%s': '%s'", cg->id, cg->throttle_io_serviced.filename); + } else { + debug(D_CGROUP, "blkio.throttle.io_serviced file for cgroup '%s': '%s' does not exist.", cg->id, filename); + } } - else - debug(D_CGROUP, "throttle_io_serviced file for cgroup '%s': '%s' does not exist.", cg->id, filename); } - if(unlikely(cgroup_enable_blkio_merged_ops && !cg->io_merged.filename)) { - snprintfz(filename, FILENAME_MAX, "%s%s/blkio.io_merged", cgroup_blkio_base, cg->id); - if(likely(stat(filename, &buf) != -1)) { + if (unlikely(cgroup_enable_blkio_merged_ops && !cg->io_merged.filename)) { + snprintfz(filename, FILENAME_MAX, "%s%s/blkio.io_merged_recursive", cgroup_blkio_base, cg->id); + if (unlikely(stat(filename, &buf) != -1)) { cg->io_merged.filename = strdupz(filename); cg->io_merged.enabled = cgroup_enable_blkio_merged_ops; - debug(D_CGROUP, "io_merged filename for cgroup '%s': '%s'", cg->id, cg->io_merged.filename); + debug(D_CGROUP, "blkio.io_merged_recursive filename for cgroup '%s': '%s'", cg->id, cg->io_merged.filename); + } else { + debug(D_CGROUP, "blkio.io_merged_recursive file for cgroup '%s': '%s' does not exist.", cg->id, filename); + snprintfz(filename, FILENAME_MAX, "%s%s/blkio.io_merged", cgroup_blkio_base, cg->id); + if (likely(stat(filename, &buf) != -1)) { + cg->io_merged.filename = strdupz(filename); + cg->io_merged.enabled = cgroup_enable_blkio_merged_ops; + debug(D_CGROUP, "blkio.io_merged filename for cgroup '%s': '%s'", cg->id, cg->io_merged.filename); + } else { + debug(D_CGROUP, "blkio.io_merged file for cgroup '%s': '%s' does not exist.", cg->id, filename); + } } - else - debug(D_CGROUP, "io_merged file for cgroup '%s': '%s' does not exist.", cg->id, filename); } - if(unlikely(cgroup_enable_blkio_queued_ops && !cg->io_queued.filename)) { - snprintfz(filename, FILENAME_MAX, "%s%s/blkio.io_queued", cgroup_blkio_base, cg->id); - if(likely(stat(filename, &buf) != -1)) { + if (unlikely(cgroup_enable_blkio_queued_ops && !cg->io_queued.filename)) { + snprintfz(filename, FILENAME_MAX, "%s%s/blkio.io_queued_recursive", cgroup_blkio_base, cg->id); + if (unlikely(stat(filename, &buf) != -1)) { cg->io_queued.filename = strdupz(filename); cg->io_queued.enabled = cgroup_enable_blkio_queued_ops; - debug(D_CGROUP, "io_queued filename for cgroup '%s': '%s'", cg->id, cg->io_queued.filename); + debug(D_CGROUP, "blkio.io_queued_recursive filename for cgroup '%s': '%s'", cg->id, cg->io_queued.filename); + } else { + debug(D_CGROUP, "blkio.io_queued_recursive file for cgroup '%s': '%s' does not exist.", cg->id, filename); + snprintfz(filename, FILENAME_MAX, "%s%s/blkio.io_queued", cgroup_blkio_base, cg->id); + if (likely(stat(filename, &buf) != -1)) { + cg->io_queued.filename = strdupz(filename); + cg->io_queued.enabled = cgroup_enable_blkio_queued_ops; + debug(D_CGROUP, "blkio.io_queued filename for cgroup '%s': '%s'", cg->id, cg->io_queued.filename); + } else { + debug(D_CGROUP, "blkio.io_queued file for cgroup '%s': '%s' does not exist.", cg->id, filename); + } } - else - debug(D_CGROUP, "io_queued file for cgroup '%s': '%s' does not exist.", cg->id, filename); } } else if(likely(cgroup_unified_exist)) { @@ -1976,11 +2202,14 @@ static inline void update_filenames() } else debug(D_CGROUP, "io.stat file for unified cgroup '%s': '%s' does not exist.", cg->id, filename); } - if(unlikely(cgroup_enable_cpuacct_stat && !cg->cpuacct_stat.filename)) { + if (unlikely( + (cgroup_enable_cpuacct_stat || cgroup_enable_cpuacct_cpu_throttling) && + !cg->cpuacct_stat.filename)) { snprintfz(filename, FILENAME_MAX, "%s%s/cpu.stat", cgroup_unified_base, cg->id); if(likely(stat(filename, &buf) != -1)) { cg->cpuacct_stat.filename = strdupz(filename); cg->cpuacct_stat.enabled = cgroup_enable_cpuacct_stat; + cg->cpuacct_cpu_throttling.enabled = cgroup_enable_cpuacct_cpu_throttling; cg->filename_cpuset_cpus = NULL; cg->filename_cpu_cfs_period = NULL; snprintfz(filename, FILENAME_MAX, "%s%s/cpu.max", cgroup_unified_base, cg->id); @@ -3359,6 +3588,7 @@ void update_cgroup_charts(int update_every) { rrddim_add(cg->st_cpu_limit, "used", NULL, 1, system_hz, RRD_ALGORITHM_ABSOLUTE); else rrddim_add(cg->st_cpu_limit, "used", NULL, 1, 1000000, RRD_ALGORITHM_ABSOLUTE); + cg->prev_cpu_usage = (calculated_number)(cg->cpuacct_stat.user + cg->cpuacct_stat.system) * 100; } else rrdset_next(cg->st_cpu_limit); @@ -3386,6 +3616,60 @@ void update_cgroup_charts(int update_every) { } } + if (likely(cg->cpuacct_cpu_throttling.updated && cg->cpuacct_cpu_throttling.enabled == CONFIG_BOOLEAN_YES)) { + if (unlikely(!cg->st_cpu_nr_throttled)) { + snprintfz(title, CHART_TITLE_MAX, "CPU Throttled Runnable Periods"); + + cg->st_cpu_nr_throttled = rrdset_create_localhost( + cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX) + , "throttled" + , NULL + , "cpu" + , "cgroup.throttled" + , title + , "percentage" + , PLUGIN_CGROUPS_NAME + , PLUGIN_CGROUPS_MODULE_CGROUPS_NAME + , cgroup_containers_chart_priority + 10 + , update_every + , RRDSET_TYPE_LINE + ); + + rrdset_update_labels(cg->st_cpu_nr_throttled, cg->chart_labels); + rrddim_add(cg->st_cpu_nr_throttled, "throttled", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); + } else { + rrdset_next(cg->st_cpu_nr_throttled); + rrddim_set(cg->st_cpu_nr_throttled, "throttled", cg->cpuacct_cpu_throttling.nr_throttled_perc); + rrdset_done(cg->st_cpu_nr_throttled); + } + + if (unlikely(!cg->st_cpu_throttled_time)) { + snprintfz(title, CHART_TITLE_MAX, "CPU Throttled Time Duration"); + + cg->st_cpu_throttled_time = rrdset_create_localhost( + cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX) + , "throttled_duration" + , NULL + , "cpu" + , "cgroup.throttled_duration" + , title + , "ms" + , PLUGIN_CGROUPS_NAME + , PLUGIN_CGROUPS_MODULE_CGROUPS_NAME + , cgroup_containers_chart_priority + 15 + , update_every + , RRDSET_TYPE_LINE + ); + + rrdset_update_labels(cg->st_cpu_throttled_time, cg->chart_labels); + rrddim_add(cg->st_cpu_throttled_time, "duration", NULL, 1, 1000000, RRD_ALGORITHM_INCREMENTAL); + } else { + rrdset_next(cg->st_cpu_throttled_time); + rrddim_set(cg->st_cpu_throttled_time, "duration", cg->cpuacct_cpu_throttling.throttled_time); + rrdset_done(cg->st_cpu_throttled_time); + } + } + if(likely(cg->cpuacct_usage.updated && cg->cpuacct_usage.enabled == CONFIG_BOOLEAN_YES)) { char id[RRD_ID_LENGTH_MAX + 1]; unsigned int i; diff --git a/collectors/charts.d.plugin/README.md b/collectors/charts.d.plugin/README.md index 4a7911a60..06f4af1ec 100644 --- a/collectors/charts.d.plugin/README.md +++ b/collectors/charts.d.plugin/README.md @@ -195,4 +195,4 @@ This is what you need to do: Execute the above in this order, since Netdata will (by default) attempt to start new plugins soon after they are created in `/usr/libexec/netdata/plugins.d/`. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fcharts.d.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/charts.d.plugin/ap/README.md b/collectors/charts.d.plugin/ap/README.md index 35a00d65d..a7953a541 100644 --- a/collectors/charts.d.plugin/ap/README.md +++ b/collectors/charts.d.plugin/ap/README.md @@ -96,4 +96,4 @@ You can only set `ap_update_every=NUMBER` to change the data collection frequenc The plugin is able to auto-detect if you are running access points on your linux box. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fcharts.d.plugin%2Fap%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/charts.d.plugin/apcupsd/README.md b/collectors/charts.d.plugin/apcupsd/README.md index b5b41e84d..f1aebf97c 100644 --- a/collectors/charts.d.plugin/apcupsd/README.md +++ b/collectors/charts.d.plugin/apcupsd/README.md @@ -18,4 +18,4 @@ cd /etc/netdata # Replace this path with your Netdata config directory, if dif sudo ./edit-config charts.d/apcupsd.conf ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fcharts.d.plugin%2Fapcupsd%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/charts.d.plugin/apcupsd/apcupsd.chart.sh b/collectors/charts.d.plugin/apcupsd/apcupsd.chart.sh index e78d99e7d..b4edc0caf 100644 --- a/collectors/charts.d.plugin/apcupsd/apcupsd.chart.sh +++ b/collectors/charts.d.plugin/apcupsd/apcupsd.chart.sh @@ -50,7 +50,7 @@ apcupsd_check() { local host working=0 failed=0 for host in "${!apcupsd_sources[@]}"; do - run apcupsd_get "${apcupsd_sources[${host}]}" > /dev/null + apcupsd_get "${apcupsd_sources[${host}]}" > /dev/null # shellcheck disable=2181 if [ $? -ne 0 ]; then error "cannot get information for apcupsd server ${host} on ${apcupsd_sources[${host}]}." diff --git a/collectors/charts.d.plugin/example/README.md b/collectors/charts.d.plugin/example/README.md index c3dfd2c00..77446b270 100644 --- a/collectors/charts.d.plugin/example/README.md +++ b/collectors/charts.d.plugin/example/README.md @@ -7,4 +7,4 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/collectors/chart If you want to understand how charts.d data collector functions, check out the [charts.d example](https://raw.githubusercontent.com/netdata/netdata/master/collectors/charts.d.plugin/example/example.chart.sh). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fcharts.d.plugin%2Fexample%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/charts.d.plugin/libreswan/README.md b/collectors/charts.d.plugin/libreswan/README.md index b1c1f05e4..41c4e24c9 100644 --- a/collectors/charts.d.plugin/libreswan/README.md +++ b/collectors/charts.d.plugin/libreswan/README.md @@ -53,4 +53,4 @@ Make sure the path `/sbin/ipsec` matches your setup (execute `which ipsec` to fi --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fcharts.d.plugin%2Flibreswan%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/charts.d.plugin/nut/README.md b/collectors/charts.d.plugin/nut/README.md index 3f9c5f0a2..69d7622cd 100644 --- a/collectors/charts.d.plugin/nut/README.md +++ b/collectors/charts.d.plugin/nut/README.md @@ -71,4 +71,4 @@ nut_update_every=2 --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fcharts.d.plugin%2Fnut%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/charts.d.plugin/opensips/README.md b/collectors/charts.d.plugin/opensips/README.md index 7575a1dad..b08d19232 100644 --- a/collectors/charts.d.plugin/opensips/README.md +++ b/collectors/charts.d.plugin/opensips/README.md @@ -16,4 +16,4 @@ cd /etc/netdata # Replace this path with your Netdata config directory, if dif sudo ./edit-config charts.d/opensips.conf ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fcharts.d.plugin%2Fopensips%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/charts.d.plugin/sensors/README.md b/collectors/charts.d.plugin/sensors/README.md index 2a1cdb676..ab7a8b660 100644 --- a/collectors/charts.d.plugin/sensors/README.md +++ b/collectors/charts.d.plugin/sensors/README.md @@ -81,4 +81,4 @@ sensors_excluded=() --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fcharts.d.plugin%2Fsensors%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/charts.d.plugin/sensors/sensors.chart.sh b/collectors/charts.d.plugin/sensors/sensors.chart.sh index bff381f1c..0527e1e7e 100644 --- a/collectors/charts.d.plugin/sensors/sensors.chart.sh +++ b/collectors/charts.d.plugin/sensors/sensors.chart.sh @@ -143,8 +143,8 @@ sensors_create() { files="$(sensors_check_files "$files")" files="$(sensors_check_temp_type "$files")" [ -z "$files" ] && continue - echo "CHART sensors.temp_$id '' '$name Temperature' 'Celsius' 'temperature' 'sensors.temp' line $((sensors_priority + 1)) $sensors_update_every '' '' 'sensors'" - echo >>"$TMP_DIR/sensors.sh" "echo \"BEGIN sensors.temp_$id \$1\"" + echo "CHART 'sensors.temp_${id}_${name}' '' 'Temperature' 'Celsius' 'temperature' 'sensors.temp' line $((sensors_priority + 1)) $sensors_update_every '' '' 'sensors'" + echo >>"$TMP_DIR/sensors.sh" "echo \"BEGIN 'sensors.temp_${id}_${name}' \$1\"" divisor=1000 ;; @@ -152,8 +152,8 @@ sensors_create() { files="$(ls "$path"/in*_input 2>/dev/null)" files="$(sensors_check_files "$files")" [ -z "$files" ] && continue - echo "CHART sensors.volt_$id '' '$name Voltage' 'Volts' 'voltage' 'sensors.volt' line $((sensors_priority + 2)) $sensors_update_every '' '' 'sensors'" - echo >>"$TMP_DIR/sensors.sh" "echo \"BEGIN sensors.volt_$id \$1\"" + echo "CHART 'sensors.volt_${id}_${name}' '' 'Voltage' 'Volts' 'voltage' 'sensors.volt' line $((sensors_priority + 2)) $sensors_update_every '' '' 'sensors'" + echo >>"$TMP_DIR/sensors.sh" "echo \"BEGIN 'sensors.volt_${id}_${name}' \$1\"" divisor=1000 ;; @@ -161,8 +161,8 @@ sensors_create() { files="$(ls "$path"/curr*_input 2>/dev/null)" files="$(sensors_check_files "$files")" [ -z "$files" ] && continue - echo "CHART sensors.curr_$id '' '$name Current' 'Ampere' 'current' 'sensors.curr' line $((sensors_priority + 3)) $sensors_update_every '' '' 'sensors'" - echo >>"$TMP_DIR/sensors.sh" "echo \"BEGIN sensors.curr_$id \$1\"" + echo "CHART 'sensors.curr_${id}_${name}' '' 'Current' 'Ampere' 'current' 'sensors.curr' line $((sensors_priority + 3)) $sensors_update_every '' '' 'sensors'" + echo >>"$TMP_DIR/sensors.sh" "echo \"BEGIN 'sensors.curr_${id}_${name}' \$1\"" divisor=1000 ;; @@ -170,8 +170,8 @@ sensors_create() { files="$(ls "$path"/power*_input 2>/dev/null)" files="$(sensors_check_files "$files")" [ -z "$files" ] && continue - echo "CHART sensors.power_$id '' '$name Power' 'Watt' 'power' 'sensors.power' line $((sensors_priority + 4)) $sensors_update_every '' '' 'sensors'" - echo >>"$TMP_DIR/sensors.sh" "echo \"BEGIN sensors.power_$id \$1\"" + echo "CHART 'sensors.power_${id}_${name}' '' 'Power' 'Watt' 'power' 'sensors.power' line $((sensors_priority + 4)) $sensors_update_every '' '' 'sensors'" + echo >>"$TMP_DIR/sensors.sh" "echo \"BEGIN 'sensors.power_${id}_${name}' \$1\"" divisor=1000000 ;; @@ -179,16 +179,16 @@ sensors_create() { files="$(ls "$path"/fan*_input 2>/dev/null)" files="$(sensors_check_files "$files")" [ -z "$files" ] && continue - echo "CHART sensors.fan_$id '' '$name Fans Speed' 'Rotations / Minute' 'fans' 'sensors.fans' line $((sensors_priority + 5)) $sensors_update_every '' '' 'sensors'" - echo >>"$TMP_DIR/sensors.sh" "echo \"BEGIN sensors.fan_$id \$1\"" + echo "CHART 'sensors.fan_${id}_${name}' '' 'Fans Speed' 'Rotations / Minute' 'fans' 'sensors.fans' line $((sensors_priority + 5)) $sensors_update_every '' '' 'sensors'" + echo >>"$TMP_DIR/sensors.sh" "echo \"BEGIN 'sensors.fan_${id}_${name}' \$1\"" ;; energy) files="$(ls "$path"/energy*_input 2>/dev/null)" files="$(sensors_check_files "$files")" [ -z "$files" ] && continue - echo "CHART sensors.energy_$id '' '$name Energy' 'Joule' 'energy' 'sensors.energy' areastack $((sensors_priority + 6)) $sensors_update_every '' '' 'sensors'" - echo >>"$TMP_DIR/sensors.sh" "echo \"BEGIN sensors.energy_$id \$1\"" + echo "CHART 'sensors.energy_${id}_${name}' '' 'Energy' 'Joule' 'energy' 'sensors.energy' areastack $((sensors_priority + 6)) $sensors_update_every '' '' 'sensors'" + echo >>"$TMP_DIR/sensors.sh" "echo \"BEGIN 'sensors.energy_${id}_${name}' \$1\"" algorithm="incremental" divisor=1000000 ;; @@ -197,8 +197,8 @@ sensors_create() { files="$(ls "$path"/humidity*_input 2>/dev/null)" files="$(sensors_check_files "$files")" [ -z "$files" ] && continue - echo "CHART sensors.humidity_$id '' '$name Humidity' 'Percent' 'humidity' 'sensors.humidity' line $((sensors_priority + 7)) $sensors_update_every '' '' 'sensors'" - echo >>"$TMP_DIR/sensors.sh" "echo \"BEGIN sensors.humidity_$id \$1\"" + echo "CHART 'sensors.humidity_${id}_${name}' '' 'Humidity' 'Percent' 'humidity' 'sensors.humidity' line $((sensors_priority + 7)) $sensors_update_every '' '' 'sensors'" + echo >>"$TMP_DIR/sensors.sh" "echo \"BEGIN 'sensors.humidity_${id}_${name}' \$1\"" divisor=1000 ;; diff --git a/collectors/checks.plugin/README.md b/collectors/checks.plugin/README.md index 5f1a6b912..6e2cf5dea 100644 --- a/collectors/checks.plugin/README.md +++ b/collectors/checks.plugin/README.md @@ -7,4 +7,4 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/collectors/check A debugging plugin (by default it is disabled) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fchecks.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/cups.plugin/README.md b/collectors/cups.plugin/README.md index 373602dca..e3d2e1661 100644 --- a/collectors/cups.plugin/README.md +++ b/collectors/cups.plugin/README.md @@ -59,4 +59,4 @@ For each destination the plugin provides these charts: At the moment only job status pending, processing, and held are reported because we do not have a method to collect stopped, canceled, aborted and completed jobs which scales. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2cups.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]() + diff --git a/collectors/cups.plugin/cups_plugin.c b/collectors/cups.plugin/cups_plugin.c index a4c94d1d6..cc57dbf1f 100644 --- a/collectors/cups.plugin/cups_plugin.c +++ b/collectors/cups.plugin/cups_plugin.c @@ -161,12 +161,12 @@ struct job_metrics *get_job_metrics(char *dest) { reset_job_metrics(&new_job_metrics, NULL); jm = dictionary_set(dict_dest_job_metrics, dest, &new_job_metrics, sizeof(struct job_metrics)); - printf("CHART cups.job_num_%s '' 'Active job number of destination %s' jobs '%s' job_num stacked %i %i\n", dest, dest, dest, netdata_priority++, netdata_update_every); + printf("CHART cups.job_num_%s '' 'Active job number of destination %s' jobs '%s' cups.job_num stacked %i %i\n", dest, dest, dest, netdata_priority++, netdata_update_every); printf("DIMENSION pending '' absolute 1 1\n"); printf("DIMENSION held '' absolute 1 1\n"); printf("DIMENSION processing '' absolute 1 1\n"); - printf("CHART cups.job_size_%s '' 'Active job size of destination %s' KB '%s' job_size stacked %i %i\n", dest, dest, dest, netdata_priority++, netdata_update_every); + printf("CHART cups.job_size_%s '' 'Active job size of destination %s' KB '%s' cups.job_size stacked %i %i\n", dest, dest, dest, netdata_priority++, netdata_update_every); printf("DIMENSION pending '' absolute 1 1\n"); printf("DIMENSION held '' absolute 1 1\n"); printf("DIMENSION processing '' absolute 1 1\n"); @@ -195,12 +195,12 @@ int collect_job_metrics(char *name, void *entry, void *data) { "END\n", name, jm->size_pending, jm->size_held, jm->size_processing); } else { - printf("CHART cups.job_num_%s '' 'Active job number of destination %s' jobs '%s' job_num stacked 1 %i 'obsolete'\n", name, name, name, netdata_update_every); + printf("CHART cups.job_num_%s '' 'Active job number of destination %s' jobs '%s' cups.job_num stacked 1 %i 'obsolete'\n", name, name, name, netdata_update_every); printf("DIMENSION pending '' absolute 1 1\n"); printf("DIMENSION held '' absolute 1 1\n"); printf("DIMENSION processing '' absolute 1 1\n"); - printf("CHART cups.job_size_%s '' 'Active job size of destination %s' KB '%s' job_size stacked 1 %i 'obsolete'\n", name, name, name, netdata_update_every); + printf("CHART cups.job_size_%s '' 'Active job size of destination %s' KB '%s' cups.job_size stacked 1 %i 'obsolete'\n", name, name, name, netdata_update_every); printf("DIMENSION pending '' absolute 1 1\n"); printf("DIMENSION held '' absolute 1 1\n"); printf("DIMENSION processing '' absolute 1 1\n"); @@ -375,22 +375,22 @@ int main(int argc, char **argv) { if (unlikely(!cups_printer_by_option_created)) { cups_printer_by_option_created = 1; - printf("CHART cups.dest_state '' 'Destinations by state' dests overview dests stacked 100000 %i\n", netdata_update_every); + printf("CHART cups.dest_state '' 'Destinations by state' dests overview cups.dests_state stacked 100000 %i\n", netdata_update_every); printf("DIMENSION idle '' absolute 1 1\n"); printf("DIMENSION printing '' absolute 1 1\n"); printf("DIMENSION stopped '' absolute 1 1\n"); - printf("CHART cups.dest_option '' 'Destinations by option' dests overview dests line 100001 %i\n", netdata_update_every); + printf("CHART cups.dest_option '' 'Destinations by option' dests overview cups.dests_option line 100001 %i\n", netdata_update_every); printf("DIMENSION total '' absolute 1 1\n"); printf("DIMENSION acceptingjobs '' absolute 1 1\n"); printf("DIMENSION shared '' absolute 1 1\n"); - printf("CHART cups.job_num '' 'Total active job number' jobs overview job_num stacked 100002 %i\n", netdata_update_every); + printf("CHART cups.job_num '' 'Total active job number' jobs overview cups.job_num stacked 100002 %i\n", netdata_update_every); printf("DIMENSION pending '' absolute 1 1\n"); printf("DIMENSION held '' absolute 1 1\n"); printf("DIMENSION processing '' absolute 1 1\n"); - printf("CHART cups.job_size '' 'Total active job size' KB overview job_size stacked 100003 %i\n", netdata_update_every); + printf("CHART cups.job_size '' 'Total active job size' KB overview cups.job_size stacked 100003 %i\n", netdata_update_every); printf("DIMENSION pending '' absolute 1 1\n"); printf("DIMENSION held '' absolute 1 1\n"); printf("DIMENSION processing '' absolute 1 1\n"); diff --git a/collectors/diskspace.plugin/README.md b/collectors/diskspace.plugin/README.md index a8b41c861..c037a0b16 100644 --- a/collectors/diskspace.plugin/README.md +++ b/collectors/diskspace.plugin/README.md @@ -40,4 +40,4 @@ Charts can be enabled/disabled for every mount separately: > for disks performance monitoring, see the `proc` plugin, [here](/collectors/proc.plugin/README.md#monitoring-disks) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fdiskspace.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/diskspace.plugin/plugin_diskspace.c b/collectors/diskspace.plugin/plugin_diskspace.c index c148e415a..b6a52c061 100644 --- a/collectors/diskspace.plugin/plugin_diskspace.c +++ b/collectors/diskspace.plugin/plugin_diskspace.c @@ -284,7 +284,7 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) { m->st_space = rrdset_find_active_bytype_localhost("disk_space", disk); if(unlikely(!m->st_space)) { char title[4096 + 1]; - snprintfz(title, 4096, "Disk Space Usage for %s [%s]", family, mi->mount_source); + snprintfz(title, 4096, "Disk Space Usage"); m->st_space = rrdset_create_localhost( "disk_space" , disk @@ -326,7 +326,7 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) { m->st_inodes = rrdset_find_active_bytype_localhost("disk_inodes", disk); if(unlikely(!m->st_inodes)) { char title[4096 + 1]; - snprintfz(title, 4096, "Disk Files (inodes) Usage for %s [%s]", family, mi->mount_source); + snprintfz(title, 4096, "Disk Files (inodes) Usage"); m->st_inodes = rrdset_create_localhost( "disk_inodes" , disk diff --git a/collectors/ebpf.plugin/README.md b/collectors/ebpf.plugin/README.md index babcd5206..c32133b1c 100644 --- a/collectors/ebpf.plugin/README.md +++ b/collectors/ebpf.plugin/README.md @@ -8,51 +8,405 @@ sidebar_label: "eBPF" # eBPF monitoring with Netdata -eBPF consists of a wide toolchain that ultimately outputs a set of bytecode that will run inside the eBPF virtual -machine (VM) which lives inside the Linux kernel. The program in particular is executed in response to a [tracepoint -or kprobe](#probes-and-tracepoints) activation. +The Netdata Agent provides many [eBPF](https://ebpf.io/what-is-ebpf/) programs to help you troubleshoot and debug how applications interact with the Linux kernel. The `ebpf.plugin` uses [tracepoints, trampoline, and2 kprobes](#data-collection) to collect a wide array of high value data about the host that would otherwise be impossible to capture. -Netdata has written many eBPF programs, which, when compiled and integrated into the Netdata Agent, are able to collect -a wide array of data about the host that would otherwise be impossible. The data eBPF programs can collect is truly unique, -which gives the Netdata Agent access to data that is high value but normally hard to capture. +> ❗ eBPF monitoring only works on Linux systems and with specific Linux kernels, including all kernels newer than `4.11.0`, and all kernels on CentOS 7.6 or later. For kernels older than `4.11.0`, improved support is in active development. -eBPF monitoring can help you troubleshoot and debug how applications interact with the Linux kernel. See -our [guide on troubleshooting apps with eBPF metrics](/docs/guides/troubleshoot/monitor-debug-applications-ebpf.md) for -configuration and troubleshooting tips. +This document provides comprehensive details about the `ebpf.plugin`. +For hands-on configuration and troubleshooting tips see our [tutorial on troubleshooting apps with eBPF metrics](/docs/guides/troubleshoot/monitor-debug-applications-ebpf.md).
An example of VFS charts, made possible by the eBPF collector plugin -
An example of VFS charts made possible by the eBPF collector plugin.
+
An example of virtual file system (VFS) charts made possible by the eBPF collector plugin.
-## Probes and Tracepoints + -The following two features from the Linux kernel are used by Netdata to run eBPF programs: +## How Netdata collects data using probes and tracepoints -- Kprobes and return probes (kretprobe): Probes can insert virtually into any kernel instruction. When eBPF runs in - `entry` mode, it attaches only `kprobes` for internal functions monitoring calls and some arguments every time a - function is called. The user can also change configuration to use [`return`](#global) mode, and this will allow users - to monitor return from these functions and detect possible failures. -- Tracepoints are hooks to call specific functions. Tracepoints are more stable than `kprobes` and are preferred when - both options are available. +Netdata uses the following features from the Linux kernel to run eBPF programs: -In each case, wherever a normal kprobe, kretprobe, or tracepoint would have run its hook function, an eBPF program is -run instead, performing various collection logic before letting the kernel continue its normal control flow. +- Tracepoints are hooks to call specific functions. Tracepoints are more stable than `kprobes` and are preferred when + both options are available. +- Trampolines are bridges between kernel functions, and BPF programs. Netdata uses them by default whenever available. +- Kprobes and return probes (`kretprobe`): Probes can insert virtually into any kernel instruction. When eBPF runs in `entry` mode, it attaches only `kprobes` for internal functions monitoring calls and some arguments every time a function is called. The user can also change configuration to use [`return`](#global) mode, and this will allow users to monitor return from these functions and detect possible failures. -There are more methods by which eBPF programs can be triggered but which are not currently supported, such as via uprobes -which allow hooking into arbitrary user-space functions in a similar manner to kprobes. +In each case, wherever a normal kprobe, kretprobe, or tracepoint would have run its hook function, an eBPF program is run instead, performing various collection logic before letting the kernel continue its normal control flow. -## Manually enable the collector on Linux +There are more methods to trigger eBPF programs, such as uprobes, but currently are not supported. -**The eBPF collector is installed and enabled by default on most new installations of the Agent**. The eBPF collector -does not currently work with [static build installations](/packaging/installer/methods/kickstart.md#static-builds) for kernels older -than `4.11`, but improved support is in active development. +## Configuring ebpf.plugin -eBPF monitoring only works on Linux systems and with specific Linux kernels, including all kernels newer than `4.11.0`, -and all kernels on CentOS 7.6 or later. +The eBPF collector is installed and enabled by default on most new installations of the Agent. +If your Agent is v1.22 or older, you may to enable the collector yourself. -If your Agent is v1.22 or older, you may to enable the collector yourself. See the [configuration](#configuration) -section for details. +### Enable the eBPF collector + +To enable or disable the entire eBPF collector: + +1. Navigate to the [Netdata config directory](/docs/configure/nodes.md#the-netdata-config-directory). + ```bash + cd /etc/netdata + ``` + +2. Use the [`edit-config`](/docs/configure/nodes.md#use-edit-config-to-edit-configuration-files) script to edit `netdata.conf`. + + ```bash + ./edit-config netdata.conf + ``` + +3. Enable the collector by scrolling down to the `[plugins]` section. Uncomment the line `ebpf` (not + `ebpf_process`) and set it to `yes`. + + ```conf + [plugins] + ebpf = yes + ``` + +### Configure the eBPF collector + +You can configure the eBPF collector's behavior to fine-tune which metrics you receive and [optimize performance]\(#performance opimization). + +To edit the `ebpf.d.conf`: + +1. Navigate to the [Netdata config directory](/docs/configure/nodes.md#the-netdata-config-directory). + ```bash + cd /etc/netdata + ``` +2. Use the [`edit-config`](/docs/configure/nodes.md#use-edit-config-to-edit-configuration-files) script to edit [`ebpf.d.conf`](https://github.com/netdata/netdata/blob/master/collectors/ebpf.plugin/ebpf.d.conf). + + ```bash + ./edit-config ebpf.d.conf + ``` + + You can now edit the behavior of the eBPF collector. The following sections describe each configuration option in detail. + +### `[global]` configuration options + +The `[global]` section defines settings for the whole eBPF collector. + +#### eBPF load mode + +The collector uses two different eBPF programs. These programs rely on the same functions inside the kernel, but they +monitor, process, and display different kinds of information. + +By default, this plugin uses the `entry` mode. Changing this mode can create significant overhead on your operating +system, but also offer valuable information if you are developing or debugging software. The `ebpf load mode` option +accepts the following values: + +- `entry`: This is the default mode. In this mode, the eBPF collector only monitors calls for the functions described in + the sections above, and does not show charts related to errors. +- `return`: In the `return` mode, the eBPF collector monitors the same kernel functions as `entry`, but also creates new + charts for the return of these functions, such as errors. Monitoring function returns can help in debugging software, + such as failing to close file descriptors or creating zombie processes. +- `update every`: Number of seconds used for eBPF to send data for Netdata. +- `pid table size`: Defines the maximum number of PIDs stored inside the application hash table. + +#### Integration with `apps.plugin` + +The eBPF collector also creates charts for each running application through an integration with the +[`apps.plugin`](/collectors/apps.plugin/README.md). This integration helps you understand how specific applications +interact with the Linux kernel. + +If you want to _disable_ the integration with `apps.plugin` along with the above charts, change the setting `apps` to +`no`. + +```conf +[global] + apps = yes +``` + +When the integration is enabled, eBPF collector allocates memory for each process running. The total allocated memory +has direct relationship with the kernel version. When the eBPF plugin is running on kernels newer than `4.15`, it uses +per-cpu maps to speed up the update of hash tables. This also implies storing data for the same PID for each processor +it runs. + +#### Integration with `cgroups.plugin` + +The eBPF collector also creates charts for each cgroup through an integration with the +[`cgroups.plugin`](/collectors/cgroups.plugin/README.md). This integration helps you understand how a specific cgroup +interacts with the Linux kernel. + +The integration with `cgroups.plugin` is disabled by default to avoid creating overhead on your system. If you want to +_enable_ the integration with `cgroups.plugin`, change the `cgroups` setting to `yes`. + +```conf +[global] + cgroups = yes +``` + +If you do not need to monitor specific metrics for your `cgroups`, you can enable `cgroups` inside +`ebpf.d.conf`, and then disable the plugin for a specific `thread` by following the steps in the +[Configuration](#configuration) section. + +#### Integration Dashboard Elements + +When an integration is enabled, your dashboard will also show the following cgroups and apps charts using low-level +Linux metrics: + +> Note: The parenthetical accompanying each bulleted item provides the chart name. + +- mem + - Number of processes killed due out of memory. (`oomkills`) +- process + - Number of processes created with `do_fork`. (`process_create`) + - Number of threads created with `do_fork` or `clone (2)`, depending on your system's kernel + version. (`thread_create`) + - Number of times that a process called `do_exit`. (`task_exit`) + - Number of times that a process called `release_task`. (`task_close`) + - Number of times that an error happened to create thread or process. (`task_error`) +- swap + - Number of calls to `swap_readpage`. (`swap_read_call`) + - Number of calls to `swap_writepage`. (`swap_write_call`) +- network + - Number of outbound connections using TCP/IPv4. (`outbound_conn_ipv4`) + - Number of outbound connections using TCP/IPv6. (`outbound_conn_ipv6`) + - Number of bytes sent. (`total_bandwidth_sent`) + - Number of bytes received. (`total_bandwidth_recv`) + - Number of calls to `tcp_sendmsg`. (`bandwidth_tcp_send`) + - Number of calls to `tcp_cleanup_rbuf`. (`bandwidth_tcp_recv`) + - Number of calls to `tcp_retransmit_skb`. (`bandwidth_tcp_retransmit`) + - Number of calls to `udp_sendmsg`. (`bandwidth_udp_send`) + - Number of calls to `udp_recvmsg`. (`bandwidth_udp_recv`) +- file access + - Number of calls to open files. (`file_open`) + - Number of calls to open files that returned errors. (`open_error`) + - Number of files closed. (`file_closed`) + - Number of calls to close files that returned errors. (`file_error_closed`) +- vfs + - Number of calls to `vfs_unlink`. (`file_deleted`) + - Number of calls to `vfs_write`. (`vfs_write_call`) + - Number of calls to write a file that returned errors. (`vfs_write_error`) + - Number of calls to `vfs_read`. (`vfs_read_call`) + - - Number of calls to read a file that returned errors. (`vfs_read_error`) + - Number of bytes written with `vfs_write`. (`vfs_write_bytes`) + - Number of bytes read with `vfs_read`. (`vfs_read_bytes`) + - Number of calls to `vfs_fsync`. (`vfs_fsync`) + - Number of calls to sync file that returned errors. (`vfs_fsync_error`) + - Number of calls to `vfs_open`. (`vfs_open`) + - Number of calls to open file that returned errors. (`vfs_open_error`) + - Number of calls to `vfs_create`. (`vfs_create`) + - Number of calls to open file that returned errors. (`vfs_create_error`) +- page cache + - Ratio of pages accessed. (`cachestat_ratio`) + - Number of modified pages ("dirty"). (`cachestat_dirties`) + - Number of accessed pages. (`cachestat_hits`) + - Number of pages brought from disk. (`cachestat_misses`) +- directory cache + - Ratio of files available in directory cache. (`dc_hit_ratio`) + - Number of files accessed. (`dc_reference`) + - Number of files accessed that were not in cache. (`dc_not_cache`) + - Number of files not found. (`dc_not_found`) +- ipc shm + - Number of calls to `shm_get`. (`shmget_call`) + - Number of calls to `shm_at`. (`shmat_call`) + - Number of calls to `shm_dt`. (`shmdt_call`) + - Number of calls to `shm_ctl`. (`shmctl_call`) + +### `[ebpf programs]` configuration options + +The eBPF collector enables and runs the following eBPF programs by default: + +- `fd` : This eBPF program creates charts that show information about calls to open files. +- `mount`: This eBPF program creates charts that show calls to syscalls mount(2) and umount(2). +- `shm`: This eBPF program creates charts that show calls to syscalls shmget(2), shmat(2), shmdt(2) and shmctl(2). +- `sync`: Monitor calls to syscalls sync(2), fsync(2), fdatasync(2), syncfs(2), msync(2), and sync_file_range(2). +- `network viewer`: This eBPF program creates charts with information about `TCP` and `UDP` functions, including the + bandwidth consumed by each. +- `vfs`: This eBPF program creates charts that show information about VFS (Virtual File System) functions. +- `process`: This eBPF program creates charts that show information about process life. When in `return` mode, it also + creates charts showing errors when these operations are executed. +- `hardirq`: This eBPF program creates charts that show information about time spent servicing individual hardware + interrupt requests (hard IRQs). +- `softirq`: This eBPF program creates charts that show information about time spent servicing individual software + interrupt requests (soft IRQs). +- `oomkill`: This eBPF program creates a chart that shows OOM kills for all applications recognized via + the `apps.plugin` integration. Note that this program will show application charts regardless of whether apps + integration is turned on or off. + +You can also enable the following eBPF programs: + +- `cachestat`: Netdata's eBPF data collector creates charts about the memory page cache. When the integration with + [`apps.plugin`](/collectors/apps.plugin/README.md) is enabled, this collector creates charts for the whole host _and_ + for each application. +- `dcstat` : This eBPF program creates charts that show information about file access using directory cache. It appends + `kprobes` for `lookup_fast()` and `d_lookup()` to identify if files are inside directory cache, outside and files are + not found. +- `disk` : This eBPF program creates charts that show information about disk latency independent of filesystem. +- `filesystem` : This eBPF program creates charts that show information about some filesystem latency. +- `swap` : This eBPF program creates charts that show information about swap access. +- `mdflush`: This eBPF program creates charts that show information about + multi-device software flushes. + +### Configuring eBPF threads + +You can configure each thread of the eBPF data collector. This allows you to overwrite global options defined in `/etc/netdata/ebpf.d.conf` and configure specific options for each thread. + +To configure an eBPF thread: + +1. Navigate to the [Netdata config directory](/docs/configure/nodes.md#the-netdata-config-directory). + ```bash + cd /etc/netdata + ``` +2. Use the [`edit-config`](/docs/configure/nodes.md#use-edit-config-to-edit-configuration-files) script to edit a thread configuration file. The following configuration files are available: + + - `network.conf`: Configuration for the [`network` thread](#network-configuration). This config file overwrites the global options and also + lets you specify which network the eBPF collector monitors. + - `process.conf`: Configuration for the [`process` thread](#sync-configuration). + - `cachestat.conf`: Configuration for the `cachestat` thread(#filesystem-configuration). + - `dcstat.conf`: Configuration for the `dcstat` thread. + - `disk.conf`: Configuration for the `disk` thread. + - `fd.conf`: Configuration for the `file descriptor` thread. + - `filesystem.conf`: Configuration for the `filesystem` thread. + - `hardirq.conf`: Configuration for the `hardirq` thread. + - `softirq.conf`: Configuration for the `softirq` thread. + - `sync.conf`: Configuration for the `sync` thread. + - `vfs.conf`: Configuration for the `vfs` thread. + + ```bash + ./edit-config FILE.conf + ``` + +### Network configuration + +The network configuration has specific options to configure which network(s) the eBPF collector monitors. These options +are divided in the following sections: + +#### `[network connections]` + +You can configure the information shown on `outbound` and `inbound` charts with the settings in this section. + +```conf +[network connections] + maximum dimensions = 500 + resolve hostname ips = no + ports = 1-1024 !145 !domain + hostnames = !example.com + ips = !127.0.0.1/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 fc00::/7 +``` + +When you define a `ports` setting, Netdata will collect network metrics for that specific port. For example, if you +write `ports = 19999`, Netdata will collect only connections for itself. The `hostnames` setting accepts +[simple patterns](/libnetdata/simple_pattern/README.md). The `ports`, and `ips` settings accept negation (`!`) to deny +specific values or asterisk alone to define all values. + +In the above example, Netdata will collect metrics for all ports between 1 and 443, with the exception of 53 (domain) +and 145. + +The following options are available: + +- `ports`: Define the destination ports for Netdata to monitor. +- `hostnames`: The list of hostnames that can be resolved to an IP address. +- `ips`: The IP or range of IPs that you want to monitor. You can use IPv4 or IPv6 addresses, use dashes to define a + range of IPs, or use CIDR values. By default, only data for private IP addresses is collected, but this can + be changed with the `ips` setting. + +By default, Netdata displays up to 500 dimensions on network connection charts. If there are more possible dimensions, +they will be bundled into the `other` dimension. You can increase the number of shown dimensions by changing +the `maximum dimensions` setting. + +The dimensions for the traffic charts are created using the destination IPs of the sockets by default. This can be +changed setting `resolve hostname ips = yes` and restarting Netdata, after this Netdata will create dimensions using +the `hostnames` every time that is possible to resolve IPs to their hostnames. + +#### `[service name]` + +Netdata uses the list of services in `/etc/services` to plot network connection charts. If this file does not contain +the name for a particular service you use in your infrastructure, you will need to add it to the `[service name]` +section. + +For example, Netdata's default port (`19999`) is not listed in `/etc/services`. To associate that port with the Netdata +service in network connection charts, and thus see the name of the service instead of its port, define it: + +```conf +[service name] + 19999 = Netdata +``` + +### Sync configuration + +The sync configuration has specific options to disable monitoring for syscalls. All syscalls are monitored by default. + +```conf +[syscalls] + sync = yes + msync = yes + fsync = yes + fdatasync = yes + syncfs = yes + sync_file_range = yes +``` + +### Filesystem configuration + +The filesystem configuration has specific options to disable monitoring for filesystems; by default, all filesystems are +monitored. + +```conf +[filesystem] + btrfsdist = yes + ext4dist = yes + nfsdist = yes + xfsdist = yes + zfsdist = yes +``` + +The ebpf program `nfsdist` monitors only `nfs` mount points. + +## Troubleshooting + +If the eBPF collector does not work, you can troubleshoot it by running the `ebpf.plugin` command and investigating its +output. + +```bash +cd /usr/libexec/netdata/plugins.d/ +sudo su -s /bin/bash ./ebpf.plugin +``` + +You can also use `grep` to search the Agent's `error.log` for messages related to eBPF monitoring. + +```bash +grep -i ebpf /var/log/netdata/error.log +``` + +### Confirm kernel compatibility + +The eBPF collector only works on Linux systems and with specific Linux kernels. We support all kernels more recent than +`4.11.0`, and all kernels on CentOS 7.6 or later. + +You can run our helper script to determine whether your system can support eBPF monitoring. If it returns no output, your system is ready to compile and run the eBPF collector. + +```bash +curl -sSL https://raw.githubusercontent.com/netdata/kernel-collector/master/tools/check-kernel-config.sh | sudo bash +``` + + +If you see a warning about a missing kernel +configuration (`KPROBES KPROBES_ON_FTRACE HAVE_KPROBES BPF BPF_SYSCALL BPF_JIT`), you will need to recompile your kernel +to support this configuration. The process of recompiling Linux kernels varies based on your distribution and version. +Read the documentation for your system's distribution to learn more about the specific workflow for recompiling the +kernel, ensuring that you set all the necessary + +- [Ubuntu](https://wiki.ubuntu.com/Kernel/BuildYourOwnKernel) +- [Debian](https://kernel-team.pages.debian.net/kernel-handbook/ch-common-tasks.html#s-common-official) +- [Fedora](https://fedoraproject.org/wiki/Building_a_custom_kernel) +- [CentOS](https://wiki.centos.org/HowTos/Custom_Kernel) +- [Arch Linux](https://wiki.archlinux.org/index.php/Kernel/Traditional_compilation) +- [Slackware](https://docs.slackware.com/howtos:slackware_admin:kernelbuilding) + +### Mount `debugfs` and `tracefs` + +The eBPF collector also requires both the `tracefs` and `debugfs` filesystems. Try mounting the `tracefs` and `debugfs` +filesystems using the commands below: + +```bash +sudo mount -t debugfs nodev /sys/kernel/debug +sudo mount -t tracefs nodev /sys/kernel/tracing +``` + +If they are already mounted, you will see an error. You can also configure your system's `/etc/fstab` configuration to +mount these filesystems on startup. More information can be found in +the [ftrace documentation](https://www.kernel.org/doc/Documentation/trace/ftrace.txt). ## Charts @@ -64,8 +418,7 @@ collected in the previous and current seconds. ### System overview -Not all charts within the System Overview menu are enabled by default, because they add around 100ns overhead for each -function call, this number is small for a human perspective, but the functions are called many times creating an impact +Not all charts within the System Overview menu are enabled by default. Charts that rely on `kprobes` are disabled by default because they add around 100ns overhead for each function call. This is a small number from a human's perspective, but the functions are called many times and create an impact on host. See the [configuration](#configuration) section for details about how to enable them. #### Processes @@ -74,12 +427,12 @@ Internally, the Linux kernel treats both processes and threads as `tasks`. To cr system calls: `fork(2)`, `vfork(2)`, and `clone(2)`. To generate this chart, the eBPF collector uses the following `tracepoints` and `kprobe`: -- `sched/sched_process_fork`: Tracepoint called after a call for `fork (2)`, `vfork (2)` and `clone (2)`. -- `sched/sched_process_exec`: Tracepoint called after a exec-family syscall. -- `kprobe/kernel_clone`: This is the main [`fork()`](https://elixir.bootlin.com/linux/v5.10/source/kernel/fork.c#L2415) - routine since kernel `5.10.0` was released. -- `kprobe/_do_fork`: Like `kernel_clone`, but this was the main function between kernels `4.2.0` and `5.9.16` -- `kprobe/do_fork`: This was the main function before kernel `4.2.0`. +- `sched/sched_process_fork`: Tracepoint called after a call for `fork (2)`, `vfork (2)` and `clone (2)`. +- `sched/sched_process_exec`: Tracepoint called after a exec-family syscall. +- `kprobe/kernel_clone`: This is the main [`fork()`](https://elixir.bootlin.com/linux/v5.10/source/kernel/fork.c#L2415) + routine since kernel `5.10.0` was released. +- `kprobe/_do_fork`: Like `kernel_clone`, but this was the main function between kernels `4.2.0` and `5.9.16` +- `kprobe/do_fork`: This was the main function before kernel `4.2.0`. #### Process Exit @@ -88,9 +441,9 @@ system that the task is finishing its work. The second step is to release the ke function `release_task`. The difference between the two dimensions can help you discover [zombie processes](https://en.wikipedia.org/wiki/Zombie_process). To get the metrics, the collector uses: -- `sched/sched_process_exit`: Tracepoint called after a task exits. -- `kprobe/release_task`: This function is called when a process exits, as the kernel still needs to remove the process - descriptor. +- `sched/sched_process_exit`: Tracepoint called after a task exits. +- `kprobe/release_task`: This function is called when a process exits, as the kernel still needs to remove the process + descriptor. #### Task error @@ -100,7 +453,7 @@ process and thread creation only. #### Swap Inside the swap submenu the eBPF plugin creates the chart `swapcalls`; this chart is displaying when processes are -calling functions [`swap_readpage` and `swap_writepage`](https://hzliu123.github.io/linux-kernel/Page%20Cache%20in%20Linux%202.6.pdf ), +calling functions [`swap_readpage` and `swap_writepage`](https://hzliu123.github.io/linux-kernel/Page%20Cache%20in%20Linux%202.6.pdf), which are functions responsible for doing IO in swap memory. To collect the exact moment that an access to swap happens, the collector attaches `kprobes` for cited functions. @@ -108,91 +461,108 @@ the collector attaches `kprobes` for cited functions. The following `tracepoints` are used to measure time usage for soft IRQs: -- [`irq/softirq_entry`](https://www.kernel.org/doc/html/latest/core-api/tracepoint.html#c.trace_softirq_entry): Called - before softirq handler -- [`irq/softirq_exit`](https://www.kernel.org/doc/html/latest/core-api/tracepoint.html#c.trace_softirq_exit): Called when - softirq handler returns. +- [`irq/softirq_entry`](https://www.kernel.org/doc/html/latest/core-api/tracepoint.html#c.trace_softirq_entry): Called + before softirq handler +- [`irq/softirq_exit`](https://www.kernel.org/doc/html/latest/core-api/tracepoint.html#c.trace_softirq_exit): Called when + softirq handler returns. #### Hard IRQ The following tracepoints are used to measure the latency of servicing a hardware interrupt request (hard IRQ). -- [`irq/irq_handler_entry`](https://www.kernel.org/doc/html/latest/core-api/tracepoint.html#c.trace_irq_handler_entry): - Called immediately before the IRQ action handler. -- [`irq/irq_handler_exit`](https://www.kernel.org/doc/html/latest/core-api/tracepoint.html#c.trace_irq_handler_exit): - Called immediately after the IRQ action handler returns. -- `irq_vectors`: These are traces from `irq_handler_entry` and - `irq_handler_exit` when an IRQ is handled. The following elements from vector - are triggered: - - `irq_vectors/local_timer_entry` - - `irq_vectors/local_timer_exit` - - `irq_vectors/reschedule_entry` - - `irq_vectors/reschedule_exit` - - `irq_vectors/call_function_entry` - - `irq_vectors/call_function_exit` - - `irq_vectors/call_function_single_entry` - - `irq_vectors/call_function_single_xit` - - `irq_vectors/irq_work_entry` - - `irq_vectors/irq_work_exit` - - `irq_vectors/error_apic_entry` - - `irq_vectors/error_apic_exit` - - `irq_vectors/thermal_apic_entry` - - `irq_vectors/thermal_apic_exit` - - `irq_vectors/threshold_apic_entry` - - `irq_vectors/threshold_apic_exit` - - `irq_vectors/deferred_error_entry` - - `irq_vectors/deferred_error_exit` - - `irq_vectors/spurious_apic_entry` - - `irq_vectors/spurious_apic_exit` - - `irq_vectors/x86_platform_ipi_entry` - - `irq_vectors/x86_platform_ipi_exit` +- [`irq/irq_handler_entry`](https://www.kernel.org/doc/html/latest/core-api/tracepoint.html#c.trace_irq_handler_entry): + Called immediately before the IRQ action handler. +- [`irq/irq_handler_exit`](https://www.kernel.org/doc/html/latest/core-api/tracepoint.html#c.trace_irq_handler_exit): + Called immediately after the IRQ action handler returns. +- `irq_vectors`: These are traces from `irq_handler_entry` and + `irq_handler_exit` when an IRQ is handled. The following elements from vector + are triggered: + - `irq_vectors/local_timer_entry` + - `irq_vectors/local_timer_exit` + - `irq_vectors/reschedule_entry` + - `irq_vectors/reschedule_exit` + - `irq_vectors/call_function_entry` + - `irq_vectors/call_function_exit` + - `irq_vectors/call_function_single_entry` + - `irq_vectors/call_function_single_xit` + - `irq_vectors/irq_work_entry` + - `irq_vectors/irq_work_exit` + - `irq_vectors/error_apic_entry` + - `irq_vectors/error_apic_exit` + - `irq_vectors/thermal_apic_entry` + - `irq_vectors/thermal_apic_exit` + - `irq_vectors/threshold_apic_entry` + - `irq_vectors/threshold_apic_exit` + - `irq_vectors/deferred_error_entry` + - `irq_vectors/deferred_error_exit` + - `irq_vectors/spurious_apic_entry` + - `irq_vectors/spurious_apic_exit` + - `irq_vectors/x86_platform_ipi_entry` + - `irq_vectors/x86_platform_ipi_exit` #### IPC shared memory -To monitor shared memory system call counts, the following `kprobes` are used: +To monitor shared memory system call counts, Netdata attaches tracing in the following functions: -- `shmget`: Runs when [`shmget`](https://man7.org/linux/man-pages/man2/shmget.2.html) is called. -- `shmat`: Runs when [`shmat`](https://man7.org/linux/man-pages/man2/shmat.2.html) is called. -- `shmdt`: Runs when [`shmdt`](https://man7.org/linux/man-pages/man2/shmat.2.html) is called. -- `shmctl`: Runs when [`shmctl`](https://man7.org/linux/man-pages/man2/shmctl.2.html) is called. +- `shmget`: Runs when [`shmget`](https://man7.org/linux/man-pages/man2/shmget.2.html) is called. +- `shmat`: Runs when [`shmat`](https://man7.org/linux/man-pages/man2/shmat.2.html) is called. +- `shmdt`: Runs when [`shmdt`](https://man7.org/linux/man-pages/man2/shmat.2.html) is called. +- `shmctl`: Runs when [`shmctl`](https://man7.org/linux/man-pages/man2/shmctl.2.html) is called. ### Memory In the memory submenu the eBPF plugin creates two submenus **page cache** and **synchronization** with the following organization: -* Page Cache - * Page cache ratio - * Dirty pages - * Page cache hits - * Page cache misses -* Synchronization - * File sync - * Memory map sync - * File system sync - * File range sync +- Page Cache + - Page cache ratio + - Dirty pages + - Page cache hits + - Page cache misses +- Synchronization + - File sync + - Memory map sync + - File system sync + - File range sync -#### Page cache ratio +#### Page cache hits -The chart `cachestat_ratio` shows how processes are accessing page cache. In a normal scenario, we expect values around -100%, which means that the majority of the work on the machine is processed in memory. To calculate the ratio, Netdata -attaches `kprobes` for kernel functions: +When the processor needs to read or write a location in main memory, it checks for a corresponding entry in the page cache. + If the entry is there, a page cache hit has occurred and the read is from the cache. -- `add_to_page_cache_lru`: Page addition. -- `mark_page_accessed`: Access to cache. -- `account_page_dirtied`: Dirty (modified) pages. -- `mark_buffer_dirty`: Writes to page cache. +A page cache hit is when the page cache is successfully accessed with a read operation. We do not count pages that were +added relatively recently. #### Dirty pages +A "dirty page" is a page in the page cache that was modified after being created. Since non-dirty pages in the page cache + have identical copies in secondary storage (e.g. hard disk drive or solid-state drive), discarding and reusing their space + is much quicker than paging out application memory, and is often preferred over flushing the dirty pages into secondary storage + and reusing their space. + On `cachestat_dirties` Netdata demonstrates the number of pages that were modified. This chart shows the number of calls to the function `mark_buffer_dirty`. -#### Page cache hits +#### Page cache ratio -A page cache hit is when the page cache is successfully accessed with a read operation. We do not count pages that were -added relatively recently. +When the processor needs to read or write in a specific memory address, it checks for a corresponding entry in the page cache. +If the processor hits a page cache (`page cache hit`), it reads the entry from the cache. If there is no entry (`page cache miss`), + the kernel allocates a new entry and copies data from the disk. Netdata calculates the percentage of accessed files that are cached on + memory. The ratio is calculated counting the accessed cached pages + (without counting [dirty pages](#dirty-pages) and pages added because of read misses) divided by total access without dirty pages. + +> \_\_**\_\_\_\_**Number of accessed cached pages\***\*\_\_\*\***
+> Number of total accessed pages - dirty pages - missed pages + +The chart `cachestat_ratio` shows how processes are accessing page cache. In a normal scenario, we expect values around +100%, which means that the majority of the work on the machine is processed in memory. To calculate the ratio, Netdata +attaches `kprobes` for kernel functions: + +- `add_to_page_cache_lru`: Page addition. +- `mark_page_accessed`: Access to cache. +- `account_page_dirtied`: Dirty (modified) pages. +- `mark_buffer_dirty`: Writes to page cache. #### Page cache misses @@ -213,7 +583,7 @@ changes to a file that was mapped into memory using [`mmap(2)`](https://man7.org #### File system sync -This chart monitors calls demonstrating commits from filesystem caches to disk. Netdata attaches `kprobes` for +This chart monitors calls demonstrating commits from filesystem caches to disk. Netdata attaches `tracing` for [`sync(2)`](https://man7.org/linux/man-pages/man2/sync.2.html), and [`syncfs(2)`](https://man7.org/linux/man-pages/man2/sync.2.html). #### File range sync @@ -240,23 +610,35 @@ By default, MD flush is disabled. To enable it, configure your To collect data related to Linux multi-device (MD) flushing, the following kprobe is used: -- `kprobe/md_flush_request`: called whenever a request for flushing multi-device data is made. +- `kprobe/md_flush_request`: called whenever a request for flushing multi-device data is made. ### Disk -The eBPF plugin also shows a chart in the Disk section when the `disk` thread is enabled. This will create the -chart `disk_latency_io` for each disk on the host. The following tracepoints are used: +The eBPF plugin also shows a chart in the Disk section when the `disk` thread is enabled. + +#### Disk Latency + +This will create the chart `disk_latency_io` for each disk on the host. The following tracepoints are used: -- [`block/block_rq_issue`](https://www.kernel.org/doc/html/latest/core-api/tracepoint.html#c.trace_block_rq_issue): - IO request operation to a device drive. -- [`block/block_rq_complete`](https://www.kernel.org/doc/html/latest/core-api/tracepoint.html#c.trace_block_rq_complete): - IO operation completed by device. +- [`block/block_rq_issue`](https://www.kernel.org/doc/html/latest/core-api/tracepoint.html#c.trace_block_rq_issue): + IO request operation to a device drive. +- [`block/block_rq_complete`](https://www.kernel.org/doc/html/latest/core-api/tracepoint.html#c.trace_block_rq_complete): + IO operation completed by device. + +Disk Latency is the single most important metric to focus on when it comes to storage performance, under most circumstances. +For hard drives, an average latency somewhere between 10 to 20 ms can be considered acceptable. For SSD (Solid State Drives), +in most cases, workloads experience less than 1 ms latency numbers, but workloads should never reach higher than 3 ms. +The dimensions refer to time intervals. ### Filesystem -This group has charts demonstrating how applications interact with the Linux -kernel to open and close file descriptors. It also brings latency charts for -several different filesystems. +This group has charts demonstrating how applications interact with the Linux kernel to open and close file descriptors. +It also brings latency charts for several different filesystems. + +#### Latency Algorithm + +We calculate the difference between the calling and return times, spanning disk I/O, file system operations (lock, I/O), +run queue latency and all events related to the monitored action. #### ext4 @@ -265,10 +647,10 @@ To measure the latency of executing some actions in an collector needs to attach `kprobes` and `kretprobes` for each of the following functions: -- `ext4_file_read_iter`: Function used to measure read latency. -- `ext4_file_write_iter`: Function used to measure write latency. -- `ext4_file_open`: Function used to measure open latency. -- `ext4_sync_file`: Function used to measure sync latency. +- `ext4_file_read_iter`: Function used to measure read latency. +- `ext4_file_write_iter`: Function used to measure write latency. +- `ext4_file_open`: Function used to measure open latency. +- `ext4_sync_file`: Function used to measure sync latency. #### ZFS @@ -276,10 +658,10 @@ To measure the latency of executing some actions in a zfs filesystem, the collector needs to attach `kprobes` and `kretprobes` for each of the following functions: -- `zpl_iter_read`: Function used to measure read latency. -- `zpl_iter_write`: Function used to measure write latency. -- `zpl_open`: Function used to measure open latency. -- `zpl_fsync`: Function used to measure sync latency. +- `zpl_iter_read`: Function used to measure read latency. +- `zpl_iter_write`: Function used to measure write latency. +- `zpl_open`: Function used to measure open latency. +- `zpl_fsync`: Function used to measure sync latency. #### XFS @@ -288,10 +670,10 @@ To measure the latency of executing some actions in an collector needs to attach `kprobes` and `kretprobes` for each of the following functions: -- `xfs_file_read_iter`: Function used to measure read latency. -- `xfs_file_write_iter`: Function used to measure write latency. -- `xfs_file_open`: Function used to measure open latency. -- `xfs_file_fsync`: Function used to measure sync latency. +- `xfs_file_read_iter`: Function used to measure read latency. +- `xfs_file_write_iter`: Function used to measure write latency. +- `xfs_file_open`: Function used to measure open latency. +- `xfs_file_fsync`: Function used to measure sync latency. #### NFS @@ -300,11 +682,11 @@ To measure the latency of executing some actions in an collector needs to attach `kprobes` and `kretprobes` for each of the following functions: -- `nfs_file_read`: Function used to measure read latency. -- `nfs_file_write`: Function used to measure write latency. -- `nfs_file_open`: Functions used to measure open latency. -- `nfs4_file_open`: Functions used to measure open latency for NFS v4. -- `nfs_getattr`: Function used to measure sync latency. +- `nfs_file_read`: Function used to measure read latency. +- `nfs_file_write`: Function used to measure write latency. +- `nfs_file_open`: Functions used to measure open latency. +- `nfs4_file_open`: Functions used to measure open latency for NFS v4. +- `nfs_getattr`: Function used to measure sync latency. #### btrfs @@ -312,26 +694,26 @@ To measure the latency of executing some actions in a [btrfs](https://elixir.boo filesystem, the collector needs to attach `kprobes` and `kretprobes` for each of the following functions: > Note: We are listing two functions used to measure `read` latency, but we use either `btrfs_file_read_iter` or -`generic_file_read_iter`, depending on kernel version. +> `generic_file_read_iter`, depending on kernel version. -- `btrfs_file_read_iter`: Function used to measure read latency since kernel `5.10.0`. -- `generic_file_read_iter`: Like `btrfs_file_read_iter`, but this function was used before kernel `5.10.0`. -- `btrfs_file_write_iter`: Function used to write data. -- `btrfs_file_open`: Function used to open files. -- `btrfs_sync_file`: Function used to synchronize data to filesystem. +- `btrfs_file_read_iter`: Function used to measure read latency since kernel `5.10.0`. +- `generic_file_read_iter`: Like `btrfs_file_read_iter`, but this function was used before kernel `5.10.0`. +- `btrfs_file_write_iter`: Function used to write data. +- `btrfs_file_open`: Function used to open files. +- `btrfs_sync_file`: Function used to synchronize data to filesystem. #### File descriptor To give metrics related to `open` and `close` events, instead of attaching kprobes for each syscall used to do these events, the collector attaches `kprobes` for the common function used for syscalls: -- [`do_sys_open`](https://0xax.gitbooks.io/linux-insides/content/SysCall/linux-syscall-5.html ): Internal function used to - open files. -- [`do_sys_openat2`](https://elixir.bootlin.com/linux/v5.6/source/fs/open.c#L1162): - Function called from `do_sys_open` since version `5.6.0`. -- [`close_fd`](https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg2271761.html): Function used to close file - descriptor since kernel `5.11.0`. -- `__close_fd`: Function used to close files before version `5.11.0`. +- [`do_sys_open`](https://0xax.gitbooks.io/linux-insides/content/SysCall/linux-syscall-5.html): Internal function used to + open files. +- [`do_sys_openat2`](https://elixir.bootlin.com/linux/v5.6/source/fs/open.c#L1162): + Function called from `do_sys_open` since version `5.6.0`. +- [`close_fd`](https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg2271761.html): Function used to close file + descriptor since kernel `5.11.0`. +- `__close_fd`: Function used to close files before version `5.11.0`. #### File error @@ -351,22 +733,22 @@ To measure the latency and total quantity of executing some VFS-level functions, ebpf.plugin needs to attach kprobes and kretprobes for each of the following functions: -- `vfs_write`: Function used monitoring the number of successful & failed - filesystem write calls, as well as the total number of written bytes. -- `vfs_writev`: Same function as `vfs_write` but for vector writes (i.e. a - single write operation using a group of buffers rather than 1). -- `vfs_read`: Function used for monitoring the number of successful & failed - filesystem read calls, as well as the total number of read bytes. -- `vfs_readv` Same function as `vfs_read` but for vector reads (i.e. a single - read operation using a group of buffers rather than 1). -- `vfs_unlink`: Function used for monitoring the number of successful & failed - filesystem unlink calls. -- `vfs_fsync`: Function used for monitoring the number of successful & failed - filesystem fsync calls. -- `vfs_open`: Function used for monitoring the number of successful & failed - filesystem open calls. -- `vfs_create`: Function used for monitoring the number of successful & failed - filesystem create calls. +- `vfs_write`: Function used monitoring the number of successful & failed + filesystem write calls, as well as the total number of written bytes. +- `vfs_writev`: Same function as `vfs_write` but for vector writes (i.e. a + single write operation using a group of buffers rather than 1). +- `vfs_read`: Function used for monitoring the number of successful & failed + filesystem read calls, as well as the total number of read bytes. +- `vfs_readv` Same function as `vfs_read` but for vector reads (i.e. a single + read operation using a group of buffers rather than 1). +- `vfs_unlink`: Function used for monitoring the number of successful & failed + filesystem unlink calls. +- `vfs_fsync`: Function used for monitoring the number of successful & failed + filesystem fsync calls. +- `vfs_open`: Function used for monitoring the number of successful & failed + filesystem open calls. +- `vfs_create`: Function used for monitoring the number of successful & failed + filesystem create calls. ##### VFS Deleted objects @@ -406,30 +788,49 @@ Metrics for directory cache are collected using kprobe for `lookup_fast`, becaus times this function is accessed. On the other hand, for `d_lookup` we are not only interested in the number of times it is accessed, but also in possible errors, so we need to attach a `kretprobe`. For this reason, the following is used: -- [`lookup_fast`](https://lwn.net/Articles/649115/): Called to look at data inside the directory cache. -- [`d_lookup`](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/dcache.c?id=052b398a43a7de8c68c13e7fa05d6b3d16ce6801#n2223): - Called when the desired file is not inside the directory cache. +- [`lookup_fast`](https://lwn.net/Articles/649115/): Called to look at data inside the directory cache. +- [`d_lookup`](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/dcache.c?id=052b398a43a7de8c68c13e7fa05d6b3d16ce6801#n2223): + Called when the desired file is not inside the directory cache. + +##### Directory Cache Interpretation + +When directory cache is showing 100% that means that every accessed file was present in the directory cache. +If files are not present in the directory cache, they are either not present in the file system or the files were not +accessed before. ### Mount Points -The following `kprobes` are used to collect `mount` & `unmount` call counts: +The following `tracing` are used to collect `mount` & `unmount` call counts: -- [`mount`](https://man7.org/linux/man-pages/man2/mount.2.html): mount filesystem on host. -- [`umount`](https://man7.org/linux/man-pages/man2/umount.2.html): umount filesystem on host. +- [`mount`](https://man7.org/linux/man-pages/man2/mount.2.html): mount filesystem on host. +- [`umount`](https://man7.org/linux/man-pages/man2/umount.2.html): umount filesystem on host. ### Networking Stack -Netdata monitors socket bandwidth attaching `kprobes` for internal functions. +Netdata monitors socket bandwidth attaching `tracing` for internal functions. + +#### TCP outbound connections + +This chart demonstrates calls to `tcp_v4_connection` and `tcp_v6_connection` that start connections for IPV4 and IPV6, respectively. -#### TCP functions +#### TCP inbound connections + +This chart demonstrates TCP and UDP connections that the host receives. +To collect this information, netdata attaches a tracing to `inet_csk_accept`. + +#### TCP bandwidth functions This chart demonstrates calls to functions `tcp_sendmsg`, `tcp_cleanup_rbuf`, and `tcp_close`; these functions are used to send & receive data and to close connections when `TCP` protocol is used. #### TCP bandwidth -Like the previous chart, this one also monitors `tcp_sendmsg` and `tcp_cleanup_rbuf`, but instead of showing the number -of calls, it demonstrates the number of bytes sent and received. +This chart demonstrates calls to functions: + +- `tcp_sendmsg`: Function responsible to send data for a specified destination. +- `tcp_cleanup_rbuf`: We use this function instead of `tcp_recvmsg`, because the last one misses `tcp_read_sock` traffic + and we would also need to add more `tracing` to get the socket and package size. +- `tcp_close`: Function responsible to close connection. #### TCP retransmit @@ -452,359 +853,11 @@ calls, it monitors the number of bytes sent and received. These are tracepoints related to [OOM](https://en.wikipedia.org/wiki/Out_of_memory) killing processes. -- `oom/mark_victim`: Monitors when an oomkill event happens. - -## Configuration - -Enable or disable the entire eBPF collector by editing `netdata.conf`. - -```bash -cd /etc/netdata/ # Replace with your Netdata configuration directory, if not /etc/netdata/ -./edit-config netdata.conf -``` - -To enable the collector, scroll down to the `[plugins]` section ensure the relevant line references `ebpf` (not -`ebpf_process`), is uncommented, and is set to `yes`. - -```conf -[plugins] - ebpf = yes -``` - -You can also configure the eBPF collector's behavior by editing `ebpf.d.conf`. - -```bash -cd /etc/netdata/ # Replace with your Netdata configuration directory, if not /etc/netdata/ -./edit-config ebpf.d.conf -``` - -### `[global]` - -The `[global]` section defines settings for the whole eBPF collector. - -#### eBPF load mode - -The collector has two different eBPF programs. These programs monitor the same functions inside the kernel, but they -monitor, process, and display different kinds of information. - -By default, this plugin uses the `entry` mode. Changing this mode can create significant overhead on your operating -system, but also offer valuable information if you are developing or debugging software. The `ebpf load mode` option -accepts the following values: ​ - -- `entry`: This is the default mode. In this mode, the eBPF collector only monitors calls for the functions described in - the sections above, and does not show charts related to errors. -- `return`: In the `return` mode, the eBPF collector monitors the same kernel functions as `entry`, but also creates new - charts for the return of these functions, such as errors. Monitoring function returns can help in debugging software, - such as failing to close file descriptors or creating zombie processes. -- `update every`: Number of seconds used for eBPF to send data for Netdata. -- `pid table size`: Defines the maximum number of PIDs stored inside the application hash table. - -#### Integration with `apps.plugin` - -The eBPF collector also creates charts for each running application through an integration with the -[`apps.plugin`](/collectors/apps.plugin/README.md). This integration helps you understand how specific applications -interact with the Linux kernel. - -If you want to _disable_ the integration with `apps.plugin` along with the above charts, change the setting `apps` to -`no`. - -```conf -[global] - apps = yes -``` - -When the integration is enabled, eBPF collector allocates memory for each process running. The total allocated memory -has direct relationship with the kernel version. When the eBPF plugin is running on kernels newer than `4.15`, it uses -per-cpu maps to speed up the update of hash tables. This also implies storing data for the same PID for each processor -it runs. - -#### Integration with `cgroups.plugin` - -The eBPF collector also creates charts for each cgroup through an integration with the -[`cgroups.plugin`](/collectors/cgroups.plugin/README.md). This integration helps you understand how a specific cgroup -interacts with the Linux kernel. - -The integration with `cgroups.plugin` is disabled by default to avoid creating overhead on your system. If you want to -_enable_ the integration with `cgroups.plugin`, change the `cgroups` setting to `yes`. - -```conf -[global] - cgroups = yes -``` - -If you do not need to monitor specific metrics for your `cgroups`, you can enable `cgroups` inside -`ebpf.d.conf`, and then disable the plugin for a specific `thread` by following the steps in the -[Configuration](#configuration) section. - -#### Integration Dashboard Elements - -When an integration is enabled, your dashboard will also show the following cgroups and apps charts using low-level -Linux metrics: - -> Note: The parenthetical accompanying each bulleted item provides the chart name. - -- mem - - Number of processes killed due out of memory. (`oomkills`) -- process - - Number of processes created with `do_fork`. (`process_create`) - - Number of threads created with `do_fork` or `clone (2)`, depending on your system's kernel - version. (`thread_create`) - - Number of times that a process called `do_exit`. (`task_exit`) - - Number of times that a process called `release_task`. (`task_close`) - - Number of times that an error happened to create thread or process. (`task_error`) -- swap - - Number of calls to `swap_readpage`. (`swap_read_call`) - - Number of calls to `swap_writepage`. (`swap_write_call`) -- network - - Number of bytes sent. (`total_bandwidth_sent`) - - Number of bytes received. (`total_bandwidth_recv`) - - Number of calls to `tcp_sendmsg`. (`bandwidth_tcp_send`) - - Number of calls to `tcp_cleanup_rbuf`. (`bandwidth_tcp_recv`) - - Number of calls to `tcp_retransmit_skb`. (`bandwidth_tcp_retransmit`) - - Number of calls to `udp_sendmsg`. (`bandwidth_udp_send`) - - Number of calls to `udp_recvmsg`. (`bandwidth_udp_recv`) -- file access - - Number of calls to open files. (`file_open`) - - Number of calls to open files that returned errors. (`open_error`) - - Number of files closed. (`file_closed`) - - Number of calls to close files that returned errors. (`file_error_closed`) -- vfs - - Number of calls to `vfs_unlink`. (`file_deleted`) - - Number of calls to `vfs_write`. (`vfs_write_call`) - - Number of calls to write a file that returned errors. (`vfs_write_error`) - - Number of calls to `vfs_read`. (`vfs_read_call`) - - Number of bytes written with `vfs_write`. (`vfs_write_bytes`) - - Number of bytes read with `vfs_read`. (`vfs_read_bytes`) - - Number of calls to read a file that returned errors. (`vfs_read_error`) - - Number of calls to `vfs_fsync`. (`vfs_fsync`) - - Number of calls to sync file that returned errors. (`vfs_fsync_error`) - - Number of calls to `vfs_open`. (`vfs_open`) - - Number of calls to open file that returned errors. (`vfs_open_error`) - - Number of calls to `vfs_create`. (`vfs_create`) - - Number of calls to open file that returned errors. (`vfs_create_error`) -- page cache - - Ratio of pages accessed. (`cachestat_ratio`) - - Number of modified pages ("dirty"). (`cachestat_dirties`) - - Number of accessed pages. (`cachestat_hits`) - - Number of pages brought from disk. (`cachestat_misses`) -- directory cache - - Ratio of files available in directory cache. (`dc_hit_ratio`) - - Number of files accessed. (`dc_reference`) - - Number of files accessed that were not in cache. (`dc_not_cache`) - - Number of files not found. (`dc_not_found`) -- ipc shm - - Number of calls to `shm_get`. (`shmget_call`) - - Number of calls to `shm_at`. (`shmat_call`) - - Number of calls to `shm_dt`. (`shmdt_call`) - - Number of calls to `shm_ctl`. (`shmctl_call`) - -### `[ebpf programs]` - -The eBPF collector enables and runs the following eBPF programs by default: - -- `fd` : This eBPF program creates charts that show information about calls to open files. -- `mount`: This eBPF program creates charts that show calls to syscalls mount(2) and umount(2). -- `shm`: This eBPF program creates charts that show calls to syscalls shmget(2), shmat(2), shmdt(2) and shmctl(2). -- `sync`: Monitor calls to syscalls sync(2), fsync(2), fdatasync(2), syncfs(2), msync(2), and sync_file_range(2). -- `network viewer`: This eBPF program creates charts with information about `TCP` and `UDP` functions, including the - bandwidth consumed by each. -- `vfs`: This eBPF program creates charts that show information about VFS (Virtual File System) functions. -- `process`: This eBPF program creates charts that show information about process life. When in `return` mode, it also - creates charts showing errors when these operations are executed. -- `hardirq`: This eBPF program creates charts that show information about time spent servicing individual hardware - interrupt requests (hard IRQs). -- `softirq`: This eBPF program creates charts that show information about time spent servicing individual software - interrupt requests (soft IRQs). -- `oomkill`: This eBPF program creates a chart that shows OOM kills for all applications recognized via - the `apps.plugin` integration. Note that this program will show application charts regardless of whether apps - integration is turned on or off. - -You can also enable the following eBPF programs: - -- `cachestat`: Netdata's eBPF data collector creates charts about the memory page cache. When the integration with - [`apps.plugin`](/collectors/apps.plugin/README.md) is enabled, this collector creates charts for the whole host _and_ - for each application. -- `dcstat` : This eBPF program creates charts that show information about file access using directory cache. It appends - `kprobes` for `lookup_fast()` and `d_lookup()` to identify if files are inside directory cache, outside and files are - not found. -- `disk` : This eBPF program creates charts that show information about disk latency independent of filesystem. -- `filesystem` : This eBPF program creates charts that show information about some filesystem latency. -- `swap` : This eBPF program creates charts that show information about swap access. -- `mdflush`: This eBPF program creates charts that show information about - multi-device software flushes. - -## Thread configuration - -You can configure each thread of the eBPF data collector by editing either the `cachestat.conf`, `process.conf`, -or `network.conf` files. Use [`edit-config`](/docs/configure/nodes.md) from your Netdata config directory: - -```bash -cd /etc/netdata/ # Replace with your Netdata configuration directory, if not /etc/netdata/ -./edit-config ebpf.d/process.conf -``` - -### Configuration files - -The following configuration files are available: - -- `cachestat.conf`: Configuration for the `cachestat` thread. -- `dcstat.conf`: Configuration for the `dcstat` thread. -- `disk.conf`: Configuration for the `disk` thread. -- `fd.conf`: Configuration for the `file descriptor` thread. -- `filesystem.conf`: Configuration for the `filesystem` thread. -- `hardirq.conf`: Configuration for the `hardirq` thread. -- `process.conf`: Configuration for the `process` thread. -- `network.conf`: Configuration for the `network viewer` thread. This config file overwrites the global options and also - lets you specify which network the eBPF collector monitors. -- `softirq.conf`: Configuration for the `softirq` thread. -- `sync.conf`: Configuration for the `sync` thread. -- `vfs.conf`: Configuration for the `vfs` thread. - -### Network configuration - -The network configuration has specific options to configure which network(s) the eBPF collector monitors. These options -are divided in the following sections: - -#### `[network connections]` - -You can configure the information shown on `outbound` and `inbound` charts with the settings in this section. - -```conf -[network connections] - maximum dimensions = 500 - resolve hostname ips = no - ports = 1-1024 !145 !domain - hostnames = !example.com - ips = !127.0.0.1/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 fc00::/7 -``` - -When you define a `ports` setting, Netdata will collect network metrics for that specific port. For example, if you -write `ports = 19999`, Netdata will collect only connections for itself. The `hostnames` setting accepts -[simple patterns](/libnetdata/simple_pattern/README.md). The `ports`, and `ips` settings accept negation (`!`) to deny -specific values or asterisk alone to define all values. - -In the above example, Netdata will collect metrics for all ports between 1 and 443, with the exception of 53 (domain) -and 145. - -The following options are available: - -- `ports`: Define the destination ports for Netdata to monitor. -- `hostnames`: The list of hostnames that can be resolved to an IP address. -- `ips`: The IP or range of IPs that you want to monitor. You can use IPv4 or IPv6 addresses, use dashes to define a - range of IPs, or use CIDR values. The default behavior is to only collect data for private IP addresses, but this can - be changed with the `ips` setting. - -By default, Netdata displays up to 500 dimensions on network connection charts. If there are more possible dimensions, -they will be bundled into the `other` dimension. You can increase the number of shown dimensions by changing -the `maximum dimensions` setting. - -The dimensions for the traffic charts are created using the destination IPs of the sockets by default. This can be -changed setting `resolve hostname ips = yes` and restarting Netdata, after this Netdata will create dimensions using -the `hostnames` every time that is possible to resolve IPs to their hostnames. - -#### `[service name]` - -Netdata uses the list of services in `/etc/services` to plot network connection charts. If this file does not contain -the name for a particular service you use in your infrastructure, you will need to add it to the `[service name]` -section. - -For example, Netdata's default port (`19999`) is not listed in `/etc/services`. To associate that port with the Netdata -service in network connection charts, and thus see the name of the service instead of its port, define it: - -```conf -[service name] - 19999 = Netdata -``` - -### Sync configuration - -The sync configuration has specific options to disable monitoring for syscalls, as default option all syscalls are -monitored. - -```conf -[syscalls] - sync = yes - msync = yes - fsync = yes - fdatasync = yes - syncfs = yes - sync_file_range = yes -``` - -### Filesystem configuration - -The filesystem configuration has specific options to disable monitoring for filesystems, by default all filesystems are -monitored. - -```conf -[filesystem] - btrfsdist = yes - ext4dist = yes - nfsdist = yes - xfsdist = yes - zfsdist = yes -``` - -The ebpf program `nfsdist` monitors only `nfs` mount points. - -## Troubleshooting - -If the eBPF collector does not work, you can troubleshoot it by running the `ebpf.plugin` command and investigating its -output. - -```bash -cd /usr/libexec/netdata/plugins.d/ -sudo su -s /bin/bash netdata -./ebpf.plugin -``` - -You can also use `grep` to search the Agent's `error.log` for messages related to eBPF monitoring. - -```bash -grep -i ebpf /var/log/netdata/error.log -``` +- `oom/mark_victim`: Monitors when an oomkill event happens. -### Confirm kernel compatibility +## Known issues -The eBPF collector only works on Linux systems and with specific Linux kernels. We support all kernels more recent than -`4.11.0`, and all kernels on CentOS 7.6 or later. - -You can run our helper script to determine whether your system can support eBPF monitoring. - -```bash -curl -sSL https://raw.githubusercontent.com/netdata/kernel-collector/master/tools/check-kernel-config.sh | sudo bash -``` - -If this script returns no output, your system is ready to compile and run the eBPF collector. - -If you see a warning about a missing kernel -configuration (`KPROBES KPROBES_ON_FTRACE HAVE_KPROBES BPF BPF_SYSCALL BPF_JIT`), you will need to recompile your kernel -to support this configuration. The process of recompiling Linux kernels varies based on your distribution and version. -Read the documentation for your system's distribution to learn more about the specific workflow for recompiling the -kernel, ensuring that you set all the necessary - -- [Ubuntu](https://wiki.ubuntu.com/Kernel/BuildYourOwnKernel) -- [Debian](https://kernel-team.pages.debian.net/kernel-handbook/ch-common-tasks.html#s-common-official) -- [Fedora](https://fedoraproject.org/wiki/Building_a_custom_kernel) -- [CentOS](https://wiki.centos.org/HowTos/Custom_Kernel) -- [Arch Linux](https://wiki.archlinux.org/index.php/Kernel/Traditional_compilation) -- [Slackware](https://docs.slackware.com/howtos:slackware_admin:kernelbuilding) - -### Mount `debugfs` and `tracefs` - -The eBPF collector also requires both the `tracefs` and `debugfs` filesystems. Try mounting the `tracefs` and `debugfs` -filesystems using the commands below: - -```bash -sudo mount -t debugfs nodev /sys/kernel/debug -sudo mount -t tracefs nodev /sys/kernel/tracing -``` - -If they are already mounted, you will see an error. You can also configure your system's `/etc/fstab` configuration to -mount these filesystems on startup. More information can be found in -the [ftrace documentation](https://www.kernel.org/doc/Documentation/trace/ftrace.txt). - -## Performance +### Performance opimization eBPF monitoring is complex and produces a large volume of metrics. We've discovered scenarios where the eBPF plugin significantly increases kernel memory usage by several hundred MB. @@ -817,7 +870,7 @@ usage (see the `system.ram` chart) has dropped significantly. Beginning with `v1.31`, kernel memory usage is configurable via the [`pid table size` setting](#ebpf-load-mode) in `ebpf.conf`. -## SELinux +### SELinux When [SELinux](https://www.redhat.com/en/topics/linux/what-is-selinux) is enabled, it may prevent `ebpf.plugin` from starting correctly. Check the Agent's `error.log` file for errors like the ones below: @@ -837,7 +890,7 @@ ess.pl" exe="/usr/libexec/netdata/plugins.d/ebpf.plugin" subj=system_u:system_r: If you see similar errors, you will have to adjust SELinux's policies to enable the eBPF collector. -### Creation of bpf policies +#### Creation of bpf policies To enable `ebpf.plugin` to run on a distribution with SELinux enabled, it will be necessary to take the following actions. @@ -883,14 +936,14 @@ Finally, you can load the new policy and start the Netdata agent again: # systemctl start netdata ``` -## Lockdown +### Linux kernel lockdown Beginning with [version 5.4](https://www.zdnet.com/article/linux-to-get-kernel-lockdown-feature/), the Linux kernel has a feature called "lockdown," which may affect `ebpf.plugin` depending how the kernel was compiled. The following table shows how the lockdown module impacts `ebpf.plugin` based on the selected options: | Enforcing kernel lockdown | Enable lockdown LSM early in init | Default lockdown mode | Can `ebpf.plugin` run with this? | -|:------------------------- |:--------------------------------- |:--------------------- |:-------------------------------- | +| :------------------------ | :-------------------------------- | :-------------------- | :------------------------------- | | YES | NO | NO | YES | | YES | Yes | None | YES | | YES | Yes | Integrity | YES | @@ -898,5 +951,3 @@ shows how the lockdown module impacts `ebpf.plugin` based on the selected option If you or your distribution compiled the kernel with the last combination, your system cannot load shared libraries required to run `ebpf.plugin`. - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Febpf.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) diff --git a/collectors/ebpf.plugin/ebpf.c b/collectors/ebpf.plugin/ebpf.c index d51d378bd..b93c2dfd7 100644 --- a/collectors/ebpf.plugin/ebpf.c +++ b/collectors/ebpf.plugin/ebpf.c @@ -51,14 +51,15 @@ ebpf_module_t ebpf_modules[] = { .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &socket_config, .config_file = NETDATA_NETWORK_CONFIG_FILE, .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4, - .load = EBPF_LOAD_LEGACY, .targets = NULL}, + .load = EBPF_LOAD_LEGACY, .targets = socket_targets}, { .thread_name = "cachestat", .config_name = "cachestat", .enabled = 0, .start_routine = ebpf_cachestat_thread, .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = ebpf_cachestat_create_apps_charts, .maps = NULL, .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &cachestat_config, .config_file = NETDATA_CACHESTAT_CONFIG_FILE, - .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_15, + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18| + NETDATA_V5_4 | NETDATA_V5_15 | NETDATA_V5_16, .load = EBPF_LOAD_LEGACY, .targets = NULL}, { .thread_name = "sync", .config_name = "sync", .enabled = 0, .start_routine = ebpf_sync_thread, .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO, @@ -67,7 +68,7 @@ ebpf_module_t ebpf_modules[] = { .config_file = NETDATA_SYNC_CONFIG_FILE, // All syscalls have the same kernels .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4, - .load = EBPF_LOAD_LEGACY, .targets = NULL}, + .load = EBPF_LOAD_LEGACY, .targets = sync_targets}, { .thread_name = "dc", .config_name = "dc", .enabled = 0, .start_routine = ebpf_dcstat_thread, .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, @@ -112,7 +113,7 @@ ebpf_module_t ebpf_modules[] = { .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &mount_config, .config_file = NETDATA_MOUNT_CONFIG_FILE, .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4, - .load = EBPF_LOAD_LEGACY, .targets = NULL}, + .load = EBPF_LOAD_LEGACY, .targets = mount_targets}, { .thread_name = "fd", .config_name = "fd", .enabled = 0, .start_routine = ebpf_fd_thread, .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, @@ -150,7 +151,7 @@ ebpf_module_t ebpf_modules[] = { .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &shm_config, .config_file = NETDATA_DIRECTORY_SHM_CONFIG_FILE, .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4, - .load = EBPF_LOAD_LEGACY, .targets = NULL}, + .load = EBPF_LOAD_LEGACY, .targets = shm_targets}, { .thread_name = "mdflush", .config_name = "mdflush", .enabled = 0, .start_routine = ebpf_mdflush_thread, .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = NULL, .maps = NULL, @@ -180,6 +181,11 @@ ebpf_network_viewer_options_t network_viewer_opt; ebpf_plugin_stats_t plugin_statistics = {.core = 0, .legacy = 0, .running = 0, .threads = 0, .tracepoints = 0, .probes = 0, .retprobes = 0, .trampolines = 0}; +#ifdef LIBBPF_MAJOR_VERSION +struct btf *default_btf = NULL; +#endif +char *btf_path = NULL; + /***************************************************************** * * FUNCTIONS USED TO CLEAN MEMORY AND OPERATE SYSTEM FILES @@ -206,6 +212,7 @@ void clean_loaded_events() static void ebpf_exit(int sig) { close_ebpf_plugin = 1; + static int remove_pid = 0; // When both threads were not finished case I try to go in front this address, the collector will crash if (!thread_finished) { @@ -289,6 +296,21 @@ static void ebpf_exit(int sig) } */ +#ifdef LIBBPF_MAJOR_VERSION + if (default_btf) { + btf__free(default_btf); + default_btf = NULL; + } +#endif + + if (!remove_pid) { + remove_pid = 1; + char filename[FILENAME_MAX + 1]; + ebpf_pid_file(filename, FILENAME_MAX); + if (unlink(filename)) + error("Cannot remove PID file %s", filename); + } + exit(sig); } @@ -957,6 +979,7 @@ static void read_local_ports(char *filename, uint8_t proto) return; size_t lines = procfile_lines(ff), l; + netdata_passive_connection_t values = {.counter = 0, .tgid = 0, .pid = 0}; for(l = 0; l < lines ;l++) { size_t words = procfile_linewords(ff, l); // This is header or end of file @@ -970,7 +993,7 @@ static void read_local_ports(char *filename, uint8_t proto) // Read local port uint16_t port = (uint16_t)strtol(procfile_lineword(ff, l, 2), NULL, 16); - update_listen_table(htons(port), proto); + update_listen_table(htons(port), proto, &values); } procfile_close(ff); @@ -1115,6 +1138,56 @@ static void ebpf_update_table_size() } } +/** + * Set Load mode + * + * @param load default load mode. + */ +static inline void ebpf_set_load_mode(netdata_ebpf_load_mode_t load) +{ +#ifdef LIBBPF_MAJOR_VERSION + if (load == EBPF_LOAD_CORE || load == EBPF_LOAD_PLAY_DICE) { + load = (!default_btf) ? EBPF_LOAD_LEGACY : EBPF_LOAD_CORE; + } +#else + load = EBPF_LOAD_LEGACY; +#endif + + int i; + for (i = 0; ebpf_modules[i].thread_name; i++) { + // TO DO: Use `load` variable after we change all threads. + ebpf_modules[i].load = EBPF_LOAD_LEGACY; // load ; + } +} + +/** + * Update mode + * + * @param str value read from configuration file. + */ +static inline void epbf_update_load_mode(char *str) +{ + netdata_ebpf_load_mode_t load = epbf_convert_string_to_load_mode(str); + + ebpf_set_load_mode(load); +} + +#ifdef LIBBPF_MAJOR_VERSION +/** + * Set default btf file + * + * Load the default BTF file on environment. + */ +static void ebpf_set_default_btf_file() +{ + char path[PATH_MAX + 1]; + snprintfz(path, PATH_MAX, "%s/vmlinux", btf_path); + default_btf = ebpf_parse_btf_file(path); + if (!default_btf) + info("Your environment does not have BTF file %s/vmlinux. The plugin will work with 'legacy' code.", + btf_path); +} +#endif /** * Read collector values @@ -1136,6 +1209,17 @@ static void read_collector_values(int *disable_apps, int *disable_cgroups, int u how_to_load(value); + btf_path = appconfig_get(&collector_config, EBPF_GLOBAL_SECTION, EBPF_CFG_PROGRAM_PATH, + EBPF_DEFAULT_BTF_FILE); + +#ifdef LIBBPF_MAJOR_VERSION + ebpf_set_default_btf_file(); +#endif + + value = appconfig_get(&collector_config, EBPF_GLOBAL_SECTION, EBPF_CFG_TYPE_FORMAT, EBPF_CFG_DEFAULT_PROGRAM); + + epbf_update_load_mode(value); + ebpf_update_interval(update_every); ebpf_update_table_size(); @@ -1371,19 +1455,6 @@ static inline void ebpf_load_thread_config() } } -/** - * Set Load mode - * - * @param load default load mode. - */ -static inline void ebpf_set_load_mode(netdata_ebpf_load_mode_t load) -{ - int i; - for (i = 0; ebpf_modules[i].thread_name; i++) { - ebpf_modules[i].load = load; - } -} - /** * Parse arguments given from user. * @@ -1771,6 +1842,19 @@ static void ebpf_kill_previous_process(char *filename, pid_t pid) sleep_usec(USEC_PER_MS * 300); } +/** + * PID file + * + * Write the filename for PID inside the given vector. + * + * @param filename vector where we will store the name. + * @param length number of bytes available in filename vector + */ +void ebpf_pid_file(char *filename, size_t length) +{ + snprintfz(filename, length, "%s%s/ebpf.d/ebpf.pid", netdata_configured_host_prefix, ebpf_plugin_dir); +} + /** * Manage PID * @@ -1781,7 +1865,7 @@ static void ebpf_kill_previous_process(char *filename, pid_t pid) static void ebpf_manage_pid(pid_t pid) { char filename[FILENAME_MAX + 1]; - snprintfz(filename, FILENAME_MAX, "%s%s/ebpf.d/ebpf.pid", netdata_configured_host_prefix, ebpf_plugin_dir); + ebpf_pid_file(filename, FILENAME_MAX); ebpf_kill_previous_process(filename, pid); ebpf_update_pid_file(filename, pid); @@ -1841,6 +1925,10 @@ int main(int argc, char **argv) ebpf_allocate_common_vectors(); +#ifdef LIBBPF_MAJOR_VERSION + libbpf_set_strict_mode(LIBBPF_STRICT_ALL); +#endif + read_local_addresses(); read_local_ports("/proc/net/tcp", IPPROTO_TCP); read_local_ports("/proc/net/tcp6", IPPROTO_TCP); diff --git a/collectors/ebpf.plugin/ebpf.d/mount.conf b/collectors/ebpf.plugin/ebpf.d/mount.conf index 9d3174755..fdd82f220 100644 --- a/collectors/ebpf.plugin/ebpf.d/mount.conf +++ b/collectors/ebpf.plugin/ebpf.d/mount.conf @@ -3,6 +3,17 @@ # `return : In the `return` mode, the eBPF collector monitors the same kernel functions as `entry`, but also creates # new charts for the return of these functions, such as errors. # -#[global] +# The `ebpf type format` option accepts the following values : +# `auto` : The eBPF collector will investigate hardware and select between the two next options. +# `legacy`: The eBPF collector will load the legacy code. Note: This has a bigger overload. +# `co-re` : The eBPF collector will use latest tracing method. Note: This is not available on all platforms. +# +# The `ebpf co-re tracing` option accepts the following values: +# `trampoline`: This is the default mode used by the eBPF collector, due the small overhead added to host. +# `tracepoint`: When available, the eBPF collector will use kernel tracepoint to monitor syscall. +# `probe` : This is the same as legacy code. +[global] # ebpf load mode = entry # update every = 1 + ebpf type format = auto + ebpf co-re tracing = trampoline diff --git a/collectors/ebpf.plugin/ebpf.d/network.conf b/collectors/ebpf.plugin/ebpf.d/network.conf index e692622a9..d939d8e1f 100644 --- a/collectors/ebpf.plugin/ebpf.d/network.conf +++ b/collectors/ebpf.plugin/ebpf.d/network.conf @@ -14,6 +14,16 @@ # `ipv6 connection table size`: Maximum number of IPV6 connections monitored # `udp connection table size`: Maximum number of UDP connections monitored # +# The `ebpf type format` option accepts the following values : +# `auto` : The eBPF collector will investigate hardware and select between the two next options. +# `legacy`: The eBPF collector will load the legacy code. Note: This has a bigger overload. +# `co-re` : The eBPF collector will use latest tracing method. Note: This is not available on all platforms. +# +# The `ebpf co-re tracing` option accepts the following values: +# `trampoline`: This is the default mode used by the eBPF collector, due the small overhead added to host. +# `tracepoint`: When available, the eBPF collector will use kernel tracepoint to monitor syscall. +# `probe` : This is the same as legacy code. +# [global] # ebpf load mode = entry # apps = yes @@ -23,6 +33,8 @@ ipv4 connection table size = 16384 ipv6 connection table size = 16384 udp connection table size = 4096 + ebpf type format = auto + ebpf co-re tracing = trampoline # # Network Connection diff --git a/collectors/ebpf.plugin/ebpf.d/shm.conf b/collectors/ebpf.plugin/ebpf.d/shm.conf index c0a10c98e..23ab96da4 100644 --- a/collectors/ebpf.plugin/ebpf.d/shm.conf +++ b/collectors/ebpf.plugin/ebpf.d/shm.conf @@ -8,13 +8,25 @@ # If you want to disable the integration with `apps.plugin` or `cgroups.plugin` along with the above charts, change # the setting `apps` and `cgroups` to 'no'. # +# The `ebpf type format` option accepts the following values : +# `auto` : The eBPF collector will investigate hardware and select between the two next options. +# `legacy`: The eBPF collector will load the legacy code. Note: This has a bigger overload. +# `co-re` : The eBPF collector will use latest tracing method. Note: This is not available on all platforms. +# +# The `ebpf co-re tracing` option accepts the following values: +# `trampoline`: This is the default mode used by the eBPF collector, due the small overhead added to host. +# `tracepoint`: When available, the eBPF collector will use kernel tracepoint to monitor syscall. +# `probe` : This is the same as legacy code. +# # Uncomment lines to define specific options for thread. -#[global] +[global] # ebpf load mode = entry # apps = yes # cgroups = no # update every = 10 # pid table size = 32768 + ebpf type format = auto + ebpf co-re tracing = trampoline # List of monitored syscalls [syscalls] diff --git a/collectors/ebpf.plugin/ebpf.d/sync.conf b/collectors/ebpf.plugin/ebpf.d/sync.conf index 03c469f68..ebec5d38e 100644 --- a/collectors/ebpf.plugin/ebpf.d/sync.conf +++ b/collectors/ebpf.plugin/ebpf.d/sync.conf @@ -8,12 +8,23 @@ # If you want to disable the integration with `apps.plugin` or `cgroups.plugin` along with the above charts, change # the setting `apps` and `cgroups` to 'no'. # +# The `ebpf type format` option accepts the following values : +# `auto` : The eBPF collector will investigate hardware and select between the two next options. +# `legacy`: The eBPF collector will load the legacy code. Note: This has a bigger overload. +# `co-re` : The eBPF collector will use latest tracing method. Note: This is not available on all platforms. +# +# The `ebpf co-re tracing` option accepts the following values: +# `trampoline`: This is the default mode used by the eBPF collector, due the small overhead added to host. +# `tracepoint`: When available, the eBPF collector will use kernel tracepoint to monitor syscall. +# `probe` : This is the same as legacy code. # -#[global] +[global] # ebpf load mode = entry # apps = yes # cgroups = no # update every = 10 + ebpf type format = auto + ebpf co-re tracing = trampoline # List of monitored syscalls [syscalls] diff --git a/collectors/ebpf.plugin/ebpf.h b/collectors/ebpf.plugin/ebpf.h index 165a6bf36..337e4f471 100644 --- a/collectors/ebpf.plugin/ebpf.h +++ b/collectors/ebpf.plugin/ebpf.h @@ -238,10 +238,13 @@ extern int ebpf_enable_tracepoint(ebpf_tracepoint_t *tp); extern int ebpf_disable_tracepoint(ebpf_tracepoint_t *tp); extern uint32_t ebpf_enable_tracepoints(ebpf_tracepoint_t *tps); +extern void ebpf_pid_file(char *filename, size_t length); + #define EBPF_PROGRAMS_SECTION "ebpf programs" #define EBPF_COMMON_DIMENSION_PERCENTAGE "%" #define EBPF_COMMON_DIMENSION_CALL "calls/s" +#define EBPF_COMMON_DIMENSION_CONNECTIONS "connections/s" #define EBPF_COMMON_DIMENSION_BITS "kilobits/s" #define EBPF_COMMON_DIMENSION_BYTES "bytes/s" #define EBPF_COMMON_DIMENSION_DIFFERENCE "difference" @@ -264,6 +267,7 @@ extern pthread_mutex_t mutex_cgroup_shm; extern size_t all_pids_count; extern uint32_t finalized_threads; extern ebpf_plugin_stats_t plugin_statistics; +extern struct btf *default_btf; // Socket functions and variables // Common functions diff --git a/collectors/ebpf.plugin/ebpf_apps.c b/collectors/ebpf.plugin/ebpf_apps.c index 015d1bf21..abc112642 100644 --- a/collectors/ebpf.plugin/ebpf_apps.c +++ b/collectors/ebpf.plugin/ebpf_apps.c @@ -275,7 +275,7 @@ int ebpf_read_apps_groups_conf(struct target **agdt, struct target **agrt, const // ---------------------------------------- - procfile *ff = procfile_open(filename, " :\t", PROCFILE_FLAG_DEFAULT); + procfile *ff = procfile_open_no_log(filename, " :\t", PROCFILE_FLAG_DEFAULT); if (!ff) return -1; diff --git a/collectors/ebpf.plugin/ebpf_apps.h b/collectors/ebpf.plugin/ebpf_apps.h index 0c72b8782..259e642ad 100644 --- a/collectors/ebpf.plugin/ebpf_apps.h +++ b/collectors/ebpf.plugin/ebpf_apps.h @@ -379,6 +379,10 @@ typedef struct ebpf_bandwidth { uint64_t retransmit; // Number of times tcp_retransmit was called uint64_t call_udp_sent; // Number of times udp_sendmsg was called uint64_t call_udp_received; // Number of times udp_recvmsg was called + uint64_t close; // Number of times tcp_close was called + uint64_t drop; // THIS IS NOT USED FOR WHILE, we are in groom section + uint32_t tcp_v4_connection; // Number of times tcp_v4_connection was called. + uint32_t tcp_v6_connection; // Number of times tcp_v6_connection was called. } ebpf_bandwidth_t; /** diff --git a/collectors/ebpf.plugin/ebpf_cachestat.c b/collectors/ebpf.plugin/ebpf_cachestat.c index 0cc16234b..ed4c14288 100644 --- a/collectors/ebpf.plugin/ebpf_cachestat.c +++ b/collectors/ebpf.plugin/ebpf_cachestat.c @@ -327,7 +327,7 @@ void ebpf_cachestat_create_apps_charts(struct ebpf_module *em, void *ptr) { struct target *root = ptr; ebpf_create_charts_on_apps(NETDATA_CACHESTAT_HIT_RATIO_CHART, - "The ratio is calculated dividing the Hit pages per total cache accesses without counting dirties.", + "Hit ratio", EBPF_COMMON_DIMENSION_PERCENTAGE, NETDATA_CACHESTAT_SUBMENU, NETDATA_EBPF_CHART_TYPE_LINE, @@ -336,7 +336,7 @@ void ebpf_cachestat_create_apps_charts(struct ebpf_module *em, void *ptr) root, em->update_every, NETDATA_EBPF_MODULE_NAME_CACHESTAT); ebpf_create_charts_on_apps(NETDATA_CACHESTAT_DIRTY_CHART, - "Number of pages marked as dirty. When a page is called dirty, this means that the data stored inside the page needs to be written to devices.", + "Number of dirty pages", EBPF_CACHESTAT_DIMENSION_PAGE, NETDATA_CACHESTAT_SUBMENU, NETDATA_EBPF_CHART_TYPE_STACKED, @@ -345,7 +345,7 @@ void ebpf_cachestat_create_apps_charts(struct ebpf_module *em, void *ptr) root, em->update_every, NETDATA_EBPF_MODULE_NAME_CACHESTAT); ebpf_create_charts_on_apps(NETDATA_CACHESTAT_HIT_CHART, - "Number of cache access without counting dirty pages and page additions.", + "Number of accessed files", EBPF_CACHESTAT_DIMENSION_HITS, NETDATA_CACHESTAT_SUBMENU, NETDATA_EBPF_CHART_TYPE_STACKED, @@ -354,7 +354,7 @@ void ebpf_cachestat_create_apps_charts(struct ebpf_module *em, void *ptr) root, em->update_every, NETDATA_EBPF_MODULE_NAME_CACHESTAT); ebpf_create_charts_on_apps(NETDATA_CACHESTAT_MISSES_CHART, - "Page caches added without counting dirty pages", + "Files out of page cache", EBPF_CACHESTAT_DIMENSION_MISSES, NETDATA_CACHESTAT_SUBMENU, NETDATA_EBPF_CHART_TYPE_STACKED, @@ -599,7 +599,7 @@ void ebpf_cachestat_calc_chart_values() static void ebpf_create_systemd_cachestat_charts(int update_every) { ebpf_create_charts_on_systemd(NETDATA_CACHESTAT_HIT_RATIO_CHART, - "Hit is calculating using total cache added without dirties per total added because of red misses.", + "Hit ratio", EBPF_COMMON_DIMENSION_PERCENTAGE, NETDATA_CACHESTAT_SUBMENU, NETDATA_EBPF_CHART_TYPE_LINE, 21100, ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX], @@ -607,21 +607,21 @@ static void ebpf_create_systemd_cachestat_charts(int update_every) update_every); ebpf_create_charts_on_systemd(NETDATA_CACHESTAT_DIRTY_CHART, - "Number of dirty pages added to the page cache.", + "Number of dirty pages", EBPF_CACHESTAT_DIMENSION_PAGE, NETDATA_CACHESTAT_SUBMENU, NETDATA_EBPF_CHART_TYPE_LINE, 21101, ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX], NETDATA_SYSTEMD_CACHESTAT_MODIFIED_CACHE_CONTEXT, NETDATA_EBPF_MODULE_NAME_CACHESTAT, update_every); - ebpf_create_charts_on_systemd(NETDATA_CACHESTAT_HIT_CHART, "Hits are function calls that Netdata counts.", + ebpf_create_charts_on_systemd(NETDATA_CACHESTAT_HIT_CHART, "Number of accessed files", EBPF_CACHESTAT_DIMENSION_HITS, NETDATA_CACHESTAT_SUBMENU, NETDATA_EBPF_CHART_TYPE_LINE, 21102, ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX], NETDATA_SYSTEMD_CACHESTAT_HIT_FILE_CONTEXT, NETDATA_EBPF_MODULE_NAME_CACHESTAT, update_every); - ebpf_create_charts_on_systemd(NETDATA_CACHESTAT_MISSES_CHART, "Misses are function calls that Netdata counts.", + ebpf_create_charts_on_systemd(NETDATA_CACHESTAT_MISSES_CHART, "Files out of page cache", EBPF_CACHESTAT_DIMENSION_MISSES, NETDATA_CACHESTAT_SUBMENU, NETDATA_EBPF_CHART_TYPE_LINE, 21103, ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX], @@ -713,7 +713,7 @@ static void ebpf_send_specific_cachestat_data(char *type, netdata_publish_caches static void ebpf_create_specific_cachestat_charts(char *type, int update_every) { ebpf_create_chart(type, NETDATA_CACHESTAT_HIT_RATIO_CHART, - "Hit is calculating using total cache added without dirties per total added because of red misses.", + "Hit ratio", EBPF_COMMON_DIMENSION_PERCENTAGE, NETDATA_CACHESTAT_CGROUP_SUBMENU, NETDATA_CGROUP_CACHESTAT_HIT_RATIO_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5200, @@ -721,7 +721,7 @@ static void ebpf_create_specific_cachestat_charts(char *type, int update_every) cachestat_counter_publish_aggregated, 1, update_every, NETDATA_EBPF_MODULE_NAME_CACHESTAT); ebpf_create_chart(type, NETDATA_CACHESTAT_DIRTY_CHART, - "Number of dirty pages added to the page cache.", + "Number of dirty pages", EBPF_CACHESTAT_DIMENSION_PAGE, NETDATA_CACHESTAT_CGROUP_SUBMENU, NETDATA_CGROUP_CACHESTAT_MODIFIED_CACHE_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5201, @@ -730,7 +730,7 @@ static void ebpf_create_specific_cachestat_charts(char *type, int update_every) update_every, NETDATA_EBPF_MODULE_NAME_CACHESTAT); ebpf_create_chart(type, NETDATA_CACHESTAT_HIT_CHART, - "Hits are function calls that Netdata counts.", + "Number of accessed files", EBPF_CACHESTAT_DIMENSION_HITS, NETDATA_CACHESTAT_CGROUP_SUBMENU, NETDATA_CGROUP_CACHESTAT_HIT_FILES_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5202, @@ -739,7 +739,7 @@ static void ebpf_create_specific_cachestat_charts(char *type, int update_every) update_every, NETDATA_EBPF_MODULE_NAME_CACHESTAT); ebpf_create_chart(type, NETDATA_CACHESTAT_MISSES_CHART, - "Misses are function calls that Netdata counts.", + "Files out of page cache", EBPF_CACHESTAT_DIMENSION_MISSES, NETDATA_CACHESTAT_CGROUP_SUBMENU, NETDATA_CGROUP_CACHESTAT_MISS_FILES_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5203, @@ -759,25 +759,25 @@ static void ebpf_create_specific_cachestat_charts(char *type, int update_every) static void ebpf_obsolete_specific_cachestat_charts(char *type, int update_every) { ebpf_write_chart_obsolete(type, NETDATA_CACHESTAT_HIT_RATIO_CHART, - "Hit is calculating using total cache added without dirties per total added because of red misses.", + "Hit ratio", EBPF_COMMON_DIMENSION_PERCENTAGE, NETDATA_CACHESTAT_SUBMENU, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_CACHESTAT_HIT_RATIO_CONTEXT, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5200, update_every); ebpf_write_chart_obsolete(type, NETDATA_CACHESTAT_DIRTY_CHART, - "Number of dirty pages added to the page cache.", + "Number of dirty pages", EBPF_CACHESTAT_DIMENSION_PAGE, NETDATA_CACHESTAT_SUBMENU, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_CACHESTAT_MODIFIED_CACHE_CONTEXT, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5201, update_every); ebpf_write_chart_obsolete(type, NETDATA_CACHESTAT_HIT_CHART, - "Hits are function calls that Netdata counts.", + "Number of accessed files", EBPF_CACHESTAT_DIMENSION_HITS, NETDATA_CACHESTAT_SUBMENU, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_CACHESTAT_HIT_FILES_CONTEXT, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5202, update_every); ebpf_write_chart_obsolete(type, NETDATA_CACHESTAT_MISSES_CHART, - "Misses are function calls that Netdata counts.", + "Files out of page cache", EBPF_CACHESTAT_DIMENSION_MISSES, NETDATA_CACHESTAT_SUBMENU, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_CACHESTAT_MISS_FILES_CONTEXT, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5203, update_every); @@ -892,7 +892,7 @@ static void cachestat_collector(ebpf_module_t *em) static void ebpf_create_memory_charts(ebpf_module_t *em) { ebpf_create_chart(NETDATA_EBPF_MEMORY_GROUP, NETDATA_CACHESTAT_HIT_RATIO_CHART, - "Hit is calculating using total cache added without dirties per total added because of red misses.", + "Hit ratio", EBPF_COMMON_DIMENSION_PERCENTAGE, NETDATA_CACHESTAT_SUBMENU, NULL, NETDATA_EBPF_CHART_TYPE_LINE, @@ -901,7 +901,7 @@ static void ebpf_create_memory_charts(ebpf_module_t *em) cachestat_counter_publish_aggregated, 1, em->update_every, NETDATA_EBPF_MODULE_NAME_CACHESTAT); ebpf_create_chart(NETDATA_EBPF_MEMORY_GROUP, NETDATA_CACHESTAT_DIRTY_CHART, - "Number of dirty pages added to the page cache.", + "Number of dirty pages", EBPF_CACHESTAT_DIMENSION_PAGE, NETDATA_CACHESTAT_SUBMENU, NULL, NETDATA_EBPF_CHART_TYPE_LINE, @@ -911,7 +911,7 @@ static void ebpf_create_memory_charts(ebpf_module_t *em) em->update_every, NETDATA_EBPF_MODULE_NAME_CACHESTAT); ebpf_create_chart(NETDATA_EBPF_MEMORY_GROUP, NETDATA_CACHESTAT_HIT_CHART, - "Hits are function calls that Netdata counts.", + "Number of accessed files", EBPF_CACHESTAT_DIMENSION_HITS, NETDATA_CACHESTAT_SUBMENU, NULL, NETDATA_EBPF_CHART_TYPE_LINE, @@ -921,7 +921,7 @@ static void ebpf_create_memory_charts(ebpf_module_t *em) em->update_every, NETDATA_EBPF_MODULE_NAME_CACHESTAT); ebpf_create_chart(NETDATA_EBPF_MEMORY_GROUP, NETDATA_CACHESTAT_MISSES_CHART, - "Misses are function calls that Netdata counts.", + "Files out of page cache", EBPF_CACHESTAT_DIMENSION_MISSES, NETDATA_CACHESTAT_SUBMENU, NULL, NETDATA_EBPF_CHART_TYPE_LINE, diff --git a/collectors/ebpf.plugin/ebpf_cgroup.c b/collectors/ebpf.plugin/ebpf_cgroup.c index ecdc46c0b..e6b483baf 100644 --- a/collectors/ebpf.plugin/ebpf_cgroup.c +++ b/collectors/ebpf.plugin/ebpf_cgroup.c @@ -242,7 +242,7 @@ static ebpf_cgroup_target_t * ebpf_cgroup_find_or_create(netdata_ebpf_cgroup_shm */ static void ebpf_update_pid_link_list(ebpf_cgroup_target_t *ect, char *path) { - procfile *ff = procfile_open(path, " \t:", PROCFILE_FLAG_DEFAULT); + procfile *ff = procfile_open_no_log(path, " \t:", PROCFILE_FLAG_DEFAULT); if (!ff) return; diff --git a/collectors/ebpf.plugin/ebpf_dcstat.c b/collectors/ebpf.plugin/ebpf_dcstat.c index 820e24e39..fba87007f 100644 --- a/collectors/ebpf.plugin/ebpf_dcstat.c +++ b/collectors/ebpf.plugin/ebpf_dcstat.c @@ -160,7 +160,7 @@ void ebpf_dcstat_create_apps_charts(struct ebpf_module *em, void *ptr) { struct target *root = ptr; ebpf_create_charts_on_apps(NETDATA_DC_HIT_CHART, - "Percentage of files listed inside directory cache", + "Percentage of files inside directory cache", EBPF_COMMON_DIMENSION_PERCENTAGE, NETDATA_DIRECTORY_CACHE_SUBMENU, NETDATA_EBPF_CHART_TYPE_LINE, @@ -169,7 +169,7 @@ void ebpf_dcstat_create_apps_charts(struct ebpf_module *em, void *ptr) root, em->update_every, NETDATA_EBPF_MODULE_NAME_DCSTAT); ebpf_create_charts_on_apps(NETDATA_DC_REFERENCE_CHART, - "Count file access.", + "Count file access", EBPF_COMMON_DIMENSION_FILES, NETDATA_DIRECTORY_CACHE_SUBMENU, NETDATA_EBPF_CHART_TYPE_STACKED, @@ -178,7 +178,7 @@ void ebpf_dcstat_create_apps_charts(struct ebpf_module *em, void *ptr) root, em->update_every, NETDATA_EBPF_MODULE_NAME_DCSTAT); ebpf_create_charts_on_apps(NETDATA_DC_REQUEST_NOT_CACHE_CHART, - "Access to files that were not present inside directory cache.", + "Files not present inside directory cache", EBPF_COMMON_DIMENSION_FILES, NETDATA_DIRECTORY_CACHE_SUBMENU, NETDATA_EBPF_CHART_TYPE_STACKED, @@ -187,7 +187,7 @@ void ebpf_dcstat_create_apps_charts(struct ebpf_module *em, void *ptr) root, em->update_every, NETDATA_EBPF_MODULE_NAME_DCSTAT); ebpf_create_charts_on_apps(NETDATA_DC_REQUEST_NOT_FOUND_CHART, - "Number of requests for files that were not found on filesystem.", + "Files not found", EBPF_COMMON_DIMENSION_FILES, NETDATA_DIRECTORY_CACHE_SUBMENU, NETDATA_EBPF_CHART_TYPE_STACKED, @@ -520,14 +520,14 @@ static void dcstat_send_global(netdata_publish_dcstat_t *publish) */ static void ebpf_create_specific_dc_charts(char *type, int update_every) { - ebpf_create_chart(type, NETDATA_DC_HIT_CHART, "Percentage of files listed inside directory cache.", + ebpf_create_chart(type, NETDATA_DC_HIT_CHART, "Percentage of files inside directory cache", EBPF_COMMON_DIMENSION_PERCENTAGE, NETDATA_DIRECTORY_CACHE_SUBMENU, NETDATA_CGROUP_DC_HIT_RATIO_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5700, ebpf_create_global_dimension, dcstat_counter_publish_aggregated, 1, update_every, NETDATA_EBPF_MODULE_NAME_DCSTAT); - ebpf_create_chart(type, NETDATA_DC_REFERENCE_CHART, "Count file access.", + ebpf_create_chart(type, NETDATA_DC_REFERENCE_CHART, "Count file access", EBPF_COMMON_DIMENSION_FILES, NETDATA_DIRECTORY_CACHE_SUBMENU, NETDATA_CGROUP_DC_REFERENCE_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5701, @@ -536,7 +536,7 @@ static void ebpf_create_specific_dc_charts(char *type, int update_every) update_every, NETDATA_EBPF_MODULE_NAME_DCSTAT); ebpf_create_chart(type, NETDATA_DC_REQUEST_NOT_CACHE_CHART, - "Access to files that were not present inside directory cache.", + "Files not present inside directory cache", EBPF_COMMON_DIMENSION_FILES, NETDATA_DIRECTORY_CACHE_SUBMENU, NETDATA_CGROUP_DC_NOT_CACHE_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5702, @@ -545,7 +545,7 @@ static void ebpf_create_specific_dc_charts(char *type, int update_every) update_every, NETDATA_EBPF_MODULE_NAME_DCSTAT); ebpf_create_chart(type, NETDATA_DC_REQUEST_NOT_FOUND_CHART, - "Number of requests for files that were not found on filesystem.", + "Files not found", EBPF_COMMON_DIMENSION_FILES, NETDATA_DIRECTORY_CACHE_SUBMENU, NETDATA_CGROUP_DC_NOT_FOUND_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5703, @@ -565,25 +565,25 @@ static void ebpf_create_specific_dc_charts(char *type, int update_every) static void ebpf_obsolete_specific_dc_charts(char *type, int update_every) { ebpf_write_chart_obsolete(type, NETDATA_DC_HIT_CHART, - "Percentage of files listed inside directory cache.", + "Percentage of files inside directory cache", EBPF_COMMON_DIMENSION_PERCENTAGE, NETDATA_DIRECTORY_CACHE_SUBMENU, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_DC_HIT_RATIO_CONTEXT, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5700, update_every); ebpf_write_chart_obsolete(type, NETDATA_DC_REFERENCE_CHART, - "Count file access.", + "Count file access", EBPF_COMMON_DIMENSION_FILES, NETDATA_DIRECTORY_CACHE_SUBMENU, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_DC_REFERENCE_CONTEXT, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5701, update_every); ebpf_write_chart_obsolete(type, NETDATA_DC_REQUEST_NOT_CACHE_CHART, - "Access to files that were not present inside directory cache.", + "Files not present inside directory cache", EBPF_COMMON_DIMENSION_FILES, NETDATA_DIRECTORY_CACHE_SUBMENU, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_DC_NOT_CACHE_CONTEXT, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5702, update_every); ebpf_write_chart_obsolete(type, NETDATA_DC_REQUEST_NOT_FOUND_CHART, - "Number of requests for files that were not found on filesystem.", + "Files not found", EBPF_COMMON_DIMENSION_FILES, NETDATA_DIRECTORY_CACHE_SUBMENU, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_DC_NOT_FOUND_CONTEXT, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5703, update_every); @@ -647,7 +647,7 @@ void ebpf_dc_calc_chart_values() static void ebpf_create_systemd_dc_charts(int update_every) { ebpf_create_charts_on_systemd(NETDATA_DC_HIT_CHART, - "Percentage of files listed inside directory cache.", + "Percentage of files inside directory cache", EBPF_COMMON_DIMENSION_PERCENTAGE, NETDATA_DIRECTORY_CACHE_SUBMENU, NETDATA_EBPF_CHART_TYPE_LINE, @@ -657,7 +657,7 @@ static void ebpf_create_systemd_dc_charts(int update_every) update_every); ebpf_create_charts_on_systemd(NETDATA_DC_REFERENCE_CHART, - "Count file access.", + "Count file access", EBPF_COMMON_DIMENSION_FILES, NETDATA_DIRECTORY_CACHE_SUBMENU, NETDATA_EBPF_CHART_TYPE_LINE, @@ -667,7 +667,7 @@ static void ebpf_create_systemd_dc_charts(int update_every) update_every); ebpf_create_charts_on_systemd(NETDATA_DC_REQUEST_NOT_CACHE_CHART, - "Access to files that were not present inside directory cache.", + "Files not present inside directory cache", EBPF_COMMON_DIMENSION_FILES, NETDATA_DIRECTORY_CACHE_SUBMENU, NETDATA_EBPF_CHART_TYPE_LINE, @@ -677,7 +677,7 @@ static void ebpf_create_systemd_dc_charts(int update_every) update_every); ebpf_create_charts_on_systemd(NETDATA_DC_REQUEST_NOT_FOUND_CHART, - "Number of requests for files that were not found on filesystem.", + "Files not found", EBPF_COMMON_DIMENSION_FILES, NETDATA_DIRECTORY_CACHE_SUBMENU, NETDATA_EBPF_CHART_TYPE_LINE, @@ -890,7 +890,7 @@ static void dcstat_collector(ebpf_module_t *em) static void ebpf_create_filesystem_charts(int update_every) { ebpf_create_chart(NETDATA_FILESYSTEM_FAMILY, NETDATA_DC_HIT_CHART, - "Percentage of files listed inside directory cache", + "Percentage of files inside directory cache", EBPF_COMMON_DIMENSION_PERCENTAGE, NETDATA_DIRECTORY_CACHE_SUBMENU, NULL, NETDATA_EBPF_CHART_TYPE_LINE, diff --git a/collectors/ebpf.plugin/ebpf_mount.c b/collectors/ebpf.plugin/ebpf_mount.c index 666936d86..1ba1e135c 100644 --- a/collectors/ebpf.plugin/ebpf_mount.c +++ b/collectors/ebpf.plugin/ebpf_mount.c @@ -30,6 +30,196 @@ struct netdata_static_thread mount_thread = {"MOUNT KERNEL", NULL, NULL, 1, NULL, NULL, NULL}; +netdata_ebpf_targets_t mount_targets[] = { {.name = "mount", .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = "umount", .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = NULL, .mode = EBPF_LOAD_TRAMPOLINE}}; + +#ifdef LIBBPF_MAJOR_VERSION +#include "includes/mount.skel.h" // BTF code + +static struct mount_bpf *bpf_obj = NULL; + +/***************************************************************** + * + * BTF FUNCTIONS + * + *****************************************************************/ + +/* + * Disable probe + * + * Disable all probes to use exclusively another method. + * + * @param obj is the main structure for bpf objects. + */ +static inline void ebpf_mount_disable_probe(struct mount_bpf *obj) +{ + bpf_program__set_autoload(obj->progs.netdata_mount_probe, false); + bpf_program__set_autoload(obj->progs.netdata_umount_probe, false); + + bpf_program__set_autoload(obj->progs.netdata_mount_retprobe, false); + bpf_program__set_autoload(obj->progs.netdata_umount_retprobe, false); +} + +/* + * Disable tracepoint + * + * Disable all tracepoints to use exclusively another method. + * + * @param obj is the main structure for bpf objects. + */ +static inline void ebpf_mount_disable_tracepoint(struct mount_bpf *obj) +{ + bpf_program__set_autoload(obj->progs.netdata_mount_exit, false); + bpf_program__set_autoload(obj->progs.netdata_umount_exit, false); +} + +/* + * Disable trampoline + * + * Disable all trampoline to use exclusively another method. + * + * @param obj is the main structure for bpf objects. + */ +static inline void ebpf_mount_disable_trampoline(struct mount_bpf *obj) +{ + bpf_program__set_autoload(obj->progs.netdata_mount_fentry, false); + bpf_program__set_autoload(obj->progs.netdata_umount_fentry, false); + bpf_program__set_autoload(obj->progs.netdata_mount_fexit, false); + bpf_program__set_autoload(obj->progs.netdata_umount_fexit, false); +} + +/** + * Set trampoline target + * + * Set the targets we will monitor. + * + * @param obj is the main structure for bpf objects. + */ +static inline void netdata_set_trampoline_target(struct mount_bpf *obj) +{ + char syscall[NETDATA_EBPF_MAX_SYSCALL_LENGTH + 1]; + ebpf_select_host_prefix(syscall, NETDATA_EBPF_MAX_SYSCALL_LENGTH, + mount_targets[NETDATA_MOUNT_SYSCALL].name, running_on_kernel); + + bpf_program__set_attach_target(obj->progs.netdata_mount_fentry, 0, + syscall); + + bpf_program__set_attach_target(obj->progs.netdata_mount_fexit, 0, + syscall); + + ebpf_select_host_prefix(syscall, NETDATA_EBPF_MAX_SYSCALL_LENGTH, + mount_targets[NETDATA_UMOUNT_SYSCALL].name, running_on_kernel); + + bpf_program__set_attach_target(obj->progs.netdata_umount_fentry, 0, + syscall); + + bpf_program__set_attach_target(obj->progs.netdata_umount_fexit, 0, + syscall); +} + +/** + * Mount Attach Probe + * + * Attach probes to target + * + * @param obj is the main structure for bpf objects. + * + * @return It returns 0 on success and -1 otherwise. + */ +static int ebpf_mount_attach_probe(struct mount_bpf *obj) +{ + char syscall[NETDATA_EBPF_MAX_SYSCALL_LENGTH + 1]; + + ebpf_select_host_prefix(syscall, NETDATA_EBPF_MAX_SYSCALL_LENGTH, + mount_targets[NETDATA_MOUNT_SYSCALL].name, running_on_kernel); + + obj->links.netdata_mount_probe = bpf_program__attach_kprobe(obj->progs.netdata_mount_probe, + false, syscall); + int ret = (int)libbpf_get_error(obj->links.netdata_mount_probe); + if (ret) + return -1; + + obj->links.netdata_mount_retprobe = bpf_program__attach_kprobe(obj->progs.netdata_mount_retprobe, + true, syscall); + ret = (int)libbpf_get_error(obj->links.netdata_mount_retprobe); + if (ret) + return -1; + + ebpf_select_host_prefix(syscall, NETDATA_EBPF_MAX_SYSCALL_LENGTH, + mount_targets[NETDATA_UMOUNT_SYSCALL].name, running_on_kernel); + + obj->links.netdata_umount_probe = bpf_program__attach_kprobe(obj->progs.netdata_umount_probe, + false, syscall); + ret = (int)libbpf_get_error(obj->links.netdata_umount_probe); + if (ret) + return -1; + + obj->links.netdata_umount_retprobe = bpf_program__attach_kprobe(obj->progs.netdata_umount_retprobe, + true, syscall); + ret = (int)libbpf_get_error(obj->links.netdata_umount_retprobe); + if (ret) + return -1; + + return 0; +} + +/** + * Set hash tables + * + * Set the values for maps according the value given by kernel. + * + * @param obj is the main structure for bpf objects. + */ +static void ebpf_mount_set_hash_tables(struct mount_bpf *obj) +{ + mount_maps[NETDATA_KEY_MOUNT_TABLE].map_fd = bpf_map__fd(obj->maps.tbl_mount); +} + +/** + * Load and attach + * + * Load and attach the eBPF code in kernel. + * + * @param obj is the main structure for bpf objects. + * @param em structure with configuration + * + * @return it returns 0 on succes and -1 otherwise + */ +static inline int ebpf_mount_load_and_attach(struct mount_bpf *obj, ebpf_module_t *em) +{ + netdata_ebpf_targets_t *mt = em->targets; + netdata_ebpf_program_loaded_t test = mt[NETDATA_MOUNT_SYSCALL].mode; + + // We are testing only one, because all will have the same behavior + if (test == EBPF_LOAD_TRAMPOLINE ) { + ebpf_mount_disable_probe(obj); + ebpf_mount_disable_tracepoint(obj); + + netdata_set_trampoline_target(obj); + } else if (test == EBPF_LOAD_PROBE || + test == EBPF_LOAD_RETPROBE ) { + ebpf_mount_disable_tracepoint(obj); + ebpf_mount_disable_trampoline(obj); + } else { + ebpf_mount_disable_probe(obj); + ebpf_mount_disable_trampoline(obj); + } + + int ret = mount_bpf__load(obj); + if (!ret) { + if (test != EBPF_LOAD_PROBE && test != EBPF_LOAD_RETPROBE ) + ret = mount_bpf__attach(obj); + else + ret = ebpf_mount_attach_probe(obj); + + if (!ret) + ebpf_mount_set_hash_tables(obj); + } + + return ret; +} +#endif /***************************************************************** * * FUNCTIONS TO CLOSE THE THREAD @@ -59,6 +249,11 @@ static void ebpf_mount_cleanup(void *ptr) } bpf_object__close(objects); } +#ifdef LIBBPF_MAJOR_VERSION + else if (bpf_obj) + mount_bpf__destroy(bpf_obj); +#endif + } /***************************************************************** @@ -191,7 +386,7 @@ static void mount_collector(ebpf_module_t *em) static void ebpf_create_mount_charts(int update_every) { ebpf_create_chart(NETDATA_EBPF_MOUNT_GLOBAL_FAMILY, NETDATA_EBPF_MOUNT_CALLS, - "Calls to mount and umount syscalls.", + "Calls to mount and umount syscalls", EBPF_COMMON_DIMENSION_CALL, NETDATA_EBPF_MOUNT_FAMILY, NULL, NETDATA_EBPF_CHART_TYPE_LINE, @@ -201,7 +396,7 @@ static void ebpf_create_mount_charts(int update_every) update_every, NETDATA_EBPF_MODULE_NAME_MOUNT); ebpf_create_chart(NETDATA_EBPF_MOUNT_GLOBAL_FAMILY, NETDATA_EBPF_MOUNT_ERRORS, - "Errors to mount and umount syscalls.", + "Errors to mount and umount file systems", EBPF_COMMON_DIMENSION_CALL, NETDATA_EBPF_MOUNT_FAMILY, NULL, NETDATA_EBPF_CHART_TYPE_LINE, @@ -219,6 +414,39 @@ static void ebpf_create_mount_charts(int update_every) * *****************************************************************/ +/* + * Load BPF + * + * Load BPF files. + * + * @param em the structure with configuration + */ +static int ebpf_mount_load_bpf(ebpf_module_t *em) +{ + int ret = 0; + if (em->load == EBPF_LOAD_LEGACY) { + probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects); + if (!probe_links) { + em->enabled = CONFIG_BOOLEAN_NO; + ret = -1; + } + } +#ifdef LIBBPF_MAJOR_VERSION + else { + bpf_obj = mount_bpf__open(); + if (!bpf_obj) + ret = -1; + else + ret = ebpf_mount_load_and_attach(bpf_obj, em); + } +#endif + + if (ret) + error("%s %s", EBPF_DEFAULT_ERROR_MSG, em->thread_name); + + return ret; +} + /** * Mount thread * @@ -238,8 +466,10 @@ void *ebpf_mount_thread(void *ptr) if (!em->enabled) goto endmount; - probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects); - if (!probe_links) { +#ifdef LIBBPF_MAJOR_VERSION + ebpf_adjust_thread_load(em, default_btf); +#endif + if (ebpf_mount_load_bpf(em)) { em->enabled = CONFIG_BOOLEAN_NO; goto endmount; } diff --git a/collectors/ebpf.plugin/ebpf_mount.h b/collectors/ebpf.plugin/ebpf_mount.h index 700bea13b..d4f48efd1 100644 --- a/collectors/ebpf.plugin/ebpf_mount.h +++ b/collectors/ebpf.plugin/ebpf_mount.h @@ -30,7 +30,15 @@ enum mount_tables { NETDATA_KEY_MOUNT_TABLE }; +enum netdata_mount_syscalls { + NETDATA_MOUNT_SYSCALL, + NETDATA_UMOUNT_SYSCALL, + + NETDATA_MOUNT_SYSCALLS_END +}; + extern struct config mount_config; extern void *ebpf_mount_thread(void *ptr); +extern netdata_ebpf_targets_t mount_targets[]; #endif /* NETDATA_EBPF_MOUNT_H */ diff --git a/collectors/ebpf.plugin/ebpf_oomkill.c b/collectors/ebpf.plugin/ebpf_oomkill.c index 434fc7fd3..f38801875 100644 --- a/collectors/ebpf.plugin/ebpf_oomkill.c +++ b/collectors/ebpf.plugin/ebpf_oomkill.c @@ -120,7 +120,7 @@ static void ebpf_create_specific_oomkill_charts(char *type, int update_every) { ebpf_create_chart(type, NETDATA_OOMKILL_CHART, "OOM kills. This chart is provided by eBPF plugin.", EBPF_COMMON_DIMENSION_KILLS, NETDATA_EBPF_MEMORY_GROUP, - NULL, NETDATA_EBPF_CHART_TYPE_LINE, + NETDATA_CGROUP_OOMKILLS_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5600, ebpf_create_global_dimension, &oomkill_publish_aggregated, 1, update_every, NETDATA_EBPF_MODULE_NAME_OOMKILL); @@ -194,7 +194,7 @@ static void ebpf_obsolete_specific_oomkill_charts(char *type, int update_every) { ebpf_write_chart_obsolete(type, NETDATA_OOMKILL_CHART, "OOM kills. This chart is provided by eBPF plugin.", EBPF_COMMON_DIMENSION_KILLS, NETDATA_EBPF_MEMORY_GROUP, - NETDATA_EBPF_CHART_TYPE_LINE, NULL, + NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_OOMKILLS_CONTEXT, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5600, update_every); } diff --git a/collectors/ebpf.plugin/ebpf_oomkill.h b/collectors/ebpf.plugin/ebpf_oomkill.h index 86f9463dd..b5f04c74c 100644 --- a/collectors/ebpf.plugin/ebpf_oomkill.h +++ b/collectors/ebpf.plugin/ebpf_oomkill.h @@ -22,6 +22,9 @@ typedef uint8_t oomkill_ebpf_val_t; #define NETDATA_OOMKILL_CHART "oomkills" +// Contexts +#define NETDATA_CGROUP_OOMKILLS_CONTEXT "cgroup.oomkills" + extern struct config oomkill_config; extern void *ebpf_oomkill_thread(void *ptr); extern void ebpf_oomkill_create_apps_charts(struct ebpf_module *em, void *ptr); diff --git a/collectors/ebpf.plugin/ebpf_shm.c b/collectors/ebpf.plugin/ebpf_shm.c index 0cfb3abdc..939741e75 100644 --- a/collectors/ebpf.plugin/ebpf_shm.c +++ b/collectors/ebpf.plugin/ebpf_shm.c @@ -41,6 +41,203 @@ static struct bpf_object *objects = NULL; struct netdata_static_thread shm_threads = {"SHM KERNEL", NULL, NULL, 1, NULL, NULL, NULL}; +netdata_ebpf_targets_t shm_targets[] = { {.name = "shmget", .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = "shmat", .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = "shmdt", .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = "shmctl", .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = NULL, .mode = EBPF_LOAD_TRAMPOLINE}}; + +#ifdef LIBBPF_MAJOR_VERSION +#include "includes/shm.skel.h" + +static struct shm_bpf *bpf_obj = NULL; + +/***************************************************************** + * + * BTF FUNCTIONS + * + *****************************************************************/ + +/* + * Disable tracepoint + * + * Disable all tracepoints to use exclusively another method. + * + * @param obj is the main structure for bpf objects. + */ +static void ebpf_shm_disable_tracepoint(struct shm_bpf *obj) +{ + bpf_program__set_autoload(obj->progs.netdata_syscall_shmget, false); + bpf_program__set_autoload(obj->progs.netdata_syscall_shmat, false); + bpf_program__set_autoload(obj->progs.netdata_syscall_shmdt, false); + bpf_program__set_autoload(obj->progs.netdata_syscall_shmctl, false); +} + +/* + * Disable probe + * + * Disable all probes to use exclusively another method. + * + * @param obj is the main structure for bpf objects. + */ +static void ebpf_disable_probe(struct shm_bpf *obj) +{ + bpf_program__set_autoload(obj->progs.netdata_shmget_probe, false); + bpf_program__set_autoload(obj->progs.netdata_shmat_probe, false); + bpf_program__set_autoload(obj->progs.netdata_shmdt_probe, false); + bpf_program__set_autoload(obj->progs.netdata_shmctl_probe, false); +} + +/* + * Disable trampoline + * + * Disable all trampoline to use exclusively another method. + * + * @param obj is the main structure for bpf objects. + */ +static void ebpf_disable_trampoline(struct shm_bpf *obj) +{ + bpf_program__set_autoload(obj->progs.netdata_shmget_fentry, false); + bpf_program__set_autoload(obj->progs.netdata_shmat_fentry, false); + bpf_program__set_autoload(obj->progs.netdata_shmdt_fentry, false); + bpf_program__set_autoload(obj->progs.netdata_shmctl_fentry, false); +} + +/** + * Set trampoline target + * + * Set the targets we will monitor. + * + * @param obj is the main structure for bpf objects. + */ +static void ebpf_set_trampoline_target(struct shm_bpf *obj) +{ + char syscall[NETDATA_EBPF_MAX_SYSCALL_LENGTH + 1]; + ebpf_select_host_prefix(syscall, NETDATA_EBPF_MAX_SYSCALL_LENGTH, + shm_targets[NETDATA_KEY_SHMGET_CALL].name, running_on_kernel); + + bpf_program__set_attach_target(obj->progs.netdata_shmget_fentry, 0, + syscall); + + ebpf_select_host_prefix(syscall, NETDATA_EBPF_MAX_SYSCALL_LENGTH, + shm_targets[NETDATA_KEY_SHMAT_CALL].name, running_on_kernel); + bpf_program__set_attach_target(obj->progs.netdata_shmat_fentry, 0, + syscall); + + ebpf_select_host_prefix(syscall, NETDATA_EBPF_MAX_SYSCALL_LENGTH, + shm_targets[NETDATA_KEY_SHMDT_CALL].name, running_on_kernel); + bpf_program__set_attach_target(obj->progs.netdata_shmdt_fentry, 0, + syscall); + + ebpf_select_host_prefix(syscall, NETDATA_EBPF_MAX_SYSCALL_LENGTH, + shm_targets[NETDATA_KEY_SHMCTL_CALL].name, running_on_kernel); + bpf_program__set_attach_target(obj->progs.netdata_shmctl_fentry, 0, + syscall); +} + +/** + * SHM Attach Probe + * + * Attach probes to target + * + * @param obj is the main structure for bpf objects. + * + * @return It returns 0 on success and -1 otherwise. + */ +static int ebpf_shm_attach_probe(struct shm_bpf *obj) +{ + char syscall[NETDATA_EBPF_MAX_SYSCALL_LENGTH + 1]; + ebpf_select_host_prefix(syscall, NETDATA_EBPF_MAX_SYSCALL_LENGTH, + shm_targets[NETDATA_KEY_SHMGET_CALL].name, running_on_kernel); + + obj->links.netdata_shmget_probe = bpf_program__attach_kprobe(obj->progs.netdata_shmget_probe, + false, syscall); + int ret = (int)libbpf_get_error(obj->links.netdata_shmget_probe); + if (ret) + return -1; + + ebpf_select_host_prefix(syscall, NETDATA_EBPF_MAX_SYSCALL_LENGTH, + shm_targets[NETDATA_KEY_SHMAT_CALL].name, running_on_kernel); + obj->links.netdata_shmat_probe = bpf_program__attach_kprobe(obj->progs.netdata_shmat_probe, + false, syscall); + ret = (int)libbpf_get_error(obj->links.netdata_shmat_probe); + if (ret) + return -1; + + ebpf_select_host_prefix(syscall, NETDATA_EBPF_MAX_SYSCALL_LENGTH, + shm_targets[NETDATA_KEY_SHMDT_CALL].name, running_on_kernel); + obj->links.netdata_shmdt_probe = bpf_program__attach_kprobe(obj->progs.netdata_shmdt_probe, + false, syscall); + ret = (int)libbpf_get_error(obj->links.netdata_shmdt_probe); + if (ret) + return -1; + + ebpf_select_host_prefix(syscall, NETDATA_EBPF_MAX_SYSCALL_LENGTH, + shm_targets[NETDATA_KEY_SHMCTL_CALL].name, running_on_kernel); + obj->links.netdata_shmctl_probe = bpf_program__attach_kprobe(obj->progs.netdata_shmctl_probe, + false, syscall); + ret = (int)libbpf_get_error(obj->links.netdata_shmctl_probe); + if (ret) + return -1; + + return 0; +} + +/** + * Set hash tables + * + * Set the values for maps according the value given by kernel. + */ +static void ebpf_shm_set_hash_tables(struct shm_bpf *obj) +{ + shm_maps[NETDATA_PID_SHM_TABLE].map_fd = bpf_map__fd(obj->maps.tbl_pid_shm); + shm_maps[NETDATA_SHM_CONTROLLER].map_fd = bpf_map__fd(obj->maps.shm_ctrl); + shm_maps[NETDATA_SHM_GLOBAL_TABLE].map_fd = bpf_map__fd(obj->maps.tbl_shm); +} + +/** + * Load and attach + * + * Load and attach the eBPF code in kernel. + * + * @param obj is the main structure for bpf objects. + * @param em structure with configuration + * + * @return it returns 0 on succes and -1 otherwise + */ +static inline int ebpf_shm_load_and_attach(struct shm_bpf *obj, ebpf_module_t *em) +{ + netdata_ebpf_targets_t *shmt = em->targets; + netdata_ebpf_program_loaded_t test = shmt[NETDATA_KEY_SHMGET_CALL].mode; + + // We are testing only one, because all will have the same behavior + if (test == EBPF_LOAD_TRAMPOLINE ) { + ebpf_shm_disable_tracepoint(obj); + ebpf_disable_probe(obj); + + ebpf_set_trampoline_target(obj); + } else if (test == EBPF_LOAD_PROBE || test == EBPF_LOAD_RETPROBE ) { + ebpf_shm_disable_tracepoint(obj); + ebpf_disable_trampoline(obj); + } else { + ebpf_disable_probe(obj); + ebpf_disable_trampoline(obj); + } + + int ret = shm_bpf__load(obj); + if (!ret) { + if (test != EBPF_LOAD_PROBE && test != EBPF_LOAD_RETPROBE) + shm_bpf__attach(obj); + else + ret = ebpf_shm_attach_probe(obj); + + if (!ret) + ebpf_shm_set_hash_tables(obj); + } + + return ret; +} +#endif /***************************************************************** * FUNCTIONS TO CLOSE THE THREAD *****************************************************************/ @@ -91,6 +288,10 @@ static void ebpf_shm_cleanup(void *ptr) } bpf_object__close(objects); } +#ifdef LIBBPF_MAJOR_VERSION + else if (bpf_obj) + shm_bpf__destroy(bpf_obj); +#endif } /***************************************************************** @@ -787,7 +988,7 @@ static void ebpf_create_shm_charts(int update_every) ebpf_create_chart( NETDATA_EBPF_SYSTEM_GROUP, NETDATA_SHM_GLOBAL_CHART, - "Calls to shared memory system calls.", + "Calls to shared memory system calls", EBPF_COMMON_DIMENSION_CALL, NETDATA_SYSTEM_IPC_SHM_SUBMENU, NULL, @@ -802,6 +1003,40 @@ static void ebpf_create_shm_charts(int update_every) fflush(stdout); } +/* + * Load BPF + * + * Load BPF files. + * + * @param em the structure with configuration + */ +static int ebpf_shm_load_bpf(ebpf_module_t *em) +{ + int ret = 0; + if (em->load == EBPF_LOAD_LEGACY) { + probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects); + if (!probe_links) { + em->enabled = CONFIG_BOOLEAN_NO; + ret = -1; + } + } +#ifdef LIBBPF_MAJOR_VERSION + else { + bpf_obj = shm_bpf__open(); + if (!bpf_obj) + ret = -1; + else + ret = ebpf_shm_load_and_attach(bpf_obj, em); + } +#endif + + + if (ret) + error("%s %s", EBPF_DEFAULT_ERROR_MSG, em->thread_name); + + return ret; +} + /** * Shared memory thread. * @@ -821,8 +1056,10 @@ void *ebpf_shm_thread(void *ptr) goto endshm; } - probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects); - if (!probe_links) { +#ifdef LIBBPF_MAJOR_VERSION + ebpf_adjust_thread_load(em, default_btf); +#endif + if (ebpf_shm_load_bpf(em)) { em->enabled = CONFIG_BOOLEAN_NO; goto endshm; } diff --git a/collectors/ebpf.plugin/ebpf_shm.h b/collectors/ebpf.plugin/ebpf_shm.h index 4e7e183a7..f0559e431 100644 --- a/collectors/ebpf.plugin/ebpf_shm.h +++ b/collectors/ebpf.plugin/ebpf_shm.h @@ -57,6 +57,7 @@ extern netdata_publish_shm_t **shm_pid; extern void *ebpf_shm_thread(void *ptr); extern void ebpf_shm_create_apps_charts(struct ebpf_module *em, void *ptr); extern void clean_shm_pid_structures(); +extern netdata_ebpf_targets_t shm_targets[]; extern struct config shm_config; diff --git a/collectors/ebpf.plugin/ebpf_socket.c b/collectors/ebpf.plugin/ebpf_socket.c index b59367f58..da42f0a49 100644 --- a/collectors/ebpf.plugin/ebpf_socket.c +++ b/collectors/ebpf.plugin/ebpf_socket.c @@ -12,9 +12,13 @@ *****************************************************************/ static char *socket_dimension_names[NETDATA_MAX_SOCKET_VECTOR] = { "received", "sent", "close", - "received", "sent", "retransmitted" }; + "received", "sent", "retransmitted", + "connected_V4", "connected_V6", "connected_tcp", + "connected_udp"}; static char *socket_id_names[NETDATA_MAX_SOCKET_VECTOR] = { "tcp_cleanup_rbuf", "tcp_sendmsg", "tcp_close", - "udp_recvmsg", "udp_sendmsg", "tcp_retransmit_skb" }; + "udp_recvmsg", "udp_sendmsg", "tcp_retransmit_skb", + "tcp_connect_v4", "tcp_connect_v6", "inet_csk_accept_tcp", + "inet_csk_accept_udp" }; static ebpf_local_maps_t socket_maps[] = {{.name = "tbl_bandwidth", .internal_input = NETDATA_COMPILED_CONNECTIONS_ALLOWED, @@ -77,6 +81,349 @@ struct config socket_config = { .first_section = NULL, .index = { .avl_tree = { .root = NULL, .compar = appconfig_section_compare }, .rwlock = AVL_LOCK_INITIALIZER } }; +netdata_ebpf_targets_t socket_targets[] = { {.name = "inet_csk_accept", .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = "tcp_retransmit_skb", .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = "tcp_cleanup_rbuf", .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = "tcp_close", .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = "udp_recvmsg", .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = "tcp_sendmsg", .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = "udp_sendmsg", .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = "tcp_v4_connect", .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = "tcp_v6_connect", .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = NULL, .mode = EBPF_LOAD_TRAMPOLINE}}; + +#ifdef LIBBPF_MAJOR_VERSION +#include "includes/socket.skel.h" // BTF code + +static struct socket_bpf *bpf_obj = NULL; + +/** + * Disable Probe + * + * Disable probes to use trampoline. + * + * @param obj is the main structure for bpf objects. + */ +static void ebpf_socket_disable_probes(struct socket_bpf *obj) +{ + bpf_program__set_autoload(obj->progs.netdata_inet_csk_accept_kretprobe, false); + bpf_program__set_autoload(obj->progs.netdata_tcp_v4_connect_kretprobe, false); + bpf_program__set_autoload(obj->progs.netdata_tcp_v6_connect_kretprobe, false); + bpf_program__set_autoload(obj->progs.netdata_tcp_retransmit_skb_kprobe, false); + bpf_program__set_autoload(obj->progs.netdata_tcp_cleanup_rbuf_kprobe, false); + bpf_program__set_autoload(obj->progs.netdata_tcp_close_kprobe, false); + bpf_program__set_autoload(obj->progs.netdata_udp_recvmsg_kprobe, false); + bpf_program__set_autoload(obj->progs.netdata_udp_recvmsg_kretprobe, false); + bpf_program__set_autoload(obj->progs.netdata_tcp_sendmsg_kretprobe, false); + bpf_program__set_autoload(obj->progs.netdata_tcp_sendmsg_kprobe, false); + bpf_program__set_autoload(obj->progs.netdata_udp_sendmsg_kretprobe, false); + bpf_program__set_autoload(obj->progs.netdata_udp_sendmsg_kprobe, false); + bpf_program__set_autoload(obj->progs.netdata_socket_release_task_kprobe, false); +} + +/** + * Disable Trampoline + * + * Disable trampoline to use probes. + * + * @param obj is the main structure for bpf objects. + */ +static void ebpf_socket_disable_trampoline(struct socket_bpf *obj) +{ + bpf_program__set_autoload(obj->progs.netdata_inet_csk_accept_fentry, false); + bpf_program__set_autoload(obj->progs.netdata_tcp_v4_connect_fexit, false); + bpf_program__set_autoload(obj->progs.netdata_tcp_v6_connect_fexit, false); + bpf_program__set_autoload(obj->progs.netdata_tcp_retransmit_skb_fentry, false); + bpf_program__set_autoload(obj->progs.netdata_tcp_cleanup_rbuf_fentry, false); + bpf_program__set_autoload(obj->progs.netdata_tcp_close_fentry, false); + bpf_program__set_autoload(obj->progs.netdata_udp_recvmsg_fentry, false); + bpf_program__set_autoload(obj->progs.netdata_udp_recvmsg_fexit, false); + bpf_program__set_autoload(obj->progs.netdata_tcp_sendmsg_fentry, false); + bpf_program__set_autoload(obj->progs.netdata_tcp_sendmsg_fexit, false); + bpf_program__set_autoload(obj->progs.netdata_udp_sendmsg_fentry, false); + bpf_program__set_autoload(obj->progs.netdata_udp_sendmsg_fexit, false); + bpf_program__set_autoload(obj->progs.netdata_socket_release_task_fentry, false); +} + +/** + * Set trampoline target. + * + * @param obj is the main structure for bpf objects. + */ +static void ebpf_set_trampoline_target(struct socket_bpf *obj) +{ + bpf_program__set_attach_target(obj->progs.netdata_inet_csk_accept_fentry, 0, + socket_targets[NETDATA_FCNT_INET_CSK_ACCEPT].name); + + bpf_program__set_attach_target(obj->progs.netdata_tcp_v4_connect_fexit, 0, + socket_targets[NETDATA_FCNT_TCP_V4_CONNECT].name); + + bpf_program__set_attach_target(obj->progs.netdata_tcp_v6_connect_fexit, 0, + socket_targets[NETDATA_FCNT_TCP_V6_CONNECT].name); + + bpf_program__set_attach_target(obj->progs.netdata_tcp_retransmit_skb_fentry, 0, + socket_targets[NETDATA_FCNT_TCP_RETRANSMIT].name); + + bpf_program__set_attach_target(obj->progs.netdata_tcp_cleanup_rbuf_fentry, 0, + socket_targets[NETDATA_FCNT_CLEANUP_RBUF].name); + + bpf_program__set_attach_target(obj->progs.netdata_tcp_close_fentry, 0, socket_targets[NETDATA_FCNT_TCP_CLOSE].name); + + bpf_program__set_attach_target(obj->progs.netdata_udp_recvmsg_fentry, 0, + socket_targets[NETDATA_FCNT_UDP_RECEVMSG].name); + + bpf_program__set_attach_target(obj->progs.netdata_udp_recvmsg_fexit, 0, + socket_targets[NETDATA_FCNT_UDP_RECEVMSG].name); + + bpf_program__set_attach_target(obj->progs.netdata_tcp_sendmsg_fentry, 0, + socket_targets[NETDATA_FCNT_TCP_SENDMSG].name); + + bpf_program__set_attach_target(obj->progs.netdata_tcp_sendmsg_fexit, 0, + socket_targets[NETDATA_FCNT_TCP_SENDMSG].name); + + bpf_program__set_attach_target(obj->progs.netdata_udp_sendmsg_fentry, 0, + socket_targets[NETDATA_FCNT_UDP_SENDMSG].name); + + bpf_program__set_attach_target(obj->progs.netdata_udp_sendmsg_fexit, 0, + socket_targets[NETDATA_FCNT_UDP_SENDMSG].name); + + bpf_program__set_attach_target(obj->progs.netdata_socket_release_task_fentry, 0, EBPF_COMMON_FNCT_CLEAN_UP); +} + + +/** + * Disable specific trampoline + * + * Disable specific trampoline to match user selection. + * + * @param obj is the main structure for bpf objects. + * @param sel option selected by user. + */ +static inline void ebpf_socket_disable_specific_trampoline(struct socket_bpf *obj, netdata_run_mode_t sel) +{ + if (sel == MODE_RETURN) { + bpf_program__set_autoload(obj->progs.netdata_tcp_sendmsg_fentry, false); + bpf_program__set_autoload(obj->progs.netdata_udp_sendmsg_fentry, false); + } else { + bpf_program__set_autoload(obj->progs.netdata_tcp_sendmsg_fexit, false); + bpf_program__set_autoload(obj->progs.netdata_udp_sendmsg_fexit, false); + } +} + +/** + * Disable specific probe + * + * Disable specific probe to match user selection. + * + * @param obj is the main structure for bpf objects. + * @param sel option selected by user. + */ +static inline void ebpf_socket_disable_specific_probe(struct socket_bpf *obj, netdata_run_mode_t sel) +{ + if (sel == MODE_RETURN) { + bpf_program__set_autoload(obj->progs.netdata_tcp_sendmsg_kprobe, false); + bpf_program__set_autoload(obj->progs.netdata_udp_sendmsg_kprobe, false); + } else { + bpf_program__set_autoload(obj->progs.netdata_tcp_sendmsg_kretprobe, false); + bpf_program__set_autoload(obj->progs.netdata_udp_sendmsg_kretprobe, false); + } +} + +/** + * Attach probes + * + * Attach probes to targets. + * + * @param obj is the main structure for bpf objects. + * @param sel option selected by user. + */ +static int ebpf_socket_attach_probes(struct socket_bpf *obj, netdata_run_mode_t sel) +{ + obj->links.netdata_inet_csk_accept_kretprobe = bpf_program__attach_kprobe(obj->progs.netdata_inet_csk_accept_kretprobe, + true, + socket_targets[NETDATA_FCNT_INET_CSK_ACCEPT].name); + int ret = libbpf_get_error(obj->links.netdata_inet_csk_accept_kretprobe); + if (ret) + return -1; + + obj->links.netdata_tcp_v4_connect_kretprobe = bpf_program__attach_kprobe(obj->progs.netdata_tcp_v4_connect_kretprobe, + true, + socket_targets[NETDATA_FCNT_TCP_V4_CONNECT].name); + ret = libbpf_get_error(obj->links.netdata_tcp_v4_connect_kretprobe); + if (ret) + return -1; + + obj->links.netdata_tcp_v6_connect_kretprobe = bpf_program__attach_kprobe(obj->progs.netdata_tcp_v6_connect_kretprobe, + true, + socket_targets[NETDATA_FCNT_TCP_V6_CONNECT].name); + ret = libbpf_get_error(obj->links.netdata_tcp_v6_connect_kretprobe); + if (ret) + return -1; + + obj->links.netdata_tcp_retransmit_skb_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_tcp_retransmit_skb_kprobe, + false, + socket_targets[NETDATA_FCNT_TCP_RETRANSMIT].name); + ret = libbpf_get_error(obj->links.netdata_tcp_retransmit_skb_kprobe); + if (ret) + return -1; + + obj->links.netdata_tcp_cleanup_rbuf_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_tcp_cleanup_rbuf_kprobe, + false, + socket_targets[NETDATA_FCNT_CLEANUP_RBUF].name); + ret = libbpf_get_error(obj->links.netdata_tcp_cleanup_rbuf_kprobe); + if (ret) + return -1; + + obj->links.netdata_tcp_close_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_tcp_close_kprobe, + false, + socket_targets[NETDATA_FCNT_TCP_CLOSE].name); + ret = libbpf_get_error(obj->links.netdata_tcp_close_kprobe); + if (ret) + return -1; + + obj->links.netdata_udp_recvmsg_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_udp_recvmsg_kprobe, + false, + socket_targets[NETDATA_FCNT_UDP_RECEVMSG].name); + ret = libbpf_get_error(obj->links.netdata_udp_recvmsg_kprobe); + if (ret) + return -1; + + obj->links.netdata_udp_recvmsg_kretprobe = bpf_program__attach_kprobe(obj->progs.netdata_udp_recvmsg_kretprobe, + true, + socket_targets[NETDATA_FCNT_UDP_RECEVMSG].name); + ret = libbpf_get_error(obj->links.netdata_udp_recvmsg_kretprobe); + if (ret) + return -1; + + if (sel == MODE_RETURN) { + obj->links.netdata_tcp_sendmsg_kretprobe = bpf_program__attach_kprobe(obj->progs.netdata_tcp_sendmsg_kretprobe, + true, + socket_targets[NETDATA_FCNT_TCP_SENDMSG].name); + ret = libbpf_get_error(obj->links.netdata_tcp_sendmsg_kretprobe); + if (ret) + return -1; + + obj->links.netdata_udp_sendmsg_kretprobe = bpf_program__attach_kprobe(obj->progs.netdata_udp_sendmsg_kretprobe, + true, + socket_targets[NETDATA_FCNT_UDP_SENDMSG].name); + ret = libbpf_get_error(obj->links.netdata_udp_sendmsg_kretprobe); + if (ret) + return -1; + } else { + obj->links.netdata_tcp_sendmsg_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_tcp_sendmsg_kprobe, + false, + socket_targets[NETDATA_FCNT_TCP_SENDMSG].name); + ret = libbpf_get_error(obj->links.netdata_tcp_sendmsg_kprobe); + if (ret) + return -1; + + obj->links.netdata_udp_sendmsg_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_udp_sendmsg_kprobe, + false, + socket_targets[NETDATA_FCNT_UDP_SENDMSG].name); + ret = libbpf_get_error(obj->links.netdata_udp_sendmsg_kprobe); + if (ret) + return -1; + } + + obj->links.netdata_socket_release_task_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_socket_release_task_kprobe, + false, EBPF_COMMON_FNCT_CLEAN_UP); + ret = libbpf_get_error(obj->links.netdata_socket_release_task_kprobe); + if (ret) + return -1; + + return 0; +} + +/** + * Set hash tables + * + * Set the values for maps according the value given by kernel. + * + * @param obj is the main structure for bpf objects. + */ +static void ebpf_socket_set_hash_tables(struct socket_bpf *obj) +{ + socket_maps[NETDATA_SOCKET_TABLE_BANDWIDTH].map_fd = bpf_map__fd(obj->maps.tbl_bandwidth); + socket_maps[NETDATA_SOCKET_GLOBAL].map_fd = bpf_map__fd(obj->maps.tbl_global_sock); + socket_maps[NETDATA_SOCKET_LPORTS].map_fd = bpf_map__fd(obj->maps.tbl_lports); + socket_maps[NETDATA_SOCKET_TABLE_IPV4].map_fd = bpf_map__fd(obj->maps.tbl_conn_ipv4); + socket_maps[NETDATA_SOCKET_TABLE_IPV6].map_fd = bpf_map__fd(obj->maps.tbl_conn_ipv6); + socket_maps[NETDATA_SOCKET_TABLE_UDP].map_fd = bpf_map__fd(obj->maps.tbl_nv_udp); + socket_maps[NETDATA_SOCKET_TABLE_CTRL].map_fd = bpf_map__fd(obj->maps.socket_ctrl); +} + +/** + * Adjust Map Size + * + * Resize maps according input from users. + * + * @param obj is the main structure for bpf objects. + * @param em structure with configuration + */ +static void ebpf_socket_adjust_map_size(struct socket_bpf *obj, ebpf_module_t *em) +{ + ebpf_update_map_size(obj->maps.tbl_bandwidth, &socket_maps[NETDATA_SOCKET_TABLE_BANDWIDTH], + em, bpf_map__name(obj->maps.tbl_bandwidth)); + + ebpf_update_map_size(obj->maps.tbl_conn_ipv4, &socket_maps[NETDATA_SOCKET_TABLE_IPV4], + em, bpf_map__name(obj->maps.tbl_conn_ipv4)); + + ebpf_update_map_size(obj->maps.tbl_conn_ipv6, &socket_maps[NETDATA_SOCKET_TABLE_IPV6], + em, bpf_map__name(obj->maps.tbl_conn_ipv6)); + + ebpf_update_map_size(obj->maps.tbl_nv_udp, &socket_maps[NETDATA_SOCKET_TABLE_UDP], + em, bpf_map__name(obj->maps.tbl_nv_udp)); +} + +/** + * Load and attach + * + * Load and attach the eBPF code in kernel. + * + * @param obj is the main structure for bpf objects. + * @param em structure with configuration + * + * @return it returns 0 on succes and -1 otherwise + */ +static inline int ebpf_socket_load_and_attach(struct socket_bpf *obj, ebpf_module_t *em) +{ + netdata_ebpf_targets_t *mt = em->targets; + netdata_ebpf_program_loaded_t test = mt[NETDATA_FCNT_INET_CSK_ACCEPT].mode; + + if (test == EBPF_LOAD_TRAMPOLINE) { + ebpf_socket_disable_probes(obj); + + ebpf_set_trampoline_target(obj); + ebpf_socket_disable_specific_trampoline(obj, em->mode); + } else { // We are not using tracepoints for this thread. + ebpf_socket_disable_trampoline(obj); + + ebpf_socket_disable_specific_probe(obj, em->mode); + } + + int ret = socket_bpf__load(obj); + if (ret) { + fprintf(stderr, "failed to load BPF object: %d\n", ret); + return ret; + } + + ebpf_socket_adjust_map_size(obj, em); + + if (test == EBPF_LOAD_TRAMPOLINE) { + ret = socket_bpf__attach(obj); + } else { + ret = ebpf_socket_attach_probes(obj, em->mode); + } + + if (!ret) { + ebpf_socket_set_hash_tables(obj); + + ebpf_update_controller(socket_maps[NETDATA_SOCKET_TABLE_CTRL].map_fd, em); + } + + return ret; +} +#endif /***************************************************************** * * PROCESS DATA AND SEND TO NETDATA @@ -293,6 +640,31 @@ static void ebpf_socket_send_nv_data(netdata_vector_plot_t *ptr) } } +/** + * Send Global Inbound connection + * + * Send number of connections read per protocol. + */ +static void ebpf_socket_send_global_inbound_conn() +{ + uint64_t udp_conn = 0; + uint64_t tcp_conn = 0; + ebpf_network_viewer_port_list_t *move = listen_ports; + while (move) { + if (move->protocol == IPPROTO_TCP) + tcp_conn += move->connections; + else + udp_conn += move->connections; + + move = move->next; + } + + write_begin_chart(NETDATA_EBPF_IP_FAMILY, NETDATA_INBOUND_CONNECTIONS); + write_chart_dimension(socket_publish_aggregated[NETDATA_IDX_INCOMING_CONNECTION_TCP].name, (long long) tcp_conn); + write_chart_dimension(socket_publish_aggregated[NETDATA_IDX_INCOMING_CONNECTION_UDP].name, (long long) udp_conn); + write_end_chart(); +} + /** * Send data to Netdata calling auxiliary functions. * @@ -304,6 +676,10 @@ static void ebpf_socket_send_data(ebpf_module_t *em) netdata_publish_vfs_common_t common_udp; ebpf_update_global_publish(socket_publish_aggregated, &common_tcp, &common_udp, socket_aggregated_data); + ebpf_socket_send_global_inbound_conn(); + write_count_chart(NETDATA_TCP_OUTBOUND_CONNECTIONS, NETDATA_EBPF_IP_FAMILY, + &socket_publish_aggregated[NETDATA_IDX_TCP_CONNECTION_V4], 2); + // We read bytes from function arguments, but bandwidth is given in bits, // so we need to multiply by 8 to convert for the final value. write_count_chart(NETDATA_TCP_FUNCTION_COUNT, NETDATA_EBPF_IP_FAMILY, socket_publish_aggregated, 3); @@ -367,6 +743,26 @@ void ebpf_socket_send_apps_data(ebpf_module_t *em, struct target *root) struct target *w; collected_number value; + write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_NET_APPS_CONNECTION_TCP_V4); + for (w = root; w; w = w->next) { + if (unlikely(w->exposed && w->processes)) { + value = ebpf_socket_sum_values_for_pids(w->root_pid, offsetof(ebpf_socket_publish_apps_t, + call_tcp_v4_connection)); + write_chart_dimension(w->name, value); + } + } + write_end_chart(); + + write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_NET_APPS_CONNECTION_TCP_V6); + for (w = root; w; w = w->next) { + if (unlikely(w->exposed && w->processes)) { + value = ebpf_socket_sum_values_for_pids(w->root_pid, offsetof(ebpf_socket_publish_apps_t, + call_tcp_v6_connection)); + write_chart_dimension(w->name, value); + } + } + write_end_chart(); + write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_NET_APPS_BANDWIDTH_SENT); for (w = root; w; w = w->next) { if (unlikely(w->exposed && w->processes)) { @@ -456,6 +852,32 @@ void ebpf_socket_send_apps_data(ebpf_module_t *em, struct target *root) */ static void ebpf_create_global_charts(ebpf_module_t *em) { + int order = 21070; + ebpf_create_chart(NETDATA_EBPF_IP_FAMILY, + NETDATA_INBOUND_CONNECTIONS, + "Inbound connections.", + EBPF_COMMON_DIMENSION_CONNECTIONS, + NETDATA_SOCKET_KERNEL_FUNCTIONS, + NULL, + NETDATA_EBPF_CHART_TYPE_LINE, + order++, + ebpf_create_global_dimension, + &socket_publish_aggregated[NETDATA_IDX_INCOMING_CONNECTION_TCP], + 2, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); + + ebpf_create_chart(NETDATA_EBPF_IP_FAMILY, + NETDATA_TCP_OUTBOUND_CONNECTIONS, + "TCP outbound connections.", + EBPF_COMMON_DIMENSION_CONNECTIONS, + NETDATA_SOCKET_KERNEL_FUNCTIONS, + NULL, + NETDATA_EBPF_CHART_TYPE_LINE, + order++, + ebpf_create_global_dimension, + &socket_publish_aggregated[NETDATA_IDX_TCP_CONNECTION_V4], + 2, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); + + ebpf_create_chart(NETDATA_EBPF_IP_FAMILY, NETDATA_TCP_FUNCTION_COUNT, "Calls to internal functions", @@ -463,7 +885,7 @@ static void ebpf_create_global_charts(ebpf_module_t *em) NETDATA_SOCKET_KERNEL_FUNCTIONS, NULL, NETDATA_EBPF_CHART_TYPE_LINE, - 21070, + order++, ebpf_create_global_dimension, socket_publish_aggregated, 3, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); @@ -473,7 +895,7 @@ static void ebpf_create_global_charts(ebpf_module_t *em) NETDATA_SOCKET_KERNEL_FUNCTIONS, NULL, NETDATA_EBPF_CHART_TYPE_LINE, - 21071, + order++, ebpf_create_global_dimension, socket_publish_aggregated, 2, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); @@ -486,7 +908,7 @@ static void ebpf_create_global_charts(ebpf_module_t *em) NETDATA_SOCKET_KERNEL_FUNCTIONS, NULL, NETDATA_EBPF_CHART_TYPE_LINE, - 21072, + order++, ebpf_create_global_dimension, socket_publish_aggregated, 2, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); @@ -499,7 +921,7 @@ static void ebpf_create_global_charts(ebpf_module_t *em) NETDATA_SOCKET_KERNEL_FUNCTIONS, NULL, NETDATA_EBPF_CHART_TYPE_LINE, - 21073, + order++, ebpf_create_global_dimension, &socket_publish_aggregated[NETDATA_IDX_TCP_RETRANSMIT], 1, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); @@ -511,7 +933,7 @@ static void ebpf_create_global_charts(ebpf_module_t *em) NETDATA_SOCKET_KERNEL_FUNCTIONS, NULL, NETDATA_EBPF_CHART_TYPE_LINE, - 21074, + order++, ebpf_create_global_dimension, &socket_publish_aggregated[NETDATA_IDX_UDP_RECVBUF], 2, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); @@ -521,7 +943,7 @@ static void ebpf_create_global_charts(ebpf_module_t *em) NETDATA_SOCKET_KERNEL_FUNCTIONS, NULL, NETDATA_EBPF_CHART_TYPE_LINE, - 21075, + order++, ebpf_create_global_dimension, &socket_publish_aggregated[NETDATA_IDX_UDP_RECVBUF], 2, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); @@ -534,7 +956,7 @@ static void ebpf_create_global_charts(ebpf_module_t *em) NETDATA_SOCKET_KERNEL_FUNCTIONS, NULL, NETDATA_EBPF_CHART_TYPE_LINE, - 21076, + order++, ebpf_create_global_dimension, &socket_publish_aggregated[NETDATA_IDX_UDP_RECVBUF], 2, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); @@ -551,12 +973,29 @@ static void ebpf_create_global_charts(ebpf_module_t *em) */ void ebpf_socket_create_apps_charts(struct ebpf_module *em, void *ptr) { - struct target *root = ptr;; + struct target *root = ptr; + int order = 20080; + ebpf_create_charts_on_apps(NETDATA_NET_APPS_CONNECTION_TCP_V4, + "Calls to tcp_v4_connection", EBPF_COMMON_DIMENSION_CONNECTIONS, + NETDATA_APPS_NET_GROUP, + NETDATA_EBPF_CHART_TYPE_STACKED, + order++, + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], + root, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); + + ebpf_create_charts_on_apps(NETDATA_NET_APPS_CONNECTION_TCP_V6, + "Calls to tcp_v6_connection", EBPF_COMMON_DIMENSION_CONNECTIONS, + NETDATA_APPS_NET_GROUP, + NETDATA_EBPF_CHART_TYPE_STACKED, + order++, + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], + root, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); + ebpf_create_charts_on_apps(NETDATA_NET_APPS_BANDWIDTH_SENT, "Bytes sent", EBPF_COMMON_DIMENSION_BITS, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_STACKED, - 20080, + order++, ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], root, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); @@ -564,7 +1003,7 @@ void ebpf_socket_create_apps_charts(struct ebpf_module *em, void *ptr) "bytes received", EBPF_COMMON_DIMENSION_BITS, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_STACKED, - 20081, + order++, ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], root, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); @@ -573,7 +1012,7 @@ void ebpf_socket_create_apps_charts(struct ebpf_module *em, void *ptr) EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_STACKED, - 20082, + order++, ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], root, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); @@ -582,7 +1021,7 @@ void ebpf_socket_create_apps_charts(struct ebpf_module *em, void *ptr) EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_STACKED, - 20083, + order++, ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], root, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); @@ -591,7 +1030,7 @@ void ebpf_socket_create_apps_charts(struct ebpf_module *em, void *ptr) EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_STACKED, - 20084, + order++, ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], root, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); @@ -600,7 +1039,7 @@ void ebpf_socket_create_apps_charts(struct ebpf_module *em, void *ptr) EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_STACKED, - 20085, + order++, ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], root, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); @@ -609,7 +1048,7 @@ void ebpf_socket_create_apps_charts(struct ebpf_module *em, void *ptr) EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_STACKED, - 20086, + order++, ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], root, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); @@ -1295,11 +1734,10 @@ netdata_vector_plot_t * select_vector_to_store(uint32_t *direction, netdata_sock * * @param values the values used to calculate the data. * @param key the key to store data. - * @param removesock check if this socket must be removed . * @param family the connection family * @param end the values size. */ -static void hash_accumulator(netdata_socket_t *values, netdata_socket_idx_t *key, int *removesock, int family, int end) +static void hash_accumulator(netdata_socket_t *values, netdata_socket_idx_t *key, int family, int end) { uint64_t bsent = 0, brecv = 0, psent = 0, precv = 0; uint16_t retransmit = 0; @@ -1320,8 +1758,6 @@ static void hash_accumulator(netdata_socket_t *values, netdata_socket_idx_t *key if (w->ct > ct) ct = w->ct; - - *removesock += (int)w->removeme; } values[0].recv_packets += precv; @@ -1329,7 +1765,6 @@ static void hash_accumulator(netdata_socket_t *values, netdata_socket_idx_t *key values[0].recv_bytes += brecv; values[0].sent_bytes += bsent; values[0].retransmit += retransmit; - values[0].removeme += (uint8_t)*removesock; values[0].protocol = (!protocol)?IPPROTO_TCP:protocol; values[0].ct = ct; @@ -1357,8 +1792,6 @@ static void read_socket_hash_table(int fd, int family, int network_connection) netdata_socket_idx_t key = {}; netdata_socket_idx_t next_key = {}; - netdata_socket_idx_t removeme; - int removesock = 0; netdata_socket_t *values = socket_values; size_t length = ebpf_nprocs*sizeof(netdata_socket_t); @@ -1375,35 +1808,41 @@ static void read_socket_hash_table(int fd, int family, int network_connection) continue; } - if (removesock) - bpf_map_delete_elem(fd, &removeme); - if (network_connection) { - removesock = 0; - hash_accumulator(values, &key, &removesock, family, end); + hash_accumulator(values, &key, family, end); } - if (removesock) - removeme = key; - key = next_key; } - if (removesock) - bpf_map_delete_elem(fd, &removeme); - test = bpf_map_lookup_elem(fd, &next_key, values); if (test < 0) { return; } if (network_connection) { - removesock = 0; - hash_accumulator(values, &next_key, &removesock, family, end); + hash_accumulator(values, &next_key, family, end); } +} - if (removesock) - bpf_map_delete_elem(fd, &next_key); +/** + * Fill Network Viewer Port list + * + * Fill the strcture with values read from /proc or hash table. + * + * @param out the structure where we will store data. + * @param value the ports we are listen to. + * @param proto the protocol used for this connection. + * @param in the strcuture with values read form different sources. + */ +static inline void fill_nv_port_list(ebpf_network_viewer_port_list_t *out, uint16_t value, uint16_t proto, + netdata_passive_connection_t *in) +{ + out->first = value; + out->protocol = proto; + out->pid = in->pid; + out->tgid = in->tgid; + out->connections = in->counter; } /** @@ -1413,31 +1852,33 @@ static void read_socket_hash_table(int fd, int family, int network_connection) * * @param value the ports we are listen to. * @param proto the protocol used with port connection. + * @param in the strcuture with values read form different sources. */ -void update_listen_table(uint16_t value, uint8_t proto) +void update_listen_table(uint16_t value, uint16_t proto, netdata_passive_connection_t *in) { ebpf_network_viewer_port_list_t *w; if (likely(listen_ports)) { ebpf_network_viewer_port_list_t *move = listen_ports, *store = listen_ports; while (move) { - if (move->protocol == proto && move->first == value) + if (move->protocol == proto && move->first == value) { + move->pid = in->pid; + move->tgid = in->tgid; + move->connections = in->counter; return; + } store = move; move = move->next; } w = callocz(1, sizeof(ebpf_network_viewer_port_list_t)); - w->first = value; - w->protocol = proto; store->next = w; } else { w = callocz(1, sizeof(ebpf_network_viewer_port_list_t)); - w->first = value; - w->protocol = proto; listen_ports = w; } + fill_nv_port_list(w, value, proto, in); #ifdef NETDATA_INTERNAL_CHECKS info("The network viewer is monitoring inbound connections for port %u", ntohs(value)); @@ -1451,11 +1892,11 @@ void update_listen_table(uint16_t value, uint8_t proto) */ static void read_listen_table() { - uint16_t key = 0; - uint16_t next_key = 0; + netdata_passive_connection_idx_t key = {}; + netdata_passive_connection_idx_t next_key = {}; int fd = socket_maps[NETDATA_SOCKET_LPORTS].map_fd; - uint8_t value; + netdata_passive_connection_t value = {}; while (bpf_map_get_next_key(fd, &key, &next_key) == 0) { int test = bpf_map_lookup_elem(fd, &key, &value); if (test < 0) { @@ -1464,14 +1905,15 @@ static void read_listen_table() } // The correct protocol must come from kernel - update_listen_table(htons(key), (key == 53)?IPPROTO_UDP:IPPROTO_TCP); + update_listen_table(key.port, key.protocol, &value); key = next_key; + memset(&value, 0, sizeof(value)); } - if (next_key) { + if (next_key.port && value.pid) { // The correct protocol must come from kernel - update_listen_table(htons(next_key), (key == 53)?IPPROTO_UDP:IPPROTO_TCP); + update_listen_table(next_key.port, next_key.protocol, &value); } } @@ -1542,11 +1984,15 @@ static void read_hash_global_tables() socket_aggregated_data[NETDATA_IDX_UDP_RECVBUF].call = res[NETDATA_KEY_CALLS_UDP_RECVMSG]; socket_aggregated_data[NETDATA_IDX_UDP_SENDMSG].call = res[NETDATA_KEY_CALLS_UDP_SENDMSG]; socket_aggregated_data[NETDATA_IDX_TCP_RETRANSMIT].call = res[NETDATA_KEY_TCP_RETRANSMIT]; + socket_aggregated_data[NETDATA_IDX_TCP_CONNECTION_V4].call = res[NETDATA_KEY_CALLS_TCP_CONNECT_IPV4]; + socket_aggregated_data[NETDATA_IDX_TCP_CONNECTION_V6].call = res[NETDATA_KEY_CALLS_TCP_CONNECT_IPV6]; socket_aggregated_data[NETDATA_IDX_TCP_SENDMSG].ecall = res[NETDATA_KEY_ERROR_TCP_SENDMSG]; socket_aggregated_data[NETDATA_IDX_TCP_CLEANUP_RBUF].ecall = res[NETDATA_KEY_ERROR_TCP_CLEANUP_RBUF]; socket_aggregated_data[NETDATA_IDX_UDP_RECVBUF].ecall = res[NETDATA_KEY_ERROR_UDP_RECVMSG]; socket_aggregated_data[NETDATA_IDX_UDP_SENDMSG].ecall = res[NETDATA_KEY_ERROR_UDP_SENDMSG]; + socket_aggregated_data[NETDATA_IDX_TCP_CONNECTION_V4].ecall = res[NETDATA_KEY_ERROR_TCP_CONNECT_IPV4]; + socket_aggregated_data[NETDATA_IDX_TCP_CONNECTION_V6].ecall = res[NETDATA_KEY_ERROR_TCP_CONNECT_IPV6]; socket_aggregated_data[NETDATA_IDX_TCP_SENDMSG].bytes = res[NETDATA_KEY_BYTES_TCP_SENDMSG]; socket_aggregated_data[NETDATA_IDX_TCP_CLEANUP_RBUF].bytes = res[NETDATA_KEY_BYTES_TCP_CLEANUP_RBUF]; @@ -1575,6 +2021,9 @@ void ebpf_socket_fill_publish_apps(uint32_t current_pid, ebpf_bandwidth_t *eb) curr->retransmit = eb->retransmit; curr->call_udp_sent = eb->call_udp_sent; curr->call_udp_received = eb->call_udp_received; + curr->call_close = eb->close; + curr->call_tcp_v4_connection = eb->tcp_v4_connection; + curr->call_tcp_v6_connection = eb->tcp_v6_connection; } /** @@ -1595,6 +2044,9 @@ void ebpf_socket_bandwidth_accumulator(ebpf_bandwidth_t *out) total->retransmit += move->retransmit; total->call_udp_sent += move->call_udp_sent; total->call_udp_received += move->call_udp_received; + total->close += move->close; + total->tcp_v4_connection += move->tcp_v4_connection; + total->tcp_v6_connection += move->tcp_v6_connection; } } @@ -1652,6 +2104,9 @@ static void ebpf_update_socket_cgroup() publish->retransmit = in->retransmit; publish->call_udp_sent = in->call_udp_sent; publish->call_udp_received = in->call_udp_received; + publish->call_close = in->call_close; + publish->call_tcp_v4_connection = in->call_tcp_v4_connection; + publish->call_tcp_v6_connection = in->call_tcp_v6_connection; } else { if (!bpf_map_lookup_elem(fd, &pid, eb)) { ebpf_socket_bandwidth_accumulator(eb); @@ -1665,6 +2120,9 @@ static void ebpf_update_socket_cgroup() publish->retransmit = out->retransmit; publish->call_udp_sent = out->call_udp_sent; publish->call_udp_received = out->call_udp_received; + publish->call_close = out->close; + publish->call_tcp_v4_connection = out->tcp_v4_connection; + publish->call_tcp_v6_connection = out->tcp_v6_connection; } } } @@ -1695,6 +2153,9 @@ static void ebpf_socket_sum_cgroup_pids(ebpf_socket_publish_apps_t *socket, stru accumulator.retransmit += w->retransmit; accumulator.call_udp_received += w->call_udp_received; accumulator.call_udp_sent += w->call_udp_sent; + accumulator.call_close += w->close; + accumulator.call_tcp_v4_connection += w->tcp_v4_connection; + accumulator.call_tcp_v6_connection += w->tcp_v6_connection; pids = pids->next; } @@ -1706,6 +2167,11 @@ static void ebpf_socket_sum_cgroup_pids(ebpf_socket_publish_apps_t *socket, stru socket->retransmit = (accumulator.retransmit >= socket->retransmit) ? accumulator.retransmit : socket->retransmit; socket->call_udp_sent = (accumulator.call_udp_sent >= socket->call_udp_sent) ? accumulator.call_udp_sent : socket->call_udp_sent; socket->call_udp_received = (accumulator.call_udp_received >= socket->call_udp_received) ? accumulator.call_udp_received : socket->call_udp_received; + socket->call_close = (accumulator.call_close >= socket->call_close) ? accumulator.call_close : socket->call_close; + socket->call_tcp_v4_connection = (accumulator.call_tcp_v4_connection >= socket->call_tcp_v4_connection) ? + accumulator.call_tcp_v4_connection : socket->call_tcp_v4_connection; + socket->call_tcp_v6_connection = (accumulator.call_tcp_v6_connection >= socket->call_tcp_v6_connection) ? + accumulator.call_tcp_v6_connection : socket->call_tcp_v6_connection; } /** @@ -1718,75 +2184,96 @@ static void ebpf_socket_sum_cgroup_pids(ebpf_socket_publish_apps_t *socket, stru */ static void ebpf_create_specific_socket_charts(char *type, int update_every) { + int order_basis = 5300; + ebpf_create_chart(type, NETDATA_NET_APPS_CONNECTION_TCP_V4, + "Calls to tcp_v4_connection", + EBPF_COMMON_DIMENSION_CONNECTIONS, NETDATA_CGROUP_NET_GROUP, + NETDATA_CGROUP_TCP_V4_CONN_CONTEXT, + NETDATA_EBPF_CHART_TYPE_LINE, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, + ebpf_create_global_dimension, + &socket_publish_aggregated[NETDATA_IDX_TCP_CONNECTION_V4], 1, + update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); + + ebpf_create_chart(type, NETDATA_NET_APPS_CONNECTION_TCP_V6, + "Calls to tcp_v6_connection", + EBPF_COMMON_DIMENSION_CONNECTIONS, NETDATA_CGROUP_NET_GROUP, + NETDATA_CGROUP_TCP_V6_CONN_CONTEXT, + NETDATA_EBPF_CHART_TYPE_LINE, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, + ebpf_create_global_dimension, + &socket_publish_aggregated[NETDATA_IDX_TCP_CONNECTION_V6], 1, + update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); + ebpf_create_chart(type, NETDATA_NET_APPS_BANDWIDTH_RECV, "Bytes received", EBPF_COMMON_DIMENSION_CALL, NETDATA_CGROUP_NET_GROUP, NETDATA_CGROUP_SOCKET_BYTES_RECV_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, - NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5300, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, ebpf_create_global_dimension, &socket_publish_aggregated[NETDATA_IDX_TCP_CLEANUP_RBUF], 1, - update_every, NETDATA_EBPF_MODULE_NAME_SWAP); + update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); ebpf_create_chart(type, NETDATA_NET_APPS_BANDWIDTH_SENT, "Bytes sent", EBPF_COMMON_DIMENSION_CALL, NETDATA_CGROUP_NET_GROUP, NETDATA_CGROUP_SOCKET_BYTES_SEND_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, - NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5301, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, ebpf_create_global_dimension, socket_publish_aggregated, 1, - update_every, NETDATA_EBPF_MODULE_NAME_SWAP); + update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); ebpf_create_chart(type, NETDATA_NET_APPS_BANDWIDTH_TCP_RECV_CALLS, "Calls to tcp_cleanup_rbuf.", EBPF_COMMON_DIMENSION_CALL, NETDATA_CGROUP_NET_GROUP, NETDATA_CGROUP_SOCKET_TCP_RECV_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, - NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5302, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, ebpf_create_global_dimension, &socket_publish_aggregated[NETDATA_IDX_TCP_CLEANUP_RBUF], 1, - update_every, NETDATA_EBPF_MODULE_NAME_SWAP); + update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); ebpf_create_chart(type, NETDATA_NET_APPS_BANDWIDTH_TCP_SEND_CALLS, "Calls to tcp_sendmsg.", EBPF_COMMON_DIMENSION_CALL, NETDATA_CGROUP_NET_GROUP, NETDATA_CGROUP_SOCKET_TCP_SEND_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, - NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5303, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, ebpf_create_global_dimension, socket_publish_aggregated, 1, - update_every, NETDATA_EBPF_MODULE_NAME_SWAP); + update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); ebpf_create_chart(type, NETDATA_NET_APPS_BANDWIDTH_TCP_RETRANSMIT, "Calls to tcp_retransmit.", EBPF_COMMON_DIMENSION_CALL, NETDATA_CGROUP_NET_GROUP, NETDATA_CGROUP_SOCKET_TCP_RETRANSMIT_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, - NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5304, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, ebpf_create_global_dimension, &socket_publish_aggregated[NETDATA_IDX_TCP_RETRANSMIT], 1, - update_every, NETDATA_EBPF_MODULE_NAME_SWAP); + update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); ebpf_create_chart(type, NETDATA_NET_APPS_BANDWIDTH_UDP_SEND_CALLS, "Calls to udp_sendmsg", EBPF_COMMON_DIMENSION_CALL, NETDATA_CGROUP_NET_GROUP, NETDATA_CGROUP_SOCKET_UDP_SEND_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, - NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5305, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, ebpf_create_global_dimension, &socket_publish_aggregated[NETDATA_IDX_UDP_SENDMSG], 1, - update_every, NETDATA_EBPF_MODULE_NAME_SWAP); + update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); ebpf_create_chart(type, NETDATA_NET_APPS_BANDWIDTH_UDP_RECV_CALLS, "Calls to udp_recvmsg", EBPF_COMMON_DIMENSION_CALL, NETDATA_CGROUP_NET_GROUP, NETDATA_CGROUP_SOCKET_UDP_RECV_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, - NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5306, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, ebpf_create_global_dimension, &socket_publish_aggregated[NETDATA_IDX_UDP_RECVBUF], 1, - update_every, NETDATA_EBPF_MODULE_NAME_SWAP); + update_every, NETDATA_EBPF_MODULE_NAME_SOCKET); } /** @@ -1799,40 +2286,51 @@ static void ebpf_create_specific_socket_charts(char *type, int update_every) */ static void ebpf_obsolete_specific_socket_charts(char *type, int update_every) { + int order_basis = 5300; + ebpf_write_chart_obsolete(type, NETDATA_NET_APPS_CONNECTION_TCP_V4, "Calls to tcp_v4_connection", + EBPF_COMMON_DIMENSION_CONNECTIONS, NETDATA_APPS_NET_GROUP, + NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_SERVICES_SOCKET_TCP_V4_CONN_CONTEXT, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, update_every); + + ebpf_write_chart_obsolete(type, NETDATA_NET_APPS_CONNECTION_TCP_V6,"Calls to tcp_v6_connection", + EBPF_COMMON_DIMENSION_CONNECTIONS, NETDATA_APPS_NET_GROUP, + NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_SERVICES_SOCKET_TCP_V6_CONN_CONTEXT, + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, update_every); + ebpf_write_chart_obsolete(type, NETDATA_NET_APPS_BANDWIDTH_RECV, "Bytes received", EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_SERVICES_SOCKET_BYTES_RECV_CONTEXT, - NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5300, update_every); + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, update_every); ebpf_write_chart_obsolete(type, NETDATA_NET_APPS_BANDWIDTH_SENT,"Bytes sent", EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_SERVICES_SOCKET_BYTES_SEND_CONTEXT, - NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5301, update_every); + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, update_every); ebpf_write_chart_obsolete(type, NETDATA_NET_APPS_BANDWIDTH_TCP_RECV_CALLS, "Calls to tcp_cleanup_rbuf.", EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_SERVICES_SOCKET_TCP_RECV_CONTEXT, - NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5302, update_every); + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, update_every); ebpf_write_chart_obsolete(type, NETDATA_NET_APPS_BANDWIDTH_TCP_SEND_CALLS, "Calls to tcp_sendmsg.", EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_SERVICES_SOCKET_TCP_SEND_CONTEXT, - NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5303, update_every); + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, update_every); ebpf_write_chart_obsolete(type, NETDATA_NET_APPS_BANDWIDTH_TCP_RETRANSMIT, "Calls to tcp_retransmit.", EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_SERVICES_SOCKET_TCP_RETRANSMIT_CONTEXT, - NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5304, update_every); + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, update_every); ebpf_write_chart_obsolete(type, NETDATA_NET_APPS_BANDWIDTH_UDP_SEND_CALLS, "Calls to udp_sendmsg", EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_SERVICES_SOCKET_UDP_SEND_CONTEXT, - NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5305, update_every); + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, update_every); ebpf_write_chart_obsolete(type, NETDATA_NET_APPS_BANDWIDTH_UDP_RECV_CALLS, "Calls to udp_recvmsg", EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_SERVICES_SOCKET_UDP_RECV_CONTEXT, - NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5306, update_every); + NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, update_every); } /* @@ -1845,6 +2343,16 @@ static void ebpf_obsolete_specific_socket_charts(char *type, int update_every) */ static void ebpf_send_specific_socket_data(char *type, ebpf_socket_publish_apps_t *values) { + write_begin_chart(type, NETDATA_NET_APPS_CONNECTION_TCP_V4); + write_chart_dimension(socket_publish_aggregated[NETDATA_IDX_TCP_CONNECTION_V4].name, + (long long) values->call_tcp_v4_connection); + write_end_chart(); + + write_begin_chart(type, NETDATA_NET_APPS_CONNECTION_TCP_V6); + write_chart_dimension(socket_publish_aggregated[NETDATA_IDX_TCP_CONNECTION_V6].name, + (long long) values->call_tcp_v6_connection); + write_end_chart(); + write_begin_chart(type, NETDATA_NET_APPS_BANDWIDTH_SENT); write_chart_dimension(socket_publish_aggregated[NETDATA_IDX_TCP_SENDMSG].name, (long long) values->bytes_sent); @@ -1890,11 +2398,30 @@ static void ebpf_send_specific_socket_data(char *type, ebpf_socket_publish_apps_ **/ static void ebpf_create_systemd_socket_charts(int update_every) { + int order = 20080; + ebpf_create_charts_on_systemd(NETDATA_NET_APPS_CONNECTION_TCP_V4, + "Calls to tcp_v4_connection", EBPF_COMMON_DIMENSION_CONNECTIONS, + NETDATA_APPS_NET_GROUP, + NETDATA_EBPF_CHART_TYPE_STACKED, + order++, + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], + NETDATA_SERVICES_SOCKET_TCP_V4_CONN_CONTEXT, NETDATA_EBPF_MODULE_NAME_SOCKET, + update_every); + + ebpf_create_charts_on_systemd(NETDATA_NET_APPS_CONNECTION_TCP_V6, + "Calls to tcp_v6_connection", EBPF_COMMON_DIMENSION_CONNECTIONS, + NETDATA_APPS_NET_GROUP, + NETDATA_EBPF_CHART_TYPE_STACKED, + order++, + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], + NETDATA_SERVICES_SOCKET_TCP_V6_CONN_CONTEXT, NETDATA_EBPF_MODULE_NAME_SOCKET, + update_every); + ebpf_create_charts_on_systemd(NETDATA_NET_APPS_BANDWIDTH_RECV, "Bytes received", EBPF_COMMON_DIMENSION_BITS, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_STACKED, - 20080, + order++, ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NETDATA_SERVICES_SOCKET_BYTES_RECV_CONTEXT, NETDATA_EBPF_MODULE_NAME_SOCKET, update_every); @@ -1903,7 +2430,7 @@ static void ebpf_create_systemd_socket_charts(int update_every) "Bytes sent", EBPF_COMMON_DIMENSION_BITS, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_STACKED, - 20081, + order++, ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NETDATA_SERVICES_SOCKET_BYTES_SEND_CONTEXT, NETDATA_EBPF_MODULE_NAME_SOCKET, update_every); @@ -1913,7 +2440,7 @@ static void ebpf_create_systemd_socket_charts(int update_every) EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_STACKED, - 20082, + order++, ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NETDATA_SERVICES_SOCKET_TCP_RECV_CONTEXT, NETDATA_EBPF_MODULE_NAME_SOCKET, update_every); @@ -1923,7 +2450,7 @@ static void ebpf_create_systemd_socket_charts(int update_every) EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_STACKED, - 20083, + order++, ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NETDATA_SERVICES_SOCKET_TCP_SEND_CONTEXT, NETDATA_EBPF_MODULE_NAME_SOCKET, update_every); @@ -1933,7 +2460,7 @@ static void ebpf_create_systemd_socket_charts(int update_every) EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_STACKED, - 20084, + order++, ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NETDATA_SERVICES_SOCKET_TCP_RETRANSMIT_CONTEXT, NETDATA_EBPF_MODULE_NAME_SOCKET, update_every); @@ -1943,7 +2470,7 @@ static void ebpf_create_systemd_socket_charts(int update_every) EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_STACKED, - 20085, + order++, ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NETDATA_SERVICES_SOCKET_UDP_SEND_CONTEXT, NETDATA_EBPF_MODULE_NAME_SOCKET, update_every); @@ -1953,7 +2480,7 @@ static void ebpf_create_systemd_socket_charts(int update_every) EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_STACKED, - 20086, + order++, ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NETDATA_SERVICES_SOCKET_UDP_RECV_CONTEXT, NETDATA_EBPF_MODULE_NAME_SOCKET, update_every); @@ -1971,6 +2498,24 @@ static int ebpf_send_systemd_socket_charts() { int ret = 1; ebpf_cgroup_target_t *ect; + write_begin_chart(NETDATA_SERVICE_FAMILY, NETDATA_NET_APPS_CONNECTION_TCP_V4); + for (ect = ebpf_cgroup_pids; ect ; ect = ect->next) { + if (unlikely(ect->systemd) && unlikely(ect->updated)) { + write_chart_dimension(ect->name, (long long)ect->publish_socket.call_tcp_v4_connection); + } else + ret = 0; + } + write_end_chart(); + + write_begin_chart(NETDATA_SERVICE_FAMILY, NETDATA_NET_APPS_CONNECTION_TCP_V6); + for (ect = ebpf_cgroup_pids; ect ; ect = ect->next) { + if (unlikely(ect->systemd) && unlikely(ect->updated)) { + write_chart_dimension(ect->name, (long long)ect->publish_socket.call_tcp_v6_connection); + } else + ret = 0; + } + write_end_chart(); + write_begin_chart(NETDATA_SERVICE_FAMILY, NETDATA_NET_APPS_BANDWIDTH_SENT); for (ect = ebpf_cgroup_pids; ect ; ect = ect->next) { if (unlikely(ect->systemd) && unlikely(ect->updated)) { @@ -3334,6 +3879,40 @@ void parse_table_size_options(struct config *cfg) EBPF_CONFIG_UDP_SIZE, NETDATA_MAXIMUM_UDP_CONNECTIONS_ALLOWED); } +/* + * Load BPF + * + * Load BPF files. + * + * @param em the structure with configuration + */ +static int ebpf_socket_load_bpf(ebpf_module_t *em) +{ + int ret = 0; + + if (em->load == EBPF_LOAD_LEGACY) { + probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects); + if (!probe_links) { + ret = -1; + } + } +#ifdef LIBBPF_MAJOR_VERSION + else { + bpf_obj = socket_bpf__open(); + if (!bpf_obj) + ret = -1; + else + ret = ebpf_socket_load_and_attach(bpf_obj, em); + } +#endif + + if (ret) { + error("%s %s", EBPF_DEFAULT_ERROR_MSG, em->thread_name); + } + + return ret; +} + /** * Socket thread * @@ -3375,8 +3954,10 @@ void *ebpf_socket_thread(void *ptr) if (running_on_kernel < NETDATA_EBPF_KERNEL_5_0) em->mode = MODE_ENTRY; - probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects); - if (!probe_links) { +#ifdef LIBBPF_MAJOR_VERSION + ebpf_adjust_thread_load(em, default_btf); +#endif + if (ebpf_socket_load_bpf(em)) { em->enabled = CONFIG_BOOLEAN_NO; pthread_mutex_unlock(&lock); goto endsocket; diff --git a/collectors/ebpf.plugin/ebpf_socket.h b/collectors/ebpf.plugin/ebpf_socket.h index e3c000c76..672001301 100644 --- a/collectors/ebpf.plugin/ebpf_socket.h +++ b/collectors/ebpf.plugin/ebpf_socket.h @@ -43,11 +43,27 @@ enum ebpf_socket_publish_index { NETDATA_IDX_UDP_RECVBUF, NETDATA_IDX_UDP_SENDMSG, NETDATA_IDX_TCP_RETRANSMIT, + NETDATA_IDX_TCP_CONNECTION_V4, + NETDATA_IDX_TCP_CONNECTION_V6, + NETDATA_IDX_INCOMING_CONNECTION_TCP, + NETDATA_IDX_INCOMING_CONNECTION_UDP, // Keep this as last and don't skip numbers as it is used as element counter NETDATA_MAX_SOCKET_VECTOR }; +enum socket_functions { + NETDATA_FCNT_INET_CSK_ACCEPT, + NETDATA_FCNT_TCP_RETRANSMIT, + NETDATA_FCNT_CLEANUP_RBUF, + NETDATA_FCNT_TCP_CLOSE, + NETDATA_FCNT_UDP_RECEVMSG, + NETDATA_FCNT_TCP_SENDMSG, + NETDATA_FCNT_UDP_SENDMSG, + NETDATA_FCNT_TCP_V4_CONNECT, + NETDATA_FCNT_TCP_V6_CONNECT +}; + typedef enum ebpf_socket_idx { NETDATA_KEY_CALLS_TCP_SENDMSG, NETDATA_KEY_ERROR_TCP_SENDMSG, @@ -69,6 +85,12 @@ typedef enum ebpf_socket_idx { NETDATA_KEY_TCP_RETRANSMIT, + NETDATA_KEY_CALLS_TCP_CONNECT_IPV4, + NETDATA_KEY_ERROR_TCP_CONNECT_IPV4, + + NETDATA_KEY_CALLS_TCP_CONNECT_IPV6, + NETDATA_KEY_ERROR_TCP_CONNECT_IPV6, + // Keep this as last and don't skip numbers as it is used as element counter NETDATA_SOCKET_COUNTER } ebpf_socket_index_t; @@ -78,6 +100,8 @@ typedef enum ebpf_socket_idx { #define NETDATA_CGROUP_NET_GROUP "network (eBPF)" // Global chart name +#define NETDATA_TCP_OUTBOUND_CONNECTIONS "tcp_outbound_conn" +#define NETDATA_INBOUND_CONNECTIONS "inbound_conn" #define NETDATA_TCP_FUNCTION_COUNT "tcp_functions" #define NETDATA_TCP_FUNCTION_BITS "total_tcp_bandwidth" #define NETDATA_TCP_FUNCTION_ERROR "tcp_error" @@ -87,6 +111,8 @@ typedef enum ebpf_socket_idx { #define NETDATA_UDP_FUNCTION_ERROR "udp_error" // Charts created on Apps submenu +#define NETDATA_NET_APPS_CONNECTION_TCP_V4 "outbound_conn_v4" +#define NETDATA_NET_APPS_CONNECTION_TCP_V6 "outbound_conn_v6" #define NETDATA_NET_APPS_BANDWIDTH_SENT "total_bandwidth_sent" #define NETDATA_NET_APPS_BANDWIDTH_RECV "total_bandwidth_recv" #define NETDATA_NET_APPS_BANDWIDTH_TCP_SEND_CALLS "bandwidth_tcp_send" @@ -114,6 +140,8 @@ typedef enum ebpf_socket_idx { #define NETDATA_MAXIMUM_IPV4_CIDR 32 // Contexts +#define NETDATA_CGROUP_TCP_V4_CONN_CONTEXT "cgroup.net_conn_ipv4" +#define NETDATA_CGROUP_TCP_V6_CONN_CONTEXT "cgroup.net_conn_ipv6" #define NETDATA_CGROUP_SOCKET_BYTES_RECV_CONTEXT "cgroup.net_bytes_recv" #define NETDATA_CGROUP_SOCKET_BYTES_SEND_CONTEXT "cgroup.net_bytes_send" #define NETDATA_CGROUP_SOCKET_TCP_RECV_CONTEXT "cgroup.net_tcp_recv" @@ -122,6 +150,8 @@ typedef enum ebpf_socket_idx { #define NETDATA_CGROUP_SOCKET_UDP_RECV_CONTEXT "cgroup.net_udp_recv" #define NETDATA_CGROUP_SOCKET_UDP_SEND_CONTEXT "cgroup.net_udp_send" +#define NETDATA_SERVICES_SOCKET_TCP_V4_CONN_CONTEXT "services.net_conn_ipv4" +#define NETDATA_SERVICES_SOCKET_TCP_V6_CONN_CONTEXT "services.net_conn_ipv6" #define NETDATA_SERVICES_SOCKET_BYTES_RECV_CONTEXT "services.net_bytes_recv" #define NETDATA_SERVICES_SOCKET_BYTES_SEND_CONTEXT "services.net_bytes_send" #define NETDATA_SERVICES_SOCKET_TCP_RECV_CONTEXT "services.net_tcp_recv" @@ -132,22 +162,16 @@ typedef enum ebpf_socket_idx { typedef struct ebpf_socket_publish_apps { // Data read - uint64_t bytes_sent; // Bytes sent - uint64_t bytes_received; // Bytes received - uint64_t call_tcp_sent; // Number of times tcp_sendmsg was called - uint64_t call_tcp_received; // Number of times tcp_cleanup_rbuf was called - uint64_t retransmit; // Number of times tcp_retransmit was called - uint64_t call_udp_sent; // Number of times udp_sendmsg was called - uint64_t call_udp_received; // Number of times udp_recvmsg was called - - // Publish information. - uint64_t publish_sent_bytes; - uint64_t publish_received_bytes; - uint64_t publish_tcp_sent; - uint64_t publish_tcp_received; - uint64_t publish_retransmit; - uint64_t publish_udp_sent; - uint64_t publish_udp_received; + uint64_t bytes_sent; // Bytes sent + uint64_t bytes_received; // Bytes received + uint64_t call_tcp_sent; // Number of times tcp_sendmsg was called + uint64_t call_tcp_received; // Number of times tcp_cleanup_rbuf was called + uint64_t retransmit; // Number of times tcp_retransmit was called + uint64_t call_udp_sent; // Number of times udp_sendmsg was called + uint64_t call_udp_received; // Number of times udp_recvmsg was called + uint64_t call_close; // Number of times tcp_close was called + uint64_t call_tcp_v4_connection;// Number of times tcp_v4_connect was called + uint64_t call_tcp_v6_connection;// Number of times tcp_v6_connect was called } ebpf_socket_publish_apps_t; typedef struct ebpf_network_viewer_dimension_names { @@ -169,10 +193,24 @@ typedef struct ebpf_network_viewer_port_list { uint16_t cmp_first; uint16_t cmp_last; - uint8_t protocol; + uint16_t protocol; + uint32_t pid; + uint32_t tgid; + uint64_t connections; struct ebpf_network_viewer_port_list *next; } ebpf_network_viewer_port_list_t; +typedef struct netdata_passive_connection { + uint32_t tgid; + uint32_t pid; + uint64_t counter; +} netdata_passive_connection_t; + +typedef struct netdata_passive_connection_idx { + uint16_t protocol; + uint16_t port; +} netdata_passive_connection_idx_t; + /** * Union used to store ip addresses */ @@ -238,20 +276,18 @@ typedef struct netdata_socket { uint64_t sent_bytes; uint64_t first; // First timestamp uint64_t ct; // Current timestamp - uint16_t retransmit; // It is never used with UDP - uint8_t protocol; - uint8_t removeme; - uint32_t reserved; + uint32_t retransmit; // It is never used with UDP + uint16_t protocol; + uint16_t reserved; } netdata_socket_t __attribute__((__aligned__(8))); - typedef struct netdata_plot_values { // Values used in the previous iteration uint64_t recv_packets; uint64_t sent_packets; uint64_t recv_bytes; uint64_t sent_bytes; - uint16_t retransmit; + uint32_t retransmit; uint64_t last_time; @@ -322,7 +358,7 @@ typedef struct netdata_vector_plot { extern void clean_port_structure(ebpf_network_viewer_port_list_t **clean); extern ebpf_network_viewer_port_list_t *listen_ports; -extern void update_listen_table(uint16_t value, uint8_t proto); +extern void update_listen_table(uint16_t value, uint16_t proto, netdata_passive_connection_t *values); extern void parse_network_viewer_section(struct config *cfg); extern void fill_ip_list(ebpf_network_viewer_ip_list_t **out, ebpf_network_viewer_ip_list_t *in, char *table); extern void parse_service_name_section(struct config *cfg); @@ -330,5 +366,6 @@ extern void clean_socket_apps_structures(); extern ebpf_socket_publish_apps_t **socket_bandwidth_curr; extern struct config socket_config; +extern netdata_ebpf_targets_t socket_targets[]; #endif diff --git a/collectors/ebpf.plugin/ebpf_swap.c b/collectors/ebpf.plugin/ebpf_swap.c index 82eb9db88..906c83da5 100644 --- a/collectors/ebpf.plugin/ebpf_swap.c +++ b/collectors/ebpf.plugin/ebpf_swap.c @@ -644,7 +644,7 @@ static void ebpf_swap_allocate_global_vectors(int apps) static void ebpf_create_swap_charts(int update_every) { ebpf_create_chart(NETDATA_EBPF_SYSTEM_GROUP, NETDATA_MEM_SWAP_CHART, - "Calls to internal functions used to access swap.", + "Calls to access swap memory", EBPF_COMMON_DIMENSION_CALL, NETDATA_SYSTEM_SWAP_SUBMENU, NULL, NETDATA_EBPF_CHART_TYPE_LINE, diff --git a/collectors/ebpf.plugin/ebpf_sync.c b/collectors/ebpf.plugin/ebpf_sync.c index b3f1b6524..233c34a5b 100644 --- a/collectors/ebpf.plugin/ebpf_sync.c +++ b/collectors/ebpf.plugin/ebpf_sync.c @@ -44,21 +44,179 @@ struct config sync_config = { .first_section = NULL, .rwlock = AVL_LOCK_INITIALIZER } }; ebpf_sync_syscalls_t local_syscalls[] = { - {.syscall = "sync", .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL}, - {.syscall = "syncfs", .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL}, - {.syscall = "msync", .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL}, - {.syscall = "fsync", .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL}, - {.syscall = "fdatasync", .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL}, - {.syscall = "sync_file_range", .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL}, + {.syscall = NETDATA_SYSCALLS_SYNC, .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL}, + {.syscall = NETDATA_SYSCALLS_SYNCFS, .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL}, + {.syscall = NETDATA_SYSCALLS_MSYNC, .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL}, + {.syscall = NETDATA_SYSCALLS_FSYNC, .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL}, + {.syscall = NETDATA_SYSCALLS_FDATASYNC, .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL}, + {.syscall = NETDATA_SYSCALLS_SYNC_FILE_RANGE, .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL}, {.syscall = NULL, .enabled = CONFIG_BOOLEAN_NO, .objects = NULL, .probe_links = NULL} }; +netdata_ebpf_targets_t sync_targets[] = { {.name = NETDATA_SYSCALLS_SYNC, .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = NETDATA_SYSCALLS_SYNCFS, .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = NETDATA_SYSCALLS_MSYNC, .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = NETDATA_SYSCALLS_FSYNC, .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = NETDATA_SYSCALLS_FDATASYNC, .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = NETDATA_SYSCALLS_SYNC_FILE_RANGE, .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = NULL, .mode = EBPF_LOAD_TRAMPOLINE}}; + + +#ifdef LIBBPF_MAJOR_VERSION +/***************************************************************** + * + * BTF FUNCTIONS + * + *****************************************************************/ + +/** + * Disable probe + * + * Disable kprobe to use another method. + * + * @param obj is the main structure for bpf objects. + */ +static inline void ebpf_sync_disable_probe(struct sync_bpf *obj) +{ + bpf_program__set_autoload(obj->progs.netdata_sync_kprobe, false); +} + +/** + * Disable tramppoline + * + * Disable trampoline to use another method. + * + * @param obj is the main structure for bpf objects. + */ +static inline void ebpf_sync_disable_trampoline(struct sync_bpf *obj) +{ + bpf_program__set_autoload(obj->progs.netdata_sync_fentry, false); +} + +/** + * Disable tracepoint + * + * Disable tracepoints according information given. + * + * @param obj object loaded + * @param idx Which syscall will not be disabled + */ +void ebpf_sync_disable_tracepoints(struct sync_bpf *obj, sync_syscalls_index_t idx) +{ + if (idx != NETDATA_SYNC_SYNC_IDX) + bpf_program__set_autoload(obj->progs.netdata_sync_entry, false); + + if (idx != NETDATA_SYNC_SYNCFS_IDX) + bpf_program__set_autoload(obj->progs.netdata_syncfs_entry, false); + + if (idx != NETDATA_SYNC_MSYNC_IDX) + bpf_program__set_autoload(obj->progs.netdata_msync_entry, false); + + if (idx != NETDATA_SYNC_FSYNC_IDX) + bpf_program__set_autoload(obj->progs.netdata_fsync_entry, false); + + if (idx != NETDATA_SYNC_FDATASYNC_IDX) + bpf_program__set_autoload(obj->progs.netdata_fdatasync_entry, false); + + if (idx != NETDATA_SYNC_SYNC_FILE_RANGE_IDX) + bpf_program__set_autoload(obj->progs.netdata_sync_file_range_entry, false); +} + +/** + * Set hash tables + * + * Set the values for maps according the value given by kernel. + * + * @param obj is the main structure for bpf objects. + * @param idx the index for the main structure + */ +static void ebpf_sync_set_hash_tables(struct sync_bpf *obj, sync_syscalls_index_t idx) +{ + sync_maps[idx].map_fd = bpf_map__fd(obj->maps.tbl_sync); +} + +/** + * Load and attach + * + * Load and attach the eBPF code in kernel. + * + * @param obj is the main structure for bpf objects. + * @param em the structure with configuration + * @param target the syscall that we are attaching a tracer. + * @param idx the index for the main structure + * + * @return it returns 0 on succes and -1 otherwise + */ +static inline int ebpf_sync_load_and_attach(struct sync_bpf *obj, ebpf_module_t *em, char *target, + sync_syscalls_index_t idx) +{ + netdata_ebpf_targets_t *synct = em->targets; + netdata_ebpf_program_loaded_t test = synct[NETDATA_SYNC_SYNC_IDX].mode; + + if (test == EBPF_LOAD_TRAMPOLINE) { + ebpf_sync_disable_probe(obj); + ebpf_sync_disable_tracepoints(obj, NETDATA_SYNC_IDX_END); + + bpf_program__set_attach_target(obj->progs.netdata_sync_fentry, 0, + target); + } else if (test == EBPF_LOAD_PROBE || + test == EBPF_LOAD_RETPROBE) { + ebpf_sync_disable_tracepoints(obj, NETDATA_SYNC_IDX_END); + ebpf_sync_disable_trampoline(obj); + } else { + ebpf_sync_disable_probe(obj); + ebpf_sync_disable_trampoline(obj); + + ebpf_sync_disable_tracepoints(obj, idx); + } + + int ret = sync_bpf__load(obj); + if (!ret) { + if (test != EBPF_LOAD_PROBE && test != EBPF_LOAD_RETPROBE) { + ret = sync_bpf__attach(obj); + } else { + obj->links.netdata_sync_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_sync_kprobe, + false, target); + ret = (int)libbpf_get_error(obj->links.netdata_sync_kprobe); + } + + if (!ret) + ebpf_sync_set_hash_tables(obj, idx); + } + + return ret; +} +#endif + /***************************************************************** * * INITIALIZE THREAD * *****************************************************************/ +/** + * Load Legacy + * + * Load legacy code. + * + * @param w is the sync output structure with pointers to objects loaded. + * @param em is structure with configuration + * + * @return 0 on success and -1 otherwise. + */ +static int ebpf_sync_load_legacy(ebpf_sync_syscalls_t *w, ebpf_module_t *em) +{ + em->thread_name = w->syscall; + if (!w->probe_links) { + w->probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &w->objects); + if (!w->probe_links) { + return -1; + } + } + + return 0; +} + /* * Initialize Syscalls * @@ -70,15 +228,33 @@ static int ebpf_sync_initialize_syscall(ebpf_module_t *em) { int i; const char *saved_name = em->thread_name; + sync_syscalls_index_t errors = 0; for (i = 0; local_syscalls[i].syscall; i++) { ebpf_sync_syscalls_t *w = &local_syscalls[i]; - if (!w->probe_links && w->enabled) { - em->thread_name = w->syscall; - w->probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &w->objects); - if (!w->probe_links) { + if (w->enabled) { + if (em->load == EBPF_LOAD_LEGACY) { + if (ebpf_sync_load_legacy(w, em)) + errors++; + em->thread_name = saved_name; - return -1; } +#ifdef LIBBPF_MAJOR_VERSION + else { + char syscall[NETDATA_EBPF_MAX_SYSCALL_LENGTH]; + ebpf_select_host_prefix(syscall, NETDATA_EBPF_MAX_SYSCALL_LENGTH, w->syscall, running_on_kernel); + w->sync_obj = sync_bpf__open(); + if (!w->sync_obj) { + errors++; + } else { + if (ebpf_sync_load_and_attach(w->sync_obj, em, syscall, i)) { + if (ebpf_sync_load_legacy(w, em)) + errors++; + + em->thread_name = saved_name; + } + } + } +#endif } } em->thread_name = saved_name; @@ -254,6 +430,10 @@ void ebpf_sync_cleanup_objects() } bpf_object__close(w->objects); } +#ifdef LIBBPF_MAJOR_VERSION + else if (w->sync_obj) + sync_bpf__destroy(w->sync_obj); +#endif } } @@ -386,6 +566,9 @@ void *ebpf_sync_thread(void *ptr) if (!em->enabled) goto endsync; +#ifdef LIBBPF_MAJOR_VERSION + ebpf_adjust_thread_load(em, default_btf); +#endif if (ebpf_sync_initialize_syscall(em)) { em->enabled = CONFIG_BOOLEAN_NO; goto endsync; diff --git a/collectors/ebpf.plugin/ebpf_sync.h b/collectors/ebpf.plugin/ebpf_sync.h index e40c77a3f..2bc18c544 100644 --- a/collectors/ebpf.plugin/ebpf_sync.h +++ b/collectors/ebpf.plugin/ebpf_sync.h @@ -3,6 +3,10 @@ #ifndef NETDATA_EBPF_SYNC_H #define NETDATA_EBPF_SYNC_H 1 +#ifdef LIBBPF_MAJOR_VERSION +#include "includes/sync.skel.h" +#endif + // Module name #define NETDATA_EBPF_MODULE_NAME_SYNC "sync" @@ -13,13 +17,20 @@ #define NETDATA_EBPF_FILE_SEGMENT_CHART "file_segment" #define NETDATA_EBPF_SYNC_SUBMENU "synchronization (eBPF)" +#define NETDATA_SYSCALLS_SYNC "sync" +#define NETDATA_SYSCALLS_SYNCFS "syncfs" +#define NETDATA_SYSCALLS_MSYNC "msync" +#define NETDATA_SYSCALLS_FSYNC "fsync" +#define NETDATA_SYSCALLS_FDATASYNC "fdatasync" +#define NETDATA_SYSCALLS_SYNC_FILE_RANGE "sync_file_range" + #define NETDATA_EBPF_SYNC_SLEEP_MS 800000ULL // configuration file #define NETDATA_SYNC_CONFIG_FILE "sync.conf" #define NETDATA_SYNC_CONFIG_NAME "syscalls" -enum sync_syscalls_index { +typedef enum sync_syscalls_index { NETDATA_SYNC_SYNC_IDX, NETDATA_SYNC_SYNCFS_IDX, NETDATA_SYNC_MSYNC_IDX, @@ -28,15 +39,23 @@ enum sync_syscalls_index { NETDATA_SYNC_SYNC_FILE_RANGE_IDX, NETDATA_SYNC_IDX_END -}; +} sync_syscalls_index_t; typedef struct ebpf_sync_syscalls { char *syscall; int enabled; uint32_t flags; + // BTF structure struct bpf_object *objects; struct bpf_link **probe_links; + + // BPF structure +#ifdef LIBBPF_MAJOR_VERSION + struct sync_bpf *sync_obj; +#else + void *sync_obj; +#endif } ebpf_sync_syscalls_t; enum netdata_sync_charts { @@ -52,5 +71,6 @@ enum netdata_sync_table { extern void *ebpf_sync_thread(void *ptr); extern struct config sync_config; +extern netdata_ebpf_targets_t sync_targets[]; #endif /* NETDATA_EBPF_SYNC_H */ diff --git a/collectors/ebpf.plugin/ebpf_vfs.c b/collectors/ebpf.plugin/ebpf_vfs.c index d1c418f85..e14165fb7 100644 --- a/collectors/ebpf.plugin/ebpf_vfs.c +++ b/collectors/ebpf.plugin/ebpf_vfs.c @@ -670,42 +670,42 @@ static void ebpf_create_specific_vfs_charts(char *type, ebpf_module_t *em) 1, em->update_every, NETDATA_EBPF_MODULE_NAME_SWAP); ebpf_create_chart(type, NETDATA_SYSCALL_APPS_VFS_FSYNC, "Calls for vfs_fsync", - EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_CGROUP_GROUP, NULL, + EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_CGROUP_GROUP, NETDATA_CGROUP_VFS_FSYNC_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5507, ebpf_create_global_dimension, &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_FSYNC], 1, em->update_every, NETDATA_EBPF_MODULE_NAME_SWAP); if (em->mode < MODE_ENTRY) { ebpf_create_chart(type, NETDATA_SYSCALL_APPS_VFS_FSYNC_CALLS_ERROR, "Sync error", - EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_CGROUP_GROUP, NULL, + EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_CGROUP_GROUP, NETDATA_CGROUP_VFS_FSYNC_ERROR_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5508, ebpf_create_global_dimension, &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_FSYNC], 1, em->update_every, NETDATA_EBPF_MODULE_NAME_SWAP); } ebpf_create_chart(type, NETDATA_SYSCALL_APPS_VFS_OPEN, "Calls for vfs_open", - EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_CGROUP_GROUP, NULL, + EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_CGROUP_GROUP, NETDATA_CGROUP_VFS_OPEN_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5509, ebpf_create_global_dimension, &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_OPEN], 1, em->update_every, NETDATA_EBPF_MODULE_NAME_SWAP); if (em->mode < MODE_ENTRY) { ebpf_create_chart(type, NETDATA_SYSCALL_APPS_VFS_OPEN_CALLS_ERROR, "Open error", - EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_CGROUP_GROUP, NULL, + EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_CGROUP_GROUP, NETDATA_CGROUP_VFS_OPEN_ERROR_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5510, ebpf_create_global_dimension, &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_OPEN], 1, em->update_every, NETDATA_EBPF_MODULE_NAME_SWAP); } ebpf_create_chart(type, NETDATA_SYSCALL_APPS_VFS_CREATE, "Calls for vfs_create", - EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_CGROUP_GROUP, NULL, + EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_CGROUP_GROUP, NETDATA_CGROUP_VFS_CREATE_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5511, ebpf_create_global_dimension, &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_CREATE], 1, em->update_every, NETDATA_EBPF_MODULE_NAME_SWAP); if (em->mode < MODE_ENTRY) { ebpf_create_chart(type, NETDATA_SYSCALL_APPS_VFS_CREATE_CALLS_ERROR, "Create error", - EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_CGROUP_GROUP, NULL, + EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_CGROUP_GROUP, NETDATA_CGROUP_VFS_CREATE_ERROR_CONTEXT, NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5512, ebpf_create_global_dimension, &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_CREATE], 1, em->update_every, NETDATA_EBPF_MODULE_NAME_SWAP); @@ -763,37 +763,37 @@ static void ebpf_obsolete_specific_vfs_charts(char *type, ebpf_module_t *em) ebpf_write_chart_obsolete(type, NETDATA_SYSCALL_APPS_VFS_FSYNC, "Calls for vfs_fsync", EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_GROUP, - NETDATA_EBPF_CHART_TYPE_LINE, NULL, + NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_VFS_FSYNC_CONTEXT, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5507, em->update_every); if (em->mode < MODE_ENTRY) { ebpf_write_chart_obsolete(type, NETDATA_SYSCALL_APPS_VFS_FSYNC_CALLS_ERROR, "Sync error", EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_GROUP, - NETDATA_EBPF_CHART_TYPE_LINE, NULL, + NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_VFS_FSYNC_ERROR_CONTEXT, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5508, em->update_every); } ebpf_write_chart_obsolete(type, NETDATA_SYSCALL_APPS_VFS_OPEN, "Calls for vfs_open", EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_GROUP, - NETDATA_EBPF_CHART_TYPE_LINE, NULL, + NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_VFS_OPEN_CONTEXT, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5509, em->update_every); if (em->mode < MODE_ENTRY) { ebpf_write_chart_obsolete(type, NETDATA_SYSCALL_APPS_VFS_OPEN_CALLS_ERROR, "Open error", EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_GROUP, - NETDATA_EBPF_CHART_TYPE_LINE, NULL, + NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_VFS_OPEN_ERROR_CONTEXT, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5510, em->update_every); } ebpf_write_chart_obsolete(type, NETDATA_SYSCALL_APPS_VFS_CREATE, "Calls for vfs_create", EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_GROUP, - NETDATA_EBPF_CHART_TYPE_LINE, NULL, + NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_VFS_CREATE_CONTEXT, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5511, em->update_every); if (em->mode < MODE_ENTRY) { ebpf_write_chart_obsolete(type, NETDATA_SYSCALL_APPS_VFS_CREATE_CALLS_ERROR, "Create error", EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_GROUP, - NETDATA_EBPF_CHART_TYPE_LINE, NULL, + NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_CGROUP_VFS_CREATE_ERROR_CONTEXT, NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5512, em->update_every); } } @@ -943,41 +943,41 @@ static void ebpf_create_systemd_vfs_charts(ebpf_module_t *em) ebpf_create_charts_on_systemd(NETDATA_SYSCALL_APPS_VFS_FSYNC, "Calls to vfs_fsync", EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_CGROUP_GROUP, NETDATA_EBPF_CHART_TYPE_STACKED, 20072, - ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NULL, + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NETDATA_SYSTEMD_VFS_FSYNC_CONTEXT, NETDATA_EBPF_MODULE_NAME_VFS, em->update_every); if (em->mode < MODE_ENTRY) { ebpf_create_charts_on_systemd(NETDATA_SYSCALL_APPS_VFS_FSYNC_CALLS_ERROR, "Sync error", EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_CGROUP_GROUP, NETDATA_EBPF_CHART_TYPE_STACKED, 20073, - ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NULL, + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NETDATA_SYSTEMD_VFS_FSYNC_ERROR_CONTEXT, NETDATA_EBPF_MODULE_NAME_VFS, em->update_every); } ebpf_create_charts_on_systemd(NETDATA_SYSCALL_APPS_VFS_OPEN, "Calls to vfs_open", EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_CGROUP_GROUP, NETDATA_EBPF_CHART_TYPE_STACKED, 20074, - ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NULL, + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NETDATA_SYSTEMD_VFS_OPEN_CONTEXT, NETDATA_EBPF_MODULE_NAME_VFS, em->update_every); if (em->mode < MODE_ENTRY) { ebpf_create_charts_on_systemd(NETDATA_SYSCALL_APPS_VFS_OPEN_CALLS_ERROR, "Open error", EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_CGROUP_GROUP, NETDATA_EBPF_CHART_TYPE_STACKED, 20075, - ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NULL, + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NETDATA_SYSTEMD_VFS_OPEN_ERROR_CONTEXT, NETDATA_EBPF_MODULE_NAME_VFS, em->update_every); } ebpf_create_charts_on_systemd(NETDATA_SYSCALL_APPS_VFS_CREATE, "Calls to vfs_create", EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_CGROUP_GROUP, NETDATA_EBPF_CHART_TYPE_STACKED, 20076, - ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NULL, + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NETDATA_SYSTEMD_VFS_CREATE_CONTEXT, NETDATA_EBPF_MODULE_NAME_VFS, em->update_every); if (em->mode < MODE_ENTRY) { ebpf_create_charts_on_systemd(NETDATA_SYSCALL_APPS_VFS_CREATE_CALLS_ERROR, "Create error", EBPF_COMMON_DIMENSION_CALL, NETDATA_VFS_CGROUP_GROUP, NETDATA_EBPF_CHART_TYPE_STACKED, 20077, - ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NULL, + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], NETDATA_SYSTEMD_VFS_CREATE_ERROR_CONTEXT, NETDATA_EBPF_MODULE_NAME_VFS, em->update_every); } } diff --git a/collectors/ebpf.plugin/ebpf_vfs.h b/collectors/ebpf.plugin/ebpf_vfs.h index 0a972c983..67542ad44 100644 --- a/collectors/ebpf.plugin/ebpf_vfs.h +++ b/collectors/ebpf.plugin/ebpf_vfs.h @@ -50,6 +50,12 @@ #define NETDATA_CGROUP_VFS_READ_ERROR_CONTEXT "cgroup.vfs_read_error" #define NETDATA_CGROUP_VFS_WRITE_BYTES_CONTEXT "cgroup.vfs_write_bytes" #define NETDATA_CGROUP_VFS_READ_BYTES_CONTEXT "cgroup.vfs_read_bytes" +#define NETDATA_CGROUP_VFS_CREATE_CONTEXT "cgroup.vfs_create" +#define NETDATA_CGROUP_VFS_CREATE_ERROR_CONTEXT "cgroup.vfs_create_error" +#define NETDATA_CGROUP_VFS_OPEN_CONTEXT "cgroup.vfs_open" +#define NETDATA_CGROUP_VFS_OPEN_ERROR_CONTEXT "cgroup.vfs_open_error" +#define NETDATA_CGROUP_VFS_FSYNC_CONTEXT "cgroup.vfs_fsync" +#define NETDATA_CGROUP_VFS_FSYNC_ERROR_CONTEXT "cgroup.vfs_fsync_error" #define NETDATA_SYSTEMD_VFS_UNLINK_CONTEXT "services.vfs_unlink" #define NETDATA_SYSTEMD_VFS_WRITE_CONTEXT "services.vfs_write" @@ -58,6 +64,12 @@ #define NETDATA_SYSTEMD_VFS_READ_ERROR_CONTEXT "services.vfs_read_error" #define NETDATA_SYSTEMD_VFS_WRITE_BYTES_CONTEXT "services.vfs_write_bytes" #define NETDATA_SYSTEMD_VFS_READ_BYTES_CONTEXT "services.vfs_read_bytes" +#define NETDATA_SYSTEMD_VFS_CREATE_CONTEXT "services.vfs_create" +#define NETDATA_SYSTEMD_VFS_CREATE_ERROR_CONTEXT "services.vfs_create_error" +#define NETDATA_SYSTEMD_VFS_OPEN_CONTEXT "services.vfs_open" +#define NETDATA_SYSTEMD_VFS_OPEN_ERROR_CONTEXT "services.vfs_open_error" +#define NETDATA_SYSTEMD_VFS_FSYNC_CONTEXT "services.vfs_fsync" +#define NETDATA_SYSTEMD_VFS_FSYNC_ERROR_CONTEXT "services.vfs_fsync_error" typedef struct netdata_publish_vfs { uint64_t pid_tgid; diff --git a/collectors/fping.plugin/README.md b/collectors/fping.plugin/README.md index 4aca2a9de..626edf5d0 100644 --- a/collectors/fping.plugin/README.md +++ b/collectors/fping.plugin/README.md @@ -99,4 +99,4 @@ That's it. Netdata will detect the new plugin and start it. You can name the new plugin any name you like. Just make sure the plugin and the configuration file have the same name. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Ffping.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/freebsd.plugin/README.md b/collectors/freebsd.plugin/README.md index 1b519a659..9a97a7ece 100644 --- a/collectors/freebsd.plugin/README.md +++ b/collectors/freebsd.plugin/README.md @@ -9,4 +9,4 @@ Collects resource usage and performance data on FreeBSD systems By default, Netdata will enable monitoring metrics for disks, memory, and network only when they are not zero. If they are constantly zero they are ignored. Metrics that will start having values, after Netdata is started, will be detected and charts will be automatically added to the dashboard (a refresh of the dashboard is needed for them to appear though). Use `yes` instead of `auto` in plugin configuration sections to enable these charts permanently. You can also set the `enable zero metrics` option to `yes` in the `[global]` section which enables charts with zero metrics for all internal Netdata plugins. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Ffreebsd.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/freeipmi.plugin/README.md b/collectors/freeipmi.plugin/README.md index 3ff6f4099..13958784e 100644 --- a/collectors/freeipmi.plugin/README.md +++ b/collectors/freeipmi.plugin/README.md @@ -191,4 +191,4 @@ If you need to disable IPMI for Netdata, edit `/etc/netdata/netdata.conf` and se freeipmi = no ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Ffreeipmi.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/idlejitter.plugin/README.md b/collectors/idlejitter.plugin/README.md index 40436d33c..5a92d5317 100644 --- a/collectors/idlejitter.plugin/README.md +++ b/collectors/idlejitter.plugin/README.md @@ -29,4 +29,4 @@ idlejitter.plugin generates the idlejitter chart which measures CPU idle jitter This chart is available without any configuration. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fidlejitter.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/ioping.plugin/README.md b/collectors/ioping.plugin/README.md index 08b0ce8b1..c4c3695c5 100644 --- a/collectors/ioping.plugin/README.md +++ b/collectors/ioping.plugin/README.md @@ -83,4 +83,4 @@ That's it. Netdata will detect the new plugin and start it. You can name the new plugin any name you like. Just make sure the plugin and the configuration file have the same name. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fioping.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/ioping.plugin/ioping.plugin.in b/collectors/ioping.plugin/ioping.plugin.in index 1a82ef6d0..1d79eb706 100755 --- a/collectors/ioping.plugin/ioping.plugin.in +++ b/collectors/ioping.plugin/ioping.plugin.in @@ -174,16 +174,14 @@ ioping_opts="-T 1000000" # ----------------------------------------------------------------------------- # load the configuration files -for CONFIG in "${NETDATA_STOCK_CONFIG_DIR}/${plugin}.conf" "${NETDATA_USER_CONFIG_DIR}/${plugin}.conf" -do - if [ -f "${CONFIG}" ] - then - info "Loading config file '${CONFIG}'..." - source "${CONFIG}" - [ $? -ne 0 ] && error "Failed to load config file '${CONFIG}'." - else - warning "Cannot find file '${CONFIG}'." - fi +for CONFIG in "${NETDATA_STOCK_CONFIG_DIR}/${plugin}.conf" "${NETDATA_USER_CONFIG_DIR}/${plugin}.conf"; do + if [ -f "${CONFIG}" ]; then + info "Loading config file '${CONFIG}'..." + source "${CONFIG}" + [ $? -ne 0 ] && error "Failed to load config file '${CONFIG}'." + elif [[ $CONFIG =~ ^$NETDATA_USER_CONFIG_DIR ]]; then + warning "Cannot find file '${CONFIG}'." + fi done if [ -z "${destination}" ] diff --git a/collectors/macos.plugin/README.md b/collectors/macos.plugin/README.md index 800eb0e85..92bbf1eb1 100644 --- a/collectors/macos.plugin/README.md +++ b/collectors/macos.plugin/README.md @@ -9,4 +9,4 @@ Collects resource usage and performance data on macOS systems By default, Netdata will enable monitoring metrics for disks, memory, and network only when they are not zero. If they are constantly zero they are ignored. Metrics that will start having values, after Netdata is started, will be detected and charts will be automatically added to the dashboard (a refresh of the dashboard is needed for them to appear though). Use `yes` instead of `auto` in plugin configuration sections to enable these charts permanently. You can also set the `enable zero metrics` option to `yes` in the `[global]` section which enables charts with zero metrics for all internal Netdata plugins. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fmacos.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/macos.plugin/macos_fw.c b/collectors/macos.plugin/macos_fw.c index 1fa2d39c8..08d1ddadd 100644 --- a/collectors/macos.plugin/macos_fw.c +++ b/collectors/macos.plugin/macos_fw.c @@ -35,7 +35,7 @@ int do_macos_iokit(int update_every, usec_t dt) { RRDSET *st; - mach_port_t master_port; + mach_port_t main_port; io_registry_entry_t drive, drive_media; io_iterator_t drive_list; CFDictionaryRef properties, statistics; @@ -73,19 +73,22 @@ int do_macos_iokit(int update_every, usec_t dt) { // NEEDED BY: do_space, do_inodes struct statfs *mntbuf; int mntsize, i; - char mntonname[MNAMELEN + 1]; char title[4096 + 1]; // NEEDED BY: do_bandwidth struct ifaddrs *ifa, *ifap; +#if !defined(MAC_OS_VERSION_12_0) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_VERSION_12_0) +#define IOMainPort IOMasterPort +#endif + /* Get ports and services for drive statistics. */ - if (unlikely(IOMasterPort(bootstrap_port, &master_port))) { + if (unlikely(IOMainPort(bootstrap_port, &main_port))) { error("MACOS: IOMasterPort() failed"); do_io = 0; error("DISABLED: system.io"); /* Get the list of all drive objects. */ - } else if (unlikely(IOServiceGetMatchingServices(master_port, IOServiceMatching("IOBlockStorageDriver"), &drive_list))) { + } else if (unlikely(IOServiceGetMatchingServices(main_port, IOServiceMatching("IOBlockStorageDriver"), &drive_list))) { error("MACOS: IOServiceGetMatchingServices() failed"); do_io = 0; error("DISABLED: system.io"); @@ -115,7 +118,7 @@ int do_macos_iokit(int update_every, usec_t dt) { CFRelease(properties); IOObjectRelease(drive_media); - if(unlikely(!diskstat.name || !*diskstat.name)) { + if(unlikely(!*diskstat.name)) { IOObjectRelease(drive); continue; } diff --git a/collectors/macos.plugin/macos_sysctl.c b/collectors/macos.plugin/macos_sysctl.c index b744ebbcc..34d3f0b3e 100644 --- a/collectors/macos.plugin/macos_sysctl.c +++ b/collectors/macos.plugin/macos_sysctl.c @@ -70,11 +70,9 @@ int do_macos_sysctl(int update_every, usec_t dt) { do_uptime = config_get_boolean("plugin:macos:sysctl", "system uptime", 1); } - RRDSET *st; + RRDSET *st = NULL; - int system_pagesize = getpagesize(); // wouldn't it be better to get value directly from hw.pagesize? - int i, n; - int common_error = 0; + int i; size_t size; // NEEDED BY: do_loadavg @@ -96,7 +94,6 @@ int do_macos_sysctl(int update_every, usec_t dt) { // NEEDED BY: do_tcp... struct tcpstat tcpstat; - uint64_t tcps_states[TCP_NSTATES]; // NEEDED BY: do_udp... struct udpstat udpstat; diff --git a/collectors/nfacct.plugin/README.md b/collectors/nfacct.plugin/README.md index 1bd8a46e8..bacc8b70e 100644 --- a/collectors/nfacct.plugin/README.md +++ b/collectors/nfacct.plugin/README.md @@ -9,7 +9,7 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/collectors/nfacc ## Prerequisites -1. install `libmnl-dev` and `libnetfilter_acct-dev` using the package manager of your system. +1. install `libmnl-dev` and `libnetfilter-acct-dev` using the package manager of your system. 2. re-install Netdata from source. The installer will detect that the required libraries are now available and will also build `netdata.plugin`. @@ -51,4 +51,4 @@ sudo /usr/libexec/netdata/plugins.d/nfacct.plugin 1 debug You will get verbose output on what the plugin does. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fnfacct.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/node.d.plugin/Makefile.am b/collectors/node.d.plugin/Makefile.am index c3142d433..1b8281748 100644 --- a/collectors/node.d.plugin/Makefile.am +++ b/collectors/node.d.plugin/Makefile.am @@ -36,11 +36,7 @@ dist_nodeconfig_DATA = \ dist_node_DATA = \ $(NULL) -include fronius/Makefile.inc -include named/Makefile.inc -include sma_webbox/Makefile.inc include snmp/Makefile.inc -include stiebeleltron/Makefile.inc nodemodulesdir=$(nodedir)/node_modules dist_nodemodules_DATA = \ diff --git a/collectors/node.d.plugin/README.md b/collectors/node.d.plugin/README.md index 8db80d85b..4c5f278bd 100644 --- a/collectors/node.d.plugin/README.md +++ b/collectors/node.d.plugin/README.md @@ -233,4 +233,4 @@ The `service` object defines a set of functions to allow you send information to _FIXME: document an operational node.d.plugin data collector - the best example is the [snmp collector](https://raw.githubusercontent.com/netdata/netdata/master/collectors/node.d.plugin/snmp/snmp.node.js)_ -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fnode.d.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/node.d.plugin/fronius/Makefile.inc b/collectors/node.d.plugin/fronius/Makefile.inc deleted file mode 100644 index da0743a88..000000000 --- a/collectors/node.d.plugin/fronius/Makefile.inc +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later - -# THIS IS NOT A COMPLETE Makefile -# IT IS INCLUDED BY ITS PARENT'S Makefile.am -# IT IS REQUIRED TO REFERENCE ALL FILES RELATIVE TO THE PARENT - -# install these files -dist_node_DATA += fronius/fronius.node.js -# dist_nodeconfig_DATA += fronius/fronius.conf - -# do not install these files, but include them in the distribution -dist_noinst_DATA += fronius/README.md fronius/Makefile.inc - diff --git a/collectors/node.d.plugin/fronius/README.md b/collectors/node.d.plugin/fronius/README.md deleted file mode 100644 index 746737d0b..000000000 --- a/collectors/node.d.plugin/fronius/README.md +++ /dev/null @@ -1,135 +0,0 @@ - - -# Fronius Symo monitoring with Netdata - -Collects metrics from the configured solar power installation from Fronius Symo. - -**Requirements** - -- Configuration file `fronius.conf` in the node.d Netdata config dir (default: `/etc/netdata/node.d/fronius.conf`) -- Fronius Symo with network access (http) - -It produces per server: - -1. **Power** - -- Current power input from the grid (positive values), output to the grid (negative values), in W -- Current power input from the solar panels, in W -- Current power stored in the accumulator (if present), in W (in theory, untested) - -2. **Consumption** - -- Local consumption in W - -3. **Autonomy** - -- Relative autonomy in %. 100 % autonomy means that the solar panels are delivering more power than it is needed by local consumption. -- Relative self consumption in %. The lower the better - -4. **Energy** - -- The energy produced during the current day, in kWh -- The energy produced during the current year, in kWh - -5. **Inverter** - -- The current power output from the connected inverters, in W, one dimension per inverter. At least one is always present. - -## configuration - -Sample: - -```json -{ - "enable_autodetect": false, - "update_every": 5, - "servers": [ - { - "name": "Symo", - "hostname": "symo.ip.or.dns", - "update_every": 5, - "api_path": "/solar_api/v1/GetPowerFlowRealtimeData.fcgi" - } - ] -} -``` - -If no configuration is given, the module will be disabled. Each `update_every` is optional, the default is `5`. - ---- - -[Fronius Symo 8.2](https://www.fronius.com/en/photovoltaics/products/all-products/inverters/fronius-symo/fronius-symo-8-2-3-m) - -The plugin has been tested with a single inverter, namely Fronius Symo 8.2-3-M: - -- Datalogger version: 240.162630 -- Software version: 3.7.4-6 -- Hardware version: 2.4D - -Other products and versions may work, but without any guarantees. - -Example Netdata configuration for node.d/fronius.conf. Copy this section to fronius.conf and change name/ip. -The module supports any number of servers. Sometimes there is a lag when collecting every 3 seconds, so 5 should be okay too. You can modify this per server. - -```json -{ - "enable_autodetect": false, - "update_every": 5, - "servers": [ - { - "name": "solar", - "hostname": "symo.ip.or.dns", - "update_every": 5, - "api_path": "/solar_api/v1/GetPowerFlowRealtimeData.fcgi" - } - ] -} -``` - -The output of /solar_api/v1/GetPowerFlowRealtimeData.fcgi looks like this: - -```json -{ - "Head" : { - "RequestArguments" : {}, - "Status" : { - "Code" : 0, - "Reason" : "", - "UserMessage" : "" - }, - "Timestamp" : "2017-07-05T12:35:12+02:00" - }, - "Body" : { - "Data" : { - "Site" : { - "Mode" : "meter", - "P_Grid" : -6834.549847, - "P_Load" : -1271.450153, - "P_Akku" : null, - "P_PV" : 8106, - "rel_SelfConsumption" : 15.685297, - "rel_Autonomy" : 100, - "E_Day" : 35020, - "E_Year" : 5826076, - "E_Total" : 14788870, - "Meter_Location" : "grid" - }, - "Inverters" : { - "1" : { - "DT" : 123, - "P" : 8106, - "E_Day" : 35020, - "E_Year" : 5826076, - "E_Total" : 14788870 - } - } - } - } -} -``` - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fnode.d.plugin%2Ffronius%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) diff --git a/collectors/node.d.plugin/fronius/fronius.node.js b/collectors/node.d.plugin/fronius/fronius.node.js deleted file mode 100644 index 436f3a325..000000000 --- a/collectors/node.d.plugin/fronius/fronius.node.js +++ /dev/null @@ -1,400 +0,0 @@ -"use strict"; -// SPDX-License-Identifier: GPL-3.0-or-later - -// This program will connect to one or more Fronius Symo Inverters. -// to get the Solar Power Generated (current, today). - -// example configuration in netdata/conf.d/node.d/fronius.conf.md - -require("url"); -require("http"); -var netdata = require("netdata"); - -netdata.debug("loaded " + __filename + " plugin"); - -var fronius = { - name: "Fronius", - enable_autodetect: false, - update_every: 5, - base_priority: 60000, - charts: {}, - - powerGridId: "p_grid", - powerPvId: "p_pv", - powerAccuId: "p_akku", // not my typo! Using the ID from the AP - consumptionLoadId: "p_load", - autonomyId: "rel_autonomy", - consumptionSelfId: "rel_selfconsumption", - solarConsumptionId: "solar_consumption", - energyTodayId: "e_day", - energyYearId: "e_year", - - createBasicDimension: function (id, name, divisor) { - return { - id: id, // the unique id of the dimension - name: name, // the name of the dimension - algorithm: netdata.chartAlgorithms.absolute,// the id of the netdata algorithm - multiplier: 1, // the multiplier - divisor: divisor, // the divisor - hidden: false // is hidden (boolean) - }; - }, - - // Gets the site power chart. Will be created if not existing. - getSitePowerChart: function (service, suffix) { - var id = this.getChartId(service, suffix); - var chart = fronius.charts[id]; - if (fronius.isDefined(chart)) return chart; - - var dim = {}; - dim[fronius.powerGridId] = this.createBasicDimension(fronius.powerGridId, "grid", 1); - dim[fronius.powerPvId] = this.createBasicDimension(fronius.powerPvId, "photovoltaics", 1); - dim[fronius.powerAccuId] = this.createBasicDimension(fronius.powerAccuId, "accumulator", 1); - - chart = { - id: id, // the unique id of the chart - name: "", // the unique name of the chart - title: service.name + " Current Site Power", // the title of the chart - units: "W", // the units of the chart dimensions - family: "power", // the family of the chart - context: "fronius.power", // the context of the chart - type: netdata.chartTypes.area, // the type of the chart - priority: fronius.base_priority + 1, // the priority relative to others in the same family - update_every: service.update_every, // the expected update frequency of the chart - dimensions: dim - }; - chart = service.chart(id, chart); - fronius.charts[id] = chart; - - return chart; - }, - - // Gets the site consumption chart. Will be created if not existing. - getSiteConsumptionChart: function (service, suffix) { - var id = this.getChartId(service, suffix); - var chart = fronius.charts[id]; - if (fronius.isDefined(chart)) return chart; - var dim = {}; - dim[fronius.consumptionLoadId] = this.createBasicDimension(fronius.consumptionLoadId, "load", 1); - - chart = { - id: id, // the unique id of the chart - name: "", // the unique name of the chart - title: service.name + " Current Load", // the title of the chart - units: "W", // the units of the chart dimensions - family: "consumption", // the family of the chart - context: "fronius.consumption", // the context of the chart - type: netdata.chartTypes.area, // the type of the chart - priority: fronius.base_priority + 2, // the priority relative to others in the same family - update_every: service.update_every, // the expected update frequency of the chart - dimensions: dim - }; - chart = service.chart(id, chart); - fronius.charts[id] = chart; - - return chart; - }, - - // Gets the site consumption chart. Will be created if not existing. - getSiteAutonomyChart: function (service, suffix) { - var id = this.getChartId(service, suffix); - var chart = fronius.charts[id]; - if (fronius.isDefined(chart)) return chart; - var dim = {}; - dim[fronius.autonomyId] = this.createBasicDimension(fronius.autonomyId, "autonomy", 1); - dim[fronius.consumptionSelfId] = this.createBasicDimension(fronius.consumptionSelfId, "self_consumption", 1); - dim[fronius.solarConsumptionId] = this.createBasicDimension(fronius.solarConsumptionId, "solar_consumption", 1); - - chart = { - id: id, // the unique id of the chart - name: "", // the unique name of the chart - title: service.name + " Current Autonomy", // the title of the chart - units: "%", // the units of the chart dimensions - family: "autonomy", // the family of the chart - context: "fronius.autonomy", // the context of the chart - type: netdata.chartTypes.area, // the type of the chart - priority: fronius.base_priority + 3, // the priority relative to others in the same family - update_every: service.update_every, // the expected update frequency of the chart - dimensions: dim - }; - chart = service.chart(id, chart); - fronius.charts[id] = chart; - - return chart; - }, - - // Gets the site energy chart for today. Will be created if not existing. - getSiteEnergyTodayChart: function (service, suffix) { - var chartId = this.getChartId(service, suffix); - var chart = fronius.charts[chartId]; - if (fronius.isDefined(chart)) return chart; - var dim = {}; - dim[fronius.energyTodayId] = this.createBasicDimension(fronius.energyTodayId, "today", 1000); - chart = { - id: chartId, // the unique id of the chart - name: "", // the unique name of the chart - title: service.name + " Energy production for today",// the title of the chart - units: "kWh", // the units of the chart dimensions - family: "energy", // the family of the chart - context: "fronius.energy.today", // the context of the chart - type: netdata.chartTypes.area, // the type of the chart - priority: fronius.base_priority + 4, // the priority relative to others in the same family - update_every: service.update_every, // the expected update frequency of the chart - dimensions: dim - }; - chart = service.chart(chartId, chart); - fronius.charts[chartId] = chart; - - return chart; - }, - - // Gets the site energy chart for today. Will be created if not existing. - getSiteEnergyYearChart: function (service, suffix) { - var chartId = this.getChartId(service, suffix); - var chart = fronius.charts[chartId]; - if (fronius.isDefined(chart)) return chart; - var dim = {}; - dim[fronius.energyYearId] = this.createBasicDimension(fronius.energyYearId, "year", 1000); - chart = { - id: chartId, // the unique id of the chart - name: "", // the unique name of the chart - title: service.name + " Energy production for this year",// the title of the chart - units: "kWh", // the units of the chart dimensions - family: "energy", // the family of the chart - context: "fronius.energy.year", // the context of the chart - type: netdata.chartTypes.area, // the type of the chart - priority: fronius.base_priority + 5, // the priority relative to others in the same family - update_every: service.update_every, // the expected update frequency of the chart - dimensions: dim - }; - chart = service.chart(chartId, chart); - fronius.charts[chartId] = chart; - - return chart; - }, - - // Gets the inverter power chart. Will be created if not existing. - // Needs the array of inverters in order to create a chart with all inverters as dimensions - getInverterPowerChart: function (service, suffix, inverters) { - var chartId = this.getChartId(service, suffix); - var chart = fronius.charts[chartId]; - if (fronius.isDefined(chart)) return chart; - - var dim = {}; - for (var key in inverters) { - if (inverters.hasOwnProperty(key)) { - var name = key; - if (!isNaN(key)) name = "inverter_" + key; - dim[key] = this.createBasicDimension("inverter_" + key, name, 1); - } - } - - chart = { - id: chartId, // the unique id of the chart - name: "", // the unique name of the chart - title: service.name + " Current Inverter Output",// the title of the chart - units: "W", // the units of the chart dimensions - family: "inverters", // the family of the chart - context: "fronius.inverter.output", // the context of the chart - type: netdata.chartTypes.stacked, // the type of the chart - priority: fronius.base_priority + 6, // the priority relative to others in the same family - update_every: service.update_every, // the expected update frequency of the chart - dimensions: dim - }; - chart = service.chart(chartId, chart); - fronius.charts[chartId] = chart; - - return chart; - }, - - processResponse: function (service, content) { - var json = fronius.convertToJson(content); - if (json === null) return; - - // add the service - service.commit(); - - var chartDefinitions = fronius.parseCharts(service, json); - var chartCount = chartDefinitions.length; - while (chartCount--) { - var chartObj = chartDefinitions[chartCount]; - service.begin(chartObj.chart); - var dimCount = chartObj.dimensions.length; - while (dimCount--) { - var dim = chartObj.dimensions[dimCount]; - service.set(dim.name, dim.value); - } - service.end(); - } - }, - - parseCharts: function (service, json) { - var site = json.Body.Data.Site; - return [ - this.parsePowerChart(service, site), - this.parseConsumptionChart(service, site), - this.parseAutonomyChart(service, site), - this.parseEnergyTodayChart(service, site), - this.parseEnergyYearChart(service, site), - this.parseInverterChart(service, json.Body.Data.Inverters) - ]; - }, - - parsePowerChart: function (service, site) { - return this.getChart(this.getSitePowerChart(service, "power"), - [ - this.getDimension(this.powerGridId, Math.round(site.P_Grid)), - this.getDimension(this.powerPvId, Math.round(Math.max(site.P_PV, 0))), - this.getDimension(this.powerAccuId, Math.round(site.P_Akku)) - ] - ); - }, - - parseConsumptionChart: function (service, site) { - return this.getChart(this.getSiteConsumptionChart(service, "consumption"), - [this.getDimension(this.consumptionLoadId, Math.round(Math.abs(site.P_Load)))] - ); - }, - - parseAutonomyChart: function (service, site) { - var selfConsumption = site.rel_SelfConsumption; - var solarConsumption = 0; - var load = Math.abs(site.P_Load); - var power = Math.max(site.P_PV, 0); - if (power <= 0) solarConsumption = 0; - else if (load >= power) solarConsumption = 100; - else solarConsumption = 100 / power * load; - return this.getChart(this.getSiteAutonomyChart(service, "autonomy"), - [ - this.getDimension(this.autonomyId, Math.round(site.rel_Autonomy)), - this.getDimension(this.consumptionSelfId, Math.round(selfConsumption === null ? 100 : selfConsumption)), - this.getDimension(this.solarConsumptionId, Math.round(solarConsumption)) - ] - ); - }, - - parseEnergyTodayChart: function (service, site) { - return this.getChart(this.getSiteEnergyTodayChart(service, "energy.today"), - [this.getDimension(this.energyTodayId, Math.round(Math.max(site.E_Day, 0)))] - ); - }, - - parseEnergyYearChart: function (service, site) { - return this.getChart(this.getSiteEnergyYearChart(service, "energy.year"), - [this.getDimension(this.energyYearId, Math.round(Math.max(site.E_Year, 0)))] - ); - }, - - parseInverterChart: function (service, inverters) { - var dimensions = []; - for (var key in inverters) { - if (inverters.hasOwnProperty(key)) { - dimensions.push(this.getDimension(key, Math.round(inverters[key].P))); - } - } - return this.getChart(this.getInverterPowerChart(service, "inverters.output", inverters), dimensions); - }, - - getDimension: function (name, value) { - return { - name: name, - value: value - }; - }, - - getChart: function (chart, dimensions) { - return { - chart: chart, - dimensions: dimensions - }; - }, - - getChartId: function (service, suffix) { - return "fronius_" + service.name + "." + suffix; - }, - - convertToJson: function (httpBody) { - if (httpBody === null) return null; - var json = httpBody; - // can't parse if it's already a json object, - // the check enables easier testing if the httpBody is already valid JSON. - if (typeof httpBody !== "object") { - try { - json = JSON.parse(httpBody); - } catch (error) { - netdata.error("fronius: Got a response, but it is not valid JSON. Ignoring. Error: " + error.message); - return null; - } - } - return this.isResponseValid(json) ? json : null; - }, - - // some basic validation - isResponseValid: function (json) { - if (this.isUndefined(json.Body)) return false; - if (this.isUndefined(json.Body.Data)) return false; - if (this.isUndefined(json.Body.Data.Site)) return false; - return this.isDefined(json.Body.Data.Inverters); - }, - - // module.serviceExecute() - // this function is called only from this module - // its purpose is to prepare the request and call - // netdata.serviceExecute() - serviceExecute: function (name, uri, update_every) { - netdata.debug(this.name + ": " + name + ": url: " + uri + ", update_every: " + update_every); - - var service = netdata.service({ - name: name, - request: netdata.requestFromURL("http://" + uri), - update_every: update_every, - module: this - }); - service.execute(this.processResponse); - }, - - - configure: function (config) { - if (fronius.isUndefined(config.servers)) return 0; - var added = 0; - var len = config.servers.length; - while (len--) { - var server = config.servers[len]; - if (fronius.isUndefined(server.update_every)) server.update_every = this.update_every; - if (fronius.areUndefined([server.name, server.hostname, server.api_path])) continue; - - var url = server.hostname + server.api_path; - this.serviceExecute(server.name, url, server.update_every); - added++; - } - return added; - }, - - // module.update() - // this is called repeatedly to collect data, by calling - // netdata.serviceExecute() - update: function (service, callback) { - service.execute(function (serv, data) { - service.module.processResponse(serv, data); - callback(); - }); - }, - - isUndefined: function (value) { - return typeof value === "undefined"; - }, - - areUndefined: function (valueArray) { - var i = 0; - for (i; i < valueArray.length; i++) { - if (this.isUndefined(valueArray[i])) return true; - } - return false; - }, - - isDefined: function (value) { - return typeof value !== "undefined"; - } -}; - -module.exports = fronius; diff --git a/collectors/node.d.plugin/named/Makefile.inc b/collectors/node.d.plugin/named/Makefile.inc deleted file mode 100644 index 95f423012..000000000 --- a/collectors/node.d.plugin/named/Makefile.inc +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later - -# THIS IS NOT A COMPLETE Makefile -# IT IS INCLUDED BY ITS PARENT'S Makefile.am -# IT IS REQUIRED TO REFERENCE ALL FILES RELATIVE TO THE PARENT - -# install these files -dist_node_DATA += named/named.node.js -# dist_nodeconfig_DATA += named/named.conf - -# do not install these files, but include them in the distribution -dist_noinst_DATA += named/README.md named/Makefile.inc - diff --git a/collectors/node.d.plugin/named/README.md b/collectors/node.d.plugin/named/README.md deleted file mode 100644 index acd03f687..000000000 --- a/collectors/node.d.plugin/named/README.md +++ /dev/null @@ -1,348 +0,0 @@ - - -# ISC BIND monitoring with Netdata - -Monitor one or more ISC Bind servers. - -## Example Netdata charts - -Depending on the number of views your bind has, you may get a large number of charts. -Here this is with just one view: - -![image](https://cloud.githubusercontent.com/assets/2662304/12765473/879b8e04-ca07-11e5-817d-b0651996c42b.png) -![image](https://cloud.githubusercontent.com/assets/2662304/12766538/12b272fa-ca0d-11e5-81e1-6a9f8ff488ff.png) - -## How it works - -The plugin will execute (from within node.js) the equivalent of: - -```sh -curl "http://localhost:8888/json/v1/server" -``` - -Here is a sample of the output this command produces. - -```js -{ - "json-stats-version":"1.0", - "boot-time":"2016-01-31T08:20:48Z", - "config-time":"2016-01-31T09:28:03Z", - "current-time":"2016-02-02T22:22:20Z", - "opcodes":{ - "QUERY":247816, - "IQUERY":0, - "STATUS":0, - "RESERVED3":0, - "NOTIFY":0, - "UPDATE":3813, - "RESERVED6":0, - "RESERVED7":0, - "RESERVED8":0, - "RESERVED9":0, - "RESERVED10":0, - "RESERVED11":0, - "RESERVED12":0, - "RESERVED13":0, - "RESERVED14":0, - "RESERVED15":0 - }, - "qtypes":{ - "A":89519, - "NS":863, - "CNAME":1, - "SOA":1, - "PTR":116779, - "MX":276, - "TXT":198, - "AAAA":39324, - "SRV":850, - "ANY":5 - }, - "nsstats":{ - "Requestv4":251630, - "ReqEdns0":1255, - "ReqTSIG":3813, - "ReqTCP":57, - "AuthQryRej":1455, - "RecQryRej":122, - "Response":245918, - "TruncatedResp":44, - "RespEDNS0":1255, - "RespTSIG":3813, - "QrySuccess":205159, - "QryAuthAns":119495, - "QryNoauthAns":120770, - "QryNxrrset":32711, - "QrySERVFAIL":262, - "QryNXDOMAIN":2395, - "QryRecursion":40885, - "QryDuplicate":5712, - "QryFailure":1577, - "UpdateDone":2514, - "UpdateFail":1299, - "UpdateBadPrereq":1276, - "QryUDP":246194, - "QryTCP":45, - "OtherOpt":101 - }, - "views":{ - "local":{ - "resolver":{ - "stats":{ - "Queryv4":74577, - "Responsev4":67032, - "NXDOMAIN":601, - "SERVFAIL":5, - "FORMERR":7, - "EDNS0Fail":7, - "Truncated":3071, - "Lame":4, - "Retry":11826, - "QueryTimeout":1838, - "GlueFetchv4":6864, - "GlueFetchv4Fail":30, - "QryRTT10":112, - "QryRTT100":42900, - "QryRTT500":23275, - "QryRTT800":534, - "QryRTT1600":97, - "QryRTT1600+":20, - "BucketSize":31, - "REFUSED":13 - }, - "qtypes":{ - "A":64931, - "NS":870, - "CNAME":185, - "PTR":5, - "MX":49, - "TXT":149, - "AAAA":7972, - "SRV":416 - }, - "cache":{ - "A":40356, - "NS":8032, - "CNAME":14477, - "PTR":2, - "MX":21, - "TXT":32, - "AAAA":3301, - "SRV":94, - "DS":237, - "RRSIG":2301, - "NSEC":126, - "!A":52, - "!NS":4, - "!TXT":1, - "!AAAA":3797, - "!SRV":9, - "NXDOMAIN":590 - }, - "cachestats":{ - "CacheHits":1085188, - "CacheMisses":109, - "QueryHits":464755, - "QueryMisses":55624, - "DeleteLRU":0, - "DeleteTTL":42615, - "CacheNodes":5188, - "CacheBuckets":2079, - "TreeMemTotal":2326026, - "TreeMemInUse":1508075, - "HeapMemMax":132096, - "HeapMemTotal":393216, - "HeapMemInUse":132096 - }, - "adb":{ - "nentries":1021, - "entriescnt":3157, - "nnames":1021, - "namescnt":3022 - } - } - }, - "public":{ - "resolver":{ - "stats":{ - "BucketSize":31 - }, - "qtypes":{ - }, - "cache":{ - }, - "cachestats":{ - "CacheHits":0, - "CacheMisses":0, - "QueryHits":0, - "QueryMisses":0, - "DeleteLRU":0, - "DeleteTTL":0, - "CacheNodes":0, - "CacheBuckets":64, - "TreeMemTotal":287392, - "TreeMemInUse":29608, - "HeapMemMax":1024, - "HeapMemTotal":262144, - "HeapMemInUse":1024 - }, - "adb":{ - "nentries":1021, - "nnames":1021 - } - } - }, - "_bind":{ - "resolver":{ - "stats":{ - "BucketSize":31 - }, - "qtypes":{ - }, - "cache":{ - }, - "cachestats":{ - "CacheHits":0, - "CacheMisses":0, - "QueryHits":0, - "QueryMisses":0, - "DeleteLRU":0, - "DeleteTTL":0, - "CacheNodes":0, - "CacheBuckets":64, - "TreeMemTotal":287392, - "TreeMemInUse":29608, - "HeapMemMax":1024, - "HeapMemTotal":262144, - "HeapMemInUse":1024 - }, - "adb":{ - "nentries":1021, - "nnames":1021 - } - } - } - } -} -``` - -From this output it collects: - -- Global Received Requests by IP version (IPv4, IPv6) -- Global Successful Queries -- Current Recursive Clients -- Global Queries by IP Protocol (TCP, UDP) -- Global Queries Analysis -- Global Received Updates -- Global Query Failures -- Global Query Failures Analysis -- Other Global Server Statistics -- Global Incoming Requests by OpCode -- Global Incoming Requests by Query Type -- Global Socket Statistics (will only work if the url is `http://127.0.0.1:8888/json/v1`, i.e. without `/server`, but keep in mind this produces a very long output and probably will account for 0.5% CPU overhead alone, per bind server added) -- Per View Statistics (the following set will be added for each bind view): - - View, Resolver Active Queries - - View, Resolver Statistics - - View, Resolver Round Trip Timings - - View, Requests by Query Type - -## Configuration - -The collector (optionally) reads a configuration file named `/etc/netdata/node.d/named.conf`, with the following contents: - -```js -{ - "enable_autodetect": true, - "update_every": 5, - "servers": [ - { - "name": "bind1", - "url": "http://127.0.0.1:8888/json/v1/server", - "update_every": 1 - }, - { - "name": "bind2", - "url": "http://10.1.2.3:8888/json/v1/server", - "update_every": 2 - } - ] -} -``` - -You can add any number of bind servers. - -If the configuration file is missing, or the key `enable_autodetect` is `true`, the collector will also attempt to fetch `http://localhost:8888/json/v1/server` which, if successful will be added too. - -### XML instead of JSON, from bind - -The collector can also accept bind URLs that return XML output. This might required if you cannot have bind 9.10+ with JSON but you have an version of bind that supports XML statistics v3. Check [this](https://www.isc.org/blogs/bind-9-10-statistics-troubleshooting-and-zone-configuration/) for versions supported. - -In such cases, use a URL like this: - -```sh -curl "http://localhost:8888/xml/v3/server" -``` - -Only `xml` and `v3` has been tested. - -Keep in mind though, that XML parsing is done using javascript code, which requires a triple conversion: - -1. from XML to JSON using a javascript XML parser (**CPU intensive**), -2. which is then transformed to emulate the output of the JSON output of bind (**CPU intensive** - and yes the converted JSON from XML is different to the native JSON - even bind produces different names for various attributes), -3. which is then processed to generate the data for the charts (this will happen even if bind is producing JSON). - -In general, expect XML parsing to be 2 to 3 times more CPU intensive than JSON. - -**So, if you can use the JSON output of bind, prefer it over XML**. Keep also in mind that even bind will use more CPU when generating XML instead of JSON. - -The XML interface of bind is not autodetected. -You will have to provide the config file `/etc/netdata/node.d/named.conf`, like this: - -```js -{ - "enable_autodetect": false, - "update_every": 1, - "servers": [ - { - "name": "local", - "url": "http://localhost:8888/xml/v3/server", - "update_every": 1 - } - ] -} -``` - -Of course, you can monitor more than one bind servers. Each one can be configured with either JSON or XML output. - -## Auto-detection - -Auto-detection is controlled by `enable_autodetect` in the config file. The default is enabled, so that if the collector can connect to `http://localhost:8888/json/v1/server` to receive bind statistics, it will automatically enable it. - -## Bind (named) configuration - -To use this plugin, you have to have bind v9.10+ properly compiled to provide statistics in `JSON` format. - -For more information on how to get your bind installation ready, please refer to the [bind statistics channel developer comments](http://jpmens.net/2013/03/18/json-in-bind-9-s-statistics-server/) and to [bind documentation](https://ftp.isc.org/isc/bind/9.10.3/doc/arm/Bv9ARM.ch06.html#statistics) or [bind Knowledge Base article AA-01123](https://kb.isc.org/article/AA-01123/0). - -Normally, you will need something like this in your `named.conf`: - -``` -statistics-channels { - inet 127.0.0.1 port 8888 allow { 127.0.0.1; }; - inet ::1 port 8888 allow { ::1; }; -}; -``` - -(use the IPv4 or IPv6 line depending on what you are using, you can also use both) - -Verify it works by running the following command (the collector is written in node.js and will query your bind server directly, but if this command works, the collector should be able to work too): - -```sh -curl "http://localhost:8888/json/v1/server" -``` - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fnode.d.plugin%2Fnamed%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) diff --git a/collectors/node.d.plugin/named/named.node.js b/collectors/node.d.plugin/named/named.node.js deleted file mode 100644 index 668a044c7..000000000 --- a/collectors/node.d.plugin/named/named.node.js +++ /dev/null @@ -1,610 +0,0 @@ -'use strict'; -// SPDX-License-Identifier: GPL-3.0-or-later - -// collect statistics from bind (named) v9.10+ -// -// bind statistics documentation at: -// http://jpmens.net/2013/03/18/json-in-bind-9-s-statistics-server/ -// https://ftp.isc.org/isc/bind/9.10.3/doc/arm/Bv9ARM.ch06.html#statistics - -// example configuration in /etc/netdata/node.d/named.conf -// the module supports auto-detection if bind is running at localhost - -/* -{ - "enable_autodetect": true, - "update_every": 5, - "servers": [ - { - "name": "bind1", - "url": "http://127.0.0.1:8888/json/v1/server", - "update_every": 1 - }, - { - "name": "bind2", - "url": "http://10.0.0.1:8888/xml/v3/server", - "update_every": 2 - } - ] -} -*/ - -// the following is the bind named.conf configuration required - -/* -statistics-channels { - inet 127.0.0.1 port 8888 allow { 127.0.0.1; }; -}; -*/ - -require('url'); -require('http'); -var XML = require('pixl-xml'); -var netdata = require('netdata'); - -if(netdata.options.DEBUG === true) netdata.debug('loaded', __filename, 'plugin'); - -var named = { - name: __filename, - enable_autodetect: true, - update_every: 1, - base_priority: 60000, - charts: {}, - - chartFromMembersCreate: function(service, obj, id, title_suffix, units, family, context, type, priority, algorithm, multiplier, divisor) { - var chart = { - id: id, // the unique id of the chart - name: '', // the unique name of the chart - title: service.name + ' ' + title_suffix, // the title of the chart - units: units, // the units of the chart dimensions - family: family, // the family of the chart - context: context, // the context of the chart - type: type, // the type of the chart - priority: priority, // the priority relative to others in the same family - update_every: service.update_every, // the expected update frequency of the chart - dimensions: {} - }; - - var found = 0; - var dims = Object.keys(obj); - var len = dims.length; - for(var i = 0; i < len ;i++) { - var x = dims[i]; - - if(typeof(obj[x]) !== 'undefined' && obj[x] !== 0) { - found++; - chart.dimensions[x] = { - id: x, // the unique id of the dimension - name: x, // the name of the dimension - algorithm: algorithm, // the id of the netdata algorithm - multiplier: multiplier, // the multiplier - divisor: divisor, // the divisor - hidden: false // is hidden (boolean) - }; - } - } - - if(!found) - return null; - - chart = service.chart(id, chart); - this.charts[id] = chart; - return chart; - }, - - chartFromMembers: function(service, obj, id_suffix, title_suffix, units, family, context, type, priority, algorithm, multiplier, divisor) { - var id = 'named_' + service.name + '.' + id_suffix; - var chart = this.charts[id]; - var dims, len, x, i; - - if(typeof chart === 'undefined') { - chart = this.chartFromMembersCreate(service, obj, id, title_suffix, units, family, context, type, priority, algorithm, multiplier, divisor); - if(chart === null) return false; - } - else { - // check if we need to re-generate the chart - dims = Object.keys(obj); - len = dims.length; - for(i = 0; i < len ;i++) { - x = dims[i]; - if(typeof(chart.dimensions[x]) === 'undefined') { - chart = this.chartFromMembersCreate(service, obj, id, title_suffix, units, family, context, type, priority, algorithm, multiplier, divisor); - if(chart === null) return false; - break; - } - } - } - - service.begin(chart); - - var found = 0; - dims = Object.keys(obj); - len = dims.length; - for(i = 0; i < len ;i++) { - x = dims[i]; - if(typeof(chart.dimensions[x]) !== 'undefined') { - found++; - service.set(x, obj[x]); - } - } - - service.end(); - - return (found > 0); - }, - - // an index to map values to different charts - lookups: { - nsstats: {}, - resolver_stats: {}, - numfetch: {} - }, - - // transform the XML response of bind - // to the JSON response of bind - xml2js: function(service, data_xml) { - var d = XML.parse(data_xml); - if(d === null) return null; - - var a, aa, alen, alen2; - - var data = {}; - var len = d.server.counters.length; - while(len--) { - a = d.server.counters[len]; - if(typeof a.counter === 'undefined') continue; - if(a.type === 'opcode') a.type = 'opcodes'; - else if(a.type === 'qtype') a.type = 'qtypes'; - else if(a.type === 'nsstat') a.type = 'nsstats'; - aa = data[a.type] = {}; - alen = 0; - alen2 = a.counter.length; - while(alen < alen2) { - aa[a.counter[alen].name] = parseInt(a.counter[alen]._Data, 10); - alen++; - } - } - - data.views = {}; - var vlen = d.views.view.length; - while(vlen--) { - var vname = d.views.view[vlen].name; - data.views[vname] = { resolver: {} }; - len = d.views.view[vlen].counters.length; - while(len--) { - a = d.views.view[vlen].counters[len]; - if(typeof a.counter === 'undefined') continue; - if(a.type === 'resstats') a.type = 'stats'; - else if(a.type === 'resqtype') a.type = 'qtypes'; - else if(a.type === 'adbstat') a.type = 'adb'; - aa = data.views[vname].resolver[a.type] = {}; - alen = 0; - alen2 = a.counter.length; - while(alen < alen2) { - aa[a.counter[alen].name] = parseInt(a.counter[alen]._Data, 10); - alen++; - } - } - } - - return data; - }, - - processResponse: function(service, data) { - if(data !== null) { - var r, x, look, id, chart, keys, len; - - // parse XML or JSON - // pepending on the URL given - if(service.request.path.match(/^\/xml/) !== null) - r = named.xml2js(service, data); - else - r = JSON.parse(data); - - if(typeof r === 'undefined' || r === null) { - service.error("Cannot parse these data: " + data.toString()); - return; - } - - if(service.added !== true) - service.commit(); - - if(typeof r.nsstats !== 'undefined') { - // we split the nsstats object to several others - var global_requests = {}, global_requests_enable = false; - var global_failures = {}, global_failures_enable = false; - var global_failures_detail = {}, global_failures_detail_enable = false; - var global_updates = {}, global_updates_enable = false; - var protocol_queries = {}, protocol_queries_enable = false; - var global_queries = {}, global_queries_enable = false; - var global_queries_success = {}, global_queries_success_enable = false; - var default_enable = false; - var RecursClients = 0; - - // RecursClients is an absolute value - if(typeof r.nsstats['RecursClients'] !== 'undefined') { - RecursClients = r.nsstats['RecursClients']; - delete r.nsstats['RecursClients']; - } - - keys = Object.keys(r.nsstats); - len = keys.length; - while(len--) { - x = keys[len]; - - // we maintain an index of the values found - // mapping them to objects split - - look = named.lookups.nsstats[x]; - if(typeof look === 'undefined') { - // a new value, not found in the index - // index it: - if(x === 'Requestv4') { - named.lookups.nsstats[x] = { - name: 'IPv4', - type: 'global_requests' - }; - } - else if(x === 'Requestv6') { - named.lookups.nsstats[x] = { - name: 'IPv6', - type: 'global_requests' - }; - } - else if(x === 'QryFailure') { - named.lookups.nsstats[x] = { - name: 'failures', - type: 'global_failures' - }; - } - else if(x === 'QryUDP') { - named.lookups.nsstats[x] = { - name: 'UDP', - type: 'protocol_queries' - }; - } - else if(x === 'QryTCP') { - named.lookups.nsstats[x] = { - name: 'TCP', - type: 'protocol_queries' - }; - } - else if(x === 'QrySuccess') { - named.lookups.nsstats[x] = { - name: 'queries', - type: 'global_queries_success' - }; - } - else if(x.match(/QryRej$/) !== null) { - named.lookups.nsstats[x] = { - name: x, - type: 'global_failures_detail' - }; - } - else if(x.match(/^Qry/) !== null) { - named.lookups.nsstats[x] = { - name: x, - type: 'global_queries' - }; - } - else if(x.match(/^Update/) !== null) { - named.lookups.nsstats[x] = { - name: x, - type: 'global_updates' - }; - } - else { - // values not mapped, will remain - // in the default map - named.lookups.nsstats[x] = { - name: x, - type: 'default' - }; - } - - look = named.lookups.nsstats[x]; - // netdata.error('lookup nsstats value: ' + x + ' >>> ' + named.lookups.nsstats[x].type); - } - - switch(look.type) { - case 'global_requests': global_requests[look.name] = r.nsstats[x]; delete r.nsstats[x]; global_requests_enable = true; break; - case 'global_queries': global_queries[look.name] = r.nsstats[x]; delete r.nsstats[x]; global_queries_enable = true; break; - case 'global_queries_success': global_queries_success[look.name] = r.nsstats[x]; delete r.nsstats[x]; global_queries_success_enable = true; break; - case 'global_updates': global_updates[look.name] = r.nsstats[x]; delete r.nsstats[x]; global_updates_enable = true; break; - case 'protocol_queries': protocol_queries[look.name] = r.nsstats[x]; delete r.nsstats[x]; protocol_queries_enable = true; break; - case 'global_failures': global_failures[look.name] = r.nsstats[x]; delete r.nsstats[x]; global_failures_enable = true; break; - case 'global_failures_detail': global_failures_detail[look.name] = r.nsstats[x]; delete r.nsstats[x]; global_failures_detail_enable = true; break; - default: default_enable = true; break; - } - } - - if(global_requests_enable === true) - service.module.chartFromMembers(service, global_requests, 'received_requests', 'Bind, Global Received Requests by IP version', 'requests/s', 'requests', 'named.requests', netdata.chartTypes.stacked, named.base_priority + 1, netdata.chartAlgorithms.incremental, 1, 1); - - if(global_queries_success_enable === true) - service.module.chartFromMembers(service, global_queries_success, 'global_queries_success', 'Bind, Global Successful Queries', 'queries/s', 'queries', 'named.queries_success', netdata.chartTypes.line, named.base_priority + 2, netdata.chartAlgorithms.incremental, 1, 1); - - if(protocol_queries_enable === true) - service.module.chartFromMembers(service, protocol_queries, 'protocols_queries', 'Bind, Global Queries by IP Protocol', 'queries/s', 'queries', 'named.protocol_queries', netdata.chartTypes.stacked, named.base_priority + 3, netdata.chartAlgorithms.incremental, 1, 1); - - if(global_queries_enable === true) - service.module.chartFromMembers(service, global_queries, 'global_queries', 'Bind, Global Queries Analysis', 'queries/s', 'queries', 'named.global_queries', netdata.chartTypes.stacked, named.base_priority + 4, netdata.chartAlgorithms.incremental, 1, 1); - - if(global_updates_enable === true) - service.module.chartFromMembers(service, global_updates, 'received_updates', 'Bind, Global Received Updates', 'updates/s', 'updates', 'named.global_updates', netdata.chartTypes.stacked, named.base_priority + 5, netdata.chartAlgorithms.incremental, 1, 1); - - if(global_failures_enable === true) - service.module.chartFromMembers(service, global_failures, 'query_failures', 'Bind, Global Query Failures', 'failures/s', 'failures', 'named.global_failures', netdata.chartTypes.line, named.base_priority + 6, netdata.chartAlgorithms.incremental, 1, 1); - - if(global_failures_detail_enable === true) - service.module.chartFromMembers(service, global_failures_detail, 'query_failures_detail', 'Bind, Global Query Failures Analysis', 'failures/s', 'failures', 'named.global_failures_detail', netdata.chartTypes.stacked, named.base_priority + 7, netdata.chartAlgorithms.incremental, 1, 1); - - if(default_enable === true) - service.module.chartFromMembers(service, r.nsstats, 'nsstats', 'Bind, Other Global Server Statistics', 'operations/s', 'other', 'named.nsstats', netdata.chartTypes.line, named.base_priority + 8, netdata.chartAlgorithms.incremental, 1, 1); - - // RecursClients chart - id = 'named_' + service.name + '.recursive_clients'; - chart = named.charts[id]; - - if(typeof chart === 'undefined') { - chart = { - id: id, // the unique id of the chart - name: '', // the unique name of the chart - title: service.name + ' Bind, Current Recursive Clients', // the title of the chart - units: 'clients', // the units of the chart dimensions - family: 'clients', // the family of the chart - context: 'named.recursive_clients', // the context of the chart - type: netdata.chartTypes.line, // the type of the chart - priority: named.base_priority + 1, // the priority relative to others in the same family - update_every: service.update_every, // the expected update frequency of the chart - dimensions: { - 'clients': { - id: 'clients', // the unique id of the dimension - name: '', // the name of the dimension - algorithm: netdata.chartAlgorithms.absolute,// the id of the netdata algorithm - multiplier: 1, // the multiplier - divisor: 1, // the divisor - hidden: false // is hidden (boolean) - } - } - }; - - chart = service.chart(id, chart); - named.charts[id] = chart; - } - - service.begin(chart); - service.set('clients', RecursClients); - service.end(); - } - - if(typeof r.opcodes !== 'undefined') - service.module.chartFromMembers(service, r.opcodes, 'in_opcodes', 'Bind, Global Incoming Requests by OpCode', 'requests/s', 'requests', 'named.in_opcodes', netdata.chartTypes.stacked, named.base_priority + 9, netdata.chartAlgorithms.incremental, 1, 1); - - if(typeof r.qtypes !== 'undefined') - service.module.chartFromMembers(service, r.qtypes, 'in_qtypes', 'Bind, Global Incoming Requests by Query Type', 'requests/s', 'requests', 'named.in_qtypes', netdata.chartTypes.stacked, named.base_priority + 10, netdata.chartAlgorithms.incremental, 1, 1); - - if(typeof r.sockstats !== 'undefined') - service.module.chartFromMembers(service, r.sockstats, 'in_sockstats', 'Bind, Global Socket Statistics', 'operations/s', 'sockets', 'named.in_sockstats', netdata.chartTypes.line, named.base_priority + 11, netdata.chartAlgorithms.incremental, 1, 1); - - if(typeof r.views !== 'undefined') { - keys = Object.keys(r.views); - len = keys.length; - while(len--) { - x = keys[len]; - var resolver = r.views[x].resolver; - - if(typeof resolver !== 'undefined') { - if(typeof resolver.stats !== 'undefined') { - var NumFetch = 0; - var key = service.name + '.' + x; - var rtt = {}, rtt_enable = false; - default_enable = false; - - // NumFetch is an absolute value - if(typeof resolver.stats['NumFetch'] !== 'undefined') { - named.lookups.numfetch[key] = true; - NumFetch = resolver.stats['NumFetch']; - delete resolver.stats['NumFetch']; - } - if(typeof resolver.stats['BucketSize'] !== 'undefined') { - delete resolver.stats['BucketSize']; - } - - // split the QryRTT* from the main chart - var ykeys = Object.keys(resolver.stats); - var ylen = ykeys.length; - while(ylen--) { - var y = ykeys[ylen]; - - // we maintain an index of the values found - // mapping them to objects split - - look = named.lookups.resolver_stats[y]; - if(typeof look === 'undefined') { - if(y.match(/^QryRTT/) !== null) { - named.lookups.resolver_stats[y] = { - name: y, - type: 'rtt' - }; - } - else { - named.lookups.resolver_stats[y] = { - name: y, - type: 'default' - }; - } - - look = named.lookups.resolver_stats[y]; - // netdata.error('lookup resolver stats value: ' + y + ' >>> ' + look.type); - } - - switch(look.type) { - case 'rtt': rtt[look.name] = resolver.stats[y]; delete resolver.stats[y]; rtt_enable = true; break; - default: default_enable = true; break; - } - } - - if(rtt_enable) - service.module.chartFromMembers(service, rtt, 'view_resolver_rtt_' + x, 'Bind, ' + x + ' View, Resolver Round Trip Timings', 'queries/s', 'view_' + x, 'named.resolver_rtt', netdata.chartTypes.stacked, named.base_priority + 12, netdata.chartAlgorithms.incremental, 1, 1); - - if(default_enable) - service.module.chartFromMembers(service, resolver.stats, 'view_resolver_stats_' + x, 'Bind, ' + x + ' View, Resolver Statistics', 'operations/s', 'view_' + x, 'named.resolver_stats', netdata.chartTypes.line, named.base_priority + 13, netdata.chartAlgorithms.incremental, 1, 1); - - // NumFetch chart - if(typeof named.lookups.numfetch[key] !== 'undefined') { - id = 'named_' + service.name + '.view_resolver_numfetch_' + x; - chart = named.charts[id]; - - if(typeof chart === 'undefined') { - chart = { - id: id, // the unique id of the chart - name: '', // the unique name of the chart - title: service.name + ' Bind, ' + x + ' View, Resolver Active Queries', // the title of the chart - units: 'queries', // the units of the chart dimensions - family: 'view_' + x, // the family of the chart - context: 'named.resolver_active_queries', // the context of the chart - type: netdata.chartTypes.line, // the type of the chart - priority: named.base_priority + 1001, // the priority relative to others in the same family - update_every: service.update_every, // the expected update frequency of the chart - dimensions: { - 'queries': { - id: 'queries', // the unique id of the dimension - name: '', // the name of the dimension - algorithm: netdata.chartAlgorithms.absolute,// the id of the netdata algorithm - multiplier: 1, // the multiplier - divisor: 1, // the divisor - hidden: false // is hidden (boolean) - } - } - }; - - chart = service.chart(id, chart); - named.charts[id] = chart; - } - - service.begin(chart); - service.set('queries', NumFetch); - service.end(); - } - } - } - - if(typeof resolver.qtypes !== 'undefined') - service.module.chartFromMembers(service, resolver.qtypes, 'view_resolver_qtypes_' + x, 'Bind, ' + x + ' View, Requests by Query Type', 'requests/s', 'view_' + x, 'named.resolver_qtypes', netdata.chartTypes.stacked, named.base_priority + 14, netdata.chartAlgorithms.incremental, 1, 1); - - //if(typeof resolver.cache !== 'undefined') - // service.module.chartFromMembers(service, resolver.cache, 'view_resolver_cache_' + x, 'Bind, ' + x + ' View, Cache Entries', 'entries', 'view_' + x, 'named.resolver_cache', netdata.chartTypes.stacked, named.base_priority + 15, netdata.chartAlgorithms.absolute, 1, 1); - - if(typeof resolver.cachestats['CacheHits'] !== 'undefined' && resolver.cachestats['CacheHits'] > 0) { - id = 'named_' + service.name + '.view_resolver_cachehits_' + x; - chart = named.charts[id]; - - if(typeof chart === 'undefined') { - chart = { - id: id, // the unique id of the chart - name: '', // the unique name of the chart - title: service.name + ' Bind, ' + x + ' View, Resolver Cache Hits', // the title of the chart - units: 'operations/s', // the units of the chart dimensions - family: 'view_' + x, // the family of the chart - context: 'named.resolver_cache_hits', // the context of the chart - type: netdata.chartTypes.area, // the type of the chart - priority: named.base_priority + 1100, // the priority relative to others in the same family - update_every: service.update_every, // the expected update frequency of the chart - dimensions: { - 'CacheHits': { - id: 'CacheHits', // the unique id of the dimension - name: 'hits', // the name of the dimension - algorithm: netdata.chartAlgorithms.incremental,// the id of the netdata algorithm - multiplier: 1, // the multiplier - divisor: 1, // the divisor - hidden: false // is hidden (boolean) - }, - 'CacheMisses': { - id: 'CacheMisses', // the unique id of the dimension - name: 'misses', // the name of the dimension - algorithm: netdata.chartAlgorithms.incremental,// the id of the netdata algorithm - multiplier: -1, // the multiplier - divisor: 1, // the divisor - hidden: false // is hidden (boolean) - } - } - }; - - chart = service.chart(id, chart); - named.charts[id] = chart; - } - - service.begin(chart); - service.set('CacheHits', resolver.cachestats['CacheHits']); - service.set('CacheMisses', resolver.cachestats['CacheMisses']); - service.end(); - } - - // this is wrong, it contains many types of info: - // 1. CacheHits, CacheMisses - incremental (added above) - // 2. QueryHits, QueryMisses - incremental - // 3. DeleteLRU, DeleteTTL - incremental - // 4. CacheNodes, CacheBuckets - absolute - // 5. TreeMemTotal, TreeMemInUse - absolute - // 6. HeapMemMax, HeapMemTotal, HeapMemInUse - absolute - //if(typeof resolver.cachestats !== 'undefined') - // service.module.chartFromMembers(service, resolver.cachestats, 'view_resolver_cachestats_' + x, 'Bind, ' + x + ' View, Cache Statistics', 'requests/s', 'view_' + x, 'named.resolver_cache_stats', netdata.chartTypes.line, named.base_priority + 1001, netdata.chartAlgorithms.incremental, 1, 1); - - //if(typeof resolver.adb !== 'undefined') - // service.module.chartFromMembers(service, resolver.adb, 'view_resolver_adb_' + x, 'Bind, ' + x + ' View, ADB Statistics', 'entries', 'view_' + x, 'named.resolver_adb', netdata.chartTypes.line, named.base_priority + 1002, netdata.chartAlgorithms.absolute, 1, 1); - } - } - } - }, - - // module.serviceExecute() - // this function is called only from this module - // its purpose is to prepare the request and call - // netdata.serviceExecute() - serviceExecute: function(name, a_url, update_every) { - if(netdata.options.DEBUG === true) netdata.debug(this.name + ': ' + name + ': url: ' + a_url + ', update_every: ' + update_every); - var service = netdata.service({ - name: name, - request: netdata.requestFromURL(a_url), - update_every: update_every, - module: this - }); - - service.execute(this.processResponse); - }, - - configure: function(config) { - var added = 0; - - if(this.enable_autodetect === true) { - this.serviceExecute('local', 'http://localhost:8888/json/v1/server', this.update_every); - added++; - } - - if(typeof(config.servers) !== 'undefined') { - var len = config.servers.length; - while(len--) { - if(typeof config.servers[len].update_every === 'undefined') - config.servers[len].update_every = this.update_every; - - this.serviceExecute(config.servers[len].name, config.servers[len].url, config.servers[len].update_every); - added++; - } - } - - return added; - }, - - // module.update() - // this is called repeatedly to collect data, by calling - // netdata.serviceExecute() - update: function(service, callback) { - service.execute(function(serv, data) { - service.module.processResponse(serv, data); - callback(); - }); - } -}; - -module.exports = named; diff --git a/collectors/node.d.plugin/node.d.conf b/collectors/node.d.plugin/node.d.conf index 95aec99ce..c79274a5e 100644 --- a/collectors/node.d.plugin/node.d.conf +++ b/collectors/node.d.plugin/node.d.conf @@ -14,12 +14,6 @@ "___help_modules": "Enable/disable the following modules. Give only XXX for node.d/XXX.node.js", "modules": { - "named": { - "enabled": true - }, - "sma_webbox": { - "enabled": true - }, "snmp": { "enabled": true } diff --git a/collectors/node.d.plugin/sma_webbox/Makefile.inc b/collectors/node.d.plugin/sma_webbox/Makefile.inc deleted file mode 100644 index 38f2fe97a..000000000 --- a/collectors/node.d.plugin/sma_webbox/Makefile.inc +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later - -# THIS IS NOT A COMPLETE Makefile -# IT IS INCLUDED BY ITS PARENT'S Makefile.am -# IT IS REQUIRED TO REFERENCE ALL FILES RELATIVE TO THE PARENT - -# install these files -dist_node_DATA += sma_webbox/sma_webbox.node.js -# dist_nodeconfig_DATA += sma_webbox/sma_webbox.conf - -# do not install these files, but include them in the distribution -dist_noinst_DATA += sma_webbox/README.md sma_webbox/Makefile.inc - diff --git a/collectors/node.d.plugin/sma_webbox/README.md b/collectors/node.d.plugin/sma_webbox/README.md deleted file mode 100644 index 99e093b70..000000000 --- a/collectors/node.d.plugin/sma_webbox/README.md +++ /dev/null @@ -1,33 +0,0 @@ - - -# SMA Sunny WebBox monitoring with Netdata - -Monitoring for the [SMA Sunny -WebBox](https://www.sma-sunny.com/en/questions-and-answers-on-discontinuation-of-the-sunny-webbox/). - -The module supports any number of name servers: - -```json -{ - "enable_autodetect": false, - "update_every": 5, - "servers": [ - { - "name": "plant1", - "hostname": "10.0.1.1", - "update_every": 10 - }, - { - "name": "plant2", - "hostname": "10.0.2.1", - "update_every": 15 - } - ] -} -``` - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fnode.d.plugin%2Fsma_webbox%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) diff --git a/collectors/node.d.plugin/sma_webbox/sma_webbox.node.js b/collectors/node.d.plugin/sma_webbox/sma_webbox.node.js deleted file mode 100644 index f32b65714..000000000 --- a/collectors/node.d.plugin/sma_webbox/sma_webbox.node.js +++ /dev/null @@ -1,239 +0,0 @@ -'use strict'; -// SPDX-License-Identifier: GPL-3.0-or-later - -// This program will connect to one or more SMA Sunny Webboxes -// to get the Solar Power Generated (current, today, total). - -// example configuration in /etc/netdata/node.d/sma_webbox.conf -/* -{ - "enable_autodetect": false, - "update_every": 5, - "servers": [ - { - "name": "plant1", - "hostname": "10.0.1.1", - "update_every": 10 - }, - { - "name": "plant2", - "hostname": "10.0.2.1", - "update_every": 15 - } - ] -} -*/ - -require('url'); -require('http'); -var netdata = require('netdata'); - -if(netdata.options.DEBUG === true) netdata.debug('loaded ' + __filename + ' plugin'); - -var webbox = { - name: __filename, - enable_autodetect: true, - update_every: 1, - base_priority: 60000, - charts: {}, - - processResponse: function(service, data) { - if(data !== null) { - var r = JSON.parse(data); - - var d = { - 'GriPwr': { - unit: null, - value: null - }, - 'GriEgyTdy': { - unit: null, - value: null - }, - 'GriEgyTot': { - unit: null, - value: null - } - }; - - // parse the webbox response - // and put it in our d object - var found = 0; - var len = r.result.overview.length; - while(len--) { - var e = r.result.overview[len]; - if(typeof(d[e.meta]) !== 'undefined') { - found++; - d[e.meta].value = e.value; - d[e.meta].unit = e.unit; - } - } - - // add the service - if(found > 0 && service.added !== true) - service.commit(); - - - // Grid Current Power Chart - if(d['GriPwr'].value !== null) { - const id = 'smawebbox_' + service.name + '.current'; - let chart = webbox.charts[id]; - - if(typeof chart === 'undefined') { - chart = { - id: id, // the unique id of the chart - name: '', // the unique name of the chart - title: service.name + ' Current Grid Power', // the title of the chart - units: d['GriPwr'].unit, // the units of the chart dimensions - family: 'now', // the family of the chart - context: 'smawebbox.grid_power', // the context of the chart - type: netdata.chartTypes.area, // the type of the chart - priority: webbox.base_priority + 1, // the priority relative to others in the same family - update_every: service.update_every, // the expected update frequency of the chart - dimensions: { - 'GriPwr': { - id: 'GriPwr', // the unique id of the dimension - name: 'power', // the name of the dimension - algorithm: netdata.chartAlgorithms.absolute,// the id of the netdata algorithm - multiplier: 1, // the multiplier - divisor: 1, // the divisor - hidden: false // is hidden (boolean) - } - } - }; - - chart = service.chart(id, chart); - webbox.charts[id] = chart; - } - - service.begin(chart); - service.set('GriPwr', Math.round(d['GriPwr'].value)); - service.end(); - } - - if(d['GriEgyTdy'].value !== null) { - const id = 'smawebbox_' + service.name + '.today'; - let chart = webbox.charts[id]; - - if(typeof chart === 'undefined') { - chart = { - id: id, // the unique id of the chart - name: '', // the unique name of the chart - title: service.name + ' Today Grid Power', // the title of the chart - units: d['GriEgyTdy'].unit, // the units of the chart dimensions - family: 'today', // the family of the chart - context: 'smawebbox.grid_power_today', // the context of the chart - type: netdata.chartTypes.area, // the type of the chart - priority: webbox.base_priority + 2, // the priority relative to others in the same family - update_every: service.update_every, // the expected update frequency of the chart - dimensions: { - 'GriEgyTdy': { - id: 'GriEgyTdy', // the unique id of the dimension - name: 'power', // the name of the dimension - algorithm: netdata.chartAlgorithms.absolute,// the id of the netdata algorithm - multiplier: 1, // the multiplier - divisor: 1000, // the divisor - hidden: false // is hidden (boolean) - } - } - }; - - chart = service.chart(id, chart); - webbox.charts[id] = chart; - } - - service.begin(chart); - service.set('GriEgyTdy', Math.round(d['GriEgyTdy'].value * 1000)); - service.end(); - } - - if(d['GriEgyTot'].value !== null) { - const id = 'smawebbox_' + service.name + '.total'; - let chart = webbox.charts[id]; - - if(typeof chart === 'undefined') { - chart = { - id: id, // the unique id of the chart - name: '', // the unique name of the chart - title: service.name + ' Total Grid Power', // the title of the chart - units: d['GriEgyTot'].unit, // the units of the chart dimensions - family: 'total', // the family of the chart - context: 'smawebbox.grid_power_total', // the context of the chart - type: netdata.chartTypes.area, // the type of the chart - priority: webbox.base_priority + 3, // the priority relative to others in the same family - update_every: service.update_every, // the expected update frequency of the chart - dimensions: { - 'GriEgyTot': { - id: 'GriEgyTot', // the unique id of the dimension - name: 'power', // the name of the dimension - algorithm: netdata.chartAlgorithms.absolute,// the id of the netdata algorithm - multiplier: 1, // the multiplier - divisor: 1000, // the divisor - hidden: false // is hidden (boolean) - } - } - }; - - chart = service.chart(id, chart); - webbox.charts[id] = chart; - } - - service.begin(chart); - service.set('GriEgyTot', Math.round(d['GriEgyTot'].value * 1000)); - service.end(); - } - } - }, - - // module.serviceExecute() - // this function is called only from this module - // its purpose is to prepare the request and call - // netdata.serviceExecute() - serviceExecute: function(name, hostname, update_every) { - if(netdata.options.DEBUG === true) netdata.debug(this.name + ': ' + name + ': hostname: ' + hostname + ', update_every: ' + update_every); - - var service = netdata.service({ - name: name, - request: netdata.requestFromURL('http://' + hostname + '/rpc'), - update_every: update_every, - module: this - }); - service.postData = 'RPC={"proc":"GetPlantOverview","format":"JSON","version":"1.0","id":"1"}'; - service.request.method = 'POST'; - service.request.headers['Content-Length'] = service.postData.length; - - service.execute(this.processResponse); - }, - - configure: function(config) { - var added = 0; - - if(typeof(config.servers) !== 'undefined') { - var len = config.servers.length; - while(len--) { - if(typeof config.servers[len].update_every === 'undefined') - config.servers[len].update_every = this.update_every; - - if(config.servers[len].update_every < 5) - config.servers[len].update_every = 5; - - this.serviceExecute(config.servers[len].name, config.servers[len].hostname, config.servers[len].update_every); - added++; - } - } - - return added; - }, - - // module.update() - // this is called repeatedly to collect data, by calling - // netdata.serviceExecute() - update: function(service, callback) { - service.execute(function(serv, data) { - service.module.processResponse(serv, data); - callback(); - }); - }, -}; - -module.exports = webbox; diff --git a/collectors/node.d.plugin/snmp/README.md b/collectors/node.d.plugin/snmp/README.md index df6d7eaca..2df94c7b5 100644 --- a/collectors/node.d.plugin/snmp/README.md +++ b/collectors/node.d.plugin/snmp/README.md @@ -442,4 +442,4 @@ This switch has a very slow SNMP processors. To respond, it needs about 8 second } ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fnode.d.plugin%2Fsnmp%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/node.d.plugin/stiebeleltron/Makefile.inc b/collectors/node.d.plugin/stiebeleltron/Makefile.inc deleted file mode 100644 index 0c6e1e213..000000000 --- a/collectors/node.d.plugin/stiebeleltron/Makefile.inc +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later - -# THIS IS NOT A COMPLETE Makefile -# IT IS INCLUDED BY ITS PARENT'S Makefile.am -# IT IS REQUIRED TO REFERENCE ALL FILES RELATIVE TO THE PARENT - -# install these files -dist_node_DATA += stiebeleltron/stiebeleltron.node.js -# dist_nodeconfig_DATA += stiebeleltron/stiebeleltron.conf - -# do not install these files, but include them in the distribution -dist_noinst_DATA += stiebeleltron/README.md stiebeleltron/Makefile.inc - diff --git a/collectors/node.d.plugin/stiebeleltron/README.md b/collectors/node.d.plugin/stiebeleltron/README.md deleted file mode 100644 index 59bbf703c..000000000 --- a/collectors/node.d.plugin/stiebeleltron/README.md +++ /dev/null @@ -1,525 +0,0 @@ - - -# Stiebel Eltron ISG monitoring with Netdata - -Collects metrics from the configured heat pump and hot water installation from Stiebel Eltron ISG web. - -**Requirements** - -- Configuration file `stiebeleltron.conf` in the node.d Netdata config dir (default: `/etc/netdata/node.d/stiebeleltron.conf`) -- Stiebel Eltron ISG web with network access (http), without password login - -The charts are configurable, however, the provided default configuration collects the following: - -1. **General** - - - Outside temperature in C - - Condenser temperature in C - - Heating circuit pressure in bar - - Flow rate in l/min - - Output of water and heat pumps in % - -2. **Heating** - - - Heat circuit 1 temperature in C (set/actual) - - Heat circuit 2 temperature in C (set/actual) - - Flow temperature in C (set/actual) - - Buffer temperature in C (set/actual) - - Pre-flow temperature in C - -3. **Hot Water** - - - Hot water temperature in C (set/actual) - -4. **Room Temperature** - - - Heat circuit 1 room temperature in C (set/actual) - - Heat circuit 2 room temperature in C (set/actual) - -5. **Electric Reheating** - - - Dual Mode Reheating temperature in C (hot water/heating) - -6. **Process Data** - - - Remaining compressor rest time in s - -7. **Runtime** - - - Compressor runtime hours (hot water/heating) - - Reheating runtime hours (reheating 1/reheating 2) - -8. **Energy** - - - Compressor today in kWh (hot water/heating) - - Compressor Total in kWh (hot water/heating) - -## configuration - -If no configuration is given, the module will be disabled. Each `update_every` is optional, the default is `10`. - ---- - -[Stiebel Eltron Heat pump system with ISG](https://www.stiebel-eltron.com/en/home/products-solutions/renewables/controller_energymanagement/internet_servicegateway/isg_web.html) - -Original author: BrainDoctor (github) - -The module supports any metrics that are parsable with RegEx. There is no API that gives direct access to the values (AFAIK), so the "workaround" is to parse the HTML output of the ISG. - -### Testing - -This plugin has been tested within the following environment: - -- ISG version: 8.5.6 -- MFG version: 12 -- Controller version: 9 -- July (summer time, not much activity) -- Interface language: English -- login- and password-less ISG web access (without HTTPS it's useless anyway) -- Heatpump model: WPL 25 I-2 -- Hot water boiler model: 820 WT 1 - -So, if the language is set to english, copy the following configuration into `/etc/netdata/node.d/stiebeleltron.conf` and change the `url`s. - -In my case, the ISG is relatively slow with responding (at least 1s, but also up to 4s). Collecting metrics every 10s is more than enough for me. - -### How to update the config - -- The dimensions support variable digits, the default is `1`. Most of the values printed by ISG are using 1 digit, some use 2. -- The dimensions also support the `multiplier` and `divisor` attributes, however the divisor gets overridden by `digits`, if specified. Default is `1`. -- The test string for the regex is always the whole HTML output from the url. For each parameter you need to have a regular expression that extracts the value from the HTML source in the first capture group. - Recommended: [regexr.com](https://regexr.com/) for testing and matching, [freeformatter.com](https://www.freeformatter.com/json-escape.html) for escaping the newly created regex for the JSON config. - -The charts are being generated using the configuration below. So if your installation is in another language or has other metrics, just adapt the structure or regexes. - -### Configuration template - -```json -{ - "enable_autodetect": false, - "update_every": 10, - "pages": [ - { - "name": "System", - "id": "system", - "url": "http://machine.ip.or.dns/?s=1,0", - "update_every": 10, - "categories": [ - { - "id": "eletricreheating", - "name": "electric reheating", - "charts": [ - { - "title": "Dual Mode Reheating Temperature", - "id": "reheatingtemp", - "unit": "Celsius", - "type": "line", - "prio": 1, - "dimensions": [ - { - "name": "Heating", - "id": "dualmodeheatingtemp", - "regex": "DUAL MODE TEMP HEATING<\\\/td>\\s*(-?[0-9]+,[0-9]+).*<\\\/td>" - }, - { - "name": "Hot Water", - "id" : "dualmodehotwatertemp", - "regex": "DUAL MODE TEMP DHW<\\\/td>\\s*(-?[0-9]+,[0-9]+).*<\\\/td>" - } - ] - } - ] - }, - { - "id": "roomtemp", - "name": "room temperature", - "charts": [ - { - "title": "Heat Circuit 1", - "id": "hc1", - "unit": "Celsius", - "type": "line", - "prio": 1, - "dimensions": [ - { - "name": "Actual", - "id": "actual", - "regex": "\\s*ACTUAL TEMPERATURE HC 1<\\\/td>\\s*(-?[0-9]+,[0-9]+).*<\\\/td>\\s*<\\\/tr>" - }, - { - "name": "Set", - "id" : "set", - "regex": "\\s*SET TEMPERATURE HC 1<\\\/td>\\s*(-?[0-9]+,[0-9]+).*<\\\/td>\\s*<\\\/tr>" - } - ] - }, - { - "title": "Heat Circuit 2", - "id": "hc2", - "unit": "Celsius", - "type": "line", - "prio": 2, - "dimensions": [ - { - "name": "Actual", - "id": "actual", - "regex": "\\s*ACTUAL TEMPERATURE HC 2<\\\/td>\\s*(-?[0-9]+,[0-9]+).*<\\\/td>\\s*<\\\/tr>" - }, - { - "name": "Set", - "id" : "set", - "regex": "\\s*SET TEMPERATURE HC 2<\\\/td>\\s*(-?[0-9]+,[0-9]+).*<\\\/td>\\s*<\\\/tr>" - } - ] - } - ] - }, - { - "id": "heating", - "name": "heating", - "charts": [ - { - "title": "Heat Circuit 1", - "id": "hc1", - "unit": "Celsius", - "type": "line", - "prio": 1, - "dimensions": [ - { - "name": "Actual", - "id": "actual", - "regex": "\\s*ACTUAL TEMPERATURE HC 1<\\\/td>\\s*(-?[0-9]+,[0-9]+).*<\\\/td>\\s*<\\\/tr>" - }, - { - "name": "Set", - "id" : "set", - "regex": "\\s*SET TEMPERATURE HC 1<\\\/td>\\s*(-?[0-9]+,[0-9]+).*<\\\/td>\\s*<\\\/tr>" - } - ] - }, - { - "title": "Heat Circuit 2", - "id": "hc2", - "unit": "Celsius", - "type": "line", - "prio": 2, - "dimensions": [ - { - "name": "Actual", - "id": "actual", - "regex": "\\s*ACTUAL TEMPERATURE HC 2<\\\/td>\\s*(-?[0-9]+,[0-9]+).*<\\\/td>\\s*<\\\/tr>" - }, - { - "name": "Set", - "id" : "set", - "regex": "\\s*SET TEMPERATURE HC 2<\\\/td>\\s*(-?[0-9]+,[0-9]+).*<\\\/td>\\s*<\\\/tr>" - } - ] - }, - { - "title": "Flow Temperature", - "id": "flowtemp", - "unit": "Celsius", - "type": "line", - "prio": 3, - "dimensions": [ - { - "name": "Heating", - "id": "heating", - "regex": "ACTUAL FLOW TEMPERATURE WP<\\\/td>\\s*(-?[0-9]+,[0-9]+).*<\\\/td>" - }, - { - "name": "Reheating", - "id" : "reheating", - "regex": "ACTUAL FLOW TEMPERATURE NHZ<\\\/td>\\s*(-?[0-9]+,[0-9]+).*<\\\/td>" - } - ] - }, - { - "title": "Buffer Temperature", - "id": "buffertemp", - "unit": "Celsius", - "type": "line", - "prio": 4, - "dimensions": [ - { - "name": "Actual", - "id": "actual", - "regex": "ACTUAL BUFFER TEMPERATURE<\\\/td>\\s*(-?[0-9]+,[0-9]+).*<\\\/td>" - }, - { - "name": "Set", - "id" : "set", - "regex": "SET BUFFER TEMPERATURE<\\\/td>\\s*(-?[0-9]+,[0-9]+).*<\\\/td>" - } - ] - }, - { - "title": "Fixed Temperature", - "id": "fixedtemp", - "unit": "Celsius", - "type": "line", - "prio": 5, - "dimensions": [ - { - "name": "Set", - "id" : "setfixed", - "regex": "SET FIXED TEMPERATURE<\\\/td>\\s*(-?[0-9]+,[0-9]+).*<\\\/td>" - } - ] - }, - { - "title": "Pre-flow Temperature", - "id": "preflowtemp", - "unit": "Celsius", - "type": "line", - "prio": 6, - "dimensions": [ - { - "name": "Actual", - "id": "actualreturn", - "regex": "ACTUAL RETURN TEMPERATURE<\\\/td>\\s*(-?[0-9]+,[0-9]+).*<\\\/td>" - } - ] - } - ] - }, - { - "id": "hotwater", - "name": "hot water", - "charts": [ - { - "title": "Hot Water Temperature", - "id": "hotwatertemp", - "unit": "Celsius", - "type": "line", - "prio": 1, - "dimensions": [ - { - "name": "Actual", - "id": "actual", - "regex": "ACTUAL TEMPERATURE<\\\/td>\\s*(-?[0-9]+,[0-9]+).*<\\\/td>" - }, - { - "name": "Set", - "id" : "set", - "regex": "SET TEMPERATURE<\\\/td>\\s*(-?[0-9]+,[0-9]+).*<\\\/td>" - } - ] - } - ] - }, - { - "id": "general", - "name": "general", - "charts": [ - { - "title": "Outside Temperature", - "id": "outside", - "unit": "Celsius", - "type": "line", - "prio": 1, - "dimensions": [ - { - "name": "Outside temperature", - "id": "outsidetemp", - "regex": "OUTSIDE TEMPERATURE<\\\/td>\\s*(-?[0-9]+,[0-9]+).*<\\\/td>\\s*<\\\/tr>" - } - ] - }, - { - "title": "Condenser Temperature", - "id": "condenser", - "unit": "Celsius", - "type": "line", - "prio": 2, - "dimensions": [ - { - "name": "Condenser", - "id": "condenser", - "regex": "CONDENSER TEMP\\.<\\\/td>\\s*(-?[0-9]+,[0-9]+).*<\\\/td>" - } - ] - }, - { - "title": "Heating Circuit Pressure", - "id": "heatingcircuit", - "unit": "bar", - "type": "line", - "prio": 3, - "dimensions": [ - { - "name": "Heating Circuit", - "id": "heatingcircuit", - "digits": 2, - "regex": "PRESSURE HTG CIRC<\\\/td>\\s*(-?[0-9]+,[0-9]*).*<\\\/td>" - } - ] - }, - { - "title": "Flow Rate", - "id": "flowrate", - "unit": "liters/min", - "type": "line", - "prio": 4, - "dimensions": [ - { - "name": "Flow Rate", - "id": "flowrate", - "digits": 2, - "regex": "FLOW RATE<\\\/td>\\s*(-?[0-9]+,[0-9]+).*<\\\/td>" - } - ] - }, - { - "title": "Output", - "id": "output", - "unit": "%", - "type": "line", - "prio": 5, - "dimensions": [ - { - "name": "Heat Pump", - "id": "outputheatpump", - "regex": "OUTPUT HP<\\\/td>\\s*(-?[0-9]+,?[0-9]*).*<\\\/td>" - }, - { - "name": "Water Pump", - "id": "intpumprate", - "regex": "INT PUMP RATE<\\\/td>\\s*(-?[0-9]+,?[0-9]*).*<\\\/td>" - } - ] - } - ] - } - ] - }, - { - "name": "Heat Pump", - "id": "heatpump", - "url": "http://machine.ip.or.dns/?s=1,1", - "update_every": 10, - "categories": [ - { - "id": "runtime", - "name": "runtime", - "charts": [ - { - "title": "Compressor", - "id": "compressor", - "unit": "h", - "type": "line", - "prio": 1, - "dimensions": [ - { - "name": "Heating", - "id": "heating", - "regex": "RNT COMP 1 HEA<\\\/td>\\s*(-?[0-9]+,?[0-9]*)" - }, - { - "name": "Hot Water", - "id" : "hotwater", - "regex": "RNT COMP 1 DHW<\\\/td>\\s*(-?[0-9]+,?[0-9]*)" - } - ] - }, - { - "title": "Reheating", - "id": "reheating", - "unit": "h", - "type": "line", - "prio": 2, - "dimensions": [ - { - "name": "Reheating 1", - "id": "rh1", - "regex": "BH 1<\\\/td>\\s*(-?[0-9]+,?[0-9]*)" - }, - { - "name": "Reheating 2", - "id" : "rh2", - "regex": "BH 2<\\\/td>\\s*(-?[0-9]+,?[0-9]*)" - } - ] - } - ] - }, - { - "id": "processdata", - "name": "process data", - "charts": [ - { - "title": "Remaining Compressor Rest Time", - "id": "remaincomp", - "unit": "s", - "type": "line", - "prio": 1, - "dimensions": [ - { - "name": "Timer", - "id": "timer", - "regex": "COMP DLAY CNTR<\\\/td>\\s*(-?[0-9]+,?[0-9]*)" - } - ] - } - ] - }, - { - "id": "energy", - "name": "energy", - "charts": [ - { - "title": "Compressor Today", - "id": "compressorday", - "unit": "kWh", - "type": "line", - "prio": 1, - "dimensions": [ - { - "name": "Heating", - "id": "heating", - "digits": 3, - "regex": "COMPRESSOR HEATING DAY<\\\/td>\\s*(-?[0-9]+,?[0-9]*)" - }, - { - "name": "Hot Water", - "id": "hotwater", - "digits": 3, - "regex": "COMPRESSOR DHW DAY<\\\/td>\\s*(-?[0-9]+,?[0-9]*)" - } - ] - }, - { - "title": "Compressor Total", - "id": "compressortotal", - "unit": "MWh", - "type": "line", - "prio": 2, - "dimensions": [ - { - "name": "Heating", - "id": "heating", - "digits": 3, - "regex": "COMPRESSOR HEATING TOTAL<\\\/td>\\s*(-?[0-9]+,?[0-9]*)" - }, - { - "name": "Hot Water", - "id": "hotwater", - "digits": 3, - "regex": "COMPRESSOR DHW TOTAL<\\\/td>\\s*(-?[0-9]+,?[0-9]*)" - } - ] - } - ] - } - ] - } - ] -} -``` - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fnode.d.plugin%2Fstiebeleltron%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) diff --git a/collectors/node.d.plugin/stiebeleltron/stiebeleltron.node.js b/collectors/node.d.plugin/stiebeleltron/stiebeleltron.node.js deleted file mode 100644 index 250c26540..000000000 --- a/collectors/node.d.plugin/stiebeleltron/stiebeleltron.node.js +++ /dev/null @@ -1,197 +0,0 @@ -'use strict'; -// SPDX-License-Identifier: GPL-3.0-or-later - -// This program will connect to one Stiebel Eltron ISG for heatpump heating -// to get the heat pump metrics. - -// example configuration in netdata/conf.d/node.d/stiebeleltron.conf.md - -require("url"); -require("http"); -var netdata = require("netdata"); - -netdata.debug("loaded " + __filename + " plugin"); - -var stiebeleltron = { - name: "Stiebel Eltron", - enable_autodetect: false, - update_every: 10, - base_priority: 60000, - charts: {}, - pages: {}, - - createBasicDimension: function (id, name, multiplier, divisor) { - return { - id: id, // the unique id of the dimension - name: name, // the name of the dimension - algorithm: netdata.chartAlgorithms.absolute,// the id of the netdata algorithm - multiplier: multiplier, // the multiplier - divisor: divisor, // the divisor - hidden: false // is hidden (boolean) - }; - }, - - processResponse: function (service, html) { - if (html === null) return; - - // add the service - service.commit(); - - var page = stiebeleltron.pages[service.name]; - var categories = page.categories; - var categoriesCount = categories.length; - while (categoriesCount--) { - var context = { - html: html, - service: service, - category: categories[categoriesCount], - page: page, - chartDefinition: null, - dimension: null - }; - stiebeleltron.processCategory(context); - - } - }, - - processCategory: function (context) { - var charts = context.category.charts; - var chartCount = charts.length; - while (chartCount--) { - context.chartDefinition = charts[chartCount]; - stiebeleltron.processChart(context); - } - }, - - processChart: function (context) { - var dimensions = context.chartDefinition.dimensions; - var dimensionCount = dimensions.length; - context.service.begin(stiebeleltron.getChartFromContext(context)); - - while (dimensionCount--) { - context.dimension = dimensions[dimensionCount]; - stiebeleltron.processDimension(context); - } - context.service.end(); - }, - - processDimension: function (context) { - var dimension = context.dimension; - var match = new RegExp(dimension.regex).exec(context.html); - if (match === null) return; - var value = match[1].replace(",", "."); - // most values have a single digit by default, which requires the values to be multiplied. can be overridden. - if (stiebeleltron.isDefined(dimension.digits)) { - value *= Math.pow(10, dimension.digits); - } else { - value *= 10; - } - context.service.set(stiebeleltron.getDimensionId(context), value); - }, - - getChartFromContext: function (context) { - var chartId = this.getChartId(context); - var chart = stiebeleltron.charts[chartId]; - if (stiebeleltron.isDefined(chart)) return chart; - - var chartDefinition = context.chartDefinition; - var service = context.service; - var dimensions = {}; - - var dimCount = chartDefinition.dimensions.length; - while (dimCount--) { - var dim = chartDefinition.dimensions[dimCount]; - var multiplier = 1; - var divisor = 10; - if (stiebeleltron.isDefined(dim.digits)) divisor = Math.pow(10, Math.max(0, dim.digits)); - if (stiebeleltron.isDefined(dim.multiplier)) multiplier = dim.multiplier; - if (stiebeleltron.isDefined(dim.divisor)) divisor = dim.divisor; - context.dimension = dim; - var dimId = this.getDimensionId(context); - dimensions[dimId] = this.createBasicDimension(dimId, dim.name, multiplier, divisor); - } - - chart = { - id: chartId, - name: '', - title: chartDefinition.title, - units: chartDefinition.unit, - family: context.category.name, - context: 'stiebeleltron.' + context.category.id + '.' + chartDefinition.id, - type: chartDefinition.type, - priority: stiebeleltron.base_priority + chartDefinition.prio,// the priority relative to others in the same family - update_every: service.update_every, // the expected update frequency of the chart - dimensions: dimensions - }; - chart = service.chart(chartId, chart); - stiebeleltron.charts[chartId] = chart; - - return chart; - }, - - // module.serviceExecute() - // this function is called only from this module - // its purpose is to prepare the request and call - // netdata.serviceExecute() - serviceExecute: function (name, uri, update_every) { - netdata.debug(this.name + ': ' + name + ': url: ' + uri + ', update_every: ' + update_every); - - var service = netdata.service({ - name: name, - request: netdata.requestFromURL(uri), - update_every: update_every, - module: this - }); - service.execute(this.processResponse); - }, - - - configure: function (config) { - if (stiebeleltron.isUndefined(config.pages)) return 0; - var added = 0; - var pageCount = config.pages.length; - while (pageCount--) { - var page = config.pages[pageCount]; - // some validation - if (stiebeleltron.isUndefined(page.categories) || page.categories.length < 1) { - netdata.error("Your Stiebel Eltron config is invalid. Disabling plugin."); - return 0; - } - if (stiebeleltron.isUndefined(page.update_every)) page.update_every = this.update_every; - this.pages[page.name] = page; - this.serviceExecute(page.name, page.url, page.update_every); - added++; - } - return added; - }, - - // module.update() - // this is called repeatedly to collect data, by calling - // netdata.serviceExecute() - update: function (service, callback) { - service.execute(function (serv, data) { - service.module.processResponse(serv, data); - callback(); - }); - }, - - getChartId: function (context) { - return "stiebeleltron_" + context.page.id + - "." + context.category.id + - "." + context.chartDefinition.id; - }, - - getDimensionId: function (context) { - return context.dimension.id; - }, - - isUndefined: function (value) { - return typeof value === 'undefined'; - }, - - isDefined: function (value) { - return typeof value !== 'undefined'; - } -}; - -module.exports = stiebeleltron; diff --git a/collectors/perf.plugin/README.md b/collectors/perf.plugin/README.md index ccd185ced..a7a87aca2 100644 --- a/collectors/perf.plugin/README.md +++ b/collectors/perf.plugin/README.md @@ -77,4 +77,4 @@ sudo /usr/libexec/netdata/plugins.d/perf.plugin 1 all debug You will get verbose output on what the plugin does. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fperf.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/plugins.d/README.md b/collectors/plugins.d/README.md index c166e11e3..ac838d21d 100644 --- a/collectors/plugins.d/README.md +++ b/collectors/plugins.d/README.md @@ -231,7 +231,7 @@ the template is: - `options` - a space separated list of options, enclosed in quotes. 4 options are currently supported: `obsolete` to mark a chart as obsolete (Netdata will hide it and delete it after some time), `detail` to mark a chart as insignificant (this may be used by dashboards to make the charts smaller, or somehow visualize properly a less important chart), `store_first` to make Netdata store the first collected value, assuming there was an invisible previous value set to zero (this is used by statsd charts - if the first data collected value of incremental dimensions is not zero based, unrealistic spikes will appear with this option set) and `hidden` to perform all operations on a chart, but do not offer it on dashboards (the chart will be send to backends). `CHART` options have been added in Netdata v1.7 and the `hidden` option was added in 1.10. + a space separated list of options, enclosed in quotes. 4 options are currently supported: `obsolete` to mark a chart as obsolete (Netdata will hide it and delete it after some time), `detail` to mark a chart as insignificant (this may be used by dashboards to make the charts smaller, or somehow visualize properly a less important chart), `store_first` to make Netdata store the first collected value, assuming there was an invisible previous value set to zero (this is used by statsd charts - if the first data collected value of incremental dimensions is not zero based, unrealistic spikes will appear with this option set) and `hidden` to perform all operations on a chart, but do not offer it on dashboards (the chart will be send to external databases). `CHART` options have been added in Netdata v1.7 and the `hidden` option was added in 1.10. - `plugin` and `module` @@ -252,7 +252,7 @@ the template is: the `id` of this dimension (it is a text value, not numeric), this will be needed later to add values to the dimension - We suggest to avoid using `.` in dimension ids. Backends expect metrics to be `.` separated and people will get confused if a dimension id contains a dot. + We suggest to avoid using `.` in dimension ids. External databases expect metrics to be `.` separated and people will get confused if a dimension id contains a dot. - `name` @@ -481,4 +481,4 @@ There are a few rules for writing plugins properly: 4. If possible, try to autodetect if your plugin should be enabled, without any configuration. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fplugins.d%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/plugins.d/plugins_d.c b/collectors/plugins.d/plugins_d.c index 42889fa8c..614e43d58 100644 --- a/collectors/plugins.d/plugins_d.c +++ b/collectors/plugins.d/plugins_d.c @@ -36,7 +36,7 @@ inline int config_isspace(char c) } // split a text into words, respecting quotes -static inline int quoted_strings_splitter(char *str, char **words, int max_words, int (*custom_isspace)(char), char *recover_input, char **recover_location, int max_recover) +inline int quoted_strings_splitter(char *str, char **words, int max_words, int (*custom_isspace)(char), char *recover_input, char **recover_location, int max_recover) { char *s = str, quote = 0; int i = 0, j, rec = 0; diff --git a/collectors/plugins.d/plugins_d.h b/collectors/plugins.d/plugins_d.h index 8f0b02857..e0b8ac570 100644 --- a/collectors/plugins.d/plugins_d.h +++ b/collectors/plugins.d/plugins_d.h @@ -66,5 +66,6 @@ extern int pluginsd_initialize_plugin_directories(); extern int config_isspace(char c); extern int pluginsd_space(char c); +int quoted_strings_splitter(char *str, char **words, int max_words, int (*custom_isspace)(char), char *recover_input, char **recover_location, int max_recover); #endif /* NETDATA_PLUGINS_D_H */ diff --git a/collectors/plugins.d/pluginsd_parser.c b/collectors/plugins.d/pluginsd_parser.c index c0dcedb67..22b77362f 100644 --- a/collectors/plugins.d/pluginsd_parser.c +++ b/collectors/plugins.d/pluginsd_parser.c @@ -132,13 +132,18 @@ PARSER_RC pluginsd_dimension_action(void *user, RRDSET *st, char *id, char *name rrddim_is_obsolete(st, rd); else rrddim_isnot_obsolete(st, rd); - if (strstr(options, "hidden") != NULL) + if (strstr(options, "hidden") != NULL) { rrddim_flag_set(rd, RRDDIM_FLAG_HIDDEN); + (void) sql_set_dimension_option(&rd->state->metric_uuid, "hidden"); + } + else + (void) sql_set_dimension_option(&rd->state->metric_uuid, NULL); if (strstr(options, "noreset") != NULL) rrddim_flag_set(rd, RRDDIM_FLAG_DONT_DETECT_RESETS_OR_OVERFLOWS); if (strstr(options, "nooverflow") != NULL) rrddim_flag_set(rd, RRDDIM_FLAG_DONT_DETECT_RESETS_OR_OVERFLOWS); } else { + (void) sql_set_dimension_option(&rd->state->metric_uuid, NULL); rrddim_isnot_obsolete(st, rd); } return PARSER_RC_OK; diff --git a/collectors/proc.plugin/README.md b/collectors/proc.plugin/README.md index a9ce2dfa5..32e2112af 100644 --- a/collectors/proc.plugin/README.md +++ b/collectors/proc.plugin/README.md @@ -604,4 +604,4 @@ As far as the message queue charts are dynamic, sane limits are applied for the # max dimensions in memory allowed = 50 ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fproc.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/proc.plugin/proc_interrupts.c b/collectors/proc.plugin/proc_interrupts.c index 2db980a03..78883c475 100644 --- a/collectors/proc.plugin/proc_interrupts.c +++ b/collectors/proc.plugin/proc_interrupts.c @@ -210,7 +210,7 @@ int do_proc_interrupts(int update_every, usec_t dt) { snprintfz(id, 50, "cpu%d_interrupts", c); char title[100+1]; - snprintfz(title, 100, "CPU%d Interrupts", c); + snprintfz(title, 100, "CPU Interrupts"); core_st[c] = rrdset_create_localhost( "cpu" , id diff --git a/collectors/proc.plugin/proc_net_dev.c b/collectors/proc.plugin/proc_net_dev.c index e06da69aa..2d1ae93ae 100644 --- a/collectors/proc.plugin/proc_net_dev.c +++ b/collectors/proc.plugin/proc_net_dev.c @@ -75,6 +75,19 @@ static struct netdev { const char *chart_id_net_carrier; const char *chart_id_net_mtu; + const char *chart_ctx_net_bytes; + const char *chart_ctx_net_packets; + const char *chart_ctx_net_errors; + const char *chart_ctx_net_fifo; + const char *chart_ctx_net_events; + const char *chart_ctx_net_drops; + const char *chart_ctx_net_compressed; + const char *chart_ctx_net_speed; + const char *chart_ctx_net_duplex; + const char *chart_ctx_net_operstate; + const char *chart_ctx_net_carrier; + const char *chart_ctx_net_mtu; + const char *chart_family; struct label *chart_labels; @@ -241,6 +254,19 @@ static void netdev_free_chart_strings(struct netdev *d) { freez((void *)d->chart_id_net_carrier); freez((void *)d->chart_id_net_mtu); + freez((void *)d->chart_ctx_net_bytes); + freez((void *)d->chart_ctx_net_compressed); + freez((void *)d->chart_ctx_net_drops); + freez((void *)d->chart_ctx_net_errors); + freez((void *)d->chart_ctx_net_events); + freez((void *)d->chart_ctx_net_fifo); + freez((void *)d->chart_ctx_net_packets); + freez((void *)d->chart_ctx_net_speed); + freez((void *)d->chart_ctx_net_duplex); + freez((void *)d->chart_ctx_net_operstate); + freez((void *)d->chart_ctx_net_carrier); + freez((void *)d->chart_ctx_net_mtu); + freez((void *)d->chart_family); } @@ -384,40 +410,42 @@ static inline void netdev_rename_cgroup(struct netdev *d, struct netdev_rename * snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_%s", r->container_device); d->chart_id_net_bytes = strdupz(buffer); - snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_compressed_%s", r->container_device); d->chart_id_net_compressed = strdupz(buffer); - snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_drops_%s", r->container_device); d->chart_id_net_drops = strdupz(buffer); - snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_errors_%s", r->container_device); d->chart_id_net_errors = strdupz(buffer); - snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_events_%s", r->container_device); d->chart_id_net_events = strdupz(buffer); - snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_fifo_%s", r->container_device); d->chart_id_net_fifo = strdupz(buffer); - snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_packets_%s", r->container_device); d->chart_id_net_packets = strdupz(buffer); - snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_speed_%s", r->container_device); d->chart_id_net_speed = strdupz(buffer); - snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_duplex_%s", r->container_device); d->chart_id_net_duplex = strdupz(buffer); - snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_operstate_%s", r->container_device); d->chart_id_net_operstate = strdupz(buffer); - snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_carrier_%s", r->container_device); d->chart_id_net_carrier = strdupz(buffer); - snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_mtu_%s", r->container_device); d->chart_id_net_mtu = strdupz(buffer); + d->chart_ctx_net_bytes = strdupz("cgroup.net_net"); + d->chart_ctx_net_compressed = strdupz("cgroup.net_compressed"); + d->chart_ctx_net_drops = strdupz("cgroup.net_drops"); + d->chart_ctx_net_errors = strdupz("cgroup.net_errors"); + d->chart_ctx_net_events = strdupz("cgroup.net_events"); + d->chart_ctx_net_fifo = strdupz("cgroup.net_fifo"); + d->chart_ctx_net_packets = strdupz("cgroup.net_packets"); + d->chart_ctx_net_speed = strdupz("cgroup.net_speed"); + d->chart_ctx_net_duplex = strdupz("cgroup.net_duplex"); + d->chart_ctx_net_operstate = strdupz("cgroup.net_operstate"); + d->chart_ctx_net_carrier = strdupz("cgroup.net_carrier"); + d->chart_ctx_net_mtu = strdupz("cgroup.net_mtu"); + snprintfz(buffer, RRD_ID_LENGTH_MAX, "net %s", r->container_device); d->chart_family = strdupz(buffer); @@ -541,6 +569,19 @@ static struct netdev *get_netdev(const char *name) { d->chart_id_net_carrier = strdupz(d->name); d->chart_id_net_mtu = strdupz(d->name); + d->chart_ctx_net_bytes = strdupz("net.net"); + d->chart_ctx_net_compressed = strdupz("net.compressed"); + d->chart_ctx_net_drops = strdupz("net.drops"); + d->chart_ctx_net_errors = strdupz("net.errors"); + d->chart_ctx_net_events = strdupz("net.events"); + d->chart_ctx_net_fifo = strdupz("net.fifo"); + d->chart_ctx_net_packets = strdupz("net.packets"); + d->chart_ctx_net_speed = strdupz("net.speed"); + d->chart_ctx_net_duplex = strdupz("net.duplex"); + d->chart_ctx_net_operstate = strdupz("net.operstate"); + d->chart_ctx_net_carrier = strdupz("net.carrier"); + d->chart_ctx_net_mtu = strdupz("net.mtu"); + d->chart_family = strdupz(d->name); d->priority = NETDATA_CHART_PRIO_FIRST_NET_IFACE; @@ -825,7 +866,7 @@ int do_proc_net_dev(int update_every, usec_t dt) { , d->chart_id_net_bytes , NULL , d->chart_family - , "net.net" + , d->chart_ctx_net_bytes , "Bandwidth" , "kilobits/s" , PLUGIN_PROC_NAME @@ -881,7 +922,7 @@ int do_proc_net_dev(int update_every, usec_t dt) { , d->chart_id_net_speed , NULL , d->chart_family - , "net.speed" + , d->chart_ctx_net_speed , "Interface Speed" , "kilobits/s" , PLUGIN_PROC_NAME @@ -916,7 +957,7 @@ int do_proc_net_dev(int update_every, usec_t dt) { , d->chart_id_net_duplex , NULL , d->chart_family - , "net.duplex" + , d->chart_ctx_net_duplex , "Interface Duplex State" , "state" , PLUGIN_PROC_NAME @@ -947,7 +988,7 @@ int do_proc_net_dev(int update_every, usec_t dt) { , d->chart_id_net_operstate , NULL , d->chart_family - , "net.operstate" + , d->chart_ctx_net_operstate , "Interface Operational State" , "state" , PLUGIN_PROC_NAME @@ -978,7 +1019,7 @@ int do_proc_net_dev(int update_every, usec_t dt) { , d->chart_id_net_carrier , NULL , d->chart_family - , "net.carrier" + , d->chart_ctx_net_carrier , "Interface Physical Link State" , "state" , PLUGIN_PROC_NAME @@ -1009,7 +1050,7 @@ int do_proc_net_dev(int update_every, usec_t dt) { , d->chart_id_net_mtu , NULL , d->chart_family - , "net.mtu" + , d->chart_ctx_net_mtu , "Interface MTU" , "octets" , PLUGIN_PROC_NAME @@ -1045,7 +1086,7 @@ int do_proc_net_dev(int update_every, usec_t dt) { , d->chart_id_net_packets , NULL , d->chart_family - , "net.packets" + , d->chart_ctx_net_packets , "Packets" , "packets/s" , PLUGIN_PROC_NAME @@ -1093,7 +1134,7 @@ int do_proc_net_dev(int update_every, usec_t dt) { , d->chart_id_net_errors , NULL , d->chart_family - , "net.errors" + , d->chart_ctx_net_errors , "Interface Errors" , "errors/s" , PLUGIN_PROC_NAME @@ -1139,7 +1180,7 @@ int do_proc_net_dev(int update_every, usec_t dt) { , d->chart_id_net_drops , NULL , d->chart_family - , "net.drops" + , d->chart_ctx_net_drops , "Interface Drops" , "drops/s" , PLUGIN_PROC_NAME @@ -1185,7 +1226,7 @@ int do_proc_net_dev(int update_every, usec_t dt) { , d->chart_id_net_fifo , NULL , d->chart_family - , "net.fifo" + , d->chart_ctx_net_fifo , "Interface FIFO Buffer Errors" , "errors" , PLUGIN_PROC_NAME @@ -1231,7 +1272,7 @@ int do_proc_net_dev(int update_every, usec_t dt) { , d->chart_id_net_compressed , NULL , d->chart_family - , "net.compressed" + , d->chart_ctx_net_compressed , "Compressed Packets" , "packets/s" , PLUGIN_PROC_NAME @@ -1277,7 +1318,7 @@ int do_proc_net_dev(int update_every, usec_t dt) { , d->chart_id_net_events , NULL , d->chart_family - , "net.events" + , d->chart_ctx_net_events , "Network Interface Events" , "events/s" , PLUGIN_PROC_NAME diff --git a/collectors/proc.plugin/proc_net_softnet_stat.c b/collectors/proc.plugin/proc_net_softnet_stat.c index a29ccccd1..1f704a427 100644 --- a/collectors/proc.plugin/proc_net_softnet_stat.c +++ b/collectors/proc.plugin/proc_net_softnet_stat.c @@ -117,7 +117,7 @@ int do_proc_net_softnet_stat(int update_every, usec_t dt) { st = rrdset_find_active_bytype_localhost("cpu", id); if(unlikely(!st)) { char title[100+1]; - snprintfz(title, 100, "CPU%zu softnet_stat", l); + snprintfz(title, 100, "CPU softnet_stat"); st = rrdset_create_localhost( "cpu" diff --git a/collectors/proc.plugin/proc_softirqs.c b/collectors/proc.plugin/proc_softirqs.c index d68c69bb7..bb14c1596 100644 --- a/collectors/proc.plugin/proc_softirqs.c +++ b/collectors/proc.plugin/proc_softirqs.c @@ -201,7 +201,7 @@ int do_proc_softirqs(int update_every, usec_t dt) { snprintfz(id, 50, "cpu%d_softirqs", c); char title[100 + 1]; - snprintfz(title, 100, "CPU%d softirqs", c); + snprintfz(title, 100, "CPU softirqs"); core_st[c] = rrdset_create_localhost( "cpu" diff --git a/collectors/proc.plugin/sys_fs_btrfs.c b/collectors/proc.plugin/sys_fs_btrfs.c index 4e58a1a4c..e28b60a7a 100644 --- a/collectors/proc.plugin/sys_fs_btrfs.c +++ b/collectors/proc.plugin/sys_fs_btrfs.c @@ -552,7 +552,7 @@ int do_sys_fs_btrfs(int update_every, usec_t dt) { snprintf(id, RRD_ID_LENGTH_MAX, "disk_%s", node->id); snprintf(name, RRD_ID_LENGTH_MAX, "disk_%s", node->label); - snprintf(title, 200, "BTRFS Physical Disk Allocation for %s", node->label); + snprintf(title, 200, "BTRFS Physical Disk Allocation"); netdata_fix_chart_id(id); netdata_fix_chart_name(name); @@ -610,7 +610,7 @@ int do_sys_fs_btrfs(int update_every, usec_t dt) { snprintf(id, RRD_ID_LENGTH_MAX, "data_%s", node->id); snprintf(name, RRD_ID_LENGTH_MAX, "data_%s", node->label); - snprintf(title, 200, "BTRFS Data Allocation for %s", node->label); + snprintf(title, 200, "BTRFS Data Allocation"); netdata_fix_chart_id(id); netdata_fix_chart_name(name); @@ -653,7 +653,7 @@ int do_sys_fs_btrfs(int update_every, usec_t dt) { snprintf(id, RRD_ID_LENGTH_MAX, "metadata_%s", node->id); snprintf(name, RRD_ID_LENGTH_MAX, "metadata_%s", node->label); - snprintf(title, 200, "BTRFS Metadata Allocation for %s", node->label); + snprintf(title, 200, "BTRFS Metadata Allocation"); netdata_fix_chart_id(id); netdata_fix_chart_name(name); @@ -698,7 +698,7 @@ int do_sys_fs_btrfs(int update_every, usec_t dt) { snprintf(id, RRD_ID_LENGTH_MAX, "system_%s", node->id); snprintf(name, RRD_ID_LENGTH_MAX, "system_%s", node->label); - snprintf(title, 200, "BTRFS System Allocation for %s", node->label); + snprintf(title, 200, "BTRFS System Allocation"); netdata_fix_chart_id(id); netdata_fix_chart_name(name); diff --git a/collectors/python.d.plugin/README.md b/collectors/python.d.plugin/README.md index 9170350fb..7c060f811 100644 --- a/collectors/python.d.plugin/README.md +++ b/collectors/python.d.plugin/README.md @@ -16,7 +16,6 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/collectors/pytho ## Disclaimer -Every module should be compatible with python2 and python3. All third party libraries should be installed system-wide or in `python_modules` directory. Module configurations are written in YAML and **pyYAML is required**. @@ -77,7 +76,6 @@ Writing new python module is simple. You just need to remember to include 5 majo - **CHART** global dictionary - **Service** class - **\_get_data** method -- all code needs to be compatible with Python 2 (**≥ 2.7**) *and* 3 (**≥ 3.1**) If you plan to submit the module in a PR, make sure and go through the [PR checklist for new modules](#pull-request-checklist-for-python-plugins) beforehand to make sure you have updated all the files you need to. @@ -270,4 +268,4 @@ At minimum, to be buildable and testable, the PR needs to include: - Optionally, chart information in `web/gui/dashboard_info.js`. This generally involves specifying a name and icon for the section, and may include descriptions for the section or individual charts. - Optionally, some default alarm configurations for your collector in `health/health.d/.conf` and a line adding `.conf` in `health/Makefile.am`. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/adaptec_raid/README.md b/collectors/python.d.plugin/adaptec_raid/README.md index 4e99508b3..da5d13b16 100644 --- a/collectors/python.d.plugin/adaptec_raid/README.md +++ b/collectors/python.d.plugin/adaptec_raid/README.md @@ -77,4 +77,4 @@ sudo ./edit-config python.d/adaptec_raid.conf --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fadaptec_raid%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/alarms/README.md b/collectors/python.d.plugin/alarms/README.md index 3f2a8176e..cd5e1b817 100644 --- a/collectors/python.d.plugin/alarms/README.md +++ b/collectors/python.d.plugin/alarms/README.md @@ -56,5 +56,3 @@ local: ``` It will default to pulling all alarms at each time step from the Netdata rest api at `http://127.0.0.1:19999/api/v1/alarms?all` - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Falarms%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]() diff --git a/collectors/python.d.plugin/am2320/README.md b/collectors/python.d.plugin/am2320/README.md index 14ddaa735..3503d7c17 100644 --- a/collectors/python.d.plugin/am2320/README.md +++ b/collectors/python.d.plugin/am2320/README.md @@ -51,4 +51,3 @@ Software install: - restart the netdata service. - check the dashboard. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fam2320%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]() diff --git a/collectors/python.d.plugin/anomalies/README.md b/collectors/python.d.plugin/anomalies/README.md index 3552053ee..32e79a82f 100644 --- a/collectors/python.d.plugin/anomalies/README.md +++ b/collectors/python.d.plugin/anomalies/README.md @@ -241,4 +241,3 @@ If you would like to go deeper on what exactly the anomalies collector is doing - Good [blog post](https://www.anodot.com/blog/what-is-anomaly-detection/) from Anodot on time series anomaly detection. Anodot also have some great whitepapers in this space too that some may find useful. - Novelty and outlier detection in the [scikit-learn documentation](https://scikit-learn.org/stable/modules/outlier_detection.html). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fanomalies%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]() diff --git a/collectors/python.d.plugin/apache/README.md b/collectors/python.d.plugin/apache/README.md index d27525095..c6086835f 100644 --- a/collectors/python.d.plugin/apache/README.md +++ b/collectors/python.d.plugin/apache/README.md @@ -79,4 +79,4 @@ Without configuration, module attempts to connect to `http://localhost/server-st --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fapache%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/beanstalk/README.md b/collectors/python.d.plugin/beanstalk/README.md index 24315adb4..3b632597e 100644 --- a/collectors/python.d.plugin/beanstalk/README.md +++ b/collectors/python.d.plugin/beanstalk/README.md @@ -130,4 +130,4 @@ If no configuration is given, module will attempt to connect to beanstalkd on `1 --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fbeanstalk%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/beanstalk/beanstalk.conf b/collectors/python.d.plugin/beanstalk/beanstalk.conf index 7586ad26b..6d9773a19 100644 --- a/collectors/python.d.plugin/beanstalk/beanstalk.conf +++ b/collectors/python.d.plugin/beanstalk/beanstalk.conf @@ -43,7 +43,7 @@ # When a plugin sends the obsolete flag, the charts are not deleted # from netdata immediately. # They will be hidden immediately (not offered to dashboard viewer, -# streamed upstream and archived to backends) and deleted one hour +# streamed upstream and archived to external databases) and deleted one hour # later (configurable from netdata.conf). # chart_cleanup: 10 diff --git a/collectors/python.d.plugin/bind_rndc/README.md b/collectors/python.d.plugin/bind_rndc/README.md index 2832575dd..2d747f81b 100644 --- a/collectors/python.d.plugin/bind_rndc/README.md +++ b/collectors/python.d.plugin/bind_rndc/README.md @@ -76,4 +76,4 @@ If no configuration is given, module will attempt to read named.stats file at ` --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fbind_rndc%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/boinc/README.md b/collectors/python.d.plugin/boinc/README.md index bd509c900..4da2d52bf 100644 --- a/collectors/python.d.plugin/boinc/README.md +++ b/collectors/python.d.plugin/boinc/README.md @@ -38,4 +38,4 @@ remote: --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fboinc%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/ceph/README.md b/collectors/python.d.plugin/ceph/README.md index 5d671f2aa..b75ba6d4f 100644 --- a/collectors/python.d.plugin/ceph/README.md +++ b/collectors/python.d.plugin/ceph/README.md @@ -45,4 +45,4 @@ local: --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fceph%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/changefinder/README.md b/collectors/python.d.plugin/changefinder/README.md index 051639d1e..7ec3a2539 100644 --- a/collectors/python.d.plugin/changefinder/README.md +++ b/collectors/python.d.plugin/changefinder/README.md @@ -215,4 +215,3 @@ sudo su -s /bin/bash netdata - Novelty and outlier detection in the [scikit-learn documentation](https://scikit-learn.org/stable/modules/outlier_detection.html). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fchangefinder%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]() diff --git a/collectors/python.d.plugin/chrony/README.md b/collectors/python.d.plugin/chrony/README.md index 4681b4f6d..3093ec3f9 100644 --- a/collectors/python.d.plugin/chrony/README.md +++ b/collectors/python.d.plugin/chrony/README.md @@ -58,4 +58,4 @@ local: Save the file and restart the Netdata Agent with `sudo systemctl restart netdata`, or the [appropriate method](/docs/configure/start-stop-restart.md) for your system, to finish configuring the `chrony` collector. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fchrony%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/couchdb/README.md b/collectors/python.d.plugin/couchdb/README.md index 896bbdd31..d359c8f7c 100644 --- a/collectors/python.d.plugin/couchdb/README.md +++ b/collectors/python.d.plugin/couchdb/README.md @@ -50,4 +50,4 @@ local: --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fcouchdb%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/dns_query_time/README.md b/collectors/python.d.plugin/dns_query_time/README.md index e1fde7471..365e22560 100644 --- a/collectors/python.d.plugin/dns_query_time/README.md +++ b/collectors/python.d.plugin/dns_query_time/README.md @@ -26,4 +26,4 @@ sudo ./edit-config python.d/dns_query_time.conf --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fdns_query_time%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/dnsdist/README.md b/collectors/python.d.plugin/dnsdist/README.md index 7c279efaf..95b2efae0 100644 --- a/collectors/python.d.plugin/dnsdist/README.md +++ b/collectors/python.d.plugin/dnsdist/README.md @@ -69,4 +69,4 @@ localhost: X-API-Key: 'dnsdist-api-key' ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fdnsdist%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/dockerd/README.md b/collectors/python.d.plugin/dockerd/README.md index 178bae2cc..6470a7c0b 100644 --- a/collectors/python.d.plugin/dockerd/README.md +++ b/collectors/python.d.plugin/dockerd/README.md @@ -43,4 +43,4 @@ sudo ./edit-config python.d/dockerd.conf --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fdockerd%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/dovecot/README.md b/collectors/python.d.plugin/dovecot/README.md index 730b64257..e6bbf0d74 100644 --- a/collectors/python.d.plugin/dovecot/README.md +++ b/collectors/python.d.plugin/dovecot/README.md @@ -102,4 +102,4 @@ If no configuration is given, module will attempt to connect to dovecot using un --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fdovecot%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/elasticsearch/README.md b/collectors/python.d.plugin/elasticsearch/README.md index cf1834c5a..a98eddf51 100644 --- a/collectors/python.d.plugin/elasticsearch/README.md +++ b/collectors/python.d.plugin/elasticsearch/README.md @@ -91,4 +91,4 @@ If no configuration is given, module will try to connect to `http://127.0.0.1:92 --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Felasticsearch%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/energid/README.md b/collectors/python.d.plugin/energid/README.md index 60c829fed..73e39ae14 100644 --- a/collectors/python.d.plugin/energid/README.md +++ b/collectors/python.d.plugin/energid/README.md @@ -74,4 +74,4 @@ bitcoin: --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fenergid%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/example/README.md b/collectors/python.d.plugin/example/README.md index b1c21ecbc..0b80aa9ea 100644 --- a/collectors/python.d.plugin/example/README.md +++ b/collectors/python.d.plugin/example/README.md @@ -11,4 +11,4 @@ Netdata provides an [example python data collection module](https://github.com/n If you want to write your own collector, read our [writing a new Python module](/collectors/python.d.plugin/README.md#how-to-write-a-new-module) tutorial. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fexample%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/exim/README.md b/collectors/python.d.plugin/exim/README.md index 240aa7bed..92b2d7a5b 100644 --- a/collectors/python.d.plugin/exim/README.md +++ b/collectors/python.d.plugin/exim/README.md @@ -38,4 +38,4 @@ Configuration is not needed. --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fexim%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/fail2ban/README.md b/collectors/python.d.plugin/fail2ban/README.md index 90a59dce0..be09e1857 100644 --- a/collectors/python.d.plugin/fail2ban/README.md +++ b/collectors/python.d.plugin/fail2ban/README.md @@ -79,4 +79,4 @@ at `/etc/fail2ban/jail.local`. If conf file is not found default jail is `ssh`. --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Ffail2ban%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/freeradius/README.md b/collectors/python.d.plugin/freeradius/README.md index 2993c8952..d5ec464b5 100644 --- a/collectors/python.d.plugin/freeradius/README.md +++ b/collectors/python.d.plugin/freeradius/README.md @@ -87,4 +87,4 @@ and restart/reload your FREERADIUS server. --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Ffreeradius%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/gearman/README.md b/collectors/python.d.plugin/gearman/README.md index b9fc914bf..34ea584ab 100644 --- a/collectors/python.d.plugin/gearman/README.md +++ b/collectors/python.d.plugin/gearman/README.md @@ -48,4 +48,3 @@ localhost: When no configuration file is found, module tries to connect to TCP/IP socket: `localhost:4730`. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fgearman%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]() diff --git a/collectors/python.d.plugin/go_expvar/README.md b/collectors/python.d.plugin/go_expvar/README.md index a73610e7a..feb150dd9 100644 --- a/collectors/python.d.plugin/go_expvar/README.md +++ b/collectors/python.d.plugin/go_expvar/README.md @@ -316,4 +316,4 @@ The images below show how do the final charts in Netdata look. ![Custom charts](https://cloud.githubusercontent.com/assets/15180106/26762051/62ae915e-493b-11e7-8518-bd25a3886650.png) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fgo_expvar%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/haproxy/README.md b/collectors/python.d.plugin/haproxy/README.md index 33d34f1ad..4eb962e24 100644 --- a/collectors/python.d.plugin/haproxy/README.md +++ b/collectors/python.d.plugin/haproxy/README.md @@ -64,4 +64,4 @@ If no configuration is given, module will fail to run. --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fhaproxy%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/hddtemp/README.md b/collectors/python.d.plugin/hddtemp/README.md index aaaf21421..d8aba62d2 100644 --- a/collectors/python.d.plugin/hddtemp/README.md +++ b/collectors/python.d.plugin/hddtemp/README.md @@ -35,4 +35,4 @@ If no configuration is given, module will attempt to connect to hddtemp daemon o --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fhddtemp%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/hpssa/README.md b/collectors/python.d.plugin/hpssa/README.md index 69c8d8a33..c1d218279 100644 --- a/collectors/python.d.plugin/hpssa/README.md +++ b/collectors/python.d.plugin/hpssa/README.md @@ -81,4 +81,3 @@ ssacli_path: /usr/sbin/ssacli Save the file and restart the Netdata Agent with `sudo systemctl restart netdata`, or the [appropriate method](/docs/configure/start-stop-restart.md) for your system. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fhpssa%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]() diff --git a/collectors/python.d.plugin/hpssa/hpssa.chart.py b/collectors/python.d.plugin/hpssa/hpssa.chart.py index ce1b43009..4da73dc56 100644 --- a/collectors/python.d.plugin/hpssa/hpssa.chart.py +++ b/collectors/python.d.plugin/hpssa/hpssa.chart.py @@ -93,6 +93,7 @@ ignored_sections_regex = re.compile( re.X ) mirror_group_regex = re.compile(r'^Mirror Group \d+:$') +disk_partition_regex = re.compile(r'^Disk Partition Information$') array_regex = re.compile(r'^Array: (?P[A-Z]+)$') drive_regex = re.compile( r''' @@ -242,7 +243,7 @@ class HPSSA(object): } for line in self: - if mirror_group_regex.match(line): + if HPSSA.match_any(line, mirror_group_regex, disk_partition_regex): self.parse_ignored_section() continue diff --git a/collectors/python.d.plugin/httpcheck/README.md b/collectors/python.d.plugin/httpcheck/README.md index 59c60f544..101b96e3e 100644 --- a/collectors/python.d.plugin/httpcheck/README.md +++ b/collectors/python.d.plugin/httpcheck/README.md @@ -56,4 +56,4 @@ server: --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fhttpcheck%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/httpcheck/httpcheck.conf b/collectors/python.d.plugin/httpcheck/httpcheck.conf index 95adba270..3f33bf65c 100644 --- a/collectors/python.d.plugin/httpcheck/httpcheck.conf +++ b/collectors/python.d.plugin/httpcheck/httpcheck.conf @@ -35,7 +35,7 @@ # A chart is marked as obsolete if it has not been updated # 'chart_cleanup' iterations in a row. # They will be hidden immediately (not offered to dashboard viewer, -# streamed upstream and archived to backends) and deleted one hour +# streamed upstream and archived to external databases) and deleted one hour # later (configurable from netdata.conf). # -- For this plugin, cleanup MUST be disabled, otherwise we lose response # time charts diff --git a/collectors/python.d.plugin/icecast/README.md b/collectors/python.d.plugin/icecast/README.md index 90cdaa5dc..c122f76a3 100644 --- a/collectors/python.d.plugin/icecast/README.md +++ b/collectors/python.d.plugin/icecast/README.md @@ -41,4 +41,4 @@ Without configuration, module attempts to connect to `http://localhost:8443/stat --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Ficecast%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/ipfs/README.md b/collectors/python.d.plugin/ipfs/README.md index 4d3b0ecbe..3a7c43632 100644 --- a/collectors/python.d.plugin/ipfs/README.md +++ b/collectors/python.d.plugin/ipfs/README.md @@ -48,4 +48,4 @@ remote: --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fipfs%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/isc_dhcpd/README.md b/collectors/python.d.plugin/isc_dhcpd/README.md index 5830bd63e..712943d99 100644 --- a/collectors/python.d.plugin/isc_dhcpd/README.md +++ b/collectors/python.d.plugin/isc_dhcpd/README.md @@ -54,4 +54,4 @@ The module will not work If no configuration is given. --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fisc_dhcpd%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/litespeed/README.md b/collectors/python.d.plugin/litespeed/README.md index 2225773b7..b58b23d7e 100644 --- a/collectors/python.d.plugin/litespeed/README.md +++ b/collectors/python.d.plugin/litespeed/README.md @@ -69,4 +69,4 @@ If no configuration is given, module will use "/tmp/lshttpd/". --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Flitespeed%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/logind/README.md b/collectors/python.d.plugin/logind/README.md index 3e2d4c190..442d388d0 100644 --- a/collectors/python.d.plugin/logind/README.md +++ b/collectors/python.d.plugin/logind/README.md @@ -83,4 +83,4 @@ sudo ./edit-config python.d/logind.conf --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Flogind%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/megacli/README.md b/collectors/python.d.plugin/megacli/README.md index e411c4c11..3c99c3de8 100644 --- a/collectors/python.d.plugin/megacli/README.md +++ b/collectors/python.d.plugin/megacli/README.md @@ -83,4 +83,4 @@ do_battery: yes Save the file and restart the Netdata Agent with `sudo systemctl restart netdata`, or the [appropriate method](/docs/configure/start-stop-restart.md) for your system. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fmegacli%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/memcached/README.md b/collectors/python.d.plugin/memcached/README.md index abd93fd01..19139ee92 100644 --- a/collectors/python.d.plugin/memcached/README.md +++ b/collectors/python.d.plugin/memcached/README.md @@ -96,4 +96,4 @@ If no configuration is given, module will attempt to connect to memcached instan --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fmemcached%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/mongodb/README.md b/collectors/python.d.plugin/mongodb/README.md index e122736ac..b6dd9c5f4 100644 --- a/collectors/python.d.plugin/mongodb/README.md +++ b/collectors/python.d.plugin/mongodb/README.md @@ -207,4 +207,4 @@ If no configuration is given, module will attempt to connect to mongodb daemon o --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fmongodb%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/monit/README.md b/collectors/python.d.plugin/monit/README.md index fe1389687..13960256b 100644 --- a/collectors/python.d.plugin/monit/README.md +++ b/collectors/python.d.plugin/monit/README.md @@ -49,4 +49,4 @@ If no configuration is given, module will attempt to connect to monit as `http:/ --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fmonit%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/mysql/README.md b/collectors/python.d.plugin/mysql/README.md index 63d2c1e53..1ba794adf 100644 --- a/collectors/python.d.plugin/mysql/README.md +++ b/collectors/python.d.plugin/mysql/README.md @@ -393,4 +393,4 @@ page](https://mariadb.com/kb/en/library/user-statistics/) --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fmysql%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/nginx/README.md b/collectors/python.d.plugin/nginx/README.md index b55b01e7c..34f63cc52 100644 --- a/collectors/python.d.plugin/nginx/README.md +++ b/collectors/python.d.plugin/nginx/README.md @@ -62,4 +62,4 @@ Without configuration, module attempts to connect to `http://localhost/stub_stat --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fnginx%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/nginx_plus/README.md b/collectors/python.d.plugin/nginx_plus/README.md index 2580740c3..489ac9c2a 100644 --- a/collectors/python.d.plugin/nginx_plus/README.md +++ b/collectors/python.d.plugin/nginx_plus/README.md @@ -162,4 +162,4 @@ Without configuration, module fail to start. --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fnginx_plus%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/nsd/README.md b/collectors/python.d.plugin/nsd/README.md index 1e7b240e7..e5183aeb7 100644 --- a/collectors/python.d.plugin/nsd/README.md +++ b/collectors/python.d.plugin/nsd/README.md @@ -65,4 +65,4 @@ Configuration is not needed. --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fnsd%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/ntpd/README.md b/collectors/python.d.plugin/ntpd/README.md index 0b08f12b8..9832707bd 100644 --- a/collectors/python.d.plugin/ntpd/README.md +++ b/collectors/python.d.plugin/ntpd/README.md @@ -87,4 +87,4 @@ If no configuration is given, module will attempt to connect to `ntpd` on `::1:1 --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fntpd%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/nvidia_smi/README.md b/collectors/python.d.plugin/nvidia_smi/README.md index f8ce824df..fb613064c 100644 --- a/collectors/python.d.plugin/nvidia_smi/README.md +++ b/collectors/python.d.plugin/nvidia_smi/README.md @@ -61,4 +61,4 @@ poll_seconds : 1 exclude_zero_memory_users : yes ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fnvidia_smi%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/nvidia_smi/nvidia_smi.chart.py b/collectors/python.d.plugin/nvidia_smi/nvidia_smi.chart.py index 00bc7884d..1913e94e4 100644 --- a/collectors/python.d.plugin/nvidia_smi/nvidia_smi.chart.py +++ b/collectors/python.d.plugin/nvidia_smi/nvidia_smi.chart.py @@ -294,14 +294,13 @@ def get_username_by_pid_safe(pid, passwd_file): try: uid = os.stat(path).st_uid except (OSError, IOError): - return '' - if IS_INSIDE_DOCKER: - try: + return '' + try: + if IS_INSIDE_DOCKER: return passwd_file[uid][0] - except KeyError: - return str(uid) - else: return pwd.getpwuid(uid)[0] + except KeyError: + return str(uid) class GPU: diff --git a/collectors/python.d.plugin/openldap/README.md b/collectors/python.d.plugin/openldap/README.md index 4942d0f39..b0cd1db42 100644 --- a/collectors/python.d.plugin/openldap/README.md +++ b/collectors/python.d.plugin/openldap/README.md @@ -76,4 +76,4 @@ openldap: --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fopenldap%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/oracledb/README.md b/collectors/python.d.plugin/oracledb/README.md index d61c7d2ad..88024f8c5 100644 --- a/collectors/python.d.plugin/oracledb/README.md +++ b/collectors/python.d.plugin/oracledb/README.md @@ -94,4 +94,4 @@ remote: All parameters are required. Without them module will fail to start. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Foracledb%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/ovpn_status_log/README.md b/collectors/python.d.plugin/ovpn_status_log/README.md index 8fa8cb833..374d1910e 100644 --- a/collectors/python.d.plugin/ovpn_status_log/README.md +++ b/collectors/python.d.plugin/ovpn_status_log/README.md @@ -47,4 +47,4 @@ default --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fovpn_status_log%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/phpfpm/README.md b/collectors/python.d.plugin/phpfpm/README.md index 9d0dbb580..fe81971b2 100644 --- a/collectors/python.d.plugin/phpfpm/README.md +++ b/collectors/python.d.plugin/phpfpm/README.md @@ -48,4 +48,4 @@ Without configuration, module attempts to connect to `http://localhost/status` --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fphpfpm%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/portcheck/README.md b/collectors/python.d.plugin/portcheck/README.md index 35521b2ad..845fa5b90 100644 --- a/collectors/python.d.plugin/portcheck/README.md +++ b/collectors/python.d.plugin/portcheck/README.md @@ -49,4 +49,4 @@ server: --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fportcheck%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/portcheck/portcheck.conf b/collectors/python.d.plugin/portcheck/portcheck.conf index df67824bd..2b32c0031 100644 --- a/collectors/python.d.plugin/portcheck/portcheck.conf +++ b/collectors/python.d.plugin/portcheck/portcheck.conf @@ -35,7 +35,7 @@ # A chart is marked as obsolete if it has not been updated # 'chart_cleanup' iterations in a row. # They will be hidden immediately (not offered to dashboard viewer, -# streamed upstream and archived to backends) and deleted one hour +# streamed upstream and archived to external databases) and deleted one hour # later (configurable from netdata.conf). # -- For this plugin, cleanup MUST be disabled, otherwise we lose latency chart chart_cleanup: 0 diff --git a/collectors/python.d.plugin/postfix/README.md b/collectors/python.d.plugin/postfix/README.md index 53073ea8d..ac16962a5 100644 --- a/collectors/python.d.plugin/postfix/README.md +++ b/collectors/python.d.plugin/postfix/README.md @@ -24,4 +24,4 @@ Configuration is not needed. --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fpostfix%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/postgres/README.md b/collectors/python.d.plugin/postgres/README.md index 0515ec57c..224b76ff5 100644 --- a/collectors/python.d.plugin/postgres/README.md +++ b/collectors/python.d.plugin/postgres/README.md @@ -115,4 +115,4 @@ tcp: --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fpostgres%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/powerdns/README.md b/collectors/python.d.plugin/powerdns/README.md index 610a665de..02449e68e 100644 --- a/collectors/python.d.plugin/powerdns/README.md +++ b/collectors/python.d.plugin/powerdns/README.md @@ -101,4 +101,4 @@ local: --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fpowerdns%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/proxysql/README.md b/collectors/python.d.plugin/proxysql/README.md index f1b369a44..8c6a394f1 100644 --- a/collectors/python.d.plugin/proxysql/README.md +++ b/collectors/python.d.plugin/proxysql/README.md @@ -103,4 +103,4 @@ If no configuration is given, module will fail to run. --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fproxysql%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/puppet/README.md b/collectors/python.d.plugin/puppet/README.md index 9b7c0a2c3..1b06d181b 100644 --- a/collectors/python.d.plugin/puppet/README.md +++ b/collectors/python.d.plugin/puppet/README.md @@ -64,4 +64,4 @@ When no configuration is given, module uses `https://fqdn.example.com:8140`. --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fpuppet%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/python_modules/bases/charts.py b/collectors/python.d.plugin/python_modules/bases/charts.py index 2526af8ce..54986a937 100644 --- a/collectors/python.d.plugin/python_modules/bases/charts.py +++ b/collectors/python.d.plugin/python_modules/bases/charts.py @@ -23,7 +23,7 @@ DIMENSION_SET = "SET '{id}' = {value}\n" CHART_VARIABLE_SET = "VARIABLE CHART '{id}' = {value}\n" -RUNTIME_CHART_CREATE = "CHART netdata.runtime_{job_name} '' 'Execution time for {job_name}' 'ms' 'python.d' " \ +RUNTIME_CHART_CREATE = "CHART netdata.runtime_{job_name} '' 'Execution time' 'ms' 'python.d' " \ "netdata.pythond_runtime line 145000 {update_every} '' 'python.d.plugin' '{module_name}'\n" \ "DIMENSION run_time 'run time' absolute 1 1\n" diff --git a/collectors/python.d.plugin/rabbitmq/README.md b/collectors/python.d.plugin/rabbitmq/README.md index 2130a7b3a..607e32c7f 100644 --- a/collectors/python.d.plugin/rabbitmq/README.md +++ b/collectors/python.d.plugin/rabbitmq/README.md @@ -113,4 +113,4 @@ socket: --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Frabbitmq%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/redis/README.md b/collectors/python.d.plugin/redis/README.md index 9fab56c33..319827100 100644 --- a/collectors/python.d.plugin/redis/README.md +++ b/collectors/python.d.plugin/redis/README.md @@ -61,4 +61,4 @@ When no configuration file is found, module tries to connect to TCP/IP socket: ` --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fredis%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/rethinkdbs/README.md b/collectors/python.d.plugin/rethinkdbs/README.md index 85cebd96a..d3fa3553a 100644 --- a/collectors/python.d.plugin/rethinkdbs/README.md +++ b/collectors/python.d.plugin/rethinkdbs/README.md @@ -50,4 +50,4 @@ When no configuration file is found, module tries to connect to `127.0.0.1:28015 --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Frethinkdbs%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/retroshare/README.md b/collectors/python.d.plugin/retroshare/README.md index d8bd3a914..297df9fca 100644 --- a/collectors/python.d.plugin/retroshare/README.md +++ b/collectors/python.d.plugin/retroshare/README.md @@ -44,4 +44,4 @@ remote: ``` --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fretroshare%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/riakkv/README.md b/collectors/python.d.plugin/riakkv/README.md index d0ea9a137..fe62c6718 100644 --- a/collectors/python.d.plugin/riakkv/README.md +++ b/collectors/python.d.plugin/riakkv/README.md @@ -124,5 +124,3 @@ With no explicit configuration given, the module will attempt to connect to The default update frequency for the plugin is set to 2 seconds as Riak internally updates the metrics every second. If we were to update the metrics every second, the resulting graph would contain odd jitter. - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Friakkv%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]() diff --git a/collectors/python.d.plugin/samba/README.md b/collectors/python.d.plugin/samba/README.md index 04cb7dcf7..767df12de 100644 --- a/collectors/python.d.plugin/samba/README.md +++ b/collectors/python.d.plugin/samba/README.md @@ -118,4 +118,4 @@ sudo ./edit-config python.d/samba.conf --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fsamba%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/sensors/README.md b/collectors/python.d.plugin/sensors/README.md index 5d2934844..149589317 100644 --- a/collectors/python.d.plugin/sensors/README.md +++ b/collectors/python.d.plugin/sensors/README.md @@ -28,4 +28,4 @@ Please join this discussion for help. --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fsensors%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/sensors/sensors.chart.py b/collectors/python.d.plugin/sensors/sensors.chart.py index 8c0cde6bb..f089e147a 100644 --- a/collectors/python.d.plugin/sensors/sensors.chart.py +++ b/collectors/python.d.plugin/sensors/sensors.chart.py @@ -19,43 +19,43 @@ ORDER = [ # This is a prototype of chart definition which is used to dynamically create self.definitions CHARTS = { 'temperature': { - 'options': [None, ' temperature', 'Celsius', 'temperature', 'sensors.temperature', 'line'], + 'options': [None, 'Temperature', 'Celsius', 'temperature', 'sensors.temperature', 'line'], 'lines': [ [None, None, 'absolute', 1, 1000] ] }, 'voltage': { - 'options': [None, ' voltage', 'Volts', 'voltage', 'sensors.voltage', 'line'], + 'options': [None, 'Voltage', 'Volts', 'voltage', 'sensors.voltage', 'line'], 'lines': [ [None, None, 'absolute', 1, 1000] ] }, 'current': { - 'options': [None, ' current', 'Ampere', 'current', 'sensors.current', 'line'], + 'options': [None, 'Current', 'Ampere', 'current', 'sensors.current', 'line'], 'lines': [ [None, None, 'absolute', 1, 1000] ] }, 'power': { - 'options': [None, ' power', 'Watt', 'power', 'sensors.power', 'line'], + 'options': [None, 'Power', 'Watt', 'power', 'sensors.power', 'line'], 'lines': [ [None, None, 'absolute', 1, 1000] ] }, 'fan': { - 'options': [None, ' fans speed', 'Rotations/min', 'fans', 'sensors.fan', 'line'], + 'options': [None, 'Fans speed', 'Rotations/min', 'fans', 'sensors.fan', 'line'], 'lines': [ [None, None, 'absolute', 1, 1000] ] }, 'energy': { - 'options': [None, ' energy', 'Joule', 'energy', 'sensors.energy', 'line'], + 'options': [None, 'Energy', 'Joule', 'energy', 'sensors.energy', 'line'], 'lines': [ [None, None, 'incremental', 1, 1000] ] }, 'humidity': { - 'options': [None, ' humidity', 'Percent', 'humidity', 'sensors.humidity', 'line'], + 'options': [None, 'Humidity', 'Percent', 'humidity', 'sensors.humidity', 'line'], 'lines': [ [None, None, 'absolute', 1, 1000] ] @@ -143,7 +143,6 @@ class Service(SimpleService): if name not in self.order: self.order.append(name) chart_def = list(CHARTS[sensor]['options']) - chart_def[1] = chip_name + chart_def[1] self.definitions[name] = {'options': chart_def} self.definitions[name]['lines'] = [] line = list(CHARTS[sensor]['lines'][0]) diff --git a/collectors/python.d.plugin/smartd_log/README.md b/collectors/python.d.plugin/smartd_log/README.md index a1b41f408..eef34ce43 100644 --- a/collectors/python.d.plugin/smartd_log/README.md +++ b/collectors/python.d.plugin/smartd_log/README.md @@ -122,4 +122,4 @@ If no configuration is given, module will attempt to read log files in `/var/log --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fsmartd_log%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/spigotmc/README.md b/collectors/python.d.plugin/spigotmc/README.md index 9b297f639..06483188b 100644 --- a/collectors/python.d.plugin/spigotmc/README.md +++ b/collectors/python.d.plugin/spigotmc/README.md @@ -35,4 +35,4 @@ By default, a connection to port 25575 on the local system is attempted with an --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fspigotmc%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/springboot/README.md b/collectors/python.d.plugin/springboot/README.md index f38e8bf05..cdbc9a900 100644 --- a/collectors/python.d.plugin/springboot/README.md +++ b/collectors/python.d.plugin/springboot/README.md @@ -142,4 +142,4 @@ Please check [springboot.conf](https://raw.githubusercontent.com/netdata/netdata/master/collectors/python.d.plugin/springboot/springboot.conf) for more examples. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fspringboot%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/squid/README.md b/collectors/python.d.plugin/squid/README.md index e3ed4e0df..c29b69a19 100644 --- a/collectors/python.d.plugin/squid/README.md +++ b/collectors/python.d.plugin/squid/README.md @@ -55,4 +55,4 @@ Without any configuration module will try to autodetect where squid presents its --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fsquid%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/tomcat/README.md b/collectors/python.d.plugin/tomcat/README.md index f9f2ffe31..b7525b88a 100644 --- a/collectors/python.d.plugin/tomcat/README.md +++ b/collectors/python.d.plugin/tomcat/README.md @@ -50,4 +50,4 @@ So it will probably fail. --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Ftomcat%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/tor/README.md b/collectors/python.d.plugin/tor/README.md index 192a86a37..3e7b8997a 100644 --- a/collectors/python.d.plugin/tor/README.md +++ b/collectors/python.d.plugin/tor/README.md @@ -61,4 +61,4 @@ Without configuration, module attempts to connect to `127.0.0.1:9051`. --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Ftor%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/traefik/README.md b/collectors/python.d.plugin/traefik/README.md index 2a1dd77aa..251cdf2e4 100644 --- a/collectors/python.d.plugin/traefik/README.md +++ b/collectors/python.d.plugin/traefik/README.md @@ -71,4 +71,4 @@ Without configuration, module attempts to connect to `http://localhost:8080/heal --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Ftraefik%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/uwsgi/README.md b/collectors/python.d.plugin/uwsgi/README.md index f564821a1..58db1a41a 100644 --- a/collectors/python.d.plugin/uwsgi/README.md +++ b/collectors/python.d.plugin/uwsgi/README.md @@ -49,4 +49,4 @@ localhost: When no configuration file is found, module tries to connect to TCP/IP socket: `localhost:1717`. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fuwsgi%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/varnish/README.md b/collectors/python.d.plugin/varnish/README.md index cb29738f5..018905f06 100644 --- a/collectors/python.d.plugin/varnish/README.md +++ b/collectors/python.d.plugin/varnish/README.md @@ -62,4 +62,4 @@ The name of the `varnishd` instance to get logs from. If not specified, the host --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fvarnish%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/w1sensor/README.md b/collectors/python.d.plugin/w1sensor/README.md index 31facef77..b6d2b2d63 100644 --- a/collectors/python.d.plugin/w1sensor/README.md +++ b/collectors/python.d.plugin/w1sensor/README.md @@ -25,4 +25,4 @@ sudo ./edit-config python.d/w1sensor.conf --- -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fw1sensor%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/python.d.plugin/web_log/README.md b/collectors/python.d.plugin/web_log/README.md index 8bbb9a83a..552d56e90 100644 --- a/collectors/python.d.plugin/web_log/README.md +++ b/collectors/python.d.plugin/web_log/README.md @@ -216,4 +216,4 @@ The column `minimum requests` state the minimum number of requests required for Netdata alarms are user-configurable. Sample config files can be found under directory `health/health.d` of the [Netdata GitHub repository](https://github.com/netdata/netdata/). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Fweb_log%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/slabinfo.plugin/README.md b/collectors/slabinfo.plugin/README.md index 21d83c999..2f4904660 100644 --- a/collectors/slabinfo.plugin/README.md +++ b/collectors/slabinfo.plugin/README.md @@ -26,4 +26,4 @@ In the following screenshot, you can clearly see a `find` done on a ext4 filesys ![netdata_slabinfo](https://user-images.githubusercontent.com/9157986/64433811-7f06e500-d0bf-11e9-8e1e-087497e61033.png) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fslabinfo.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/statsd.plugin/Makefile.am b/collectors/statsd.plugin/Makefile.am index 71f2d468d..c8144c137 100644 --- a/collectors/statsd.plugin/Makefile.am +++ b/collectors/statsd.plugin/Makefile.am @@ -11,6 +11,7 @@ statsdconfigdir=$(libconfigdir)/statsd.d dist_statsdconfig_DATA = \ example.conf \ k6.conf \ + asterisk.conf \ $(NULL) userstatsdconfigdir=$(configdir)/statsd.d diff --git a/collectors/statsd.plugin/README.md b/collectors/statsd.plugin/README.md index 1d1c8ab70..aadd55bd6 100644 --- a/collectors/statsd.plugin/README.md +++ b/collectors/statsd.plugin/README.md @@ -27,6 +27,10 @@ On these charts, we can have alarms as with any metric and chart. - **Description:** k6 is a developer-centric, free and open-source load testing tool built for making performance testing a productive and enjoyable experience. - [Documentation](/collectors/statsd.plugin/k6.md) - [Configuration](https://github.com/netdata/netdata/blob/master/collectors/statsd.plugin/k6.conf) +- [Asterisk](https://www.asterisk.org/) + - **Description:** Asterisk is an Open Source PBX and telephony toolkit. + - [Documentation](/collectors/statsd.plugin/asterisk.md) + - [Configuration](https://github.com/netdata/netdata/blob/master/collectors/statsd.plugin/asterisk.conf) ## Metrics supported by Netdata @@ -611,4 +615,4 @@ The function is smart enough to call `nc` just once and pass all the metrics to If you have gotten thus far, make sure to check out our [community forums](https://community.netdata.cloud) to share your experience using Netdata with StatsD. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fstatsd.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/statsd.plugin/asterisk.conf b/collectors/statsd.plugin/asterisk.conf new file mode 100644 index 000000000..160b80f93 --- /dev/null +++ b/collectors/statsd.plugin/asterisk.conf @@ -0,0 +1,208 @@ +[app] + name = asterisk + metrics = asterisk.* + private charts = yes + gaps when not collected = no + +[dictionary] + # https://www.voip-info.org/asterisk-variable-hangupcause/ + q931.1 = unallocated 1 + q931.2 = no route transit net 2 + q931.3 = no route destination 3 + q931.6 = channel unacceptable 6 + q931.7 = call awarded delivered 7 + q931.16 = normal 16 + q931.17 = busy 17 + q931.18 = no response 18 + q931.19 = no answer 19 + q931.21 = rejected call 21 + q931.22 = number changed 22 + q931.27 = dst out of order 27 + q931.28 = invalid number 28 + q931.29 = rejected facility 29 + q931.30 = response to status 30 + q931.31 = normal unspecified 31 + q931.34 = congestion circuit 34 + q931.38 = net out of order 38 + q931.41 = normal tmp fail 41 + q931.42 = congestion switch 42 + q931.43 = access info discarded 43 + q931.44 = requested chan unavail 44 + q931.45 = pre empted 45 + q931.47 = resource unavailable, unspecified 47 + q931.50 = facility not subscribed 50 + q931.52 = outgoing call barred 52 + q931.54 = incoming call barred 54 + q931.57 = bearer capability not auth 57 + q931.58 = bearer capability not avail 58 + q931.65 = bearer capability not implemented 65 + q931.66 = chan not implemented 66 + q931.69 = facility not implemented 67 + q931.81 = invalid call reference 81 + q931.88 = incompatible destination 88 + q931.95 = invalid msg specified 95 + q931.96 = mandatory ie missing 96 + q931.97 = message type non exist 97 + q931.98 = wrong message 98 + q931.99 = ie non exist 99 + q931.100 = invalid ie contents 100 + q931.101 = wrong call state 101 + q931.102 = recovery on timer expire 102 + q931.103 = mandatory ie length error 103 + q931.111 = protocol error 111 + q931.127 = interworking 127 + + +[channels] + name = channels + title = Active Channels + family = channels + context = asterisk.channels + units = channels + priority = 91000 + type = stacked + dimension = pattern asterisk.channels.count 'channels' last 1 1 + # FIXME: netdata needs to prevent this from going negative + +[endpoints] + name = endpoints + title = Active Endpoints + family = endpoints + context = asterisk.endpoints + units = endpoints + priority = 91005 + type = stacked + dimension = pattern asterisk.endpoints.count 'endpoints' last 1 1 + +[endpoints_by_status] + name = endpoints_by_status + title = Active Endpoints by Status + family = endpoints + context = asterisk.endpoints_by_status + units = endpoints + priority = 91006 + type = stacked + dimension = pattern asterisk.endpoints.state.* '' last 1 1 + +[sip_channels_by_endpoint] + name = sip_channels_by_endpoint + title = Active SIP channels by endpoint + family = channels + context = asterisk.sip_channels_by_endpoint + units = channels + priority = 91110 + type = stacked + dimension = pattern asterisk.endpoints.SIP.*.channels '' last 1 1 + +[pjsip_channels_by_endpoint] + name = pjsip_channels_by_endpoint + title = Active PJSIP channels by endpoint + family = channels + context = asterisk.pjsip_channels_by_endpoint + units = channels + priority = 91111 + type = stacked + dimension = pattern asterisk.endpoints.PJSIP.*.channels '' last 1 1 + +[dialstatuses] + name = dialstatuses + title = Distribution of Dial Statuses + family = dial_statuses + context = asterisk.dialstatus + units = calls + priority = 91150 + type = stacked + dimension = pattern 'asterisk.dialstatus.*' '' last 1 1 + +[calltime] + name = calltime + title = Asterisk Channels Call Duration + family = calltime + context = asterisk.calltime + units = milliseconds + priority = 91160 + type = stacked + dimension = asterisk.channels.calltime 'calltime' average 1 1 + dimension = asterisk.channels.calltime 'sum' sum 1 1 hidden + dimension = asterisk.channels.calltime 'count' events 1 1 hidden + +[hangupcause] + name = hangupcause + title = Distribution of Hangup Causes + family = hangup_causes + context = asterisk.hangupcause + units = calls + priority = 91200 + type = stacked + dimension = pattern 'asterisk.hangupcause.*' 'q931.' last 1 1 + +[hangupcause_answer] + name = hangupcause_answer + title = Distribution of Hangup Causes for ANSWERed calls + family = hangup_causes + context = asterisk.hangupcause_answer + units = calls + priority = 91210 + type = stacked + dimension = pattern 'asterisk.dialhangupcause.ANSWER.*' 'q931.' last 1 1 + +[hangupcause_busy] + name = hangupcause_busy + title = Distribution of Hangup Causes for BUSY calls + family = hangup_causes + context = asterisk.hangupcause_busy + units = calls + priority = 91215 + type = stacked + dimension = pattern 'asterisk.dialhangupcause.BUSY.*' 'q931.' last 1 1 + +[hangupcause_cancel] + name = hangupcause_cancel + title = Distribution of Hangup Causes for CANCELled calls + family = hangup_causes + context = asterisk.hangupcause_cancel + units = calls + priority = 91220 + type = stacked + dimension = pattern 'asterisk.dialhangupcause.CANCEL.*' 'q931.' last 1 1 + +[hangupcause_chanunavail] + name = hangupcause_chanunavail + title = Distribution of Hangup Causes for CHANUNVAILed calls + family = hangup_causes + context = asterisk.hangupcause_chanunavail + units = calls + priority = 91230 + type = stacked + dimension = pattern 'asterisk.dialhangupcause.CHANUNAVAIL.*' 'q931.' last 1 1 + +[hangupcause_congestion] + name = hangupcause_congestion + title = Distribution of Hangup Causes for CONGESTIONed calls + family = hangup_causes + context = asterisk.hangupcause_congestion + units = calls + priority = 91240 + type = stacked + dimension = pattern 'asterisk.dialhangupcause.CONGESTION.*' 'q931.' last 1 1 + +[events] + name = events + title = Asterisk Dialplan Events + family = events + context = asterisk.events + units = events/s + priority = 91400 + type = stacked + dimension = pattern 'asterisk.stasis.message.ast_channel_*_type' '' last 1 1 + +[qualify] + name = qualify + title = Asterisk PJSIP Peers Qualify + family = qualify + context = asterisk.qualify + units = milliseconds + priority = 91500 + type = stacked + dimension = pattern 'asterisk.PJSIP.contacts.*.rtt' '' max 1 1 + # FIXME: netdata needs to set update every = 15 on this diff --git a/collectors/statsd.plugin/asterisk.md b/collectors/statsd.plugin/asterisk.md new file mode 100644 index 000000000..94da94ee2 --- /dev/null +++ b/collectors/statsd.plugin/asterisk.md @@ -0,0 +1,61 @@ + + +# Asterisk monitoring with Netdata + +Monitors [Asterisk](https://www.asterisk.org/) dialplan application's statistics. + +## Requirements + +- Asterisk [integrated with StatsD](https://www.asterisk.org/integrating-asterisk-with-statsd/). + +## Configuration + +Netdata ships +with [asterisk.conf](https://github.com/netdata/netdata/blob/master/collectors/statsd.plugin/asterisk.conf) with +preconfigured charts. + +To receive Asterisk metrics in Netdata, uncomment the following lines in the `/etc/asterisk/statsd.conf` file: + +```ini +[general] +enabled = yes ; When set to yes, statsd support is enabled +server = 127.0.0.1 ; server[:port] of statsd server to use. + ; If not specified, the port is 8125 +prefix = asterisk ; Prefix to prepend to all metrics +``` + +> See [statsd.conf.sample](https://github.com/asterisk/asterisk/blob/master/configs/samples/statsd.conf.sample) for all available options. + +## Charts and metrics + +
Click to see screenshots of the charts. + +![image](https://user-images.githubusercontent.com/2662304/158055351-fcc7a7fb-9b95-4656-bdc6-2e5f5a909215.png) +![image](https://user-images.githubusercontent.com/2662304/158055367-cfd25cd5-d71a-4bab-8cd1-bfcc47bc7312.png) + +
+ +Mapping Asterisk StatsD metrics and Netdata charts. + +| Chart | Metrics | +|------------------------------------------------------|--------------------------------------------| +| Active Channels | asterisk.channels.count | +| Active Endpoints | asterisk.endpoints.count | +| Active Endpoints by Status | asterisk.endpoints.state.* | +| Active SIP channels by endpoint | asterisk.endpoints.SIP.*.channels | +| Active PJSIP channels by endpoint | asterisk.endpoints.PJSIP.*.channels | +| Distribution of Dial Statuses | asterisk.dialstatus.* | +| Asterisk Channels Call Duration | asterisk.channels.calltime | +| Distribution of Hangup Causes | asterisk.hangupcause.* | +| Distribution of Hangup Causes for ANSWERed calls | asterisk.dialhangupcause.ANSWER.* | +| Distribution of Hangup Causes for BUSY calls | asterisk.dialhangupcause.BUSY.* | +| Distribution of Hangup Causes for CANCELled calls | asterisk.dialhangupcause.CANCEL.* | +| Distribution of Hangup Causes for CHANUNVAILed calls | asterisk.dialhangupcause.CHANUNAVAIL.* | +| Distribution of Hangup Causes for CONGESTIONed calls | asterisk.dialhangupcause.CONGESTION.* | +| Asterisk Dialplan Events | asterisk.stasis.message.ast_channel_*_type | +| Asterisk PJSIP Peers Qualify | asterisk.PJSIP.contacts.*.rtt | diff --git a/collectors/tc.plugin/README.md b/collectors/tc.plugin/README.md index 480076087..32c20f490 100644 --- a/collectors/tc.plugin/README.md +++ b/collectors/tc.plugin/README.md @@ -202,4 +202,4 @@ Finally, create `/etc/netdata/tc-qos-helper.conf` with this content: Please note, that by default Netdata will enable monitoring metrics only when they are not zero. If they are constantly zero they are ignored. Metrics that will start having values, after Netdata is started, will be detected and charts will be automatically added to the dashboard (a refresh of the dashboard is needed for them to appear though). Set `yes` for a chart instead of `auto` to enable it permanently. You can also set the `enable zero metrics` option to `yes` in the `[global]` section which enables charts with zero metrics for all internal Netdata plugins. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Ftc.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/collectors/timex.plugin/README.md b/collectors/timex.plugin/README.md index 79947441f..18665f807 100644 --- a/collectors/timex.plugin/README.md +++ b/collectors/timex.plugin/README.md @@ -6,12 +6,16 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/collectors/timex # timex.plugin -This plugin monitors the system clock synchronization state on Linux nodes. +This plugin monitors the system kernel clock synchronization state. -This plugin creates two charts: +This plugin creates the following charts: -- System clock synchronization state -- Computed time offset between local system and reference clock +- System clock synchronization state according to the system kernel +- System clock status which gives the value of the `time_status` variable in the kernel +- Computed time offset between local system and reference clock + +This is obtained from the information provided by the [ntp_adjtime()](https://man7.org/linux/man-pages/man2/adjtimex.2.html) system call. +An unsynchronized clock may indicate a hardware clock error, or an issue with UTC synchronization. ## Configuration @@ -19,11 +23,9 @@ Edit the `netdata.conf` configuration file using [`edit-config`](/docs/configure Scroll down to the `[plugin:timex]` section to find the available options: -``` +```ini [plugin:timex] # update every = 1 # clock synchronization state = yes # time offset = yes ``` - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Ftimex.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) diff --git a/collectors/timex.plugin/plugin_timex.c b/collectors/timex.plugin/plugin_timex.c index b69f34292..34a3415a0 100644 --- a/collectors/timex.plugin/plugin_timex.c +++ b/collectors/timex.plugin/plugin_timex.c @@ -1,12 +1,35 @@ // SPDX-License-Identifier: GPL-3.0-or-later #include "daemon/common.h" -#include "sys/timex.h" +#include "libnetdata/os.h" #define PLUGIN_TIMEX_NAME "timex.plugin" #define CONFIG_SECTION_TIMEX "plugin:timex" +struct status_codes { + char *name; + int code; + RRDDIM *rd; +} sta_codes[] = { + // {"pll", STA_PLL, NULL}, + // {"ppsfreq", STA_PPSFREQ, NULL}, + // {"ppstime", STA_PPSTIME, NULL}, + // {"fll", STA_FLL, NULL}, + // {"ins", STA_INS, NULL}, + // {"del", STA_DEL, NULL}, + {"unsync", STA_UNSYNC, NULL}, + // {"freqhold", STA_FREQHOLD, NULL}, + // {"ppssignal", STA_PPSSIGNAL, NULL}, + // {"ppsjitter", STA_PPSJITTER, NULL}, + // {"ppswander", STA_PPSWANDER, NULL}, + // {"ppserror", STA_PPSERROR, NULL}, + {"clockerr", STA_CLOCKERR, NULL}, + // {"nano", STA_NANO, NULL}, + // {"clk", STA_CLK, NULL}, + {NULL, 0, NULL}, +}; + static void timex_main_cleanup(void *ptr) { struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr; @@ -44,7 +67,17 @@ void *timex_main(void *ptr) struct timex timex_buf = {}; int sync_state = 0; - sync_state = adjtimex(&timex_buf); + static int prev_sync_state = 0; + + sync_state = ADJUST_TIMEX(&timex_buf); + + int non_seq_failure = (sync_state == -1 && prev_sync_state != -1); + prev_sync_state = sync_state; + + if (non_seq_failure) { + error("Cannot get clock synchronization state"); + continue; + } collected_number divisor = USEC_PER_MS; if (timex_buf.status & STA_NANO) @@ -78,9 +111,39 @@ void *timex_main(void *ptr) rrddim_set_by_pointer(st_sync_state, rd_sync_state, sync_state != TIME_ERROR ? 1 : 0); rrdset_done(st_sync_state); + + static RRDSET *st_clock_status = NULL; + + if (unlikely(!st_clock_status)) { + st_clock_status = rrdset_create_localhost( + "system", + "clock_status", + NULL, + "clock synchronization", + NULL, + "System Clock Status", + "status", + PLUGIN_TIMEX_NAME, + NULL, + NETDATA_CHART_PRIO_CLOCK_STATUS, + update_every, + RRDSET_TYPE_LINE); + + for (int i = 0; sta_codes[i].name != NULL; i++) { + sta_codes[i].rd = + rrddim_add(st_clock_status, sta_codes[i].name, NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); + } + } else { + rrdset_next(st_clock_status); + } + + for (int i = 0; sta_codes[i].name != NULL; i++) { + rrddim_set_by_pointer(st_clock_status, sta_codes[i].rd, timex_buf.status & sta_codes[i].code ? 1 : 0); + } + rrdset_done(st_clock_status); } - if (do_sync) { + if (do_offset) { static RRDSET *st_offset = NULL; static RRDDIM *rd_offset; @@ -132,13 +195,14 @@ void *timex_main(void *ptr) update_every, RRDSET_TYPE_STACKED); - rd_user = rrddim_add(stcpu_thread, "user", NULL, 1, USEC_PER_MS, RRD_ALGORITHM_INCREMENTAL); + rd_user = rrddim_add(stcpu_thread, "user", NULL, 1, USEC_PER_MS, RRD_ALGORITHM_INCREMENTAL); rd_system = rrddim_add(stcpu_thread, "system", NULL, 1, USEC_PER_MS, RRD_ALGORITHM_INCREMENTAL); } else { rrdset_next(stcpu_thread); } - rrddim_set_by_pointer(stcpu_thread, rd_user, thread.ru_utime.tv_sec * USEC_PER_SEC + thread.ru_utime.tv_usec); + rrddim_set_by_pointer( + stcpu_thread, rd_user, thread.ru_utime.tv_sec * USEC_PER_SEC + thread.ru_utime.tv_usec); rrddim_set_by_pointer( stcpu_thread, rd_system, thread.ru_stime.tv_sec * USEC_PER_SEC + thread.ru_stime.tv_usec); rrdset_done(stcpu_thread); diff --git a/collectors/xenstat.plugin/README.md b/collectors/xenstat.plugin/README.md index 61be271d9..8cbe086fc 100644 --- a/collectors/xenstat.plugin/README.md +++ b/collectors/xenstat.plugin/README.md @@ -50,4 +50,4 @@ sudo /usr/libexec/netdata/plugins.d/xenstat.plugin 1 debug You will get verbose output on what the plugin does. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fnfacct.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/configure.ac b/configure.ac index 1dc6c53ac..c488f06f5 100644 --- a/configure.ac +++ b/configure.ac @@ -71,10 +71,10 @@ AC_ARG_ENABLE( [enable_plugin_xenstat="detect"] ) AC_ARG_ENABLE( - [backend-kinesis], - [AS_HELP_STRING([--enable-backend-kinesis], [enable kinesis backend @<:@default autodetect@:>@])], + [exporting-kinesis], + [AS_HELP_STRING([--enable-exporting-kinesis], [enable kinesis exporting connector @<:@default autodetect@:>@])], , - [enable_backend_kinesis="detect"] + [enable_exporting_kinesis="detect"] ) AC_ARG_ENABLE( [exporting-pubsub], @@ -83,16 +83,16 @@ AC_ARG_ENABLE( [enable_exporting_pubsub="detect"] ) AC_ARG_ENABLE( - [backend-prometheus-remote-write], - [AS_HELP_STRING([--enable-backend-prometheus-remote-write], [enable prometheus remote write backend @<:@default autodetect@:>@])], + [exporting-prometheus-remote-write], + [AS_HELP_STRING([--enable-exporting-prometheus-remote-write], [enable prometheus remote write exporting connector @<:@default autodetect@:>@])], , - [enable_backend_prometheus_remote_write="detect"] + [enable_exporting_prometheus_remote_write="detect"] ) AC_ARG_ENABLE( - [backend-mongodb], - [AS_HELP_STRING([--enable-backend-mongodb], [enable mongodb backend @<:@default autodetect@:>@])], + [exporting-mongodb], + [AS_HELP_STRING([--enable-exporting-mongodb], [enable mongodb exporting @<:@default autodetect@:>@])], , - [enable_backend_mongodb="detect"] + [enable_exporting_mongodb="detect"] ) AC_ARG_ENABLE( [pedantic], @@ -262,7 +262,6 @@ AC_FUNC_STRERROR_R AC_C__GENERIC AC_C___ATOMIC # AC_C_STMT_EXPR -AC_CHECK_SIZEOF([void *]) AC_CANONICAL_HOST AC_HEADER_MAJOR AC_HEADER_RESOLV @@ -281,15 +280,38 @@ fi # ----------------------------------------------------------------------------- # operating system detection +originalCFLAGS="${CFLAGS}" AC_MSG_CHECKING([operating system]) case "$host_os" in freebsd*) build_target=freebsd - CFLAGS="${CFLAGS} -I/usr/local/include -L/usr/local/lib" + OPTIONAL_OS_DEP_CFLAGS="-I/usr/local/include" + CFLAGS="${CFLAGS} ${OPTIONAL_OS_DEP_CFLAGS}" + LDFLAGS="${LDFLAGS} -L/usr/local/lib" ;; darwin*) build_target=macos LDFLAGS="${LDFLAGS} -framework CoreFoundation -framework IOKit" + # ----------------------------------------------------------------------------- + # Pull in OpenSSL properly if on macOS + if brew --prefix > /dev/null 2>&1; then + if brew --prefix --installed openssl > /dev/null 2>&1; then + HOMEBREW_OPENSSL_PREFIX=$(brew --prefix --installed openssl) + elif brew --prefix --installed openssl@3 > /dev/null 2>&1; then + HOMEBREW_OPENSSL_PREFIX=$(brew --prefix --installed openssl@3) + elif brew --prefix --installed openssl@1.1 > /dev/null 2>&1; then + HOMEBREW_OPENSSL_PREFIX=$(brew --prefix --installed openssl@1.1) + fi + if test -n "${HOMEBREW_OPENSSL_PREFIX}"; then + OPTIONAL_OS_DEP_CFLAGS="-I${HOMEBREW_OPENSSL_PREFIX}/include" + CFLAGS="${CFLAGS} ${OPTIONAL_OS_DEP_CFLAGS}" + LDFLAGS="${LDFLAGS} -L${HOMEBREW_OPENSSL_PREFIX}/lib" + fi + HOMEBREW_PREFIX=$(brew --prefix) + OPTIONAL_OS_DEP_CFLAGS="${OPTIONAL_OS_DEP_CFLAGS} -I${HOMEBREW_PREFIX}/include" + CFLAGS="${CFLAGS} -I${HOMEBREW_PREFIX}/include" + LDFLAGS="${LDFLAGS} -L${HOMEBREW_PREFIX}/lib" + fi ;; *) build_target=linux @@ -405,7 +427,6 @@ PKG_CHECK_MODULES( [have_uuid=yes], [AC_MSG_ERROR([libuuid required but not found. Try installing 'uuid-dev' or 'libuuid-devel'.])] ) -AC_DEFINE([NETDATA_WITH_UUID], [1], [uuid usability]) OPTIONAL_UUID_CFLAGS="${UUID_CFLAGS}" OPTIONAL_UUID_LIBS="${UUID_LIBS}" @@ -1216,11 +1237,10 @@ if test "${build_target}" = "linux" -a "${enable_ebpf}" != "no"; then [have_libbpf=no] ) - AC_MSG_CHECKING([if ebpf.plugin should be enabled]) if test "${have_libelf}" = "yes" -a \ "${have_bpf}" = "yes" -a \ "${have_libbpf}" = "yes"; then - OPTIONAL_BPF_CFLAGS="${LIBELF_CFLAGS} -I \$(abs_top_srcdir)/externaldeps/libbpf/include" + OPTIONAL_BPF_CFLAGS="${LIBELF_CFLAGS} -I \$(abs_top_srcdir)/externaldeps/libbpf/include -I \$(abs_top_srcdir)/externaldeps/libbpf/include/uapi" OPTIONAL_BPF_LIBS="\$(abs_top_srcdir)/externaldeps/libbpf/libbpf.a ${LIBELF_LIBS}" AC_DEFINE([HAVE_LIBBPF], [1], [libbpf usability]) enable_ebpf="yes" @@ -1230,6 +1250,7 @@ if test "${build_target}" = "linux" -a "${enable_ebpf}" != "no"; then else enable_ebpf="no" fi +AC_MSG_CHECKING([if ebpf.plugin should be enabled]) AC_MSG_RESULT([${enable_ebpf}]) AM_CONDITIONAL([ENABLE_PLUGIN_EBPF], [test "${enable_ebpf}" = "yes"]) @@ -1248,7 +1269,7 @@ AM_CONDITIONAL([ENABLE_PLUGIN_SLABINFO], [test "${enable_plugin_slabinfo}" = "ye # ----------------------------------------------------------------------------- -# AWS Kinesis backend - libaws-cpp-sdk-kinesis, libaws-cpp-sdk-core, libssl, libcrypto, libcurl +# AWS Kinesis exporting connector - libaws-cpp-sdk-kinesis, libaws-cpp-sdk-core, libssl, libcrypto, libcurl PKG_CHECK_MODULES( [LIBCRYPTO], @@ -1300,39 +1321,39 @@ PKG_CHECK_MODULES( [have_libaws_cpp_sdk_kinesis=no] ) -test "${enable_backend_kinesis}" = "yes" -a "${have_libaws_cpp_sdk_kinesis}" != "yes" && \ +test "${enable_exporting_kinesis}" = "yes" -a "${have_libaws_cpp_sdk_kinesis}" != "yes" && \ AC_MSG_ERROR([libaws-cpp-sdk-kinesis required but not found. try installing AWS C++ SDK]) -test "${enable_backend_kinesis}" = "yes" -a "${have_libaws_cpp_sdk_core}" != "yes" && \ +test "${enable_exporting_kinesis}" = "yes" -a "${have_libaws_cpp_sdk_core}" != "yes" && \ AC_MSG_ERROR([libaws-cpp-sdk-core required but not found. try installing AWS C++ SDK]) -test "${enable_backend_kinesis}" = "yes" -a "${have_libcurl}" != "yes" && \ +test "${enable_exporting_kinesis}" = "yes" -a "${have_libcurl}" != "yes" && \ AC_MSG_ERROR([libcurl required but not found]) -test "${enable_backend_kinesis}" = "yes" -a "${have_libssl}" != "yes" && \ +test "${enable_exporting_kinesis}" = "yes" -a "${have_libssl}" != "yes" && \ AC_MSG_ERROR([libssl required but not found]) -test "${enable_backend_kinesis}" = "yes" -a "${have_libcrypto}" != "yes" && \ +test "${enable_exporting_kinesis}" = "yes" -a "${have_libcrypto}" != "yes" && \ AC_MSG_ERROR([libcrypto required but not found]) -AC_MSG_CHECKING([if kinesis backend should be enabled]) -if test "${enable_backend_kinesis}" != "no" -a "${have_libaws_cpp_sdk_kinesis}" = "yes" \ +AC_MSG_CHECKING([if kinesis exporting connector should be enabled]) +if test "${enable_exporting_kinesis}" != "no" -a "${have_libaws_cpp_sdk_kinesis}" = "yes" \ -a "${have_libaws_cpp_sdk_core}" = "yes" \ -a "${have_libcurl}" = "yes" \ -a "${have_libssl}" = "yes" \ -a "${have_libcrypto}" = "yes"; then - enable_backend_kinesis="yes" + enable_exporting_kinesis="yes" AC_DEFINE([HAVE_KINESIS], [1], [libaws-cpp-sdk-kinesis usability]) OPTIONAL_KINESIS_CFLAGS="${LIBCRYPTO_CFLAGS} ${LIBSSL_CFLAGS} ${LIBCURL_CFLAGS}" CXX11FLAG="${AWS_CPP_SDK_KINESIS_CFLAGS} ${AWS_CPP_SDK_CORE_CFLAGS}" OPTIONAL_KINESIS_LIBS="${AWS_CPP_SDK_KINESIS_LIBS} ${AWS_CPP_SDK_CORE_LIBS} \ ${LIBCRYPTO_LIBS} ${LIBSSL_LIBS} ${LIBCURL_LIBS}" else - enable_backend_kinesis="no" + enable_exporting_kinesis="no" fi -AC_MSG_RESULT([${enable_backend_kinesis}]) -AM_CONDITIONAL([ENABLE_BACKEND_KINESIS], [test "${enable_backend_kinesis}" = "yes"]) +AC_MSG_RESULT([${enable_exporting_kinesis}]) +AM_CONDITIONAL([ENABLE_EXPORTING_KINESIS], [test "${enable_exporting_kinesis}" = "yes"]) # ----------------------------------------------------------------------------- @@ -1367,7 +1388,7 @@ test "${enable_pubsub}" = "yes" -a "${have_grpc}" != "yes" && \ test "${enable_pubsub}" = "yes" -a "${have_pubsub_protos}" != "yes" && \ AC_MSG_ERROR([libgoogleapis_cpp_pubsub_protos required but not found. try installing googleapis]) -test "${enable_backend_prometheus_remote_write}" = "yes" -a "${have_CXX_compiler}" != "yes" && \ +test "${enable_exporting_prometheus_remote_write}" = "yes" -a "${have_CXX_compiler}" != "yes" && \ AC_MSG_ERROR([C++ compiler required but not found. try installing g++]) AC_MSG_CHECKING([if pubsub exporting connector should be enabled]) @@ -1386,7 +1407,7 @@ AM_CONDITIONAL([ENABLE_EXPORTING_PUBSUB], [test "${enable_exporting_pubsub}" = " # ----------------------------------------------------------------------------- -# Prometheus remote write backend - libprotobuf, libsnappy, protoc +# Prometheus remote write exporting connector - libprotobuf, libsnappy, protoc AC_MSG_CHECKING([for snappy::RawCompress in -lsnappy]) @@ -1423,22 +1444,22 @@ AC_MSG_CHECKING([for snappy::RawCompress in -lsnappy]) AC_MSG_RESULT([${have_libsnappy}]) -test "${enable_backend_prometheus_remote_write}" = "yes" -a "${have_libprotobuf}" != "yes" && \ +test "${enable_exporting_prometheus_remote_write}" = "yes" -a "${have_libprotobuf}" != "yes" && \ AC_MSG_ERROR([libprotobuf required but not found. try installing protobuf]) -test "${enable_backend_prometheus_remote_write}" = "yes" -a "${have_libsnappy}" != "yes" && \ +test "${enable_exporting_prometheus_remote_write}" = "yes" -a "${have_libsnappy}" != "yes" && \ AC_MSG_ERROR([libsnappy required but not found. try installing snappy]) -test "${enable_backend_prometheus_remote_write}" = "yes" -a "${have_protoc}" != "yes" && \ +test "${enable_exporting_prometheus_remote_write}" = "yes" -a "${have_protoc}" != "yes" && \ AC_MSG_ERROR([protoc compiler required but not found. try installing protobuf]) -test "${enable_backend_prometheus_remote_write}" = "yes" -a "${have_CXX_compiler}" != "yes" && \ +test "${enable_exporting_prometheus_remote_write}" = "yes" -a "${have_CXX_compiler}" != "yes" && \ AC_MSG_ERROR([C++ compiler required but not found. try installing g++]) -AC_MSG_CHECKING([if prometheus remote write backend should be enabled]) -if test "${enable_backend_prometheus_remote_write}" != "no" -a "${have_libprotobuf}" = "yes" -a "${have_libsnappy}" = "yes" \ +AC_MSG_CHECKING([if prometheus remote write exporting connector should be enabled]) +if test "${enable_exporting_prometheus_remote_write}" != "no" -a "${have_libprotobuf}" = "yes" -a "${have_libsnappy}" = "yes" \ -a "${have_protoc}" = "yes" -a "${have_CXX_compiler}" = "yes"; then - enable_backend_prometheus_remote_write="yes" + enable_exporting_prometheus_remote_write="yes" AC_DEFINE([ENABLE_PROMETHEUS_REMOTE_WRITE], [1], [Prometheus remote write API usability]) OPTIONAL_PROMETHEUS_REMOTE_WRITE_CFLAGS="${SNAPPY_CFLAGS} -I \$(abs_top_srcdir)/exporting/prometheus/remote_write" CXX11FLAG="-std=c++11" @@ -1446,15 +1467,15 @@ if test "${enable_backend_prometheus_remote_write}" != "no" -a "${have_libprotob OPTIONAL_PROTOBUF_CFLAGS="${PROTOBUF_CFLAGS}" OPTIONAL_PROTOBUF_LIBS="${PROTOBUF_LIBS}" else - enable_backend_prometheus_remote_write="no" + enable_exporting_prometheus_remote_write="no" fi -AC_MSG_RESULT([${enable_backend_prometheus_remote_write}]) -AM_CONDITIONAL([ENABLE_BACKEND_PROMETHEUS_REMOTE_WRITE], [test "${enable_backend_prometheus_remote_write}" = "yes"]) +AC_MSG_RESULT([${enable_exporting_prometheus_remote_write}]) +AM_CONDITIONAL([ENABLE_EXPORTING_PROMETHEUS_REMOTE_WRITE], [test "${enable_exporting_prometheus_remote_write}" = "yes"]) # ----------------------------------------------------------------------------- -# MongoDB backend - libmongoc +# MongoDB exporting connector - libmongoc PKG_CHECK_MODULES( [LIBMONGOC], @@ -1463,21 +1484,21 @@ PKG_CHECK_MODULES( [have_libmongoc=no] ) -test "${enable_backend_mongodb}" = "yes" -a "${have_libmongoc}" != "yes" && \ +test "${enable_exporting_mongodb}" = "yes" -a "${have_libmongoc}" != "yes" && \ AC_MSG_ERROR([libmongoc required but not found. Try installing `mongoc`.]) -AC_MSG_CHECKING([if mongodb backend should be enabled]) -if test "${enable_backend_mongodb}" != "no" -a "${have_libmongoc}" = "yes"; then - enable_backend_mongodb="yes" +AC_MSG_CHECKING([if mongodb exporting connector should be enabled]) +if test "${enable_exporting_mongodb}" != "no" -a "${have_libmongoc}" = "yes"; then + enable_exporting_mongodb="yes" AC_DEFINE([HAVE_MONGOC], [1], [libmongoc usability]) OPTIONAL_MONGOC_CFLAGS="${LIBMONGOC_CFLAGS}" OPTIONAL_MONGOC_LIBS="${LIBMONGOC_LIBS}" else - enable_backend_mongodb="no" + enable_exporting_mongodb="no" fi -AC_MSG_RESULT([${enable_backend_mongodb}]) -AM_CONDITIONAL([ENABLE_BACKEND_MONGODB], [test "${enable_backend_mongodb}" = "yes"]) +AC_MSG_RESULT([${enable_exporting_mongodb}]) +AM_CONDITIONAL([ENABLE_EXPORTING_MONGODB], [test "${enable_exporting_mongodb}" = "yes"]) # ----------------------------------------------------------------------------- @@ -1516,7 +1537,7 @@ test "${enable_lto}" = "yes" -a "${have_lto}" != "yes" && \ AC_MSG_CHECKING([if LTO should be enabled]) if test "${enable_lto}" != "no" -a "${have_lto}" = "yes"; then enable_lto="yes" - CFLAGS="${CFLAGS} -flto" + OPTIONAL_LTO_CFLAGS="-flto" else enable_lto="no" fi @@ -1525,42 +1546,42 @@ AC_MSG_RESULT([${enable_lto}]) # ----------------------------------------------------------------------------- -if test "${enable_backend_kinesis}" = "yes" -o \ +if test "${enable_exporting_kinesis}" = "yes" -o \ "${enable_exporting_pubsub}" = "yes" -o \ - "${enable_backend_prometheus_remote_write}" = "yes" -o \ + "${enable_exporting_prometheus_remote_write}" = "yes" -o \ "${new_cloud_protocol}" = "yes" -o \ "${build_ml}" = "yes"; then enable_cxx_linker="yes" +fi - # Try to unconditionally link with -latomic. If the compiler can satisfy - # all the atomic ops with builtins then, the library will be left unused. - # Otherwise, some ops will be covered by the compiler's intrinsics and some - # will be picked up by the linker from -latomic. In the later case, if - # -latomic is not available there will be a build failure, which would - # have happened either way before this change. - AC_LANG_PUSH([C++]) - - AC_MSG_CHECKING(whether we can use -latomic) - OLD_LIBS="${LIBS}" - LIBS="-latomic" - AC_LINK_IFELSE([AC_LANG_SOURCE([[ - #include - #include - std::atomic v; - int main() { - return v; - } - ]])], CAN_USE_LIBATOMIC=yes, CAN_USE_LIBATOMIC=no) - LIBS="${OLD_LIBS}" - AC_MSG_RESULT($CAN_USE_LIBATOMIC) - - if test "x$CAN_USE_LIBATOMIC" = xyes; then - OPTIONAL_ATOMIC_LIBS="-latomic" - fi - AC_SUBST([OPTIONAL_ATOMIC_LIBS]) +# Try to unconditionally link with -latomic. If the compiler can satisfy +# all the atomic ops with builtins then, the library will be left unused. +# Otherwise, some ops will be covered by the compiler's intrinsics and some +# will be picked up by the linker from -latomic. In the later case, if +# -latomic is not available there will be a build failure, which would +# have happened either way before this change. +AC_LANG_PUSH([C++]) - AC_LANG_POP([C++]) +AC_MSG_CHECKING(whether we can use -latomic) +OLD_LIBS="${LIBS}" +LIBS="-latomic" +AC_LINK_IFELSE([AC_LANG_SOURCE([[ + #include + #include + std::atomic v; + int main() { + return v; + } +]])], CAN_USE_LIBATOMIC=yes, CAN_USE_LIBATOMIC=no) +LIBS="${OLD_LIBS}" +AC_MSG_RESULT($CAN_USE_LIBATOMIC) + +if test "x$CAN_USE_LIBATOMIC" = xyes; then + OPTIONAL_ATOMIC_LIBS="-latomic" fi +AC_SUBST([OPTIONAL_ATOMIC_LIBS]) + +AC_LANG_POP([C++]) AM_CONDITIONAL([ENABLE_CXX_LINKER], [test "${enable_cxx_linker}" = "yes"]) @@ -1589,11 +1610,12 @@ AC_SUBST([logdir]) AC_SUBST([pluginsdir]) AC_SUBST([webdir]) -CFLAGS="${CFLAGS} ${OPTIONAL_PROTOBUF_CFLAGS} ${OPTIONAL_MATH_CFLAGS} ${OPTIONAL_NFACCT_CFLAGS} ${OPTIONAL_ZLIB_CFLAGS} ${OPTIONAL_UUID_CFLAGS} \ +CFLAGS="${originalCFLAGS} ${OPTIONAL_LTO_CFLAGS} ${OPTIONAL_PROTOBUF_CFLAGS} ${OPTIONAL_MATH_CFLAGS} ${OPTIONAL_NFACCT_CFLAGS} \ + ${OPTIONAL_ZLIB_CFLAGS} ${OPTIONAL_UUID_CFLAGS} \ ${OPTIONAL_LIBCAP_CFLAGS} ${OPTIONAL_IPMIMONITORING_CFLAGS} ${OPTIONAL_CUPS_CFLAGS} ${OPTIONAL_XENSTAT_FLAGS} \ ${OPTIONAL_KINESIS_CFLAGS} ${OPTIONAL_PUBSUB_CFLAGS} ${OPTIONAL_PROMETHEUS_REMOTE_WRITE_CFLAGS} \ ${OPTIONAL_MONGOC_CFLAGS} ${LWS_CFLAGS} ${OPTIONAL_JSONC_STATIC_CFLAGS} ${OPTIONAL_BPF_CFLAGS} ${OPTIONAL_JUDY_CFLAGS} \ - ${OPTIONAL_ACLK_CFLAGS} ${OPTIONAL_ML_CFLAGS} ${OPTIONAL_ML_TESTS_CFLAGS}" + ${OPTIONAL_ACLK_CFLAGS} ${OPTIONAL_ML_CFLAGS} ${OPTIONAL_ML_TESTS_CFLAGS} ${OPTIONAL_OS_DEP_CFLAGS}" CXXFLAGS="${CFLAGS} ${CXX11FLAG}" @@ -1690,14 +1712,6 @@ AC_DEFINE_UNQUOTED( AC_CONFIG_FILES([ Makefile netdata.spec - backends/graphite/Makefile - backends/json/Makefile - backends/Makefile - backends/opentsdb/Makefile - backends/prometheus/Makefile - backends/prometheus/remote_write/Makefile - backends/aws_kinesis/Makefile - backends/mongodb/Makefile collectors/Makefile collectors/apps.plugin/Makefile collectors/cgroups.plugin/Makefile diff --git a/contrib/README.md b/contrib/README.md index e253efa99..36abd3b10 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -58,4 +58,4 @@ source is to remove the current package from your system, then install the new package. Upgrading on wheezy is known to not work cleanly; Jessie may behave as expected. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcontrib%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/contrib/debian/compat b/contrib/debian/compat index ec635144f..f599e28b8 100644 --- a/contrib/debian/compat +++ b/contrib/debian/compat @@ -1 +1 @@ -9 +10 diff --git a/contrib/debian/netdata.postinst b/contrib/debian/netdata.postinst index f26c94f93..a6bd29960 100644 --- a/contrib/debian/netdata.postinst +++ b/contrib/debian/netdata.postinst @@ -50,9 +50,7 @@ case "$1" in dpkg-statoverride --force --update --add root netdata 0775 /var/lib/netdata/registry > /dev/null 2>&1 - chown -R root:netdata /usr/share/netdata chown -R root:netdata /usr/libexec/netdata/plugins.d - chown -R root:netdata /var/lib/netdata/www setcap cap_dac_read_search,cap_sys_ptrace+ep /usr/libexec/netdata/plugins.d/apps.plugin setcap cap_dac_read_search+ep /usr/libexec/netdata/plugins.d/slabinfo.plugin capsh --supports=cap_perfmon 2>/dev/null && setcap cap_perfmon+ep /usr/libexec/netdata/plugins.d/perf.plugin || setcap cap_sys_admin+ep /usr/libexec/netdata/plugins.d/perf.plugin @@ -65,6 +63,7 @@ case "$1" in # Workaround for other plugins not installed directly by this package chmod -f 4750 /usr/libexec/netdata/plugins.d/freeipmi.plugin || true + chmod -f 4750 /usr/libexec/netdata/plugins.d/ioping || true ;; esac diff --git a/contrib/debian/rules b/contrib/debian/rules index f36e995fc..cbf4a8375 100755 --- a/contrib/debian/rules +++ b/contrib/debian/rules @@ -23,26 +23,20 @@ HAVE_EBPF = 1 endif %: - # For jessie and beyond - # - dh $@ --with autoreconf,systemd - - # For wheezy or other non-systemd distributions use the following. You - # should also see contrib/README.md which gives details of updates to - # make to debian/control. - # - #dh $@ --with autoreconf + dh $@ override_dh_installinit: echo "SystemD Version: $(SYSTEMD_VERSION)" echo "Using SystemD Unit: $(SYSTEMD_UNIT)" cp -v $(SYSTEMD_UNIT) debian/netdata.service + dh_systemd_enable dh_installinit override_dh_auto_configure: if [ $(HAVE_EBPF) -eq 1 ]; then \ packaging/bundle-libbpf.sh . ${TOP}/usr/libexec/netdata/plugins.d; \ + packaging/bundle-ebpf-co-re.sh . ${TOP}/usr/libexec/netdata/plugins.d; \ fi autoreconf -ivf dh_auto_configure -- --prefix=/usr --sysconfdir=/etc --localstatedir=/var --libdir=/usr/lib \ @@ -75,6 +69,10 @@ override_dh_install: mkdir -p "$(TOP)/var/cache/netdata" mkdir -p "$(TOP)/var/run/netdata" + # Copy the updater script + # + cp -v packaging/installer/netdata-updater.sh $(TOP)/usr/libexec/netdata/netdata-updater.sh + # Move files that local user shouldn't be editing to /usr/share/netdata # mkdir -p "$(TOP)/usr/share/netdata/www" @@ -108,6 +106,10 @@ override_dh_installdocs: override_dh_fixperms: dh_fixperms + # Updater script should be executable + # + chmod 0755 $(TOP)/usr/libexec/netdata/netdata-updater.sh + # apps.plugin should only be runnable by the netdata user. It will be # given extra capabilities in the postinst script. # diff --git a/contrib/sles11/README.md b/contrib/sles11/README.md deleted file mode 100644 index 4cdf7e9f9..000000000 --- a/contrib/sles11/README.md +++ /dev/null @@ -1,17 +0,0 @@ - - -# Spec to build Netdata RPM for sles 11 - -Based on [openSUSE rpm spec](https://build.opensuse.org/package/show/network/netdata) with some -changes and additions for sles 11 backport, namely: - -- init.d script -- run-time dependency on python ordereddict backport -- patch for Netdata python.d plugin to work with older python -- crude hack of notification script to work with bash 3 (email and syslog only, one destination, - see comments at the top) - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcontrib%2Fsles11%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) diff --git a/contrib/sles11/alarm-notify-basic.bash3.sh b/contrib/sles11/alarm-notify-basic.bash3.sh deleted file mode 100755 index df382923e..000000000 --- a/contrib/sles11/alarm-notify-basic.bash3.sh +++ /dev/null @@ -1,755 +0,0 @@ -#!/usr/bin/env bash - -# basic version of netdata notifier to work with bash3 -# only mail and syslog destinations are supported, one recipient each -# - email: DEFAULT_RECIPIENT_EMAIL, "root" by default -# - syslog: "netdata" with local6 facility; disabled by default -# - also: setting recipient to "disabled" or "silent" stops notifications for this alert - -# in /etc/netdata/health_alarm_notify.conf set something like -# EMAIL_SENDER="netdata@gesdev-vm.m0.maxidom.ru" -# SEND_EMAIL="YES" -# DEFAULT_RECIPIENT_EMAIL="root" -# SEND_SYSLOG="YES" -# SYSLOG_FACILITY="local6" -# DEFAULT_RECIPIENT_SYSLOG="netdata" - -# netdata -# real-time performance and health monitoring, done right! -# (C) 2017 Costa Tsaousis -# GPL v3+ -# -# Script to send alarm notifications for netdata -# -# Supported notification methods: -# - emails by @ktsaou -# - syslog messages by @Ferroin -# - all the rest is pruned :) - -# ----------------------------------------------------------------------------- -# testing notifications - -if [ \( "${1}" = "test" -o "${2}" = "test" \) -a "${#}" -le 2 ] -then - if [ "${2}" = "test" ] - then - recipient="${1}" - else - recipient="${2}" - fi - - [ -z "${recipient}" ] && recipient="sysadmin" - - id=1 - last="CLEAR" - test_res=0 - for x in "WARNING" "CRITICAL" "CLEAR" - do - echo >&2 - echo >&2 "# SENDING TEST ${x} ALARM TO ROLE: ${recipient}" - - "${0}" "${recipient}" "$(hostname)" 1 1 "${id}" "$(date +%s)" "test_alarm" "test.chart" "test.family" "${x}" "${last}" 100 90 "${0}" 1 $((0 + id)) "units" "this is a test alarm to verify notifications work" "new value" "old value" - if [ $? -ne 0 ] - then - echo >&2 "# FAILED" - test_res=1 - else - echo >&2 "# OK" - fi - - last="${x}" - id=$((id + 1)) - done - - exit $test_res -fi - -export PATH="${PATH}:/sbin:/usr/sbin:/usr/local/sbin" -export LC_ALL=C - -# ----------------------------------------------------------------------------- - -PROGRAM_NAME="$(basename "${0}")" - -logdate() { - date "+%Y-%m-%d %H:%M:%S" -} - -log() { - local status="${1}" - shift - - echo >&2 "$(logdate): ${PROGRAM_NAME}: ${status}: ${*}" - -} - -warning() { - log WARNING "${@}" -} - -error() { - log ERROR "${@}" -} - -info() { - log INFO "${@}" -} - -fatal() { - log FATAL "${@}" - exit 1 -} - -debug=${NETDATA_ALARM_NOTIFY_DEBUG-0} -debug() { - [ "${debug}" = "1" ] && log DEBUG "${@}" -} - -docurl() { - if [ -z "${curl}" ] - then - error "\${curl} is unset." - return 1 - fi - - if [ "${debug}" = "1" ] - then - echo >&2 "--- BEGIN curl command ---" - printf >&2 "%q " ${curl} "${@}" - echo >&2 - echo >&2 "--- END curl command ---" - - local out=$(mktemp /tmp/netdata-health-alarm-notify-XXXXXXXX) - local code=$(${curl} ${curl_options} --write-out %{http_code} --output "${out}" --silent --show-error "${@}") - local ret=$? - echo >&2 "--- BEGIN received response ---" - cat >&2 "${out}" - echo >&2 - echo >&2 "--- END received response ---" - echo >&2 "RECEIVED HTTP RESPONSE CODE: ${code}" - rm "${out}" - echo "${code}" - return ${ret} - fi - - ${curl} ${curl_options} --write-out %{http_code} --output /dev/null --silent --show-error "${@}" - return $? -} - -# ----------------------------------------------------------------------------- -# this is to be overwritten by the config file - -custom_sender() { - info "not sending custom notification for ${status} of '${host}.${chart}.${name}'" -} - - -# ----------------------------------------------------------------------------- - -# check for BASH v4+ (required for associative arrays) -[ $(( ${BASH_VERSINFO[0]} )) -lt 3 ] && \ - fatal "BASH version 3 or later is required (this is ${BASH_VERSION})." - -# ----------------------------------------------------------------------------- -# defaults to allow running this script by hand - -[ -z "${NETDATA_CONFIG_DIR}" ] && NETDATA_CONFIG_DIR="$(dirname "${0}")/../../../../etc/netdata" -[ -z "${NETDATA_CACHE_DIR}" ] && NETDATA_CACHE_DIR="$(dirname "${0}")/../../../../var/cache/netdata" -[ -z "${NETDATA_REGISTRY_URL}" ] && NETDATA_REGISTRY_URL="https://registry.my-netdata.io" - -# ----------------------------------------------------------------------------- -# parse command line parameters - -roles="${1}" # the roles that should be notified for this event -host="${2}" # the host generated this event -unique_id="${3}" # the unique id of this event -alarm_id="${4}" # the unique id of the alarm that generated this event -event_id="${5}" # the incremental id of the event, for this alarm id -when="${6}" # the timestamp this event occurred -name="${7}" # the name of the alarm, as given in netdata health.d entries -chart="${8}" # the name of the chart (type.id) -family="${9}" # the family of the chart -status="${10}" # the current status : REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL -old_status="${11}" # the previous status: REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL -value="${12}" # the current value of the alarm -old_value="${13}" # the previous value of the alarm -src="${14}" # the line number and file the alarm has been configured -duration="${15}" # the duration in seconds of the previous alarm state -non_clear_duration="${16}" # the total duration in seconds this is/was non-clear -units="${17}" # the units of the value -info="${18}" # a short description of the alarm -value_string="${19}" # friendly value (with units) -old_value_string="${20}" # friendly old value (with units) - -# ----------------------------------------------------------------------------- -# find a suitable hostname to use, if netdata did not supply a hostname - -this_host=$(hostname -s 2>/dev/null) -[ -z "${host}" ] && host="${this_host}" - -# ----------------------------------------------------------------------------- -# screen statuses we don't need to send a notification - -# don't do anything if this is not WARNING, CRITICAL or CLEAR -if [ "${status}" != "WARNING" -a "${status}" != "CRITICAL" -a "${status}" != "CLEAR" ] -then - info "not sending notification for ${status} of '${host}.${chart}.${name}'" - exit 1 -fi - -# don't do anything if this is CLEAR, but it was not WARNING or CRITICAL -if [ "${old_status}" != "WARNING" -a "${old_status}" != "CRITICAL" -a "${status}" = "CLEAR" ] -then - info "not sending notification for ${status} of '${host}.${chart}.${name}' (last status was ${old_status})" - exit 1 -fi - -# ----------------------------------------------------------------------------- -# load configuration - -# By default fetch images from the global public registry. -# This is required by default, since all notification methods need to download -# images via the Internet, and private registries might not be reachable. -# This can be overwritten at the configuration file. -images_base_url="https://registry.my-netdata.io" - -# curl options to use -curl_options= - -# needed commands -# if empty they will be searched in the system path -curl= -sendmail= - -# enable / disable features -SEND_EMAIL="YES" -SEND_SYSLOG="YES" - -# syslog configs -SYSLOG_FACILITY="local6" - -# email configs -EMAIL_SENDER= -DEFAULT_RECIPIENT_EMAIL="root" -EMAIL_CHARSET=$(locale charmap 2>/dev/null) - -# load the user configuration -# this will overwrite the variables above -if [ -f "${NETDATA_CONFIG_DIR}/health_alarm_notify.conf" ] - then - source "${NETDATA_CONFIG_DIR}/health_alarm_notify.conf" -else - error "Cannot find file ${NETDATA_CONFIG_DIR}/health_alarm_notify.conf. Using internal defaults." -fi - -# If we didn't autodetect the character set for e-mail and it wasn't -# set by the user, we need to set it to a reasonable default. UTF-8 -# should be correct for almost all modern UNIX systems. -if [ -z ${EMAIL_CHARSET} ] - then - EMAIL_CHARSET="UTF-8" -fi - -# disable if role = silent or disabled -if [[ "${role}" = "silent" || "${role}" = "disabled" ]]; then - SEND_EMAIL="NO" - SEND_SYSLOG="NO" -fi - -if [[ "SEND_EMAIL" != "NO" ]]; then - to_email=$DEFAULT_RECIPIENT_EMAIL -else - to_email='' -fi - -if [[ "SEND_SYSLOG" != "NO" ]]; then - to_syslog=$DEFAULT_RECIPIENT_SYSLOG -else - to_syslog='' -fi - -# if we need sendmail, check for the sendmail command -if [ "${SEND_EMAIL}" = "YES" -a -z "${sendmail}" ] - then - sendmail="$(which sendmail 2>/dev/null || command -v sendmail 2>/dev/null)" - if [ -z "${sendmail}" ] - then - debug "Cannot find sendmail command in the system path. Disabling email notifications." - SEND_EMAIL="NO" - fi -fi - -# if we need logger, check for the logger command -if [ "${SEND_SYSLOG}" = "YES" -a -z "${logger}" ] - then - logger="$(which logger 2>/dev/null || command -v logger 2>/dev/null)" - if [ -z "${logger}" ] - then - debug "Cannot find logger command in the system path. Disabling syslog notifications." - SEND_SYSLOG="NO" - fi -fi - -# check that we have at least a method enabled -if [ "${SEND_EMAIL}" != "YES" \ - -a "${SEND_SYSLOG}" != "YES" \ - ] - then - fatal "All notification methods are disabled. Not sending notification for host '${host}', chart '${chart}' to '${roles}' for '${name}' = '${value}' for status '${status}'." -fi - -# ----------------------------------------------------------------------------- -# get the date the alarm happened - -date=$(date --date=@${when} "${DATE_FORMAT}" 2>/dev/null) -[ -z "${date}" ] && date=$(date "${DATE_FORMAT}" 2>/dev/null) -[ -z "${date}" ] && date=$(date --date=@${when} 2>/dev/null) -[ -z "${date}" ] && date=$(date 2>/dev/null) - -# ----------------------------------------------------------------------------- -# function to URL encode a string - -urlencode() { - local string="${1}" strlen encoded pos c o - - strlen=${#string} - for (( pos=0 ; pos ]] - then - # the name includes single quotes - opts=" -f $(echo "${EMAIL_SENDER}" | cut -d '<' -f 2 | cut -d '>' -f 1) -F $(echo "${EMAIL_SENDER}" | cut -d '<' -f 1)" - elif [[ "${EMAIL_SENDER}" =~ \'.*\'\ \<.*\> ]] - then - # the name includes double quotes - opts=" -f $(echo "${EMAIL_SENDER}" | cut -d '<' -f 2 | cut -d '>' -f 1) -F $(echo "${EMAIL_SENDER}" | cut -d '<' -f 1)" - elif [[ "${EMAIL_SENDER}" =~ .*\ \<.*\> ]] - then - # the name does not have any quotes - opts=" -f $(echo "${EMAIL_SENDER}" | cut -d '<' -f 2 | cut -d '>' -f 1) -F '$(echo "${EMAIL_SENDER}" | cut -d '<' -f 1)'" - else - # no name at all - opts=" -f ${EMAIL_SENDER}" - fi - fi - - if [[ "${debug}" = "1" ]] - then - echo >&2 "--- BEGIN sendmail command ---" - printf >&2 "%q " "${sendmail}" -t ${opts} - echo >&2 - echo >&2 "--- END sendmail command ---" - fi - - "${sendmail}" -t ${opts} - ret=$? - - if [ ${ret} -eq 0 ] - then - info "sent email notification for: ${host} ${chart}.${name} is ${status} to '${to_email}'" - return 0 - else - error "failed to send email notification for: ${host} ${chart}.${name} is ${status} to '${to_email}' with error code ${ret}." - return 1 - fi - fi - - return 1 -} - -# ----------------------------------------------------------------------------- -# syslog sender - -send_syslog() { - local facility=${SYSLOG_FACILITY:-"local6"} level='info' targets="${1}" - local priority='' message='' host='' port='' prefix='' - local temp1='' temp2='' - - [[ "${SEND_SYSLOG}" == "YES" ]] || return 1 - - if [[ "${status}" == "CRITICAL" ]] ; then - level='crit' - elif [[ "${status}" == "WARNING" ]] ; then - level='warning' - fi - - for target in ${targets} ; do - priority="${facility}.${level}" - message='' - host='' - port='' - prefix='' - temp1='' - temp2='' - - prefix=$(echo ${target} | cut -d '/' -f 2) - temp1=$(echo ${target} | cut -d '/' -f 1) - - if [[ ${prefix} != ${temp1} ]] ; then - if (echo ${temp1} | grep -q '@' ) ; then - temp2=$(echo ${temp1} | cut -d '@' -f 1) - host=$(echo ${temp1} | cut -d '@' -f 2) - - if [ ${temp2} != ${host} ] ; then - priority=${temp2} - fi - - port=$(echo ${host} | rev | cut -d ':' -f 1 | rev) - - if ( echo ${host} | grep -E -q '\[.*\]' ) ; then - if ( echo ${port} | grep -q ']' ) ; then - port='' - else - host=$(echo ${host} | rev | cut -d ':' -f 2- | rev) - fi - else - if [ ${port} = ${host} ] ; then - port='' - else - host=$(echo ${host} | cut -d ':' -f 1) - fi - fi - else - priority=${temp1} - fi - fi - - # message="${prefix} ${status} on ${host} at ${date}: ${chart} ${value_string}" - - message="${prefix} ${status}: ${chart} ${value_string}" - - if [ ${host} ] ; then - logger_options="${logger_options} -n ${host}" - if [ ${port} ] ; then - logger_options="${logger_options} -P ${port}" - fi - fi - - ${logger} -p ${priority} ${logger_options} "${message}" - done - - return $? -} - - -# ----------------------------------------------------------------------------- -# prepare the content of the notification - -# the url to send the user on click -urlencode "${host}" >/dev/null; url_host="${REPLY}" -urlencode "${chart}" >/dev/null; url_chart="${REPLY}" -urlencode "${family}" >/dev/null; url_family="${REPLY}" -urlencode "${name}" >/dev/null; url_name="${REPLY}" -goto_url="${NETDATA_REGISTRY_URL}/goto-host-from-alarm.html?host=${url_host}&chart=${url_chart}&family=${url_family}&alarm=${url_name}&alarm_unique_id=${unique_id}&alarm_id=${alarm_id}&alarm_event_id=${event_id}" - -# the severity of the alarm -severity="${status}" - -# the time the alarm was raised -duration4human ${duration} >/dev/null; duration_txt="${REPLY}" -duration4human ${non_clear_duration} >/dev/null; non_clear_duration_txt="${REPLY}" -raised_for="(was ${old_status} for ${duration_txt})" - -# the key status message -status_message="status unknown" - -# the color of the alarm -color="grey" - -# the alarm value -alarm="${name//_/ } = ${value_string}" - -# the image of the alarm -image="${images_base_url}/images/seo-performance-128.png" - -# prepare the title based on status -case "${status}" in - CRITICAL) - image="${images_base_url}/images/alert-128-red.png" - status_message="is critical" - color="#ca414b" - ;; - - WARNING) - image="${images_base_url}/images/alert-128-orange.png" - status_message="needs attention" - color="#ffc107" - ;; - - CLEAR) - image="${images_base_url}/images/check-mark-2-128-green.png" - status_message="recovered" - color="#77ca6d" - ;; -esac - -if [ "${status}" = "CLEAR" ] -then - severity="Recovered from ${old_status}" - if [ ${non_clear_duration} -gt ${duration} ] - then - raised_for="(alarm was raised for ${non_clear_duration_txt})" - fi - - # don't show the value when the status is CLEAR - # for certain alarms, this value might not have any meaning - alarm="${name//_/ } ${raised_for}" - -elif [ "${old_status}" = "WARNING" -a "${status}" = "CRITICAL" ] -then - severity="Escalated to ${status}" - if [ ${non_clear_duration} -gt ${duration} ] - then - raised_for="(alarm is raised for ${non_clear_duration_txt})" - fi - -elif [ "${old_status}" = "CRITICAL" -a "${status}" = "WARNING" ] -then - severity="Demoted to ${status}" - if [ ${non_clear_duration} -gt ${duration} ] - then - raised_for="(alarm is raised for ${non_clear_duration_txt})" - fi - -else - raised_for= -fi - -# prepare HTML versions of elements -info_html= -[ ! -z "${info}" ] && info_html="
${info}
" - -raised_for_html= -[ ! -z "${raised_for}" ] && raised_for_html="
${raised_for}" - - -# ----------------------------------------------------------------------------- -# send the syslog message - -send_syslog ${to_syslog} - -SENT_SYSLOG=$? - -# ----------------------------------------------------------------------------- -# send the email - -send_email < - - - - - - - - - -
-
- - - - - - - - - - - - -
-
netdata notification
-
-

${host} ${status_message}

-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ${chart} - Chart -
- ${value_string} - Value -
- ${alarm}${info_html} - Alarm -
- ${family} - Family -
- ${severity} - Severity -
${date} - ${raised_for_html} Time -
- View Netdata -
The source of this alarm is line ${src}
(alarms are configurable, edit this file to adapt the alarm to your needs) -
Sent by - netdata, the real-time performance and health monitoring, on ${this_host}. -
-
-
-
-
- - ---multipart-boundary-- -EOF - -SENT_EMAIL=$? - -# ----------------------------------------------------------------------------- -# let netdata know - -if [ ${SENT_EMAIL} -eq 0 \ - -o ${SENT_SYSLOG} -eq 0 \ - ] - then - # we did send something - exit 0 -fi - -# we did not send anything -exit 1 diff --git a/contrib/sles11/netdata-alarms-bash3.patch b/contrib/sles11/netdata-alarms-bash3.patch deleted file mode 100644 index 142659ba9..000000000 --- a/contrib/sles11/netdata-alarms-bash3.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- system/netdata.conf.orig 2018-05-10 19:44:49.000000000 +0300 -+++ system/netdata.conf 2018-05-10 19:45:14.000000000 +0300 -@@ -22,3 +22,7 @@ - [web] - web files owner = root - web files group = netdata -+ -+[health] -+ # script for sles 11, mail notifications only -+ script to execute on alarm = /usr/lib64/netdata/plugins.d/alarm-notify.bash3.sh diff --git a/contrib/sles11/netdata-automake-no-dist-xz.patch b/contrib/sles11/netdata-automake-no-dist-xz.patch deleted file mode 100644 index d373efac2..000000000 --- a/contrib/sles11/netdata-automake-no-dist-xz.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -u netdata-1.6.0.orig/Makefile.am netdata-1.6.0/Makefile.am ---- netdata-1.6.0.orig/Makefile.am 2017-03-20 19:32:47.000000000 +0100 -+++ netdata-1.6.0/Makefile.am 2017-06-25 23:46:14.403426661 +0200 -@@ -1,7 +1,7 @@ - # - # Copyright (C) 2015 Alon Bar-Lev - # --AUTOMAKE_OPTIONS=foreign dist-bzip2 dist-xz 1.10 -+AUTOMAKE_OPTIONS=foreign dist-bzip2 1.10 - ACLOCAL_AMFLAGS = -I m4 - - MAINTAINERCLEANFILES= \ - diff --git a/contrib/sles11/netdata-python-plugin-sles11.patch b/contrib/sles11/netdata-python-plugin-sles11.patch deleted file mode 100644 index d2e8f6b69..000000000 --- a/contrib/sles11/netdata-python-plugin-sles11.patch +++ /dev/null @@ -1,28 +0,0 @@ -diff -u netdata-1.10.0.orig/plugins.d/python.d.plugin netdata-1.10.0/plugins.d/python.d.plugin ---- netdata-1.10.0.orig/plugins.d/python.d.plugin 2018-05-08 20:01:40.000000000 +0300 -+++ netdata-1.10.0/plugins.d/python.d.plugin 2018-05-08 20:06:57.000000000 +0300 -@@ -15,10 +15,8 @@ - from sys import version_info, argv - from time import sleep - --try: -- from time import monotonic as time --except ImportError: -- from time import time -+# from time import monotonic as time -+from time import time - - PY_VERSION = version_info[:2] - PLUGIN_CONFIG_DIR = os.getenv('NETDATA_CONFIG_DIR', os.path.dirname(__file__) + '/../../../../etc/netdata') + '/' -@@ -32,10 +30,7 @@ - from bases.loggers import PythonDLogger - from bases.collection import setdefault_values, run_and_exit - --try: -- from collections import OrderedDict --except ImportError: -- from third_party.ordereddict import OrderedDict -+from ordereddict import OrderedDict - - BASE_CONFIG = {'update_every': os.getenv('NETDATA_UPDATE_EVERY', 1), - 'retries': 60, diff --git a/contrib/sles11/netdata.init b/contrib/sles11/netdata.init deleted file mode 100755 index 3081c427c..000000000 --- a/contrib/sles11/netdata.init +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/bash -# -### BEGIN INIT INFO -# Provides: netdata -# Required-Start: $all -# Should-Start: -# Required-Stop: $all -# Should-Stop: -# Default-Start: 2 3 5 -# Default-Stop: -# Short-Description: Start and stop the netdata real-time monitoring server daemon -# Description: Controls the main netdata monitoring server daemon "netdata". -### END INIT INFO - -DAEMON="netdata" -DAEMON_BIN="/usr/sbin/${DAEMON}" -DAEMON_PID="/var/run/${DAEMON}.pid" -DAEMON_ARGS="" - -. /etc/rc.status -rc_reset - -if [ ! -x $DAEMON_BIN ]; then - echo -n >&2 "${DAEMON} binary is not installed. " - rc_status -s - exit 5 -fi - -case "$1" in - start) - echo -n "Starting $DAEMON" - /sbin/startproc $DAEMON_BIN $DAEMON_ARGS - rc_status -v - ;; - - stop) - echo -n "Stopping $DAEMON" - /sbin/killproc $DAEMON_BIN - rc_status -v - ;; - - reload) - # netdata: HUP reopen log files, USR1 save DB, USR2 reload health config - echo -n "Reloading $DAEMON config" - /sbin/killproc -USR2 $DAEMON_BIN - ;; - - restart) - $0 stop - $0 start - ;; - - status) - echo -n "Checking $DAEMON" - /sbin/checkproc $DAEMON_BIN - rc_status -v - ;; - - *) - echo "Usage: $0 {start|stop|status|reload|restart}" - exit 1 - ;; - -esac -rc_exit diff --git a/coverity-scan.sh b/coverity-scan.sh index 047d882cd..a745b07dd 100755 --- a/coverity-scan.sh +++ b/coverity-scan.sh @@ -21,7 +21,7 @@ # COVERITY_SCAN_TOKEN="TOKEN taken from Coverity site" # # the absolute path of the cov-build - optional -# COVERITY_BUILD_PATH="/opt/cov-analysis-linux64-2019.03/bin/cov-build" +# COVERITY_BUILD_PATH="/opt/cov-analysis-linux64-2021.12/bin/cov-build" # # when set, the script will print on screen the curl command that submits the build to coverity # this includes the token, so the default is not to print it. @@ -40,7 +40,7 @@ set -e INSTALL_DIR="/opt" # the version of coverity to use -COVERITY_BUILD_VERSION="${COVERITY_BUILD_VERSION:-cov-analysis-linux64-2020.09}" +COVERITY_BUILD_VERSION="${COVERITY_BUILD_VERSION:-cov-analysis-linux64-2021.12}" # TODO: For some reasons this does not fully load on Debian 10 (Haven't checked if it happens on other distros yet), it breaks source packaging/installer/functions.sh || echo "Failed to fully load the functions library" @@ -147,6 +147,8 @@ installit() { run sudo tar -z -x -f "${TMP_DIR}/${COVERITY_BUILD_VERSION}.tar.gz" || exit 1 rm "${TMP_DIR}/${COVERITY_BUILD_VERSION}.tar.gz" export PATH=${PATH}:${INSTALL_DIR}/${COVERITY_BUILD_VERSION}/bin/ + elif find . -name "*.tar.gz" > /dev/null 2>&1; then + fatal "Downloaded coverity tool tarball does not appear to be the version we were expecting, exiting." else fatal "Failed to download coverity tool tarball!" fi @@ -157,11 +159,11 @@ installit() { fatal "Failed to install coverity." fi - # Clean temp directory - [ -n "${TMP_DIR}" ] && rm -rf "${TMP_DIR}" - progress "Coverity scan tools are installed." cd "$ORIGINAL_DIR" + + # Clean temp directory + [ -n "${TMP_DIR}" ] && rm -rf "${TMP_DIR}" return 0 } @@ -173,11 +175,11 @@ OTHER_OPTIONS+=" --enable-jsonc" OTHER_OPTIONS+=" --enable-plugin-nfacct" OTHER_OPTIONS+=" --enable-plugin-freeipmi" OTHER_OPTIONS+=" --enable-plugin-cups" -OTHER_OPTIONS+=" --enable-backend-prometheus-remote-write" +OTHER_OPTIONS+=" --enable-exporting-prometheus-remote-write" # TODO: enable these plugins too #OTHER_OPTIONS+=" --enable-plugin-xenstat" -#OTHER_OPTIONS+=" --enable-backend-kinesis" -#OTHER_OPTIONS+=" --enable-backend-mongodb" +#OTHER_OPTIONS+=" --enable-exporting-kinesis" +#OTHER_OPTIONS+=" --enable-exporting-mongodb" FOUND_OPTS="NO" while [ -n "${1}" ]; do diff --git a/daemon/README.md b/daemon/README.md index 1ea865f89..44abfa8e9 100644 --- a/daemon/README.md +++ b/daemon/README.md @@ -254,57 +254,14 @@ where: See [debugging](#debugging). -## OOM Score - -Netdata runs with `OOMScore = 1000`. This means Netdata will be the first to be killed when your server runs out of -memory. - -You can set Netdata OOMScore in `netdata.conf`, like this: - -```conf -[global] - OOM score = 1000 -``` - -Netdata logs its OOM score when it starts: - -```sh -# grep OOM /var/log/netdata/error.log -2017-10-15 03:47:31: netdata INFO : Adjusted my Out-Of-Memory (OOM) score from 0 to 1000. -``` - -### OOM score and systemd - -Netdata will not be able to lower its OOM Score below zero, when it is started as the `netdata` user (systemd case). - -To allow Netdata control its OOM Score in such cases, you will need to edit `netdata.service` and set: - -```sh -[Service] -# The minimum Netdata Out-Of-Memory (OOM) score. -# Netdata (via [global].OOM score in netdata.conf) can only increase the value set here. -# To decrease it, set the minimum here and set the same or a higher value in netdata.conf. -# Valid values: -1000 (never kill netdata) to 1000 (always kill netdata). -OOMScoreAdjust=-1000 -``` - -Run `systemctl daemon-reload` to reload these changes. - -The above, sets and OOMScore for Netdata to `-1000`, so that Netdata can increase it via `netdata.conf`. - -If you want to control it entirely via systemd, you can set in `netdata.conf`: - -```conf -[global] - OOM score = keep -``` - -Using the above, whatever OOM Score you have set at `netdata.service` will be maintained by netdata. - ## Netdata process scheduling policy -By default Netdata runs with the `idle` process scheduling policy, so that it uses CPU resources, only when there is -idle CPU to spare. On very busy servers (or weak servers), this can lead to gaps on the charts. +By default Netdata versions prior to 1.34.0 run with the `idle` process scheduling policy, so that it uses CPU +resources, only when there is idle CPU to spare. On very busy servers (or weak servers), this can lead to gaps on +the charts. + +Starting with version 1.34.0, Netdata instead uses the `batch` scheduling policy by default. This largely eliminates +issues with gaps in charts on busy systems while still keeping the impact on the rest of the system low. You can set Netdata scheduling policy in `netdata.conf`, like this: @@ -315,9 +272,9 @@ You can set Netdata scheduling policy in `netdata.conf`, like this: You can use the following: -| policy | description | +| policy | description | | :-----------------------: | :---------- | -| `idle` | use CPU only when there is spare - this is lower than nice 19 - it is the default for Netdata and it is so low that Netdata will run in "slow motion" under extreme system load, resulting in short (1-2 seconds) gaps at the charts. | +| `idle` | use CPU only when there is spare - this is lower than nice 19 - it is the default for Netdata and it is so low that Netdata will run in "slow motion" under extreme system load, resulting in short (1-2 seconds) gaps at the charts. | | `other`
or
`nice` | this is the default policy for all processes under Linux. It provides dynamic priorities based on the `nice` level of each process. Check below for setting this `nice` level for netdata. | | `batch` | This policy is similar to `other` in that it schedules the thread according to its dynamic priority (based on the `nice` value). The difference is that this policy will cause the scheduler to always assume that the thread is CPU-intensive. Consequently, the scheduler will apply a small scheduling penalty with respect to wake-up behavior, so that this thread is mildly disfavored in scheduling decisions. | | `fifo` | `fifo` can be used only with static priorities higher than 0, which means that when a `fifo` threads becomes runnable, it will always immediately preempt any currently running `other`, `batch`, or `idle` thread. `fifo` is a simple scheduling algorithm without time slicing. | @@ -551,4 +508,4 @@ valgrind $(which netdata) -D Netdata will start and it will be a lot slower. Now reproduce the crash and `valgrind` will dump on your console the stack trace. Open a new github issue and post the output. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdaemon%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/daemon/analytics.c b/daemon/analytics.c index 4501a46a5..0af41fdda 100644 --- a/daemon/analytics.c +++ b/daemon/analytics.c @@ -362,21 +362,15 @@ void analytics_alarms_notifications(void) void analytics_get_install_type(void) { - struct install_type_info t = get_install_type(); - - if (t.install_type == NULL) { + if (localhost->system_info->install_type == NULL) { analytics_set_data_str(&analytics_data.netdata_install_type, "unknown"); } else { - analytics_set_data_str(&analytics_data.netdata_install_type, t.install_type); + analytics_set_data_str(&analytics_data.netdata_install_type, localhost->system_info->install_type); } - if (t.prebuilt_distro != NULL) { - analytics_set_data_str(&analytics_data.netdata_prebuilt_distro, t.prebuilt_distro); + if (localhost->system_info->prebuilt_dist != NULL) { + analytics_set_data_str(&analytics_data.netdata_prebuilt_distro, localhost->system_info->prebuilt_dist); } - - freez(t.prebuilt_arch); - freez(t.prebuilt_distro); - freez(t.install_type); } /* @@ -422,12 +416,16 @@ void analytics_metrics(void) rrdset_foreach_read(st, localhost) { rrdset_rdlock(st); - rrddim_foreach_read(rd, st) - { - if (rrddim_flag_check(rd, RRDDIM_FLAG_HIDDEN) || rrddim_flag_check(rd, RRDDIM_FLAG_OBSOLETE)) - continue; - dimensions++; + + if (rrdset_is_available_for_viewers(st)) { + rrddim_foreach_read(rd, st) + { + if (rrddim_flag_check(rd, RRDDIM_FLAG_HIDDEN) || rrddim_flag_check(rd, RRDDIM_FLAG_OBSOLETE)) + continue; + dimensions++; + } } + rrdset_unlock(st); } { diff --git a/daemon/anonymous-statistics.sh.in b/daemon/anonymous-statistics.sh.in index 9167b7062..9f8df188d 100755 --- a/daemon/anonymous-statistics.sh.in +++ b/daemon/anonymous-statistics.sh.in @@ -18,7 +18,11 @@ ACTION_DATA=$(echo "${ACTION_DATA}" | tr '"' "'") # ------------------------------------------------------------------------------------------------- # check opt-out -if [ -f "@configdir_POST@/.opt-out-from-anonymous-statistics" ] || [ ! "${DO_NOT_TRACK:-0}" -eq 0 ] || [ -n "$DO_NOT_TRACK" ]; then +if [ -f "@configdir_POST@/.opt-out-from-anonymous-statistics" ] || + [ ! "${DISABLE_TELEMETRY:-0}" -eq 0 ] || + [ -n "$DISABLE_TELEMETRY" ] || + [ ! "${DO_NOT_TRACK:-0}" -eq 0 ] || + [ -n "$DO_NOT_TRACK" ]; then exit 0 fi diff --git a/daemon/buildinfo.c b/daemon/buildinfo.c index b64a78f29..86c586afc 100644 --- a/daemon/buildinfo.c +++ b/daemon/buildinfo.c @@ -60,7 +60,6 @@ // Optional libraries #ifdef HAVE_PROTOBUF -#if defined(ACLK_NG) || defined(ENABLE_PROMETHEUS_REMOTE_WRITE) #define FEAT_PROTOBUF 1 #ifdef BUNDLED_PROTOBUF #define FEAT_PROTOBUF_BUNDLED " (bundled)" @@ -71,10 +70,6 @@ #define FEAT_PROTOBUF 0 #define FEAT_PROTOBUF_BUNDLED "" #endif -#else -#define FEAT_PROTOBUF 0 -#define FEAT_PROTOBUF_BUNDLED "" -#endif #ifdef ENABLE_JSONC #define FEAT_JSONC 1 @@ -222,9 +217,8 @@ char *get_value_from_key(char *buffer, char *key) { return s; } -struct install_type_info get_install_type() { +void get_install_type(char **install_type, char **prebuilt_arch, char **prebuilt_dist) { char *install_type_filename; - struct install_type_info ret = {.install_type = NULL, .prebuilt_arch = NULL, .prebuilt_distro = NULL}; int install_type_filename_len = (strlen(netdata_configured_user_config_dir) + strlen(".install-type") + 3); install_type_filename = mallocz(sizeof(char) * install_type_filename_len); @@ -237,41 +231,42 @@ struct install_type_info get_install_type() { while ((s = fgets_trim_len(buf, 256, fp, &len))) { if (!strncmp(buf, "INSTALL_TYPE='", 14)) - ret.install_type = strdupz((char *)get_value_from_key(buf, "INSTALL_TYPE")); + *install_type = strdupz((char *)get_value_from_key(buf, "INSTALL_TYPE")); else if (!strncmp(buf, "PREBUILT_ARCH='", 15)) - ret.prebuilt_arch = strdupz((char *)get_value_from_key(buf, "PREBUILT_ARCH")); + *prebuilt_arch = strdupz((char *)get_value_from_key(buf, "PREBUILT_ARCH")); else if (!strncmp(buf, "PREBUILT_DISTRO='", 17)) - ret.prebuilt_distro = strdupz((char *)get_value_from_key(buf, "PREBUILT_DISTRO")); + *prebuilt_dist = strdupz((char *)get_value_from_key(buf, "PREBUILT_DISTRO")); } fclose(fp); } freez(install_type_filename); - - return ret; } void print_build_info(void) { - struct install_type_info t = get_install_type(); + char *install_type = NULL; + char *prebuilt_arch = NULL; + char *prebuilt_distro = NULL; + get_install_type(&install_type, &prebuilt_arch, &prebuilt_distro); printf("Configure options: %s\n", CONFIGURE_COMMAND); - if (t.install_type == NULL) { + if (install_type == NULL) { printf("Install type: unknown\n"); } else { - printf("Install type: %s\n", t.install_type); + printf("Install type: %s\n", install_type); } - if (t.prebuilt_arch != NULL) { - printf(" Binary architecture: %s\n", t.prebuilt_arch); + if (prebuilt_arch != NULL) { + printf(" Binary architecture: %s\n", prebuilt_arch); } - if (t.prebuilt_distro != NULL) { - printf(" Packaging distro: %s\n", t.prebuilt_distro); + if (prebuilt_distro != NULL) { + printf(" Packaging distro: %s\n", prebuilt_distro); } - freez(t.install_type); - freez(t.prebuilt_arch); - freez(t.prebuilt_distro); + freez(install_type); + freez(prebuilt_arch); + freez(prebuilt_distro); printf("Features:\n"); printf(" dbengine: %s\n", FEAT_YES_NO(FEAT_DBENGINE)); @@ -372,41 +367,104 @@ void print_build_info_json(void) { printf("}\n"); }; -//return a list of enabled features for use in analytics -//find a way to have proper | +#define add_to_bi(buffer, str) \ + { if(first) { \ + buffer_strcat (b, str); \ + first = 0; \ + } else \ + buffer_strcat (b, "|" str); } + void analytics_build_info(BUFFER *b) { - if(FEAT_DBENGINE) buffer_strcat (b, "dbengine"); - if(FEAT_NATIVE_HTTPS) buffer_strcat (b, "|Native HTTPS"); - if(FEAT_CLOUD) buffer_strcat (b, "|Netdata Cloud"); - if(FEAT_CLOUD) buffer_strcat (b, "|ACLK Next Generation"); - if(NEW_CLOUD_PROTO) buffer_strcat (b, "|New Cloud Protocol Support"); - if(FEAT_TLS_HOST_VERIFY) buffer_strcat (b, "|TLS Host Verification"); - if(FEAT_ML) buffer_strcat (b, "|Machine Learning"); - if(FEAT_STREAM_COMPRESSION) buffer_strcat (b, "|Stream Compression"); - - if(FEAT_PROTOBUF) buffer_strcat (b, "|protobuf"); - if(FEAT_JEMALLOC) buffer_strcat (b, "|jemalloc"); - if(FEAT_JSONC) buffer_strcat (b, "|JSON-C"); - if(FEAT_LIBCAP) buffer_strcat (b, "|libcap"); - if(FEAT_CRYPTO) buffer_strcat (b, "|libcrypto"); - if(FEAT_LIBM) buffer_strcat (b, "|libm"); - - if(FEAT_TCMALLOC) buffer_strcat(b, "|tcalloc"); - if(FEAT_ZLIB) buffer_strcat(b, "|zlib"); - - if(FEAT_APPS_PLUGIN) buffer_strcat(b, "|apps"); - if(FEAT_CGROUP_NET) buffer_strcat(b, "|cgroup Network Tracking"); - if(FEAT_CUPS) buffer_strcat(b, "|CUPS"); - if(FEAT_EBPF) buffer_strcat(b, "|EBPF"); - if(FEAT_IPMI) buffer_strcat(b, "|IPMI"); - if(FEAT_NFACCT) buffer_strcat(b, "|NFACCT"); - if(FEAT_PERF) buffer_strcat(b, "|perf"); - if(FEAT_SLABINFO) buffer_strcat(b, "|slabinfo"); - if(FEAT_XEN) buffer_strcat(b, "|Xen"); - if(FEAT_XEN_VBD_ERROR) buffer_strcat(b, "|Xen VBD Error Tracking"); - - if(FEAT_KINESIS) buffer_strcat(b, "|AWS Kinesis"); - if(FEAT_PUBSUB) buffer_strcat(b, "|GCP PubSub"); - if(FEAT_MONGO) buffer_strcat(b, "|MongoDB"); - if(FEAT_REMOTE_WRITE) buffer_strcat(b, "|Prometheus Remote Write"); + int first = 1; +#ifdef ENABLE_DBENGINE + add_to_bi(b, "dbengine"); +#endif +#ifdef ENABLE_HTTPS + add_to_bi(b, "Native HTTPS"); +#endif +#ifdef ENABLE_ACLK + add_to_bi(b, "Netdata Cloud|ACLK Next Generation"); +#endif +#ifdef ENABLE_NEW_CLOUD_PROTOCOL + add_to_bi(b, "New Cloud Protocol Support"); +#endif +#if (FEAT_TLS_HOST_VERIFY!=0) + add_to_bi(b, "TLS Host Verification"); +#endif +#ifdef ENABLE_ML + add_to_bi(b, "Machine Learning"); +#endif +#ifdef ENABLE_COMPRESSION + add_to_bi(b, "Stream Compression"); +#endif + +#ifdef HAVE_PROTOBUF + add_to_bi(b, "protobuf"); +#endif +#ifdef ENABLE_JEMALLOC + add_to_bi(b, "jemalloc"); +#endif +#ifdef ENABLE_JSONC + add_to_bi(b, "JSON-C"); +#endif +#ifdef HAVE_CAPABILITY + add_to_bi(b, "libcap"); +#endif +#ifdef HAVE_CRYPTO + add_to_bi(b, "libcrypto"); +#endif +#ifdef STORAGE_WITH_MATH + add_to_bi(b, "libm"); +#endif + +#ifdef ENABLE_TCMALLOC + add_to_bi(b, "tcalloc"); +#endif +#ifdef NETDATA_WITH_ZLIB + add_to_bi(b, "zlib"); +#endif + +#ifdef ENABLE_APPS_PLUGIN + add_to_bi(b, "apps"); +#endif +#ifdef HAVE_SETNS + add_to_bi(b, "cgroup Network Tracking"); +#endif +#ifdef HAVE_CUPS + add_to_bi(b, "CUPS"); +#endif +#ifdef HAVE_LIBBPF + add_to_bi(b, "EBPF"); +#endif +#ifdef HAVE_FREEIPMI + add_to_bi(b, "IPMI"); +#endif +#ifdef HAVE_NFACCT + add_to_bi(b, "NFACCT"); +#endif +#ifdef ENABLE_PERF_PLUGIN + add_to_bi(b, "perf"); +#endif +#ifdef ENABLE_SLABINFO + add_to_bi(b, "slabinfo"); +#endif +#ifdef HAVE_LIBXENSTAT + add_to_bi(b, "Xen"); +#endif +#ifdef HAVE_XENSTAT_VBD_ERROR + add_to_bi(b, "Xen VBD Error Tracking"); +#endif + +#ifdef HAVE_KINESIS + add_to_bi(b, "AWS Kinesis"); +#endif +#ifdef ENABLE_EXPORTING_PUBSUB + add_to_bi(b, "GCP PubSub"); +#endif +#ifdef HAVE_MONGOC + add_to_bi(b, "MongoDB"); +#endif +#ifdef ENABLE_PROMETHEUS_REMOTE_WRITE + add_to_bi(b, "Prometheus Remote Write"); +#endif } diff --git a/daemon/buildinfo.h b/daemon/buildinfo.h index e2a31c94a..542a0e92e 100644 --- a/daemon/buildinfo.h +++ b/daemon/buildinfo.h @@ -3,18 +3,12 @@ #ifndef NETDATA_BUILDINFO_H #define NETDATA_BUILDINFO_H 1 -struct install_type_info { - char *install_type; - char *prebuilt_arch; - char *prebuilt_distro; -}; - extern void print_build_info(void); extern void print_build_info_json(void); extern char *get_value_from_key(char *buffer, char *key); -extern struct install_type_info get_install_type(); +extern void get_install_type(char **install_type, char **prebuilt_arch, char **prebuilt_dist); #endif // NETDATA_BUILDINFO_H diff --git a/daemon/commands.c b/daemon/commands.c index ddf20fe0b..6efc37c96 100644 --- a/daemon/commands.c +++ b/daemon/commands.c @@ -387,6 +387,7 @@ static void pipe_write_cb(uv_write_t* req, int status) uv_close((uv_handle_t *)client, pipe_close_cb); --clients; + freez(client->data); info("Command Clients = %u\n", clients); } @@ -400,6 +401,10 @@ static inline void add_string_to_command_reply(char *reply_string, unsigned *rep unsigned len; len = strlen(str); + + if (MAX_COMMAND_LENGTH - 1 < len + *reply_string_size) + len = MAX_COMMAND_LENGTH - *reply_string_size - 1; + strncpyz(reply_string + *reply_string_size, str, len); *reply_string_size += len; } @@ -407,7 +412,7 @@ static inline void add_string_to_command_reply(char *reply_string, unsigned *rep static void send_command_reply(struct command_context *cmd_ctx, cmd_status_t status, char *message) { int ret; - char reply_string[MAX_COMMAND_LENGTH] = {'\0', }; + char *reply_string = mallocz(MAX_COMMAND_LENGTH); char exit_status_string[MAX_EXIT_STATUS_LENGTH + 1] = {'\0', }; unsigned reply_string_size = 0; uv_buf_t write_buf; @@ -424,6 +429,7 @@ static void send_command_reply(struct command_context *cmd_ctx, cmd_status_t sta } cmd_ctx->write_req.data = client; + client->data = reply_string; write_buf.base = reply_string; write_buf.len = reply_string_size; ret = uv_write(&cmd_ctx->write_req, (uv_stream_t *)client, &write_buf, 1, pipe_write_cb); diff --git a/daemon/common.h b/daemon/common.h index 5354e2ae0..e11a6d6b6 100644 --- a/daemon/common.h +++ b/daemon/common.h @@ -51,9 +51,7 @@ // the registry is actually an API feature #include "registry/registry.h" -// backends for archiving the metrics -#include "backends/backends.h" -// the new exporting engine for archiving the metrics +// exporting engine for archiving the metrics #include "exporting/exporting_engine.h" // the netdata API diff --git a/daemon/config/README.md b/daemon/config/README.md index cc755af78..c3c639923 100644 --- a/daemon/config/README.md +++ b/daemon/config/README.md @@ -19,10 +19,9 @@ This config file **is not needed by default**. Netdata works fine out of the box settings. 4. `[health]` to [configure](#health-section-options) general settings for [health monitoring](/health/README.md) 5. `[registry]` for the [Netdata registry](/registry/README.md). -6. `[backend]` to set up [streaming and replication](/streaming/README.md) options. -7. `[statsd]` for the general settings of the [stats.d.plugin](/collectors/statsd.plugin/README.md). -8. `[plugin:NAME]` sections for each collector plugin, under the comment [Per plugin configuration](#per-plugin-configuration). -9. `[CHART_NAME]` sections for each chart defined, under the comment [Per chart configuration](#per-chart-configuration). +6. `[statsd]` for the general settings of the [stats.d.plugin](/collectors/statsd.plugin/README.md). +7. `[plugin:NAME]` sections for each collector plugin, under the comment [Per plugin configuration](#per-plugin-configuration). +8. `[CHART_NAME]` sections for each chart defined, under the comment [Per chart configuration](#per-chart-configuration). The configuration file is a `name = value` dictionary. Netdata will not complain if you set options unknown to it. When you check the running configuration by accessing the URL `/netdata.conf` on your Netdata server, Netdata will add a comment on settings it does not currently use. @@ -47,45 +46,45 @@ Please note that your data history will be lost if you have modified `history` p ### [global] section options -| setting|default|info||| -|:-----:|:-----:|:---|---|---| -| process scheduling policy|`keep`|See [Netdata process scheduling policy](/daemon/README.md#netdata-process-scheduling-policy)||| -| OOM score|`1000`|See [OOM score](/daemon/README.md#oom-score)||| -| glibc malloc arena max for plugins|`1`|See [Virtual memory](/daemon/README.md#virtual-memory).||| -| glibc malloc arena max for Netdata|`1`|See [Virtual memory](/daemon/README.md#virtual-memory).||| -| hostname|auto-detected|The hostname of the computer running Netdata.||| -| history|`3996`| Used with `memory mode = save/map/ram/alloc`, not the default `memory mode = dbengine`. This number reflects the number of entries the `netdata` daemon will by default keep in memory for each chart dimension. This setting can also be configured per chart. Check [Memory Requirements](/database/README.md) for more information. ||| -| update every|`1`|The frequency in seconds, for data collection. For more information see the [performance guide](/docs/guides/configure/performance.md).||| -| config directory|`/etc/netdata`|The directory configuration files are kept.||| -| stock config directory|`/usr/lib/netdata/conf.d`|||| -| log directory|`/var/log/netdata`|The directory in which the [log files](/daemon/README.md#log-files) are kept.||| -| web files directory|`/usr/share/netdata/web`|The directory the web static files are kept.||| -| cache directory|`/var/cache/netdata`|The directory the memory database will be stored if and when Netdata exits. Netdata will re-read the database when it will start again, to continue from the same point.||| -| lib directory|`/var/lib/netdata`|Contains the alarm log and the Netdata instance guid.||| -| home directory|`/var/cache/netdata`|Contains the db files for the collected metrics||| -| plugins directory|`"/usr/libexec/netdata/plugins.d" "/etc/netdata/custom-plugins.d"`|The directory plugin programs are kept. This setting supports multiple directories, space separated. If any directory path contains spaces, enclose it in single or double quotes.||| +| setting|default|info| +|:-----:|:-----:|:---| +| process scheduling policy|`keep`|See [Netdata process scheduling policy](/daemon/README.md#netdata-process-scheduling-policy)| +| OOM score|`0`|| +| glibc malloc arena max for plugins|`1`|See [Virtual memory](/daemon/README.md#virtual-memory).| +| glibc malloc arena max for Netdata|`1`|See [Virtual memory](/daemon/README.md#virtual-memory).| +| hostname|auto-detected|The hostname of the computer running Netdata.| +| history|`3996`| Used with `memory mode = save/map/ram/alloc`, not the default `memory mode = dbengine`. This number reflects the number of entries the `netdata` daemon will by default keep in memory for each chart dimension. This setting can also be configured per chart. Check [Memory Requirements](/database/README.md) for more information. | +| update every|`1`|The frequency in seconds, for data collection. For more information see the [performance guide](/docs/guides/configure/performance.md).| +| config directory|`/etc/netdata`|The directory configuration files are kept.| +| stock config directory|`/usr/lib/netdata/conf.d`|| +| log directory|`/var/log/netdata`|The directory in which the [log files](/daemon/README.md#log-files) are kept.| +| web files directory|`/usr/share/netdata/web`|The directory the web static files are kept.| +| cache directory|`/var/cache/netdata`|The directory the memory database will be stored if and when Netdata exits. Netdata will re-read the database when it will start again, to continue from the same point.| +| lib directory|`/var/lib/netdata`|Contains the alarm log and the Netdata instance guid.| +| home directory|`/var/cache/netdata`|Contains the db files for the collected metrics| +| plugins directory|`"/usr/libexec/netdata/plugins.d" "/etc/netdata/custom-plugins.d"`|The directory plugin programs are kept. This setting supports multiple directories, space separated. If any directory path contains spaces, enclose it in single or double quotes.| | memory mode | `dbengine` | `dbengine`: The default for long-term metrics storage with efficient RAM and disk usage. Can be extended with `page cache size` and `dbengine disk space`.
`save`: Netdata will save its round robin database on exit and load it on startup.
`map`: Cache files will be updated in real-time. Not ideal for systems with high load or slow disks (check `man mmap`).
`ram`: The round-robin database will be temporary and it will be lost when Netdata exits.
`none`: Disables the database at this host, and disables health monitoring entirely, as that requires a database of metrics. | -| page cache size | 32 | Determines the amount of RAM in MiB that is dedicated to caching Netdata metric values. ||| -| dbengine disk space | 256 | Determines the amount of disk space in MiB that is dedicated to storing Netdata metric values and all related metadata describing them. ||| -| dbengine multihost disk space | 256 | Same functionality as `dbengine disk space`, but includes support for storing metrics streamed to a parent node by its children. Can be used in single-node environments as well. ||| -| host access prefix||This is used in docker environments where /proc, /sys, etc have to be accessed via another path. You may also have to set SYS_PTRACE capability on the docker for this work. Check [issue 43](https://github.com/netdata/netdata/issues/43).| -| memory deduplication (ksm)|`yes`|When set to `yes`, Netdata will offer its in-memory round robin database to kernel same page merging (KSM) for deduplication. For more information check [Memory Deduplication - Kernel Same Page Merging - KSM](/database/README.md#ksm)||| -| TZ environment variable|`:/etc/localtime`|Where to find the timezone||| -| timezone|auto-detected|The timezone retrieved from the environment variable||| -| debug flags|`0x0000000000000000`|Bitmap of debug options to enable. For more information check [Tracing Options](/daemon/README.md#debugging).||| -| debug log|`/var/log/netdata/debug.log`|The filename to save debug information. This file will not be created if debugging is not enabled. You can also set it to `syslog` to send the debug messages to syslog, or `none` to disable this log. For more information check [Tracing Options](/daemon/README.md#debugging).||| -| error log|`/var/log/netdata/error.log`|The filename to save error messages for Netdata daemon and all plugins (`stderr` is sent here for all Netdata programs, including the plugins). You can also set it to `syslog` to send the errors to syslog, or `none` to disable this log.||| -| access log|`/var/log/netdata/access.log`|The filename to save the log of web clients accessing Netdata charts. You can also set it to `syslog` to send the access log to syslog, or `none` to disable this log.||| -| errors flood protection period|`1200`|Length of period (in sec) during which the number of errors should not exceed the `errors to trigger flood protection`.||| -| errors to trigger flood protection|`200`|Number of errors written to the log in `errors flood protection period` sec before flood protection is activated.||| -| run as user|`netdata`|The user Netdata will run as.||| -| pthread stack size|auto-detected|||| -| cleanup obsolete charts after seconds|`3600`|See [monitoring ephemeral containers](/collectors/cgroups.plugin/README.md#monitoring-ephemeral-containers), also sets the timeout for cleaning up obsolete dimensions||| -| gap when lost iterations above|`1`|||| -| cleanup orphan hosts after seconds|`3600`|How long to wait until automatically removing from the DB a remote Netdata host (child) that is no longer sending data.||| -| delete obsolete charts files|`yes`|See [monitoring ephemeral containers](/collectors/cgroups.plugin/README.md#monitoring-ephemeral-containers), also affects the deletion of files for obsolete dimensions||| -| delete orphan hosts files|`yes`|Set to `no` to disable non-responsive host removal.||| -| enable zero metrics|`no`|Set to `yes` to show charts when all their metrics are zero.||| +| page cache size | 32 | Determines the amount of RAM in MiB that is dedicated to caching Netdata metric values. | +| dbengine disk space | 256 | Determines the amount of disk space in MiB that is dedicated to storing Netdata metric values and all related metadata describing them. | +| dbengine multihost disk space | 256 | Same functionality as `dbengine disk space`, but includes support for storing metrics streamed to a parent node by its children. Can be used in single-node environments as well. | +| host access prefix| |This is used in docker environments where /proc, /sys, etc have to be accessed via another path. You may also have to set SYS_PTRACE capability on the docker for this work. Check [issue 43](https://github.com/netdata/netdata/issues/43).| +| memory deduplication (ksm)|`yes`|When set to `yes`, Netdata will offer its in-memory round robin database to kernel same page merging (KSM) for deduplication. For more information check [Memory Deduplication - Kernel Same Page Merging - KSM](/database/README.md#ksm)| +| TZ environment variable|`:/etc/localtime`|Where to find the timezone| +| timezone|auto-detected|The timezone retrieved from the environment variable| +| debug flags|`0x0000000000000000`|Bitmap of debug options to enable. For more information check [Tracing Options](/daemon/README.md#debugging).| +| debug log|`/var/log/netdata/debug.log`|The filename to save debug information. This file will not be created if debugging is not enabled. You can also set it to `syslog` to send the debug messages to syslog, or `none` to disable this log. For more information check [Tracing Options](/daemon/README.md#debugging).| +| error log|`/var/log/netdata/error.log`|The filename to save error messages for Netdata daemon and all plugins (`stderr` is sent here for all Netdata programs, including the plugins). You can also set it to `syslog` to send the errors to syslog, or `none` to disable this log.| +| access log|`/var/log/netdata/access.log`|The filename to save the log of web clients accessing Netdata charts. You can also set it to `syslog` to send the access log to syslog, or `none` to disable this log.| +| errors flood protection period|`1200`|Length of period (in sec) during which the number of errors should not exceed the `errors to trigger flood protection`.| +| errors to trigger flood protection|`200`|Number of errors written to the log in `errors flood protection period` sec before flood protection is activated.| +| run as user|`netdata`|The user Netdata will run as.| +| pthread stack size|auto-detected|| +| cleanup obsolete charts after seconds|`3600`|See [monitoring ephemeral containers](/collectors/cgroups.plugin/README.md#monitoring-ephemeral-containers), also sets the timeout for cleaning up obsolete dimensions| +| gap when lost iterations above|`1`|| +| cleanup orphan hosts after seconds|`3600`|How long to wait until automatically removing from the DB a remote Netdata host (child) that is no longer sending data.| +| delete obsolete charts files|`yes`|See [monitoring ephemeral containers](/collectors/cgroups.plugin/README.md#monitoring-ephemeral-containers), also affects the deletion of files for obsolete dimensions| +| delete orphan hosts files|`yes`|Set to `no` to disable non-responsive host removal.| +| enable zero metrics|`no`|Set to `yes` to show charts when all their metrics are zero.| ### [web] section options @@ -129,10 +128,6 @@ monitoring](/health/README.md). To understand what this section is and how it should be configured, please refer to the [registry documentation](/registry/README.md). -### [backend] - -Refer to the [streaming and replication](/streaming/README.md) documentation. - ## Per-plugin configuration The configuration options for plugins appear in sections following the pattern `[plugin:NAME]`. @@ -227,4 +222,4 @@ multiplying the value of `out` by -1, Netdata creates the negative values seen i ![The system.io chart on a macOS laptop](https://user-images.githubusercontent.com/1153921/69286708-2cfb3900-0bb1-11ea-9fcd-dd8fbb2adf11.png) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdaemon%2Fconfig%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/daemon/daemon.c b/daemon/daemon.c index 68e161a3f..2b8a6552b 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -102,7 +102,11 @@ int become_user(const char *username, int pid_fd) { gid_t *supplementary_groups = NULL; if(ngroups > 0) { supplementary_groups = mallocz(sizeof(gid_t) * ngroups); +#ifdef __APPLE__ + if(getgrouplist(username, gid, (int *)supplementary_groups, &ngroups) == -1) { +#else if(getgrouplist(username, gid, supplementary_groups, &ngroups) == -1) { +#endif /* __APPLE__ */ if(am_i_root) error("Cannot get supplementary groups of user '%s'.", username); @@ -173,7 +177,7 @@ int become_user(const char *username, int pid_fd) { static void oom_score_adj(void) { char buf[30 + 1]; - long long int old_score, wanted_score = OOM_SCORE_ADJ_MAX, final_score = 0; + long long int old_score, wanted_score = 0, final_score = 0; // read the existing score if(read_single_signed_number_file("/proc/self/oom_score_adj", &old_score)) { @@ -271,8 +275,8 @@ struct sched_def { // the available members are important too! // these are all the possible scheduling policies supported by netdata -#ifdef SCHED_IDLE - { "idle", SCHED_IDLE, 0, SCHED_FLAG_NONE }, +#ifdef SCHED_BATCH + { "batch", SCHED_BATCH, 0, SCHED_FLAG_USE_NICE }, #endif #ifdef SCHED_OTHER @@ -280,6 +284,10 @@ struct sched_def { { "nice", SCHED_OTHER, 0, SCHED_FLAG_USE_NICE }, #endif +#ifdef SCHED_IDLE + { "idle", SCHED_IDLE, 0, SCHED_FLAG_NONE }, +#endif + #ifdef SCHED_RR { "rr", SCHED_RR, 0, SCHED_FLAG_PRIORITY_CONFIGURABLE }, #endif @@ -288,10 +296,6 @@ struct sched_def { { "fifo", SCHED_FIFO, 0, SCHED_FLAG_PRIORITY_CONFIGURABLE }, #endif -#ifdef SCHED_BATCH - { "batch", SCHED_BATCH, 0, SCHED_FLAG_USE_NICE }, -#endif - // do not change the scheduling priority { "keep", 0, 0, SCHED_FLAG_KEEP_AS_IS }, { "none", 0, 0, SCHED_FLAG_KEEP_AS_IS }, @@ -339,13 +343,7 @@ static void sched_getscheduler_report(void) { } } } -#else // !HAVE_SCHED_GETSCHEDULER -static void sched_getscheduler_report(void) { -#ifdef HAVE_GETPRIORITY - info("Running with priority %d", getpriority(PRIO_PROCESS, 0)); -#endif // HAVE_GETPRIORITY -} -#endif // !HAVE_SCHED_GETSCHEDULER +#endif /* HAVE_SCHED_GETSCHEDULER */ #ifdef HAVE_SCHED_SETSCHEDULER @@ -418,11 +416,11 @@ fallback: report: sched_getscheduler_report(); } -#else // !HAVE_SCHED_SETSCHEDULER +#else /* HAVE_SCHED_SETSCHEDULER */ static void sched_setscheduler_set(void) { process_nice_level(); } -#endif // !HAVE_SCHED_SETSCHEDULER +#endif /* HAVE_SCHED_SETSCHEDULER */ int become_daemon(int dont_fork, const char *user) { diff --git a/daemon/get-kubernetes-labels.sh.in b/daemon/get-kubernetes-labels.sh.in index 5aa89ab9d..7e11ba3dd 100644 --- a/daemon/get-kubernetes-labels.sh.in +++ b/daemon/get-kubernetes-labels.sh.in @@ -1,6 +1,8 @@ #!/usr/bin/env bash -# Checks if netdata is running in a kubernetes pod and fetches that pod's labels +# Checks if netdata is running in a kubernetes pod and fetches: +# - pod's labels +# - kubernetes cluster name (GKE only) if [ -z "${KUBERNETES_SERVICE_HOST}" ] || [ -z "${KUBERNETES_PORT_443_TCP_PORT}" ] || [ -z "${MY_POD_NAMESPACE}" ] || [ -z "${MY_POD_NAME}" ]; then exit 0 @@ -37,5 +39,20 @@ if ! KUBE_SYSTEM_NS_UID=$(jq -r '.metadata.uid' <<< "$KUBE_SYSTEM_NS_DATA" 2>&1) exit 1 fi -echo -e "$POD_LABELS\nk8s_cluster_id:$KUBE_SYSTEM_NS_UID" +LABELS="$POD_LABELS\nk8s_cluster_id:$KUBE_SYSTEM_NS_UID" + +GCP_META_HEADER="Metadata-Flavor: Google" +GCP_META_URL="http://metadata/computeMetadata/v1" +GKE_CLUSTER_NAME="" + +if id=$(curl --fail -s -m 5 --noproxy "*" -H "$GCP_META_HEADER" "$GCP_META_URL/project/project-id"); then + loc=$(curl --fail -s -m 5 --noproxy "*" -H "$GCP_META_HEADER" "$GCP_META_URL/instance/attributes/cluster-location") + name=$(curl --fail -s -m 5 --noproxy "*" -H "$GCP_META_HEADER" "$GCP_META_URL/instance/attributes/cluster-name") + [ -n "$id" ] && [ -n "$loc" ] && [ -n "$name" ] && GKE_CLUSTER_NAME="gke_${id}_${loc}_${name}" +fi + +[ -n "$GKE_CLUSTER_NAME" ] && LABELS+="\nk8s_cluster_name:$GKE_CLUSTER_NAME" + +echo -e "$LABELS" + exit 0 diff --git a/daemon/global_statistics.c b/daemon/global_statistics.c index f4f3e5762..d5cc03159 100644 --- a/daemon/global_statistics.c +++ b/daemon/global_statistics.c @@ -37,7 +37,7 @@ static struct global_statistics { .rrdr_result_points_generated = 0, }; -#if defined(HAVE_C___ATOMIC) && !defined(NETDATA_NO_ATOMIC_INSTRUCTIONS) +#if defined(HAVE_C___ATOMIC) #else netdata_mutex_t global_statistics_mutex = NETDATA_MUTEX_INITIALIZER; @@ -52,7 +52,7 @@ static inline void global_statistics_unlock(void) { void rrdr_query_completed(uint64_t db_points_read, uint64_t result_points_generated) { -#if defined(HAVE_C___ATOMIC) && !defined(NETDATA_NO_ATOMIC_INSTRUCTIONS) +#if defined(HAVE_C___ATOMIC) __atomic_fetch_add(&global_statistics.rrdr_queries_made, 1, __ATOMIC_SEQ_CST); __atomic_fetch_add(&global_statistics.rrdr_db_points_read, db_points_read, __ATOMIC_SEQ_CST); __atomic_fetch_add(&global_statistics.rrdr_result_points_generated, result_points_generated, __ATOMIC_SEQ_CST); @@ -75,7 +75,7 @@ void finished_web_request_statistics(uint64_t dt, uint64_t bytes_sent, uint64_t content_size, uint64_t compressed_content_size) { -#if defined(HAVE_C___ATOMIC) && !defined(NETDATA_NO_ATOMIC_INSTRUCTIONS) +#if defined(HAVE_C___ATOMIC) uint64_t old_web_usec_max = global_statistics.web_usec_max; while(dt > old_web_usec_max) __atomic_compare_exchange(&global_statistics.web_usec_max, &old_web_usec_max, &dt, 1, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); @@ -107,7 +107,7 @@ void finished_web_request_statistics(uint64_t dt, } uint64_t web_client_connected(void) { -#if defined(HAVE_C___ATOMIC) && !defined(NETDATA_NO_ATOMIC_INSTRUCTIONS) +#if defined(HAVE_C___ATOMIC) __atomic_fetch_add(&global_statistics.connected_clients, 1, __ATOMIC_SEQ_CST); uint64_t id = __atomic_fetch_add(&global_statistics.web_client_count, 1, __ATOMIC_SEQ_CST); #else @@ -125,7 +125,7 @@ uint64_t web_client_connected(void) { } void web_client_disconnected(void) { -#if defined(HAVE_C___ATOMIC) && !defined(NETDATA_NO_ATOMIC_INSTRUCTIONS) +#if defined(HAVE_C___ATOMIC) __atomic_fetch_sub(&global_statistics.connected_clients, 1, __ATOMIC_SEQ_CST); #else if (web_server_is_multithreaded) @@ -140,7 +140,7 @@ void web_client_disconnected(void) { static inline void global_statistics_copy(struct global_statistics *gs, uint8_t options) { -#if defined(HAVE_C___ATOMIC) && !defined(NETDATA_NO_ATOMIC_INSTRUCTIONS) +#if defined(HAVE_C___ATOMIC) gs->connected_clients = __atomic_fetch_add(&global_statistics.connected_clients, 0, __ATOMIC_SEQ_CST); gs->web_requests = __atomic_fetch_add(&global_statistics.web_requests, 0, __ATOMIC_SEQ_CST); gs->web_usec = __atomic_fetch_add(&global_statistics.web_usec, 0, __ATOMIC_SEQ_CST); diff --git a/daemon/main.c b/daemon/main.c index 7c8e09a5f..c18778974 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -250,6 +250,8 @@ void cancel_main_threads() { else info("All threads finished."); + for (i = 0; static_threads[i].name != NULL ; i++) + freez(static_threads[i].thread); free(static_threads); } @@ -445,15 +447,6 @@ static void backwards_compatible_config() { config_move(CONFIG_SECTION_GLOBAL, "web compression level", CONFIG_SECTION_WEB, "gzip compression level"); - - config_move(CONFIG_SECTION_GLOBAL, "web files owner", - CONFIG_SECTION_WEB, "web files owner"); - - config_move(CONFIG_SECTION_GLOBAL, "web files group", - CONFIG_SECTION_WEB, "web files group"); - - config_move(CONFIG_SECTION_BACKEND, "opentsdb host tags", - CONFIG_SECTION_BACKEND, "host tags"); } static void get_netdata_configured_variables() { @@ -690,6 +683,7 @@ int main(int argc, char **argv) { int i; int config_loaded = 0; int dont_fork = 0; + bool close_open_fds = true; size_t default_stacksize; char *user = NULL; @@ -794,8 +788,13 @@ int main(int argc, char **argv) { } if(strcmp(optarg, "unittest") == 0) { - if(unit_test_buffer()) return 1; - if(unit_test_str2ld()) return 1; + if (unit_test_static_threads()) + return 1; + if (unit_test_buffer()) + return 1; + if (unit_test_str2ld()) + return 1; + // No call to load the config file on this code-path post_conf_load(&user); get_netdata_configured_variables(); @@ -1038,7 +1037,13 @@ int main(int argc, char **argv) { print_build_info_json(); return 0; } - else { + else if(strcmp(optarg, "keepopenfds") == 0) { + // Internal dev option to skip closing inherited + // open FDs. Useful, when we want to run the agent + // under profiling tools that open/maintain their + // own FDs. + close_open_fds = false; + } else { fprintf(stderr, "Unknown -W parameter '%s'\n", optarg); return help(1); } @@ -1053,12 +1058,12 @@ int main(int argc, char **argv) { } #ifdef _SC_OPEN_MAX - // close all open file descriptors, except the standard ones - // the caller may have left open files (lxc-attach has this issue) - { - int fd; - for(fd = (int) (sysconf(_SC_OPEN_MAX) - 1); fd > 2; fd--) - if(fd_is_valid(fd)) close(fd); + if (close_open_fds == true) { + // close all open file descriptors, except the standard ones + // the caller may have left open files (lxc-attach has this issue) + for(int fd = (int) (sysconf(_SC_OPEN_MAX) - 1); fd > 2; fd--) + if(fd_is_valid(fd)) + close(fd); } #endif @@ -1205,11 +1210,6 @@ int main(int argc, char **argv) { info("netdata started on pid %d.", getpid()); - // IMPORTANT: these have to run once, while single threaded - // but after we have switched user - web_files_uid(); - web_files_gid(); - netdata_threads_init_after_fork((size_t)config_get_number(CONFIG_SECTION_GLOBAL, "pthread stack size", (long)default_stacksize)); // initialize internal registry @@ -1232,6 +1232,7 @@ int main(int argc, char **argv) { struct rrdhost_system_info *system_info = calloc(1, sizeof(struct rrdhost_system_info)); get_system_info(system_info); system_info->hops = 0; + get_install_type(&system_info->install_type, &system_info->prebuilt_arch, &system_info->prebuilt_dist); if(rrd_init(netdata_configured_hostname, system_info)) fatal("Cannot initialize localhost instance with name '%s'.", netdata_configured_hostname); @@ -1317,12 +1318,6 @@ int main(int argc, char **argv) { snprintfz(filename, FILENAME_MAX, "%s/.aclk_report_sent", netdata_configured_varlib_dir); if (netdata_anonymous_statistics_enabled > 0 && access(filename, F_OK)) { // -1 -> not initialized send_statistics("ACLK_DISABLED", "-", "-"); -#ifdef ACLK_NO_LWS - send_statistics("BUILD_FAIL_LWS", "-", "-"); -#endif -#ifdef ACLK_NO_LIBMOSQ - send_statistics("BUILD_FAIL_MOSQ", "-", "-"); -#endif int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 444); if (fd == -1) error("Cannot create file '%s'. Please fix this.", filename); diff --git a/daemon/service.c b/daemon/service.c index d3a4e5500..61cc1281a 100644 --- a/daemon/service.c +++ b/daemon/service.c @@ -31,6 +31,11 @@ void *service_main(void *ptr) heartbeat_next(&hb, step); rrd_cleanup_obsolete_charts(); + + rrd_wrlock(); + rrdhost_cleanup_orphan_hosts_nolock(localhost); + rrd_unlock(); + } netdata_thread_cleanup_pop(1); diff --git a/daemon/static_threads.c b/daemon/static_threads.c index 534b3c3d8..c07473bd6 100644 --- a/daemon/static_threads.c +++ b/daemon/static_threads.c @@ -11,8 +11,18 @@ extern void *health_main(void *ptr); extern void *pluginsd_main(void *ptr); extern void *service_main(void *ptr); extern void *statsd_main(void *ptr); +extern void *timex_main(void *ptr); const struct netdata_static_thread static_threads_common[] = { + { + .name = "PLUGIN[timex]", + .config_section = CONFIG_SECTION_PLUGINS, + .config_name = "timex", + .enabled = 1, + .thread = NULL, + .init_routine = NULL, + .start_routine = timex_main + }, { .name = "PLUGIN[check]", .config_section = CONFIG_SECTION_PLUGINS, @@ -85,15 +95,6 @@ const struct netdata_static_thread static_threads_common[] = { .init_routine = NULL, .start_routine = statsd_main }, - { - .name = "BACKENDS", - .config_section = NULL, - .config_name = NULL, - .enabled = 1, - .thread = NULL, - .init_routine = NULL, - .start_routine = backends_main - }, { .name = "EXPORTING", .config_section = NULL, diff --git a/daemon/static_threads_linux.c b/daemon/static_threads_linux.c index e55c0fec7..5f7a67768 100644 --- a/daemon/static_threads_linux.c +++ b/daemon/static_threads_linux.c @@ -9,15 +9,6 @@ extern void *tc_main(void *ptr); extern void *timex_main(void *ptr); const struct netdata_static_thread static_threads_linux[] = { - { - .name = "PLUGIN[timex]", - .config_section = CONFIG_SECTION_PLUGINS, - .config_name = "timex", - .enabled = 1, - .thread = NULL, - .init_routine = NULL, - .start_routine = timex_main - }, { .name = "PLUGIN[tc]", .config_section = CONFIG_SECTION_PLUGINS, diff --git a/daemon/system-info.sh b/daemon/system-info.sh index 728e38091..7fb2f25b5 100755 --- a/daemon/system-info.sh +++ b/daemon/system-info.sh @@ -21,7 +21,7 @@ if [ -z "${VIRTUALIZATION}" ]; then if [ -n "$(command -v systemd-detect-virt 2> /dev/null)" ]; then VIRTUALIZATION="$(systemd-detect-virt -v)" VIRT_DETECTION="systemd-detect-virt" - CONTAINER="$(systemd-detect-virt -c)" + CONTAINER=${CONTAINER:-$(systemd-detect-virt -c)} CONT_DETECTION="systemd-detect-virt" else if grep -q "^flags.*hypervisor" /proc/cpuinfo 2> /dev/null; then @@ -153,7 +153,6 @@ if [ "${CONTAINER}" = "unknown" ] || [ "${CONTAINER}" = "none" ]; then else # Otherwise try and use a user-supplied bind-mount into the container to resolve the host details if [ -e "/host/etc/os-release" ]; then - OS_DETECTION="/etc/os-release" eval "$(grep -E "^(NAME|ID|ID_LIKE|VERSION|VERSION_ID)=" < /host/etc/os-release | sed 's/^/HOST_/')" HOST_OS_DETECTION="/host/etc/os-release" fi @@ -197,10 +196,14 @@ if [ -n "${lscpu}" ] && lscpu > /dev/null 2>&1; then LCPU_COUNT="$(echo "${lscpu_output}" | grep "^CPU(s):" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" CPU_VENDOR="$(echo "${lscpu_output}" | grep "^Vendor ID:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" CPU_MODEL="$(echo "${lscpu_output}" | grep "^Model name:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" - possible_cpu_freq="$(echo "${lscpu_output}" | grep -F "CPU max MHz:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | grep -o '^[0-9]*') MHz" - if [ "${possible_cpu_freq}" = " MHz" ]; then - possible_cpu_freq="$(echo "${lscpu_output}" | grep -F "CPU MHz:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | grep -o '^[0-9]*') MHz" + possible_cpu_freq="$(echo "${lscpu_output}" | grep -F "CPU max MHz:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | grep -o '^[0-9]*')" + if [ -z "$possible_cpu_freq" ]; then + possible_cpu_freq="$(echo "${lscpu_output}" | grep -F "CPU MHz:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | grep -o '^[0-9]*')" fi + if [ -z "$possible_cpu_freq" ]; then + possible_cpu_freq="$(echo "${lscpu_output}" | grep "^Model name:" | grep -Eo "[0-9\.]+GHz" | grep -o "^[0-9\.]*" | awk '{print int($0*1000)}')" + fi + [ -n "$possible_cpu_freq" ] && possible_cpu_freq="${possible_cpu_freq} MHz" elif [ -n "${dmidecode}" ] && dmidecode -t processor > /dev/null 2>&1; then dmidecode_output="$(${dmidecode} -t processor 2> /dev/null)" CPU_INFO_SOURCE="dmidecode" @@ -215,6 +218,13 @@ else elif [ "${KERNEL_NAME}" = FreeBSD ]; then CPU_INFO_SOURCE="sysctl" LCPU_COUNT="$(sysctl -n kern.smp.cpus)" + if ! possible_cpu_freq=$(sysctl -n machdep.tsc_freq 2> /dev/null); then + possible_cpu_freq=$(sysctl -n hw.model 2> /dev/null | grep -Eo "[0-9\.]+GHz" | grep -o "^[0-9\.]*" | awk '{print int($0*1000)}') + [ -n "$possible_cpu_freq" ] && possible_cpu_freq="${possible_cpu_freq} MHz" + fi + elif [ "${KERNEL_NAME}" = Darwin ]; then + CPU_INFO_SOURCE="sysctl" + LCPU_COUNT="$(sysctl -n hw.logicalcpu)" elif [ -d /sys/devices/system/cpu ]; then CPU_INFO_SOURCE="sysfs" # This is potentially more accurate than checking `/proc/cpuinfo`. @@ -224,8 +234,15 @@ else LCPU_COUNT="$(grep -c ^processor /proc/cpuinfo)" fi - # If we have GNU uname, we can use that to get CPU info (probably). - if uname --version 2> /dev/null | grep -qF 'GNU coreutils'; then + if [ "${KERNEL_NAME}" = Darwin ]; then + CPU_MODEL="$(sysctl -n machdep.cpu.brand_string)" + if [ "${ARCHITECTURE}" = "x86_64" ]; then + CPU_VENDOR="$(sysctl -n machdep.cpu.vendor)" + else + CPU_VENDOR="Apple" + fi + echo "${CPU_INFO_SOURCE}" | grep -qv sysctl && CPU_INFO_SOURCE="${CPU_INFO_SOURCE} sysctl" + elif uname --version 2> /dev/null | grep -qF 'GNU coreutils'; then CPU_INFO_SOURCE="${CPU_INFO_SOURCE} uname" CPU_MODEL="$(uname -p)" CPU_VENDOR="$(uname -i)" @@ -245,12 +262,15 @@ else fi fi -if [ -r /sys/devices/system/cpu/cpu0/cpufreq/base_frequency ]; then +if [ "${KERNEL_NAME}" = Darwin ] && [ "${ARCHITECTURE}" = "x86_64" ]; then + CPU_FREQ="$(sysctl -n hw.cpufrequency)" +elif [ -r /sys/devices/system/cpu/cpu0/cpufreq/base_frequency ]; then if (echo "${CPU_INFO_SOURCE}" | grep -qv sysfs); then CPU_INFO_SOURCE="${CPU_INFO_SOURCE} sysfs" fi - CPU_FREQ="$(cat /sys/devices/system/cpu/cpu0/cpufreq/base_frequency)" + value="$(cat /sys/devices/system/cpu/cpu0/cpufreq/base_frequency)" + CPU_FREQ="$((value * 1000))" elif [ -n "${possible_cpu_freq}" ]; then CPU_FREQ="${possible_cpu_freq}" elif [ -r /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq ]; then @@ -258,7 +278,14 @@ elif [ -r /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq ]; then CPU_INFO_SOURCE="${CPU_INFO_SOURCE} sysfs" fi - CPU_FREQ="$(cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq)" + value="$(cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq)" + CPU_FREQ="$((value * 1000))" +elif [ -r /proc/cpuinfo ]; then + if (echo "${CPU_INFO_SOURCE}" | grep -qv procfs); then + CPU_INFO_SOURCE="${CPU_INFO_SOURCE} procfs" + fi + value=$(grep "cpu MHz" /proc/cpuinfo 2>/dev/null | grep -o "[0-9]*" | head -n 1 | awk '{print int($0*1000000)}') + [ -n "$value" ] && CPU_FREQ="$value" fi freq_units="$(echo "${CPU_FREQ}" | cut -f 2 -d ' ')" @@ -376,6 +403,47 @@ elif pgrep "kubelet"; then HOST_IS_K8S_NODE="true" fi +# ------------------------------------------------------------------------------------------------ +# Detect instance metadata for VMs running on cloud providers + +CLOUD_TYPE="unknown" +CLOUD_INSTANCE_TYPE="unknown" +CLOUD_INSTANCE_REGION="unknown" + +if [ "${VIRTUALIZATION}" != "none" ] && command -v curl > /dev/null 2>&1; then + # Try AWS IMDSv2 + if [ "${CLOUD_TYPE}" = "unknown" ]; then + AWS_IMDS_TOKEN="$(curl --fail -s -m 5 --noproxy "*" -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")" + if [ -n "${AWS_IMDS_TOKEN}" ]; then + CLOUD_TYPE="AWS" + CLOUD_INSTANCE_TYPE="$(curl --fail -s -m 5 --noproxy "*" -H "X-aws-ec2-metadata-token: $AWS_IMDS_TOKEN" -v "http://169.254.169.254/latest/meta-data/instance-type" 2> /dev/null)" + CLOUD_INSTANCE_REGION="$(curl --fail -s -m 5 --noproxy "*" -H "X-aws-ec2-metadata-token: $AWS_IMDS_TOKEN" -v "http://169.254.169.254/latest/meta-data/placement/region" 2> /dev/null)" + fi + fi + + # Try GCE computeMetadata v1 + if [ "${CLOUD_TYPE}" = "unknown" ]; then + if [ -n "$(curl --fail -s -m 5 --noproxy "*" -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1")" ]; then + CLOUD_TYPE="GCP" + CLOUD_INSTANCE_TYPE="$(curl --fail -s -m 5 --noproxy "*" -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/machine-type")" + [ -n "$CLOUD_INSTANCE_TYPE" ] && CLOUD_INSTANCE_TYPE=$(basename "$CLOUD_INSTANCE_TYPE") + CLOUD_INSTANCE_REGION="$(curl --fail -s -m 5 --noproxy "*" -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/zone")" + [ -n "$CLOUD_INSTANCE_REGION" ] && CLOUD_INSTANCE_REGION=$(basename "$CLOUD_INSTANCE_REGION") && CLOUD_INSTANCE_REGION=${CLOUD_INSTANCE_REGION%-*} + fi + fi + + # TODO: needs to be tested in Microsoft Azure + # Try Azure IMDS + # if [ "${CLOUD_TYPE}" = "unknown" ]; then + # AZURE_IMDS_DATA="$(curl --fail -s -m 5 -H "Metadata: true" --noproxy "*" "http://169.254.169.254/metadata/instance?version=2021-10-01")" + # if [ -n "${AZURE_IMDS_DATA}" ]; then + # CLOUD_TYPE="Azure" + # CLOUD_INSTANCE_TYPE="$(curl --fail -s -m 5 -H "Metadata: true" --noproxy "*" "http://169.254.169.254/metadata/instance/compute/vmSize?version=2021-10-01&format=text")" + # CLOUD_INSTANCE_REGION="$(curl --fail -s -m 5 -H "Metadata: true" --noproxy "*" "http://169.254.169.254/metadata/instance/compute/location?version=2021-10-01&format=text")" + # fi + # fi +fi + echo "NETDATA_CONTAINER_OS_NAME=${CONTAINER_NAME}" echo "NETDATA_CONTAINER_OS_ID=${CONTAINER_ID}" echo "NETDATA_CONTAINER_OS_ID_LIKE=${CONTAINER_ID_LIKE}" @@ -406,3 +474,6 @@ echo "NETDATA_SYSTEM_TOTAL_RAM=${TOTAL_RAM}" echo "NETDATA_SYSTEM_RAM_DETECTION=${RAM_DETECTION}" echo "NETDATA_SYSTEM_TOTAL_DISK_SIZE=${DISK_SIZE}" echo "NETDATA_SYSTEM_DISK_DETECTION=${DISK_DETECTION}" +echo "NETDATA_INSTANCE_CLOUD_TYPE=${CLOUD_TYPE}" +echo "NETDATA_INSTANCE_CLOUD_INSTANCE_TYPE=${CLOUD_INSTANCE_TYPE}" +echo "NETDATA_INSTANCE_CLOUD_INSTANCE_REGION=${CLOUD_INSTANCE_REGION}" diff --git a/daemon/unit_test.c b/daemon/unit_test.c index 456dff961..7a52735d5 100644 --- a/daemon/unit_test.c +++ b/daemon/unit_test.c @@ -404,6 +404,44 @@ int unit_test_buffer() { return 0; } +int unit_test_static_threads() { + struct netdata_static_thread *static_threads = static_threads_get(); + + /* + * make sure enough static threads have been registered + */ + if (!static_threads) { + fprintf(stderr, "empty static_threads array\n"); + return 1; + } + + int n; + for (n = 0; static_threads[n].start_routine != NULL; n++) {} + + if (n < 2) { + fprintf(stderr, "only %d static threads registered", n); + freez(static_threads); + return 1; + } + + /* + * verify that each thread's start routine is unique. + */ + for (int i = 0; i != n - 1; i++) { + for (int j = i + 1; j != n; j++) { + if (static_threads[i].start_routine != static_threads[j].start_routine) + continue; + + fprintf(stderr, "Found duplicate threads with name: %s\n", static_threads[i].name); + freez(static_threads); + return 1; + } + } + + freez(static_threads); + return 0; +} + // -------------------------------------------------------------------------------------------------------------------- struct feed_values { @@ -1521,7 +1559,7 @@ static RRDHOST *dbengine_rrdhost_find_or_create(char *name) , netdata_configured_timezone , netdata_configured_abbrev_timezone , netdata_configured_utc_offset - , config_get(CONFIG_SECTION_BACKEND, "host tags", "") + , "" , program_name , program_version , default_rrd_update_every @@ -1694,7 +1732,7 @@ static int test_dbengine_check_rrdr(RRDSET *st[CHARTS], RRDDIM *rd[CHARTS][DIMS] update_every = REGION_UPDATE_EVERY[current_region]; long points = (time_end - time_start) / update_every; for (i = 0 ; i < CHARTS ; ++i) { - RRDR *r = rrd2rrdr(st[i], points, time_start + update_every, time_end, RRDR_GROUPING_AVERAGE, 0, 0, NULL, NULL); + RRDR *r = rrd2rrdr(st[i], points, time_start + update_every, time_end, RRDR_GROUPING_AVERAGE, 0, 0, NULL, NULL, 0); if (!r) { fprintf(stderr, " DB-engine unittest %s: empty RRDR ### E R R O R ###\n", st[i]->name); return ++errors; @@ -1813,7 +1851,7 @@ int test_dbengine(void) long points = (time_end[REGIONS - 1] - time_start[0]) / update_every; // cover all time regions with RRDR long point_offset = (time_start[current_region] - time_start[0]) / update_every; for (i = 0 ; i < CHARTS ; ++i) { - RRDR *r = rrd2rrdr(st[i], points, time_start[0] + update_every, time_end[REGIONS - 1], RRDR_GROUPING_AVERAGE, 0, 0, NULL, NULL); + RRDR *r = rrd2rrdr(st[i], points, time_start[0] + update_every, time_end[REGIONS - 1], RRDR_GROUPING_AVERAGE, 0, 0, NULL, NULL, 0); if (!r) { fprintf(stderr, " DB-engine unittest %s: empty RRDR ### E R R O R ###\n", st[i]->name); ++errors; diff --git a/daemon/unit_test.h b/daemon/unit_test.h index 3a3b64902..6a7a966c3 100644 --- a/daemon/unit_test.h +++ b/daemon/unit_test.h @@ -8,6 +8,7 @@ extern int unit_test(long delay, long shift); extern int run_all_mockup_tests(void); extern int unit_test_str2ld(void); extern int unit_test_buffer(void); +extern int unit_test_static_threads(void); extern int test_sqlite(void); #ifdef ENABLE_DBENGINE extern int test_dbengine(void); diff --git a/database/README.md b/database/README.md index 9fef70580..a8bb21e4e 100644 --- a/database/README.md +++ b/database/README.md @@ -212,4 +212,4 @@ Netdata will create charts for kernel memory de-duplication performance, like th ![image](https://cloud.githubusercontent.com/assets/2662304/11998786/eb23ae54-aab6-11e5-94d4-e848e8a5c56a.png) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdatabase%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/database/engine/README.md b/database/engine/README.md index a782716f0..7defcce9d 100644 --- a/database/engine/README.md +++ b/database/engine/README.md @@ -256,4 +256,4 @@ and generate a read load of 1.7M/sec, whereas in the CPU-bound scenario the read Consequently, there is a significant degree of interference by the reader threads, that slow down the writer threads. This is also possible because the interference effects are greater than the SSD impact on data generation throughput. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdatabase%2Fengine%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/database/engine/datafile.c b/database/engine/datafile.c index d42311079..46d7a8f10 100644 --- a/database/engine/datafile.c +++ b/database/engine/datafile.c @@ -159,6 +159,7 @@ int create_data_file(struct rrdengine_datafile *datafile) if (unlikely(ret)) { fatal("posix_memalign:%s", strerror(ret)); } + memset(superblock, 0, sizeof(*superblock)); (void) strncpy(superblock->magic_number, RRDENG_DF_MAGIC, RRDENG_MAGIC_SZ); (void) strncpy(superblock->version, RRDENG_DF_VER, RRDENG_VER_SZ); superblock->tier = 1; diff --git a/database/engine/journalfile.c b/database/engine/journalfile.c index 640656161..1541eb10a 100644 --- a/database/engine/journalfile.c +++ b/database/engine/journalfile.c @@ -210,6 +210,7 @@ int create_journal_file(struct rrdengine_journalfile *journalfile, struct rrdeng if (unlikely(ret)) { fatal("posix_memalign:%s", strerror(ret)); } + memset(superblock, 0, sizeof(*superblock)); (void) strncpy(superblock->magic_number, RRDENG_JF_MAGIC, RRDENG_MAGIC_SZ); (void) strncpy(superblock->version, RRDENG_JF_VER, RRDENG_VER_SZ); @@ -428,7 +429,7 @@ static uint64_t iterate_transactions(struct rrdengine_instance *ctx, struct rrde iov = uv_buf_init(buf, size_bytes); ret = uv_fs_read(NULL, &req, file, &iov, 1, pos, NULL); if (ret < 0) { - error("uv_fs_read: pos=%lu, %s", pos, uv_strerror(ret)); + error("uv_fs_read: pos=%"PRIu64", %s", pos, uv_strerror(ret)); uv_fs_req_cleanup(&req); goto skip_file; } diff --git a/database/rrd.c b/database/rrd.c index dcab65189..321d35615 100644 --- a/database/rrd.c +++ b/database/rrd.c @@ -140,6 +140,7 @@ const char *rrdset_type_name(RRDSET_TYPE chart_type) { // RRD - cache directory char *rrdset_cache_dir(RRDHOST *host, const char *id, const char *config_section) { + UNUSED(config_section); char *ret = NULL; char b[FILENAME_MAX + 1]; @@ -147,7 +148,7 @@ char *rrdset_cache_dir(RRDHOST *host, const char *id, const char *config_section rrdset_strncpyz_name(b, id, FILENAME_MAX); snprintfz(n, FILENAME_MAX, "%s/%s", host->cache_dir, b); - ret = config_get(config_section, "cache directory", n); + ret = strdupz(n); if(host->rrd_memory_mode == RRD_MEMORY_MODE_MAP || host->rrd_memory_mode == RRD_MEMORY_MODE_SAVE) { int r = mkdir(ret, 0775); diff --git a/database/rrd.h b/database/rrd.h index 3e0daa169..071e1d038 100644 --- a/database/rrd.h +++ b/database/rrd.h @@ -53,7 +53,6 @@ struct context_param { uint8_t flags; }; -#define RRDSET_MINIMUM_LIVE_COUNT 3 #define META_CHART_UPDATED 1 #define META_PLUGIN_UPDATED 2 #define META_MODULE_UPDATED 4 @@ -168,7 +167,9 @@ typedef enum rrddim_flags { // No new values have been collected for this dimension since agent start or it was marked RRDDIM_FLAG_OBSOLETE at // least rrdset_free_obsolete_time seconds ago. RRDDIM_FLAG_ARCHIVED = (1 << 3), - RRDDIM_FLAG_ACLK = (1 << 4) + RRDDIM_FLAG_ACLK = (1 << 4), + + RRDDIM_FLAG_PENDING_FOREACH_ALARM = (1 << 5), // set when foreach alarm has not been initialized yet } RRDDIM_FLAGS; #ifdef HAVE_C___ATOMIC @@ -239,6 +240,7 @@ extern void rrdset_add_label_to_new_list(RRDSET *st, char *key, char *value, LAB extern void rrdset_finalize_labels(RRDSET *st); extern void rrdset_update_labels(RRDSET *st, struct label *labels); extern int rrdset_contains_label_keylist(RRDSET *st, char *key); +extern int rrdset_matches_label_keys(RRDSET *st, char *key, char *words[], uint32_t *hash_key_list, int *word_count, int size); extern struct label *rrdset_lookup_label_key(RRDSET *st, char *key, uint32_t key_hash); // ---------------------------------------------------------------------------- @@ -436,6 +438,7 @@ struct rrdset_volatile { uuid_t hash_id; struct label *new_labels; struct label_index labels; + bool is_ar_chart; }; // ---------------------------------------------------------------------------- @@ -461,23 +464,23 @@ typedef enum rrdset_flags { // (the master data set should be the one that has the same family and is not detail) RRDSET_FLAG_DEBUG = 1 << 2, // enables or disables debugging for a chart RRDSET_FLAG_OBSOLETE = 1 << 3, // this is marked by the collector/module as obsolete - RRDSET_FLAG_EXPORTING_SEND = 1 << 4, // if set, this chart should be sent to Prometheus web API - RRDSET_FLAG_EXPORTING_IGNORE = 1 << 5, // if set, this chart should not be sent to Prometheus web API + RRDSET_FLAG_EXPORTING_SEND = 1 << 4, // if set, this chart should be sent to Prometheus web API and external databases + RRDSET_FLAG_EXPORTING_IGNORE = 1 << 5, // if set, this chart should not be sent to Prometheus web API and external databases RRDSET_FLAG_UPSTREAM_SEND = 1 << 6, // if set, this chart should be sent upstream (streaming) RRDSET_FLAG_UPSTREAM_IGNORE = 1 << 7, // if set, this chart should not be sent upstream (streaming) RRDSET_FLAG_UPSTREAM_EXPOSED = 1 << 8, // if set, we have sent this chart definition to netdata parent (streaming) RRDSET_FLAG_STORE_FIRST = 1 << 9, // if set, do not eliminate the first collection during interpolation RRDSET_FLAG_HETEROGENEOUS = 1 << 10, // if set, the chart is not homogeneous (dimensions in it have multiple algorithms, multipliers or dividers) RRDSET_FLAG_HOMOGENEOUS_CHECK = 1 << 11, // if set, the chart should be checked to determine if the dimensions are homogeneous - RRDSET_FLAG_HIDDEN = 1 << 12, // if set, do not show this chart on the dashboard, but use it for backends + RRDSET_FLAG_HIDDEN = 1 << 12, // if set, do not show this chart on the dashboard, but use it for exporting RRDSET_FLAG_SYNC_CLOCK = 1 << 13, // if set, microseconds on next data collection will be ignored (the chart will be synced to now) RRDSET_FLAG_OBSOLETE_DIMENSIONS = 1 << 14, // this is marked by the collector/module when a chart has obsolete dimensions // No new values have been collected for this chart since agent start or it was marked RRDSET_FLAG_OBSOLETE at // least rrdset_free_obsolete_time seconds ago. RRDSET_FLAG_ARCHIVED = 1 << 15, RRDSET_FLAG_ACLK = 1 << 16, - RRDSET_FLAG_BACKEND_SEND = 1 << 17, // if set, this chart should be sent to backends - RRDSET_FLAG_BACKEND_IGNORE = 1 << 18 // if set, this chart should not be sent to backends + RRDSET_FLAG_PENDING_FOREACH_ALARMS = 1 << 17, // contains dims with uninitialized foreach alarms + RRDSET_FLAG_ANOMALY_DETECTION = 1 << 18 // flag to identify anomaly detection charts. } RRDSET_FLAGS; #ifdef HAVE_C___ATOMIC @@ -632,10 +635,11 @@ typedef enum rrdhost_flags { RRDHOST_FLAG_ORPHAN = 1 << 0, // this host is orphan (not receiving data) RRDHOST_FLAG_DELETE_OBSOLETE_CHARTS = 1 << 1, // delete files of obsolete charts RRDHOST_FLAG_DELETE_ORPHAN_HOST = 1 << 2, // delete the entire host when orphan - RRDHOST_FLAG_BACKEND_SEND = 1 << 3, // send it to backends - RRDHOST_FLAG_BACKEND_DONT_SEND = 1 << 4, // don't send it to backends + RRDHOST_FLAG_EXPORTING_SEND = 1 << 3, // send it to external databases + RRDHOST_FLAG_EXPORTING_DONT_SEND = 1 << 4, // don't send it to external databases RRDHOST_FLAG_ARCHIVED = 1 << 5, // The host is archived, no collected charts yet RRDHOST_FLAG_MULTIHOST = 1 << 6, // Host belongs to localhost/megadb + RRDHOST_FLAG_PENDING_FOREACH_ALARMS = 1 << 7, // contains dims with uninitialized foreach alarms } RRDHOST_FLAGS; #ifdef HAVE_C___ATOMIC @@ -729,6 +733,10 @@ typedef struct alarm_log { // RRD HOST struct rrdhost_system_info { + char *cloud_provider_type; + char *cloud_instance_type; + char *cloud_instance_region; + char *host_os_name; char *host_os_id; char *host_os_id_like; @@ -756,6 +764,9 @@ struct rrdhost_system_info { uint16_t hops; bool ml_capable; bool ml_enabled; + char *install_type; + char *prebuilt_arch; + char *prebuilt_dist; }; struct rrdhost { diff --git a/database/rrdcalctemplate.c b/database/rrdcalctemplate.c index 67288e9db..9789f4bea 100644 --- a/database/rrdcalctemplate.c +++ b/database/rrdcalctemplate.c @@ -120,6 +120,9 @@ inline void rrdcalctemplate_free(RRDCALCTEMPLATE *rt) { freez(rt->name); freez(rt->exec); freez(rt->recipient); + freez(rt->classification); + freez(rt->component); + freez(rt->type); freez(rt->context); freez(rt->source); freez(rt->units); diff --git a/database/rrddim.c b/database/rrddim.c index 78885df3d..df45363bc 100644 --- a/database/rrddim.c +++ b/database/rrddim.c @@ -3,32 +3,6 @@ #define NETDATA_RRD_INTERNALS #include "rrd.h" -static inline void calc_link_to_rrddim(RRDDIM *rd) -{ - RRDHOST *host = rd->rrdset->rrdhost; - RRDSET *st = rd->rrdset; - if (host->alarms_with_foreach || host->alarms_template_with_foreach) { - int count = 0; - int hostlocked; - for (count = 0; count < 5; count++) { - hostlocked = netdata_rwlock_trywrlock(&host->rrdhost_rwlock); - if (!hostlocked) { - rrdcalc_link_to_rrddim(rd, st, host); - rrdhost_unlock(host); - break; - } else if (hostlocked != EBUSY) { - error("Cannot lock host to create an alarm for the dimension."); - } - sleep_usec(USEC_PER_MS * 200); - } - - if (count == 5) { - error( - "Failed to create an alarm for dimension %s of chart %s 5 times. Skipping alarm.", rd->name, st->name); - } - } -} - // ---------------------------------------------------------------------------- // RRDDIM index @@ -73,9 +47,15 @@ inline int rrddim_set_name(RRDSET *st, RRDDIM *rd, const char *name) { snprintfz(varname, CONFIG_MAX_NAME, "dim %s name", rd->id); rd->name = config_set_default(st->config_section, varname, name); rd->hash_name = simple_hash(rd->name); - rrddimvar_rename_all(rd); + + if (!st->state->is_ar_chart) + rrddimvar_rename_all(rd); + rd->exposed = 0; rrdset_flag_clear(st, RRDSET_FLAG_UPSTREAM_EXPOSED); + + ml_dimension_update_name(st, rd, name); + return 1; } @@ -238,7 +218,10 @@ RRDDIM *rrddim_add_custom(RRDSET *st, const char *id, const char *name, collecte rrddimvar_create(rd, RRDVAR_TYPE_CALCULATED, NULL, NULL, &rd->last_stored_value, RRDVAR_OPTION_DEFAULT); rrddimvar_create(rd, RRDVAR_TYPE_COLLECTED, NULL, "_raw", &rd->last_collected_value, RRDVAR_OPTION_DEFAULT); rrddimvar_create(rd, RRDVAR_TYPE_TIME_T, NULL, "_last_collected_t", &rd->last_collected_time.tv_sec, RRDVAR_OPTION_DEFAULT); - calc_link_to_rrddim(rd); + + rrddim_flag_set(rd, RRDDIM_FLAG_PENDING_FOREACH_ALARM); + rrdset_flag_set(st, RRDSET_FLAG_PENDING_FOREACH_ALARMS); + rrdhost_flag_set(host, RRDHOST_FLAG_PENDING_FOREACH_ALARMS); } if (unlikely(rc)) { debug(D_METADATALOG, "DIMENSION [%s] metadata updated", rd->id); @@ -252,7 +235,6 @@ RRDDIM *rrddim_add_custom(RRDSET *st, const char *id, const char *name, collecte char filename[FILENAME_MAX + 1]; char fullfilename[FILENAME_MAX + 1]; - char varname[CONFIG_MAX_NAME + 1]; unsigned long size = sizeof(RRDDIM) + (st->entries * sizeof(storage_number)); debug(D_RRD_CALLS, "Adding dimension '%s/%s'.", st->id, id); @@ -350,18 +332,14 @@ RRDDIM *rrddim_add_custom(RRDSET *st, const char *id, const char *name, collecte rd->cache_filename = strdupz(fullfilename); - snprintfz(varname, CONFIG_MAX_NAME, "dim %s name", rd->id); - rd->name = config_get(st->config_section, varname, (name && *name)?name:rd->id); + rd->name = (name && *name)?strdupz(name):strdupz(rd->id); rd->hash_name = simple_hash(rd->name); - snprintfz(varname, CONFIG_MAX_NAME, "dim %s algorithm", rd->id); - rd->algorithm = rrd_algorithm_id(config_get(st->config_section, varname, rrd_algorithm_name(algorithm))); + rd->algorithm = algorithm; - snprintfz(varname, CONFIG_MAX_NAME, "dim %s multiplier", rd->id); - rd->multiplier = config_get_number(st->config_section, varname, multiplier); + rd->multiplier = multiplier; - snprintfz(varname, CONFIG_MAX_NAME, "dim %s divisor", rd->id); - rd->divisor = config_get_number(st->config_section, varname, divisor); + rd->divisor = divisor; if(!rd->divisor) rd->divisor = 1; rd->entries = st->entries; @@ -443,7 +421,7 @@ RRDDIM *rrddim_add_custom(RRDSET *st, const char *id, const char *name, collecte td->next = rd; } - if(host->health_enabled) { + if(host->health_enabled && !st->state->is_ar_chart) { rrddimvar_create(rd, RRDVAR_TYPE_CALCULATED, NULL, NULL, &rd->last_stored_value, RRDVAR_OPTION_DEFAULT); rrddimvar_create(rd, RRDVAR_TYPE_COLLECTED, NULL, "_raw", &rd->last_collected_value, RRDVAR_OPTION_DEFAULT); rrddimvar_create(rd, RRDVAR_TYPE_TIME_T, NULL, "_last_collected_t", &rd->last_collected_time.tv_sec, RRDVAR_OPTION_DEFAULT); @@ -452,7 +430,9 @@ RRDDIM *rrddim_add_custom(RRDSET *st, const char *id, const char *name, collecte if(unlikely(rrddim_index_add(st, rd) != rd)) error("RRDDIM: INTERNAL ERROR: attempt to index duplicate dimension '%s' on chart '%s'", rd->id, st->id); - calc_link_to_rrddim(rd); + rrddim_flag_set(rd, RRDDIM_FLAG_PENDING_FOREACH_ALARM); + rrdset_flag_set(st, RRDSET_FLAG_PENDING_FOREACH_ALARMS); + rrdhost_flag_set(host, RRDHOST_FLAG_PENDING_FOREACH_ALARMS); ml_new_dimension(rd); @@ -503,6 +483,10 @@ void rrddim_free_custom(RRDSET *st, RRDDIM *rd, int db_rotated) error("RRDDIM: INTERNAL ERROR: attempt to remove from index dimension '%s' on chart '%s', removed a different dimension.", rd->id, st->id); // free(rd->annotations); +#if defined(ENABLE_ACLK) && defined(ENABLE_NEW_CLOUD_PROTOCOL) + if (!netdata_exit) + aclk_send_dimension_update(rd); +#endif RRD_MEMORY_MODE rrd_memory_mode = rd->rrd_memory_mode; switch(rrd_memory_mode) { @@ -511,6 +495,7 @@ void rrddim_free_custom(RRDSET *st, RRDDIM *rd, int db_rotated) case RRD_MEMORY_MODE_RAM: debug(D_RRD_CALLS, "Unmapping dimension '%s'.", rd->name); freez((void *)rd->id); + freez((void *)rd->name); freez(rd->cache_filename); freez(rd->state); munmap(rd, rd->memsize); @@ -521,6 +506,7 @@ void rrddim_free_custom(RRDSET *st, RRDDIM *rd, int db_rotated) case RRD_MEMORY_MODE_DBENGINE: debug(D_RRD_CALLS, "Removing dimension '%s'.", rd->name); freez((void *)rd->id); + freez((void *)rd->name); freez(rd->cache_filename); freez(rd->state); freez(rd); @@ -546,6 +532,7 @@ int rrddim_hide(RRDSET *st, const char *id) { error("Cannot find dimension with id '%s' on stats '%s' (%s) on host '%s'.", id, st->name, st->id, host->hostname); return 1; } + (void) sql_set_dimension_option(&rd->state->metric_uuid, "hidden"); rrddim_flag_set(rd, RRDDIM_FLAG_HIDDEN); #ifdef ENABLE_ACLK @@ -563,6 +550,7 @@ int rrddim_unhide(RRDSET *st, const char *id) { error("Cannot find dimension with id '%s' on stats '%s' (%s) on host '%s'.", id, st->name, st->id, host->hostname); return 1; } + (void) sql_set_dimension_option(&rd->state->metric_uuid, NULL); rrddim_flag_clear(rd, RRDDIM_FLAG_HIDDEN); #ifdef ENABLE_ACLK diff --git a/database/rrdhost.c b/database/rrdhost.c index 79e283a63..649736ca4 100644 --- a/database/rrdhost.c +++ b/database/rrdhost.c @@ -385,17 +385,15 @@ RRDHOST *rrdhost_create(const char *hostname, // ------------------------------------------------------------------------ // init new ML host and update system_info to let upstreams know // about ML functionality + // - ml_new_host(host); if (is_localhost && host->system_info) { -#ifndef ENABLE_ML - host->system_info->ml_capable = 0; -#else - host->system_info->ml_capable = 1; -#endif - host->system_info->ml_enabled = host->ml_host != NULL; + host->system_info->ml_capable = ml_capable(); + host->system_info->ml_enabled = ml_enabled(host); } + ml_new_host(host); + info("Host '%s' (at registry as '%s') with guid '%s' initialized" ", os '%s'" ", timezone '%s'" @@ -642,8 +640,6 @@ RRDHOST *rrdhost_find_or_create( rrdhost_unlock(host); } - rrdhost_cleanup_orphan_hosts_nolock(host); - rrd_unlock(); return host; @@ -652,7 +648,7 @@ inline int rrdhost_should_be_removed(RRDHOST *host, RRDHOST *protected_host, tim if(host != protected_host && host != localhost && rrdhost_flag_check(host, RRDHOST_FLAG_ORPHAN) - && host->receiver + && !host->receiver && host->senders_disconnected_time && host->senders_disconnected_time + rrdhost_free_orphan_time < now) return 1; @@ -722,7 +718,7 @@ int rrd_init(char *hostname, struct rrdhost_system_info *system_info) { , netdata_configured_timezone , netdata_configured_abbrev_timezone , netdata_configured_utc_offset - , config_get(CONFIG_SECTION_BACKEND, "host tags", "") + , "" , program_name , program_version , default_rrd_update_every @@ -810,6 +806,9 @@ void rrdhost_system_info_free(struct rrdhost_system_info *system_info) { info("SYSTEM_INFO: free %p", system_info); if(likely(system_info)) { + freez(system_info->cloud_provider_type); + freez(system_info->cloud_instance_type); + freez(system_info->cloud_instance_region); freez(system_info->host_os_name); freez(system_info->host_os_id); freez(system_info->host_os_id_like); @@ -834,6 +833,9 @@ void rrdhost_system_info_free(struct rrdhost_system_info *system_info) { freez(system_info->container); freez(system_info->container_detection); freez(system_info->is_k8s_node); + freez(system_info->install_type); + freez(system_info->prebuilt_arch); + freez(system_info->prebuilt_dist); freez(system_info); } } @@ -846,6 +848,10 @@ void rrdhost_free(RRDHOST *host) { rrd_check_wrlock(); // make sure the RRDs are write locked + rrdhost_wrlock(host); + ml_delete_host(host); + rrdhost_unlock(host); + // ------------------------------------------------------------------------ // clean up streaming rrdpush_sender_thread_stop(host); // stop a possibly running thread @@ -877,7 +883,20 @@ void rrdhost_free(RRDHOST *host) { rrdhost_wrlock(host); // lock this RRDHOST - +#if defined(ENABLE_ACLK) && defined(ENABLE_NEW_CLOUD_PROTOCOL) + struct aclk_database_worker_config *wc = host->dbsync_worker; + if (wc && !netdata_exit) { + struct aclk_database_cmd cmd; + memset(&cmd, 0, sizeof(cmd)); + cmd.opcode = ACLK_DATABASE_ORPHAN_HOST; + struct aclk_completion compl ; + init_aclk_completion(&compl ); + cmd.completion = &compl ; + aclk_database_enq_cmd(wc, &cmd); + wait_for_aclk_completion(&compl ); + destroy_aclk_completion(&compl ); + } +#endif // ------------------------------------------------------------------------ // release its children resources @@ -922,8 +941,6 @@ void rrdhost_free(RRDHOST *host) { rrdeng_exit(host->rrdeng_ctx); #endif - ml_delete_host(host); - // ------------------------------------------------------------------------ // remove it from the indexes @@ -980,7 +997,10 @@ void rrdhost_free(RRDHOST *host) { freez(host->node_id); freez(host); - +#if defined(ENABLE_ACLK) && defined(ENABLE_NEW_CLOUD_PROTOCOL) + if (wc) + wc->is_orphan = 0; +#endif rrd_hosts_available--; } @@ -1019,6 +1039,18 @@ static struct label *rrdhost_load_auto_labels(void) { struct label *label_list = NULL; + if (localhost->system_info->cloud_provider_type) + label_list = + add_label_to_list(label_list, "_cloud_provider_type", localhost->system_info->cloud_provider_type, LABEL_SOURCE_AUTO); + + if (localhost->system_info->cloud_instance_type) + label_list = + add_label_to_list(label_list, "_cloud_instance_type", localhost->system_info->cloud_instance_type, LABEL_SOURCE_AUTO); + + if (localhost->system_info->cloud_instance_region) + label_list = + add_label_to_list(label_list, "_cloud_instance_region", localhost->system_info->cloud_instance_region, LABEL_SOURCE_AUTO); + if (localhost->system_info->host_os_name) label_list = add_label_to_list(label_list, "_os_name", localhost->system_info->host_os_name, LABEL_SOURCE_AUTO); @@ -1071,6 +1103,18 @@ static struct label *rrdhost_load_auto_labels(void) label_list = add_label_to_list(label_list, "_is_k8s_node", localhost->system_info->is_k8s_node, LABEL_SOURCE_AUTO); + if (localhost->system_info->install_type) + label_list = + add_label_to_list(label_list, "_install_type", localhost->system_info->install_type, LABEL_SOURCE_AUTO); + + if (localhost->system_info->prebuilt_arch) + label_list = + add_label_to_list(label_list, "_prebuilt_arch", localhost->system_info->prebuilt_arch, LABEL_SOURCE_AUTO); + + if (localhost->system_info->prebuilt_dist) + label_list = + add_label_to_list(label_list, "_prebuilt_dist", localhost->system_info->prebuilt_dist, LABEL_SOURCE_AUTO); + label_list = add_aclk_host_labels(label_list); label_list = add_label_to_list( @@ -1206,50 +1250,6 @@ struct label *parse_json_tags(struct label *label_list, const char *tags) return label_list; } -static struct label *rrdhost_load_labels_from_tags(void) -{ - if (!localhost->tags) - return NULL; - - struct label *label_list = NULL; - BACKEND_TYPE type = BACKEND_TYPE_UNKNOWN; - - if (config_exists(CONFIG_SECTION_BACKEND, "enabled")) { - if (config_get_boolean(CONFIG_SECTION_BACKEND, "enabled", CONFIG_BOOLEAN_NO) != CONFIG_BOOLEAN_NO) { - const char *type_name = config_get(CONFIG_SECTION_BACKEND, "type", "graphite"); - type = backend_select_type(type_name); - } - } - - switch (type) { - case BACKEND_TYPE_GRAPHITE: - label_list = parse_simple_tags( - label_list, localhost->tags, '=', ';', DO_NOT_STRIP_QUOTES, DO_NOT_STRIP_QUOTES, - DO_NOT_SKIP_ESCAPED_CHARACTERS); - break; - case BACKEND_TYPE_OPENTSDB_USING_TELNET: - label_list = parse_simple_tags( - label_list, localhost->tags, '=', ' ', DO_NOT_STRIP_QUOTES, DO_NOT_STRIP_QUOTES, - DO_NOT_SKIP_ESCAPED_CHARACTERS); - break; - case BACKEND_TYPE_OPENTSDB_USING_HTTP: - label_list = parse_simple_tags( - label_list, localhost->tags, ':', ',', STRIP_QUOTES, STRIP_QUOTES, - DO_NOT_SKIP_ESCAPED_CHARACTERS); - break; - case BACKEND_TYPE_JSON: - label_list = parse_json_tags(label_list, localhost->tags); - break; - default: - label_list = parse_simple_tags( - label_list, localhost->tags, '=', ',', DO_NOT_STRIP_QUOTES, STRIP_QUOTES, - DO_NOT_SKIP_ESCAPED_CHARACTERS); - break; - } - - return label_list; -} - static struct label *rrdhost_load_kubernetes_labels(void) { struct label *l=NULL; @@ -1313,10 +1313,8 @@ void reload_host_labels(void) struct label *from_auto = rrdhost_load_auto_labels(); struct label *from_k8s = rrdhost_load_kubernetes_labels(); struct label *from_config = rrdhost_load_config_labels(); - struct label *from_tags = rrdhost_load_labels_from_tags(); struct label *new_labels = merge_label_lists(from_auto, from_k8s); - new_labels = merge_label_lists(new_labels, from_tags); new_labels = merge_label_lists(new_labels, from_config); rrdhost_rdlock(localhost); @@ -1489,6 +1487,11 @@ restart_after_removal: } continue; } +#if defined(ENABLE_ACLK) && defined(ENABLE_NEW_CLOUD_PROTOCOL) + else { + aclk_send_dimension_update(rd); + } +#endif } last = rd; rd = rd->next; @@ -1518,6 +1521,10 @@ restart_after_removal: rrdset_free(st); goto restart_after_removal; } +#if defined(ENABLE_ACLK) && defined(ENABLE_NEW_CLOUD_PROTOCOL) + else + sql_check_chart_liveness(st); +#endif } } @@ -1553,6 +1560,18 @@ int rrdhost_set_system_info_variable(struct rrdhost_system_info *system_info, ch if (!strcmp(name, "NETDATA_PROTOCOL_VERSION")) return res; + else if(!strcmp(name, "NETDATA_INSTANCE_CLOUD_TYPE")){ + freez(system_info->cloud_provider_type); + system_info->cloud_provider_type = strdupz(value); + } + else if(!strcmp(name, "NETDATA_INSTANCE_CLOUD_INSTANCE_TYPE")){ + freez(system_info->cloud_instance_type); + system_info->cloud_instance_type = strdupz(value); + } + else if(!strcmp(name, "NETDATA_INSTANCE_CLOUD_INSTANCE_REGION")){ + freez(system_info->cloud_instance_region); + system_info->cloud_instance_region = strdupz(value); + } else if(!strcmp(name, "NETDATA_CONTAINER_OS_NAME")){ freez(system_info->container_os_name); system_info->container_os_name = strdupz(value); @@ -1580,6 +1599,7 @@ int rrdhost_set_system_info_variable(struct rrdhost_system_info *system_info, ch else if(!strcmp(name, "NETDATA_HOST_OS_NAME")){ freez(system_info->host_os_name); system_info->host_os_name = strdupz(value); + json_fix_string(system_info->host_os_name); } else if(!strcmp(name, "NETDATA_HOST_OS_ID")){ freez(system_info->host_os_id); diff --git a/database/rrdset.c b/database/rrdset.c index 19af449d8..f8e471be7 100644 --- a/database/rrdset.c +++ b/database/rrdset.c @@ -144,25 +144,38 @@ int rrdset_set_name(RRDSET *st, const char *name) { debug(D_RRD_CALLS, "rrdset_set_name() old: '%s', new: '%s'", st->name?st->name:"", name); - char b[CONFIG_MAX_VALUE + 1]; - char n[RRD_ID_LENGTH_MAX + 1]; + char full_name[RRD_ID_LENGTH_MAX + 1]; + char sanitized_name[CONFIG_MAX_VALUE + 1]; + char new_name[CONFIG_MAX_VALUE + 1]; - snprintfz(n, RRD_ID_LENGTH_MAX, "%s.%s", st->type, name); - rrdset_strncpyz_name(b, n, CONFIG_MAX_VALUE); + snprintfz(full_name, RRD_ID_LENGTH_MAX, "%s.%s", st->type, name); + rrdset_strncpyz_name(sanitized_name, full_name, CONFIG_MAX_VALUE); + strncpyz(new_name, sanitized_name, CONFIG_MAX_VALUE); - if(rrdset_index_find_name(host, b, 0)) { - info("RRDSET: chart name '%s' on host '%s' already exists.", b, host->hostname); - return 0; + if(rrdset_index_find_name(host, new_name, 0)) { + debug(D_RRD_CALLS, "RRDSET: chart name '%s' on host '%s' already exists.", new_name, host->hostname); + if(!strcmp(st->id, full_name) && !st->name) { + unsigned i = 1; + + do { + snprintfz(new_name, CONFIG_MAX_VALUE, "%s_%u", sanitized_name, i); + i++; + } while (rrdset_index_find_name(host, new_name, 0)); + + info("RRDSET: using name '%s' for chart '%s' on host '%s'.", new_name, full_name, host->hostname); + } else { + return 0; + } } if(st->name) { rrdset_index_del_name(host, st); - st->name = config_set_default(st->config_section, "name", b); + st->name = strdupz(new_name); st->hash_name = simple_hash(st->name); rrdsetvar_rename_all(st); } else { - st->name = config_get(st->config_section, "name", b); + st->name = strdupz(new_name); st->hash_name = simple_hash(st->name); } @@ -177,8 +190,6 @@ int rrdset_set_name(RRDSET *st, const char *name) { rrdset_flag_clear(st, RRDSET_FLAG_EXPORTING_SEND); rrdset_flag_clear(st, RRDSET_FLAG_EXPORTING_IGNORE); - rrdset_flag_clear(st, RRDSET_FLAG_BACKEND_SEND); - rrdset_flag_clear(st, RRDSET_FLAG_BACKEND_IGNORE); rrdset_flag_clear(st, RRDSET_FLAG_UPSTREAM_SEND); rrdset_flag_clear(st, RRDSET_FLAG_UPSTREAM_IGNORE); rrdset_flag_clear(st, RRDSET_FLAG_UPSTREAM_EXPOSED); @@ -384,6 +395,13 @@ void rrdset_free(RRDSET *st) { netdata_rwlock_destroy(&st->state->labels.labels_rwlock); // free directly allocated members + freez((void *)st->name); + freez(st->type); + freez(st->family); + freez(st->title); + freez(st->units); + freez(st->context); + freez(st->cache_dir); freez(st->config_section); freez(st->plugin_name); freez(st->module_name); @@ -617,10 +635,8 @@ RRDSET *rrdset_create_custom( mark_rebuild |= META_CHART_UPDATED; } - RRDSET_TYPE new_chart_type = - rrdset_type_id(config_get(st->config_section, "chart type", rrdset_type_name(chart_type))); - if (st->chart_type != new_chart_type) { - st->chart_type = new_chart_type; + if (st->chart_type != chart_type) { + st->chart_type = chart_type; mark_rebuild |= META_CHART_UPDATED; } @@ -709,19 +725,11 @@ RRDSET *rrdset_create_custom( // get the options from the config, we need to create it long entries; - if(memory_mode == RRD_MEMORY_MODE_DBENGINE) { - // only sets it the first time - entries = config_get_number(config_section, "history", 5); - } else { - long rentries = config_get_number(config_section, "history", history_entries); - entries = align_entries_to_pagesize(memory_mode, rentries); - if (entries != rentries) entries = config_set_number(config_section, "history", entries); - - if (memory_mode == RRD_MEMORY_MODE_NONE && entries != rentries) - entries = config_set_number(config_section, "history", 10); - } int enabled = config_get_boolean(config_section, "enabled", 1); - if(!enabled) entries = 5; + if(!enabled || memory_mode == RRD_MEMORY_MODE_DBENGINE) + entries = 5; + else + entries = align_entries_to_pagesize(memory_mode, history_entries); unsigned long size = sizeof(RRDSET); char *cache_dir = rrdset_cache_dir(host, fullid, config_section); @@ -840,22 +848,25 @@ RRDSET *rrdset_create_custom( st->cache_dir = cache_dir; - st->chart_type = rrdset_type_id(config_get(st->config_section, "chart type", rrdset_type_name(chart_type))); - st->type = config_get(st->config_section, "type", type); + st->chart_type = chart_type; + st->type = strdupz(type); st->state = callocz(1, sizeof(*st->state)); - st->family = config_get(st->config_section, "family", family?family:st->type); + + st->family = family ? strdupz(family) : strdupz(st->type); json_fix_string(st->family); - st->units = config_get(st->config_section, "units", units?units:""); + st->state->is_ar_chart = strcmp(st->id, ML_ANOMALY_RATES_CHART_ID) == 0; + + st->units = units ? strdupz(units) : strdupz(""); json_fix_string(st->units); - st->context = config_get(st->config_section, "context", context?context:st->id); + st->context = context ? strdupz(context) : strdupz(st->id); st->state->old_context = strdupz(st->context); json_fix_string(st->context); st->hash_context = simple_hash(st->context); - st->priority = config_get_number(st->config_section, "priority", priority); + st->priority = priority; if(enabled) rrdset_flag_set(st, RRDSET_FLAG_ENABLED); else @@ -866,8 +877,6 @@ RRDSET *rrdset_create_custom( rrdset_flag_clear(st, RRDSET_FLAG_OBSOLETE); rrdset_flag_clear(st, RRDSET_FLAG_EXPORTING_SEND); rrdset_flag_clear(st, RRDSET_FLAG_EXPORTING_IGNORE); - rrdset_flag_clear(st, RRDSET_FLAG_BACKEND_SEND); - rrdset_flag_clear(st, RRDSET_FLAG_BACKEND_IGNORE); rrdset_flag_clear(st, RRDSET_FLAG_UPSTREAM_SEND); rrdset_flag_clear(st, RRDSET_FLAG_UPSTREAM_IGNORE); rrdset_flag_clear(st, RRDSET_FLAG_UPSTREAM_EXPOSED); @@ -905,7 +914,7 @@ RRDSET *rrdset_create_custom( // could not use the name, use the id rrdset_set_name(st, id); - st->title = config_get(st->config_section, "title", title); + st->title = strdupz(title); st->state->old_title = strdupz(st->title); json_fix_string(st->title); @@ -1392,9 +1401,9 @@ void rrdset_done(RRDSET *st) { rrdset_rdlock(st); #ifdef ENABLE_ACLK - if (unlikely(!rrdset_flag_check(st, RRDSET_FLAG_ACLK))) { - if (st->counter_done >= RRDSET_MINIMUM_LIVE_COUNT && st->dimensions) { - if (likely(!queue_chart_to_aclk(st))) + if (likely(!st->state->is_ar_chart)) { + if (unlikely(!rrdset_flag_check(st, RRDSET_FLAG_ACLK))) { + if (likely(st->dimensions && st->counter_done && !queue_chart_to_aclk(st))) rrdset_flag_set(st, RRDSET_FLAG_ACLK); } } @@ -1475,7 +1484,14 @@ void rrdset_done(RRDSET *st) { // check if we will re-write the entire page if(unlikely(st->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE && dt_usec(&st->last_collected_time, &st->last_updated) > (RRDENG_BLOCK_SIZE / sizeof(storage_number)) * update_every_ut)) { - info("%s: too old data (last updated at %ld.%ld, last collected at %ld.%ld). Resetting it. Will not store the next entry.", st->name, st->last_updated.tv_sec, st->last_updated.tv_usec, st->last_collected_time.tv_sec, st->last_collected_time.tv_usec); + info( + "%s: too old data (last updated at %" PRId64 ".%" PRId64 ", last collected at %" PRId64 ".%" PRId64 "). " + "Resetting it. Will not store the next entry.", + st->name, + (int64_t)st->last_updated.tv_sec, + (int64_t)st->last_updated.tv_usec, + (int64_t)st->last_collected_time.tv_sec, + (int64_t)st->last_collected_time.tv_usec); rrdset_reset(st); rrdset_init_last_updated_time(st); @@ -1815,8 +1831,10 @@ after_second_database_work: continue; #if defined(ENABLE_ACLK) && defined(ENABLE_NEW_CLOUD_PROTOCOL) + if (likely(!st->state->is_ar_chart)) { if (!rrddim_flag_check(rd, RRDDIM_FLAG_HIDDEN)) { - int live = ((mark - rd->last_collected_time.tv_sec) < (RRDSET_MINIMUM_LIVE_COUNT * rd->update_every)); + int live = + ((mark - rd->last_collected_time.tv_sec) < RRDSET_MINIMUM_DIM_LIVE_MULTIPLIER * rd->update_every); if (unlikely(live != rd->state->aclk_live_status)) { if (likely(rrdset_flag_check(st, RRDSET_FLAG_ACLK))) { if (likely(!queue_dimension_to_aclk(rd))) { @@ -1826,6 +1844,7 @@ after_second_database_work: } } } + } #endif if(unlikely(!rd->updated)) continue; @@ -1926,6 +1945,9 @@ after_second_database_work: delete_dimension_uuid(&rd->state->metric_uuid); } else { /* Do not delete this dimension */ +#if defined(ENABLE_ACLK) && defined(ENABLE_NEW_CLOUD_PROTOCOL) + aclk_send_dimension_update(rd); +#endif last = rd; rd = rd->next; continue; @@ -2021,3 +2043,39 @@ struct label *rrdset_lookup_label_key(RRDSET *st, char *key, uint32_t key_hash) } return ret; } + +static inline int k8s_space(char c) { + switch(c) { + case ':': + case ',': + return 1; + default: + return 0; + } +} + +int rrdset_matches_label_keys(RRDSET *st, char *keylist, char *words[], uint32_t *hash_key_list, int *word_count, int size) +{ + struct label_index *labels = &st->state->labels; + + if (!labels->head) + return 0; + + struct label *one_label; + + if (!*word_count) { + *word_count = quoted_strings_splitter(keylist, words, size, k8s_space, NULL, NULL, 0); + for (int i = 0; i < *word_count - 1; i += 2) { + hash_key_list[i] = simple_hash(words[i]); + } + } + + int ret = 1; + netdata_rwlock_rdlock(&labels->labels_rwlock); + for (int i = 0; ret && i < *word_count - 1; i += 2) { + one_label = label_list_lookup_key(labels->head, words[i], hash_key_list[i]); + ret = (one_label && !strcmp(one_label->value, words[i + 1])); + } + netdata_rwlock_unlock(&labels->labels_rwlock); + return ret; +} diff --git a/database/sqlite/sqlite_aclk.c b/database/sqlite/sqlite_aclk.c index 63196a81e..989328097 100644 --- a/database/sqlite/sqlite_aclk.c +++ b/database/sqlite/sqlite_aclk.c @@ -209,7 +209,7 @@ struct aclk_database_worker_config *find_inactive_wc_by_node_id(char *node_id) void aclk_sync_exit_all() { - rrd_wrlock(); + rrd_rdlock(); RRDHOST *host = localhost; while(host) { struct aclk_database_worker_config *wc = host->dbsync_worker; @@ -508,11 +508,16 @@ void aclk_database_worker(void *arg) aclk_update_retention(wc, cmd); aclk_process_dimension_deletion(wc, cmd); break; -#endif // NODE_INSTANCE DETECTION + case ACLK_DATABASE_ORPHAN_HOST: + wc->host = NULL; + wc->is_orphan = 1; + aclk_add_worker_thread(wc); + break; +#endif case ACLK_DATABASE_TIMER: - if (unlikely(localhost && !wc->host)) { + if (unlikely(localhost && !wc->host && !wc->is_orphan)) { if (claimed()) { wc->host = rrdhost_find_by_guid(wc->host_guid, 0); if (wc->host) { @@ -567,7 +572,7 @@ void aclk_database_worker(void *arg) freez(loop); - rrd_wrlock(); + rrd_rdlock(); if (likely(wc->host)) wc->host->dbsync_worker = NULL; freez(wc); @@ -815,7 +820,7 @@ void aclk_data_rotated(void) return; time_t next_rotation_time = now_realtime_sec()+ACLK_DATABASE_ROTATION_DELAY; - rrd_wrlock(); + rrd_rdlock(); RRDHOST *this_host = localhost; while (this_host) { struct aclk_database_worker_config *wc = this_host->dbsync_worker; diff --git a/database/sqlite/sqlite_aclk.h b/database/sqlite/sqlite_aclk.h index 424949740..894d93489 100644 --- a/database/sqlite/sqlite_aclk.h +++ b/database/sqlite/sqlite_aclk.h @@ -125,6 +125,7 @@ enum aclk_database_opcode { ACLK_DATABASE_CHART_ACK, ACLK_DATABASE_UPD_RETENTION, ACLK_DATABASE_DIM_DELETION, + ACLK_DATABASE_ORPHAN_HOST, #endif ACLK_DATABASE_ALARM_HEALTH_LOG, ACLK_DATABASE_CLEANUP, @@ -194,6 +195,7 @@ struct aclk_database_worker_config { int chart_pending; int chart_reset_count; volatile unsigned is_shutting_down; + volatile unsigned is_orphan; struct aclk_database_worker_config *next; }; diff --git a/database/sqlite/sqlite_aclk_alert.c b/database/sqlite/sqlite_aclk_alert.c index 238b500a8..54e8be4a7 100644 --- a/database/sqlite/sqlite_aclk_alert.c +++ b/database/sqlite/sqlite_aclk_alert.c @@ -127,7 +127,7 @@ void aclk_push_alert_event(struct aclk_database_worker_config *wc, struct aclk_d int rc; if (unlikely(!wc->alert_updates)) { - log_access("AC [%s (%s)]: Ignoring alert push event, updates have been turned off for this node.", wc->node_id, wc->host ? wc->host->hostname : "N/A"); + log_access("ACLK STA [%s (%s)]: Ignoring alert push event, updates have been turned off for this node.", wc->node_id, wc->host ? wc->host->hostname : "N/A"); return; } @@ -135,6 +135,11 @@ void aclk_push_alert_event(struct aclk_database_worker_config *wc, struct aclk_d if (unlikely(!claim_id)) return; + if (unlikely(!wc->host)) { + freez(claim_id); + return; + } + BUFFER *sql = buffer_create(1024); if (wc->alerts_start_seq_id != 0) { @@ -242,7 +247,9 @@ void aclk_push_alert_event(struct aclk_database_worker_config *wc, struct aclk_d alarm_log.old_value = (calculated_number) sqlite3_column_double(res, 24); alarm_log.updated = (sqlite3_column_int64(res, 8) & HEALTH_ENTRY_FLAG_UPDATED) ? 1 : 0; - alarm_log.rendered_info = strdupz((char *)sqlite3_column_text(res, 18)); + alarm_log.rendered_info = sqlite3_column_type(res, 18) == SQLITE_NULL ? + strdupz((char *)"") : + strdupz((char *)sqlite3_column_text(res, 18)); aclk_send_alarm_log_entry(&alarm_log); @@ -267,7 +274,13 @@ void aclk_push_alert_event(struct aclk_database_worker_config *wc, struct aclk_d db_execute(buffer_tostring(sql)); } else { if (log_first_sequence_id) - log_access("OG [%s (%s)]: Sent alert events, first sequence_id %"PRIu64", last sequence_id %"PRIu64, wc->node_id, wc->host ? wc->host->hostname : "N/A", log_first_sequence_id, log_last_sequence_id); + log_access( + "ACLK RES [%s (%s)]: ALERTS SENT from %" PRIu64 " to %" PRIu64 " batch=%" PRIu64, + wc->node_id, + wc->host ? wc->host->hostname : "N/A", + log_first_sequence_id, + log_last_sequence_id, + wc->alerts_batch_id); log_first_sequence_id = 0; log_last_sequence_id = 0; } @@ -288,23 +301,32 @@ void aclk_send_alarm_health_log(char *node_id) if (unlikely(!node_id)) return; - log_access("IN [%s (N/A)]: Request to send alarm health log.", node_id); + char *hostname= NULL; struct aclk_database_worker_config *wc = NULL; struct aclk_database_cmd cmd; memset(&cmd, 0, sizeof(cmd)); cmd.opcode = ACLK_DATABASE_ALARM_HEALTH_LOG; - rrd_wrlock(); + rrd_rdlock(); RRDHOST *host = find_host_by_node_id(node_id); - if (likely(host)) + if (likely(host)) { wc = (struct aclk_database_worker_config *)host->dbsync_worker; + hostname = host->hostname; + } + else + hostname = get_hostname_by_node_id(node_id); rrd_unlock(); + + log_access("ACLK REQ [%s (%s)]: HEALTH LOG request received", node_id, hostname ? hostname : "N/A"); + if (unlikely(!host)) + freez(hostname); + if (wc) aclk_database_enq_cmd(wc, &cmd); else { if (aclk_worker_enq_cmd(node_id, &cmd)) - log_access("AC [%s (N/A)]: ACLK synchronization thread is not active.", node_id); + log_access("ACLK STA [%s (N/A)]: ACLK synchronization thread is not active.", node_id); } return; } @@ -323,7 +345,7 @@ void aclk_push_alarm_health_log(struct aclk_database_worker_config *wc, struct a RRDHOST *host = wc->host; if (unlikely(!host)) { - rrd_wrlock(); + rrd_rdlock(); host = find_host_by_node_id(wc->node_id); rrd_unlock(); @@ -391,7 +413,7 @@ void aclk_push_alarm_health_log(struct aclk_database_worker_config *wc, struct a wc->alert_sequence_id = last_sequence; aclk_send_alarm_log_health(&alarm_log); - log_access("OG [%s (%s)]: Alarm health log sent, first sequence id %"PRIu64", last sequence id %"PRIu64, wc->node_id, wc->host ? wc->host->hostname : "N/A", first_sequence, last_sequence); + log_access("ACLK RES [%s (%s)]: HEALTH LOG SENT from %"PRIu64" to %"PRIu64, wc->node_id, wc->host ? wc->host->hostname : "N/A", first_sequence, last_sequence); rc = sqlite3_finalize(res); if (unlikely(rc != SQLITE_OK)) @@ -415,7 +437,7 @@ void aclk_send_alarm_configuration(char *config_hash) return; } - log_access("IN [%s (%s)]: Request to send alert config %s.", wc->node_id, wc->host ? wc->host->hostname : "N/A", config_hash); + log_access("ACLK REQ [%s (%s)]: Request to send alert config %s.", wc->node_id, wc->host ? wc->host->hostname : "N/A", config_hash); struct aclk_database_cmd cmd; memset(&cmd, 0, sizeof(cmd)); @@ -525,14 +547,14 @@ int aclk_push_alert_config_event(struct aclk_database_worker_config *wc, struct } if (likely(p_alarm_config.cfg_hash)) { - log_access("OG [%s (%s)]: Sent alert config %s.", wc->node_id, wc->host ? wc->host->hostname : "N/A", config_hash); + log_access("ACLK RES [%s (%s)]: Sent alert config %s.", wc->node_id, wc->host ? wc->host->hostname : "N/A", config_hash); aclk_send_provide_alarm_cfg(&p_alarm_config); freez((char *) cmd.data_param); freez(p_alarm_config.cfg_hash); destroy_aclk_alarm_configuration(&alarm_config); } else - log_access("AC [%s (%s)]: Alert config for %s not found.", wc->node_id, wc->host ? wc->host->hostname : "N/A", config_hash); + log_access("ACLK STA [%s (%s)]: Alert config for %s not found.", wc->node_id, wc->host ? wc->host->hostname : "N/A", config_hash); bind_fail: rc = sqlite3_finalize(res); @@ -552,28 +574,30 @@ void aclk_start_alert_streaming(char *node_id, uint64_t batch_id, uint64_t start if (unlikely(!node_id)) return; - log_access("IN [%s (N/A)]: Start streaming alerts with batch_id %"PRIu64" and start_seq_id %"PRIu64".", node_id, batch_id, start_seq_id); + //log_access("ACLK REQ [%s (N/A)]: ALERTS STREAM from %"PRIu64" batch=%"PRIu64".", node_id, start_seq_id, batch_id); uuid_t node_uuid; if (uuid_parse(node_id, node_uuid)) return; struct aclk_database_worker_config *wc = NULL; - rrd_wrlock(); + rrd_rdlock(); RRDHOST *host = find_host_by_node_id(node_id); - if (likely(host)) + rrd_unlock(); + if (likely(host)) { wc = (struct aclk_database_worker_config *)host->dbsync_worker ? (struct aclk_database_worker_config *)host->dbsync_worker : (struct aclk_database_worker_config *)find_inactive_wc_by_node_id(node_id); - rrd_unlock(); - if (unlikely(!host->health_enabled)) { - log_access("AC [%s (N/A)]: Ignoring request to stream alert state changes, health is disabled.", node_id); - return; - } + if (unlikely(!host->health_enabled)) { + log_access("ACLK STA [%s (N/A)]: Ignoring request to stream alert state changes, health is disabled.", node_id); + return; + } + } else + wc = (struct aclk_database_worker_config *)find_inactive_wc_by_node_id(node_id); if (likely(wc)) { - log_access("AC [%s (%s)]: Start streaming alerts enabled with batch_id %"PRIu64" and start_seq_id %"PRIu64".", node_id, wc->host ? wc->host->hostname : "N/A", batch_id, start_seq_id); + log_access("ACLK REQ [%s (%s)]: ALERTS STREAM from %"PRIu64" batch=%"PRIu64, node_id, wc->host ? wc->host->hostname : "N/A", start_seq_id, batch_id); __sync_synchronize(); wc->alerts_batch_id = batch_id; wc->alerts_start_seq_id = start_seq_id; @@ -581,7 +605,7 @@ void aclk_start_alert_streaming(char *node_id, uint64_t batch_id, uint64_t start __sync_synchronize(); } else - log_access("AC [%s (N/A)]: ACLK synchronization thread is not active.", node_id); + log_access("ACLK STA [%s (N/A)]: ACLK synchronization thread is not active.", node_id); #else UNUSED(node_id); @@ -607,7 +631,7 @@ void sql_process_queue_removed_alerts_to_aclk(struct aclk_database_worker_config db_execute(buffer_tostring(sql)); - log_access("AC [%s (%s)]: Queued removed alerts.", wc->node_id, wc->host ? wc->host->hostname : "N/A"); + log_access("ACLK STA [%s (%s)]: Queued removed alerts.", wc->node_id, wc->host ? wc->host->hostname : "N/A"); buffer_free(sql); #endif @@ -644,7 +668,7 @@ void aclk_process_send_alarm_snapshot(char *node_id, char *claim_id, uint64_t sn return; struct aclk_database_worker_config *wc = NULL; - rrd_wrlock(); + rrd_rdlock(); RRDHOST *host = find_host_by_node_id(node_id); if (likely(host)) wc = (struct aclk_database_worker_config *)host->dbsync_worker; @@ -657,6 +681,8 @@ void aclk_process_send_alarm_snapshot(char *node_id, char *claim_id, uint64_t sn wc->host ? wc->host->hostname : "N/A", snapshot_id, sequence_id); + if (wc->alerts_snapshot_id == snapshot_id) + return; __sync_synchronize(); wc->alerts_snapshot_id = snapshot_id; wc->alerts_ack_sequence_id = sequence_id; @@ -669,7 +695,7 @@ void aclk_process_send_alarm_snapshot(char *node_id, char *claim_id, uint64_t sn cmd.completion = NULL; aclk_database_enq_cmd(wc, &cmd); } else - log_access("AC [%s (N/A)]: ACLK synchronization thread is not active.", node_id); + log_access("ACLK STA [%s (N/A)]: ACLK synchronization thread is not active.", node_id); #else UNUSED(node_id); UNUSED(snapshot_id); @@ -714,7 +740,7 @@ void health_alarm_entry2proto_nolock(struct alarm_log_entry *alarm_log, ALARM_EN alarm_log->utc_offset = host->utc_offset; alarm_log->timezone = strdupz((char *)host->abbrev_timezone); alarm_log->exec_path = ae->exec ? strdupz((char *)ae->exec) : strdupz((char *)host->health_default_exec); - alarm_log->conf_source = ae->source ? strdupz((char *)ae->source) : ""; + alarm_log->conf_source = ae->source ? strdupz((char *)ae->source) : strdupz((char *)""); alarm_log->command = strdupz((char *)edit_command); @@ -738,7 +764,7 @@ void health_alarm_entry2proto_nolock(struct alarm_log_entry *alarm_log, ALARM_EN alarm_log->old_value = (!isnan(ae->old_value)) ? (calculated_number)ae->old_value : 0; alarm_log->updated = (ae->flags & HEALTH_ENTRY_FLAG_UPDATED) ? 1 : 0; - alarm_log->rendered_info = strdupz(ae->info); + alarm_log->rendered_info = ae->info ? strdupz(ae->info) : strdupz((char *)""); freez(edit_command); } @@ -770,7 +796,7 @@ void aclk_push_alert_snapshot_event(struct aclk_database_worker_config *wc, stru UNUSED(cmd); // we perhaps we don't need this for snapshots if (unlikely(!wc->alert_updates)) { - log_access("AC [%s (%s)]: Ignoring alert snapshot event, updates have been turned off for this node.", wc->node_id, wc->host ? wc->host->hostname : "N/A"); + log_access("ACLK STA [%s (%s)]: Ignoring alert snapshot event, updates have been turned off for this node.", wc->node_id, wc->host ? wc->host->hostname : "N/A"); return; } @@ -779,11 +805,14 @@ void aclk_push_alert_snapshot_event(struct aclk_database_worker_config *wc, stru return; } + if (unlikely(!wc->alerts_snapshot_id)) + return; + char *claim_id = is_agent_claimed(); if (unlikely(!claim_id)) return; - log_access("OG [%s (%s)]: Sending alerts snapshot, snapshot_id %" PRIu64, wc->node_id, wc->host ? wc->host->hostname : "N/A", wc->alerts_snapshot_id); + log_access("ACLK REQ [%s (%s)]: Sending alerts snapshot, snapshot_id %" PRIu64, wc->node_id, wc->host ? wc->host->hostname : "N/A", wc->alerts_snapshot_id); aclk_mark_alert_cloud_ack(wc->uuid_str, wc->alerts_ack_sequence_id); @@ -906,3 +935,44 @@ void sql_aclk_alert_clean_dead_entries(RRDHOST *host) UNUSED(host); #endif } + +int get_proto_alert_status(RRDHOST *host, struct proto_alert_status *proto_alert_status) +{ + int rc; + struct aclk_database_worker_config *wc = NULL; + wc = (struct aclk_database_worker_config *)host->dbsync_worker; + if (!wc) + return 1; + + proto_alert_status->alert_updates = wc->alert_updates; + proto_alert_status->alerts_batch_id = wc->alerts_batch_id; + + BUFFER *sql = buffer_create(1024); + sqlite3_stmt *res = NULL; + + buffer_sprintf(sql, "SELECT MIN(sequence_id), MAX(sequence_id), " \ + "(select MAX(sequence_id) from aclk_alert_%s where date_cloud_ack is not NULL), " \ + "(select MAX(sequence_id) from aclk_alert_%s where date_submitted is not NULL) " \ + "FROM aclk_alert_%s where date_submitted is null;", wc->uuid_str, wc->uuid_str, wc->uuid_str); + + rc = sqlite3_prepare_v2(db_meta, buffer_tostring(sql), -1, &res, 0); + if (rc != SQLITE_OK) { + error_report("Failed to prepare statement to get alert log status from the database."); + buffer_free(sql); + return 1; + } + + while (sqlite3_step(res) == SQLITE_ROW) { + proto_alert_status->pending_min_sequence_id = sqlite3_column_bytes(res, 0) > 0 ? (uint64_t) sqlite3_column_int64(res, 0) : 0; + proto_alert_status->pending_max_sequence_id = sqlite3_column_bytes(res, 1) > 0 ? (uint64_t) sqlite3_column_int64(res, 1) : 0; + proto_alert_status->last_acked_sequence_id = sqlite3_column_bytes(res, 2) > 0 ? (uint64_t) sqlite3_column_int64(res, 2) : 0; + proto_alert_status->last_submitted_sequence_id = sqlite3_column_bytes(res, 3) > 0 ? (uint64_t) sqlite3_column_int64(res, 3) : 0; + } + + rc = sqlite3_finalize(res); + if (unlikely(rc != SQLITE_OK)) + error_report("Failed to finalize statement to get alert log status from the database, rc = %d", rc); + + buffer_free(sql); + return 0; +} diff --git a/database/sqlite/sqlite_aclk_alert.h b/database/sqlite/sqlite_aclk_alert.h index 1aaaa5d23..957cb94ac 100644 --- a/database/sqlite/sqlite_aclk_alert.h +++ b/database/sqlite/sqlite_aclk_alert.h @@ -5,6 +5,15 @@ extern sqlite3 *db_meta; +struct proto_alert_status { + int alert_updates; + uint64_t alerts_batch_id; + uint64_t last_acked_sequence_id; + uint64_t pending_min_sequence_id; + uint64_t pending_max_sequence_id; + uint64_t last_submitted_sequence_id; +}; + int aclk_add_alert_event(struct aclk_database_worker_config *wc, struct aclk_database_cmd cmd); void aclk_push_alert_event(struct aclk_database_worker_config *wc, struct aclk_database_cmd cmd); void aclk_send_alarm_health_log(char *node_id); @@ -16,5 +25,6 @@ void sql_queue_removed_alerts_to_aclk(RRDHOST *host); void sql_process_queue_removed_alerts_to_aclk(struct aclk_database_worker_config *wc, struct aclk_database_cmd cmd); void aclk_push_alert_snapshot_event(struct aclk_database_worker_config *wc, struct aclk_database_cmd cmd); void aclk_process_send_alarm_snapshot(char *node_id, char *claim_id, uint64_t snapshot_id, uint64_t sequence_id); +int get_proto_alert_status(RRDHOST *host, struct proto_alert_status *proto_alert_status); #endif //NETDATA_SQLITE_ACLK_ALERT_H diff --git a/database/sqlite/sqlite_aclk_chart.c b/database/sqlite/sqlite_aclk_chart.c index eea48a567..7afa1d451 100644 --- a/database/sqlite/sqlite_aclk_chart.c +++ b/database/sqlite/sqlite_aclk_chart.c @@ -3,12 +3,12 @@ #include "sqlite_functions.h" #include "sqlite_aclk_chart.h" -#ifdef ENABLE_NEW_CLOUD_PROTOCOL +#if defined(ENABLE_ACLK) && defined(ENABLE_NEW_CLOUD_PROTOCOL) #include "../../aclk/aclk_charts_api.h" #include "../../aclk/aclk.h" -static inline int sql_queue_chart_payload(struct aclk_database_worker_config *wc, - void *data, enum aclk_database_opcode opcode) +static inline int +sql_queue_chart_payload(struct aclk_database_worker_config *wc, void *data, enum aclk_database_opcode opcode) { int rc; if (unlikely(!wc)) @@ -29,23 +29,22 @@ static int payload_sent(char *uuid_str, uuid_t *uuid, void *payload, size_t payl int send_status = 0; if (unlikely(!res)) { - BUFFER *sql = buffer_create(1024); - buffer_sprintf(sql,"SELECT 1 FROM aclk_chart_latest_%s acl, aclk_chart_payload_%s acp " + char sql[ACLK_SYNC_QUERY_SIZE]; + snprintfz(sql,ACLK_SYNC_QUERY_SIZE-1, "SELECT 1 FROM aclk_chart_latest_%s acl, aclk_chart_payload_%s acp " "WHERE acl.unique_id = acp.unique_id AND acl.uuid = @uuid AND acp.payload = @payload;", uuid_str, uuid_str); - rc = prepare_statement(db_meta, (char *) buffer_tostring(sql), &res); - buffer_free(sql); + rc = prepare_statement(db_meta, sql, &res); if (rc != SQLITE_OK) { error_report("Failed to prepare statement to check payload data"); return 0; } } - rc = sqlite3_bind_blob(res, 1, uuid , sizeof(*uuid), SQLITE_STATIC); + rc = sqlite3_bind_blob(res, 1, uuid, sizeof(*uuid), SQLITE_STATIC); if (unlikely(rc != SQLITE_OK)) goto bind_fail; - rc = sqlite3_bind_blob(res, 2, payload , payload_size, SQLITE_STATIC); + rc = sqlite3_bind_blob(res, 2, payload, payload_size, SQLITE_STATIC); if (unlikely(rc != SQLITE_OK)) goto bind_fail; @@ -60,24 +59,23 @@ bind_fail: } static int aclk_add_chart_payload(struct aclk_database_worker_config *wc, uuid_t *uuid, char *claim_id, - ACLK_PAYLOAD_TYPE payload_type, void *payload, size_t payload_size) + ACLK_PAYLOAD_TYPE payload_type, void *payload, size_t payload_size, int *send_status) { static __thread sqlite3_stmt *res_chart = NULL; int rc; rc = payload_sent(wc->uuid_str, uuid, payload, payload_size); + if (send_status) + *send_status = rc; if (rc == 1) return 0; if (unlikely(!res_chart)) { - BUFFER *sql = buffer_create(1024); - - buffer_sprintf(sql,"INSERT INTO aclk_chart_payload_%s (unique_id, uuid, claim_id, date_created, type, payload) " \ - "VALUES (@unique_id, @uuid, @claim_id, strftime('%%s','now'), @type, @payload);", wc->uuid_str); - - rc = prepare_statement(db_meta, (char *) buffer_tostring(sql), &res_chart); - buffer_free(sql); - + char sql[ACLK_SYNC_QUERY_SIZE]; + snprintfz(sql,ACLK_SYNC_QUERY_SIZE-1, + "INSERT INTO aclk_chart_payload_%s (unique_id, uuid, claim_id, date_created, type, payload) " \ + "VALUES (@unique_id, @uuid, @claim_id, strftime('%%s','now'), @type, @payload);", wc->uuid_str); + rc = prepare_statement(db_meta, sql, &res_chart); if (rc != SQLITE_OK) { error_report("Failed to prepare statement to store chart payload data"); return 1; @@ -91,15 +89,15 @@ static int aclk_add_chart_payload(struct aclk_database_worker_config *wc, uuid_t if (uuid_parse(claim_id, claim_uuid)) return 1; - rc = sqlite3_bind_blob(res_chart, 1, &unique_uuid , sizeof(unique_uuid), SQLITE_STATIC); + rc = sqlite3_bind_blob(res_chart, 1, &unique_uuid, sizeof(unique_uuid), SQLITE_STATIC); if (unlikely(rc != SQLITE_OK)) goto bind_fail; - rc = sqlite3_bind_blob(res_chart, 2, uuid , sizeof(*uuid), SQLITE_STATIC); + rc = sqlite3_bind_blob(res_chart, 2, uuid, sizeof(*uuid), SQLITE_STATIC); if (unlikely(rc != SQLITE_OK)) goto bind_fail; - rc = sqlite3_bind_blob(res_chart, 3, &claim_uuid , sizeof(claim_uuid), SQLITE_STATIC); + rc = sqlite3_bind_blob(res_chart, 3, &claim_uuid, sizeof(claim_uuid), SQLITE_STATIC); if (unlikely(rc != SQLITE_OK)) goto bind_fail; @@ -127,7 +125,6 @@ bind_fail: return (rc != SQLITE_DONE); } - int aclk_add_chart_event(struct aclk_database_worker_config *wc, struct aclk_database_cmd cmd) { int rc = 0; @@ -162,7 +159,7 @@ int aclk_add_chart_event(struct aclk_database_worker_config *wc, struct aclk_dat size_t size; char *payload = generate_chart_instance_updated(&size, &chart_payload); if (likely(payload)) - rc = aclk_add_chart_payload(wc, st->chart_uuid, claim_id, ACLK_PAYLOAD_CHART, (void *) payload, size); + rc = aclk_add_chart_payload(wc, st->chart_uuid, claim_id, ACLK_PAYLOAD_CHART, (void *) payload, size, NULL); freez(payload); chart_instance_updated_destroy(&chart_payload); } @@ -170,7 +167,8 @@ int aclk_add_chart_event(struct aclk_database_worker_config *wc, struct aclk_dat } static inline int aclk_upd_dimension_event(struct aclk_database_worker_config *wc, char *claim_id, uuid_t *dim_uuid, - const char *dim_id, const char *dim_name, const char *chart_type_id, time_t first_time, time_t last_time) + const char *dim_id, const char *dim_name, const char *chart_type_id, time_t first_time, time_t last_time, + int *send_status) { int rc = 0; size_t size; @@ -185,6 +183,9 @@ static inline int aclk_upd_dimension_event(struct aclk_database_worker_config *w if (!first_time) info("Host %s (node %s) deleting dimension id=[%s] name=[%s] chart=[%s]", wc->host_guid, wc->node_id, dim_id, dim_name, chart_type_id); + if (last_time) + info("Host %s (node %s) stopped collecting dimension id=[%s] name=[%s] chart=[%s] %ld seconds ago at %ld", + wc->host_guid, wc->node_id, dim_id, dim_name, chart_type_id, now_realtime_sec() - last_time, last_time); #endif dim_payload.node_id = wc->node_id; @@ -196,7 +197,7 @@ static inline int aclk_upd_dimension_event(struct aclk_database_worker_config *w dim_payload.last_timestamp.tv_sec = last_time; char *payload = generate_chart_dimension_updated(&size, &dim_payload); if (likely(payload)) - rc = aclk_add_chart_payload(wc, dim_uuid, claim_id, ACLK_PAYLOAD_DIMENSION, (void *)payload, size); + rc = aclk_add_chart_payload(wc, dim_uuid, claim_id, ACLK_PAYLOAD_DIMENSION, (void *)payload, size, send_status); freez(payload); return rc; } @@ -220,8 +221,13 @@ void aclk_process_dimension_deletion(struct aclk_database_worker_config *wc, str if (!claim_id) return; - rc = sqlite3_prepare_v2(db_meta, "DELETE FROM dimension_delete where host_id = @host_id " \ - "RETURNING dimension_id, dimension_name, chart_type_id, dim_id LIMIT 10;", -1, &res, 0); + rc = sqlite3_prepare_v2( + db_meta, + "DELETE FROM dimension_delete where host_id = @host_id " + "RETURNING dimension_id, dimension_name, chart_type_id, dim_id LIMIT 10;", + -1, + &res, + 0); if (rc != SQLITE_OK) { error_report("Failed to prepare statement when trying to delete dimension deletes"); @@ -229,7 +235,7 @@ void aclk_process_dimension_deletion(struct aclk_database_worker_config *wc, str return; } - rc = sqlite3_bind_blob(res, 1, &host_id , sizeof(host_id), SQLITE_STATIC); + rc = sqlite3_bind_blob(res, 1, &host_id, sizeof(host_id), SQLITE_STATIC); if (unlikely(rc != SQLITE_OK)) goto bind_fail; @@ -243,7 +249,8 @@ void aclk_process_dimension_deletion(struct aclk_database_worker_config *wc, str (const char *)sqlite3_column_text(res, 1), (const char *)sqlite3_column_text(res, 2), 0, - 0); + 0, + NULL); count++; } @@ -272,12 +279,13 @@ int aclk_add_dimension_event(struct aclk_database_worker_config *wc, struct aclk RRDDIM *rd = cmd.data; if (likely(claim_id)) { + int send_status = 0; time_t now = now_realtime_sec(); time_t first_t = rd->state->query_ops.oldest_time(rd); - time_t last_t = rd->state->query_ops.latest_time(rd); + time_t last_t = rd->state->query_ops.latest_time(rd); - int live = ((now - last_t) < (RRDSET_MINIMUM_LIVE_COUNT * rd->update_every)); + int live = ((now - last_t) < (RRDSET_MINIMUM_DIM_LIVE_MULTIPLIER * rd->update_every)); rc = aclk_upd_dimension_event( wc, @@ -287,7 +295,11 @@ int aclk_add_dimension_event(struct aclk_database_worker_config *wc, struct aclk rd->name, rd->rrdset->id, first_t, - live ? 0 : last_t); + live ? 0 : last_t, + &send_status); + + if (!send_status) + rd->state->aclk_live_status = live; freez(claim_id); } @@ -295,14 +307,16 @@ int aclk_add_dimension_event(struct aclk_database_worker_config *wc, struct aclk return rc; } - void aclk_send_chart_event(struct aclk_database_worker_config *wc, struct aclk_database_cmd cmd) { int rc; wc->chart_pending = 0; if (unlikely(!wc->chart_updates)) { - log_access("AC [%s (%s)]: Ignoring chart push event, updates have been turned off for this node.", wc->node_id, wc->host ? wc->host->hostname : "N/A"); + log_access( + "ACLK STA [%s (%s)]: Ignoring chart push event, updates have been turned off for this node.", + wc->node_id, + wc->host ? wc->host->hostname : "N/A"); return; } @@ -320,32 +334,31 @@ void aclk_send_chart_event(struct aclk_database_worker_config *wc, struct aclk_d uint64_t last_sequence; time_t last_timestamp = 0; - BUFFER *sql = buffer_create(1024); - - sqlite3_stmt *res = NULL; - - buffer_sprintf(sql, "SELECT ac.sequence_id, acp.payload, ac.date_created, ac.type, ac.uuid " \ - "FROM aclk_chart_%s ac, aclk_chart_payload_%s acp " \ - "WHERE ac.date_submitted IS NULL AND ac.unique_id = acp.unique_id AND ac.update_count > 0 " \ - "AND acp.claim_id = @claim_id ORDER BY ac.sequence_id ASC LIMIT %d;", wc->uuid_str, wc->uuid_str, limit); + char sql[ACLK_SYNC_QUERY_SIZE]; + static __thread sqlite3_stmt *res = NULL; - rc = sqlite3_prepare_v2(db_meta, buffer_tostring(sql), -1, &res, 0); - if (rc != SQLITE_OK) { - error_report("Failed to prepare statement when trying to send a chart update via ACLK"); - buffer_free(sql); - freez(claim_id); - return; + if (unlikely(!res)) { + snprintfz(sql,ACLK_SYNC_QUERY_SIZE-1,"SELECT ac.sequence_id, acp.payload, ac.date_created, ac.type, ac.uuid " \ + "FROM aclk_chart_%s ac, aclk_chart_payload_%s acp " \ + "WHERE ac.date_submitted IS NULL AND ac.unique_id = acp.unique_id AND ac.update_count > 0 " \ + "AND acp.claim_id = @claim_id ORDER BY ac.sequence_id ASC LIMIT %d;", wc->uuid_str, wc->uuid_str, limit); + rc = prepare_statement(db_meta, sql, &res); + if (rc != SQLITE_OK) { + error_report("Failed to prepare statement when trying to send a chart update via ACLK"); + freez(claim_id); + return; + } } - rc = sqlite3_bind_blob(res, 1, claim_uuid , sizeof(claim_uuid), SQLITE_STATIC); + rc = sqlite3_bind_blob(res, 1, claim_uuid, sizeof(claim_uuid), SQLITE_STATIC); if (unlikely(rc != SQLITE_OK)) goto bind_fail; - char **payload_list = callocz(limit+1, sizeof(char *)); - size_t *payload_list_size = callocz(limit+1, sizeof(size_t)); - size_t *payload_list_max_size = callocz(limit+1, sizeof(size_t)); - struct aclk_message_position *position_list = callocz(limit+1, sizeof(*position_list)); - int *is_dim = callocz(limit+1, sizeof(*is_dim)); + char **payload_list = callocz(limit + 1, sizeof(char *)); + size_t *payload_list_size = callocz(limit + 1, sizeof(size_t)); + size_t *payload_list_max_size = callocz(limit + 1, sizeof(size_t)); + struct aclk_message_position *position_list = callocz(limit + 1, sizeof(*position_list)); + int *is_dim = callocz(limit + 1, sizeof(*is_dim)); int loop = cmd.param1; @@ -388,29 +401,31 @@ void aclk_send_chart_event(struct aclk_database_worker_config *wc, struct aclk_d error_report("Failed to reset statement when pushing chart events, rc = %d", rc); if (likely(first_sequence)) { - buffer_flush(sql); db_lock(); - buffer_sprintf(sql, "UPDATE aclk_chart_%s SET status = NULL, date_submitted=strftime('%%s','now') " + snprintfz(sql,ACLK_SYNC_QUERY_SIZE-1, "UPDATE aclk_chart_%s SET status = NULL, date_submitted=strftime('%%s','now') " "WHERE date_submitted IS NULL AND sequence_id BETWEEN %" PRIu64 " AND %" PRIu64 ";", wc->uuid_str, first_sequence, last_sequence); - db_execute(buffer_tostring(sql)); - - buffer_flush(sql); - buffer_sprintf(sql, "INSERT OR REPLACE INTO aclk_chart_latest_%s (uuid, unique_id, date_submitted) " + db_execute(sql); + snprintfz(sql,ACLK_SYNC_QUERY_SIZE-1, "INSERT OR REPLACE INTO aclk_chart_latest_%s (uuid, unique_id, date_submitted) " " SELECT uuid, unique_id, date_submitted FROM aclk_chart_%s s " " WHERE date_submitted IS NOT NULL AND sequence_id BETWEEN %" PRIu64 " AND %" PRIu64 " ;", wc->uuid_str, wc->uuid_str, first_sequence, last_sequence); - db_execute(buffer_tostring(sql)); + db_execute(sql); db_unlock(); aclk_chart_inst_and_dim_update(payload_list, payload_list_size, is_dim, position_list, wc->batch_id); - log_access("OG [%s (%s)]: Sending charts and dimensions update, batch_id %"PRIu64", first sequence %"PRIu64", last sequence %"PRIu64, wc->node_id, wc->host ? wc->host->hostname : "N/A", wc->batch_id, first_sequence, last_sequence); + log_access( + "ACLK RES [%s (%s)]: CHARTS SENT from %" PRIu64 " to %" PRIu64 " batch=%" PRIu64, + wc->node_id, + wc->host ? wc->host->hostname : "N/A", + first_sequence, + last_sequence, + wc->batch_id); wc->chart_sequence_id = last_sequence; wc->chart_timestamp = last_timestamp; - } - else + } else break; --loop; } @@ -419,11 +434,14 @@ void aclk_send_chart_event(struct aclk_database_worker_config *wc, struct aclk_d time_t now = now_realtime_sec(); if (wc->rotation_after > now && wc->rotation_after < now + ACLK_DATABASE_ROTATION_DELAY) wc->rotation_after = now + ACLK_DATABASE_ROTATION_DELAY; - } - else { + } else { wc->chart_payload_count = sql_get_pending_count(wc); if (!wc->chart_payload_count) - log_access("AC [%s (%s)]: Sync of charts and dimensions done in %ld seconds.", wc->node_id, wc->host ? wc->host->hostname : "N/A", now_realtime_sec() - wc->startup_time); + log_access( + "ACLK STA [%s (%s)]: Sync of charts and dimensions done in %ld seconds.", + wc->node_id, + wc->host ? wc->host->hostname : "N/A", + now_realtime_sec() - wc->startup_time); } for (int i = 0; i <= limit; ++i) @@ -436,11 +454,10 @@ void aclk_send_chart_event(struct aclk_database_worker_config *wc, struct aclk_d freez(is_dim); bind_fail: - rc = sqlite3_finalize(res); + rc = sqlite3_reset(res); if (unlikely(rc != SQLITE_OK)) - error_report("Failed to finalize statement when pushing chart events, rc = %d", rc); + error_report("Failed to reset statement when pushing chart events, rc = %d", rc); - buffer_free(sql); freez(claim_id); return; } @@ -496,40 +513,44 @@ int aclk_send_chart_config(struct aclk_database_worker_config *wc, struct aclk_d } if (likely(chart_config.config_hash)) { - log_access("OG [%s (%s)]: Sending chart config for %s.", wc->node_id, wc->host ? wc->host->hostname : "N/A", hash_id); + log_access( + "ACLK REQ [%s (%s)]: Sending chart config for %s.", + wc->node_id, + wc->host ? wc->host->hostname : "N/A", + hash_id); aclk_chart_config_updated(&chart_config, 1); destroy_chart_config_updated(&chart_config); - } - else - log_access("AC [%s (%s)]: Chart config for %s not found.", wc->node_id, wc->host ? wc->host->hostname : "N/A", hash_id); + } else + log_access( + "ACLK STA [%s (%s)]: Chart config for %s not found.", + wc->node_id, + wc->host ? wc->host->hostname : "N/A", + hash_id); - bind_fail: - rc = sqlite3_finalize(res); - if (unlikely(rc != SQLITE_OK)) - error_report("Failed to reset statement when pushing chart config hash, rc = %d", rc); - fail: - freez((char *) cmd.data_param); - buffer_free(sql); - return rc; +bind_fail: + rc = sqlite3_finalize(res); + if (unlikely(rc != SQLITE_OK)) + error_report("Failed to reset statement when pushing chart config hash, rc = %d", rc); +fail: + freez((char *)cmd.data_param); + buffer_free(sql); + return rc; } - void aclk_receive_chart_ack(struct aclk_database_worker_config *wc, struct aclk_database_cmd cmd) { int rc; sqlite3_stmt *res = NULL; - log_access("IN [%s (%s)]: Received ack chart sequence id %"PRIu64, wc->node_id, wc->host ? wc->host->hostname : "N/A", cmd.param1); + char sql[ACLK_SYNC_QUERY_SIZE]; - BUFFER *sql = buffer_create(1024); + snprintfz(sql,ACLK_SYNC_QUERY_SIZE-1,"UPDATE aclk_chart_%s SET date_updated=strftime('%%s','now') WHERE sequence_id <= @sequence_id " + "AND date_submitted IS NOT NULL AND date_updated IS NULL;", wc->uuid_str); - buffer_sprintf(sql, "UPDATE aclk_chart_%s SET date_updated=strftime('%%s','now') WHERE sequence_id <= @sequence_id " - "AND date_submitted IS NOT NULL AND date_updated IS NULL;", wc->uuid_str); - - rc = sqlite3_prepare_v2(db_meta, buffer_tostring(sql), -1, &res, 0); + rc = sqlite3_prepare_v2(db_meta, sql, -1, &res, 0); if (rc != SQLITE_OK) { - error_report("Failed to prepare statement count sequence ids in the database"); - goto prepare_fail; + error_report("Failed to prepare statement to ack chart sequence ids"); + return; } rc = sqlite3_bind_int64(res, 1, (uint64_t) cmd.param1); @@ -539,28 +560,34 @@ void aclk_receive_chart_ack(struct aclk_database_worker_config *wc, struct aclk_ rc = execute_insert(res); if (rc != SQLITE_DONE) error_report("Failed to ACK sequence id, rc = %d", rc); + else + log_access( + "ACLK STA [%s (%s)]: CHARTS ACKNOWLEDGED in the database upto %" PRIu64, + wc->node_id, + wc->host ? wc->host->hostname : "N/A", + cmd.param1); - bind_fail: - if (unlikely(sqlite3_finalize(res) != SQLITE_OK)) - error_report("Failed to finalize statement to ACK older sequence ids, rc = %d", rc); - - prepare_fail: - buffer_free(sql); - return; +bind_fail: + if (unlikely(sqlite3_finalize(res) != SQLITE_OK)) + error_report("Failed to finalize statement to ACK older sequence ids, rc = %d", rc); + return; } void aclk_receive_chart_reset(struct aclk_database_worker_config *wc, struct aclk_database_cmd cmd) { BUFFER *sql = buffer_create(1024); - buffer_sprintf(sql, "UPDATE aclk_chart_%s SET status = NULL, date_submitted = NULL WHERE sequence_id >= %"PRIu64";", - wc->uuid_str, cmd.param1); + buffer_sprintf( + sql, + "UPDATE aclk_chart_%s SET status = NULL, date_submitted = NULL WHERE sequence_id >= %" PRIu64 ";", + wc->uuid_str, + cmd.param1); db_execute(buffer_tostring(sql)); if (cmd.param1 == 1) { - db_lock(); buffer_flush(sql); - log_access("IN [%s (%s)]: Received chart full resync.", wc->node_id, wc->host ? wc->host->hostname : "N/A"); + log_access("ACLK REQ [%s (%s)]: Received chart full resync.", wc->node_id, wc->host ? wc->host->hostname : "N/A"); buffer_sprintf(sql, "DELETE FROM aclk_chart_payload_%s; DELETE FROM aclk_chart_%s; " \ "DELETE FROM aclk_chart_latest_%s;", wc->uuid_str, wc->uuid_str, wc->uuid_str); + db_lock(); db_execute("BEGIN TRANSACTION;"); db_execute(buffer_tostring(sql)); @@ -587,12 +614,14 @@ void aclk_receive_chart_reset(struct aclk_database_worker_config *wc, struct acl rrdset_unlock(st); } rrdhost_unlock(host); - } - else + } else error_report("ACLK synchronization thread for %s is not linked to HOST", wc->host_guid); - } - else { - log_access("AC [%s (%s)]: Restarting chart sync from sequence %"PRIu64, wc->node_id, wc->host ? wc->host->hostname : "N/A", cmd.param1); + } else { + log_access( + "ACLK STA [%s (%s)]: Restarting chart sync from sequence %" PRIu64, + wc->node_id, + wc->host ? wc->host->hostname : "N/A", + cmd.param1); wc->chart_payload_count = sql_get_pending_count(wc); sql_get_last_chart_sequence(wc); } @@ -601,7 +630,6 @@ void aclk_receive_chart_reset(struct aclk_database_worker_config *wc, struct acl return; } - // // Functions called directly from ACLK threads and will queue commands // @@ -617,7 +645,12 @@ void aclk_get_chart_config(char **hash_id) cmd.opcode = ACLK_DATABASE_PUSH_CHART_CONFIG; for (int i = 0; hash_id[i]; ++i) { // TODO: Verify that we have a valid hash_id - log_access("IN [%s (%s)]: Request %d for chart config with hash %s received.", wc->node_id, wc->host ? wc->host->hostname : "N/A", i, hash_id[i]); + log_access( + "ACLK REQ [%s (%s)]: Request %d for chart config with hash %s received.", + wc->node_id, + wc->host ? wc->host->hostname : "N/A", + i, + hash_id[i]); cmd.data_param = (void *)strdupz(hash_id[i]); aclk_database_enq_cmd(wc, &cmd); } @@ -632,13 +665,13 @@ static void aclk_submit_param_command(char *node_id, enum aclk_database_opcode a if (unlikely(!node_id)) return; - struct aclk_database_worker_config *wc = NULL; + struct aclk_database_worker_config *wc = NULL; struct aclk_database_cmd cmd; memset(&cmd, 0, sizeof(cmd)); cmd.opcode = aclk_command; cmd.param1 = param; - rrd_wrlock(); + rrd_rdlock(); RRDHOST *host = find_host_by_node_id(node_id); if (likely(host)) wc = (struct aclk_database_worker_config *)host->dbsync_worker; @@ -647,7 +680,7 @@ static void aclk_submit_param_command(char *node_id, enum aclk_database_opcode a aclk_database_enq_cmd(wc, &cmd); else { if (aclk_worker_enq_cmd(node_id, &cmd)) - log_access("AC [%s (N/A)]: ACLK synchronization thread is not active.", node_id); + log_access("ACLK STA [%s (N/A)]: ACLK synchronization thread is not active.", node_id); } return; } @@ -657,7 +690,10 @@ void aclk_ack_chart_sequence_id(char *node_id, uint64_t last_sequence_id) if (unlikely(!node_id)) return; - log_access("AC [%s (N/A)]: Node reports last sequence id received %"PRIu64, node_id, last_sequence_id); + char *hostname = get_hostname_by_node_id(node_id); + log_access("ACLK REQ [%s (%s)]: CHARTS ACKNOWLEDGED upto %" PRIu64, node_id, hostname ? hostname : "N/A", + last_sequence_id); + freez(hostname); aclk_submit_param_command(node_id, ACLK_DATABASE_CHART_ACK, last_sequence_id); return; } @@ -669,15 +705,17 @@ void aclk_start_streaming(char *node_id, uint64_t sequence_id, time_t created_at if (unlikely(!node_id)) return; - log_access("IN [%s (N/A)]: Start streaming charts from sequence %"PRIu64" t=%ld, batch=%"PRIu64, node_id, - sequence_id, created_at, batch_id); + // log_access("ACLK REQ [%s (N/A)]: CHARTS STREAM from %"PRIu64" t=%ld batch=%"PRIu64, node_id, + // sequence_id, created_at, batch_id); uuid_t node_uuid; - if (uuid_parse(node_id, node_uuid)) + if (uuid_parse(node_id, node_uuid)) { + log_access("ACLK REQ [%s (N/A)]: CHARTS STREAM ignored, invalid node id", node_id); return; + } struct aclk_database_worker_config *wc = NULL; - rrd_wrlock(); + rrd_rdlock(); RRDHOST *host = localhost; while(host) { if (host->node_id && !(uuid_compare(*host->node_id, node_uuid))) { @@ -692,10 +730,23 @@ void aclk_start_streaming(char *node_id, uint64_t sequence_id, time_t created_at wc->batch_id = batch_id; __sync_synchronize(); wc->batch_created = now_realtime_sec(); + log_access( + "ACLK REQ [%s (%s)]: CHARTS STREAM from %" PRIu64 " t=%ld resets=%d", + wc->node_id, + wc->host ? wc->host->hostname : "N/A", + wc->chart_sequence_id, + wc->chart_timestamp, + wc->chart_reset_count); if (sequence_id > wc->chart_sequence_id || wc->chart_reset_count > 10) { - log_access("AC [%s (%s)]: Requesting full resync from the cloud " - "(reset=%d, remote_seq=%"PRIu64", local_seq=%"PRIu64")" - , wc->node_id, wc->host ? wc->host->hostname : "N/A", wc->chart_reset_count, sequence_id, wc->chart_sequence_id); + log_access( + "ACLK RES [%s (%s)]: CHARTS FULL RESYNC REQUEST " + "remote_seq=%" PRIu64 " local_seq=%" PRIu64 " resets=%d ", + wc->node_id, + wc->host ? wc->host->hostname : "N/A", + sequence_id, + wc->chart_sequence_id, + wc->chart_reset_count); + chart_reset_t chart_reset; chart_reset.claim_id = is_agent_claimed(); if (chart_reset.claim_id) { @@ -710,26 +761,34 @@ void aclk_start_streaming(char *node_id, uint64_t sequence_id, time_t created_at struct aclk_database_cmd cmd; memset(&cmd, 0, sizeof(cmd)); // TODO: handle timestamp - if (sequence_id < wc->chart_sequence_id || !sequence_id) { // || created_at != wc->chart_timestamp) { - log_access("AC [%s (%s)]: Reset streaming charts from sequence %"PRIu64 \ - " t=%ld (reset count=%d)", wc->node_id, wc->host ? wc->host->hostname : "N/A", wc->chart_sequence_id, - wc->chart_timestamp, wc->chart_reset_count); + if (sequence_id < wc->chart_sequence_id || + !sequence_id) { // || created_at != wc->chart_timestamp) { + log_access( + "ACLK REQ [%s (%s)]: CHART RESET from %" PRIu64 " t=%ld batch=%" PRIu64, + wc->node_id, + wc->host ? wc->host->hostname : "N/A", + wc->chart_sequence_id, + wc->chart_timestamp, + wc->batch_id); cmd.opcode = ACLK_DATABASE_RESET_CHART; cmd.param1 = sequence_id + 1; cmd.completion = NULL; aclk_database_enq_cmd(wc, &cmd); - } - else { - log_access("AC [%s (%s)]: Start streaming charts enabled -- last streamed sequence %"PRIu64 \ - " t=%ld (reset count=%d)", wc->node_id, wc->host ? wc->host->hostname : "N/A", wc->chart_sequence_id, - wc->chart_timestamp, wc->chart_reset_count); + } else { +// log_access( +// "ACLK RES [%s (%s)]: CHARTS STREAM from %" PRIu64 +// " t=%ld resets=%d", +// wc->node_id, +// wc->host ? wc->host->hostname : "N/A", +// wc->chart_sequence_id, +// wc->chart_timestamp, +// wc->chart_reset_count); wc->chart_reset_count = 0; wc->chart_updates = 1; } } - } - else - log_access("AC [%s (N/A)]: ACLK synchronization thread is not active.", node_id); + } else + log_access("ACLK STA [%s (N/A)]: ACLK synchronization thread is not active.", node_id); return; } host = host->next; @@ -761,7 +820,7 @@ static RRD_MEMORY_MODE sql_get_host_memory_mode(uuid_t *host_id) } while (sqlite3_step(res) == SQLITE_ROW) { - memory_mode = (RRD_MEMORY_MODE) sqlite3_column_int(res, 0); + memory_mode = (RRD_MEMORY_MODE)sqlite3_column_int(res, 0); } failed: @@ -771,11 +830,13 @@ failed: return memory_mode; } -#define SELECT_HOST_DIMENSION_LIST "SELECT d.dim_id, c.update_every, c.type||'.'||c.id, d.id, d.name FROM chart c, dimension d " \ - "WHERE d.chart_id = c.chart_id AND c.host_id = @host_id ORDER BY c.update_every ASC;" +#define SELECT_HOST_DIMENSION_LIST \ + "SELECT d.dim_id, c.update_every, c.type||'.'||c.id, d.id, d.name FROM chart c, dimension d " \ + "WHERE d.chart_id = c.chart_id AND c.host_id = @host_id ORDER BY c.update_every ASC;" -#define SELECT_HOST_CHART_LIST "SELECT distinct h.host_id, c.update_every, c.type||'.'||c.id FROM chart c, host h " \ - "WHERE c.host_id = h.host_id AND c.host_id = @host_id ORDER BY c.update_every ASC;" +#define SELECT_HOST_CHART_LIST \ + "SELECT distinct h.host_id, c.update_every, c.type||'.'||c.id FROM chart c, host h " \ + "WHERE c.host_id = h.host_id AND c.host_id = @host_id ORDER BY c.update_every ASC;" void aclk_update_retention(struct aclk_database_worker_config *wc, struct aclk_database_cmd cmd) { @@ -821,10 +882,12 @@ void aclk_update_retention(struct aclk_database_worker_config *wc, struct aclk_d goto failed; } - time_t start_time = LONG_MAX; - time_t first_entry_t; - time_t last_entry_t; + time_t start_time = LONG_MAX; + time_t first_entry_t; + time_t last_entry_t; uint32_t update_every = 0; + uint32_t dimension_update_count = 0; + int send_status; struct retention_updated rotate_data; @@ -840,11 +903,11 @@ void aclk_update_retention(struct aclk_database_worker_config *wc, struct aclk_d rotate_data.claim_id = claim_id; rotate_data.node_id = strdupz(wc->node_id); - // time_t now = now_realtime_sec(); + time_t now = now_realtime_sec(); while (sqlite3_step(res) == SQLITE_ROW) { - if (!update_every || update_every != (uint32_t) sqlite3_column_int(res, 1)) { + if (!update_every || update_every != (uint32_t)sqlite3_column_int(res, 1)) { if (update_every) { - debug(D_ACLK_SYNC,"Update %s for %u oldest time = %ld", wc->host_guid, update_every, start_time); + debug(D_ACLK_SYNC, "Update %s for %u oldest time = %ld", wc->host_guid, update_every, start_time); if (start_time == LONG_MAX) rotate_data.interval_durations[rotate_data.interval_duration_count].retention = 0; else @@ -852,13 +915,14 @@ void aclk_update_retention(struct aclk_database_worker_config *wc, struct aclk_d rotate_data.rotation_timestamp.tv_sec - start_time; rotate_data.interval_duration_count++; } - update_every = (uint32_t) sqlite3_column_int(res, 1); + update_every = (uint32_t)sqlite3_column_int(res, 1); rotate_data.interval_durations[rotate_data.interval_duration_count].update_every = update_every; start_time = LONG_MAX; } #ifdef ENABLE_DBENGINE if (memory_mode == RRD_MEMORY_MODE_DBENGINE) - rc = rrdeng_metric_latest_time_by_uuid((uuid_t *)sqlite3_column_blob(res, 0), &first_entry_t, &last_entry_t); + rc = + rrdeng_metric_latest_time_by_uuid((uuid_t *)sqlite3_column_blob(res, 0), &first_entry_t, &last_entry_t); else #endif { @@ -869,8 +933,7 @@ void aclk_update_retention(struct aclk_database_worker_config *wc, struct aclk_d first_entry_t = rrdset_first_entry_t(st); last_entry_t = rrdset_last_entry_t(st); } - } - else { + } else { rc = 0; first_entry_t = rotate_data.rotation_timestamp.tv_sec; } @@ -878,6 +941,24 @@ void aclk_update_retention(struct aclk_database_worker_config *wc, struct aclk_d if (likely(!rc && first_entry_t)) start_time = MIN(start_time, first_entry_t); + + if (memory_mode == RRD_MEMORY_MODE_DBENGINE && wc->chart_updates) { + int live = ((now - last_entry_t) < (RRDSET_MINIMUM_DIM_LIVE_MULTIPLIER * update_every)); + if ((!live || !first_entry_t) && (dimension_update_count < ACLK_MAX_DIMENSION_CLEANUP)) { + (void)aclk_upd_dimension_event( + wc, + claim_id, + (uuid_t *)sqlite3_column_blob(res, 0), + (const char *)(const char *)sqlite3_column_text(res, 3), + (const char *)(const char *)sqlite3_column_text(res, 4), + (const char *)(const char *)sqlite3_column_text(res, 2), + first_entry_t, + live ? 0 : last_entry_t, + &send_status); + if (!send_status) + dimension_update_count++; + } + } } if (update_every) { debug(D_ACLK_SYNC, "Update %s for %u oldest time = %ld", wc->host_guid, update_every, start_time); @@ -891,8 +972,12 @@ void aclk_update_retention(struct aclk_database_worker_config *wc, struct aclk_d #ifdef NETDATA_INTERNAL_CHECKS for (int i = 0; i < rotate_data.interval_duration_count; ++i) - info("Update for host %s (node %s) for %u Retention = %u", wc->host_guid, wc->node_id, - rotate_data.interval_durations[i].update_every, rotate_data.interval_durations[i].retention); + info( + "Update for host %s (node %s) for %u Retention = %u", + wc->host_guid, + wc->node_id, + rotate_data.interval_durations[i].update_every, + rotate_data.interval_durations[i].retention); #endif aclk_retention_updated(&rotate_data); freez(rotate_data.node_id); @@ -906,63 +991,60 @@ failed: return; } - uint32_t sql_get_pending_count(struct aclk_database_worker_config *wc) { - BUFFER *sql = buffer_create(1024); - sqlite3_stmt *res = NULL; + char sql[ACLK_SYNC_QUERY_SIZE]; + static __thread sqlite3_stmt *res = NULL; - buffer_sprintf(sql,"SELECT count(1) FROM aclk_chart_%s ac WHERE ac.date_submitted IS NULL;", wc->uuid_str); + snprintfz(sql,ACLK_SYNC_QUERY_SIZE-1, "SELECT count(1) FROM aclk_chart_%s ac WHERE ac.date_submitted IS NULL;", wc->uuid_str); int rc; uint32_t chart_payload_count = 0; - rc = sqlite3_prepare_v2(db_meta, buffer_tostring(sql), -1, &res, 0); - if (rc != SQLITE_OK) { - error_report("Failed to prepare statement to count pending messages"); - goto fail; + if (unlikely(!res)) { + rc = prepare_statement(db_meta, sql, &res); + if (rc != SQLITE_OK) { + error_report("Failed to prepare statement to count pending messages"); + return 0; + } } while (sqlite3_step(res) == SQLITE_ROW) chart_payload_count = (uint32_t) sqlite3_column_int(res, 0); - rc = sqlite3_finalize(res); + rc = sqlite3_reset(res); if (unlikely(rc != SQLITE_OK)) error_report("Failed to reset statement when fetching pending messages, rc = %d", rc); -fail: - buffer_free(sql); return chart_payload_count; } void sql_get_last_chart_sequence(struct aclk_database_worker_config *wc) { - BUFFER *sql = buffer_create(1024); + char sql[ACLK_SYNC_QUERY_SIZE]; - buffer_sprintf(sql,"SELECT ac.sequence_id, ac.date_created FROM aclk_chart_%s ac " \ - "WHERE ac.date_submitted IS NOT NULL ORDER BY ac.sequence_id DESC LIMIT 1;", wc->uuid_str); + snprintfz(sql,ACLK_SYNC_QUERY_SIZE-1, "SELECT ac.sequence_id, ac.date_created FROM aclk_chart_%s ac " \ + "WHERE ac.date_submitted IS NOT NULL ORDER BY ac.sequence_id DESC LIMIT 1;", wc->uuid_str); int rc; sqlite3_stmt *res = NULL; - rc = sqlite3_prepare_v2(db_meta, buffer_tostring(sql), -1, &res, 0); + rc = sqlite3_prepare_v2(db_meta, sql, -1, &res, 0); if (rc != SQLITE_OK) { error_report("Failed to prepare statement to find last chart sequence id"); - goto fail; + return; } wc->chart_sequence_id = 0; wc->chart_timestamp = 0; while (sqlite3_step(res) == SQLITE_ROW) { - wc->chart_sequence_id = (uint64_t) sqlite3_column_int64(res, 0); - wc->chart_timestamp = (time_t) sqlite3_column_int64(res, 1); + wc->chart_sequence_id = (uint64_t)sqlite3_column_int64(res, 0); + wc->chart_timestamp = (time_t)sqlite3_column_int64(res, 1); } - debug(D_ACLK_SYNC,"Node %s reports last sequence_id=%"PRIu64, wc->node_id, wc->chart_sequence_id); + debug(D_ACLK_SYNC, "Node %s reports last sequence_id=%" PRIu64, wc->node_id, wc->chart_sequence_id); rc = sqlite3_finalize(res); if (unlikely(rc != SQLITE_OK)) error_report("Failed to reset statement when fetching chart sequence info, rc = %d", rc); -fail: - buffer_free(sql); return; } @@ -973,6 +1055,184 @@ int queue_dimension_to_aclk(RRDDIM *rd) return rc; } +void aclk_send_dimension_update(RRDDIM *rd) +{ + if (!aclk_use_new_cloud_arch) + return; + + char *claim_id = is_agent_claimed(); + if (unlikely(!claim_id)) + return; + + time_t first_entry_t = rrddim_first_entry_t(rd); + time_t last_entry_t = rrddim_last_entry_t(rd); + + time_t now = now_realtime_sec(); + int live = ((now - rd->last_collected_time.tv_sec) < (RRDSET_MINIMUM_DIM_LIVE_MULTIPLIER * rd->update_every)); + + if (!live || rd->state->aclk_live_status != live || !first_entry_t) { + (void)aclk_upd_dimension_event( + rd->rrdset->rrdhost->dbsync_worker, + claim_id, + &rd->state->metric_uuid, + rd->id, + rd->name, + rd->rrdset->id, + first_entry_t, + live ? 0 : last_entry_t, + NULL); + + if (!first_entry_t) + debug( + D_ACLK_SYNC, + "%s: Update dimension chart=%s dim=%s live=%d (%ld, %ld)", + rd->rrdset->rrdhost->hostname, + rd->rrdset->name, + rd->name, + live, + first_entry_t, + last_entry_t); + else + debug( + D_ACLK_SYNC, + "%s: Update dimension chart=%s dim=%s live=%d (%ld, %ld) collected %ld seconds ago", + rd->rrdset->rrdhost->hostname, + rd->rrdset->name, + rd->name, + live, + first_entry_t, + last_entry_t, + now - last_entry_t); + rd->state->aclk_live_status = live; + } + + freez(claim_id); + return; +} + +#define SQL_SEQ_NULL(result, n) sqlite3_column_type(result, n) == SQLITE_NULL ? 0 : sqlite3_column_int64(result, n) + +struct aclk_chart_sync_stats *aclk_get_chart_sync_stats(RRDHOST *host) +{ + struct aclk_chart_sync_stats *aclk_statistics = NULL; + + struct aclk_database_worker_config *wc = NULL; + wc = (struct aclk_database_worker_config *)host->dbsync_worker; + if (!wc) + return NULL; + + aclk_statistics = callocz(1, sizeof(struct aclk_chart_sync_stats)); + + aclk_statistics->updates = wc->chart_updates; + aclk_statistics->batch_id = wc->batch_id; + + char host_uuid_fixed[GUID_LEN + 1]; + + strncpy(host_uuid_fixed, host->machine_guid, GUID_LEN); + host_uuid_fixed[GUID_LEN] = 0; + + host_uuid_fixed[8] = '_'; + host_uuid_fixed[13] = '_'; + host_uuid_fixed[18] = '_'; + host_uuid_fixed[23] = '_'; + + sqlite3_stmt *res = NULL; + BUFFER *sql = buffer_create(1024); + buffer_sprintf(sql, "SELECT min(sequence_id), max(sequence_id), 0 FROM aclk_chart_%s;", host_uuid_fixed); + buffer_sprintf(sql, "SELECT min(sequence_id), max(sequence_id), 0 FROM aclk_chart_%s WHERE date_submitted IS NULL;", host_uuid_fixed); + buffer_sprintf(sql, "SELECT min(sequence_id), max(sequence_id), 0 FROM aclk_chart_%s WHERE date_submitted IS NOT NULL;", host_uuid_fixed); + buffer_sprintf(sql, "SELECT min(sequence_id), max(sequence_id), 0 FROM aclk_chart_%s WHERE date_updated IS NOT NULL;", host_uuid_fixed); + buffer_sprintf(sql, "SELECT max(date_created), max(date_submitted), max(date_updated), 0 FROM aclk_chart_%s;", host_uuid_fixed); + + int rc = sqlite3_prepare_v2(db_meta, buffer_tostring(sql), -1, &res, 0); + if (rc != SQLITE_OK) { + buffer_free(sql); + freez(aclk_statistics); + return NULL; + } + + rc = sqlite3_step(res); + if (rc == SQLITE_ROW) { + aclk_statistics->min_seqid = SQL_SEQ_NULL(res, 0); + aclk_statistics->max_seqid = SQL_SEQ_NULL(res, 1); + } + + rc = sqlite3_step(res); + if (rc == SQLITE_ROW) { + aclk_statistics->min_seqid_pend = SQL_SEQ_NULL(res, 0); + aclk_statistics->max_seqid_pend = SQL_SEQ_NULL(res, 1); + } + + rc = sqlite3_step(res); + if (rc == SQLITE_ROW) { + aclk_statistics->min_seqid_sent = SQL_SEQ_NULL(res, 0); + aclk_statistics->max_seqid_sent = SQL_SEQ_NULL(res, 1); + } + + rc = sqlite3_step(res); + if (rc == SQLITE_ROW) { + aclk_statistics->min_seqid_ack = SQL_SEQ_NULL(res, 0); + aclk_statistics->max_seqid_ack = SQL_SEQ_NULL(res, 1); + } + + rc = sqlite3_step(res); + if (rc == SQLITE_ROW) { + aclk_statistics->min_seqid_ack = SQL_SEQ_NULL(res, 0); + aclk_statistics->max_seqid_ack = SQL_SEQ_NULL(res, 1); + } + + rc = sqlite3_step(res); + if (rc == SQLITE_ROW) { + aclk_statistics->max_date_created = (time_t) SQL_SEQ_NULL(res, 0); + aclk_statistics->max_date_submitted = (time_t) SQL_SEQ_NULL(res, 1); + aclk_statistics->max_date_ack = (time_t) SQL_SEQ_NULL(res, 2); + } + + rc = sqlite3_finalize(res); + if (unlikely(rc != SQLITE_OK)) + error_report("Failed to finalize statement when fetching aclk sync statistics, rc = %d", rc); + + buffer_free(sql); + return aclk_statistics; +} + +void sql_check_chart_liveness(RRDSET *st) { + RRDDIM *rd; + + if (unlikely(st->state->is_ar_chart)) + return; + + rrdset_rdlock(st); + if (unlikely(!rrdset_flag_check(st, RRDSET_FLAG_ACLK))) { + if (likely(st->dimensions && st->counter_done && !queue_chart_to_aclk(st))) { + debug(D_ACLK_SYNC,"Check chart liveness [%s] submit chart definition", st->name); + rrdset_flag_set(st, RRDSET_FLAG_ACLK); + } + } + else + debug(D_ACLK_SYNC,"Check chart liveness [%s] chart definition already submitted", st->name); + time_t mark = now_realtime_sec(); + + debug(D_ACLK_SYNC,"Check chart liveness [%s] scanning dimensions", st->name); + rrddim_foreach_read(rd, st) { + if (!rrddim_flag_check(rd, RRDDIM_FLAG_HIDDEN)) { + int live = (mark - rd->last_collected_time.tv_sec) < RRDSET_MINIMUM_DIM_LIVE_MULTIPLIER * rd->update_every; + if (unlikely(live != rd->state->aclk_live_status)) { + if (likely(rrdset_flag_check(st, RRDSET_FLAG_ACLK))) { + if (likely(!queue_dimension_to_aclk(rd))) { + debug(D_ACLK_SYNC,"Dimension change [%s] on [%s] from live %d --> %d", rd->id, rd->rrdset->name, rd->state->aclk_live_status, live); + rd->state->aclk_live_status = live; + rrddim_flag_set(rd, RRDDIM_FLAG_ACLK); + } + } + } + else + debug(D_ACLK_SYNC,"Dimension check [%s] on [%s] liveness matches", rd->id, st->name); + } + } + rrdset_unlock(st); +} + #endif //ENABLE_NEW_CLOUD_PROTOCOL // ST is read locked @@ -994,4 +1254,3 @@ int queue_chart_to_aclk(RRDSET *st) st, ACLK_DATABASE_ADD_CHART); #endif } - diff --git a/database/sqlite/sqlite_aclk_chart.h b/database/sqlite/sqlite_aclk_chart.h index 67d81a534..1d25de24e 100644 --- a/database/sqlite/sqlite_aclk_chart.h +++ b/database/sqlite/sqlite_aclk_chart.h @@ -12,10 +12,30 @@ typedef enum payload_type { extern sqlite3 *db_meta; -#ifndef RRDSET_MINIMUM_LIVE_COUNT -#define RRDSET_MINIMUM_LIVE_COUNT 3 +#ifndef RRDSET_MINIMUM_DIM_LIVE_MULTIPLIER +#define RRDSET_MINIMUM_DIM_LIVE_MULTIPLIER (3) #endif +#ifndef ACLK_MAX_DIMENSION_CLEANUP +#define ACLK_MAX_DIMENSION_CLEANUP (500) +#endif + +struct aclk_chart_sync_stats { + int updates; + uint64_t batch_id; + uint64_t min_seqid; + uint64_t max_seqid; + uint64_t min_seqid_pend; + uint64_t max_seqid_pend; + uint64_t min_seqid_sent; + uint64_t max_seqid_sent; + uint64_t min_seqid_ack; + uint64_t max_seqid_ack; + time_t max_date_created; + time_t max_date_submitted; + time_t max_date_ack; +}; + extern int queue_chart_to_aclk(RRDSET *st); extern int queue_dimension_to_aclk(RRDDIM *rd); extern void sql_create_aclk_table(RRDHOST *host, uuid_t *host_uuid, uuid_t *node_id); @@ -34,4 +54,7 @@ void aclk_receive_chart_reset(struct aclk_database_worker_config *wc, struct acl void aclk_receive_chart_ack(struct aclk_database_worker_config *wc, struct aclk_database_cmd cmd); void aclk_process_dimension_deletion(struct aclk_database_worker_config *wc, struct aclk_database_cmd cmd); uint32_t sql_get_pending_count(struct aclk_database_worker_config *wc); +void aclk_send_dimension_update(RRDDIM *rd); +struct aclk_chart_sync_stats *aclk_get_chart_sync_stats(RRDHOST *host); +void sql_check_chart_liveness(RRDSET *st); #endif //NETDATA_SQLITE_ACLK_CHART_H diff --git a/database/sqlite/sqlite_aclk_node.c b/database/sqlite/sqlite_aclk_node.c index 6261b9af5..97e6bebd1 100644 --- a/database/sqlite/sqlite_aclk_node.c +++ b/database/sqlite/sqlite_aclk_node.c @@ -17,16 +17,23 @@ void sql_build_node_info(struct aclk_database_worker_config *wc, struct aclk_dat if (!wc->host) return; - rrd_wrlock(); + rrd_rdlock(); node_info.node_id = wc->node_id; node_info.claim_id = is_agent_claimed(); node_info.machine_guid = wc->host_guid; node_info.child = (wc->host != localhost); - node_info.ml_info.ml_capable = localhost->system_info->ml_capable; - node_info.ml_info.ml_enabled = wc->host->ml_host != NULL; + node_info.ml_info.ml_capable = ml_capable(localhost); + node_info.ml_info.ml_enabled = ml_enabled(wc->host); now_realtime_timeval(&node_info.updated_at); RRDHOST *host = wc->host; + char *host_version = NULL; + if (host != localhost) { + netdata_mutex_lock(&host->receiver_lock); + host_version = + strdupz(host->receiver && host->receiver->program_version ? host->receiver->program_version : "unknown"); + netdata_mutex_unlock(&host->receiver_lock); + } node_info.data.name = host->hostname; node_info.data.os = (char *) host->os; @@ -35,15 +42,15 @@ void sql_build_node_info(struct aclk_database_worker_config *wc, struct aclk_dat node_info.data.kernel_name = host->system_info->kernel_name; node_info.data.kernel_version = host->system_info->kernel_version; node_info.data.architecture = host->system_info->architecture; - node_info.data.cpus = str2uint32_t(host->system_info->host_cores); - node_info.data.cpu_frequency = host->system_info->host_cpu_freq; - node_info.data.memory = host->system_info->host_ram_total; - node_info.data.disk_space = host->system_info->host_disk_space; - node_info.data.version = VERSION; + node_info.data.cpus = host->system_info->host_cores ? str2uint32_t(host->system_info->host_cores) : 0; + node_info.data.cpu_frequency = host->system_info->host_cpu_freq ? host->system_info->host_cpu_freq : "0"; + node_info.data.memory = host->system_info->host_ram_total ? host->system_info->host_ram_total : "0"; + node_info.data.disk_space = host->system_info->host_disk_space ? host->system_info->host_disk_space : "0"; + node_info.data.version = host_version ? host_version : VERSION; node_info.data.release_channel = "nightly"; node_info.data.timezone = (char *) host->abbrev_timezone; - node_info.data.virtualization_type = host->system_info->virtualization; - node_info.data.container_type = host->system_info->container; + node_info.data.virtualization_type = host->system_info->virtualization ? host->system_info->virtualization : "unknown"; + node_info.data.container_type = host->system_info->container ? host->system_info->container : "unknown"; node_info.data.custom_info = config_get(CONFIG_SECTION_WEB, "custom dashboard_info.js", ""); node_info.data.services = NULL; // char ** node_info.data.service_count = 0; @@ -56,11 +63,12 @@ void sql_build_node_info(struct aclk_database_worker_config *wc, struct aclk_dat node_info.data.host_labels_head = labels->head; aclk_update_node_info(&node_info); - log_access("OG [%s (%s)]: Sending node info for guid [%s] (%s).", wc->node_id, wc->host->hostname, wc->host_guid, wc->host == localhost ? "parent" : "child"); + log_access("ACLK RES [%s (%s)]: NODE INFO SENT for guid [%s] (%s)", wc->node_id, wc->host->hostname, wc->host_guid, wc->host == localhost ? "parent" : "child"); netdata_rwlock_unlock(&labels->labels_rwlock); rrd_unlock(); freez(node_info.claim_id); + freez(host_version); #else UNUSED(wc); #endif diff --git a/database/sqlite/sqlite_functions.c b/database/sqlite/sqlite_functions.c index d5afdb6ee..1e1d2a741 100644 --- a/database/sqlite/sqlite_functions.c +++ b/database/sqlite/sqlite_functions.c @@ -2,6 +2,8 @@ #include "sqlite_functions.h" +#define DB_METADATA_VERSION "1" + const char *database_config[] = { "PRAGMA auto_vacuum=incremental; PRAGMA synchronous=1 ; PRAGMA journal_mode=WAL; PRAGMA temp_store=MEMORY;", "PRAGMA journal_size_limit=16777216;", @@ -40,6 +42,9 @@ const char *database_config[] = { "CREATE VIEW IF NOT EXISTS v_chart_hash as SELECT ch.*, chm.chart_id FROM chart_hash ch, chart_hash_map chm " "WHERE ch.hash_id = chm.hash_id;", + "CREATE TRIGGER IF NOT EXISTS ins_host AFTER INSERT ON host BEGIN INSERT INTO node_instance (host_id, date_created)" + " SELECT new.host_id, strftime(\"%s\") WHERE new.host_id NOT IN (SELECT host_id FROM node_instance); END;", + "CREATE TRIGGER IF NOT EXISTS tr_v_chart_hash INSTEAD OF INSERT on v_chart_hash BEGIN " "INSERT INTO chart_hash (hash_id, type, id, name, family, context, title, unit, plugin, " "module, priority, chart_type, last_used) " @@ -49,6 +54,7 @@ const char *database_config[] = { "INSERT INTO chart_hash_map (chart_id, hash_id) values (new.chart_id, new.hash_id) " "on conflict (chart_id, hash_id) do nothing; END; ", + "PRAGMA user_version="DB_METADATA_VERSION";", NULL }; @@ -115,7 +121,7 @@ static int store_active_uuid_object(sqlite3_stmt **res, char *statement, uuid_t // Check if we should need to prepare the statement if (!*res) { - rc = sqlite3_prepare_v2(db_meta, statement, -1, res, 0); + rc = prepare_statement(db_meta, statement, res); if (unlikely(rc != SQLITE_OK)) { error_report("Failed to prepare statement to store active object, rc = %d", rc); return rc; @@ -136,7 +142,7 @@ static int store_active_uuid_object(sqlite3_stmt **res, char *statement, uuid_t */ void store_active_chart(uuid_t *chart_uuid) { - sqlite3_stmt *res = NULL; + static __thread sqlite3_stmt *res = NULL; int rc; if (unlikely(!db_meta)) { @@ -152,7 +158,7 @@ void store_active_chart(uuid_t *chart_uuid) if (rc != SQLITE_DONE) error_report("Failed to store active chart, rc = %d", rc); - rc = sqlite3_finalize(res); + rc = sqlite3_reset(res); if (unlikely(rc != SQLITE_OK)) error_report("Failed to finalize statement in store active chart, rc = %d", rc); return; @@ -164,7 +170,7 @@ void store_active_chart(uuid_t *chart_uuid) */ void store_active_dimension(uuid_t *dimension_uuid) { - sqlite3_stmt *res = NULL; + static __thread sqlite3_stmt *res = NULL; int rc; if (unlikely(!db_meta)) { @@ -180,7 +186,7 @@ void store_active_dimension(uuid_t *dimension_uuid) if (rc != SQLITE_DONE) error_report("Failed to store active dimension, rc = %d", rc); - rc = sqlite3_finalize(res); + rc = sqlite3_reset(res); if (unlikely(rc != SQLITE_OK)) error_report("Failed to finalize statement in store active dimension, rc = %d", rc); return; @@ -905,6 +911,49 @@ bind_fail: return 1; } +/* + * Store set option for a dimension + */ +int sql_set_dimension_option(uuid_t *dim_uuid, char *option) +{ + sqlite3_stmt *res = NULL; + int rc; + + if (unlikely(!db_meta)) { + if (default_rrd_memory_mode != RRD_MEMORY_MODE_DBENGINE) + return 0; + error_report("Database has not been initialized"); + return 1; + } + + rc = sqlite3_prepare_v2(db_meta, "UPDATE dimension SET options = @options WHERE dim_id = @dim_id", -1, &res, 0); + if (unlikely(rc != SQLITE_OK)) { + error_report("Failed to prepare statement to update dimension options"); + return 0; + }; + + rc = sqlite3_bind_blob(res, 2, dim_uuid, sizeof(*dim_uuid), SQLITE_STATIC); + if (unlikely(rc != SQLITE_OK)) + goto bind_fail; + + if (!option || !strcmp(option,"unhide")) + rc = sqlite3_bind_null(res, 1); + else + rc = sqlite3_bind_text(res, 1, option, -1, SQLITE_STATIC); + if (unlikely(rc != SQLITE_OK)) + goto bind_fail; + + rc = execute_insert(res); + if (unlikely(rc != SQLITE_DONE)) + error_report("Failed to update dimension option, rc = %d", rc); + +bind_fail: + rc = sqlite3_finalize(res); + if (unlikely(rc != SQLITE_OK)) + error_report("Failed to finalize statement in update dimension options, rc = %d", rc); + return 0; +} + // // Support for archived charts @@ -1286,7 +1335,7 @@ void add_migrated_file(char *path, uint64_t file_size) void sql_store_chart_label(uuid_t *chart_uuid, int source_type, char *label, char *value) { - sqlite3_stmt *res = NULL; + static __thread sqlite3_stmt *res = NULL; int rc; if (unlikely(!db_meta)) { @@ -1295,10 +1344,12 @@ void sql_store_chart_label(uuid_t *chart_uuid, int source_type, char *label, cha return; } - rc = sqlite3_prepare_v2(db_meta, SQL_INS_CHART_LABEL, -1, &res, 0); - if (unlikely(rc != SQLITE_OK)) { - error_report("Failed to prepare statement store chart labels"); - return; + if (unlikely(!res)) { + rc = prepare_statement(db_meta, SQL_INS_CHART_LABEL, &res); + if (unlikely(rc != SQLITE_OK)) { + error_report("Failed to prepare statement store chart labels"); + return; + } } rc = sqlite3_bind_blob(res, 1, chart_uuid, sizeof(*chart_uuid), SQLITE_STATIC); @@ -1330,8 +1381,8 @@ void sql_store_chart_label(uuid_t *chart_uuid, int source_type, char *label, cha error_report("Failed to store chart label entry, rc = %d", rc); failed: - if (unlikely(sqlite3_finalize(res) != SQLITE_OK)) - error_report("Failed to finalize the prepared statement when storing chart label information"); + if (unlikely(sqlite3_reset(res) != SQLITE_OK)) + error_report("Failed to reset the prepared statement when storing chart label information"); return; } @@ -1402,12 +1453,14 @@ static RRDDIM *create_rrdim_entry(RRDSET *st, char *id, char *name, uuid_t *metr } #endif -#define SELECT_CHART_CONTEXT "select d.dim_id, d.id, d.name, c.id, c.type, c.name, c.update_every, c.chart_id from chart c, " \ +#define SELECT_CHART_CONTEXT "select d.dim_id, d.id, d.name, c.id, c.type, c.name, c.update_every, c.chart_id, " \ + "c.context, CASE WHEN d.options = 'hidden' THEN 1 else 0 END from chart c, " \ "dimension d, host h " \ "where d.chart_id = c.chart_id and c.host_id = h.host_id and c.host_id = @host_id and c.context = @context " \ "order by c.chart_id asc, c.type||c.id desc;" -#define SELECT_CHART_SINGLE "select d.dim_id, d.id, d.name, c.id, c.type, c.name, c.update_every, c.chart_id, c.context from chart c, " \ +#define SELECT_CHART_SINGLE "select d.dim_id, d.id, d.name, c.id, c.type, c.name, c.update_every, c.chart_id, " \ + "c.context, CASE WHEN d.options = 'hidden' THEN 1 else 0 END from chart c, " \ "dimension d, host h " \ "where d.chart_id = c.chart_id and c.host_id = h.host_id and c.host_id = @host_id and c.type||'.'||c.id = @chart " \ "order by c.chart_id asc, c.type||'.'||c.id desc;" @@ -1501,6 +1554,8 @@ void sql_build_context_param_list(struct context_param **param_list, RRDHOST *ho st->last_entry_t = MAX(st->last_entry_t, (*param_list)->last_entry_t); RRDDIM *rd = create_rrdim_entry(st, (char *)sqlite3_column_text(res, 1), (char *)sqlite3_column_text(res, 2), &rrdeng_uuid); + if (sqlite3_column_int(res, 9) == 1) + rrddim_flag_set(rd, RRDDIM_FLAG_HIDDEN); rd->next = (*param_list)->rd; (*param_list)->rd = rd; } @@ -1828,25 +1883,75 @@ failed: return rc - 1; } -#define SQL_SELECT_HOST_BY_NODE_ID "select host_id from node_instance where node_id = @node_id;" +#define SQL_SELECT_HOSTNAME_BY_NODE_ID "SELECT h.hostname FROM node_instance ni, " \ +"host h WHERE ni.host_id = h.host_id AND ni.node_id = @node_id;" -int get_host_id(uuid_t *node_id, uuid_t *host_id) +char *get_hostname_by_node_id(char *node) { sqlite3_stmt *res = NULL; + char *hostname = NULL; int rc; + rrd_rdlock(); + RRDHOST *host = find_host_by_node_id(node); + rrd_unlock(); + if (host) + return strdupz(host->hostname); + if (unlikely(!db_meta)) { if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) error_report("Database has not been initialized"); - return 1; + return NULL; + } + + uuid_t node_id; + if (uuid_parse(node, node_id)) + return NULL; + + rc = sqlite3_prepare_v2(db_meta, SQL_SELECT_HOSTNAME_BY_NODE_ID, -1, &res, 0); + if (unlikely(rc != SQLITE_OK)) { + error_report("Failed to prepare statement to fetch hostname by node id"); + return NULL; } - rc = sqlite3_prepare_v2(db_meta, SQL_SELECT_HOST_BY_NODE_ID, -1, &res, 0); + rc = sqlite3_bind_blob(res, 1, &node_id, sizeof(node_id), SQLITE_STATIC); if (unlikely(rc != SQLITE_OK)) { - error_report("Failed to prepare statement to select node instance information for a node"); + error_report("Failed to bind host_id parameter to select node instance information"); + goto failed; + } + + rc = sqlite3_step(res); + if (likely(rc == SQLITE_ROW)) + hostname = strdupz((char *)sqlite3_column_text(res, 0)); + +failed: + if (unlikely(sqlite3_finalize(res) != SQLITE_OK)) + error_report("Failed to finalize the prepared statement when search for hostname by node id"); + + return hostname; +} + +#define SQL_SELECT_HOST_BY_NODE_ID "select host_id from node_instance where node_id = @node_id;" + +int get_host_id(uuid_t *node_id, uuid_t *host_id) +{ + static __thread sqlite3_stmt *res = NULL; + int rc; + + if (unlikely(!db_meta)) { + if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) + error_report("Database has not been initialized"); return 1; } + if (unlikely(!res)) { + rc = prepare_statement(db_meta, SQL_SELECT_HOST_BY_NODE_ID, &res); + if (unlikely(rc != SQLITE_OK)) { + error_report("Failed to prepare statement to select node instance information for a node"); + return 1; + } + } + rc = sqlite3_bind_blob(res, 1, node_id, sizeof(*node_id), SQLITE_STATIC); if (unlikely(rc != SQLITE_OK)) { error_report("Failed to bind host_id parameter to select node instance information"); @@ -1858,8 +1963,8 @@ int get_host_id(uuid_t *node_id, uuid_t *host_id) uuid_copy(*host_id, *((uuid_t *) sqlite3_column_blob(res, 0))); failed: - if (unlikely(sqlite3_finalize(res) != SQLITE_OK)) - error_report("Failed to finalize the prepared statement when selecting node instance information"); + if (unlikely(sqlite3_reset(res) != SQLITE_OK)) + error_report("Failed to reset the prepared statement when selecting node instance information"); return (rc == SQLITE_ROW) ? 0 : -1; } @@ -1978,7 +2083,7 @@ struct node_instance_list *get_node_list(void) node_list = callocz(row + 1, sizeof(*node_list)); int max_rows = row; row = 0; - rrd_wrlock(); + rrd_rdlock(); while (sqlite3_step(res) == SQLITE_ROW) { if (sqlite3_column_bytes(res, 0) == sizeof(uuid_t)) uuid_copy(node_list[row].node_id, *((uuid_t *)sqlite3_column_blob(res, 0))); @@ -2011,7 +2116,7 @@ failed: void sql_load_node_id(RRDHOST *host) { - sqlite3_stmt *res = NULL; + static __thread sqlite3_stmt *res = NULL; int rc; if (unlikely(!db_meta)) { @@ -2020,11 +2125,13 @@ void sql_load_node_id(RRDHOST *host) return; } - rc = sqlite3_prepare_v2(db_meta, SQL_GET_HOST_NODE_ID, -1, &res, 0); - if (unlikely(rc != SQLITE_OK)) { - error_report("Failed to prepare statement to fetch node id"); - return; - }; + if (unlikely(!res)) { + rc = prepare_statement(db_meta, SQL_GET_HOST_NODE_ID, &res); + if (unlikely(rc != SQLITE_OK)) { + error_report("Failed to prepare statement to fetch node id"); + return; + }; + } rc = sqlite3_bind_blob(res, 1, &host->host_uuid, sizeof(host->host_uuid), SQLITE_STATIC); if (unlikely(rc != SQLITE_OK)) { @@ -2041,8 +2148,8 @@ void sql_load_node_id(RRDHOST *host) } failed: - if (unlikely(sqlite3_finalize(res) != SQLITE_OK)) - error_report("Failed to finalize the prepared statement when loading node instance information"); + if (unlikely(sqlite3_reset(res) != SQLITE_OK)) + error_report("Failed to reset the prepared statement when loading node instance information"); return; }; diff --git a/database/sqlite/sqlite_functions.h b/database/sqlite/sqlite_functions.h index 3e41f6aaa..30b8dee6c 100644 --- a/database/sqlite/sqlite_functions.h +++ b/database/sqlite/sqlite_functions.h @@ -98,4 +98,6 @@ extern void invalidate_node_instances(uuid_t *host_id, uuid_t *claim_id); extern struct node_instance_list *get_node_list(void); extern void sql_load_node_id(RRDHOST *host); extern void compute_chart_hash(RRDSET *st); +extern int sql_set_dimension_option(uuid_t *dim_uuid, char *option); +char *get_hostname_by_node_id(char *node_id); #endif //NETDATA_SQLITE_FUNCTIONS_H diff --git a/database/sqlite/sqlite_health.c b/database/sqlite/sqlite_health.c index 27c67c3aa..8ba95628f 100644 --- a/database/sqlite/sqlite_health.c +++ b/database/sqlite/sqlite_health.c @@ -900,7 +900,8 @@ int sql_store_alert_config_hash(uuid_t *hash_id, struct alert_config *cfg) #endif int alert_hash_and_store_config( uuid_t hash_id, - struct alert_config *cfg) + struct alert_config *cfg, + int store_hash) { #if !defined DISABLE_CLOUD && defined ENABLE_HTTPS EVP_MD_CTX *evpctx; @@ -946,10 +947,12 @@ int alert_hash_and_store_config( uuid_copy(hash_id, *((uuid_t *)&hash_value)); /* store everything, so it can be recreated when not in memory or just a subset ? */ - (void)sql_store_alert_config_hash( (uuid_t *)&hash_value, cfg); + if (store_hash) + (void)sql_store_alert_config_hash( (uuid_t *)&hash_value, cfg); #else UNUSED(hash_id); UNUSED(cfg); + UNUSED(store_hash); #endif return 1; diff --git a/database/sqlite/sqlite_health.h b/database/sqlite/sqlite_health.h index 3b9460897..ef837894a 100644 --- a/database/sqlite/sqlite_health.h +++ b/database/sqlite/sqlite_health.h @@ -12,6 +12,6 @@ extern void sql_health_alarm_log_update(RRDHOST *host, ALARM_ENTRY *ae); extern void sql_health_alarm_log_insert(RRDHOST *host, ALARM_ENTRY *ae); extern void sql_health_alarm_log_save(RRDHOST *host, ALARM_ENTRY *ae); extern void sql_health_alarm_log_cleanup(RRDHOST *host); -extern int alert_hash_and_store_config(uuid_t hash_id, struct alert_config *cfg); +extern int alert_hash_and_store_config(uuid_t hash_id, struct alert_config *cfg, int store_hash); extern void sql_aclk_alert_clean_dead_entries(RRDHOST *host); #endif //NETDATA_SQLITE_HEALTH_H diff --git a/diagrams/data_structures/README.md b/diagrams/data_structures/README.md index 27705c548..12ea1afa2 100644 --- a/diagrams/data_structures/README.md +++ b/diagrams/data_structures/README.md @@ -15,4 +15,4 @@ These are the main internal data structures of `netdata`. Created with `draw.io` ![Web](https://raw.githubusercontent.com/netdata/netdata/master/diagrams/data_structures/web.svg?sanitize=true) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdiagrams%2Fdata_structures%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/Add-more-charts-to-netdata.md b/docs/Add-more-charts-to-netdata.md index 44aa1abad..6090644e3 100644 --- a/docs/Add-more-charts-to-netdata.md +++ b/docs/Add-more-charts-to-netdata.md @@ -11,5 +11,3 @@ This file has been deprecated. Please see our [collectors docs](/collectors/READ See the [list of supported collectors](/collectors/COLLECTORS.md) to see all the sources Netdata can collect metrics from. - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2FAdd-more-charts-to-netdata&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]() diff --git a/docs/Demo-Sites.md b/docs/Demo-Sites.md index 5c0369c15..e6e8eb3dc 100644 --- a/docs/Demo-Sites.md +++ b/docs/Demo-Sites.md @@ -22,4 +22,4 @@ You can also view live demos of Netdata at **[https://www.netdata.cloud](https:/ Netdata dashboards are mobile- and touch-friendly. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2FDemo-Sites&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/Donations-netdata-has-received.md b/docs/Donations-netdata-has-received.md index df6c040ba..a8623c5db 100644 --- a/docs/Donations-netdata-has-received.md +++ b/docs/Donations-netdata-has-received.md @@ -26,4 +26,4 @@ Thank you! Please contact me at costa@tsaousis.gr. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2FDonations-netdata-has-received&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/README.md b/docs/README.md index 47950f388..e3b915617 100644 --- a/docs/README.md +++ b/docs/README.md @@ -14,4 +14,4 @@ perfect. Now get out there and build an exceptional infrastructure. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/Running-behind-apache.md b/docs/Running-behind-apache.md index de95f55ea..989c51fc7 100644 --- a/docs/Running-behind-apache.md +++ b/docs/Running-behind-apache.md @@ -368,4 +368,4 @@ Make sure the requests reach Netdata, by examining `/var/log/netdata/access.log` 1. if the requests do not reach Netdata, your apache does not forward them. 2. if the requests reach Netdata but the URLs are wrong, you have not re-written them properly. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2FRunning-behind-apache&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/Running-behind-caddy.md b/docs/Running-behind-caddy.md index a20fd0535..0282d0750 100644 --- a/docs/Running-behind-caddy.md +++ b/docs/Running-behind-caddy.md @@ -31,4 +31,4 @@ You would also need to instruct Netdata to listen only to `127.0.0.1` or `::1`. To limit access to Netdata only from localhost, set `bind socket to IP = 127.0.0.1` or `bind socket to IP = ::1` in `/etc/netdata/netdata.conf`. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2FRunning-behind-caddy&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/Running-behind-haproxy.md b/docs/Running-behind-haproxy.md index d4b09f85c..ee1790cfe 100644 --- a/docs/Running-behind-haproxy.md +++ b/docs/Running-behind-haproxy.md @@ -6,7 +6,7 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/docs/Running-beh # Netdata via HAProxy > HAProxy is a free, very fast and reliable solution offering high availability, load balancing, -> and proxying for TCP and HTTP-based applications. It is particularly suited for very high traffic web sites +> and proxying for TCP and HTTP-based applications. It is particularly suited for very high traffic websites > and powers quite a number of the world's most visited ones. If Netdata is running on a host running HAProxy, rather than connecting to Netdata from a port number, a domain name can @@ -59,7 +59,7 @@ backend netdata_backend ## Configuration with subpath -A example where the base URL is used with a subpath `/netdata/`: +An example where the base URL is used with a subpath `/netdata/`: ### Frontend @@ -290,4 +290,4 @@ backend netdata_backend http-request set-header Connection "keep-alive" ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2FRunning-behind-haproxy&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/Running-behind-lighttpd.md b/docs/Running-behind-lighttpd.md index 1e86f334f..2623560e1 100644 --- a/docs/Running-behind-lighttpd.md +++ b/docs/Running-behind-lighttpd.md @@ -68,4 +68,4 @@ You would also need to instruct Netdata to listen only to `127.0.0.1` or `::1`. To limit access to Netdata only from localhost, set `bind socket to IP = 127.0.0.1` or `bind socket to IP = ::1` in `/etc/netdata/netdata.conf`. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2FRunning-behind-lighttpd&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/Running-behind-nginx.md b/docs/Running-behind-nginx.md index 83720039e..0cb16309a 100644 --- a/docs/Running-behind-nginx.md +++ b/docs/Running-behind-nginx.md @@ -267,4 +267,4 @@ If you get an 502 Bad Gateway error you might check your Nginx error log: If you see something like the above, chances are high that SELinux prevents nginx from connecting to the backend server. To fix that, just use this policy: `setsebool -P httpd_can_network_connect true`. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2FRunning-behind-nginx&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/a-github-star-is-important.md b/docs/a-github-star-is-important.md index d309d3928..22659ea6f 100644 --- a/docs/a-github-star-is-important.md +++ b/docs/a-github-star-is-important.md @@ -21,4 +21,4 @@ Thank you! Costa Tsaousis -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fa-github-star-is-important&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/agent-cloud.md b/docs/agent-cloud.md index fcec10af8..ed54325c3 100644 --- a/docs/agent-cloud.md +++ b/docs/agent-cloud.md @@ -75,5 +75,3 @@ about how you might want to use or configure Cloud, we recommend the following: onboarding and connect your first nodes. - Better understand how agents connect securely to the Cloud with [connect agent to Cloud](/claim/README.md) and [Agent-Cloud link](/aclk/README.md) documentation. - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fagent-cloud&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]() diff --git a/docs/anonymous-statistics.md b/docs/anonymous-statistics.md index 82c018e1b..73ac8e978 100644 --- a/docs/anonymous-statistics.md +++ b/docs/anonymous-statistics.md @@ -8,8 +8,7 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/docs/anonymous-s # Anonymous statistics By default, Netdata collects anonymous usage information from the open-source monitoring agent using the open-source -product analytics platform [PostHog](https://github.com/PostHog/posthog). We self-host our PostHog instance, which means -your data is never sent or processed by any third parties outside of the Netdata infrastructure. +product analytics platform [PostHog](https://github.com/PostHog/posthog). We use their [cloud enterprise platform](https://posthog.com/product). We are strongly committed to your [data privacy](https://netdata.cloud/data-privacy/). @@ -86,11 +85,11 @@ installation, including manual, offline, and macOS installations. Create the fil **Pass the option `--disable-telemetry` to any of the installer scripts in the [installation docs](/packaging/installer/README.md).** You can append this option during the initial installation or a manual -update. You can also export the environment variable `DO_NOT_TRACK` with a non-zero or non-empty value -(e.g: `export DO_NOT_TRACK=1`). +update. You can also export the environment variable `DISABLE_TELEMETRY` with a non-zero or non-empty value +(e.g: `export DISABLE_TELEMETRY=1`). -When using Docker, **set your `DO_NOT_TRACK` environment variable to `1`.** You can set this variable with the following -command: `export DO_NOT_TRACK=1`. When creating a container using Netdata's [Docker +When using Docker, **set your `DISABLE_TELEMETRY` environment variable to `1`.** You can set this variable with the following +command: `export DISABLE_TELEMETRY=1`. When creating a container using Netdata's [Docker image](/packaging/docker/README.md#create-a-new-netdata-agent-container) for the first time, this variable will disable the anonymous statistics script inside of the container. @@ -98,7 +97,7 @@ Each of these opt-out processes does the following: - Prevents the daemon from executing the anonymous statistics script. - Forces the anonymous statistics script to exit immediately. -- Stops the PostHog Javascript snippet, which remains on the dashboard, from firing and sending any data to the Netdata PostHog. +- Stops the PostHog JavaScript snippet, which remains on the dashboard, from firing and sending any data to the Netdata PostHog. ## Migration from Google Analytics and Google Tag Manager. @@ -106,4 +105,3 @@ Prior to v1.29.4 we used Google Analytics to capture this information. This led While we migrate fully away from Google Analytics to PostHog there maybe be a small period of time where we run both in parallel before we remove all Google Analytics related code. This is to ensure we can fully test and validate the Netdata PostHog implementation before fully defaulting to it. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fanonymous-statistics&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]() diff --git a/docs/collect/application-metrics.md b/docs/collect/application-metrics.md index 4fb9ed6ab..5af58b105 100644 --- a/docs/collect/application-metrics.md +++ b/docs/collect/application-metrics.md @@ -77,4 +77,4 @@ Collecting all the available metrics on your nodes, and across your entire infra puzzle. Next, learn more about Netdata's famous real-time visualizations by [seeing an overview of your infrastructure](/docs/visualize/overview-infrastructure.md) using Netdata Cloud. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fcollect%2Fapplication-metrics&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/collect/container-metrics.md b/docs/collect/container-metrics.md index b5bb9da01..5d145362e 100644 --- a/docs/collect/container-metrics.md +++ b/docs/collect/container-metrics.md @@ -96,4 +96,4 @@ brokers, and more. See more in the [application metrics doc](/docs/collect/appli If you already have all the information you need about collecting metrics, move into Netdata's meaningful visualizations with [seeing an overview of your infrastructure](/docs/visualize/overview-infrastructure.md) using Netdata Cloud. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fcollect%2Fcontainer-metrics&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/collect/enable-configure.md b/docs/collect/enable-configure.md index 584d23715..19e680c21 100644 --- a/docs/collect/enable-configure.md +++ b/docs/collect/enable-configure.md @@ -65,4 +65,4 @@ Netdata's visualization features. [See an overview of your infrastructure](/docs using Netdata Cloud, or learn how to [interact with dashboards and charts](/docs/visualize/interact-dashboards-charts.md). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fcollect%2Fenable-configure&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/collect/how-collectors-work.md b/docs/collect/how-collectors-work.md index b4a6c8796..983de35a8 100644 --- a/docs/collect/how-collectors-work.md +++ b/docs/collect/how-collectors-work.md @@ -77,4 +77,4 @@ your infrastructure. See our [collectors reference](/collectors/REFERENCE.md) for detailed information on Netdata's collector architecture, troubleshooting a collector, developing a custom collector, and more. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fcollect%2Fhow-collectors-work&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/collect/system-metrics.md b/docs/collect/system-metrics.md index 14e2cc2aa..623302894 100644 --- a/docs/collect/system-metrics.md +++ b/docs/collect/system-metrics.md @@ -63,4 +63,4 @@ should investigate Netdata's container compatibility if you use them heavily in If you don't use containers, skip ahead to collecting [application metrics](/docs/collect/application-metrics.md) with Netdata. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fcollect%2Fsystem-metrics&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/configure/nodes.md b/docs/configure/nodes.md index 8399e89d9..02cf6f052 100644 --- a/docs/configure/nodes.md +++ b/docs/configure/nodes.md @@ -19,7 +19,7 @@ anomaly, or change in infrastructure affects how their Agents should perform. ## The Netdata config directory On most Linux systems, using our [recommended one-line -installation](/docs/get-started.mdx#install-on-linux-with-one-line-installer-recommended), the **Netdata config +installation](/docs/get-started.mdx#install-on-linux-with-one-line-installer), the **Netdata config directory** is `/etc/netdata/`. The config directory contains several configuration files with the `.conf` extension, a few directories, and a shell script named `edit-config`. diff --git a/docs/contributing/contributing-documentation.md b/docs/contributing/contributing-documentation.md index 76fc609d5..68b861d40 100644 --- a/docs/contributing/contributing-documentation.md +++ b/docs/contributing/contributing-documentation.md @@ -106,4 +106,4 @@ specific sections and ask for additional information or other fixes. After merging your PR, the Netdata team rebuilds the [documentation site](https://learn.netdata.cloud) to publish the changed documentation. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fcontributing%2Fcontributing-documentation&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/contributing/style-guide.md b/docs/contributing/style-guide.md index 025b45f64..2af58d54a 100644 --- a/docs/contributing/style-guide.md +++ b/docs/contributing/style-guide.md @@ -489,4 +489,4 @@ The following tables describe the standard spelling, capitalization, and usage o | **preconfigured** | The concept that many of Netdata's features come with sane defaults that users don't need to configure to find [immediate value](/docs/overview/why-netdata.md#simple-to-deploy). | | **real time**/**real-time** | Use _real time_ as a noun phrase, most often with _in_: _Netdata collects metrics in real time_. Use _real-time_ as an adjective: _Netdata collects real-time metrics from hundreds of supported applications and services. | -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fcontributing%2Fstyle-guide&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/export/enable-connector.md b/docs/export/enable-connector.md index 1ddecfd2c..a914a114a 100644 --- a/docs/export/enable-connector.md +++ b/docs/export/enable-connector.md @@ -92,4 +92,4 @@ labels](/docs/guides/using-host-labels.md) on exported metrics. - [OpenTSDB connector](/exporting/opentsdb/README.md) - [Graphite connector](/exporting/graphite/README.md) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fexporting%2Fenable-connector&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/export/external-databases.md b/docs/export/external-databases.md index 6f7f488b6..a542e8ee7 100644 --- a/docs/export/external-databases.md +++ b/docs/export/external-databases.md @@ -85,6 +85,5 @@ Graphite_](/docs/guides/export/export-netdata-metrics-graphite.md). ### Related reference documentation - [Exporting engine reference](/exporting/README.md) -- [Backends reference (deprecated)](/backends/README.md) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fexporting%2Fexternal-databases&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/collect-apache-nginx-web-logs.md b/docs/guides/collect-apache-nginx-web-logs.md index 1ffa9d3b6..0298e1d43 100644 --- a/docs/guides/collect-apache-nginx-web-logs.md +++ b/docs/guides/collect-apache-nginx-web-logs.md @@ -159,4 +159,4 @@ into powerful real-time tools for keeping your servers happy. Don't forget to give GitHub user [Wing924](https://github.com/Wing924) a big 👍 for his hard work in starting up the Go refactoring effort. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fcollect-apache-nginx-web-logs&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/collect-unbound-metrics.md b/docs/guides/collect-unbound-metrics.md index 5709c872c..8edcab102 100644 --- a/docs/guides/collect-unbound-metrics.md +++ b/docs/guides/collect-unbound-metrics.md @@ -137,4 +137,4 @@ for improvement or refinement based on real-world use cases. Feel free to [file issue](https://github.com/netdata/netdata/issues/new?assignees=&labels=bug%2Cneeds+triage&template=BUG_REPORT.yml) with your thoughts. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Funbound-metrics&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/deploy/ansible.md b/docs/guides/deploy/ansible.md index f7bf514e2..7e5532b62 100644 --- a/docs/guides/deploy/ansible.md +++ b/docs/guides/deploy/ansible.md @@ -171,4 +171,4 @@ provisioning/infrastructure as code software, such as Chef or Puppet, in our [co repo](https://github.com/netdata/community). Anyone is able to fork the repo and submit a PR, either to improve this playbook, extend it, or create an entirely new experience for deploying Netdata across entire infrastructure. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fdeploy%2Fansible.md&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/export/export-netdata-metrics-graphite.md b/docs/guides/export/export-netdata-metrics-graphite.md index 37d2fdb50..007c30f8b 100644 --- a/docs/guides/export/export-netdata-metrics-graphite.md +++ b/docs/guides/export/export-netdata-metrics-graphite.md @@ -180,4 +180,4 @@ often. For full details about each configuration option and what it does, see the [exporting reference guide](/exporting/README.md). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fexport%2Fexport-netdata-metrics-graphite.md&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/longer-metrics-storage.md b/docs/guides/longer-metrics-storage.md index b682125f5..85edb55ee 100644 --- a/docs/guides/longer-metrics-storage.md +++ b/docs/guides/longer-metrics-storage.md @@ -157,4 +157,4 @@ charts](/web/README.md#using-charts). And if you'd now like to reduce Netdata's resource usage, view our [performance guide](/docs/guides/configure/performance.md) for our best practices on optimization. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Flonger-metrics-storage&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/monitor-cockroachdb.md b/docs/guides/monitor-cockroachdb.md index 327237836..46dd2535e 100644 --- a/docs/guides/monitor-cockroachdb.md +++ b/docs/guides/monitor-cockroachdb.md @@ -133,4 +133,4 @@ Also, be sure to check out these useful resources: - [Monitor CockroachDB with Prometheus](https://www.cockroachlabs.com/docs/stable/monitor-cockroachdb-with-prometheus.html) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fmonitor-cockroachdb&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/monitor-hadoop-cluster.md b/docs/guides/monitor-hadoop-cluster.md index 69f2bc8e3..62403f897 100644 --- a/docs/guides/monitor-hadoop-cluster.md +++ b/docs/guides/monitor-hadoop-cluster.md @@ -200,4 +200,4 @@ issue](https://github.com/netdata/netdata/issues/new?assignees=&labels=bug%2Cnee file](https://github.com/netdata/go.d.plugin/blob/master/config/go.d/zookeeper.conf) to understand how to configure global options or per-job options, timeouts, TLS certificates, and more. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fmonitor-hadoop-cluster&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/monitor/anomaly-detection-python.md b/docs/guides/monitor/anomaly-detection-python.md index d10e9da4f..ad8398cc6 100644 --- a/docs/guides/monitor/anomaly-detection-python.md +++ b/docs/guides/monitor/anomaly-detection-python.md @@ -23,7 +23,7 @@ library](https://github.com/yzhao062/pyod/tree/master), which periodically runs quantify how anomalous certain charts are. All these metrics and alarms are available for centralized monitoring in [Netdata Cloud](https://app.netdata.cloud). If -you choose to sign up for Netdata Cloud and [coonect your nodes](/claim/README.md), you will have the ability to run +you choose to sign up for Netdata Cloud and [connect your nodes](/claim/README.md), you will have the ability to run tailored anomaly detection on every node in your infrastructure, regardless of its purpose or workload. In this guide, you'll learn how to set up the anomalies collector to instantly detect anomalies in an Nginx web server @@ -143,7 +143,7 @@ dimensions](https://user-images.githubusercontent.com/1153921/102813877-db5e4880 As you can see in the above screenshot, this node is now looking for anomalies in many places. The result is a single `anomalies_local.probability` chart with more than twenty dimensions, some of which the dashboard hides at the bottom of -a scroll-able area. In addition, training and analyzing the anomaly collector on many charts might require more CPU +a scrollable area. In addition, training and analyzing the anomaly collector on many charts might require more CPU utilization that you're willing to give. First, explicitly declare which `system.` charts to monitor rather than of all of them using regex (`system\..*`). diff --git a/docs/guides/monitor/dimension-templates.md b/docs/guides/monitor/dimension-templates.md index 7cbe7959c..539127366 100644 --- a/docs/guides/monitor/dimension-templates.md +++ b/docs/guides/monitor/dimension-templates.md @@ -173,4 +173,4 @@ Or, at the very least, simplify your configuration files. For information about other advanced features in Netdata's health monitoring toolkit, check out our [health documentation](/health/README.md). And if you have some cool alarms you built using dimension templates, -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fmonitor%2dimension-templates&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/monitor/kubernetes-k8s-netdata.md b/docs/guides/monitor/kubernetes-k8s-netdata.md index bd893ede6..5cfefe892 100644 --- a/docs/guides/monitor/kubernetes-k8s-netdata.md +++ b/docs/guides/monitor/kubernetes-k8s-netdata.md @@ -251,4 +251,4 @@ clusters of all sizes. collector](https://learn.netdata.cloud/docs/agent/collectors/go.d.plugin/modules/k8s_kubeproxy) - [Netdata Agent · `cgroups.plugin`](/collectors/cgroups.plugin/README.md) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fmonitor%2Fkubernetes-k8s-netdata.md&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/monitor/lamp-stack.md b/docs/guides/monitor/lamp-stack.md index 4fe0defb0..595d64400 100644 --- a/docs/guides/monitor/lamp-stack.md +++ b/docs/guides/monitor/lamp-stack.md @@ -244,4 +244,3 @@ source of issues faster with [Metric Correlations](https://learn.netdata.cloud/d - [Netdata Agent · MySQL data collector](https://learn.netdata.cloud/docs/agent/collectors/go.d.plugin/modules/mysql) - [Netdata Agent · PHP-FPM data collector](https://learn.netdata.cloud/docs/agent/collectors/go.d.plugin/modules/phpfpm) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fmonitor%2Flamp-stack&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) \ No newline at end of file diff --git a/docs/guides/monitor/pi-hole-raspberry-pi.md b/docs/guides/monitor/pi-hole-raspberry-pi.md index 9dc60d3af..721ba2a8f 100644 --- a/docs/guides/monitor/pi-hole-raspberry-pi.md +++ b/docs/guides/monitor/pi-hole-raspberry-pi.md @@ -159,4 +159,4 @@ troubleshooting the health of your systems and services. If you have any questions about using Netdata to monitor your Raspberry Pi, Pi-hole, or any other applications, head on over to our [community forum](https://community.netdata.cloud/). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fmonitor%2Fpi-hole-raspberry-pi.md&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/monitor/process.md b/docs/guides/monitor/process.md index d322035b1..2f46d7abc 100644 --- a/docs/guides/monitor/process.md +++ b/docs/guides/monitor/process.md @@ -298,4 +298,4 @@ frameworks. - [Netdata Agent · Dashboards](/web/README.md#dimensions) - [Netdata Agent · MySQL collector](https://learn.netdata.cloud/docs/agent/collectors/go.d.plugin/modules/mysql) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fmonitor%2Fprocess&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/monitor/raspberry-pi-anomaly-detection.md b/docs/guides/monitor/raspberry-pi-anomaly-detection.md index 029dfcbc7..73f57cd04 100644 --- a/docs/guides/monitor/raspberry-pi-anomaly-detection.md +++ b/docs/guides/monitor/raspberry-pi-anomaly-detection.md @@ -122,4 +122,4 @@ feedback on our [community forum](https://community.netdata.cloud/t/anomalies-co - [Netdata Agent · Get Netdata](/docs/get-started.mdx) - [Netdata Agent · Anomalies collector](/collectors/python.d.plugin/anomalies/README.md) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fmonitor%2Fraspberry-pi-anomaly-detection&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/monitor/statsd.md b/docs/guides/monitor/statsd.md index 214b488f2..3e2f0f85c 100644 --- a/docs/guides/monitor/statsd.md +++ b/docs/guides/monitor/statsd.md @@ -295,4 +295,4 @@ Netdata allows you easily visualize any StatsD metric without any configuration, - [Netdata Agent · StatsD](/collectors/statsd.plugin/README.md) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fmonitor%2Fstatsdr&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/monitor/stop-notifications-alarms.md b/docs/guides/monitor/stop-notifications-alarms.md index ad054d5c7..a8b73a86a 100644 --- a/docs/guides/monitor/stop-notifications-alarms.md +++ b/docs/guides/monitor/stop-notifications-alarms.md @@ -89,4 +89,4 @@ You can also use Netdata's [Health Management API](/web/api/health/README.md#hea checks and notifications while Netdata runs. With this API, you can disable health checks during a maintenance window or backup process, for example. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fmonitor%2Fstop-notifications-alarms%2F&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/monitor/visualize-monitor-anomalies.md b/docs/guides/monitor/visualize-monitor-anomalies.md index 9eace5232..1f8c2c8f8 100644 --- a/docs/guides/monitor/visualize-monitor-anomalies.md +++ b/docs/guides/monitor/visualize-monitor-anomalies.md @@ -139,4 +139,4 @@ that works well for monitoring some other popular application, like MySQL, Postg - [Netdata Agent · Anomalies collector](/collectors/python.d.plugin/anomalies/README.md) - [Netdata Cloud · Build new dashboards](https://learn.netdata.cloud/docs/cloud/visualize/dashboards) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fmonitor%2Fanomaly-detectionl&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/python-collector.md b/docs/guides/python-collector.md index c3784194a..f93c724bf 100644 --- a/docs/guides/python-collector.md +++ b/docs/guides/python-collector.md @@ -483,4 +483,4 @@ Now we you ready to start developing our Netdata python Collector and share it w production-grade collectors. - Celebrate! You have contributed to an open-source project with hundreds of thousands of users! -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fpython-collector&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/step-by-step/step-00.md b/docs/guides/step-by-step/step-00.md index 3cb85ceda..ab68fe741 100644 --- a/docs/guides/step-by-step/step-00.md +++ b/docs/guides/step-by-step/step-00.md @@ -117,4 +117,4 @@ MongoDB, TimescaleDB, and others. Run Netdata behind an Nginx proxy to improve performance, and enable TLS/HTTPS for better security. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fstep-by-step%2Fstep-00&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/step-by-step/step-01.md b/docs/guides/step-by-step/step-01.md index cdcfcd7a2..f5430e3a6 100644 --- a/docs/guides/step-by-step/step-01.md +++ b/docs/guides/step-by-step/step-01.md @@ -153,4 +153,4 @@ get right into that dashboard you've heard so much about. [Next: Get to know Netdata's dashboard →](step-02.md) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fstep-by-step%2Fstep-01&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/step-by-step/step-02.md b/docs/guides/step-by-step/step-02.md index c87712c9a..4b802ffd6 100644 --- a/docs/guides/step-by-step/step-02.md +++ b/docs/guides/step-by-step/step-02.md @@ -205,4 +205,4 @@ Next, you'll learn how to monitor multiple nodes through the dashboard. [Next: Monitor more than one system with Netdata →](step-03.md) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fstep-by-step%2Fstep-02&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/step-by-step/step-03.md b/docs/guides/step-by-step/step-03.md index a2f37beeb..c1d283ba0 100644 --- a/docs/guides/step-by-step/step-03.md +++ b/docs/guides/step-by-step/step-03.md @@ -88,4 +88,4 @@ customize your Netdata experience to your exact infrastructure and the informati [Next: The basics of configuring Netdata →](step-04.md) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fstep-by-step%2Fstep-03&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/step-by-step/step-04.md b/docs/guides/step-by-step/step-04.md index 41431b1d0..37b4245be 100644 --- a/docs/guides/step-by-step/step-04.md +++ b/docs/guides/step-by-step/step-04.md @@ -141,4 +141,4 @@ choosing. [Next: Health monitoring alarms and notifications →](step-05.md) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fstep-by-step%2Fstep-04&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/step-by-step/step-05.md b/docs/guides/step-by-step/step-05.md index c0b622618..3cd8c5dbc 100644 --- a/docs/guides/step-by-step/step-05.md +++ b/docs/guides/step-by-step/step-05.md @@ -347,4 +347,4 @@ from hundreds of services with almost no configuration on your part. Onward! [Next: Collect metrics from more services and apps →](step-06.md) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fstep-by-step%2Fstep-05&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/step-by-step/step-06.md b/docs/guides/step-by-step/step-06.md index 618886076..89a8cb732 100644 --- a/docs/guides/step-by-step/step-06.md +++ b/docs/guides/step-by-step/step-06.md @@ -119,4 +119,4 @@ the dashboard to learn more about some of its more advanced features. [Next: Netdata's dashboard in depth →](step-07.md) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fstep-by-step%2Fstep-06&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/step-by-step/step-07.md b/docs/guides/step-by-step/step-07.md index f2f665575..17a02cd46 100644 --- a/docs/guides/step-by-step/step-07.md +++ b/docs/guides/step-by-step/step-07.md @@ -111,4 +111,4 @@ Next, you'll learn how to build your first custom dashboard! [Next: Build your first custom dashboard →](step-08.md) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fstep-by-step%2Fstep-07&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/step-by-step/step-08.md b/docs/guides/step-by-step/step-08.md index 76a1b0775..e9c0f902c 100644 --- a/docs/guides/step-by-step/step-08.md +++ b/docs/guides/step-by-step/step-08.md @@ -392,4 +392,4 @@ Next, you'll learn how to store long-term historical metrics in Netdata! [Next: Long-term metrics storage →](/docs/guides/step-by-step/step-09.md) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fstep-by-step%2Fstep-08&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/step-by-step/step-09.md b/docs/guides/step-by-step/step-09.md index 6e29d84c5..6333dfe69 100644 --- a/docs/guides/step-by-step/step-09.md +++ b/docs/guides/step-by-step/step-09.md @@ -159,4 +159,4 @@ our Netdata dashboard. [Next: Set up a proxy →](/docs/guides/step-by-step/step-10.md) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fstep-by-step%2Fstep-09&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/step-by-step/step-10.md b/docs/guides/step-by-step/step-10.md index d1c065c51..c9acf5aaf 100644 --- a/docs/guides/step-by-step/step-10.md +++ b/docs/guides/step-by-step/step-10.md @@ -156,7 +156,7 @@ sudo certbot --nginx > The requested nginx plugin does not appear to be installed` > ``` > -> You must install `python-certbox-nginx`. On Ubuntu or Debian systems, you can run `sudo apt-get install +> You must install `python-certbot-nginx`. On Ubuntu or Debian systems, you can run `sudo apt-get install > python-certbot-nginx` to download and install this package. You'll be prompted with a few questions. At the `Which names would you like to activate HTTPS for?` question, hit @@ -229,4 +229,4 @@ For some celebratory emoji and a clap on the back, head on over to our final ste [Next: The end. →](step-99.md) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fstep-by-step%2Fstep-10&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/step-by-step/step-99.md b/docs/guides/step-by-step/step-99.md index 06a826a15..58902fee7 100644 --- a/docs/guides/step-by-step/step-99.md +++ b/docs/guides/step-by-step/step-99.md @@ -44,8 +44,8 @@ If that feels like too much possibility to you, why not one of these options: - Share your experience with Netdata and this guide. Be sure to [@mention](https://twitter.com/linuxnetdata) us on Twitter! - Contribute to what we do. Browse our [open issues](https://github.com/netdata/netdata/issues) and check out out - [contributions doc](/README.md#contribute) for ideas of how you can pitch in. + [contributions doc](https://learn.netdata.cloud/contribute/) for ideas of how you can pitch in. We can't wait to see what you monitor next! Bon voyage! ⛵ -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fstep-by-step%2Fstep-99&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/troubleshoot/monitor-debug-applications-ebpf.md b/docs/guides/troubleshoot/monitor-debug-applications-ebpf.md index 688e7d296..3ebca5425 100644 --- a/docs/guides/troubleshoot/monitor-debug-applications-ebpf.md +++ b/docs/guides/troubleshoot/monitor-debug-applications-ebpf.md @@ -267,4 +267,4 @@ we'd love to hear them: [info@netdata.cloud](mailto:info@netdata.cloud). Happy troubleshooting! -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%troubleshoot%2Fmonitor-debug-applications-ebpf.md&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/guides/using-host-labels.md b/docs/guides/using-host-labels.md index d3a51bea6..7a5381e99 100644 --- a/docs/guides/using-host-labels.md +++ b/docs/guides/using-host-labels.md @@ -86,7 +86,7 @@ They capture the following: - What virtualization layer the system runs on top of, if any - Whether the system is a streaming parent or child -If you want to organize your systems without manually creating host tags, try the automatic labels in some of the +If you want to organize your systems without manually creating host labels, try the automatic labels in some of the features below. ## Host labels in streaming @@ -209,4 +209,4 @@ If you have issues or questions around using host labels, don't hesitate to [fil issue](https://github.com/netdata/netdata/issues/new?assignees=&labels=bug%2Cneeds+triage&template=BUG_REPORT.yml) on GitHub. We're excited to make host labels even more valuable to our users, which we can only do with your input. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fguides%2Fusing-host-labels&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/monitor/configure-alarms.md b/docs/monitor/configure-alarms.md index 563e61560..ac4581152 100644 --- a/docs/monitor/configure-alarms.md +++ b/docs/monitor/configure-alarms.md @@ -145,4 +145,4 @@ state. To build complex, dynamic alarms, read our guide on [dimension templates](/docs/guides/monitor/dimension-templates.md). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fmonitor%2Fview-active-alarms&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/monitor/enable-notifications.md b/docs/monitor/enable-notifications.md index d0ff04d99..8cf697972 100644 --- a/docs/monitor/enable-notifications.md +++ b/docs/monitor/enable-notifications.md @@ -144,4 +144,4 @@ architecture](/docs/store/distributed-data-architecture.md) for the best-in-clas - [Netdata Cloud · Alarm notifications](https://learn.netdata.cloud/docs/cloud/alerts-notifications/notifications) - [Netdata Agent · Notifications](/health/notifications/README.md) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fmonitor%2Fenable-notifications&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/monitor/view-active-alarms.md b/docs/monitor/view-active-alarms.md index 99169c2c8..be2182683 100644 --- a/docs/monitor/view-active-alarms.md +++ b/docs/monitor/view-active-alarms.md @@ -72,4 +72,4 @@ If you're happy with the pre-configured alarms, skip ahead to [enable notifications](/docs/monitor/enable-notifications.md) to use Netdata Cloud's centralized alarm notifications and/or per-node notifications to endpoints like Slack, PagerDuty, Twilio, and more. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fmonitor%2Fview-active-alarms&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/netdata-for-IoT.md b/docs/netdata-for-IoT.md index 77b95229f..35d770537 100644 --- a/docs/netdata-for-IoT.md +++ b/docs/netdata-for-IoT.md @@ -71,4 +71,4 @@ Then restart Netdata. You will get this: ![image](https://user-images.githubusercontent.com/2662304/29658868-23aa65ae-88c5-11e7-9dad-c159600db5cc.png) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fnetdata-for-IoT&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/netdata-security.md b/docs/netdata-security.md index bb4ac30c4..9bb26ad23 100644 --- a/docs/netdata-security.md +++ b/docs/netdata-security.md @@ -205,7 +205,7 @@ The default configuration uses a public registry under registry.my-netdata.io (m - The url where you open the web-ui in the browser (via http request referrer) - The hostnames of the Netdata servers -If sending this information to the central Netdata registry violates your security policies, you can configure Netdat to [run your own registry](/registry/README.md#run-your-own-registry). +If sending this information to the central Netdata registry violates your security policies, you can configure Netdata to [run your own registry](/registry/README.md#run-your-own-registry). ### Opt-out of anonymous statistics @@ -226,4 +226,4 @@ _actively_ contributing to Netdata's future. | `/var/lib/netdata`|user `netdata`
group `netdata`|dirs `0750`
files `0660`|reads, writes, creates, deletes|**Netdata permanent database files**
Netdata stores here the registry data, health alarm log db, etc.| | `/var/log/netdata`|user `netdata`
group `root`|dirs `0755`
files `0644`|writes, creates|**Netdata log files**
all the Netdata applications, logs their errors or other informational messages to files in this directory. These files should be log rotated.| -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fnetdata-security&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/overview/netdata-monitoring-stack.md b/docs/overview/netdata-monitoring-stack.md index 3a954f055..ae9252272 100644 --- a/docs/overview/netdata-monitoring-stack.md +++ b/docs/overview/netdata-monitoring-stack.md @@ -59,4 +59,4 @@ charts, or use Netdata's health watchdog to send notifications whenever an anoma Whether you're using Netdata standalone or as part of a larger monitoring stack, the next step is the same: [**Get Netdata**](/docs/get-started.mdx). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Foverview%2Fnetdata-monitoring-stacka&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/overview/what-is-netdata.md b/docs/overview/what-is-netdata.md index 37f974ad8..3df1d949b 100644 --- a/docs/overview/what-is-netdata.md +++ b/docs/overview/what-is-netdata.md @@ -71,4 +71,4 @@ case: Learn more about [why you should use Netdata](/docs/overview/why-netdata.md), or [how Netdata works with your existing monitoring stack](/docs/overview/netdata-monitoring-stack.md). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Foverview%2Fwhat-is-netdata&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/overview/why-netdata.md b/docs/overview/why-netdata.md index 27a30a4c6..9a308f25c 100644 --- a/docs/overview/why-netdata.md +++ b/docs/overview/why-netdata.md @@ -60,4 +60,4 @@ Whether you already have a monitoring stack you want to integrate Netdata into, ground-up, you should read more on how Netdata can work either [standalone or as an interoperable part of a monitoring stack](/docs/overview/netdata-monitoring-stack.md). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Foverview%2Fwhy-netdata&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/quickstart/infrastructure.md b/docs/quickstart/infrastructure.md index ea803cf13..9db66c052 100644 --- a/docs/quickstart/infrastructure.md +++ b/docs/quickstart/infrastructure.md @@ -182,4 +182,4 @@ To change how the Netdata Agent runs on each node, dig in to configuration files GitHub](https://learn.netdata.cloud/docs/cloud/manage/sign-in) - [Netdata Cloud · Nodes view](https://learn.netdata.cloud/docs/cloud/visualize/nodes) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fquickstart%2Finfrastructure&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/quickstart/single-node.md b/docs/quickstart/single-node.md index ab98a8389..7855a4876 100644 --- a/docs/quickstart/single-node.md +++ b/docs/quickstart/single-node.md @@ -89,4 +89,4 @@ out some of Netdata's other visualization and health monitoring features: - [Export metrics](/docs/export/external-databases.md) to an external time-series database to use Netdata alongside other monitoring and troubleshooting tools. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fquickstart%2Fsingle-node&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/store/change-metrics-storage.md b/docs/store/change-metrics-storage.md index 2ed026c5c..99760e8d3 100644 --- a/docs/store/change-metrics-storage.md +++ b/docs/store/change-metrics-storage.md @@ -74,4 +74,4 @@ further analysis, visualization, or correlation with other tools. - [Netdata Agent · Database engine](/database/engine/README.md) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fstore%2Fchange-metrics-storage&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/store/distributed-data-architecture.md b/docs/store/distributed-data-architecture.md index 0ec5c1420..c834d710a 100644 --- a/docs/store/distributed-data-architecture.md +++ b/docs/store/distributed-data-architecture.md @@ -68,4 +68,4 @@ You can configure the Netdata Agent to store days, weeks, or months worth of dis resources required to retain your desired amount of metrics, and expand or contract the database by editing a single setting. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fstore%2Fdistributed-data&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/visualize/create-dashboards.md b/docs/visualize/create-dashboards.md index 91a8dcccc..696cd1a74 100644 --- a/docs/visualize/create-dashboards.md +++ b/docs/visualize/create-dashboards.md @@ -61,4 +61,4 @@ While it's useful to see real-time metrics on flexible dashboards, you need ways strikes. Every Netdata Agent comes with a health watchdog that uses [alarms](/docs/monitor/configure-alarms.md) and [notifications](/docs/monitor/enable-notifications.md) to notify you of issues seconds after they strike. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fvisualize%2Fcreate-dashboards&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/visualize/interact-dashboards-charts.md b/docs/visualize/interact-dashboards-charts.md index c5b4c1b62..5dbbf19ab 100644 --- a/docs/visualize/interact-dashboards-charts.md +++ b/docs/visualize/interact-dashboards-charts.md @@ -128,4 +128,4 @@ to get informed when something goes wrong in your infrastructure. - [Netdata Cloud · Nodes](https://learn.netdata.cloud/docs/cloud/visualize/nodes) - [Netdata Cloud · Build new dashboards](https://learn.netdata.cloud/docs/cloud/visualize/dashboards) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fvisualize%2Finteract-dashboards-charts&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/visualize/overview-infrastructure.md b/docs/visualize/overview-infrastructure.md index 288bfc515..4edbb0f3a 100644 --- a/docs/visualize/overview-infrastructure.md +++ b/docs/visualize/overview-infrastructure.md @@ -108,4 +108,4 @@ visualizations_](/docs/guides/monitor/kubernetes-k8s-netdata.md), for a full wal - [Netdata Cloud · Nodes view](https://learn.netdata.cloud/docs/cloud/visualize/nodes) - [Netdata Cloud · Kubernetes visualizations](https://learn.netdata.cloud/docs/cloud/visualize/kubernetes) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fvisualize%2Foverview-infrastructure&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/why-netdata/1s-granularity.md b/docs/why-netdata/1s-granularity.md index a2cc65b8f..4fc7fab2d 100644 --- a/docs/why-netdata/1s-granularity.md +++ b/docs/why-netdata/1s-granularity.md @@ -56,4 +56,4 @@ Netdata has been designed to: So, for Netdata 1s granularity is easy, the natural outcome... -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fwhy-netdata%2F1s-granularity&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/why-netdata/README.md b/docs/why-netdata/README.md index 39cda51e2..c482ee944 100644 --- a/docs/why-netdata/README.md +++ b/docs/why-netdata/README.md @@ -32,4 +32,4 @@ Netdata's helps us troubleshoot slowdowns without touching the console. So, everything is a bit different. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2FWhy-Netdata&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/why-netdata/immediate-results.md b/docs/why-netdata/immediate-results.md index ba7c7d684..b35aa5381 100644 --- a/docs/why-netdata/immediate-results.md +++ b/docs/why-netdata/immediate-results.md @@ -43,4 +43,4 @@ Netdata: - Does not introduce any query languages or any other technology to be learned. Of course some familiarity with the tool is required, but nothing too complicated. - Includes all the community expertise and experience for monitoring systems and applications. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fwhy-netdata%2Fimmediate-results&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/why-netdata/meaningful-presentation.md b/docs/why-netdata/meaningful-presentation.md index 64d83b4f6..fc670e33f 100644 --- a/docs/why-netdata/meaningful-presentation.md +++ b/docs/why-netdata/meaningful-presentation.md @@ -65,4 +65,4 @@ But it simplifies everything else. Data collection, metrics database and visuali Netdata goes a step further, by enriching the dashboard with information that is useful for most people. So, to improve clarity and help users be more effective, Netdata includes right in the dashboard the community knowledge and expertise about the metrics. So, that Netdata users can focus on solving their infrastructure problem, not on the technicalities of data collection and visualization. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fwhy-netdata%2Fmeaningful-presentation&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/docs/why-netdata/unlimited-metrics.md b/docs/why-netdata/unlimited-metrics.md index 8e50062c7..b79a4ede3 100644 --- a/docs/why-netdata/unlimited-metrics.md +++ b/docs/why-netdata/unlimited-metrics.md @@ -46,4 +46,4 @@ Due to Netdata's distributed nature, the number of metrics collected does not ha Of course, since Netdata is also about [meaningful presentation](meaningful-presentation.md), the number of metrics makes Netdata development slower. We, the Netdata developers, need to have a good understanding of the metrics before adding them into Netdata. We need to organize the metrics, add information related to them, configure alarms for them, so that you, the Netdata users, will have the best out-of-the-box experience and all the information required to kill the console for troubleshooting slowdowns. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fdocs%2Fwhy-netdata%2Funlimited-metrics&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/exporting/README.md b/exporting/README.md index 18f56fbb6..ae9c8ccf2 100644 --- a/exporting/README.md +++ b/exporting/README.md @@ -20,12 +20,6 @@ the same time. You can have different update intervals and filters configured fo When you enable the exporting engine and a connector, the Netdata Agent exports metrics _beginning from the time you restart its process_, not the entire [database of long-term metrics](/docs/store/change-metrics-storage.md). -The exporting engine has its own configuration file `exporting.conf`. The configuration is almost similar to the -deprecated [backends](/backends/README.md#configuration) system. The most important difference is that type of a -connector should be specified in a section name before a colon and an instance name after the colon. Also, you can't use -`host tags` anymore. Set your labels using the [`[host labels]`](/docs/guides/using-host-labels.md) section in -`netdata.conf`. - Since Netdata collects thousands of metrics per server per second, which would easily congest any database server when several Netdata servers are sending data to it, Netdata allows sending metrics at a lower frequency, by resampling them. @@ -271,12 +265,6 @@ Configure individual connectors and override any global settings with the follow - `send automatic labels = yes | no` controls if automatically created labels, like `_os_name` or `_architecture` should be sent to the external database -> Starting from Netdata v1.20 the host tags (defined in the `[backend]` section of `netdata.conf`) are parsed in -> accordance with a configured backend type and stored as host labels so that they can be reused in API responses and -> exporting connectors. The parsing is supported for graphite, json, opentsdb, and prometheus (default) backend types. -> You can check how the host tags were parsed using the /api/v1/info API call. But, keep in mind that backends subsystem -> is deprecated and will be deleted soon. Please move your existing tags to the `[host labels]` section. - ## HTTPS Netdata can send metrics to external databases using the TLS/SSL protocol. Unfortunately, some of @@ -311,4 +299,4 @@ Netdata adds 3 alarms: ![image](https://cloud.githubusercontent.com/assets/2662304/20463779/a46ed1c2-af43-11e6-91a5-07ca4533cac3.png) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fexporting%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/exporting/TIMESCALE.md b/exporting/TIMESCALE.md index c98003ed4..07aa1b7a2 100644 --- a/exporting/TIMESCALE.md +++ b/exporting/TIMESCALE.md @@ -20,7 +20,7 @@ What's TimescaleDB? Here's how their team defines the project on their [GitHub p To get started archiving metrics to TimescaleDB right away, check out Mahlon's [`netdata-timescale-relay` repository](https://github.com/mahlonsmith/netdata-timescale-relay) on GitHub. Please be aware that backends subsystem -is deprecated and Netdata configuration should be moved to the new `exporting conf` configuration file. Use +was removed and Netdata configuration should be moved to the new `exporting.conf` configuration file. Use ```conf [json:my_instance] ``` @@ -66,4 +66,4 @@ blog](https://blog.timescale.com/blog/writing-it-metrics-from-netdata-to-timesca Thank you to Mahlon, Rune, TimescaleDB, and the members of the Netdata community that requested and then built this exporting connection between Netdata and TimescaleDB! -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fexporting%2FTIMESCALE&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/exporting/WALKTHROUGH.md b/exporting/WALKTHROUGH.md index d6ede8235..0612b298a 100644 --- a/exporting/WALKTHROUGH.md +++ b/exporting/WALKTHROUGH.md @@ -263,4 +263,4 @@ achieved you do not have to think about the monitoring system until Prometheus c happens there are options presented in the Prometheus documentation for solving this. Hope this was helpful, happy monitoring. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fexporting%2FWALKTHROUGH&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/exporting/aws_kinesis/README.md b/exporting/aws_kinesis/README.md index 299fec581..29dd3438e 100644 --- a/exporting/aws_kinesis/README.md +++ b/exporting/aws_kinesis/README.md @@ -55,4 +55,4 @@ Alternatively, you can set AWS credentials for the `netdata` user using AWS SDK Netdata automatically computes a partition key for every record with the purpose to distribute records across available shards evenly. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fexporting%2Faws_kinesis%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/exporting/aws_kinesis/aws_kinesis.c b/exporting/aws_kinesis/aws_kinesis.c index 036afb49f..fe4181e3a 100644 --- a/exporting/aws_kinesis/aws_kinesis.c +++ b/exporting/aws_kinesis/aws_kinesis.c @@ -151,7 +151,7 @@ void aws_kinesis_connector_worker(void *instance_p) char error_message[ERROR_LINE_MAX + 1] = ""; debug( - D_BACKEND, + D_EXPORTING, "EXPORTING: kinesis_put_record(): dest = %s, id = %s, key = %s, stream = %s, partition_key = %s, \ buffer = %zu, record = %zu", instance->config.destination, @@ -175,7 +175,7 @@ void aws_kinesis_connector_worker(void *instance_p) // oops! we couldn't send (all or some of the) data error("EXPORTING: %s", error_message); error( - "EXPORTING: failed to write data to database backend '%s'. Willing to write %zu bytes, wrote %zu bytes.", + "EXPORTING: failed to write data to external database '%s'. Willing to write %zu bytes, wrote %zu bytes.", instance->config.destination, sent_bytes, sent_bytes - lost_bytes); stats->transmission_failures++; diff --git a/exporting/check_filters.c b/exporting/check_filters.c index d2d7d870f..f7eba22db 100644 --- a/exporting/check_filters.c +++ b/exporting/check_filters.c @@ -16,19 +16,19 @@ int rrdhost_is_exportable(struct instance *instance, RRDHOST *host) RRDHOST_FLAGS *flags = &host->exporting_flags[instance->index]; - if (unlikely((*flags & (RRDHOST_FLAG_BACKEND_SEND | RRDHOST_FLAG_BACKEND_DONT_SEND)) == 0)) { + if (unlikely((*flags & (RRDHOST_FLAG_EXPORTING_SEND | RRDHOST_FLAG_EXPORTING_DONT_SEND)) == 0)) { char *host_name = (host == localhost) ? "localhost" : host->hostname; if (!instance->config.hosts_pattern || simple_pattern_matches(instance->config.hosts_pattern, host_name)) { - *flags |= RRDHOST_FLAG_BACKEND_SEND; + *flags |= RRDHOST_FLAG_EXPORTING_SEND; info("enabled exporting of host '%s' for instance '%s'", host_name, instance->config.name); } else { - *flags |= RRDHOST_FLAG_BACKEND_DONT_SEND; + *flags |= RRDHOST_FLAG_EXPORTING_DONT_SEND; info("disabled exporting of host '%s' for instance '%s'", host_name, instance->config.name); } } - if (likely(*flags & RRDHOST_FLAG_BACKEND_SEND)) + if (likely(*flags & RRDHOST_FLAG_EXPORTING_SEND)) return 1; else return 0; @@ -47,6 +47,10 @@ int rrdset_is_exportable(struct instance *instance, RRDSET *st) RRDHOST *host = st->rrdhost; #endif + // Do not export anomaly rates charts. + if (st->state && st->state->is_ar_chart) + return 0; + if (st->exporting_flags == NULL) st->exporting_flags = callocz(instance->engine->instance_num, sizeof(size_t)); @@ -61,18 +65,18 @@ int rrdset_is_exportable(struct instance *instance, RRDSET *st) *flags |= RRDSET_FLAG_EXPORTING_SEND; else { *flags |= RRDSET_FLAG_EXPORTING_IGNORE; - debug(D_BACKEND, "BACKEND: not sending chart '%s' of host '%s', because it is disabled for backends.", st->id, host->hostname); + debug(D_EXPORTING, "EXPORTING: not sending chart '%s' of host '%s', because it is disabled for exporting.", st->id, host->hostname); return 0; } } if(unlikely(!rrdset_is_available_for_exporting_and_alarms(st))) { - debug(D_BACKEND, "BACKEND: not sending chart '%s' of host '%s', because it is not available for backends.", st->id, host->hostname); + debug(D_EXPORTING, "EXPORTING: not sending chart '%s' of host '%s', because it is not available for exporting.", st->id, host->hostname); return 0; } if(unlikely(st->rrd_memory_mode == RRD_MEMORY_MODE_NONE && !(EXPORTING_OPTIONS_DATA_SOURCE(instance->config.options) == EXPORTING_SOURCE_DATA_AS_COLLECTED))) { - debug(D_BACKEND, "BACKEND: not sending chart '%s' of host '%s' because its memory mode is '%s' and the backend requires database access.", st->id, host->hostname, rrd_memory_mode_name(host->rrd_memory_mode)); + debug(D_EXPORTING, "EXPORTING: not sending chart '%s' of host '%s' because its memory mode is '%s' and the exporting engine requires database access.", st->id, host->hostname, rrd_memory_mode_name(host->rrd_memory_mode)); return 0; } diff --git a/exporting/exporting_engine.h b/exporting/exporting_engine.h index f08583fb5..20f260c15 100644 --- a/exporting/exporting_engine.h +++ b/exporting/exporting_engine.h @@ -34,6 +34,9 @@ typedef enum exporting_options { (EXPORTING_SOURCE_DATA_AS_COLLECTED | EXPORTING_SOURCE_DATA_AVERAGE | EXPORTING_SOURCE_DATA_SUM) #define EXPORTING_OPTIONS_DATA_SOURCE(exporting_options) (exporting_options & EXPORTING_OPTIONS_SOURCE_BITS) +extern EXPORTING_OPTIONS global_exporting_options; +extern const char *global_exporting_prefix; + #define sending_labels_configured(instance) \ (instance->config.options & (EXPORTING_OPTION_SEND_CONFIGURED_LABELS | EXPORTING_OPTION_SEND_AUTOMATIC_LABELS)) @@ -51,11 +54,11 @@ typedef enum exporting_connector_types { EXPORTING_CONNECTOR_TYPE_JSON_HTTP, // Send data in JSON format using HTTP API EXPORTING_CONNECTOR_TYPE_OPENTSDB, // Send data to OpenTSDB using telnet API EXPORTING_CONNECTOR_TYPE_OPENTSDB_HTTP, // Send data to OpenTSDB using HTTP API - EXPORTING_CONNECTOR_TYPE_PROMETHEUS_REMOTE_WRITE, // User selected to use Prometheus backend + EXPORTING_CONNECTOR_TYPE_PROMETHEUS_REMOTE_WRITE, // Send data using Prometheus remote write protocol EXPORTING_CONNECTOR_TYPE_KINESIS, // Send message to AWS Kinesis EXPORTING_CONNECTOR_TYPE_PUBSUB, // Send message to Google Cloud Pub/Sub EXPORTING_CONNECTOR_TYPE_MONGODB, // Send data to MongoDB collection - EXPORTING_CONNECTOR_TYPE_NUM // Number of backend types + EXPORTING_CONNECTOR_TYPE_NUM // Number of exporting connector types } EXPORTING_CONNECTOR_TYPE; struct engine; @@ -265,6 +268,8 @@ size_t exporting_name_copy(char *dst, const char *src, size_t max_len); int rrdhost_is_exportable(struct instance *instance, RRDHOST *host); int rrdset_is_exportable(struct instance *instance, RRDSET *st); +extern EXPORTING_OPTIONS exporting_parse_data_source(const char *source, EXPORTING_OPTIONS exporting_options); + calculated_number exporting_calculate_value_from_stored_data( struct instance *instance, RRDDIM *rd, diff --git a/exporting/graphite/README.md b/exporting/graphite/README.md index d755e0934..6c96c78c9 100644 --- a/exporting/graphite/README.md +++ b/exporting/graphite/README.md @@ -32,4 +32,4 @@ Add `:http` or `:https` modifiers to the connector type if you need to use other The Graphite connector is further configurable using additional settings. See the [exporting reference doc](/exporting/README.md#options) for details. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fexporting%2Fjson%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/exporting/json/README.md b/exporting/json/README.md index 7cce463e2..d129ffbd7 100644 --- a/exporting/json/README.md +++ b/exporting/json/README.md @@ -32,4 +32,4 @@ Add `:http` or `:https` modifiers to the connector type if you need to use other The JSON connector is further configurable using additional settings. See the [exporting reference doc](/exporting/README.md#options) for details. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fexporting%2Fjson%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/exporting/mongodb/README.md b/exporting/mongodb/README.md index 2934f38c5..b10d54716 100644 --- a/exporting/mongodb/README.md +++ b/exporting/mongodb/README.md @@ -35,4 +35,4 @@ You can find more information about the `destination` string URI format in the M The default socket timeout depends on the exporting connector update interval. The timeout is 500 ms shorter than the interval (but not less than 1000 ms). You can alter the timeout using the `sockettimeoutms` MongoDB URI option. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fexporting%2Fmongodb%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/exporting/mongodb/mongodb.c b/exporting/mongodb/mongodb.c index 49ce95269..aab1770d2 100644 --- a/exporting/mongodb/mongodb.c +++ b/exporting/mongodb/mongodb.c @@ -327,7 +327,7 @@ void mongodb_connector_worker(void *instance_p) } debug( - D_BACKEND, + D_EXPORTING, "EXPORTING: mongodb_insert(): destination = %s, database = %s, collection = %s, data size = %zu", instance->config.destination, connector_specific_config->database, diff --git a/exporting/nc-exporting.sh b/exporting/nc-exporting.sh index 168c0d4b7..740f65d18 100755 --- a/exporting/nc-exporting.sh +++ b/exporting/nc-exporting.sh @@ -2,17 +2,17 @@ # SPDX-License-Identifier: GPL-3.0-or-later -# This is a simple backend database proxy, written in BASH, using the nc command. +# This is a simple exporting proxy, written in BASH, using the nc command. # Run the script without any parameters for help. MODE="${1}" MY_PORT="${2}" -BACKEND_HOST="${3}" -BACKEND_PORT="${4}" -FILE="${NETDATA_NC_BACKEND_DIR-/tmp}/netdata-nc-backend-${MY_PORT}" +EXPORTING_HOST="${3}" +EXPORTING_PORT="${4}" +FILE="${NETDATA_NC_EXPORTING_DIR-/tmp}/netdata-nc-exporting-${MY_PORT}" log() { - logger --stderr --id=$$ --tag "netdata-nc-backend" "${*}" + logger --stderr --id=$$ --tag "netdata-nc-exporting" "${*}" } mync() { @@ -28,7 +28,7 @@ mync() { } listen_save_replay_forever() { - local file="${1}" port="${2}" real_backend_host="${3}" real_backend_port="${4}" ret delay=1 started ended + local file="${1}" port="${2}" real_exporting_host="${3}" real_exporting_port="${4}" ret delay=1 started ended while true do @@ -40,23 +40,23 @@ listen_save_replay_forever() { if [ -s "${file}" ] then - if [ -n "${real_backend_host}" ] && [ -n "${real_backend_port}" ] + if [ -n "${real_exporting_host}" ] && [ -n "${real_exporting_port}" ] then - log "Attempting to send the metrics to the real backend at ${real_backend_host}:${real_backend_port}" + log "Attempting to send the metrics to the real external database at ${real_exporting_host}:${real_exporting_port}" - mync "${real_backend_host}" "${real_backend_port}" <"${file}" + mync "${real_exporting_host}" "${real_exporting_port}" <"${file}" ret=$? if [ ${ret} -eq 0 ] then - log "Successfully sent the metrics to ${real_backend_host}:${real_backend_port}" + log "Successfully sent the metrics to ${real_exporting_host}:${real_exporting_port}" mv "${file}" "${file}.old" touch "${file}" else - log "Failed to send the metrics to ${real_backend_host}:${real_backend_port} (nc returned ${ret}) - appending more data to ${file}" + log "Failed to send the metrics to ${real_exporting_host}:${real_exporting_port} (nc returned ${ret}) - appending more data to ${file}" fi else - log "No backend configured - appending more data to ${file}" + log "No external database configured - appending more data to ${file}" fi fi @@ -92,7 +92,7 @@ if [ "${MODE}" = "start" ] # save our PID to the lock file echo "$$" >"${FILE}.lock" - listen_save_replay_forever "${FILE}" "${MY_PORT}" "${BACKEND_HOST}" "${BACKEND_PORT}" + listen_save_replay_forever "${FILE}" "${MY_PORT}" "${EXPORTING_HOST}" "${EXPORTING_PORT}" ret=$? log "listener exited." @@ -131,20 +131,20 @@ else cat <) + diff --git a/exporting/process_data.c b/exporting/process_data.c index 2c0c2d17c..c77b7ad4a 100644 --- a/exporting/process_data.c +++ b/exporting/process_data.c @@ -109,7 +109,7 @@ calculated_number exporting_calculate_value_from_stored_data( if (unlikely(before < first_t || after > last_t)) { // the chart has not been updated in the wanted timeframe debug( - D_BACKEND, + D_EXPORTING, "EXPORTING: %s.%s.%s: aligned timeframe %lu to %lu is outside the chart's database range %lu to %lu", host->hostname, st->id, @@ -143,7 +143,7 @@ calculated_number exporting_calculate_value_from_stored_data( rd->state->query_ops.finalize(&handle); if (unlikely(!counter)) { debug( - D_BACKEND, + D_EXPORTING, "EXPORTING: %s.%s.%s: no values stored in database for range %lu to %lu", host->hostname, st->id, diff --git a/exporting/prometheus/README.md b/exporting/prometheus/README.md index ceb778a43..5c15ca580 100644 --- a/exporting/prometheus/README.md +++ b/exporting/prometheus/README.md @@ -458,4 +458,4 @@ through a web proxy, or when multiple Prometheus servers are NATed to a single I `&server=NAME` to the URL. This `NAME` is used by Netdata to uniquely identify each Prometheus server and keep track of its last access time. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fexporting%2Fprometheus%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/exporting/prometheus/prometheus.c b/exporting/prometheus/prometheus.c index 0a3190074..97c3a29f0 100644 --- a/exporting/prometheus/prometheus.c +++ b/exporting/prometheus/prometheus.c @@ -20,6 +20,10 @@ inline int can_send_rrdset(struct instance *instance, RRDSET *st) RRDHOST *host = st->rrdhost; #endif + // Do not send anomaly rates charts. + if (st->state && st->state->is_ar_chart) + return 0; + if (unlikely(rrdset_flag_check(st, RRDSET_FLAG_EXPORTING_IGNORE))) return 0; @@ -31,7 +35,7 @@ inline int can_send_rrdset(struct instance *instance, RRDSET *st) else { rrdset_flag_set(st, RRDSET_FLAG_EXPORTING_IGNORE); debug( - D_BACKEND, + D_EXPORTING, "EXPORTING: not sending chart '%s' of host '%s', because it is disabled for exporting.", st->id, host->hostname); @@ -41,7 +45,7 @@ inline int can_send_rrdset(struct instance *instance, RRDSET *st) if (unlikely(!rrdset_is_available_for_exporting_and_alarms(st))) { debug( - D_BACKEND, + D_EXPORTING, "EXPORTING: not sending chart '%s' of host '%s', because it is not available for exporting.", st->id, host->hostname); @@ -52,7 +56,7 @@ inline int can_send_rrdset(struct instance *instance, RRDSET *st) st->rrd_memory_mode == RRD_MEMORY_MODE_NONE && !(EXPORTING_OPTIONS_DATA_SOURCE(instance->config.options) == EXPORTING_SOURCE_DATA_AS_COLLECTED))) { debug( - D_BACKEND, + D_EXPORTING, "EXPORTING: not sending chart '%s' of host '%s' because its memory mode is '%s' and the exporting connector requires database access.", st->id, host->hostname, diff --git a/exporting/prometheus/remote_write/README.md b/exporting/prometheus/remote_write/README.md index ce379063e..54c5d6588 100644 --- a/exporting/prometheus/remote_write/README.md +++ b/exporting/prometheus/remote_write/README.md @@ -55,4 +55,4 @@ buffer size on failures. The remote write exporting connector does not support `buffer on failures` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fexporting%2Fprometheus%2Fremote_write%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/exporting/prometheus/remote_write/remote_write.c b/exporting/prometheus/remote_write/remote_write.c index 8339712eb..59a488e1b 100644 --- a/exporting/prometheus/remote_write/remote_write.c +++ b/exporting/prometheus/remote_write/remote_write.c @@ -236,7 +236,7 @@ int format_dimension_prometheus_remote_write(struct instance *instance, RRDDIM * if (unlikely(rd->last_collected_time.tv_sec < instance->after)) { debug( - D_BACKEND, + D_EXPORTING, "EXPORTING: not sending dimension '%s' of chart '%s' from host '%s', " "its last data collection (%lu) is not within our timeframe (%lu to %lu)", rd->id, rd->rrdset->id, diff --git a/exporting/pubsub/README.md b/exporting/pubsub/README.md index 73b6a2031..2f9ac83d4 100644 --- a/exporting/pubsub/README.md +++ b/exporting/pubsub/README.md @@ -35,4 +35,4 @@ Next, create the credentials JSON file by following Google Cloud's [authenticati `chmod 400 google_cloud_credentials.json; chown netdata google_cloud_credentials.json`. Set the `credentials file` option to the full path of the file. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fexporting%2Fpubsub%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/exporting/pubsub/pubsub.c b/exporting/pubsub/pubsub.c index 336a096ab..5a5afbdc2 100644 --- a/exporting/pubsub/pubsub.c +++ b/exporting/pubsub/pubsub.c @@ -141,7 +141,7 @@ void pubsub_connector_worker(void *instance_p) } debug( - D_BACKEND, "EXPORTING: pubsub_publish(): project = %s, topic = %s, buffer = %zu", + D_EXPORTING, "EXPORTING: pubsub_publish(): project = %s, topic = %s, buffer = %zu", connector_specific_config->project_id, connector_specific_config->topic_id, buffer_len); if (pubsub_publish((void *)connector_specific_data, error_message, stats->buffered_metrics, buffer_len)) { diff --git a/exporting/read_config.c b/exporting/read_config.c index 77687d845..b834e867d 100644 --- a/exporting/read_config.c +++ b/exporting/read_config.c @@ -2,6 +2,9 @@ #include "exporting_engine.h" +EXPORTING_OPTIONS global_exporting_options = EXPORTING_SOURCE_DATA_AVERAGE | EXPORTING_OPTION_SEND_NAMES; +const char *global_exporting_prefix = "netdata"; + struct config exporting_config = { .first_section = NULL, .last_section = NULL, .mutex = NETDATA_MUTEX_INITIALIZER, @@ -160,7 +163,7 @@ EXPORTING_CONNECTOR_TYPE exporting_select_type(const char *type) return EXPORTING_CONNECTOR_TYPE_UNKNOWN; } -EXPORTING_OPTIONS exporting_parse_data_source(const char *data_source, EXPORTING_OPTIONS exporting_options) +inline EXPORTING_OPTIONS exporting_parse_data_source(const char *data_source, EXPORTING_OPTIONS exporting_options) { if (!strcmp(data_source, "raw") || !strcmp(data_source, "as collected") || !strcmp(data_source, "as-collected") || !strcmp(data_source, "as_collected") || !strcmp(data_source, "ascollected")) { @@ -194,7 +197,7 @@ struct engine *read_exporting_config() static struct engine *engine = NULL; struct connector_instance_list { struct connector_instance local_ci; - EXPORTING_CONNECTOR_TYPE backend_type; + EXPORTING_CONNECTOR_TYPE exporting_type; struct connector_instance_list *next; }; @@ -238,21 +241,14 @@ struct engine *read_exporting_config() prometheus_exporter_instance->config.update_every = prometheus_config_get_number(EXPORTING_UPDATE_EVERY_OPTION_NAME, EXPORTING_UPDATE_EVERY_DEFAULT); - // wait for backend subsystem to be initialized - for (int retries = 0; !global_backend_source && retries < 1000; retries++) - sleep_usec(10000); - - if (!global_backend_source) - global_backend_source = "average"; - - prometheus_exporter_instance->config.options |= global_backend_options & EXPORTING_OPTIONS_SOURCE_BITS; + prometheus_exporter_instance->config.options |= global_exporting_options & EXPORTING_OPTIONS_SOURCE_BITS; - char *data_source = prometheus_config_get("data source", global_backend_source); + char *data_source = prometheus_config_get("data source", "average"); prometheus_exporter_instance->config.options = exporting_parse_data_source(data_source, prometheus_exporter_instance->config.options); if (prometheus_config_get_boolean( - "send names instead of ids", global_backend_options & EXPORTING_OPTION_SEND_NAMES)) + "send names instead of ids", global_exporting_options & EXPORTING_OPTION_SEND_NAMES)) prometheus_exporter_instance->config.options |= EXPORTING_OPTION_SEND_NAMES; else prometheus_exporter_instance->config.options &= ~EXPORTING_OPTION_SEND_NAMES; @@ -268,18 +264,17 @@ struct engine *read_exporting_config() prometheus_exporter_instance->config.options &= ~EXPORTING_OPTION_SEND_AUTOMATIC_LABELS; prometheus_exporter_instance->config.charts_pattern = simple_pattern_create( - prometheus_config_get("send charts matching", global_backend_send_charts_matching), + prometheus_config_get("send charts matching", "*"), NULL, SIMPLE_PATTERN_EXACT); prometheus_exporter_instance->config.hosts_pattern = simple_pattern_create( prometheus_config_get("send hosts matching", "localhost *"), NULL, SIMPLE_PATTERN_EXACT); - prometheus_exporter_instance->config.prefix = prometheus_config_get("prefix", global_backend_prefix); + prometheus_exporter_instance->config.prefix = prometheus_config_get("prefix", global_exporting_prefix); prometheus_exporter_instance->config.initialized = 1; } - // TODO: change BACKEND to EXPORTING while (get_connector_instance(&local_ci)) { info("Processing connector instance (%s)", local_ci.instance_name); @@ -290,7 +285,7 @@ struct engine *read_exporting_config() tmp_ci_list = (struct connector_instance_list *)callocz(1, sizeof(struct connector_instance_list)); memcpy(&tmp_ci_list->local_ci, &local_ci, sizeof(local_ci)); - tmp_ci_list->backend_type = exporting_select_type(local_ci.connector_name); + tmp_ci_list->exporting_type = exporting_select_type(local_ci.connector_name); tmp_ci_list->next = tmp_ci_list_prev; tmp_ci_list_prev = tmp_ci_list; instances_to_activate++; @@ -320,34 +315,34 @@ struct engine *read_exporting_config() info("Instance %s on %s", tmp_ci_list->local_ci.instance_name, tmp_ci_list->local_ci.connector_name); - if (tmp_ci_list->backend_type == EXPORTING_CONNECTOR_TYPE_UNKNOWN) { + if (tmp_ci_list->exporting_type == EXPORTING_CONNECTOR_TYPE_UNKNOWN) { error("Unknown exporting connector type"); goto next_connector_instance; } #ifndef ENABLE_PROMETHEUS_REMOTE_WRITE - if (tmp_ci_list->backend_type == EXPORTING_CONNECTOR_TYPE_PROMETHEUS_REMOTE_WRITE) { + if (tmp_ci_list->exporting_type == EXPORTING_CONNECTOR_TYPE_PROMETHEUS_REMOTE_WRITE) { error("Prometheus Remote Write support isn't compiled"); goto next_connector_instance; } #endif #ifndef HAVE_KINESIS - if (tmp_ci_list->backend_type == EXPORTING_CONNECTOR_TYPE_KINESIS) { + if (tmp_ci_list->exporting_type == EXPORTING_CONNECTOR_TYPE_KINESIS) { error("AWS Kinesis support isn't compiled"); goto next_connector_instance; } #endif #ifndef ENABLE_EXPORTING_PUBSUB - if (tmp_ci_list->backend_type == EXPORTING_CONNECTOR_TYPE_PUBSUB) { + if (tmp_ci_list->exporting_type == EXPORTING_CONNECTOR_TYPE_PUBSUB) { error("Google Cloud Pub/Sub support isn't compiled"); goto next_connector_instance; } #endif #ifndef HAVE_MONGOC - if (tmp_ci_list->backend_type == EXPORTING_CONNECTOR_TYPE_MONGODB) { + if (tmp_ci_list->exporting_type == EXPORTING_CONNECTOR_TYPE_MONGODB) { error("MongoDB support isn't compiled"); goto next_connector_instance; } @@ -358,7 +353,7 @@ struct engine *read_exporting_config() engine->instance_root = tmp_instance; tmp_instance->engine = engine; - tmp_instance->config.type = tmp_ci_list->backend_type; + tmp_instance->config.type = tmp_ci_list->exporting_type; instance_name = tmp_ci_list->local_ci.instance_name; diff --git a/exporting/send_data.c b/exporting/send_data.c index 0f5e41929..ed649b640 100644 --- a/exporting/send_data.c +++ b/exporting/send_data.c @@ -41,7 +41,7 @@ int exporting_discard_response(BUFFER *buffer, struct instance *instance) { *d = '\0'; debug( - D_BACKEND, + D_EXPORTING, "EXPORTING: received %zu bytes from %s connector instance. Ignoring them. Sample: '%s'", buffer_strlen(buffer), instance->config.name, diff --git a/exporting/tests/test_exporting_engine.c b/exporting/tests/test_exporting_engine.c index fb08ff43b..4e1addbb5 100644 --- a/exporting/tests/test_exporting_engine.c +++ b/exporting/tests/test_exporting_engine.c @@ -14,11 +14,6 @@ char *netdata_configured_hostname = "test_global_host"; char log_line[MAX_LOG_LINE + 1]; -BACKEND_OPTIONS global_backend_options = 0; -const char *global_backend_source = "average"; -const char *global_backend_prefix = "netdata"; -const char *global_backend_send_charts_matching = "*"; - void init_connectors_in_tests(struct engine *engine) { expect_function_call(__wrap_now_realtime_sec); @@ -235,7 +230,7 @@ static void test_rrdhost_is_exportable(void **state) assert_string_equal(log_line, "enabled exporting of host 'localhost' for instance 'instance_name'"); assert_ptr_not_equal(localhost->exporting_flags, NULL); - assert_int_equal(localhost->exporting_flags[0], RRDHOST_FLAG_BACKEND_SEND); + assert_int_equal(localhost->exporting_flags[0], RRDHOST_FLAG_EXPORTING_SEND); } static void test_false_rrdhost_is_exportable(void **state) @@ -255,7 +250,7 @@ static void test_false_rrdhost_is_exportable(void **state) assert_string_equal(log_line, "disabled exporting of host 'localhost' for instance 'instance_name'"); assert_ptr_not_equal(localhost->exporting_flags, NULL); - assert_int_equal(localhost->exporting_flags[0], RRDHOST_FLAG_BACKEND_DONT_SEND); + assert_int_equal(localhost->exporting_flags[0], RRDHOST_FLAG_EXPORTING_DONT_SEND); } static void test_rrdset_is_exportable(void **state) diff --git a/health/Makefile.am b/health/Makefile.am index 349b86d61..d5eb88468 100644 --- a/health/Makefile.am +++ b/health/Makefile.am @@ -27,7 +27,6 @@ dist_healthconfig_DATA = \ health.d/adaptec_raid.conf \ health.d/anomalies.conf \ health.d/apcupsd.conf \ - health.d/backend.conf \ health.d/bcache.conf \ health.d/beanstalkd.conf \ health.d/bind_rndc.conf \ @@ -46,7 +45,6 @@ dist_healthconfig_DATA = \ health.d/fping.conf \ health.d/geth.conf \ health.d/ioping.conf \ - health.d/fronius.conf \ health.d/gearman.conf \ health.d/go.d.plugin.conf \ health.d/haproxy.conf \ @@ -66,6 +64,7 @@ dist_healthconfig_DATA = \ health.d/mysql.conf \ health.d/net.conf \ health.d/netfilter.conf \ + health.d/nut.conf \ health.d/pihole.conf \ health.d/portcheck.conf \ health.d/processes.conf \ @@ -77,7 +76,6 @@ dist_healthconfig_DATA = \ health.d/riakkv.conf \ health.d/scaleio.conf \ health.d/softnet.conf \ - health.d/stiebeleltron.conf \ health.d/synchronization.conf \ health.d/swap.conf \ health.d/systemdunits.conf \ diff --git a/health/QUICKSTART.md b/health/QUICKSTART.md index bc91caf7c..5cf6929dc 100644 --- a/health/QUICKSTART.md +++ b/health/QUICKSTART.md @@ -52,8 +52,8 @@ Navigate to the health configuration directory to see all the available files an cd /usr/lib/netdata/conf.d/health.d/ ls adaptec_raid.conf entropy.conf memory.conf squid.conf -am2320.conf fping.conf mongodb.conf stiebeleltron.conf -apache.conf fronius.conf mysql.conf swap.conf +am2320.conf fping.conf mongodb.conf +apache.conf mysql.conf swap.conf ... ``` @@ -140,4 +140,4 @@ Or, get guided insights into specific health configurations with our [health gui Finally, move on to Netdata's [notification system](/health/notifications/README.md) to learn more about how Netdata can let you know when the health of your systems or apps goes awry. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fquickstart%2F&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/README.md b/health/README.md index 37f09e848..2b1caf548 100644 --- a/health/README.md +++ b/health/README.md @@ -35,4 +35,4 @@ content. **[Notifications](/health/notifications/README.md)**: Get notified about ongoing alarms from your Agents via your favorite platform(s), such as Slack, Discord, PagerDuty, email, and much more. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/REFERENCE.md b/health/REFERENCE.md index 4feb782d6..3c1e53b2a 100644 --- a/health/REFERENCE.md +++ b/health/REFERENCE.md @@ -82,6 +82,7 @@ Netdata parses the following lines. Beneath the table is an in-depth explanation | [`repeat`](#alarm-line-repeat) | no | The interval for sending notifications when an alarm is in WARNING or CRITICAL mode. | | [`options`](#alarm-line-options) | no | Add an option to not clear alarms. | | [`host labels`](#alarm-line-host-labels) | no | List of labels present on a host. | +| [`info`](#alarm-line-info) | no | A brief description of the alarm. | The `alarm` or `template` line must be the first line of any entity. @@ -311,7 +312,7 @@ Everything is the same with [badges](/web/api/badges/README.md). In short: above too). - `OPTIONS` is a space separated list of `percentage`, `absolute`, `min2max`, `unaligned`, - `match-ids`, `match-names`. Check the badges documentation for more info. + `match-ids`, `match-names`. Check the [badges](/web/api/badges/README.md) documentation for more info. - `of DIMENSIONS` is optional and has to be the last parameter. Dimensions have to be separated by `,` or `|`. The space characters found in dimensions will be kept as-is (a few dimensions @@ -533,6 +534,14 @@ host labels: installed = 201* See our [simple patterns docs](/libnetdata/simple_pattern/README.md) for more examples. +#### Alarm line `info` + +The info field can contain a small piece of text describing the alarm or template. This will be rendered in notifications and UI elements whenever the specific alarm is in focus. An example for the `ram_available` alarm is: + +```yaml +info: percentage of estimated amount of RAM available for userspace processes, without causing swapping +``` + ## Expressions Netdata has an internal [infix expression parser](/libnetdata/eval). This parses expressions and creates an internal @@ -913,4 +922,4 @@ to temporary disable notifications (for instance when running backups triggers a notifications are runtime. The health checks can be controlled at runtime via the [health management api](/web/api/health/README.md). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Freference%2F&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/health.c b/health/health.c index e94339fae..528238d74 100644 --- a/health/health.c +++ b/health/health.c @@ -223,6 +223,8 @@ void health_reload(void) { if (netdata_cloud_setting) aclk_single_update_disable(); #endif + sql_refresh_hashes(); + rrd_rdlock(); RRDHOST *host; @@ -653,6 +655,41 @@ static int update_disabled_silenced(RRDHOST *host, RRDCALC *rc) { return 0; } +// Create alarms for dimensions that have been added to charts +// since the previous iteration. +static void init_pending_foreach_alarms(RRDHOST *host) { + rrdhost_wrlock(host); + + if (host->alarms_with_foreach || host->alarms_template_with_foreach) { + if (rrdhost_flag_check(host, RRDHOST_FLAG_PENDING_FOREACH_ALARMS)) { + RRDSET *st; + + rrdset_foreach_read(st, host) { + rrdset_wrlock(st); + + if (rrdset_flag_check(st, RRDSET_FLAG_PENDING_FOREACH_ALARMS)) { + RRDDIM *rd; + + rrddim_foreach_write(rd, st) { + if (rrddim_flag_check(rd, RRDDIM_FLAG_PENDING_FOREACH_ALARM)) { + rrdcalc_link_to_rrddim(rd, st, host); + rrddim_flag_clear(rd, RRDDIM_FLAG_PENDING_FOREACH_ALARM); + } + } + + rrdset_flag_clear(st, RRDSET_FLAG_PENDING_FOREACH_ALARMS); + } + + rrdset_unlock(st); + } + + rrdhost_flag_clear(host, RRDHOST_FLAG_PENDING_FOREACH_ALARMS); + } + } + + rrdhost_unlock(host); +} + /** * Health Main * @@ -737,6 +774,8 @@ void *health_main(void *ptr) { if(likely(!host->health_log_fp) && (loop == 1 || loop % cleanup_sql_every_loop == 0)) sql_health_alarm_log_cleanup(host); + init_pending_foreach_alarms(host); + rrdhost_rdlock(host); // the first loop is to lookup values from the db @@ -745,6 +784,33 @@ void *health_main(void *ptr) { if (update_disabled_silenced(host, rc)) continue; + // create an alert removed event if the chart is obsolete and + // has stopped being collected for 60 seconds + if (unlikely(rc->rrdset && rc->status != RRDCALC_STATUS_REMOVED && + rrdset_flag_check(rc->rrdset, RRDSET_FLAG_OBSOLETE) && + now > (rc->rrdset->last_collected_time.tv_sec + 60))) { + if (!rrdcalc_isrepeating(rc)) { + time_t now = now_realtime_sec(); + ALARM_ENTRY *ae = health_create_alarm_entry( + host, rc->id, rc->next_event_id++, rc->config_hash_id, now, rc->name, rc->rrdset->id, + rc->rrdset->family, rc->classification, rc->component, rc->type, rc->exec, rc->recipient, now - rc->last_status_change, + rc->value, NAN, rc->status, RRDCALC_STATUS_REMOVED, rc->source, rc->units, rc->info, 0, 0); + if (ae) { + health_alarm_log(host, ae); + rc->old_status = rc->status; + rc->status = RRDCALC_STATUS_REMOVED; + rc->last_status_change = now; + rc->last_updated = now; + rc->value = NAN; +#if defined(ENABLE_ACLK) && defined(ENABLE_NEW_CLOUD_PROTOCOL) + if (netdata_cloud_setting && likely(!aclk_alert_reloaded)) + sql_queue_removed_alerts_to_aclk(host); +#endif + } + } + continue; + } + if (unlikely(!rrdcalc_isrunnable(rc, now, &next_run))) { if (unlikely(rc->rrdcalc_flags & RRDCALC_FLAG_RUNNABLE)) rc->rrdcalc_flags &= ~RRDCALC_FLAG_RUNNABLE; @@ -764,7 +830,7 @@ void *health_main(void *ptr) { int ret = rrdset2value_api_v1(rc->rrdset, NULL, &rc->value, rc->dimensions, 1, rc->after, rc->before, rc->group, 0, rc->options, &rc->db_after, - &rc->db_before, &value_is_null + &rc->db_before, &value_is_null, 0 ); if (unlikely(ret != 200)) { @@ -1004,7 +1070,7 @@ void *health_main(void *ptr) { RRDCALC *rc; for(rc = host->alarms; rc ; rc = rc->next) { int repeat_every = 0; - if(unlikely(rrdcalc_isrepeating(rc))) { + if(unlikely(rrdcalc_isrepeating(rc) && rc->delay_up_to_timestamp <= now)) { if(unlikely(rc->status == RRDCALC_STATUS_WARNING)) { rc->rrdcalc_flags &= ~RRDCALC_FLAG_RUN_ONCE; repeat_every = rc->warn_repeat_every; diff --git a/health/health.d/backend.conf b/health/health.d/backend.conf deleted file mode 100644 index 91d469395..000000000 --- a/health/health.d/backend.conf +++ /dev/null @@ -1,42 +0,0 @@ -# Alert that backends subsystem will be disabled soon - alarm: backend_metrics_eol - on: netdata.backend_metrics - class: Errors - type: Netdata -component: Exporting engine - units: boolean - calc: $now - $last_collected_t - every: 1m - warn: $this > 0 - delay: down 5m multiplier 1.5 max 1h - info: the backends subsystem is deprecated and will be removed soon. Migrate your configuration to exporting.conf. - to: sysadmin - -# make sure we are sending data to backend - - alarm: backend_last_buffering - on: netdata.backend_metrics - class: Latency - type: Netdata -component: Exporting engine - calc: $now - $last_collected_t - units: seconds ago - every: 10s - warn: $this > (($status >= $WARNING) ? ($update_every) : ( 5 * $update_every)) - crit: $this > (($status == $CRITICAL) ? ($update_every) : (60 * $update_every)) - delay: down 5m multiplier 1.5 max 1h - info: number of seconds since the last successful buffering of backend data - to: dba - - alarm: backend_metrics_sent - on: netdata.backend_metrics - class: Workload - type: Netdata -component: Exporting engine - units: % - calc: abs($sent) * 100 / abs($buffered) - every: 10s - warn: $this != 100 - delay: down 5m multiplier 1.5 max 1h - info: percentage of metrics sent to the backend server - to: dba diff --git a/health/health.d/cgroups.conf b/health/health.d/cgroups.conf index 45b34806c..aa416c795 100644 --- a/health/health.d/cgroups.conf +++ b/health/health.d/cgroups.conf @@ -32,3 +32,40 @@ component: Memory delay: down 15m multiplier 1.5 max 1h info: cgroup memory utilization to: sysadmin + +# ----------------------------------------------------------------------------- +# check for packet storms + +# 1. calculate the rate packets are received in 1m: 1m_received_packets_rate +# 2. do the same for the last 10s +# 3. raise an alarm if the later is 10x or 20x the first +# we assume the minimum packet storm should at least have +# 10000 packets/s, average of the last 10 seconds + + template: cgroup_1m_received_packets_rate + on: cgroup.net_packets + class: Workload + type: Cgroups +component: Network + hosts: * + lookup: average -1m unaligned of received + units: packets + every: 10s + info: average number of packets received by the network interface $family over the last minute + + template: cgroup_10s_received_packets_storm + on: cgroup.net_packets + class: Workload + type: Cgroups +component: Network + hosts: * + lookup: average -10s unaligned of received + calc: $this * 100 / (($1m_received_packets_rate < 1000)?(1000):($1m_received_packets_rate)) + every: 10s + units: % + warn: $this > (($status >= $WARNING)?(200):(5000)) + crit: $this > (($status == $CRITICAL)?(5000):(6000)) + options: no-clear-notification + info: ratio of average number of received packets for the network interface $family over the last 10 seconds, \ + compared to the rate over the last minute + to: sysadmin diff --git a/health/health.d/fronius.conf b/health/health.d/fronius.conf deleted file mode 100644 index 853bd7fbc..000000000 --- a/health/health.d/fronius.conf +++ /dev/null @@ -1,14 +0,0 @@ - template: fronius_last_collected_secs - families: * - on: fronius.power - class: Latency - type: Power Supply -component: Solar - calc: $now - $last_collected_t - every: 10s - units: seconds ago - warn: $this > (($status >= $WARNING) ? ($update_every) : ( 5 * $update_every)) - crit: $this > (($status == $CRITICAL) ? ($update_every) : (60 * $update_every)) - delay: down 5m multiplier 1.5 max 1h - info: number of seconds since the last successful data collection - to: sitemgr diff --git a/health/health.d/ioping.conf b/health/health.d/ioping.conf index ee4befbea..8b498ad3c 100644 --- a/health/health.d/ioping.conf +++ b/health/health.d/ioping.conf @@ -4,12 +4,12 @@ class: Latency type: System component: Disk - lookup: average -10s unaligned of average - units: ms + lookup: average -10s unaligned of latency + units: microseconds every: 10s - green: 500 - red: 1000 - warn: $this > $green OR $max > $red + green: 5000 + red: 10000 + warn: $this > $green crit: $this > $red delay: down 30m multiplier 1.5 max 2h info: average I/O latency over the last 10 seconds diff --git a/health/health.d/net.conf b/health/health.d/net.conf index 028ca7b81..9d5b3b8d3 100644 --- a/health/health.d/net.conf +++ b/health/health.d/net.conf @@ -68,7 +68,7 @@ component: Network component: Network os: linux hosts: * - families: !net* * + families: * lookup: sum -10m unaligned absolute of inbound units: packets every: 1m @@ -81,7 +81,7 @@ component: Network component: Network os: linux hosts: * - families: !net* * + families: * lookup: sum -10m unaligned absolute of outbound units: packets every: 1m @@ -94,7 +94,7 @@ component: Network component: Network os: linux hosts: * - families: !net* !wl* * + families: !wl* * lookup: sum -10m unaligned absolute of received calc: (($inbound_packets_dropped != nan AND $this > 10000) ? ($inbound_packets_dropped * 100 / $this) : (0)) units: % @@ -111,7 +111,7 @@ component: Network component: Network os: linux hosts: * - families: !net* !wl* * + families: !wl* * lookup: sum -10m unaligned absolute of sent calc: (($outbound_packets_dropped != nan AND $this > 1000) ? ($outbound_packets_dropped * 100 / $this) : (0)) units: % diff --git a/health/health.d/nut.conf b/health/health.d/nut.conf new file mode 100644 index 000000000..6231dd97b --- /dev/null +++ b/health/health.d/nut.conf @@ -0,0 +1,47 @@ +# you can disable an alarm notification by setting the 'to' line to: silent + + template: nut_10min_ups_load + on: nut.load + class: Utilization + type: Power Supply +component: UPS + os: * + hosts: * + lookup: average -10m unaligned of load + units: % + every: 1m + warn: $this > (($status >= $WARNING) ? (70) : (80)) + crit: $this > (($status == $CRITICAL) ? (85) : (95)) + delay: down 10m multiplier 1.5 max 1h + info: average UPS load over the last 10 minutes + to: sitemgr + + template: nut_ups_charge + on: nut.charge + class: Errors + type: Power Supply +component: UPS + os: * + hosts: * + lookup: average -60s unaligned of battery_charge + units: % + every: 60s + warn: $this < 100 + crit: $this < (($status == $CRITICAL) ? (60) : (50)) + delay: down 10m multiplier 1.5 max 1h + info: average UPS charge over the last minute + to: sitemgr + + template: nut_last_collected_secs + on: nut.load + class: Latency + type: Power Supply +component: UPS device + calc: $now - $last_collected_t + every: 10s + units: seconds ago + warn: $this > (($status >= $WARNING) ? ($update_every) : ( 5 * $update_every)) + crit: $this > (($status == $CRITICAL) ? ($update_every) : (60 * $update_every)) + delay: down 5m multiplier 1.5 max 1h + info: number of seconds since the last successful data collection + to: sitemgr diff --git a/health/health.d/stiebeleltron.conf b/health/health.d/stiebeleltron.conf deleted file mode 100644 index 493c8b73a..000000000 --- a/health/health.d/stiebeleltron.conf +++ /dev/null @@ -1,14 +0,0 @@ - template: stiebeleltron_last_collected_secs - families: * - on: stiebeleltron.heating.hc1 - class: Latency - type: Other -component: Sensors - calc: $now - $last_collected_t - every: 10s - units: seconds ago - warn: $this > (($status >= $WARNING) ? ($update_every) : ( 5 * $update_every)) - crit: $this > (($status == $CRITICAL) ? ($update_every) : (60 * $update_every)) - delay: down 5m multiplier 1.5 max 1h - info: number of seconds since the last successful data collection - to: sitemgr diff --git a/health/health.d/tcp_resets.conf b/health/health.d/tcp_resets.conf index 190271e47..35cb6366c 100644 --- a/health/health.d/tcp_resets.conf +++ b/health/health.d/tcp_resets.conf @@ -26,7 +26,7 @@ component: Network lookup: average -10s unaligned absolute of OutRsts units: tcp resets/s every: 10s - warn: $this > ((($1m_ipv4_tcp_resets_sent < 5)?(5):($1m_ipv4_tcp_resets_sent)) * (($status >= $WARNING) ? (1) : (20))) + warn: $this > ((($1m_ipv4_tcp_resets_sent < 5)?(5):($1m_ipv4_tcp_resets_sent)) * (($status >= $WARNING) ? (1) : (10))) delay: up 20s down 60m multiplier 1.2 max 2h options: no-clear-notification info: average number of sent TCP RESETS over the last 10 seconds. \ diff --git a/health/health.d/timex.conf b/health/health.d/timex.conf index ea90c4000..23c18ba10 100644 --- a/health/health.d/timex.conf +++ b/health/health.d/timex.conf @@ -13,5 +13,5 @@ component: Clock every: 10s warn: $system.uptime.uptime > 17 * 60 AND $this == 0 delay: down 5m - info: the system time is not synchronized to a reliable server + info: when set to 0, the system kernel believes the system clock is not properly synchronized to a reliable server to: silent diff --git a/health/health.h b/health/health.h index 323279bac..f25ae6bc6 100644 --- a/health/health.h +++ b/health/health.h @@ -87,6 +87,7 @@ extern void *health_cmdapi_thread(void *ptr); extern void health_label_log_save(RRDHOST *host); extern char *health_edit_command_from_source(const char *source); +extern void sql_refresh_hashes(void); extern SIMPLE_PATTERN *health_pattern_from_foreach(char *s); diff --git a/health/health_config.c b/health/health_config.c index da71f13d8..e1f5f0e31 100644 --- a/health/health_config.c +++ b/health/health_config.c @@ -538,6 +538,7 @@ static inline void alert_config_free(struct alert_config *cfg) freez(cfg); } +int sql_store_hashes = 1; static int health_readfile(const char *filename, void *data) { RRDHOST *host = (RRDHOST *)data; @@ -662,17 +663,15 @@ static int health_readfile(const char *filename, void *data) { if(hash == hash_alarm && !strcasecmp(key, HEALTH_ALARM_KEY)) { if(rc) { - if(ignore_this || !alert_hash_and_store_config(rc->config_hash_id, alert_cfg) || !rrdcalc_add_alarm_from_config(host, rc)) { + if(!alert_hash_and_store_config(rc->config_hash_id, alert_cfg, sql_store_hashes) || ignore_this || !rrdcalc_add_alarm_from_config(host, rc)) { rrdcalc_free(rc); - alert_config_free(alert_cfg); } // health_add_alarms_loop(host, rc, ignore_this) ; } if(rt) { - if (ignore_this || !alert_hash_and_store_config(rt->config_hash_id, alert_cfg) || !rrdcalctemplate_add_template_from_config(host, rt)) { + if (!alert_hash_and_store_config(rt->config_hash_id, alert_cfg, sql_store_hashes) || ignore_this || !rrdcalctemplate_add_template_from_config(host, rt)) { rrdcalctemplate_free(rt); - alert_config_free(alert_cfg); } rt = NULL; } @@ -690,6 +689,8 @@ static int health_readfile(const char *filename, void *data) { rc->old_status = RRDCALC_STATUS_UNINITIALIZED; rc->warn_repeat_every = host->health_default_warn_repeat_every; rc->crit_repeat_every = host->health_default_crit_repeat_every; + if (alert_cfg) + alert_config_free(alert_cfg); alert_cfg = callocz(1, sizeof(struct alert_config)); if(rrdvar_fix_name(rc->name)) @@ -701,18 +702,16 @@ static int health_readfile(const char *filename, void *data) { else if(hash == hash_template && !strcasecmp(key, HEALTH_TEMPLATE_KEY)) { if(rc) { // health_add_alarms_loop(host, rc, ignore_this) ; - if(ignore_this || !alert_hash_and_store_config(rc->config_hash_id, alert_cfg) || !rrdcalc_add_alarm_from_config(host, rc)) { + if(!alert_hash_and_store_config(rc->config_hash_id, alert_cfg, sql_store_hashes) || ignore_this || !rrdcalc_add_alarm_from_config(host, rc)) { rrdcalc_free(rc); - alert_config_free(alert_cfg); } rc = NULL; } if(rt) { - if(ignore_this || !alert_hash_and_store_config(rt->config_hash_id, alert_cfg) || !rrdcalctemplate_add_template_from_config(host, rt)) { + if(!alert_hash_and_store_config(rt->config_hash_id, alert_cfg, sql_store_hashes) || ignore_this || !rrdcalctemplate_add_template_from_config(host, rt)) { rrdcalctemplate_free(rt); - alert_config_free(alert_cfg); } } @@ -725,6 +724,8 @@ static int health_readfile(const char *filename, void *data) { rt->delay_multiplier = 1.0; rt->warn_repeat_every = host->health_default_warn_repeat_every; rt->crit_repeat_every = host->health_default_crit_repeat_every; + if (alert_cfg) + alert_config_free(alert_cfg); alert_cfg = callocz(1, sizeof(struct alert_config)); if(rrdvar_fix_name(rt->name)) @@ -1225,13 +1226,13 @@ static int health_readfile(const char *filename, void *data) { if(rc) { //health_add_alarms_loop(host, rc, ignore_this) ; - if(ignore_this || !alert_hash_and_store_config(rc->config_hash_id, alert_cfg) || !rrdcalc_add_alarm_from_config(host, rc)) { + if(!alert_hash_and_store_config(rc->config_hash_id, alert_cfg, sql_store_hashes) || ignore_this || !rrdcalc_add_alarm_from_config(host, rc)) { rrdcalc_free(rc); } } if(rt) { - if(ignore_this || !alert_hash_and_store_config(rt->config_hash_id, alert_cfg) || !rrdcalctemplate_add_template_from_config(host, rt)) { + if(!alert_hash_and_store_config(rt->config_hash_id, alert_cfg, sql_store_hashes) || ignore_this || !rrdcalctemplate_add_template_from_config(host, rt)) { rrdcalctemplate_free(rt); } } @@ -1243,6 +1244,11 @@ static int health_readfile(const char *filename, void *data) { return 1; } +void sql_refresh_hashes(void) +{ + sql_store_hashes = 1; +} + void health_readdir(RRDHOST *host, const char *user_path, const char *stock_path, const char *subpath) { if(unlikely(!host->health_enabled)) { debug(D_HEALTH, "CONFIG health is not enabled for host '%s'", host->hostname); @@ -1258,4 +1264,5 @@ void health_readdir(RRDHOST *host, const char *user_path, const char *stock_path } recursive_config_double_dir_load(user_path, stock_path, subpath, health_readfile, (void *) host, 0); + sql_store_hashes = 0; } diff --git a/health/notifications/README.md b/health/notifications/README.md index 53541981d..0bd6c7649 100644 --- a/health/notifications/README.md +++ b/health/notifications/README.md @@ -83,4 +83,4 @@ bash -x /usr/libexec/netdata/plugins.d/alarm-notify.sh test ``` Then look in the output for the alarm-notify.sh calls and run the one you want to trace with `bash -x`. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/alerta/README.md b/health/notifications/alerta/README.md index 85a0cd488..9603aae01 100644 --- a/health/notifications/alerta/README.md +++ b/health/notifications/alerta/README.md @@ -78,4 +78,4 @@ We can test alarms using the standard approach: For more information see the [Alerta documentation](https://docs.alerta.io) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Falerta%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/awssns/README.md b/health/notifications/awssns/README.md index c68251379..fc4a665e9 100644 --- a/health/notifications/awssns/README.md +++ b/health/notifications/awssns/README.md @@ -6,7 +6,8 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/health/notificat # Amazon SNS -As part of it's AWS suite, Amazon provides a notification broker service called 'Simple Notification Service' or SNS. Amazon SNS works kind of similarly to Netdata's own notification system, allowing dispatch of a single notification to multiple subscribers of different types. Among other things, SNS supports sending notifications to: +As part of its AWS suite, Amazon provides a notification broker service called 'Simple Notification Service' (SNS). Amazon SNS works similarly to Netdata's own notification system, allowing to dispatch a single notification to multiple subscribers of different types. While Amazon SNS supports sending differently formatted messages for different delivery methods, Netdata does not currently support this functionality. +Among other things, SNS supports sending notifications to: - Email addresses. - Mobile Phones via SMS. @@ -15,29 +16,38 @@ As part of it's AWS suite, Amazon provides a notification broker service called - AWS SQS queues. - Mobile applications via push notifications. -To get this working, you will need: +For email notification support, we recommend using Netdata's email notifications, as it is has the following benefits: -- The Amazon Web Services CLI tools. Most distributions provide these with the package name `awscli`. -- An actual home directory for the user you run Netdata as, instead of just using `/` as a home directory. Setup of this is distribution specific. `/var/lib/netdata` is the recommended directory (because the permissions will already be correct) if you are using a dedicated user (which is how most distributions work). -- An Amazon SNS topic to send notifications to with one or more subscribers. The [Getting - Started](https://docs.aws.amazon.com/sns/latest/dg/sns-getting-started.html) section of the Amazon SNS documentation - covers the basics of how to set this up. Make note of the Topic ARN when you create the topic. -- While not mandatory, it is highly recommended to create a dedicated IAM user on your account for Netdata to send notifications. This user needs to have programmatic access, and should only allow access to SNS. If you're really paranoid, you can create one for each system or group of systems. +- In most cases, it requires less configuration. +- Netdata's emails are nicely pre-formatted and support features like threading, which requires a lot of manual effort in SNS. +- It is less resource intensive and more cost-efficient than SNS. -Once you have all the above, run the following command as the user Netdata runs under: +Read on to learn how to set up Amazon SNS in Netdata. -``` -aws configure -``` +## Prerequisites -THis will prompt you for the access key and secret key for accessing Amazon SNS (as well as the default region and output format, but you can leave those blank because we don't use them). +Before you can enable SNS, you need: -Once that's done, you're ready to go and can specify the desired topic ARN as a recipient. +- The [Amazon Web Services CLI tools](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) (`awscli`). +- An actual home directory for the user you run Netdata as, instead of just using `/` as a home directory. The setup depends on the distribution, but `/var/lib/netdata` is the recommended directory. If you are using Netdata as a dedicated user, the permissions will already be correct. +- An Amazon SNS topic to send notifications to with one or more subscribers. The [Getting Started](https://docs.aws.amazon.com/sns/latest/dg/sns-getting-started.html) section of the Amazon SNS documentation covers the basics of how to set this up. Make note of the **Topic ARN** when you create the topic. +- While not mandatory, it is highly recommended to create a dedicated IAM user on your account for Netdata to send notifications. This user needs to have programmatic access, and should only allow access to SNS. For an additional layer of security, you can create one for each system or group of systems. -Notes: +## Enabling Amazon SNS -- Netdata's native email notification support is far better in almost all respects than it's support through Amazon SNS. If you want email notifications, use the native support, not SNS. - - If you need to change the notification format for SNS notifications, you can do so by specifying the format in `AWSSNS_MESSAGE_FORMAT` in the configuration. This variable supports all the same variables you can use in custom notifications. - - While Amazon SNS supports sending differently formatted messages for different delivery methods, Netdata does not currently support this functionality. +To enable SNS: +1. Run the following command as the user Netdata runs under: + ``` + aws configure + ``` +2. Enter the access key and secret key for accessing Amazon SNS. The system also prompts you to enter the default region and output format, but you can leave those blank because Netdata doesn't use them. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Fawssns%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) +3. Specify the desired topic ARN as a recipient, see [SNS documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/US_SetupSNS.html#set-up-sns-topic-cli). +4. Optional: To change the notification format for SNS notifications, change the `AWSSNS_MESSAGE_FORMAT` variable in `health_alarm_notify.conf`. +This variable supports all the same variables you can use in custom notifications. + + The default format looks like this: + ```bash + AWSSNS_MESSAGE_FORMAT="${status} on ${host} at ${date}: ${chart} ${value_string}" + ``` + diff --git a/health/notifications/custom/README.md b/health/notifications/custom/README.md index bcb09ef53..edc42623d 100644 --- a/health/notifications/custom/README.md +++ b/health/notifications/custom/README.md @@ -89,4 +89,4 @@ The following are more human friendly: - `${severity}` like "Escalated to CRITICAL", "Recovered from WARNING" - `${raised_for}` like "(alarm was raised for 10 minutes)" -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Fcustom%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/discord/README.md b/health/notifications/discord/README.md index 1650d9cec..568d03bc3 100644 --- a/health/notifications/discord/README.md +++ b/health/notifications/discord/README.md @@ -47,4 +47,4 @@ role_recipients_discord[webmaster]="marketing development" The keywords `systems`, `databases`, `marketing`, `development` are discordapp.com channels (they should already exist within your discord server). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Fdiscord%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/dynatrace/README.md b/health/notifications/dynatrace/README.md index cc82ee78d..3f8ad85b6 100644 --- a/health/notifications/dynatrace/README.md +++ b/health/notifications/dynatrace/README.md @@ -32,5 +32,3 @@ The default value is `CUSTOM_INFO`. This is a required parameter. 6. Specify the annotation type. This is the source of the Dynatrace event. Put whatever it fits you, for example, _Netdata Alarm_, which is also the default value. - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Fdynatrace%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]() diff --git a/health/notifications/email/README.md b/health/notifications/email/README.md index 82786fca1..3dc84dd40 100644 --- a/health/notifications/email/README.md +++ b/health/notifications/email/README.md @@ -74,4 +74,4 @@ sendmail="/usr/bin/msmtp" chmod 600 ~/.msmtprc ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Femail%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/flock/README.md b/health/notifications/flock/README.md index b24ecdb25..b9e0025b3 100644 --- a/health/notifications/flock/README.md +++ b/health/notifications/flock/README.md @@ -34,4 +34,4 @@ FLOCK_WEBHOOK_URL="https://api.flock.com/hooks/sendMessage/XXXXXXXXXXXXXXXXXXXXX DEFAULT_RECIPIENT_FLOCK="alarms" ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Fflock%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/hangouts/README.md b/health/notifications/hangouts/README.md index 886abfc43..7554b39cd 100644 --- a/health/notifications/hangouts/README.md +++ b/health/notifications/hangouts/README.md @@ -52,4 +52,4 @@ You can define multiple rooms like this: `sysadmin devops alarms|critical`. The keywords `sysadmin`, `devops`, and `alarms` are Hangouts rooms. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Fhangouts%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/irc/README.md b/health/notifications/irc/README.md index e7f22e1fd..21c998d11 100644 --- a/health/notifications/irc/README.md +++ b/health/notifications/irc/README.md @@ -75,4 +75,4 @@ role_recipients_irc[webmaster]="#networking-alarms" The keywords `#user-alarms`, `#networking-alarms`, `#system-alarms`, `#databases-alarms` are irc channels which belong to the specified IRC network. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Firc%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/kavenegar/README.md b/health/notifications/kavenegar/README.md index b59799fc2..6123eb901 100644 --- a/health/notifications/kavenegar/README.md +++ b/health/notifications/kavenegar/README.md @@ -43,4 +43,4 @@ KAVENEGAR_SENDER="" DEFAULT_RECIPIENT_KAVENEGAR="" ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Fkavenegar%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/matrix/README.md b/health/notifications/matrix/README.md index ea22b4a8a..8eeecf55d 100644 --- a/health/notifications/matrix/README.md +++ b/health/notifications/matrix/README.md @@ -55,4 +55,4 @@ MATRIX_ACCESSTOKEN="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" DEFAULT_RECIPIENT_MATRIX="!XXXXXXXXXXXX:matrix.org" ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Fmatrix%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/messagebird/README.md b/health/notifications/messagebird/README.md index 8e3d1a5b3..f70e86c68 100644 --- a/health/notifications/messagebird/README.md +++ b/health/notifications/messagebird/README.md @@ -42,4 +42,4 @@ MESSAGEBIRD_NUMBER="XXXXXXX" DEFAULT_RECIPIENT_MESSAGEBIRD="XXXXXXX" ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Fmessagebird%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/msteams/README.md b/health/notifications/msteams/README.md index 3ff5de68d..14dbe7511 100644 --- a/health/notifications/msteams/README.md +++ b/health/notifications/msteams/README.md @@ -42,4 +42,4 @@ role_recipients_msteams[dba]="YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY" role_recipients_msteams[webmaster]="ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Fmsteams%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/opsgenie/README.md b/health/notifications/opsgenie/README.md index 10b9f5242..640fcd42a 100644 --- a/health/notifications/opsgenie/README.md +++ b/health/notifications/opsgenie/README.md @@ -59,4 +59,4 @@ message: You can find more details about the Opsgenie error codes in their [response docs](https://docs.opsgenie.com/docs/response). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Fopsgenie%2FREADME%2FDonations-netdata-has-received&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/prowl/README.md b/health/notifications/prowl/README.md index 7c60de270..dc136820c 100644 --- a/health/notifications/prowl/README.md +++ b/health/notifications/prowl/README.md @@ -25,5 +25,3 @@ the Prowl website after registering. Once you have an API key, simply specify that as a recipient for Prowl notifications. - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Fprowl%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]() diff --git a/health/notifications/pushbullet/README.md b/health/notifications/pushbullet/README.md index 7c2f6774e..194050bc1 100644 --- a/health/notifications/pushbullet/README.md +++ b/health/notifications/pushbullet/README.md @@ -47,4 +47,4 @@ PUSHBULLET_ACCESS_TOKEN="o.Sometokenhere" DEFAULT_RECIPIENT_PUSHBULLET="admin1@example.com admin3@somemail.com #examplechanneltag #anotherchanneltag" ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Fpushbullet%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/pushover/README.md b/health/notifications/pushover/README.md index 3ba97fbc3..1e50f7140 100644 --- a/health/notifications/pushover/README.md +++ b/health/notifications/pushover/README.md @@ -20,4 +20,4 @@ pushover.net notifications look like this: ![image](https://cloud.githubusercontent.com/assets/2662304/18407319/839c10c4-7715-11e6-92c0-12f8215128d3.png) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Fpushover%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/rocketchat/README.md b/health/notifications/rocketchat/README.md index a54f5826c..96d6160b2 100644 --- a/health/notifications/rocketchat/README.md +++ b/health/notifications/rocketchat/README.md @@ -49,4 +49,4 @@ role_recipients_rocketchat[webmaster]="marketing development" The keywords `systems`, `databases`, `marketing`, `development` are RocketChat channels (they should already exist). Both public and private channels can be used, even if they differ from the channel configured in your RocketChat incoming webhook. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Frocketchat%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/slack/README.md b/health/notifications/slack/README.md index e338e9af0..ad36ce34a 100644 --- a/health/notifications/slack/README.md +++ b/health/notifications/slack/README.md @@ -47,4 +47,4 @@ role_recipients_slack[dba]="databases systems" role_recipients_slack[webmaster]="marketing development" ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Fslack%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/smstools3/README.md b/health/notifications/smstools3/README.md index 6d90e702a..6618dfa18 100644 --- a/health/notifications/smstools3/README.md +++ b/health/notifications/smstools3/README.md @@ -41,4 +41,4 @@ Netdata uses the script `sendsms` that is installed by `smstools3` and just pass sendsms="" ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Fsmstools3%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/stackpulse/README.md b/health/notifications/stackpulse/README.md index 4c44954ab..c478fd584 100644 --- a/health/notifications/stackpulse/README.md +++ b/health/notifications/stackpulse/README.md @@ -78,4 +78,4 @@ access the **TRIGGER** tab to define the scenarios used to trigger the event. Th For more details how to create a scenario, take a look at the [StackPulse documentation](https://docs.stackpulse.io). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Fopsgenie%2FREADME%2FDonations-netdata-has-received&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/syslog/README.md b/health/notifications/syslog/README.md index 360f6844d..8b7863a1a 100644 --- a/health/notifications/syslog/README.md +++ b/health/notifications/syslog/README.md @@ -31,4 +31,4 @@ The `facility` and `level` are the standard syslog facility and level options, f You can configure sending directly to remote log servers by specifying a host (and optionally a port). However, this has a somewhat high overhead, so it is much preferred to use your local syslog daemon to handle the forwarding of messages to remote systems (pretty much all of them allow at least simple forwarding, and most of the really popular ones support complex queueing and routing of messages to remote log servers). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Fsyslog%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/telegram/README.md b/health/notifications/telegram/README.md index c1c6f2a4e..2a2ed5623 100644 --- a/health/notifications/telegram/README.md +++ b/health/notifications/telegram/README.md @@ -42,4 +42,4 @@ Telegram messages look like this: ![Netdata notifications via Telegram](https://user-images.githubusercontent.com/1153921/66612223-f07dfb80-eb75-11e9-976f-5734ffd93ecd.png) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Ftelegram%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/twilio/README.md b/health/notifications/twilio/README.md index b36d40b99..b563c66c1 100644 --- a/health/notifications/twilio/README.md +++ b/health/notifications/twilio/README.md @@ -44,4 +44,4 @@ TWILIO_NUMBER="xxxxxxxxxxx" DEFAULT_RECIPIENT_TWILIO="+15555555555" ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Ftwilio%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/health/notifications/web/README.md b/health/notifications/web/README.md index 9e4918603..185843af5 100644 --- a/health/notifications/web/README.md +++ b/health/notifications/web/README.md @@ -10,4 +10,4 @@ The Netdata dashboard shows HTML notifications, when it is open. Such web notifications look like this: ![image](https://cloud.githubusercontent.com/assets/2662304/18407279/82bac6a6-7714-11e6-847e-c2e84eeacbfb.png) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Fweb%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/libnetdata/README.md b/libnetdata/README.md index cdb199f51..fe0690d68 100644 --- a/libnetdata/README.md +++ b/libnetdata/README.md @@ -7,4 +7,4 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/libnetdata/READM `libnetdata` is a collection of library code that is used by all Netdata `C` programs. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Flibnetdata%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/libnetdata/adaptive_resortable_list/README.md b/libnetdata/adaptive_resortable_list/README.md index 74e379a92..9eb942bc8 100644 --- a/libnetdata/adaptive_resortable_list/README.md +++ b/libnetdata/adaptive_resortable_list/README.md @@ -96,4 +96,4 @@ Compared to unoptimized code (test No 1: 4.6sec): Do not use ARL if the a name/keyword may appear more than once in the source data. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Flibnetdata%2Fadaptive_resortable_list%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/libnetdata/avl/README.md b/libnetdata/avl/README.md index 2097be57f..36392bd79 100644 --- a/libnetdata/avl/README.md +++ b/libnetdata/avl/README.md @@ -14,4 +14,4 @@ use any memory allocations and their memory footprint is optimized In addition to the above, this version of AVL, provides versions using locks and traversal functions. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Flibnetdata%2Favl%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/libnetdata/buffer/README.md b/libnetdata/buffer/README.md index 5a9d7b023..c5f66e6e3 100644 --- a/libnetdata/buffer/README.md +++ b/libnetdata/buffer/README.md @@ -13,5 +13,4 @@ Also, they are super fast in printing and appending data to the string and its ` is just a lookup (it does not traverse the string). Netdata uses `BUFFER`s for preparing web responses and buffering data to be sent upstream or -to backend databases. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Flibnetdata%2Fbuffer%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) +to external databases. diff --git a/libnetdata/buffer/buffer.c b/libnetdata/buffer/buffer.c index c37da21e1..8ea90985c 100644 --- a/libnetdata/buffer/buffer.c +++ b/libnetdata/buffer/buffer.c @@ -87,14 +87,19 @@ inline char *print_number_llu_r(char *str, unsigned long long uvalue) { } inline char *print_number_llu_r_smart(char *str, unsigned long long uvalue) { -#ifdef ENVIRONMENT32 - if(uvalue > (unsigned long long)0xffffffff) - str = print_number_llu_r(str, uvalue); - else - str = print_number_lu_r(str, uvalue); -#else - do *str++ = (char)('0' + (uvalue % 10)); while(uvalue /= 10); -#endif + switch (sizeof(void *)) { + case 4: + str = (uvalue > (unsigned long long) 0xffffffff) ? print_number_llu_r(str, uvalue) : + print_number_lu_r(str, uvalue); + break; + case 8: + do { + *str++ = (char) ('0' + (uvalue % 10)); + } while (uvalue /= 10); + break; + default: + fatal("Netdata supports only 32-bit & 64-bit systems."); + } return str; } @@ -106,14 +111,19 @@ void buffer_print_llu(BUFFER *wb, unsigned long long uvalue) char *str = &wb->buffer[wb->len]; char *wstr = str; -#ifdef ENVIRONMENT32 - if(uvalue > (unsigned long long)0xffffffff) - wstr = print_number_llu_r(wstr, uvalue); - else - wstr = print_number_lu_r(wstr, uvalue); -#else - do *wstr++ = (char)('0' + (uvalue % 10)); while(uvalue /= 10); -#endif + switch (sizeof(void *)) { + case 4: + wstr = (uvalue > (unsigned long long) 0xffffffff) ? print_number_llu_r(wstr, uvalue) : + print_number_lu_r(wstr, uvalue); + break; + case 8: + do { + *wstr++ = (char) ('0' + (uvalue % 10)); + } while (uvalue /= 10); + break; + default: + fatal("Netdata supports only 32-bit & 64-bit systems."); + } // terminate it *wstr = '\0'; diff --git a/libnetdata/circular_buffer/README.md b/libnetdata/circular_buffer/README.md index d36c05f5a..4482173d7 100644 --- a/libnetdata/circular_buffer/README.md +++ b/libnetdata/circular_buffer/README.md @@ -8,5 +8,3 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/libnetdata/circu `struct circular_buffer` is an adaptive circular buffer. It will start at an initial size and grow up to a maximum size as it fills. Two indices within the structure track the current `read` and `write` position for data. - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Flibnetdata%2Fcircular_buffer%2README&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]() diff --git a/libnetdata/clocks/README.md b/libnetdata/clocks/README.md index e53b86a61..3a7ce55f9 100644 --- a/libnetdata/clocks/README.md +++ b/libnetdata/clocks/README.md @@ -2,4 +2,4 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/libnetdata/clocks/README.md --> -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Flibnetdata%2Fclocks%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/libnetdata/config/README.md b/libnetdata/config/README.md index a71f1ee18..2eccf7a21 100644 --- a/libnetdata/config/README.md +++ b/libnetdata/config/README.md @@ -51,4 +51,4 @@ When you get the configuration file from the server, there will be a comment above all `name = value` pairs the server does not use. So you know that whatever you wrote there, is not used. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Flibnetdata%2Fconfig%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/libnetdata/config/appconfig.c b/libnetdata/config/appconfig.c index 37e9e7688..0daa6e5e4 100644 --- a/libnetdata/config/appconfig.c +++ b/libnetdata/config/appconfig.c @@ -591,7 +591,7 @@ int appconfig_load(struct config *root, char *filename, int overwrite_used, cons int line = 0; struct section *co = NULL; int is_exporter_config = 0; - int _backends = 0; // number of backend sections we have + int _connectors = 0; // number of exporting connector sections we have char working_instance[CONFIG_MAX_NAME + 1]; char working_connector[CONFIG_MAX_NAME + 1]; struct section *working_connector_section = NULL; @@ -641,8 +641,8 @@ int appconfig_load(struct config *root, char *filename, int overwrite_used, cons strncpy(working_connector, s, CONFIG_MAX_NAME); s = s + rc + 1; if (unlikely(!(*s))) { - _backends++; - sprintf(buffer, "instance_%d", _backends); + _connectors++; + sprintf(buffer, "instance_%d", _connectors); s = buffer; } strncpy(working_instance, s, CONFIG_MAX_NAME); @@ -793,7 +793,6 @@ void appconfig_generate(struct config *root, BUFFER *wb, int only_changed) || !strcmp(co->name, CONFIG_SECTION_CLOUD) || !strcmp(co->name, CONFIG_SECTION_REGISTRY) || !strcmp(co->name, CONFIG_SECTION_HEALTH) - || !strcmp(co->name, CONFIG_SECTION_BACKEND) || !strcmp(co->name, CONFIG_SECTION_STREAM) || !strcmp(co->name, CONFIG_SECTION_HOST_LABEL) || !strcmp(co->name, CONFIG_SECTION_ML) diff --git a/libnetdata/config/appconfig.h b/libnetdata/config/appconfig.h index bfc927353..b5cf77419 100644 --- a/libnetdata/config/appconfig.h +++ b/libnetdata/config/appconfig.h @@ -89,7 +89,6 @@ #define CONFIG_SECTION_CLOUD "cloud" #define CONFIG_SECTION_REGISTRY "registry" #define CONFIG_SECTION_HEALTH "health" -#define CONFIG_SECTION_BACKEND "backend" #define CONFIG_SECTION_STREAM "stream" #define CONFIG_SECTION_ML "ml" #define CONFIG_SECTION_EXPORTING "exporting:global" diff --git a/libnetdata/dictionary/README.md b/libnetdata/dictionary/README.md index 234ff1845..6049c7f66 100644 --- a/libnetdata/dictionary/README.md +++ b/libnetdata/dictionary/README.md @@ -2,4 +2,4 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/libnetdata/dictionary/README.md --> -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Flibnetdata%2Fdictionary%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/libnetdata/ebpf/README.md b/libnetdata/ebpf/README.md index 09c6607d9..534867f31 100644 --- a/libnetdata/ebpf/README.md +++ b/libnetdata/ebpf/README.md @@ -2,4 +2,4 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/libnetdata/ebpf/README.md --> -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Flibnetdata%2Febpf%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/libnetdata/ebpf/ebpf.c b/libnetdata/ebpf/ebpf.c index ca40492f1..dde6d57fc 100644 --- a/libnetdata/ebpf/ebpf.c +++ b/libnetdata/ebpf/ebpf.c @@ -279,7 +279,7 @@ static char *ebpf_select_kernel_name(uint32_t selector) { static char *kernel_names[] = { NETDATA_IDX_STR_V3_10, NETDATA_IDX_STR_V4_14, NETDATA_IDX_STR_V4_16, NETDATA_IDX_STR_V4_18, NETDATA_IDX_STR_V5_4, NETDATA_IDX_STR_V5_10, - NETDATA_IDX_STR_V5_11, NETDATA_IDX_STR_V5_15 + NETDATA_IDX_STR_V5_11, NETDATA_IDX_STR_V5_15, NETDATA_IDX_STR_V5_16 }; return kernel_names[selector]; @@ -301,7 +301,9 @@ static int ebpf_select_max_index(int is_rhf, uint32_t kver) if (kver >= NETDATA_EBPF_KERNEL_4_11) return NETDATA_IDX_V4_18; } else { // Kernels from kernel.org - if (kver >= NETDATA_EBPF_KERNEL_5_15) + if (kver >= NETDATA_EBPF_KERNEL_5_16) + return NETDATA_IDX_V5_16; + else if (kver >= NETDATA_EBPF_KERNEL_5_15) return NETDATA_IDX_V5_15; else if (kver >= NETDATA_EBPF_KERNEL_5_11) return NETDATA_IDX_V5_11; @@ -451,14 +453,53 @@ void ebpf_update_pid_table(ebpf_local_maps_t *pid, ebpf_module_t *em) pid->user_input = em->pid_map_size; } -void ebpf_update_map_sizes(struct bpf_object *program, ebpf_module_t *em) +/** + * Update map size + * + * Update map size with information read from configuration files. + * + * @param map the structure with file descriptor to update. + * @param lmap the structure with information from configuration files. + * @param em the structure with information about how the module/thread is working. + * @param map_name the name of the file used to log. + */ +void ebpf_update_map_size(struct bpf_map *map, ebpf_local_maps_t *lmap, ebpf_module_t *em, const char *map_name) +{ + uint32_t apps_type = NETDATA_EBPF_MAP_PID | NETDATA_EBPF_MAP_RESIZABLE; + if (lmap->user_input && lmap->user_input != lmap->internal_input) { +#ifdef NETDATA_INTERNAL_CHECKS + info("Changing map %s from size %u to %u ", map_name, lmap->internal_input, lmap->user_input); +#endif +#ifdef LIBBPF_MAJOR_VERSION + bpf_map__set_max_entries(map, lmap->user_input); +#else + bpf_map__resize(map, lmap->user_input); +#endif + } else if (((lmap->type & apps_type) == apps_type) && (!em->apps_charts) && (!em->cgroup_charts)) { + lmap->user_input = ND_EBPF_DEFAULT_MIN_PID; +#ifdef LIBBPF_MAJOR_VERSION + bpf_map__set_max_entries(map, lmap->user_input); +#else + bpf_map__resize(map, lmap->user_input); +#endif + } +} + +/** + * Update Legacy map sizes + * + * Update map size for eBPF legacy code. + * + * @param program the structure with values read from binary. + * @param em the structure with information about how the module/thread is working. + */ +static void ebpf_update_legacy_map_sizes(struct bpf_object *program, ebpf_module_t *em) { struct bpf_map *map; ebpf_local_maps_t *maps = em->maps; if (!maps) return; - uint32_t apps_type = NETDATA_EBPF_MAP_PID | NETDATA_EBPF_MAP_RESIZABLE; bpf_map__for_each(map, program) { const char *map_name = bpf_map__name(map); @@ -467,15 +508,7 @@ void ebpf_update_map_sizes(struct bpf_object *program, ebpf_module_t *em) ebpf_local_maps_t *w = &maps[i]; if (w->type & NETDATA_EBPF_MAP_RESIZABLE) { if (!strcmp(w->name, map_name)) { - if (w->user_input && w->user_input != w->internal_input) { -#ifdef NETDATA_INTERNAL_CHECKS - info("Changing map %s from size %u to %u ", map_name, w->internal_input, w->user_input); -#endif - bpf_map__resize(map, w->user_input); - } else if (((w->type & apps_type) == apps_type) && (!em->apps_charts) && (!em->cgroup_charts)) { - w->user_input = ND_EBPF_DEFAULT_MIN_PID; - bpf_map__resize(map, w->user_input); - } + ebpf_update_map_size(map, w, em, map_name); } } @@ -564,7 +597,32 @@ static void ebpf_update_maps(ebpf_module_t *em, struct bpf_object *obj) } } -static void ebpf_update_controller(ebpf_module_t *em, struct bpf_object *obj) +/** + * Update Controller + * + * Update controller value with user input. + * + * @param fd the table file descriptor + * @param em structure with information about eBPF program we will load. + */ +void ebpf_update_controller(int fd, ebpf_module_t *em) +{ + uint32_t key = NETDATA_CONTROLLER_APPS_ENABLED; + uint32_t value = em->apps_charts | em->cgroup_charts; + int ret = bpf_map_update_elem(fd, &key, &value, 0); + if (ret) + error("Add key(%u) for controller table failed.", key); +} + +/** + * Update Legacy controller + * + * Update legacy controller table when eBPF program has it. + * + * @param em structure with information about eBPF program we will load. + * @param obj bpf object with tables. + */ +static void ebpf_update_legacy_controller(ebpf_module_t *em, struct bpf_object *obj) { ebpf_local_maps_t *maps = em->maps; if (!maps) @@ -580,11 +638,7 @@ static void ebpf_update_controller(ebpf_module_t *em, struct bpf_object *obj) w->type &= ~NETDATA_EBPF_MAP_CONTROLLER; w->type |= NETDATA_EBPF_MAP_CONTROLLER_UPDATED; - uint32_t key = NETDATA_CONTROLLER_APPS_ENABLED; - int value = em->apps_charts | em->cgroup_charts; - int ret = bpf_map_update_elem(w->map_fd, &key, &value, 0); - if (ret) - error("Add key(%u) for controller table failed.", key); + ebpf_update_controller(w->map_fd, em); } i++; } @@ -620,7 +674,7 @@ struct bpf_link **ebpf_load_program(char *plugins_dir, ebpf_module_t *em, int kv return NULL; } - ebpf_update_map_sizes(*obj, em); + ebpf_update_legacy_map_sizes(*obj, em); if (bpf_object__load(*obj)) { error("ERROR: loading BPF object file failed %s\n", lpath); @@ -629,7 +683,7 @@ struct bpf_link **ebpf_load_program(char *plugins_dir, ebpf_module_t *em, int kv } ebpf_update_maps(em, *obj); - ebpf_update_controller(em, *obj); + ebpf_update_legacy_controller(em, *obj); size_t count_programs = ebpf_count_programs(*obj); @@ -716,14 +770,131 @@ static void ebpf_select_mode_string(char *output, size_t len, netdata_run_mode_t } /** + * Convert string to load mode + * + * Convert the string given as argument to value present in enum. + * + * @param str value read from configuraion file. + * + * @return It returns the value to be used. + */ +netdata_ebpf_load_mode_t epbf_convert_string_to_load_mode(char *str) +{ + if (!strcasecmp(str, EBPF_CFG_CORE_PROGRAM)) + return EBPF_LOAD_CORE; + else if (!strcasecmp(str, EBPF_CFG_LEGACY_PROGRAM)) + return EBPF_LOAD_LEGACY; + + return EBPF_LOAD_PLAY_DICE; +} + +/** + * Convert load mode to string + * + * @param mode value that will select the string + * + * @return It returns the string associated to mode. + */ +static char *ebpf_convert_load_mode_to_string(netdata_ebpf_load_mode_t mode) +{ + if (mode == EBPF_LOAD_CORE) + return EBPF_CFG_CORE_PROGRAM; + else if (mode == EBPF_LOAD_LEGACY) + return EBPF_CFG_LEGACY_PROGRAM; + + return EBPF_CFG_DEFAULT_PROGRAM; +} + +/** + * CO-RE type + * + * Select the preferential type of CO-RE + * + * @param str value read from configuration file. + * @param lmode load mode used by collector. + */ +netdata_ebpf_program_loaded_t ebpf_convert_core_type(char *str, netdata_run_mode_t lmode) +{ + if (!strcasecmp(str, EBPF_CFG_ATTACH_TRACEPOINT)) + return EBPF_LOAD_TRACEPOINT; + else if (!strcasecmp(str, EBPF_CFG_ATTACH_PROBE)) { + return (lmode == MODE_ENTRY) ? EBPF_LOAD_PROBE : EBPF_LOAD_RETPROBE; + } + + return EBPF_LOAD_TRAMPOLINE; +} + +#ifdef LIBBPF_MAJOR_VERSION +/** + * Adjust Thread Load + * + * Adjust thread configuraton according specified load. + * + * @param mod the main structure that will be adjusted. + * @param file the btf file used with thread. + */ +void ebpf_adjust_thread_load(ebpf_module_t *mod, struct btf *file) +{ + if (!file) { + mod->load = EBPF_LOAD_LEGACY; + } else if (mod->load == EBPF_LOAD_PLAY_DICE && file) { + mod->load = EBPF_LOAD_CORE; + } +} + +/** + * + * @param filename + * @return + */ +struct btf *ebpf_parse_btf_file(const char *filename) +{ + struct btf *bf = btf__parse(filename, NULL); + if (libbpf_get_error(bf)) { + fprintf(stderr, "Cannot parse btf file"); + btf__free(bf); + return NULL; + } + + return bf; +} +#endif + +/** + * Update target with configuration + * + * Update target load mode with value. + * + * @param em the module structure + * @param value value used to update. + */ +static void ebpf_update_target_with_conf(ebpf_module_t *em, netdata_ebpf_program_loaded_t value) +{ + netdata_ebpf_targets_t *targets = em->targets; + if (!targets) { + return; + } + + int i = 0; + while (targets[i].name) { + targets[i].mode = value; + i++; + } +} + +/** + * Update Module using config + * + * Update configuration for a specific thread. + * * @param modules structure that will be updated */ void ebpf_update_module_using_config(ebpf_module_t *modules) { char default_value[EBPF_MAX_MODE_LENGTH + 1]; ebpf_select_mode_string(default_value, EBPF_MAX_MODE_LENGTH, modules->mode); - char *mode = appconfig_get(modules->cfg, EBPF_GLOBAL_SECTION, EBPF_CFG_LOAD_MODE, default_value); - modules->mode = ebpf_select_mode(mode); + char *value = appconfig_get(modules->cfg, EBPF_GLOBAL_SECTION, EBPF_CFG_LOAD_MODE, default_value); + modules->mode = ebpf_select_mode(value); modules->update_every = (int)appconfig_get_number(modules->cfg, EBPF_GLOBAL_SECTION, EBPF_CFG_UPDATE_EVERY, modules->update_every); @@ -733,8 +904,15 @@ void ebpf_update_module_using_config(ebpf_module_t *modules) modules->pid_map_size = (uint32_t)appconfig_get_number(modules->cfg, EBPF_GLOBAL_SECTION, EBPF_CFG_PID_SIZE, modules->pid_map_size); -} + value = ebpf_convert_load_mode_to_string(modules->load); + value = appconfig_get(modules->cfg, EBPF_GLOBAL_SECTION, EBPF_CFG_TYPE_FORMAT, value); + modules->load = epbf_convert_string_to_load_mode(value); + + value = appconfig_get(modules->cfg, EBPF_GLOBAL_SECTION, EBPF_CFG_CORE_ATTACH, EBPF_CFG_ATTACH_TRAMPOLINE); + netdata_ebpf_program_loaded_t fill_lm = ebpf_convert_core_type(value, modules->mode); + ebpf_update_target_with_conf(modules, fill_lm); +} /** * Update module @@ -991,3 +1169,45 @@ int ebpf_disable_tracing_values(char *subsys, char *eventname) { return ebpf_change_tracing_values(subsys, eventname, "0"); } + +/** + * Select PC prefix + * + * Identify the prefix to run on PC architecture. + * + * @return It returns 32 or 64 according to host arch. + */ +static uint32_t ebpf_select_pc_prefix() +{ + long counter = 1; + uint32_t i; + for (i = 0; i < 128; i++) { + counter <<= 1; + if (counter < 0) + break; + } + + return counter; +} + +/** + * Select Host Prefix + * + * Select prefix to syscall when host is running a kernel newer than 4.17.0 + * + * @param output the vector to store data. + * @param length length of output vector. + * @param syscall the syscall that prefix will be attached; + * @param kver the current kernel version in format MAJOR*65536 + MINOR*256 + PATCH + */ +void ebpf_select_host_prefix(char *output, size_t length, char *syscall, int kver) +{ + if (kver < NETDATA_EBPF_KERNEL_4_17) + snprintfz(output, length, "sys_%s", syscall); + else { + uint32_t arch = ebpf_select_pc_prefix(); + // Prefix selected according https://www.kernel.org/doc/html/latest/process/adding-syscalls.html + char *prefix = (arch == 32) ? "__ia32" : "__x64"; + snprintfz(output, length, "%s_sys_%s", prefix, syscall); + } +} \ No newline at end of file diff --git a/libnetdata/ebpf/ebpf.h b/libnetdata/ebpf/ebpf.h index 125299672..f701e1d4d 100644 --- a/libnetdata/ebpf/ebpf.h +++ b/libnetdata/ebpf/ebpf.h @@ -5,6 +5,10 @@ #include #include +#ifdef LIBBPF_DEPRECATED +#include +#include +#endif #include // Necessary for stdtoul #define NETDATA_DEBUGFS "/sys/kernel/debug/tracing/" @@ -17,11 +21,25 @@ #define EBPF_CFG_LOAD_MODE_RETURN "return" #define EBPF_MAX_MODE_LENGTH 6 +#define EBPF_CFG_TYPE_FORMAT "ebpf type format" +#define EBPF_CFG_DEFAULT_PROGRAM "auto" +#define EBPF_CFG_CORE_PROGRAM "CO-RE" +#define EBPF_CFG_LEGACY_PROGRAM "legacy" + +#define EBPF_CFG_CORE_ATTACH "ebpf co-re tracing" +#define EBPF_CFG_ATTACH_TRAMPOLINE "trampoline" +#define EBPF_CFG_ATTACH_TRACEPOINT "tracepoint" +#define EBPF_CFG_ATTACH_PROBE "probe" + +#define EBPF_CFG_PROGRAM_PATH "btf path" + #define EBPF_CFG_UPDATE_EVERY "update every" #define EBPF_CFG_PID_SIZE "pid table size" #define EBPF_CFG_APPLICATION "apps" #define EBPF_CFG_CGROUP "cgroups" +#define EBPF_COMMON_FNCT_CLEAN_UP "release_task" + /** * The RedHat magic number was got doing: * @@ -57,7 +75,8 @@ enum netdata_ebpf_kernel_versions { NETDATA_EBPF_KERNEL_5_0 = 327680, // 327680 = 5 * 65536 + 0 * 256 NETDATA_EBPF_KERNEL_5_10 = 330240, // 330240 = 5 * 65536 + 10 * 256 NETDATA_EBPF_KERNEL_5_11 = 330496, // 330240 = 5 * 65536 + 11 * 256 - NETDATA_EBPF_KERNEL_5_15 = 331520 // 331520 = 5 * 65536 + 15 * 256 + NETDATA_EBPF_KERNEL_5_15 = 331520, // 331520 = 5 * 65536 + 15 * 256 + NETDATA_EBPF_KERNEL_5_16 = 331776 // 331776 = 5 * 65536 + 16 * 256 }; enum netdata_kernel_flag { @@ -68,7 +87,8 @@ enum netdata_kernel_flag { NETDATA_V5_4 = 1 << 4, NETDATA_V5_10 = 1 << 5, NETDATA_V5_11 = 1 << 6, - NETDATA_V5_15 = 1 << 7 + NETDATA_V5_15 = 1 << 7, + NETDATA_V5_16 = 1 << 8 }; enum netdata_kernel_idx { @@ -79,7 +99,8 @@ enum netdata_kernel_idx { NETDATA_IDX_V5_4 , NETDATA_IDX_V5_10, NETDATA_IDX_V5_11, - NETDATA_IDX_V5_15 + NETDATA_IDX_V5_15, + NETDATA_IDX_V5_16 }; #define NETDATA_IDX_STR_V3_10 "3.10" @@ -90,6 +111,7 @@ enum netdata_kernel_idx { #define NETDATA_IDX_STR_V5_10 "5.10" #define NETDATA_IDX_STR_V5_11 "5.11" #define NETDATA_IDX_STR_V5_15 "5.15" +#define NETDATA_IDX_STR_V5_16 "5.16" /** * Minimum value has relationship with libbpf support. @@ -229,6 +251,8 @@ extern void ebpf_load_addresses(ebpf_addresses_t *fa, int fd); extern void ebpf_fill_algorithms(int *algorithms, size_t length, int algorithm); extern char **ebpf_fill_histogram_dimension(size_t maximum); extern void ebpf_update_stats(ebpf_plugin_stats_t *report, ebpf_module_t *em); +extern void ebpf_update_controller(int fd, ebpf_module_t *em); +extern void ebpf_update_map_size(struct bpf_map *map, ebpf_local_maps_t *lmap, ebpf_module_t *em, const char *map_name); // Histogram #define NETDATA_EBPF_HIST_MAX_BINS 24UL @@ -250,4 +274,19 @@ extern int ebpf_is_tracepoint_enabled(char *subsys, char *eventname); extern int ebpf_enable_tracing_values(char *subsys, char *eventname); extern int ebpf_disable_tracing_values(char *subsys, char *eventname); +// BTF Section +#define EBPF_DEFAULT_BTF_FILE "/sys/kernel/btf" +#define EBPF_DEFAULT_ERROR_MSG "Cannot open or load BPF file for thread" + +// BTF helpers +#define NETDATA_EBPF_MAX_SYSCALL_LENGTH 255 + +extern netdata_ebpf_load_mode_t epbf_convert_string_to_load_mode(char *str); +extern netdata_ebpf_program_loaded_t ebpf_convert_core_type(char *str, netdata_run_mode_t lmode); +extern void ebpf_select_host_prefix(char *output, size_t length, char *syscall, int kver); +#ifdef LIBBPF_MAJOR_VERSION +extern void ebpf_adjust_thread_load(ebpf_module_t *mod, struct btf *file); +extern struct btf *ebpf_parse_btf_file(const char *filename); +#endif + #endif /* NETDATA_EBPF_H */ diff --git a/libnetdata/eval/README.md b/libnetdata/eval/README.md index 72b4089a9..8b1378917 100644 --- a/libnetdata/eval/README.md +++ b/libnetdata/eval/README.md @@ -1 +1 @@ -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Flibnetdata%2Feval%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/libnetdata/json/README.md b/libnetdata/json/README.md index 79a48e240..2e04b8b6b 100644 --- a/libnetdata/json/README.md +++ b/libnetdata/json/README.md @@ -7,4 +7,4 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/libnetdata/json/ `json` contains a parser for json strings, based on `jsmn` (), but case you have installed the JSON-C library, the installation script will prefer it, you can also force its use with `--enable-jsonc` in the compilation time. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Flibnetdata%2Fjson%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/libnetdata/libnetdata.h b/libnetdata/libnetdata.h index 809cefa01..7f62c882e 100644 --- a/libnetdata/libnetdata.h +++ b/libnetdata/libnetdata.h @@ -168,14 +168,6 @@ extern "C" { // ---------------------------------------------------------------------------- // netdata common definitions -#if (SIZEOF_VOID_P == 8) -#define ENVIRONMENT64 -#elif (SIZEOF_VOID_P == 4) -#define ENVIRONMENT32 -#else -#error "Cannot detect if this is a 32 or 64 bit CPU" -#endif - #ifdef __GNUC__ #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #endif // __GNUC__ @@ -304,6 +296,13 @@ extern char *find_and_replace(const char *src, const char *find, const char *rep /* misc. */ #define UNUSED(x) (void)(x) + +#ifdef __GNUC__ +#define UNUSED_FUNCTION(x) __attribute__((unused)) UNUSED_##x +#else +#define UNUSED_FUNCTION(x) UNUSED_##x +#endif + #define error_report(x, args...) do { errno = 0; error(x, ##args); } while(0) // Taken from linux kernel diff --git a/libnetdata/locks/README.md b/libnetdata/locks/README.md index b525c97f0..a83f1b647 100644 --- a/libnetdata/locks/README.md +++ b/libnetdata/locks/README.md @@ -2,4 +2,4 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/libnetdata/locks/README.md --> -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Flibnetdata%2Flocks%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/libnetdata/log/README.md b/libnetdata/log/README.md index c0d7a340c..a767dd446 100644 --- a/libnetdata/log/README.md +++ b/libnetdata/log/README.md @@ -2,4 +2,4 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/libnetdata/log/README.md --> -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Flibnetdata%2Flog%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/libnetdata/log/log.h b/libnetdata/log/log.h index c8380d0c1..4cb62e955 100644 --- a/libnetdata/log/log.h +++ b/libnetdata/log/log.h @@ -36,7 +36,7 @@ extern "C" { #define D_CONNECT_TO 0x0000000001000000 #define D_RRDHOST 0x0000000002000000 #define D_LOCKS 0x0000000004000000 -#define D_BACKEND 0x0000000008000000 +#define D_EXPORTING 0x0000000008000000 #define D_STATSD 0x0000000010000000 #define D_POLLFD 0x0000000020000000 #define D_STREAM 0x0000000040000000 diff --git a/libnetdata/os.h b/libnetdata/os.h index 7872f82b9..5e7746df8 100644 --- a/libnetdata/os.h +++ b/libnetdata/os.h @@ -57,4 +57,11 @@ extern pid_t get_system_pid_max(void); extern unsigned int system_hz; extern void get_system_HZ(void); +#include +#if defined(__FreeBSD__) || defined(__APPLE__) +#define ADJUST_TIMEX(x) ntp_adjtime(x) +#else +#define ADJUST_TIMEX(x) adjtimex(x) +#endif + #endif //NETDATA_OS_H diff --git a/libnetdata/popen/README.md b/libnetdata/popen/README.md index e51e2059b..db4aefaed 100644 --- a/libnetdata/popen/README.md +++ b/libnetdata/popen/README.md @@ -2,4 +2,4 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/libnetdata/popen/README.md --> -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Flibnetdata%2Fpopen%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/libnetdata/procfile/README.md b/libnetdata/procfile/README.md index 3eeb1e205..65638030d 100644 --- a/libnetdata/procfile/README.md +++ b/libnetdata/procfile/README.md @@ -64,4 +64,4 @@ and the data are inside the processor's caches. This library is extensively used in Netdata and its plugins. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Flibnetdata%2Fprocfile%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/libnetdata/procfile/procfile.h b/libnetdata/procfile/procfile.h index d29adf8e6..5263ad770 100644 --- a/libnetdata/procfile/procfile.h +++ b/libnetdata/procfile/procfile.h @@ -103,4 +103,7 @@ extern int procfile_adaptive_initial_allocation; // return the Nth word of the current line #define procfile_lineword(ff, line, word) (((line) < procfile_lines(ff) && (word) < procfile_linewords((ff), (line))) ? procfile_word((ff), (ff)->lines->lines[(line)].first + (word)) : "") +// Open file without logging file IO error if any +#define procfile_open_no_log(filename, separators, flags) procfile_open(filename, separators, flags | PROCFILE_FLAG_NO_ERROR_ON_FILE_IO) + #endif /* NETDATA_PROCFILE_H */ diff --git a/libnetdata/simple_pattern/README.md b/libnetdata/simple_pattern/README.md index a90759c3a..cb377f84e 100644 --- a/libnetdata/simple_pattern/README.md +++ b/libnetdata/simple_pattern/README.md @@ -40,4 +40,4 @@ Netdata stops processing to the first positive or negative match (left to right). If it is not matched by either positive or negative patterns, it is denied at the end. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Flibnetdata%2Fsimple_pattern%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/libnetdata/socket/README.md b/libnetdata/socket/README.md index 6736f13bd..70bfd3441 100644 --- a/libnetdata/socket/README.md +++ b/libnetdata/socket/README.md @@ -2,4 +2,4 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/libnetdata/socket/README.md --> -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Flibnetdata%2Fsocket%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/libnetdata/statistical/README.md b/libnetdata/statistical/README.md index ee1faba22..f254081d2 100644 --- a/libnetdata/statistical/README.md +++ b/libnetdata/statistical/README.md @@ -2,4 +2,4 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/libnetdata/statistical/README.md --> -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Flibnetdata%2Fstatistical%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/libnetdata/storage_number/README.md b/libnetdata/storage_number/README.md index 295b3d6e7..4cd19a98b 100644 --- a/libnetdata/storage_number/README.md +++ b/libnetdata/storage_number/README.md @@ -14,4 +14,4 @@ have less decimal precision) and 3 bits for flags. This provides an extremely optimized memory footprint with just 0.0001% max accuracy loss. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Flibnetdata%2Fstorage_number%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/libnetdata/threads/README.md b/libnetdata/threads/README.md index 377da5ea3..75ab11b1e 100644 --- a/libnetdata/threads/README.md +++ b/libnetdata/threads/README.md @@ -2,4 +2,4 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/libnetdata/threads/README.md --> -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Flibnetdata%2Fthreads%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/libnetdata/threads/threads.c b/libnetdata/threads/threads.c index d7636940f..12007afff 100644 --- a/libnetdata/threads/threads.c +++ b/libnetdata/threads/threads.c @@ -147,6 +147,7 @@ void uv_thread_set_name_np(uv_thread_t ut, const char* name) { pthread_set_name_np(ut, threadname); #elif defined(__APPLE__) // Apple can only set its own name + UNUSED(ut); #else ret = pthread_setname_np(ut, threadname); #endif diff --git a/libnetdata/url/README.md b/libnetdata/url/README.md index 4a95547a5..bd289d955 100644 --- a/libnetdata/url/README.md +++ b/libnetdata/url/README.md @@ -2,4 +2,4 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/libnetdata/url/README.md --> -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Flibnetdata%2Furl%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/ml/Config.cc b/ml/Config.cc index df0a2825e..99109e05f 100644 --- a/ml/Config.cc +++ b/ml/Config.cc @@ -32,10 +32,13 @@ void Config::readMLConfig(void) { unsigned MinTrainSamples = config_get_number(ConfigSectionML, "minimum num samples to train", 1 * 3600); unsigned TrainEvery = config_get_number(ConfigSectionML, "train every", 1 * 3600); + unsigned DBEngineAnomalyRateEvery = config_get_number(ConfigSectionML, "dbengine anomaly rate every", 60); + unsigned DiffN = config_get_number(ConfigSectionML, "num samples to diff", 1); unsigned SmoothN = config_get_number(ConfigSectionML, "num samples to smooth", 3); unsigned LagN = config_get_number(ConfigSectionML, "num samples to lag", 5); + double RandomSamplingRatio = config_get_float(ConfigSectionML, "random sampling ratio", 1.0 / LagN); unsigned MaxKMeansIters = config_get_number(ConfigSectionML, "maximum number of k-means iterations", 1000); double DimensionAnomalyScoreThreshold = config_get_float(ConfigSectionML, "dimension anomaly score threshold", 0.99); @@ -59,10 +62,13 @@ void Config::readMLConfig(void) { MinTrainSamples = clamp(MinTrainSamples, 1 * 3600u, 6 * 3600u); TrainEvery = clamp(TrainEvery, 1 * 3600u, 6 * 3600u); + DBEngineAnomalyRateEvery = clamp(DBEngineAnomalyRateEvery, 1 * 30u, 15 * 60u); + DiffN = clamp(DiffN, 0u, 1u); SmoothN = clamp(SmoothN, 0u, 5u); - LagN = clamp(LagN, 0u, 5u); + LagN = clamp(LagN, 1u, 5u); + RandomSamplingRatio = clamp(RandomSamplingRatio, 0.2, 1.0); MaxKMeansIters = clamp(MaxKMeansIters, 500u, 1000u); DimensionAnomalyScoreThreshold = clamp(DimensionAnomalyScoreThreshold, 0.01, 5.00); @@ -102,10 +108,13 @@ void Config::readMLConfig(void) { Cfg.MinTrainSamples = MinTrainSamples; Cfg.TrainEvery = TrainEvery; + Cfg.DBEngineAnomalyRateEvery = DBEngineAnomalyRateEvery; + Cfg.DiffN = DiffN; Cfg.SmoothN = SmoothN; Cfg.LagN = LagN; + Cfg.RandomSamplingRatio = RandomSamplingRatio; Cfg.MaxKMeansIters = MaxKMeansIters; Cfg.DimensionAnomalyScoreThreshold = DimensionAnomalyScoreThreshold; @@ -120,9 +129,10 @@ void Config::readMLConfig(void) { Cfg.HostsToSkip = config_get(ConfigSectionML, "hosts to skip from training", "!*"); Cfg.SP_HostsToSkip = simple_pattern_create(Cfg.HostsToSkip.c_str(), NULL, SIMPLE_PATTERN_EXACT); - Cfg.ChartsToSkip = config_get(ConfigSectionML, "charts to skip from training", - "!system.* !cpu.* !mem.* !disk.* !disk_* " - "!ip.* !ipv4.* !ipv6.* !net.* !net_* !netfilter.* " - "!services.* !apps.* !groups.* !user.* !ebpf.* !netdata.* *"); + // Always exclude anomaly_detection charts from training. + Cfg.ChartsToSkip = "anomaly_detection.* "; + Cfg.ChartsToSkip += config_get(ConfigSectionML, "charts to skip from training", "netdata.*"); Cfg.SP_ChartsToSkip = simple_pattern_create(ChartsToSkip.c_str(), NULL, SIMPLE_PATTERN_EXACT); + + Cfg.StreamADCharts = config_get_boolean(ConfigSectionML, "stream anomaly detection charts", true); } diff --git a/ml/Config.h b/ml/Config.h index 58ecce53f..595fd072b 100644 --- a/ml/Config.h +++ b/ml/Config.h @@ -15,10 +15,13 @@ public: unsigned MinTrainSamples; unsigned TrainEvery; + unsigned DBEngineAnomalyRateEvery; + unsigned DiffN; unsigned SmoothN; unsigned LagN; + double RandomSamplingRatio; unsigned MaxKMeansIters; double DimensionAnomalyScoreThreshold; @@ -30,6 +33,8 @@ public: double ADWindowRateThreshold; double ADDimensionRateThreshold; + bool StreamADCharts; + std::string HostsToSkip; SIMPLE_PATTERN *SP_HostsToSkip; @@ -37,6 +42,7 @@ public: SIMPLE_PATTERN *SP_ChartsToSkip; std::string AnomalyDBPath; + std::vector RandomNums; void readMLConfig(); }; diff --git a/ml/Dimension.cc b/ml/Dimension.cc index c27f30bb4..290d4c743 100644 --- a/ml/Dimension.cc +++ b/ml/Dimension.cc @@ -125,9 +125,15 @@ MLResult TrainableDimension::trainModel() { if (!CNs) return MLResult::MissingData; - SamplesBuffer SB = SamplesBuffer(CNs, N, 1, Cfg.DiffN, Cfg.SmoothN, Cfg.LagN); + unsigned TargetNumSamples = Cfg.MaxTrainSamples * Cfg.RandomSamplingRatio; + double SamplingRatio = std::min(static_cast(TargetNumSamples) / N, 1.0); + + SamplesBuffer SB = SamplesBuffer(CNs, N, 1, Cfg.DiffN, Cfg.SmoothN, Cfg.LagN, + SamplingRatio, Cfg.RandomNums); KM.train(SB, Cfg.MaxKMeansIters); + Trained = true; + ConstantModel = true; delete[] CNs; return MLResult::Success; @@ -146,6 +152,10 @@ void PredictableDimension::addValue(CalculatedNumber Value, bool Exists) { } std::rotate(std::begin(CNs), std::begin(CNs) + 1, std::end(CNs)); + + if (CNs[N - 1] != Value) + ConstantModel = false; + CNs[N - 1] = Value; } @@ -157,7 +167,8 @@ std::pair PredictableDimension::predict() { CalculatedNumber *TmpCNs = new CalculatedNumber[N * (Cfg.LagN + 1)](); std::memcpy(TmpCNs, CNs.data(), N * sizeof(CalculatedNumber)); - SamplesBuffer SB = SamplesBuffer(TmpCNs, N, 1, Cfg.DiffN, Cfg.SmoothN, Cfg.LagN); + SamplesBuffer SB = SamplesBuffer(TmpCNs, N, 1, Cfg.DiffN, Cfg.SmoothN, Cfg.LagN, + 1.0, Cfg.RandomNums); AnomalyScore = computeAnomalyScore(SB); delete[] TmpCNs; diff --git a/ml/Dimension.h b/ml/Dimension.h index fdf923ccc..44b348e9b 100644 --- a/ml/Dimension.h +++ b/ml/Dimension.h @@ -12,11 +12,7 @@ namespace ml { class RrdDimension { public: - RrdDimension(RRDDIM *RD) : RD(RD), Ops(&RD->state->query_ops) { - std::stringstream SS; - SS << RD->rrdset->id << "|" << RD->name; - ID = SS.str(); - } + RrdDimension(RRDDIM *RD) : RD(RD), Ops(&RD->state->query_ops) { } RRDDIM *getRD() const { return RD; } @@ -26,12 +22,29 @@ public: unsigned updateEvery() const { return RD->update_every; } - const std::string getID() const { return ID; } + const std::string getID() const { + RRDSET *RS = RD->rrdset; + + std::stringstream SS; + SS << RS->context << "|" << RS->id << "|" << RD->name; + return SS.str(); + } - virtual ~RrdDimension() {} + void setAnomalyRateRD(RRDDIM *ARRD) { AnomalyRateRD = ARRD; } + RRDDIM *getAnomalyRateRD() const { return AnomalyRateRD; } + + void setAnomalyRateRDName(const char *Name) const { + rrddim_set_name(AnomalyRateRD->rrdset, AnomalyRateRD, Name); + } + + virtual ~RrdDimension() { + rrddim_free_custom(AnomalyRateRD->rrdset, AnomalyRateRD, 0); + } private: RRDDIM *RD; + RRDDIM *AnomalyRateRD; + struct rrddim_volatile::rrddim_query_ops *Ops; std::string ID; @@ -55,27 +68,28 @@ public: } bool shouldTrain(const TimePoint &TP) const { + if (ConstantModel) + return false; + return (LastTrainedAt + TrainEvery) < TP; } bool isTrained() const { return Trained; } - double updateTrainingDuration(double Duration) { - return TrainingDuration.exchange(Duration); - } - private: std::pair getCalculatedNumbers(); public: TimePoint LastTrainedAt{Seconds{0}}; +protected: + std::atomic ConstantModel{false}; + private: Seconds TrainEvery; KMeans KM; std::atomic Trained{false}; - std::atomic TrainingDuration{0.0}; }; class PredictableDimension : public TrainableDimension { @@ -88,9 +102,20 @@ public: bool isAnomalous() { return AnomalyBit; } + void updateAnomalyBitCounter(RRDSET *RS, unsigned Elapsed, bool IsAnomalous) { + AnomalyBitCounter += IsAnomalous; + + if (Elapsed == Cfg.DBEngineAnomalyRateEvery) { + double AR = static_cast(AnomalyBitCounter) / Cfg.DBEngineAnomalyRateEvery; + rrddim_set_by_pointer(RS, getAnomalyRateRD(), AR * 1000); + AnomalyBitCounter = 0; + } + } + private: CalculatedNumber AnomalyScore{0.0}; std::atomic AnomalyBit{false}; + unsigned AnomalyBitCounter{0}; std::vector CNs; }; diff --git a/ml/Host.cc b/ml/Host.cc index b632710a4..3166720cc 100644 --- a/ml/Host.cc +++ b/ml/Host.cc @@ -20,13 +20,18 @@ static void updateDimensionsChart(RRDHOST *RH, static thread_local RRDDIM *NumAnomalousDimensionsRD = nullptr; if (!RS) { + std::stringstream IdSS, NameSS; + + IdSS << "dimensions_on_" << localhost->machine_guid; + NameSS << "dimensions_on_" << localhost->hostname; + RS = rrdset_create( - RH, // host + RH, "anomaly_detection", // type - "dimensions", // id - NULL, // name + IdSS.str().c_str(), // id + NameSS.str().c_str(), // name "dimensions", // family - NULL, // ctx + "anomaly_detection.dimensions", // ctx "Anomaly detection dimensions", // title "dimensions", // units "netdata", // plugin @@ -35,6 +40,7 @@ static void updateDimensionsChart(RRDHOST *RH, RH->rrd_update_every, // update_every RRDSET_TYPE_LINE // chart_type ); + rrdset_flag_set(RS, RRDSET_FLAG_ANOMALY_DETECTION); NumTotalDimensionsRD = rrddim_add(RS, "total", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); @@ -60,13 +66,18 @@ static void updateRateChart(RRDHOST *RH, collected_number AnomalyRate) { static thread_local RRDDIM *AnomalyRateRD = nullptr; if (!RS) { + std::stringstream IdSS, NameSS; + + IdSS << "anomaly_rate_on_" << localhost->machine_guid; + NameSS << "anomaly_rate_on_" << localhost->hostname; + RS = rrdset_create( - RH, // host + RH, "anomaly_detection", // type - "anomaly_rate", // id - NULL, // name + IdSS.str().c_str(), // id + NameSS.str().c_str(), // name "anomaly_rate", // family - NULL, // ctx + "anomaly_detection.anomaly_rate", // ctx "Percentage of anomalous dimensions", // title "percentage", // units "netdata", // plugin @@ -75,6 +86,7 @@ static void updateRateChart(RRDHOST *RH, collected_number AnomalyRate) { RH->rrd_update_every, // update_every RRDSET_TYPE_LINE // chart_type ); + rrdset_flag_set(RS, RRDSET_FLAG_ANOMALY_DETECTION); AnomalyRateRD = rrddim_add(RS, "anomaly_rate", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE); @@ -91,13 +103,18 @@ static void updateWindowLengthChart(RRDHOST *RH, collected_number WindowLength) static thread_local RRDDIM *WindowLengthRD = nullptr; if (!RS) { + std::stringstream IdSS, NameSS; + + IdSS << "detector_window_on_" << localhost->machine_guid; + NameSS << "detector_window_on_" << localhost->hostname; + RS = rrdset_create( - RH, // host + RH, "anomaly_detection", // type - "detector_window", // id - NULL, // name + IdSS.str().c_str(), // id + NameSS.str().c_str(), // name "detector_window", // family - NULL, // ctx + "anomaly_detection.detector_window", // ctx "Anomaly detector window length", // title "seconds", // units "netdata", // plugin @@ -106,6 +123,7 @@ static void updateWindowLengthChart(RRDHOST *RH, collected_number WindowLength) RH->rrd_update_every, // update_every RRDSET_TYPE_LINE // chart_type ); + rrdset_flag_set(RS, RRDSET_FLAG_ANOMALY_DETECTION); WindowLengthRD = rrddim_add(RS, "duration", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); @@ -126,13 +144,18 @@ static void updateEventsChart(RRDHOST *RH, static thread_local RRDDIM *NewAnomalyEventRD = nullptr; if (!RS) { + std::stringstream IdSS, NameSS; + + IdSS << "detector_events_on_" << localhost->machine_guid; + NameSS << "detector_events_on_" << localhost->hostname; + RS = rrdset_create( - RH, // host + RH, "anomaly_detection", // type - "detector_events", // id - NULL, // name + IdSS.str().c_str(), // id + NameSS.str().c_str(), // name "detector_events", // family - NULL, // ctx + "anomaly_detection.detector_events", // ctx "Anomaly events triggered", // title "boolean", // units "netdata", // plugin @@ -141,6 +164,7 @@ static void updateEventsChart(RRDHOST *RH, RH->rrd_update_every, // update_every RRDSET_TYPE_LINE // chart_type ); + rrdset_flag_set(RS, RRDSET_FLAG_ANOMALY_DETECTION); AboveThresholdRD = rrddim_add(RS, "above_threshold", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); @@ -161,82 +185,94 @@ static void updateEventsChart(RRDHOST *RH, rrdset_done(RS); } -static void updateDetectionChart(RRDHOST *RH, collected_number PredictionDuration) { +static void updateDetectionChart(RRDHOST *RH) { static thread_local RRDSET *RS = nullptr; - static thread_local RRDDIM *PredictiobDurationRD = nullptr; + static thread_local RRDDIM *UserRD, *SystemRD = nullptr; if (!RS) { - RS = rrdset_create( - RH, // host - "anomaly_detection", // type - "prediction_stats", // id - NULL, // name - "prediction_stats", // family - NULL, // ctx - "Time it took to run prediction", // title - "milliseconds", // units + std::stringstream IdSS, NameSS; + + IdSS << "prediction_stats_" << RH->machine_guid; + NameSS << "prediction_stats_for_" << RH->hostname; + + RS = rrdset_create_localhost( + "netdata", // type + IdSS.str().c_str(), // id + NameSS.str().c_str(), // name + "ml", // family + "netdata.prediction_stats", // ctx + "Prediction thread CPU usage", // title + "milliseconds/s", // units "netdata", // plugin "ml", // module - 39187, // priority + 136000, // priority RH->rrd_update_every, // update_every - RRDSET_TYPE_LINE // chart_type + RRDSET_TYPE_STACKED // chart_type ); - PredictiobDurationRD = rrddim_add(RS, "duration", NULL, - 1, 1, RRD_ALGORITHM_ABSOLUTE); + UserRD = rrddim_add(RS, "user", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL); + SystemRD = rrddim_add(RS, "system", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL); } else rrdset_next(RS); - rrddim_set_by_pointer(RS, PredictiobDurationRD, PredictionDuration); + struct rusage TRU; + getrusage(RUSAGE_THREAD, &TRU); + rrddim_set_by_pointer(RS, UserRD, TRU.ru_utime.tv_sec * 1000000ULL + TRU.ru_utime.tv_usec); + rrddim_set_by_pointer(RS, SystemRD, TRU.ru_stime.tv_sec * 1000000ULL + TRU.ru_stime.tv_usec); rrdset_done(RS); } -static void updateTrainingChart(RRDHOST *RH, - collected_number TotalTrainingDuration, - collected_number MaxTrainingDuration) +static void updateTrainingChart(RRDHOST *RH, struct rusage *TRU) { static thread_local RRDSET *RS = nullptr; - static thread_local RRDDIM *TotalTrainingDurationRD = nullptr; - static thread_local RRDDIM *MaxTrainingDurationRD = nullptr; + static thread_local RRDDIM *UserRD = nullptr; + static thread_local RRDDIM *SystemRD = nullptr; if (!RS) { - RS = rrdset_create( - RH, // host - "anomaly_detection", // type - "training_stats", // id - NULL, // name - "training_stats", // family - NULL, // ctx - "Training step statistics", // title - "milliseconds", // units + std::stringstream IdSS, NameSS; + + IdSS << "training_stats_" << RH->machine_guid; + NameSS << "training_stats_for_" << RH->hostname; + + RS = rrdset_create_localhost( + "netdata", // type + IdSS.str().c_str(), // id + NameSS.str().c_str(), // name + "ml", // family + "netdata.training_stats", // ctx + "Training thread CPU usage", // title + "milliseconds/s", // units "netdata", // plugin "ml", // module - 39188, // priority + 136001, // priority RH->rrd_update_every, // update_every - RRDSET_TYPE_LINE // chart_type + RRDSET_TYPE_STACKED // chart_type ); - TotalTrainingDurationRD = rrddim_add(RS, "total_training_duration", NULL, - 1, 1, RRD_ALGORITHM_ABSOLUTE); - MaxTrainingDurationRD = rrddim_add(RS, "max_training_duration", NULL, - 1, 1, RRD_ALGORITHM_ABSOLUTE); + UserRD = rrddim_add(RS, "user", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL); + SystemRD = rrddim_add(RS, "system", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL); } else rrdset_next(RS); - rrddim_set_by_pointer(RS, TotalTrainingDurationRD, TotalTrainingDuration); - rrddim_set_by_pointer(RS, MaxTrainingDurationRD, MaxTrainingDuration); - + rrddim_set_by_pointer(RS, UserRD, TRU->ru_utime.tv_sec * 1000000ULL + TRU->ru_utime.tv_usec); + rrddim_set_by_pointer(RS, SystemRD, TRU->ru_stime.tv_sec * 1000000ULL + TRU->ru_stime.tv_usec); rrdset_done(RS); } void RrdHost::addDimension(Dimension *D) { - std::lock_guard Lock(Mutex); + RRDDIM *AnomalyRateRD = rrddim_add(AnomalyRateRS, D->getID().c_str(), NULL, + 1, 1000, RRD_ALGORITHM_ABSOLUTE); + D->setAnomalyRateRD(AnomalyRateRD); + + { + std::lock_guard Lock(Mutex); - DimensionsMap[D->getRD()] = D; + DimensionsMap[D->getRD()] = D; - // Default construct mutex for dimension - LocksMap[D]; + // Default construct mutex for dimension + LocksMap[D]; + } } void RrdHost::removeDimension(Dimension *D) { @@ -272,6 +308,7 @@ void RrdHost::getConfigAsJson(nlohmann::json &Json) const { Json["smooth-n"] = Cfg.SmoothN; Json["lag-n"] = Cfg.LagN; + Json["random-sampling-ratio"] = Cfg.RandomSamplingRatio; Json["max-kmeans-iters"] = Cfg.MaxKMeansIters; Json["dimension-anomaly-score-threshold"] = Cfg.DimensionAnomalyScoreThreshold; @@ -310,11 +347,7 @@ void TrainableHost::trainDimension(Dimension *D, const TimePoint &NowTP) { return; D->LastTrainedAt = NowTP + Seconds{D->updateEvery()}; - - TimePoint StartTP = SteadyClock::now(); D->trainModel(); - Duration Duration = SteadyClock::now() - StartTP; - D->updateTrainingDuration(Duration.count()); { std::lock_guard Lock(Mutex); @@ -323,14 +356,21 @@ void TrainableHost::trainDimension(Dimension *D, const TimePoint &NowTP) { } void TrainableHost::train() { - Duration MaxSleepFor = Seconds{updateEvery()}; + Duration MaxSleepFor = Seconds{10 * updateEvery()}; while (!netdata_exit) { + netdata_thread_testcancel(); + netdata_thread_disable_cancelability(); + + updateResourceUsage(); + TimePoint NowTP = SteadyClock::now(); auto P = findDimensionToTrain(NowTP); trainDimension(P.first, NowTP); + netdata_thread_enable_cancelability(); + Duration AllottedDuration = P.second; Duration RealDuration = SteadyClock::now() - NowTP; @@ -344,7 +384,7 @@ void TrainableHost::train() { } void DetectableHost::detectOnce() { - auto P = BRW.insert(AnomalyRate >= Cfg.HostAnomalyRateThreshold); + auto P = BRW.insert(WindowAnomalyRate >= Cfg.HostAnomalyRateThreshold); BitRateWindow::Edge Edge = P.first; size_t WindowLength = P.second; @@ -358,8 +398,9 @@ void DetectableHost::detectOnce() { size_t NumNormalDimensions = 0; size_t NumTrainedDimensions = 0; - double TotalTrainingDuration = 0.0; - double MaxTrainingDuration = 0.0; + bool CollectAnomalyRates = (++AnomalyRateTimer == Cfg.DBEngineAnomalyRateEvery); + if (CollectAnomalyRates) + rrdset_next(AnomalyRateRS); { std::lock_guard Lock(Mutex); @@ -371,38 +412,44 @@ void DetectableHost::detectOnce() { auto P = D->detect(WindowLength, ResetBitCounter); bool IsAnomalous = P.first; - double AnomalyRate = P.second; + double AnomalyScore = P.second; NumTrainedDimensions += D->isTrained(); - double DimTrainingDuration = D->updateTrainingDuration(0.0); - MaxTrainingDuration = std::max(MaxTrainingDuration, DimTrainingDuration); - TotalTrainingDuration += DimTrainingDuration; - if (IsAnomalous) NumAnomalousDimensions += 1; - if (NewAnomalyEvent && (AnomalyRate >= Cfg.ADDimensionRateThreshold)) - DimsOverThreshold.push_back({ AnomalyRate, D->getID() }); + if (NewAnomalyEvent && (AnomalyScore >= Cfg.ADDimensionRateThreshold)) + DimsOverThreshold.push_back({ AnomalyScore, D->getID() }); + + D->updateAnomalyBitCounter(AnomalyRateRS, AnomalyRateTimer, IsAnomalous); } if (NumAnomalousDimensions) - AnomalyRate = static_cast(NumAnomalousDimensions) / DimensionsMap.size(); + WindowAnomalyRate = static_cast(NumAnomalousDimensions) / DimensionsMap.size(); else - AnomalyRate = 0.0; + WindowAnomalyRate = 0.0; NumNormalDimensions = DimensionsMap.size() - NumAnomalousDimensions; } + if (CollectAnomalyRates) { + AnomalyRateTimer = 0; + rrdset_done(AnomalyRateRS); + } + this->NumAnomalousDimensions = NumAnomalousDimensions; this->NumNormalDimensions = NumNormalDimensions; this->NumTrainedDimensions = NumTrainedDimensions; updateDimensionsChart(getRH(), NumTrainedDimensions, NumNormalDimensions, NumAnomalousDimensions); - updateRateChart(getRH(), AnomalyRate * 10000.0); + updateRateChart(getRH(), WindowAnomalyRate * 10000.0); updateWindowLengthChart(getRH(), WindowLength); updateEventsChart(getRH(), P, ResetBitCounter, NewAnomalyEvent); - updateTrainingChart(getRH(), TotalTrainingDuration * 1000.0, MaxTrainingDuration * 1000.0); + + struct rusage TRU; + getResourceUsage(&TRU); + updateTrainingChart(getRH(), &TRU); if (!NewAnomalyEvent || (DimsOverThreshold.size() == 0)) return; @@ -431,15 +478,17 @@ void DetectableHost::detectOnce() { void DetectableHost::detect() { std::this_thread::sleep_for(Seconds{10}); - while (!netdata_exit) { - TimePoint StartTP = SteadyClock::now(); - detectOnce(); - TimePoint EndTP = SteadyClock::now(); + heartbeat_t HB; + heartbeat_init(&HB); - Duration Dur = EndTP - StartTP; - updateDetectionChart(getRH(), Dur.count() * 1000); + while (!netdata_exit) { + netdata_thread_testcancel(); + heartbeat_next(&HB, updateEvery() * USEC_PER_SEC); - std::this_thread::sleep_for(Seconds{updateEvery()}); + netdata_thread_disable_cancelability(); + detectOnce(); + updateDetectionChart(getRH()); + netdata_thread_enable_cancelability(); } } @@ -457,6 +506,9 @@ void DetectableHost::startAnomalyDetectionThreads() { } void DetectableHost::stopAnomalyDetectionThreads() { + netdata_thread_cancel(TrainingThread.native_handle()); + netdata_thread_cancel(DetectionThread.native_handle()); + TrainingThread.join(); DetectionThread.join(); } diff --git a/ml/Host.h b/ml/Host.h index 86591d7ae..61d3b1625 100644 --- a/ml/Host.h +++ b/ml/Host.h @@ -14,7 +14,27 @@ namespace ml { class RrdHost { public: - RrdHost(RRDHOST *RH) : RH(RH) {} + RrdHost(RRDHOST *RH) : RH(RH) { + AnomalyRateRS = rrdset_create( + RH, + "anomaly_detection", + "anomaly_rates", + NULL, // name + "anomaly_rates", + NULL, // ctx + "Average anomaly rate", + "anomaly rate", + "netdata", + "ml", + 39189, + Cfg.DBEngineAnomalyRateEvery, + RRDSET_TYPE_LINE + ); + + AnomalyRateRS->flags = static_cast( + static_cast(AnomalyRateRS->flags) | RRDSET_FLAG_HIDDEN + ); + } RRDHOST *getRH() { return RH; } @@ -35,12 +55,13 @@ public: protected: RRDHOST *RH; + RRDSET *AnomalyRateRS; // Protect dimension and lock maps std::mutex Mutex; - std::map DimensionsMap; - std::map LocksMap; + std::unordered_map DimensionsMap; + std::unordered_map LocksMap; }; class TrainableHost : public RrdHost { @@ -49,9 +70,22 @@ public: void train(); + void updateResourceUsage() { + std::lock_guard Lock(ResourceUsageMutex); + getrusage(RUSAGE_THREAD, &ResourceUsage); + } + + void getResourceUsage(struct rusage *RU) { + std::lock_guard Lock(ResourceUsageMutex); + memcpy(RU, &ResourceUsage, sizeof(struct rusage)); + } + private: std::pair> findDimensionToTrain(const TimePoint &NowTP); void trainDimension(Dimension *D, const TimePoint &NowTP); + + struct rusage ResourceUsage{}; + std::mutex ResourceUsageMutex; }; class DetectableHost : public TrainableHost { @@ -88,12 +122,14 @@ private: static_cast(Cfg.ADMinWindowSize * Cfg.ADWindowRateThreshold) }; - CalculatedNumber AnomalyRate{0.0}; + CalculatedNumber WindowAnomalyRate{0.0}; size_t NumAnomalousDimensions{0}; size_t NumNormalDimensions{0}; size_t NumTrainedDimensions{0}; + unsigned AnomalyRateTimer{0}; + Database DB{Cfg.AnomalyDBPath}; }; diff --git a/ml/README.md b/ml/README.md index 06f099fc2..06979ea15 100644 --- a/ml/README.md +++ b/ml/README.md @@ -1,3 +1,9 @@ + # Machine learning (ML) powered anomaly detection ## Overview @@ -154,9 +160,11 @@ Below is a list of all the available configuration params and their default valu # maximum num samples to train = 14400 # minimum num samples to train = 3600 # train every = 3600 + # dbengine anomaly rate every = 60 # num samples to diff = 1 # num samples to smooth = 3 # num samples to lag = 5 + # random sampling ratio = 0.2 # maximum number of k-means iterations = 1000 # dimension anomaly score threshold = 0.99 # host anomaly rate threshold = 0.01000 @@ -166,7 +174,7 @@ Below is a list of all the available configuration params and their default valu # window minimum anomaly rate = 0.25000 # anomaly event min dimension rate threshold = 0.05000 # hosts to skip from training = !* - # charts to skip from training = !system.* !cpu.* !mem.* !disk.* !disk_* !ip.* !ipv4.* !ipv6.* !net.* !net_* !netfilter.* !services.* !apps.* !groups.* !user.* !ebpf.* !netdata.* * + # charts to skip from training = netdata.* ``` ### Descriptions (min/max) @@ -175,9 +183,11 @@ Below is a list of all the available configuration params and their default valu - `maximum num samples to train`: (`3600`/`21600`) This is the maximum amount of time you would like to train each model on. For example, the default of `14400` trains on the preceding 4 hours of data, assuming an `update every` of 1 second. - `minimum num samples to train`: (`900`/`21600`) This is the minimum amount of data required to be able to train a model. For example, the default of `3600` implies that once at least 1 hour of data is available for training, a model is trained, otherwise it is skipped and checked again at the next training run. - `train every`: (`1800`/`21600`) This is how often each model will be retrained. For example, the default of `3600` means that each model is retrained every hour. Note: The training of all models is spread out across the `train every` period for efficiency, so in reality, it means that each model will be trained in a staggered manner within each `train every` period. +- `dbengine anomaly rate every`: (`30`/`900`) This is how often netdata will aggregate all the anomaly bits into a single chart (`anomaly_detection.anomaly_rates`). The aggregation into a single chart allows enabling anomaly rate ranking over _all_ metrics with one API call as opposed to a call per chart. - `num samples to diff`: (`0`/`1`) This is a `0` or `1` to determine if you want the model to operate on differences of the raw data or just the raw data. For example, the default of `1` means that we take differences of the raw values. Using differences is more general and works on dimensions that might naturally tend to have some trends or cycles in them that is normal behavior to which we don't want to be too sensitive. - `num samples to smooth`: (`0`/`5`) This is a small integer that controls the amount of smoothing applied as part of the feature processing used by the model. For example, the default of `3` means that the rolling average of the last 3 values is used. Smoothing like this helps the model be a little more robust to spiky types of dimensions that naturally "jump" up or down as part of their normal behavior. - `num samples to lag`: (`0`/`5`) This is a small integer that determines how many lagged values of the dimension to include in the feature vector. For example, the default of `5` means that in addition to the most recent (by default, differenced and smoothed) value of the dimension, the feature vector will also include the 5 previous values too. Using lagged values in our feature representation allows the model to work over strange patterns over recent values of a dimension as opposed to just focusing on if the most recent value itself is big or small enough to be anomalous. +- `random sampling ratio`: (`0.2`/`1.0`) This parameter determines how much of the available training data is randomly sampled when training a model. The default of `0.2` means that Netdata will train on a random 20% of training data. This parameter influences cost efficiency. At `0.2` the model is still reasonably trained while minimizing system overhead costs caused by the training. - `maximum number of k-means iterations`: This is a parameter that can be passed to the model to limit the number of iterations in training the k-means model. Vast majority of cases can ignore and leave as default. - `dimension anomaly score threshold`: (`0.01`/`5.00`) This is the threshold at which an individual dimension at a specific timestep is considered anomalous or not. For example, the default of `0.99` means that a dimension with an anomaly score of 99% or higher is flagged as anomalous. This is a normalized probability based on the training data, so the default of 99% means that anything that is as strange (based on distance measure) or more strange as the most strange 1% of data observed during training will be flagged as anomalous. If you wanted to make the anomaly detection on individual dimensions more sensitive you could try a value like `0.90` (90%) or to make it less sensitive you could try `1.5` (150%). - `host anomaly rate threshold`: (`0.0`/`1.0`) This is the percentage of dimensions (based on all those enabled for anomaly detection) that need to be considered anomalous at specific timestep for the host itself to be considered anomalous. For example, the default value of `0.01` means that if more than 1% of dimensions are anomalous at the same time then the host itself is considered in an anomalous state. @@ -186,7 +196,7 @@ Below is a list of all the available configuration params and their default valu - `window minimum anomaly rate`: (`0.0`/`1.0`) This parameter corresponds to a threshold on the percentage of time in the rolling window that the host was considered in an anomalous state. For example, the default of `0.25` means that if the host is in an anomalous state for 25% of more of the rolling window then and anomaly event will be triggered or extended if one is already active. Note: If you want to make the anomaly detector itself less sensitive, you can adjust this value to something like `0.75` which would mean the host needs to be much more consistently in an anomalous state to trigger an anomaly detection event. Likewise, a lower value like `0.1` would make the anomaly detector more sensitive. - `anomaly event min dimension rate threshold`: (`0.0`/`1.0`) This is a parameter that helps filter out irrelevant dimensions from anomaly events. For example, the default of `0.05` means that only dimensions that were considered anomalous for at least 5% of the anomaly event itself will be included in that anomaly event. The idea here is to just include dimensions that were consistently anomalous as opposed to those that may have just randomly happened to be anomalous at the same time. - `hosts to skip from training`: This parameter allows you to turn off anomaly detection for any child hosts on a parent host by defining those you would like to skip from training here. For example, a value like `dev-*` skips all hosts on a parent that begin with the "dev-" prefix. The default value of `!*` means "don't skip any". -- `charts to skip from training`: This parameter allows you to exclude certain charts from anomaly detection by defining them here. By default, all charts, apart from a specific allow list of the typical basic Netdata charts, are excluded. If you have additional charts you would like to include for anomaly detection, you can add them here. **Note**: It is recommended to add charts in small groups and then measure any impact on performance before adding additional ones. +- `charts to skip from training`: This parameter allows you to exclude certain charts from anomaly detection. By default, only netdata related charts are excluded. This is to avoid the scenario where accessing the netdata dashboard could itself tigger some anomalies if you don't access them regularly. If you want to include charts that are excluded by default, add them in small groups and then measure any impact on performance before adding additional ones. Example: If you want to include system, apps, and user charts:`!system.* !apps.* !user.* *`. ## Charts diff --git a/ml/kmeans/SamplesBuffer.cc b/ml/kmeans/SamplesBuffer.cc index f8211fb54..d276c6e09 100644 --- a/ml/kmeans/SamplesBuffer.cc +++ b/ml/kmeans/SamplesBuffer.cc @@ -130,7 +130,13 @@ std::vector SamplesBuffer::preprocess() { DSamples.reserve(OutN); Preprocessed = true; + uint32_t MaxMT = std::numeric_limits::max(); + uint32_t CutOff = static_cast(MaxMT) * SamplingRatio; + for (size_t Idx = NumSamples - OutN; Idx != NumSamples; Idx++) { + if (RandNums[Idx] > CutOff) + continue; + DSample DS; DS.set_size(NumDimsPerSample * (LagN + 1)); diff --git a/ml/kmeans/SamplesBuffer.h b/ml/kmeans/SamplesBuffer.h index 5c3cb1a97..1c7215cca 100644 --- a/ml/kmeans/SamplesBuffer.h +++ b/ml/kmeans/SamplesBuffer.h @@ -80,9 +80,11 @@ class SamplesBuffer { public: SamplesBuffer(CalculatedNumber *CNs, size_t NumSamples, size_t NumDimsPerSample, - size_t DiffN = 1, size_t SmoothN = 3, size_t LagN = 3) : + size_t DiffN, size_t SmoothN, size_t LagN, + double SamplingRatio, std::vector &RandNums) : CNs(CNs), NumSamples(NumSamples), NumDimsPerSample(NumDimsPerSample), DiffN(DiffN), SmoothN(SmoothN), LagN(LagN), + SamplingRatio(SamplingRatio), RandNums(RandNums), BytesPerSample(NumDimsPerSample * sizeof(CalculatedNumber)), Preprocessed(false) {}; @@ -129,6 +131,9 @@ private: size_t DiffN; size_t SmoothN; size_t LagN; + double SamplingRatio; + std::vector &RandNums; + size_t BytesPerSample; bool Preprocessed; }; diff --git a/ml/ml-dummy.c b/ml/ml-dummy.c index 222f0b0f6..fad480f4b 100644 --- a/ml/ml-dummy.c +++ b/ml/ml-dummy.c @@ -4,6 +4,15 @@ #if !defined(ENABLE_ML) +bool ml_capable() { + return false; +} + +bool ml_enabled(RRDHOST *RH) { + (void) RH; + return false; +} + void ml_init(void) {} void ml_new_host(RRDHOST *RH) { (void) RH; } @@ -38,4 +47,19 @@ char *ml_get_anomaly_event_info(RRDHOST *RH, const char *AnomalyDetectorName, return NULL; } +void ml_process_rrdr(RRDR *R, int MaxAnomalyRates) { + (void) R; + (void) MaxAnomalyRates; +} + +void ml_dimension_update_name(RRDSET *RS, RRDDIM *RD, const char *name) { + (void) RS; + (void) RD; + (void) name; +} + +bool ml_streaming_enabled() { + return false; +} + #endif diff --git a/ml/ml.cc b/ml/ml.cc index cfda3d28f..b56401b07 100644 --- a/ml/ml.cc +++ b/ml/ml.cc @@ -4,8 +4,24 @@ #include "Dimension.h" #include "Host.h" +#include + using namespace ml; +bool ml_capable() { + return true; +} + +bool ml_enabled(RRDHOST *RH) { + if (!Cfg.EnableAnomalyDetection) + return false; + + if (simple_pattern_matches(Cfg.SP_HostsToSkip, RH->hostname)) + return false; + + return true; +} + /* * Assumptions: * 1) hosts outlive their sets, and sets outlive their dimensions, @@ -13,14 +29,24 @@ using namespace ml; */ void ml_init(void) { + // Read config values Cfg.readMLConfig(); -} -void ml_new_host(RRDHOST *RH) { if (!Cfg.EnableAnomalyDetection) return; - if (simple_pattern_matches(Cfg.SP_HostsToSkip, RH->hostname)) + // Generate random numbers to efficiently sample the features we need + // for KMeans clustering. + std::random_device RD; + std::mt19937 Gen(RD()); + + Cfg.RandomNums.reserve(Cfg.MaxTrainSamples); + for (size_t Idx = 0; Idx != Cfg.MaxTrainSamples; Idx++) + Cfg.RandomNums.push_back(Gen()); +} + +void ml_new_host(RRDHOST *RH) { + if (!ml_enabled(RH)) return; Host *H = new Host(RH); @@ -64,7 +90,10 @@ void ml_delete_dimension(RRDDIM *RD) { return; Host *H = static_cast(RD->rrdset->rrdhost->ml_host); - H->removeDimension(D); + if (!H) + delete D; + else + H->removeDimension(D); RD->state->ml_dimension = nullptr; } @@ -150,6 +179,48 @@ char *ml_get_anomaly_event_info(RRDHOST *RH, const char *AnomalyDetectorName, return strdup(Json.dump(4, '\t').c_str()); } +void ml_process_rrdr(RRDR *R, int MaxAnomalyRates) { + if (R->rows != 1) + return; + + if (MaxAnomalyRates < 1 || MaxAnomalyRates >= R->d) + return; + + calculated_number *CNs = R->v; + RRDR_DIMENSION_FLAGS *DimFlags = R->od; + + std::vector> V; + + V.reserve(R->d); + for (int Idx = 0; Idx != R->d; Idx++) + V.emplace_back(CNs[Idx], Idx); + + std::sort(V.rbegin(), V.rend()); + + for (int Idx = MaxAnomalyRates; Idx != R->d; Idx++) { + int UnsortedIdx = V[Idx].second; + + int OldFlags = static_cast(DimFlags[UnsortedIdx]); + int NewFlags = OldFlags | RRDR_DIMENSION_HIDDEN; + + DimFlags[UnsortedIdx] = static_cast(NewFlags); + } +} + +void ml_dimension_update_name(RRDSET *RS, RRDDIM *RD, const char *Name) { + (void) RS; + + Dimension *D = static_cast(RD->state->ml_dimension); + if (!D) + return; + + D->setAnomalyRateRDName(Name); +} + +bool ml_streaming_enabled() { + return Cfg.StreamADCharts; +} + #if defined(ENABLE_ML_TESTS) #include "gtest/gtest.h" @@ -163,3 +234,5 @@ int test_ml(int argc, char *argv[]) { } #endif // ENABLE_ML_TESTS + +#include "ml-private.h" diff --git a/ml/ml.h b/ml/ml.h index 783bfabb9..4b33b2236 100644 --- a/ml/ml.h +++ b/ml/ml.h @@ -8,10 +8,19 @@ extern "C" { #endif #include "daemon/common.h" +#include "web/api/queries/rrdr.h" + +// This is an internal DBEngine function redeclared here so that we can free +// the anomaly rate dimension, whenever its backing dimension is freed. +extern void rrddim_free_custom(RRDSET *st, RRDDIM *rd, int db_rotated); typedef void* ml_host_t; typedef void* ml_dimension_t; +bool ml_capable(); + +bool ml_enabled(RRDHOST *RH); + void ml_init(void); void ml_new_host(RRDHOST *RH); @@ -31,6 +40,14 @@ char *ml_get_anomaly_events(RRDHOST *RH, const char *AnomalyDetectorName, char *ml_get_anomaly_event_info(RRDHOST *RH, const char *AnomalyDetectorName, int AnomalyDetectorVersion, time_t After, time_t Before); +void ml_process_rrdr(RRDR *R, int MaxAnomalyRates); + +void ml_dimension_update_name(RRDSET *RS, RRDDIM *RD, const char *name); + +bool ml_streaming_enabled(); + +#define ML_ANOMALY_RATES_CHART_ID "anomaly_detection.anomaly_rates" + #if defined(ENABLE_ML_TESTS) int test_ml(int argc, char *argv[]); #endif diff --git a/ml/notebooks/README.md b/ml/notebooks/README.md new file mode 100644 index 000000000..5e9db6dee --- /dev/null +++ b/ml/notebooks/README.md @@ -0,0 +1,5 @@ +## Machine Learning Notebooks + +This folder is a home for any documentation supporting machine learning related notebooks. + +- [Netdata anomaly detection deepdive](netdata_anomaly_detection_deepdive.ipynb): This is a starter notebook to help users understand how anomaly detection works in the Netdata agent and go a little deeper if they want. \ No newline at end of file diff --git a/ml/notebooks/netdata_anomaly_detection_deepdive.ipynb b/ml/notebooks/netdata_anomaly_detection_deepdive.ipynb new file mode 100644 index 000000000..8d0c0c7e5 --- /dev/null +++ b/ml/notebooks/netdata_anomaly_detection_deepdive.ipynb @@ -0,0 +1,1712 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "## Netdata Anomaly Detection Deepdive" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/netdata/netdata/blob/master/ml/notebooks/netdata_anomaly_detection_deepdive.ipynb)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "This notebook will walk through a simplified python based implementation of the C & C++ code in [`netdata/netdata/ml/`](https://github.com/netdata/netdata/tree/master/ml) used to power the [anomaly detection capabilities](https://github.com/netdata/netdata/blob/master/ml/README.md) of the Netdata agent.\n", + "\n", + "The main goal here is to help interested users learn more about how the machine learning works under the hood. If you just want to get started by enabling ml on your agent you can check out these [simple configuration steps](https://learn.netdata.cloud/docs/agent/ml#configuration). \n", + "\n", + "🚧 **Note**: This functionality is still under active development and considered experimental. Changes might cause the feature to break. We dogfood it internally and among early adopters within the Netdata community to build the feature. If you would like to get involved and help us with some feedback, email us at analytics-ml-team@netdata.cloud or come join us in the [🤖-ml-powered-monitoring](https://discord.gg/4eRSEUpJnc) channel of the Netdata discord. Alternativley, if GitHub is more of your thing, feel free to create a [GitHub discussion](https://github.com/netdata/netdata/discussions?discussions_q=label%3Aarea%2Fml).\n", + "\n", + "In this notebook we will:\n", + "\n", + "1. [**Get raw data**](#get-raw-data): Pull some recent data from one of our demo agents.\n", + "2. [**Add some anomalous data**](#add-some-anomalous-data): Be evil and mess up the tail end of the data to make it obviously \"anomalous\".\n", + "3. [**Lets do some ML!**](#lets-do-some-ml): Implement an unsupervised clustering based approach to anomaly detection.\n", + "4. [**Lets visualize all this!**](#lets-visualize-all-this): Plot and explore all this visually.\n", + "5. [**So, how does it _actually_ work?**](#so-how-does-it-actually-work): Dig a little deeper on what's going on under the hood." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "### Imports & Helper Functions" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "Uncomment and run the next cell to install [netdata-pandas](https://github.com/netdata/netdata-pandas) which we will use to easily pull data from the [Netdata agent REST API](https://learn.netdata.cloud/docs/agent/web/api) into a nice clean [Pandas](https://pandas.pydata.org/) [DataFrame](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html) where it will be easier to work with. \n", + "\n", + "Once you have [netdata-pandas](https://github.com/netdata/netdata-pandas) installed you can comment it back out and rerun the cell to clear the output." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "id": "aL4gm-jUffEx", + "pycharm": { + "is_executing": true + } + }, + "outputs": [], + "source": [ + "# uncomment the line below (when running in google colab) to install the netdata-pandas library, comment it again when done.\n", + "#!pip install netdata-pandas" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "id": "EMZBHjG4mOQh", + "pycharm": { + "is_executing": true + } + }, + "outputs": [], + "source": [ + "from datetime import datetime, timedelta\n", + "import itertools\n", + "import random\n", + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "import matplotlib.patches as mpatches\n", + "from sklearn.cluster import KMeans\n", + "from scipy.spatial.distance import cdist\n", + "from netdata_pandas.data import get_data\n", + "\n", + "# helper functions\n", + "\n", + "\n", + "def preprocess_df(df, lags_n, diffs_n, smooth_n):\n", + " \"\"\"Given a pandas dataframe preprocess it to take differences, add smoothing, lags and abs values. \n", + " \"\"\"\n", + " if diffs_n >= 1:\n", + " # take differences\n", + " df = df.diff(diffs_n).dropna()\n", + " if smooth_n >= 2:\n", + " # apply a rolling average to smooth out the data a bit\n", + " df = df.rolling(smooth_n).mean().dropna()\n", + " if lags_n >= 1:\n", + " # for each dimension add a new columns for each of lags_n lags of the differenced and smoothed values for that dimension\n", + " df_columns_new = [f'{col}_lag{n}' for n in range(lags_n+1) for col in df.columns]\n", + " df = pd.concat([df.shift(n) for n in range(lags_n + 1)], axis=1).dropna()\n", + " df.columns = df_columns_new\n", + " # sort columns to have lagged values next to each other for clarity when looking at the feature vectors\n", + " df = df.reindex(sorted(df.columns), axis=1)\n", + " \n", + " # take absolute values as last step\n", + " df = abs(df)\n", + " \n", + " return df\n", + "\n", + "\n", + "def add_shading_to_plot(ax, a, b, t, c='y', alpha=0.2):\n", + " \"\"\"Helper function to add shading to plot and add legend item.\n", + " \"\"\"\n", + " plt.axvspan(a, b, color=c, alpha=alpha, lw=0)\n", + " handles, labels = ax.get_legend_handles_labels()\n", + " patch = mpatches.Patch(color=c, label=t, alpha=alpha)\n", + " handles.append(patch) \n", + " plt.legend(handles=handles)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Inputs & Parameters" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A full list of all the anomaly detection configuration parameters, and descriptions of each, can be found in the [configuration](https://github.com/netdata/netdata/blob/master/ml/README.md#configuration) section of the [ml readme](https://github.com/netdata/netdata/blob/master/ml/README.md).\n", + "\n", + "Below we will focus on some basic params to decide what data to pull and the main ml params of importance in understanding how it all works.\n", + "\n", + "#### training size/scheduling parameters:\n", + "- `train_every`: How often to train or retrain each model.\n", + "- `num_samples_to_train`: How much of the recent data to train on, for example 3600 would mean training on the last 1 hour of raw data. The default in the netdata agent currently is 14400, so last 4 hours.\n", + "\n", + "#### feature preprocessing related parameters:\n", + "- `num_samples_to_diff`: This is really just a 1 or 0 flag to turn on or off differencing in the feature preprocessing. It defaults to 1 (to take differences) and generally should be left alone.\n", + "- `num_samples_to_smooth`: The extent of smoothing (averaging) applied as part of feature preprocessing.\n", + "- `num_samples_to_lag`: The number of previous values to also include in our feature vector.\n", + "\n", + "#### anomaly score related parameters:\n", + "- `dimension_anomaly_score_threshold`: The threshold on the anomaly score, above which the data it considered anomalous and the [anomaly bit](https://github.com/netdata/netdata/blob/master/ml/README.md#anomaly-bit) is set to 1 (its actually set to 100 in reality but this just to make it behave more like a rate when aggregated in the netdata agent api). By default this is `0.99` which means anything with an anomaly score above 99% is considered anomalous. Decreasing this threshold makes the model more sensitive and will leave to more anomaly bits, increasing it does the opposite.\n", + "\n", + "#### model parameters:\n", + "- `n_clusters_per_dimension`: This is the number of clusters to fit for each model, by default it is set to 2 such that 2 cluster [centroids](https://en.wikipedia.org/wiki/Centroid) will be fit for each model.\n", + "- `max_iterations`: The maximum number of iterations the fitting of the clusters is allowed to take. In reality the clustering will converge a lot sooner than this.\n", + "\n", + "**Note**: There is much more detailed discussion of all there configuration parameters in the [\"Configuration\"](https://github.com/netdata/netdata/blob/master/ml/README.md#configuration) section of the ml readme." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "id": "tBUVUpR3fohX" + }, + "outputs": [], + "source": [ + "# data params\n", + "hosts = ['london.my-netdata.io']\n", + "charts = ['system.cpu']\n", + "# if want to just focus on a subset of dims, in this case lets just pick one for simplicity\n", + "dims = ['system.cpu|user'] \n", + "last_n_hours = 2\n", + "# based on last_n_hours define the relevant 'before' and 'after' params for the netdata rest api on the agent\n", + "before = int(datetime.utcnow().timestamp())\n", + "after = int((datetime.utcnow() - timedelta(hours=last_n_hours)).timestamp())\n", + "\n", + "# ml params\n", + "train_every = 3600\n", + "num_samples_to_train = 3600\n", + "num_samples_to_diff = 1\n", + "num_samples_to_smooth = 3\n", + "num_samples_to_lag = 5\n", + "dimension_anomaly_score_threshold = 0.99\n", + "n_clusters_per_dimension = 2\n", + "max_iterations = 1000" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1. Get raw data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next we will use the `get_data()` function from the [netdata-pandas](https://github.com/netdata/netdata-pandas) library to just pull down our raw data from the agent into a Pandas dataframe." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 660 + }, + "id": "Ypudrfu-fpje", + "outputId": "b25c7322-03b4-4475-c416-37c3abbe78a4" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(7200, 1)\n", + "1647978087 1647985286\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
system.cpu|user
time_idx
16479780871.503759
16479780880.252525
16479780890.755668
16479780900.503778
16479780910.501253
\n", + "
" + ], + "text/plain": [ + " system.cpu|user\n", + "time_idx \n", + "1647978087 1.503759\n", + "1647978088 0.252525\n", + "1647978089 0.755668\n", + "1647978090 0.503778\n", + "1647978091 0.501253" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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iIiIiEizJ35ejw17Sw1d5oDOLfDYnwaG/L2iogJXXHEF8vPz0dDQgEceeQRffvklfvjhBwDAjBkz8Oabb2Ly5Mm45ZZbkJOTAyEEbr75ZnTr1g05OTm49tpr0aRJEyxatAgbNmzAfffdh/LycrRr1w4TJ05Ep06dcPrpp+O4447DH3/8gYqKCnzyySd49tlnsXbtWlx55ZUYP358UNqWLVuGu+++GxUVFcjMzMSsWbPw7bff4vvvv0dJSQn27NmD6667Do899hhyc3Nx4YUXYt26dQCAF198EeXl5UFXLidOnIicnBy8/vrrAIALL7wQDzzwAEaNGhW0fffeey+2b9+OO+64A4WFhWjatCnee+899OvXDzfeeCOysrKwcuVKjBw5Ei+//HJMx4kBpo0crqhF6+wMq5NBREREROQ4U6dORefOnTFlyhQAQElJCR577DEUFhaiffv2+Oijj3DzzTdj1apV2LNnjy+AKy4uRqtWrfD666/jxRdfxLBhw1BXV4e77roLP/74I9q3b49JkybhP//5Dz788EMAQEZGBnJycvDf//4XF110EZYvX442bdqgV69euPfee9G2bVtfumpra3HllVdi0qRJGD58OEpLS9GkSRMAwNKlS7Fu3To0bdoUw4cPx5gxY9CuXbuY9oPa9gHArbfeirfffhu9e/fGkiVL8I9//AOzZ88G4H7FzMKFC5GamhrTugEGmLbx46o9uPurVfjhjpEY0q2V1ckhIiIiIopauCuNZhk0aBDuv/9+/Otf/8KFF16IUaNG4frrr8dnn32Gm266CYsWLcInn3yCsrIy7NixA3fddRfGjBmDc845J2hZmzdvxrp163D22WcDABoaGtCpUyff7//3f//nW+fAgQN9v/Xs2RN5eXl+AebmzZvRqVMnDB8+HADQokUL329nn322b9pLLrkE8+fPx5///OeY9kPPnj2Dtq+8vBwLFy7E5Zdf7puupqbG9/fll19uSHAJMMC0jUXbDwIANu4rZYBJRERERKRTnz59sGLFCvz6668YN24czjrrLPz1r3/Fn/70J2RlZeHyyy9HWloaWrdujdWrV2PatGl4++238fXXX/uuTHpJKTFw4EAsWrRIdV2ZmZkAgJSUFN/f3s967mMMfA2IEAJpaWlwuVy+70K9hzLUdGrb9+qrr6JVq1ZYtWqV6rKys7M1pzkSPuSHiIiIiIgcb+/evWjatCmuu+46PPjgg1ixYgU6d+6Mzp07Y/z48bjpppsAAEVFRXC5XLj00ksxfvx4rFixAgDQvHlzlJWVAQD69u2LwsJCX4BZV1eH9evXR5Wuvn37Yt++fVi2bBkAoKyszBeEzpgxA4cOHUJVVRV++OEHjBw5Eh07dkRBQQEOHjyImpoa/PLLL6rL7d69O1atWgWXy4W8vDwsXbo05Pa1aNECPXr0wDfffAPAHUCvXr06qu2JhFcwiYiIiIjI8dauXYsHH3wQKSkpSE9Px1tvvQUAuPbaa1FYWIj+/fsDAPbs2YObbrrJd/Xv2WefBQDceOONuP32230P+Zk8eTL++c9/oqSkBPX19bjnnnswcKD2ob8XXHAB3n//fXTu3BmTJk3CXXfdhaqqKjRp0gQzZ84EAIwYMQKXXnop8vPzcd1112HYsGEAgEcffRQjRoxAly5d0K9fP9Xljxw5Ej169MCAAQPQv39/HH/88WG37/PPP8ff//53jB8/HnV1dbjqqqswePBgXftYCyGlNHyhw4YNkzk5OYYvN5GN/XYNvlqWh2cvGYSrRxxpdXKIiIiIiHTZuHGjL4izkzvvvBPHHXccbrnlFquT4ifwKbBa58nNzY3ruzDVjqsQYrmUcpja9LyCSURERERECWno0KHIzs7GSy+9ZHVSkgYDTCIiIiIiSkjLly+3Ogkh3Xjjjbjxxht1zTNkyBB0797dlPQYhQGmTZgwUpmIiIiIKK6klEFPRiXjDBkyJK7ri+Z2Sj5FloiIiIiIYpaVlYWDBw9GFZSQ/UgpcfDgQWRlZemaj1cwbYIdPURERETkZF27dkV+fj4KCwutTgoZJCsrC127dtU1DwNMIiIiIiKKWXp6Onr06GF1MshiHCJLREREREREhmCASURERERERIZggElERERERESGYIBpE3zYFhEREREROR0DTJvhw2SJiIiIiMipGGDaDC9kEhERERGRUzHAtAm+B5OIiIiIiJyOASYREREREREZggEmERERERERGYIBJhERERERERmCAaZN8DUlRERERETkdAwwbYbP+iEiIiIiIqdigGkzvJBJREREREROxQDTJviaEiIiIiIicjoGmERERERERGQIBphERERERERkCAaYNsGnyBIRERERkdMxwLQZ3opJREREREROxQCTiIiIiIiIDMEAk4iIiIiIiAzBANNmeCsmERERERE5FQNMm+B7MImIiIiIyOkYYBIREREREZEhGGDaBF9TQkRERERETscA02Y4UpaIiIiIiJyKASYREREREREZggEmERERERERGYIBJhERERERERmCAabN8Fk/RERERETkVAwwbYLvwSQiIiIiIqdjgGkTfE0JERERERE5HQNMm+GFTCIiIiIicioGmERERERERGQIBphERERERERkCAaYREREREREZAjNAaYQIlUIsVII8YuZCSIiIiIiIiJn0nMF824AG81KCLnxYbJERERERORUmgJMIURXAGMAvG9ucoiIiIgomU1fvx+FZTVWJ8P2dhZVYOH2IquTYXvVdQ34dnk+JN8JGDdar2C+CuAhAK5QEwghbhVC5AghcgoLC41IW1JKlteU3DJxGT6cv9PqZBAREZGNVNU24NZPl+P6D5ZYnRTbO+PFubjmPe6nSJ6fuhn3f7Ma87YwPomXiAGmEOJCAAVSyuXhppNSviulHCalHNa+fXvDEkiJadamAjz5ywark0FEREQ20uC5ypR3qNLilFCiOFBWDQAoq663OCXJQ8sVzJEA/k8IkQvgKwBnCiE+MzVVRERERERE5DgRA0wp5cNSyq5Syu4ArgIwW0p5nekpIyIiIqKkxLvliJyL78EkIiIiIltIlmdRECWyND0TSynnAphrSkqIiIiIiIhMwKvi8cMrmERERERElJB4VTz+GGASEREREVFC4pXL+GOASURERERECY1XMuOHASYRERER2YrkZScix2KASURERES2IHiZiUzCPov4YYBJREREREQJiX0W8ccAk4iIiIhsgUNjiZyPASYZZuO+Ujz83Rq4XKwdiIiSxTvztuPXtfusTgYREdkEA0wyzF8/zsGXS/Owt6TK6qQQEVGcPPvbJvzj8xVWJ4MSBO/BJHI+BphERERERJSQOK4u/hhgkuF4/wQRERHFQjIsIHIsBphEREREZAuCz/wkgzFHxR8DTCIiIiIiIjIEA0yb4FAQIiIiIiJyOgaYNsOnpxERERERkVMxwLQZPiCHiIiIiMhYko3suGGAaRO8qZ2IiIjIjbEAkXMxwCTDcHgvEREREdmRYEM1bhhgEhERERERkSEYYJLhOKyFiIiIosGn6hM5HwNMm2CBSkRERERkDj7kJ34YYNpMIgwPT4RtICIiIiLn472X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A/CilHKt57d/AHgfwDYA2wH8FrctInKIWBq5AJYB6O15YmwGgKsA/MRGLpEmqnWfEOJiIUQ+gJMATBFCTAOChqd3AjDH8/yBZXDfg/mL57d/AbhPCLEN7uHqH8RzoxKJcJdlRNETQpwC4A8AawG4PF//G+57Ub4GcCSAXQCukFIe8jy2/XbvMFkhxM2e6QHgaSnlR57vhwGYCKAJ3A3cuyQzLBER2UCYui8TwP8AtAdQDGCVlPJcz2uA3vcOk/V0Br0KIBXAh1LKpz3f94T7oT9tAKwEcJ3iic9ERLbHAJOIiIiIiIgMwSGyREREREREZAgGmERERERERGQIBphERERERERkCAaYREREREREZAgGmERERERERGQIBphERERERERkCAaYRESUVIQQrYQQ//D83VkIMdnEdd0uhPiLyvfdhRDrzFovERGRVfgeTCIiSipCiO4AfpFSHpPMaSAiIjIDr2ASEVGymQCglxBilRDiG++VRCHEjUKIH4QQM4QQuUKIO4UQ9wkhVgohFgsh2nim6yWEmCqEWC6E+EMI0S/UioQQjwshHvD8PVQIsVoIsRrAHYpp7hVCfOj5e5AQYp0QoqmZO4CIiMgsDDCJiCjZjAWwXUo5BMCDAb8dA+ASAMMBPA2gUkp5HIBFALxDXd8FcJeUciiABwC8qXG9H3nmGxzw/X8BHC2EuNgzzW1Sykp9m0RERGQPaVYngIiIyEbmSCnLAJQJIUoA/Oz5fi2AY4UQzQCcDOAbIYR3nsxICxVCtALQSkr5u+erTwGcDwBSSpcQ4kYAawC8I6VcYNC2EBERxR0DTCIiokY1ir9dis8uuOvMFADFnqufRuoNoBxAZ4OXS0REFFccIktERMmmDEDzaGaUUpYC2CmEuBwAhFvgkFe1+YoBFAshTvF8da33NyFESwCvATgVQFshxGXRpI2IiMgOGGASEVFSkVIeBLDA83CfF6JYxLUAbvE8rGc9gIs0zncTgDeEEKsACMX3rwB4Q0q5BcAtACYIITpEkS4iIiLL8TUlREREREREZAhewSQiIiIiIiJD8CE/REREMRJC/AfA5QFffyOlfNqK9BAREVmFQ2SJiIiIiIjIEBwiS0RERERERIZggElERERERESGYIBJREREREREhmCASURERERERIZggElERERERESG+H8YbnsU6K+XPwAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# get raw data\n", + "df = get_data(hosts=hosts, charts=charts, after=after, before=before)\n", + "\n", + "# filter df for just the dims if set\n", + "if len(dims):\n", + " df = df[[dim for dim in dims]]\n", + "\n", + "# set some variables based on our data\n", + "df_timestamp_min = df.index.min()\n", + "df_timestamp_max = df.index.max()\n", + "\n", + "# print some info\n", + "print(df.shape)\n", + "print(df_timestamp_min, df_timestamp_max)\n", + "display(df.head())\n", + "\n", + "# lets just plot each dimension to have a look at it\n", + "for col in df.columns: \n", + "\n", + " # plot dimension, setting index to datetime so its more readable on the plot\n", + " df[[col]].set_index(pd.to_datetime(df.index, unit='s')).plot(title=f'Raw Data - {col}', figsize=(16,6))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2. Add some anomalous data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Below we will pick the last `n_tail_anomalous` observations and mess them up in some random but noticable way. In this case we randomly shuffle the data and then multiply each observation by some integer randomly chosen from `integers_to_pick_randomly`" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 405 + }, + "id": "RDuB5PdjOaAX", + "outputId": "d686cea5-d0a8-4ed4-aa58-64770a063fbb" + }, + "outputs": [], + "source": [ + "# size of anomalous data\n", + "n_tail_anomalous = 500\n", + "integers_to_pick_randomly = [0,1,5,10]\n", + "\n", + "# randomly scramble data and multiply randomly by some numbers to make it anomalous looking\n", + "anomalous_shape = (n_tail_anomalous, len(df.columns))\n", + "randomly_scrambled_data = np.random.choice(df.tail(n_tail_anomalous).values.reshape(-1,), anomalous_shape)\n", + "random_integers = np.random.choice(integers_to_pick_randomly, anomalous_shape)\n", + "data_anomalous = randomly_scrambled_data * random_integers\n", + "\n", + "# create anomalous dataframe\n", + "df_anomalous = pd.DataFrame(data = data_anomalous, columns = df.columns)\n", + "# make sure it has the expected index since we don't want to shuffle that\n", + "df_anomalous.index = df.tail(n_tail_anomalous).index\n", + "\n", + "# overwrite last n_tail observations with anomalous data\n", + "df.update(df_anomalous)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the plot below it should be clear that the light yellow section of the data has been messed with and is now \"anomalous\" or \"strange looking\" in comparison to all the data that comes before it. \n", + "\n", + "Our goal now is to create some sort of [anomaly score](https://github.com/netdata/netdata/blob/master/ml/README.md#anomaly-score) that can easily capture this." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "image/png": "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5Zdfrscee6xO2ubOnavf/e53KisrU2Zmpr799lt9/PHH+vTTT1VUVKQtW7bo6quv1kMPPaT8/HyNGTNGS5culSQ9/fTTKi0trVPS+frrrysvL08vvPCCJGnMmDG68847dfLJJ9fZv9tvv13r1q3Tb37zGxUWFionJ0cvv/yy+vfvr+uvv15ZWVlasGCBTjzxRP39739v/AkDAAAA0OI0q8AzWSZMmKBu3bpp3LhxkqSioiI99NBDKiwsVOfOnfXaa6/pxhtv1MKFC7VlyxZfYLdv3z61a9dOL7zwgp5++mmNGDFCNTU1uu222/T555+rc+fOev/993X//ffr1VdflSRlZGQoLy9P//jHP3ThhRdq3rx56tChgw4//HDdfvvt6tixoy9d1dXVuvzyy/X+++/rmGOOUXFxsbKzsyVJc+bM0dKlS5WTk6NjjjlGo0ePVqdOnRp1HELtnyTddNNNevHFF9W3b1/Nnj1bv/71rzVlyhRJ7uFwZsyYodTU1EZtGwAAADjQFFW4lJtllHIAdMzZrALPaCWTiTJ48GD94Q9/0N13360xY8bo5JNP1jXXXKO3335bN9xwg2bOnKk333xTJSUlWr9+vW677TaNHj1aZ599dp11rVq1SkuXLtVZZ50lSXI6neratatv+gUXXODb5qBBg3zTevfurc2bNwcEnqtWrVLXrl11zDHHSJLatGnjm3bWWWf55r344ov1ww8/6KKLLmrUcejdu3ed/SstLdWMGTN06aWX+uarqqry/X3ppZcSdAIAAAD1tLvMqVHPFupXJ7XSrafmJjs5CdesAs9kOeKIIzR//nyNHz9ef/rTn3TGGWfoF7/4hX7yk58oKytLl156qdLS0tS+fXstWrRIEydO1IsvvqgPPvjAV5LpZa3VoEGDNHPmzJDbyszMlCSlpKT4/vZ+rk87yeDhSowxSktLk8vl8n0XbhzNcPOF2r9nn31W7dq108KFC0Ouq1WrVjGnGQAAAIDb7jJ3fvzbVVUHROBJ50KStm7dqpycHF199dW66667NH/+fHXr1k3dunXTY489phtuuEGStGvXLrlcLl1yySV67LHHNH/+fElSbm6uSkpKJEn9+vVTYWGhL/CsqanRsmXLGpSufv36adu2bZo7d64kqaSkxBecTpo0SXv27FFFRYU+++wznXjiierSpYt27typ3bt3q6qqSl999VXI9fbs2VMLFy6Uy+XS5s2bNWfOnLD716ZNG/Xq1UsffvihJHdgvWjRogbtDwAAAIADEyWekpYsWaK77rpLKSkpSk9P17///W9J0lVXXaXCwkINGDBAkrRlyxbdcMMNvtLCJ554QpJ0/fXX6+abb/Z1LvTRRx/pt7/9rYqKiuRwOPT73/9egwbFXo34/PPP1yuvvKJu3brp/fff12233aaKigplZ2dr8uTJkqSRI0fqkksuUUFBga6++mqNGDFCkvTggw9q5MiR6t69u/r37x9y/SeeeKJ69eqlgQMHasCAATr66KMj7t8777yjW265RY899phqamr0f//3fxoyZEi9jjEAAACAA5ex1jbZxkaMGGHz8vICvluxYoUvsGtubr31Vg0bNkw///nPk52UAMG90sa6TH5+fpOO5dmczy0AAACQSCUl8yJOX72zRpe8vFt9Oqfp05sa10loc9KmzYh51toRwd9T4hnG8OHD1apVK/3tb39LdlIAAAAAYL9G4BnGvHmR31Ak0/XXX6/rr7++XssMHTpUPXv2TEh6AAAAACASAs8DxNChQ5OdBAAAAAAHKHq1BQAAAAAkFIEnAAAAACChCDwBAAAAAAnV7Np4FhXNksOxL27rS0trp7Ztj4vb+hJp1KhRevrpp31jcibS9ddfrzFjxuhnP/tZ2Hlef/11nX322erWrVvC0wMAAACg5Wp2gafDsU8ZGZ3jtr7q6sK4retA8/rrr+vII48k8AQAAADQKFS1lXTRRRdp+PDhGjRokF566SXf961bt9b999+vIUOG6LjjjtOOHTskSfn5+Tr99NN11FFH6YwzztCmTZskuUsRb7nlFh133HHq3bu3pk2bphtvvFEDBgwIGP7klltu0YgRIzRo0CA99NBDIdP03nvvafDgwTryyCN19913B6TJ66OPPvKt98MPP9SRRx6pIUOG6JRTTqmzPmutbr31VvXr109nnnmmdu7c6Zv26KOP6phjjtGRRx6pm266SdZaffTRR8rLy9NVV12loUOHqqKiIuR8AAAAABANgaekV199VfPmzVNeXp6ee+457d69W5JUVlam4447TosWLdIpp5yil19+WZJ022236brrrtPixYt11VVX6be//a1vXXv37tXMmTP1zDPP6IILLtDtt9+uZcuWacmSJVq4cKEk6fHHH1deXp4WL16s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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# let's just plot each dimension now that we have added some anomalous data\n", + "for col in df.columns:\n", + " \n", + " ax = df.set_index(pd.to_datetime(df.index, unit='s')).plot(title=f'Anomalous Data Appended - {col}', figsize=(16,6))\n", + " add_shading_to_plot(ax, df_timestamp_max - n_tail_anomalous, df_timestamp_max, 'anomalous data')\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3. Lets do some ML!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "In this notebook we will just use good old [kmeans](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html) from [scikit-learn](https://scikit-learn.org/stable/index.html). \n", + "\n", + "In reality the Netdata Agent uses the awesome [dlib](https://github.com/davisking/dlib) c++ library and the [`find_clusters_using_kmeans`](http://dlib.net/ml.html#find_clusters_using_kmeans) function along with a few others. You can see the Netdata KMeans code [here](https://github.com/netdata/netdata/blob/master/ml/kmeans/KMeans.cc).\n", + "\n", + "The code below:\n", + "\n", + "1. Will initialize some empty objects to use during model training and inference.\n", + "2. Will loop over every observation and run training and inference in a similar way to how the Agent would process each observation.\n", + "\n", + "Of course the Agent implemtation is a lot more efficient and uses more efficient streaming and buffer based approaches as opposed to the fairly naive implementation below. \n", + "\n", + "The idea in this notebook is to make the general approach as readable and understandable as possible." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "id": "W6UL8U04ppmM" + }, + "outputs": [], + "source": [ + "# initialize an empty kmeans model for each dimension\n", + "models = {\n", + " dim: {\n", + " 'model' : KMeans(n_clusters=n_clusters_per_dimension, max_iter=max_iterations),\n", + " 'fitted': False\n", + " } for dim in df.columns\n", + "}\n", + "\n", + "# initialize dictionary for storing anomaly scores for each dim\n", + "anomaly_scores = {\n", + " dim: {\n", + " 't' : [],\n", + " 'anomaly_score': []\n", + " } for dim in df.columns\n", + "}\n", + "\n", + "# initialize dictionary for storing anomaly bits for each dim\n", + "anomaly_bits = {\n", + " dim: {\n", + " 't' : [],\n", + " 'anomaly_bit': []\n", + " }\n", + " for dim in df.columns\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we are ready to just loop over each row of data and produce anomaly scores once we have some trained models and train or retrain periodically as defined by `train_every`. \n", + "\n", + "**Note**: The Netdata Agent implementation spreads out the training across each `train_every` window as opposed to trying to train all models in one go like the below implementation. It also avoids some obvious edges cases where there is no need to retrain, for example when the data have not changed at all since last model was trained." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "_wxIeEhGiWYv", + "outputId": "8fdfad43-917d-42d1-8997-a49daac25b3d" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train at t=1647981687, (n=3600, train_after=1647981687, train_before=1647978087)\n" + ] + } + ], + "source": [ + "# loop over each row of data in dataframe\n", + "for t, row in df.iterrows():\n", + "\n", + " # get n based on timestamp\n", + " n = t - df_timestamp_min\n", + "\n", + " # for each dimension, if we have a fitted model then make predictions\n", + " for dim in df.columns:\n", + "\n", + " # if we have a fitted model, get anomaly score\n", + " if models[dim]['fitted']:\n", + " \n", + " #################################\n", + " # Inference / Scoring\n", + " #################################\n", + "\n", + " # get a buffer of recent data\n", + " buffer_size = num_samples_to_diff + num_samples_to_smooth + num_samples_to_lag * 2\n", + " df_dim_recent = df[[dim]].loc[(t-buffer_size):t]\n", + "\n", + " # preprocess/featurize recent data\n", + " df_dim_recent_preprocessed = preprocess_df(\n", + " df_dim_recent,\n", + " num_samples_to_lag,\n", + " num_samples_to_diff,\n", + " num_samples_to_smooth\n", + " )\n", + "\n", + " # take most recent feature vector\n", + " X = df_dim_recent_preprocessed.tail(1).values\n", + " \n", + " # get the existing trained cluster centers\n", + " cluster_centers = models[dim]['model'].cluster_centers_\n", + "\n", + " # get anomaly score based on the sum of the euclidian distances between the \n", + " # feature vector and each cluster centroid\n", + " raw_anomaly_score = np.sum(cdist(X, cluster_centers, metric='euclidean'), axis=1)[0]\n", + "\n", + " # normalize anomaly score based on min-max normalization\n", + " # https://en.wikipedia.org/wiki/Feature_scaling#Rescaling_(min-max_normalization)\n", + " # the idea here is to convert the raw_anomaly_score we just computed into a number on a\n", + " # [0, 1] scale such that it behaves more like a percentage. We use the min and max raw scores\n", + " # observed during training to achieve this. This would mean that a normalized score of 1 would\n", + " # correspond to a distance as big as the biggest distance (most anomalous) observed on the \n", + " # training data. So scores that are 99% or higher will tend to be as strange or more strange\n", + " # as the most strange 1% observed during training.\n", + " \n", + " # normalize based on scores observed during training the model\n", + " train_raw_anomaly_score_min = models[dim]['train_raw_anomaly_score_min']\n", + " train_raw_anomaly_score_max = models[dim]['train_raw_anomaly_score_max']\n", + " train_raw_anomaly_score_range = train_raw_anomaly_score_max - train_raw_anomaly_score_min\n", + " \n", + " # normalize\n", + " anomaly_score = (raw_anomaly_score - train_raw_anomaly_score_min) / train_raw_anomaly_score_range\n", + " \n", + " # The Netdata Agent does not actually store the normalized_anomaly_score since doing so would require more storage\n", + " # space for each metric, essentially doubling the amount of metrics that need to be stored. Instead, the Netdata Agent\n", + " # makes use of an existing bit (the anomaly bit) in the internal storage representation used by netdata. So if the \n", + " # normalized_anomaly_score passed the dimension_anomaly_score_threshold netdata will flip the corresponding anomaly_bit\n", + " # from 0 to 1 to signify that the observation the scored feature vector is considered \"anomalous\". \n", + " # All without any extra storage overhead required for the Netdata Agent database! Yes it's almost magic :)\n", + "\n", + " # get anomaly bit\n", + " anomaly_bit = 100 if anomaly_score >= dimension_anomaly_score_threshold else 0\n", + " \n", + " # save anomaly score\n", + " anomaly_scores[dim]['t'].append(t)\n", + " anomaly_scores[dim]['anomaly_score'].append(anomaly_score)\n", + "\n", + " # save anomaly bit\n", + " anomaly_bits[dim]['t'].append(t)\n", + " anomaly_bits[dim]['anomaly_bit'].append(anomaly_bit)\n", + " \n", + " # check if the model needs (re)training\n", + " if (n >= num_samples_to_train) & (n % train_every == 0):\n", + " \n", + " #################################\n", + " # Train / Re-Train\n", + " #################################\n", + "\n", + " train_before = t - num_samples_to_train\n", + " train_after = t\n", + " print(f'train at t={t}, (n={n}, train_after={train_after}, train_before={train_before})')\n", + "\n", + " # loop over each dimension/model\n", + " for dim in df.columns:\n", + " \n", + " # get training data based on most recent num_samples_to_train\n", + " df_dim_train = df[[dim]].loc[(t-num_samples_to_train):t]\n", + " \n", + " # preprocess/featurize training data\n", + " df_dim_train_preprocessed = preprocess_df(\n", + " df_dim_train,\n", + " num_samples_to_lag,\n", + " num_samples_to_diff,\n", + " num_samples_to_smooth\n", + " )\n", + "\n", + " # fit model using the fit method of kmeans\n", + " models[dim]['model'].fit(df_dim_train_preprocessed.values) \n", + " models[dim]['fitted'] = True # mark model as fitted\n", + " \n", + " # get cluster centers of model we just trained\n", + " cluster_centers = models[dim]['model'].cluster_centers_\n", + "\n", + " # get training scores, needed to get min and max scores for normalization at inference time\n", + " train_raw_anomaly_scores = np.sum(cdist(df_dim_train_preprocessed.values, cluster_centers, metric='euclidean'), axis=1)\n", + " # save min and max anomaly score during training, used to normalize all scores to be 0,1 scale\n", + " models[dim]['train_raw_anomaly_score_min'] = min(train_raw_anomaly_scores)\n", + " models[dim]['train_raw_anomaly_score_max'] = max(train_raw_anomaly_scores)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The hard work is now all done. The above cell has processed all the data, trained or retrained models as defined by the inital config, and saved all anomaly scores and anomaly bits.\n", + "\n", + "The rest of the notebook will try to help make more sense of all this." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "id": "0iN0PCPGiWBx" + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
system.cpu|usersystem.cpu|user__anomaly_scoresystem.cpu|user__anomaly_bit
time_idx
16479818880.7537690.2283370.0
16479841900.7575760.1442310.0
16479836510.7537690.1986060.0
16479820840.7575760.1898670.0
16479834221.0025060.3331990.0
\n", + "
" + ], + "text/plain": [ + " system.cpu|user system.cpu|user__anomaly_score \\\n", + "time_idx \n", + "1647981888 0.753769 0.228337 \n", + "1647984190 0.757576 0.144231 \n", + "1647983651 0.753769 0.198606 \n", + "1647982084 0.757576 0.189867 \n", + "1647983422 1.002506 0.333199 \n", + "\n", + " system.cpu|user__anomaly_bit \n", + "time_idx \n", + "1647981888 0.0 \n", + "1647984190 0.0 \n", + "1647983651 0.0 \n", + "1647982084 0.0 \n", + "1647983422 0.0 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# create dataframe of anomaly scores\n", + "df_anomaly_scores = pd.DataFrame()\n", + "for dim in anomaly_scores:\n", + " df_anomaly_scores_dim = pd.DataFrame(data=zip(anomaly_scores[dim]['t'],anomaly_scores[dim]['anomaly_score']),columns=['time_idx',f'{dim}__anomaly_score']).set_index('time_idx')\n", + " df_anomaly_scores = df_anomaly_scores.join(df_anomaly_scores_dim, how='outer')\n", + "\n", + "# create dataframe of anomaly bits\n", + "df_anomaly_bits = pd.DataFrame()\n", + "for dim in anomaly_bits:\n", + " df_anomaly_bits_dim = pd.DataFrame(data=zip(anomaly_bits[dim]['t'],anomaly_bits[dim]['anomaly_bit']),columns=['time_idx',f'{dim}__anomaly_bit']).set_index('time_idx')\n", + " df_anomaly_bits = df_anomaly_bits.join(df_anomaly_bits_dim, how='outer')\n", + "\n", + "# join anomaly scores to raw df\n", + "df_final = df.join(df_anomaly_scores, how='outer')\n", + "\n", + "# join anomaly bits to raw df\n", + "df_final = df_final.join(df_anomaly_bits, how='outer')\n", + "\n", + "# let's look at a sample of some scored observations\n", + "display(df_final.tail(num_samples_to_train).sample(5))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the dataframe above we see that each observation now also has a column with the `__anomaly_score` and one with the `__anomaly_bit`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 4. Lets visualize all this!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that we have our raw data, our anomaly scores, and our anomaly bits - we can plot this all side by side to get a clear picture of how it all works together.\n", + "\n", + "In the plots below we see that during the light yellow \"anomalous\" period the \"[anomaly scores](https://github.com/netdata/netdata/blob/master/ml/README.md#anomaly-score)\" get elevated to such an extend that many \"[anomaly bits](https://github.com/netdata/netdata/blob/master/ml/README.md#anomaly-bit)\" start flipping from 0 to 1 and essentially \"turning on\" to signal potentially anomalous data." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + }, + "id": "zVoR1BJ5nCGv", + "outputId": "ffcc7765-ea39-47c1-da99-ec79647d0871", + "scrolled": true + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABH4AAAEXCAYAAADbdoMsAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAB9c0lEQVR4nO3dd3gUVdsG8PukJ6SShBog9N5DkaIgqFhREUXRV9TXXj4bihULKvb6KqIiFkQUFAuI9F5D7z1AAoT03nb3fH9MyWzNpm7K/bsuLrK7U87Mzs6cec5zzggpJYiIiIiIiIiIqP7x8nQBiIiIiIiIiIioejDwQ0RERERERERUTzHwQ0RERERERERUTzHwQ0RERERERERUTzHwQ0RERERERERUTzHwQ0RERERERERUTzHwQ0REVMsJIe4XQnzk6XKUlxBitRDiv54uR20khHhFCPFjZecVQjQVQhwUQvhXbQlJPX5HeLocRERElcXADxER1QlCiAQhRIEQIlcIcV4IMVsIEVzN65wthCgWQuSo//YJId4SQoSVs9yjK1EGPwAvAnjX5v1gdV/8U9Fl11dCiLZCCIsQ4gtPl6W6SSmTAawCcJ+ny6KpTFCLiIiIqh4DP0REVJdcK6UMBtAHQF8Az9XAOt+RUoYAiAZwF4DBADYIIRrVwLoBYCyAQ1LKJJv3xwEoAnCZEKJZDZWlrvgPgAwAtzSQTJg5AO73dCGocoSCdXMiIqpyvLgQEVGdI6U8D+BfKAEgAIAQYooQ4riamXNACHGD4bNTQoj+6t8ThRBSCNFdfX2PEGKhG+sslFJuA3AdgEgoQSAIIdoLIVYKIdKEEKlCiDlCiHD1sx8AtAbwl5qd84z6/q9q1lKWEGKtVhYnrgSwxsH7dwKYAWAPgNuNH6hZRk8LIfao65gnhAgwfH6vEOKYECJdCPGnEKKF4TMphHhICHFU3Zevq9u4UQiRLYT4Rc1CghAiQgjxtxAiRQiRof4d42gjhBBeQogX1e/ighDiey1zSggxQgiR6GAbRqt/DxRCxKvrTxZCfOBsZwkhBJTAz4sASgBca/O5FEI8JoQ4oX5f72o320KISUKIDUKIz9T9dkgIMcowb5gQ4hshxDkhRJIQYpoQwtsw73ohxHvqvjgphLjSMG9bIcQadZ8uAxBlU67B6j7OFELsFoYuRmXNC2ALgHZCiDbO9osrQogO6vKz1H0yT33/f0KI922m/VMI8YT697PqfsgRQhwWQowSQowB8DyUoFuuEGK3m/tugxDiQ3X7Twghhqjvn1GPlztdlL+VEOI39ThME0J8ZrNcZ9+nVTaecJGpVJljtIzvdrUQ4g0hxAYA+QDaufquiIiIKoKBHyIiqnOEEly4EsAxw9vHAQwHEAbgVQA/CiGaq5+tATBC/fsSACcAXGx47Siw4pCUMgfAMnVdACAAvAWgBYCuAFoBeEWd9g4Ap6FmKkkp31Hn+QdARwBNAOyAkrHhTE8Ah41vqDf4I9T55kAJdNi6GcAYAG0B9AIwSZ33UrW8NwNoDuAUgJ9t5r0CQH8o2U3PAJgJJbjUCkAPALeq03kB+BZAGygBrgIAnznZjknqv5FQbm6DXUxr62MAH0spQwG0B/CLi2mHAYhRt+kXKAEyWzcAiAPQD0pG1d2GzwZBOZaiAEwF8JsQorH62WwAJgAdoGScXQ7gvzbzHlbnfQfAN2ogCgB+ArBd/ex1Y7mEEC0BLAIwDUBjAE8DWCCEiC5rXgCQUpqg/BZ6u9gvrrwOYCmACCj77lP1/e8A3GoIjEUBGA3gJyFEZwCPABigZsRdASBBSrkEwJsA5qnHvFam2Sh73+2BElT9Ccr3N0Cd/nYAnwkHXTvV4NHfUI7jWAAtYX08u/o+q5LDY9SN7xYA7oDSVS9E3Q4iIqIqxcAPERHVJQuFEDkAzgC4AOVGDgAgpfxVSnlWSmmRUs4DcBTAQPXjNVACPIASsHnL8LpcgR/VWSg3cZBSHpNSLpNSFkkpUwB8YFi2Q1LKWVLKHCllEZQgUW/hfNygcAA5Nu/dAWCPlPIAlJvc7kKIvjbTfKLuj3QAf6E0O2oigFlSyh3q+p8DcJEQItYw7ztSymwp5X4A+wAslVKekFJmQQla9VW3I01KuUBKma8GxN5wse0TAXygLidXXe8EIYSPk+mNSgB0EEJESSlzpZSbXUx7J4B/pJQZUAIIY4QQTWymeVtKmS6lPA3gI5QGsgDluPpISlmiHkeHAVwthGgK4CoAj0sp86SUFwB8CGCCYd5TUsqvpJRmKEGT5gCaCiFaQwlivKQeJ2uhfCea2wEsllIuVo/fZQDiAVzlxryaHCjHSkWUQAnetVAz29YDgJRyK4AsAFqWzAQAq9VxhcwA/AF0E0L4SikTpJTHHS3czX13Ukr5rbrv5kEJMr6mbvNSAMVQgkC2BkIJuk5Wl62XX+Xw+yzvDnKDs2PU6XdrmHe2lHK/lNIkpSyphrIREVEDx8APERHVJder2QUjAHSBocuLEOI/QohdaneKTCiZKdrnawAMVzOAvKG0xg9Vgx1hAHaVsxwtAaSr620qhPhZ7b6SDeBH2HfF0QkhvIUQ04XSLS0bQIL6kbN5MqBkAhj9B2qWkDr2zxrYZ7acN/ydDyXDBlBukvWsAjUIk6ZukybZ8HeBg9fB6rYECSG+FEr3rWwAawGEa114bFitV/3bB0BTB9PaugdAJwCHhBDbhBDXOJpICBEIYDxK980mKBlXt9lMesamHC0Mr5OklNLB520A+AI4ZzjGvoSStaXR97mUMl/9M1idP0NKmWezXE0bAOO15arLHgYlcFTWvJoQAJm2bwohWqtdrnKFELkO5gOUrC4BYKsQYr8QwpgB9R1KuxLeDuAHdfuOAXgcSuDygvobMO5HI3f2ne0xpg1cbXzP0WDuraAE3ExO1u3s+6xqzo5RV9+t5gyIiIiqEQM/RERU50gp10DpOvIeoHd9+gpK15NIKWU4lEwVoU5/DErw41EAa6WU2VBu0u8DsF5KaXF33Wp3k9EA1qlvvQlAAuipdvO4XVuvVlybRdwGpXvRaChBp1ht0U5WuQfKDaW2/iFQuok9J5Rxgs5D6c5ym5vZM2eh3Ixqy2sEpXuN7eDR7ngKQGcAg9Rt17rPOdoWq/VC6RpmgnLDnwcgyFAmbyiDaQMApJRHpZS3QgkUvA1gvnA8uPYNAEIBfG7YNy1hHxRrZVOOs4bXLQ3ds4yfn4EymHaUlDJc/RcqpXQ1PpPmHIAImzK3Nvx9BsAPhuWGSykbSSmnuzEv1O+9A4DdtiuWUp5Wu1wFqwOj25FSnpdS3iulbAFlkOjPhRBads2PAMYKIXpD6cq40DDfT1LKYVC+VwnluwHsj/nK7LuynAHQ2sWx7+z7BGyOOwCuBkmv6DHq6rvVZ3e9iURERJXDwA8REdVVH0F5olVvAI2g3DylAIAQ4i4oGT9Ga6AEhrRuXattXrskhPAXygDRC6Fk4XyrfhQCIBdAljqex2SbWZNhPWBrCJSb4DQoN5JvlrHqxbDuPnUnlDGGukHpvtUHyrYGQhn3qCxzAdwlhOgjlCdevQlgi5QywY15bYVAycTIVMdNmepi2rkAnhDKQMXBKB0HxgTgCIAAIcTVQghfKAMz60/jEkLcLoSIVgN0merbjoJ1dwKYBWVcpD7qv6FQutL1NEw3WSgDU7cC8H9QuhZpmgB4TAjhK4QYDyXYsVhKeQ7KODjvCyFChTJYdXshhMtufQAgpTwFpXvPq0IIPyHEMFgPOv0jgGuFEFeoGWEBQhlMOMaNeQGlu1OCOm25CSHGi9JBuTOg/JYsatkTAWyDkumzQEpZoM7TWQhxqXoMFUI5DrTvJBlArFDHBqrMvnPDVijBselCiEbqvhtq+Nzh96l+tgtKd0NfIUQcgJtcrKeix6jT77bSW05EROQmBn6IiKhOksp4Ot8DeFkd6+Z9AJug3HT2BLDBZpY1UAIVa528duYZoYwrlKaubzuAIYauN69CGSQ4C8ogrr/ZzP8WgBfVbh5Pq8s4BSXD5gAAV+PVAMp4Ll2EEC2E8mSumwF8qmZpaP9OQrkxd/rkI42UcjmAlwAsgHLD3B7WY62Ux0dQAk6p6nYscTHtLLWMawGchBIseFQtUxaAhwB8DWW/5AEwPkFpDID9aleljwFM0AIQGjXoNgrKeC7GfbNdLZdx3/wB5XvcBeU7+8bw2RYoGVWpUMYsuklKmaZ+9h8AflC+twwA82HdZceV26BkZqVDCZB9r30gpTwDJQvseSjByzNQAoheZc2rmgjlCW8VNQDAFnX//gng/6SUJwyffwflN/WD4T1/ANOh7KfzUAIsz6mf/ar+nyaE2KH+XZl9Z0UI8bwQ4h8AUMcEuhZKxtNpKMfNLYbJXX2fL0E5/jOg/I5/crbOih6jbny3RERE1U5Yd3smIiKi2kYIcR+AblLKxz1dlrpOCCEBdFS7/9l+NgnAf9XuS3WCUAauXgOgr5SysJrWcTGUzJU2sg5VHCv7fQohVgN4RUq5ugqLRUREVOPcGQuAiIiIPEhKOdPTZaDaSX1CVtfqWr7aren/AHxdl4I+REREVIpppkRERERkRwjRFcp4Nc2hdOtraGaj9Kl7REREdRa7ehERERERERER1VPM+CEiIiIiIiIiqqdqdIyfqKgoGRsbW5OrJCIiIiIiIqI6wmLJ93QR6qSdOw+mSimjHX1Wo4Gf2NhYxMfH1+QqiYiIiIiIiKiOyMnZ7uki1EmhoXGnnH3Grl5ERERERERERPUUAz9ERERERERERPUUAz9ERERERERERPVUjY7x40hJSQkSExNRWFjo6aJQFQoICEBMTAx8fX09XRQiIiIiIiKiBsvjgZ/ExESEhIQgNjYWQghPF4eqgJQSaWlpSExMRNu2bT1dHCIiIiIiIqIGy+NdvQoLCxEZGcmgTz0ihEBkZCSzuIiIiIiIiIg8zOOBHwAM+tRD/E6JiIiIiIiIPK9WBH6IiIiIiIiIiMpr/7kSpOSYPV2MWo2BHyIiIiIiIiKqkybMSsO1M1I9XYxajYGfKjB79mycPXvW08Vwafbs2XjllVc8XQwiIiIiIiKiKpVXLD1dhFqNgZ8qUBcCP9XNZDJ5ughEREREREREZMPjj3M3evWv/ThwNrtKl9mtRSimXtvd5TR5eXm4+eabkZiYCLPZjJdeeglz587FwoULAQDLli3D559/jvnz5+Oee+5BfHw8hBC4++670apVK8THx2PixIkIDAzEpk2bcODAATz55JPIzc1FVFQUZs+ejebNm2PEiBHo27cv1q1bh7y8PHz//fd46623sHfvXtxyyy2YNm2aXdm2bduG//u//0NeXh78/f2xYsUKLFiwAL///juysrKQlJSE22+/HVOnTkVCQgKuueYa7Nu3DwDw3nvvITc31y7TZ/bs2YiPj8dnn30GALjmmmvw9NNPY/jw4Xbb98QTT+D48eN4+OGHkZKSgqCgIHz11Vfo0qULJk2ahICAAOzcuRNDhw7FBx98UPkvjIiIiIiIiIiqTK0K/HjKkiVL0KJFCyxatAgAkJWVhalTpyIlJQXR0dH49ttvcffdd2PXrl1ISkrSAyuZmZkIDw/HZ599hvfeew9xcXEoKSnBo48+ij/++APR0dGYN28eXnjhBcyaNQsA4Ofnh/j4eHz88ccYO3Ystm/fjsaNG6N9+/Z44oknEBkZqZeruLgYt9xyC+bNm4cBAwYgOzsbgYGBAICtW7di3759CAoKwoABA3D11VcjKiqqUvvB0fYBwH333YcZM2agY8eO2LJlCx566CGsXLkSAJCYmIiNGzfC29u7UusmIiIiIiIioqpXqwI/ZWXmVJeePXviqaeewrPPPotrrrkGw4cPxx133IEff/wRd911FzZt2oTvv/8eOTk5OHHiBB599FFcffXVuPzyy+2WdfjwYezbtw+XXXYZAMBsNqN58+b659ddd52+zu7du+uftWvXDmfOnLEK/Bw+fBjNmzfHgAEDAAChoaH6Z5dddpk+7Y033oj169fj+uuvr9R+aNeund325ebmYuPGjRg/frw+XVFRkf73+PHjGfQhIiIiIiIiqqVqVeDHUzp16oQdO3Zg8eLFePHFFzFq1Cj897//xbXXXouAgACMHz8ePj4+iIiIwO7du/Hvv/9ixowZ+OWXX/RMHo2UEt27d8emTZscrsvf3x8A4OXlpf+tvS7PODlCCLvXPj4+sFgs+nuFhYUO53U2naPt++ijjxAeHo5du3Y5XFajRo3cLjMRERERERER1SwO7gzg7NmzCAoKwu23347Jkydjx44daNGiBVq0aIFp06bhrrvuAgCkpqbCYrFg3LhxmDZtGnbs2AEACAkJQU5ODgCgc+fOSElJ0QM/JSUl2L9/f4XK1blzZ5w7dw7btm0DAOTk5OjBoWXLliE9PR0FBQVYuHAhhg4diqZNm+LChQtIS0tDUVER/v77b4fLjY2Nxa5du2CxWHDmzBls3brV6faFhoaibdu2+PXXXwEoga3du3dXaHuIiIiIiIiIqGYx4wfA3r17MXnyZHh5ecHX1xdffPEFAGDixIlISUlB165dAQBJSUm466679GyZt956CwAwadIkPPDAA/rgzvPnz8djjz2GrKwsmEwmPP744+je3f1ubFdddRW+/vprtGjRAvPmzcOjjz6KgoICBAYGYvny5QCAgQMHYty4cUhMTMTtt9+OuLg4AMDLL7+MgQMHomXLlujSpYvD5Q8dOhRt27ZFt27d0LVrV/Tr18/l9s2ZMwcPPvggpk2bhpKSEkyYMAG9e/cu1z4mIiIiIiIioponpKy5593HxcXJ+Ph4q/cOHjyoB1Zqm0ceeQR9+/bFPffc4+miWLF9Kpe78yQkJNg94as61ebvloiIiIiIiGqfnJzt5Zq+5xvnAQB7X2hWHcWpM0JD47ZLKeMcfcaMHyf69++PRo0a4f333/d0UYiIiIiIiIiIKoSBHye2by9flLEmTZo0CZMmTSrXPH369EFsbGy1lIeIiIiIiIiIaicGfhqIPn36eLoIRERERERERFTD+FQvIiIiIiIiIqJ6ioEfIiIiIiIiIqJ6ioEfIiIiIiIiIqJ6qtaN8ZOVtRkmU2aVLc/HJxxhYYPLnG7hwoW44YYbcPDgQXTp0qXK1l9ewcHByM3NrZZlz549G5MnT0ZMTAxyc3PRrl07TJ06FUOGDHE538KFC9GpUyd069atWspFRERERERERNWj1mX8mEyZ8POLrrJ/7gaR5s6di2HDhmHu3LnVu4Eedsstt2Dnzp04evQopkyZghtvvBEHDx50Oc/ChQtx4MCBGiohEREREREREVWVWhf48YTc3FysX78e33zzDX7++Wf9/dWrV2PEiBG46aab0KVLF0ycOBFSSgDAihUr0LdvX/Ts2RN33303ioqKAACxsbF47rnn0KdPH8TFxWHHjh244oor0L59e8yYMUNf36hRo9CvXz/07NkTf/zxh12ZpJSYPHkyevTogZ49e2LevHl6ma655hp9ukceeQSzZ88GAEyZMgXdunVDr1698PTTT5e53SNHjsR9992HmTNnAgC++uorDBgwAL1798a4ceOQn5+PjRs34s8//8TkyZPRp08fHD9+3OF0RERERERERFT7lBn4EUK0EkKsEkIcEELsF0L8n/p+YyHEMiHEUfX/iOovbvX4448/MGbMGHTq1AmRkZHYvn27/tnOnTvx0Ucf4cCBAzhx4gQ2bNiAwsJCTJo0CfPmzcPevXthMpnwxRdf6PO0bt0au3btwvDhwzFp0iTMnz8fmzdvxtSpUwEAAQEB+P3337Fjxw6sWrUKTz31lB5Q0vz222/YtWsXdu/ejeXLl2Py5Mk4d+6c021IS0vD77//jv3792PPnj148cUX3dr2fv364dChQwCAG2+8Edu2bcPu3bvRtWtXfPPNNxgyZAiuu+46vPvuu9i1axfat2/vcDoiIiIiIiIiqn3cyfgxAXhKStkNwGAADwshugGYAmCFlLIjgBXq6zpp7ty5mDBhAgBgwoQJVt29Bg4ciJiYGHh5eaFPnz5ISEjA4cOH0bZtW3Tq1AkAcOedd2Lt2rX6PNdddx0AoGfPnhg0aBBCQkIQHR0Nf39/ZGZmQkqJ559/Hr169cLo0aORlJSE5ORkqzKtX78et956K7y9vdG0aVNccskl2LZtm9NtCAsLQ0BAAO655x789ttvCAoKcmvbjQGnffv2Yfjw4ejZsyfmzJmD/fv3O5zH3emIiIiIiIiIyLPKHNxZSnkOwDn17xwhxEEALQGMBTBCnew7AKsBPFstpaxG6enpWLlyJfbu3QshBMxmM4QQePfddwEA/v7++rTe3t4wmUxlLlObx8vLy2p+Ly8vmEwmzJkzBykpKdi+fTt8fX0RGxuLwsJCt8rr4+MDi8Wiv9bm8/HxwdatW7FixQrMnz8fn332GVauXFnm8nbu3ImuXbsCACZNmoSFCxeid+/emD17NlavXu1wHnenIyIiIiIiIqqrpJRYebgIl3Tyh4+X8HRxKqxcY/wIIWIB9AWwBUBTNSgEAOcBNK3aotWM+fPn44477sCpU6eQkJCAM2fOoG3btli3bp3TeTp37oyEhAQcO3YMAPDDDz/gkksucXudWVlZaNKkCXx9fbFq1SqcOnXKbprhw4dj3rx5MJvNSElJwdq1azFw4EC0adMGBw4cQFFRETIzM7FixQoAyrhBWVlZuOqqq/Dhhx9i9+7dZZZjzZo1mDlzJu69914AQE5ODpo3b46SkhLMmTNHny4kJAQ5OTn6a2fTEREREREREdUXa44W4fEFmZi5vvJP3r77x3T857u0KigV8OSCDFw7I8Xt6d1+nLsQIhjAAgCPSymzhSiNdkkppRBCOpnvPgD3AcrYN2UWyCccxcXub4A7y3Nl7ty5ePZZ60SlcePGYe7cubjlllsczhMQEIBvv/0W48ePh8lkwoABA/DAAw+4XaaJEyfi2muvRc+ePREXF+fw8fE33HADNm3ahN69e0MIgXfeeQfNmjUDANx8883o0aMH2rZti759+wJQgjFjx45FYWEhpJT44IMPHK573rx5WL9+PfLz89G2bVssWLBAz/h5/fXXMWjQIERHR2PQoEF6sGfChAm499578cknn2D+/PlOpyMiIiIiIiKqL9Lzld4257MtZUxZtm2niiu9DM2yQ0Xlml7YDirscCIhfAH8DeBfKeUH6nuHAYyQUp4TQjQHsFpK2dnVcuLi4mR8fLzVewcPHtQDD1S/8LslIiIiIiKi8sjJ2V72RAY93zgPANj7QrMqL8tvu/IxdVE2bugdiNeuCavUsqqynI6WFRoat11KGedoenee6iUAfAPgoBb0Uf0J4E717zsB2D+TnIiIiIiIiIioDnIjT6ZOcKer11AAdwDYK4TYpb73PIDpAH4RQtwD4BSAm6ulhEREREREREREVCHuPNVrPQBnw1ePqopCSClhHDOI6j53uhASERERERERUfUq11O9qkNAQADS0tIYKKhHpJRIS0tDQECAp4tCREREREREVCl1PU3F7ad6VZeYmBgkJiYiJaXqnuRFnhcQEICYmBhPF4OIiIiIiIioQfN44MfX1xdt27b1dDGIiIiIiIiIiHT1pV+Sx7t6ERERERERERFR9WDgh4iIiIiIiIjIRl0f20fDwA8RERERERERkQ129SIiIiIiIiIiqudEHU/9YeCHiIiIiIiIiKieYuCHiIiIiIiIiKieYuCHiIiIiIiIiKieYuCHiIiIiIiIiMiGrCejOzPwQ0RERERERERUTzHwQ0RERERERERko64/zUvDwA8RERERERERkY360tXLx9MFICIiIiIiIiKqDzLzLfDyAkIDqj7PprBEIqvAUu75GPghIiIiIiIionrl09U5yCqw4MUrw2p0vcM/vAAA2PtCsypf9sPzMrD1VHG552NXLyIiIiIiIiKqE06nm9DzjfNYcqDA5XQzN+Rh3g7X09Q1FQn6AAz8EBEREREREVEdcTDZBABYerDQwyWpOxj4ISIiIiIiIiKyUU/Gdmbgh4iIiIiIiIjImbr+WHcGfoiIiIiIiIiInKjrj3Vn4IeIiIiIiIiI6oQ6nnzjEQz8EBERERERERE5wa5eREREREREREQ1qK53v6pJDPwQEREREREREdmqJ8ElBn6IiIiIiIiIiOopBn6IiIiIiIiIqE6o0fF26vjYPhoGfoiIiIiIiIiIbLGrFxERERERERFR/VbXE38Y+CEiIiIiIiKiOqWeJOPUCAZ+iIiIiIiIiIjqKQZ+iIiIiIiIiIjqKQZ+iIiIiIiIiKhOqMnxdupLdzIGfoiIiIiIiIiI6ikGfoiIiIiIiIioTpE1kI5T15/mpSkz8COEmCWEuCCE2Gd47xUhRJIQYpf676rqLSYRERERERERUc1pSF29ZgMY4+D9D6WUfdR/i6u2WERERERERERE7ikxSyzYmQ9LNaQCiUqk/uxJKsa+syVVV5gKKDPwI6VcCyC9BspCRERERERERGQlM9+CRfsKAFh3vzqXZdb//m5zHl5ZnI2+byXXSJksUmL+znyUmF0HmibOTset36bprzeeKMKJVFN1F89KZcb4eUQIsUftChZRZSUiIiIiIiIiIlI9/XsmpvyRhaRM64DJzd+k6n9nFFgAAJYa6p/1995CvLo4G99szCvXfPfPzcDYL1PLnrAKVTTw8wWA9gD6ADgH4H1nEwoh7hNCxAsh4lNSUiq4OiIiIiIiIiJqiJKzlcyeIptEmcwCz43Ck11oUctg8VgZ3FWhwI+UMllKaZZSWgB8BWCgi2lnSinjpJRx0dHRFS0nERERERERETVEDsbYqYmQT008OawmVCjwI4Robnh5A4B9zqYlIiIiIiIiIqpO1RmkqeuPdfcpawIhxFwAIwBECSESAUwFMEII0QdKkC0BwP3VV0QiIiIiIiIiIs+o64k/ZQZ+pJS3Onj7m2ooCxERERERERFRrVeXgkGVeaoXEREREREREVG1cqerVXUGYup6Vy8GfoiIiIiIiIioblCjMJ4eeLkuBYMY+CEiIiIiIiKiWq+mgz3SRR4Ru3oREREREREREVUBUYvTa2px0XQM/BARERERERFRnVDbAi11IfOHgR8iIiIiIiIiqvVcdb2qVrU55cgNDPwQERERERERUa0l3Mnz8VRMyDOrLRcGfoiIiIiIiIiIKoBdvYiIiIiIiIiIyGMY+CEiIiIiIiKiWq+mH+fuDnb1IiIiIiIiIiKqBG1s5ZqO+7gTaKqFsSg7DPwQEREREREREdVTDPwQERERERERUZ2gZ//UQKqNO09xZ1cvIiIiIiIiIqIqUNNj/LCrFxERERERERFRLVAdAZjkHIvD9y1S1mgQymyp3MoY+CEiIiIiIiKiOsGdrlWHk0sqvPzcIgvOZ5uRV2TBrE15AIB52/Otprn4wwt4d3lOmeV569/sCpdDczLNhD5vJePfg4UVXoZPpUtBRERERERERFRNtLF25mzLh59P2aGfm75Oq/C6xn+dhsRMM9pGejudJqug7AycjSeK8FN8fpnTleXgeSWItfwQAz9EREREREREVI/9vrug2teRmGkGAJxMM1dqOQt2VU1ZtTBXZbqWsasXEREREREREdUptX1QZVlFgwC582SxsjDwQ0RERERERES1Vl14ZHp1q0wYiYEfIiIiIiIiIqJarDIZRAz8EBERERERERHVQqIK+nox8ENEREREREREdVoVDalTLzHwQ0RERERERES1lqOcl9oe6Kmq8vGpXkRERERERERE9ZTW04uDOxMRERERERER1RJVlZDEjB8iIiIiIiIiqteqYHzj6uOkbFXd1asyGPghIiIiIiIiIqqIGhpriF29iIiIiIiIiKhecifrpbaN9Vxl5dHG+GFXLyIiIiIiIiKiGlbN3dDY1YuIiIiIiIiIyFNqW6qRAwz8EBEREREREVGdImt5xKXKBndmVy8iIiIiIiIiIg9hVy8iIiIiIiIiokpwI/pRVRk25canehERERERERERVS2PBXrcVNVdvSqjzMCPEGKWEOKCEGKf4b3GQohlQoij6v8RlS8KEREREREREVEdUs1dvTTVPcbPbABjbN6bAmCFlLIjgBXqayIiIiIiIiKiKlVVsZXUXDPyiy1VtDTXqiohSagpP5UZzNqnrAmklGuFELE2b48FMEL9+zsAqwE8W+FSEBEREREREVGDV2KW2H+uBH1i/AAAZzJMOHDeVOHlFZsknlyQifuHNcJts9OtPpv/30h0burr1nLMFglvL8chqH1nS9C6sTe+25zndrky8y1IzjHjpq/T8OglwQgL9EJyjhmPjQjRpzmXZUZSprLtzjJ+lh4sxOdrc12uq8zAjxNNpZTn1L/PA2jqbEIhxH0A7gOA1q1bV3B1RERERERERFTfvbMsBz9vz8fC+6LQPtoHV32eWqnljfsqFQnpZpxKtw8erT9e5HbgZ/LvmfhgnP0oN7mFErd+m4aoRl5IzSvNJiqra9aEWWlIyjIDAL5YlwuTOqsx8HP5Zyllluup3zLLnKbSgztLKSVcZDFJKWdKKeOklHHR0dGVXR0RERERERER1VNHLpQAADIKytcly1lQIiHd7HSe8gycvOxQkcP3i8zKmo1BH3doQR93eeKpXslCiOYAoP5/oRJlICIiIiIiIiKialDRwM+fAO5U/74TwB9VUxwiIiIiIiIiorqtMoMxO1xedT7VSwgxF8AmAJ2FEIlCiHsATAdwmRDiKIDR6msiIiIiIiIiojpB1NSz2KtAZcJI7jzV61YnH42qxHqJiIiIiIiIiOql8mTolGesoYqo9ODORERERERERER1TXUHXKpStXb1IiIiIiIiIiKqTap2BJ2KqwuxIwZ+iIiIiIiIiKhWqUyGi7uqM2hTnuJXd/CIgR8iIiIiIiIiqttqIlJUDlVdHHb1IiIiIiIiIqIGY+OJ4sovpBpTbTaddL98HNyZiIiIiIiIiBqEaguCOFhuVayqpgaIrkwCEQM/RERERERERFTL1K6uW87UVA8zSyVWxMAPERERERERETU4VZGtUxfCUwz8EBERERERERFVRA1Ffji4MxERERERERHVeRVNwvFU5k1VrJePcyciIiIiIiIiqoVq8inyFQ0QMfBDRERERERERA1OVWTaVEnGjxuDDbGrFxERERERERFRDZM1lPIjUfHBqBn4ISIiIiIiIqJapSbiKVXxVK+6gIEfIiIiIiIiIqIKKDHXzHoqEwjzqbpiEBERERERERHVvF92FLj8PCHNPkIzfWkOpi/NAQB8eWsEzme7juKcTjehyGQdgVl9tKicJXUtq8CCsED7HJ3dSSV27+UWWdxaJgM/RERERERERFQruDPQcXW4f25GmdNc/UVqtZfjcHIJBsb6uzXtkgOFbk3Hrl5ERERERERERPUUAz9ERERERERERB5S0SQnd8f9YeCHiIiIiIiIiGqVmnlIesPAwA8RERERERER1QoN5AnrVqp7mxn4ISIiIiIiIiKqpxj4ISIiIiIiIiKqpxj4ISIiIiIiIqJaxd2Bi+sD4+DO1fE0ewZ+iIiIiIiIiIhqgfIEvNydlIEfIiIiIiIiIqpVqiPzpaHy8XQBiIiIiIiIiIiMGlJXL6PCEoknF2SgZbh3mdO6Gxtj4IeIiIiIiIiIaoWGmOlj3OS3luYgMdPs1nzs6kVEREREREREVIdcyHEv6FMeDPwQEREREREREXmKIeWnOnq4MfBDRERERERERLVKAx3ip1rGNmLgh4iIiIiIiIionmLgh4iIiIiIiIjIQ6p7PGsGfoiIiIiIiIiIagELu3oRERERERERUX1XHWPdNFQ+lZlZCJEAIAeAGYBJShlXFYUiIiIiIiIiImpoqiPgVanAj2qklDK1CpZDRERERERERNSgCD7OnYiIiIiIiIjqOykltiQUA1DGuhnzWYqHS1QzsgoqFu55/Z9st6arbOBHAlgqhNguhLjP0QRCiPuEEPFCiPiUlIbxpRERERERERFRxf21twBJWWZPF6NeqGzgZ5iUsh+AKwE8LIS42HYCKeVMKWWclDIuOjq6kqujyioymfH63weQXVji6aIQERERERER6Yzj2+QXc3TnqlKpwI+UMkn9/wKA3wEMrIpCUfWZvz0R36w/iQ+XHfF0UYiIiIiIiIh0DPVUjwoHfoQQjYQQIdrfAC4HsK+qCkbVw2xRfkomM39SREREREREVHtIQ8oPH+dedSrzVK+mAH4XyvDTPgB+klIuqZJSEREREREREVGDwlhP9ahw4EdKeQJA7yosCxERERERERE1UMzyqR58nHsDo/2QlEQtIiIiIiIiotpBMuenWjDwQ0REREREREQex4yf6sHAD5ETM9Ycx87TGZ4uBhERERHVQu8vPYw/diV5uhgNygfLjuD3nYmeLkaDMmXBHmw8nurpYlAlVWZwZ6qDJEOobpv+zyEAQML0qz1cEiIiIiKqbT5deQwAMLZPSw+XpOH4ZMVRAMANfWM8XJKG4+dtZ/DztjM1dk9kvF3lnWvVYcYP1Xv5xSZc8+k67EvK8nRRiIiIGoQnf9mFOVtOeboYRERUxxjH+Fl7rMiDJalfGPhpYEQDHNV51+lM7EvKxhuLDnq6KERERA3CbzuS8MLv+zxdDCIiqgT2Fqk/GPipQ8wWiQXbE2Gx8AdYHlqwy8ITV60mpcT/Vh3D+axCTxeFiIiIiKjB88TtE2/ZqgcDP3XIdxsT8NSvuzF32+kKL0OL2jakvB8tyYknkdrtcHIO3v33MB75aYeni0JERERE1OB54vaJt2zVg4GfOiQ1V+njmJFX7OGSeM6R5Jxyb7+XGvmRPI3UamY1ky23yOThkhARlV9OYQnyeP4iIqJ6xBM9Jti9rHow8FOHaD+BhjhOj+byD9fi6k/WlWseL3V3sYdc7SYaVB4aEdU3PV9Zir6vL/N0MYiIiKqMR7p61fwqGwQGfhqouhw8OlvOMWCEHvjx/GlkX1JWnchoqQtlJCJyV16RqUbGxys2Wap9HURE5B7WZyvPEz0masEtW73EwE8dUpU/goaUQqcFucqzydWxfwpLzLjm0/V48MftVb7sqhQ7ZRF6TP0X87cn1uh6ORYTEVWH3CITuk/9F+8uPezpotQqsVMW4WGOqdbgrDmSgqHTV6KwxOzpohBVq7/3nEWPqf9iX1KWp4tSp3mkXs57gWrBwE8dokVc63Cyjkdou6s8wZzqOMmZ1NbmHacyqn7h1WDVoQs1uj498MOzPRFVoZzCEgDAbztqNphdFyzac87TRaAa9upf+5GUWYDEjHxPF4WoWq05nAIAOHA228Mlqds809WL9wLVgYGfukT9DVRkLJTr/7cBPab+W8UFqn2WHUhG7JRFuP3rLYidsgjfbjhpGNwZ+O932xA7ZRFmrT/pcjm1oVuYp9X0PuAYP9Xr0bk78faSQ3bvd3xhMV75c78HStQw5RebEDtlEeZurfjTGal8tHMLT+uKr9edwKRvt3q6GFUidsoiPPXLbo+W4cNlR/DR8iP665zCEsROWYRlB5IBAFtOpOHid1Yhv7h6u5yYLRKj3l+Nf/Yqwbyft57GlAV77CdUfwcHzuUgdsqiepENMeajtYibxvG1yBpP+VWDXb3qDwZ+6qCKZPzsOpNp1c+1Lo/x48onK44CANYfSwUAvPrXAT3wY5ESyw8qWSyv/X3A5XKq43xT17rXeaq4dWw31Rl/7T6LL1Yft3u/xCwxe2NCzReogUrJUZ7O6Oi7oOpRmk1IADBt0UGsVlvC64MFHs7k+njFUXy0/Kj++kRKHgDg05XKe1P/3I/T6fn6+9Ulr9iE4yl5mDxfCfZM+W0vft52xm467Xew4qASmFq6/3y1lqsmHDqfg9TchvvEWypD/bzlqTEc3Ln+YOCnjrjjmy34Y9fZSi+nLv+Q3AmcOIpn6YM7l2PMzerIdqnouKJSSvxv1TEkZRaUa77Fe8/hr90VP2YsUmLFwWT8Gm9fcawOte3m7PediUjNLfJ0Meqd95cextQ/9nm6GFYOnM3GBjVYXN0Y2Kx5pd19KzZ/scmCz1cfQ5Gp5sdEScstwm1fbcaFnNKHGnyx+jjGfrbe7WXM23YaWQUl1VG8GvP2kkOIT0iv8uVKKfHB0sM4mpzj1vQnUnLx3G97YXZxQbf9JKdQaXQL9vdxuewDZ7Pxyp/7XdZ19iVl4bW/DkBKCSklvlh9HGfS7bts7Txd2qX82AXrbdOW78l74c0n0vABx9yiaqb9lJ6ZvwcZeXUjMPhr/BmsPJTs6WJYqalqS0pOEW6duRlpuUV1rrG8rmDgp45YdzQV57OVil9DDVy7EzhxlclUnlNIdZxvKnoSO52ej3f/PYx7v4sv13wPzdmBR+fuLNc8xjJKAPd8F6+3Hla3iozFVF0uZBfiiXm7cd/35dvnVLZPVx7Dd5tOeboYVq76ZB0mfr3F08Wg6qJfFip2bvl+UwLeWXIY35TRRbg6zN16GhuPp2H2hgT9vbeXHMLuRPe65+xNzMKzC/Y67vJTh3yx+jhumrGpypebU2TCJyuP4ZaZm92a/qE5OzB362kcPu9eoAgAis1Kq1NZR99tX2/G7I0JyMh3HqSbMHMzZm04iZwiE85lFeLtJYdw9+xtdtPd8PlG/e+xn22w+kwrhyczvyfM3IxPVh7z2PqpYTB2UfpsVd043ibP34O7Z9euumdN1ctnbzyJTSfS2BW+GtW7wM+WE2nIq+Sj+9YdTUG6i8jwsQs52Hwize3l/bj5FNYdLX9adbHJgl/iz9g9grYy1+ofNzu/4crKL8GcLafsfuD7krJwPCXXbvqTqXl6K3lCah7unLW1WjIkikxmfLriKAoMT6DYfSYTexIzsfVkut6FbfHeczidZp9KrW2OoxPXnC2nsCcxU3/95+6z2JeU5TDw89fus8jMLz0uElLzcMuXm7Bk3zkUlpjxa/wZSCmx5kiKwz7zFc340VoWnY0P8NuORBxxs7XSVkZeMb5YfRzJalBxw7HS47qm4y+1qfehVlFPzmbGz/6zWdhhaD2uiNwiE37YlGD3G1xzJAUbK5hpk1tkwksL96GguPS8sDcxC3/vqXxmpCtSSvwSf6bC2R/OjvOftpzWzy/HLuTWi3E3XDmanIMt5biOVop62FX0HJxXpHzXxmOtKmUXluDHzfbXXqDyN+faddPVtfnfCnb1Sc8rtqrbnEjJRUKq/TX4THo+1hxxXAf6flMCzpaRzWpbB9IYs6Ac+WNXErILXWc6aV3B3X3ClXY99vV2/r04+8QiJbaeTMfWk44zl7T5pv9z0K4e++Wa43hozna9viNQmpmcrx6XUs1qtj2O8myOW+3j2nTNrQiLReLbDSer7XdZXscu5OCXGsqQril/7Eqq8DXak+ZuPY03Fx+0irZW5nA/cDa7Sh94ci6rAAfP1Z0Bpyt67awMzzcB10+u807rmAs5hbhl5mZc3q0pZv4nrkLLKDKZccc3W9GzZRj+enSYw2lGf7AWAJAw/Wq3lvniwn3lml7z+epj+Gj5Ufh4Vd3V+biLPuZP/boLyw9eQJ9W4ejeIkx//5pPlZRy2/KPfG+1/v6l76+GRQKTvt2Kvx8dXmXlBYBZ6xPw/rIjVu+N/V9pC9bIztGYNWkAHprj+LG0WsTfUfetF363/m4eUzNkDrx2hdV0iRn5eHTuTgzvGIUf7hkEALj3+3gcvZCLLSfTcffQtpi14SSigv1xl9r6Zru/XKWGu1JWxf9JdWDL8h5fAHD/j9ux9WQ63l5yCAnTr8bt35RmPdR05o0eoKvRtVJZrv7E8e+/PF79cz9+3Z6ItlHBVu/fOWtrhZc9Y/Vx/LD5FGIiAnH/Je0BANeq3V+u6dWiwmUty7/7k/HM/D1ISM3DM2O6VMkyD5zNxvO/78WKg8n4ZtIAjP5gDYDK7fPa7rIPy3cdrQyLi+B/eVTXffLzv+3F33vOoUuzEMTFNnY4TXWeF+//YTv+eHgoercKL9d8k77dij2JWTgy7Ur4+Xjh0vcdH7ej3l+DYrPF7v0LOYV4+Y/9mLP5NP594mKn6ylx0k/7kZ+cZ7QePp+D//t5F8Z0b4YZd/R3Op12TJjcvD5r03lXoF5msUjc/KWSteTouNeu9b/EJyKikR+eu7Kr/tlb/9gPzG97OJvdPL71J8Rqg567NVfts+xgMl796wBOpdWOp5ON+WgdTBaJm+NaebooVeb/ft4FoO5di577bS8AICzQV3+vMoHOqz5ZB6Dq9sNFb62s0uVVuxo+SUjJbvHVpc5n/Czee05/VKsW9V99JAW/xJ+xazExWyTmb0/EafUikVdk0jMddp3JRH6xSU/fdTeDYsOxVPyxKwnbEtJhUrMELmQXWg2krNFawhJS87Bk3zk9EJBbZMK2hHScSsvDxmOpej9UbRDQ33YkWS1HQOCkg1Y1Z7RyGZ3LKsCR5BwcPp+DEvXzc1nKvrBYlG3IKSxxOyKt1ZmOXbDPDDJaeSgZ208prV15RSbsP5uF2RtO6q2RR5NzkJRZgPiEdGTmF2PV4Qv6k4gOOCnL+mOp+NAwsKKtpfuVvrJHkq3LlmPTEnjKkC1krAOezypEkUnZR0kZpS2TRw3bulh9ikaO4XvffkrZhoy8Ymw/lV7hwE96nn1LbVZBCeZvT3TrEZWOvn+NcZv3n7XOMHA1zlFBsdkuC0xKibVHUmCxSKTkFGFfUpbTllqj4ym5Sn9efUH202jLM4pPSNd/v2U5kpyDYpP7gzy5yhJLySmyO3Y86WRqnssb2rwik8NWeFu/7Uh0eaxUhpZBWeCkVd12vam59t+33TzqsXUqPR9L9p3Xz2PVTcsgMGZQFJnM+jZuS0h3mXWqfVW289u+52i9pyt5g5OQmof9Z7Ow8ViqW7+H81nu/b40uUWmSj0212KRuODkN73+aKrVcbLjdIbdcXMiJRc7TmfY/T61c1lGfgmy8kscjoliJKVEfEI6Tqfl44SDbFdACVrYnjNtl7Hq8AX8s/ec3e/zr91nrc5daeqgtOU5R1W1jceV7CuzReKPXUkOs3wz84ux60ym/vqQWl8qtvkesgtLsNaQ4WP8vLDErNcTtGtiZkExLBaJJfvs9xUAmMyOz29pTn4vp9Pyseqw0jp/roxrhBZTMl6f84tNTjP6TOoMm5xkq13IKcRew7krMSNfr8t962AQ/cSMfD3Tz3hfWlRiQUZesd34PLblBoCkzAKcyyrQf6/OrgbHLuSq1y/l/FRWIPTw+RyYzBacSc/HH7uSrKYvMVv0cYRcfXdl0eqD5VFYYsYPmxL0+liioV62+0wmTqbmOfyN5xaZkFNYAotFYsH2RKd1sqyCEqss12KTBYkZZZ97bYOH+cUmp+ePqpacXWi1/x3V37PyS1BQbEZydqHDa0mRyayPJWkyW3DofOUzUswW6fZ1KzW3qNzXnLIYxzariq6NWfklbh0L1WH/2axy/8aM5+LTafkVvg9x56leZousUO+WyqyTyq9OZ/wcu5CLh+bs0Ft0tNaLYpMFz8zfgxlrjmPlUyP06T9beQwfqo/cTJh+Na7/3wYcvZCLFU9dguv/t8HRKlwyW6TVuBA39muJD27ug4FvrkDbqEZY9fQIq+lHvLcab4/riWcXKJHoKVd2wQOXtMf9P8RbdbHpHROGPx4Zph/y623SLJcfTMYbiw/ii4n9cGXP5mWW81MH/aj/3Z+Mf9WAyN1D2+Lla7vplSsfb4GBb64oc7mOFJY4r7iuP5qq91tNmH41HvhxO9YdVbbtlb8OIGH61XorsCP/7HOcjl5ilvrTvBxx1q+35ytLrV5f8u5q/W/jyXXwWyvwwlVdraY1dvkCoI+/ZGwEHPeF9XgE913czmkZXbFdDqA8mnutk9R5Wx8sO+I0M8FYX9cyOzSurg8P/7QDKw9dwLE3roSPtxI//nf/eTzw4w68fE03/alpT17WCY+N6uiyfKPeX4MQfx/8+uBFABxXWi/7cA0y80usWkdumrEJYYG+2D31cpfLv5BdiMs/XItbB7bGWzf2dDmtOwa8sRxNQvyx9YXRlV5WZW06noZbv9qMd8b1ws0DHLcy3vXtNmx1Y1DUJ3/ZjeTsIjw4on1VF7PMljbbY/SaT9bjfHahW61hP205jZ+2nMZ/LmpT2WK6Rw8Klr51/w/bsfpwCra/OBrjZ2zC6K5N8fWdrrNO8w3dE9ypkF776XqcSsuvVAvhCDVLEwAmDYnFK9d1dzrtlhNpuGXmZnxya19c19u9DKq7Z2/D1pPpOPnWVRWqZH+++hjeW3oE654ZiVaNg/T3NxxLxe3fbMHjozvi8dGdsC8pCzd+vhEPjWhvddxoGSfdW4Ri0WOlmafGIHbv15Tzvqv9+PO2M3qLMQA8Ptr+HDbq/TXIKTQ5Xc7ivefx8E9KFurnE/vhKvVaXVBsxqNzd6Jjk2Ase/IS6/K5eDiBo/q+lNLt/azN76xb1dtLDuHmuBj8uPm0VT3J6LavtuDAuWy794tNFsC/9PWjP+102rXrqV93Y9Gec9j/amlWrYDAnK2n8dLCfXjnpl52GRPOAj/ObmIufneVw/cd0fa9cVndXv4X7aMbYYWh/qivUy3LC7/vw419YxDo5231+cA3SutOAsCwt0vL8tMW+3Erhr29Sr+epNkMMTDm47VIzi5yeIzZNsxoGQSuaJmEzpZhdDI1D1d8tBb3XdwOM9eeAKAE8O8a2hYA8N6/h/Hl2hNY/NhwbDmZhlf/OoD3x/fGuP4xZZbDaNwXm/DTfwdhSIcot+d5Y9FB/GAYtsA4ML8xG9x2v/V9bSlKzBLTb+yJKb/tRWZBCe4Z1tZu+Xd9uxU7Tmfq9ZvnftuLBTsSsf/VK9CojAG6AeVY8vYSuPd7pW5f3VkdR5JzcPmHazH12m7693PP7HhsTbA+F/d+bSlaNQ7EmXTlHGBbrid/UX6bR6ZdiQ+WHcGMNZV/8uQ7/x7Cl2tOYMOUS9EyPNDltHHTljssV3lVZ7b65R+tcfqbrE5L9p3HAz9ux0e39MH1fVu6Pd9jc3di9eEULHhwCMZ9sRGPjOyAp6/oXO71u7NLZ6w5jnf/PYzv7h6ISzpFl3sdQGkWorLSCi2CyuCRjB9jK51x3JL8YpP+g72QXYgL2YUu++5qn+110jKsPTrTYpGwWCSO2LScaBkbzkZ6zy0yISOvGFJKfRlGtk/JMGbmnEzNc9i3XAt0AKXZI9tOWo+foZXL2clLa4nYp7Y2ZhWUoLDErE8vpcS5rNLK3ZaTrsdR2H4qHVJKFKotXK76rmvcPbFKKXEiJRcFxWZstSmHcV8ArjNTato5m1aHXYZxgAAgwUkLRqaLQRm1DIZ89bsyq8eU9l1l5BUjq6AEJWYLsgpK7LLGzqstOratqbaKTRarluM9hkFAzRaJjLxi/XhJc5BNpHE2plBydiFWqn2dk3OKkJRZgIJiM7afUo7L04aWNmeVf1s5RSb9wmKyWJBbZLJq+Xe2X7XfYEpOkdOn1pxSy6O1LEopkVtkQm6RSf9NX8gptGkZ0v53/Fu4oLbgFhSbUVBshslssfrNGR0tZ7ZReWit8rbHp5E7QR9Nam4RLmQXuvwtasdsXpHJ5bgYeUUm/RjSbqqcnTf22WSJnHfRSl9sUlqgbTPhjONm5BSWIL/YhKz8Er3lPi23CFnqcWQ8nxu31aT+9gDl2HK1H/JLzCg2WVBkMuuPxtYyA43ZShaLtAsUa2wzg2z3TpHJjBKzBWczC5x2Z0hXr1GawhKzW08AtB2cVkoJk9mi/79f/U52nHJvfCeT2aJ/B7YZIGXNp30v2vniWEqu1bGlZcdo+0Ab28X2uNHsN7yfZzi3GBUUm51mJB53krmaaThHGLMmHAUgkjJLv6/T6fl6/UbrtpSUWYCMPCXTRR9s11DpLSwxI7/YZOiOY78Os0Uip7AEydmFsFikfrzmuvhtunqk+NnMQqsx72yzCbWsW+2JUtp222bHuMqY3qRmFhWUmK2+l/Pq+dPR+DfOjqcSJwEhR7Ly7X/PJWaLfn0ArDOIjqfkwWJRtvF8VmHp+cLwXecUuc78zHFzvMkLOaXnJr0secX6GHOOrm2uunXlO6g3OzoHaXUMbQwrQGlQTc4u1LOUNh4vrafFJ2Qgu1A5p65V62/pecV6ndU2Y1E7h+YXm/R96ChbPTGzAPnFJhSbLHq2nnYuMi5HW59tJouzTFKLRVrVY7TjJV3dF9rj7AHr37E2cLpFKlnR/+xTMrqL3LyOa9mnWoOu8bepbQNgXVdzdI+hva/d6xiDtiazBafS8pBryOjdcCxV3wbtum9W94G2Hi3o48jKgxf0eXYbMvvKQ7t+aNYeUY4T20zOU2l5VtvrKHs7K7+kzDFbtfUZz3fOzgvuhMgLS8wus2KM4z4q1xb7LC8j7RruDiml03q39tTBoxdyXF67tHJpy9GyK7XsfuPvWatLOVqWlFI/TvOLTWXGYExmi35tsf0ube9J3MW4T/Wo8Yyff/aew4NzdmD5kxcjq8CEcV9sxLeTBqBzsxAMmb4Sr1zbDbcNamOVcXJ42hj4+5S2qmxLSMd4w9MdkjILMHfraQxz0mLQ5eUlaBURiI5NQtwupwTQY+q/AIDHRnXEL9vOwGSRiH+xtJW/3+vL7OaLnbJI/7vXK0ux8qlLrD433khapERqbpFdpcZXzaBwdl3XTmpKH0iJ3q8qLZhPXdYJj47qiO82JuCVvw7gn/8bjvPZhdh8wvWNnwTw4bIjhhsL56fHEym5uPT9NejbOtzlMjVzt57B87/vtXvf0U3y1D/3u7XMmnC5TebRoj3nrF47yxDTxnNyREullxKYseaE3oUNANY9MxLD31FaBls3DsLp9Hz4+3jh8LQr9WkKSyz4at0JvLnYvq8/oJx4fby90Pe1pVbjDxgDeVP/3IcfNyutjlf3bO4yir8twf6GL7/YhEGG3+bQ6WW3MrpLa308k16g//bcbVUZ8MZyhPj7YO+r1mMzmS1SP1dog3gaj8mW4YF4+opOeGKe9ThJ7jYYdX15id17LcMDsWHKpQCUgNRlH67FLXGt8PZNvZwuJzEjH8PeXmWVGeCO0mwA6wLf+308lh1ILnP/2Q0CWmTCwDdX4PbBrTHteuvsqA7PL8ZF7SNxUftIvLNEeQxv87AAbHpuFADl8bwTZm7GhimXIiTAB73UjLp9r16BVYddBwCdBYS0llOjuGnLkF1oXzkyLsI2my9h+tXob2hNvPLjdTiekouFDw/VxzADlHEBft2eiKNvXInery51+b0t2nPO7rygfR/Gm7KPVxzFxyuOYtsLoxEd4m/Vyt596r/48o7+aBYaYLcNAND5Rfvjy+jYhRyM/mAtpl3fA7cPVjKeHp6zAysOXbDLurENwtq29j8zfw9+3Z6I16/vgZcW7sP9l7Sz2iZX8otN6Pbyv/rr6f8cwtRrnWcTGb30x37M3XoaR6ZdqQc57vp2m9XvSKuX2halrKzH7acyMO6LjXhtrH1Zur68BHcNjXWrnNqu+n7TKbw2tofVZ1+uPYHpZYy/Mv2fQ/o074/vDUC5Oe/7+jLcEtdKr+Ea93XctOXILTLhWS2jycFP5OMVR+0yepc9cTEu+3AtYiODsHrySP39+FMZVvUTR661eUS8No7frw9cZBWYMFskZm9M0G+QbCv1rs6f2nnYePwJURr0mr89EXcMbmM13pDJyRg/xhu0A2ez0a1FKP7abT+4u9ki0fu1pRjfPwbvqvsfAF7764BV5kj/acux2JAp1u75xfrfz4zpjIdGdLAK/Fz+4Vrserk041Qbv0fjKsg2c+1xq2u5lommMW6HVsczskiJedvcH0i4z2v29dXl6o3+rA0nMbxjlD4+IQD8cr+SgbsvqTTIsmjvOSzaa33O2382S89k8vYSiJ2yCLcObIU3b+hpV+4Xr+6KaYsO4m+b8TOfmb8HzxieHrr1+VEY+OYKvH59D9w2sDV6v7oUN8fF4Jf4RLe3Fyj9/va9egWCDZk6qTnKDe3G42k4kpyDTk1D8MCP2/HvfuWaqV2POr34j9Xy3M1htO3yNW3RQczacBLH37wKW06k4bavt2DWpDg8+tNOeHkJ7H3lCtw0YyN2nM60u2a/rWbMvHNTLzwzfw9+uncQooP9rbLjZ6pjWC0/eAHtn19stYz52xMx5Tf7OrgjxuuXr0/F8gK0uu2eVy5HaIAvzOpv94bPN+rlOpmah5Hvrcb/jeqIJy7rhOTsQqt6pab3a0vRuJEfdrx0mcv1bTyeinVHU/XlOw202HyBJrMFHV74B8+O6aJnOnd5aQluiWuF167vjs4vLkGIv4/DAK52L/vGDT0wcZBy7T18PgdXfLQWH0/og7F9lKyczi8uQeemIS7HMNPM2XLa6T2EVqcoKLag68tL8OilHZCRX4w5W07j5Ful3/dfu8/qT/Pd9Nyl+vnWUTDr2QV78PtOJWHh+j4t8NGEvpj49WbEJ2Tg1eu6Y8pve/H5xH54aM4OPHel8/EMtftCfyfHzEVvrUB2YQmOvnGV3WexUxZhbJ8W+HhCX7vPOMZP9ajxjB+tu86+pGzEqxHpTSfS9FaAf/cn27Ue2Wb9LDdE6TVL9593epAUmyw4npLndPC+so6tuVtP43x2YYWeWGXbqmo871gkHI69od2ou0rD1eY3btOsDScBlHYNO5Oej12nM8sso5TAXEMFwtV6lx5Q9v1ON5YLQM8CseXoaUm2FYrqZgxe1fRAxn/ssh63yZjirWXMOGpd0oJHjhSUKJknecVmqxtjP8PJ+HdDVlpF9nd2QeWemOdKZb8CRxdnRxUA4xNskjILsPyA/ZMayvrtuWLMttBaVJ2NB6HRMhQW7kxyOZ0t4aQquuyA/TnSEdvKgFZeR/ObLBLrjqZa3WwbM+N+Uc8hm4+nWWVRGlurne1VZ/vbUdaCo6CPq2U4cjg5ByaLtMsuWLBDubHQWsx/31W+78PYeqtZol7ztOuH7WXI3aw4R7TB+lcbAmsr1Gw82/X8bXNDbLu7ft2ubPtc9SZOy0h1dowZ2WbkfWt49HhZft+prNdksVhdII2/I+271QJZxrK7avnUxiDRWp1t/eLmjbOrI8vZMpwVa6HNMTUv/oxhsN1S+tObXOx+2/H/gNJzibOs1IpYcfACNhhaik3qeIkau8CPiz2mxXHNFuupjNuZYPN0TmddvYz1H+1Jq/EOMhy1OuWv260DB2sdjEdx1MmYOhvV7A1jNoPtce/saV2OvK0GzyvKYoF+01YVtHNfee0xZDcaG1ccHf9afdDR+FFG2rH7x84k/Rpe3qCPUbZNxpRxDDAtq0Eb+qAq2GaWaXXzErNFz9iPT8hAXrFZzxzc4aROrQX3tCdrHTyXo2ckuWOxkyESHNF+gmaLhJ8bmf+O/LxNuX5o45Y5uu/SGn613ggXXDw91dUTlgHl/sy294CzwI/ttUyrY2tDRWjXknnxZ/RhK5xl7Wn1SONxc+Cc8r2stHn612E3x4zVMssc0XajlgE1f3siftx82u46blx3UkaB3nDmqHpknHbhLqV+sOFYGopMFv3cqDVuObrv1mjXHG1/2h45aXnFLrMz/9jl+EmsHOOnetRoxs+Z9PzSlGZRekKYufaE3od404k0u1aCPq8ts3qakpeDmtCqwyl42cGR/T/D+C7GA9fY8mXMHtIYKzJayisAq37/7rC9ef/TUPmeu/U05m617/OdmluMsf/bUGaq5Yw1x9E7Jkx/nZFfgss/XKMPYuzjLdwayMu2q5yzSpaz1kLbirc23bYXRjutTDjKmHHVTao6GINXjjI3HDFZZJmtpu44ZBMQnDDT/hgE7Pf5aheZE3d9uw3xDgJtWgZZdmGJ3WNd3VUV21wWY+aFJqugxOp8oJXjxJulLQcPzdmu//3ITzuwNykLayaPxKz1J5FseNyvlxC46K0Vdt34jBeXi99ZhdFdm+qPBE/KLNDX+emtfXGtYawTV/skdsoizLtvMJqFKZkcp9Pz9enfHtcTi/aex9ojKegdE4bdiVl48WplDCnt1JaWW6RnqBx/8yr0fW0pokP89Rt9rZ+2lrk0d+sZLDuQjBbhgVZP5HNUxtgpi/DP/w3HlR+vs/tMu7FOzi5Cu+cWOay822YQauu4OU4Z2+GpX3dbfW7MCrv/h9LvyjgWg9ki8dxvezF362lMNvQ//zX+DF756wB2v3w5er+2FK0N477YOupiYHnjfvjA8IRAbSwqjba9g9XWx2KTRZ/3wRHt8eyYLnhmwR44o3U5MEuJCTM3ITTAV6/0JWUUONznP205jQnq+EyJGfm46K2yx1eb/s8hbD2ZhgfUp5ktP5iM2CmL8NRlnfRptpxMw21fKWPQOWq1NEuJ1/8+gPVHU60qplp3nr/VCt+sDSf1GxdHZtzeHw/8uN3u/U9XHMWepCyEBfriPTXLIj2vGP1eX4ZvJw3Qp9Mu2xbpuEX98Z936pVSIZTxzYzZEDd8vgF/PDIMH9o8+bHD84v1OoarSusrf+7H7I0JuP/idvhSrYfYcjWGnCOurt+2NylAaXblLTM34+qezXF1r9KsPy1T6Mu1J3BZt6a4ySbb2ZaxelSV520/79IGhAFvLNdvWAHYjc3nqGEHUG74tW6ytmPSGL/7//t5l/40IQCIaxOh/61t05s39LTKBHrt7wN2v2dAGex3syHwrs1/v5Mx9177y34ZQOlTvGzrVB/YHHfuquggq5oHftxeqQYKW3/bZC/e/0O8W/MZsx6N+99RnUpr+C1yMRYkUJo5dSo9H11ecq9u5sql76/G5xP76a+NAcAJMzdbPfkJcB7ovWv2Nix8eCgA5bc3dPpK9HOQ/e6sa2KRyaKf75wFdGOnLEJUsB9Sc4tx++DWen28NOgt7Roq7/vB/vyrcZUVqWUa2xr72Xq7wLFSLn+EBvrgq//EYdT7a7D8yUvQoUnpkzq3n0rXew4YA7x21LdKn+RqPc3X607gv8Ptf5/nsgpw0Vsr8fN9g/X3jEMLGK8Vzjw2dyfMFon/TexnaFBQPjMGqcpqDNbGthRQ9k276EZ6ht+WE+mInbII654pzbjs9OI/KDZZ8NaNPXHrwNb6+99vSsDFHaOtxt/TPDxnh10D7bx4JRBorMfmFpnQ59Wl+PKO/nblts1C3nE6E7d9tdlhI/JyQ4OfFiTT9pGxB8Brfx3ArA0nsfWFUVZjmpWuU+DguWxc+fE6/HDPQKvPpJQY8MZypOYW411DNnXslEXYbcieBOBW4gKVX41m/Jgt1icsZwEGR+cJY2XJWRza0Qnm3X8r16piy1GgxhVnT4Yoi7v9a2fbPCXC+OQqHy8vp49BdaW8ZXaWSVWRpzV4iqtBqY2q+okD5V2/K46CPkBphT3RRd/u2mqPk7FrjMfc4r2lLVp/7zmnVzxe+/sAvlxTeiPn5WU/dhNg3RJyOj0fszac1G9OjLT0WXfN3XraYbbEswv26pUxreVOC6Zo0xszBXMLTcguNOlBH8DxgOWpucXYk5jl1jnqi9VlD9pY3vsSX+/yXU6M5ziLLD23frWu9DvTtlPLADhdxtOY3OHOTbyjMSPc2WdadqrFIrH5RLqeIQm4zrDTvveM/BKHx6itGWuOY8fpTLsxqN433ITONAQxHLVaWqTEN+tPut0a6cyv8Y4zXt5fdgTLDiRbZYZojQzfrC8NJGmHmbMbYWNF3kvAriuP9hv62OZ7dffx3No11FnQpyyObuAqOj4GoBwnC7Y7bjBxJ5OqIo8ZL4sQ1r/vHCdZd2VZ4SQAV1hidpna5Oja9spf+/WBlstivA7o7zn5vm0HWNb4qPvV9rgqb1Cwquw6k1np4JErGZVsiHM1poezMXlspTi4DldEYYkFc7c6z+5zNj6gLeMT7bSxqhxl6ji7tykymfXrqqMGbE2qmi3z4+bTenDTOijhVnHLtMRJNpCzbMHU3CKcSMnDn+o5+U+bc7Gx26lWXGf7wsj2MJ626KDD6bSMujkOBkkHUGbQRwilzNq1WA+qqZ8bA8llXT8CfL30ZQLW3Tq1MQqNmd7a78E2eWDaooNO6wbuZuWfSMmFySLx4fIjdvvSW9ift5z1HLAKnKvb5Si4rDUEuQrMaL+P5TbZ4yVmqR/fn9vUqXacsT7PO3oKIlWeqMkuLv7NO8rmd34EABjeMQp9WoU7fOKUM4+M7ICUnCI94mnronaRZXapqG/6tg53u9tVTWsRFoCz1RQoodqrSYi/XeDktbHd8b9Vx+xagm/qH2N1Y2hreMcohy3kB167wmpMkZoS7O9jN+i2KyufukR/0pC7JgxohdaRQfo4Os5MGhJrF/itDxr5edtlpo3sHF3mOEG1gXbsl/c4KY9p1/fQxwGIaxPhNOBbmwxu17jMseYciYkItHpUszPNwwLcCphVhW/vGoCFO5P09PQOTYL1ATSJqG5zVufQJEy/GmaLRP9py5xmqa9+egRu+2qzw/rvIyM74LNVx9ClWYie+f3opR3KvBfSzoVRwf5lDjux86XL0NfBGKRVLcDXC4UlFnRtHoob+rawGrNq2RMX43hKnlU26OcT+8FLAA/8uEN/766hsbiudwvc8PlGq2W3jWqkDwHy2KiO+GTFUfh6i3IN6G7LmJVTli3Pj3I47lBt9OyYLlZjhjrStXmo3aDolRUR5OswQNwyPBDB/j52jUrDOkQhLMjXbmxEo/bRjawaOaliTr19zXYppcNHy3rsce7rjqaiR8uwsic0cPZYbk1DC/oAZafMehKDPg2To2yZl/9wPHC3q6AP4LhbBOB+a35VK+/NfEVaZH92c9yR+hj0ARw/kaMuBH2A0mO/OlvijYM/1oWgD2DfPdBd7gR9AMeZfNXlrm+3Wb2u6fHhiKj6uAr6aLYlpLscmiAxo8Bp/Xe/+jReY3d/dxrAtXOhO2ONGrNmq5OWqX7wXLZdUKHYbLHrAvzQnB2w9e2GBFzTq4Xd+8anv2lZdZUJ+gCuB1u3VZ3X8KpWVtAHQJUHfQDnWYHOniqqjT/rCoM+1c9jGT9ERBXlKKuIiIiIiDyLmZBEnuMq46fGn+pFRFRZDPoQERER1T4M+hDVTgz8uOn6PvapiHXdwNjGni5CnffgiPYeW/frY7t7bN1ERFT/+ZVz0HYiV6ph7PFyOTxtDBKmX+3ZQhAReQiv6DaGd4xy+P5l3ZrVcEmq3+huTTyyXuPjH8sytEOk1WvjY25rA2fHS01oG+XefowO8a/ydTcLDajyZRIRUe3i4+3hO3WqV+IcNDg2buRXoWVpdZvLujV1ex5fL+W2J65NRIXWSUR1Q5vG3p4uQq3kscGdq8qaySOQlFmA277aAgC4rncLu0cM2urSLARf/Ufp+tYk1B/pecXw9faCxSIRFeyPIpMFyw4m47G5OzGyczQ+va0fAn1LD6CNUy7FuC822g0o+dCI9laPpwv09UZBiRkPXNIeM9Yo729/cTS8vQR8vb3w4Jwd+mOdASD+xdE4n1WIaz5d77TsM+/ojz6twzHwDWW0+T6twvVHTApR+pjHuDYR+PauAcgpNGHI9JUAgFaNA3HG8Ejv0V2bwtfbC6/+dQCubH1+FAZW4ej2Cx4YggA/L8zdchqvlLHu7+8ehPbPLwYAbHthNKKC/fDOuF6wSImeryzVp3t4ZHvERATZPSoRAG7s1xK/7Uiyem/r86Mw9n8b7L7D/a9eAQB44fe9Vo+G3PPK5SgxWdB/2nKr6Ye0j8L2F0cjLNAXuxMzMe6LTQCAD27ujSd/2a1Pd3NcDH6JT8Tjozvio+XWj3/977C2+NrweGPN05d3wntLj1i9d3jaGFzILkJYkC9CA3z19x+4pD32n83SBybc+8rlKCgxIyzQFwICEhKdX1xit44Dr10BLyFQYrYgwNcbHV/4x+pzYz/trc+PQmigL4pMFgT5eSMjr7hKj4uaNOXKLpj+T9kD4pHixau7IiWnqEKPvL6mV3P87eIpDjUh/sXRiLP57QLAN3fG4Z7v4h3OY3zqirtGd22KRv7e+hOfXPnk1r54bO5Oq/fm/HcQJn69pVzrrG7LnrgYJ1LzcP8P28ueuBx6tgzTH+/eUNg+xbCRnzc2PjcKvV9d6nSe6Tf2REQjP4f7f0TnaKx2MPD5oLaNMfM/cRACeOXP/fr1b+dLl8EsJfKLzLjvh3gcOp+DgbGNsTUhHZd1a4plB+wft277ON8VT12C8EBfFJSYUWKW+M+sLVb1CgCYe+9g3PrVZtc7o5w2PXcpLnprpV6vqqitL4yCv7c3vt140u5aDADeXsLpwK7bXhiNgmIzokL8kJFfgiBfbxSazLjorZX6NNtfHA0A8PHywv6zWbjt6y1o3TgI/z5+sX5NPnYhF1d8tNbqCYaHXh+DzPwSDH5LuaY6+273vHI5BAB/H2+YLBb96ZZTruyCWwe0xsj3VyM9rxhX92qORXvOYVy/GFikxO87S+tAh6eNgcks0X2q+0/GPPrGlcjML0F4kC+yC0oQFuiLX7cnOqxzGcW/OBpfrzup14H7tg7XH8tt3K9aPQ8A7hnWFo+M7IAtJ9PtBgje+sIoBPn5wMdLwN/HC9mFJoQG+KDELGGREj5eAn/vOYfH5+0CAIzrF4MFOxL17fZSU47m3jfYrr5TH6146hKMKueTResy7alprrxzUy/0ignDmI/Wlbk8d56iVleM7ByNg+dy9MfNa/x9vFBkqr0PCqqobs18kZ5vQU5h3RmouybU+YyfmIggdIguzXxo4kZ2w+XdmqJV4yC0ahwEfx9vNA8LRFSwP5qEBsDLSyDQzxttGgcBAHrFhCPY3wfe6sWif5sItAgPxIjO0XbLHWDTkqFN07V5iP5eZLA/woP80Mjfxy6FOirYv8zsjJAAXzQJKc22uMaQATOme2lWUv82EQgJ8EWL8ED9vd4x4XbL6t7C8ZPVWhrma1KO7A5/H/tDanRX69aY0EAf+Pt4o7sbT3XT9ntEkC+iQ/whhEAjfx+EBPhiQGxpi02vmHB0bla6n0d3Lc1m6tsq3G65kcH+DluJGvn7oJG/D4Z1tP5+QwN8nbZKRQb7w8fbCzERyjEzrl8MurUItZpmYFslc6lz0xC7+WOjGjlcbssI5TsI8C3dp/4+3mjVOMgq6AMox1gfw3Zqx4m/jzf8fLzg7+PtMNMqyM8HAb7eCAnwha96PPr7eKFHS6X8Fxv2Q5PQAAT4eiMsUJm2PMdFbWM8duq75mFlf0+9HfxGjPq2jkC/CraQhgX6lj1RFWgX7fh3BCjnVkfaOvntAcCoruXPiIwO8cNF7SLLnhBAaIB9u4uzc0FN6do81O69jk1D3LqulkegrzcGtW14XY0H2xwb1/VpUebvIyYiCDERgQ4/c/R9AUBcbATCApXGAePxGNHID1HB/mgdGYSLOynn9it6KPWGEZ2jHZ4XR3a2/h20jw5GZLA/YiKC0DaqkdU1AgBaNw5y+VusCH8fL4So17zKZtk2CQlAWJCvXscx1nU6Nw1x+fuNDlH2XZCfD1qGByKikR+ah1l/NxFBfogM9kdYkC9aRyp1gpGdoxHo543Gjfzg7SX0jNmRXZro56AAX280M5yrr+phnd2s1a1CA3wREuALPx8vBPmVnkM6NQ1GWJCvXvfp11r5Lge3a4yBNr81fx9vNPJ3v913VJcm8PX2QnSIP3y9vfQ6T3/DNcFR3Q9Qzr2D25Wuv1MT+zqQt03/r0FtGyOikR+6OTi+m4QEINhfqbcIIZTGLSHg5+OFAF9v+Hh7WZ3X+7YOt9pujW8D6cLYPtr9DPv6wJ3sr+4tQq3ujVwZ1K56rlMh5fj9VZWWEYEY2UU5X/sZfq+254f6wssLcHJaatBq/Mj77La+CPDxxsbjaYgM9kOL8AAkZRQgLFC5mO1NysIdg9tgxaELKCwxo0V4AOITMnDfxe1wIacIO09nINjfF4PaNYaUEt5eAk1CAzD33sGIiQjENzaZEzNu76+3GHx71wAIAMM72gdtbPVuFY6FDw9FT0NwYsVTl6CpesF+5bru6NYiDC+pj9add99gDGoXibn3DkZYoC/yik2IaxOB+FMZiGsTgaahAXYXGu2Jam/d2FOvEDYNDcDMO/pj/bFUfL/pFAClBUnLNCk2W0dl7xnWFtEh/gj09calXZpg+cEL8BLACENlbfNzo+AlgOAAH1zWrSmGd4zG2cwCRIcogab3xveGn48X+rYKx+yNCRjToxk6RAfjcHKOwy49vz00BAXFZrSJDIKfjxcOnM1GRJAfmoUFwNtLYG9SFjpEByMjvxhmi0SPlmE4cDYbwQE+yCk0QQjlIj8gtjE+ubUvOjcNgY+3gJTA8ZRcpOcVo0OTYDRVA1zLnrjY6iSl+fTWfjifXQiLlHolR/Pe+N7o89oyAMDtg9uga/NQhAX6IjLYH2m5RfD2Enjx6m4Y2bkJIoP9sOpQCq7tXVrRGtevJdpHN0LbqEZ6dFwIgZ/+Owi3qS3ySx4fbrXOpqEB+OPhoejcLAQBvt7465FhaBkRiKyCEsRGKpXkfq3DsXHKpfDxEnq2zG0DW+O1vw7YfbdtIhvpy1u4MwlXdLfvbrjpuUux9WQ6ruvdArlFJnRoEoxODoJLALDgwSF6y3L8i6ORmV9sN83yJy9BWKAvAny9kJJThFaNg9C9RSgu7eL4JnjdMyNxLqsQX607gWUHktGqcSBeu64Hjl3IxRuLDwJQWvOOJufo+83WGzf0wB87z2JrQjpC/H3w8KUdrLJxbujbUm+t3Pr8KOQXm7H8YDJScotwWdemmLn2BJaqLdUfT+gDIQS2nkzDj5tP263r+7sHIjjAB/1aR2DuvYMR6OeNyEZ++HnbafRpFYG8IhPOZxciI78YQ9tHoUmoP1YfTkF2QYlVNp/Gx0vg6zvjcOBcNjo2CUGxyYImof4YP0PJ/Pr2rgHILTTBbJG4pFM0+r6+zG4Zz47pAl9vgWmLlP315R390TQ0AEF+3lh16ALeKmdm0v2XtMPFHaOx/VQG2kcHo1dMGHy8hd4qrbUEa+b8dxDaRAZh2NurENnID7PvGoiHftqOM+kFmHZ9D0QE+ekV/AUPDkGgrzcyC4rRIiwQI95bbbd+26wV20q95pNb+yIrvxhto4KRlleEjk1CcC6rAGczCxAc4AOTWWLy/D0O520f3cjusZ8TBrTCm4uVfbXosWG4+hPrzMm/Hx2G5OxCSAmEBfnC20ugXXSw0xbRK3s0R/voYOQVmRDg6432TYKRmFGAvq3CkZFfjD2JWSgoNqNddCMs3Z+MefFn4OfthVsGtEKJRSIluxD92kTgaHIuMvKL8fnq4+jYJBhH1Qw6H6/Sc9o3d8ahTWQjq5vQ2we3xuB2kSg2WayyBzX3XdwOM9UMrAkDWuH6vi0RogaTbLfd1o/3DMKzC/YgKbMAAb5eeOvGnkjPK8HNcTFYdTgFXkLJ9muk3lg6ai97Z1wvLD1wHssPXnC5rpGdo3Fxp2g9s/TXBy5CaIAvWkYEIjaqEWIiApGZX6K30GseHtke/1tV+pv7fGI/xEQE4tC5HGQWFGNQ20iM/d8GAMAlnaLx3FVd8Nfus/Dx8sLH6uN/+7eJwLTreyC7oARrjqQgv9iMvq3D0b1FGHacysAItRKsZdDOuL0/lh44j9aNg9C3dQTunLXV4TY9NqojOjcNQVZBCZ7/fa++T0+k5uJCdpHe4jz/gYtwJDkXz/++Fy3DAzGuX0sUlJhxba/mSMosQEf1Jnj5kxfjz11nERroiyA/H3RuFqxnjw5pHwkvL4E/HxmKQ+dz0MjPB/3ahONcViEEgC/U89LMO/qjbVQjnMnIx6C2pcGLm/rHQAK4wqa7+uQrOuO63i3Qo2UYBrVtjO4tQjGmezP8s+882kU3Qs+WYTh2IRd9WoVj4/E0nErLx7AO9kGXV67rjuv7tkRekXJt7xMTjrAgX/xwz0CUmC0I9vfFzV9u0r97X28vmC0SsZFByCk0oaDEjCs/Vlre/350GBIzCtAmMghZBSWICvbHqkMXcMvAVgj298Gix4ahXVQwur68RJ++aWgA9iZlIrvAhKhgfzQPD0BogC9OpeXhcHIO4to0xvZTGWgb1QihgaVVXi2TaWiHSEwc1AZBft56Y4ZtBtYXE/s57KKkWfX0CPh6C+QVmfWMEkAJ2i15fLhdgDksyBeLH1PeLzKZrR5WsOixYTiVlo+rejZHh6bBiAkPRH6xGSEBPsgrss90Wv7kxTiVlo9Luyg3vK9f3wMTB7VBr5gw9GkVjn5q4KNb81BEh/hb/Za3vjAKZotETqEJOYUlyCooQfOwQAgBbEvIQMcmwYgI8kNrtSHUVqemIfjzkaEI8FWuoxdyinAkOQedmoZg0/E0jFXHxjTWR2/s1xJt1cBgTEQgcgtNAJT6dbPQABw8l63v69aRQVjw4EVoGhqAlYcu2AUhnendKhwfT+iD/GIzJgxohcu6NbXLXDP64Z6BeOSnncgqcP6IdgB4YnQnmKVyLT+Rkuv0+gTYZ/cB1nUZQPkNtotqhAcdPOZc88fDQ/Xz3Fs39sSork2QXWCCv48XjiTnICmzAO2igtEk1B9JmQVIyS5SG0mhN0DufvlyvLn4IIZ1jMKh89n6eXXt5JHYmpCOAF8vPPLTTqdlMNr6wij9fDn/gYtw9EIurujeDPEJ6bBI5b5G257WjYNwOj0fAPDXI8NQZDLjJrVu5MznE/shMSMfoQG+uKxbUxw6n4OwQF9YpMR1n22wmnbyFZ3RJjIICal5eG/pETQJ8bdqxPp8Yj/9EfJz7x2MdtGNcC6rEN1bhMFkqG/PmhSHrIISxEQE6XU3rW4b1yYCo7o0wcWdopGWWwwfbyXTbMXBC4iJCESRyYLU3CIIIRDi74OcIhNiIgJx17fbACj126YhAcgvMesZvvMfuAjdW4Th0PlseHsJzFhzHIv3ngcAqzoCADx/VRdMGNgaKw4mo0uzUGQXlOCWmUo25fvjeyPA1xuT5+/Wr207T2cCAMb2aeEw83jqtd3Rr3UELu/WDGezCrA3KUsP3m8+odyX703KwjtLDlvN1ysmDHsSs6zK2C6qEaZe1x3JWYUY2aUJ0vOKse5oil6X/ebOOGw6nqZnOjZu5Kd/9sJVXbFgR6KeVf3e+N5Izi5El2YhCAv0RVpeMY6n5NqVozy8BVAbEpluHxiEH7fmO/18ZCd/rDpSc1lllQr8CCHGAPgYgDeAr6WU08ua55peyoVgtJOo7PV9WwJQAhqaG/rGAFBuhG2zajQXtVcqOqE2rWdjepRWdty9aGj62LSCGyPn/j7euGNwGz3wM0gN3Gjl0GjltW3pA4DIYCWDpE3jIKuKweXdmyHDcFMeGeyvX0R8bG6ihBAY26el/tq4vRpjK5I2rTF75ab+MfrfL13TTf/bUZlHdo62C7I06RxgM42yn1sZKgvOMgqu6209aLajrJSOTgIZzcICrLbNKDyodPuEEFaVNm3b/Xy8MFINaPSyyYYSQqCvup3GZQ0xVHy7NLNvjTJuZ8+YMKv1aTfPti0NXl4C1/Rqjt92WndHC/H30bd9wsDWDrezeVig/p2GBPhaHQu2jC3LUcH+DrMgjPtfa2EdZzg+bGmZcysPXcAyJOPpyztjZJcmGNmliR740QKMjjwysgMmDmqD6GB/bE1Ix439WuKBS9ojp7BEr5xMHNRaryxpFfP/Dm+nL6PYZMHSA8kY3z9G3/7rerdAUkYBVtmkymut3ID1b3XyFV2cbqP2PWuBnyu6N8W/+5VAU7OwAIzo3MSqYmvk7JzTKyYM+5KyYJGlA4R/vOIocgpNVgE+7aLYLqoRTqTmOVyWrdAAXwztEIWhDm7SAKUlWQv8xEYGYWiHKCSrwc02kUHoGROGoe2j8HP6GbRuHGS1z/q7kfUztEMU3rihB174XTk3ase/bdepHi1C0c6mNdKYKZdfbMLk+XvQtXkoDp7Ltt6Gns3x6UrrdG5j63f3FmG4pFM01hi60vZoGYYeDrIM20cHo0VYAM6q3T5jI4OQkJaPAF8v3NjP+tjXzn2tGgdZnTNScoowL/4MooKVrMQ7BrfRPxvRuYnehWZohyh0ahqCRXvPoZF/aevzKENWpLb+KVd2RbC/D86kO64wGINEL1zdVf+9lqVJiD+GdYzCrQNb4b2lRzD12u76NRawPycDjlvzr+zZDD7eAssPXsBjl3bAJysdp9cP7RBlda6MaxOhB/9vN+ynVYcv6BXV3q3CcUX3ZlaBn6t6KoF523M1oGS+dmkWqq9HC/yM6tpEz4oZZHM9c3StGdOjmX4NzS9WbkjbRzfCqbR8mAzdfwa1baz/vrTAz7COURjWMQqpuUrgp3uLUMTFNkbryCA8/zsQFWJ9bBivKx2ahODJyzs72n16IKFXTLjVtjcPC9R/F5d1a4rL1fOG7fVSCIGb41rZLdfX20v/PWj/Rwb7W30n2jVQOZ84LB58vb0c1sscNbDZThepXoOahQbgfHYhujUPtfuNGr8n2wxlbVot6GEUHeKvX/eN2cCaQPV8ERlsfbNoUb/nFmEB6NsmAov2nEPz8ECX2diuMgcd1ROA0nNdoJ+31bHQvUWYvp22da1IB8kbHZqEoIMhi8bfx1vfHuP52lEdTMseb+4g+dpZuW0Zj8nIYH/99+YsG00IYbVdWtG1+rVtgK1/G+X1fy6Kdas8GmNdqGkZ2cnDO0bjhr4tMXtjgv6en7eX3hj34Ij2+GL1ccRGBenL7d8mwmXg55kxneElgF/iS4M/4/rFWAV+Hh5p/aMa3jFK766v6d0qHBFBvsjIL8GEAa0ghND3WSubgJyzRr+wIF+8fVMvAECQn3LdGdE5Gq0jg/SsNHcDP8YeB3GxjfXvSzv/7DN0333uyi54cM4OtG6s1CsshnNo56YhOJys1AeM3Te187xmaIfS31276EY4YWjwiY1shKt7NceWE2kAlHOwkfEY1Op72rHgozbEB/l5W50/wgJ9kVVQotdtAej1AGOd+c4hsQ73j62Jg5Tzqda98ca+LfV9pp1fn7miCxbvPY82kUF468aeenDswRHtcd/FSv3QeI3u1jwUB85l49IuTRDRyA9nMvIx/Z9DuKFvSz3wc+vA1vr1dNKQWMzemKA26npjvHo9CAvytdpH2v13dIg/3llyGCM7R+t16PH9Y7AnMQuTr+iM2MhGePinHbisW1NcYqgfRof4I8jPG9MWHcTgdo0xqmtTq7oNAExbdBC+3gL3XtwOYYG+eGbBHjx1WSer+1DNX2UM21IWLyFgrsLAj583UGwGQgMEssvRfaxXC9d1s/DAmk1LqnDgRwjhDeB/AC4DkAhgmxDiTyml00FbYiOrP439oRHtEdnID0PaR+JUmlJh/uf/hlfb45//eHgo8tQKYnm9fG139IoJtwsWAcBN/Vthd2IWhrZXTmSvXNcdPVuGYYg67Zd39Hd6kq8OsybFYe2RVPzfqI41ts6K+P2hIfoFZOkTFyMxw3mU1dP+ffxi/abu1bHd0bdNBBoHKVlwR5NznQa8KuOnewc5TcmujMdHd0SzUH9c26v0pvHHewYh2NCdRctk+XPXWVzUPhLnsgpwywDlAjS6a1O8cm033DJACXA9emlHBPh4I6KRkm2y4MGL4GTYBVzUPhKvX9/D7sl7H9zcB5Pn78aLV3fD4eSccg0q7sjvDw1BscmCLs1CMarLefj7ejkNhMy+a4DDoOTfjw7D1+tO4PmruiKnyIQjhkDIokeHY99Z6zFPLuvaFJOv6IyxfVrgtx1JGNI+Eik5RWgRHoicQhP2nc2ClErL2uJ956wyeZy5skczPD66I5bsO4+f7xsMQKkMvTe+t9499cVruqF7i9Ayu1WseOoS/LTlNMb2aWHVGndLXCscOJuN4R2jMLJLE4QG+OK2Qa3x05bTyCooQWigr13Qx1aQnw8+n9gP/dtEIDm7EKsOpeCi9pHYl5SF2wa1xqVdmuDrdSfRsWkwIhv5YcKAVmgS4o/26vf82W198Z9ZWzHj9v5l7pNfHrgIKw9dQICvN0Z3bYp/95+3upkqy039Y1BQYtYrebZGd22C18d2x7j+MSgxSVzUPhJ9WoXj1wcugm1D9Ge39cPOM5kIVlPBYyIC8dyVXfD9plMY3C4SV3RXuip3aBKMhbuS0KVZqF3Q57eHhsBklvDxFvhm/UncM6wtzmUq2ZFa14d7L26HRv4+GO8isKvp3iIM02/sqd+kZuQV64Hm7IIS3DqotR74eX1sd7z0x34Ayrgjdw6JhY+XwP2XtEPbyEZ60MfWs2O6oEuzUIQG+uDybs0QFeyHt27siW7NQ/XApK0vJvbDphNpdgG6Xx+4CF+uOYH/DmvncD5b/z5+MZIyra8VQX4++PCW3hjSPgr5xWbsOpOBJ+YpmVdehm1Y+dQlVtlnkY388NI13fTsmCYhAXh/fO9yd1H6dtIANA93fcPatXko3hnXy2E2aG3ym3rudGbBQ0Ow41SGVbaMK6ueHoGjyeUbf8vWNT2bIz23yK5RxctL4NNb+6JfmwiEBvhgaPso9I4pu1s6uTb/AefXcE+ZfdcA/WZe+0lPGhKLgW0b6+cdPx8vdG0eiqYh1vUbQLn+/bDpFK7v2xKFJWb4enth0/FU+Hh7oUlIAF6+tjt6xoSjo5o92aNlKKZd3wMxEYFW5+xv7oxD68ZBiAz2x/IDySgoMWPqn/v1z/98ZBj2JGY5PXdWhd8eGoI9ZzIRHuSH0+n5OJmah9sHt8HmE2kIC/RF39bhSMtVGqRnTYpDs1DHXaW6twjF81d1QWGJBWN6NMPHE/roXYm8vAQ+ubUvjl3Ixe2DWmPd0VTkFpkwonM0Dp3PcTgUgtGP9wzCm4sP4q6hsdiXlI0r1SD9wLaNMe36HrhWbbSYNSkOf+0+h7ZRjfDVf+LQ3knX0xm397MLUP796DDsTsx0e7858/3dA62CxX1bh+OZMZ1xQ1/7xlnjz6J/mwi8NrY7svJLcO/Fjq9fs+8egDWHUxChNqrdM6wt/H28cNvA1ujcNAR+Pl7o0yocz13ZBV5C4J5hbdEuupHDBgBHujQLxZs39MRVPZvhfHYhzmUWIi42AlkFJbhtYGuEBfri1eu66/V3o1aNg/DOuF56o7qtGbf30+9dx6n1pgkDHZfLq5LHu7cXnI7XVhnV+DOsEUK6SH90OaMQFwF4RUp5hfr6OQCQUr7lbJ64uDgZH+94IE2iuiJ2yiIA4CNBqVZ5Z8khfL76OJ6+vBMeudQ+QFvdxy1/Fw2b8ftv//ximC0Sh6eNsRpXo64bP2MjtiVk4Jf7L6q34yIQNUSv/rUf325IwItXd7XKKPaU6rqerjyUjLtnx2NE52jMvmtglS6bKuZkah5GvrcabSKDsGbySE8Xp9b4Z+85l90gy3JLv0CsPFKElNyqSfvRMn7CAgWyCkpjJ77egKvnDbxzfRieWej8QRY39A7E77sLnH5eEafevma7lDLO0WeV6erVEsAZw+tEAINsJxJC3AfgPgBo3dpxdxWiuuTpyzs57G5A5En3X9Ie57IKnaYgz7i9P5Iyq/biYvTGDT30LBVqeN4f3xsmi1LB+v2hIfhz11m7BxjUde+N740vVh/Xx00hovrhsUs7Iiu/BLc66VZf02ZNisOR5NyyJyynYR2iMb5/DB6/rFOVL5sqpk3jINwxuA3+c5HjjOGG6lJ1oPpeLXyx56wy/tbHN4Xj/+ZnWk03eXQI3l1emgF6ZbcA/HOgEDf0CcLITgGYt0PJ5g0P9ML5bDPaRflgTLcArD5aBAEgLc+iB15CAgRGdw5AYYnEPwcK0T7KB8dTTegQ7YPpY8Pw264CXN87EL/syMf8nco8X09sjDu/V7ry+XkDTUK8kZhpRpvG3hjQxg+juwSgV4t8fRt8vKzHHnpsRDDMUuLPPepwA429kZBuxoiO/igokTiUXGIVaAKAm/sFIshP4GSqGTsSi/Unlz16STA+XeP6vFGZjJ+bAIyRUv5XfX0HgEFSykeczcOMHyIiIiIiIiJyJidnu6eLUCeFhsY5zfipTHNcEgBjx7wY9T0iIiIiIiIiIqoFKhP42QagoxCirRDCD8AEAH9WTbGIiIiIiIiIiKiyKjwgg5TSJIR4BMC/UB7nPktKub+M2YiIiIiIiIiIqIZUaiROKeViAIurqCxERERERERERFSF6tcjN4iIiIiIiIiISMfADxERERERERFRPcXADxERERERERFRPcXADxERERERERFRPSWklDW3MiFyAByusRUSVU4UgFRPF4KI6qUwAFmeLgQR1TusuxBRdWC9pW7oLKUMcfRBpZ7qVQGHpZRxNbxOogoRQsTzeCWi6iCEmCmlvM/T5SCi+oV1FyKqDqy31A1CiHhnn7GrFxERUc37y9MFICIiInIT6y11HAM/RERENUxKyQoUERER1Qmst9R9NR34mVnD6yOqDB6vREREVJew7kJE1HA5vQbU6ODORERERERERERUc9jVi4iIqIKEEK2EEKuEEAeEEPuFEP+nvt9YCLFMCHFU/T/CwbxthBA7hBC71HkfMHzWXwixVwhxTAjxiRBC1OR2ERERUf3jot4yXn1tEUI4HCBeCBEghNgqhNitTvuq4bO2Qogtar1lnhDCr6a2idzDwA8REVHFmQA8JaXsBmAwgIeFEN0ATAGwQkrZEcAK9bWtcwAuklL2ATAIwBQhRAv1sy8A3Augo/pvTLVuBRERETUEzuot+wDcCGCti3mLAFwqpewNoA+AMUKIwepnbwP4UErZAUAGgHuqqfxUQQz8UINQmVZ5dbo71WmOCiHuNLzPVnmiBkxKeU5KuUP9OwfAQQAtAYwF8J062XcArncwb7GUskh96Q/1miyEaA4gVEq5WSr9sb93ND8R1V+VaZVXpxsjhDis1k+mGN5nqzxRA+as3iKlPCilPFzGvFJKmau+9FX/SfX+51IA89XPHNZ7yLMY+KGGosKt8kKIxgCmQmmRHwhgqiFAxFZ5IgIACCFiAfQFsAVAUynlOfWj8wCaqtPECSG+NszTSgixB8AZAG9LKc9CCRwlGhadqL5HRA1HhVvlhRDeAP4H4EoA3QDcqs4LsFWeiFQ29RZn07QQQiw2vPYWQuwCcAHAMinlFgCRADKllCZ1MtZbaiEGfqhBqEyrPIAroJzY0qWUGQCWQUltZKs8EQEAhBDBABYAeFxKmW38TD0/SPXveCnlfw2fnZFS9gLQAcCdQoimNVhsIqqlKtMqD6WR6piU8oSUshjAzwDGslWeiDSu6i1GUsqzUsqrDK/Nahf1GAADhRA9qr2wVCUY+KEGpwKt8i2htMZrtCg2W+WJCEIIXyiVpzlSyt/Ut5PV4LDWdeuCq2WomT77AAwHkASlQqWJUd8jogaoAq3yzuotbJUnImf1lnKRUmYCWAWlt0MagHAhhI/6MesttRADP9SgVLRVnojIEbUF/RsAB6WUHxg++hOANh7YnQD+cDBvjBAiUP07AsAwAIfVYHS2EGKwuvz/OJqfiOq/irbKExE54qLe4s680UKIcPXvQACXATik3kOtAnCTOqnDeg95FgM/1GBUolU+CUArw2stis1WeSIaCuAOAJeqj2XfJYS4CsB0AJcJIY4CGK2+ts0m7ApgixBiN4A1AN6TUu5VP3sIwNcAjgE4DuCfGtsiIqoVKtEq76zewlZ5InJYbxFC3CCESARwEYBFQoh/AbtswuYAVqljE26DMhTG3+pnzwJ4UghxDEp24Tc1uVFUNqEE6IjqNzW6/R2AdCnl44b33wWQJqWcrj71orGU8hmbeRsD2A6gn/rWDgD9pZTpQoitAB6Dkn69GMCnUsrFICIiIqogZ/UWw+erATwtpYx38JkPgCMARkEJ7GwDcJuUcr8Q4lcAC6SUPwshZgDYI6X8vPq2hIiIagMGfqhBEEIMA7AOwF4AFvXt56EEbH4B0BrAKQA3qwGdOAAPaN29hBB3q9MDwBtSym/V9+MAzAYQCKVF/lHJHxURERFVgot6iz+ATwFEA8gEsEtKeYUQogWAr7XuXmrm4UcAvAHMklK+ob7fDspgz40B7ARwu5SyqIY2i4iIPISBHyIiIiIiIiKieopj/BARERERERER1VMM/BARERERERER1VMM/BARERERERER1VMM/BARERERERER1VMM/BARERERERER1VMM/BARERERERER1VMM/BAREVGdJ4QIF0I8pP7dQggxvxrX9YAQ4j8O3o8VQuyrrvUSERERVYSQUnq6DERERESVIoSIBfC3lLJHQy4DERERkS1m/BAREVF9MB1AeyHELiHEr1rmjRBikhBioRBimRAiQQjxiBDiSSHETiHEZiFEY3W69kKIJUKI7UKIdUKILs5WJIR4RQjxtPp3fyHEbiHEbgAPG6Z5QggxS/27pxBinxAiqDp3ABEREZEjDPwQERFRfTAFwHEpZR8Ak20+6wHgRgADALwBIF9K2RfAJgBal62ZAB6VUvYH8DSAz91c77fqfL1t3v8YQAchxA3qNPdLKfPLt0lERERElefj6QIQERERVbNVUsocADlCiCwAf6nv7wXQSwgRDGAIgF+FENo8/mUtVAgRDiBcSrlWfesHAFcCgJTSIoSYBGAPgC+llBuqaFuIiIiIyoWBHyIiIqrvigx/WwyvLVDqQl4AMtVsoarUEUAugBZVvFwiIiIit7GrFxEREdUHOQBCKjKjlDIbwEkhxHgAEArbrluO5ssEkCmEGKa+NVH7TAgRBuATABcDiBRC3FSRshERERFVFgM/REREVOdJKdMAbFAHdX63AouYCOAedZDm/QDGujnfXQD+J4TYBUAY3v8QwP+klEcA3ANguhCiSQXKRURERFQpfJw7EREREREREVE9xYwfIiIiIiIiIqJ6ioM7ExERETkghHgBwHibt3+VUr7hifIQERERVQS7ehERERERERER1VPs6kVEREREREREVE8x8ENEREREREREVE8x8ENEREREREREVE8x8ENEREREREREVE/9P44ckr5e3L2eAAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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DjtM8+fP18SJE/Xwww/rlFNO0U033aRzzz1XaWlpuvTSS5WUlKQWLVpo0aJF+vbbb/Xmm2/q448/DquusNaqZ8+emjVrVsRrpaamSpISEhICt/33y9N7xRgTdj8pKUlerzfwWEFBQcRjo+0X6fm9+OKLat68uRYuXBjxXI0aNYp7zH5///vfddJJJ+mLL77Q+vXrNWTIkMA292uSmJhY5muSnJwceC3cr6n79fzPf/6jdu3aadGiRfJ6vUpLC28L1bBhQ5122mkaP368Pv74Y82bNy/qNUeMGKGhQ4dq4sSJGjhwoL799tu4n7ub/7Ur63sGAAAAAICKiqeh8qmSfrfWpltriyV9LmlAGcfUOVu3blXDhg119dVX67777tP8+fPVoUMHdejQQU888YSuv/56SdKuXbvk9Xp18cUX64knntD8+fMlSU2aNFF2drYk6fDDD1d6enrgjXpxcbGWLVtWoXEdfvjh2rZtm+bMmSNJys7ODgQWkydP1u7du5Wfn69x48Zp4MCBateunXbu3KmMjAwVFhbq66+/jnjeTp06aeHChfJ6vdq0aZN+/fXXqM+vadOm6ty5sz755BNJviBi0aJFFXo+fllZWTrwwAMl+fr/lKV///6aOnWqdu3aJY/HozFjxgSqYeK9Xvv27ZWQkKAPPvhAHo8n4n433XST/vKXv6hfv35q0aJF1POtW7dOvXr10v33369+/fpp5cqVOu200zRy5Ejl5eVJknbv3q1mzZqpRYsWmj59uiTpgw8+iDjuqvyeAQAAAADALZ6eOxslHW+MaSjftKxTJM2NfUjds2TJEt13331KSEhQcnKy3njjDUm+6T/p6ek64ogjJElbtmzR9ddfH6h6efrppyVJw4cP16233hpoqPzpp5/qL3/5i7KyslRSUqK77rpLPXvGP93s7LPP1n//+1916NBBY8eO1R133KH8/Hw1aNBAU6ZMkeQLPC6++GJt3rxZV199tfr27StJeuSRR9S/f38deOCB6t69e8TzDxw4UJ07d1aPHj10xBFH6Jhjjon5/EaPHq3bbrtNTzzxhIqLi3XFFVdE7UcTj7/97W+67rrr9MQTT2jo0KFl7t++fXs988wzOumkkwINlc8///y4r/enP/1JF198sd5//32deeaZUauNjj32WDVt2jQQ5kXz4osv6scff1RCQoJ69uyps846S6mpqVq4cKH69u2rlJQUnX322Xrqqaf03nvvBRoqd+nSRSNHjgw7X0pKSqW/ZwAAAAAAiMRYW/YMKmPM45Iul1QiaYGkm6y1hdH279u3rw1tZrtixYpAgFKX3H777Tr66KN144031vZQgoSudhXvMevXrw9bOQultm7dqiFDhmjlypVKSIincK3m1dWfFQAAAACoKtnZ0dtkRNLrye2SpCUPHVAdw6k3mjbtO89a2zf08bje3VprH7XWdrfWHmmtvSZWsFOfHHvssVq8eLGuvvrq2h4KasD777+v4447Tk8++WSdDXYAAAAAACiveJdC3yfFaqhb24YPHx5zNadI+vTpo06dOlXLeCRp5MiReumll4IeW7Nmjbp16xb02MCBA/Xaa69V2zgq6tprr9W1114b9Fik51RXxw8AAAAAQCT7dbizr+nTp0+1nv/6668vs1dNfbMvPicAAAAAwP6FuSkAAAAAAAD1GOEOAAAAAACoF+JZFGp/RLgDAAAAAADqBaKdyGqt505W1myVlGRW2fmSkpqrWbPjy9xv3LhxuvDCC7VixQp17969yq5fXo0bN1ZOTk61nHvUqFG677771LFjR+Xk5KhLly569NFHNWDAgJjHjRs3Tocddph69OhRLeMCAAAAAABVr9Yqd0pKMpWS0qbK/os3KBozZoxOPPFEjRkzpnqfYC27/PLLtWDBAq1Zs0YjRozQRRddpBUrVsQ8Zty4cVq+fHkNjRAAAAAAgPJhVlZk+9W0rJycHM2YMUPvvPOOPvroo8DjP/30k4YMGaJLLrlE3bt317BhwwLz+L7//nsdffTR6tWrl2644QYVFhZKkjp16qQHHnhAffr0Ud++fTV//nydccYZ6tq1q958883A9U455RQdc8wx6tWrl8aPHx82Jmut7rvvPh155JHq1auXxo4dGxjTOeecE9jv9ttv16hRoyRJI0aMUI8ePXTUUUfp3nvvLfN5n3TSSbrlllv01ltvSZLefvtt9evXT71799bFF1+svLw8zZw5U19++aXuu+8+9enTR+vWrYu4HwAAAAAAtYVsJ7L9KtwZP368zjzzTB122GFq1aqV5s2bF9i2YMECvfjii1q+fLl+++03/fzzzyooKNDw4cM1duxYLVmyRCUlJXrjjTcCxxx88MFauHChBg0apOHDh+vTTz/V7Nmz9eijj0qS0tLS9MUXX2j+/Pn68ccf9de//jWs+dPnn3+uhQsXatGiRZoyZYruu+8+bdu2LepzyMjI0BdffKFly5Zp8eLFevjhh+N67sccc4xWrlwpSbrooos0Z84cLVq0SEcccYTeeecdDRgwQOedd56ef/55LVy4UF27do24HwAAAAAAtYXKncj2q3BnzJgxuuKKKyRJV1xxRdDUrP79+6tjx45KSEhQnz59tH79eq1atUqdO3fWYYcdJkm67rrrNG3atMAx5513niSpV69eOu6449SkSRO1adNGqampyszMlLVWDz74oI466iideuqp2rJli3bs2BE0phkzZujKK69UYmKi2rVrp8GDB2vOnDlRn0OzZs2UlpamG2+8UZ9//rkaNmwY13N3h0pLly7VoEGD1KtXL40ePVrLli2LeEy8+wEAAAAAgNpTaw2Va9ru3bv1ww8/aMmSJTLGyOPxyBij559/XpKUmpoa2DcxMVElJSVlntN/TEJCQtDxCQkJKikp0ejRo5Wenq558+YpOTlZnTp1UkFBQVzjTUpKktfrDdz3H5eUlKRff/1V33//vT799FO9+uqr+uGHH8o834IFC3TEEUdIkoYPH65x48apd+/eGjVqlH766aeIx8S7HwAAAAAANYHKncj2m8qdTz/9VNdcc402bNig9evXa9OmTercubOmT58e9ZjDDz9c69ev19q1ayVJH3zwgQYPHhz3NbOystS2bVslJyfrxx9/1IYNG8L2GTRokMaOHSuPx6P09HRNmzZN/fv31yGHHKLly5ersLBQmZmZ+v777yX5+vhkZWXp7LPP1n/+8x8tWrSozHFMnTpVb731lm6++WZJUnZ2ttq3b6/i4mKNHj06sF+TJk2UnZ0duB9tPwAAAAAAUHfUWuVOUlJzFRWlV+n5YhkzZozuv//+oMcuvvhijRkzRpdffnnEY9LS0jRy5EhdeumlKikpUb9+/XTrrbfGPaZhw4bp3HPPVa9evdS3b9+IS69feOGFmjVrlnr37i1jjJ577jkdcMABkqTLLrtMRx55pDp37qyjjz5aki9wOf/881VQUCBrrV544YWI1x47dqxmzJihvLw8de7cWZ999lmgcuef//ynjjvuOLVp00bHHXdcINC54oordPPNN+vll1/Wp59+GnU/AAAAAABqA4U7kZnQBr9VoW/fvnbu3LlBj61YsSIQLgCI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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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PvjgDcb06U9/mptuuokBAwYAcOihh3LLLbfQv3//Ou9hxowZfOpTn+Ltt9/msssu49xzz61+/6dOncp3vvMd3n//fZ544gmuvPJKTjnllAa9N5IkSZIk5dNmA6GIGEOugPQOETEfuJpcEHRvRIwCXgdOzpo/BAwFXgHeA84uwJi3mj//+c/07NmTP/7xjwAsW7aMq6++msWLF9OtWzfuvPNOzjnnHKZPn86CBQuqA5elS5fSpUsXbr75Zn72s59RVVXF6tWrueiii5gwYQLdunVj7NixfOtb3+KOO+4AoE2bNkyePJkbb7yRYcOGMWXKFLbffnt23XVXvva1r9G1a9fqcX344YeccsopjB07lgMOOIB3332X9u1zU8+effZZXnjhBTp06MABBxzAMcccww477NCk96Gu+wM477zzuPXWW9ltt9145pln+MpXvsLDDz8MwPz583nyySdp2bLhSeWee+7J448/TqtWrfjrX//KN7/5Te6///7qMUybNo22bduyxx57cNFFF9GyZUsuv/xypkyZwnbbbcdRRx3F+PHjOf7441m5ciWf+cxnuO666zjhhBO46qqrmDhxIrNmzWLEiBEcd9xxfOxjH2PixIm0a9eOOXPmcNpppzF58uQNxjRq1ChGjx7NDTfcwD/+8Q9WrVpVbxgE8Pzzz/P000+zcuVKBg4cyDHHHFN9rE2bNnz/+9/fIHSTJEmSJKkYGvKUsdPqOXRkHW0TcEFTB1Xb5mbyFEq/fv34xje+weWXX86xxx7LYYcdxplnnslvf/tbzj77bJ566inuvvtuli9fzmuvvcZFF13EMcccw1FHHbVRXy+//DIvvPACQ4YMAWDt2rX06NGj+vhxxx1Xfc299967+tguu+zCvHnzNgiEXn75ZXr06MEBBxwAQOfOH62bHDJkSHXbE088kSeeeILjjz++Se/DLrvsstH9rVixgieffJLhw4dXt/vggw+qXw8fPnyLwiDIBW4jRoxgzpw5RASrV6+uPnbkkUey7bbbAtC3b19ef/11lixZwuDBg+nWLbfW8vTTT+exxx7j+OOPp02bNhx99NFA7j1t27YtrVu3pl+/fsydOxeA1atXc+GFFzJ9+nRatmzJP/7xj43GNHz4cH7wgx9w3XXXcccddzBy5MhN3sOwYcNo37497du354gjjuDZZ5+tnl0kSZIkSWqcci08XKhxp1p/NkZlF3fZjN13352pU6fy0EMPcdVVV3HkkUfy5S9/mS984Qu0a9eO4cOH06pVK7bbbjtmzJjBX/7yF2699Vbuvffe6pk/66WU2HvvvXnqqafqvFbbtm0BaNGiRfXr9dtr1qxp8Jij1qPqIoJWrVqxbt1H6w1Xraq7Cnl97eq6vxtuuIEuXbowffr0OvvaZpttGjzm9b797W9zxBFH8MADDzB37lwGDx5cfazme9KyZcvNvietW7eufi9qvqc138+f//zndO/enRkzZrBu3TratWu3UT8dOnRgyJAhTJgwgXvvvZcpU6Zs8rp1vf+SJEmSJJWaFsUeQClbuHAhHTp04IwzzuDSSy9l6tSp9OzZk549e3LNNddw9tm5FXFvv/0269at46STTuKaa65h6tSpAHTq1Inly5cDsMcee7B48eLqQGj16tW8+OKLjRrXHnvswaJFi3juuecAWL58eXXIMXHiRN555x3ef/99xo8fzyGHHEL37t156623WLJkCR988AF/+MMf6uy3d+/eTJ8+nXXr1jFv3jyeffbZeu+vc+fO9OnTh/vuuw/IBV4zZsxo1P2st2zZMnbccUcgV89ocwYNGsTf/vY33n77bdauXcuYMWM4/PDDt+h6PXr0oEWLFvzmN79h7dq1dbb78pe/zMUXX8wBBxzAdtttt8k+J0yYwKpVq1iyZAmPPvpo9Syu9Wr+TkiSJEmSGqdcvnuPWn9ucGwL7qF2203121AGQpswc+ZMBg0axIABA/je977HVVddBeSWJu20007stddeACxYsIDBgwczYMAAzjjjDH70ox8BMHLkSM4//3wGDBjA2rVrGTduHJdffjn9+/dnwIABPPnkk1s0nqFDh7Jw4ULatGnD2LFjueiii+jfvz9Dhgypns0zaNAgTjrpJPbdd19OOukkqqqqaN26Nd/5zncYNGgQQ4YMYc8996yz/0MOOYQ+ffrQt29fLr74Yvbbb79N3t8999zD7bffTv/+/dl7772ZMGFCnf021GWXXcaVV17JwIEDGzQrqkePHvz4xz/miCOOoH///uy///4MGzaswdf7yle+wl133UX//v156aWX6p3VtP/++9O5c+fqAHBT9t13X4444ggOOuggvv3tb2/0hLkjjjiCWbNmMWDAAMaOHdvgsUqSJEmSlE+RK/tTXFVVVal2Md/Zs2dXBy6l5sILL2TgwIGMGjWq2EPZQO2nhDX0nLlz5270xDF9ZOHChQwePJiXXnqJFi0Km6GW8u+9JEmSJBXL3U/N5TsTPlplc0L/9nz/2G0Ldr1+174BwMxvfbxB++tzzZ+WMXbq+1w+pBNnDNpwEsLUeR8y4u53GtTfsvfXcej1b1W3vXfKe/zgz+8yfGB7vjO0/vehc+eqKSmlqrqOOUNoC+2///48//zznHHGGcUeiraCu+++mwMPPJBrr7224GGQJEmSJKluJTCXpVEKXVS6KSwqvYU2V1S4mEaOHLnZp2DVNmDAAHr37l2Q8QDceeed3HjjjRvsmzNnDrvtttsG+w455BBuueWWgo2jsc466yzOOuusDfbVdU+lOn5JkiRJao7KpIRQtbrqBRX7HgyEKlyhH4l+9tlnN6j2TjlpjvckSZIkScq/QoU++ejXNTCSJEmSJEkVxkBIkiRJkiSpwhgISZIkSZKkklYKT0hvDItK58GyZU+zZs3SvPXXqlUXtt32oM22Gz9+PCeccAKzZ89mzz33zNv1t1THjh1ZsWJFQfoePXo0l156Kb169WLFihXssssuXH311Rx88MGbPG/8+PHsvvvu9O3btyDjkiRJkiSpLnUVaS43xb6HspkhtGbNUtq06Za3n4aGS2PGjOHQQw9lzJgxhb3BIjvllFOYNm0ac+bM4YorruDEE09k9uzZmzxn/PjxzJo1ayuNUJIkSZKk8pKvzKd2eGRR6QJbsWIFTzzxBLfffju/+93vqvc/+uijDB48mC9+8YvsueeenH766dXT1yZNmsTAgQPp168f55xzDh988AEAvXv35sorr2TAgAFUVVUxdepUPve5z7Hrrrty6623Vl/vyCOPZL/99qNfv35MmDBhozGllLj00kvZZ5996NevH2PHjq0e07HHHlvd7sILL2T06NEAXHHFFfTt25d9992XSy65ZLP3fcQRR3Deeedx2223AfCrX/2KAw44gP79+3PSSSfx3nvv8eSTT/Lggw9y6aWXMmDAAF599dU620mSJEmSpNJjILQJEyZM4Oijj2b33Xena9euTJkypfrYtGnTuOGGG5g1axavvfYaf//731m1ahUjR45k7NixzJw5kzVr1vDLX/6y+pydd96Z6dOnc9hhhzFy5EjGjRvH008/zdVXXw1Au3bteOCBB5g6dSqPPPII3/jGNzZaJ/n73/+e6dOnM2PGDP76179y6aWXsmjRonrvYcmSJTzwwAO8+OKLPP/881x11VUNuvf99tuPl156CYATTzyR5557jhkzZrDXXntx++23c/DBB3Pcccdx3XXXMX36dHbdddc620mSJEmSpNJjILQJY8aM4dRTTwXg1FNP3WDZ2KBBg+jVqxctWrRgwIABzJ07l5dffpk+ffqw++67AzBixAgee+yx6nOOO+44APr168eBBx5Ip06d6NatG23btmXp0qWklPjmN7/Jvvvuy2c/+1kWLFjAm2++ucGYnnjiCU477TRatmxJ9+7dOfzww3nuuefqvYdtt92Wdu3aMWrUKH7/+9/ToUOHBt17zSDqhRde4LDDDqNfv37cc889vPjii3We09B2kiRJkiRtifIsKW1R6bL0zjvv8PDDDzNz5kwigrVr1xIRXHfddQC0bdu2um3Lli1Zs2bNZvtcf06LFi02OL9FixasWbOGe+65h8WLFzNlyhRat25N7969WbVqVYPG26pVK9atW1e9vf68Vq1a8eyzzzJp0iTGjRvHzTffzMMPP7zZ/qZNm8Zee+0FwMiRIxk/fjz9+/dn9OjRPProo3We09B2kiRJkiRVklKsge0MoXqMGzeOM888k9dff525c+cyb948+vTpw+OPP17vOXvssQdz587llVdeAeA3v/kNhx9+eIOvuWzZMj72sY/RunVrHnnkEV5//fWN2hx22GGMHTuWtWvXsnjxYh577DEGDRrEJz7xCWbNmsUHH3zA0qVLmTRpEpCrS7Rs2TKGDh3Kz3/+c2bMmLHZcfztb3/jtttu49xzzwVg+fLl9OjRg9WrV3PPPfdUt+vUqRPLly+v3q6vnSRJkiRJlShvRaUL0G/ZzBBq1aoLH364OK/9bcqYMWO4/PLLN9h30kknMWbMGE455ZQ6z2nXrh133nknw4cPZ82aNRxwwAGcf/75DR7T6aefzhe+8AX69etHVVVVnY+5P+GEE3jqqafo378/EcFPf/pTPv7xjwNw8skns88++9CnTx8GDhwI5EKaYcOGsWrVKlJKXH/99XVee+zYsTzxxBO899579OnTh/vvv796htAPfvADDjzwQLp168aBBx5YHQKdeuqpnHvuudx0002MGzeu3naSJEmSJKm0RO2ixcVQVVWVJk+evMG+2bNnVwcSUqXw916S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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABIEAAAEXCAYAAAA6MVQ4AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAC4FUlEQVR4nOzdd3gUVdsG8Pvsbhq9BaSoFOktQMCCCEgRRUVBbKCC7bXBa6OoKBawYUFfLJ+NiCKCqKCCIL1ITYDQOwFCDQnpbcv5/pid2dnd2ZZCErh/16Xs7szOnJ3Mzs4885znCCkliIiIiIiIiIjo4mYq6wYQEREREREREVHpYxCIiIiIiIiIiOgSwCAQEREREREREdElgEEgIiIiIiIiIqJLAINARERERERERESXAAaBiIiIiIiIiIguAQwCERERXUBCiNeFED/6mb5LCNGrFNbbSwiRHGCeWUKIO0p63ZcyIcQVQohsIYTZx/QIIcReIUT0hW7bxU4IESeEGFHW7SAiIipPGAQiIiICIIS4XwgR77xgPyWE+FsIcf2FboeUsq2UcuWFXq8QogOAjgDmO5+PEELYndsjUwiRKIS49QK3KVwI8aEQItnZjiQhxNQL2YZAPLZTthDisBDiSXW6lPKYlLKKlNLunH+lEOJR3fQCAN8BGH/hW2/M+ZnWlnU7iIiIqOQxCERERJc8IcTzAKYCeBtAPQBXAPgcwKAybNaF9h8AM6WUUvfaeillFQA1oGyPn4UQNS5gm14CEAugG4CqAHoB2FKSKxBCWEpgMeudgZ4qAIYAeF8I0SmE9/8E4CEhREQJtIXKkK+MLyIiovKCQSAiIrqkCSGqA3gTwNNSyt+klDlSSquU8k8p5RjnPBFCiKlCiJPO/6aqF+xqNyshxFghxFlnFtEdQohbhBD7hRBpQoiXPVYbKYSYLYTIEkJsEUJ01LUnSQjR1/n4dSHEHCHEDOe8u4QQsbp5GwghfhVCpAghjgghRuumRTm7w5wXQuwG0DXAprgZwCqjCVJKB4AfAFQG0Ny5/GZCiOVCiFQhxDkhxEw1QCSEGCmE+FPXlgNCiF90z48LIWICtAfONv8upTwpFUlSyhm65VwuhPjN+flThRDTnK+bhBAThBBHnX+TGc6/M4QQjYUQUgjxiBDiGIDlztcfFkLscW6vxUKIK4Non9G22gpgD4DWHuuzCCEmA+gBYJoza2ia8z3JAM4DuKYo6xRC1BFC/CWESHfub2uc22CMEOJXj3k/FUJ84nw8wpm5lOXcf4YJIVoD+BLAtc42pjvnjRBCfCCEOCaEOCOE+FIIEeWcVpTvgL5NtYQQ053frfNCiHkey33ZuY8lCSGG6d7nllUl/GQw6f8ORu8XQlwlhFglhMhwrmu2br5WQoglzs+xTwhxt25anBDiCyHEQiFEDoDeQfzJiIiIygyDQEREdKm7FkAkgN/9zPMKlAv0GChdproBmKCbfplzGQ0BvAbgawDDAXSBctH/qhCiiW7+QQB+AVALShbIPCFEmI913w7gZyjZOH8A0AIdAP4EkOhcbx8AzwohbnK+byKAZs7/bgLwkK8PJ4SoDKAJgH0+ppsBjARgBXBUfRnAOwAaQAl4XA7gdee0VQB6OAMRDQCEQ9nOEEI0BVAFwHZf7dHZAOB5IcRTQoj2Qgjh0aa/nO1p7NwGPzsnj3D+1xuAur5pHsvu6Wz3TUKIQQBeBjAYQDSANQBmBdE+L0KIrgBaAIj3nCalfMW57GecmUPP6CbvgbJvFcULAJKhtL0elM8iAfwIYIAuOGcBcC+AGc6/+acAbpZSVgVwHYBtUso9AJ6AK7uphnMd7zo/VwyAq+Da11Whfgf0fgBQCUBbAHUBfOyx3DrO5T4E4CshRMuQtk5w3gLwD4CaABoB+B+gfTeWQPme1oWy/T4XQrTRvfd+AJOhZKuxGx0REZVrDAIREdGlrjaAc1JKm595hgF4U0p5VkqZAuANAA/oplsBTJZSWqEEIuoA+ERKmSWl3AVgN9wv8BOklHOd838E5eLZVxbIWinlQmdNmR90y+kKIFpK+aaUslBKeRjKhfe9zul3O9uUJqU8DuWC35cazn+zPF6/xpkJkg/gAwDDpZRnAUBKeVBKuURKWeDcJh9BCazA2ZYsKAGDGwAsBnBSCNHKOc8aZ3ZRIO8AeA/K9o8HcEIIoQazukEJQI1xZm/lSynVC/BhAD6SUh6WUmZD6VZ2r3Dv+vW68315UIIe70gp9zj3g7cBxISQDXSNMwsnC8AmKH+nA0G+V5UF198hVFYA9QFc6cxiW+PMnDoFYDWAoc75BkDZ1xOczx0A2gkhoqSUp5z7qhdn8O1xAM8596csKNvoXt1soX4H1GXXh5KF9oSU8ryz/Z4Zaa8697NVABZA2bdLmhXAlQAaeOxLtwJIklJOl1LanJlev8K1TQFgvpTyXymlQ0qZXwptIyIiKjEMAhER0aUuFUAd4b82TAO4MmDgfNxAvwy18C+APOe/Z3TT86Bko6iOqw+cwZBkj+XpndY9zoXSlcwC5wWrM/iQ7gzWvAwlE0Rt83Hde/Xt95Tu/Leqx+sbnJkgNaFkIfVQJwgh6gkhfhZCnBBCZELJOqmje+8qKDV8bnA+XgklANQTPrqdeZJS2qWUn0kpu0MJkEwG8J2zy9LlAI76CN4Z/b0scG0bwH3bXAngE912TIOS6dQwmHbCuZ2cGTWXQcloeTvI96qqwvV3cCNcRaezhRBXGMwyBcBBAP84u3fpi0x/DyUjB85/fwAAKWUOgHugBMBOCSEWOIN0RqKhZOok6LbRIufrqlC/A6rLAaRJKc/7WPd5Z1tVnt+9kjIWyt98k1C6XT7sfP1KAFd7fM+GQfk7q46DiIiogmAQiIiILnXrARQAuMPPPCehXAyqrnC+VlSXqw+c3boaFWF5xwEccQYf1P+qSilvcU4/pV+Ps82GnBfZh6B09zGang3gSQAPCFfB47ehdDlqL6WsBiXAIHRvU4NAPZyPVyHEIJBHG/KklJ9BqZ3TBsrnv8JH8M7o72WDe1BCXwD7OID/eGzLKCnluiK08wyUTJHbfM3i4/XWULr2GS2ziu6/YwbTs6SUL0gpm0LpPvi8EKKPc/I8AB2EEO2gZLXM1L1vsZSyH5Qsor1QMsmM2ngOShCnrW77VJdKIeziOg6glvBdcLyms0uWSv/dy4ESnFLpAzOe1ECS4fxSytNSyseklA2gFEn/XAhxlbN9qzz2jSpSyid1y/H1NyUiIip3GAQiIqJLmpQyA0oNk8+cxWwrCSHChBA3CyHed842C8AEIUS0EKKOc/4fi7HaLkKIwc4AxrNQglAbQlzGJgBZQohxQikCbRZCtHPWpAGAOQBeEkLUFEI0AjAqwPIWwtmdy4iUMg3AN3DVgakKIBtAhhCiIYAxHm9ZBaUmT5Sz8PEaKN2RagPYqs7kLM77utE6hRDPOosDRwmlsPJDzvVudX7+UwDeFUJUFkJECiG6O986C8BzQogmQogqUAJWs/10+fsSyrZq61xvdSGE1t3HXxsN2lwbwJ0ADLtWQQlENfV4T0Mo9aFC3QfU99/qLGwsAGQAsEPp6gVn96S5UGrabFKDSM5MrkHOAEsBlL+l2kXvDIBGQohw5zIcUAJEHwsh6qpt1tWfKjJnl7W/oQRdajq/ezd4zPaGECJcCNEDSiBLLTK+DcBg53f2KgCP+FlPCoATAIY7vysPQ6mXBefnGer8ngBKoFFC2R5/AWghhHjA2bYwIURXZzYaERFRhcMgEBERXfKklB8CeB5KsecUKHf/n4GSRQEAk6DUpNkOYAeUYconFWOV86F0xTkPpbbQYGctlVDabIdyQRwD4AiUbI1vAFR3zvIGlK4zR6AUvP0hwCK/AjDMGUjwZSqAW4QQHZzL7wwl6LAAwG8e7dsPJbCwxvk8E8BhAP/qug0BSrbSvz7WlwvgQyhd4s4BeBrAEGetHzuUbJurAByD0qXuHuf7vnN+3tVQPn8+/ATBpJS/Q6k99LOza9tOKHVqgmkj4BpJKxtKgecUP+v7BMBdQhkFS63TdD+A76WUBX7W4U9zAEuhbO/1AD6XUq7QTf8eQHu47wMmKPv8SSjd33pCyfYClBHTdgE4LYQ453xtHJQuZxuc22gpgCIVaBbKKGT6INkDUGry7AVwFkpgVHUayvfkJJQspieklHud0z4GUAglaPU9dFlOPjwGJViZCqXLnj7TqyuAjc6/4R8A/uvcz7IA9IdS/+iksz3vAYgI4SMTERGVG0JKZrASERERIIT4CcAcKeW8C7S+Rs71XXch1lcUpd1GIUQElG5gN6hFt0thHVdACbBc5gzGVQhCiF4AfpRSNgowq6/3xwFYKaWMK7lWERERVWz+imASERHRJURKef8FXl8ylKHJy63SbqMz+8dXQeZic9aceh7AzxUpAERERESlg0EgIiIioouQs97PGSjdAgeUcXPKwjwASWXcBiIionKF3cGIiIiIiIiIiC4BLAxNRERERERERHQJKLPuYHXq1JGNGzcuq9UTERERERERUTnncOSWdRMqnK1b95yTUkYbTSuzIFDjxo0RHx9fVqsnIiIiIiIionIuKyuhrJtQ4VSrFnvU1zR2ByMiIiIiIiIiugQwCEREREREREREdAlgEIiIiIiIiIiI6BJQZjWBjFitViQnJyM/P7+sm0JUbkVGRqJRo0YICwsr66YQERERERFRBVKugkDJycmoWrUqGjduDCFEWTeHqNyRUiI1NRXJyclo0qRJWTeHiIiIiIiIKpCA3cGEEN8JIc4KIXb6mC6EEJ8KIQ4KIbYLIToXtTH5+fmoXbs2A0BEPgghULt2bWbLERERERERUciCqQkUB2CAn+k3A2ju/O9xAF8Up0EMABH5x+8IERERERERFUXA7mBSytVCiMZ+ZhkEYIaUUgLYIISoIYSoL6U8VVKNJCIiIiIiIqJLS3ZhNv44sgp59nzsOZ+E9rWu8jv/uWwrKmUmo1KDopXOOJ17DhHmcNSMqOb2+tm8NJiECXUiawS9rOScM2hUuZ7htExrDipbomAWgfNyjmafQp3IGqhsiQIA7Dl/GK1rNgFQtOSAkqgJ1BDAcd3zZOdrXkEgIcTjULKFcMUVV5TAqomIiIiIiIjoYrQ4aTHe3Tpde/7P8fXBvTFlbSm1qHxYeOzfIr/3ghaGllJ+BeArAIiNjZUXct0XSlxcHPr3748GDRqUdVN8iouLQ1JSEl5//fWybgoRERERERGRIavD6va8V4NYvBjzoM/5Z037Fo+ZF6AwdigKu94X8vpuXTgaAPDXLZ8G9bovn+2cjb+P/YvHWt+JQU16u03blXYI4zZ8EtTyMq3ZuH/Jy9q8C46uwRe7fkH/y6/B6Pb3+3xfY9zoc1pJBIFOALhc97yR87VLUlxcHNq1a1eug0ClzWazwWIpVwPPERERERERUQVXOSwKtSKr+ZxutkWhtnCgAGYU+pkvEF/r8LduvUhzBACgUlik13uqhlcKenn67mK1IquhSpjSJaySxXu5wSqJK/U/ADwjhPgZwNUAMkqiHtAbf+7C7pOZxW6cXpsG1TDxtrZ+58nJycHdd9+N5ORk2O12vPrqq5g1axbmzZsHAFiyZAk+//xzzJ07F4888gji4+MhhMDDDz+Myy+/HPHx8Rg2bBiioqKwfv167N69G88//zyys7NRp04dxMXFoX79+ujVqxc6deqENWvWICcnBzNmzMA777yDHTt24J577sGkSZO82rZ582b897//RU5ODiIiIrBs2TL8+uuv+P3335GRkYETJ05g+PDhmDhxIpKSknDrrbdi505lULcPPvgA2dnZXtk/cXFxiI+Px7Rp0wAAt956K1588UX06NHD6/M999xzOHToEJ5++mmkpKSgUqVK+Prrr9GqVSuMGDECkZGR2Lp1K7p3746PPvqo+H8wIiIiIiIioiA51LGvpKNsG1KOBQwCCSFmAegFoI4QIhnARABhACCl/BLAQgC3ADgIIBfAyNJq7IWwaNEiNGjQAAsWLAAAZGRkYOLEiUhJSUF0dDSmT5+Ohx9+GNu2bcOJEye0IEt6ejpq1KiBadOm4YMPPkBsbCysVitGjRqF+fPnIzo6GrNnz8Yrr7yC7777DgAQHh6O+Ph4fPLJJxg0aBASEhJQq1YtNGvWDM899xxq166ttauwsBD33HMPZs+eja5duyIzMxNRUUoUcNOmTdi5cycqVaqErl27YuDAgahTp06xtoPR5wOAxx9/HF9++SWaN2+OjRs34qmnnsLy5csBAMnJyVi3bh3MZnOx1k1EREREREQUKruzWLJw2Mu4JeVXMKOD+e1I5xwV7OkSa5FToIyd0tK+fXu88MILGDduHG699Vb06NEDDzzwAH788UeMHDkS69evx4wZM5CVlYXDhw9j1KhRGDhwIPr37++1rH379mHnzp3o168fAMBut6N+/fra9Ntvv11bZ9u2bbVpTZs2xfHjx92CQPv27UP9+vXRtWtXAEC1aq7Ur379+mnzDh48GGvXrsUdd9xRrO3QtGlTr8+XnZ2NdevWYejQodp8BQUF2uOhQ4cyAEREREREREQlQiK0UsL2cpMJVDolkNWlymIsnoVbPLRo0QJbtmzBwoULMWHCBPTp0wePPvoobrvtNkRGRmLo0KGwWCyoWbMmEhMTsXjxYnz55ZeYM2eOluGjklKibdu2WL/euIJ5RITST9BkMmmP1ec2my3oNgshvJ5bLBY4HK4dPz8/3/C9vuYz+nxTp05FjRo1sG3bNsNlVa5cOeg2ExEREREREZUkdgcLLPCg9JeYkydPolKlShg+fDjGjBmDLVu2oEGDBmjQoAEmTZqEkSOV3m7nzp2Dw+HAkCFDMGnSJGzZsgUAULVqVWRlZQEAWrZsiZSUFC0IZLVasWvXriK1q2XLljh16hQ2b94MAMjKytICRUuWLEFaWhry8vIwb948dO/eHfXq1cPZs2eRmpqKgoIC/PXXX4bLbdy4MbZt2waHw4Hjx49j06ZNPj9ftWrV0KRJE/zyyy8AlCBXYmJikT4PERERERERUShEgOlaJpCjrINAwuNf/ZRAn0I3r8eswsfroWAmkIcdO3ZgzJgxMJlMCAsLwxdffAEAGDZsGFJSUtC6dWsAwIkTJzBy5Egti+add94BAIwYMQJPPPGEVhh67ty5GD16NDIyMmCz2fDss8+ibdvgu7rdcsst+Oabb9CgQQPMnj0bo0aNQl5eHqKiorB06VIAQLdu3TBkyBAkJydj+PDhiI2NBQC89tpr6NatGxo2bIhWrVoZLr979+5o0qQJ2rRpg9atW6Nz585+P9/MmTPx5JNPYtKkSbBarbj33nvRsWPHkLYxERERERERUUljJlBgDAJ5uOmmm3DTTTd5vb527Vo89thj2vOOHTtq2T96Q4YMwZAhQ7TnMTExWL16tdd8K1eu1B736tULvXr1Mpy2cOFC7XHXrl2xYcMGr2U1atRIG71Mb/To0Rg9erTX63pCCMycOdNwmtHna9KkCRYtWuT1elxcnN/1EBEREREREZUmV00gFob2hUGgIHTp0gWVK1fGhx9+WNZNISIiIiIiIrokyBArINugDFRU9qODlW5h6OJgECgICQkJZd0En0aMGIERI0aE9J6YmBg0bty4VNpDREREREREVBpCqadTHhi113NgpwuNQaBLUExMTFk3gYiIiIiIiOgiVVKBHuHnWdFwdDAiIiIiIiIiuohUrIyhC4lBICIiIiIiIiKq8EQp1eK5mDAIRERERERERETljgwxqFN+8n/Kb2FoBoGIiIiIiIiIqPwLEOUpb5lARjWgyzpQxSBQCYuLi8PJkyfLuhl+xcXF4fXXXy/rZpQrSUlJaNeuXVk3g4iIiIiIiIpIDQLJMh6Bq6RCPZ5LKYmllt/Rwf4eD5zeUbLLvKw9cPO7JbtMD3FxcWjXrh0aNGhQquspz2w2GyyW8rtrlWfcdkREREREREVT1qGfioCZQB5ycnIwcOBAdOzYEe3atcPs2bNxxx13aNOXLFmCO++8E3a7HSNGjEC7du3Qvn17fPzxx5g7dy7i4+MxbNgwxMTEIC8vDwkJCejZsye6dOmCm266CadOnQIA9OrVC8899xxiY2PRunVrbN68GYMHD0bz5s0xYcIEw7Zt3rwZ1113HTp27Ihu3bohKysLcXFxGDRoEHr16oXmzZvjjTfeAOCd2fLBBx8YZv/ExcXhmWee0Z7feuutWLlypeHnA4BDhw5hwIAB6NKlC3r06IG9e/cCAEaMGIEnnngCV199NcaOHRv09t60aROuvfZadOrUCddddx327duntWvw4MEYMGAAmjdv7rbMWbNmoX379mjXrh3GjRunvV6lShWMGTMGbdu2Rd++fbFp0yb06tULTZs2xR9//KFtlx49eqBz587o3Lkz1q1b59WmG264Adu2bdOeX3/99UhMTDRs/6pVqxATE4OYmBh06tQJWVlZAID33nsP7du3R8eOHTF+/HgAwLZt23DNNdegQ4cOuPPOO3H+/HkAyr7w7LPPIjY2Fp988onPfYaIiIiIiIh8K2/dwcqj8ptyUMoZO74sWrQIDRo0wIIFCwAAGRkZmDhxIlJSUhAdHY3p06fj4YcfxrZt23DixAns3LkTAJCeno4aNWpg2rRp+OCDDxAbGwur1YpRo0Zh/vz5iI6OxuzZs/HKK6/gu+++AwCEh4cjPj4en3zyCQYNGoSEhATUqlULzZo1w3PPPYfatWtr7SosLMQ999yD2bNno2vXrsjMzERUVBQAJZCyc+dOVKpUCV27dsXAgQNRp06dYm0Ho88HAI8//ji+/PJLNG/eHBs3bsRTTz2F5cuXAwCSk5Oxbt06mM3moNfTqlUrrFmzBhaLBUuXLsXLL7+MX3/9VWvD1q1bERERgZYtW2LUqFEwm80YN24cEhISULNmTfTv3x/z5s3DHXfcgZycHNx4442YMmUK7rzzTkyYMAFLlizB7t278dBDD+H2229H3bp1sWTJEkRGRuLAgQO47777EB8f79amRx55BHFxcZg6dSr279+P/Px8dOzY0bD9H3zwAT777DN0794d2dnZiIyMxN9//4358+dj48aNqFSpEtLS0gAADz74IP73v/+hZ8+eeO211/DGG29g6tSpAJS/b3x8PKxWK3r27OlznyEiIiIiIiJj5ScIVH4LQ5ffIFAZad++PV544QWMGzcOt956K3r06IEHHngAP/74I0aOHIn169djxowZyMrKwuHDhzFq1CgMHDgQ/fv391rWvn37sHPnTvTr1w8AYLfbUb9+fW367bffrq2zbdu22rSmTZvi+PHjbkGgffv2oX79+ujatSsAoFq1atq0fv36afMOHjwYa9eudcteKoqmTZt6fb7s7GysW7cOQ4cO1eYrKCjQHg8dOjSkABCgBNkeeughHDhwAEIIWK1WbVqfPn1QvXp1AECbNm1w9OhRpKamolevXoiOjgYADBs2DKtXr8Ydd9yB8PBwDBgwAICyTSMiIhAWFob27dsjKSkJAGC1WvHMM89g27ZtMJvN2L9/v1ebhg4dirfeegtTpkzBd999hxEjRvhsf/fu3fH8889j2LBhGDx4MBo1aoSlS5di5MiRqFSpEgCgVq1ayMjIQHp6Onr27AkAeOihh9y24z333AMg8D5DRERERER0qRIBOny5gkCl0zHs30MF6NAwDFUjg+tUZdzesu20xiCQhxYtWmDLli1YuHAhJkyYgD59+uDRRx/FbbfdhsjISAwdOhQWiwU1a9ZEYmIiFi9ejC+//BJz5szxytaQUqJt27ZYv3694boiIiIAACaTSXusPrfZbEG3WXgUvRJCwGKxwOFwaK/l5+cbvtfXfEafb+rUqahRo4ZbVym9ypUrB91m1auvvorevXvj999/R1JSEnr16qVN028Ts9kccJuEhYVp20K/TfXb8+OPP0a9evWQmJgIh8OByMhIr+VUqlQJ/fr1w/z58zFnzhwkJCT4XOf48eMxcOBALFy4EN27d8fixYuD/ux66rYLtM8QERERERGRsdLOBHri5/O4vlk4vri3VsCWlASva32DeT5ZkYXv1ucg8eXLglomawJ5OHnyJCpVqoThw4djzJgx2LJlCxo0aIAGDRpg0qRJGDlyJADg3LlzcDgcGDJkCCZNmoQtW7YAAKpWrarVhWnZsiVSUlK0C3qr1Ypdu3YVqV0tW7bEqVOnsHnzZgBAVlaWFthYsmQJ0tLSkJeXh3nz5qF79+6oV68ezp49i9TUVBQUFOCvv/4yXG7jxo2xbds2OBwOHD9+HJs2bfL5+apVq4YmTZrgl19+AaAELHzVyglWRkYGGjZsCECpAxRIt27dsGrVKpw7dw52ux2zZs3SsmuCXV/9+vVhMpnwww8/wG63G8736KOPYvTo0ejatStq1qzpc3mHDh1C+/btMW7cOHTt2hV79+5Fv379MH36dOTm5gIA0tLSUL16ddSsWRNr1qwBAPzwww+G7S7JfYaIiIiIiOhSIrwelLykVONryLLyzbocOEKIfTETyMOOHTswZswYmEwmhIWF4YsvvgCgdDtKSUlB69atAQAnTpzAyJEjtSyad955B4CrQHJUVBTWr1+PuXPnYvTo0cjIyIDNZsOzzz6Ltm3bBt2eW265Bd988w0aNGiA2bNnY9SoUcjLy0NUVBSWLl0KQAmMDBkyBMnJyRg+fDhiY2MBAK+99hq6deuGhg0bolWrVobL7969O5o0aYI2bdqgdevW6Ny5s9/PN3PmTDz55JOYNGkSrFYr7r33Xp/1coIxduxYPPTQQ5g0aRIGDhwYcP769evj3XffRe/evSGlxMCBAzFo0KCg1/fUU09hyJAhmDFjBgYMGOAze6lLly6oVq2aFvTzZerUqVixYgVMJhPatm2Lm2++GREREdi2bRtiY2MRHh6OW265BW+//Ta+//57PPHEE8jNzUXTpk0xffp0r+WFh4cXe58hIiIiIiK6GEgZWmZP+akJVH6JUDdqSYmNjZWeBXn37NmjBVnKm2eeeQadOnXCI488UtZNcRMXF4f4+HhMmzYtpPckJSUZjhZGipMnT6JXr17Yu3cvTKbylzBXnr8rREREREREJeHH3T/ivc3vac9vb9wT4zv7vlEf/kF/RAgbCtvfgoL+L4a8vut+GwEAWDc4zvD1rD3volENM/5+OtrvcqZs/R6/H1mB5zsOx13N+rpN25F6EP9ZNclwPZ6yrbno/+dT2ry/HV6OD7bNwB1NemFsJ6VN7SefVpb7iqs7WLVqsQlSylijZZa/q9tyqEuXLti+fTuGDx9e1k2hC2DGjBm4+uqrMXny5HIZACIiIiIiIroUBSoMHSGCr617IRiWhS7butDsDhYMf4WBy9qIESP8jl5lJCYmBo0bNy6V9gDA9OnT8cknn7i9duDAATRv3tztte7du+Ozzz4rtXYU1YMPPogHH3zQ7TWjz1Re209ERERERERlqYQKQyNwYehQMQh0CYqJiSnV5Y8cOTJgLZ2K5mL8TERERERERBen0ku3KetMnuJiXxciIiIiIiIiKndkhS30XDrtLomlMghEREREREREROVe0Fk4FT1dpxQxCEREREREREREVOK8g1GBiluXNgaBiIiIiIiIiIhKTOkEekpiqQwClbC4uDicPHmyrJvhV1xcHF5//fWybka5kpSUhHbt2oX8vtdffx0ffPCB1+snT57EXXfdBQDYtm0bFi5cWOw2EhERERERERVHuR0d7L1N72Fv2t4SXWarWq0wrtu4El2mp7i4OLRr1w4NGjQo1fWUZzabDRZLud21LogGDRpg7ty5AJQgUHx8PG655ZYybhUREREREVHFIWURSyFLR8k2RCe4bBwWhq4wcnJyMHDgQHTs2BHt2rXD7Nmzcccdd2jTlyxZgjvvvBN2ux0jRoxAu3bt0L59e3z88ceYO3cu4uPjMWzYMMTExCAvLw8JCQno2bMnunTpgptu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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "figsize = (20,4)\n", + "\n", + "for dim in models:\n", + "\n", + " # create a dim with the raw data, anomaly score and anomaly bit for the dim\n", + " df_final_dim = df_final[[dim,f'{dim}__anomaly_score',f'{dim}__anomaly_bit']]\n", + " \n", + " # plot raw data, including the anomalous data\n", + " ax = df_final_dim[[dim]].set_index(pd.to_datetime(df_final_dim.index, unit='s')).plot(\n", + " title=f'Raw Data (Anomalous Appended) - {dim}', figsize=figsize\n", + " )\n", + " add_shading_to_plot(ax, df_timestamp_max - n_tail_anomalous, df_timestamp_max, 'Anomalous Data')\n", + " \n", + " # plat the corresponding anomaly scores\n", + " ax = df_final_dim[[f'{dim}__anomaly_score']].set_index(pd.to_datetime(df_final_dim.index, unit='s')).plot(\n", + " title=f'Anomaly Score - {dim}', figsize=figsize\n", + " )\n", + " add_shading_to_plot(ax, df_timestamp_max - n_tail_anomalous, df_timestamp_max, 'Anomalous Data')\n", + " \n", + " # plot the corresponding anomaly bits\n", + " ax = df_final_dim[[f'{dim}__anomaly_bit']].set_index(pd.to_datetime(df_final_dim.index, unit='s')).plot(\n", + " title=f'Anomaly Bit - {dim}', figsize=figsize\n", + " )\n", + " add_shading_to_plot(ax, df_timestamp_max - n_tail_anomalous, df_timestamp_max, 'Anomalous Data')\n", + "\n", + " # finally, plot it all on the same plot (which might not be so easy or clear to read)\n", + " df_final_dim_normalized = (df_final_dim-df_final_dim.min())/(df_final_dim.max()-df_final_dim.min())\n", + " ax = df_final_dim_normalized.set_index(pd.to_datetime(df_final_dim_normalized.index, unit='s')).plot(\n", + " title=f'Combined (Raw, Score, Bit) - {dim}', figsize=figsize\n", + " )\n", + " add_shading_to_plot(ax, df_timestamp_max - n_tail_anomalous, df_timestamp_max, 'Anomalous Data')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The last concept to introduce now is the \"[anomaly rate](https://github.com/netdata/netdata/blob/master/ml/README.md#anomaly-rate)\" which is really just an average over \"anomaly bits\".\n", + "\n", + "For example, in the next cell we will just average all the anomaly bits across the light yellow window of time to find the anomaly rate for the metric within this window. " + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "n_tail_anomalous_anomaly_rate = 96.6%\n", + "\n", + "This means the \"anomaly rate\" within the yellow period of anomalous data was 96.6%\n", + "\n", + "Another way to think of this is that 96.6% of the observations during the yellow \n", + "window were considered anomalous based on the latest trained model.\n" + ] + } + ], + "source": [ + "# average the anomaly bits within the n_tail_anomalous period of the data\n", + "n_tail_anomalous_anomaly_rate = df_final_dim[[f'{dim}__anomaly_bit']].tail(n_tail_anomalous).mean()[0]\n", + "\n", + "print(f'n_tail_anomalous_anomaly_rate = {n_tail_anomalous_anomaly_rate}%')\n", + "print(f'\\nThis means the \"anomaly rate\" within the yellow period of anomalous data was {n_tail_anomalous_anomaly_rate}%')\n", + "print(f'\\nAnother way to think of this is that {n_tail_anomalous_anomaly_rate}% of the observations during the yellow \\nwindow were considered anomalous based on the latest trained model.')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 5. So, how does it _actually_ work?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this final section of the notebook below we will dig in to try understand this a bit more intuitivley.\n", + "\n", + "First we will \"[featureize](https://brilliant.org/wiki/feature-vector/)\" or \"preprocess\" all the data. Then we will explore what these feature vectors actually are, how they look, and how we derive anomaly scores based on thier distance to the models cluster centroids." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# preprocess/featurize all data\n", + "df_preprocessed = preprocess_df(\n", + " df,\n", + " num_samples_to_lag,\n", + " num_samples_to_diff,\n", + " num_samples_to_smooth\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that we have preprocessed all of our data, lets just take a look at it.\n", + "\n", + "You will see that we have essentially just added `num_samples_to_lag` additional columns to the dataframe, one for each lag. The numbers themselve also are now longer the original raw metric values, instead they have first been differenced (just take difference of latest value with pervious value so that we are working with delta's as opposed to original raw metric) and also smoothed (in this case by just averaging the previous `num_samples_to_smooth` previous differenced values).\n", + "\n", + "The idea here is to define the representation that the model will work in. In this case the model will decide if a recent observation is anomalous based on it's corresponding feature vector which is a differenced, smoothed, and lagged array or list of recent values." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(7192, 6)\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
system.cpu|user_lag0system.cpu|user_lag1system.cpu|user_lag2system.cpu|user_lag3system.cpu|user_lag4system.cpu|user_lag5
time_idx
16479834453.330669e-160.1672930.4995610.1675040.0006330.253165
16479806135.967300e-030.0004220.1666650.3358480.0839630.083542
16479843832.531518e-010.0833270.0018990.2518860.0839630.082700
16479844471.696266e-010.0835420.0814590.0820740.0822800.168344
16479832705.101800e-030.0824980.0827030.0042620.1740510.001050
\n", + "
" + ], + "text/plain": [ + " system.cpu|user_lag0 system.cpu|user_lag1 system.cpu|user_lag2 \\\n", + "time_idx \n", + "1647983445 3.330669e-16 0.167293 0.499561 \n", + "1647980613 5.967300e-03 0.000422 0.166665 \n", + "1647984383 2.531518e-01 0.083327 0.001899 \n", + "1647984447 1.696266e-01 0.083542 0.081459 \n", + "1647983270 5.101800e-03 0.082498 0.082703 \n", + "\n", + " system.cpu|user_lag3 system.cpu|user_lag4 system.cpu|user_lag5 \n", + "time_idx \n", + "1647983445 0.167504 0.000633 0.253165 \n", + "1647980613 0.335848 0.083963 0.083542 \n", + "1647984383 0.251886 0.083963 0.082700 \n", + "1647984447 0.082074 0.082280 0.168344 \n", + "1647983270 0.004262 0.174051 0.001050 " + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(df_preprocessed.shape)\n", + "df_preprocessed.sample(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The model works based on these feature vectors. A lot of ML is about training a model to define some [\"compressed representation\"](https://en.wikipedia.org/wiki/Data_compression#Machine_learning) of the training data that can then be useful for new data in some way.\n", + "\n", + "This is exactly what our cluster models are trying to do. They process a big bag of preprocessed feature vectors, covering `num_samples_to_train` raw observations, during training to come up with the best, synthetic, `n_clusters_per_dimension` feature vectors as a useful compressed representation of the training data.\n", + "\n", + "The cell below will just show you what those `n_clusters_per_dimension` (in this case 2) synthetic (made up by the kemans algo) feature vectors are." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
system.cpu|user_lag0system.cpu|user_lag1system.cpu|user_lag2system.cpu|user_lag3system.cpu|user_lag4system.cpu|user_lag5
centroid 00.1826260.1695060.1004840.1787780.1778430.100711
centroid 10.1155320.1410290.2766270.1226110.1244480.276112
\n", + "
" + ], + "text/plain": [ + " system.cpu|user_lag0 system.cpu|user_lag1 system.cpu|user_lag2 \\\n", + "centroid 0 0.182626 0.169506 0.100484 \n", + "centroid 1 0.115532 0.141029 0.276627 \n", + "\n", + " system.cpu|user_lag3 system.cpu|user_lag4 system.cpu|user_lag5 \n", + "centroid 0 0.178778 0.177843 0.100711 \n", + "centroid 1 0.122611 0.124448 0.276112 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# lets pick the first model to look at\n", + "model = list(models.keys())[0]\n", + "\n", + "# get the cluster centroids and put them in a dataframe similar to above\n", + "df_cluster_centers = pd.DataFrame(models[model]['model'].cluster_centers_, columns=df_preprocessed.columns)\n", + "df_cluster_centers.index = [f'centroid {i}' for i in df_cluster_centers.index.values]\n", + "display(df_cluster_centers)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "At inference time we can now use our `n_clusters_per_dimension` cluster centers as a sort of set of \"reference\" feature vectors we can compare against. \n", + "\n", + "When we see a new feature vector that is very far away from these \"reference\" feature vectors, we can take that as a signal that the recent data the feature vecotr was derived from may look significantly different than most of the data the clusters where initially train on. And as such it may be \"anomalous\" or \"strange\" in some way that might be meaningful to you are a user trying to monitor and troubleshoot systems based on these metrics.\n", + "\n", + "To try make this visually clearer we will take 10 random feature vectors from the first half of our data where things were generally normal and we will also take 10 random feature vectors from the yellow anomalous period of time. Lastly we will also include the cluster centroids themselves to see how they compare to both sets of 10 feature vectors. \n", + "\n", + "Basically this is represented in the heatmap below where each row is a processed feature vectors corresponding to some timestamp `t`." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# prepare heatmap\n", + "df_heatmap = pd.concat([df_preprocessed.sample(10),df_preprocessed.tail(n_tail_anomalous).sample(10), df_cluster_centers])\n", + "df_heatmap = df_heatmap.round(2)\n", + "\n", + "# get scores\n", + "heatmap_scores = np.sum(cdist(df_heatmap, models[dim]['model'].cluster_centers_, metric='euclidean'), axis=1)\n", + "heatmap_bits = [1 if score >= dimension_anomaly_score_threshold else 0 for score in heatmap_scores]\n", + "\n", + "# add anomaly score to index\n", + "heatmap_index_inputs = list(zip(range(1, len(df_heatmap)+1), df_heatmap.index, heatmap_scores, heatmap_bits))\n", + "df_heatmap.index = [f'{x[0]}. t={x[1]} (AS={round(x[2]*100)}%, AB={x[3]})' for x in heatmap_index_inputs]\n", + "\n", + "fig, ax = plt.subplots(figsize=(10,10))\n", + "sns.heatmap(df_heatmap, annot=True, ax=ax, cmap='RdYlBu')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You should see from the above heatmap that the top 10 rows all tend to have lower anomaly scores (AS) and anomaly bits (AB) that are 0. While its the opposite for rows 11-20.\n", + "\n", + "The final two rows are the cluster centroids themselve which should look more similar to the first 10 rows, fairly different to rows 11-20. And of course, you would expect that each cluster centroid itself has a low anomaly score and non-anomalous anomaly bit." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Another way to present this visually is via line or bar plots. Below we just plot each of the rows above as a line. First all at the same time on one plot and then each one individually as a bar plot." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the plot below the dotted lines correspond to the feature vectors sampled from the yellow anomalous period and as such we expect them to look very different to the solid lines (sampled from the normal period) and the solid circled lines which correspond to the two centroids. (Admittedly its not the clearest of plots to read since the normal lines all bunch together)." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAnYAAAFMCAYAAABGXfGvAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAD6HklEQVR4nOzdd3zT1frA8c83SZPuvRctlFX23qCAIAgq7oUD3Bv1XvXqHfpz3Ot14eKiKIJbQRRxAbKHUsqmFChddO82adLM8/sjUEVGS9s0Hef9evVVbb75fp+UNHlyznmeowghkCRJkiRJkto/lbsDkCRJkiRJklqGTOwkSZIkSZI6CJnYSZIkSZIkdRAysZMkSZIkSeogZGInSZIkSZLUQcjETpIkSZIkqYPQuDuAPwsNDRUJCQnuDkOSJEmSJKlBqampZUKIMHfHcVKbS+wSEhLYuXOnu8OQJEmSJElqkKIoOe6O4Y/kVKwkSZIkSVIHIRM7SZIkSZKkDkImdpIkSZIkSR2ETOwkSZIkSZI6CJnYSZIkSZIkdRAysZMkSZIkSeogZGInSZIkSZLUQcjETpIkSZIkqYOQiZ0kSZIkSVIHIRM7SZIkSZKkDkImdpIkSZLUHJU5sPJBMFa4OxJJkomdJEmSJDWLxQC7lsCO99wdiSTJxE6SJEmSmuzYerBboMc0+G0BmA3ujkjq5GRiJ0mSJElNIQT88Bfn17hHwFTpHLmTJDeSiZ0kSZIkNUXWJig/CkPnQtxwSBgH294Em9ndkUmdmEzsJEmSJKkpdr4PXkHQZ5bz/8c/Br1mgNXk3rikTk3j6gsoihIILAL6AgKYI4TY7urrSpIkSZLL1BTCoVUw8h7w8HT+rOsFzi9JciOXJ3bAfOAnIcRViqJoAe9WuKYkSZIkuU7xQdD6wtA5p/5cCMjZBghIGOuW0KTOzaWJnaIoAcB44FYAIYQFsLjympIkSZLkct0nw1+OgkZ36s+FgO8eAo0n3L0ZFMU98UmdlqvX2CUCpcBiRVF2K4qySFEUHxdfU5IkSZJcx1TpTOD+nNQBqFQwdh4U74eMta0fm9TpuTqx0wCDgQVCiEFALfDEnw9SFOVORVF2Koqys7S01MUhSZIkSVIzLJsDH19x9tv7XQ3+sbD5ldaLSZJOcHVilwfkCSF+O/H/y3AmeqcQQrwrhBgqhBgaFhbm4pAkSZIkqYnKj8GxdRA38uzHaLQw+gHI3X5ivZ0ktR6XJnZCiCLguKIoPU/8aBKQ5sprSpIkSZLLpC4GRQ2Dbz73cYNvhrBeoC9qnbgk6YTWqIp9APjkREVsJnBbK1xTkiRJklqW1QS7P4Zel4B/1LmP1XrDvb/K4gmp1bk8sRNC7AGGuvo6kiRJkuRSh75zFk4Mm9u44xUFHHbIS4H4c0zdSlILkjtPSJIkSVJjJF8G134CiRMaf5+tr8Piac61eZLUCmRiJ0mSJEmNodFB7xnnN7068CZQeTgTPElqBTKxkyRJkqSGbPg3bH/7/O/nFwGDZ8Oez6A6v+XjkqQ/kYmdJEmSJJ1LXQ1sfQOKm9jUYfSDIBxNSwwl6TzJxE6SJEmSzmXfF2CthWFzGj72TIK6OJsW52wBh6NlY5OkP2mNdieSJEmS1D4JASnvQ9RAiBnS9PNMfwm0vs4txyTJheQzTJIkSZLOJmcblB5qfIuTs/EMAJUazAawGFsmNkk6A5nYSZIkSdLZeHg525z0vbL55zKUwOv9YOf7zT+XJJ2FTOwkSZIk6WxiBsM1S0Hr0/xz+YZDZF/Y9hbYzM0/nySdgUzsJEmSJOlMsrdAZU7LnnPco2Aogj2ftux5JekEmdhJkiRJ0p857LDiHlh5f8ueN3ECRA92Niy221r23JKETOwkSZIk6XQZa6E6F4Y2scXJ2SiKc9SuMhsyN7TsuSUJ2e5EkiRJkk6X8j74RkCvGS1/7p7T4fZfIHZoy59b6vTkiJ0kSZIk/VFlDhxdDYNvBrVHy59fpfo9qZMNi6UWJhM7SZIkSfqjvBTQ6GDIra69zsaXYOmlzibIktRCZGInSZIkSX/U7yp47AgExLr2Ol5BkL3ZWX0rSS1EJnaSJEmSdJLV5PzuGeD6aw26CXzCYcurrr+W1GnIxE6SJEmSTvr4Smebk9bg4QWj7oVj66Bgd+tcU+rwZGInSZIkSQDFaZCzFcJ7td41h84FXQBslqN2UsuQ7U4kSZIkCWDnB6DWwcCbWu+anv5w+TsQ3rv1ril1aDKxkyRJkiSzAfZ+Dn0uB5+Q1r12bxf0ypM6LTkVK0mSJEn7vwKL3jk16g7lx+CLm6DquHuuL3UYcsROkiRJkvpc7uxdFzfcPddXa+Hwj+AfA9P+454YpA5BjthJkiRJklcQDLzBuZerOwTGQf9rIXUJ1Ja5JwapQ5CJnSRJktS5bfov7PvK3VHAmIfBVge/LnB3JFI7JhM7SZIkqfMyVsDG/0LudndHAmE9oPdM2PEe1NW4OxqpnZJr7CRJkqTOa/fHYDfDMDcVTfzZuEchrBX76EkdjkzsJEmSpM7J4XD2rosbCRF93B2NU/RA55ckNZGcipUkSZI6p8z1UJnVdkbrThICDq2CQ9+5OxKpHZIjdpIkSVLnpFJDt4mQfJm7Iznd1vlgKIIeF4Paw93RSO2IHLGTJEmSOqeuF8DsFc7+dW2JosC4R6AqFw4sd3c0Ujvj8sROUZRsRVH2K4qyR1GUna6+niRJkiQ16HgKmCrdHcXZdZ8K4cmw5TXnWkBJaqTWGrG7UAgxUAgxtJWuJ0mSJElnZrc6t+/65j53R3J2KhWMfQRK0+HwD+6ORmpH5FSsJEmS1Lkc/sG5fm3wbHdHcm59ZkHiBEC4OxKpHWmNxE4AqxVFSVUU5c5WuJ4kSZIknV3K+xAQB92nuDuSc1Nr4JaVzqbF0nmpS0uj+KX/Ytfr3R1Kq2uNxG6sEGIwMA24T1GU8X8+QFGUOxVF2akoys7S0tJWCEmSJEnqlMqOQtZGGHKLsyq2PbDWOdufSI1WtuB/VC/vnIUnLk/shBD5J76XACuA4Wc45l0hxFAhxNCwsDBXhyRJkiR1VsfWg8oDBt3s7kgaL3UxfHEj5KW6O5J2I/LZZ4h54w3Ufn7uDqXVuTSxUxTFR1EUv5P/DUwBDrjympIkSZJ0ViPuhHkHwC/C3ZE03qCbwDMAtrzq7kjaPCEEQgg0QUH4jDhtHKlTcPWIXQSwRVGUvcAO4HshxE8uvqYkSZIknc5hd373i3RvHOdL5wfD74L0VVCS7u5o2jTDunVkX30N1qIid4fiNi5N7IQQmUKIASe++gghnnfl9SRJkiTprBZPhzX/dHcUTTPibvDwhq2vuzuSNkvY7ZS89hoOgwFNaKi7w3Eb2e5EkiRJ6vgKdsPxX8E/2t2RNI1PCAy5FSoywW5zdzRtUvV332HJOEbYww+haDrvjqmd95FLkiRJnUfK+84RrwHXuTuSppv8L1BrnVuOSadwWCyUvfEmnn364DeljbexcTE5YidJkiR1bKYq2L8M+l3tLEJorzQ6Z1JXWw7GCndH06ZUr/gGa0EBYfPmoag6d2ojR+wkSZKkjm3v52AzwbC57o6k+UxVMH+A87Fc9Iy7o2kzAmZdjtrfD58xo90ditvJxE6SJEnq2Hpd4mxGHDXA3ZE0n1cgdL/IObU8dp7z/zs5IQQqrRb/adPcHUqb0LnHKyVJkqSOLzAOht/h7ihazth5YNFDynvujsTtbJWVZF16KbXbtrk7lDZDJnaSJElSx7XldTi2zt1RtKyo/s59bn9dABaju6Nxq/J338N8LBNNeLi7Q2kzZGInSZIkdUz6Ilj3f5Dxi7sjaXljHwFjOWRucHckbmMtLKTyk08IuOwydElJ7g6nzZBr7CRJkqSOaddH4LDB0DnujqTldRkFD+6G4K7ujsRtSt9+G4Qg7P773B1KmyJH7CRJkqSOx2GH1A+h6wUQ0s3d0bjGyaTOWufeONzAcvw41V+vIPD66/CIiXF3OG2KTOwkSZKkjufIz1CTB8Nud3ckrrXuOXh3wu/74HYSHrGxxL75BqF33eXuUNocmdhJkiRJHY/dAnEjoUcHb4ERngyl6ZC+yt2RtBohBIqi4DdpEpqQEHeH0+bIxE6SJEnqePpcDnN/BnUHX0qefBkEd4PNr4AQ7o6mVeQ/+CDlHyx2dxhtlkzsJEmSpI6laD/YzO6OonWo1DDmISjc2/HaupxB7fbt6NesRVHL9OVs5G9GkiRJ6jisdbD0MvjuYXdH0noGXAd+0bDtTXdH4lJCCEpefQ1NVBSB113n7nDarA4+Ri1JkiR1KmnfOvu79b/G3ZG0Ho0Ornq/w7c+0a9ZQ93+/UQ9/zwqnc7d4bRZMrGTJEmSOo6d7zvXnCVOcHckravLaHdH4FJCCErfeANtt24EXHapu8Np02RiJ0mSJHUMRQfg+G8w5XlQdcKVRmUZ8N2DMP2/ENHH3dG0KEVRiHnpJRwmE4pGpi7n0gmf+ZIkSVKHdGglaDxh4A3ujsQ9vIOdRRRbXnN3JC7hmZyM95Ah7g6jzZOJnSRJktQxXPAk3L3VmeB0Rt7BMPQ2OLAcKrLcHU2LqVi6lILHH8dhsbg7lHZBJnaSJElS+ycEKAqEdvLN4EfeByoNbJ3v7khahN1goOydBdhKS1Fpte4Op12QiZ0kSZLUvgkBi6fBtrfcHYn7+UfBwBthzyegL3J3NM1WsfhD7FVVhM2b5+5Q2g25AlGSJElq347/BrnbYcD17o6kbRjzEIT2AJ2fuyNpFlt5ORWLF+M3dSpe/fq5O5x2QyZ2kiRJUvuWsgh0AdDvKndH0jYEJ8Koe90dRbOVv/seDrOZsIcecnco7YpM7CRJkqT2q7bM2ZR4yG2g9XF3NG3L7k/AbnEWVLRDwXPm4NknGV3XRHeH0q7INXaSJElS+7X7oxPJyxx3R9L2HFoJvzwLllp3R9IkHhHhBFwqmxGfL5nYSZIkSe1X0kUw+RkI7+XuSNqesY+AqQJSl7g7kvNiPnqUnFtuxZKT4+5Q2iWZ2EmSJEntV2RfGPuwu6Nom+JHQJexsO1NsJndHU2jlcyfT93Bg6j8/d0dSrskEztJkiSpffp1ARTsdncUbdu4eaAvgH1fuDuSRjHt3Yth7S8Ez7kNTVCQu8Npl2RiJ0mSJLU/Vcfh57/Boe/cHUnb1m0S9L8O/KLcHUmDhBCUvPIq6uBgQm65xd3htFuyKlaSJElqf1I/dH4fcqs7o2j7FAWuWOjuKBqldts2jDt2EPHUU6h8ZIVzU7XKiJ2iKGpFUXYrirKqNa4nSZIkdWA2C+xaAt2nQmC8u6NpH0xVkPK+c5eONsp70CAi/vYkgdde4+5Q2rXWmop9CDjUSteSJEmSOrL076C2FIbNdXck7cfhH+D7R+DoGndHclYqb2+Cb75Z7gnbTC5P7BRFiQUuARa5+lqSJElSJ2CqgqiBzvVjUuP0vQr8Y2HLq+6O5DTCZiP3rrswbNrk7lA6hNYYsXsd+CvgONsBiqLcqSjKTkVRdpaWlrZCSJIkSVK7NWwu3LkBVLL+r9E0WhjzoHNP3Zxt7o7mFFUrVlC7cRPCZnN3KB2CS/8qFEWZAZQIIVLPdZwQ4l0hxFAhxNCwsDBXhiRJkiS1Z+XHnOvEFMXdkbQ/g2aDdyhsbjujdo66OsreehuvgQPxvfBCd4fTIbj6484Y4FJFUbKBz4GJiqJ87OJrSpIkSR2RpRbevQB+fsrdkbRPWm8YeQ8g2kzD4spPPsVWXEzYI/NQZLLeIlza7kQI8STwJICiKBcAjwkhbnLlNSVJkqQOav8yMNdA75nujqT9GvdomxnttOv1lL/7Lj7jxuEzfLi7w+kwZB87SZIkqe0TAna+D+HJED/S3dG0XyeTuqpcUNQQEOO2UFQ+PkT8/e/ouie5LYaOqNVWngohNgghZrTW9SRJkqQOJH8XFO51Fk60kRGndstsgHdGwcZ/uzUMRaUiYMYlePbs6dY4OhpZUiRJkiS1ffs+B60v9L/W3ZG0fzpfGHAd7PkMqvPdEkLJ669T/sFit1y7o5OJnSRJktT2TX0Bbv0edH7ujqRjGP0gCAdsf7vVL205fpzy9z/AkpPT6tfuDGRiJ0mSJLV9ag+IHujuKDqOoC7Q72pIXQy15a166dI330RRqQi9995WvW5nIRM7SZLOyF5TQ+2vv7o7DKmzczhgyUzntKHUssbOA4cNcluvYXHd4SPUfLeK4Jtn4xER3mrX7UxkYidJ0hmZ9u0n99bbqFq2zN2hSJ1Z1kbI2gSKfLtqceG94NHDrdo+pvT111H5+hJy++2tds3ORrY7kSTpjHxGjsB75EgKn3kWj/h42WdKco+d74NXMCRf5u5IOibvYOd3Y8Xv/+1CIXfcgf8ll6AOCHD5tTor+RFIkqRTGDZvpmzhu6BSEfvGfLSxseQ/+BCW48fdHZrU2dQUQPoPMOgm8PB0dzQd19pnnO1PWmE3Cu/BgwiYcYnLr9OZycROkqR61qIiCv76ODWrViEsFtT+/sQteAchBMfvuQdhsbg7RKkz2bUUhB2G3ubuSDq2rhPAUAR7PnXZJQybN1P4r39h1+tddg3JSSZ2kiQBIGw28h99DIfZTMz811F5OkdItAkJxM6fT+hdd6FotW6OUupUuoyBC56E4K7ujqRjS5wA0YNh6+tgt7X46YXDQckrr1K7dRsqna7Fzy+dSiZ2kiQBUPrGm5hSU4l65l/oup76RuozcgQBM50LrK357mloKnVCiePggifcHUXHpyjOPWQrsyHtmxY/fc0PP2JOTyfswQflh8NWIBM7SZKw5udTvngxgVdfVZ/AnYlp716OXTxNVspKrrdzMVRkuTuKzqPndAjrBSmLWvS0wmKhdP58dD174n/J9BY9t3RmsipWkiQ8YmJI+PgjdA3s2ejZpw/ew4dT+MyzaLt0wXvYsFaKUOpUyo/Bqofhwqdhwl/cHU3noFLBVR9AQGyLnrZq+XKsx48T+78FKCo5ltQa5G9ZkjoxYbNh3LkTAK8BA+rX1Z2NotEQ89qraGNjyXvgQVkpK7nGzg9ApYHBN7s7ks4log94BoAQzq8W4DNuHGEPPYjvhAktcj6pYTKxk6ROrPSNN8m5aTZ1hw41+j5/rpS1G2pdGKHU6VhNsPtj6DUD/CLcHU3nU5YBC8ZAztYWOZ02NpbQe+5BUZQWOZ/UMJnYSVInZdi8mfJ33yXw6qvx7N37vO57slLWb+IkVN5eLopQ6pQOroC6Khg2192RdE4BMVBbAptfbdZp7NXV5D30MObMzBYKTGosmdhJUid0sl+drkcPIp76W5PO4TNyBOGPzENRqWRvKqnlVOdBZD9IGOfuSDonDy8YeS8c+wUKdjf5NOWLFqFfvRphtbZgcFJjyMROkjqZk/3qhNlMzOuvN7iuriGW3FyOTZ8uK2WlljHhr3DHBmcLDsk9hs0FXQBsea1Jd7cWl1Dx0cf4z5iBZwMFWVLLk4mdJHU2ajUBM2cQ+X/Pouua2OzTeURH49mzF4XPPIsxJaUFApQ6LX2x87taNmxwK88AGH47pK2EsqPnffeyBe8gbDbCHnzABcFJDZGJnSR1IsJqRVEUgq67joBLWma/RkWjIebVV2SlrNQ8ddXwxiDY/Iq7I5EARtwDl78DQQnndTdLTg5Vy5YTdM01aOPiXBObdE6dMrE7XmFEXyfn/aXOxVpUxLGLp6HfsKHFz316payhxa8hdXB7vwBrLXSb6O5IJADfMBh4A6g9zutu6pAQQu+8k9B77nZRYFJDOl1iZ3cIbl+yk1nvbCOrTLZpkDoHYbOR/8ij2Cor0cZ3Ob/7NrKflbNS9nW0XRKaEKHUqQnh3PEgejBED3J3NNIf/bYQNr7U6MPVvr6EPfgAmrAwFwYlnUunS+zUKoV/XdqHcoOZy97awqYjpe4OSZJcrnT+G5h27TqxD+y519VZ7Q6eW5XGocIahBDc8/EuXv75MHVWe4PX8Rk5kri330Lt6yur4aTGy9kKZYdli5O2qHCvs/VJbVmDhxa98AKGzZtbISjpXDpdYgcwqlsIK+8fS3SgF7cu3sGizZmNHpWQpPbGsHkz5e+9R+DVV59zH1iAcoOZmxb9xqItWWw8UorF7sBbp+at9RlMf2MzO7IqGnVNW2Ul2dddLytlpcbZtdS5YL/PFe6ORPqzMQ+DrQ5+XXDOw4wpKVQu/QjzkSOtE5d0Vp0ysQOIC/Zm+T2jmZIcyXf7CrHaZWIndUzGHSnoevZssF/dgfxqLn1rK3uOV/HatQO4e0I3dBo1r14zkKVzhmOxObhm4Xae/mZ/g2tU1X5+qAMDZaWs1DjTX4brvwCtt7sjkf4srAf0ngk73oO6mjMeIoSg5NXX0ISHE3Tjja0coPRnSlsbqRo6dKjYeWLvytbgcAj0ZhsBXh5Um6yYLHYiA5rX10uS2hpHbS0qH5+z3r47t5Lr3v2VEB8tC2cPpV9swGnHGC02Xll9hO/2FrB63ngCvbXnvKa9pobsa6/DXllJwldfygo5SWqvCnbDuxfA5H/B2Hmn3axfv568e+4l8plnCLr2mlYPz90URUkVQgx1dxwnddoRu5NUKoUAL2fVz5Nf7+PSt7awK7fSzVFJUvNVLFlCXVoawDmTOoA+0QHMHtmFlQ+MPWNSB+Ct1fD3Gcmse+wCAr212OwO/vNTOqV68xmPl5WyUoMcdvjkGjjys7sjkc4lepAzoYsddtpNwm6n9NXX0HbpQuAVs9wQnPRnnT6x+6OHJvXA00PNdQt/5audsheX1H4ZNm2i+MV/n3ONW5XRwl+X7aWi1oJWo+LpGcmE+uoaPLevztk8dm9eNe9vzmLyqxtZlpp3xnWqJytlFbUGR3V10x+Q1DEdXQNHf3au4ZLatsn/goSxZ7wp+JabCX/icRSP82uNIrlGp5+K/bPKWgv3f7aLrRnl3DYmgaem90ajlvmv1H5Yi4rIunwWmogIEr74/Ixbhh0u0nPnRzspqDKxcPYQJvaKaNK1Mkr0PLF8PztzKhnXPZQXZvUjLvj0dVLCbkdRqxFCoMitoqSTPrkaCvfBvAPn3S9NcgN9EaR+COMelf9efyCnYtu4IB8tS24bzm1jEvhhfyGVRtmyQWo/TvarExYLMa+9dsak7qcDhcx6ZytGi53P7xzV5KQOICncjy/vGsX/XdaHXTmV3P/prjOO3ClqNQ6zmYK//FVWykpOldnOEbsht8gkob0o2A0bXoQDywGoWvENFUs/Qjgcbg5M+iO5Id8ZaNQq/jmzDw9M7E6wjxa7Q5BXaaRLyLnXKUmSu1V++SWmXbuIfvnlM/arW5aax2Nf7WVgXCALZw8hwr/5hUIqlcLsUQlM6h1BTZ1zyzKD2cbxCiO9o/zrj1PUauyVlRQ+8yzaLl3wHnb6eh2pE9m5GBQVDL7F3ZFIjdV9KoT3gS2v4eh6CSWvvIKua1eCZt/k7sikP3DpiJ2iKJ6KouxQFGWvoigHFUV5xpXXa2nBPs6qv7fWZTB9/mZWHyxyc0SSdG5BV19NzBvzCZhx5n1gL+wZxl0TuvL5nSNbJKn7o+hAL3pFOhO5N9cdZeabW05pbKxoNMS89qrcU1ZyihkMYx+GgBh3RyI1lkrlLKIoTafitX9gLysj/JF5cnlFG+PqqVgzMFEIMQAYCFysKMpIF1+zxV07LI6kcF/u/CiVN345isPRttYlSpK1uARbRQWKhwf+U6acctuxUgOPL9uH1e4gxFfHk9N64+mhdmk8d4/vxqUDo+sbG6dkOxsby0pZqV7yZTDpH+6OQjpffWZh8+pC+bKf8Z00Ca+BA90dkfQnLk3shNPJV26PE1/tLiuKDPDki7tGccWgGF5dc4T7Pt1Frdnm7rAkCTixrm7ePHJumo2wnfq8XJdezOVvbWXNoWJyyo2tFlOQj5ZXrxnIkjnDMVsdXP2/7Xy0PRv4vVLWXlGJJSu71WKS2pB9X4KxcbuYSG2MWkN5ySAcVkH4fXe6OxrpDFxePKEoilpRlD1ACbBGCPGbq6/pCp4eal65ZgBPX9KbDYdLySqrdXdIkgRA6fz5mHbtIvTee1E0zmWzQgjeXp/B3CU7iQ/x5rsHxpIU7tvqsU3oEcbqeeO5Y1wi43s4NwU32+z4jBxJ0to1ePXr2+oxSW5WfBC+vgN2f+zuSKQm8r36HsIeehhdcn93hyKdQau1O1EUJRBYATwghDjwp9vuBO4EiI+PH5KTk9MqMTVVmcFc3+8rt9xIfIjcBkdyD8PGjRy/624Cr72WqGf+Vf/zZ79L44OtWVw2MJp/X9EfL61rp14bSwjB7Ut24qVV88+ZfQj11VL+3iI0IcEEXnmlu8OTWsP3j8Kuj+DRdPAOdnc0UnMUHwSVh3PbsU6s07Y7EUJUAeuBi89w27tCiKFCiKFhYWGtFVKTnUzqftxfyMRXNrB0e/YZWzxIkitZCwspePwJdL16EfHkE6fcdvXQWJ6+pDevXzuwzSR1AA4BA+ICWX2wmMmvbmT5zlyMv/1G4b+ekXvKdgZmPez9AvpeIZO6dsicmUXxi//GXl0N1jr48BL4pV3VRHYKrq6KDTsxUoeiKF7ARUC6K6/ZmsZ2D2VCjzD+8e1B/rZiPxab7OUjtR7F0xPvESOIee1VVJ6ebDlaxr9/dP559Y7y5/ZxXdtctZpapfDgpO788NBYuof78tjyAzw7+AZU0THkPfgQlrw8d4coudK+L8Gih6Fz3R2J1ASlb7xB5VdfOdfyenjCsDsgfRWUdJi39Q7B1SN2UcB6RVH2ASk419itcvE1W42fpwfv3jyU+y7sxmc7jnPDe7+edd9MSWpJQgg0QUHEzn8dbUICizZncvMHv7EuvRh9Xdtvqv3HxsbHTCpC5r+BcDjIk5WyHVtpOkT2h9g2M2slNZLpwEH0P/1EyK23oAkJcf5wxN3g4Q1bXnNvcNIpXF0Vu08IMUgI0V8I0VcI8awrr+cOapXCX6b24s3rB3GwoIbfssrdHZLUwRk2biTnptnYysups9p55Mu9PPf9IaYkR/L1vWPw82wfXfxPNjZeM288ob26E/Xqq9Rm5XDk543uDk1ylen/hbmroY2NJEsNK33tNdSBgQTfdtvvP/QJgSG3wv6voLJtr43vTOSWYi1k5oBoNv7lAmb0jwYgr7L1WktIncfJdXWO2loUHx9uXbyDFbvzefSiHrxz42B8de1vM5mTezEXJ/Xj4Zn/YGaqwiurf29sLHUQdTXO7x5e7o1DOm+1v/5G7dathNx1F2o/v1NvHHU/6PygcK97gpNO02pVsY01dOhQsXPnTneH0SyHCmu47O2tzB2byGNTeqJWyU+nUvMJq5Wcm2/BfPgwiV8vR5uQwM8Hi1ArCpOTm77fa1tSUWvhue/TyPthDd10dq548k6GJchF9u1ebTm83g8ufsE5wiO1K5bsbMrf/4CIp59CpdOdfoC1zrnmrpPqtFWxnUm3MF+uGhLLgg3HuH1JCjXtYM2T1PaVzp+PafduMm5+kGXFzj/dqX0iO0xSB85t/F65egB/sxzkhs0f88HbX8udXjqCPR+DtRbiRrg7EqkJtAkJRP3fs2dO6sCZ1AkBFVmtG5h0RjKxcwGtRsULs/rx3OV92Xy0jMvf3kpmqVwQLjWdw2ikZs1aDg+/iPuKQll/uKTDtthRFIV+C+bjGR/Hg5sWYcvPQ19nZX16ibtDk5rC4YCdiyF+NIT3dnc00nkQdjtFL7yAObMRCdsvz8DC8WCqcnlc0rnJxM6FbhrZhU9uH0GV0cqK3fnuDkdqx8psKv4x7S/8JWIi913Yjf/dNKTNtTJpSeqAALr8bwEq4Pg99/DR2jRu+zCF+z/dRZlBVp63K5nroDILhskWJ+1N9bcrqVz6EeajRxs+uM8sMNdAyiLXByadk1xj1wqKa+oI9dWhVikUVdcR4a/r0G/KUssRViuF7y/mutI4Si0KL189gEv6R7k7rFZT++uv5M69ndAnnuCz6BG8tS4Db52apy9J5srBMfLvqD34/EY4/hvMOwias0zlSW2Ow2Lh2MUXowkOIeGrLxv3t/bxVVCwGx7eD9rOsyOTXGPXCUX4e6JWKVTUWrj0rS3M+2KPrPiTGqX0jTeofv01Hg2p5ut7R3eqpA7AZ+RIEr9eTuhNN9Y3Nk4K8+Wxr/byyuoj7g5PaoxpL8EV78mkrp2p+vxzbAWFhD8yr/EfoMY9AsYy2P2Ra4OTzkkmdq0oyNuDW0Yn8O3eAq5ZuJ3CapO7Q5LaKKvdwbsvfUT5e4sIvO5aLrv3OnpH+bs7LLfw7NkTRVEwZ2QQnrqFL+8axbOX9eGaoXEAVJus2GWBRdsVEAPdLnR3FNJ5sBtqKVvwP7xHjcRn9OjG37HLaIgf5dxhRHIbmdi1IkVRuO/CJN6bPZTM0lpmvrmV1JwKd4cltTHlBjP3vf4jAz56nZqYRCKefNLdIbUJpW+8Sf5fH6cudSc3j0ogPsQbIQSPfLGHKxZsI72oxt0hSn9kt8JXt0Lub+6ORDpfwkHAZZcRPm/e+d/3ivfg1u9bPiap0WRi5waTkyNYce9ofHRqFm7MdHc4UhtysKCaS9/ayoSV7+GjFgx6/52ztxjoZKL+71m0MafvKXvZoBjyKozMeGMLr6w+jNkmlzm0Cemr4OAKqKtydyTSeVL7+RHxxON49e9//ncOjHO2P7FbnRXRUquTxRNuVGW0oCgKAV4eVNZa8PXU4KGWuXZndbhIz2VvbyHIW8vCC8Poaq7Ed8IEd4fVpliys8m69jo8wsPo8tlnqH19AaistfB/36fx9a58uoX58L+bhtA9wq+Bs0ku9eEM5zZTD+0Bldrd0UiNVPHJJ+gSE89vCva0k2TCkstg6nOQfFnLBddGyeIJqV6gt5YALw9sdge3fpjCze/voLLW4u6wJDfpHu7Lw/38+Pa+MfQf2V8mdWegTUggdv7rmDOzKH/3vfqfB/loefWagSyZMxx/Lw/C/TpvF/w2ofQIZG+GobfKpK4dsRYUUPKfl6j+vplTqYFdQO0Bm191Ni6WWpVM7NoAjVrF7JFdSM2t5NK3t8i1Qp1ItdHKg5/t5niFEXtxERNfeQwWL3R3WG2az8iRxL+/iND77zvttgk9wvj6ntEEeDs/MN2+ZCe/HCp2Q5Sd3M4PQOUBg252dyTSeSh9+20Awu47/W/rvKjUMOYhKNwDx9Y1PzDpvMjEro24akgsX9w5ErPVwRXvbOOnA0XuDklysSPFei59ews/HijkYG45+fMeQdhsBF7W8acumstn5EhUWi32qioMGzeectvJ1gwlejPHK4zMXbKTBz7bLRsbt6bQJBh5D/iGuTsSqZHMx45RveIbgm64AY/o6OafcMB14BcFW15r/rmk8yITuzZkUHwQ3z0wlh4Rfry8+jBWu1x42lH9fLCIWW9vxWix8/mdoxi05nNMe/Y4CwQSEtwdXrtR8sqrHL//AYxnWJcbHejFdw+M5ZGLevDzgSImv7qR5al5HXYrtjZl2O0w5f/cHYV0Hkpfn4/Ky4uQu+5smRNqdDD6AeeUfP6uljmn1CiyeKINqrPaqai1EB3oRZ3Vjs0h8NVp3B2W1EJ+2F/IvZ/sYkBcIAtvGoLPru3k3XMvgddfR9Q//+nu8NoVe3U12ddeh726moSvvkQbG3vG444W63ni6/3o66ysemAcWo38TOsy6T9At4nOykipXRBCUPnxJyAEwTfPbrkTmw3OxK77VFB13L+5tlY8IRO7Nu6xr/ayP6+a924eSnxI59mipSMzWmws3JjJPRd0w9NDjWHzFioWf0DsggWytUkTnK1S9s8cDkGZwUy4vyf6Oivf7M7nhhFdUKvktmQtJj8V3psIl7ziHLWTpE6grSV2HTeF7iAuGxhNUU0dl769hW0ZZe4OR2qizFID936SSq3ZhrdWw7yLeuDp4awW9B03lrj335dJXRP9sVK25D//OetxKpVCuL9zFGnF7nz+/u1B2di4paV8AB4+0O8ad0ciNZIxJYWqZcsQNpvrLrL5Ffj+UdedXzqFTOzauHHdw/j2vjGE+eqY/cEOPtyaJdcItTPr00u47K2t/JpZQU65sf7nJa+9TtnCdxFCyM3sm8ln5EhiXnuVsAcfbNTxs0d2Yf51Azl+orHxq7KxcfOZKuHAcuh/NXh2zu3v2hshBMX//g9l7yxAuLKZsKnSWSldkeW6a0j1ZGLXDiSE+rDivjFM7BXOq2uOUCqr+9oFIQRvr89gzpIU4oK9WXn/GJKjnW94+g0bKF+4EGtRoUzqWoj/lClowsIQNhvG3bvPeayiKFw2MIa1j0zg0gHRvLEug3+tTGulSDuoPZ+BzQRD57o7EqmR9D+vpu7gQUIfeACVVuu6C428D1Qa2DrfddeQ6nXKNXa7amoJ0Kjp5t2+Fvc6HIKs8lq6hfkihKDaZCXQ24V/jFKzvPzzYd5an8HMAdG8dGV/vLTOqVdrQQFZs65AEx1NwueftckpWCEElZWVWCwWIiIi2lXyWTJ/PuWL3qfL4g/wHtq4ZS8bj5SSGOJDfIg3pXoznh4q/Dw9XBxpB/PFbNAXwu1r3R2J1AjCZiNz5qWgVtH1229R1C5uJP3dw7DnE3h4P/hFuvZaraytrbHrdImdEIJpqUc5aDBxZ1wY87pE4Ktpf53RF23OZNHmLBbOHsKAuEB3hyOdQV6lkZ8PFjNnTEJ9YiSsVnJm34z56FESly9rE61NbDYbJpMJPz8/HA4HS5YsoaioCLPZOTIcHh7OpEmT6Nmzp5sjbZzGVsqeze1LUjhYUMPzs/oysVeEi6LsgIRwTrl5B7s7EqkRqpYto/DpvxP71pv4TZ7s+gtWZMKbQ2DUfTDlOddfrxW1tcSu003FKorC0n6JXBkRxNu5JYz+7RBfFlXgaGMJbkNGdQtBrVK4euF2VuzOa/gOUqvYmlHG48v24XAIYoO8mTs28ZTRLmPqLkz797u1X11OTg7btm3j66+/5p133uGFF15g5cqVAKhUKnx9fenfvz8zZ85kxowZqFQqrFarM36jkdLSUrfE3VjqgABiF7yDsNvJu+ce7AbDed3/3guT8PPUMOdD2di40WxmUBSZ1LUjmqgoAi6/HN9Jk1rngsFdYeoL0OeK1rleJ9bpRuz+aFdNLU8fzWdXjZH3+iQwMzywVa7bUsoNZu79ZBe/ZVVw5/iuPH5xL9m6wU2EEHywNZsXfjhEtzAfPr9zFME+Z54mt+Tmoo2Pd2k8DoeDyspKiouL60ffpk2bBsDixYvJycnBz8+PyMhIIiMjiYuLo0ePHmc8lxACIQQqlYpNmzaxbt06EhMTGTZsGD179kTt6imcJqrdto3cO+7E76KLiH39/LrfW2wO/rfxGG+ty8Bbp2bRzUMZmiCTljPSF8HbI+DSNzrFhu+S9GdtbcSuU3e9Hezvw6rB3fmxrJqLQwMA2FKpp6ePJ2Hatr++JsRXx8e3j+D/VqWxaHMm0/tFMVBOy7a6Oqudv329n6935zO1TwSvXDPwtIbS1oICzEeP4jthQosndVarldLSUqJPbAO0fv16tm/fjsViAZyj1JGRkTgcDlQqFTNnzsTLywsfH59GnV9RlPpRx8GDB6MoCjt37uTLL7/E39+foUOHMm7cuDa3Ds9n9Giinn8OXffu531frUbFg5O6M61vJC+vPkz3cD8AWcF8JruWQl0VRPR1dyRSI9j1eiqWLiX45ptR+/m1fgCV2bDtTbjoWdA27jVIOj+desTuzywOB0O3p2GyO3gsMZI5MWF4tJMRsMNFenpGOv9Ia+qs+MuF363mtsU7WH+4lEcu6sH9Fyah+tNzRlit5Nw0G3NmJklr16AOCGjW9UpLSzly5AhFRUUUFRVRVlaGEIJHH30UPz8/9u3bR15eXv1oXFhYGB4eLft8cDgcHDlyhJSUFNRqNTfccAMAJSUlhIWFtcnkx5Kd3azpb6vdwfXv/sq0flHcOjpBjo4D2G0wvz+E9YTZK9wdjdQIpW+8Qdk7C0hYtgyvvn1aP4DjO+D9i2DqizDq3ta/vgvIEbs2TKtSsWJQEn8/ms8/Mwr4uKCcZ5NiuDCk7fdkOpnUbThcwoOf7eb16wbKhd+t5O4J3bhhRBcuSj7z77vktdcx7d1LzGuvNjqpczgcVFRUUFRUVD+dOnnyZCIiIsjPz2fNmjX4+/sTGRlJ7969iYyMRHeiurZ///7079+/xR7fmahUKnr16kWvXr2w25393yorK3nnnXeIiIhg2LBh9OvXrz4md6v88kuK/u+586qU/bNasw0/Tw3/tyqNlXsL+M+V/egV2fZfG1zqyE9Qkw/TXnJ3JFIj2MrKKP9wCX7TLnZPUgcQNxy6jHWO2g2b69xTVmpRcsTuLNaUVfOPjHyyTBZWD+1Bf7/2sZ1XfpWJO5fuJK2whr9M7ck9E7q1ydGT9u6T33KoMFh4YNK5p/n069aTd++9BN1wPZH/+McZj7FYLJSUlODr60tgYCB5eXksWbKkvmBBURTCwsKYPn06CQkJmM1m7HY73t5t6zlpsVjYv38/O3bsoLi4GJ1Ox8CBAxk7dix+7pjy+YPmVsqeJIRg5d4CnvkujRqTlXsv6MZ9E5PQtcPK+hbx0SwoPQwP7QO1HCdo64qee57Kzz6j66rv0CUmui+QjLXw8ZVw6Zsw+Gb3xdFC2tqInUzszsHscLCmrIYZJ4oq1pXXMCLAB582/iJustj56/J9fLe3gEsHRPOfP/RQk5rHYnPwz5UH+WxHLhf2DGPRLcPOOiVnKy/n2PRL8IiJJuGz3/vVWSwWduzYUT+VWl5ejhCCiRMnMn78eIxGIxs3biQiIsJlU6muJITg+PHjpKSkcPjwYR588EF8fX2pqanBx8fHbcUW5qwssq+9Do+I8HPuKdsYFbUW/m9VGmkFNXz3wFi0mk7XYMCp6ADUFECPKe6ORGqAJS+PY9OmE3j55UT937PuDUYIeHcCmA1wfwqo2vf7k0zsGtCWErs/KrVYGbItjWAPDf9IimZWeGCbHgkTQrBg4zH++/NhXr5qAFcOadoIhfS7En0d93y8i9ScSu69oBuPTul51qTO4XBQXl5O5opvqAoJptRkIjo6mokTJ2K323nxxRfx8fGpXwcXGRlJTEwM/v4da2rPbDbXT8d+8MEHVFVVMWTIEIYMGYJvMxKrpjpZKes7bhyxC95p9t+wwWzDV6ehps7Kgg3HuPeCbrKxsdQmWXJyKH7pv0T+/Wk8IttAg+D07+HYOpj8L9C5d0S/uWRi14C2mtgB7Kyu5W9H89inNzE8wIfnu8fQr41P0R7Ir6ZPtD+KotS/CUnnr85q56LXNlKmt/Dfq/szo390/W0Wi4Xi4mLMZjNJSUkAvDl/PuWVlYBzPVpYWBh9+vRh/PjxwKkJT1tWVZ1KgP/gZidAQgjS09NJSUkhMzMTlUpFcnIyo0aNIiYmpoWibZzKL75E7eeL//TpLXbOH/YXct+nu4j09+wcjY2tdfDjX2HkPRDe293RSJJbdarETlGUOGApEAEI4F0hxDk3i2vLiR2AQwg+L6rg+WOF6G12Ukcnt4vWKMdKDVz9v+38ZWpPrh/u2h5qHdU3u/PpEeFHcrQ/e/fura9MLS8vByAoKIiHHnoI/br1bHrzTcLm3Eb8sGGEhoai0bTNhNpozEJvOISx9hi1xkyMxmOo1b4MGfwpQgh2pl6NThtKr14voNW2TB+3srIyUlJS2LNnDxMnTmTEiBFYrVaEEGhduV/lGdgqK9EEBbXIuXblVvLE8n0cKTYwc0A0/5yZTKhv20/em2Tv57DiLrj5W+h6gbujkRpQsWQJvpMmNXltqUvlbAO1DmKHuDuSJmtriZ2r321swKNCiF2KovgBqYqirBFCtNvdtlWKwg1RIVwSGsD2qtr6pG51WTUXBvu32fYoob46+sUE8OTX+0krqOEfM5PxUHfSdUGN4HA4KC4pZeHPu4jyqMPbbqC8vJxLH3wQgNzcXPLz84mMjKRfv37106nWggIKnnyS3jHRJEyZ4vZ9YIUQWK3l1NY6k7ZaYyYWcwl9+zo/Xx079golpT8CCp6eMfh4d8XP72S1nCAyYgZHM/7NbzsuoU/yywQHj2l2TKGhoUybNo1Jf+h4v2/fPlavXs3AgQMZdiIZdjXD5s3kP/Qwce8ubHKl7B8Njg9i1QPjWLDhGG+tP4pDCN6+YXALRNoGpbwPId0hcYK7I5EaYNy1m+IX/43DZCL07rvdHc6p7FZYfgcExsOcH90dTYfRqlOxiqJ8C7wlhFhztmPa+ojdmezVG5m68wg9fTx5LimGccFtc72A3SF46ad0Fm7KZERiMO/cOJiQjjqicB7MZnN9S5H+/fvj6enJj2t+4betm50HKCoiI8KJjIzk4osvxtPTs77Z7x/V96vLyCDx6+Vou3RptcfgcFipq8ujtvYYRuMx4uJuRaXSkZHxH3Jy360/TqXyxNu7K0OHLEOt1mEwHEYIB97eCajVXmc8t16fxoGDD2M0HiM+bi7duj2GStWyI2sFBQVs27aNtLQ0HA4HXbt2ZdiwYfTq1ctla1lbqlL2TI4W6/HSqokN8qaw2oTNLogLbtvLNhqtcB8sHNeh+pB1VEIIcmffjDk7m6Sff0LVyKbkrerX/8FPj8NtP0GXUe6Opkk624hdPUVREoBBwG+tdc3W0t/Xiw/7JvLPjHyu3nuMS8IC+Ge3aOK92lbSpFYpPDm9N72i/Hh8+X7e3ZTJk9M7z/qYP26NVVhYyObNmykqKqKioqL+mPDwcGq1QbyeYgR7V2ZPHMB14/qcNpX656QOTu1X56qkzmqtwWg8ho9PEhqNH6Wla8g49l9MplyEsNYfFxo6CR+fJEJCJ6LVhePj3Q1v7254ekahKL/H7uvbs8Fr+vklM3zYtxzNeJEa/X4UpeUr2KKjo7nqqqswGAykpqaSmprKli1b6N3b+fy0WCwtPk17ck/Z7GuvI++ee5pdKftH3SN+/3D3f6vSWJ9eymNTe3aMxsY73weNFwy83t2RSA2o3bIF486dRPz96baZ1IGz3cmml2DLq9DlK3dH0yG0yoidoii+wEbgeSHE12e4/U7gToD4+PghOTk5Lo/JFersDhYeL+X1nGL8NSpSRiWjPUMC0BakFdTQNcwHTw81Jou9w7VDcTgclJWV1bcUOfk1bdo0+vXrR35+PsuWLTulKjUyMpJqm4Ypr28iyFvLwtlD6B8b2KjrCSEoevZZ5/ZdZ+lX11hCOBDChkqlxWjMIjf3/fr1bxZLGQADBywmJGQ8lZU7OJ63GG/vbvh4d8Xbx/ldo3HNqLHDYUal0mG2lFFW9gvRUde4ZETNbrdjMBgICAjAaDQyf/58evTowbBhw4iLi2vRa9ZXyo4dS+w7b6O0cDuW/CoTT6/Yz/rDpQyIC2z/jY3XvwgWA0x93t2RSOcgHA6yrrwKh15Ptx++R2nl9avnZdN/Yd1zcNdmiHJtc3VXaGsjdi5P7BRF8QBWAT8LIV5t6Pj2OBX7ZwV1Fo4Y67gg2B+HEPxSXsPkEP822R6l2mRl1ttbmdE/iocn9zhtO6z2oK6urn4qNSQkhKSkJKqrq3ntNefG72q1mvBw51TqoEGDiG9gr9YPtmQxc0A0YX7nP+IqHA6U80jm7XYjpWW/YKzNpNZ4DKMxE6Mxi549/kl09DXo9YfYtfvGU5I2b+9uBAYOwcOjZRb9N0Vm5nyyst8gNHQyvXu9gFYb4rJrGQwGNm/ezJ49ezCbzURGRtbvbNFSo3iVn32GtbiYsAcfPK9/v8b6c2PjBTcNOetOJQ1xOES7/DuVWpfDaKT4pZfwHjqMgBmXuDucczNVwbsXwJTnoPcMd0dz3jpVYqc4M5klQIUQ4uHG3KcjJHZ/tLKkijsPZjMywIfne8TSx/fM65jcxWyz8/SKA3yVmsfk3hG8du2ANtuHSwiBxWJBp9MhhGDZsmUUFBRQeaKtCDg3qb/00ksRQnDgwAHCw8MJDQ09Z1PcaqOVx5fv44FJSfSJPr99XIXFQsHfniJkzm14JiefJeZSZ9L2h+QtNORC4uJuwWqtZNPmoYAKL6/Y+pG38PBpBAQM4uTfZ1v7UCCEg+N5S8jIeAkPjwCSe/+XkJBxLr2mxWJh3759pKSkUFxczH333UdYWBh2u71Fmx47LBZULhrdqKi1MH/tER6Z0pMALw/MNvt57VpxNKWYjZ8dZsINPek+tJVbqggB2VugyxhoozMRUjvmcLTb51VnS+zGApuB/YDjxI//JoT44Wz36WiJnV0IPi0s58XMQqqsdmZHh/B41yiCPdpO+wshBB9uy+a57w/RNdSHRbcMpUuI+9djlJaWUlBQcMpUamRkJLfccgsAn376KRqN5pSpVD8/v/NKgo4U67lz6U7yq0y8fPUALht4fj3Viv/zEhWLFxP1+n/RjOuJ8UT1qVYbRnT01QjhYMPGfjgcdQCo1d54e3clKupK4mKdW+kYDEfw8uqCWt221mQ2hl5/iINp86itPUpy7/8SFXWFy68phKC4uJjIE01Wv/zyS+rq6hg+fDjdu3dvVpJXd+gQx++5l5iX/9silbLnYrU7uPztrQzpEsRfL+51zh6Tljobmz8/QvqvRfiHeXH9P4aj8VBTnF1DYLgXOu9W+DCWsw0WT4Mr3oP+17j+elKT6devRx0QiPfgQe4O5fw47FC4B2LaV+uTTpXYNUVHS+xOqrLaeDm7iMX5ZQzw8+aHIT3cHdJptmaUcd+nuxgUF8ji24a32nUdDgcFBQXk5+djMBjq22AsXbqUzMxMNBpN/VRqfHw8AwcObJHr/nywiEe+2IOXVsP/bhrM0ISG+7RZrZXUGjOx22rR7rWRd+99VD8fijG4GCHs9ceFhV5E//7/A6CoaCVabQje3l3R6SLb3Ohbc9ntdWRlv0WX+Ll4eAQhhGjVx7h582Z27NiBXq8nICCAIUOGMHjw4CbtbOHKStk/q7Pa+feP6SzZnn3OxsbFWTWs/uAg+jITQ6YnMGx6Aiq1CrvdwcdPb8duczDysm70Gh3l2inaZXPh6Bp49BBo3f/BTzozh8nEsSlT8YiLo8snH7ev15t1z8OW1+DhfeAf3fDxbYRM7BrQURO7kw4ZTBjsDoYF+FBrt7NPb2JUYOtvrXQ2ueVGPD1UhPt7Ume1o9OoXPbCUFRUxO7du0lLS0Ov1wPg6+vLvHnzUKvVFBYWolarCQkJafH9RdcfLuG2xSkMiA1g4eyhRAZ41t8mhB2zuRhPT+cLS07uIkpL12A0ZmK1OitodR6RhD1mRxsTA/+9EIdiOVF52hVv70Q0mrbzb9qaHA4ru/fcQkT4dGJibmy1NxW73c7hw4dJSUkhKyuL8ePHM3HixCZNZf++p2wEXT77tMUqZc/mj42NLx0QzXOz+uL/h+UQu1fnsm/DcS66rQ/R3QNPuW9prp7NXx6hMKOasHg/xl3bg6hu57ecoFEMpfBqbxg2F6b9p+XPL7WY8kWLKHn5Fbp8/JHLR51bXGUOvDHIuaNJOyrOkYldAzp6YvdHb+YU83xmITPDAvlnUjSxnm2naslmd3DbhymE+zlHEjw9mp9Y2e12cnJyiIyMxNvbm5SUFH766SeSkpJITk4mMTHxvKdSm8pqd/D+lixuHZ1AXe1uyss3YjRmUWs8hsmUjRBw4QUHUBQ1Gcf+S3VVKt4+XeuTN+MHP2D6coOzX10DxRididVaw8G0hykv30ho6CR693rRpYUVZ1JaWoqXlxe+vr6kp6ezYcOG8y62cHWl7J9ZbA7e2ZDBL4dKWH7PaCx6C9WlJmJ6BCEcAovZjs7rzFO1QgiO7ixm2/Jj1FaZueqJoUQktHDV7eZX4Zdn4L4UCGt7sw2Sk72mhoyLpuA1cADxCxe6O5ym+fouOPQdzDsA3i2z242rycSuAZ0psTPZHbyTW8JbucUA3B8fwb3x4Xi1gR0hHA7B/F+OMv+XowyMC2Th7CFE+Hs2fMc/sdvtZGVlkZaWRnp6OkajkZkzZzJkyBDMZjOAy/dMtVqr0OsPkltyiK3pqQyNrcFqzmbY0G/Q6cLIyn6brKz5eHrG4ePjTNx8vLsRGXkpKtWZYxNWK+Zjx/Ds1culsbdHQgjy8paQcew/aDT+JworxrslliNHjrB27VpKSkrw9PSs39kiJKThZLPi00+p3bKVmFdeRuXVOkVPNruDnL1lrPs4nVq7g1lPD6VLWONGDK1mO0dTiuk9JgpFUSjMqCK8iz9qjxZ4PfngYlBp4NZVzT+X5DIlr71O+cKFJH6zov2+NpUcgndGwoQn4MIn3R1No8jErgGdKbE7Ka/OwrPHClhZUsUVEUG8k9x6OxY05Mf9hTz61V58dRoWzh7CoPjGt9gwmUzMnz+furo6tFotPXr0IDk5maSkpBZvNmu3mzGZsk9Unzq3zkrocg++vj0oLPyatEN/ccZk88TPN4mwwB507ToPT89obLZaVCrNWZO4PzLu2oU2IQFNcPv4JOlOBsNhDhx8GCEcjBj+PSqVewqGhBDk5uayY8cODh06REBAAA8++GCjRoZPtq9pjXWDVrOdzV8e4dDWQrwjvXjPUk2VBh6b0pNbzrOxsUlvYenftuEdqGPs1d1J6BfSvPjtNjCWgV9k088huVzF0qVYsrOb3UvT7T67AWpLYO4aaAdrBGVi14DOmNidtK3SQIhWQ08fT4rMViqtNnq3gfYohwpruGPpTtQqhbWPTDjjHrNWq5WMjAzS0tJQqVTMmjULgHXr1hEdHU23bt3w8Ghe5Z5z39MKZ7Pe2mMEBAzC17cnVVU7Sd11HfD7c9nTM4bevV4kKGg0725IYUXKNnx8uvHadROJb2LFrzU/n8wrrsR70CDi/regWY+ls7Db67BYSvHyisNuN2Kqy8fXp7vb4tHr9VRWVhIfH4/VamXx4sX07t2bwYMH43OWzvzW4hLyHnyAiL/+Fe8hrqnWq6u1svylVKpKjAye0oXhMxMpMph5asV+NhwuZWBcIP+5sj89IxvfePp4WgWbvzxCZZGR+D7BjL26O0GRTXjut+M2FFI7ZawAzwBQtY/G+TKxa0BnTuz+6NH0XD4vquDW6FD+khhJoJvbo1TUWijVm+kZ6YfN7uxco1GrOHbsGLt27eLIkSNYrVa8vLzo27cvl1zS9IaYDoeNurrjKIoGL684LJYy9u2/h9raTGy2qvrjunX7Kwld7sJiKScv7+M/rIFLQK127sv5zoYMXvrpMDP6R/HSVf3x1jbt9ygsFrJnz8ZyLFOuq2uio0dfIC//I5KSniQ2Zrbbq/Wqqqr49ttvycrKQq1W06dPH4YNG0ZsbOwpsbVGpawQgq3LMkjoH0psz6BTfn6ysfHAuEA+uHXYeZ3XbndwYEM+O77LxG4TzH5+FD4B57H0oTLH2eLk8gXQdcJ5XVtqPZbjxzHt3Yf/9GkuabDtNpZa5xIATdtuBSUTuwa0RmJXsXcdnsEReMf1cel1mqPCauOlrCKW5pcR6KHmicQobowOQe3mN8O6ujpe+mIDGVZ/3rxhGLt+20JKSgq9e/cmOTmZhISE865gFcJOZtYb1NYeobY2E5MpByGsxMbMpmfPf+FwWNmz9za8vRPr17+dad/TM6motbBqXwGzR3ZpViJR/O//UPHhh8S8/hr+F1/c5PO0J0XHjpJ7YC8Dp16C1rP5I8dmSxmHDj1OefkGQkIuoHfv/6DThrZApM1TWlpKSkoKe/bswWKxcMcddxATc2o/w1MrZT9D7dv8dh+1VWY2fHqYUbO6ERx17vNV1Fqw2BxEBniSV2nk+32F9IjwIyncl5hArwbbnBhrLBxPK6fnyCgACo5WEdUtAKWh6d21z8DW1+Hh/RDgutYvUvPk/+Wv6NesIWnNajRhYe4Op2VUHYeF42HS32HonPO+u9lYi4enByqV64sSZWLXAFcndkIIPr1zBlW1NiYMjaTPLf9ACenmsus110GDiaeP5rG9qpZHEiL4a2JUq8dgMpk4fPgwaWlpHDt2DLvdznpbD5SAKBZcP4Ce0YGoGvEpUQhBXd1xqqpSqa5ORa3xpXvSEwBs2z4RRdGcsnWWn3//Jk3bbcso48Nt2bx1w2C0muZ/etVv2EDe3fcQdMMNRP7j780+X3uRe2AvX/3fU/iHRTDlzgfo0n9gs88phCAv/yMyMl5ErfajX7+3CQo8v1EoVzGbzRw+fJh+/fqhKApr167FZrPVF1vUV8qOG0fs2281q1I2c08p6z9Kx2axM3lOMt0GhTf6vk+t2M8nv+XW/7+Xh5qkcF8+vWMEfp4eZJfVIoD4YO8zrssryzPwxXM7CE/wZ9y13YlMPEt7FJsFXkuG2GFw/Wfn+xClVlKXnk7WrCsIueMOwh+Z5+5wWo4QsGgSGMvh/lRQN262xWqu49fV/6TK+AOR8aMYNupdFwcqE7sGtcaIXVnab6xZ8DIFJSZivauZfEEPQi55EkKTXHrdphJCsLK0ilEBvoTrPMgw1uGtUhHtwvYoJxeLl5aWsmDBAhwOB/7+/iQnJ5OcnEyJw4e7P95NndXO69cOZPIZ9r0Uwo6iON/8MjJeorDoayyWUgDUal/Cwi6iT/LLgHP6tbmL64UQLN6azfM/HCIx1IeP5444pT9dU9kqKyn/30LCHpmHysUVvO4khODwtk1UlxQzYpZzZ4HcA3tZu+gdKgvz6XvhFCbMnoOnT/P7uhkMh0k//Hf6JL+Ml1fbnNZeuXIle/bsweFw0K1bN4YPH05oairVn31G/IcfomlEZe2fWS12ti7L4OCmfELjfJkyt0+T1r1VGS1klBg4WmLgaLGB45VG3p09BEVReOSLPXy9Ox+tRkXXUB+6R/iRHOXPPRc4P8A67A6OphSzbcUxjNUWeo2MZOSsbqdP0e5fBsvnwo3Lofvk845Rah3H77ob4549JK1Zjdq/hdvcuNuhVfDFjXDFIuh/9VkPE0Jg0B8id3chW774iJCBe/GPUZGQOJceyfe6PEyZ2DWgtdbYCYeD/T8uY9Pnn2C1Wrn66nHEXtk+Squv3pPBzmojD3UJ5+64cDxbqD2KwWAgPT2dtLQ0QkNDmT59OkIINm7cSFJSEtHR0aeMzBVUmbjro1QySgxsfvxCAnQmqqt3UVW9i+rqVGprMxg7ZhsqlQdZ2W9jrM0kIHAIgQFD8PFJqk/6WkKd1c5TKw6wfFceFyVH8Oo1zd/zVlitACjNLPpoD6qKi/jl/XfI3ruLqKSeXPvMf1BrnIm21WJm+1efsvO7FfSfPJXJt9/XItc8+eFBCEFGxotERV2Jr2/PFjl3S9Hr9aSmppKamoper2f06NFMnjChyQn+zh+z+e3bTAZeFM/IS7u2TCuSP0kvqmFfXjXHTiZ+JXp8tBp+etjZcubmD3ZQWGWiR7APPSocaDJq0flouO2FMafGs3g61OTDA7tl8UQbZdy5k5ybZhP26COE3nGHu8NpeQ4HLBgFigru3nra89BiKaeo6BsKCr6k1pjBoS+6Ehjcl/E33kBcn6Gtto5XJnYNaO3iidqqSlK/+Ywx196M2ssX05b38CrYAuP/ApF9Wy2O85FrMvPMsQK+L60m3lPLM0nRXBwa0OQn8d69e9m9ezc5OTkIIQgODmbIkCGMGTPmrPcRQjgb+arCSSsyE6n+jiNHnwVAUTT4+fUhIGAwXRMfQqNpfCVfU93/6S5W7Svk4cndeXBi9xbZWqn43//BtG8f8Ys/6LAjdXablZ3freDX5Z+j0qgZc+3NDJw6HdUZqtGKMo7gFxqGT2AQ1SXFeHh64u3f/F0O6uoKSNk5C5uthqRujxMbe4vbCyv+7OTOFmFhYYSFhZF77BibFi9m5AUX0G3SpHPGKxyC2moLvkE6bFY7Jdk1RHdvfNuglmCzO9Cc+AD4v43HSM2pJKPEQE55Lf42hQkRgcx/bDRCCJ5dvBvPaG9GK/uJ84XwYbOaXHQkuVbttm2UvvMO8e+912q9Flvd3s9hxV1w6/eQMBZwvmYczXiR0pLVCGz4+w9E6Pvhox5B8tiprV5AIhO7BrizKtZsrOXD+28mTlvIBaFH8O471ZngRQ90SzwN2VKp56mj+RyureON3vFcE9m43mrV1dUcPXqUIUOcUzcrV64kNze3fpo1IiLitDcqh8NCjX4/1VWpVFWnUl29C6u1goEDPiQkZBx6/UE27lvJykOhPD3rCuKbME3VHOlFNeSUG5nap2X6bOl/+YW8++4n6MYbifz70y1yzraosjCfJY/dR9chw7nw1jvxC25cMcMXzzxBed5xJs25hx4jxzQ7EbNYyjh06EnKytcREjye3sn/bROFFWeze/t2fvj+B6waNZEhoQwfM5q+ffue1p+xttrMuiWHqCw2ct3fh6P1bFsJUp3VTnZ5LTa7oG9MABm7S/h54QEyPez84mmlSu18f7hzfFf+Nr03QgiWpeaRFO5LUrhvs0fFJalBdivk76Iu3Nkhwd+/PzUVeezYOYOyQx70GvAAAy+42a0hysSuAe5M7GwWC7+t+IId3y5Dq1EYH55FX59slDEPwJTn3BJTQ2wOwedFFVwZEYSXWsUBvZF4Lx3+mlNHXCorK0lLSyMtLY38/HwA7r77biIjI7Faraf1mLNYKqiu3oWnZzR+fsno9QfZkXIpAF5eXQgMGEJAwGBCQyeh0zkXfm84XMIDn+1Gq1bxzo2DGdHVtcndZztySS+s4ZnLWnZk1ZKXT9YVV6CNjaXL55+hauFmyu5mMug5sn0zAy6aDkBlUQFBkee34XZpbjY/L5hPceZRkoaNYtLce/ANal7TZiEE+fmfcDTjBby9Ehg+fFWDVc/uVHPkCJv+9hQZ3bpS5eVFcHAw999/f/1yhez9ZaxbeghLnZ2xVyXRZ3xMmxuJ/DO7zcG+NZmkfJ+JzaHBf2AIFfGe9E0IZGKvCPKrTIz597r646MCPEkK92XO2EQu7BmOxebAaLER6N2x/mbaGuFwUPXllwRcdlnHHanDOaBQVraOgoIvKK/YjJ9vX0TBjez45kus5jr6T57O6Kuuxzsg0K1xysSuAW2hj1153nHWvPcW+ekHiYnyZ9ac69H1n+lsmlh2FOJHuDW+s7ELwZjfDqG3OXiqaxTXRASiUavJzMxk6dKlAERFRZGcnEzv3r0JDf19REQIO4WFy0+MxqViNGYBEBs7m549/oXDYaOs/BcCAoaccyTlWKmBO5buJLfcyL8u7cNNI1t+Fw2LzcEz3x3kk99ymdAjjHdvHoJO0zLr9YTFQvZNs7Fkdrx+dUII0rdsYP3SRdQZ9Nzy8tuExMQ1+XwOu52dq1aw7atP0Gi1XPm3Z4lKav4aOYPhCFZrJUFBI3A4bAhhQ61ufhGMK9Ru20bOHXdimDgR3dw5DBg4EJvVzvtvfUJtthdRIfFMub0PIdHNLzgBKLfYWFdRQ08fT/r7ebfIOU+T+iG13/yTX6M+In2fjfAEf6563Dm6b3cIjlcY69fuZZQYyCgxcO8FSVzcN5Kd2RVc9b/thPrq6B7uS/cI58jelOTIFilkkpyqv/uOgr/8lZjXXsV/2jR3h+MSefmfkpn5GlZrBTpdJFHmSPb8ZCQ7R03XIcMZf+NtzXr9akkysWtAW0jswPmJ6MDGteTu38v0Bx5zLvLe8BLKhuchcQJM+Gv9fH9bsjEnn39mFpKOhq7YmD+4NwO9tezYsYPk5GSCgoKw283U6PdRXb0LlaIhPn6us0Hq1jE4hIWAgMEEBDiLHPz8+qFWn9/6spo6Kw99tpv1h0v55r4xDIwLbLHHV6o3c+8nqaRkV3L3hG78ZWrP89pqqSHW/Hxy58wlbN48/C+e2mLndbfKwnzWvr+A3P17iErqyeQ77iM8oWuLnLuiIJ9fv/6ci+64Dw+dZ/02XC0hK+tNiku+p0+f1/HzbZt7X1Z8+ill89+gy+efoUtMpLy8ggVvLcQmzAQEBDJs2FAGDRp01p0tGlJrt6Og4K1WsSS/jMeP5AEw1N+bObFhzAgLQNtSa4qEgIXjnN/v3kJRdg0Wk4345BDsVgcVhbWExZ99zWx+lYnv9xXUV+xmFBvQm20su3sUQxOCWZtWzMJNx0gK96tP/LqH+xHhr2vzo5lthbBYODb9ElR+fiQuX9ZhGhLb7UaKS34gLHQSHh5BFBZ+TWnZWrT2kST2vALdznfJXfk6zHiN+AlXujvcU8jErgFtJbH7s5rSEr75z78YPySchLxPnPvYdRnjTPC6XuDu8Ni0aRP79u2jrKwMAVT1HsAvkYmUOWDloCSGB/qSe3wxxcXfo9cfQAhnxWdQ0GgGD/oIALO5BK02rEVeYO0OweajpVzQ0zlN+8fF280559TXN5FXaeSlqwZw6YDzmz5sLIfF0qGmX+02G4semIvFZGLc9bfQ/6KLz1gc0RKs5jo+/8fj9J98Mf0nNX8Rc3nFFtLS/oLVWkVS0l+Ji72lTU7PWsvLOXywjsQBofgE6LCYrRzNOEJKSgrZ2dmo1WrmzJlzWuPjs57PIdhYqWdFcSU/llXzr27R3BwTSrXVxjGjmdQaI4vzy8g0mUnw0rJ1RO+WaV5+PAXenwyXvArD5p5y0561uWxdnkHv0VGMvKwb3v4N/40IISiuMRPk44FOo2ZtWjHvbsrkSImeKqO1/rjNf72QuGBvNh0pJb2ohu7hjW++3NlUfPopxc/+H3HvLsR3/Hh3h9MsQgj0+v3kF3xBcfEq7HYDvXq9QEz0tVQW5rPpkw/JSNnOuBtuZfjUi+C1ftDtArhmqbtDP0VbS+za1kreNsykr8Fms7H8m530Gj2XCwZ74bNnAfy6oNUTOyEEhYWFHD9+nBEjnNPCBQUF+Pr6MmzYUBISdNhs6dxc+QXfVXsz1N/ZxmVXTS0RaIiPu42AE2vktNrf10WdXCvXEtQqhQt6hiMcgt0Z5fzl2wPMv2EQvTy1WPINOEy2+i9hshFwSSIq3bmfjmqVwlPTexPur6NPdPOrMf/Imp9PxdKlhM2bh8qzY0wZFWYcJqJrEmqNhmn3PUpwTGyz18E1xGIy4enry9pFb3N42yam3PUggZFNb6odEjyWEcO/51D6kxw9+hzl5RtJ7v1Siz5Xm8ukt7Du8zyy95dTtm4bw2ck4j10KH369KFPnz6UlJSwd+9eIiOdhT27d+8GoG/fvqetbbULwd+P5vNtSRXlVhuBGjVXRgQxyN857RrgoWFwgIbBAT7MjQ1lY4We3DoL6hNtY549VsBFIQGMCvRp2ge0ne+D1hf6X3PaTcljoqmttrDvl+McSy1h2IxE+l0Yi/ocH9gURTllCnZycgSTkyMQQlBea+FosYGMEj0xgc51YusPl7B4a3b98V4eanpE+vH1PaNRqxSOFOvRqlXEnaX5cksTQiCsjvrXKYfR+ZqljfND7a/FWlSL4bdChMkGioImzAuPcG90XQNQebd8YYnDaKTsnQV4Dx2Kz7hxLX7+1mS3m9iZejUGwyFUKk8iwqcTHX0tWlV31n24kL2rf0DtoWXMtbMZdPEM0HnC8Nth86tQegTCerj7IbRZcsTuPNgsFnZ8+xU7vvkKjU7H+Otuov+oYeAXCeXHYMXdMO5R6DEVWnhaweFwkJ+fz6FDh0hLS6OqqgqVSsXDD9+Lr28AoKa4eAVHjj6PzVYNgIdHMIEBQ+jd+98Y8WXI9jTCtBqeTYrhotDGJ0bCIUCAolaw11qx/ikxc5hs+I6KQhPkielQOTVrcn5P2sx2EPCwr4UDZgsf9u1C7O7y30+uVlB5aQh/YBCaAB2GXwtQ+Wjx6huCoijY7A5e+CGdLiHe3DI6oUV/p/WP74/7wH6zwiV7gbYmk76GjR9/wMENa7nozgfoP6l1p5SFEBxYv4YNSxfhsNsZe91sBk2b2axRQiEE+QWfkZHxHwYP+gh///4tGHHT5aaV88uHhzAbbYy8JA7f+ffjaGBP2aVLl5KZmYmnpyeDBg0iuN9AclUeXHmiqv3K3RmEaDVcER7EhSF+6Bo56llQZ2FSymEqbXZ6+ngyJyaUqyKC8Gns+lMhYNU80PrA1OfPelhlUS1bvjpK7sEKug+LYMrclt2asbLWQkaps/Hy0RI9NSYbr1wzAIBbPtjBxiOlpzRfHhQXyJyxiScegjgtoRVCICx252vSicRME+yJJsgTu96CYVvBaR80/SbG4dU7BHNmNaXv7jstxpCbeuPVN5S6I5WUf5aOyksDDoG9ygxA2L0D0MX7YzpcgTG1GI9wbzTh3s7voV4oTdwRx5qfT8ETTxI2bx7egwc16RzuIoSDyspfMdQeJj7uNgDSD/8TX9+eREbMrG+L9c1/nyMzdQf9Jk5h9DU34hP4h9ZAhlJ4vR/0vRIuf9sdD+OM2tqInUzsmqCiII+1771NUHQMF91xv/OH2Vvgm3ugKhci+zunaHte0qzGng6HA4fDgUajYffu3Xz77bfodHV076EiMtKARpOD0ZjOoIFLCAoaSWVVCkWFX9c3AfbySqh/kRPCObXz9JF8MkxmLtB58rTOnwQLOEw2PHuHoI3ywVJgoHpV5qkvdGY7Ibf2watXMKa0csqXpp0aqEZF2Ny+6BIDqMuowrAlH5WXBpWXBuXEd1NSAPeu2EdGThX3DovntolJqH08UDxUv8foEJQs2Iv1uB5tF3+UC2N5aPNRth0r545xiTx1SXKTf5fn8vs+sK+363V1QgjSNq1j40fvYzbWMmTGLEZdeR0eOveMQOorylj73tvUGQxc98x/WmQtkM2mr38DKC7+ntDQiajV7qkKPPxrIWs/PERQlA9T5vYhNNa3UXvKCiHYkZHJ4vRMtggPyvwC0SJIHz8Ab7XqjMlJY5nsDr4pqeSDvDL2G0z4qVV8MbAbg/2bv7ftnx9Dzv5yvAO0hHfxp85gxWyyERDmmn8LIQTCbCc9u5LMvGoyq+vYozeRVaznWkXH9f1jcJisbNhXhJddkB2mw9griN6+nvT9LgfFcer5AqYn4jc+FmupkeJXU095rVJ5afAbF4tnjyDsNRZqdxXX//zklybUC9UZWtc4zHZspUY8IrxRPNTU7iqm5pdc7BV1cPKtVgVRT4xA7a/FnFWNvdrsTPrCvFA8XLNEwp3qzEUUFi6noOAr6uqO4+ERzJjRm+sLooQQHPl1K9E9euEXEkp53nGEw05ofMKZT7h/GUQNbFM7RcnErgHtIbED55PRbrWi0WopzDhMxo7tjLz8KjwOfwubX4aKTIgeBHPXNnqPO3A2Qs3NzSUtLY1Dhw4yblw3+vUbihChpKf/TFX1XwBQKTp8PZLxU/UjxDEV/7hkdF38sRssVH6d8fvUwYmvgIsT8B0djbHQwJvfHODdbjosalixuZbIOkHQld3xGRaJtaiWym8yTnkRUzw1eA8IwyPcG3utFVup8cRtHs7bG9k932Jz8I9vD/B5ynFevnoAVw05fURD2AXG1GLKf85CVWtjo2LDf1oCM8cnNvp3eD46Ur+61e++yf5ffiaqRy8uuuN+ws72wtiKhBBYTCZ03t7UVlVycOMvDLnk8vpdLZqqtvYYv/42FW/vbvTt8xp+fq5J+s/kZOJVV2tl95pchk1PQKP9/Q25oT1lPyss55H04wign7eOQcZKro2LZEhSVyoqKkhLS2Pw4MF4eze96lUIQWqNkU8Ly3m+eyxeahU/lFahVhQmh/ifvh7P4YCStCY3Zd/0+RHSthQw8KI4hlycgIfu9ARFOJzJmcNkA0AT7Hxjr00txmGwnPJhUhvnh9+4WOeyk+d/w1Fr/T0xAnxGRhF0eRLC7iD/qa2gApWXhmqHoFo4WK2x82GtAY2AFyNCmTI4BsVLzYepefgF6gjp4k9ClyC6hvrg5aFGcfG0rrDasZaasJUYsZaa8J8cj6IoVHx1BGNqsfMgBdTBnnhE+hByU2/njEWV2flaq1NTs2YNXv0H4BHRdpYhNKSo6FsOpj0GOAgKHEl09LWEhU2pT+oKjhxiw0fvU3gknRGzrmHsde7tR9dUMrFrQHtJ7P7otxVfsuXzpQSERzBpzj0k9h8IB7+G6uPOqVmAjF+ca/FUaux6Cw6jFUedvf6FTPHV8Ev6ZvLyfkGryyPQvxR//zJUGgvBhdPoGvIYflOiyc1ZgvVzDzxruqCI398c/S6II+DiBBxGKyUL9532CdOrTyi6rgE4LHbMmdWUe8A6m5kbo0NQeWnYXWtioL83KhdXpgkhWJNWzKTeEahVzvYJf14rU6o3M/Wl9dyg0nGN0BJ51wC0MS3TLuKUWKxWMqZORRMY1G771dmsVoTDjofOk+Np+6nIz2uRogVX2PXDt6xf8h5hCV2ZevdDRCR2a9b5Kiq2cjDtMazWSrp1e4z4uDkuLawQQnBwcwFHU4q59KGBqM8xnVbxyScUv/AikUs/Ylt8Il8XV3J9VAiTQ/zJMppZVlzBFRFBdPM+dTT1t99+48cff0StVtO3b1+GDx/e6IKLhszafZTtVbXEenpwa3QoN0SHEOxx4jXk2Dr4aBbc8KVzKcnZfgcOgaizIawO1Cf2lq07Uokx30B2ajHVeQa8PNVE9A4m4eZk537Ti/ZjyTcg6mz1yZmuRxBhc5xJZOGLO7BXm+uXZai8NHglhxAwzflhruqHLJQ/3Kby0jjXskU4RyEdZhuKVn3aKGed1U5WWS0alUL3CD/0dVaueGcbWWW12BzOQBQFHpvSk/suTMJksfPdvgK6t2LzZWFzYCs3YS02OpO+EiPC6iD0Fuf0dumi/ZgzqlD5abBk7kMT5kXw9dPwHhDm8tiawmjMoqDgK4KCRhISMh6TKZ/8gs+IjroKb++E+uOqiovY/OmHHPl1Cz5BwYy59ib6TJjU+OUaZUdh3XNwySvg4/5G5jKxa0B7SOyE1X7qGjOjjbKCHNZ+/y4VBXmM63c9XRL6obarnbfX6NFW/0Rw5I8w7jEKvkvEWmsmzyuT2sAjxBBIZPhlrLL8SnTMq6gUI9q6WHwtvfGx98FfGYh/Ug+8B4Q7t/LaW3rKtEH9yFoTq04zjHWM/y2dAX7ePN8jpsWnbc6msNrE7Pd38I8ZyYzvceoL1fLUPMb1CCVUq6kvqqj8NgO1nxbfsTGotC0zZWHOykLRaNDGtY1+SOcj98A+1i56m65DhnPB7LkN36ENOLpjG2sXvYNJX8Pwy65m5JXXoWnGXrwWSwWH0p+krGwtYaEX0a/fApe0zagzWFn30SGy9pYR1zuIKbf3xdPnzHE7hGBrpYGvMnL5yWynxuYg1EPD37tFc21Uw8UrJSUlpKSksHfvXiwWC/Hx8dx6662n7NPcFFaH4Oeyaj7IK2VbdS06lcITiVHMVXtjW/kSjtICHKOfwmERgELgdGdiVfltBnXpFaesmdWEeRH5qPN9rGThXixZNc6LqBQsQlBuduC4II4Rl3alenU2DpPtlFF+TbAnuq7Odb52vQVFpz5lWYYrWe0OcsprT6zhMzAiMZgRXUPYl1fFpW9trT/uZPPlByZ2Z3hiMHVWO3VWe6s2X647UoklX49+za/YKq2og7ugSwwg7PZ+AM71fyrl1DV8Ed6oz/LcdAW73URJyU8UFH5JVdUOFEVNYuJDJCacfU/p1Qvf4NDWjQybeQVDZ16B1vM8p/BLj8Dbw50DJ5P+3sxH0HwysWtAayR2Z6p0EnYHnif2b6xNLT6tQEDl40Hozc7pnpJ39mDJ1Z9yTo84P0Lu7MPOlcvRbREE+UfhFexfn3RpPfPwLHuO/Y4KikJDwK8SnWctAN66JEYMWoXipUFvOIiXZzweHv4u/R38kUMIlhVX8tyxAkosNq6LDOZvXaMI17n2xSGv0sjtS3ZypFjPY1N7siunijljEhiddPonMOEQlH9yiLqD5aj9tfhP6YL34IgmT6EYd+3Ga9DAdtk7y1hTzaaPP+Dgxl8IiIhk8tx7SRgw2N1hNZrJoGfj0kXOadkZs5qdlAohKCj4HJVKS1RUy/e3ykuvYO3iNEwGK6NmdWPAxLjTnndCCIotNiJ1HjiEYMSvh6i02pgeFsDFBTmMDfDBf+iQ87puXV0d+/btw2AwMHHiRMA5ote9e3eCAgJBpTin6yrqsJYaT1l64Vx+kYiiVtBvyceYWnzKmtkMfzU/XhnHpBB/hv6cSe7hWlJC1EwqsqFVK2gCPYl8zPk+pd+Yh7Wo9pR1aGp/Ld79nR/GbFV1KIqCcmJZhhCQvq2Q2N5B+Id4oa+oQ6NV4eXbtkfET2u+fCLxe/qS3ozoGsLPB4u466PUU5ovdw/3ZXq/KEJ8XbeXtDkri8wZMwm6/noi/vY3RJ0NlbcHQgiqvs7AUlSLrdiIsNgB8B4cTvA1PRFCUP1dJppQLzThXniE+6Dy82jx17wdKZeh1x/Ayyue6KhriYq64rSqdbvNyp6ffyCmVzKR3bpjrK7CYbfjG9yM3Ym+uAkyN8G8A+DZeu+XZyITuwa0RmJX8cVhjLtLTvmZykdD9N9HAVD+URp1x6pOWywbNKs7AMa9pX/4BHriy8ejfs1IVVEhXoGeGIwHyUr/DodSwLCRS9i0cRN5+S8SHJyPovciLPFyuiZNJyCgLyqV+/dcNNjsvJZTzLvHS/HXqEkZlYx3M3vPNaSiwsQ/vj3AqsMl+CkKT4zoyg2X9Tzri485s5qqH7OwHtfjEelD0DU90J5nV/+T6+qiXniBwCtmtcTDaDVZe1L54c2XsZiMDLv0SkZccS0eWte9qbhS1p5UIhK74R0QiL68DE9f3xYp9CgoWEZ1zW56dH8Ktbp5uzM4HIIvntuBwy6YMrfPac15c0xmvi6u5OviSsqtNvaO7ouHSuGQwUSClw5Ph53MSy/DXlVFwldfoY1t+rRqRUk5by54CyEEAQ5vonvGExETSZeaIDy21ZxyrOKhIurJ4ai8PTDsKKTuUMWpo/teGnxHRaOoFGw/vMLC/CL+L+lGQj003BQdws3RIUR7tkwituqtvRRlVjN8ZiJ9x8egcvFriqtkldWyJq2ofqTvWImz+fIvj06gW5gvy1Lz+GrncXpG+tE9wo+eJ74Cmtn2JG/ePAwbN5G0+mc0oWeedhRCYK+2YCtxrn/WxvlhN1goejnVOQV+guKpca63HhmFw2LHklXtHOELaFyDaKu1huLilZSU/sSA/u+jVusoLfsFjdqHwMDhpy2FEEKQsWM7mz5dTFVRIcMuvZLxN97WrN9Hvfxd8N6FMPlfMHZey5yziWRi14DWSOxMB8uwlppOTcy8PerXcZ1vVdrJ36GiKJSWruZY5uvU1h4FHAihYKryws98J30nXUOlvoLELkloDPkQlAAOO3x8JfScBoNvBg/37/uXaTSzR2/kigjnCOaumtoWn54tzzewb30eR34rov/EOHJjPfDJNJKzvoDQOF8GXRRP0pDwM74JCCEw7S9Dvy6X0Dl9UfvrEDZHo1oI1O8DGxdHl88+bTfr6k4+JysK8vjl/QVceOudhMa1/HZt7iCE4LN//AVTdTVT7nqAuD7Na2WSmfUGWVlv4O2dSJ8+r+Hvd/4FAVUlRrz9tWg9NVSXmvD2155SELClUs+LmYWk1hgBGBngwxURQVwTGYznn56z5swssq87d6XsuTjqbOT8sh/brxU4rA4ywysp0+g5bMhEY/Hg4slTGBTXl8KaElZv/YXwiAgiIiMIDw8nIiICX99zfPARAt4ejiOwC5umf8AHeWWsKa9BpcAlYYH8L7lLs9fdVhTUsvnLI+SlVxIc7cO4a7oT28u1/RRbw8nmy2F+OtQqhW9257N0ezZHig0YzL8nUwefmYqPTsP69BJKDWZ6RvjRPcIXb23DBUTCbqfwqafxiI4m7MEHmhSjw2A9ZQ2fV58QPLsHYc6tofSdvQAoWvWJUT1vfMfEoI3xRdgdzkWIClRV7aCg8EtKSn7E4TDj65tMv75vnrJu7s+KMo6w4aNF5KenERIbz4Sb5pAwcEjLjhguvRyKD8LD+9z63ikTuwa0hzV2DocNgyGN6updJ/ZW3UXfPvPR6frwww8vgbKG6uowrJZ4IiNG4sgvInPTL/iFhjFpzj10GzL895MZSuDLWyB3G/hGwJiHYMhtoHXRPpDnaWOFnmv3HuOiEH+eTYoh0bt5o0NZe0vZ+8tx8o9UofFQ0WNEJP0vjCUkxhe71cHhHUXsWZNLZZERv2BPBkyOo/+FsWd8MTiZ7AghKHtvP+oAHf5Tu6AJPPOozyn7wK74ul2sq7NZLPz2zZdUFRVyyYN/cXc4LnP84D5WL3yTquJCBlw0jXE33IauGVWhFRXbSEt7DIu1gm5dHyE+/vZGFVYIITi0rZDNXx6l9+goxl/rbIJaa7PzY1k1/fy86enjybZKA08dzeOKiCBmRQQR28DoVkOVsmficDjYWbyTr3Z9xt1bZrDfN4PSQVZuu/huykxlPL3laXYW7MRD5cGUblOYEjCF7F3ZlJSUUFtbW3+euXPnEhcXR2FhIYWFhYSHhxMeHo725Icas965D3aQ84NCjsnM0oJyKq02Xu3l3Cv557JqxgT64tvEPZmFEGTtLWPrsqPUlNUx6dbe9BrZ9MbVbZkQgoLqOo4U6cmrNDJ7VAIAd320k58PFtcfFxfsxZD4IF6/ztmPrrDaRLCP9oz7XjenBc7ZOCx2rHkGrCW/J33WYiMh1/dE1zWQ2n2lVH11BEt8Hpnd/oYaH0K9Liaux40EhAxo8Py/Lv+c3T+vYsw1N9H3wotQNeI5f95ytjkLf8Y8BLqzb3XnajKxa0BbTOxsNj0OhwWtNgSD4TApO6/E4TABoFJCUam7M2jg4/j59eWDDz4gOjqa5ORk4uLi6hc856UfZO17b1Oel8u1//w3scl/GkXI3gIb/wNZm8A7FG77AcKav6F6c1kcDt7LK+PV7CKsDsFdcWE83CWi8U1PAUudDe2Jnk8/vXuA4uxq+k2IJXlMNJ6+p09TCIcg+0A5u1fnoPXSMOO+Aaed55Tj7Q6qV+dg2JoPgN+YGPwujDutz1Txiy9SsWQpMfPn4z91SqPjd5ecfXtY+/7bVBUV0nvchUy9+0HUGvdP2buK1VzH1i8+JvWHb/ELDuWKJ//VrFFJq7WSQ+l/o7R0NYMHf05Q4LBzHl9Xa2XDJ4c5tquEmJ6BTLilNzsdFr4uruSnshpMDgfzukTweNeoJr3RntwKKuaN+fhPOfvzz15jRr8pn7zsLK73e5hgz2Bui7+ZywddSaBn4CnHZlRm8Pnhz1l5bCUmm4lPp39Kv7B+GAwGSkpKKC4uZtCgQXh6erJ+/Xo2btxYf9+goCAiIiK4/PLL8fT0xGQyodVqUf/pDTjXZGb4r4fwVau4NjKY22JDSfJu2pS5zWpn3/o8+o6LQeuloarYiE+QDo8WKoZqy+wOQW6FkcNFeo4U6zl8YheN164dCMCMNzdzqFBPYqgPPSP8GGIpoXekH6OmjWm1GB0OG+XlGyko/BKtLYyogjlYSmqptG7AK6c3KoeOyL8MRRPihXFPCaa08vrCDeGvkLr5O6J69aL7sFFYLWaE3Y7Wq20MUriSTOwa4O7ETghBXd1xqqpSqT4xGmeoPUKX+DtISnqcmppy9u77B0WFPmRkgNnsTUxMDHfccUeD57bbrBzZvoVeYy9AURSKs44R1iXh1BLvnO2w52OYMd/Z/+74DmeC59myW2idr2KzlecyC/iqqJK+vl6sGdqjwTe2+unWHUVc/cQwgqN9qDNY0XqpG73Oxmqx46FVU11q4vPndtBzRCQDJ8cRGH76i4Wtqo6an3Mw7ilB5aUh9La+aON+/xRn2LgR4549hD/00Pk9+FZm0tewfsl7HNq8nsDIKCbPvY8u/Qe6O6xWU3AknR3ffsUlD/0VD62uWaMVQgiqq1MJDHS+5hqNOXh7n54sluTU8OP/9mOstjDisq70nxzH2JR0sk0WgjRqZoYHckVEEMMDfJo1NVn72w68hw874+PRl1SS9v12oo76okLBo18QWwcc5pKeM9Cpzz1Srrfo+SX3Fy7rdhmKorBgzwIsDgvX9LiGKF/nyJjD4aCyspKSkhJn0nf8GJXZ+7nz1ptQYofwzTffsH//fsLCwupH9SIjI+nWrRu7TuxN+21JFVYhGB/kyws9Ypuc4DnjEXz+fzuw1tkYc1V3ug1umX2q26sf9xdysKCGw8V6jhTV8NCKl4i1Gxi2bQOKRsNNi34jzE9Hjwg/ekb60iPCj5hArxb5nZlMuRQUfEVh4XLMlmI8PEKIi51NYuLv07/1zZejfVFUCobtBei35J/SfNku7OQNyGPMDTdRd9hZSe3y5stCwOEfQK2D7pNdc40GyMSuAa2d2DkcFvSGQ9hsekKCxyKEg02bh2KzVaNW+xIQMAgvz75ERU0hIKA/q1atYufOnQQHB5OcnExycjJRUVHn/cdVW1XJogdvJyQmnovuvP/MPb1sZnitD9gtMPJeGHEXeAWdflwrSq2updxqY0poADaH4LCxjj6+v69tcDgE2fvK2Lf+OPmHq1B7qOg5PIIh0xLwD236Ggh9RR07f8jm8K9F2O0Oug0MY9CULkQknl4NZck3oN+UR9CV3VFp1dgqalEHebebNw1jTTVL//oA/SZOYcTl16BpJ+sAXcFaV8fyF//BkBmz6D5sVLPOpTekk5JyOVFRV9Cj+9OnFFak5lUxf/0xarv7smyE80PL0vwyInUeXBDsh7aF+wLWHTmCo7YW70GDKDOVsXb9d4zclIhAkNGlmAuvuQxNSNP/Xp7a8hSrMlcBcGHchVzX6zpGRI449W/gp7/BjoUwLw38Ijh69ChZWVkUFxdTUlKCXq8nJCSEBx5wvrmvXr2aMqudXYHhbBQefDugK9F+vqTXmgjz8CCkEWvG/qzgaCWbvjhKeZ6B6O6BjLu2B6GxLd+zsr05WeDl89TfiZ99A2abnTuWpnK0WE9hdV39cXeN78qT03tjttn55NfcE4UbvoT5NlwMYbebUam0KIpC+uG/k5//OSEhE4iOvprQkImNKujL3rebDYsXYS8zkZg4iF6DxhE9ayAAZR8epC69wnngiebLui7+BF/jnImyVdSh8vFAdYZm1ufF4YD/jQHhgHu2N2u3p6aSiV0DWiOxq6z8jfKKzVRXp1JTsw+How5v726MGrkagLKydVitfmRnWzl0KJ3c3Fxuv/12YmNjKS8vx2q1EhER0axEQQjB4W2bWL/kPUw1NQyePpPR19x0ej+fgj2w6b+Qvgp0/jD8Thh1H3i7f/Hx0vwyHj+Sxw1RwTyRGEmYTktdrZUlT27F09fjnNOtTVVbbWb/+jwObMrHarFz67/HnLONgsNYR/7f16L21xFyy3B0Ce4d+TybsuM57Pn5eybOuQuVSo3VXOe2rcDakuqSYr595XlKszPpOWocE+fcjbd/0/4NHQ4LmVnzyclZiLd3At7h/+bTdB92hiocrK1DBUwI9uPdPgn4NXEtWWMIIci+6mpsVXbS7p7KM3Xvorap+Jv5HpIuGky/bi2zB2iBoYAvD3/J8qPLqTJXMbfvXB4e8rDzRosRXu0N3SbC1YvPeH+j0YjBYCA83Nm64osvviAzMxOz2Yyz0x306dOHJV0HsN9g4kKdipsjAhkfF4XmPHYWcTgEaVsK+PXbY1iMNi5/ZBDR3d37AdadhN1O1uWXI6w2uq76DuVPv8tqk5WjJ6Zye0X6M6RLEOlFNVz8+ub6Y4K8PegR4ceDk7ozJimUOqsds9VBgLcHekM6BQVfUFT0LQMGvEdgwBDq6gpAUeGpi2xcjCdG0dM2r+e3r79g/E1z6Dr41JHoMzVfVjzUBF/tXLdaPH8X1sJa1IG6+h58usQAvPo0oQXKvi/h6zvguk+h1yXnf/9m6nSJnaIoHwAzgBIhRIPlaa2R2B1Me4zi4pX4+iYTGDCkfm9VnS6CyspKli9fTl5eHgDh4eEkJyczaNAgAgJaPimoqzWw5bMl7F3zI/5h4dzy37fOvCahaL8zwUtbCbd8B4njWjyW81Vjs/P8geN8XFGF1i54omcMc2LDqMozEBLj49K2BpY6G0WZ1cQnO18E1n+STlTXALoPizhlR4CiF/6NfsNRvEfegrAoeCaHEDAtAY+wtrHuw2ox89vXX5CycjlaL2+ue+YlQmLbflFHa7LbbKSsXM6vyz/Dw8ubibfdRa/R45v0warKaqO6aidZBx5ms6MXb6seZoCXJ1fHhnBZeCBhWteuYRRCsHdfChFbHdhzrdiMBXx2+UFuGDqXLv6uqXI22838nP0zycHJJAUlkVaexort/+H6vavoeuO3kDD2vOKvrq6uH9Xz9/dHl9SDD46X8mleCTa1hoiaCi6sKmKsj5a+ffvSq1evUzoHnE1drZUDG/MZfHEXVCqFisJaAiO8Ubl4u6+2puqbbyh84snz2rtaCEGZweJcu1ek52iJ8/tjU3oyOimUdenH+XDNAiZ1+Y1Y32wcQoPVYzwDej9ETFjjq8ZrykrZ+vlSwhK6MnTGLMSJ/cybskWg6VA51sJaZ/FGsXOrNa8+IYRc3wuA4tdTUflqT2m+7BHpjepM7WPsNnhzsHMXitt/cVbztqLOmNiNBwzA0raS2JnNpWg0PqjV3pSXl5OWloaPjw+DBw/GarXy0Ucf0b17d3r37k3oWfoGtbT8w4fIO3SAEZdf7YzRaDxzVWBFJgQlOp+4a/8FdiuMfgD8GvdJqyU47A6y95U7p1uPVFERpGHz+AD2eQpmhAWwqK9r9nU9G4vJxtcv76I834BPoI4BE+PoMy4a87aNzn1gZ88m/C+PY9iaj35DHsJqJ/yegaesv3OH7L27WPv+O1QXF9FnwiTG3zSnyaNRnUF5Xi4/L5iPolZz3b/+3eht00x2B2vKa1hRXMkv5TVcXqbQe1MO0ROW4ZM0gskD7nVx5GB32Nm6cx2W9SX0qozHqrXjl6Ch9I1H8B05pNGVsi1h+ZHlPL/tX1gVGBE5gut7X8+E2AloVE3fv9fhcJBZVMyneSV8bbAytqaUblnp9B82nF5Dh+FnqeOtt96qX7sXEeFsxxIVFYWn5+kj0xaTjY/+vh2fAB3jru1OTI/OM4JX8fEn6FevJn7Jh82eFbJYStHpwskqreDo/onU2oJILRnH9xn9qKzz5ueHx9Mz0o8f9hfy9a78+rV7PSP96Brqi/bEh2Sz0UjKymWkrvoGgWDUldczYtY1LfWQnfE6BMJiR+WpQdgcVH59tL5iV1gcAPiOjyVweiLCaqfq+6zfk74Ib1SHPkL54RG4eSV0ndCisTWk0yV2AIqiJACr2kpiV1paSlpaGmlpaRQXO8vP+/fvzxVXXOHS6zZWYcZhlj33d0ZffSODLp5x9jLx7x6GXUtB7QGDb3GWfAe0zL6S53L410LWfngI32Bd/XSrzkfD6vIaAjVqRgT6UmOzU2m10cWrdZrnCiE4nlbBrtW55B+uxEOnov++BUSEOOjy6Sf1/ersBgu1KcX4TYhFUSmYc2rwiPJpsS3KGstht/Pho86EYvLt9xHft3m92zoLh8NOncGAt38AtVWVZO3eSZ8LJp+1Hc5jh4+zsqQKvd1BhFZDn1wL3ffqmTk+nkFTu6BSgaKoqKjYitVWQ0T4tBaO18GX6V+w5NBSuhZEcF/xdVT0tzNo+gR8fH2de8r+33NE/vMfBF1/fYte+6yEoGLXEr6u2s8Xlfsoqi2iR1APls1c1iLrUB1CYBfgoVL4MK+Uvx3NZ3KgNwOKcwkqPE5pSQkmk7OrwKxZsxgwYAClpaXs2rWrPukLDQ0ld38VW5cfxVBhJmloOKOvSMIvuHMsT2hOwZDFUkZh0TcUFHyJEFZGjfwFRVFRV1eITheJojj36M4pryUu2BsPtYplqXm8u+kYmaW/76OrUSns+sdFlOxP5Yf/vYHVUEPcsLFcNPs2giIiWvLhnpOz+bIZW4kJdYAWjwgfrGUmSt7a86fmy2qCAr7Ae/o0HHGTsOQZ8Ij0Ru3v+vcgmdg1oDUSu88//5z09HTi4uJITk6md+/eBAYGuvSa56O6pJhf3n+HrD2phCd2Y8qdDxDRNenMB5cfgy2vwt7PQVHBzDdgYMu+QZysbg3v4kefcTFYLXaOH6wgoX/IWadbn80o4P38Uu6JC+eBLuH4tNJoBDgrHFOXbqfLjy+Q9MXHlNX54enjQXD0qY1hHWY7hS/uQNGqCLioC95Dmr5FWWMIh4ODm9bRY+QYtJ5eVBUV4hsS2qy9UjuzbV99wvZlnxHfbyBT7nwA/7Bw9hlMpFbXMifWud3VXQez0SkKV4QHMi7En6IjzoKeyK6njozu3XcXZWVriYq6mh7d/45G07yG3EarEeWoiZr1x/lJs5HVcTu4rfdtTIgaj8efet5Vf7cK/6lTUNxQJGNz2NiYt5GKugqu7nE1QgheS32Ni7pcRL+wfs0+//E6C0vyy/i0sJwKq53u3jrmxIQyy09LWWkpERER+Pn5cejQIZYvX47N5nyjVhSF4OBgrph1Ffl76khZfQQUOzc+NYHA8NbZy7q12Q21GHf8hu+FFzYpqaup2Ud2zkLKyn5BCCsBAUOIjrqGyMjLUTVyNNZss5NVVkt6YQ3Hy/Q8cFFv8tIP8uEb77BSN5QSXTg6jYqkcF8GxAXywiznc6TaZMXfU9OqBWpCCBx6K9YS55Zq1hIjPkMj0cb5YUorp3xpmnNqd3ayy2ORid2Zb78TuBMgPj5+SE5OjkvjKSsrQ6vV4u/v3v3lzkUIwZFft7L+w4UYq6sZdukVjLvh1rPfoTLHmeCNvA/CejinbFEguGnTon+ebtV4qBh8cReGXdK48xWaLTx3rJDlxZVE6zz4R7doLgsPbNU/fLtej9rPj69eTKEkR09C/1AGTYknqltAfRzm7Gqqf8jCkqtHE+FNwLREPHsGtXicpbnZrHnvLQqPpDNpzj0MnNr6C3w7GuFwsHftT3yz8hsOJvYha+Bo8lQeeKoU9ozuQ6CHhppyE2s/SCO2VxDDZ3Y967kcDitZWfPJzvkfXl7x9O3zOv7+5z+KmlOVzaa1P5J4IJiEumjUQTp0EyMJGhrX4HPKVlmJtaAArz59zvu6jWaqgtTFzhH+MxRg5dTkcM1312C0Gekb0pfre1/P1ISpDbZbaUid3cG3JVW8n1+Kp0rFysHO7RlLLdb6dY0Oh4OKior69XvFxcXMnDkTHx8fVv+4lm2/bUGj0RAeHk6AbzBxCdEMGzYMjw7ywaj07bcpe/MtEr9ZgWevXo26j8mUj1rtiVYbQknpz6SnP01U5Cyio6/Bx+csgwENKMnOZONH7xMcE8ukOfcAYDTbOFZa62zFcmIdn4daYdEtzt6QV7yzlSPFBrpH+NIzwo8eEX4MiAtkSBc3TKFb63Ac2YzVaziKh6pVltzIxK4B7u5j19aYjbVs+XwpfiFhDL/sqkYtQgacu1kc+g4GXAfjHoWQM7RTOYefFx0gY2fJKdOtTalu3VFl4Omj+ewzmLg/Ppynu0Wf9znOh37dehS1Ct8Jv6+xMBks7N+Qz/71edTVWons6s+Iy7oR29P5oiOEwHSgnJqfsrCV1xH+0GC0US0zKmCtq2P78s9I/f4bdN4+XHDz7fQe17RP5NLplhVVcP+hXBQhiC3IYoa/Jw9Nm0Kgh4ajO4vZ8MlhhBBMuL4nPUc0vA61svI3DqY9isVSyrChX+Pn17gka0/JHj48+CF9f4vk4qoxVPnWEjKxG5EjuqE0sogo9447qTtwoNl7yp7Tr/+Dnx6HOzdC9MAzHmKwGPgu8zs+S/+MrOosgnRBLJq6iB5BPZp9eSEEersDf42aMouNodsPMjzAhzkxYVwU6o/6LH8X5eXl5ObmUlxcTEFeIXm5BQiVnXtvf5iwWH/Wrl1LXl5e/dq9iIgIwsLC0Onaxz7KtspKjk2+CJ/Ro4h9881zHutwmCktXcv/s3fWcXaddf5/P8eu3zuumWQm2iR1N+pKXSiFAkVbXJYfUmAXWJzdxZddoJRSWCqUUlrq7m1Sb+M+7jPXjz+/P86dyUwy8aRNm/t5vZ7Xc1zu955zPs9Xu3v+yvDwk7S1foaZMz+H77uAj6LsnOY3OzzIUzf9mSWPP0Q4Fue4y9633QPQv73QyaudoyXil2M4b3PGgnp++4GA63zqLy9SEzOY2xCQvrl1u15Dd4t4/D/h4e/AJ5+Duu0jyLuKMrHbBsrEbutY+dxTLHnsIU798MdJ1tRtecNMDzz9C3j+D+BZsP+lcML/22I1i6GuHK8+2smR57YRS4XoWjmClXe3am7dXnhScmPPMEdXxJgdDdNrOehC7FTeq63B7uxk3UUXY7S20nrzTZs51zu2x/Kne3j5wXaOPG8m845qwLE9hABNV5Guj7lqhMj8INI2/0IfobYU2i749dz9q/9i2ROPsP/JZ3DCFR8kkth7tcR7O3Klsl639Y1waX0llzRU0Wc53No3wgW1KTKLn6L14MPQjBgP3/ACq1/I0jCzgtM/vJBU7fbnhHOcNN09f2V6y0cQQuD7zhZzeknXp+fpVXxg5dUUYw4fr/sQZ6ROoe7Qth026+9qTdltQkr476MgFIePPbwdm0ue632Of675J9885pvoqs4DGx4grsc5uvHoXR6cpB2X67uG+GP3IN2Ww7SwzpVNNby/qZoKfcvvBt/zWfJEN8/csQLXVDjgxGa82l5WrVlBf38/juMAUFFRwec//3kAXnnlFVRVpa6ujurq6s2qa7zZ6Pvhjxi+4QZm3vEPQrOn1rRJKVmz5sd09/wVxxkhHGqiseldNDVeSji8awPmlc8+yT2//inS8zjk7PM56qLLCMd2Pp/gYM6iaHu0VEVxPJ93/+aZzWrofuKkWXzlrP1wPZ+/v9TFvIYEs+u2r4buVlEYDvK/zj8fLv7Nrh1rO7HPETshxI3ASUAN0Ad8U0r5+y1tXyZ2W8erD93HI3/8LQLBse96L4e+84Kt1+DL9cPTv4TF1wYJjk/71vgq35esf2Vw3Nyq6gpnfnQhbQfV7tF7+Ojr63hiJMeX2xq4sqkGbTf4tUnbZv0V78Nevz6oAztt2ha39b0gwkpRFV64dz2vPNzJgSdPY/8TmgnHSmahokvPDxchXZ/4cU0kT2qZOsx+CuSGhxCKQqyikuHuLgqjI5uXkCtjuyCl5IGhDH/rG+H+wTRFXzItrPOl1kbe3Th1Lsf+9Wn+7+v/j2hS56Iv/z/q2rZsgt0WisUOXnzpCmbP/ir1de8EwHRN/rniDpSX8xyzYQFexmb4GJj9zsOI6ruWRif31FN0XHU18RNOYNqvfrl7I2XXPQF/PBcu+DUccsVOHeKyOy9j2fAy2lJtXD7vcs6fdT5xY9cSCru+5L6hNNd1DvL0aI6nj5pPWzREwfOJbmVQWczZPHfHOpY80UU0YXDFvx+NZiiMjo7S39+P67rsv3/w3P3iF79geDhIlquqKjU1NSxcuJATTjgBgFwuRywWe1M06U5PD2vOPIvkOefQ9IPvT1rnunlGRp+ltuZUAF57/bOApKnxXVRVHYcQO///8H0PK58nkkgy2tfLUzf/ieMvfz+puj2TYWFiDd2VfVkOaE5x7OwaVvfnOO0nQak7IWB6VZQ5dQk+cnwbx8yqxvF8pGQ8Qne7cO/X4Ln/hc++NF4DeU9inyN2O4oysds2MgP9PHTd/7D2xcXUts7kjI99mobZ2zCT5AdBUYPKFSvvw33+L9z42ofIjPi7bG7dUSzPF/nXVV08MZJjv1iY785p5vjKXfOD6P3+9xm54U80//IXJE8/fbv36149ygt3r6d96TBaSGXh8U0cdGoLiaowbtoic/8GCi/2IcIayVOmEz+mEbGFF4zve7zywD08eeMNtB18GOd+/iu7dE/7KnwpWVe0mFUqV3Xq4uX0WA7n1VZwSX0lR6Q2/wD7vqRz2TDTF1YjpeTVhx/hqZt+j5XPc9RFl3HURe/aqTq7xWIHry/5HJnMK1TXnc9zbhsjT/Rwbu87qPASaG0JKk6dQWjW7vMfHYuUrf3CF6i5+qrdckwA/vpBWPMIfHE56DtX1cLyLO5ffz83Lr+R1wZfI6pF+eLhX+Syebsn9UWnaTOtFFzywdfW0me5fHhaDefVVhDeAskb6MjSuybNAScFg7mR3jyVDZO1nY7jMDg4uLGcWl8fTU1NnHLKKfi+z/e///1x/70xU25rayu1tXt2kAtQeP55ur/+dWZcdx16czNSSjKZl+nuvoW+/rvwvDzHHvMIkcj0XYqWnYj1L7/AY3++jkR1DRdf8+3dcBc7j6lq6K7szXLNO/fjlP3qeWr1IFdet4i2mhhzGxLjPnzHzKomFdnCM53ugp8fBIddCef81x6/hzKx2wbKxG77IKVk9aJnePj633Di+z7MfsdtO2/PUFeOrpUjHJh6FO77Os8Nnk3NjEraLroUpeWN/U9KKblnMM03V3fTYdr817wWrmiqZtRxMX1Jja5ttyav+MorrH/35VR+4P00fO1rO3U9g51ZXnqgnVWL+2mZX8l5nzl4fJ3dnSN973qsNaM0fPHwKU2z/evX8sDvfkXv6pVMP+BgTvvoJ6ls2LP+hG83LMsVua1vhNv6Rhh2PF4/biExTWVD0aIpZKBv4f+QHTZ58A9L6V41yqVfOXy8zFwhk+aR63/L8qceo2Z6Kxd+6Rs7pY3wfYcnXvoS9uidDLmCRPuHmOeexLSzFhJuq9iVW94ihm+4geQ556BV70QW/qng+3DTe6FmNpzx3d1yyNcHX+fG5TdyzsxzOLbpWHpyPSwdWsqJLbuWE28Mf+ga5PedA6wuWFTpKu9rrOYDzTXjxG8qdK8a5e//9SJzjqjn2ItnE6/cto+d4zi89NJL44Svv78fy7I4+eSTOfHEE8nn89x+++2TSF9NTc0OVdfYFqTvIxSFbHYJS5Z+kXx+FYoSob7+XJqbLiOZPGS3ELrB9vU89ufrWP/Ki6TqGzjhvR9kzlHH7dU+v2sGcvz9xa7xwI324QJSwp2fPp4DpqV4ZHk/d77SvZH0NSRoSoURd34WBlfDB+/a42XGysRuGygTux2DbRbRQ2GEELz60H2EojHmHr3xQd20dqsWUrnye8cSVvOw6HfwzK/AHIVD3g8X/OoNv/6i53Nt5wBXNFVTpWv8pqOfb67uRgDVukZ9SKPO0Pnl/BnUGBqvZQtsKNrUh3TqDI16QyekCLL33EPitNN2OWVEdtjEsTyqGmNkh00e+8sKDj59Os1zK/CGTLRSvdvRu9cS2a+K0MwKVjzzBHf94j+IJJKc9IGPst9xJ+7VL8q9DU+NZPnGqi6W5U1UASdWJri4vpJzt6KlGcOal/p55E/L8TzJCe+ey37HNGz2269+/jlevOt2LrrmW+jG9jvTvzbwGl7OpnVZFblnu7nvmNuYFX+a+pqTmT//+9s+wG6AdBzszk5Cbbsp6bfv77GP3P+88j/8+uVf0xBr4LK5l3HxnIupjuwaMZVS8sRIjj90DXLfYJovtjbwxbYGfCkRbB5E5lgeL963gZfub0eogsPOmsHBp7Wg7UAB+rHqGpqmEY/HGRgY4NZbb2VgYADfD9w4hBBceumlLFy4kGw2S1dXF1VVVYTDYUKhEIZhbNc7IPPwQ9gLFRQjTFXlMTjOCK+8+nEaGy6ivv4cNG33RXSufO4p/vnTHxGKRjn6kss56Ixz3pKplgq2y+r+HPMaEoQ0lZsWtfOzB1fRm9lYQzce0njyX46mIpl8Q6pQlIndNlAmdjsHKSU3f+urdC1fQtvBh3HqRz5BMRfh/muXkB02t2xuNTOB/12iAQ5+L7gWdL0IM3at4PrOYnm+yHOjefpsh37Lpc926LMd/n7IbGKqyjdXd/GbjoFJ+6Q0ldeOW4ihKNzaO8zruSL1hj5O/hpCOrOjOx4A0bFsmAeuW0Ix61A7PcEhZ0xn1iG1yKJL/y9fwkvbhOdXEXpHDc8//g+OvvQ9ROJvbjWLtwJGHJc7+0fZPxHh0GSMJbkiX17RwcX1lZy/A2W9nrxlFa883EHdjASnf3ghFfXb9m9zTJM7f/oDjrro3TTvt3l+K1/6PNH5BLe9cAvzVjRwdvp4dKkRObCW5OkzIOUghIqmxcjlV6GpsV12XN8aev7138g+9BCtt9yy85GyngvZHqjYs6XqxnLi3bT8Jp7teRZd0Tl35rl8+9hv75aBTodpE1MVqnSNf/aP8qN1PXyouYbLGqqIb1LbNz1Q5Om/rWbtywPUTk/wrmsO3+Vr8DyPoaGhcc3eQQcdRE1NDa+88gp///vfJ20rhOCjH/0ozc3NLFu2jKeeeopQKDShFZgWf4XBnr/iVYNhHEpD/fcnbZNMJlF2kYQ7lkl2aIiqpmasQp5Ft/+Vw8+/5G35nppYQ3f9YJ6vvXP+GzbALhO7baBM7HYevufx5M1/46V7bgEkR5x3GQNds9j/pOm0HVizfdGtL/wR7vwstL4DTvgStJ3whtfd2xpGHZdO06bPdll12+10rlyF8r4P8O8HBXmxrlnZyV96hrD8jf/rKl1l6fFBIs2vr+zktVxxXNtXH9KZETG4oC5IfZJzPaKqglK6Z9fxWPFsLy8/2MFoX4GK+ijnfmoWj9/we1KDKWaFDkLaHrEjGkie2Yoae+uNgLeIwjCYaahs3eX/QMHzeWAoiGh9eCiLIyWfbKnj32bvPCla9nQPo30FjjyvbVJ94K1hqLOd2374LTKDAxxy1rkcf/kHMMKBFvah9of4xYu/oH10A/+3+ofEvSjhQ2qoPKUNvWayT5qUkudfeBeFwmr2m/dd6uvP3en72Bp2S6Ts8rvg5vfBh+6B6Ufv/oucAmvTa7l5+c04vsO/HfNvADzW8RhHNR5FWNv16hGPDmf4wdoeXskWiasKlzVU8aHmGubEJh+7Y+kwxZzN3CMbkL4kPVikom731om2bZu+vj5GR0exLGu8HXHEESQSCVasWMFzzz03vry65mFqa19BCAitNnBmXsnjT+WRcjI5/dKXvkQsFuOxxx5j8eLFmxDDEJdeeimaprFy5Ur6+/snrdN1nUL7Wp666Qb0WIL3/+Cn6G9CAux9BWVitw2Uid2OY1Nza32rQNeeYvXiZ7niez/ZdmDFRNgFePGP8NTPg1F+y9Fw4pdg1ql7FcHLPPAAXZ/5LJXvfz8NX5/sVyelJON69Nku/bZDwfM5oyaoNPCf63p5ejRHv+3QZzlkPZ/94xEePCJIA/POF1byarZArbHR1Ht4KsanW+pY91I/f3v+cUZWPkE0m+aAhSdwyrvehf/8AIXXBmn44mEo4d2bwmWPwinC8DoYWb+xjW6Ad/5noN15+pdw/zegYgbMPQvmnhkUjNd2LDeYlJJ3LFrO6oJFg6FzYX0FF9dXckA8skMjaulLXn6wg3BcZ/6xjTt0DRNhm0WevPEGXrr3TuI1tZzysU/Q2riQFx98gv9K/J4r9/8gJ5pHEG5MolVumYQUi+0sWfIvpDMv0dhwMXPnfhNN27UI0amwy5Gyf7oY+pfC518H9c35f64dXcsF/7iAilAFF8+5mMvmXUZzfNdz9b2YyXNd5yB39I8yLWzw1FH7bfE/tfzZHh65YTkHnDyNI85tIxR5Y36LfH4N3T1/pXXGJ9H1JL29dzC64lGcr91N81XXELnsMrLZ7CRSaFkWBx10EKqqsmzZMlatWjVpnW3bfPzjH0cIwR133MGLL7446ZxCSuLLX6Bh9lz82fuzZkM7qqqOE7+KigquvPJKAJ5++mmGhoY20xYuWBBotAcHB5FSjq/bXjPzvoQysdsGysRux7Di2R6eu3Md2aHNza3969dS1xqkelj+9OO0Hngo4fh2fngcE176Ezz5U4jVBAlN95KHeVK+uv/78y751RU8n5zrURcKNG039wyzpmCOk8I+y2FBPML366Lc8V/f51vHXkguXipHJSUxS3Kip/OTQ9uoaIrzs3W9sLiPpuYk0+fX0BAxqDd0IruYC3Cn4PsBOZ9I3EbWw7GfhsaD4PXb4NYPbdzeSEBVK1z4v9Cwf0D6Vj8Iqx+CtY+CW4RQCv7fiiCq0rVBm/zbSyl5KVvgtr4RFo3muefwuahCcHvfCDWGxjEV8S0mod0a8qMWD16/lM7lI8w7qoHTPrRrZYK6c9386f5fEbm3iyMrT2Wa0obQFWo/eTBGw/ZrxXzfZf36/2bd+l8RCU/jkENuIBLZ/SbPsUjZ6o9fTV0pN9v27bgOfnEwnPhVOPma3X5d2wspJYt7F3Pj8ht5pOMRJJITpp3ANUdeQ1N8103ZA7ZDh2lzaDJG0fM578VVnF9XwXsbq6kp5UUrZGye+8calj7dQySuc/SFs5h/TOMeKSPoeQX6+++hq/sW0unnEULjwAP+l5qak5FSsv6yd+MODjLr3ntQdjGJspQS13WxLIvVLz7P/b//NdHKak591+Xsd8w7WLV6NX19fZOIoa7rnHfeeQDcdtttrFmzBsuyxku61dXV8clPBrWsr732Wjo7O8fPJ4SgtbV1nBjedttt5PP5ScSwoaGBgw8+GICVK1cihJi0PhKJvGWSR28P9jZi9xZSL5QxhqGuHMmaCHpIxTY9ElVhjrt09mbm1jFSlx0e5J5f/YRwPM7JV36MeceesO0Rlx6GIz8Gh34Asr0BqSsMw83vh6M/AfPeuccjjaaCtG26vvAvADT/9Ce7HCwRVZVJubK2lBvNtW30cIj/qlAI7ddKv+2yfqjAig2jiJUZ/nLXItoOq+Uns33sWgl2Gl5JA/Chpmp+MK8F2/d5zytrqTM06kJ6YAo2NA5ORpkVDW9/VZGJMDOBlm0icZt/Psw8Ebqeh99PSP0iFEhNg1wpNcX0Y+DS6wJTa2VbkApn4rmr2oL/wJEfC7R7656AwRUbU2X8+WKwczD3LLpaz+AvfgN/70+ztmhhCMHpNUnSrkeVrnFh/c6XFlr3ygAP37Ac1/E46Yp5LDh+54nA0qGlXP/69Sxa8wyf634vR1SdjTQgcXwLyv4xOnuWMrPhiO0+nqJozJz5OaqqjqOj43pCoT2TA6zqiivwhkdInHbqju34wh9AqEHahzcRQgiObDySIxuPpDffyy0rbuGedfeQMAJfrzWja6iP1u90TrxaQx/3zRx0XCp1le+v7eE/1/VyQX0FH2qu4dBkjJPfP5+FJzTzxM0reeRPy+lYOsyZH9u9OSZte4innzkFz8sRjbYxe9ZXaGi8mJBRA4A3MgJSUvvpT+8yqQMoZtIMd3UybcH+HHjcOxBWgYUnnoZWejfOnTuXuXO3bLW5+OKLx6dd18W2bTzPG1922mmnbaZRjG+iIDBNk3Q6Pb6+ra1tnNj94x//IJ/PT9p+//3359JLLwWCHIObEr+5c+dy6KGHIqWcwj8xRGVlJalUCiklnudtMULZsiyEEBj7mBm6rLF7i2BTc+uJ753H/ic0b3deo761q3ngd/9N39pVtB50KKd+5JNU1O/gR6j75UDDM7wW6vcPKlnMv+ANJXi+ZdH3/R8QO/64HcpXtzNYvfhZFt95G5d87dsY4cgWf+v8qMUrD3ewanEfl33jCHKaYO1LvXS92k+faTMzFeW0i+eTCStc+do6+iyHftuhWPID/PrMRj4zo572osUJi5ZTWyJ89SGdOl3l0pjDYXYn+eF21qWHqG+YR/WCs1CyPfCT+ZMvJpwKklAf/uHAP+71v5WIWyukWkDdfT6A/U/+GrH6QWrXP8zDlUdwxQE/4jglw8XzDuCcmhSprVQP2F4MdeW46TuLqGmJc8ZHFm6Wn2xHIKXkM//4JM8XXuKy2Zdx2TPHkzywgfgxTShhjUdv+B0v3PUP5r/jZE6+8mM7XSXEcUZZvuJfmT3rK0QiW06UvbPwcjmGr/sD4YULCC9YgNaweSQwAL4HP1kALUfAu/+8269jV+FLH0UoSCm57J+X0Z5p57xZ53H5vMuZXblzdU4nYkXe5PquQW7pHSbv+Txw+FwOSAT+dVJKVi7qIxLXmb6wGsf2sIsusdT2Ey3XzVEorCWfX0U+vxohNGbN+iIA69b9korKo6lITR20IaUEKTerjrMjcGyLF+/6B4v+8VeMcISP/uo61N2YgmVXMPFdOTAwgGmak4hhKpVi1qygzOWdd9652fqFCxdy4okn4jgO3/ve9zY7/jve8Q5OPfVUCoUCP/7xjyeZmYUQ1NXVUSgU6Ozs5IILLuCggw7ao/e7t2nsysRuL4fvS155sIPXHuuc0ty6Y8fyePm+u3nq5htQVI2r/vsP6OEddGT23IAsPP4fMLQKaufDRx8MyhTtYeyu5JzbQmZwgIf/8BvWPP8sNdNbOf+LX9uunHS+56OowYfq5u8tRvg+h8+pIJG1qf3IAQhVIB0foSvjNTP7LIeUm6Mu30nfYAf/MwIDegV9kcYgMjgzyPdW/ZxL+x/gueQBXHBIkJJGFVCra9Q5w3w7leeY+gY2RJp5tKBQb+jUhQL/wFpDw9iNxDvretw9EARBPDGS5VPT6/h6g4G76kEG1jxB44zDAlJZHIFbPxL45c09MyCWOwAz74xXAVn70gAz9q9G1XfsPhzP4e51d3Pjshv5+YwfIp4cxRrOk/rC/iRjqc3+T67j8Nzfb2HR7bcQjic49cMfZ+7Rx+/QOSGoN/vKq0Fi4f3mfYeGhvN3+BhbQ/HVV1l/+XsCUzugVlYSXrCA2s98msjBByNdFxQlIA3ZXrDzO1wr+o3GWE68e9fdi+3bHNlwJFcfeDVHNh65y8fOuh73D6a5uL4SIQTfW9MNwAeaa2gp5cRb9M91vPxAO4e/s5WDTmmZ9F9znAz5wirMYte4LJcu/RI9vbeNbyOETip1CIce8uetVoMovvIK+vTpaJU7r8GWvs+ypx7jyRtvIDs0wKzDj+aEKz5IVdPuH0S82RgzM29K/JLJJDU1NZimySOPPEJ/fz/Dw8Nks9nxlDSNjY3MnDmTAw88kPr6+j16nWVitw2UiV2AfNoaHz3e+qPn0XSFA09u2S21W7PDg/SuWcWcI45BSslQxwZqprfu2EF8D5b8PUiNclYpp9eGZ2DaEXvEQdvu6KDrC/9C4/e/R3grZoVdge97vHTPP3nq5j8hpRwv2bajo2Dfl6x8rpcX729npCdPvDLEQcdE2W/GCCO3Q6SlSPLyM4ISZb8+FvqXTD7A/PPh3X8Kpp/8GTJciahqZSgxnWe8JH2uT7/t0mcFqWC+OrORgxJRbu8b4eNLN2x2Pf88dA6Hp2I8OZLl5t7hkgl4I/k7KBHdLh/Azy1r5x/9I5i+ZHrY4OL6Si5tqJw6lUzPq/C3j8DgymC+dr+A4B3xsa2m3QiqRnTy3B1rueDzh4wnG94RZO0st668lf9b+n/M7mvkytELaMnXo1aESJw4jdgRDVusHgJBsun7/vfn9K9bw8lXfoxD33nBDl9DsdjBkqX/Qjr9Ig31FzJv3rd2a04yv1jEWrGC4tKlmKXW+O1vEzngANJ33UXvN79FeP58wgsWBJq9+fMxZs7cvSXK9gBGzBFuW3UbN6+4mU8d/CkumH0BeSdP0S1SE6nZ5eNLKfnMsnZu6xsB4MyaFB9urmF/R+Hp219k/UsWqdoYB5+/Hlu7m3x+NbbdX9pbcNKJr6GqEXp778A0O4nFZhOLzSEcbkHZRlJm37JYc9bZGK0zmPGHP+z0PXQue52bv/VV6mfO5sT3fZiWhQfu9LHeikin06xbt461a9eydu1acrkcAFVVVcycOZOZM2fS2tpKNLp7o5+3hjKx2wb2ZWI30dzauzbDlT84lkjcwLE89NCeeSGvXvws//jP73LAqWfyjvd+cOfzG42sh18cEkRQvuOLcNDlu83s59s2G957BfaGDdusA7srkFJyy79fgx4Kc+qHP0GqbjtHeVIG/ocj62F0PVg5OOxKpC/Z8D9f46UVTXTbCzkl+Vvq9dkUvNMRYYPkKS3ElTsQirfRXFoxA8I7ZwJ0fcmgU8r9Zznj5O8DzdXUGjq39g7zg7U99NsuzoTnftHR85keCXFt5wB/6BykLqRRrQjCZhHVtvhCSw0NDQ38e/sgErikvpLDktHt054OrYFV98PKe2H9U/DJZ4PqB+3PwmgHzD4VooFfYyFj89Afl9K+ZJjWA2s45f37EUnsmG9Mxs5w1t/OImtneXf4fD740lmo1WGSJ7cQPbhuq4RuInzP48V77mDBCacQTaYw8zlC0R2rJer7Lus3/Jp1635JY+MlLJj/wx26l51F8dVXSf/lOsxFj2IOSaRlAzD74YfQm5rIP/scTmcH4QULCM2evct+qnsCnu/h46MrOn9c8kd+9uLPOLP1TN6z33s4sObAXdbcrx5dx7XrV/H3dIq0H+IScScX+9czo/rvPHdbARm7l+ZDFlHfvP84eYvFZhMONyPEzg2sh66/nv4f/ojp1/+B2NE7lnZmuLuT3jWrWPCOkwFY/+pLzNj/oF0y5b5VUCwWWb9+/TiRGxoaAiAajY4Tuba2Nip3QQu6qygTu21gXyR2VsFhyZPdvP5oV5BMuDLEAScFRemNPRyS75gmT9/6F1646/Zdq5wgJay4Bx77EfS8DBXT4fh/CZIe72B6jE3R+73vM/KnHa8Duz2wCgWe+duNHHbOBSSqarCLBfTwFGk4XCsgIiPrIdMJh30wWH7/v8LzfwA7u3FbIwHXdASBCIuvhWwvfc4camY3oda0seQxE+3VIWI5G7UiRN2nD0aNv3EfV19KRhyPfjsgf0clI2SGh7lpbQf3posMOB5poVIIBZq49z73AFHHoqqqiqamJhobG8f78I6Y8q0shEoDhzs+G6TVEQq0HM2G2KU8tGgWtg3HXTKb/U9s3u7/4IrhFSzqXcT75l5B4cV+Fm94jrpT5jC/aj7mihHCcyt3KfLR9z1u+tcvE47HOe1jnyZZs2P1Q0fTLxAJTycUqsVxRlDVxDa1O7uMf34BXv4L8rOvYfelMZcvJ3nuuQgh6P7610n/rWRG1HXCc+YQPuAAGr71TYQQ4+Wt9hasT6/nphU3cfvq28k7eRZUL+A9+72HC2ZdsMX/iJQSy+op+b+tCfrCaubMvoZU6lD6++/ltdc/ha9W8ZJxLgfFdeanGuiKnsk/Bn2O6XA5dl4NtdMTmDkHRRW79C72cjnWnHY64QULmH7d77d7v0ImzTO33sirD95DKBbnY7/6PXpo1/MA7s1wXZeOjo5xItfd3Y2UEl3XmTFjxjiZq6ur2+UEzrsLZWK3DexLxM5zfVRNYbSvwP9961maZldw4CnTtj+Z8G7ExFqn899xMu/89Bd37kBSwqoHAoLX+yp89mVI7Xy+qsz999P12c/tUh3YqS9TsmrR0zzyh9+QGx3hjKs+wwFHHjwhsvS8IPpz8bXwxE8h0wVMeFa+2h4EKrx8I3S/tFHjVtkKlTPA2LKT/6I71/Life1UIpnXFKPh8nk0zEzhDptT1qHd3bBtm+7ubtrb2+no6KCjowPTDMrxRKNRpk+fTktLCy0tLSRTKQb6++np6aG7u5uenh7S6fT4saqqqmhsbJxE9iKR7Sgw7/vB77byXlh5L4tX78ca5yRO/8oFVDfFofd1qJ4dRGdPASklz/Q8wx+X/JHnOxdzXvYkPpa/DJl2MNpS1F51wG7zx5S+z0v3/ZMnbvwjiqJw4vs+wgGnnrnDx5fS58WX3oeUDgsX/GSPpEUBAgL9X/sFJv2L/mfz6/B9nPb2wIS7bBnmkqVI22bGnwPzf/vHrsLt7QnMuKUWmj8fdXtTJe0h5J08/1zzT25cfiO10Vp+d8bvkNKnP70U1e0nn19FRcWRpFKHkE6/zPMvXDK+r65XEYvNYWbb56msPBLXzeN5eQyjdpIcr+8a5N9WdWFLyfEVcT48rQb1ri66l45wzEWzmHdUw04NEgZ++SsG//u/af3rX4kcsO0oXNe2eeneO3nu77dgm0UOPPUsjn3Xe4mmKnb43Hs7fN+nr69vnMht2LAB13URQjBt2rRxjdy0adN2a33e3YkysdsG3u7EbqK5NRTVOfvqoCJCZrBIsmY7Poh79No8Xn3gXqIVFcw96jh8z8P3/Z2rJyglDK6C2pI/3N8+Bk2HBJouY/t9Hzqu/jju8PAu56sDgpQdo+2k177Kww+9zNpXXqG2oZrTG9fS6K0Gp7Bx208+C3Xzg6z9y+6cbCqtbA1KsO0CcShkbF57tJPXHu3EKrgcelwjLcuHCM+uIPXONvT6nY/+3BTZbHYSievp6Rl3MK6pqRknctOnT6eqqmqbhCWfz08iej09PYyOjo6vr6ysnET0Ghsbp/R3GerOYeYcmudW4g934qe70dqOBM+B/5gV9DNPDnzz5pwBySAp8YrhFXzjqW+wfHg5p9rH8pmuywmZGkZrkuQp0wnNqdgjQTajfb088Ntf0P76q7QsPJBzPvslYhU7Zv7p7b2D5Sv+FYB5875NY8OFu/06WXwt3PVF+OhDMG3HvzVDv7+OwqJFmEuX4g4E5fuixxw97hc28te/ojc1BRG5b5D5y/ddisV2hBBEIq0MF7pYs+ST5Aqrkb41vt3MmV+krfWTuG6e3r5/EIvOJhabhWFsf83aQdvlxp4hru8apMtymG8YfPLJAv3rMtS3JXnHu+dS37pj7hLd13wNv1hk2s9+ul3bD3V28McvfYq2gw/jhCs+RPW06Tt0vr0dw8PD40Ru3bp1FItFAGpra8c1cjNmzNgxi8CbiDKx2wbeCGLX96Mfk3vkEZRUEjWZQk0m0erqqP/KlwEoLF6MOzoarEslUZNJ1FQKJbbzH1sz77D0qW5ef6xrPLr1wJNbOOT0vfeBff7O23jt4fs5/WOfZtqCXcj1ZOfhL++G9U9ArBaO/WwQObkdkbTScfAyGbTq7Xgx+z7k+gKNW2VrQAS6X4J7vhosy/UCcH/PbJblWzju8is5dH4NyqJfb6Jxa4Wqmbs1NciWYJsuy57uobo+SmqwSObhdnzLI3pYHRVntqImd8yM7fs+AwMD40Suvb19nHRpmkZzc/M4iZs2bdpuczAuFAqTyF53d/cksldRUTFO9hoaGsisU1l8ZzsVdRHe/fUjJ2tBPBfWPlLS5t0H6Q7yQjB44v9jxknfYGi4j68+/FXOPug8zoqeQv7eDpInTyc0M7Vb7mVrkFLy2sP38dpD93HZt36Ibuy4m0Gx2MmSpV8knX6e+vrz2W/ev+++wAop4X+OA0WFqx/f5aTiTn8/1rJlCMMgdswx+JbFisMOh1IiW62pkfCCBVRceCGJ007buVyMky5/Y6Ty+vW/JptbRj6/mkJhPVLaNDZczIIF/xHI4bVPIPQ6Xhrt5b7uV1mVz1GfaOPy/S7nwtkXEtN3bXDk+pIHhtKkXY9311ex9Nke/nVFJ/utKnLFO2ez8Pgds0RIx0FsZZDctXwpG157iWPfdQUQ+NW9XSJd8/n8pICHsXdDIpGY5CeXTO6cf/GbjTKx2wbeCGI3cvMt5J99Bj+dwcsETQmFmHnnHQC0X301+ccen7SPPn06s++/D4Dur16DtXZtQPiSSZRkgtDMWVR94P0A5BctAl+Ok0IlleL5R/p5/q71NM1588ytO4r1L7/AA9f+msxAH/uffDonXPGhnc7tBcCGp+GxHwcf7UgVvPeWIMfWFBi55RYSp52GVrVJwmArFyTkDSWD6Mp0Z+BPNLIeRtvBDUyKnPfzQDvYvxzu+iLdXiN6VTO1s/enYNThJmaQbG7d+XvZQ3j57nWk799AW0gFTVD7L4cRqd6yJte2bTo7O8dJXGdnJ5YVaDDi8fi4SXX69Ok0NDS8oaaMMbI31rq7uxkdypFIzyVkVePHMtQcbNM8o2Gc9MU2GTz15/v4vxd+wV833MMB4f34ceL75J7qICyeo/qwdUGps5knbfTde4MwRkAc0+S+3/yCYy55D9XTtt+06vsuGzb8Lz29f+fII27ffcTOc2HRb4NE1At2b5qV8VOMjgYm3KVLMZcEEbmV730PVR/4AE5PD+vedRnhBfMnmHIXojc3bUb2crmV5HLLx/3f8vnVRMLTOPjgQDP47HNn4ftWELgQnU0sNptE8gDisTmbXZPt2dy/4X5uXH4jrw++zn2X3EdDrAHLswipu6fCwYq8yTkvrCTn+RwQDfPR6XWcHo6QSoS2WKvY6e3Fz+cJzdpyupmR3m6e+Mv1rHruaeJV1Vz5H/+9/RWC9lLYtk17e/s4kevtDQbVoVCI1tbWcTJXU1PztihPViZ228DeYIp1+vrxhgYD0pfO4GXSCF2n4sILAej/yU8xly7Fy2Tw02m8TIbQnDnMuOGPAKw+5zy601E6mk+ipetRagdfRTvuFCq//SNqpsXp+NSnkcXiJI1h+ID9SZ5xBgCF559HRCKoqWCdEo+/ac7MjmXyzN9u4oV//p1QNMaZn/gcsw47atcO2rEYnv01nP+L4IPc+3rwIYpUgO+RueMWur7679R88hPUfuJjcMdnNvq+5QPTECd8GU75ehCNesP5m5hK26DxQIjXYeZzPHnjDbzy4D3MOuwoLvzSN3bt2vcwpJR0LBtmyd3rcdsz9CgKB5zYzMHzqwjPqSCTy46bVNvb2+nt7R3XktTV1Y2TuJaWFiorK/eql2ZuxOSW7y/GLDg0HaJiJ/vp7e1heHh4fJtkMklTUxOiWvCU8xRPDD5BpZPg8/aHOKRrNsKDyGyNhHYrRvdfwUqDogc1bC/638BE/gaid/VK/vaDb+KYRY659L0cft7FO5Qex/ctFCWE51l0d99Ec/MVez6wYg9gjOjanZ0M/uq/MZctw1q9Gl9zcRskiS9cjj87hp3upbn3VMLzF7Ak/W+MjDyNECqRSCux2CxSqcOYMf2jQEB+d+a36Mh00JIMSPbVD1yN4ztcPu9yTp5+Mrqya1r4nOvx174RruscYFXBIuZKPvWizaXnzmb6ws2tCt1fvYbM/fcz57FHUROTybuZz/HMrTfy8n13oWoaR1xwCYefc9GO5xbdC+B5Ht3d3eOm1Y6ODjzPQ1VVWlpaxolcY2Mj6l6ecmdnUCZ228CeJnajfb30rF5BLFVJrCJoodiOpTHYEsy8w7Knenj1wXXkMh6xqOSQWXmmRYbQ6utInXMOAJ2f/wJOT/ckjWHqnHNo+lGQDmH5gQchbXvjgRWFqve/j/prrkH6Ph0f/ShKYsxEnERJpogefjjRQw9Bui7msuUbtYWJxG7JXTXQvp4Hr/01J1zxIZrnzd/2DttA1s6yNr2W7mwXZ9/9Lcj28I/KaroHM7zjFgNZGyN5yy00pVrQf/MOiNdvDEyobIXGg7eadFVKycpnn+SR639LIZ3mkLPO5bh3vw8j8sblNtpV9K1P8+w/VyGyBQ5NCzJqkUWsY73Wg27oNDc3j5O4adOmbV/QwiawXZeOoWHah0fozGTpzhXoNS36HY8hH0ygTno0qdAS0miNRZlZkaSlqpJEVTVGZDvTnhDI5Om/rWbe0Q3UTNv4kTNNc1yj19XdRV9vH4vsRbxW9Rqt2VauGr2UAwrTyTZJ9KNraZjfQiKRCHzw2p+FVfcFORQ/fF+QQ/HpXwUm+blnQstRe9yknh8d4eHr/peVzz1FXesszvzE58bL+W0venvvYMnSL5BMHsL+C39CJLITLhr5wcB8vfDiHfJj3R0YS+JbyK+lsfFShBCsWPZtOntuGN9GCJ2wXUPF5wcRUuDONgjNmEW8+RDqrvoEWs2u56mbCCkl1y+5npuW30R3vpu6aB2Xzb2MS+Zesss58aSUPDWa40/Lejnu3kGy/UWefUcFvSmFqsowlRVh1EwWed8zfNgT1L3nYu71TNKKJBHTieoqwjZ5+dpfceb0Jo697H2s0cJ4viSkKoQUQUhRiKsKlaUKLm9UgvbtgZSSwcHBcY3c+vXrxy0FDQ0N40Ru+vTp+0Q5rzKx2wb2NLF79aH7eOC3v5y0TNU0oqlKYhUVRCs2Er4x8rdxWcVWQ81v+s5zDHXld9jcKqUE10XoOlJKCosX449rCwONYWT//Umceip+oUD7hz6Ml82Oawyl41DzqU9R+5lP4/T3s/qEEzceXAiUeJy6f/kCle95D05fP33f/e4kbaGaShI9+mhCbW34ponb14dSMjNPJIUTXyyP/un3GOEIR174rq0GV4yaoyRDSRShcO/6e7lt5W2sSa+hvxAk/RQInj3lWqKLf8/3Mys46Pp+6kYlX/mQykCFoCZSwyOXPQLAzctvJm2nmRafxrRE0CpDU2ullj7+MPf890+oa5vFGVd9hvqZu16iaE/DsqzNzKq2bYMP88ItHGbOJGprZHRB4owZTDt+2hZf9DnTZMPgEO0jo3RlcnQXCvSZDgOux5AUjKg6aT1MIRRBTqENjlhFklYRQ/oMh6Lkw5OJgu7YJLMjVOQz1NhF6qVLswItYZ0ZsQj1FRXEKyrx/DgvP5jm1A8upKJuap8n13d5cMOD/GHJH7hkziVcVHUuQw+sYbjJYdQwGWjvZah3kPbR7vF9EonEZgEa4/45d3wWXv4L+E4QuTz7NFhw4R4zTY5h5XNP8dDv/4ealum861+/v8P79/X9k+UrvoGUPvPmfouGhot27EP+5E/hwW/BJ5+Duv12+PzbA9seRtPiKIrB4OAjtHdct0kSXzju2CcJhxsZHHyEbG5pkAcuOodIZDrCk1hr146bcM2lS7GWL2f2o4+gJpMM/u53ZO9/YHJE7tw5u1RT1fM9nuh6ghuX38jT3U/zhcO+wIf3/zC+9BGIXSZLnuPzyiMd/MfQEGuioKcMCKtkB4eJ5gze/2iQCun3pyXprp6sgZwx4vAvyyShqMa/z1fo3uQ2j1RD/Kq6Lgi062pnyPUITyB+Z9Yk+e6cwA/vA6+uxZGSsBKsNxTBsRVxLm8MNIk/Wd+LLgQhRZS2UdgvHuagRBRfSp4dzRMu7RcqHaNS10hoKlJKMpnMpHxy2WxwXxUVFZP85DZ1p9gXUCZ228CeJnaOaZIZGqAwOkJ+dIT86Cj59MiE+aAVMunAEXkTGJEIsYpKIslKFK0Ns9jE3MNM4lUVFHMJUnUpmubWEU1WvCF1+6SUSNMEKVGiUfxikfwzz+ClM/iZ9Dg5TJx2GrGjj8Jau47Oz3wGL5PGT2fGNYONP/wBFRdeSOHFF9nw3ivGj6/E4yjJBI3//h3ixx+HuWIFQzfcwHPDPawb7icZS3D8sScz56JL6DWKPLXmITb0r2Kl28mq7DqGzWHuvuhuWpIt3LryVm5deSuzKmYxMzVzvJ+WmIYiFPp//nOG/ud/if/nd+g/oo3ObCe2b/Ouue8C4Kr7r+KZnmcm3f+hdYfyx7MDE/gNr/0RkTZpbV1AY7iezMurOPjks1D2UtX/6OjoOInr6Oigr69vnDzX1dVNilZNpVIUMhYrb1xOYl0GFbhX9Ric5dNe4zLg+wyjMKrqZIwIZmhz7Z3wfWJWgZRjUek7VAtJraZSHzZoikWYlkgyvSrF9OpqYpt8SPOuy5qRNKuGRlmbzbIhb9LpePT4gn5Vp7iJVixkFjh6eZZjV2n4wmN15QrCxhDNKkwLG1QmkqgVMZ7XV3Nf8Wn6nUGOEYfyWfNKKtbpCE0hdU4b8aM3lnKzLIve3t5JARqDg4Pj6+Px+DjZa65JMs1eTaTjMcSq+6HtRLi0lD9s0e9gxnFB1PNu1oAUc1kcs0iypo786AiZgX4a58zb7v1Ns5slS/6F0fRiWls/zayZX9i+HX0ffnFwUA/4Q3ft3MVvdi09DAw+QD6/utRW4TjDHH7YraRSh9Dffy8bNvymlMB3YhLfaTuUxHdi3rzR2/5O+h//wFy6FL9EHJRkkrnPPoNQFPLPPocwDML7zUPZicCf9en1VIYrSYVS3LnmTv609E+8Z7/3cHbb2YS13WcCLb78MmvfcwXJT3yO6KXvpWv5chbf9WcGetaTaJ7B2V/6BrmiztLHu0hkPayCwwrVI+N6zD+thURTjI51adbd28HsXgeAp/cLUzAEMw6vQ08ZDA4WiCzLcnpaIRTV+OkMSVETaAkdR0DR9ThZi/Cluhr0iMrC5as3u86rW2r59uxmcq7H7Cde22z9lXGVEwc6eLWjk5/NPRLV99B8H0MRRFSVTzdXc9Wc6XSZNp9etmGcVI4Rw8sbqjm2Mk6v5fCn7sHN1h9TEWdGJMSo4/J6rkhkk/W1hk5EVfClRLDzQTl7GmVitw3sDT52EGSeL2YzAckbHSGfHg1e1INp+jZoZIZq8L0IUmaxM39H+oObHSOSSG6i8asklqrYbFk49ub50PmmiZfOoMRiqPEY7uAg+aeemqQt9NMZqj54JaH99qPzoX+S+eb3kdkcw4bOkmm1FEI6cxcehHbpUdz5h2v4zJ1BKg0npOEnosQqa5n+818SmtlGYfFisg89XDIhJ8cDUKJHHolfLJJ7+GEqLr10i9dbdIt057rpzHbSmeskqkW5aM5FdK1Yxu/+84sI2+fvJ3bhqYE28ILZF/Cd474DwPWvX091pJqWRAvTEtOoDle/YS8Kz/Po6+ublHYkk8kAoBsGqaZmtKpqvEiUgqKOJw8e9CQjQmVUC5ENRXB0g6Tpc9Yqk9p2m3jRZ/DAMA/UuQhhUSU9qhWo01QaIiGa4lGmJZO0VlfRXFWBPkW5NyklnuNRHLbID1sURk2KIxbFjIVn+USqw8TroyQao6RqopslapVSMup6tJs27UWb9QMZCv/sJL7OpLte4+9HRhmOTt4nVswTG/xPpFxN2Knni+3v4Xh7LrZvs85aQr+xAaMyRqyiilhlJbGKKuKlPlYZLNONEJZl0dfXtxnZG3uvxWIxGhvqmV5XQe30OTTHfZK/Pza4iNT0jbVsW9+xxZx5O4sHfvsrXnv4fg4790KOfdd7tzuxrJQeGzb8ltra04nFZm+fCW7VA/B/l8Kl18H+l2x92/HzjCXx3Ujc8oXVtM74JDU1JzMysogXX3oPmpaYEMAwh7q6swmHG7frHDsLKSVOZyfm0mV4I8NUXn45AOvedRnma6+BEBhtbYQXLCB2zDFUXHLxDp/j4faH+eVLv2T16GpSoRQXz7mYd897N83x7Y92la6PX3TxTRd8iRI3UKIao3/9K4P/+7803fgXHr7xj6x85gliFZUc9+73s/CkU1GUbQ82HcsjO2xiFVysgjPezzq0jlgqRMfyYV59uHPCumD9u79+JBX1UV5+sJ2nbt1I5iTgqnDpN4/CSBm8vqiXjhf6qTF0tKjKmqSg4Fk4lTm6BwcYGi5Qky7QYGapmtHEkpmziFVWoEWi2FJi+j4X1lVySnWS9qLF55a3Y/kSy/exfEnR8/nXWU1cWF/Ji+k873xx1Wb3+JuFM7igrpLHh7Nc9sqazdb/+cCZnFad5J6BUT70+voS6QuInyEE1+7fxiHJKA8PZfjFhr6AOKqCkBCEfJuvVJhMq2qC+I4lFd9RlIndNrC3ELupkBkscuO/P4dr+5PMrb7nUigRv0lav3RpOj0akMOREVzH3uy4iqoRTaXGiV40tdH0uykJNMJ7PtedL326c92sTa9lzegaDqk7hIPrDubVgVe54u6N2rwaJcUCdRon9cyi97WVXPrdH0FmGOOFZfjZ7CQfwoZ/+1f0+nqG//IX+v/jP5GlvEVjmP3YY+j1dTt8rWYuxxM3Xs+rD95LorqGw694L8qcOjqyHXTmOmlNtnJ229lYnsWR/3ckvvTH9w2rYT524Me46sCrcDyHW1beQnO8mWnxaTQnmoloO/9bm6bJ2g0beGXNWlb0DdBRMMlqOgUjjBmKYBohCppBTg+RC0Xwp9AqhhyblGVS6bhU+z61COqESp2i06gZNCghKgagYnkaVEEHAq8yxKzmOIYAHB/f9fFMD89y8S0f3/GQrg+uBF8ifIkiN1dcRZRHSGk3oIpBPFlD2v0ABe8kHAmuAF9VwFBRwipqTEdPGIQqQoSrQrz8+jBLXx/m8BOaOPAdTYiwxpAGi9JruH31jcxt+QD9XgR3xes8GynSrc/ivA6bGkty8wyDnAaVdpHKfJpkeojYUD/J9DCp7Aip7DDxfA6BJBSNbRwwVVaN9+FEEhOFrGUznMnSPzDAwMDAxiCTsMuhiSFm+aupHn0VxTORF1+LOPBdQTCOa43nzNsVWIUCj//fdbz64L1UNDRy5tWf2+G0QVJKli79IuFwM21tn0XZkvP/Xy6HrhfgC0tAMzY5ho9pdo5XYIgnFlBddTyFwgaeefaU8e2CJL6zmTH9KmpqTsbzLFw3vVkS3zcTTl/fJDOuuXQpkQMPZNovfg7A+iveh1ZdvbFG7oIFW02V5Nseizqf4+ZVN/NI32PMjLTx57m/wS96+KaLLJG2gLx5yPFpF7/ogetvflBVoMR11JgCiRB3PfNL2mYdwsHHnU24OomaMFCTBkrMQKh77nctZGwyg0XM/GTid8jp09EMlaVPdfHa4x3kMkWsgoNvC4RUGWx4kqbmRqKjMxldM/n6jLDKR396AkIIXrxvAz1r0oQiGqFo0KKpEPufEBDj0b4CvicJxYJ1iqZgTyB+pu9TrWvENJVRx2VJrjiJGFq+5ISqOI0hgxV5kzv6RrCcIpZVwLIKmI7JF+Rq2gobeNgM8Ut9AZYvsSVYKJw4tIhvrvsfdOkFmuxT/w0OvGyP/NZlYrcN7E3EbiyZcG7E4sCTpyGlZPE/1zHzkNpJzt/bCykldrE4QQu4CRGcaBpOjyL9zV8aeig8gexVjPsCjs9PmFa1rTuNe75HZ64TgWB6cjpZO8tH7vsI69LrMD1zfLvPHPIZrjrwKgpOgTvW3DFuQq2ObHxhmvkc4Vg8cJC/5c/sd9xJW03/IG17nPR56cCHcGs5nqZCur+Pv3zjixQzGQ595/kce9kVWyW+lmdN0vZ1Zjs5ouEITpx2Iu3pDZz7j/MmbV9jVPO52Z/i7JozGC2O8vjgkzRpDVT41RSLOr1Fi17bot916JYuPcJnQBOMGBq5UIiiHprS1JeyPaotnxpLUmNDjSmptWQwb0lq7GBdxNv+38KXEkUICr5kRdEDRTDNUNClxAN8yaRe0RUUQ0UNqWgRDS2ioUc1jJigonA3yQ0/RkxI/OqLEEPVX2aEU/FyLr7pIC0fxfXRBKhIPARRReBKSd6HlCqQSJZE1nBr9QM8l3gNw9P5j/7/x7zCDKTtozfFEQ0R+qMqXWFBlwFdKnQKn07p0eG59HuTfwgdSa3nUGMXqMxlSGSGiA/2Eu7tIj7cR9gqMvFX13SDSGUVWkU1MhbHVg0Knk/OtFBxaaWTwXAb1U1tHOU/z9z1f8St2x91v3ci5p4VJNbeBY16++uvcv9vf0G6r5ezPvkFFp546vbL1XdYvuIb9PTcSjJ5EAsX/JRodMbkjVwbrjsTf9aJFI/+AFK6xONzkdJj8fMXk8+vxvc3Ps/TWz7CnDlfQ0qPru6bdyqJ796AwDfZx8uYSE/gZYr0/eDfsFevwO3rGt8uduIlxE68Aq9gYy9bjJJsQSpJpOUFA5wSBrQRhrU088xWCorJV6f/jFOyR3GGfTzJUBIR0VDCKkpEQwlrpXkNJaKihDUQYA8XeOWBG1k7uI6zDrsaUQA3Y0JxCgIoQInpG4lewhifVhMT5hMGQt89Fp2RkZFJ+eQKhSApe01NTZAUeHorM2e1EYlEGO0vkB4ISJ+VD4ih5/ocdX4QGPTcnWtZ/+pgaZ2DbXrEK0Nc+YPjALjzl6/QvmRo/NyqrlDbkuCSLx8GwLO3ryE7YhIKCUKaSVgtkAxnaKvrhlw/6f4sarGfkNWBlu9G5PvA21wxgqIHwXXxuqCPVkO2F9Y9Cr67cTs9Auf9Yo+QuzKx2wb2NLGzHQ/P8QlpyhZHoWbBYdkzPbz+eDfZYZPKhijvvuYIlF2oN7mj8H0PM5clPzpa0vyNUsiMUphA/AIt4ShmPjvlMcKxBLGKCiKpVBAIkqrkkfBrdKvD9PiDdFm9ONLh/Nbz+O6x30VKyeef+ALTYs3MTM1iZqqNmcmZpELbn/g1MzjAn77+ORzT5IhzL+bIC961nUlcJdKTSNcPmuMj3eDFHUxvbE7BRBUavuPx9KM3MXf20VRXTNtkX7+kmdp8f+nK8WWUlvlS0mvkWRkbYm14iM7QIP36IFXiWPzQfnRqy+kzfzzhanU8rZZc1QdxwvNRnUGihZWE/RQVbop6O0yjozDdM2iQKrUoNKg69bpBSNdAUxC6gtAmNF0BVeBJsCwPy/Ywix6m6VLMOxQLLvm8Qz5jk886uL7Ek+AjUXCo14vsH7UwRIGXCzk0UWD6bJ3qar/04iyiiyK6zCPsHFgZsHNBCaqxNrH6xlTQo0FAQqnJUIqiG6FznU/RjVDZ0ohlhikUDDIFjVtrbmd1vBfXi3Nh32Wcmj+CqNDwAVcP7lmVoLg+OFN8/ABTgd6IQldU0J3Q6I2pdEeVgAjqkN5E2RmT0CglDZ5LjV2kspglmR0iMtRDuK8Dd2gAq5BHCoEfiuKFo/iRKF44RkXIYr5YzVzW0kIPCpKCkuLZA39C84w2GpqbiVfV7LD/rGOaPPv3mznsnAuJJlM4trVDyY37+u9m+fKvI6XHrNlfo7nxMhRFob39OtKZl0pJfNchpUN19UkcfFDgT7h06ZfQ9IqNfnDR2ej6nk/kvD0YI2Zj2rExTZicoBGbUms2YR5v6u+XtAt46Q78TDtaw0yM1v3x8z2k/xIkoRexJPq02Ritc4ifcAahWbMnEDWNDqeLf3v5W7wy+CoRLcK5M8/l8v0uZ27l3CnP5/k+KxY9y1O//28ymTSNzdM545pvE68KyLL0fLycjZexkTkHL2vjZW38bGk65+BlbPy8Paly4RhEWENN6EGLGyhJAzVeIn0JfSMBNNRJ37ViscD69etZt24d69atY2RkFAj8Udva2mhra6O1dQbJ5K7/J3zPx7X9wFXDd+lf1kGuZxArncHO5rFyJobMcHDzc5Af4JFlJzGQb8byItgyCijUG8s4t+qbgOD+kWuw/SiGyBNWcsT0LLWVo8xszQOSoc4iqixiiCK6zKF5WVQvizJBKbEZUi3whdd3+V43RZnYbQN7ktjd/lIX3/n76wzbLnUIribEGUw2W3TYPq8UPDygWhXMDCk06AJlLzFFbAvtRg9rw120Gz20h3ppD/VQ71TxnY5PA/CJtu9iKhbTrUam2w1MtxqZY86g1WraxpG3H6aX5+WhR9iQX0Jcq+SwmjNoiLTu8nE96bEivYiV6ec5o/mDRCcmdVVEiRyJcaKEpiA1hRHNp0/z6Vc9+lSfAcVjQIMBFYY1wZChMhoysLXNzaG665K0TOJ2kbDTh+r0Ip1epDeIzwgL7SM4tHou2cou/tBz3fh+VeEqpsWn8d3jv0tbqo2OTAftI11UejVErRRW2iU/amIOj2KlR3DSo3i5Ubx8BtXPYyiF4IUlihiiQMQwiRgWYb1ISDExRAGNApqfR3FzCN/Z5u8nUZBaFJQwPiGk1PE9Fc9V8G2BZ0n8okdF/dopYwqkhMzoTNSwQDUkiubhSonr2oSUPCElj2BqcjYGX4ZwlTgmMUw3StGNYvkxLBnD9mN4Io4WSaFFKzCiFeixFEa4AiOcQjOSKFJFmh6+6eEXXaTpkrFdOvHoUqErIuiOKHRHlPFpU5t8MxWOpNmGZlfS6Pg02C61tkVNIU8sN0K6OMygncb0RmjQ1pPU8jwujgbgffJvCN9lvdNMt2hFiTVSVVlJvLLk+1fyCYxXBKbhqXKSWbbJTd/8CrGGWmZeeAam5pJxMmTt7KSWsScvwx2hNdfMo+veSdqqRNUzXDD7bk5ofoGsSGIqVXhaHYSnE4rMJGkkSYaSQT9hOqbHUHYguGFLkLI0QJpAusZkMtFcOXneDeQ35pe2BWI2Dk2Mk62NWrIta80mkjMlrE3SdPm2jblkyQQzbpBrr+W/f0X0He9g+LlFDP/qV7jz9qMwew7p2XN5PV7g6Y7b6V/5GKGizwE1H0YUwc+mGahvYdm8Q0ivGUJ/uYucGifpZjm762n+9NEPTulesS/A8G2Sbo6UkyXpjlLhpkk6WZK+R8rNkbL7SDmjpLwcSTdP0i2Q9ExSnkPSzRGWU2jlJsBBkFF1cCqwvQSOH8cuvUM6E0mWVizi80MdTP3FFvCt0d1+z2Vitw3sKWJ3+0tdXHPbaxSdjWYdXcC7KhMscDWkJsAQOAUPa8SFhIKnCzzPx5MS15O4vsT1fTxf4vm7/rupikBVBJqioCkCTRWoY9OKQFXF+LSmKOPznmIzrPYwqPYwILqxRJEr1A+jKgo/c7/PEvkqAkGD0kiLOo0F+n5cFrsEVQHfs1EcF88ycawidrGIY5rYxSK2VcQpFrDNIrZpTmkKVlQNIxLBCEfQw5HxaSMyNh/GCAXTPb0refLxG3Fsi8uv+A6aPnU+o7u6R/jFyl56TYeGiM7n92/mvFm14+RMaAo9nSt59LbrGO7rZPYhR3HsZR9mSEBnNkNnLkt3oUivZTHgeAz6ghFFI6OHyIWj+FM4Kodsk4RVpMKzqcanRhXUGTqN4RCVuopuWXjpUUa6uxgs1ctUFIWGhgZmtDQzvaGKabUpErrEyY6SGeyht381o5lOCvlebGsQ3xlhP3MWhm2RUzbgGn3EfEnc94n7kqj02Z7Pq1TDoEeRagQpwvgYSD8gZb4j8BzwTYlr+vh5Fzdv42YsPL+K0AEfxFcr6cl7vOJVoGU6mNHxILUDL6FIHxGNoiYSqMlEkBsxkaCx/k40JbfZdbhejK71p+FlMli5Ikuqz6Kv6iAqRlYwff0NPHxgmscPBsXw+eGNkrrK/QhNm4/fcx9qTKDFo6hhFzUkUXWJorkI4YC0EH4R1csj2Lr92ZUGjojjqgmkkYJICiVagZaoRE9VIcIppIgjlRg+cXw/yrAXpcMPs94Ps8EXdPgencKnS5F0axJ3giZeyMAs3lT0aSpImos+DUWPhJnHKI6yv/cXmsSrVIkgWGqAKhbJQ1nlHELEloRtD8OywTZxfRNLsckbFlmjyIiRJ2OY5HSbupEQ0/ojWIbPovnDrGsqMPYl0oRGwkhs1gb6W3nmlTZcb+O/RhcOP9B+x6IDFZZqkoyVIWNn8OSWf0dFKCSMBEk9SbVWSa1STQ1VVIoKKkiS8uPE/RgxL0zECxF2DXRHRbMVFIsdJGbKOOlSIhpinHSpm8yPrd9I2jYlZluDLyU5zyftBpGlaafUu1P3GdOiUCwwikrW82lY8RLz1yxn/9VLCVlFHFWhsmAycyDL1dd8n4vuupbQBP9o21DpnNfAhgM+wLJFabwJv4MuJKefMpP5c/ecaVvKwLrhmy7pkTQjoyOMZtOkzWwQbIMgJkLEpU7M1QijECaFgkKBEQrKMJ7q4KkunmrjYdKk7I/EZth5DctdScjLEHFzhP0iUc9mpllP2Ldw1T40MsSlS8x3iUuPuO9R6WlEpYWBu9VrdxBkFEFWUcZbXoQQVhsFNURntINhrVhap5JXNHy9kmmpIzDDOq/mXsb0TRShBA2VSlFNW3g/JBqrnSVcu/xR6pwpNHdljd2bgz1F7I774cN0jRY3Wx5DcG5OZ+aBtRx8WgtCCISgFFoNMHFejC8PrAg+jidxvaB3PB/H87E9H8eVOL5fWiaxXa/Ul7ZxS8s9D9uT2M7GfW03aEWvQEH2YtEH+YNxXImVuBuSTwffACGRUsG3aii2Xw0oCKMbUJF2NbB1c5GuCEKaQthQCWkqIU3B0BRCukpIFUSlRcwrEHELhNw8ITuPbudQrTyqmUOYWShkkGZ+yuNrkShGPIURiZCoawhMUPkcrQceQqq6mnhlJY90uSy+7498nptoEoN0yxp+Kt9N/PDzaKyGnnwB+fh9pFYvpRBN8OwRp7KsbQGF8NSpDqJmnpRtUuG7VONTqynUhwyaoiFaYiFmxDRaYhoJ4YCVxSuOMtrXQbqvk+xQN8XRPhQnTwibiOKS0CGieISkjeYVUdwcqrSmPPdESClwiOApUTwliqOEKKqCvAJZ4TGqOAwLh9Pz85AW3B3r5MmKNDlF4Lsq0ZxCfFjy0TskQgq6q0D1oToD2gS+rUSjQXRxIjGhT6AmglJ3SrQCL1eP0x9FAu0SXhl1iVcaHHvxLGYfMUWQwKu3wJ2fBWfC87KJf4rn+fzjpy9RM9fg4fhN/LPrXizf5qTwIXx45GzquhqQjgZqHsFLyEzPuE/lWLUWP7cpeZQIVQbaQN1Hi6pQlUCmUshoBBnWQAOhuCjCRqWIToGQkscQgcZQFdtwTNTCyHASz0jghmLYeoSMGmZYCTMgwgwQpV9J0Ksk6dUq6NGqyOgJ0lqcjBbHRaPCNjlwdD2nDT/H0dnnWa4uZLE4jGixm4u9e1hFG+vlLKKyjho/SY2foEYmSMkoru/g+Ca2bzFsdbNk9BkKbppKo4FpVfMxYhGUSAgZD0MiikjGEMk4ajLJZx/qZjC/uWa2WmT5rwuOQbpBMIC0PGzTwi6aOKaNZzv4lotvewhbIhyB6oLmqijbGFrYOJiKhalYFBUbU7FwVBdP8/F0QAd0BSWkooQ0tLCBEQ5hhMOEIxFi4TgxLUpUjxHRwihiai2Wj8T0fPITWsHzyXteqZ+43Juw3qfgB9sBqK5D2CwSsQoovk9/bWCJWLj8RWpHB4laBUJmEc02MesaGT3zXcRUhcTtf4L0MEo0ihaNY2g6FaEI04VO4tJLyXVswH7iceynn8MQkKkyWJswubP+PVhic3/rukSIm686Et838V0TzyuSUkMYUmW0OMy6zHqKdgHLLlJ0ipiuyXytlbgfoaPYyfPF17E8G9uzsHwb23c42dyfuGXwKht4OrISGw9H+HjCxxMeJ3UdRWXOZ218BaubO4jik/A3tnNWtlCJzkDVAMPxwUnrkr5Pix1HJR8MtrYCF0FWUSkIjYJQKSg6pqLTxHRcLUq7VmRAc3G1CI4WwzdiKKEIB6f2wwt5rPa6yJFBE0UUCqgijyozVCmjSOli+cH3VhOgCFDVGIZRSyhUN96HjFoMow4jVEuotEzTKjaaobfjHbY7USZ228CeInZtX72L85Qn+bJ2yziB+LF7GXf4x+/2c70dMFmNvel/pFToGwki6IM2Nu2XlgNCMjYjPInieEhF4Bk6vqpwtvMsP9SvJSo2joYL0uCr7kf5e+oUhJDMGNlAQikiUiqVSo4K0lSSJTXWZI6kLJCgQFRaRKRN2HcJSYew7xDyXUK+izqV88om8AW4ioKrqriqUpoea2ppXpTWCVxV4CkCT4CnBM0XPj4+2+OSKRFIIeiTCt1SYdAXDEnBkC9wEVyVEPhCcH1WstKVKEBKgQpVoUlTOC0RaEGHXZ+IIgiLqXM9hcxKWtaejWGleKX+IXJrTiI58xHiTa/h2yGEVDBCGZSS/BoG88zqzBOyfSxDYUNjlKFUnP51p1PX9ARSKxCVgowPX7IMjlV8LvLDzFz1bYRbgYysQdTchRJ9HRWB4oMig16VwbRwJdIGTIEsSmQRpAm+FfhI+xZ4lsSzwLPAnzhdckVy9DjFcA1mpJpiuAonksKLRfGjYURIw1BNDCVPSOQJiRyGMowuhtHVDLqSRVcLhBSTsLCJ4rGt8B1LaGSVKBklRlqNM6okySgxMiKG78GMXBeO1MjKML1KDe1KPRtoIuPHKHphpNRBqoCKLzVcqVCQLpaUSCWMLdiqzvL88jtsr8OOyESRHgounuaAcEFxEMIF4VKVE0QcH2HkcVIjJEWeFHlSskgSkxlFnUrhYWhpNG2YhLRISouktElIiwrfJSIcNLF1dwhPgilULHTMYGhEXkQx/QryooqcqMCiEkEFmkxgyDghP0bUjxHz46SkgYqCr9i4oTSeMYobGqUQHiUfSmOFRnFCaWRoFNVIo+lZhNj83Vtw4mSdFDknRc5JlqYrxpeN9ba/c2mITnMe42r3/6iXg4jUtHJU7JuJPUXsvvXdb/Jl59ebEYhv2h9FyZ4y/snftJ+8LPjoCekED6jvoOCiShfFd1Gki4KLIh2E9FCkiygtE0KiComtW/SlMhTDRXIhm4Ju4mguJ/S2Ue1G6Y1mWBMbIOWHSMkQSUKkFIOYqqMqAqFJUGWgNVRlcHWKXyJQPkJIpPCBTZrvgXRBeps0HyFL65nQSw8fBSlVfERpWgn8tBClaYFEKf1AStDJgN6J0paK9FHwx+fDdpGYmUfBx9ENjhNLJslkDK5UMIVBFGvsyFtFURrkiJCVEXJEyJX67ITpnIxOms8TnrB9lDwhPKGgCR8dF0246Iw1Bw0HHQe9tFwTHqpw0RQPVXioir+xqT6KIlFViaJKVBUUVaBooKoCRRMomoKm+qjCRyvtp5WOoynB8jGO1uPkGHSLpD2TjGeS9kziisr7YrVo0uHn2V56fY8IUK0IaoVkviI5XXXQpMuI71KFiyY1UFyEU0l07Zex6v/OquFpdHSdQ13DkzROexAjNsqjw4dzU89ZDNoVVBujnF/7NNM6D8dMt7Jk1i10Nz3JJ1Muqh9Gz8zGrnsFFJ/aNZeQr15CsXL5pqOD7UKgCVcxPR3L0zE9naKnU/Q0Cr5O0Sut8zVcx8BzNTxHw3f18V6WGq6O74Vx/QieDGETxpEhbBHCFgaO0HARuFLgCoGLRMciLookRZ4khQl9YUKfn9QnStulyGNsQ2NooZEhRpYoWRElTwSTMI4wEEIHxWAkL4gnkgglhuOHcbwIjhtlqd3PNfoNm73D/t35IHPNGL608KWJ75t4mEjPREoXtuH3SGkLWwthamFMPYSlhbDUEKY+Nh/G1CNBP2EbUwthaga2aiC34YdsuDaaZ4/3mlNE8WxUzySRGSWZTRO2LQzbxnBcdNelq0ZB821qRnzi5ib5ExVwpyXQFB0lZyNciaZpqLqBphloRgjNiCClguuC43q4nsRzfVxP4ns+nhcEbfm+H7z2/OBPqAAKIkgFBEypZ5QSUZfh26HrJ8mkKA1+6FxCtwJxfGLSJYZHtaMQFy6GUiSk5YhhERcmcYrERSHoKWCIrZsyLRn8hzIyOqGPkpGxTfqp13tKCEURqEKgKJT6YF5VQBUSXXUwFAtDtTAUk5BaIKwWCas5wmqOiJohrObRVRdNcdAVB11x0RUXww8RciPEnCgRJ0rESRCxgxZyKsCuwPRTFDSDvK6Q1wR5XQTTuiBXmi9qYpcSiLcP51nSnaXoeDRXRPjSmfO48JDtz1G4IygTu21gTxG7wo/2I1rs2Wy5jwKhVPBESy/I4C5LZGiM9JQoTBngoeCLEtETokTZAq3TWB+o5xRQFIRQEIqKoqiopaagUMxmMQsFqoziFh31R1svINXQiufr2KZCMa9QKCjk8xq5vE62aJAphhix4+S8KAWhYxt5TD2HpeextAKe4uFJBemr6KaCXpSECg6hYhHhWniKi6d6WLrAMjRMXcfUNSxVw1RVLFXFUlRsRcVWFByhUqLz+KhIqYHUSr0KUoPt8pzbPijCRREuKi6qcFFx0ISLhosunHHi6ShecC+Kj6v62MKjUoHDtAgRXed2pwtH2CRUlUojTCv1HNm/P9GiQahCp99Q6FpfRPiQmxbi7mwWe4LfkCrhSBsG6h+kWJfhmIoTmDM4E7HBxvUki+amGfZNipaJ6drYrovrufjSx/clUgqkFCAVZOn3kr6OlBq+r+FLPeh9DTn1Z3S7IfCDD43qTvjglHrVKX2IJi8bm9cUF114aPhoSDQhgx6JJiW672J4LiHPxnAtwo5J2C4SsfKEnSJhzyOsKBiaEZTa0w3SkSpMI8zs3Os0Wt14KAwZFYxqCSyhE/EtUm6OpJsjJLcdBLMpfBREogGJxJfBOMufOC3leB8sk5T4Cz6y1G/7A7pxKFfqJRsHbTIY9CpSIqSPKPUqwcDO98GV6vi5pAzeqjHNRhFgeSq2r5bkR2mgCqrm4ovSQFJu8q4p2QjGmhgbVMpgaDm2TIxvsy3IYFxKiU+MueUIsbEpoIzPgyj2o2wHcZ4IT2o4RLD9KJYfxfTjFIhQUDQKiqCoCExhYMowjlOF59Ti2fVIrwqpR5GhEEpUQ0QMlEgIIgaEVNAV0AW+piA1gVRFYEFQBJ6QmG6BgpWjYOUp2kVM26RoW5iOg+W4WK6H5UocT8XxNRxfn9DrOJ5e+s13HpoAQ1EwAAMR9L7EkMG8DoTGliMI6QohQyUc0giHNUJhjXBUJxLRCcd1wjGDSEInbGiBO5GuENIUnlo9yM8eXIU1Ic9gRFf5wcUH7BFyVyZ228Aei4r9VgVTxZFLoGdaLRIfKXwkHhIfX3ogSnuM92J83geKfmCKyvgKSU1Sp0tyvuCejB68OAFNgaQKC8LQogt8HywPovgIP0gSG2yslD58KtJXwFeRUsX1dbIiQVZJkFOSZEWMvIiRFxHySoSCEqGoGBTUMEXFoKiFMDUNUzMwDS14rYrgdTxGyMZ64YPhCHQXQg4YtsBwgz7kQMgeWw5hRxC2IWxLopZDyLZR/ZKm0ndKbarpoFdFoIFSFFAViapAQc1ywqxbqdAym8llxK3gzrXfxA6lsI0kcgrfHMUdQmpDuKEsVsSiEHLHX8wJqdCgG0xLxmiprqa6tgYtmQqCBMZ80eLxSbVwtxtSIq0cbnEQqzCIlR/ELg5jFYexzBGKhTS5YpaCmSdvFcmXXp4Fx6HouphSoYg+bgox0bBL8zYatgjhYARN6LhSw5EanlSD5qsBWR0nlSr4E6Y3I5s7lh9w1+EHfnCKh6pINFWiqaCrYGgKhibQVQVNUdEUFVWoqEJDEFy75wtcT2J7PpbjY7oeRdujYHu42whaihuC6hhUxQSVEUlFRJIKS5Jhn2RYEjd8YoZHzPCJ6B4RzSWseRiqi8DG8y38UnMdE6sUTOTYRRzbxHNNPM/E922EYiMUF6E6wf2qDkLdsrZF8SUVow41wzY1QzYRyycb0fnzEUcyQB1+McQaow05rHDgsy8ybbib0fpaVi04CF2X/GjVT6b8rErgLw3nbEMmEl2AIQS6MtYrwUd2rAmBrggMEdQL1YWCUZrXFIF0PRzbwrVNXMvGsS1StXUY4QjZ4SF6Vq3AtS08dyM5bTvkSNRQnOGeTka71iNUDSE0UDRARYQqAz9h1wXfR0oNIZVxzT9SKRGzrd+bEB4CL+hLpk1Zar5wgwGe8HCFh6MEzVY8LMXDUXx84SG3MHjXkOgSdAkGoCNKJERwYCG7RZn0qCqqlGiAIiWGlBjhCtR4PQOhGaz1m1lbTLIhq2CXFL31VRVMa5xOQ8MsKhP1eBbYxVJy4aKLXXCwSvN20cUyTTx/GM8fRjVGUSNptPAoWiSNFi61SBotnEEom2uTpR9F+FUoVKMq1ehqzbgfWzhaRzTWQDzRSDRehaoruL7Ecn0sxwt61w8IobOF6W1t65aecdvDslxMyw22t0vrPR/bk1gyaLvKVporIjz11VO2veEOYm8jdnu8mKkQ4izg5wTa7GullD/c0+ecEqlpkO7YbHFB13k8MR3fV/F9pdSryFLvo5FGIoVGjUiB0PkLLzJEDkf1xnX0R+sHcW7sdIQSwkq8SlNoGs3hFiqMCnxVIYPHs77LKB6j0iXte2SkT0b6ZH2fnC/JS0ERFRMdW4RxlQhS2Ub1A2mjenl0P0/IyxHx8sTcQeJujiYzS6VfoMq3qRYedUJSr6o06hHq9QRxvQIZr8TTUrhaAk9N4KlxXBE4/Lu+GpgtbA+36OCaNq7p4FkuruXg2i6e7eHaHp7r4zl+sL0r8VyJ44FXUoJ6vsCTAk8qTBw9L8olOTH1a0ITTBm2NHi9+B5ijdXURAXRuEM0CV7MJ6cWGXay9I0OMTA6CoCqqjQ1NXFwqbZqS0vLtgtRSxnkcMuOgjkKxR3p0wjfYcx3PL7ZwQWEkxCugEipVVVvnN9aH07BdpQbklLiShfbs7E8a7yfatp0TYqOQ96xKNg2Rceh6NgUbAfTdSkWbarWRFEsnburn6VvzUVMreGQXH5kH8c934bZaFNcCNH6CJWROFWRBNXRFNWRJDFjz1VHMR2PdNEhXXTIlPqp2ti6zszGZeYW8uSNIWaopCI6yYhOapOWjOikkhvnE2GNKAK14CFzLoVRi+yASWYoT2Y4R340iy+tgOyVyF8kCZmUZCDmEm61qPDbCXtDHD9ajeqNMm/Z3/CBTLiCkZYYr4cr6N1gMq34IgMnzGDISFJjbz4IGgoleXJ2K3ElR5Q8UfLESn2UAjHyhClu5tLgAcVScy2FfE8cJ6/jFAzcgoZb0Kia4xCvE2S7DdY/unlUe9VBDkZ1jOJIFYWR+Qg1hFAjCBFFETGeXVqPIIbvGUhPx7eDXno6gW5V4ghwVYGvCaQmEIYSJM4Oq4QigYYmGtOJx3USiRCpZIjKVNDCMR09pCK25tAqJXgOuGZQVWST3rFzZMwRslaajJ0OIoudLBknT8bJkXGLZNwCGc8k41tkPJuMdMhIl9vaCzR5mxOmHlXlzOkbNUMRN0JdsS5oI3WEvcBvrGAUyKQyFJIF7JTN6pBGSH2NsKWSciRx1SOueEQTDuGkRRgLQxYxZIGIn0fxC1Nbk0QCQRVCVoI/E9wqpFOJNKtwiynsfBIzk8DKqwFBzLv4Uw6aBkstSDA8VmXCiGgYYYWQoWAYYOig65KE6lOleoG7ighcWHRpofk2imshbQvfspCWjbQ2n/ftCessC9/eOO3ZFq7jY4sothbDiVTihitwwimcUBInlMAJxXGMGNcY6pSvsO4pAijfjtijGjshhAqsBE4HOoHFwHuklEu3tM8e09hNESXjq2H6jvo6oy2n4zgOnufhui73DtzL2sJauu1u+p1+XFxma3N5Z/hyRlyXR+07kITQqEGIOnxRh63EMVUdS9GxNR1LNbA0HUs3cKeozzkRmudiuA4h1yHk2oScsWmHkGcT8l0ivktE+gRJHCApBElVIaZqaIpEEz4aHpp0Ss1G8y0030Rzi2heAc3NBc3OojmZYBo32G+qXtURY8Rke0jJxF6f+uMupcT3ZUACHR/X8VGW3Erome+iFnoh2Yw47Zs48y+iq6uLjo4O2tvb6ezspFgqQxaNRmlpaWF6SwstDdU0pUJobnbLZMxMT73M34ovi1BKSXh34v5DyV2qVPBm49jvPUh3dvPI37HRrpd3UGNvtBZw12G53tSEsOCQLrqbEcOMuXG+YG/ddy6iq5OJYFijStWo8AVxF8K2j2b6iLyLm3WwM84kA4KquCysWkxr5HkavMXofhYpdLoWfAX10HdT39qM9dS1hB77VxRvYkUQg/amDzAQOQTbDrSMrlPAck2KZg4PD6lJXM8i2zuC5zh4rhuUlrN9wtN1ojNUPNNh5KmNz4PQJGrYp+KAIokZJr4lya830GMOeszBiNkYcRs97O60G5TvBS4S0tMCC4W/UfMsSr0yQT+mihCKEkJRwqhKCE2PomlB00MxtFACPZTAiCQIRSowYhXo4QRqaZ8tlmPbBXiv3IRy5+cR7sbviqeFWHbUJ3jdmM9Q1xCZngxW1gIketQjWm9jVBbREnkUNYfq59D8PIYsEqIYkLcpfDU9CVlfkPEEGRdyriDvCAq2oGgJTEtgmQLXBNUB3QXDC3rdBcPduCziqYR9lZCnEPYUdE8Q8kJoMozqRVBkGCHDIMNIQkjC+CKML0J4ShhPCeNq0VLkawRXiyKVrX/nFN8JvkVuofRNMtGljYaNMea7rHjoqoeh+hi6RNcFRghChoIW1hGhEErIQBghRCiECBkoodBm86c/kqdnimof+4rGbk8Tu2OAb0kpzyzNXwMgpfzBlvbZo5UnXr0F78FvoWS6GQ2n+Mv0w/hHLMposQeJTk3zx8l5kO69Dt8dxdMacPUmHL0FJzQbz5ixxUML30KVgYEtLBwiwiOmSOIKJFWFlKJSoapUqQaVqk61GqJKNahWDAwpcF13tzdvipHkjkIVY6TRL5E+NyCN0t46KRSgaTqargdOzHoYLRRGC0XRwjG0UAwtkii1JGo0xeDQCB3dPbT3DtMzUmBsAFkT9pgeLtCijzBd9FBl9yCs0YCcya1oYYS6BfK1HYTNSLylydmu4LYn1vG1u5dhTng3hBXBDy45kIsOm/YmXtmbB9v1JxG9SQSxsHWtYX4KUqhISPiClC+oEQq1ikalVEh6EHM8WlhOa+h51lhH0+/MpSn8OiJ/GwYFTm5cT1hY5KngWe9SViuX4JoOdu+t4OaQfh5kUEFEDR2KHj0JKR2s0V+CiCCUGIgYvhLDCc2hGGrDxkGV/fhGHD+SRI2E0Q2FUFgQNSQRwyeme0R0n6jmEVU9wkowgBReEdct4DgFPLeA65l4vokr7VJAh4OPjS+ccfOoVFxQXFC8oKkeQvURqhc0xUdRvaApHsqYaV/d+Xea9EVgjfHU8X4joSyRSl9DyLGmo2AghIEqDBQlhKqEUJUIqhZBLxHL6pHl1K27G80cwtQTvJhayPJIHMMoEgqZxCMWIaOIUPPBfW8C4aloVhjNDKEWdNSchppTUbMKSkagjvgowz6kXTDHNF1bT+K7PfB0BU9T8XQFV1dwNYGrCRwNbE1gqxJbA1v1sVSJqfqYioel+uPbOCrBtAqupuOrEaQILE1CREFEUIiiyAiKjKDJCJofISRjhLwoIS+K4YbRnTCK3LqlQqo+GB4i5CNCEiUEWligRgR6WMGIqBhRjXBE58URl+tfyU3yE96XfOz2tCm2GZho/+wEjtrD59wyDryML/uV3LHqr4QLzyCd1Xi5ejy9BdeYTqfdgCaL6NWfIKx4RIVHTJUkVEFKU6jQeqgyDGpCEepCURoiMZrCSVqiFcT07S8P9EbB9/1xLeSuEsTNljsOrm1iORZ5xw7mXRfX83A9P0jm7AhwgM2qVLlAutQmQ8OlmV6OpZsWumkRA0SVMKgVYFSUyNdh26c9M+K7FFW1r+Lid7ShxA1+fNcyenIWjckwXz57vz0WUfZWgKEp1MRD1MR3/Dl3PH8zLWHGdDcjh6NFhw2l+Vx+ATI/B036VGg2hwnJOZWS9UMav15x5PixbcNnJJXHElArHXw9gWc0II0ERJKIymaM+hTRuEE88kNSlTFSyRAVCYOKqDGuYYxuUopqb4Dv+/i2jV0o4hTyuMUidqGAVczimBkcK4tt53GdPK4bkEuvRCo938KTNj42EhsfF1kilihuqQ9I5FgvdHucXI4vUzwUxUcSmK6nopUDtbC8VgA1pSWraQUoCtRRUAdBzQiUDKhpFSUdzKtFA80MoxBCNcIljVMIxTDGp0XIQKkJIZonaqc2aqyUUGlbY8L60vz4uqnmdR2xkwNXX/qbuYBM5Qoy5TJ/bFkR20tjeRZZz8ZyLWzbwTODdEbSFPiWQNgq2ArC1lAcHdU20N0QhhkhlI9guBFCXoSQG0WVYlxKKeB0XeOJsEtG9WmuiO7RqNi9DXtaY3cpcJaU8qOl+fcDR0kpP73JdlcBVwFMnz79sA0bNuyxa3pmcD03r32aSl1ndqqVllgVTdEkTZEUUW3qyghl7ByklFOTQtvCLWZw86NBX8zgmlkqEjEaGprQYpUbCZoRK5OzMvZZuJ5P1txoJs6kRyi8+E+K8TaS9dOobaijtqaKVEQnrG+5/nUZOwfPtrFzGczCKHZ+FKuYwTEz2FYO18rhOPmAULpFVAT1iWZi4UZCoVq0cGJqUjVGrMqy2ilsiVgWTJNC3qRYsCnmrVLAicMB82czf+bsPXpNe5vGbt8yxZZRRhlllFFGGWXsRuxtxG5POxEtBuYIIdqEEAZwOXDHHj5nGWWUUUYZZZRRxj6JPepjJ6V0hRCfBu4jSAxynZRyyZ48ZxlllFFGGWWUUca+ij2ex05KeTdw954+TxlllFFGGWWUUca+jn0zn0MZZZRRRhlllFHG2xBlYldGGWWUUUYZZZTxNkGZ2JVRRhlllFFGGWW8TVAmdmWUUUYZZZRRRhlvE5SJXRlllFFGGWWUUcbbBGViV0YZZZRRRhlllPE2QZnYlVFGGWWUUUYZZbxNsEdLiu0MhBADwJ4rFhugBhjcw+coY8dRlsveh7JM9k6U5bL3oSyTvRNvhFxmSClr9/A5tht7HbF7IyCEeH5vqutWRoCyXPY+lGWyd6Isl70PZZnsndgX5VI2xZZRRhlllFFGGWW8TVAmdmWUUUYZZZRRRhlvE+yrxO63b/YFlDElynLZ+1CWyd6Jslz2PpRlsndin5PLPuljV0YZZZRRRhlllPF2xL6qsSujjDLKKKOMMsp426FM7Mooo4wyyiijjDLeJigTu7cohBAhIYRemhZv9vWUAUIIpdSX5bGXQAhhCCHU0nRZLnsJSu+vUGm6LJc3EWO/vxAiIoSoLU2XucFeAiFEXAjRWprermelLLy3GIQQxwshlgAPAV8AkGVHyTcNQoiEEOJLQohXgV+UFpefqzcRQoh6IcQ3hRBPAfcCn4Xyc/JmQwhRJ4T4gRDiYeBh4AtCiFBZLm8upJRSCHEw0A585U2+nDIAIUSVEOI7Qoi7gJeAK2H732Hanry4MnYdpZGTkFJ6QogwcBVwDfA4cJcQYi3wt/LL8Y1DSSaKlNIFVKARuAG4AkBK6b2Jl7dPYuJzArQQyOTzBFVsHhZCvCKlfPhNvMR9Eps8KyFAB74BvAY8DTwPPPjmXeG+hzFtnJTSn7B4PoGyoG2KdWW8AdjkWUkAXwXOkFI+sqPHKmsW9lKMqVyllP4YUZBSmsCRwEtSylHgv4CTgHlv0mXuU9hEJm5pehT4AfATwBJCHDJx2zL2LKZ6ToDVwP+TUi6WUvYDiyh9sMp4Y7CFZ6VDSvn/pJRPSymzwFrAfDOvc1/CJjLZlLhdCtwMmEKIwyZuX8aexRaelQ3AklJDCNG4I8csE7s3GSKAuqlPQ0k93iCEOEkI8XMhxHlCiBTwJLB/abMlgAWUycRuxHbK5GdCiAtKywdKL8rXgDNLm5efrd2IHZDJ+VLKUSllTghhlDYLAWUt6h7Ajshlwj4fEkI4BDU8m97oa367Y0ffXyUz7GrgZaCPQHsH5XfYbsUOyOWS0qrXgWeFEC8AvxJCXLW9vo9lwb3BEEJUCCHOKZE0ZABPSulPJGZCiCsITBXvBE4DPgQUgG42PngDQC/QPHasN+5O3j7YSZmcCnyktHzsOXoMOOGNvfq3J3ZBJh8rLdellLYQ4khgBnBreeCz69hVuZRwD1BdWnbxGMEoY+ewCzL5eGnVXKBbSrkOGAWuFkJcXXYp2TXsglw+Wlr1M+CHwHHAj4ALgYu359xlH7s3HgsIfLEs4EEhxDzgfcBRwBNCiF8RmCeOBT4npbxTCPEgcC0ggOXAWQBSyuHS/ve88bfxtsKWZHIk8ORWZHIdBCr00oP6HPCl0rLyS3HXsKsycUrH+RLwayll7o2+gbcpdkkuAFLK3tLkUiFEJ9AmhFDKfl07jZ39pvy+pNWeC7xfCHEVECf4znS/CffxdsPOPit/AJBSPk/ggwqwSAixFKjfnmelrLHbAyipXLf0264nUHvPLs2fRKB5+xKQB/6N4I9wOPBKSfNwP4Gs5gO3AwcLIc4o7T+9tH8ZW8FOyuTLbJSJzeYyGYsmGxuNrQIKQoifCCE+IoSo31P383bAHpTJmGvCMQQvzueFEBcIId4rhEjsqft5u2BPPysTzqMCc4DlZVK3deyhb4oAZhFEXf4QOA84AlhMYJItu/dsA3voWfGneFY0Al/6VdvzrJSJ3R5A6SO/pR9/AOghGCUB/BF4AfgkgQr2eMAobXfUBM1DFrhASlkAvg18UAgxBLxaamVsBbtBJjrQDxy9iUzeCSCEOFoI8RjBh+oQwCEwa5SxBexBmZxbmv4MwYj5WoJo8gJQ3M238bbDHpTLmQBCiKuFEIsJfLpWE2i6y9gK9uA35SIp5V1Syj9IKdcSEMC7Kfmklt17to49+KycDSCEuFIEPnYvASsIAsG2ibIpdhcwlUq0xN5nAh8EHCnltyeul1I6Qoh24FAhxHQCxn41gX/W9wiiK48BfgdcVrLPC2CQQLULgdbuIRlEZJYxAdshE1tK+e8T128ikxkEL7erCVLKTJTJtQQySZZ2HQIOKk23A5+XUr60R27sLYw3WCbDwH6l6euAX0gpn90jN/YWx5sglwNL0y8Bn5ZSlgndJngTvikHlM4RklJaUso08Ps9eItvSbwJz8oBpenXgE/t6DusrLHbTgghlJLpYBxjghZC7C+CHHMQCOvnBCOeP25yjDG1djuBRqcZOBFISSl/D7gEqvFLpJT/IBD4eQQ5bf6Hkkq35IA5Wjqmuq+qy3dSJjdscoxNZdLERplcy5ZlkiSQyazSebvHSF1JJpOua1/BXiCTX1NK/yOlfHDshTjVde1L2MvksmiM1JXfX2/6N2VO6bzWpte2m27zLYe95FmZWzrvixPeYdv9rJQ1dluAEEJMVENPpW4VQnyVIP9PBnhMCHEDQUb1I4C/SinXT9x+wvF6Su1gAu3bB4QQfyMQ6u0EQodgxPUycBiB6vbHm16D3Iec9Msy2fuwt8tk7Pq2Yi55W+ItJJfyszJ5mzf9/bWla3u7Ym+Xy848K2ViNwET1a0TBS2CmqxnApcR2L9/TGAblwSRRyngVqAC+ClB4s2t/bZDpXYM8Fvg0wSRro9JKZdO2C5cOlcKuAu4c1fv8a2Gskz2PryVZDLx+t7uKMtl78NbSSb7Et5KctmpZ0VKuc82gmz0VwHNU6xrBs4tTZ8BPABcAiwsLTuTwDn+QYIoot+XBB8lUJefv41zzwTatrBOfbN/m7JMyjIpy2TvbmW57H2tLJO9s+1rctknNXYT2HoNgaP1aqBLCHEyEJFS3k3gD/IFIcQKArWpRuDIWCgd5gUCFv8xGSR2nHj8PuAAIcQjUspsyS4u2FjLEhlEIE3cZ6ysiJT7kHliDGWZ7H0oy2TvRFkuex/KMtk7sa/KZZ9wkBz7ISf8oGMJZVcS5OsZqyN5AhtLQj1NoIptIkgAPAR8CvipEGJMTboIuEAE5UBOF0H+sgaCsl+9wLiqV06oZSmEmC6CjPibCnmfME9AWSZ7I8oy2TtRlsveh7JM9k6U5RLgbaexE6VoHrkxikVIKaUohXMLIUIEKtmUlPK7QoheYGbpR38ZOFsIUSel7BdC9BCEHT8tpby0dLwEga38GOATBKHOdxHkrPkHkJNS3rHJNYWBc4BTgEMJwsx/WbrOt/2DV5bJ3oeyTPZOlOWy96Esk70TZblsGW95YrepcOWEiBYhRLWUckgIUUcQyXKslHJECGEDFSXBrSXIr9QMrCEIXT6QwJ7eQVC77WYhRAVBrbaDCWzrz5X+EN8Bvrmp0MTkvDenE1SI+F+CLOsOb2O8hWTSQlkmZZm8iSjLZe/DW0gm+8w3Bd5ScnnTn5W3vClWBmrPMcYeE0KcIoT4tRBiJfAHIcQxUsp+gvIeJ5V2WwOECHL4rCFI6DifQF2bJWDcENjb9wMagfrS9rcB7y8dEymlUxolTMp9M/FPJ6W8U0r5Uynla/vCA/gWksnPyjIpy+TNRFkuex/eQjLZZ74p8JaSy5v+rLyliZ0QIiWC+o9/EUIcQSCY7xNEmswFngE+LoSYDTzCRpv6egKb+BwCu/sgMF9KaRNkqz9YCPE6gRPk54EVUsonpZRXSSn/JqXMbHotcoJdfV9GWSZ7H8oy2TtRlsveh7JM9k6U5bJj2OtMsUKM28knJQ2cYjsF+BaBWvVxAgEqwHKCkhwANxLYxY8BHgXeDyClXC2EOArISilvFkJ0AAcJIZJSypVCiHePsfQpzjmJoe8LKMtk70NZJnsnynLZ+/D/2zu7EKuqKI7/1oipWApa2XcxlgYS4WQRJWVBD0YkRVBWEAoZ9FBRYRBMJD2UMEhG1EMPfUCQRFARUilJiVEig4NRlD1MjRqWipCVWbp6WPvYndtY15xx1j3+f7C5H3P3Ofee33lYs/bea8tJTuRl5EgR2JlZtTz4UCW4ejSzGcAud9/TdANcA8x198sbjjMO2ETMPcDd+82sE/jC3TdabMmxHJhKjKn/ajHZcYCY6NgJbK5EN8ttV8n/BznJh5zkRF7yISc5kZfjw6gEduUiNtZ5caJODBap1FOJlSdvlC5bgMVNUf0eSp0Zi2rRhzxWwvQDS8zsdXfvIyYyVlH9QmBBOd477v5z6b+T2KC3E9hc3VTtLvdokJN8yElO5CUfcpITeRkdjktgZ4NXjfwjGjazyUTdmHHERrj7idowt7r7gJltNbMud+9t6LYb+N3Mrnb3DeU4Vb2a74AeixUy64Dect4+oK/hvNV/BduADyk3RdNNVUvkJB9ykhN5yYec5ERecjCigV252POAN8vrakx9HjCfiNa73X2HmS0AvnT3LjObTYyZn1wOtQ64ysw2+9+p0u1m1gs8WI53HTH+/izwGdDh7k8N8Z2GSgUfADYM/xXIh5zkQ05yIi/5kJOcyEsuhnVVrJVx6gqP8eslwB1mthSYZGbTgbuJaHo1sMLMzgbeB34oMrYBHxH7sQF8DlwKTDSzsWY2v7z/BFH8bwqwAnga+IVYxtxZvpM1fi8PapV2/TfkJB9ykhN5yYec5ERecjOsgV11Ec3sfDOba2ZdxEqWZcCFhISHgB3APmLlyhyibswW4BxgArHh7tfEJEeILT+uIKSOB643s/HufsDd17v7I+6+2qPOzEEi1dpTvtMJKxfkJCNykhN5yYec5ERekuPuLTXAiJoxQ/1tQmmXAR8T4rqBM4BHgZ6Gzz5OjG8/CdwMjCvvn0dIml5e3wSsr84J3AJMPML5O4h0bMu/pw5NTvI1OcnZ5CVfk5OcTV7avx2L/MnlcRLwInAncBewvOlzs4EPgAuIOX03AJ80feba8vgpsKA8nwrMrGQOcePZaF+8bE1O8jU5ydnkJV+Tk5xNXtqv/efiiYZJkDOA24CTiNTqDGJMfVoRvpaI4heVce6dwDfu/q7F9hunuXs/sMbMHjOz54h0axfwNhH9LyL2c8PddxOrYfCm9KoX4ycqcpIPOcmJvORDTnIiL/XBWrluZnYx8AqwhpD6I/AasJgYH/8KmOXu+81sDrHC5UrgHmIvtoXEHmynAy+5+xozu53YYHetuw8M8++qPXKSDznJibzkQ05yIi/1oNVyJ9OBb4FXge3u/puZPQM8DLwHvAVMM7Pv3X0THC4EOBMYC7xApG/3ErVncPdVw/g7TkTkJB9ykhN5yYec5EReakCrGbtTgJeJis0dxDLjFcRWH8uAVe7+gJlNIFK43USkvwp4/kjpVGsqZihaR07yISc5kZd8yElO5KUetBTYDeoQqdrFwC4iOl8JnOnuN5qZEYUI/3D3vUP0HUNsB6Jx82FETvIhJzmRl3zISU7kpX1paSi2SDwLuIQoJDgbuN/d95nZRmCKmY3xqCvzU0OfjvIeAI3PxbEhJ/mQk5zISz7kJCfyUg9aKlBcou5zgXuBP4Gl7r7VzC4C7gN63f1gEXy4j+SOHHKSDznJibzkQ05yIi/14KiHYgd1jtUus4CVHkuWxSgjJ/mQk5zISz7kJCfy0l4cVWBXpVyJIF0TIRMgJ/mQk5zISz7kJCfy0t4cU8ZOCCGEEELkoaU5dkIIIYQQIj8K7IQQQgghaoICOyGEEEKImqDATgghhBCiJiiwE0IIIYSoCQrshBBCCCFqwl/NH4JW4v3sUgAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "line_styles = ['-' for i in range(10)] + ['--' for i in range(10)] + ['o-' for i in range(2)]\n", + "df_heatmap.transpose().plot(legend=False, style=line_styles, figsize=(10,5), rot=15)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also just plot each feature vector itself as a bar plot with one bar for each of our 6 features. We have set the y-axis in the below plots to be fixed such that the differences are more obvious." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlEAAADvCAYAAADSI4HyAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAhaElEQVR4nO3deZhlVXnv8e+PZlSmi7SIILag4IQKtiiiBmdx4jrEOOOQtF41inHMTUxQ40Aeg0OcLhEVIyoqifMQiTigEWwmEXBA0jJLA6K0KON7/1i75HBS3VW9u8/uqurv53n2U6f22cPa7951zltrrb12qgpJkiStnU02dAEkSZLmI5MoSZKkHkyiJEmSejCJkiRJ6sEkSpIkqQeTKEmSpB5MoiTNW0m2SHJ2kp03dFk2ZkmOS3LQhi6HNDSTKAlI8q0kf0iyqpt+upbr/nnP/b45yZlJbkhy2DTvL07yiSS/SfLrJMdMs8wOSVYmOXFk3rNGjmVVkmuSVJL7du9vn+ToJJd102Ej6+42tu6qbt1Xde8nyd8kOT/Jb5N8Ksm2syzXkm5bo9t+w8j7uyT5fJIrk1yY5MUzhHAZ8J2qumRs34d1+7n/2PzNk/xTt+1VSVYkedcM+5hWkqcnOSfJ75L8IsmDp1nm77pyPGJk3muSXJ7krCR7j8w/IMnnepblo901tPPY/MOSXD8S63OSPKXnPh6e5CfdtXRCkjuOvH048A99tivNZyZR0s1eVlVbd9NeA+3zXOC1wJdX8/6/AZcCuwG3Bd4xzTKHA+eMzqiqY0aOZWvgJcB5wKndIu8EbgUsAfYDnpPk+d2654+tuzdwE3Bct+5zgecABwC3B7YC/nk25Rqx/cg+3jwy/+PAfwM7AY8D3prkoavZBsCLgX8dnZEkXRmv7H6O+mtgaXfM2wAHcnNMZi3JI2nH9/xuOw+hxXd0mT2APwUuGZm3M/BCYHfgA8DbuvmbAv8EHNqjLLcGngL8Bnj2NIscO3IuDwU+nmSntdzHjrRr8Q3ADsBy4Nip96vqZGDbJEvXtvzSfGYSJa2DJG8BHgy8t/tP/71rs35VHV1VXwWunmbbjwLuALymqn5TVddX1WljyzwQuCfwkRl2dQjwsbr5EQVPAP6xqq6pqhXAUcALVrPuc2m1PStG1j2qqi6oqlW0ZOLPktyqR7lGj2VrWlLzlu5YzwA+u7pyJdmNloycNPbWg4GdgZcDT0+y+ch79wP+vaourmZFVX1stmUc8UbgTVX1g6q6qaouqqqLxpZ5H/A64LqRebsBp1XVb4Hju/JDS26+MBLjtfEU4CrgTbTzvFpV9XXatbbHWu7jycBZVfWZqvoDcBhw7yR3HVnmW7TEV9pomERJN3tb18zyvSQHzmaFqvob4LvcXIv1MoAkP0py1Wqm98+yPA8AfgocneSKJD9M8idTbyZZBLwXeBmw2uc3dc0uDwHGk4WMvb7nNOtO1eocPcO6WwB3WYty/bJrUvtIV8sxus0Zy9XZGzivqm4Ym38I8EXg093vTxh57wfAXyV5SZK9u+O7eWfJl9Zw3r40cnxLgcVJzu2O471JthrZzp8C11bVV8bKdi6wd5LtgUcAZyW5A/B0pq9lnI1DgE8CnwLumq7Jdlxrhc3jgM2Bs7t5u63heK9K8sxu9XsAZ0xtq6p+B/yimz/lHODePY9BmpdMoqTmdbRagV2AI4Evds0xvVTVvapq+9VML5nlZnYFHgWcANyO1tzz+ZGk4+XASVV1ygzbeS7w3ar675F5XwNen2SbJHem1fbcapp1H0RrWvvs2Lp/nta/aTta7BhZf03lupxWG3RH4L60prBjAKrqauB7wBuSbJlkX1oty3TlAtiesRq8rjbsT4FPVNX1XblHm/TeRqs5exatSeqiJH+svamqx6/hvD2+W2wnYDPgqbRar/sA+wB/25VhG+CtwCvGC1xVVwBvAb5Jq7V5NfBuWgyflOTbaX3Cdl3NMd9CVxv30O54fwX8J/+zCfNpSa4CVgFfAN5aVVd15Tl/Dce7fVV9otvG1rTmwlG/oZ2/KVfTzom00TCJkoCqOqmqrq6qa6vqaNqX+WM3cLF+D6yoqqO65q1PARcAByS5PS1Z+ZtZbGe6mqSXd9v/OfB5Wk3GhdOsewhwXNdsN+XD3fLfAs6iJXkAF85UrqpaVVXLq+qG7kv/ZcCjusQDWnJzp+44P0DrIzVduQB+zS2/xAGeBNwATNUAHQMclGRxt/8bq+p9VXUA7Qv/LcCHk9xtNfuYzu+7n/9cVZdU1eXAEdx8vRwG/Ovqmuaq6pNVtW9VHUSrZbsWOI1WE/UE4DPMvlbqOcA5VXV69/sxwDOTbDayzKe7hOjWtGa85yZ50Sy3P2UVMH7zwLbcMondhtasKG00TKKk6RW3bFaaadlb6O68Gr/DbWr64Cy3+6Nptj31+360fj9nJ7mUVpuxX5JLu+amqXJMdf7+7C02UnVlVT2rqm5XVfegfRacPHYMW9FqdY4eW/emqvr7qlpSVbvSEqmLumlW5ZrmeDbptv3LrjZocVXdH9hxvFxj8blT1yl7yiG0WpPzu/1/hlZr9Mzxlavq91X1PloydvfumL+6hvP21W69X9MSu9FzM/r64cDLu2O+lNav7dNJXjeyzFR83wq8itYUekHXV+qHwL1Wc8zjngvsPrKvI2gxm/YfgC6x+ypdE2emvxNzdHpWt+pZjDTVpXVm36ObP+VujDT5SRuFqnJy2qgnWo3Eo4EtgU1ptSG/A/ac5fqfojWR9Nn3Zt1+P0G7RXxLYFH33g60L/hDgEW05qMraV+SW9Ca+KamV9A6WN9ubPtH0jqUj+93D+A23XYPojWz3WNsmWcCK4CMzd+hWz+05OPHwLLuvTWWC7g/sBctaboN7Q6vE0a2fTdajcbmtDvNLgcWryF+PwIe2L3eBbiR1gQ6Woa3A6d0yxxK67y+VXeuD6HVBO2+luftTbRk57bA/6L1i3tz995txvZ/AS0Z3XpsG28BXtm93hm4gtZU+GLgS938JbQEbck0ZdifVuu299j+jqHVHkKrFfv4yDq7AmcCh6/l8S6mNd89hXaNHg78YGyZnwH7bei/ZyenIacNXgAnpw09dV8QP6Q1TVxF63z8yJH3HwysWsP6+3dfIL8G3rOW+/5o9yU5Oj1vbN9n0ppTlgMPXs12ngecODZvy+54Hj7N8k8DLgauAU4HHj3NMl+fSgzG5u9J6/B+DfBL4K/WcHy3KBfwDNoQBr+j3fr/MUYSP1qSs7J7/0Rg6Qzxeynwge716+mSpbFlbg9cT2s6Wwac0iUEV9FquR7f45rZDHh/t41LgfcAW65m2RXAI8bm3bW75haNzHsNLWk8G9h75PyvADabZrsfpEuWxubvR0sMd6AlUdd318+qLuYfBG7V45gfAfyE1pz5LUYSO1o/t1PX99+mk9Ncn1K12pt6JGlOS7IFrT/Rw2tswM2FIMnfAiur6v9t6LKsSZLjaMNejN+NKC1oJlGSJEk92LFckiSpB5MoSZKkHkyiJEmSejCJkiRJ6mHTmRdZezvuuGMtWbJkEpuWJElar0455ZTLq2rx2q43kSRqyZIlLF++fBKbliRJWq+S/LLPejbnSZIk9TCrJCrJ9kk+m+QnSc5Jsv+kCyZJkjSXzbY5793A16rqqUk2B241wTJJkiTNeTMmUUm2Ax5CewYWVXUdcN1kiyVJkjS3zaY57060B4J+JMlpST6U5NbjCyVZlmR5kuUrV65c7wWVJEmaS2aTRG0K7Et7Uvo+tKerv358oao6sqqWVtXSxYvX+i5BSZKkeWU2SdSFwIVVdVL3+2dpSZUkSdJGa8YkqqouBS5Islc36+HA2RMtlSRJ0hw327vz/hI4prsz7zzg+ZMrkiRJ0tw3qySqqk4Hlk62KJIkSfOHI5ZLkiT1YBIlSZLUg0mUJElSDyZRkiRJPZhESZIk9WASJUmS1INJlCRJUg8mUZIkST2YREmSJPVgEiVJktSDSZQkSVIPJlGSJEk9mERJkiT1YBIlSZLUg0mUJElSDyZRkiRJPZhESZIk9bDpbBZKsgK4GrgRuKGqlk6yUJIkSXPdrJKozkOr6vKJlUSSJGkesTlPkiSph9kmUQX8R5JTkiybboEky5IsT7J85cqV66+EkiRJc9Bsk6gHVdW+wEHAS5M8ZHyBqjqyqpZW1dLFixev10JKkiTNNbNKoqrqou7nZcC/A/tNslCSJElz3YxJVJJbJ9lm6jXwKODHky6YJEnSXDabu/N2Av49ydTyn6iqr020VJIkSXPcjElUVZ0H3HuAskiSJM0bDnEgSZLUg0mUJElSDyZRkiRJPZhESZIk9WASJUmS1INJlCRJUg8mUZIkST2YREmSJPVgEiVJktSDSZQkSVIPJlGSJEk9mERJkiT1YBIlSZLUg0mUJElSDyZRkiRJPZhESZIk9WASJUmS1MOsk6gki5KcluRLkyyQJEnSfLA2NVGvAM6ZVEEkSZLmk1klUUl2BR4HfGiyxZEkSZofZlsT9S7gtcBNkyuKJEnS/DFjEpXk8cBlVXXKDMstS7I8yfKVK1eutwJKkiTNRbOpiToAeGKSFcCngIcl+fj4QlV1ZFUtraqlixcvXs/FlCRJmltmTKKq6q+rateqWgI8HfhmVT174iWTJEmawxwnSpIkqYdN12bhqvoW8K2JlESSJGkesSZKkiSpB5MoSZKkHkyiJEmSejCJkiRJ6sEkSpIkqQeTKEmSpB5MoiRJknowiZIkSerBJEqSJKkHkyhJkqQeTKIkSZJ6MImSJEnqwSRKkiSpB5MoSZKkHkyiJEmSejCJkiRJ6sEkSpIkqYcZk6gkWyY5OckZSc5K8sYhCiZJkjSXbTqLZa4FHlZVq5JsBpyY5KtV9YMJl02SJGnOmjGJqqoCVnW/btZNNclCSZIkzXWz6hOVZFGS04HLgG9U1UkTLZUkSdIcN6skqqpurKr7ALsC+yW55/gySZYlWZ5k+cqVK9dzMSVJkuaWtbo7r6quAk4AHjPNe0dW1dKqWrp48eL1VDxJkqS5aTZ35y1Osn33eivgkcBPJlwuSZKkOW02d+ftDBydZBEt6fp0VX1pssWSJEma22Zzd96PgH0GKIskSdK84YjlkiRJPZhESZIk9WASJUmS1INJlCRJUg8mUZIkST2YREmSJPVgEiVJktSDSZQkSVIPJlGSJEk9mERJkiT1YBIlSZLUg0mUJElSDyZRkiRJPZhESZIk9WASJUmS1INJlCRJUg8mUZIkST3MmEQluUOSE5KcneSsJK8YomCSJElz2aazWOYG4FVVdWqSbYBTknyjqs6ecNkkSZLmrBlroqrqkqo6tXt9NXAOsMukCyZJkjSXrVWfqCRLgH2AkyZSGkmSpHli1klUkq2B44BDq+q307y/LMnyJMtXrly5PssoSZI058wqiUqyGS2BOqaq/m26ZarqyKpaWlVLFy9evD7LKEmSNOfM5u68AEcB51TVEZMvkiRJ0tw3m5qoA4DnAA9Lcno3PXbC5ZIkSZrTZhzioKpOBDJAWSRJkuYNRyyXJEnqwSRKkiSpB5MoSZKkHkyiJEmSejCJkiRJ6sEkSpIkqQeTKEmSpB5MoiRJknowiZIkSerBJEqSJKkHkyhJkqQeTKIkSZJ6MImSJEnqwSRKkiSpB5MoSZKkHkyiJEmSejCJkiRJ6mHGJCrJh5NcluTHQxRIkiRpPphNTdRHgcdMuBySJEnzyoxJVFV9B7hygLJIkiTNG/aJkiRJ6mG9JVFJliVZnmT5ypUr19dmJUmS5qT1lkRV1ZFVtbSqli5evHh9bVaSJGlOsjlPkiSph9kMcfBJ4L+AvZJcmOSFky+WJEnS3LbpTAtU1TOGKIgkSdJ8YnOeJElSDyZRkiRJPZhESZIk9WASJUmS1INJlCRJUg8mUZIkST2YREmSJPVgEiVJktSDSZQkSVIPJlGSJEk9mERJkiT1YBIlSZLUw4wPIJY0vCWv//KGLkIvK97+uA1dBEkajDVRkiRJPZhESZIk9WASJUmS1INJlCRJUg+z6lie5DHAu4FFwIeq6u0TLdUa2OFWkhYGP881381YE5VkEfA+4CDg7sAzktx90gWTJEmay2ZTE7UfcG5VnQeQ5FPAwcDZkyyY5g7/W5Qk6X+aTZ+oXYALRn6/sJsnSZK00Vpvg20mWQYs635dleSn62vbA9oRuHwSG87hk9jqgmDMh2fMhzexmGu1vM6HN5+v8zv2WWk2SdRFwB1Gft+1m3cLVXUkcGSfQswVSZZX1dINXY6NiTEfnjEfnjEfnjEf3sYY89k05/0QuEuSOyXZHHg68IXJFkuSJGlum7EmqqpuSPIy4Ou0IQ4+XFVnTbxkkiRJc9is+kRV1VeAr0y4LHPBvG6OnKeM+fCM+fCM+fCM+fA2upinqjZ0GSRJkuYdH/siSZLUg0mUJElSDyZRC0iSLZJs1r3Ohi7PxiDJJt1P4z2QJJt3j6My7gPpPlu26F4b8wmaim+SrZIs7l77XT2AJFsnWdK9ntV17olZAJI8KMlZwH8CrwQoO7tNTJJtkrwmyY+A93Sz/VuaoCQ7Jfn7JN8Dvga8HLzOJynJbZO8Lck3gW8Cr0yyhTGfrKqqJPcBzgdet4GLs+Al2SHJm5N8GTgNOARm/9my3kYs13C6/0pSVTcm2ZI2UvxfA98BvpzkPOA4P+zWny7mm1TVDbShPnYGPgY8C6CqbtyAxVuQRq9z2oC/OwOHAr8EvpnkjKr65gYs4oIzdp1vAWwG/C1wJvB9YDlw/IYr4cIzVctUVTeNzL4b7Z/iO03zntbR2HW+DfB64FFVdcLabsv/nueRqerFqrpp6ku7qv5Ae0j0aVV1FfBPwIHAXhuomAvKWMxv6F5fBbwNOAK4Nsk+o8tq3Ux3nQPnAq+uqh9W1WXAyXRfMFp3q7nOL6iqV1fV96vqauA84A8bspwLyVjMx5OkpwLHAn9Ict/R5dXfaq7zXwJndRNJdl6bbZpEzUFpFo23g3fVvLdLcmCSdyd5QpLtgBOBe3aLnQVcC/jFvhZmGfN3JTm4m7+y++A7E3h0t7h/T2thLWL+xKq6qqpWdU9NgFZLYu3fWlqbmI+s8/wk19Oei3b7ocs8363tZ0vXlHcucDrwK1qtFPj5MmtrEfOndG/9GPhBklOA9yZZNtt+aJ6UOSDJ9kke1yVEVHNjVd00mgQleRatSv2xwCOA5wPXABdz8x/aSuBSYJepbQ13JPNHz5g/HHhhN3/qb+fbwEOGLf38tA4x/4tu/mZVdV2S/WgPC/2s/ySs2brGvPNV4DbdvCdPfdlreusQ8xd3b+0JXFxV/w1cBbwoyYvsMrB66xDzP+/eehfwduAA4HDgfwNPns2+7RM1N9yd1rfmWuD4JHsBzwbuD3w3yXtp1egPBF5RVV9McjzwISDAT4DHAFTVld36Xx3+MOaV1cV8P+DENcT8w9Cqg7s/zpOA13Tz/JBbs3WN+fXddl4DvL+qVg19APPQOsUcoKou7V6eneRC4E5JNrGfzmr1/Tw/qqtp3RN4TpJlwNa0z/iLN8BxzCd9r/OPAFTVclp/P4CTk5wN7DSb69yaqIF01Yuri/cKWvXtnbvfD6TVKL0G+B3wd7SLYylwRvcf+X/Qzt/dgM8B90nyqG793br1N2o9Y/5abo75dfzPmE/dOTP1387PgWuSHJHkhUl2mtTxzAcTjPlU8/T+tA/D5UkOTvLMJNtM6njmg0lf5yP7WQTcBfjJxp5ATejzPMAetDvE3g48Abgf8ENas95G3T1jQtf5TdNc55vS+hT/fDbXuUnUQLov3NWdkJXAJbT/QACOBk4BXkKrbnwQsHm33P1H/iO/Gji4qq4B3gg8L8kVwI+6aaO2HmK+GXAZ8ICxmD8WIMkDknyb9sWyD3A9rfp9ozXBmD++e/2XtP84P0S7K/Ua4Pfr+TDmlQnG/NEASV6U5Ie0Pjrn0mpfN2oT/Dx/UlV9uao+UlXn0ZKtr9D1/9uYu2dM8Do/CCDJIWl9ok4Dfkq7eWVGNuetZ9NV/3XZ8+7A84Drq+qNo+9X1fVJzgf2TbIbLWN+Ea2/zVtod4HtD/wL8LSu3TfA5bRqTGi1Uf9Z7c6xjcosYn5dVb1p9P2xmN+R9mH1ItowEaMx/xAt5tt2q14B3Lt7fT5waFWdNpEDm8MGjvmVwF271x8G3lNVP5jIgc1hGyDm9+penwa8rKo2uuRpA3ye793tY4uquraqfgMcNcFDnHM2wHW+d/f6TOCla/vZYk3UOkiySVfF/UdTJz/JPdPGcIJ2At9N+2/i6LFtTFXPnk+rydgF+BNgu6o6CriBVsX7lKr6PO0ieAJtbIsP0FVfdp3oruq2uWihVvv2jPnHxrYxHvPbc3PMP8TqY74tLeZ7dPu9eCqB6mJ+i3ItFHMg5u+nG7Kjqo6f+pCbrlwLxRyL+clTCZSfLcBkP8/v0u332vGyrafDnFPmyHW+Z7ffU0c+W2Z9nVsTtRaSZLQ6dbqqxSSvp43x8Vvg20k+Rhvt937AZ6pqxejyI9u7pJvuQ6tVem6S42gn+nO0CwHafzOnA/elVVP+43gZagF1cDbmw5vrMZ8q3xqq9uedeRRzr/OBP1tWV7b5aK7HvM91bhI1g9GqxdGTn/aMukcDT6O1q/4jrc21aHdhbAd8FtgeeCdtoLo1xfuKbtofOBJ4Ge2Ou29X1dkjy23Z7Ws74MvAF9f1GOcaYz68+RTz0fLNZ8Z8ePMp5gvFfIp5r+u8qpxGJtooyMuAXaZ5bxfg8d3rRwHfAJ4C3KOb92hax+LjaXdUHNVdDLeiVfs+cYZ97w7caTXvLdrQsTHmC2cy5sbcmBtzY77ukzVRnZFseUdaJ9ZzgYuSPBTYqqq+Qusj8MokP6VVEW5K64x2TbeZU2hZ9F9UGyhtdPu/AvZOckJVXd21t4abnw1GtbsxRteZGqK+agFVo08x5sMz5sMz5sMz5sPbWGO+IDurzcZUcEeCPDV44s9oY3JMPZfrIdz8WI/v06odb08bzPIK4KXAO5NMVQmeDBycNrT8I9PGD7od7dEslwJ/rNaskWeDJdktbSTm8RO/IKrRwZhvCMZ8eMZ8eMZ8eMa82ShqojL2lOykdR5Ldxtpki1o1Y/bVdU/JLkU2L07EacDByW5bVVdluQS2i2R36+qp3bb24bWBrs/8H9ot2F+mTZ2xeeBVVX1hbEybQk8DngYsC/t9tZ/7so57//QjPnwjPnwjPnwjPnwjPnqLcgkavyE18gdAEluU1VXJLktref/A6vq10muA7bvTuZ5tDFSdgF+Qbut8l60dtoLaM/cOTbJ9rRn7NyH1mZ7UneRvBn4+/ETmVuOf/FI2sjiH6SNAHw989g8ivkdMObGvCdjPrx5FHM/zzfC63xBNudVq+KbyphvneRhSd6f5GfAR5LsX1WX0YaKP7Bb7Re0J8PfpXt9He2RKj+jVT8+rltuW1p7787ATt3y/wY8p9smVXV9l6XfYgyM0Quxqr5YVe+sqjPn+x8czKuYv8uYG/O+jPnw5lHM/TzfCK/zBZdEJdku7Xlan0hyP9rJeiutZ/6ewH8BL05yZ+AEbm6rXUFra70LrT33cuBuVXUdbZTk+yT5Ma0j26HAT6vqxKpaVlXHVdVvx8tSI+21C5kxH54xH54xH54xH54xXzvzojkv+WP76y0G6ppmuU2Aw2hViN+hndRNgJ/QhncH+CStvXV/4FvAcwCq6twk9weurqpjk1wA3DvJtlX1syR/NpUlT7PPW2TIC4ExH54xH54xH54xH54xn5w5m0Qlmbp18aapkz71M8mewOVVdeXYRfEQ4EFVdb+R7WwBLKe1V1NVK5LsDvy4qk5OG979cOA2tLbaa9I6rF1A66y2O3D61MkfP+Hz9cRPx5gPz5gPz5gPz5gPz5gPY84kUV1gR8d7KNp4EaRVG+5I66n/qW6VM4EXjGXVV9KNN5E2GupN1e4cWAEsS3JMVZ1B64w2lVU/Azi4297nq+rqbv1f0R5iuDtw+tSFNt9P+ChjPjxjPjxjPjxjPjxjvmFssCQqY09qHg9s2pOtX0rrqPYE4A+0MSKeXFUXJPl5kn2r6tSR1a4Ark1yQFV9r9vO1LgVvwTekXZHwQnAqd1+zwDOGNnvVFZ+IfAfdBfK2IU2Lxnz4Rnz4Rnz4Rnz4RnzuWHwJKo7AQcCn+l+n2qrPRA4iJYtv6GqLk5yMHB2Ve2bZB9aW+zW3aZOAB6Y5PS6uVrwoiSnAq/otvdQWrvuu4AfAJtU1ZunKdN01Z7XAd9b/xEYnjEfnjEfnjEfnjEfnjGfWyZ+d1669s8p1dpFlwFPT/JaYNskewDPpmWzXwGOSLIL8DXgku4EXUh7kvP9u02dBNwbuHWSzZIc1M3/O9qAWzsARwBvA35Hu8Vy965MGS1XNQumitGYD8+YD8+YD8+YD8+Yz20TT6KmApvkjkkelGRfWs//NwJ3pp2YQ4GLgVW0nv5LaeNHnAnsCmxFeyjhT2kd1aANH78f7URvCTwsyZZVdV1VfbeqXlVVX6k23sSNtGrFd3RlWtAn3JgPz5gPz5gPz5gPz5jPcbVuT2sOq3kyMu2kbQXcF/g27WS+Abgd8GrgHSPL/l9au+lhwBOBLbr5u9FO3B7d748Hvju1T+BJwK1Xs/9NaFWP63SMc20y5sbcmBtzY74wJmM+/6f1fUFs1/3cFvgA8EzgWcDhY8vtA3wdWELrl/VI4Dtjy/xJ9/P7wMHd69sAe02d4GkuxmzogA5+Ao25Md8IJmNuzDeGyZjPv6lXx/KRjmx7Ak8FNqdVI+5Ja6vdqbsIjqdl0c/v2k9/Bfysqr6QNpT74qpaAXwjyeuSvIdWtbgv8Dla9v182nN4qKoraHcPUGNVidVdBQuVMR+eMR+eMR+eMR+eMV840jduSe4KfBT4Bu1EXwZ8DHgBrd31HOAeVfWHJEtpdwQ8ADiE9gydZ9CenXNb4F+q6htJ/oz2EMLjq+qCdTiuBcmYD8+YD8+YD8+YD8+YLwzrMsTBHsC5wNHARVX1+yRvB/4K+BJwHLBTkvOrajn8cfCtvYDNgPfTqiqvoo1BQVUduw7l2RgY8+EZ8+EZ8+EZ8+EZ8wVgXWqitgE+QhuRdBPaLZBH0IaNfyNwbFW9PMlWtOrKN9Ay7WOB966u6jBjA4jpZsZ8eMZ8eMZ8eMZ8eMZ8YeidRN1iI61a8gW0pza/H3g3sHNVPTZJaIN/XV9VV02z7iLa0PK2x64FYz48Yz48Yz48Yz48Yz5/9W7O607s7YG9aYN37QO8pKpWJTkZ2CHJomrjS6wcWWeTbh4Ao6+1ZsZ8eMZ8eMZ8eMZ8eMZ8Yeg92GaX9d4B+AvgBuC1VfXzJHcBXgScWlU3dif9j+t4wvsz5sMz5sMz5sMz5sMz5gvDemnOu8UG290B9wDeXe12Sk2YMR+eMR+eMR+eMR+eMZ9f1jmJmqpepCXJdmYbgDEfnjEfnjEfnjEfnjGf39Z7TZQkSdLGYOIPIJYkSVqITKIkSZJ6MImSJEnqwSRKkiSpB5MoSZKkHkyiJEmSevj/1yc4QpVzGUAAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlEAAADvCAYAAADSI4HyAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAh/klEQVR4nO3debgkVX3/8feHYVW2CCOyqIiKCyiLI4gr7iIqUYk74hJH474H80Qj0cTlZ9xiTH6IG7+oQcUVxAVFCa4MmwiIEoKAbCOIggvr9/fHqStNOzO3b810T98779fz9HP7dlWfOvWtut3fe86pU6kqJEmSNDfrre0KSJIkzUcmUZIkST2YREmSJPVgEiVJktSDSZQkSVIPJlGSJEk9mERJmleSbJTkrCTbru26qJ8kL0vyjrVdD2l1mURpwUry0iTLklyb5GNDyzZM8tkk5yepJPvOsexKcpcedZp1u0n2THJCkmuSXJbkFStY5yHd+9868Np/dO+ZeVyb5OqB5fdI8q0kv0lybpInDpX5lCRnJ7m6S1L+cmDZc5LcOFT+vt2y2yb5VJKLu7K/m2TvobJfluR/k/y2OyYPHFj25iTXD5W90yrCuBQ4oaouGdrGm7uYDG97wyT/kuSiruzzk7x3FeWv0KrOp275w5P8NMnvkxyf5I4DyzZK8pFu/y9N8uqh994qyQeT/KqL4QkDy56R5JKu3g8deP3OSb6XZFGPfVlZrIaP83lJ/mau5XdlHZbknCQ3JXnO0OIPAc9Mcts+ZUvTwiRKC9nFwFuBj6xk+YnAs4BLJ1ajWbabZGvgq8D/BbYC7gJ8fWidDYD3AT8cfL2qXlRVm848gE8Bn+nesz7wReBo4Da0ROQ/k+zcLd8e+E/g1cDmwOuATw59yX1/sPyq+nb3+qbAScB9urI/DhyTZNOu7L2BtwMHAlsAHwY+P/Tlf+RQ2eetIn4vAv7fUEwCPBu4svs56A3AEmAvYDNgX+CUVZS/Mis9n7rj9jngjbQYLAOOHFjlzcBdgTsCDwVen+QxA8sP6953j+7nq7py16fFbk/gpcC/Drzn/cCrqurGuezELLGCgeMMPBl4Z5I95rKNzunAi1lBrKvqj8CxK9m+NG+YRGnBqqrPVdUXgCtWsOy6qnpvVZ0IzPVLaKaV4PTuv/WnzqFOs2331cDXquoTVXVtVV1dVWcPrfMaWmL101XU8da0L8CPdy/dHdgOeE9V3VhV3wK+CxzULd8BuKqqjq3mGOB3wJ1H2KfzqurdVXVJV/ZhwIbA3bpVdgTOrKqTq90i4Qhga2DOrRBJ7gDsxFACCTwI2BZ4OfC0JBsOLLsv8Pmqurjbt/Or6oi5bntV5xPwJNo+fqZLEN4M7Jbk7t3yg4G3VNWvu+P5IeA53T7dHXgCsLSqlncxPLl731bAL7tWt+O6fSfJgd3rw3EYxapiNbzPpwJn05K7Oamqf6uqbwJ/XMkq3wb2n2u50jQxiZLmqKoe3D3drfuP/cgkd0hy1Soezxix+PsBV3bdNJcn+XKXOADQdRE9D/jHWcp5MrAcOGEV6wTYtXu+DDg7yROSLOq68q4Ffjyw/h5dd9PPkryxayX580KT3WlJ1LndS8cCi5Ls3bU+PQ84jVu2xD0+yZVJzpyl++hewHlVdcPQ6wcDXwY+PVPewLIfAK9O8uIk9+paYgbre/QqjtvRq6jLoF1oLS8AVNXvgP8BdknyF7Sk5fSB9U/v3gOthewXwKFdfM9I8uRu2XJgqyQ7AI8EzkyyGfD3tBa2PlYVq1tIcl9gZ9r5MfPaqs7zQ+ZQj7OB3XrUX5oaK/wQlDQ3VXUBsOUaKGoHWtfNI4EzgHfSuuUe0C1/P/DGqrpmKBcYdjBwRN18c8xzgMuB1yV5D61L6SHA8V39b0xyBPBJYGPgOuCvumQAWjK2K+3LfhdaV9UNwNsGN5pkc1pX26FV9Zvu5auBo2jdmAGuAvYbqNunad1ZlwF7A0cluaqqPrWC/dqyK29wm7cC/gp4dlVdn+SztG6io7pV3gb8Gngm8B7giiRvqKqPd/v+uJWHcWSb0hKeQb+hdR9uOvD78DJox3zXrr7bAfvQukPPqqqzu6Tys7Sk9gXAobRuvXsneRPtWL2mqn4yWyVHiBXA/ZJcBSzq6v4B4OczC6tqy9m2M6Krad270rxlS5Q0Xf5A63o6qesWOhS4f5Itkjwe2KyqjlxVAV3L1b60bjMAqup64C9p3SeX0roEPw1c1L3nEbSEbV9aK9JDgMO7VqWZLrv/raqbquoMWkvYgUPb3YTWwvGDqhpMrp4PPJeWfG1IGw92dJLturLP6rrabqyq79HGe92i7AG/5ubkY8YTaQndV7rfPwHsl2RxV/6NXdfSA2hJ2D8BH0ky5y6qVbiGNpZs0Oa0ROGagd+Hl0E75tcDb+26e79DS24f1dX/m1V1v6p6CFC08V0fox3f5wBvAQ4fsZ6rjFXnB1W1ZVVtBtyOdtz+ecTy52IzbplYSvOOSZS0BnTdedes4vHMEYv6Me2Lcsbg84cDS9Ku7roUeCrwyiRfHCrjIOC7w4Ozq+rHVfWQqtqqqh5NG1/zo27x7rQr3pZ1idJJtHFHj1hJPYvWqjSz/xsBX6AlZS8cWnd34Oiq+llX9leBS4D7j1L2kB8DdxrqSjyY1mJyQReXzwAbAH/WhVpVf6iqf6MlY/fs6n7sKo7bsSupx7AzGeia6sak3Zk2TurX3f4Odl3t1r1nZp/+rKrDL3TdkB+gjWXaGlhUVb+gDeq/94j1HDlWAFV1Ga2V6k9dfrOc5383Yj2gjbM6fda1pClmEqUFK8n6STamdUssSrLx4Jdv2mXnG3e/btgtX2Uf2YDL6Ab5QuvOG7q6bPjxiRG3+1HgiUl2T7sK743AiV3X2Btp41N27x5fog1Qfu5Q3Z5Na6kYjse9u23dKslraeN0ZtY7CXjQTMtT2tVYD6L7gk+yX5Jtuud37+ryxe73DWjdTX8ADq6qm4Y2fRKwf5Kd0jyy24+fdO8/IMlfdMv2oiUJw4nhTJwvoo212qt77/a05PJxA3HZDXhHFweSvDLJvkk26c6Jg2mtIKd2Ze63iuO230D8VnU+fR7YNcmTu3XeBPy4qmYG/x8B/H23n3endcvNxP4E4ALgDd02HkDrbv3a0O7/NXBKVZ1GG9y+SZJ7duv+KWHOyqfOmDVWK3jPVrTWq5mEj1nO838eeO+GXSwCbNDFa/A75yG08XLS/FVVPnwsyAftCqkaerx5YPn5K1i+Y7fs74BjV1H2i2itC1cBT5ljvVa63W753wC/pLWWfBm4/UrK+RitC2jwtX1oV9VttoL1/09X5jW0L6+7DC1/KS1BuZr2pfyagWXvoiWOv+uW/SOwQbdsppvp913ZM48HdcvTrX9BV/bZwEEDZX+KlhRcQ7vi8OWzxO8lwL93zw8BTl7BOtvRush2pU3ncDKt6+gqWuvb48ZwPj2iq/8faFeeDR7TjWhTI/y2i+Orh8reBfh+F9+zgCcOLd+alnRuPvDaM2lds+cDD+1eu323ja1WUP9RYvUc2lWjM8fw8u743LZHvL69gnjt2y3bmNZquc0kPxN8+FjTj1T9WauxJE2truvwVODhNTTh5rouybOAXaqq75V7E5HkZbR/Dl6/tusirQ6TKEmSpB4cEyVJktSDSZQkSVIPJlGSJEk9mERJkiT1MJbbvmy99da14447jqNoSZKkNerkk0/+VVUtnn3NWxpLErXjjjuybNmy2VeUJElay5L8os/77M6TJEnqYaQkKsmWST6b5KdJzk6yz7grJkmSNM1G7c57H/DVqjowyYbArcZYJ0mSpKk3axKVZAvgwbR7KlFV1wHXjbdakiRJ022U7rw7AcuBjyY5NcnhSW49vFKSpUmWJVm2fPnyNV5RSZKkaTJKErU+sCftrul70O4yfsjwSlV1WFUtqaolixfP+SpBSZKkeWWUJOoi4KKq+mH3+2dpSZUkSdI6a9YkqqouBS5McrfupYcDZ421VpIkSVNu1KvzXgZ8orsy7zzgueOrkiRJ0vQbKYmqqtOAJeOtiiRJ0vzhjOWSJEk9mERJkiT1YBIlSZLUg0mUJElSDyZRkiRJPZhESZIk9WASJUmS1INJlCRJUg8mUZIkST2YREmSJPVgEiVJktSDSZQkSVIPJlGSJEk9mERJkiT1YBIlSZLUg0mUJElSDyZRkiRJPaw/ykpJzgeuBm4EbqiqJeOslCRJ0rQbKYnqPLSqfjW2mkiSJM0jdudJkiT1MGoSVcDXk5ycZOmKVkiyNMmyJMuWL1++5mooSZI0hUZNoh5YVXsC+wEvSfLg4RWq6rCqWlJVSxYvXrxGKylJkjRtRkqiquqX3c/Lgc8De42zUpIkSdNu1iQqya2TbDbzHHgU8JNxV0ySJGmajXJ13jbA55PMrP/JqvrqWGslSZI05WZNoqrqPGC3CdRFkiRp3nCKA0mSpB5MoiRJknowiZIkSerBJEqSJKkHkyhJkqQeTKIkSZJ6MImSJEnqwSRKkiSpB5MoSZKkHkyiJEmSejCJkiRJ6sEkSpIkqQeTKEmSpB5MoiRJknowiZIkSerBJEqSJKkHkyhJkqQeRk6ikixKcmqSo8dZIUmSpPlgLi1RrwDOHldFJEmS5pORkqgkOwD7A4ePtzqSJEnzw6gtUe8FXg/cNL6qSJIkzR+zJlFJHgdcXlUnz7Le0iTLkixbvnz5GqugJEnSNBqlJeoBwBOSnA/8F/CwJP85vFJVHVZVS6pqyeLFi9dwNSVJkqbLrElUVb2hqnaoqh2BpwHfqqpnjb1mkiRJU8x5oiRJknpYfy4rV9W3gW+PpSaSJEnziC1RkiRJPZhESZIk9WASJUmS1INJlCRJUg8mUZIkST2YREmSJPVgEiVJktSDSZQkSVIPJlGSJEk9mERJkiT1YBIlSZLUg0mUJElSD3O6AfE02PGQY9Z2FXo5/+37r+0qaB7xPJek6WdLlCRJUg8mUZIkST2YREmSJPVgEiVJktTDrElUko2T/CjJ6UnOTHLoJComSZI0zUa5Ou9a4GFVdU2SDYATkxxbVT8Yc90kSZKm1qxJVFUVcE336wbdo8ZZKUmSpGk30pioJIuSnAZcDnyjqn441lpJkiRNuZGSqKq6sap2B3YA9kqy6/A6SZYmWZZk2fLly9dwNSVJkqbLnK7Oq6qrgOOBx6xg2WFVtaSqlixevHgNVU+SJGk6jXJ13uIkW3bPNwEeCfx0zPWSJEmaaqNcnbct8PEki2hJ16er6ujxVkuSJGm6jXJ13o+BPSZQF0mSpHnDGcslSZJ6MImSJEnqwSRKkiSpB5MoSZKkHkyiJEmSejCJkiRJ6sEkSpIkqQeTKEmSpB5MoiRJknowiZIkSerBJEqSJKkHkyhJkqQeTKIkSZJ6MImSJEnqwSRKkiSpB5MoSZKkHkyiJEmSepg1iUpy+yTHJzkryZlJXjGJikmSJE2z9UdY5wbgNVV1SpLNgJOTfKOqzhpz3SRJkqbWrC1RVXVJVZ3SPb8aOBvYftwVkyRJmmZzGhOVZEdgD+CHY6mNJEnSPDFyEpVkU+Ao4JVV9dsVLF+aZFmSZcuXL1+TdZQkSZo6IyVRSTagJVCfqKrPrWidqjqsqpZU1ZLFixevyTpKkiRNnVGuzgvwYeDsqnr3+KskSZI0/UZpiXoAcBDwsCSndY/HjrlekiRJU23WKQ6q6kQgE6iLJEnSvOGM5ZIkST2YREmSJPVgEiVJktTDKLd9kaQFb8dDjlnbVejl/Lfvv7arIK2zbImSJEnqwSRKkiSpB5MoSZKkHkyiJEmSejCJkiRJ6sEkSpIkqQeTKEmSpB5MoiRJknowiZIkSerBJEqSJKkHb/uiWXk7DEnj4GeL5jtboiRJknowiZIkSeph1iQqyUeSXJ7kJ5OokCRJ0nwwSkvUx4DHjLkekiRJ88qsSVRVnQBcOYG6SJIkzRuOiZIkSephjSVRSZYmWZZk2fLly9dUsZIkSVNpjSVRVXVYVS2pqiWLFy9eU8VKkiRNJbvzJEmSehhlioNPAd8H7pbkoiTPH3+1JEmSptust32pqqdPoiKSJEnziffOkyRpHeH9Ctcsx0RJkiT1YBIlSZLUg0mUJElSDyZRkiRJPZhESZIk9WASJUmS1INJlCRJUg8mUZIkST2YREmSJPVgEiVJktSDSZQkSVIPJlGSJEk9mERJkiT1YBIlSZLUg0mUJElSDyZRkiRJPYyURCV5TJJzkpyb5JBxV0qSJGnazZpEJVkE/BuwH3BP4OlJ7jnuikmSJE2zUVqi9gLOrarzquo64L+AA8ZbLUmSpOk2ShK1PXDhwO8Xda9JkiSts1JVq14hORB4TFX9dff7QcDeVfXSofWWAku7X+8GnLPmqzt2WwO/WtuVWMcY88kz5pNnzCfPmE/efI75Hatq8VzftP4I6/wSuP3A7zt0r91CVR0GHDbXCkyTJMuqasnarse6xJhPnjGfPGM+ecZ88tbFmI/SnXcScNckd0qyIfA04EvjrZYkSdJ0m7UlqqpuSPJS4GvAIuAjVXXm2GsmSZI0xUbpzqOqvgJ8Zcx1mQbzujtynjLmk2fMJ8+YT54xn7x1LuazDiyXJEnSn/O2L5IkST2YREmSJPVgErWAJNkoyQbd86zt+qwLkqzX/TTeE5Jkw+52VMZ9QrrPlo2658Z8jGbim2STJIu7535XT0CSTZPs2D0f6Tz3wCwASR6Y5Ezgm8CrAMrBbmOTZLMkr0vyY+D93cv+LY1Rkm2S/EOS7wJfBV4OnufjlOS2Sd6W5FvAt4BXJdnImI9XVVWS3YELgL9dy9VZ8JLcJslbkhwDnAocDKN/tox0dZ6mS/dfSarqxiQb02aKfwNwAnBMkvOAo/ywW3O6mK9XVTfQpvrYFjgCeCZAVd24Fqu3IA2e57QJf7cFXgn8AvhWktOr6ltrsYoLztB5vhGwAfD3wBnA94BlwHFrr4YLz0wrU1XdNPDyPWj/FN9pBcu0mobO882AQ4BHVdXxcy3L/57nkZnmxaq6aeZLu6r+SLtJ9KlVdRXwL8C+tFvvaDUNxfyG7vlVwNuAdwPXJtljcF2tnhWd58C5wGur6qSquhz4Ed0XjFbfSs7zC6vqtVX1vaq6GjgP+OParOdCMhTz4STpQOBI4I9J7jO4vvpbyXn+C+DM7kGSbedSpknUFEqzaLgfvGvmvV2SfZO8L8njk2wBnAjs2q12JnAt4Bf7HIwY8/cmOaB7fXn3wXcG8Ohudf+e5mAOMX9CVV1VVdd0d02A1kpi698czSXmA+95bpLrafdF227SdZ7v5vrZ0nXlnQucBlxGa5UCP19GNoeYP7lb9BPgB0lOBj6QZOmo49A8KFMgyZZJ9u8SIqq5sapuGkyCkjyT1qT+WOARwHOB3wMXc/Mf2nLgUmD7mbImtyfzR8+YPxx4fvf6zN/Od4AHT7b289NqxPwF3esbVNV1SfYC7gh81n8SVm11Y945Ftiqe+1JM1/2WrHViPmLukU7AxdX1f8CVwEvTPJChwys3GrE/K+7Re8F3g48AHgH8JfAk0bZtmOipsM9aWNrrgWOS3I34FnA3sB/J/kArRn9/sArqurLSY4DDgcC/BR4DEBVXdm9/9jJ78a8srKY7wWcuIqYfwRac3D3x/lD4HXda37Irdrqxvz6rpzXAR+sqmsmvQPz0GrFHKCqLu2enpXkIuBOSdZznM5K9f08/3DX0rozcFCSpcCmtM/4i9fCfswnfc/zjwJU1TLaeD+AHyU5C9hmlPPclqgJ6ZoXVxbv82nNt3fpft+X1qL0OuB3wJtoJ8cS4PTuP/Kv047fPYAvALsneVT3/jt071+n9Yz567k55tfx5zGfuXJm5r+dnwO/T/LuJM9Pss249mc+GGPMZ7qn96F9GC5LckCSZyTZbFz7Mx+M+zwf2M4i4K7AT9f1BGpMn+cB7ky7QuztwOOB+wIn0br11unhGWM6z29awXm+Pm1M8c9HOc9Noiak+8Jd2QFZDlxC+w8E4OPAycCLac2NDwQ27Nbbe+A/8quBA6rq98ChwHOSXAH8uHus09ZAzDcALgfuNxTzxwIkuV+S79C+WPYArqc1v6+zxhjzx3XPX0b7j/Nw2lWpvwf+sIZ3Y14ZY8wfDZDkhUlOoo3ROZfW+rpOG+Pn+ROr6piq+mhVnUdLtr5CN/5vXR6eMcbzfD+AJAenjYk6FTiHdvHKrOzOW8NW1PzXZc87Ac8Brq+qQweXV9X1SS4A9kxyB1rG/ELaeJt/ol0Ftg/wIeApXb9vgF/RmjGhtUZ9s9qVY+uUEWJ+XVX94+DyoZjfkfZh9ULaNBGDMT+cFvPNu7deAezWPb8AeGVVnTqWHZtiE475lcDdu+cfAd5fVT8Yy45NsbUQ83t3z08FXlpV61zytBY+z+/VbWOjqrq2qn4DfHiMuzh11sJ5fq/u+RnAS+b62WJL1GpIsl7XxP0nMwc/ya5pczhBO4Dvo/038fGhMmaaZy+gtWRsDzwE2KKqPgzcQGvifXJVfZF2EjyeNrfFv9M1X3aD6K7qyly0UJt9e8b8iKEyhmO+HTfH/HBWHvPNaTG/c7fdi2cSqC7mt6jXQjEFMf8g3ZQdVXXczIfciuq1UExZzH80k0D52QKM9/P8rt12rx2u2xrazakyJef5zt12Txn4bBn5PLclag6SZLA5dUVNi0kOoc3x8VvgO0mOoM32e1/gM1V1/uD6A+Vd0j12p7UqPTvJUbQD/QXaiQDtv5nTgPvQminfOVyHWkADnI355E17zGfqt4qm/XlnHsXc83zCny0rq9t8NO0x73Oem0TNYrBpcfDgp92j7tHAU2j9qu+k9bkW7SqMLYDPAlsC76FNVLeqeF/RPfYBDgNeSrvi7jtVddbAeht329oCOAb48uru47Qx5pM3n2I+WL/5zJhP3nyK+UIxn2Le6zyvKh8DD9osyEuB7VewbHvgcd3zRwHfAJ4M7NK99mjawOLjaFdUfLg7GW5Fa/Z9wizb3gm400qWLVrbsTHmC+dhzI25MTfmxnz1H7ZEdQay5a1pg1jPBX6Z5KHAJlX1FdoYgVclOYfWRLg+bTDa77tiTqZl0S+oNlHaYPmXAfdKcnxVXd31t4ab7w1GtasxBt8zM0V91QJqRp9hzCfPmE+eMZ88Yz5562rMF+RgtVHMBHcgyDOTJ/6MNifHzH25HszNt/X4Hq3ZcTvaZJZXAC8B3pNkpknwR8ABaVPLPzJt/qDb0W7Ncinwp2bNGrg3WJI7pM3EPHzgF0QzOhjztcGYT54xnzxjPnnGvFknWqIydJfspA0eS3cZaZKNaM2PW1TVW5NcCuzUHYjTgP2S3LaqLk9yCe2SyO9V1YFdeZvR+mD3Af6GdhnmMbS5K74IXFNVXxqq08bA/sDDgD1pl7f+a1fPef+HZswnz5hPnjGfPGM+ecZ85RZkEjV8wGvgCoAkW1XVFUluSxv5f/+q+nWS64Atu4N5Hm2OlO2B/6FdVnlvWj/thbR77hyZZEvaPXZ2p/XZ/rA7Sd4C/MPwgcwt5794JG1m8f+gzQB8PfPYPIr57THmxrwnYz558yjmfp6vg+f5guzOq9bEN5Mx3zrJw5J8MMnPgI8m2aeqLqdNFb9v97b/od0Z/q7d8+tot1T5Ga35cf9uvc1p/b3bAtt0638OOKgrk6q6vsvSbzEHxuCJWFVfrqr3VNUZ8/0PDuZVzN9rzI15X8Z88uZRzP08XwfP8wWXRCXZIu1+Wp9Mcl/awfpn2sj8nYHvAy9KchfgeG7uqz2f1td6V1p/7q+Ae1TVdbRZkndP8hPaQLZXAudU1YlVtbSqjqqq3w7XpQb6axcyYz55xnzyjPnkGfPJM+ZzMy+685I/9b/eYqKuFay3HvBmWhPiCbSDuh7wU9r07gCfovW37gN8GzgIoKrOTbI3cHVVHZnkQmC3JJtX1c+SPHUmS17BNm+RIS8ExnzyjPnkGfPJM+aTZ8zHZ2qTqCQzly7eNHPQZ34m2Rn4VVVdOXRSPBh4YFXdd6CcjYBltP5qqur8JDsBP6mqH6VN7/4OYCtaX+3v0wasXUgbrLYTcNrMwR8+4PP1wK+IMZ88Yz55xnzyjPnkGfPJmJokqgvs4HwPRZsvgrRmw61pI/X/q3vLGcDzhrLqK+nmm0ibDfWmalcOnA8sTfKJqjqdNhhtJqt+OnBAV94Xq+rq7v2X0W5iuBNw2syJNt8P+CBjPnnGfPKM+eQZ88kz5mvHWkuiMnSn5uHApt3Z+iW0gWqPB/5ImyPiSVV1YZKfJ9mzqk4ZeNsVwLVJHlBV3+3KmZm34hfAu9KuKDgeOKXb7unA6QPbncnKLwK+TneiDJ1o85IxnzxjPnnGfPKM+eQZ8+kw8SSqOwD7Ap/pfp/pq90X2I+WLb+xqi5OcgBwVlXtmWQPWl/spl1RxwP3T3Ja3dws+MskpwCv6Mp7KK1f973AD4D1quotK6jTipo9rwO+u+YjMHnGfPKM+eQZ88kz5pNnzKfL2K/OS9f/OaNav+hS4GlJXg9snuTOwLNo2exXgHcn2R74KnBJd4Auot3Jee+uqB8CuwG3TrJBkv26199Em3DrNsC7gbcBv6NdYrlTV6cM1quaBdPEaMwnz5hPnjGfPGM+ecZ8uo09iZoJbJI7Jnlgkj1pI/8PBe5COzCvBC4GrqGN9F9Cmz/iDGAHYBPaTQnPoQ1UgzZ9/F60A70x8LAkG1fVdVX131X1mqr6SrX5Jm6kNSu+q6vTgj7gxnzyjPnkGfPJM+aTZ8ynXK3e3ZrDSu6MTDtomwD3Ab5DO5hvBG4HvBZ418C6f0frN30z8ARgo+71O9AO3J273x8H/PfMNoEnArdeyfbXozU9rtY+TtvDmBtzY27MjfnCeBjz+f9Y0yfEFt3PzYF/B54BPBN4x9B6ewBfA3akjct6JHDC0DoP6X5+Dzige74VcLeZA7yCkzFrO6ATP4DG3JivAw9jbszXhYcxn3+PXgPLBway7QwcCGxIa0bcmdZXu013EhxHy6Kf2/WfXgb8rKq+lDaV++KqOh/4RpK/TfJ+WtPinsAXaNn3c2n34aGqrqBdPUANNSVWdxYsVMZ88oz55BnzyTPmk2fMF470jVuSuwMfA75BO9CXA0cAz6P1u54N7FJVf0yyhHZFwP2Ag2n30Hk67d45twU+VFXfSPJU2k0Ij6uqC1djvxYkYz55xnzyjPnkGfPJM+YLw+pMcXBn4Fzg48Avq+oPSd4OvBo4GjgK2CbJBVW1DP40+dbdgA2AD9KaKq+izUFBVR25GvVZFxjzyTPmk2fMJ8+YT54xXwBWpyVqM+CjtBlJ16NdAvlu2rTxhwJHVtXLk2xCa658Iy3TPhL4wMqaDjM0gZhuZswnz5hPnjGfPGM+ecZ8YeidRN2ikNYs+TzaXZs/CLwP2LaqHpsktMm/rq+qq1bw3kW0qeXtj50DYz55xnzyjPnkGfPJM+bzV+/uvO7AbgfcizZ51x7Ai6vqmiQ/Am6TZFG1+SWWD7xnve41AAafa9WM+eQZ88kz5pNnzCfPmC8MvSfb7LLe2wMvAG4AXl9VP09yV+CFwClVdWN30P/0Hg94f8Z88oz55BnzyTPmk2fMF4Y10p13iwLb1QG7AO+rdjmlxsyYT54xnzxjPnnGfPKM+fyy2knUTPMiLUl2MNsEGPPJM+aTZ8wnz5hPnjGf39Z4S5QkSdK6YOw3IJYkSVqITKIkSZJ6MImSJEnqwSRKkiSpB5MoSZKkHkyiJEmSevj/qdMLq8AScJcAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlEAAADvCAYAAADSI4HyAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAgpklEQVR4nO3dd7xlVX338c+XIqi0KCMCFpqgolIcUSIi4qPYMepjw24c8yixPFFj8sREY4zGKJZY8iDYEgu2WLGAHQ1laAqIgoh0GEBCC/2XP9a+cLjcmTl3z5w99975vF+v/brnnt3W/u19z/ndtdZeO1WFJEmSZmedNV0ASZKk+cgkSpIkqQeTKEmSpB5MoiRJknowiZIkSerBJEqSJKkHkyhJqyzJ1Um2W868lyQ5ajXua78kX11d21M/SY5NsvOaLoe0JplESdMk2SDJoUl+n+SqJCcleeLI/EckOSLJ5UmWJfliki1nsf1KssNkSj97SX6U5E9XZRtVtVFVndVz/wcn+XWSW5K8ZIxV3gG8a9o2kuSsJKfNsP2dk3yvO19XJDk+yZNmWcYVnvPumvnXJBd3y3wjydYj89+f5A9J/jPJvUbef36SD86mLCPr/qjb5gbT3v9kkhu6xPaq7ngf3XMfz+/+Dq5J8tUkdxuZ/R7g7/tsV1ooTKKkO1oPOBd4NLAp8DfAF5Js083/I+BgYBvgvsBVwCcGL+VAkqw34V2cDLwKOGGMsjwM2LSqjp42a2/gHsB23TKjvgEcAdyzW+Y1wJWzLOPKzvlrgT2BhwBbAX8A/qUr8x7AQ7v9HwW8uXt/U+CNtOtrVrpr8VFAAU+bYZF3V9VGwCbAR4GvJFl3lvvYGfj/wAuBLYBrgY+MLPJ14DFJ7jnb8ksLhUmUNE1VXVNVb62qs6vqlqr6JvA72hchVfXtqvpiVV1ZVdcCHwIeOc62k/yke3lyV1PwnNmULcn+Xc3YlUl+m+QJ3fubdrVnFyY5P8k/TH1pTjWnJXlPV3Pxu6matSTvoH0Zf6grz4e69yvJq5OcAZzRvfeKJGd2NS1fT7LVSLlurV1Lcvdu/pVJjgW2X9ExVdWHq+r7wHVjhOCJwI9neP/FwNeAw7vXU+XaHNgW+FhV3dBNP6uqWTUvjnHOtwW+W1UXV9V1wGHAziPzjqqq64HvA1PNnu8A/rmqZpvQAbwIOBr4JCPHO0O5C/gscDdaIjQbBwDfqKqfVNXVwFuAZyTZuNv2dcDxwH6zLr20QJhESSuRZAtgR+DU5Syy9wrm3U5V7d293KVrAjssyX26ZqblTc/vyrEH8Gla7cVm3X7P7rb3SeAmYAdgN+DxwGgT3cOBXwObA+8GDk2Sqvp/wE+BA7vyHDiyztO79R6YZF/gncCzgS2B3wOfX85hfpiWEG0JvKybVpcHd8dxqyR3AZ4FfKabnpvkTt3sy4AzgX9P8vTuXI6uO1bsZzD9nB8KPDLJVl15DgC+3c07FXhUkjsDjwVOTbIY2KmqPtszDi8aOd79ph/XyPGt2y37O+Di7r29VnLMe3Wr70yrJQSgqn4L3ED7W5jyK2CXnscgzXuTrqaX5rUk69O+qD5VVafPMP8hwN8C+/fdR1WdQ0uKVublwMer6oju9/O7MmwBPAnYrKr+G7gmyfuAJbTmGIDfV9XHuuU/RWuW2QK4aAX7e2dVXd6tc0C37xO63/8K+EOSbarq7KkVui/tZwIPrqprgFO6/e19h633sxmtKW3UM4Drge/RPtPWB54M/EdVVZLH0JrQ3gtsm9bJ/eVVdcYsYn+r5ZzzM2hNwOcDNwO/BA4EqKpTknyZVnN0evf+14CXJ3kNLQE8F3h1VV0xxv73ojUpfqGqLk3yW+D5wPtGFntDkgOBDYB0x3tzV56jxjzmjYD/mvbefwEbj/x+FS1ZltZK1kRJy5FkHeDfaP99HzjD/B1otQ2vraqfDlCkewO/neH9+9IShwunahNoydM9Rpa5NVnqmqOgfUmuyLkjr7ei1T5NbeNqWi3P1tPWWcRtfcqm/J7V5w/c/kscWnPWF6rqpq6J6cuMNHFV1XlVdWBVbU+L1TW0Gr1ZW8E5/zAtYbk7cFfgK9xWE0VVva+qdqmq59Bq835C+/xdQqud+hVdX6kxvBj4XlVd2v3+We7YpPeeqtoMuAuwGPjnjNwcMaaraX2qRm3C7ZPYjYErZrldacEwiZJmkCS0JpotgGdW1Y3T5t8XOBJ4e1X92yru6z5df6TlTQd0i57LzP2LzqXVxGxeVZt10yZVNe7t5zXG+xfQEpCpMt+VljCcP22dZbRmxXuPvHefMcsxjl8w0pyUdqfbvsALklyU5CJazc6Tuv5Qt1NV59ISngd1648b+5Wd812BT1bV5V3fp38B9phehq7WcAntrrYHAb/orq3jaJ3SV6hrEnw28OiR4309sEuSOzSrVXMK8DNa7RxJHrWSY35Ut/qpjDTVpQ1hsQHwm5FdPICRJj9pbWMSJc3so7QviKd2TWS3Srt1/QfAh6rqX3ts+2Ju61xMVZ3T9Uda3vSZbtFDgZcmeWySdZJsneT+VXUhrSnrvUk26eZtn/Fva79deZbjc92+d027pf4fgWNGm/K6Y7mZVgvz1iR3SfJAVtDxGSDJnZJsSGt2Wj/Jhl0t4EwOp901OeWFtC/1nWiJzK60JOs84HlJ/ijJ25Ls0MVlc1ofraO78o4V+zHO+XHAi9I6+K9Pu9vwgpHaoikHAW/tagN/BzwsyUbAPsBZ3b72SbK8xPbptObCB44c7wNo/dpeNNMKSe4P7EXXh6uqfrqSY56qYfsM8NQu6borLfH7SlVd1W13Q9rNFkfcca/SWqKqnJycRiZajUvROkdfPTId0M3/u27+6LyrR9b/a+DbK9j+nwEX0ppBnj3Lsv0JrTbmKlqH6f269zelJX7n0fqtnAg8t5v3EtrdYaPbKWCH7vWetETkD8AHp8+fVu7fApcD3wTutZztLermXwkcC7x9+v6nbfdH3fqj0z4rWP444OHd69OBP59hmTcBS2lNa5+idcC/mtas+Tlg61nGfWXn/O60pOOS7rweBewxbRv7At+a9t77u7gfPRVPWmL4s+WU4zvAe2d4/9ndsa1Hu8nghq6M1wDn0JLedXr8LTy/W/8aWj+uu43M+9+0pGqN/806Oa2pKVXL+4dHkuaeJI8HXlVVT1/TZZmEJIcAX6yq767psqxIkmNoHdZPWdNlkdYUkyhJkqQe7BMlSZLUg0mUJElSDyZRkiRJPZhESZIk9TCRx75svvnmtc0220xi05IkSavV8ccff2lVLZrtehNJorbZZhuWLl06iU1LkiStVkl6PZ7K5jxJkqQexkqikmyW5EtJTk/yqyR7TrpgkiRJc9m4zXkfAL5TVc9Kcifak8ElSZLWWitNopJsCuxNe/4WVXUD7blMkiRJa61xmvO2BZYBn0hyYpJDuid6306SJUmWJlm6bNmy1V5QSZKkuWScJGo9YHfgo1W1G+1p3m+evlBVHVxVi6tq8aJFs75LUJIkaV4ZJ4k6Dzivqo7pfv8SLamSJElaa600iaqqi4Bzk+zUvfVY4LSJlkqSJGmOG/fuvD8HPtPdmXcW8NLJFUmSJGnuGyuJqqqTgMWTLYokSdL84YjlkiRJPZhESZIk9WASJUmS1INJlCRJUg8mUZIkST2YREmSJPVgEiVJktSDSZQkSVIPJlGSJEk9mERJkiT1YBIlSZLUg0mUJElSDyZRkiRJPZhESZIk9WASJUmS1INJlCRJUg8mUZIkST2sN85CSc4GrgJuBm6qqsWTLJQkSdJcN1YS1XlMVV06sZJIkiTNIzbnSZIk9TBuElXA95Icn2TJTAskWZJkaZKly5YtW30llCRJmoPGTaL2qqrdgScCr06y9/QFqurgqlpcVYsXLVq0WgspSZI014yVRFXV+d3PS4D/APaYZKEkSZLmupUmUUnummTjqdfA44FTJl0wSZKkuWycu/O2AP4jydTyn62q70y0VJIkSXPcSpOoqjoL2GWAskiSJM0bDnEgSZLUg0mUJElSDyZRkiRJPZhESZIk9WASJUmS1INJlCRJUg8mUZIkST2YREmSJPVgEiVJktSDSZQkSVIPJlGSJEk9mERJkiT1YBIlSZLUg0mUJElSDyZRkiRJPZhESZIk9WASJUmS1MPYSVSSdZOcmOSbkyyQJEnSfDCbmqjXAr+aVEEkSZLmk7GSqCT3Ap4MHDLZ4kiSJM0P49ZEvR94E3DL5IoiSZI0f6w0iUryFOCSqjp+JcstSbI0ydJly5attgJKkiTNRePURD0SeFqSs4HPA/sm+ffpC1XVwVW1uKoWL1q0aDUXU5IkaW5ZaRJVVX9VVfeqqm2A5wI/qKoXTLxkkiRJc5jjREmSJPWw3mwWrqofAT+aSEkkSZLmEWuiJEmSejCJkiRJ6sEkSpIkqQeTKEmSpB5MoiRJknowiZIkSerBJEqSJKkHkyhJkqQeTKIkSZJ6MImSJEnqwSRKkiSpB5MoSZKkHkyiJEmSejCJkiRJ6sEkSpIkqQeTKEmSpB5MoiRJknpYaRKVZMMkxyY5OcmpSd42RMEkSZLmsvXGWOZ6YN+qujrJ+sBRSb5dVUdPuGySJElz1kqTqKoq4Oru1/W7qSZZKEmSpLlurD5RSdZNchJwCXBEVR0z0VJJkiTNcWMlUVV1c1XtCtwL2CPJg6Yvk2RJkqVJli5btmw1F1OSJGlumdXdeVV1BfBD4AkzzDu4qhZX1eJFixatpuJJkiTNTePcnbcoyWbd6zsDjwNOn3C5JEmS5rRx7s7bEvhUknVpSdcXquqbky2WJEnS3DbO3Xm/AHYboCySJEnzhiOWS5Ik9WASJUmS1INJlCRJUg8mUZIkST2YREmSJPVgEiVJktSDSZQkSVIPJlGSJEk9mERJkiT1YBIlSZLUg0mUJElSDyZRkiRJPZhESZIk9WASJUmS1INJlCRJUg8mUZIkST2YREmSJPWw0iQqyb2T/DDJaUlOTfLaIQomSZI0l603xjI3AX9RVSck2Rg4PskRVXXahMsmSZI0Z620JqqqLqyqE7rXVwG/AraedMEkSZLmsln1iUqyDbAbcMxESiNJkjRPjJ1EJdkI+DLwuqq6cob5S5IsTbJ02bJlq7OMkiRJc85YSVSS9WkJ1Geq6iszLVNVB1fV4qpavGjRotVZRkmSpDlnnLvzAhwK/KqqDpp8kSRJkua+cWqiHgm8ENg3yUnd9KQJl0uSJGlOW+kQB1V1FJAByiJJkjRvOGK5JElSDyZRkiRJPZhESZIk9WASJUmS1INJlCRJUg8mUZIkST2YREmSJPVgEiVJktSDSZQkSVIPJlGSJEk9mERJkiT1YBIlSZLUg0mUJElSDyZRkiRJPZhESZIk9WASJUmS1INJlCRJUg8rTaKSfDzJJUlOGaJAkiRJ88E4NVGfBJ4w4XJIkiTNKytNoqrqJ8DlA5RFkiRp3rBPlCRJUg+rLYlKsiTJ0iRLly1btro2K0mSNCettiSqqg6uqsVVtXjRokWra7OSJElzks15kiRJPYwzxMHngP8EdkpyXpKXT75YkiRJc9t6K1ugqp43REEkSZLmE5vzJEmSejCJkiRJ6sEkSpIkqQeTKEmSpB5MoiRJknowiZIkSerBJEqSJKkHkyhJkqQeTKIkSZJ6MImSJEnqwSRKkiSpB5MoSZKkHkyiJEmSejCJkiRJ6mG9NV0ASXe0zZu/taaL0MvZ73rymi6CpBXws2X1siZKkiSpB5MoSZKkHsZqzkvyBOADwLrAIVX1romWSnOK1b+SJN3RSpOoJOsCHwYeB5wHHJfk61V12qQLNxO/0CVNgp8twzPmmu/Gac7bAzizqs6qqhuAzwP7T7ZYkiRJc9s4SdTWwLkjv5/XvSdJkrTWSlWteIHkWcATqupPu99fCDy8qg6cttwSYEn3607Ar1d/cSduc+DSNV2ItYwxH54xH54xH54xH958jvl9q2rRbFcap2P5+cC9R36/V/fe7VTVwcDBsy3AXJJkaVUtXtPlWJsY8+EZ8+EZ8+EZ8+GtjTEfpznvOOB+SbZNcifgucDXJ1ssSZKkuW2lNVFVdVOSA4Hv0oY4+HhVnTrxkkmSJM1hY40TVVWHA4dPuCxzwbxujpynjPnwjPnwjPnwjPnw1rqYr7RjuSRJku7Ix75IkiT1YBIlSZLUg0nUApJkgyTrd6+zpsuzNkiyTvfTeA8kyZ26x1EZ94F0ny0bdK+N+QRNxTfJnZMs6l77XT2AJBsl2aZ7PdZ17olZAJLsleRU4PvA6wHKzm4Tk2TjJG9M8gvgg93b/i1NUJItkvxdkp8B3wFeA17nk5TkHknemeQHwA+A1yfZwJhPVlVVkl2Bc4C/XMPFWfCS3C3J25N8CzgReDGM/9ky1t15mlu6/0pSVTcn2ZA2UvxfAT8BvpXkLODLftitPl3M16mqm2hDfWwJfBo4AKCqbl6DxVuQRq9z2oC/WwKvA34P/CDJyVX1gzVYxAVn2nW+AbA+8DfAL4GfA0uBI9dcCReeqVqmqrpl5O0H0P4p3naGeVpF067zjYE3A4+vqh/Odlv+9zyPTFUvVtUtU1/aVXUd7SHRJ1bVFcB7gX1oj97RKpoW85u611cA7wQOAq5Pstvoslo1M13nwJnAG6rquKq6BDiW7gtGq2451/m5VfWGqvp5VV0FnAVctybLuZBMi/n0JOlZwGHAdUkeOrq8+lvOdf574NRuIsmWs9mmSdQclGbd6e3gXTXvPZPsk+QDSZ6aZFPgKOBB3WKnAtcDfrHPwpgxf3+S/bv3l3UffL8E9usW9+9pFmYR86dV1RVVdXX31ARotSTW/s3SbGI+ss5Lk9xIey7aVkOXeb6b7WdL15R3JnAScDGtVgr8fBnbLGL+zG7WKcDRSY4HPpRkybj90Dwpc0CSzZI8uUuIqObmqrplNAlKcgCtSv1JwP8CXgpcC1zAbX9oy4CLgK2ntjXckcwfPWP+WODl3ftTfzs/BvYetvTz0yrE/BXd++tX1Q1J9gDuC3zJfxJWbFVj3vk2cPfuvWdMfdlrZqsQ8z/rZu0IXFBVvwOuAF6Z5JV2GVi+VYj5n3az3g+8C3gk8E/A04FnjLNv+0TNDQ+k9a25HjgyyU7AC4CHAz9N8iFaNfofA6+tqm8kORI4BAhwOvAEgKq6vFv/28MfxryyvJjvARy1gph/HFp1cPfHeQzwxu49P+RWbFVjfmO3nTcCH6mqq4c+gHlolWIOUFUXdS9PS3IesG2Sdeyns1x9P88P7WpadwRemGQJsBHtM/6CNXAc80nf6/wTAFW1lNbfD+DYJKcBW4xznVsTNZCuenF58T6bVn27Q/f7PrQapTcC1wB/S7s4FgMnd/+Rf492/h4AfBXYNcnju/Xv062/VusZ8zdxW8xv4I4xn7pzZuq/nTOAa5MclOTlSbaY1PHMBxOM+VTz9J60D8OlSfZP8vwkG0/qeOaDSV/nI/tZF7gfcPrankBN6PM8wPa0O8TeBTwVeBhwHK1Zb63unjGh6/yWGa7z9Wh9is8Y5zo3iRpI94W7vBOyDLiQ9h8IwKeA44FX0aob9wLu1C338JH/yK8C9q+qa4G3AS9Jchnwi25aq62GmK8PXAI8YlrMnwSQ5BFJfkz7YtkNuJFW/b7WmmDMn9K9/nPaf5yH0O5KvRb479V8GPPKBGO+H0CSVyY5jtZH50xa7etabYKf539SVd+qqk9U1Vm0ZOtwuv5/a3P3jAle508ESPLitD5RJwK/pt28slI2561mM1X/ddnzdsBLgBur6m2j86vqxiTnALsnuQ8tY34lrb/NO2h3ge0JfAx4dtfuG+BSWjUmtNqo71e7c2ytMkbMb6iqvx+dPy3m96V9WL2SNkzEaMwPocV8k27Vy4BdutfnAK+rqhMncmBz2MAxvxy4f/f648AHq+roiRzYHLYGYv6Q7vWJwIFVtdYlT2vg8/zB3T42qKrrq+q/gEMneIhzzhq4zh/cvf4l8OrZfrZYE7UKkqzTVXHfaurkJ3lQ2hhO0E7gB2j/TXxq2jamqmfPodVkbA08Gti0qg4FbqJV8T6zqr5GuwieShvb4qN01ZddJ7orum2uu1CrfXvG/NPTtjE95ltxW8wPYfkx34QW8+27/V4wlUB1Mb9duRaKORDzj9AN2VFVR059yM1UroVijsX82KkEys8WYLKf5/fr9nv99LKtpsOcU+bIdb5jt98TRj5bxr7OrYmahSQZrU6dqWoxyZtpY3xcCfw4yadpo/0+DPhiVZ09uvzI9i7spl1ptUovSvJl2on+Ku1CgPbfzEnAQ2nVlO+eXoZaQB2cjfnw5nrMp8q3gqr9eWcexdzrfODPluWVbT6a6zHvc52bRK3EaNXi6MlPe0bdfsCzae2q76a1uRbtLoxNgS8BmwHvow1Ut6J4X9ZNewIHAwfS7rj7cVWdNrLcht2+NgW+BXxjVY9xrjHmw5tPMR8t33xmzIc3n2K+UMynmPe6zqvKaWSijYK8BNh6hnlbA0/pXj8eOAJ4JrBz995+tI7FR9LuqDi0uxjuQqv2fdpK9r0dsO1y5q27pmNjzBfOZMyNuTE35sZ81Sdrojoj2fLmtE6sZwLnJ3kMcOeqOpzWR+D1SX5NqyJcj9YZ7dpuM8fTsuhXVBsobXT7FwMPTvLDqrqqa28Ntz0bjGp3Y4yuMzVEfdUCqkafYsyHZ8yHZ8yHZ8yHt7bGfEF2VhvHVHBHgjw1eOJvaGNyTD2Xa29ue6zHz2nVjlvRBrO8DHg18L4kU1WCxwL7pw0t/7i08YPuSXs0y0XArdWaNfJssCT3SRuJefqJXxDV6GDM1wRjPjxjPjxjPjxj3qwVNVGZ9pTspHUeS3cbaZINaNWPm1bVPyS5CNiuOxEnAU9Mco+quiTJhbRbIn9eVc/qtrcxrQ12T+D/0G7D/BZt7IqvAVdX1denlWlD4MnAvsDutNtb/6Ur57z/QzPmwzPmwzPmwzPmwzPmy7cgk6jpJ7xG7gBIcvequizJPWg9//+4qv6Q5AZgs+5knkUbI2Vr4Le02yofQmunPZf2zJ3DkmxGe8bOrrQ222O6i+TtwN9NP5G5/fgXj6ONLP6vtBGAb2Qem0cxvzfG3Jj3ZMyHN49i7uf5WnidL8jmvGpVfFMZ812T7JvkI0l+A3wiyZ5VdQltqPh9utV+S3sy/P261zfQHqnyG1r145O75TahtfduCWzRLf8V4IXdNqmqG7ss/XZjYIxeiFX1jap6X1X9cr7/wcG8ivn7jbkx78uYD28exdzP87XwOl9wSVSSTdOep/XZJA+jnax/pPXM3xH4T+DPkuwA/JDb2mrPprW13o/Wnnsp8ICquoE2SvKuSU6hdWR7HfDrqjqqqpZU1Zer6srpZamR9tqFzJgPz5gPz5gPz5gPz5jPzrxozktubX+93UBdMyy3DvBWWhXiT2gndR3gdNrw7gCfo7W37gn8CHghQFWdmeThwFVVdViSc4FdkmxSVb9J8pypLHmGfd4uQ14IjPnwjPnwjPnwjPnwjPnkzNkkKsnUrYu3TJ30qZ9JdgQurarLp10UewN7VdXDRrazAbCU1l5NVZ2dZDvglKo6Nm14938C7k5rq702rcPaubTOatsBJ02d/OknfL6e+JkY8+EZ8+EZ8+EZ8+EZ82HMmSSqC+zoeA9FGy+CtGrDzWk99T/frfJL4GXTsurL6cabSBsN9ZZqdw6cDSxJ8pmqOpnWGW0qq34esH+3va9V1VXd+hfTHmK4HXDS1IU230/4KGM+PGM+PGM+PGM+PGO+ZqyxJCrTntQ8PbBpT7Z+Na2j2lOB62hjRDyjqs5NckaS3avqhJHVLgOuT/LIqvpZt52pcSt+D7wn7Y6CHwIndPs9GTh5ZL9TWfl5wPfoLpRpF9q8ZMyHZ8yHZ8yHZ8yHZ8znhsGTqO4E7AN8sft9qq12H+CJtGz5LVV1QZL9gdOqavcku9HaYjfqNvVD4I+TnFS3VQuen+QE4LXd9h5Da9d9P3A0sE5VvX2GMs1U7XkD8LPVH4HhGfPhGfPhGfPhGfPhGfO5ZeJ356Vr/5xSrV10CfDcJG8CNkmyPfACWjZ7OHBQkq2B7wAXdifoPNqTnB/ebeoYYBfgrknWT/LE7v2/pQ24dTfgIOCdwDW0Wyy368qU0XJVs2CqGI358Iz58Iz58Iz58Iz53DbxJGoqsEnum2SvJLvTev6/DdiBdmJeB1wAXE3r6b+YNn7EL4F7AXemPZTw17SOatCGj9+DdqI3BPZNsmFV3VBVP62qv6iqw6uNN3EzrVrxPV2ZFvQJN+bDM+bDM+bDM+bDM+ZzXK3a05rDcp6MTDtpdwYeCvyYdjLfAtwTeAPwnpFl/5rWbvpW4GnABt3796GduO27358C/HRqn8CfAHddzv7XoVU9rtIxzrXJmBtzY27MjfnCmIz5/J9W9wWxafdzE+CjwPOBA4B/mrbcbsB3gW1o/bIeB/xk2jKP7n7+HNi/e313YKepEzzDxZg1HdDBT6AxN+ZrwWTMjfnaMBnz+Tf16lg+0pFtR+BZwJ1o1Yg70tpqt+gugiNpWfRLu/bTi4HfVNXX04ZyX1RVZwNHJPnLJB+kVS3uDnyVln2/lPYcHqrqMtrdA9S0qsTqroKFypgPz5gPz5gPz5gPz5gvHOkbtyT3Bz4JHEE70ZcAnwZeRmt3/RWwc1Vdl2Qx7Y6ARwAvpj1D53m0Z+fcA/hYVR2R5Dm0hxAeWVXnrsJxLUjGfHjGfHjGfHjGfHjGfGFYlSEOtgfOBD4FnF9V/53kXcD/Bb4JfBnYIsk5VbUUbh18aydgfeAjtKrKK2hjUFBVh61CedYGxnx4xnx4xnx4xnx4xnwBWJWaqI2BT9BGJF2HdgvkQbRh498GHFZVr0lyZ1p15VtomfZhwIeWV3WYaQOI6TbGfHjGfHjGfHjGfHjGfGHonUTdbiOtWvJltKc2fwT4ALBlVT0pSWiDf91YVVfMsO66tKHlbY+dBWM+PGM+PGM+PGM+PGM+f/VuzutO7FbAg2mDd+0GvKqqrk5yLHC3JOtWG19i2cg663TvATD6WitmzIdnzIdnzIdnzIdnzBeG3oNtdlnvvYFXADcBb6qqM5LcD3glcEJV3dyd9FvX8YT3Z8yHZ8yHZ8yHZ8yHZ8wXhtXSnHe7Dba7A3YGPlDtdkpNmDEfnjEfnjEfnjEfnjGfX1Y5iZqqXqQlyXZmG4AxH54xH54xH54xH54xn99We02UJEnS2mDiDyCWJElaiEyiJEmSejCJkiRJ6sEkSpIkqQeTKEmSpB5MoiRJknr4H+QNmJ3YD5xkAAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "for i,row in df_heatmap.iterrows():\n", + " ax = row.plot(kind='bar', figsize=(10,3),title=f'{i}', rot=15)\n", + " ax.set_ylim(np.min(df_heatmap.values),np.max(df_heatmap.values))\n", + " plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Lastly, an alternative way to visualize the distances between the three groups of points from the heatmap would be a series of scatter plots, one for each pair of features. \n", + "\n", + "This should give a good intuition for the distance measures (in 6 dimensional feature space, lastest preprocessed observation plus the 5 lagged values) that underpin the raw anomaly score.\n", + "\n", + "Generally we would expect to see the blue 'normal' points group closer together and 'near' the green cluster centroids, meanwhile the anomalous orange points should tend to be further away from the other two groups." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# get list of feature pair combinations\n", + "feature_pairs = list(itertools.combinations(df_heatmap.columns, 2))\n", + "feature_pairs_sample = random.sample(feature_pairs,5) # just sample 5 pairs\n", + "\n", + "# define colors of points\n", + "point_colors = ['blue' for i in range(10)] + ['orange' for i in range(10)] + ['green' for i in range(2)]\n", + "\n", + "# plot each pair of features\n", + "for feature_pair in feature_pairs_sample:\n", + " df_heatmap.plot.scatter(x=feature_pair[0], y=feature_pair[1], color=point_colors, subplots=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You made it! Congratualtions to getting all the way to the end (its ok if you just skipped here too), as a reward [here](https://youtube.com/playlist?list=PL6Zhl9mK2r0Ja7SKX72rD4dfBNnaQbbwR) is a playlist of interesting data science and machine learning youtube videos that you might like considering you just read a jupyter notebook about using kmeans to do unsupervised anomaly detection :)" + ] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [], + "name": "Netdata Anomaly Detection Deepdive.ipynb", + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.1" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} \ No newline at end of file diff --git a/netdata-installer.sh b/netdata-installer.sh index 8fd6e3875..f59bc2b34 100755 --- a/netdata-installer.sh +++ b/netdata-installer.sh @@ -28,27 +28,6 @@ if [ "${NETDATA_SOURCE_DIR}" != "${INSTALLER_DIR}" ] && [ "${INSTALLER_DIR}" != echo >&2 "Warning: you are currently in '${NETDATA_SOURCE_DIR}' but the installer is in '${INSTALLER_DIR}'." fi -# ----------------------------------------------------------------------------- -# Pull in OpenSSL properly if on macOS -if [ "$(uname -s)" = 'Darwin' ]; then - if brew --prefix > /dev/null 2>&1; then - if brew --prefix --installed openssl > /dev/null 2>&1; then - HOMEBREW_OPENSSL_PREFIX=$(brew --prefix --installed openssl) - elif brew --prefix --installed openssl@3 > /dev/null 2>&1; then - HOMEBREW_OPENSSL_PREFIX=$(brew --prefix --installed openssl@3) - elif brew --prefix --installed openssl@1.1 > /dev/null 2>&1; then - HOMEBREW_OPENSSL_PREFIX=$(brew --prefix --installed openssl@1.1) - fi - if [ -n "${HOMEBREW_OPENSSL_PREFIX}" ]; then - export CFLAGS="${CFLAGS} -I${HOMEBREW_OPENSSL_PREFIX}/include" - export LDFLAGS="${LDFLAGS} -L${HOMEBREW_OPENSSL_PREFIX}/lib" - fi - HOMEBREW_PREFIX=$(brew --prefix) - export CFLAGS="${CFLAGS} -I${HOMEBREW_PREFIX}/include" - export LDFLAGS="${LDFLAGS} -L${HOMEBREW_PREFIX}/lib" - fi -fi - # ----------------------------------------------------------------------------- # reload the user profile @@ -207,7 +186,7 @@ banner_root_notify() { Netdata will work, but a few data collection modules that require root access will fail. - If you installing netdata permanently on your system, run + If you are installing netdata permanently on your system, run the installer like this: ${TPUT_YELLOW}${TPUT_BOLD}sudo $PROGRAM ${@}${TPUT_RESET} @@ -223,50 +202,47 @@ usage() { USAGE: ${PROGRAM} [options] where options include: - --install Install netdata in . Ex. --install /opt will put netdata in /opt/netdata - --dont-start-it Do not (re)start netdata after installation - --dont-wait Run installation in non-interactive mode - --auto-update or -u Install netdata-updater in cron to update netdata automatically once per day - --auto-update-type Override the auto-update scheduling mechanism detection, currently supported types - are: systemd, interval, crontab - --stable-channel Use packages from GitHub release pages instead of GCS (nightly updates). + --install Install netdata in . Ex. --install /opt will put netdata in /opt/netdata. + --dont-start-it Do not (re)start netdata after installation. + --dont-wait Run installation in non-interactive mode. + --stable-channel Use packages from GitHub release pages instead of nightly updates. This results in less frequent updates. --nightly-channel Use most recent nightly updates instead of GitHub releases. This results in more frequent updates. --disable-go Disable installation of go.d.plugin. - --disable-ebpf Disable eBPF Kernel plugin (Default: enabled) + --disable-ebpf Disable eBPF Kernel plugin. Default: enabled. --disable-cloud Disable all Netdata Cloud functionality. --require-cloud Fail the install if it can't build Netdata Cloud support. --enable-plugin-freeipmi Enable the FreeIPMI plugin. Default: enable it when libipmimonitoring is available. - --disable-plugin-freeipmi - --disable-https Explicitly disable TLS support - --disable-dbengine Explicitly disable DB engine support + --disable-plugin-freeipmi Explicitly disable the FreeIPMI plugin. + --disable-https Explicitly disable TLS support. + --disable-dbengine Explicitly disable DB engine support. --enable-plugin-nfacct Enable nfacct plugin. Default: enable it when libmnl and libnetfilter_acct are available. - --disable-plugin-nfacct - --enable-plugin-xenstat Enable the xenstat plugin. Default: enable it when libxenstat and libyajl are available - --disable-plugin-xenstat Disable the xenstat plugin. - --enable-backend-kinesis Enable AWS Kinesis backend. Default: enable it when libaws_cpp_sdk_kinesis and libraries - it depends on are available. - --disable-backend-kinesis - --enable-backend-prometheus-remote-write Enable Prometheus remote write backend. Default: enable it when libprotobuf and - libsnappy are available. - --disable-backend-prometheus-remote-write - --enable-backend-mongodb Enable MongoDB backend. Default: enable it when libmongoc is available. - --disable-backend-mongodb + --disable-plugin-nfacct Explicitly disable the nfacct plugin. + --enable-plugin-xenstat Enable the xenstat plugin. Default: enable it when libxenstat and libyajl are available. + --disable-plugin-xenstat Explicitly disable the xenstat plugin. + --enable-exporting-kinesis Enable AWS Kinesis exporting connector. Default: enable it when libaws_cpp_sdk_kinesis + and its dependencies are available. + --disable-exporting-kinesis Explicitly disable AWS Kinesis exporting connector. + --enable-exporting-prometheus-remote-write Enable Prometheus remote write exporting connector. Default: enable it + when libprotobuf and libsnappy are available. + --disable-exporting-prometheus-remote-write Explicitly disable Prometheus remote write exporting connector. + --enable-exporting-mongodb Enable MongoDB exporting connector. Default: enable it when libmongoc is available. + --disable-exporting-mongodb Explicitly disable MongoDB exporting connector. --enable-exporting-pubsub Enable Google Cloud PubSub exporting connector. Default: enable it when libgoogle_cloud_cpp_pubsub_protos and its dependencies are available. - --disable-exporting-pubsub - --enable-lto Enable Link-Time-Optimization. Default: disabled - --disable-lto - --enable-ml Enable anomaly detection with machine learning. (Default: autodetect) - --disable-ml - --disable-x86-sse Disable SSE instructions. By default SSE optimizations are enabled. - --use-system-lws Use a system copy of libwebsockets instead of bundling our own (default is to use the bundled copy). - --use-system-protobuf Use a system copy of libprotobuf instead of bundling our own (default is to use the bundled copy). - --zlib-is-really-here or - --libs-are-really-here If you get errors about missing zlib or libuuid but you know it is available, you might + --disable-exporting-pubsub Explicitly disable Google Cloud PubSub exporting connector. + --enable-lto Enable link-time optimization. Default: disabled. + --disable-lto Explicitly disable link-time optimization. + --enable-ml Enable anomaly detection with machine learning. Default: autodetect. + --disable-ml Explicitly disable anomaly detection with machine learning. + --disable-x86-sse Disable SSE instructions & optimizations. Default: enabled. + --use-system-lws Use a system copy of libwebsockets instead of bundled copy. Default: bundled. + --use-system-protobuf Use a system copy of libprotobuf instead of bundled copy. Default: bundled. + --zlib-is-really-here + --libs-are-really-here If you see errors about missing zlib or libuuid but you know it is available, you might have a broken pkg-config. Use this option to proceed without checking pkg-config. - --disable-telemetry Use this flag to opt-out from our anonymous telemetry program. (DO_NOT_TRACK=1) + --disable-telemetry Opt-out from our anonymous telemetry program. (DISABLE_TELEMETRY=1) --skip-available-ram-check Skip checking the amount of RAM the system has and pretend it has enough to build safely. Netdata will by default be compiled with gcc optimization -O2 @@ -284,7 +260,13 @@ or use the following if both LDFLAGS and CFLAGS need to be overridden: For the installer to complete successfully, you will need these packages installed: - gcc make autoconf automake pkg-config zlib1g-dev (or zlib-devel) uuid-dev (or libuuid-devel) + gcc + make + autoconf + automake + pkg-config + zlib1g-dev (or zlib-devel) + uuid-dev (or libuuid-devel) For the plugins, you will at least need: @@ -295,12 +277,11 @@ HEREDOC DONOTSTART=0 DONOTWAIT=0 -AUTOUPDATE=0 NETDATA_PREFIX= LIBS_ARE_HERE=0 NETDATA_ENABLE_ML="" NETDATA_CONFIGURE_OPTIONS="${NETDATA_CONFIGURE_OPTIONS-}" -RELEASE_CHANNEL="nightly" # check .travis/create_artifacts.sh before modifying +RELEASE_CHANNEL="nightly" # valid values are 'nightly' and 'stable' IS_NETDATA_STATIC_BINARY="${IS_NETDATA_STATIC_BINARY:-"no"}" while [ -n "${1}" ]; do case "${1}" in @@ -313,19 +294,8 @@ while [ -n "${1}" ]; do "--dont-scrub-cflags-even-though-it-may-break-things") DONT_SCRUB_CFLAGS_EVEN_THOUGH_IT_MAY_BREAK_THINGS=1 ;; "--dont-start-it") DONOTSTART=1 ;; "--dont-wait") DONOTWAIT=1 ;; - "--auto-update" | "-u") AUTOUPDATE=1 ;; - "--auto-update-type") - AUTO_UPDATE_TYPE="$(echo "${2}" | tr '[:upper:]' '[:lower:]')" - case "${AUTO_UPDATE_TYPE}" in - systemd|interval|crontab) - shift 1 - ;; - *) - echo "Unrecognized value for --auto-update-type. Valid values are: systemd, interval, crontab" - exit 1 - ;; - esac - ;; + "--auto-update" | "-u") ;; + "--auto-update-type") ;; "--stable-channel") RELEASE_CHANNEL="stable" ;; "--nightly-channel") RELEASE_CHANNEL="nightly" ;; "--enable-plugin-freeipmi") NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--enable-plugin-freeipmi)}" | sed 's/$/ --enable-plugin-freeipmi/g')" ;; @@ -339,15 +309,20 @@ while [ -n "${1}" ]; do "--disable-plugin-nfacct") NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--disable-plugin-nfacct)}" | sed 's/$/ --disable-plugin-nfacct/g')" ;; "--enable-plugin-xenstat") NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--enable-plugin-xenstat)}" | sed 's/$/ --enable-plugin-xenstat/g')" ;; "--disable-plugin-xenstat") NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--disable-plugin-xenstat)}" | sed 's/$/ --disable-plugin-xenstat/g')" ;; - "--enable-backend-kinesis") NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--enable-backend-kinesis)}" | sed 's/$/ --enable-backend-kinesis/g')" ;; - "--disable-backend-kinesis") NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--disable-backend-kinesis)}" | sed 's/$/ --disable-backend-kinesis/g')" ;; - "--enable-backend-prometheus-remote-write") NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--enable-backend-prometheus-remote-write)}" | sed 's/$/ --enable-backend-prometheus-remote-write/g')" ;; - "--disable-backend-prometheus-remote-write") - NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--disable-backend-prometheus-remote-write)}" | sed 's/$/ --disable-backend-prometheus-remote-write/g')" + "--enable-exporting-kinesis" | "--enable-backend-kinesis") + NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--enable-exporting-kinesis)}" | sed 's/$/ --enable-exporting-kinesis/g')" ;; + "--disable-exporting-kinesis" | "--disable-backend-kinesis") + NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--disable-exporting-kinesis)}" | sed 's/$/ --disable-exporting-kinesis/g')" ;; + "--enable-exporting-prometheus-remote-write" | "--enable-backend-prometheus-remote-write") + NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--enable-exporting-prometheus-remote-write)}" | sed 's/$/ --enable-exporting-prometheus-remote-write/g')" ;; + "--disable-exporting-prometheus-remote-write" | "--disable-backend-prometheus-remote-write") + NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--disable-exporting-prometheus-remote-write)}" | sed 's/$/ --disable-exporting-prometheus-remote-write/g')" NETDATA_DISABLE_PROMETHEUS=1 ;; - "--enable-backend-mongodb") NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--enable-backend-mongodb)}" | sed 's/$/ --enable-backend-mongodb/g')" ;; - "--disable-backend-mongodb") NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--disable-backend-mongodb)}" | sed 's/$/ --disable-backend-mongodb/g')" ;; + "--enable-exporting-mongodb" | "--enable-backend-mongodb") + NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--enable-exporting-mongodb)}" | sed 's/$/ --enable-exporting-mongodb/g')" ;; + "--disable-exporting-mongodb" | "--disable-backend-mongodb") + NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--disable-exporting-mongodb)}" | sed 's/$/ --disable-exporting-mongodb/g')" ;; "--enable-exporting-pubsub") NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--enable-exporting-pubsub)}" | sed 's/$/ --enable-exporting-pubsub/g')" ;; "--disable-exporting-pubsub") NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--disable-exporting-pubsub)}" | sed 's/$/ --disable-exporting-pubsub/g')" ;; "--enable-lto") NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--enable-lto)}" | sed 's/$/ --enable-lto/g')" ;; @@ -411,6 +386,13 @@ while [ -n "${1}" ]; do shift 1 done +if [ ! "${DISABLE_TELEMETRY:-0}" -eq 0 ] || + [ -n "$DISABLE_TELEMETRY" ] || + [ ! "${DO_NOT_TRACK:-0}" -eq 0 ] || + [ -n "$DO_NOT_TRACK" ]; then + NETDATA_DISABLE_TELEMETRY=1 +fi + make="make" # See: https://github.com/netdata/netdata/issues/9163 if [ "$(uname -s)" = "FreeBSD" ]; then @@ -515,8 +497,8 @@ if [ -z "$NETDATA_DISABLE_TELEMETRY" ]; then ${TPUT_YELLOW}${TPUT_BOLD}NOTE${TPUT_RESET}: Anonymous usage stats will be collected and sent to Netdata. To opt-out, pass --disable-telemetry option to the installer or export - the environment variable DO_NOT_TRACK to a non-zero or non-empty value - (e.g: export DO_NOT_TRACK=1). + the environment variable DISABLE_TELEMETRY to a non-zero or non-empty value + (e.g: export DISABLE_TELEMETRY=1). BANNER4 fi @@ -688,7 +670,7 @@ bundle_protobuf() { "${PROTOBUF_PACKAGE_BASENAME}" \ "${tmp}" \ "${NETDATA_LOCAL_TARBALL_VERRIDE_PROTOBUF}"; then - if run tar -xf "${tmp}/${PROTOBUF_PACKAGE_BASENAME}" -C "${tmp}" && + if run tar --no-same-owner -xf "${tmp}/${PROTOBUF_PACKAGE_BASENAME}" -C "${tmp}" && build_protobuf "${tmp}/protobuf-${PROTOBUF_PACKAGE_VERSION}" && copy_protobuf "${tmp}/protobuf-${PROTOBUF_PACKAGE_VERSION}" && rm -rf "${tmp}"; then @@ -773,7 +755,7 @@ bundle_judy() { "${JUDY_PACKAGE_BASENAME}" \ "${tmp}" \ "${NETDATA_LOCAL_TARBALL_OVERRIDE_JUDY}"; then - if run tar -xf "${tmp}/${JUDY_PACKAGE_BASENAME}" -C "${tmp}" && + if run tar --no-same-owner -xf "${tmp}/${JUDY_PACKAGE_BASENAME}" -C "${tmp}" && build_judy "${tmp}/libjudy-${JUDY_PACKAGE_VERSION}" && copy_judy "${tmp}/libjudy-${JUDY_PACKAGE_VERSION}" && rm -rf "${tmp}"; then @@ -857,7 +839,7 @@ bundle_jsonc() { "${JSONC_PACKAGE_BASENAME}" \ "${tmp}" \ "${NETDATA_LOCAL_TARBALL_OVERRIDE_JSONC}"; then - if run tar -xf "${tmp}/${JSONC_PACKAGE_BASENAME}" -C "${tmp}" && + if run tar --no-same-owner -xf "${tmp}/${JSONC_PACKAGE_BASENAME}" -C "${tmp}" && build_jsonc "${tmp}/json-c-json-c-${JSONC_PACKAGE_VERSION}" && copy_jsonc "${tmp}/json-c-json-c-${JSONC_PACKAGE_VERSION}" && rm -rf "${tmp}"; then @@ -891,6 +873,37 @@ get_kernel_version() { printf "%03d%03d%03d" "${maj}" "${min}" "${patch}" } +detect_libc() { + libc= + if ldd --version 2>&1 | grep -q -i glibc; then + echo >&2 " Detected GLIBC" + libc="glibc" + elif ldd --version 2>&1 | grep -q -i 'gnu libc'; then + echo >&2 " Detected GLIBC" + libc="glibc" + elif ldd --version 2>&1 | grep -q -i musl; then + echo >&2 " Detected musl" + libc="musl" + else + ls_path=$(command -v ls) + if [ -n "${ls_path}" ] ; then + cmd=$(ldd "$ls_path" | grep -w libc | cut -d" " -f 3) + if bash -c "${cmd}" 2>&1 | grep -q -i "GNU C Library"; then + echo >&2 " Detected GLIBC" + libc="glibc" + fi + fi + fi + + if [ -z "$libc" ]; then + echo >&2 " ERROR: Cannot detect a supported libc on your system!" + return 1 + fi + + echo "${libc}" + return 0 +} + rename_libbpf_packaging() { if [ "$(get_kernel_version)" -ge "004014000" ]; then cp packaging/current_libbpf.checksums packaging/libbpf.checksums @@ -923,6 +936,7 @@ copy_libbpf() { run cp "${1}/usr/${lib_subdir}/libbpf.a" "${target_dir}/libbpf.a" || return 1 run cp -r "${1}/usr/include" "${target_dir}" || return 1 + run cp -r "${1}/include/uapi" "${target_dir}/include" || return 1 } bundle_libbpf() { @@ -930,6 +944,14 @@ bundle_libbpf() { return 0 fi + # When libc is not detected, we do not have necessity to compile libbpf and we should not do download of eBPF programs + libc="${EBPF_LIBC:-"$(detect_libc)"}" + if [ -z "$libc" ]; then + NETDATA_DISABLE_EBPF=1 + NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--disable-ebpf)}" | sed 's/$/ --disable-ebpf/g')" + return 0 + fi + [ -n "${GITHUB_ACTIONS}" ] && echo "::group::Bundling libbpf." rename_libbpf_packaging @@ -946,7 +968,7 @@ bundle_libbpf() { "${LIBBPF_PACKAGE_BASENAME}" \ "${tmp}" \ "${NETDATA_LOCAL_TARBALL_OVERRIDE_LIBBPF}"; then - if run tar -xf "${tmp}/${LIBBPF_PACKAGE_BASENAME}" -C "${tmp}" && + if run tar --no-same-owner -xf "${tmp}/${LIBBPF_PACKAGE_BASENAME}" -C "${tmp}" && build_libbpf "${tmp}/libbpf-${LIBBPF_PACKAGE_VERSION}" && copy_libbpf "${tmp}/libbpf-${LIBBPF_PACKAGE_VERSION}" && rm -rf "${tmp}"; then @@ -973,6 +995,59 @@ bundle_libbpf() { bundle_libbpf +copy_co_re() { + cp -R "${1}/includes" "collectors/ebpf.plugin/" +} + +bundle_ebpf_co_re() { + if { [ -n "${NETDATA_DISABLE_EBPF}" ] && [ ${NETDATA_DISABLE_EBPF} = 1 ]; } || [ "$(uname -s)" != Linux ]; then + return 0 + fi + + [ -n "${GITHUB_ACTIONS}" ] && echo "::group::Bundling libbpf." + + progress "eBPF CO-RE" + + CORE_PACKAGE_VERSION="$(cat packaging/ebpf-co-re.version)" + + tmp="$(mktemp -d -t netdata-ebpf-co-re-XXXXXX)" + CORE_PACKAGE_BASENAME="netdata-ebpf-co-re-glibc-${CORE_PACKAGE_VERSION}.tar.xz" + + if fetch_and_verify "ebpf-co-re" \ + "https://github.com/netdata/ebpf-co-re/releases/download/${CORE_PACKAGE_VERSION}/${CORE_PACKAGE_BASENAME}" \ + "${CORE_PACKAGE_BASENAME}" \ + "${tmp}" \ + "${NETDATA_LOCAL_TARBALL_OVERRIDE_CORE}"; then + if run tar --no-same-owner -xf "${tmp}/${CORE_PACKAGE_BASENAME}" -C "${tmp}" && + copy_co_re "${tmp}" && + rm -rf "${tmp}"; then + run_ok "libbpf built and prepared." + else + run_failed "Failed to get eBPF CO-RE files." + if [ -n "${NETDATA_DISABLE_EBPF}" ] && [ ${NETDATA_DISABLE_EBPF} = 0 ]; then + exit 1 + else + defer_error_highlighted "Failed to get CO-RE. You will not be able to use eBPF plugin." + NETDATA_DISABLE_EBPF=1 + NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--disable-ebpf)}" | sed 's/$/ --disable-ebpf/g')" + fi + fi + else + run_failed "Unable to fetch sources for libbpf." + if [ -n "${NETDATA_DISABLE_EBPF}" ] && [ ${NETDATA_DISABLE_EBPF} = 0 ]; then + exit 1 + else + defer_error_highlighted "Unable to fetch sources for eBPF CO-RE. You will not be able to use eBPF plugin." + NETDATA_DISABLE_EBPF=1 + NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--disable-ebpf)}" | sed 's/$/ --disable-ebpf/g')" + fi + fi + + [ -n "${GITHUB_ACTIONS}" ] && echo "::endgroup::" +} + +bundle_ebpf_co_re + # ----------------------------------------------------------------------------- # If we have the dashboard switching logic, make sure we're on the classic # dashboard during the install (updates don't work correctly otherwise). @@ -1062,14 +1137,6 @@ if [ -d "${NETDATA_PREFIX}/etc/netdata" ]; then run mkdir "${NETDATA_PREFIX}/etc/netdata/node.d" fi - # move the node.d config files - for x in named sma_webbox snmp; do - for y in "" ".old" ".orig"; do - if [ -f "${NETDATA_PREFIX}/etc/netdata/${x}.conf${y}" ] && [ ! -f "${NETDATA_PREFIX}/etc/netdata/node.d/${x}.conf${y}" ]; then - run mv -f "${NETDATA_PREFIX}/etc/netdata/${x}.conf${y}" "${NETDATA_PREFIX}/etc/netdata/node.d/${x}.conf${y}" - fi - done - done fi # ----------------------------------------------------------------------------- @@ -1200,15 +1267,6 @@ NETDATA_GROUP="$(id -g -n "${NETDATA_USER}")" [ -z "${NETDATA_GROUP}" ] && NETDATA_GROUP="${NETDATA_USER}" echo >&2 "Netdata user and group is finally set to: ${NETDATA_USER}/${NETDATA_GROUP}" -# the owners of the web files -NETDATA_WEB_USER="$(config_option "web" "web files owner" "${NETDATA_USER}")" -NETDATA_WEB_GROUP="${NETDATA_GROUP}" -if [ "$(id -u)" = "0" ] && [ "${NETDATA_USER}" != "${NETDATA_WEB_USER}" ]; then - NETDATA_WEB_GROUP="$(id -g -n "${NETDATA_WEB_USER}")" - [ -z "${NETDATA_WEB_GROUP}" ] && NETDATA_WEB_GROUP="${NETDATA_WEB_USER}" -fi -NETDATA_WEB_GROUP="$(config_option "web" "web files group" "${NETDATA_WEB_GROUP}")" - # port defport=19999 NETDATA_PORT="$(config_option "web" "default port" ${defport})" @@ -1228,8 +1286,6 @@ cat << OPTIONSEOF Permissions - netdata user : ${NETDATA_USER} - netdata group : ${NETDATA_GROUP} - - web files user : ${NETDATA_WEB_USER} - - web files group : ${NETDATA_WEB_GROUP} - root user : ${ROOT_USER} Directories @@ -1274,7 +1330,6 @@ if [ ! -d "${NETDATA_WEB_DIR}" ]; then echo >&2 "Creating directory '${NETDATA_WEB_DIR}'" run mkdir -p "${NETDATA_WEB_DIR}" || exit 1 fi -run chown -R "${NETDATA_WEB_USER}:${NETDATA_WEB_GROUP}" "${NETDATA_WEB_DIR}" run find "${NETDATA_WEB_DIR}" -type f -exec chmod 0664 {} \; run find "${NETDATA_WEB_DIR}" -type d -exec chmod 0775 {} \; @@ -1534,10 +1589,10 @@ install_go() { # Install new files run rm -rf "${NETDATA_STOCK_CONFIG_DIR}/go.d" run rm -rf "${NETDATA_STOCK_CONFIG_DIR}/go.d.conf" - run tar -xf "${tmp}/config.tar.gz" -C "${NETDATA_STOCK_CONFIG_DIR}/" + run tar --no-same-owner -xf "${tmp}/config.tar.gz" -C "${NETDATA_STOCK_CONFIG_DIR}/" run chown -R "${ROOT_USER}:${ROOT_GROUP}" "${NETDATA_STOCK_CONFIG_DIR}" - run tar -xf "${tmp}/${GO_PACKAGE_BASENAME}" + run tar --no-same-owner -xf "${tmp}/${GO_PACKAGE_BASENAME}" run mv "${GO_PACKAGE_BASENAME%.tar.gz}" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/go.d.plugin" if [ "$(id -u)" -eq 0 ]; then run chown "root:${NETDATA_GROUP}" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/go.d.plugin" @@ -1550,25 +1605,6 @@ install_go() { install_go -detect_libc() { - libc= - if ldd --version 2>&1 | grep -q -i glibc; then - echo >&2 " Detected GLIBC" - libc="glibc" - elif ldd --version 2>&1 | grep -q -i 'gnu libc'; then - echo >&2 " Detected GLIBC" - libc="glibc" - elif ldd --version 2>&1 | grep -q -i musl; then - echo >&2 " Detected musl" - libc="musl" - else - echo >&2 " ERROR: Cannot detect a supported libc on your system!" - return 1 - fi - echo "${libc}" - return 0 -} - should_install_ebpf() { if [ "${NETDATA_DISABLE_EBPF:=0}" -eq 1 ]; then run_failed "eBPF explicitly disabled." @@ -1606,7 +1642,7 @@ remove_old_ebpf() { mv "${NETDATA_PREFIX}/etc/netdata/ebpf_process.conf" "${NETDATA_PREFIX}/etc/netdata/ebpf.d.conf" fi - # Added to remove eBPF programs with name pattern: NAME_VERSION.SUBVERSION.PATCH + # Added to remove eBPF programs with name pattern: NAME_VERSION.SUBVERSION.PATCH if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/pnetdata_ebpf_process.3.10.0.o" ]; then echo >&2 "Removing old eBPF programs with patch." rm -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/rnetdata_ebpf"*.?.*.*.o @@ -1666,7 +1702,7 @@ install_ebpf() { fi echo >&2 " Extracting ${EBPF_TARBALL} ..." - tar -xf "${tmp}/${EBPF_TARBALL}" -C "${tmp}" + tar --no-same-owner -xf "${tmp}/${EBPF_TARBALL}" -C "${tmp}" # chown everything to root:netdata before we start copying out of our package run chown -R root:netdata "${tmp}" @@ -1695,10 +1731,6 @@ install_ebpf # ----------------------------------------------------------------------------- progress "Telemetry configuration" -if [ ! "${DO_NOT_TRACK:-0}" -eq 0 ] || [ -n "$DO_NOT_TRACK" ]; then - NETDATA_DISABLE_TELEMETRY=1 -fi - # Opt-out from telemetry program if [ -n "${NETDATA_DISABLE_TELEMETRY+x}" ]; then run touch "${NETDATA_USER_CONFIG_DIR}/.opt-out-from-anonymous-statistics" @@ -1887,13 +1919,6 @@ progress "Installing (but not enabling) the netdata updater tool" cleanup_old_netdata_updater || run_failed "Cannot cleanup old netdata updater tool." install_netdata_updater || run_failed "Cannot install netdata updater tool." -progress "Check if we must enable/disable the netdata updater tool" -if [ "${AUTOUPDATE}" = "1" ]; then - enable_netdata_updater "${AUTO_UPDATE_TYPE}" || run_failed "Cannot enable netdata updater tool" -else - disable_netdata_updater || run_failed "Cannot disable netdata updater tool" -fi - # ----------------------------------------------------------------------------- progress "Wrap up environment set up" diff --git a/netdata.spec.in b/netdata.spec.in index c4f53fed5..3d016c971 100644 --- a/netdata.spec.in +++ b/netdata.spec.in @@ -139,15 +139,23 @@ BuildRequires: libuuid-devel BuildRequires: libuv-devel >= 1 BuildRequires: openssl-devel %if 0%{?suse_version} +BuildRequires: protobuf-devel +BuildRequires: libprotobuf-c-devel BuildRequires: judy-devel BuildRequires: liblz4-devel BuildRequires: libjson-c-devel %else %if 0%{?fedora} +BuildRequires: protobuf-devel +BuildRequires: protobuf-c-devel BuildRequires: Judy-devel BuildRequires: lz4-devel BuildRequires: json-c-devel %else +%if 0%{?centos_ver} >= 8 +BuildRequires: protobuf-devel +BuildRequires: protobuf-c-devel +%endif BuildRequires: lz4-devel BuildRequires: json-c-devel %endif @@ -200,12 +208,6 @@ BuildRequires: cups-devel >= 1.7 # Prometheus remote write dependencies BuildRequires: snappy-devel -BuildRequires: protobuf-devel -%if 0%{?suse_version} -BuildRequires: libprotobuf-c-devel -%else -BuildRequires: protobuf-c-devel -%endif # end - prometheus remote write dependencies # ##################################################################### @@ -227,15 +229,24 @@ happened, on your systems and applications. %if 0%{!?fedora:1} && 0%{!?suse_version:1} export CFLAGS="${CFLAGS} -fPIC" && ${RPM_BUILD_DIR}/%{name}-%{version}/packaging/bundle-judy.sh ${RPM_BUILD_DIR}/%{name}-%{version} %endif +# Only bundle protobuf on CentOS 7 or earlier +%if 0%{?centos_ver:1} +%if %{centos_ver} < 8 +export CFLAGS="${CFLAGS} -fPIC" && ${RPM_BUILD_DIR}/%{name}-%{version}/packaging/bundle-protobuf.sh ${RPM_BUILD_DIR}/%{name}-%{version} +%endif +%endif %if 0%{?_have_ebpf} %if 0%{?centos_ver:1} %if %{centos_ver} < 8 export CFLAGS="${CFLAGS} -fPIC" && ${RPM_BUILD_DIR}/%{name}-%{version}/packaging/bundle-libbpf.sh ${RPM_BUILD_DIR}/%{name}-%{version} centos7 +export CFLAGS="${CFLAGS} -fPIC" && ${RPM_BUILD_DIR}/%{name}-%{version}/packaging/bundle-ebpf-co-re.sh ${RPM_BUILD_DIR}/%{name}-%{version} %else export CFLAGS="${CFLAGS} -fPIC" && ${RPM_BUILD_DIR}/%{name}-%{version}/packaging/bundle-libbpf.sh ${RPM_BUILD_DIR}/%{name}-%{version} centos8 +export CFLAGS="${CFLAGS} -fPIC" && ${RPM_BUILD_DIR}/%{name}-%{version}/packaging/bundle-ebpf-co-re.sh ${RPM_BUILD_DIR}/%{name}-%{version} %endif %else export CFLAGS="${CFLAGS} -fPIC" && ${RPM_BUILD_DIR}/%{name}-%{version}/packaging/bundle-libbpf.sh ${RPM_BUILD_DIR}/%{name}-%{version} other +export CFLAGS="${CFLAGS} -fPIC" && ${RPM_BUILD_DIR}/%{name}-%{version}/packaging/bundle-ebpf-co-re.sh ${RPM_BUILD_DIR}/%{name}-%{version} %endif %endif @@ -249,6 +260,11 @@ autoreconf -ivf %if 0%{!?fedora:1} && 0%{!?suse_version:1} --with-bundled-libJudy \ %endif + %if 0%{?centos_ver:1} + %if %{centos_ver} < 8 + --with-bundled-protobuf \ + %endif + %endif --prefix="%{_prefix}" \ --sysconfdir="%{_sysconfdir}" \ --localstatedir="%{_localstatedir}" \ @@ -270,6 +286,10 @@ rm -rf "${RPM_BUILD_ROOT}" install -m 644 -p system/netdata.conf "${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}" +# ########################################################### +# Install updater script +install -m 755 -p packaging/installer/netdata-updater.sh "${RPM_BUILD_ROOT}%{_libexecdir}/%{name}/netdata-updater.sh" + # ########################################################### # logrotate settings install -m 755 -d "${RPM_BUILD_ROOT}%{_sysconfdir}/logrotate.d" @@ -497,7 +517,7 @@ rm -rf "${RPM_BUILD_ROOT}" # Enforce 0644 for files and 0755 for directories # for the netdata web directory -%defattr(0644,root,netdata,0755) +%defattr(0644,root,root,0755) %{_datadir}/%{name}/web # Enforce 0660 for files and 0770 for directories @@ -544,6 +564,8 @@ are sensor monitoring, system event monitoring, power control, and serial-over-L %attr(4750,root,netdata) %{_libexecdir}/%{name}/plugins.d/freeipmi.plugin %changelog +* Wed Feb 03 2022 Austin Hemmelgarn 0.0.0-16 +- Bundle updater script in native packages. * Mon Oct 11 2021 Austin Hemmelgarn 0.0.0-15 - Remove support code for legacy ACLK implementation. * Wed Sep 16 2020 Austin Hemmelgarn 0.0.0-14 diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index e3a98fdf2..000000000 --- a/package-lock.json +++ /dev/null @@ -1,6320 +0,0 @@ -{ - "requires": true, - "lockfileVersion": 1, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/core": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.0.tgz", - "integrity": "sha512-mkLq8nwaXmDtFmRkQ8ED/eA2CnVw4zr7dCztKalZXBvdK5EeNUAesrrwUqjQEzFgomJssayzB0aqlOsP1vGLqg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.0", - "@babel/helper-module-transforms": "^7.11.0", - "@babel/helpers": "^7.10.4", - "@babel/parser": "^7.11.0", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.11.0", - "@babel/types": "^7.11.0", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.19", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz", - "integrity": "sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==", - "dev": true, - "requires": { - "@babel/types": "^7.11.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", - "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", - "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz", - "integrity": "sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q==", - "dev": true, - "requires": { - "@babel/types": "^7.11.0" - } - }, - "@babel/helper-module-imports": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", - "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-module-transforms": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", - "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/template": "^7.10.4", - "@babel/types": "^7.11.0", - "lodash": "^4.17.19" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", - "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-replace-supers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", - "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.10.4", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-simple-access": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", - "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", - "dev": true, - "requires": { - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", - "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", - "dev": true, - "requires": { - "@babel/types": "^7.11.0" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", - "dev": true - }, - "@babel/helpers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", - "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", - "dev": true, - "requires": { - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.0.tgz", - "integrity": "sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw==", - "dev": true - }, - "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/traverse": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", - "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.0", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.11.0", - "@babel/types": "^7.11.0", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.19" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", - "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - }, - "@istanbuljs/schema": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", - "dev": true - }, - "@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "dev": true, - "requires": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - } - }, - "@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", - "dev": true - }, - "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "requires": { - "defer-to-connect": "^1.0.1" - } - }, - "@types/component-emitter": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz", - "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==", - "dev": true - }, - "@types/cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg==", - "dev": true - }, - "@types/cors": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.9.tgz", - "integrity": "sha512-zurD1ibz21BRlAOIKP8yhrxlqKx6L9VCwkB5kMiP6nZAhoF5MvC7qS1qPA7nRcr1GJolfkQC7/EAL4hdYejLtg==", - "dev": true - }, - "@types/node": { - "version": "14.14.22", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.22.tgz", - "integrity": "sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw==", - "dev": true - }, - "@types/unist": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", - "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==", - "dev": true - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "adverb-where": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/adverb-where/-/adverb-where-0.2.1.tgz", - "integrity": "sha512-IAveFBziMRMNPKFdWRcdIKaJvJG1cAfU9/tf9MzqQ84Dh4QjD9eqwnt4hNSt9cbrcEJD74BMIOaRVgVDEU7MwQ==", - "dev": true - }, - "aggregate-error": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", - "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - }, - "dependencies": { - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-differ": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", - "dev": true - }, - "array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", - "dev": true - }, - "array-iterate": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-1.1.4.tgz", - "integrity": "sha512-sNRaPGh9nnmdC8Zf+pT3UqP8rnWj5Hf9wiFGsX3wUQ2yVSIhO2ShFwCoceIPpB41QF6i2OEmrHmCo36xronCVA==", - "dev": true - }, - "array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "automated-readability": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/automated-readability/-/automated-readability-1.0.5.tgz", - "integrity": "sha512-N6mr0nUS0TB+SLHCrDYzLIdJQ1wklXNhsiKYh6tcrjDMlhjfz6BFGlDvngcpcBvZpko10jVjvF5XziJOxyA9Sg==", - "dev": true - }, - "bail": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", - "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "base64-arraybuffer": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", - "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=", - "dev": true - }, - "base64id": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", - "dev": true - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - } - } - }, - "call-me-maybe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "ccount": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.5.tgz", - "integrity": "sha512-MOli1W+nfbPLlKEhInaxhRdp7KVLFxLN5ykwzHgLsLI3H3gs5jjFAK4Eoj3OzzcxCtumDaI8onoVDeQyWaNTkw==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "character-entities": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", - "dev": true - }, - "character-entities-html4": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz", - "integrity": "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==", - "dev": true - }, - "character-entities-legacy": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", - "dev": true - }, - "character-reference-invalid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", - "dev": true - }, - "check-links": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/check-links/-/check-links-1.1.8.tgz", - "integrity": "sha512-lxt1EeQ1CVkmiZzPfbPufperYK0t7MvhdLs3zlRH9areA6NVT1tcGymAdJONolNWQBdCFU/sek59RpeLmVHCnw==", - "dev": true, - "requires": { - "got": "^9.6.0", - "is-relative-url": "^2.0.0", - "p-map": "^2.0.0", - "p-memoize": "^2.1.0" - } - }, - "chokidar": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.1.tgz", - "integrity": "sha512-TQTJyr2stihpC4Sya9hs2Xh+O2wf+igjL36Y75xx2WdHuiICcn/XJza46Jwt0eT5hVpQOzo3FpY3cj3RVYLX0g==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.4.0" - }, - "dependencies": { - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "co": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz", - "integrity": "sha1-TqVOpaCJOBUxheFSEMaNkJK8G3g=", - "dev": true - }, - "coffee-script": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.7.1.tgz", - "integrity": "sha1-YplqhheAx15tUGnROCJyO3NAS/w=", - "dev": true, - "requires": { - "mkdirp": "~0.3.5" - }, - "dependencies": { - "mkdirp": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", - "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", - "dev": true - } - } - }, - "coffeescript": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.5.1.tgz", - "integrity": "sha512-J2jRPX0eeFh5VKyVnoLrfVFgLZtnnmp96WQSLAS8OrLm2wtQLcnikYKe1gViJKDH7vucjuhHvBKKBP3rKcD1tQ==", - "dev": true - }, - "coleman-liau": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/coleman-liau/-/coleman-liau-1.0.5.tgz", - "integrity": "sha512-g4N/LvbIoGP7cq9E8QGrUWkHnhm9DXP0g1+axHIQnmQq/MwwPbBx5dGxQ0GbY5+ojibsIo1Rg0XuYkF+JPr7sw==", - "dev": true - }, - "collapse-white-space": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", - "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", - "dev": true - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "colors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", - "dev": true - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } - }, - "connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", - "dev": true, - "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } - }, - "cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", - "dev": true - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "cuss": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/cuss/-/cuss-1.20.0.tgz", - "integrity": "sha512-ca6Z5roeWhHgXeDLn0g3SLrG68Cb9922MvHme7Q/dz4XfwuxcBLalW4RqFUyZOiczzAqKc2XVtR2Kof+sIfinQ==", - "dev": true - }, - "custom-event": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", - "dev": true - }, - "dale-chall": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/dale-chall/-/dale-chall-1.0.4.tgz", - "integrity": "sha512-3Wp5GrsQVxw+KVXfZK9iA6W0jGnkq5uXXQ51Scofb92cbipkRvUZTaeQBr/6rlxdOezkjUGglV1euWIBOGCTRA==", - "dev": true - }, - "dale-chall-formula": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/dale-chall-formula/-/dale-chall-formula-1.0.5.tgz", - "integrity": "sha512-p7f37Bc6HkIUWDj/b/9r76qrXU7/yyR0lnp0Vmj0QjAG54KrFJbE8kVuPHdcKaCbwAFT8yNvCALMaajid/Mkfw==", - "dev": true - }, - "date-format": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz", - "integrity": "sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w==", - "dev": true - }, - "dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - }, - "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", - "dev": true - }, - "di": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", - "dev": true - }, - "dictionary-en-us": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dictionary-en-us/-/dictionary-en-us-2.2.1.tgz", - "integrity": "sha512-Z8mycV0ywTfjbUTi0JZfQHqBZhu4CYFtpf7KluSGpt3xHpFlal2S/hiK50tlPynOtR5K3pG5wCradnz1yxwOHA==", - "dev": true - }, - "dns-packet": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.2.1.tgz", - "integrity": "sha512-JHj2yJeKOqlxzeuYpN1d56GfhzivAxavNwHj9co3qptECel27B1rLY5PifJAvubsInX5pGLDjAHuCfCUc2Zv/w==", - "dev": true, - "requires": { - "ip": "^1.1.5" - } - }, - "dns-socket": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/dns-socket/-/dns-socket-4.2.1.tgz", - "integrity": "sha512-fNvDq86lS522+zMbh31X8cQzYQd6xumCNlxsuZF5TKxQThF/e+rJbVM6K8mmlsdcSm6yNjKJQq3Sf38viAJj8g==", - "dev": true, - "requires": { - "dns-packet": "^5.1.2" - } - }, - "dom-serialize": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", - "dev": true, - "requires": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" - } - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true - }, - "e-prime": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/e-prime/-/e-prime-0.10.4.tgz", - "integrity": "sha512-tzBmM2mFSnAq5BuxPSyin6qXb3yMe1wufJN7L7ZPcEWS5S+jI2dhKQEoqHVEcSMMXo/j5lcWpX5jzA6wLSmX6w==", - "dev": true - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "engine.io": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.2.tgz", - "integrity": "sha512-t5z6zjXuVLhXDMiFJPYsPOWEER8B0tIsD3ETgw19S1yg9zryvUfY3Vhtk3Gf4sihw/bQGIqQ//gjvVlu+Ca0bQ==", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.4.1", - "cors": "~2.8.5", - "debug": "~4.3.1", - "engine.io-parser": "~4.0.0", - "ws": "~7.4.2" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "engine.io-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz", - "integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==", - "dev": true, - "requires": { - "base64-arraybuffer": "0.1.4" - } - }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "eventemitter2": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", - "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", - "dev": true - }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", - "dev": true, - "requires": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - }, - "dependencies": { - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - } - } - }, - "fault": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", - "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", - "dev": true, - "requires": { - "format": "^0.2.0" - } - }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, - "findup-sync": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", - "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", - "dev": true, - "requires": { - "glob": "~5.0.0" - }, - "dependencies": { - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "fined": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", - "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "is-plain-object": "^2.0.3", - "object.defaults": "^1.1.0", - "object.pick": "^1.2.0", - "parse-filepath": "^1.0.1" - } - }, - "flagged-respawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", - "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", - "dev": true - }, - "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "flesch": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/flesch/-/flesch-1.0.5.tgz", - "integrity": "sha512-SE5X7jm4tp7sbKagLB0V9i0SrjWsFovus7db3E1nCyquy5249+Fyh+bBIK2crUuzX4maXn3Tu5bcMw8nF5oU8Q==", - "dev": true - }, - "fn-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fn-name/-/fn-name-2.0.1.tgz", - "integrity": "sha1-UhTXU3pNBqSjAcDMJi/rhBiAAuc=", - "dev": true - }, - "follow-redirects": { - "version": "1.14.7", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", - "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==", - "dev": true - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=", - "dev": true - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "gaze": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", - "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", - "dev": true, - "requires": { - "globule": "^1.0.0" - } - }, - "gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getobject": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", - "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=", - "dev": true - }, - "github-slugger": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.3.0.tgz", - "integrity": "sha512-gwJScWVNhFYSRDvURk/8yhcFBee6aFjye2a7Lhb2bUyRulpIoek9p0I9Kt7PT67d/nUlZbFu8L9RLiA0woQN8Q==", - "dev": true, - "requires": { - "emoji-regex": ">=6.0.0 <=6.1.1" - }, - "dependencies": { - "emoji-regex": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.1.1.tgz", - "integrity": "sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4=", - "dev": true - } - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "glob-to-regexp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", - "dev": true - }, - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "globule": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz", - "integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==", - "dev": true, - "requires": { - "glob": "~7.1.1", - "lodash": "~4.17.10", - "minimatch": "~3.0.2" - } - }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - } - }, - "graceful-fs": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", - "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=", - "dev": true - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "grunt": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.2.1.tgz", - "integrity": "sha512-zgJjn9N56tScvRt/y0+1QA+zDBnKTrkpyeSBqQPLcZvbqTD/oyGMrdZQXmm6I3828s+FmPvxc3Xv+lgKFtudOw==", - "dev": true, - "requires": { - "dateformat": "~3.0.3", - "eventemitter2": "~0.4.13", - "exit": "~0.1.2", - "findup-sync": "~0.3.0", - "glob": "~7.1.6", - "grunt-cli": "~1.3.2", - "grunt-known-options": "~1.1.0", - "grunt-legacy-log": "~2.0.0", - "grunt-legacy-util": "~1.1.1", - "iconv-lite": "~0.4.13", - "js-yaml": "~3.14.0", - "minimatch": "~3.0.4", - "mkdirp": "~1.0.4", - "nopt": "~3.0.6", - "rimraf": "~3.0.2" - }, - "dependencies": { - "grunt-cli": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.3.2.tgz", - "integrity": "sha512-8OHDiZZkcptxVXtMfDxJvmN7MVJNE8L/yIcPb4HB7TlyFD1kDvjHrb62uhySsU14wJx9ORMnTuhRMQ40lH/orQ==", - "dev": true, - "requires": { - "grunt-known-options": "~1.1.0", - "interpret": "~1.1.0", - "liftoff": "~2.5.0", - "nopt": "~4.0.1", - "v8flags": "~3.1.1" - }, - "dependencies": { - "nopt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", - "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", - "dev": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - } - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } - } - }, - "grunt-exec": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/grunt-exec/-/grunt-exec-3.0.0.tgz", - "integrity": "sha512-cgAlreXf3muSYS5LzW0Cc4xHK03BjFOYk0MqCQ/MZ3k1Xz2GU7D+IAJg4UKicxpO+XdONJdx/NJ6kpy2wI+uHg==", - "dev": true - }, - "grunt-known-options": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.1.tgz", - "integrity": "sha512-cHwsLqoighpu7TuYj5RonnEuxGVFnztcUqTqp5rXFGYL4OuPFofwC4Ycg7n9fYwvK6F5WbYgeVOwph9Crs2fsQ==", - "dev": true - }, - "grunt-legacy-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-2.0.0.tgz", - "integrity": "sha512-1m3+5QvDYfR1ltr8hjiaiNjddxGdQWcH0rw1iKKiQnF0+xtgTazirSTGu68RchPyh1OBng1bBUjLmX8q9NpoCw==", - "dev": true, - "requires": { - "colors": "~1.1.2", - "grunt-legacy-log-utils": "~2.0.0", - "hooker": "~0.2.3", - "lodash": "~4.17.5" - } - }, - "grunt-legacy-log-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.0.1.tgz", - "integrity": "sha512-o7uHyO/J+i2tXG8r2bZNlVk20vlIFJ9IEYyHMCQGfWYru8Jv3wTqKZzvV30YW9rWEjq0eP3cflQ1qWojIe9VFA==", - "dev": true, - "requires": { - "chalk": "~2.4.1", - "lodash": "~4.17.10" - } - }, - "grunt-legacy-util": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.1.1.tgz", - "integrity": "sha512-9zyA29w/fBe6BIfjGENndwoe1Uy31BIXxTH3s8mga0Z5Bz2Sp4UCjkeyv2tI449ymkx3x26B+46FV4fXEddl5A==", - "dev": true, - "requires": { - "async": "~1.5.2", - "exit": "~0.1.1", - "getobject": "~0.1.0", - "hooker": "~0.2.3", - "lodash": "~4.17.10", - "underscore.string": "~3.3.4", - "which": "~1.3.0" - } - }, - "gunning-fog": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/gunning-fog/-/gunning-fog-1.0.6.tgz", - "integrity": "sha512-yXkDi7mbWTPiITTztwhwXFMhXKnMviX/7kprz92BroMJbB/AgDATrHCRCtc87Ox024pQy2kMCihsm7tPonvV6A==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "requires": { - "parse-passwd": "^1.0.0" - } - }, - "hooker": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", - "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", - "dev": true - }, - "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", - "dev": true - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", - "dev": true - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, - "ip-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.1.0.tgz", - "integrity": "sha512-pKnZpbgCTfH/1NLIlOduP/V+WRXzC2MOz3Qo8xmxk8C5GudJLgK5QyLVXOSWy3ParAH7Eemurl3xjv/WXYFvMA==", - "dev": true - }, - "irregular-plurals": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-2.0.0.tgz", - "integrity": "sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw==", - "dev": true - }, - "is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "requires": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - } - }, - "is-absolute-url": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", - "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", - "dev": true - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", - "dev": true - }, - "is-alphanumeric": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz", - "integrity": "sha1-Spzvcdr0wAHB2B1j0UDPU/1oifQ=", - "dev": true - }, - "is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", - "dev": true, - "requires": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-docker": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", - "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", - "dev": true - }, - "is-empty": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-empty/-/is-empty-1.2.0.tgz", - "integrity": "sha1-3pu1snhzigWgsJpX4ftNSjQan2s=", - "dev": true - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - }, - "is-hexadecimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", - "dev": true - }, - "is-hidden": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-hidden/-/is-hidden-1.1.3.tgz", - "integrity": "sha512-FFzhGKA9h59OFxeaJl0W5ILTYetI8WsdqdofKr69uLKZdV6hbDKxj8vkpG3L9uS/6Q/XYh1tkXm6xwRGFweETA==", - "dev": true - }, - "is-ip": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-3.1.0.tgz", - "integrity": "sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==", - "dev": true, - "requires": { - "ip-regex": "^4.0.0" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", - "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=", - "dev": true - }, - "is-online": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/is-online/-/is-online-8.4.0.tgz", - "integrity": "sha512-i0qGRbtUaQEU5Z7O3LmOnH3yorhG1lnygqY2cv3InlQKKm3nx6XiGXZk49lATR3N7hyxoiuHMR0pKwRuB+s5lg==", - "dev": true, - "requires": { - "got": "^9.6.0", - "p-any": "^2.0.0", - "p-timeout": "^3.0.0", - "public-ip": "^4.0.1" - } - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "requires": { - "is-unc-path": "^1.0.0" - } - }, - "is-relative-url": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-relative-url/-/is-relative-url-2.0.0.tgz", - "integrity": "sha1-cpAtf+BLPUeS59sV+duEtyBMnO8=", - "dev": true, - "requires": { - "is-absolute-url": "^2.0.0" - } - }, - "is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "requires": { - "unc-path-regex": "^0.1.2" - } - }, - "is-whitespace-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", - "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-word-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", - "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", - "dev": true - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "requires": { - "is-docker": "^2.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isbinaryfile": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.6.tgz", - "integrity": "sha512-ORrEy+SNVqUhrCaal4hA4fBzhggQQ+BaLntyPOdoEiwlKZW9BZiJXjg3RMiruE4tPEI3pyVPpySHQF/dKWperg==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "requires": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - } - }, - "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jasmine": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.6.1.tgz", - "integrity": "sha512-Jqp8P6ZWkTVFGmJwBK46p+kJNrZCdqkQ4GL+PGuBXZwK1fM4ST9BizkYgIwCFqYYqnTizAy6+XG2Ej5dFrej9Q==", - "dev": true, - "requires": { - "fast-glob": "^2.2.6", - "jasmine-core": "~3.6.0" - } - }, - "jasmine-core": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.6.0.tgz", - "integrity": "sha512-8uQYa7zJN8hq9z+g8z1bqCfdC8eoDAeVnM5sfqs7KHv9/ifoJ500m018fpFc7RDaO6SWCLCXwo/wPSNcdYTgcw==", - "dev": true - }, - "jasmine-growl-reporter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jasmine-growl-reporter/-/jasmine-growl-reporter-2.0.0.tgz", - "integrity": "sha512-RYwVfPaGgxQQSHDOt6jQ99/KAkFQ/Fiwg/AzBS+uO9A4UhGhxb7hwXaUUSU/Zs0MxBoFNqmIRC+7P4/+5O3lXg==", - "dev": true, - "requires": { - "growl": "^1.10.5" - } - }, - "jasmine-node": { - "version": "github:BrainDoctor/jasmine-node#eac79306acaf016256cdd5824003d99db053f722", - "from": "github:BrainDoctor/jasmine-node", - "dev": true, - "requires": { - "coffee-script": "~1.7.1", - "gaze": "~0.5.1", - "grunt-exec": "~0.4.5", - "jasmine-growl-reporter": "~0.2.0", - "jasmine-reporters": "~2.0.6", - "minimist": "~0.0.8", - "mkdirp": "~0.3.5", - "underscore": "~1.6.0", - "walkdir": "~0.0.7", - "xml2js": "~0.4.1" - }, - "dependencies": { - "gaze": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", - "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=", - "dev": true, - "requires": { - "globule": "~0.1.0" - } - }, - "glob": { - "version": "3.1.21", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", - "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", - "dev": true, - "requires": { - "graceful-fs": "~1.2.0", - "inherits": "1", - "minimatch": "~0.2.11" - } - }, - "globule": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", - "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=", - "dev": true, - "requires": { - "glob": "~3.1.21", - "lodash": "~1.0.1", - "minimatch": "~0.2.11" - } - }, - "growl": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.7.0.tgz", - "integrity": "sha1-3i1mE20ALhErpw8/EMMc98NQsto=", - "dev": true - }, - "grunt-exec": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/grunt-exec/-/grunt-exec-0.4.7.tgz", - "integrity": "sha1-QAUf+k6wyWV+BTuV6I1ENSocLCU=", - "dev": true - }, - "inherits": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", - "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=", - "dev": true - }, - "jasmine-growl-reporter": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/jasmine-growl-reporter/-/jasmine-growl-reporter-0.2.1.tgz", - "integrity": "sha1-1fCje5L2qD/VxkgrgJSVyQqLVf4=", - "dev": true, - "requires": { - "growl": "~1.7.0" - } - }, - "jasmine-reporters": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/jasmine-reporters/-/jasmine-reporters-2.0.8.tgz", - "integrity": "sha1-XLMn1yRFAqGHzuxml+WmJvgMNbo=", - "dev": true, - "requires": { - "mkdirp": "~0.3.5" - } - }, - "lodash": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", - "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=", - "dev": true - }, - "minimatch": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", - "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", - "dev": true, - "requires": { - "lru-cache": "2", - "sigmund": "~1.0.0" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", - "dev": true - }, - "mkdirp": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", - "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", - "dev": true - }, - "underscore": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", - "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=", - "dev": true - }, - "walkdir": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.0.12.tgz", - "integrity": "sha512-HFhaD4mMWPzFSqhpyDG48KDdrjfn409YQuVW7ckZYhW4sE87mYtWifdB/+73RA7+p4s4K18n5Jfx1kHthE1gBw==", - "dev": true - } - } - }, - "jasmine-reporters": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/jasmine-reporters/-/jasmine-reporters-2.3.2.tgz", - "integrity": "sha512-u/7AT9SkuZsUfFBLLzbErohTGNsEUCKaQbsVYnLFW1gEuL2DzmBL4n8v90uZsqIqlWvWUgian8J6yOt5Fyk/+A==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1", - "xmldom": "^0.1.22" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true, - "optional": true - } - } - }, - "karma": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.0.2.tgz", - "integrity": "sha512-GBm8vPkQvjJL1ye//iH6yk9ROHOW+1TaFzRvbc6TbbCOFszbEG66dyDMoFjMMTAHy0ERNqRrMHap/LEHWeijNA==", - "dev": true, - "requires": { - "body-parser": "^1.19.0", - "braces": "^3.0.2", - "chokidar": "^3.4.2", - "colors": "^1.4.0", - "connect": "^3.7.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.1", - "glob": "^7.1.6", - "graceful-fs": "^4.2.4", - "http-proxy": "^1.18.1", - "isbinaryfile": "^4.0.6", - "lodash": "^4.17.19", - "log4js": "^6.2.1", - "mime": "^2.4.5", - "minimatch": "^3.0.4", - "qjobs": "^1.2.0", - "range-parser": "^1.2.1", - "rimraf": "^3.0.2", - "socket.io": "^3.0.4", - "source-map": "^0.6.1", - "tmp": "0.2.1", - "ua-parser-js": "^0.7.23", - "yargs": "^16.1.1" - }, - "dependencies": { - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - } - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.1.tgz", - "integrity": "sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw==", - "dev": true, - "optional": true - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "karma-chrome-launcher": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz", - "integrity": "sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg==", - "dev": true, - "requires": { - "which": "^1.2.1" - } - }, - "karma-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.0.3.tgz", - "integrity": "sha512-atDvLQqvPcLxhED0cmXYdsPMCQuh6Asa9FMZW1bhNqlVEhJoB9qyZ2BY1gu7D/rr5GLGb5QzYO4siQskxaWP/g==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.1", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.0", - "minimatch": "^3.0.4" - } - }, - "karma-firefox-launcher": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-1.3.0.tgz", - "integrity": "sha512-Fi7xPhwrRgr+94BnHX0F5dCl1miIW4RHnzjIGxF8GaIEp7rNqX7LSi7ok63VXs3PS/5MQaQMhGxw+bvD+pibBQ==", - "dev": true, - "requires": { - "is-wsl": "^2.1.0" - } - }, - "karma-jasmine": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-2.0.1.tgz", - "integrity": "sha512-iuC0hmr9b+SNn1DaUD2QEYtUxkS1J+bSJSn7ejdEexs7P8EYvA1CWkEdrDQ+8jVH3AgWlCNwjYsT1chjcNW9lA==", - "dev": true, - "requires": { - "jasmine-core": "^3.3" - } - }, - "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "requires": { - "json-buffer": "3.0.0" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "levenshtein-edit-distance": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/levenshtein-edit-distance/-/levenshtein-edit-distance-1.0.0.tgz", - "integrity": "sha1-iVuvR4zOi1waDSfkXXwdl4pmHkk=", - "dev": true - }, - "liftoff": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", - "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", - "dev": true, - "requires": { - "extend": "^3.0.0", - "findup-sync": "^2.0.0", - "fined": "^1.0.1", - "flagged-respawn": "^1.0.0", - "is-plain-object": "^2.0.4", - "object.map": "^1.0.0", - "rechoir": "^0.6.2", - "resolve": "^1.1.7" - }, - "dependencies": { - "findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^3.1.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - } - } - }, - "load-plugin": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/load-plugin/-/load-plugin-2.3.1.tgz", - "integrity": "sha512-dYB1lbwqHgPTrruy9glukCu8Ya9vzj6TMfouCtj2H/GuJ+8syioisgKTBPxnCi6m8K8jINKfTOxOHngFkUYqHw==", - "dev": true, - "requires": { - "npm-prefix": "^1.2.0", - "resolve-from": "^5.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=", - "dev": true - }, - "lodash.intersection": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.intersection/-/lodash.intersection-4.4.0.tgz", - "integrity": "sha1-ChG6Yx0OlcI8fy9Mu5ppLtF45wU=", - "dev": true - }, - "log4js": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.3.0.tgz", - "integrity": "sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw==", - "dev": true, - "requires": { - "date-format": "^3.0.0", - "debug": "^4.1.1", - "flatted": "^2.0.1", - "rfdc": "^1.1.4", - "streamroller": "^2.2.4" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "longest-streak": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", - "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", - "dev": true - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true - }, - "lru-cache": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", - "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", - "dev": true - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, - "make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dev": true, - "requires": { - "p-defer": "^1.0.0" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "markdown-escapes": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", - "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", - "dev": true - }, - "markdown-extensions": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-1.1.1.tgz", - "integrity": "sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==", - "dev": true - }, - "markdown-table": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", - "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", - "dev": true - }, - "match-casing": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/match-casing/-/match-casing-1.0.3.tgz", - "integrity": "sha512-oMyC3vUVCFbGu+M2Zxl212LPJThcaw7QxB5lFuJPQCgV/dsGBP0yZeCoLmX6CiBkoBcVbAKDJZrBpJVu0XcLMw==", - "dev": true - }, - "mdast-comment-marker": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/mdast-comment-marker/-/mdast-comment-marker-1.1.2.tgz", - "integrity": "sha512-vTFXtmbbF3rgnTh3Zl3irso4LtvwUq/jaDvT2D1JqTGAwaipcS7RpTxzi6KjoRqI9n2yuAhzLDAC8xVTF3XYVQ==", - "dev": true - }, - "mdast-util-compact": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.4.tgz", - "integrity": "sha512-3YDMQHI5vRiS2uygEFYaqckibpJtKq5Sj2c8JioeOQBU6INpKbdWzfyLqFFnDwEcEnRFIdMsguzs5pC1Jp4Isg==", - "dev": true, - "requires": { - "unist-util-visit": "^1.1.0" - } - }, - "mdast-util-heading-style": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/mdast-util-heading-style/-/mdast-util-heading-style-1.0.6.tgz", - "integrity": "sha512-8ZuuegRqS0KESgjAGW8zTx4tJ3VNIiIaGFNEzFpRSAQBavVc7AvOo9I4g3crcZBfYisHs4seYh0rAVimO6HyOw==", - "dev": true - }, - "mdast-util-to-nlcst": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/mdast-util-to-nlcst/-/mdast-util-to-nlcst-3.2.3.tgz", - "integrity": "sha512-hPIsgEg7zCvdU6/qvjcR6lCmJeRuIEpZGY5xBV+pqzuMOvQajyyF8b6f24f8k3Rw8u40GwkI3aAxUXr3bB2xag==", - "dev": true, - "requires": { - "nlcst-to-string": "^2.0.0", - "repeat-string": "^1.5.2", - "unist-util-position": "^3.0.0", - "vfile-location": "^2.0.0" - } - }, - "mdast-util-to-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", - "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==", - "dev": true - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - }, - "dependencies": { - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - } - } - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "mime": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.0.tgz", - "integrity": "sha512-ft3WayFSFUVBuJj7BMLKAQcSlItKtfjsKDDsii3rqFDAZ7t11zRe8ASw/GlmivGwVUYtwkQrxiGGpL6gFvB0ag==", - "dev": true - }, - "mime-db": { - "version": "1.45.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", - "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==", - "dev": true - }, - "mime-types": { - "version": "2.1.28", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", - "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", - "dev": true, - "requires": { - "mime-db": "1.45.0" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true - }, - "nlcst-is-literal": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/nlcst-is-literal/-/nlcst-is-literal-1.2.1.tgz", - "integrity": "sha512-abNv1XY7TUoyLn5kSSorMIYHfRvVfXbgftNFNvEMiQQkyKteLdjrGuDqEMMyK70sMbn7uPA6oUbRvykM6pg+pg==", - "dev": true, - "requires": { - "nlcst-to-string": "^2.0.0" - } - }, - "nlcst-normalize": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/nlcst-normalize/-/nlcst-normalize-2.1.4.tgz", - "integrity": "sha512-dWJ3XUoAoWoau24xOM59Y1FPozv7DyYWy+rdUaXj9Ow0hBCVuwqDQbXzTF7H+HskyTVpTkRPXYPu4YsMEScmRw==", - "dev": true, - "requires": { - "nlcst-to-string": "^2.0.0" - } - }, - "nlcst-search": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/nlcst-search/-/nlcst-search-1.5.1.tgz", - "integrity": "sha512-G3ws0fgNlVsUvHvA2G1PTjyxzGOJ0caI0+WOvlZzev5iSUTX+R1q4lnlL4Y7E+he4ZMUW/0FMn9rYwdYon/13g==", - "dev": true, - "requires": { - "nlcst-is-literal": "^1.1.0", - "nlcst-normalize": "^2.1.0", - "unist-util-visit": "^1.0.0" - } - }, - "nlcst-to-string": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-2.0.4.tgz", - "integrity": "sha512-3x3jwTd6UPG7vi5k4GEzvxJ5rDA7hVUIRNHPblKuMVP9Z3xmlsd9cgLcpAMkc5uPOBna82EeshROFhsPkbnTZg==", - "dev": true - }, - "no-cliches": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/no-cliches/-/no-cliches-0.2.2.tgz", - "integrity": "sha512-iEOqDAOFl6uN5jZGRj39Jdo8qALzf2HPXtpFso8+BMaDylDrUMYMwhFbfYGgxdnMlsRnxYTwv68kaXEpsHIapg==", - "dev": true - }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "normalize-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/normalize-strings/-/normalize-strings-1.1.0.tgz", - "integrity": "sha1-skp17UgXY5RAT3Rkm1y4BA6JmnU=", - "dev": true - }, - "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", - "dev": true - }, - "npm-prefix": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/npm-prefix/-/npm-prefix-1.2.0.tgz", - "integrity": "sha1-5hlFX3B0ulTMZtbQ033Z8b5ry8A=", - "dev": true, - "requires": { - "rc": "^1.1.0", - "shellsubstitute": "^1.1.0", - "untildify": "^2.1.0" - } - }, - "nspell": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/nspell/-/nspell-2.1.2.tgz", - "integrity": "sha512-j79L4A5aJSiswMUJ/6BW8+7ytgBUVce5BJX6xq8LtvKQpU96CMB340/yMeREH9U+gB/8dk4ctTn62DLiPMAXsA==", - "dev": true, - "requires": { - "is-buffer": "^2.0.0" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "number-to-words": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/number-to-words/-/number-to-words-1.2.4.tgz", - "integrity": "sha512-/fYevVkXRcyBiZDg6yzZbm0RuaD6i0qRfn8yr+6D0KgBMOndFPxuW10qCHpzs50nN8qKuv78k8MuotZhcVX6Pw==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", - "dev": true, - "requires": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "object.map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "p-any": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-any/-/p-any-2.1.0.tgz", - "integrity": "sha512-JAERcaMBLYKMq+voYw36+x5Dgh47+/o7yuv2oQYuSSUml4YeqJEFznBrY2UeEkoSHqBua6hz518n/PsowTYLLg==", - "dev": true, - "requires": { - "p-cancelable": "^2.0.0", - "p-some": "^4.0.0", - "type-fest": "^0.3.0" - }, - "dependencies": { - "p-cancelable": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz", - "integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==", - "dev": true - } - } - }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true - }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-memoize": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-memoize/-/p-memoize-2.1.0.tgz", - "integrity": "sha512-c6+a2iV4JyX0r4+i2IBJYO0r6LZAT2fg/tcB6GQbv1uzZsfsmKT7Ej5DRT1G6Wi7XUJSV2ZiP9+YEtluvhCmkg==", - "dev": true, - "requires": { - "mem": "^4.0.0", - "mimic-fn": "^1.0.0" - } - }, - "p-some": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-some/-/p-some-4.1.0.tgz", - "integrity": "sha512-MF/HIbq6GeBqTrTIl5OJubzkGU+qfFhAFi0gnTAK6rgEIJIknEiABHOTtQu4e6JiXjIwuMPMUFQzyHh5QjCl1g==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0", - "p-cancelable": "^2.0.0" - }, - "dependencies": { - "p-cancelable": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz", - "integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==", - "dev": true - } - } - }, - "p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "dev": true, - "requires": { - "p-finally": "^1.0.0" - } - }, - "parse-english": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/parse-english/-/parse-english-4.1.3.tgz", - "integrity": "sha512-IQl1v/ik9gw437T8083coohMihae0rozpc7JYC/9h6hi9xKBSxFwh5HWRpzVC2ZhEs2nUlze2aAktpNBJXdJKA==", - "dev": true, - "requires": { - "nlcst-to-string": "^2.0.0", - "parse-latin": "^4.0.0", - "unist-util-modify-children": "^1.0.0", - "unist-util-visit-children": "^1.0.0" - } - }, - "parse-entities": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", - "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", - "dev": true, - "requires": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - } - }, - "parse-filepath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "map-cache": "^0.2.0", - "path-root": "^0.1.1" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "parse-latin": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-4.2.1.tgz", - "integrity": "sha512-7T9g6mIsFFpLlo0Zzb2jLWdCt+H9Qtf/hRmMYFi/Mq6Ovi+YKo+AyDFX3OhFfu0vXX5Nid9FKJGKSSzNcTkWiA==", - "dev": true, - "requires": { - "nlcst-to-string": "^2.0.0", - "unist-util-modify-children": "^1.0.0", - "unist-util-visit-children": "^1.0.0" - } - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "passive-voice": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/passive-voice/-/passive-voice-0.1.0.tgz", - "integrity": "sha1-Fv+RrkC6DpLEPmcXY/3IQqcCcLE=", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", - "dev": true, - "requires": { - "path-root-regex": "^0.1.0" - } - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", - "dev": true - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "plur": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/plur/-/plur-3.1.1.tgz", - "integrity": "sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w==", - "dev": true, - "requires": { - "irregular-plurals": "^2.0.0" - } - }, - "pluralize": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", - "dev": true - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true - }, - "propose": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/propose/-/propose-0.0.5.tgz", - "integrity": "sha1-SKBl2ex9TIZn9AULFcSi2F28pWs=", - "dev": true, - "requires": { - "levenshtein-edit-distance": "^1.0.0" - } - }, - "public-ip": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/public-ip/-/public-ip-4.0.2.tgz", - "integrity": "sha512-ZHqUjaYT/+FuSiy5/o2gBxvj0PF7M3MXGnaLJBsJNMCyXI4jzuXXHJKrk0gDxx1apiF/jYsBwjTQOM9V8G6oCQ==", - "dev": true, - "requires": { - "dns-socket": "^4.2.1", - "got": "^9.6.0", - "is-ip": "^3.1.0" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "qjobs": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", - "dev": true - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true - }, - "quotation": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/quotation/-/quotation-1.1.3.tgz", - "integrity": "sha512-45gUgmX/RtQOQV1kwM06boP49OYXcKCPrYwdmAvs5YqkpiobhNKKwo524JM6Ma0ko3oN9tXNcWs9+ABq3Ry7YA==", - "dev": true - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", - "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "^1.1.6" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remark": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/remark/-/remark-11.0.2.tgz", - "integrity": "sha512-bh+eJgn8wgmbHmIBOuwJFdTVRVpl3fcVP6HxmpPWO0ULGP9Qkh6INJh0N5Uy7GqlV7DQYGoqaKiEIpM5LLvJ8w==", - "dev": true, - "requires": { - "remark-parse": "^7.0.0", - "remark-stringify": "^7.0.0", - "unified": "^8.2.0" - } - }, - "remark-cli": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/remark-cli/-/remark-cli-7.0.1.tgz", - "integrity": "sha512-CUjBLLSbEay0mNwOO+pptnLIoS8UB6cHlhZVpTRKbtbIcw6YEzEfD7jGjW1HCA8lZK87IfY3/DuWE6DlXu+hfg==", - "dev": true, - "requires": { - "markdown-extensions": "^1.1.0", - "remark": "^11.0.0", - "unified-args": "^7.0.0" - } - }, - "remark-frontmatter": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-1.3.3.tgz", - "integrity": "sha512-fM5eZPBvu2pVNoq3ZPW22q+5Ativ1oLozq2qYt9I2oNyxiUd/tDl0iLLntEVAegpZIslPWg1brhcP1VsaSVUag==", - "dev": true, - "requires": { - "fault": "^1.0.1", - "xtend": "^4.0.1" - } - }, - "remark-lint": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-6.0.6.tgz", - "integrity": "sha512-JBY6zz5fYQFN724Vq6VeiHwhyjVIlrww/dE1+hWGcDyUuz7YNCqwZKwBdQGDvslICkzHw/wEExNEb8D4PNiLlA==", - "dev": true, - "requires": { - "remark-message-control": "^4.0.0" - } - }, - "remark-lint-blockquote-indentation": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-1.0.4.tgz", - "integrity": "sha512-ExcDP7lufshEBNkVddSHa+Bz/97PtFstIniQ8ZF2TahHPmpx92z3mkI/nXL2Qt5d3B09eTVvh4Pvhgp6x2470g==", - "dev": true, - "requires": { - "mdast-util-to-string": "^1.0.2", - "plur": "^3.0.0", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-checkbox-character-style": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-checkbox-character-style/-/remark-lint-checkbox-character-style-1.0.4.tgz", - "integrity": "sha512-tpuOtk7URmE6EIBgqklB4iCl00GabkemqEUFWxt69IIzG8bFjebiXrYh5BYIewIVQkOwiSDMsCbHdzYnXxgz0g==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1", - "vfile-location": "^2.0.1" - } - }, - "remark-lint-code-block-style": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-code-block-style/-/remark-lint-code-block-style-1.0.4.tgz", - "integrity": "sha512-Wq5F94nkaWTx8W/9C/ydG+DhVWLirBrWb0xnoMQ0cHnizAd3BWw8g0x5L7yglMYSUSVLWY0jfMHgOe9UW3JfTw==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-definition-case": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-definition-case/-/remark-lint-definition-case-1.0.5.tgz", - "integrity": "sha512-iirq74fKhJZsFw7x4FJuLVRkXclntutG1YKajfLaE3Gm14YlJWBEoabNTk+ENR4QXoB9rTdEqn3Cc3ImO8qciQ==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.4.0" - } - }, - "remark-lint-definition-spacing": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-definition-spacing/-/remark-lint-definition-spacing-1.0.5.tgz", - "integrity": "sha512-ss8OQmK4c/1amEAJpDjkFiByLyXpsYFNzmk6rEZQkxZZd+DVHI0oF+CzSeMVHu48rF2qHOkKhVghqrCM0vleAA==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.4.0" - } - }, - "remark-lint-emphasis-marker": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-emphasis-marker/-/remark-lint-emphasis-marker-1.0.4.tgz", - "integrity": "sha512-TdYISSw7Ib6EJDApDj9zcZNDCJEaEoQIrYS3+QH2TQxoDx96B0t1bbErRM5L/hx1UWPBpeFLKpgIWL163eMmYA==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-fenced-code-flag": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-1.0.4.tgz", - "integrity": "sha512-bkQvlEYco6ZzdzvGPrY7DBsqSq/2mZEmdhpn0KdMEZ9kcKJP4unQdVQys04SKnf9QISqQ446VnQj5Q4E3HMSkQ==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-fenced-code-marker": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-1.0.4.tgz", - "integrity": "sha512-aJF4ISIEvK3NX+C2rN93QoS/32SSiytQKRSeGa+HwsAn3sTwqmy2IoAwbFeZIZA2vqKcVB4h1b9yKamSlfX30Q==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-file-extension": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-file-extension/-/remark-lint-file-extension-1.0.5.tgz", - "integrity": "sha512-oVQdf5vEomwHkfQ7R/mgmsWW2H/t9kSvnrxtVoNOHr+qnOEafKKDn+AFhioN2kqtjCZBAjSSrePs6xGKmXKDTw==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0" - } - }, - "remark-lint-final-definition": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-final-definition/-/remark-lint-final-definition-1.0.4.tgz", - "integrity": "sha512-y9aDZPhqWcI7AtrJtL69HE6MoWMqDqLQUyWMadzAYUYb9/m4ciLdygJ4cWVpEN3n4mkBepHIsWzASaKHHBDJOQ==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-final-newline": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-1.0.5.tgz", - "integrity": "sha512-rfLlW8+Fz2dqnaEgU4JwLA55CQF1T4mfSs/GwkkeUCGPenvEYwSkCN2KO2Gr1dy8qPoOdTFE1rSufLjmeTW5HA==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0" - } - }, - "remark-lint-hard-break-spaces": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-1.0.5.tgz", - "integrity": "sha512-Rss7ujNtxipO/hasWYc0QdiO8D5VyliSwj3zAZ8GeDn0ix2KH+pY4/AJC7i9IGcVVbUGvvXLpJB3Pp1VeY7oKw==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-heading-increment": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-heading-increment/-/remark-lint-heading-increment-1.0.4.tgz", - "integrity": "sha512-3PJj32G7W1OUyRVSZiZbSOxyFAsw/mNssIosS9G8+6Lq2yeTSMDoCJy0+LC+s00nORFcbzeMedMK5U/eLbDe4w==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-heading-style": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-heading-style/-/remark-lint-heading-style-1.0.4.tgz", - "integrity": "sha512-ASssbw0vj9urTMxDJGpOn4K7d9MgPQPJGaCD+7v7je42krofvqC4CxpYvO/fOAkRZcttE91VfFHxkaPjiBtQLw==", - "dev": true, - "requires": { - "mdast-util-heading-style": "^1.0.2", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-heading-whitespace": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-heading-whitespace/-/remark-lint-heading-whitespace-1.0.0.tgz", - "integrity": "sha512-DykoBIXNbkihg64D+mztSOv3l82RTH4tIZW/HUB4QM4NpIEB+pVIPQpCYD0K4pTgvKiwoqsj4NY8qJ1EhNHAmQ==", - "dev": true, - "requires": { - "mdast-util-to-string": "^1.0.4", - "unified-lint-rule": "^1.0.2", - "unist-util-visit": "^1.3.0" - } - }, - "remark-lint-link-title-style": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-link-title-style/-/remark-lint-link-title-style-1.0.5.tgz", - "integrity": "sha512-Nu0cKj220q/PmUzELhYRUR2uxXabWuFJq9sApkgsc59uh+NKDtCEdpxkx7Zwvn6kUEwpuQVimeRfdesiKxX52g==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1", - "vfile-location": "^2.0.1" - } - }, - "remark-lint-list-item-bullet-indent": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-1.0.4.tgz", - "integrity": "sha512-SqhAmVFkeFQYP5I1qztCi2rfhLWwfSvia3DZ56sz9+h1pMqWIj3FmWRueY36xrnQo3LxsLljM5atI7AJBWxQEw==", - "dev": true, - "requires": { - "plur": "^3.0.0", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-list-item-content-indent": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-content-indent/-/remark-lint-list-item-content-indent-1.0.4.tgz", - "integrity": "sha512-zfEeAayZjEKkPr07fnhkGLENxOhnm0WZJTj6UBIXhtGu7rX23WNKSZaiou8iUoHxcO6ySCvIUJAEmq/XN1FxkQ==", - "dev": true, - "requires": { - "plur": "^3.0.0", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-list-item-indent": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-1.0.5.tgz", - "integrity": "sha512-DjRgxjqaVMrnlQFJypizTPtLa9gSM5ad0LVIFDSstV2UVXSgpBi2+bSsFJEXb4Fkjo/d2JAgt27UhzhcoF2lnw==", - "dev": true, - "requires": { - "plur": "^3.0.0", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-list-item-spacing": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-spacing/-/remark-lint-list-item-spacing-1.1.4.tgz", - "integrity": "sha512-zZELzTPYCoOCnOWh/nYTfQWnGXWg4/I5KpwrjBqe7WYwoMtvLVU9mqjRj2jHEbmirEXas54NZnYnkCoIBMS4bw==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-maximum-heading-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-maximum-heading-length/-/remark-lint-maximum-heading-length-1.0.4.tgz", - "integrity": "sha512-dhDBnUFXMuHoW8LSV/VICJAJO+wWumnvuu3ND7MJquCYrsjX2vcRmJXL5cusJSY4yqPosKlOowIkzdV5B6/SDQ==", - "dev": true, - "requires": { - "mdast-util-to-string": "^1.0.2", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-maximum-line-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/remark-lint-maximum-line-length/-/remark-lint-maximum-line-length-1.2.2.tgz", - "integrity": "sha512-ItAdjK+tUhqggqFvtAJ8iJ0MbBgShLl0HDgpG3In0QSYp/dmofO77DjvRjCJQo1pQYS8/LwlBii9cqg/3MwFfA==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.4.0" - } - }, - "remark-lint-no-auto-link-without-protocol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-1.0.4.tgz", - "integrity": "sha512-dhDHQLeaI79p7SRoKfxJ9c8J5otQsGua7ILeNbs2Onzn46/tp9ir6zjq3Lfh4VJJr4OVign2e8u+MzXsS7Uu/A==", - "dev": true, - "requires": { - "mdast-util-to-string": "^1.0.2", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-no-blockquote-without-marker": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-2.0.4.tgz", - "integrity": "sha512-a5LFGj7It2z7aBRGaAcztk4D2pax2b7dK9iOarIWv/JBus/PSjZJxzZCma2aAAOQhv3wbNTwqQwuQC0UJHMbPg==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1", - "vfile-location": "^2.0.1" - } - }, - "remark-lint-no-consecutive-blank-lines": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-1.0.4.tgz", - "integrity": "sha512-33rYrp+3OQ2UjG2/xhctruCvkP2iKLuHJhoUOAUV3BGwqJjAB+xNOl+0DdvDo0fxh5dyZuNesBuos3xr2yVR+w==", - "dev": true, - "requires": { - "plur": "^3.0.0", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-no-dead-urls": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-dead-urls/-/remark-lint-no-dead-urls-0.5.0.tgz", - "integrity": "sha512-wMr1+7Sh5rRGF9hmF9iyajRNQfA2BnADc9myYjpRxsYozRDj6p2ddVwBh76loUKwCZ64sLRKamyhMDwQ0NIdYA==", - "dev": true, - "requires": { - "check-links": "^1.1.7", - "is-online": "^8.2.0", - "unified-lint-rule": "^1.0.4", - "unist-util-visit": "^2.0.0" - }, - "dependencies": { - "unist-util-is": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", - "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==", - "dev": true - }, - "unist-util-visit": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", - "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", - "dev": true, - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0", - "unist-util-visit-parents": "^3.0.0" - } - }, - "unist-util-visit-parents": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.0.tgz", - "integrity": "sha512-0g4wbluTF93npyPrp/ymd3tCDTMnP0yo2akFD2FIBAYXq/Sga3lwaU1D8OYKbtpioaI6CkDcQ6fsMnmtzt7htw==", - "dev": true, - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0" - } - } - } - }, - "remark-lint-no-duplicate-definitions": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-1.0.6.tgz", - "integrity": "sha512-0biPtjVtGLRTN+ie7TzJpvKBau6sqkuQsQtuD07M0NSOmSvSU4vXUeOW73O5Q5xM3i6sYVESe+opaPefD3zEoA==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-stringify-position": "^2.0.0", - "unist-util-visit": "^1.4.0" - } - }, - "remark-lint-no-duplicate-headings": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-headings/-/remark-lint-no-duplicate-headings-1.0.5.tgz", - "integrity": "sha512-4GKPxhKpN797V/6Jg1K4Zwqq+PhsjC633+wQMrZcTvOJfY+Rq1i7sNJ9lJVZnsDAlZJI56VqZCKnPJmS2br87g==", - "dev": true, - "requires": { - "mdast-util-to-string": "^1.0.2", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-stringify-position": "^2.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-no-emphasis-as-heading": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-no-emphasis-as-heading/-/remark-lint-no-emphasis-as-heading-1.0.4.tgz", - "integrity": "sha512-gnsInLxTkc59eVD3/qelFagD/NcrMPKXT1sy7i4e8D2jqQyrIHHl0p3TfiyNNt8qIjKMKhlIii4k4kVk/3Mczg==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-no-file-name-articles": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-1.0.5.tgz", - "integrity": "sha512-AQk5eTb3s3TAPPjiglZgqlQj4ycao+gPs8/XkdN1VCPUtewW0GgwoQe7YEuBKayJ6ioN8dGP37Kg/P/PlKaRQA==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0" - } - }, - "remark-lint-no-file-name-consecutive-dashes": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-1.0.5.tgz", - "integrity": "sha512-Mg2IDsi790/dSdAzwnBnsMYdZm3qC2QgGwqOWcr0TPABJhhjC3p8r5fX4MNMTXI5It7B7bW9+ImmCeLOZiXkLg==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0" - } - }, - "remark-lint-no-file-name-irregular-characters": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-irregular-characters/-/remark-lint-no-file-name-irregular-characters-1.0.5.tgz", - "integrity": "sha512-Oe5i99qNUKc2bxmiH421o5B/kqlf1dfjAxpHNLhi2X2dXE91zRGavrlRM/4f4oR0N9Bqb3qB9JZPyMPWrzu9XA==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0" - } - }, - "remark-lint-no-file-name-mixed-case": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-mixed-case/-/remark-lint-no-file-name-mixed-case-1.0.5.tgz", - "integrity": "sha512-ilrUCbHZin/ENwr8c3SC2chgkFsizXjBQIB/oZ7gnm1IkCkZPiMyXZAHdpwC/DjbrpGxfMYh9JmIHao4giS5+A==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0" - } - }, - "remark-lint-no-file-name-outer-dashes": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-1.0.6.tgz", - "integrity": "sha512-rT8CmcIlenegS0Yst4maYXdZfqIjBOiRUY8j/KJkORF5tKH+3O1/S07025qPGmcRihzK3w4yO0K8rgkKQw0b9w==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0" - } - }, - "remark-lint-no-heading-content-indent": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-1.0.4.tgz", - "integrity": "sha512-z+hcAsGbGiy28ERAZuOT1pYf6lkkoR2YlFUt4po4azfXMz5lmidYTotkezsWvA3Bh8N0mIi7hs8syPt8RRIGqg==", - "dev": true, - "requires": { - "mdast-util-heading-style": "^1.0.2", - "plur": "^3.0.0", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-no-heading-punctuation": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-no-heading-punctuation/-/remark-lint-no-heading-punctuation-1.0.4.tgz", - "integrity": "sha512-++/HXg/qtVssJjzq2ZgEreoxaazw9KkYrAbTDImKV7Fypo+7bZFELUvFicq0/i9qwAwt1tvhkKtLYt1W/sr1JQ==", - "dev": true, - "requires": { - "mdast-util-to-string": "^1.0.2", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-no-inline-padding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-1.0.5.tgz", - "integrity": "sha512-AjS34hBRasYiIAKZJ7/9U42LouRHok2WVTRdQPcVtRBswStNOuot59S+FRsatqlk1wvMmjytqxUKQfVTSeu9ag==", - "dev": true, - "requires": { - "mdast-util-to-string": "^1.0.2", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.4.0" - } - }, - "remark-lint-no-literal-urls": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-1.0.4.tgz", - "integrity": "sha512-sHjbzaSG4z6jMu1L0Qx1b7VvIQHy0bR4xZ6t9auJ5AoB5ua8hb/970s77irH1+46TF1ezhE7i+QDjmhcQi09xg==", - "dev": true, - "requires": { - "mdast-util-to-string": "^1.0.2", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-no-multiple-toplevel-headings": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-1.0.5.tgz", - "integrity": "sha512-RZ1YPxRO7Bo8mT+A36cZ7nx2QHFAKk+oE6j87YrZYpAKr2oF6snKS8nIGhVku4PSI/9cW1G12MZz1cAA5rcjFw==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-stringify-position": "^2.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-no-shell-dollars": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-1.0.4.tgz", - "integrity": "sha512-YXFj8FUVTKkVvoAbFY3zv1Ol7Kj1i+qdze3pXSgRG61y1LpfL8/HpnvFrseMbBmNw6o4WpjTo7GoArngJ1sCeg==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-no-shortcut-reference-image": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-1.0.4.tgz", - "integrity": "sha512-5/9QoesnOHIDwMHU9x+AGPBiFoMe9ZBKIR8nC17C6ZdksgwUIpjBJ3VX5POFlt5E6OhAZaeXqUCq9G2USccEdA==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-no-shortcut-reference-link": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-1.0.5.tgz", - "integrity": "sha512-qDVL7/0ptOTd/nyd9u/4MYFWQtYQU8povdUB45UgTXy5Rrf1WsC+4DfzAEZkX3tOSTExdAIf1WOKqdC5xRcfvA==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-no-table-indentation": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-1.0.5.tgz", - "integrity": "sha512-eE1GL+IzU3vtHdYCKHCZEIhCwiwCM7UH+pMDIMpGfH2LB3cB/Nrfbiz9xadGkARKqxxDMsJSBZDw4A/01IU+kA==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.4.0" - } - }, - "remark-lint-no-undefined-references": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-1.1.2.tgz", - "integrity": "sha512-/MEXcusNFHx+BYUf4wuil+GVKTkofvT+VodjyGw5X0OuPZZJ9c/kL0QjHHzuLuGH+oJUsgOOfnJC/eyO0tV8bw==", - "dev": true, - "requires": { - "collapse-white-space": "^1.0.4", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.4.0" - } - }, - "remark-lint-no-unused-definitions": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-1.0.6.tgz", - "integrity": "sha512-hYHMjbg3wBGT30R9PN74Bieejg2qRkXH9Rc2YakP1unuJoF+X+i5RMsW71spW11/r/+gW2mdzuwBuBoQrWpGTA==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.4.0" - } - }, - "remark-lint-ordered-list-marker-style": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-1.0.4.tgz", - "integrity": "sha512-c6AIqeePzm3nfkPCbTdwBS3/AQICgwE76+ryOc7tsSq4ulyK/Nt8Syvi/oiHYuonBddZoGtFTNCn0jqen9qscA==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-ordered-list-marker-value": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-value/-/remark-lint-ordered-list-marker-value-1.0.5.tgz", - "integrity": "sha512-eKepbNNfu9rEuG8WvV0sc7B+KiPMgq5Nc9baAxL9Hi6mhpj347YFWXxJUNttSINS13YTpnHxPvXmF9SzhjFKNQ==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-rule-style": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-rule-style/-/remark-lint-rule-style-1.0.4.tgz", - "integrity": "sha512-omr5P6CCvo2zixCzK9uiGZpwzOE+4rc+95kWH95k2iA6Rp8Qohp8RK4unSRKLtFYGUhSbiQPgWaQXHDxMkWczg==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-strong-marker": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-strong-marker/-/remark-lint-strong-marker-1.0.4.tgz", - "integrity": "sha512-X9f6yhZ85cdP0cmCgkqlbxllpeQ60pS9Qqk9Jb9SZo6f95esaHptQ5bExb1ZVXzhSHz2Xz86tUhXtzG3zGFD4g==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-table-cell-padding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-1.0.5.tgz", - "integrity": "sha512-N/WpcymrGBSPbLiv2OQTvdzNn6H9ctdyEA+P/odn4G9FqyrLmeTMkGJuGtinU569hLG/RtHqZIDeFVDiYi8Wzw==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.4.0" - } - }, - "remark-lint-table-pipe-alignment": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-table-pipe-alignment/-/remark-lint-table-pipe-alignment-1.0.4.tgz", - "integrity": "sha512-pmELEOXeUjMQedyVvOtZcTCnTu6FxZ4gfBskMx6iJhOFEEKTFOmviqlKLpndPBxFNZB86AiE0C00/NvAaut8dw==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-table-pipes": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-table-pipes/-/remark-lint-table-pipes-1.0.4.tgz", - "integrity": "sha512-0fdnoiiSLIPd/76gNvQY4pg27d8HkMmmv5gCGfD+Z/Si9DdpbJdq93U0kX+Botb3+/4VEDIlcU7Cp5HXppMTWA==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-unordered-list-marker-style": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-1.0.4.tgz", - "integrity": "sha512-lcuG1J74VGTT4gl8oH33HpkHrqorxjxMlJnBupLFrVowqvJ2hAq8yPJdGZ7P46uZOYw+Xz+Qv08bF8A73PNWxQ==", - "dev": true, - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } - }, - "remark-lint-write-good": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/remark-lint-write-good/-/remark-lint-write-good-1.2.0.tgz", - "integrity": "sha512-HYiwM16RRBm979yDb/IVwPe1eFhzA1HATe1WucRiYWS10jcPRgJe9FihH7W5uzQFDqX5aRbTtu/yPdq+hPnYkw==", - "dev": true, - "requires": { - "nlcst-to-string": "^2.0.0", - "unified-lint-rule": "^1.0.1", - "unist-util-visit": "^1.1.1", - "write-good": "^1.0.2" - } - }, - "remark-message-control": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/remark-message-control/-/remark-message-control-4.2.0.tgz", - "integrity": "sha512-WXH2t5ljTyhsXlK1zPBLF3iPHbXl58R94phPMreS1xcHWBZJt6Oiu8RtNjy1poZFb3PqKnbYLJeR/CWcZ1bTFw==", - "dev": true, - "requires": { - "mdast-comment-marker": "^1.0.0", - "unified-message-control": "^1.0.0", - "xtend": "^4.0.1" - } - }, - "remark-parse": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-7.0.2.tgz", - "integrity": "sha512-9+my0lQS80IQkYXsMA8Sg6m9QfXYJBnXjWYN5U+kFc5/n69t+XZVXU/ZBYr3cYH8FheEGf1v87rkFDhJ8bVgMA==", - "dev": true, - "requires": { - "collapse-white-space": "^1.0.2", - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "is-word-character": "^1.0.0", - "markdown-escapes": "^1.0.0", - "parse-entities": "^1.1.0", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "trim": "0.0.1", - "trim-trailing-lines": "^1.0.0", - "unherit": "^1.0.4", - "unist-util-remove-position": "^1.0.0", - "vfile-location": "^2.0.0", - "xtend": "^4.0.1" - } - }, - "remark-preset-lint-consistent": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/remark-preset-lint-consistent/-/remark-preset-lint-consistent-2.0.4.tgz", - "integrity": "sha512-cGFSS0ONYEnEYG/USN4f+01BFog2DfBq+jftI1ajSJDPBni6gYffPj6qkT+DZ1F3xkesxLnWAQQb6ZZfa/zGog==", - "dev": true, - "requires": { - "remark-lint": "^6.0.0", - "remark-lint-blockquote-indentation": "^1.0.0", - "remark-lint-checkbox-character-style": "^1.0.0", - "remark-lint-code-block-style": "^1.0.0", - "remark-lint-emphasis-marker": "^1.0.0", - "remark-lint-fenced-code-marker": "^1.0.0", - "remark-lint-heading-style": "^1.0.0", - "remark-lint-link-title-style": "^1.0.0", - "remark-lint-list-item-content-indent": "^1.0.0", - "remark-lint-ordered-list-marker-style": "^1.0.0", - "remark-lint-rule-style": "^1.0.0", - "remark-lint-strong-marker": "^1.0.0", - "remark-lint-table-cell-padding": "^1.0.0" - } - }, - "remark-preset-lint-markdown-style-guide": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/remark-preset-lint-markdown-style-guide/-/remark-preset-lint-markdown-style-guide-2.1.4.tgz", - "integrity": "sha512-CGEN3DRtJEp+BvfgZ+VKxuq0Ij8Uw2DXfrbhK2xn4/XxatcHRPN8tnagXbMe1LHaQJGN8Gl1+UyLjsfIk6hyGQ==", - "dev": true, - "requires": { - "remark-lint": "^6.0.0", - "remark-lint-blockquote-indentation": "^1.0.0", - "remark-lint-code-block-style": "^1.0.0", - "remark-lint-definition-case": "^1.0.0", - "remark-lint-definition-spacing": "^1.0.0", - "remark-lint-emphasis-marker": "^1.0.0", - "remark-lint-fenced-code-flag": "^1.0.0", - "remark-lint-fenced-code-marker": "^1.0.0", - "remark-lint-file-extension": "^1.0.0", - "remark-lint-final-definition": "^1.0.0", - "remark-lint-hard-break-spaces": "^1.0.0", - "remark-lint-heading-increment": "^1.0.0", - "remark-lint-heading-style": "^1.0.0", - "remark-lint-link-title-style": "^1.0.0", - "remark-lint-list-item-content-indent": "^1.0.0", - "remark-lint-list-item-indent": "^1.0.0", - "remark-lint-list-item-spacing": "^1.0.0", - "remark-lint-maximum-heading-length": "^1.0.0", - "remark-lint-maximum-line-length": "^1.0.0", - "remark-lint-no-auto-link-without-protocol": "^1.0.0", - "remark-lint-no-blockquote-without-marker": "^2.0.0", - "remark-lint-no-consecutive-blank-lines": "^1.0.0", - "remark-lint-no-duplicate-headings": "^1.0.0", - "remark-lint-no-emphasis-as-heading": "^1.0.0", - "remark-lint-no-file-name-articles": "^1.0.0", - "remark-lint-no-file-name-consecutive-dashes": "^1.0.0", - "remark-lint-no-file-name-irregular-characters": "^1.0.0", - "remark-lint-no-file-name-mixed-case": "^1.0.0", - "remark-lint-no-file-name-outer-dashes": "^1.0.0", - "remark-lint-no-heading-punctuation": "^1.0.0", - "remark-lint-no-inline-padding": "^1.0.0", - "remark-lint-no-literal-urls": "^1.0.0", - "remark-lint-no-multiple-toplevel-headings": "^1.0.0", - "remark-lint-no-shell-dollars": "^1.0.0", - "remark-lint-no-shortcut-reference-image": "^1.0.0", - "remark-lint-no-shortcut-reference-link": "^1.0.0", - "remark-lint-no-table-indentation": "^1.0.0", - "remark-lint-ordered-list-marker-style": "^1.0.0", - "remark-lint-ordered-list-marker-value": "^1.0.0", - "remark-lint-rule-style": "^1.0.0", - "remark-lint-strong-marker": "^1.0.0", - "remark-lint-table-cell-padding": "^1.0.0", - "remark-lint-table-pipe-alignment": "^1.0.0", - "remark-lint-table-pipes": "^1.0.0", - "remark-lint-unordered-list-marker-style": "^1.0.0" - } - }, - "remark-preset-lint-recommended": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-3.0.4.tgz", - "integrity": "sha512-i4GoobwWKt5LDJxIZjhHnnYiQISacNE8Oxj1ViwSHJnTUCtd7vh3KwtsfV8DrLsFUqRogX49iJEuZWXipY3PJA==", - "dev": true, - "requires": { - "remark-lint": "^6.0.0", - "remark-lint-final-newline": "^1.0.0", - "remark-lint-hard-break-spaces": "^1.0.0", - "remark-lint-list-item-bullet-indent": "^1.0.0", - "remark-lint-list-item-indent": "^1.0.0", - "remark-lint-no-auto-link-without-protocol": "^1.0.0", - "remark-lint-no-blockquote-without-marker": "^2.0.0", - "remark-lint-no-duplicate-definitions": "^1.0.0", - "remark-lint-no-heading-content-indent": "^1.0.0", - "remark-lint-no-inline-padding": "^1.0.0", - "remark-lint-no-literal-urls": "^1.0.0", - "remark-lint-no-shortcut-reference-image": "^1.0.0", - "remark-lint-no-shortcut-reference-link": "^1.0.0", - "remark-lint-no-undefined-references": "^1.0.0", - "remark-lint-no-unused-definitions": "^1.0.0", - "remark-lint-ordered-list-marker-style": "^1.0.0" - } - }, - "remark-retext": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/remark-retext/-/remark-retext-3.1.3.tgz", - "integrity": "sha512-UujXAm28u4lnUvtOZQFYfRIhxX+auKI9PuA2QpQVTT7gYk1OgX6o0OUrSo1KOa6GNrFX+OODOtS5PWIHPxM7qw==", - "dev": true, - "requires": { - "mdast-util-to-nlcst": "^3.2.0" - } - }, - "remark-stringify": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-7.0.4.tgz", - "integrity": "sha512-qck+8NeA1D0utk1ttKcWAoHRrJxERYQzkHDyn+pF5Z4whX1ug98uCNPPSeFgLSaNERRxnD6oxIug6DzZQth6Pg==", - "dev": true, - "requires": { - "ccount": "^1.0.0", - "is-alphanumeric": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "longest-streak": "^2.0.1", - "markdown-escapes": "^1.0.0", - "markdown-table": "^1.1.0", - "mdast-util-compact": "^1.0.0", - "parse-entities": "^1.0.2", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "stringify-entities": "^2.0.0", - "unherit": "^1.0.4", - "xtend": "^4.0.1" - } - }, - "remark-validate-links": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/remark-validate-links/-/remark-validate-links-9.2.0.tgz", - "integrity": "sha512-hRFU6+Xu+OSOowGoLhc73Et7HgEoXg+SGjQuUUANv3Hf9seuFHQCzO76w150tOYpM8APbdoTioxLFwAY2XEAZg==", - "dev": true, - "requires": { - "github-slugger": "^1.2.0", - "hosted-git-info": "^2.5.0", - "mdast-util-to-string": "^1.0.4", - "propose": "0.0.5", - "to-vfile": "^6.0.0", - "trough": "^1.0.0", - "unist-util-visit": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "retext-contractions": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/retext-contractions/-/retext-contractions-3.0.0.tgz", - "integrity": "sha512-Wn95agseXHTsoXvhavuTcnwUEb9TbL7QtnYkHeFMh8L53jdQbbooLX68cbpKyaaPbxYiomrgJpu7eB3arcr2rw==", - "dev": true, - "requires": { - "nlcst-is-literal": "^1.0.0", - "nlcst-to-string": "^2.0.0", - "unist-util-visit": "^1.1.0" - } - }, - "retext-diacritics": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/retext-diacritics/-/retext-diacritics-2.0.0.tgz", - "integrity": "sha512-wr3mqJ9whlIG/q6vP601qR+/C7AMgc7O60kebs9kvN/HtTX7CpvFsKF68+yw86drMOMVCBJP8JB1Qlnj8CkY5A==", - "dev": true, - "requires": { - "match-casing": "^1.0.0", - "nlcst-search": "^1.0.0", - "nlcst-to-string": "^2.0.0", - "quotation": "^1.0.1", - "unist-util-position": "^3.0.0" - } - }, - "retext-english": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/retext-english/-/retext-english-3.0.4.tgz", - "integrity": "sha512-yr1PgaBDde+25aJXrnt3p1jvT8FVLVat2Bx8XeAWX13KXo8OT+3nWGU3HWxM4YFJvmfqvJYJZG2d7xxaO774gw==", - "dev": true, - "requires": { - "parse-english": "^4.0.0", - "unherit": "^1.0.4" - } - }, - "retext-equality": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/retext-equality/-/retext-equality-4.5.0.tgz", - "integrity": "sha512-k+fxJpR/mXpm8PvpMo3DPlGVtdTcxYLFhsV+CGd9XmC+22X26y2Xi6fC/rWYwWkxUJSMZiB9HveTN0Cy8VNYuw==", - "dev": true, - "requires": { - "lodash.difference": "^4.5.0", - "lodash.intersection": "^4.4.0", - "nlcst-normalize": "^2.0.0", - "nlcst-search": "^1.1.1", - "nlcst-to-string": "^2.0.0", - "object-keys": "^1.0.7", - "quotation": "^1.0.1", - "unist-util-is": "^4.0.0", - "unist-util-visit": "^2.0.0" - }, - "dependencies": { - "unist-util-is": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", - "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==", - "dev": true - }, - "unist-util-visit": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", - "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", - "dev": true, - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0", - "unist-util-visit-parents": "^3.0.0" - } - }, - "unist-util-visit-parents": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.0.tgz", - "integrity": "sha512-0g4wbluTF93npyPrp/ymd3tCDTMnP0yo2akFD2FIBAYXq/Sga3lwaU1D8OYKbtpioaI6CkDcQ6fsMnmtzt7htw==", - "dev": true, - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0" - } - } - } - }, - "retext-indefinite-article": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/retext-indefinite-article/-/retext-indefinite-article-1.1.7.tgz", - "integrity": "sha512-pqvEfEHL8uoeonbEjk8+d/hmyA3ozIeNTl4t3uurMcBpoIqN3+nbuMCFQrfDy2wjaKZ40KsLmEi+Zjv7m1ejLQ==", - "dev": true, - "requires": { - "format": "^0.2.2", - "nlcst-to-string": "^2.0.0", - "number-to-words": "^1.2.3", - "unist-util-is": "^3.0.0", - "unist-util-visit": "^1.1.0" - } - }, - "retext-overuse": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/retext-overuse/-/retext-overuse-1.1.1.tgz", - "integrity": "sha1-Q+YoGzg8Byl56rqPKsCARmqPa/o=", - "dev": true, - "requires": { - "array-differ": "^1.0.0", - "nlcst-search": "^1.1.1", - "nlcst-to-string": "^1.0.0", - "object-keys": "^1.0.9", - "quotation": "^1.0.1", - "stopwords": "0.0.5", - "thesaurus": "0.0.0" - }, - "dependencies": { - "nlcst-to-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-1.1.0.tgz", - "integrity": "sha1-ErLllHXsKffWGhRqebNZba/LNE0=", - "dev": true - } - } - }, - "retext-passive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/retext-passive/-/retext-passive-2.0.0.tgz", - "integrity": "sha512-IIOEH6p3Eu/sTYWEgDfdOBnEsDqxa6ZnHJjPNo6u4gfGct5rH4oaEaApTGpEIkYigUpylIHK0U6iWieqbBja0Q==", - "dev": true, - "requires": { - "lodash.difference": "^4.5.0", - "nlcst-search": "^1.0.0", - "nlcst-to-string": "^2.0.0", - "unist-util-find-before": "^2.0.0", - "unist-util-position": "^3.0.0" - } - }, - "retext-profanities": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/retext-profanities/-/retext-profanities-5.0.0.tgz", - "integrity": "sha512-zaPCKtrMDLs0U/2yN3V3rpYn1VZ3hW+AsEZdovWIRlEYZPCaUmkChOSob45LOQYJUnM+YZIahXuU9zHPm+aTKQ==", - "dev": true, - "requires": { - "cuss": "^1.15.0", - "lodash.difference": "^4.5.0", - "lodash.intersection": "^4.4.0", - "nlcst-search": "^1.0.0", - "nlcst-to-string": "^2.0.0", - "object-keys": "^1.0.9", - "pluralize": "^8.0.0", - "quotation": "^1.0.0" - } - }, - "retext-quotes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/retext-quotes/-/retext-quotes-3.0.0.tgz", - "integrity": "sha512-2htggeOFsrorhXrQvb4BI1O/r7CGVQZx/TysAT7wlVMsRUTZooiIGkBcLrcySa4sbqjsVgg1RjMy8K5O+gCQlg==", - "dev": true, - "requires": { - "nlcst-to-string": "^2.0.0", - "unist-util-is": "^3.0.0", - "unist-util-visit": "^1.1.0" - } - }, - "retext-readability": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/retext-readability/-/retext-readability-5.0.0.tgz", - "integrity": "sha512-g3AzwyfPKUH0KLP57+kpeRJFI3uxu7x+UP4NH5srtmAhyt7b45JJfzMNwt73cYraq2AG+aMlQ541cjeefjsQlg==", - "dev": true, - "requires": { - "automated-readability": "^1.0.0", - "coleman-liau": "^1.0.0", - "dale-chall": "^1.0.0", - "dale-chall-formula": "^1.0.0", - "flesch": "^1.0.0", - "gunning-fog": "^1.0.0", - "nlcst-to-string": "^2.0.0", - "smog-formula": "^1.0.0", - "spache": "^1.1.0", - "spache-formula": "^1.0.0", - "syllable": "^3.2.0", - "unist-util-visit": "^1.0.0" - } - }, - "retext-redundant-acronyms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/retext-redundant-acronyms/-/retext-redundant-acronyms-2.0.0.tgz", - "integrity": "sha512-9E62yXkDKYItNZO+lT4Pp0rAP8e/H7ppjYP681L0fk74xyItoE6okl0BMNVOa0W4XidLoGX2uWdlwWpCUeqQiw==", - "dev": true, - "requires": { - "nlcst-normalize": "^2.0.0", - "nlcst-search": "^1.0.0", - "nlcst-to-string": "^2.0.0", - "pluralize": "^8.0.0", - "quotation": "^1.0.0", - "unist-util-find-after": "^2.0.0", - "unist-util-position": "^3.0.0" - } - }, - "retext-repeated-words": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/retext-repeated-words/-/retext-repeated-words-2.0.0.tgz", - "integrity": "sha512-CGqM88ViAKtSgdWGObTU974AdmfxyiyB19MvuQTBBW3crWYIS7p21m0sJH/pCnp11gVa0YOU+vqdNaSvRiLTFA==", - "dev": true, - "requires": { - "nlcst-to-string": "^2.0.0", - "unist-util-is": "^3.0.0", - "unist-util-visit": "^1.1.0" - } - }, - "retext-sentence-spacing": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/retext-sentence-spacing/-/retext-sentence-spacing-3.0.0.tgz", - "integrity": "sha512-UWltTXZNh6kBwJJc0js3nOmbqze3LqhJg68jaRErNIPZQHtZ5hMn7h7f8kVY5OrbEL9XiY88m5DRPbFz16eTkQ==", - "dev": true, - "requires": { - "nlcst-to-string": "^2.0.0", - "unist-util-is": "^3.0.0", - "unist-util-visit": "^1.1.0" - } - }, - "retext-spell": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/retext-spell/-/retext-spell-3.0.0.tgz", - "integrity": "sha512-PvJaRhEuHOsPXX/5h3EfqEpoWZWvDBnLoopn8TGfSfPIonjwpJNvYx8qBCRp1CQlUrPPO9Vi/Hl5CvNMp7GiSA==", - "dev": true, - "requires": { - "lodash.includes": "^4.2.0", - "nlcst-is-literal": "^1.0.0", - "nlcst-to-string": "^2.0.0", - "nspell": "^2.0.0", - "quotation": "^1.1.0", - "unist-util-visit": "^1.0.0" - } - }, - "retext-syntax-urls": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/retext-syntax-urls/-/retext-syntax-urls-1.0.2.tgz", - "integrity": "sha512-Ud7i50IEP33OK9g5xCBIKh/DjoEdZi6sRJqnWDW3Wxt4B48llgfSbGLgiLeXZvJD923mOf7EAoLt/WjundXmwg==", - "dev": true, - "requires": { - "nlcst-to-string": "^2.0.0", - "unist-util-is": "^3.0.0", - "unist-util-modify-children": "^1.1.1", - "unist-util-position": "^3.0.0" - } - }, - "retext-usage": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/retext-usage/-/retext-usage-0.5.0.tgz", - "integrity": "sha1-qX3Jjn6Uf1z02Q5N1kJ1TWS6aJg=", - "dev": true, - "requires": { - "array-differ": "^1.0.0", - "nlcst-search": "^1.0.0", - "nlcst-to-string": "^1.1.0", - "object-keys": "^1.0.9", - "quotation": "^1.0.0" - }, - "dependencies": { - "nlcst-to-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-1.1.0.tgz", - "integrity": "sha1-ErLllHXsKffWGhRqebNZba/LNE0=", - "dev": true - } - } - }, - "rfdc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.2.0.tgz", - "integrity": "sha512-ijLyszTMmUrXvjSooucVQwimGUk84eRcmCuLV8Xghe3UO85mjUtRAHRyoMM6XtyqbECaXuBWx18La3523sXINA==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "dev": true - }, - "shellsubstitute": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shellsubstitute/-/shellsubstitute-1.2.0.tgz", - "integrity": "sha1-5PcCpQxRiw9v6YRRiQ1wWvKba3A=", - "dev": true - }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true - }, - "sliced": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", - "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=", - "dev": true - }, - "smog-formula": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/smog-formula/-/smog-formula-1.0.5.tgz", - "integrity": "sha512-ogE7LgeO/UeaEP1f1FPrQHwBWURWzb+VIQfw/1K3xR+uzI7o5uS9B5K6rw1+Eq+GtseAg3KGz2m49YylwnfCoQ==", - "dev": true - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "socket.io": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.0.tgz", - "integrity": "sha512-Aqg2dlRh6xSJvRYK31ksG65q4kmBOqU4g+1ukhPcoT6wNGYoIwSYPlCPuRwOO9pgLUajojGFztl6+V2opmKcww==", - "dev": true, - "requires": { - "@types/cookie": "^0.4.0", - "@types/cors": "^2.8.8", - "@types/node": "^14.14.10", - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "debug": "~4.3.1", - "engine.io": "~4.1.0", - "socket.io-adapter": "~2.1.0", - "socket.io-parser": "~4.0.3" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "socket.io-adapter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz", - "integrity": "sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg==", - "dev": true - }, - "socket.io-parser": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz", - "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==", - "dev": true, - "requires": { - "@types/component-emitter": "^1.2.10", - "component-emitter": "~1.3.0", - "debug": "~4.3.1" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "spache": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/spache/-/spache-1.1.5.tgz", - "integrity": "sha512-fblcef79rv7R/pRogLcnt8pYEWc5oLJ8RS7hArT6kCHp5gaVPG8EVzy2FjLbpCclfu77E6GpuNdnP6muTe4YxQ==", - "dev": true - }, - "spache-formula": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/spache-formula/-/spache-formula-1.0.5.tgz", - "integrity": "sha512-eYX6hYxeFRZbkcpunMrxhKcGAydeT0hZ958Q20J/UA119EybMrU+KuiSSKNbCwR4D55Yk8J6APg16yuWGtjcDw==", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true - }, - "state-toggle": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", - "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", - "dev": true - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - }, - "stopwords": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stopwords/-/stopwords-0.0.5.tgz", - "integrity": "sha1-Wa2dzrluoPonRZ4c7+DuDm3f1RQ=", - "dev": true - }, - "streamroller": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-2.2.4.tgz", - "integrity": "sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ==", - "dev": true, - "requires": { - "date-format": "^2.1.0", - "debug": "^4.1.1", - "fs-extra": "^8.1.0" - }, - "dependencies": { - "date-format": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz", - "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==", - "dev": true - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "stringify-entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-2.0.0.tgz", - "integrity": "sha512-fqqhZzXyAM6pGD9lky/GOPq6V4X0SeTAFBl0iXb/BzOegl40gpf/bV3QQP7zULNYvjr6+Dx8SCaDULjVoOru0A==", - "dev": true, - "requires": { - "character-entities-html4": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.2", - "is-hexadecimal": "^1.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "syllable": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/syllable/-/syllable-3.6.1.tgz", - "integrity": "sha512-L2yAT4DRi9rwHpHMResxA/VKSM9T7X+eRAOEKoAFvHJxaxjtxT2Rt8qfB6pbrxeOZWsHu+ON0kTc9Oo0lU2PHA==", - "dev": true, - "requires": { - "normalize-strings": "^1.1.0", - "pluralize": "^7.0.0", - "trim": "0.0.1" - }, - "dependencies": { - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "dev": true - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "thesaurus": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/thesaurus/-/thesaurus-0.0.0.tgz", - "integrity": "sha1-CjszVvwdgYxsFsI/Vrp/PFolyQU=", - "dev": true - }, - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "requires": { - "rimraf": "^3.0.0" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "to-vfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/to-vfile/-/to-vfile-6.1.0.tgz", - "integrity": "sha512-BxX8EkCxOAZe+D/ToHdDsJcVI4HqQfmw0tCkp31zf3dNP/XWIAjU4CmeuSwsSoOzOTqHPOL0KUzyZqJplkD0Qw==", - "dev": true, - "requires": { - "is-buffer": "^2.0.0", - "vfile": "^4.0.0" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "dev": true - }, - "too-wordy": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/too-wordy/-/too-wordy-0.2.2.tgz", - "integrity": "sha512-ePZfjs1ajL4b8jT4MeVId+9Ci5hJCzAtNIEXIHyFYmKmQuX+eHC/RNv6tuLMUhrGrhJ+sYWW/lBF/LKILHGZEA==", - "dev": true - }, - "trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", - "dev": true - }, - "trim-trailing-lines": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.3.tgz", - "integrity": "sha512-4ku0mmjXifQcTVfYDfR5lpgV7zVqPg6zV9rdZmwOPqq0+Zq19xDqEgagqVbc4pOOShbncuAOIs59R3+3gcF3ZA==", - "dev": true - }, - "trough": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", - "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", - "dev": true - }, - "type-fest": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "ua-parser-js": { - "version": "0.7.23", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.23.tgz", - "integrity": "sha512-m4hvMLxgGHXG3O3fQVAyyAQpZzDOvwnhOTjYz5Xmr7r/+LpkNy3vJXdVRWgd1TkAb7NGROZuSy96CrlNVjA7KA==", - "dev": true - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", - "dev": true - }, - "underscore": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz", - "integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg==", - "dev": true - }, - "underscore.string": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz", - "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==", - "dev": true, - "requires": { - "sprintf-js": "^1.0.3", - "util-deprecate": "^1.0.2" - } - }, - "unherit": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", - "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", - "dev": true, - "requires": { - "inherits": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "unified": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-8.4.2.tgz", - "integrity": "sha512-JCrmN13jI4+h9UAyKEoGcDZV+i1E7BLFuG7OsaDvTXI5P0qhHX+vZO/kOhz9jn8HGENDKbwSeB0nVOg4gVStGA==", - "dev": true, - "requires": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^2.0.0", - "trough": "^1.0.0", - "vfile": "^4.0.0" - } - }, - "unified-args": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/unified-args/-/unified-args-7.1.0.tgz", - "integrity": "sha512-soi9Rn7l5c1g0RfElSCHMwaxeiclSI0EsS3uZmMPUOfwMeeeZjLpNmHAowV9iSlQh59iiZhSMyQu9lB8WnIz5g==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "chalk": "^2.0.0", - "chokidar": "^3.0.0", - "fault": "^1.0.2", - "json5": "^2.0.0", - "minimist": "^1.2.0", - "text-table": "^0.2.0", - "unified-engine": "^7.0.0" - } - }, - "unified-engine": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/unified-engine/-/unified-engine-7.0.0.tgz", - "integrity": "sha512-zH/MvcISpWg3JZtCoY/GYBw1WnVHkhnPoMBWpmuvAifCPSS9mzT9EbtimesJp6t2nnr/ojI0mg3TmkO1CjIwVA==", - "dev": true, - "requires": { - "concat-stream": "^2.0.0", - "debug": "^4.0.0", - "fault": "^1.0.0", - "figures": "^3.0.0", - "fn-name": "^2.0.1", - "glob": "^7.0.3", - "ignore": "^5.0.0", - "is-empty": "^1.0.0", - "is-hidden": "^1.0.1", - "is-object": "^1.0.1", - "js-yaml": "^3.6.1", - "load-plugin": "^2.0.0", - "parse-json": "^4.0.0", - "to-vfile": "^6.0.0", - "trough": "^1.0.0", - "unist-util-inspect": "^4.1.2", - "vfile-reporter": "^6.0.0", - "vfile-statistics": "^1.1.0", - "x-is-string": "^0.1.0", - "xtend": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "unified-lint-rule": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-1.0.6.tgz", - "integrity": "sha512-YPK15YBFwnsVorDFG/u0cVVQN5G2a3V8zv5/N6KN3TCG+ajKtaALcy7u14DCSrJI+gZeyYquFL9cioJXOGXSvg==", - "dev": true, - "requires": { - "wrapped": "^1.0.1" - } - }, - "unified-message-control": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unified-message-control/-/unified-message-control-1.0.4.tgz", - "integrity": "sha512-e1dEtN4Z/TvLn/qHm+xeZpzqhJTtfZusFErk336kkZVpqrJYiV9ptxq+SbRPFMlN0OkjDYHmVJ929KYjsMTo3g==", - "dev": true, - "requires": { - "trim": "0.0.1", - "unist-util-visit": "^1.0.0", - "vfile-location": "^2.0.0" - } - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unist-util-find-after": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-2.0.4.tgz", - "integrity": "sha512-zo0ShIr+E/aU9xSK7JC9Kb+WP9seTFCuqVYdo5+HJSjN009XMfhiA1FIExEKzdDP1UsgvKGleGlB/pSdTSqZww==", - "dev": true, - "requires": { - "unist-util-is": "^3.0.0" - } - }, - "unist-util-find-before": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/unist-util-find-before/-/unist-util-find-before-2.0.5.tgz", - "integrity": "sha512-6WeMwHCC+CLB6D78xdqLq9DVgRope3rZVAUp4bUTevLKq63adgZTHqQ9Xagd5d69vUqTKZA1kA+DQbdaVgd65g==", - "dev": true, - "requires": { - "unist-util-is": "^4.0.0" - }, - "dependencies": { - "unist-util-is": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", - "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==", - "dev": true - } - } - }, - "unist-util-generated": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.5.tgz", - "integrity": "sha512-1TC+NxQa4N9pNdayCYA1EGUOCAO0Le3fVp7Jzns6lnua/mYgwHo0tz5WUAfrdpNch1RZLHc61VZ1SDgrtNXLSw==", - "dev": true - }, - "unist-util-inspect": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/unist-util-inspect/-/unist-util-inspect-4.1.4.tgz", - "integrity": "sha512-7xxyvKiZ1SC9vL5qrMqKub1T31gRHfau4242F69CcaOrXt//5PmRVOmDZ36UAEgiT+tZWzmQmbNZn+mVtnR9HQ==", - "dev": true, - "requires": { - "is-empty": "^1.0.0" - } - }, - "unist-util-is": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", - "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==", - "dev": true - }, - "unist-util-modify-children": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-1.1.6.tgz", - "integrity": "sha512-TOA6W9QLil+BrHqIZNR4o6IA5QwGOveMbnQxnWYq+7EFORx9vz/CHrtzF36zWrW61E2UKw7sM1KPtIgeceVwXw==", - "dev": true, - "requires": { - "array-iterate": "^1.0.0" - } - }, - "unist-util-position": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", - "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==", - "dev": true - }, - "unist-util-remove-position": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz", - "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==", - "dev": true, - "requires": { - "unist-util-visit": "^1.1.0" - } - }, - "unist-util-stringify-position": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", - "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", - "dev": true, - "requires": { - "@types/unist": "^2.0.2" - } - }, - "unist-util-visit": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", - "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", - "dev": true, - "requires": { - "unist-util-visit-parents": "^2.0.0" - } - }, - "unist-util-visit-children": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-1.1.4.tgz", - "integrity": "sha512-sA/nXwYRCQVRwZU2/tQWUqJ9JSFM1X3x7JIOsIgSzrFHcfVt6NkzDtKzyxg2cZWkCwGF9CO8x4QNZRJRMK8FeQ==", - "dev": true - }, - "unist-util-visit-parents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", - "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", - "dev": true, - "requires": { - "unist-util-is": "^3.0.0" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - } - } - }, - "untildify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-2.1.0.tgz", - "integrity": "sha1-F+soB5h/dpUunASF/DEdBqgmouA=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, - "requires": { - "prepend-http": "^2.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true - }, - "v8flags": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", - "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true - }, - "vfile": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.0.tgz", - "integrity": "sha512-a/alcwCvtuc8OX92rqqo7PflxiCgXRFjdyoGVuYV+qbgCb0GgZJRvIgCD4+U/Kl1yhaRsaTwksF88xbPyGsgpw==", - "dev": true, - "requires": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "replace-ext": "1.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-message": "^2.0.0" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "vfile-location": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz", - "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==", - "dev": true - }, - "vfile-message": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", - "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", - "dev": true, - "requires": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" - } - }, - "vfile-reporter": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile-reporter/-/vfile-reporter-6.0.1.tgz", - "integrity": "sha512-0OppK9mo8G2XUpv+hIKLVSDsoxJrXnOy73+vIm0jQUOUFYRduqpFHX+QqAQfvRHyX9B0UFiRuNJnBOjQCIsw1g==", - "dev": true, - "requires": { - "repeat-string": "^1.5.0", - "string-width": "^4.0.0", - "supports-color": "^6.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-sort": "^2.1.2", - "vfile-statistics": "^1.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "vfile-sort": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/vfile-sort/-/vfile-sort-2.2.2.tgz", - "integrity": "sha512-tAyUqD2R1l/7Rn7ixdGkhXLD3zsg+XLAeUDUhXearjfIcpL1Hcsj5hHpCoy/gvfK/Ws61+e972fm0F7up7hfYA==", - "dev": true - }, - "vfile-statistics": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-1.1.4.tgz", - "integrity": "sha512-lXhElVO0Rq3frgPvFBwahmed3X03vjPF8OcjKMy8+F1xU/3Q3QU3tKEDp743SFtb74PdF0UWpxPvtOP0GCLheA==", - "dev": true - }, - "void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", - "dev": true - }, - "walkdir": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", - "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==", - "dev": true - }, - "weasel-words": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/weasel-words/-/weasel-words-0.1.1.tgz", - "integrity": "sha1-cTeUZYXHP+RIggE4U70ADF1oek4=", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } - } - }, - "wrapped": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wrapped/-/wrapped-1.0.1.tgz", - "integrity": "sha1-x4PZ2Aeyc+mwHoUWgKk4yHyQckI=", - "dev": true, - "requires": { - "co": "3.1.0", - "sliced": "^1.0.1" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write-good": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/write-good/-/write-good-1.0.2.tgz", - "integrity": "sha512-1gm9Ouz7mBROF7aC8vvSm/3JtPfTiZ+fegPGCKdxsYhf6VYeStHfVFx2Hnj2kJviHPx5zZkiQ8DytzZMP0Zqwg==", - "dev": true, - "requires": { - "adverb-where": "^0.2.1", - "commander": "^2.19.0", - "e-prime": "^0.10.2", - "no-cliches": "^0.2.2", - "passive-voice": "^0.1.0", - "too-wordy": "^0.2.2", - "weasel-words": "^0.1.1" - } - }, - "ws": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz", - "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==", - "dev": true - }, - "x-is-string": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", - "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=", - "dev": true - }, - "xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "dev": true, - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - } - }, - "xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "dev": true - }, - "xmldom": { - "version": "0.1.31", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz", - "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", - "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index 02b633202..000000000 --- a/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "devDependencies": { - "coffeescript": "^2.4.1", - "dictionary-en-us": "^2.1.1", - "gaze": "^1.1.3", - "grunt": "^1.1.0", - "grunt-exec": "^3.0.0", - "jasmine": "^3.4.0", - "jasmine-core": "^3.4.0", - "jasmine-growl-reporter": "^2.0.0", - "jasmine-node": "BrainDoctor/jasmine-node", - "jasmine-reporters": "^2.3.2", - "karma": "^6.0.2", - "karma-chrome-launcher": "^3.1.0", - "karma-coverage": "^2.0.1", - "karma-firefox-launcher": "^1.2.0", - "karma-jasmine": "^2.0.1", - "minimist": "^1.2.5", - "mkdirp": "^0.5.1", - "remark-cli": "^7.0.0", - "remark-frontmatter": "^1.3.2", - "remark-lint-heading-whitespace": "^1.0.0", - "remark-lint-no-dead-urls": "^0.5.0", - "remark-lint-unordered-list-marker-style": "^1.0.3", - "remark-lint-write-good": "^1.1.0", - "remark-preset-lint-consistent": "^2.0.3", - "remark-preset-lint-markdown-style-guide": "^2.1.3", - "remark-preset-lint-recommended": "^3.0.3", - "remark-retext": "^3.1.3", - "remark-stringify": "^7.0.3", - "remark-validate-links": "^9.0.1", - "retext-contractions": "^3.0.0", - "retext-diacritics": "^2.0.0", - "retext-english": "^3.0.3", - "retext-equality": "^4.0.0", - "retext-indefinite-article": "^1.1.7", - "retext-overuse": "^1.1.1", - "retext-passive": "^2.0.0", - "retext-profanities": "^5.0.0", - "retext-quotes": "^3.0.0", - "retext-readability": "^5.0.0", - "retext-redundant-acronyms": "^2.0.0", - "retext-repeated-words": "^2.0.0", - "retext-sentence-spacing": "^3.0.0", - "retext-spell": "^3.0.0", - "retext-syntax-urls": "^1.0.2", - "retext-usage": "^0.5.0", - "underscore": "^1.9.1", - "walkdir": "^0.4.1", - "xml2js": "^0.4.22" - }, - "scripts": { - "lint-md": "remark .", - "lint-md-path": "remark", - "fix-md": "remark . --output" - } -} diff --git a/packaging/bundle-ebpf-co-re.sh b/packaging/bundle-ebpf-co-re.sh new file mode 100755 index 000000000..9d2eaf570 --- /dev/null +++ b/packaging/bundle-ebpf-co-re.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +SRCDIR="${1}" + +CORE_VERSION="$(cat "${SRCDIR}/packaging/ebpf-co-re.version")" +CORE_TARBALL="netdata-ebpf-co-re-glibc-${CORE_VERSION}.tar.xz" +curl -sSL --connect-timeout 10 --retry 3 "https://github.com/netdata/ebpf-co-re/releases/download/${CORE_VERSION}/${CORE_TARBALL}" > "${CORE_TARBALL}" || exit 1 +grep "${CORE_TARBALL}" "${SRCDIR}/packaging/ebpf-co-re.checksums" | sha256sum -c - || exit 1 +tar -xaf "${CORE_TARBALL}" -C "${SRCDIR}/collectors/ebpf.plugin" || exit 1 diff --git a/packaging/bundle-libbpf.sh b/packaging/bundle-libbpf.sh index 3ca183b0f..7e6e22a9e 100755 --- a/packaging/bundle-libbpf.sh +++ b/packaging/bundle-libbpf.sh @@ -24,3 +24,4 @@ tar -xzf "${LIBBPF_TARBALL}" -C "${1}/externaldeps/libbpf" || exit 1 make -C "${LIBBPF_BUILD_PATH}/src" BUILD_STATIC_ONLY=1 OBJDIR=build/ DESTDIR=../ install || exit 1 cp -a "${LIBBPF_BUILD_PATH}/usr/${lib_subdir}/libbpf.a" "${1}/externaldeps/libbpf" || exit 1 cp -a "${LIBBPF_BUILD_PATH}/usr/include" "${1}/externaldeps/libbpf" || exit 1 +cp -a "${LIBBPF_BUILD_PATH}/include/uapi" "${1}/externaldeps/libbpf/include" || exit 1 diff --git a/packaging/bundle-protobuf.sh b/packaging/bundle-protobuf.sh new file mode 100755 index 000000000..98ab1ed17 --- /dev/null +++ b/packaging/bundle-protobuf.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +PROTOBUF_TARBALL="protobuf-cpp-$(cat "${1}/packaging/protobuf.version").tar.gz" +PROTOBUF_BUILD_PATH="${1}/externaldeps/protobuf/protobuf-$(cat "${1}/packaging/protobuf.version")" + +mkdir -p "${1}/externaldeps/protobuf" || exit 1 +curl -sSL --connect-timeout 10 --retry 3 "https://github.com/protocolbuffers/protobuf/releases/download/v$(cat "${1}/packaging/protobuf.version")/${PROTOBUF_TARBALL}" > "${PROTOBUF_TARBALL}" || exit 1 +sha256sum -c "${1}/packaging/protobuf.checksums" || exit 1 +tar -xzf "${PROTOBUF_TARBALL}" -C "${1}/externaldeps/protobuf" || exit 1 +OLDPWD="${PWD}" +cd "${PROTOBUF_BUILD_PATH}" || exit 1 +./configure --disable-shared --without-zlib --disable-dependency-tracking --with-pic || exit 1 +make -j "$(nproc)" || exit 1 +cd "${OLDPWD}" || exit 1 + +cp -a "${PROTOBUF_BUILD_PATH}/src" "${1}/externaldeps/protobuf" || exit 1 diff --git a/packaging/current_libbpf.checksums b/packaging/current_libbpf.checksums index 4b6ed4580..1e545cc47 100644 --- a/packaging/current_libbpf.checksums +++ b/packaging/current_libbpf.checksums @@ -1 +1 @@ -de0a406ca56b73597a95a96cc0c5bf523161f69517fc5f2f5096fbaef7f223b5 v0.6.1_netdata.tar.gz +d8f935cfdd9256c0902112fc949c9d5d23f1687c66ed359a9a18f06cc71dc676 v0.7_netdata.tar.gz diff --git a/packaging/current_libbpf.version b/packaging/current_libbpf.version index 4263286b6..08c143919 100644 --- a/packaging/current_libbpf.version +++ b/packaging/current_libbpf.version @@ -1 +1 @@ -0.6.1_netdata +0.7_netdata diff --git a/packaging/docker/Dockerfile b/packaging/docker/Dockerfile index d99d393ae..89e723a4f 100644 --- a/packaging/docker/Dockerfile +++ b/packaging/docker/Dockerfile @@ -65,8 +65,8 @@ ARG NETDATA_UID=201 ARG NETDATA_GID=201 ENV DOCKER_GRP netdata ENV DOCKER_USR netdata -# If DO_NOT_TRACK is set, it will disable anonymous stats collection and reporting -#ENV DO_NOT_TRACK=1 +# If DISABLE_TELEMETRY is set, it will disable anonymous stats collection and reporting +#ENV DISABLE_TELEMETRY=1 # Copy files over RUN mkdir -p /opt/src /var/log/netdata && \ @@ -80,6 +80,7 @@ RUN mkdir -p /opt/src /var/log/netdata && \ # Add netdata user addgroup -g ${NETDATA_GID} -S "${DOCKER_GRP}" && \ adduser -S -H -s /usr/sbin/nologin -u ${NETDATA_GID} -h /etc/netdata -G "${DOCKER_GRP}" "${DOCKER_USR}" + # Fix handling of config directory # Long-term this should leverage BuildKit’s mount option. COPY --from=builder /wheels /wheels @@ -110,7 +111,8 @@ RUN chown -R root:root \ find /var/lib/netdata /var/cache/netdata -type d -exec chmod 0770 {} \; && \ find /var/lib/netdata /var/cache/netdata -type f -exec chmod 0660 {} \; && \ pip --no-cache-dir install /wheels/* && \ - rm -rf /wheels + rm -rf /wheels && \ + cp -va /etc/netdata /etc/netdata.stock ENV NETDATA_LISTENER_PORT 19999 EXPOSE $NETDATA_LISTENER_PORT diff --git a/packaging/docker/README.md b/packaging/docker/README.md index 0052bebe1..dcce9a4a1 100644 --- a/packaging/docker/README.md +++ b/packaging/docker/README.md @@ -489,4 +489,4 @@ Once you have contacted the Netdata owners to setup you up on Github and Travis, Having followed these instructions, your forked repository should be all set up for integration with Travis CI. Happy testing! -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fpackaging%2Fdocker%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/packaging/docker/run.sh b/packaging/docker/run.sh index 3f05a1708..1e001256c 100755 --- a/packaging/docker/run.sh +++ b/packaging/docker/run.sh @@ -9,13 +9,20 @@ # Author : Austin S. Hemmelgarn set -e -if [ ! "${DO_NOT_TRACK:-0}" -eq 0 ] || [ -n "$DO_NOT_TRACK" ]; then - touch /etc/netdata/.opt-out-from-anonymous-statistics +if [ ! -w / ] && [ "${EUID}" -eq 0 ]; then + echo >&2 "WARNING: This Docker host appears to not properly support newer stat system calls. This is known to cause issues with Netdata (most notably, nodes running on such hosts **cannot be claimed**)." + echo >&2 "WARNING: For more information, see https://learn.netdata.cloud/docs/agent/claim#known-issues-on-older-hosts-with-seccomp-enabled" fi +if [ ! "${DISABLE_TELEMETRY:-0}" -eq 0 ] || + [ -n "$DISABLE_TELEMETRY" ] || + [ ! "${DO_NOT_TRACK:-0}" -eq 0 ] || + [ -n "$DO_NOT_TRACK" ]; then + touch /etc/netdata/.opt-out-from-anonymous-statistics +fi -BALENA_PGID=$(ls -nd /var/run/balena.sock | awk '{print $4}') -DOCKER_PGID=$(ls -nd /var/run/docker.sock | awk '{print $4}') +BALENA_PGID=$(stat -c %g /var/run/balena.sock 2>/dev/null || true) +DOCKER_PGID=$(stat -c %g /var/run/docker.sock 2>/dev/null || true) re='^[0-9]+$' if [[ $BALENA_PGID =~ $re ]]; then @@ -25,7 +32,7 @@ if [[ $BALENA_PGID =~ $re ]]; then elif [[ $DOCKER_PGID =~ $re ]]; then echo "Netdata detected docker.sock" DOCKER_HOST="/var/run/docker.sock" - PGID=$(ls -nd /var/run/docker.sock | awk '{print $4}') + PGID="$DOCKER_PGID" fi export PGID export DOCKER_HOST @@ -37,12 +44,19 @@ if [ -n "${PGID}" ]; then usermod -a -G "${PGID}" "${DOCKER_USR}" || echo >&2 "Could not add netdata user to group docker with ID ${PGID}" fi +if mountpoint -q /etc/netdata && [ -z "$(ls -A /etc/netdata)" ]; then + echo "Copying stock configuration to /etc/netdata" + cp -a /etc/netdata.stock/. /etc/netdata +fi + if [ -n "${NETDATA_CLAIM_URL}" ] && [ -n "${NETDATA_CLAIM_TOKEN}" ] && [ ! -f /var/lib/netdata/cloud.d/claimed_id ]; then + # shellcheck disable=SC2086 /usr/sbin/netdata-claim.sh -token="${NETDATA_CLAIM_TOKEN}" \ -url="${NETDATA_CLAIM_URL}" \ ${NETDATA_CLAIM_ROOMS:+-rooms="${NETDATA_CLAIM_ROOMS}"} \ ${NETDATA_CLAIM_PROXY:+-proxy="${NETDATA_CLAIM_PROXY}"} \ + ${NETDATA_EXTRA_CLAIM_OPTS} \ -daemon-not-running fi -exec /usr/sbin/netdata -u "${DOCKER_USR}" -D -s /host -p "${NETDATA_LISTENER_PORT}" -W set web "web files group" root -W set web "web files owner" root "$@" +exec /usr/sbin/netdata -u "${DOCKER_USR}" -D -s /host -p "${NETDATA_LISTENER_PORT}" "$@" diff --git a/packaging/ebpf-co-re.checksums b/packaging/ebpf-co-re.checksums new file mode 100644 index 000000000..ec7a07abc --- /dev/null +++ b/packaging/ebpf-co-re.checksums @@ -0,0 +1 @@ +0e3a6928a9b69a1a1e7911635b6d6fda44e78b67a3e38daad9d8cc3babfcdfee netdata-ebpf-co-re-glibc-v0.9.3.2.tar.xz diff --git a/packaging/ebpf-co-re.version b/packaging/ebpf-co-re.version new file mode 100644 index 000000000..87752222e --- /dev/null +++ b/packaging/ebpf-co-re.version @@ -0,0 +1 @@ +v0.9.3.2 diff --git a/packaging/ebpf.checksums b/packaging/ebpf.checksums index d98e99b0a..dc5ce6cf1 100644 --- a/packaging/ebpf.checksums +++ b/packaging/ebpf.checksums @@ -1,3 +1,3 @@ -44f21082c348b81f73034a986904207ee050379d51d6a6733a71323f2d36c8dd netdata-kernel-collector-glibc-v0.9.0.tar.xz -9589070de6b7fe29fb0ea8f23394625c2887ddf3007bca9e65cfdb11ce41a7f7 netdata-kernel-collector-musl-v0.9.0.tar.xz -f39c5c97f10d08ce72551a64aef8f9264346608e7d215afc910a5fe2158db868 netdata-kernel-collector-static-v0.9.0.tar.xz +cee483b29e1fd3125d635d03f9266d267eab1ba13e02c99afcf6a84bdcb729f4 ./netdata-kernel-collector-glibc-v0.9.3.tar.xz +33aeae2cf7e9c0967c62f262bf6c6c44db49dc5dbb6d3a16e8bfde4433779069 ./netdata-kernel-collector-musl-v0.9.3.tar.xz +9eba23184be7c9b29d22271e439e3fac517d32d500bd796c4e21f653b6f4d337 ./netdata-kernel-collector-static-v0.9.3.tar.xz diff --git a/packaging/ebpf.version b/packaging/ebpf.version index f979adec6..188bef592 100644 --- a/packaging/ebpf.version +++ b/packaging/ebpf.version @@ -1 +1 @@ -v0.9.0 +v0.9.3 diff --git a/packaging/go.d.checksums b/packaging/go.d.checksums index 38e6266da..e6b2dceb4 100644 --- a/packaging/go.d.checksums +++ b/packaging/go.d.checksums @@ -1,16 +1,16 @@ -76e94278ceefb85114dd28f120620b7702fa42766970943b0862863e25404cc8 *config.tar.gz -c32139dac787601da92f0bee3d7401fe50f20cde27aab0c902b470c8779b308b *go.d.plugin-v0.31.2.darwin-amd64.tar.gz -2092e64f0b86fc9f3623614c4f1da55eaca599d79fa54774d00156eec422f0a0 *go.d.plugin-v0.31.2.freebsd-386.tar.gz -02d8a5fb3fee3de629fd933889d4cab6e049a780a5b382d566a8cc3baf099d9a *go.d.plugin-v0.31.2.freebsd-amd64.tar.gz -a488f4b1c0cc5b44e89432343dfe5941c977995d729ce7ea516b92570ca712fc *go.d.plugin-v0.31.2.freebsd-arm64.tar.gz -5c054378676527b8d736f0962c33367e456099ac33cc53fb7f91cc67f6a89d08 *go.d.plugin-v0.31.2.freebsd-arm.tar.gz -178f2a6ffe93dd4593bfc830cff6987949f4e32f2a52a225cb86256b35daa266 *go.d.plugin-v0.31.2.linux-386.tar.gz -4c2936e42a924339f1145144e228fdd73871bbb08960f8e42753a0cc8ce6db8e *go.d.plugin-v0.31.2.linux-amd64.tar.gz -58dd5a893764b127ab90b73512c37d5c9d01bd73aade817ed1d728ec89edec0c *go.d.plugin-v0.31.2.linux-arm64.tar.gz -9b86ca8b438aacf0844466f7ba2a0a239ea3298fc5ddf19049a86bb930143932 *go.d.plugin-v0.31.2.linux-arm.tar.gz -a4a4424058fdb3f99ee07fa112ba71270fa8620ab85074e14bb620fff7849649 *go.d.plugin-v0.31.2.linux-mips64le.tar.gz -bd0fe2e815bbe56a555e9c486c6d36e9a9726f9fea5d82f58d77c988cb2b9abb *go.d.plugin-v0.31.2.linux-mips64.tar.gz -1a99dc67deea941281fa9f8b61db6efa8be5d95142ac8f6332fb52b2f3575d4f *go.d.plugin-v0.31.2.linux-mipsle.tar.gz -9a4d4eae52b9b2a50944de5e8a8340d71a397f421fe4c093a65e5282a3f27f2d *go.d.plugin-v0.31.2.linux-mips.tar.gz -25ef59e2bb79fa9ea9fa43a96b365c5ef13da7188f0de8f82541a829b5a60add *go.d.plugin-v0.31.2.linux-ppc64le.tar.gz -68c31790599800ded99a9f0095620850ec1bc1360a3a38414fcfd79d5b585778 *go.d.plugin-v0.31.2.linux-ppc64.tar.gz \ No newline at end of file +756173c6636ad285e7e41d87880780051af7ea1e587acf865e03e3d69f1e9f76 *config.tar.gz +272fcfb626f8c899dd2fb801054f2326fc684bcf0573f4e248d8fd666266ed7d *go.d.plugin-v0.32.2.darwin-amd64.tar.gz +0966ac55887c0b7296a2fd0b7289710dcaadd1fd958c85848953170896b27deb *go.d.plugin-v0.32.2.freebsd-386.tar.gz +e7582216ed5d86e899af73116c4b7fd116e44f2d58e78e1449c078098ff89254 *go.d.plugin-v0.32.2.freebsd-amd64.tar.gz +6fbf4b5fe0db0a2248ba7ca50fa25069289afe6fa48689a00db3a3b806d78562 *go.d.plugin-v0.32.2.freebsd-arm.tar.gz +75e571dbd919bf24ecff403ab1a9f7abda768b3d0f11f541ba9e7de499c106cd *go.d.plugin-v0.32.2.freebsd-arm64.tar.gz +80ba16a9368acd797b57b9d8d91b336e37cf5205393df95d98a5c978cc4ce6c2 *go.d.plugin-v0.32.2.linux-386.tar.gz +cb7ee8a199212ef15ff83f441186c573bbb4c638cf7251dbbec70f7cdb5ea0a4 *go.d.plugin-v0.32.2.linux-amd64.tar.gz +614c70ae0d332c47eab57a6b3422c2d620b0fff323378e72e81d18158662fbc0 *go.d.plugin-v0.32.2.linux-arm.tar.gz +bed2d5c7bf7bd547d1c32c8d1520e21ba4500a022d2a5c27ad05778a428bdb33 *go.d.plugin-v0.32.2.linux-arm64.tar.gz +2d111d268f454a1e116cae8fd3c0dbeb627c933031ca64b9d9909b64b10496d9 *go.d.plugin-v0.32.2.linux-mips.tar.gz +c6dc76a12de2ac94a5fe67adf482937bd5dad9396a5da68b3c5afa286e7b9d99 *go.d.plugin-v0.32.2.linux-mips64.tar.gz +e5829378c043d01f7d1aa5f8870d6952fc1203f233dbf056f86ac1c202261469 *go.d.plugin-v0.32.2.linux-mips64le.tar.gz +7d76f353cbcfead7a3992f1e73db143cc1fbbaec8fd2701227a611ae621037e6 *go.d.plugin-v0.32.2.linux-mipsle.tar.gz +b69175675d38fe046d2c3ec4a4a6ba1c99e1c2132d6d95abb369b9499f6cd5b5 *go.d.plugin-v0.32.2.linux-ppc64.tar.gz +7c17cbd172cdeeec547ab9fddcf7f58b27be91ecfb8eabb964817556263b0f70 *go.d.plugin-v0.32.2.linux-ppc64le.tar.gz diff --git a/packaging/go.d.version b/packaging/go.d.version index c11797e18..c6a2605c4 100644 --- a/packaging/go.d.version +++ b/packaging/go.d.version @@ -1 +1 @@ -v0.31.2 +v0.32.2 diff --git a/packaging/installer/README.md b/packaging/installer/README.md index f2f826edb..2854d0723 100644 --- a/packaging/installer/README.md +++ b/packaging/installer/README.md @@ -188,26 +188,21 @@ visit the Agent dashboard at `http://NODE:19999`, you need to update Netdata's p system. Run `ls -la /usr/share/netdata/web/index.html` to find the file's permissions. You may need to change this path based on -the error you're seeing in your browser. In the below example, the file is owned by the user `netdata` and the group -`netdata`. +the error you're seeing in your browser. In the below example, the file is owned by the user `root` and the group +`root`. ```bash ls -la /usr/share/netdata/web/index.html --rw-r--r--. 1 netdata netdata 89377 May 5 06:30 /usr/share/netdata/web/index.html +-rw-r--r--. 1 root root 89377 May 5 06:30 /usr/share/netdata/web/index.html ``` -Open your `netdata.conf` file and find the `[web]` section, plus the `web files owner`/`web files group` settings. Edit -the lines to match the output from `ls -la` above and uncomment them if necessary. +These files need to have the same user and group used to install your netdata. Suppose you installed netdata with user +`netdata` and group `netdata`, in this scenario you will need to run the following command to fix the error: -```conf -[web] - web files owner = netdata - web files group = netdata +```bash +# chown -R netdata.netdata /usr/share/netdata/web ``` -Save the file, restart Netdata using `sudo systemctl restart netdata`, or the [appropriate -method](/docs/configure/start-stop-restart.md) for your system, and try accessing the dashboard again. - ### Multiple versions of OpenSSL We've received reports from the community about issues with running the `kickstart.sh` script on systems that have both @@ -220,4 +215,4 @@ Our current build process has some issues when using certain configurations of t section on `nonrepresentable section on output` errors](/packaging/installer/methods/manual.md#nonrepresentable-section-on-output-errors) for a workaround. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fpackaging%2Finstaller%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/packaging/installer/REINSTALL.md b/packaging/installer/REINSTALL.md index 1398551df..ddfc8bcb5 100644 --- a/packaging/installer/REINSTALL.md +++ b/packaging/installer/REINSTALL.md @@ -33,4 +33,4 @@ installer](/packaging/installer/methods/kickstart.md). You can also post to our [community forums](https://community.netdata.cloud/c/support/13) or create a new [bug report](https://github.com/netdata/netdata/issues/new?assignees=&labels=bug%2Cneeds+triage&template=BUG_REPORT.yml). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Finstaller%2FREINSTALL&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/packaging/installer/UNINSTALL.md b/packaging/installer/UNINSTALL.md index c18a1bfc8..87c76ca65 100644 --- a/packaging/installer/UNINSTALL.md +++ b/packaging/installer/UNINSTALL.md @@ -51,4 +51,4 @@ The default `environment_file` is `/etc/netdata/.environment`. > Note: This uninstallation method assumes previous installation with `netdata-installer.sh` or the kickstart script. > Currently using it when Netdata was installed by a package manager can work or cause unexpected results. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Finstaller%2FUNINSTALL&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/packaging/installer/UPDATE.md b/packaging/installer/UPDATE.md index 8230d00cd..009e970f2 100644 --- a/packaging/installer/UPDATE.md +++ b/packaging/installer/UPDATE.md @@ -6,8 +6,9 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/packaging/instal # Update the Netdata Agent -By default, the Netdata Agent automatically updates with the latest nightly version. If you opted out of automatic -updates, you need to update your Netdata Agent to the latest nightly or stable version. +By default, the Netdata Agent automatically updates with the latest nightly or stable version depending on which +you installed. If you opted out of automatic updates, you need to update your Netdata Agent to the latest nightly +or stable version. You can also [enable or disable automatic updates on an existing install](#control-automatic-updates). > 💡 Looking to reinstall the Netdata Agent to enable a feature, update an Agent that cannot update automatically, or > troubleshoot an error during the installation process? See our [reinstallation doc](/packaging/installer/REINSTALL.md) @@ -16,32 +17,43 @@ updates, you need to update your Netdata Agent to the latest nightly or stable v Before you update the Netdata Agent, check to see if your Netdata Agent is already up-to-date by clicking on the update icon in the local Agent dashboard's top navigation. This modal informs you whether your Agent needs an update or not. -![Opening the Agent's Update modal](https://user-images.githubusercontent.com/1153921/99738428-add06780-2a87-11eb-8268-0e17b689eb3f.gif) +The exact update method to use depends on the install type: + +- Installs with an install type of 'custom' usually indicate installing a third-party package through the system + package manager. To update these installs, you should update the package just like you would any other package + on your system. +- Installs with an install type starting with `binpkg` or ending with `build` or `static` can be updated using + our [regular update method](#updates-for-most-systems). +- Installs with an install type of 'oci' were created from our official Docker images, and should be updated + using our [Docker](#docker) update procedure. +- macOS users should check [our update instructions for macOS](#macos). +- Manually built installs should check [our update instructions for manual builds](#manual-installation-from-git). ## Determine which installation method you used -If you are not sure where your Netdata config directory is, see the [configuration doc](/docs/configure/nodes.md). In -most installations, this is `/etc/netdata`. +Starting with netdata v1.33.0, you can use Netdata itself to determine the installation type by running: + +```bash +netdata -W buildinfo | grep 'Install type:' +``` + +If you are using an older version of Netdata, or the above command produces no output, you can run our one-line +installation script in dry-run mode to attempt to determine what method to use to update by running the following +command: -Use `cd` to navigate to the Netdata config directory, then use `ls -a` to look for a file called `.install-type`. +```bash +wget -O /tmp/netdata-kickstart.sh https://my-netdata.io/kickstart.sh && sh /tmp/netdata-kickstart.sh --dry-run +``` -- If the `.install-type` file doex not exist, look for a file in the same directory called `.environment`. - - If the `.environment` file does not exist, you probably installed Netdata using your system package manager - and should update it the same way you would run updates on the system itself. - - If the `.environment` file does exist, then our [regular update method](#updates-for-most-systems) should - work correctly. -- If the `.install-type` file does exist, check it’s contents with `cat .install-type`. - - If the `INSTALL_TYPE` key has a value of `custom`, you probably installed Netdata using your system - package manager and should update it the same way you would run updates on the system itself. - - If the `INSTALL_TYPE` key has a value of `oci`, the install is from a Docker image. - - Otherwise, the install should work with our [regular update method](#updates-for-most-systems). +Note that if you installed Netdata using an installation prefix, you will need to add an `--install` option +specifying that prefix to make sure it finds the existing install. -Next, use the appropriate method to update the Netdata Agent: +If you see a line starting with `--- Would attempt to update existing installation by running the updater script +located at:`, then our [regular update method](#updates-for-most-systems) will work for you. -- [Updates for most systems](#updates-for-most-systems) -- [Docker](#docker) -- [macOS](#macos) -- [Manual installation from Git](#manual-installation-from-git) +Otherwise, it should either indicate that the installation type is not supported (which probably means you either +have a `custom` instal or built Netdata manually) or indicate that it would create a new install (which means that +you either used a non-standard install path, or that you don’t actually have Netdata installed). ## Updates for most systems @@ -56,9 +68,21 @@ that prefix to this command to make sure it finds Netdata. wget -O /tmp/netdata-kickstart.sh https://my-netdata.io/kickstart.sh && sh /tmp/netdata-kickstart.sh ``` -> ❗ If the above command fails, you can [reinstall -> Netdata](/packaging/installer/REINSTALL.md#one-line-installer-script-kickstartsh) to get the latest version. This also -> preserves your [configuration](/docs/configure/nodes.md) in `netdata.conf` or other files. +### Issues with older binpkg installs + +The above command is known not to work with binpkg type installs for stable releases with a version number of +v1.33.1 or earlier, and nightly builds with a version number of v1.33.1-93 or earlier. If you have such a system, +the above command will report that it found an existing install, and then issue a warning about not being able to +find the updater script. + +On such installs, you can update Netdata using your distribution package manager. + +### If the kickstart script does not work + +If the above command fails, you can [reinstall +Netdata](/packaging/installer/REINSTALL.md#one-line-installer-script-kickstartsh) to get the latest version. This +also preserves your [configuration](/docs/configure/nodes.md) in `netdata.conf` or other files just like updating +normally would, though you will need to specify any installation options you used originally again. ## Docker @@ -95,6 +119,9 @@ Homebrew downloads the latest Netdata via the [formulae](https://github.com/Homebrew/homebrew-core/blob/master/Formula/netdata.rb), ensures all dependencies are met, and updates Netdata via reinstallation. +If you instead installed Netdata using our one-line installation script, you can use our [regular update +instructions](#updates-for-most-systems) to update Netdata. + ## Manual installation from Git If you installed [Netdata manually from Git](/packaging/installer/methods/manual.md), you can run that installer again @@ -117,4 +144,31 @@ sudo ./netdata-installer.sh > ⚠️ If you installed Netdata with any optional parameters, such as `--no-updates` to disable automatic updates, and > want to retain those settings, you need to set them again during this process. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Finstaller%2FUPDATE&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) +## Control automatic updates + +Starting with Netdata v1.34.0, you can easily enable or disable automatic updates on an existing installation +using the updater script. + +For most installs on Linux, you can enable auto-updates with: + +```bash +/usr/libexec/netdata/netdata-updater.sh --enable-auto-updates +``` + +and disable them with: + +```bash +/usr/libexec/netdata/netdata-updater.sh --disable-auto-updates +``` + +For static installs, instead use: + +```bash +/opt/netdata/usr/libexec/netdata/netdata-updater.sh --enable-auto-updates +``` + +and: + +```bash +/opt/netdata/usr/libexec/netdata/netdata-updater.sh --disable-auto-updates +``` diff --git a/packaging/installer/dependencies/alpine.sh b/packaging/installer/dependencies/alpine.sh index 8cbd98adf..cc3908d29 100755 --- a/packaging/installer/dependencies/alpine.sh +++ b/packaging/installer/dependencies/alpine.sh @@ -16,6 +16,7 @@ package_tree=" autoconf cmake make + libatomic libtool pkgconfig tar diff --git a/packaging/installer/dependencies/centos.sh b/packaging/installer/dependencies/centos.sh index d17911664..738a0ce75 100755 --- a/packaging/installer/dependencies/centos.sh +++ b/packaging/installer/dependencies/centos.sh @@ -12,6 +12,7 @@ declare -a package_tree=( autoconf-archive autogen automake + libatomic libtool pkgconfig cmake @@ -36,7 +37,7 @@ os_version() { # shellcheck disable=SC2002 cat /etc/os-release | grep VERSION_ID | cut -d'=' -f2 | cut -d'"' -f2 else - echo "Erorr: Cannot determine OS version!" + echo "Error: Cannot determine OS version!" exit 1 fi } diff --git a/packaging/installer/dependencies/debian.sh b/packaging/installer/dependencies/debian.sh index 66a4b6826..e8c2d0c6c 100755 --- a/packaging/installer/dependencies/debian.sh +++ b/packaging/installer/dependencies/debian.sh @@ -17,6 +17,7 @@ package_tree=" autoconf autoconf-archive autogen + libatomic1 libtool pkg-config tar diff --git a/packaging/installer/dependencies/fedora.sh b/packaging/installer/dependencies/fedora.sh index edb695bca..62a129f4c 100755 --- a/packaging/installer/dependencies/fedora.sh +++ b/packaging/installer/dependencies/fedora.sh @@ -12,7 +12,7 @@ os_version() { # shellcheck disable=SC2002 cat /etc/os-release | grep VERSION_ID | cut -d'=' -f2 else - echo "Erorr: Cannot determine OS version!" + echo "Error: Cannot determine OS version!" exit 1 fi } @@ -32,6 +32,7 @@ declare -a package_tree=( autoconf-archive autogen automake + libatomic libtool cmake nmap-ncat diff --git a/packaging/installer/dependencies/ol.sh b/packaging/installer/dependencies/ol.sh index 4b95722a8..8d0feb3f5 100755 --- a/packaging/installer/dependencies/ol.sh +++ b/packaging/installer/dependencies/ol.sh @@ -15,6 +15,7 @@ declare -a package_tree=( autoconf-archive autogen automake + libatomic libtool pkgconfig cmake diff --git a/packaging/installer/dependencies/opensuse.sh b/packaging/installer/dependencies/opensuse.sh index cfaaf6753..7c5b840e7 100755 --- a/packaging/installer/dependencies/opensuse.sh +++ b/packaging/installer/dependencies/opensuse.sh @@ -17,6 +17,7 @@ declare -a package_tree=( autoconf-archive autogen automake + libatomic1 libtool pkg-config cmake diff --git a/packaging/installer/dependencies/rockylinux.sh b/packaging/installer/dependencies/rockylinux.sh index 1cf07fc58..92050a457 100755 --- a/packaging/installer/dependencies/rockylinux.sh +++ b/packaging/installer/dependencies/rockylinux.sh @@ -15,6 +15,7 @@ declare -a package_tree=( autoconf-archive autogen automake + libatomic libtool pkgconfig cmake diff --git a/packaging/installer/dependencies/ubuntu.sh b/packaging/installer/dependencies/ubuntu.sh index 3d0bb5959..2bf116a11 100755 --- a/packaging/installer/dependencies/ubuntu.sh +++ b/packaging/installer/dependencies/ubuntu.sh @@ -17,6 +17,7 @@ package_tree=" autoconf autoconf-archive autogen + libatomic1 libtool pkg-config tar diff --git a/packaging/installer/functions.sh b/packaging/installer/functions.sh index 56f1a5658..471e64571 100644 --- a/packaging/installer/functions.sh +++ b/packaging/installer/functions.sh @@ -632,7 +632,7 @@ stop_all_netdata() { fi fi - if [ -n "$(netdata_pids)" ] && [ -n "$(type netdatacli)" ]; then + if [ -n "$(netdata_pids)" ] && [ -n "$(command -v netdatacli)" ]; then netdatacli shutdown-agent sleep 20 fi @@ -667,7 +667,7 @@ restart_netdata() { # shellcheck disable=SC2086 run ${NETDATA_INSTALLER_START_CMD} && started=1 - if [ ${started} -eq 1 ] && [ -z "$(netdata_pids)" ]; then + if [ ${started} -eq 1 ] && sleep 5 && [ -z "$(netdata_pids)" ]; then echo >&2 "Ooops! it seems netdata is not started." started=0 fi @@ -677,13 +677,14 @@ restart_netdata() { # shellcheck disable=SC2086 run ${NETDATA_INSTALLER_START_CMD} && started=1 fi - fi - if [ ${started} -eq 1 ] && [ -z "$(netdata_pids)" ]; then - echo >&2 "Hm... it seems netdata is still not started." - started=0 + if [ ${started} -eq 1 ] && sleep 5 && [ -z "$(netdata_pids)" ]; then + echo >&2 "Hm... it seems netdata is still not started." + started=0 + fi fi + if [ ${started} -eq 0 ]; then # still not started... another forced attempt, just run the binary echo >&2 "Netdata service still not started, attempting another forced restart by running '${netdata} ${*}'" @@ -968,76 +969,6 @@ cleanup_old_netdata_updater() { return 0 } -enable_netdata_updater() { - - if [ -n "${1}" ] ; then - updater_type="${1}" - else - updater_type="$(_get_scheduler_type)" - fi - - case "${updater_type}" in - "systemd") - systemctl enable netdata-updater.timer - - echo >&2 "Auto-updating has been enabled using a systemd timer unit." - echo >&2 - echo >&2 "If the update process fails, the failure will be logged to the systemd journal just like a regular service failure." - echo >&2 "Successful updates should produce empty logs." - echo >&2 - ;; - "interval") - ln -sf "${NETDATA_PREFIX}/usr/libexec/netdata/netdata-updater.sh" "$(_get_intervaldir)/netdata-updater" - - echo >&2 "Auto-updating has been enabled through cron, updater script linked to ${TPUT_RED}${TPUT_BOLD}$(_get_intervaldir)/netdata-updater${TPUT_RESET}" - echo >&2 - echo >&2 "If the update process fails and you have email notifications set up correctly for cron on this system, you should receive an email notification of the failure." - echo >&2 "Successful updates will not send an email." - echo >&2 - ;; - "crontab") - cat "${NETDATA_SOURCE_DIR}/system/netdata.crontab" > "/etc/cron.d/netdata-updater" - - echo >&2 "Auto-updating has been enabled through cron, using a crontab at ${TPUT_RED}${TPUT_BOLD}/etc/cron.d/netdata-updater${TPUT_RESET}" - echo >&2 - echo >&2 "If the update process fails and you have email notifications set up correctly for cron on this system, you should receive an email notification of the failure." - echo >&2 "Successful updates will not send an email." - echo >&2 - ;; - *) - echo >&2 "Unable to determine what type of auto-update scheduling to use, not enabling auto-updates." - echo >&2 - return 1 - esac - - return 0 -} - -disable_netdata_updater() { - echo >&2 "You chose *NOT* to enable auto-update, removing any links to the updater from cron (it may have happened if you are reinstalling)" - echo >&2 - - if issystemd && [ -n "$(get_systemd_service_dir)" ] ; then - systemctl disable netdata-updater.timer - fi - - if [ -d /etc/cron.daily ]; then - rm -f /etc/cron.daily/netdata-updater.sh - rm -f /etc/cron.daily/netdata-updater - fi - - if [ -d /etc/periodic/daily ]; then - rm -f /etc/periodic/daily/netdata-updater.sh - rm -f /etc/periodic/daily/netdata-updater - fi - - if [ -d /etc/cron.d ]; then - rm -f /etc/cron.d/netdata-updater - fi - - return 0 -} - set_netdata_updater_channel() { sed -i -e "s/^RELEASE_CHANNEL=.*/RELEASE_CHANNEL=\"${RELEASE_CHANNEL}\"/" "${NETDATA_USER_CONFIG_DIR}/.environment" } diff --git a/packaging/installer/install-required-packages.sh b/packaging/installer/install-required-packages.sh index 52fdc348c..7bfbeaafb 100755 --- a/packaging/installer/install-required-packages.sh +++ b/packaging/installer/install-required-packages.sh @@ -198,7 +198,7 @@ get_os_release() { eval "$(grep -E "^(NAME|ID|ID_LIKE|VERSION|VERSION_ID)=" "${os_release_file}")" for x in "${ID}" ${ID_LIKE}; do case "${x,,}" in - alpine | arch | centos | clear-linux-os | debian | fedora | gentoo | manjaro | opensuse-leap | ol | rhel | rocky | sabayon | sles | suse | ubuntu) + almalinux | alpine | arch | centos | clear-linux-os | debian | fedora | gentoo | manjaro | opensuse-leap | ol | rhel | rocky | sabayon | sles | suse | ubuntu) distribution="${x}" version="${VERSION_ID}" codename="${VERSION}" @@ -419,12 +419,12 @@ detect_package_manager_from_distribution() { fi ;; - centos* | clearos* | rocky*) + centos* | clearos* | rocky* | almalinux*) package_installer="" tree="centos" - [ -n "${dnf}" ] && package_installer="install_dnf" [ -n "${yum}" ] && package_installer="install_yum" - if [ "${IGNORE_INSTALLED}" -eq 0 ] && [ -z "${yum}" ]; then + [ -n "${dnf}" ] && package_installer="install_dnf" + if [ "${IGNORE_INSTALLED}" -eq 0 ] && [ -z "${package_installer}" ]; then echo >&2 "command 'yum' or 'dnf' is required to install packages on a '${distribution} ${version}' system." exit 1 fi @@ -433,8 +433,8 @@ detect_package_manager_from_distribution() { fedora* | redhat* | red\ hat* | rhel*) package_installer= tree="rhel" - [ -n "${dnf}" ] && package_installer="install_dnf" [ -n "${yum}" ] && package_installer="install_yum" + [ -n "${dnf}" ] && package_installer="install_dnf" if [ "${IGNORE_INSTALLED}" -eq 0 ] && [ -z "${package_installer}" ]; then echo >&2 "command 'yum' or 'dnf' is required to install packages on a '${distribution} ${version}' system." exit 1 @@ -444,8 +444,8 @@ detect_package_manager_from_distribution() { ol*) package_installer= tree="ol" - [ -n "${dnf}" ] && package_installer="install_dnf" [ -n "${yum}" ] && package_installer="install_yum" + [ -n "${dnf}" ] && package_installer="install_dnf" if [ "${IGNORE_INSTALLED}" -eq 0 ] && [ -z "${package_installer}" ]; then echo >&2 "command 'yum' or 'dnf' is required to install packages on a '${distribution} ${version}' system." exit 1 @@ -699,6 +699,19 @@ declare -A pkg_json_c_dev=( ['default']="json-c-devel" ) +declare -A pkg_libatomic=( + ['arch']="NOTREQUIRED" + ['clearlinux']="NOTREQUIRED" + ['debian']="libatomic1" + ['freebsd']="NOTREQUIRED" + ['gentoo']="NOTREQUIRED" + ['macos']="NOTREQUIRED" + ['sabayon']="NOTREQUIRED" + ['suse']="libatomic1" + ['ubuntu']="libatomic1" + ['default']="libatomic" +) + declare -A pkg_bridge_utils=( ['gentoo']="net-misc/bridge-utils" ['clearlinux']="network-basic" @@ -1339,6 +1352,7 @@ packages() { # basic build environment suitable_package distro-sdk + suitable_package libatomic require_cmd git || suitable_package git require_cmd find || suitable_package find diff --git a/packaging/installer/kickstart.sh b/packaging/installer/kickstart.sh index 3f1197407..ffc951559 100755 --- a/packaging/installer/kickstart.sh +++ b/packaging/installer/kickstart.sh @@ -5,9 +5,16 @@ # ====================================================================== # Constants +AGENT_BUG_REPORT_URL="https://github.com/netdata/netdata/issues/new/choose" +CLOUD_BUG_REPORT_URL="https://github.com/netdata/netdata-cloud/issues/new/choose" +DISCUSSIONS_URL="https://github.com/netdata/netdata/discussions" +DISCORD_INVITE="https://discord.gg/5ygS846fR6" +DOCS_URL="https://learn.netdata.cloud/docs/" +FORUM_URL="https://community.netdata.cloud/" KICKSTART_OPTIONS="${*}" PACKAGES_SCRIPT="https://raw.githubusercontent.com/netdata/netdata/master/packaging/installer/install-required-packages.sh" PATH="${PATH}:/usr/local/bin:/usr/local/sbin" +PUBLIC_CLOUD_URL="https://app.netdata.cloud" REPOCONFIG_URL_PREFIX="https://packagecloud.io/netdata/netdata-repoconfig/packages" REPOCONFIG_VERSION="1-1" TELEMETRY_URL="https://posthog.netdata.cloud/capture/" @@ -16,20 +23,29 @@ START_TIME="$(date +%s)" # ====================================================================== # Defaults for environment variables +DRY_RUN=0 SELECTED_INSTALL_METHOD="none" INSTALL_TYPE="unknown" INSTALL_PREFIX="" NETDATA_AUTO_UPDATES="1" NETDATA_CLAIM_ONLY=0 -NETDATA_CLAIM_URL="https://app.netdata.cloud" +NETDATA_CLAIM_URL="${PUBLIC_CLOUD_URL}" NETDATA_DISABLE_CLOUD=0 NETDATA_ONLY_BUILD=0 NETDATA_ONLY_NATIVE=0 NETDATA_ONLY_STATIC=0 NETDATA_REQUIRE_CLOUD=1 RELEASE_CHANNEL="nightly" +WARNINGS="" + +if [ -n "$DISABLE_TELEMETRY" ]; then + NETDATA_DISABLE_TELEMETRY="${DISABLE_TELEMETRY}" +elif [ -n "$DO_NOT_TRACK" ]; then + NETDATA_DISABLE_TELEMETRY="${DO_NOT_TRACK}" +else + NETDATA_DISABLE_TELEMETRY=0 +fi -NETDATA_DISABLE_TELEMETRY="${DO_NOT_TRACK:-0}" NETDATA_TARBALL_BASEURL="${NETDATA_TARBALL_BASEURL:-https://storage.googleapis.com/netdata-nightlies}" NETDATA_INSTALLER_OPTIONS="${NETDATA_INSTALLER_OPTIONS:-""}" TELEMETRY_API_KEY="${NETDATA_POSTHOG_API_KEY:-mqkwGT0JNFqO-zX2t0mW6Tec9yooaVu7xCBlXtHnt5Y}" @@ -44,6 +60,56 @@ else INTERACTIVE=1 fi +main() { + if [ "${ACTION}" = "uninstall" ]; then + uninstall + printf >&2 "Finished uninstalling the Netdata Agent." + deferred_warnings + cleanup + trap - EXIT + exit 0 + fi + + if [ "${ACTION}" = "reinstall-clean" ]; then + NEW_INSTALL_PREFIX="${INSTALL_PREFIX}" + uninstall + cleanup + + ACTION= + INSTALL_PREFIX="${NEW_INSTALL_PREFIX}" + # shellcheck disable=SC2086 + main + + trap - EXIT + exit 0 + fi + + tmpdir="$(create_tmp_directory)" + progress "Using ${tmpdir} as a temporary directory." + cd "${tmpdir}" || fatal "Failed to change current working directory to ${tmpdir}." F000A + + case "${SYSTYPE}" in + Linux) install_on_linux ;; + Darwin) install_on_macos ;; + FreeBSD) install_on_freebsd ;; + esac + + if [ -n "${NETDATA_CLAIM_TOKEN}" ]; then + claim + elif [ "${NETDATA_DISABLE_CLOUD}" -eq 1 ]; then + soft_disable_cloud + fi + + set_auto_updates + + printf >&2 "%s\n\n" "Successfully installed the Netdata Agent." + deferred_warnings + success_banner + telemetry_event INSTALL_SUCCESS "" "" + cleanup + trap - EXIT +} + # ====================================================================== # Usage info @@ -55,10 +121,12 @@ USAGE: kickstart.sh [options] --non-interactive Do not prompt for user input. (default: prompt if there is a controlling terminal) --interactive Prompt for user input even if there is no controlling terminal. --dont-start-it Do not start the agent by default (only for static installs or local builds) + --dry-run Report what we would do with the given options on this system, but don’t actually do anything. --stable-channel Install a stable version instead of a nightly build (default: install a nightly build) --nightly-channel Install a nightly build instead of a stable version - --no-updates Do not enable automatic updates (default: enable automatic updates) + --no-updates Do not enable automatic updates (default: enable automatic updates using the best supported scheduling method) --auto-update Enable automatic updates. + --auto-update-type Specify a particular scheduling type for auto-updates (valid types: systemd, interval, crontab) --disable-telemetry Opt-out of anonymous statistics. --native-only Only install if native binary packages are available. --static-only Only install if a static build is available. @@ -68,11 +136,14 @@ USAGE: kickstart.sh [options] --disable-cloud Disable support for Netdata Cloud (default: detect) --require-cloud Only install if Netdata Cloud can be enabled. Overrides --disable-cloud. --install Specify an installation prefix for local builds (default: autodetect based on system type). + --old-install-prefix Specify an old local builds installation prefix for uninstall/reinstall (if it's not default). --claim-token Use a specified token for claiming to Netdata Cloud. --claim-rooms When claiming, add the node to the specified rooms. --claim-only If there is an existing install, only try to claim it, not update it. --claim-* Specify other options for the claiming script. --no-cleanup Don't do any cleanup steps. This is intended to help with debugging the installer. + --uninstall Uninstall an existing installation of Netdata. + --reinstall-clean Clean reinstall Netdata. Additionally, this script may use the following environment variables: @@ -83,7 +154,7 @@ Additionally, this script may use the following environment variables: default we try to use sudo, doas, or pkexec (in that order of preference), but if you need special options for one of those to work, or have a different tool to do the same thing on your system, you can specify it here. - DO_NOT_TRACK If set to a value other than 0, behave as if \`--disable-telemetry\` was specified. + DISABLE_TELEMETRY If set to a value other than 0, behave as if \`--disable-telemetry\` was specified. NETDATA_INSTALLER_OPTIONS: Specifies extra options to pass to the static installer or local build script. HEREDOC @@ -93,7 +164,7 @@ HEREDOC # Telemetry functions telemetry_event() { - if [ "${NETDATA_DISABLE_TELEMETRY}" -eq 1 ]; then + if [ "${NETDATA_DISABLE_TELEMETRY}" -eq 1 ] || [ "${DRY_RUN}" -eq 1 ]; then return 0 fi @@ -130,7 +201,7 @@ telemetry_event() { if [ -f /etc/machine-id ]; then DISTINCT_ID="$(cat /etc/machine-id)" elif command -v uuidgen > /dev/null 2>&1; then - DISTINCT_ID="$(uuidgen)" + DISTINCT_ID="$(uuidgen | tr '[:upper:]' '[:lower:]')" else DISTINCT_ID="null" fi @@ -185,8 +256,21 @@ trap_handler() { code="${1}" lineno="${2}" + deferred_warnings + printf >&2 "%s\n\n" "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD} ERROR ${TPUT_RESET} Installer exited unexpectedly (${code}-${lineno})" + case "${code}" in + 0) + printf >&2 "%s\n" "This is almost certainly the result of a bug. If you have time, please report it at ${AGENT_BUG_REPORT_URL}." + ;; + *) + printf >&2 "%s\n" "This is probably a result of a transient issue on your system. Things should work correctly if you try again." + printf >&2 "%s\n" "If you continue to experience this issue, you can reacn out to us for support on:" + support_list + ;; + esac + telemetry_event INSTALL_CRASH "Installer exited unexpectedly (${code}-${lineno})" "E${code}-${lineno}" trap - EXIT @@ -234,38 +318,58 @@ setup_terminal() { return 0 } +support_list() { + printf >&2 "%s\n" " - GitHub: ${DISCUSSIONS_URL}" + printf >&2 "%s\n" " - Discord: ${DISCORD_INVITE}" + printf >&2 "%s\n" " - Our community forums: ${FORUM_URL}" +} + +success_banner() { + printf >&2 "%s\n\n" "Official documentation can be found online at ${DOCS_URL}." + + if [ -z "${CLAIM_TOKEN}" ]; then + printf >&2 "%s\n\n" "Looking to monitor all of your infrastructure with Netdata? Check out Netdata Cloud at ${PUBLIC_CLOUD_URL}." + fi + + printf >&2 "%s\n" "Join our community and connect with us on:" + support_list +} + cleanup() { if [ -z "${NO_CLEANUP}" ]; then ${ROOTCMD} rm -rf "${tmpdir}" fi } +deferred_warnings() { + if [ -n "${WARNINGS}" ]; then + printf >&2 "%s\n" "The following non-fatal warnings or errors were encountered:" + echo >&2 "${WARNINGS}" + printf >&2 "\n" + fi +} + fatal() { + deferred_warnings printf >&2 "%s\n\n" "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD} ABORTED ${TPUT_RESET} ${1}" + printf >&2 "%s\n" "For community support, you can connect with us on:" + support_list telemetry_event "INSTALL_FAILED" "${1}" "${2}" cleanup trap - EXIT exit 1 } -run_ok() { - printf >&2 "%s\n\n" "${TPUT_BGGREEN}${TPUT_WHITE}${TPUT_BOLD} OK ${TPUT_RESET}" -} - -run_failed() { - printf >&2 "%s\n\n" "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD} FAILED ${TPUT_RESET}" -} - ESCAPED_PRINT_METHOD= # shellcheck disable=SC3050 -if printf "%q " test > /dev/null 2>&1; then +if printf "%s " test > /dev/null 2>&1; then ESCAPED_PRINT_METHOD="printfq" fi escaped_print() { if [ "${ESCAPED_PRINT_METHOD}" = "printfq" ]; then # shellcheck disable=SC3050 - printf "%q " "${@}" + printf "%s " "${@}" else printf "%s" "${*}" fi @@ -289,6 +393,10 @@ run() { info_console="[${TPUT_DIM}${dir}${TPUT_RESET}]$ " fi + if [ "${DRY_RUN}" -eq 1 ]; then + printf >&2 "%s" "Would run command:\n" + fi + { printf "%s" "${info}" escaped_print "${@}" @@ -299,14 +407,19 @@ run() { escaped_print >&2 "${@}" printf >&2 "%s\n" "${TPUT_RESET}" - "${@}" + if [ "${DRY_RUN}" -ne 1 ]; then + "${@}" + ret=$? + else + ret=0 + fi - ret=$? if [ ${ret} -ne 0 ]; then - run_failed + printf >&2 "%s\n\n" "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD} FAILED ${TPUT_RESET}" printf "%s\n" "FAILED with exit code ${ret}" >> "${run_logfile}" + WARNINGS="${WARNINGS}\n - Command \"${*}\" failed with exit code ${ret}." else - run_ok + printf >&2 "%s\n\n" "${TPUT_BGGREEN}${TPUT_WHITE}${TPUT_BOLD} OK ${TPUT_RESET}" printf "OK\n" >> "${run_logfile}" fi @@ -315,6 +428,7 @@ run() { warning() { printf >&2 "%s\n\n" "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD} WARNING ${TPUT_RESET} ${*}" + WARNINGS="${WARNINGS}\n - ${*}" } _cannot_use_tmpdir() { @@ -353,6 +467,17 @@ create_tmp_directory() { mktemp -d -t netdata-kickstart-XXXXXXXXXX } +check_for_remote_file() { + url="${1}" + if command -v curl > /dev/null 2>&1; then + curl --output /dev/null --silent --head --fail "${url}" || return 1 + elif command -v wget > /dev/null 2>&1; then + wget -S --spider "${url}" 2>&1 | grep -q 'HTTP/1.1 200 OK' || return 1 + else + fatal "I need curl or wget to proceed, but neither of them are available on this system." F0003 + fi +} + download() { url="${1}" dest="${2}" @@ -380,10 +505,10 @@ get_redirect() { safe_sha256sum() { # Within the context of the installer, we only use -c option that is common between the two commands # We will have to reconsider if we start using non-common options - if command -v sha256sum > /dev/null 2>&1; then - sha256sum "$@" - elif command -v shasum > /dev/null 2>&1; then + if command -v shasum > /dev/null 2>&1; then shasum -a 256 "$@" + elif command -v sha256sum > /dev/null 2>&1; then + sha256sum "$@" else fatal "I could not find a suitable checksum binary to use" F0004 fi @@ -421,7 +546,7 @@ get_system_info() { opensuse-leap) DISTRO_COMPAT_NAME="opensuse" ;; - rocky|rhel) + almalinux|rocky|rhel) DISTRO_COMPAT_NAME="centos" ;; *) @@ -514,6 +639,11 @@ update() { updater="${ndprefix}/usr/libexec/netdata/netdata-updater.sh" if [ -x "${updater}" ]; then + if [ "${DRY_RUN}" -eq 1 ]; then + progress "Would attempt to update existing installation by running the updater script located at: ${updater}" + return 0 + fi + if run ${ROOTCMD} "${updater}" --not-running-from-cron; then progress "Updated existing install at ${ndprefix}" return 0 @@ -521,15 +651,61 @@ update() { fatal "Failed to update existing Netdata install at ${ndprefix}" F0100 fi else + warning "Could not find a usable copy of the updater script." return 1 fi } +uninstall() { + get_system_info + detect_existing_install + + if [ -n "${OLD_INSTALL_PREFIX}" ]; then + INSTALL_PREFIX="$(echo "${OLD_INSTALL_PREFIX}/" | sed 's/$/netdata/g')" + else + INSTALL_PREFIX="${ndprefix}" + fi + + uninstaller="${INSTALL_PREFIX}/usr/libexec/netdata/netdata-uninstaller.sh" + uninstaller_url="https://raw.githubusercontent.com/netdata/netdata/master/packaging/installer/netdata-uninstaller.sh" + + if [ $INTERACTIVE = 0 ]; then + FLAGS="--yes --force" + else + FLAGS="--yes" + fi + + if [ -x "${uninstaller}" ]; then + if [ "${DRY_RUN}" -eq 1 ]; then + progress "Would attempt to uninstall existing install with uninstaller script found at: ${uninstaller}" + return 0 + else + progress "Found existing netdata-uninstaller. Running it.." + if ! run ${ROOTCMD} "${uninstaller}" $FLAGS; then + warning "Uninstaller failed. Some parts of Netdata may still be present on the system." + fi + fi + else + if [ "${DRY_RUN}" -eq 1 ]; then + progress "Would download installer script from: ${uninstaller_url}" + progress "Would attempt to uninstall existing install with downloaded uninstaller script." + return 0 + else + progress "Downloading netdata-uninstaller ..." + download "${uninstaller_url}" "${tmpdir}/netdata-uninstaller.sh" + chmod +x "${tmpdir}/netdata-uninstaller.sh" + if ! run ${ROOTCMD} "${tmpdir}/netdata-uninstaller.sh" $FLAGS; then + warning "Uninstaller failed. Some parts of Netdata may still be present on the system." + fi + fi + fi +} + detect_existing_install() { + progress "Checking for existing installations of Netdata..." + if pkg_installed netdata; then ndprefix="/" - elif [ -n "${INSTALL_PREFIX}" ]; then - ndprefix="${INSTALL_PREFIX}" else if [ -n "${INSTALL_PREFIX}" ]; then searchpath="${INSTALL_PREFIX}/bin:${INSTALL_PREFIX}/sbin:${INSTALL_PREFIX}/usr/bin:${INSTALL_PREFIX}/usr/sbin:${PATH}" @@ -548,7 +724,7 @@ detect_existing_install() { ndprefix="$(dirname "$(dirname "${ndpath}")")" fi - if echo "${ndprefix}" | grep -Eq '/usr$'; then + if echo "${ndprefix}" | grep -Eq '^/usr$'; then ndprefix="$(dirname "${ndprefix}")" fi fi @@ -557,20 +733,34 @@ detect_existing_install() { typefile="${ndprefix}/etc/netdata/.install-type" if [ -r "${typefile}" ]; then ${ROOTCMD} sh -c "cat \"${typefile}\" > \"${tmpdir}/install-type\"" - # shellcheck disable=SC1091 + # shellcheck disable=SC1090,SC1091 . "${tmpdir}/install-type" else INSTALL_TYPE="unknown" fi - fi - INSTALL_PREFIX="${ndprefix}" + envfile="${ndprefix}/etc/netdata/.environment" + if [ "${INSTALL_TYPE}" = "unknown" ] || [ "${INSTALL_TYPE}" = "custom" ]; then + if [ -r "${envfile}" ]; then + ${ROOTCMD} sh -c "cat \"${envfile}\" > \"${tmpdir}/environment\"" + # shellcheck disable=SC1091 + . "${tmpdir}/environment" + if [ -n "${NETDATA_IS_STATIC_INSTALL}" ]; then + if [ "${NETDATA_IS_STATIC_INSTALL}" = "yes" ]; then + INSTALL_TYPE="legacy-static" + else + INSTALL_TYPE="legacy-build" + fi + fi + fi + fi + fi } handle_existing_install() { detect_existing_install - if [ -z "${INSTALL_PREFIX}" ] || [ -z "${INSTALL_TYPE}" ]; then + if [ -z "${ndprefix}" ] || [ -z "${INSTALL_TYPE}" ]; then progress "No existing installations of netdata found, assuming this is a fresh install." return 0 fi @@ -578,13 +768,14 @@ handle_existing_install() { case "${INSTALL_TYPE}" in kickstart-*|legacy-*|binpkg-*|manual-static|unknown) if [ "${INSTALL_TYPE}" = "unknown" ]; then - warning "Found an existing netdata install at ${INSTALL_PREFIX}, but could not determine the install type." + warning "Found an existing netdata install at ${ndprefix}, but could not determine the install type." + warning "Usually this means you installed Netdata through your distribution’s regular package repositories or some other unsupported method." else - progress "Found an existing netdata install at ${INSTALL_PREFIX}, with installation type '${INSTALL_TYPE}'." + progress "Found an existing netdata install at ${ndprefix}, with installation type '${INSTALL_TYPE}'." fi if [ -n "${NETDATA_REINSTALL}" ] || [ -n "${NETDATA_UNSAFE_REINSTALL}" ]; then - progress "Found an existing netdata install at ${INSTALL_PREFIX}, but user requested reinstall, continuing." + progress "Found an existing netdata install at ${ndprefix}, but user requested reinstall, continuing." case "${INSTALL_TYPE}" in binpkg-*) NETDATA_ONLY_NATIVE=1 ;; @@ -606,34 +797,41 @@ handle_existing_install() { esac return 0 + elif [ "${INSTALL_TYPE}" = "unknown" ]; then + fatal "We do not support trying to update or claim installations when we cannot determine the install type. You will need to uninstall the existing install using the same method you used to install it to proceed." F0106 fi ret=0 - if [ "${NETDATA_CLAIM_ONLY}" -eq 0 ] && echo "${INSTALL_TYPE}" | grep -vq "binpkg-*"; then + if [ "${NETDATA_CLAIM_ONLY}" -eq 0 ]; then if ! update; then - warning "Unable to find usable updater script, not updating existing install at ${INSTALL_PREFIX}." + warning "Failed to update existing Netdata install at ${ndprefix}." + else + progress "Successfully updated existing netdata install at ${ndprefix}." fi else - warning "Not updating existing install at ${INSTALL_PREFIX}." + warning "Not updating existing install at ${ndprefix}." fi if [ -n "${NETDATA_CLAIM_TOKEN}" ]; then - progress "Attempting to claim existing install at ${INSTALL_PREFIX}." + progress "Attempting to claim existing install at ${ndprefix}." + INSTALL_PREFIX="${ndprefix}" claim ret=$? elif [ "${NETDATA_CLAIM_ONLY}" -eq 1 ]; then fatal "User asked to claim, but did not proide a claiming token." F0202 else - progress "Not attempting to claim existing install at ${INSTALL_PREFIX} (no claiming token provided)." + progress "Not attempting to claim existing install at ${ndprefix} (no claiming token provided)." fi + deferred_warnings + success_banner cleanup trap - EXIT exit $ret ;; oci) - fatal "This is an OCI container, use the regular image lifecycle management commands in your container instead of this script for managing it." F0203 + fatal "This is an OCI container, use the regular container lifecycle management commands for your container tools instead of this script for managing it." F0203 ;; *) if [ -n "${NETDATA_REINSTALL}" ] || [ -n "${NETDATA_UNSAFE_REINSTALL}" ]; then @@ -649,7 +847,20 @@ handle_existing_install() { fi fi else - fatal "Found an existing netdata install at ${INSTALL_PREFIX}, but the install type is '${INSTALL_TYPE}', which is not supported, refusing to proceed." F0103 + if [ -n "${NETDATA_CLAIM_TOKEN}" ]; then + progress "Attempting to claim existing install at ${ndprefix}." + INSTALL_PREFIX="${ndprefix}" + claim + ret=$? + + cleanup + trap - EXIT + exit $ret + elif [ "${NETDATA_CLAIM_ONLY}" -eq 1 ]; then + fatal "User asked to claim, but did not proide a claiming token." F0202 + else + fatal "Found an existing netdata install at ${ndprefix}, but the install type is '${INSTALL_TYPE}', which is not supported, refusing to proceed." F0103 + fi fi ;; esac @@ -690,7 +901,7 @@ EOF confirm_install_prefix() { if [ -n "${INSTALL_PREFIX}" ] && [ "${NETDATA_ONLY_BUILD}" -ne 1 ]; then - fatal "The \`--install\` option is only supported together with the \`--only-build\` option." F0204 + fatal "The \`--install\` option is only supported together with the \`--build-only\` option." F0204 fi if [ -n "${INSTALL_PREFIX}" ]; then @@ -715,7 +926,7 @@ confirm_install_prefix() { check_claim_opts() { # shellcheck disable=SC2235,SC2030 if [ -z "${NETDATA_CLAIM_TOKEN}" ] && [ -n "${NETDATA_CLAIM_ROOMS}" ]; then - fatal "Invalid claiming options, claim rooms may only be specified when a token and URL are specified." F0204 + fatal "Invalid claiming options, claim rooms may only be specified when a token is specified." F0204 elif [ -z "${NETDATA_CLAIM_TOKEN}" ] && [ -n "${NETDATA_CLAIM_EXTRA}" ]; then fatal "Invalid claiming options, a claiming token must be specified." F0204 elif [ "${NETDATA_DISABLE_CLOUD}" -eq 1 ] && [ -n "${NETDATA_CLAIM_TOKEN}" ]; then @@ -748,28 +959,128 @@ is_netdata_running() { } claim() { + if [ "${DRY_RUN}" -eq 1 ]; then + progress "Would attempt to claim agent to ${NETDATA_CLAIM_URL}" + else + progress "Attempting to claim agent to ${NETDATA_CLAIM_URL}" + fi + progress "Attempting to claim agent to ${NETDATA_CLAIM_URL}" - if [ -z "${INSTALL_PREFIX}" ] || [ "${INSTALL_PREFIX}" = "/" ]; then + if command -v netdata-claim.sh > /dev/null 2>&1; then + NETDATA_CLAIM_PATH="$(command -v netdata-claim.sh)" + elif [ -z "${INSTALL_PREFIX}" ] || [ "${INSTALL_PREFIX}" = "/" ]; then NETDATA_CLAIM_PATH=/usr/sbin/netdata-claim.sh elif [ "${INSTALL_PREFIX}" = "/opt/netdata" ]; then NETDATA_CLAIM_PATH="/opt/netdata/bin/netdata-claim.sh" + elif [ ! -d "${INSTALL_PREFIX}/netdata" ]; then + if [ -d "${INSTALL_PREFIX}/usr" ]; then + NETDATA_CLAIM_PATH="${INSTALL_PREFIX}/usr/sbin/netdata-claim.sh" + else + NETDATA_CLAIM_PATH="${INSTALL_PREFIX}/sbin/netdata-claim.sh" + fi else NETDATA_CLAIM_PATH="${INSTALL_PREFIX}/netdata/usr/sbin/netdata-claim.sh" fi + if [ ! -x "${NETDATA_CLAIM_PATH}" ]; then + fatal "Unable to find usable claiming script." F0106 + fi + if ! is_netdata_running; then NETDATA_CLAIM_EXTRA="${NETDATA_CLAIM_EXTRA} -daemon-not-running" fi # shellcheck disable=SC2086 - if ${ROOTCMD} "${NETDATA_CLAIM_PATH}" -token="${NETDATA_CLAIM_TOKEN}" -rooms="${NETDATA_CLAIM_ROOMS}" -url="${NETDATA_CLAIM_URL}" ${NETDATA_CLAIM_EXTRA}; then - progress "Successfully claimed node" + run ${ROOTCMD} "${NETDATA_CLAIM_PATH}" -token="${NETDATA_CLAIM_TOKEN}" -rooms="${NETDATA_CLAIM_ROOMS}" -url="${NETDATA_CLAIM_URL}" ${NETDATA_CLAIM_EXTRA} + case $? in + 0) + progress "Successfully claimed node" + return 0 + ;; + 1) + warning "Unable to claim node due to invalid claiming options. If you are seeing this message, you’ve probably found a bug and should open a bug report at ${AGENT_BUG_REPORT_URL}" + ;; + 2) + warning "Unable to claim node due to issues creating the claiming directory or preparing the local claiming key. Make sure you have a working openssl command and that ${INSTALL_PREFIX}/var/lib/netdata/cloud.d exists, then try again." + ;; + 3) + warning "Unable to claim node due to missing dependencies. Usually this means that the Netdata Agent was built without support for Netdata Cloud. If you built the agent from source, please install all needed dependencies for Cloud support. If you used the regular installation script and see this error, please file a bug." + ;; + 4) + warning "Failed to claim node due to inability to connect to ${NETDATA_CLAIM_URL}. Usually this either means that the specified claiming URL is wrong, or that you are having networking problems." + ;; + 5) + progress "Successfully claimed node, but was not able to notify the Netdata Agent. You will need to restart the Netdata service on this node before it will show up in the Cloud." + return 0 + ;; + 8) + warning "Failed to claim node due to an invalid agent ID. You can usually resolve this by removing ${INSTALL_PREFIX}/var/lib/netdata/registry/netdata.public.unique.id and restarting the agent. Then try to claim it again using the same options." + ;; + 9) + warning "Failed to claim node due to an invalid node name. This probably means you tried to specify a custom name for this node (for example, using the --claim-hostname option), but the hostname itself was either empty or consisted solely of whitespace. You can resolve this by specifying a valid host name and trying again." + ;; + 10) + warning "Failed to claim node due to an invalid room ID. This issue is most likely caused by a typo. Please check if the room(s) you are trying to add appear on the list of rooms provided to the --claim-rooms option ('${NETDATA_CLAIM_ROOMS}'). Then verify if the rooms are visible in Netdata Cloud and try again." + ;; + 11) + warning "Failed to claim node due to an issue with the generated RSA key pair. You can usually resolve this by removing all files in ${INSTALL_PREFIX}/var/lib/netdata/cloud.d and then trying again." + ;; + 12) + warning "Failed to claim node due to an invalid or expired claiming token. Please check that the token specified with the --claim-token option ('${NETDATA_CLAIM_TOKEN}') matches what you see in the Cloud and try again." + ;; + 13) + warning "Failed to claim node because the Cloud thinks it is already claimed. If this node was created by cloning a VM or as a container from a template, please remove the file ${INSTALL_PREFIX}/var/lib/netdata/registry/netdata.public.unique.id and restart the agent. Then try to claim it again with the same options. Otherwise, if you are certain this node has never been claimed before, you can use the --claim-id option to specify a new node ID to use for claiming, for example by using the uuidgen command like so: --claim-id \"\$(uuidgen)\"" + ;; + 14) + warning "Failed to claim node because the node is already in the process of being claimed. You should not need to do anything to resolve this, the node should show up properly in the Cloud soon. If it does not, please report a bug at ${AGENT_BUG_REPORT_URL}." + ;; + 15|16|17) + warning "Failed to claim node due to an internal server error in the Cloud. Please retry claiming this node later, and if you still see this message file a bug report at ${CLOUD_BUG_REPORT_URL}." + ;; + 18) + warning "Unable to claim node because this Netdata installation does not have a unique ID yet. Make sure the agent is running and started up correctly, and then try again." + ;; + *) + warning "Failed to claim node for an unknown reason. This usually means either networking problems or a bug. Please retry claiming later, and if you still see this message file a bug report at ${AGENT_BUG_REPORT_URL}" + ;; + esac + + if [ -z "${NETDATA_NEW_INSTALL}" ]; then + deferred_warnings + printf >&2 "%s\n" "For community support, you can connect with us on:" + support_list + cleanup + trap - EXIT + exit 1 + fi +} + +# ====================================================================== +# Auto-update handling code. +set_auto_updates() { + if [ -x "${INSTALL_PREFIX}/usr/libexec/netdata/netdata-updater.sh" ]; then + updater="${INSTALL_PREFIX}/usr/libexec/netdata/netdata-updater.sh" + elif [ -x "${INSTALL_PREFIX}/netdata/usr/libexec/netdata/netdata-updater.sh" ]; then + updater="${INSTALL_PREFIX}/netdata/usr/libexec/netdata/netdata-updater.sh" else - warning "Unable to claim node, you must do so manually." - if [ -z "${NETDATA_NEW_INSTALL}" ]; then - cleanup - trap - EXIT - exit 1 + warning "Could not find netdata-updater.sh. This means that auto-updates cannot (currently) be enabled on this system. See https://learn.netdata.cloud/docs/agent/packaging/installer/update for more information about updating Netdata." + return 0 + fi + + if [ "${NETDATA_AUTO_UPDATES}" = "1" ]; then + if [ "${DRY_RUN}" -eq 1 ]; then + progress "Would have attempted to enable automatic updates." + # This first case is for catching using a new kickstart script with an old build. It can be safely removed after v1.34.0 is released. + elif ! grep -q '\-\-enable-auto-updates' ${updater}; then + echo + elif ! ${ROOTCMD} ${updater} --enable-auto-updates "${NETDATA_AUTO_UPDATE_TYPE}"; then + warning "Failed to enable auto updates. Netdata will still work, but you will need to update manually." + fi + else + if [ "${DRY_RUN}" -eq 1 ]; then + progress "Would have attempted to disable automatic updates." + else + ${ROOTCMD} ${updater} --disable-auto-updates fi fi } @@ -803,7 +1114,7 @@ netdata_avail_check() { ;; centos|fedora|ol) # shellcheck disable=SC2086 - ${pm_cmd} search -v netdata | grep -qE 'Repo *: netdata(-edge)?$' + ${pm_cmd} search --nogpgcheck -v netdata | grep -qE 'Repo *: netdata(-edge)?$' return $? ;; opensuse) @@ -820,12 +1131,10 @@ netdata_avail_check() { check_special_native_deps() { if [ "${DISTRO_COMPAT_NAME}" = "centos" ] && [ "${SYSVERSION}" = "7" ]; then progress "Checking for libuv availability." - # shellcheck disable=SC2086 - if ${pm_cmd} search ${interactive_opts} -v libuv | grep -q "No matches found"; then - progress "libv not found, checking for EPEL availability." - # shellcheck disable=SC2086 - if ${pm_cmd} search ${interactive_opts} -v epel-release | grep -q "No matches found"; then - warning "Unable to find a suitable source for libuv, cannot install on this system." + if ${pm_cmd} search --nogpgcheck -v libuv | grep -q "No matches found"; then + progress "libuv not found, checking for EPEL availability." + if ${pm_cmd} search --nogpgcheck -v epel-release | grep -q "No matches found"; then + warning "Unable to find a suitable source for libuv, cannot install using native packages on this system." return 1 else progress "EPEL is available, attempting to install so that required dependencies are available." @@ -845,10 +1154,14 @@ check_special_native_deps() { try_package_install() { if [ -z "${DISTRO}" ] || [ "${DISTRO}" = "unknown" ]; then warning "Unable to determine Linux distribution for native packages." - return 1 + return 2 fi - progress "Attempting to install using native packages..." + if [ "${DRY_RUN}" -eq 1 ]; then + progress "Would attempt to install using native packages..." + else + progress "Attempting to install using native packages..." + fi if [ "${RELEASE_CHANNEL}" = "nightly" ]; then release="-edge" @@ -962,14 +1275,17 @@ try_package_install() { repoconfig_url="${REPOCONFIG_URL_PREFIX}/${repo_prefix}/${repoconfig_file}/download.${pkg_type}" if ! pkg_installed "${repoconfig_name}"; then - progress "Downloading repository configuration package." - if ! download "${repoconfig_url}" "${tmpdir}/${repoconfig_file}"; then - warning "Failed to download repository configuration package." + progress "Checking for availability of repository configuration package." + if ! check_for_remote_file "${repoconfig_url}"; then + warning "No repository configuration package available for ${DISTRO} ${SYSVERSION}." return 2 fi + if ! download "${repoconfig_url}" "${tmpdir}/${repoconfig_file}"; then + fatal "Failed to download repository configuration package." F0209 + fi + if [ -n "${needs_early_refresh}" ]; then - progress "Updating repository metadata." # shellcheck disable=SC2086 if ! run ${ROOTCMD} env ${env} ${pm_cmd} ${repo_subcmd} ${repo_update_opts}; then warning "Failed to refresh repository metadata." @@ -977,7 +1293,6 @@ try_package_install() { fi fi - progress "Installing repository configuration package." # shellcheck disable=SC2086 if ! run ${ROOTCMD} env ${env} ${pm_cmd} install ${pkg_install_opts} "${tmpdir}/${repoconfig_file}"; then warning "Failed to install repository configuration package." @@ -985,10 +1300,9 @@ try_package_install() { fi if [ -n "${repo_subcmd}" ]; then - progress "Updating repository metadata." # shellcheck disable=SC2086 if ! run ${ROOTCMD} env ${env} ${pm_cmd} ${repo_subcmd} ${repo_update_opts}; then - fatal "Failed to update repository metadata." F0205 + fatal "Failed to refresh repository metadata." F0205 fi fi else @@ -996,7 +1310,7 @@ try_package_install() { fi if ! check_special_native_deps; then - warning "Could not find secondary dependencies ${DISTRO} on ${SYSARCH}." + warning "Could not find secondary dependencies for ${DISTRO} on ${SYSARCH}." if [ -z "${NO_CLEANUP}" ]; then progress "Attempting to uninstall repository configuration package." # shellcheck disable=SC2086 @@ -1005,7 +1319,6 @@ try_package_install() { return 2 fi - progress "Checking for usable Netdata package." if ! netdata_avail_check "${DISTRO_COMPAT_NAME}"; then warning "Could not find a usable native package for ${DISTRO} on ${SYSARCH}." if [ -z "${NO_CLEANUP}" ]; then @@ -1021,7 +1334,6 @@ try_package_install() { run ${ROOTCMD} touch "/etc/netdata/.opt-out-from-anonymous-statistics" fi - progress "Installing Netdata package." # shellcheck disable=SC2086 if ! run ${ROOTCMD} env ${env} ${pm_cmd} install ${pkg_install_opts} netdata; then warning "Failed to install Netdata package." @@ -1050,19 +1362,32 @@ set_static_archive_urls() { try_static_install() { set_static_archive_urls "${RELEASE_CHANNEL}" - progress "Downloading static netdata binary: ${NETDATA_STATIC_ARCHIVE_URL}" + if [ "${DRY_RUN}" -eq 1 ]; then + progress "Would attempt to install using static build..." + else + progress "Attempting to install using static build..." + fi - if ! download "${NETDATA_STATIC_ARCHIVE_URL}" "${tmpdir}/netdata-${SYSARCH}-latest.gz.run"; then - warning "Unable to download static build archive for ${SYSARCH}." + # Check status code first, so that we can provide nicer fallback for dry runs. + if ! check_for_remote_file "${NETDATA_STATIC_ARCHIVE_URL}"; then + warning "No static build available for ${SYSARCH} CPUs." return 2 fi + if ! download "${NETDATA_STATIC_ARCHIVE_URL}" "${tmpdir}/netdata-${SYSARCH}-latest.gz.run"; then + fatal "Unable to download static build archive for ${SYSARCH}." F0208 + fi + if ! download "${NETDATA_STATIC_ARCHIVE_CHECKSUM_URL}" "${tmpdir}/sha256sum.txt"; then fatal "Unable to fetch checksums to verify static build archive." F0206 fi - if ! grep "netdata-${SYSARCH}-latest.gz.run" "${tmpdir}/sha256sum.txt" | safe_sha256sum -c - > /dev/null 2>&1; then - fatal "Static binary checksum validation failed. Usually this is a result of an older copy of the file being cached somewhere upstream and can be resolved by retrying in an hour." F0207 + if [ "${DRY_RUN}" -eq 1 ]; then + progress "Would validate SHA256 checksum of downloaded static build archive." + else + if ! grep "netdata-${SYSARCH}-latest.gz.run" "${tmpdir}/sha256sum.txt" | safe_sha256sum -c - > /dev/null 2>&1; then + fatal "Static binary checksum validation failed. Usually this is a result of an older copy of the file being cached somewhere upstream and can be resolved by retrying in an hour." F0207 + fi fi if [ "${INTERACTIVE}" -eq 0 ]; then @@ -1077,18 +1402,20 @@ try_static_install() { return 2 fi + if [ "${DRY_RUN}" -ne 1 ]; then install_type_file="/opt/netdata/etc/netdata/.install-type" - if [ -f "${install_type_file}" ]; then - ${ROOTCMD} sh -c "cat \"${install_type_file}\" > \"${tmpdir}/install-type\"" - ${ROOTCMD} chown "$(id -u)":"$(id -g)" "${tmpdir}/install-type" - # shellcheck disable=SC1091 - . "${tmpdir}/install-type" - cat > "${tmpdir}/install-type" <<- EOF + if [ -f "${install_type_file}" ]; then + ${ROOTCMD} sh -c "cat \"${install_type_file}\" > \"${tmpdir}/install-type\"" + ${ROOTCMD} chown "$(id -u)":"$(id -g)" "${tmpdir}/install-type" + # shellcheck disable=SC1090,SC1091 + . "${tmpdir}/install-type" + cat > "${tmpdir}/install-type" <<- EOF INSTALL_TYPE='kickstart-static' PREBUILT_ARCH='${PREBUILT_ARCH}' EOF - ${ROOTCMD} chown netdata:netdata "${tmpdir}/install-type" - ${ROOTCMD} cp "${tmpdir}/install-type" "${install_type_file}" + ${ROOTCMD} chown netdata:netdata "${tmpdir}/install-type" + ${ROOTCMD} cp "${tmpdir}/install-type" "${install_type_file}" + fi fi } @@ -1114,33 +1441,38 @@ install_local_build_dependencies() { return 1 fi - progress "Fetching script to detect required packages..." - download "${PACKAGES_SCRIPT}" "${tmpdir}/install-required-packages.sh" + if ! download "${PACKAGES_SCRIPT}" "${tmpdir}/install-required-packages.sh"; then + fatal "Failed to download dependency handling script for local build." F000D + fi - if [ ! -s "${tmpdir}/install-required-packages.sh" ]; then - warning "Downloaded dependency installation script is empty." + if [ "${DRY_RUN}" -eq 1 ]; then + progress "Would run downloaded script to install required build dependencies..." else - progress "Running downloaded script to detect required packages..." + progress "Running downloaded script to install required build dependencies..." + fi - if [ "${INTERACTIVE}" -eq 0 ]; then - opts="--dont-wait --non-interactive" - fi + if [ "${INTERACTIVE}" -eq 0 ]; then + opts="--dont-wait --non-interactive" + fi - if [ "${SYSTYPE}" = "Darwin" ]; then - sudo="" - else - sudo="${ROOTCMD}" - fi + if [ "${SYSTYPE}" = "Darwin" ]; then + sudo="" + else + sudo="${ROOTCMD}" + fi - # shellcheck disable=SC2086 - if ! run ${sudo} "${bash}" "${tmpdir}/install-required-packages.sh" ${opts} netdata; then - warning "It failed to install all the required packages, but installation might still be possible." - fi + # shellcheck disable=SC2086 + if ! run ${sudo} "${bash}" "${tmpdir}/install-required-packages.sh" ${opts} netdata; then + warning "Failed to install all required packages, but installation might still be possible." fi } build_and_install() { - progress "Building netdata" + if [ "${DRY_RUN}" -eq 1 ]; then + progress "Would attempt to build netdata..." + else + progress "Building netdata..." + fi echo "INSTALL_TYPE='kickstart-build'" > system/.install-type @@ -1169,40 +1501,57 @@ build_and_install() { case $? in 1) - fatal "netdata-installer.sh exited with error" F0007 + fatal "netdata-installer.sh failed to run correctly." F0007 ;; 2) - fatal "Insufficient RAM to install netdata" F0008 + fatal "Insufficient RAM to install netdata." F0008 ;; esac } try_build_install() { + if [ "${DRY_RUN}" -eq 1 ]; then + progress "Would attempt to install by building locally..." + else + progress "Attempting to install by building locally..." + fi + if ! install_local_build_dependencies; then return 1 fi set_source_archive_urls "${RELEASE_CHANNEL}" - download "${NETDATA_SOURCE_ARCHIVE_CHECKSUM_URL}" "${tmpdir}/sha256sum.txt" - download "${NETDATA_SOURCE_ARCHIVE_URL}" "${tmpdir}/netdata-latest.tar.gz" + if ! download "${NETDATA_SOURCE_ARCHIVE_URL}" "${tmpdir}/netdata-latest.tar.gz"; then + fatal "Failed to download source tarball for local build." F000B + fi + + if ! download "${NETDATA_SOURCE_ARCHIVE_CHECKSUM_URL}" "${tmpdir}/sha256sum.txt"; then + fatal "Failed to download checksums for source tarball verification." F000C + fi - if ! grep netdata-latest.tar.gz "${tmpdir}/sha256sum.txt" | safe_sha256sum -c - > /dev/null 2>&1; then - fatal "Tarball checksum validation failed. Usually this is a result of an older copy of the file being cached somewhere upstream and can be resolved by retrying in an hour." F0005 + if [ "${DRY_RUN}" -eq 1 ]; then + progress "Would validate SHA256 checksum of downloaded source archive." + else + if ! grep netdata-latest.tar.gz "${tmpdir}/sha256sum.txt" | safe_sha256sum -c - > /dev/null 2>&1; then + fatal "Tarball checksum validation failed. Usually this is a result of an older copy of the file being cached somewhere upstream and can be resolved by retrying in an hour." F0005 + fi fi run tar -xf "${tmpdir}/netdata-latest.tar.gz" -C "${tmpdir}" rm -rf "${tmpdir}/netdata-latest.tar.gz" > /dev/null 2>&1 - cd "$(find "${tmpdir}" -mindepth 1 -maxdepth 1 -type d -name netdata-)" || fatal "Cannot cd to netdata source tree" F0006 + if [ "${DRY_RUN}" -ne 1 ]; then + cd "$(find "${tmpdir}" -mindepth 1 -maxdepth 1 -type d -name netdata-)" || fatal "Cannot change directory to netdata source tree" F0006 + fi - if [ -x netdata-installer.sh ]; then + if [ -x netdata-installer.sh ] || [ "${DRY_RUN}" -eq 1 ]; then build_and_install || return 1 else # This case is needed because some platforms produce an extra directory on the source tarball extraction. if [ "$(find . -mindepth 1 -maxdepth 1 -type d | wc -l)" -eq 1 ] && [ -x "$(find . -mindepth 1 -maxdepth 1 -type d)/netdata-installer.sh" ]; then cd "$(find . -mindepth 1 -maxdepth 1 -type d)" && build_and_install || return 1 else - fatal "Cannot install netdata from source (the source directory does not include netdata-installer.sh). Leaving all files in ${tmpdir}" F0009 + fatal "Cannot install netdata from source (the source directory does not include netdata-installer.sh)." F0009 fi fi } @@ -1218,6 +1567,7 @@ install_on_linux() { case "$?" in 0) NETDATA_INSTALL_SUCCESSFUL=1 + INSTALL_PREFIX="/" ;; 1) fatal "Unable to install on this system." F0300 @@ -1329,9 +1679,22 @@ while [ -n "${1}" ]; do "--no-cleanup") NO_CLEANUP=1 ;; "--dont-wait"|"--non-interactive") INTERACTIVE=0 ;; "--interactive") INTERACTIVE=1 ;; + "--dry-run") DRY_RUN=1 ;; "--stable-channel") RELEASE_CHANNEL="stable" ;; "--no-updates") NETDATA_AUTO_UPDATES=0 ;; "--auto-update") NETDATA_AUTO_UPDATES="1" ;; + "--auto-update-method") + NETDATA_AUTO_UPDATE_TYPE="$(echo "${2}" | tr '[:upper:]' '[:lower:]')" + case "${NETDATA_AUTO_UPDATE_TYPE}" in + systemd|interval|crontab) + shift 1 + ;; + *) + echo "Unrecognized value for --auto-update-type. Valid values are: systemd, interval, crontab" + exit 1 + ;; + esac + ;; "--reinstall") NETDATA_REINSTALL=1 ;; "--reinstall-even-if-unsafe") NETDATA_UNSAFE_REINSTALL=1 ;; "--claim-only") NETDATA_CLAIM_ONLY=1 ;; @@ -1355,6 +1718,16 @@ while [ -n "${1}" ]; do INSTALL_PREFIX="${2}" shift 1 ;; + "--old-install-prefix") + OLD_INSTALL_PREFIX="${2}" + shift 1 + ;; + "--uninstall") + ACTION="uninstall" + ;; + "--reinstall-clean") + ACTION="reinstall-clean" + ;; "--native-only") NETDATA_ONLY_NATIVE=1 NETDATA_ONLY_STATIC=0 @@ -1385,11 +1758,11 @@ while [ -n "${1}" ]; do NETDATA_CLAIM_URL="${2}" shift 1 ;; - "--claim-*") + "--claim-"*) optname="$(echo "${1}" | cut -d '-' -f 4-)" case "${optname}" in id|proxy|user|hostname) - NETDATA_CLAIM_EXTRA="${NETDATA_CLAIM_EXTRA} -${optname} ${2}" + NETDATA_CLAIM_EXTRA="${NETDATA_CLAIM_EXTRA} -${optname}=${2}" shift 1 ;; verbose|insecure|noproxy|noreload|daemon-not-running) @@ -1413,24 +1786,8 @@ confirm_root_support get_system_info confirm_install_prefix -tmpdir="$(create_tmp_directory)" -progress "Using ${tmpdir} as a temporary directory." -cd "${tmpdir}" || exit 1 - -handle_existing_install - -case "${SYSTYPE}" in - Linux) install_on_linux ;; - Darwin) install_on_macos ;; - FreeBSD) install_on_freebsd ;; -esac - -if [ -n "${NETDATA_CLAIM_TOKEN}" ]; then - claim -elif [ "${NETDATA_DISABLE_CLOUD}" -eq 1 ]; then - soft_disable_cloud +if [ -z "${ACTION}" ]; then + handle_existing_install fi -telemetry_event INSTALL_SUCCESS "" "" -cleanup -trap - EXIT +main diff --git a/packaging/installer/methods/cloud-providers.md b/packaging/installer/methods/cloud-providers.md index 08c0ed9da..bc5c9aae2 100644 --- a/packaging/installer/methods/cloud-providers.md +++ b/packaging/installer/methods/cloud-providers.md @@ -123,4 +123,4 @@ Name: Netdata Click **Add** to apply your new inbound security rule. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fpackaging%2Finstaller%2Fmethods%2Fcloud-providers&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/packaging/installer/methods/freebsd.md b/packaging/installer/methods/freebsd.md index 9c3db900f..12b55d6ad 100644 --- a/packaging/installer/methods/freebsd.md +++ b/packaging/installer/methods/freebsd.md @@ -93,16 +93,15 @@ The `netdata-updater.sh` script will update your Agent. | `--disable-plugin-nfacct` | Disable nfacct plugin. Default: enable it when libmnl and libnetfilter_acct are available| | `--enable-plugin-xenstat` | Enable the xenstat plugin. Default: enable it when libxenstat and libyajl are available| | `--disable-plugin-xenstat` | Disable the xenstat plugin| -| `--enable-backend-kinesis` | Enable AWS Kinesis backend. Default: enable it when libaws_cpp_sdk_kinesis and libraries (it depends on are available)| -| `--disable-backend-kinesis` | Disable AWS Kinesis backend. Default: enable it when libaws_cpp_sdk_kinesis and libraries (it depends on are available)| -| `--enable-backend-prometheus-remote-write` | Enable Prometheus remote write backend. Default: enable it when libprotobuf and libsnappy are available| -| `--disable-backend-prometheus-remote-write` | Disable Prometheus remote write backend. Default: enable it when libprotobuf and libsnappy are available| -| `--enable-backend-mongodb` | Enable MongoDB backend. Default: enable it when libmongoc is available| -| `--disable-backend-mongodb` | Disable MongoDB backend| +| `--disable-exporting-kinesis` | Disable AWS Kinesis exporting connector. Default: enable it when libaws_cpp_sdk_kinesis and libraries (it depends on are available)| +| `--enable-exporting-prometheus-remote-write` | Enable Prometheus remote write exporting connector. Default: enable it when libprotobuf and libsnappy are available| +| `--disable-exporting-prometheus-remote-write` | Disable Prometheus remote write exporting connector. Default: enable it when libprotobuf and libsnappy are available| +| `--enable-exporting-mongodb` | Enable MongoDB exporting connector. Default: enable it when libmongoc is available| +| `--disable-exporting-mongodb` | Disable MongoDB exporting connector| | `--enable-lto` | Enable Link-Time-Optimization. Default: enabled| | `--disable-lto` | Disable Link-Time-Optimization. Default: enabled| | `--disable-x86-sse` | Disable SSE instructions. By default SSE optimizations are enabled| | `--zlib-is-really-here` or `--libs-are-really-here` | If you get errors about missing zlib or libuuid but you know it is available, you might have a broken pkg-config. Use this option to proceed without checking pkg-config| -|`--disable-telemetry` | Use this flag to opt-out from our anonymous telemetry program. (DO_NOT_TRACK=1)| +|`--disable-telemetry` | Use this flag to opt-out from our anonymous telemetry program. (DISABLE_TELEMETRY=1)| + -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fpackaging%2Finstaller%2Fmethods%2Ffreebsd&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) diff --git a/packaging/installer/methods/freenas.md b/packaging/installer/methods/freenas.md index a0dafdff8..a69f1e3fb 100644 --- a/packaging/installer/methods/freenas.md +++ b/packaging/installer/methods/freenas.md @@ -21,4 +21,4 @@ To start the Netdata service: service netdata start ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fpackaging%2Finstaller%2Fmethods%2Ffreenas&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/packaging/installer/methods/kickstart.md b/packaging/installer/methods/kickstart.md index 5bd9633da..2ff20cfd6 100644 --- a/packaging/installer/methods/kickstart.md +++ b/packaging/installer/methods/kickstart.md @@ -12,7 +12,7 @@ import { OneLineInstallWget, OneLineInstallCurl } from '../../../../../src/compo This page covers detailed instructions on using and configuring the automatic one-line installation script named `kickstart.sh`. -The kickstart script works on all Linux distributions and macOS environments. By default, automatic nightly updates are enabled. If you are installing on macOS, make sure to check the [install documentation for macOS](packaging/installer/methods/macos.md) before continuing. +The kickstart script works on all Linux distributions and macOS environments. By default, automatic nightly updates are enabled. If you are installing on macOS, make sure to check the [install documentation for macOS](macos.md) before continuing. > If you are unsure whether you want nightly or stable releases, read the [installation guide](/packaging/installer/README.md#nightly-vs-stable-releases). > If you want to turn off [automatic updates](/packaging/installer/README.md#automatic-updates), use the `--no-updates` option. You can find more installation options below. @@ -48,7 +48,8 @@ The `kickstart.sh` script accepts a number of optional parameters to control how - `--non-interactive`: Don’t prompt for anything and assume yes whenever possible, overriding any automatic detection of an interactive run. - `--interactive`: Act as if running interactively, even if automatic detection indicates a run is non-interactive. - `--dont-wait`: Synonym for `--non-interactive` -- `--dont-start-it`: Don’t auto-start the daemon after installing. This parameter is not gauranteed to work. +- `--dry-run`: Show what the installer would do, but don’t actually do any of it. +- `--dont-start-it`: Don’t auto-start the daemon after installing. This parameter is not guaranteed to work. - `--nightly-channel`: Use a nightly build instead of a stable release (this is the default). - `--stable-channel`: Use a stable release instead of a nightly build. - `--auto-update`: Enable automatic updates (this is the default). @@ -63,6 +64,9 @@ The `kickstart.sh` script accepts a number of optional parameters to control how use runtime configuration to disable cloud support. - `--require-cloud`: Only install if Netdata Cloud can be enabled. Overrides `--disable-cloud`. - `--install`: Specify an installation prefix for local builds (by default, we use a sane prefix based on the type of system). +- `--old-install-prefix`: Specify the custom local build's installation prefix that should be removed. +- `--uninstall`: Uninstall an existing installation of Netdata. +- `--reinstall-clean`: Performs an uninstall of Netdata and clean installation. Additionally, the following environment variables may be used to further customize how the script runs (most users should not need to use special values for any of these): @@ -73,15 +77,21 @@ should not need to use special values for any of these): - `ROOTCMD`: Used to specify a command to use to run another command with root privileges if needed. By default we try to use sudo, doas, or pkexec (in that order of preference), but if you need special options for one of those to work, or have a different tool to do the same thing on your system, you can specify it here. -- `DO_NOT_TRACK`: If set to a value other than 0, behave as if `--disable-telemetry` was specified. +- `DISABLE_TELEMETRY`: If set to a value other than 0, behave as if `--disable-telemetry` was specified. - `NETDATA_INSTALLER_OPTIONS`: Specifies extra options to pass to the static installer or local build script. ### Connect node to Netdata Cloud during installation -The `kickstart.sh` script accepts additional parameters to automatically [connect](/claim/README.md) your node to Netdata -Cloud immediately after installation. Find the `token` and `rooms` strings by [signing in to Netdata -Cloud](https://app.netdata.cloud/sign-in?cloudRoute=/spaces), then clicking on **Connect Nodes** in the [Spaces management -area](https://learn.netdata.cloud/docs/cloud/spaces#manage-spaces). +The `kickstart.sh` script accepts additional parameters to automatically [connect](/claim/README.md) your node to Netdata Cloud immediately after installation. + +> Note: You either need to run the command with root privileges or run it with the user that is running the agent. More details: [Connect an agent without root privileges](/claim/README.md#connect-an-agent-without-root-privileges) section. + +To automatically claim nodes after installation: + +1. Sign in to [Netdata Cloud](https://app.netdata.cloud/sign-in?cloudRoute=/spaces) +2. Go to the [Spaces management area](https://learn.netdata.cloud/docs/cloud/spaces#manage-spaces) +3. Click on **Connect Nodes** +4. Find the `token` and `rooms` strings and specify your nodes: - `--claim-token`: Specify a unique claiming token associated with your Space in Netdata Cloud to be used to connect to the node after the install. @@ -93,11 +103,9 @@ area](https://learn.netdata.cloud/docs/cloud/spaces#manage-spaces). For example: ```bash -wget -O /tmp/netdata-kickstart.sh https://my-netdata.io/kickstart.sh && sh /tmp/netdata-kickstart.sh --claim-token=TOKEN --claim-rooms=ROOM1,ROOM2 +wget -O /tmp/netdata-kickstart.sh https://my-netdata.io/kickstart.sh && sh /tmp/netdata-kickstart.sh --claim-token TOKEN --claim-rooms ROOM1,ROOM2 ``` -Please note that to run it you will either need to have root privileges or run it with the user that is running the agent, more details on the [Connect an agent without root privileges](/claim/README.md#connect-an-agent-without-root-privileges) section. - ### Native packages We publish official DEB/RPM packages for a number of common Linux distributions as part of our releases and nightly @@ -136,7 +144,7 @@ To use `md5sum` to verify the integrity of the `kickstart.sh` script you will do run the following: ```bash -[ "2ea326514c5166eabf02622e75d10a53" = "$(curl -Ss https://my-netdata.io/kickstart.sh | md5sum | cut -d ' ' -f 1)" ] && echo "OK, VALID" || echo "FAILED, INVALID" +[ "" = "$(curl -Ss https://my-netdata.io/kickstart.sh | md5sum | cut -d ' ' -f 1)" ] && echo "OK, VALID" || echo "FAILED, INVALID" ``` If the script is valid, this command will return `OK, VALID`. @@ -152,4 +160,4 @@ Read through Netdata's [documentation](https://learn.netdata.cloud/docs), which solutions, to enable features like health monitoring, alarm notifications, long-term metrics storage, exporting to external databases, and more. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fpackaging%2Finstaller%2Fmethods%2Fkickstart&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/packaging/installer/methods/kubernetes.md b/packaging/installer/methods/kubernetes.md index f12850665..216703a33 100644 --- a/packaging/installer/methods/kubernetes.md +++ b/packaging/installer/methods/kubernetes.md @@ -194,4 +194,4 @@ utilization metrics, and application metrics. - [Netdata Helm chart](https://github.com/netdata/helmchart) - [Netdata service discovery](https://github.com/netdata/agent-service-discovery/) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fpackaging%2Finstaller%2Fmethods%2Fkubernetes&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/packaging/installer/methods/macos.md b/packaging/installer/methods/macos.md index 4fa0300c6..7257e1a60 100644 --- a/packaging/installer/methods/macos.md +++ b/packaging/installer/methods/macos.md @@ -12,13 +12,13 @@ You could also use a macOS system as the parent node in a [streaming configurati You can install Netdata in one of the three following ways: - **[Install Netdata with the our automatic one-line installation script (recommended)](#install-netdata-with-our-automatic-one-line-installation-script)**, -- [Install Netdata via Homebrew](#install-netdata-with-the-homebrew-package) +- [Install Netdata via Homebrew](#install-netdata-via-homebrew) - [Install Netdata from source](#install-netdata-from-source) Each of these installation option requires [Homebrew](https://brew.sh/) for handling dependencies. > The Netdata Homebrew package is community-created and -maintained. -> Community-maintained packages _may_ receive support from Netdata, but are only a best-effort affair. Learn more about [Netdata's platform support policy](/packaging/platform_support). +> Community-maintained packages _may_ receive support from Netdata, but are only a best-effort affair. Learn more about [Netdata's platform support policy](/packaging/PLATFORM_SUPPORT.md). ## Install Netdata with our automatic one-line installation script @@ -52,7 +52,7 @@ curl https://my-netdata.io/kickstart.sh > /tmp/netdata-kickstart.sh && sh /tmp/n ``` The Netdata Agent is installed under `/usr/local/netdata` on your machine. Your machine will also show up as a node in your Netdata Cloud. -If you experience issues while claiming your node, follow the steps in our [Troubleshooting](claim/README.md#troubleshooting) documentation. +If you experience issues while claiming your node, follow the steps in our [Troubleshooting](/claim/README.md#troubleshooting) documentation. ## Install Netdata via Homebrew To install Netdata and all its dependencies, run Homebrew using the following command: @@ -108,4 +108,4 @@ When you're finished with installation, check out our [single-node](/docs/quicks Or, skip straight to [configuring the Netdata Agent](/docs/configure/nodes.md). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fpackaging%2Finstaller%2Fmethods%2Fmacos&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/packaging/installer/methods/manual.md b/packaging/installer/methods/manual.md index 6d88fbd8e..aaf1451df 100644 --- a/packaging/installer/methods/manual.md +++ b/packaging/installer/methods/manual.md @@ -244,4 +244,4 @@ Read through Netdata's [documentation](https://learn.netdata.cloud/docs), which solutions, to enable features like health monitoring, alarm notifications, long-term metrics storage, exporting to external databases, and more. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fpackaging%2Finstaller%2Fmethods%2Fmanual&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/packaging/installer/methods/offline.md b/packaging/installer/methods/offline.md index c978dd613..53390c71b 100644 --- a/packaging/installer/methods/offline.md +++ b/packaging/installer/methods/offline.md @@ -86,5 +86,3 @@ Or, skip straight to [configuring the Netdata Agent](/docs/configure/nodes.md). Read through Netdata's [documentation](https://learn.netdata.cloud/docs), which is structured based on actions and solutions, to enable features like health monitoring, alarm notifications, long-term metrics storage, exporting to external databases, and more. - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fpackages%2Finstaller%2Fmethods%2Foffline&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]() diff --git a/packaging/installer/methods/pfsense.md b/packaging/installer/methods/pfsense.md index 6d9de7606..f0d730036 100644 --- a/packaging/installer/methods/pfsense.md +++ b/packaging/installer/methods/pfsense.md @@ -81,4 +81,4 @@ workaround from **Note:** In pfSense, the Netdata configuration files are located under `/usr/local/etc/netdata`. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fpackaging%2Finstaller%2Fmethods%2Fpfsense&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/packaging/installer/methods/source.md b/packaging/installer/methods/source.md index 737ea166a..a25323f0c 100644 --- a/packaging/installer/methods/source.md +++ b/packaging/installer/methods/source.md @@ -234,4 +234,4 @@ repository](https://github.com/netdata/kernel-collector/blob/master/README.md), which outlines both the required dependencies, as well as multiple options for building the code. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fpackaging%2Finstaller%2Fmethods%2Fsource&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/packaging/installer/methods/synology.md b/packaging/installer/methods/synology.md index 8e55924c1..30ec3035c 100644 --- a/packaging/installer/methods/synology.md +++ b/packaging/installer/methods/synology.md @@ -34,9 +34,7 @@ chown -R netdata:netdata /opt/netdata/var/lib/netdata /opt/netdata/var/cache/net chown -R netdata:root /opt/netdata/var/log/netdata ``` -4. Uncomment and set `web files owner` to `root`, and `web files group` to `netdata` in - the `/opt/netdata/etc/netdata/netdata.conf`. -5. Restart Netdata +4. Restart Netdata ```sh /etc/rc.netdata restart @@ -58,4 +56,4 @@ installed. You'll have to do this manually: 3. Make sure `/etc/rc.netdata` is executable: `chmod 0755 /etc/rc.netdata`. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fpackaging%2Finstaller%2Fmethods%2Fsynology&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/packaging/installer/netdata-uninstaller.sh b/packaging/installer/netdata-uninstaller.sh index a248860da..f2cc7b7c4 100755 --- a/packaging/installer/netdata-uninstaller.sh +++ b/packaging/installer/netdata-uninstaller.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/bin/sh # # This is the netdata uninstaller script # @@ -21,6 +21,7 @@ where: FILE_REMOVAL_STATUS=0 ENVIRONMENT_FILE="/etc/netdata/.environment" +# shellcheck disable=SC2034 INTERACTIVITY="-i" YES=0 while :; do @@ -35,6 +36,7 @@ while :; do ;; -y | --yes) YES=1 + FLAG=-y shift ;; -e | --env) @@ -55,15 +57,219 @@ if [ "$YES" != "1" ]; then exit 1 fi -if [[ $EUID -ne 0 ]]; then +if [ "$(id -u)" -ne 0 ]; then echo >&2 "This script SHOULD be run as root or otherwise it won't delete all installed components." key="n" - read -r -s -n 1 -p "Do you want to continue as non-root user [y/n] ? " key + read -r 1 -p "Do you want to continue as non-root user [y/n] ? " key if [ "$key" != "y" ] && [ "$key" != "Y" ]; then exit 1 fi fi +user_input() { + if [ "${INTERACTIVITY}" = "-i" ]; then + TEXT="$1 [y/n]" + + while true; do + echo "$TEXT" + read -r yn + + case "$yn" in + [Yy]*) return 0;; + [Nn]*) return 1;; + *) echo "Please answer yes or no.";; + esac + done + fi +} + +_cannot_use_tmpdir() { + testfile="$(TMPDIR="${1}" mktemp -q -t netdata-test.XXXXXXXXXX)" + ret=0 + + if [ -z "${testfile}" ]; then + return "${ret}" + fi + + if printf '#!/bin/sh\necho SUCCESS\n' > "${testfile}"; then + if chmod +x "${testfile}"; then + if [ "$("${testfile}")" = "SUCCESS" ]; then + ret=1 + fi + fi + fi + + rm -f "${testfile}" + return "${ret}" +} + +create_tmp_directory() { + if [ -z "${TMPDIR}" ] || _cannot_use_tmpdir "${TMPDIR}"; then + if _cannot_use_tmpdir /tmp; then + if _cannot_use_tmpdir "${PWD}"; then + fatal "Unable to find a usable temporary directory. Please set \$TMPDIR to a path that is both writable and allows execution of files and try again." F0400 + else + TMPDIR="${PWD}" + fi + else + TMPDIR="/tmp" + fi + fi + + mktemp -d -t netdata-kickstart-XXXXXXXXXX +} + +tmpdir="$(create_tmp_directory)" + +detect_existing_install() { + if pkg_installed netdata; then + ndprefix="/" + else + if [ -n "${INSTALL_PREFIX}" ]; then + searchpath="${INSTALL_PREFIX}/bin:${INSTALL_PREFIX}/sbin:${INSTALL_PREFIX}/usr/bin:${INSTALL_PREFIX}/usr/sbin:${PATH}" + searchpath="${INSTALL_PREFIX}/netdata/bin:${INSTALL_PREFIX}/netdata/sbin:${INSTALL_PREFIX}/netdata/usr/bin:${INSTALL_PREFIX}/netdata/usr/sbin:${searchpath}" + else + searchpath="${PATH}" + fi + + ndpath="$(PATH="${searchpath}" command -v netdata 2>/dev/null)" + + if [ -z "$ndpath" ] && [ -x /opt/netdata/bin/netdata ]; then + ndpath="/opt/netdata/bin/netdata" + fi + + if [ -n "${ndpath}" ]; then + ndprefix="$(dirname "$(dirname "${ndpath}")")" + fi + + if echo "${ndprefix}" | grep -Eq '/usr$'; then + ndprefix="$(dirname "${ndprefix}")" + fi + fi + + if [ -n "${ndprefix}" ]; then + typefile="${ndprefix}/etc/netdata/.install-type" + envfile="${ndprefix}/etc/netdata/.environment" + if [ -r "${typefile}" ]; then + ${ROOTCMD} sh -c "cat \"${typefile}\" > \"${tmpdir}/install-type\"" + # shellcheck disable=SC1090,SC1091 + . "${tmpdir}/install-type" + else + INSTALL_TYPE="unknown" + fi + + if [ "${INSTALL_TYPE}" = "unknown" ] || [ "${INSTALL_TYPE}" = "custom" ]; then + if [ -r "${envfile}" ]; then + ${ROOTCMD} sh -c "cat \"${envfile}\" > \"${tmpdir}/environment\"" + # shellcheck disable=SC1091 + . "${tmpdir}/environment" + if [ -n "${NETDATA_IS_STATIC_INSTALL}" ]; then + if [ "${NETDATA_IS_STATIC_INSTALL}" = "yes" ]; then + INSTALL_TYPE="legacy-static" + else + INSTALL_TYPE="legacy-build" + fi + fi + fi + fi + fi +} + +pkg_installed() { + case "${DISTRO_COMPAT_NAME}" in + debian|ubuntu) + dpkg-query --show --showformat '${Status}' "${1}" 2>&1 | cut -f 1 -d ' ' | grep -q '^install$' + return $? + ;; + centos|fedora|opensuse|ol) + rpm -q "${1}" > /dev/null 2>&1 + return $? + ;; + *) + return 1 + ;; + esac +} + +detect_existing_install + +if [ -x "$(command -v apt-get)" ] && [ "${INSTALL_TYPE}" = "binpkg-deb" ]; then + if dpkg -s netdata > /dev/null; then + echo "Found netdata native installation" + if user_input "Do you want to remove netdata? "; then + apt-get remove netdata ${FLAG} + fi + if dpkg -s netdata-repo-edge > /dev/null; then + if user_input "Do you want to remove netdata-repo-edge? "; then + apt-get remove netdata-repo-edge ${FLAG} + fi + fi + if dpkg -s netdata-repo > /dev/null; then + if user_input "Do you want to remove netdata-repo? "; then + apt-get remove netdata-repo ${FLAG} + fi + fi + exit 0 + fi +elif [ -x "$(command -v dnf)" ] && [ "${INSTALL_TYPE}" = "binpkg-rpm" ]; then + if rpm -q netdata > /dev/null; then + echo "Found netdata native installation." + if user_input "Do you want to remove netdata? "; then + dnf remove netdata ${FLAG} + fi + if rpm -q netdata-repo-edge > /dev/null; then + if user_input "Do you want to remove netdata-repo-edge? "; then + dnf remove netdata-repo-edge ${FLAG} + fi + fi + if rpm -q netdata-repo > /dev/null; then + if user_input "Do you want to remove netdata-repo? "; then + dnf remove netdata-repo ${FLAG} + fi + fi + exit 0 + fi +elif [ -x "$(command -v yum)" ] && [ "${INSTALL_TYPE}" = "binpkg-rpm" ]; then + if rpm -q netdata > /dev/null; then + echo "Found netdata native installation." + if user_input "Do you want to remove netdata? "; then + yum remove netdata ${FLAG} + fi + if rpm -q netdata-repo-edge > /dev/null; then + if user_input "Do you want to remove netdata-repo-edge? "; then + yum remove netdata-repo-edge ${FLAG} + fi + fi + if rpm -q netdata-repo > /dev/null; then + if user_input "Do you want to remove netdata-repo? "; then + yum remove netdata-repo ${FLAG} + fi + fi + exit 0 + fi +elif [ -x "$(command -v zypper)" ] && [ "${INSTALL_TYPE}" = "binpkg-rpm" ]; then + if [ "${FLAG}" = "-y" ]; then + FLAG=-n + fi + if zypper search -i netdata > /dev/null; then + echo "Found netdata native installation." + if user_input "Do you want to remove netdata? "; then + zypper ${FLAG} remove netdata + fi + if zypper search -i netdata-repo-edge > /dev/null; then + if user_input "Do you want to remove netdata-repo-edge? "; then + zypper ${FLAG} remove netdata-repo-edge + fi + fi + if zypper search -i netdata-repo > /dev/null; then + if user_input "Do you want to remove netdata-repo? "; then + zypper ${FLAG} remove netdata-repo + fi + fi + exit 0 + fi +fi + # ----------------------------------------------------------------------------- # portable service command @@ -72,7 +278,8 @@ rcservice_cmd="$(command -v rc-service 2> /dev/null)" systemctl_cmd="$(command -v systemctl 2> /dev/null)" service() { - local cmd="${1}" action="${2}" + cmd="${1}" + action="${2}" if [ -n "${systemctl_cmd}" ]; then run "${systemctl_cmd}" "${action}" "${cmd}" @@ -127,12 +334,12 @@ run_failed() { } ESCAPED_PRINT_METHOD= -if printf "%q " test > /dev/null 2>&1; then +if printf "%s " test > /dev/null 2>&1; then ESCAPED_PRINT_METHOD="printfq" fi escaped_print() { if [ "${ESCAPED_PRINT_METHOD}" = "printfq" ]; then - printf "%q " "${@}" + printf "%s " "${@}" else printf "%s" "${*}" fi @@ -141,9 +348,10 @@ escaped_print() { run_logfile="/dev/null" run() { - local user="${USER--}" dir="${PWD}" info info_console + user="${USER--}" + dir="${PWD}" - if [ "${UID}" = "0" ]; then + if [ "$(id -u)" = "0" ]; then info="[root ${dir}]# " info_console="[${TPUT_DIM}${dir}${TPUT_RESET}]# " else @@ -163,7 +371,7 @@ run() { "${@}" - local ret=$? + ret=$? if [ ${ret} -ne 0 ]; then run_failed printf >> "${run_logfile}" "FAILED with exit code %s\n" "${ret}" @@ -176,7 +384,7 @@ run() { } portable_del_group() { - local groupname="${1}" + groupname="${1}" # Check if group exist echo >&2 "Removing ${groupname} user group ..." @@ -206,7 +414,11 @@ portable_del_group() { } issystemd() { - local pids p myns ns systemctl + pids='' + p='' + myns='' + ns='' + systemctl='' # if the directory /lib/systemd/system OR /usr/lib/systemd/system (SLES 12.x) does not exit, it is not systemd if [ ! -d /lib/systemd/system ] && [ ! -d /usr/lib/systemd/system ]; then @@ -240,7 +452,7 @@ issystemd() { } portable_del_user() { - local username="${1}" + username="${1}" echo >&2 "Deleting ${username} user account ..." # Linux @@ -258,7 +470,8 @@ portable_del_user() { } portable_del_user_from_group() { - local groupname="${1}" username="${2}" + groupname="${1}" + username="${2}" # username is not in group echo >&2 "Deleting ${username} user from ${groupname} group ..." @@ -296,30 +509,25 @@ quit_msg() { fi } -user_input() { - TEXT="$1" - if [ "${INTERACTIVITY}" = "-i" ]; then - read -r -p "$TEXT" >&2 - fi -} - rm_file() { FILE="$1" if [ -f "${FILE}" ]; then - run rm -v ${INTERACTIVITY} "${FILE}" + if user_input "Do you want to delete this file '$FILE' ? "; then + run rm -v "${FILE}" + fi fi } rm_dir() { DIR="$1" if [ -n "$DIR" ] && [ -d "$DIR" ]; then - user_input "Press ENTER to recursively delete directory '$DIR' > " - run rm -v -f -R "${DIR}" + if user_input "Do you want to delete this directory '$DIR' ? "; then + run rm -v -f -R "${DIR}" + fi fi } safe_pidof() { - local pidof_cmd pidof_cmd="$(command -v pidof 2> /dev/null)" if [ -n "${pidof_cmd}" ]; then ${pidof_cmd} "${@}" @@ -345,7 +553,9 @@ pidisnetdata() { } stop_netdata_on_pid() { - local pid="${1}" ret=0 count=0 + pid="${1}" + ret=0 + count=0 pidisnetdata "${pid}" || return 0 @@ -386,7 +596,8 @@ stop_netdata_on_pid() { } netdata_pids() { - local p myns ns + p='' + ns='' myns="$(readlink /proc/self/ns/pid 2> /dev/null)" @@ -403,9 +614,9 @@ netdata_pids() { } stop_all_netdata() { - local p + p='' - if [ "${UID}" -eq 0 ]; then + if [ "$(id -u)" -eq 0 ]; then uname="$(uname 2> /dev/null)" # Any of these may fail, but we need to not bail if they do. @@ -428,7 +639,7 @@ stop_all_netdata() { fi fi - if [ -n "$(netdata_pids)" ] && [ -n "$(builtin type -P netdatacli)" ]; then + if [ -n "$(netdata_pids)" ] && [ -n "$(command -v netdatacli)" ]; then netdatacli shutdown-agent sleep 20 fi @@ -441,8 +652,9 @@ stop_all_netdata() { trap quit_msg EXIT -#shellcheck source=/dev/null -source "${ENVIRONMENT_FILE}" || exit 1 +# shellcheck source=/dev/null +# shellcheck disable=SC1090 +. "${ENVIRONMENT_FILE}" || exit 1 #### STOP NETDATA echo >&2 "Stopping a possibly running netdata..." @@ -484,16 +696,19 @@ FILE_REMOVAL_STATUS=1 #### REMOVE NETDATA USER FROM ADDED GROUPS if [ -n "$NETDATA_ADDED_TO_GROUPS" ]; then - user_input "Press ENTER to delete 'netdata' from following groups: '$NETDATA_ADDED_TO_GROUPS' > " - for group in $NETDATA_ADDED_TO_GROUPS; do - portable_del_user_from_group "${group}" "netdata" - done + if user_input "Do you want to delete 'netdata' from following groups: '$NETDATA_ADDED_TO_GROUPS' ? "; then + for group in $NETDATA_ADDED_TO_GROUPS; do + portable_del_user_from_group "${group}" "netdata" + done + fi fi #### REMOVE USER -user_input "Press ENTER to delete 'netdata' system user > " -portable_del_user "netdata" || : +if user_input "Do you want to delete 'netdata' system user ? "; then + portable_del_user "netdata" || : +fi ### REMOVE GROUP -user_input "Press ENTER to delete 'netdata' system group > " -portable_del_group "netdata" || : +if user_input "Do you want to delete 'netdata' system group ? "; then + portable_del_group "netdata" || : +fi diff --git a/packaging/installer/netdata-updater.sh b/packaging/installer/netdata-updater.sh index bfb5503ca..632804376 100755 --- a/packaging/installer/netdata-updater.sh +++ b/packaging/installer/netdata-updater.sh @@ -30,6 +30,8 @@ set -e +PACKAGES_SCRIPT="https://raw.githubusercontent.com/netdata/netdata/master/packaging/installer/install-required-packages.sh" + script_dir="$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd -P)" if [ -x "${script_dir}/netdata-updater" ]; then @@ -46,32 +48,195 @@ else INTERACTIVE=1 fi +if [ -n "${script_source}" ]; then + script_name="$(basename "${script_source}")" +else + script_name="netdata-updater.sh" +fi + info() { - echo >&3 "$(date) : INFO: " "${@}" + echo >&3 "$(date) : INFO: ${script_name}: " "${@}" } error() { - echo >&3 "$(date) : ERROR: " "${@}" + echo >&3 "$(date) : ERROR: ${script_name}: " "${@}" } -: "${ENVIRONMENT_FILE:=THIS_SHOULD_BE_REPLACED_BY_INSTALLER_SCRIPT}" +fatal() { + echo >&3 "$(date) : FATAL: ${script_name}: FAILED TO UPDATE NETDATA: " "${@}" + exit 1 +} -if [ "${ENVIRONMENT_FILE}" = "THIS_SHOULD_BE_REPLACED_BY_INSTALLER_SCRIPT" ]; then - if [ -r "${script_dir}/../../../etc/netdata/.environment" ]; then - ENVIRONMENT_FILE="${script_dir}/../../../etc/netdata/.environment" - elif [ -r "/etc/netdata/.environment" ]; then - ENVIRONMENT_FILE="/etc/netdata/.environment" - elif [ -r "/opt/netdata/etc/netdata/.environment" ]; then - ENVIRONMENT_FILE="/opt/netdata/etc/netdata/.environment" +issystemd() { + # if the directory /lib/systemd/system OR /usr/lib/systemd/system (SLES 12.x) does not exit, it is not systemd + if [ ! -d /lib/systemd/system ] && [ ! -d /usr/lib/systemd/system ]; then + return 1 + fi + + # if there is no systemctl command, it is not systemd + systemctl=$(command -v systemctl 2> /dev/null) + if [ -z "${systemctl}" ] || [ ! -x "${systemctl}" ]; then + return 1 + fi + + # if pid 1 is systemd, it is systemd + [ "$(basename "$(readlink /proc/1/exe)" 2> /dev/null)" = "systemd" ] && return 0 + + # if systemd is not running, it is not systemd + pids=$(safe_pidof systemd 2> /dev/null) + [ -z "${pids}" ] && return 1 + + # check if the running systemd processes are not in our namespace + myns="$(readlink /proc/self/ns/pid 2> /dev/null)" + for p in ${pids}; do + ns="$(readlink "/proc/${p}/ns/pid" 2> /dev/null)" + + # if pid of systemd is in our namespace, it is systemd + [ -n "${myns}" ] && [ "${myns}" = "${ns}" ] && return 0 + done + + # else, it is not systemd + return 1 +} + +_get_intervaldir() { + if [ -d /etc/cron.daily ]; then + echo /etc/cron.daily + elif [ -d /etc/periodic/daily ]; then + echo /etc/periodic/daily else - envpath="$(find / -type d \( -path /sys -o -path /proc -o -path /dev \) -prune -false -o -path '*netdata/.environment' -type f 2> /dev/null | head -n 1)" - if [ -r "${envpath}" ]; then - ENVIRONMENT_FILE="${envpath}" - else - fatal "Cannot find environment file, unable to update." + return 1 + fi + + return 0 +} + +_get_scheduler_type() { + if _get_intervaldir > /dev/null ; then + echo 'interval' + elif issystemd ; then + echo 'systemd' + elif [ -d /etc/cron.d ] ; then + echo 'crontab' + else + echo 'none' + fi +} + +install_build_dependencies() { + bash="$(command -v bash 2> /dev/null)" + + if [ -z "${bash}" ] || [ ! -x "${bash}" ]; then + error "Unable to find a usable version of \`bash\` (required for local build)." + return 1 + fi + + info "Fetching dependency handling script..." + download "${PACKAGES_SCRIPT}" "./install-required-packages.sh" || true + + if [ ! -s "./install-required-packages.sh" ]; then + error "Downloaded dependency installation script is empty." + else + info "Running dependency handling script..." + + opts="--dont-wait --non-interactive" + + # shellcheck disable=SC2086 + if ! "${bash}" "./install-required-packages.sh" ${opts} netdata >&3 2>&3; then + error "Installing build dependencies failed. The update should still work, but you might be missing some features." fi fi -fi +} + +enable_netdata_updater() { + updater_type="$(echo "${1}" | tr '[:upper:]' '[:lower:]')" + case "${updater_type}" in + systemd|interval|crontab) + updater_type="${1}" + ;; + "") + updater_type="$(_get_scheduler_type)" + ;; + *) + error "Unrecognized updater type ${updater_type} requested. Supported types are 'systemd', 'interval', and 'crontab'." + exit 1 + ;; + esac + + case "${updater_type}" in + "systemd") + if issystemd; then + systemctl enable netdata-updater.timer + + info "Auto-updating has been ENABLED using a systemd timer unit.\n" + info "If the update process fails, the failure will be logged to the systemd journal just like a regular service failure." + info "Successful updates should produce empty logs." + else + error "Systemd-based auto-update scheduling requested, but this does not appear to be a systemd system." + error "Auto-updates have NOT been enabled." + return 1 + fi + ;; + "interval") + if _get_intervaldir > /dev/null; then + ln -sf "${NETDATA_PREFIX}/usr/libexec/netdata/netdata-updater.sh" "$(_get_intervaldir)/netdata-updater" + + info "Auto-updating has been ENABLED through cron, updater script linked to $(_get_intervaldir)/netdata-updater\n" + info "If the update process fails and you have email notifications set up correctly for cron on this system, you should receive an email notification of the failure." + info "Successful updates will not send an email." + else + error "Interval-based auto-update scheduling requested, but I could not find an interval scheduling directory." + error "Auto-updates have NOT been enabled." + return 1 + fi + ;; + "crontab") + if [ -d "/etc/cron.d" ]; then + cat > "/etc/cron.d/netdata-updater" <<-EOF + 2 57 * * * root ${NETDATA_PREFIX}/netdata-updater.sh + EOF + + info "Auto-updating has been ENABLED through cron, using a crontab at /etc/cron.d/netdata-updater\n" + info "If the update process fails and you have email notifications set up correctly for cron on this system, you should receive an email notification of the failure." + info "Successful updates will not send an email." + else + error "Crontab-based auto-update scheduling requested, but there is no '/etc/cron.d'." + error "Auto-updates have NOT been enabled." + return 1 + fi + ;; + *) + error "Unable to determine what type of auto-update scheduling to use." + error "Auto-updates have NOT been enabled." + return 1 + esac + + return 0 +} + +disable_netdata_updater() { + if issystemd && ( systemctl list-units --full -all | grep -Fq "netdata-updater.timer" ) ; then + systemctl disable netdata-updater.timer + fi + + if [ -d /etc/cron.daily ]; then + rm -f /etc/cron.daily/netdata-updater.sh + rm -f /etc/cron.daily/netdata-updater + fi + + if [ -d /etc/periodic/daily ]; then + rm -f /etc/periodic/daily/netdata-updater.sh + rm -f /etc/periodic/daily/netdata-updater + fi + + if [ -d /etc/cron.d ]; then + rm -f /etc/cron.d/netdata-updater + fi + + info "Auto-updates have been DISABLED." + + return 0 +} str_in_list() { printf "%s\n" "${2}" | tr ' ' "\n" | grep -qE "^${1}\$" @@ -90,12 +255,6 @@ safe_sha256sum() { fi } -# this is what we will do if it fails (head-less only) -fatal() { - error "FAILED TO UPDATE NETDATA : ${1}" - exit 1 -} - cleanup() { if [ -n "${logfile}" ]; then cat >&2 "${logfile}" @@ -117,7 +276,7 @@ _cannot_use_tmpdir() { if printf '#!/bin/sh\necho SUCCESS\n' > "${testfile}" ; then if chmod +x "${testfile}" ; then - if [ "$("${testfile}")" = "SUCCESS" ] ; then + if [ "$("${testfile}" 2>/dev/null)" = "SUCCESS" ] ; then ret=1 fi fi @@ -199,16 +358,27 @@ get_netdata_latest_tag() { newer_commit_date() { info "Checking if a newer version of the updater script is available." + commit_check_url="https://api.github.com/repos/netdata/netdata/commits?path=packaging%2Finstaller%2Fnetdata-updater.sh&page=1&per_page=1" + python_version_check="from __future__ import print_function;import sys,json;data = json.load(sys.stdin);print(data[0]['commit']['committer']['date'] if isinstance(data, list) else '')" + if command -v jq > /dev/null 2>&1; then - commit_date="$(_safe_download "https://api.github.com/repos/netdata/netdata/commits?path=packaging%2Finstaller%2Fnetdata-updater.sh&page=1&per_page=1" /dev/stdout | jq '.[0].commit.committer.date' | tr -d '"')" + commit_date="$(_safe_download "${commit_check_url}" /dev/stdout | jq '.[0].commit.committer.date' 2>/dev/null | tr -d '"')" elif command -v python > /dev/null 2>&1;then - commit_date="$(_safe_download "https://api.github.com/repos/netdata/netdata/commits?path=packaging%2Finstaller%2Fnetdata-updater.sh&page=1&per_page=1" /dev/stdout | python -c 'from __future__ import print_function;import sys,json;print(json.load(sys.stdin)[0]["commit"]["committer"]["date"])')" + commit_date="$(_safe_download "${commit_check_url}" /dev/stdout | python -c "${python_version_check}")" elif command -v python3 > /dev/null 2>&1;then - commit_date="$(_safe_download "https://api.github.com/repos/netdata/netdata/commits?path=packaging%2Finstaller%2Fnetdata-updater.sh&page=1&per_page=1" /dev/stdout | python3 -c 'from __future__ import print_function;import sys,json;print(json.load(sys.stdin)[0]["commit"]["committer"]["date"])')" + commit_date="$(_safe_download "${commit_check_url}" /dev/stdout | python3 -c "${python_version_check}")" fi if [ -z "${commit_date}" ] ; then - commit_date="9999-12-31T23:59:59Z" + return 0 + elif [ "$(uname)" = "Linux" ]; then + commit_date="$(date -d "${commit_date}" +%s)" + else # assume BSD-style `date` if we are not on Linux + commit_date="$(/bin/date -j -f "%Y-%m-%dT%H:%M:%SZ" "${commit_date}" +%s 2>/dev/null)" + + if [ -z "${commit_date}" ]; then + return 0 + fi fi if [ -e "${script_source}" ]; then @@ -217,7 +387,7 @@ newer_commit_date() { script_date="$(date +%s)" fi - [ "$(date -d "${commit_date}" +%s)" -ge "${script_date}" ] + [ "${commit_date}" -ge "${script_date}" ] } self_update() { @@ -269,7 +439,19 @@ get_latest_version() { fi } +validate_environment_file() { + if [ -n "${RELEASE_CHANNEL}" ] && [ -n "${NETDATA_PREFIX}" ] && [ -n "${REINSTALL_OPTIONS}" ] && [ -n "${IS_NETDATA_STATIC_BINARY}" ]; then + return 0 + else + error "Environment file located at ${ENVIRONMENT_FILE} is not valid, unable to update." + fi +} + update_available() { + if [ "$NETDATA_FORCE_UPDATE" = "1" ]; then + info "Force update requested" + return 0 + fi basepath="$(dirname "$(dirname "$(dirname "${NETDATA_LIB_DIR}")")")" searchpath="${basepath}/bin:${basepath}/sbin:${basepath}/usr/bin:${basepath}/usr/sbin:${PATH}" searchpath="${basepath}/netdata/bin:${basepath}/netdata/sbin:${basepath}/netdata/usr/bin:${basepath}/netdata/usr/sbin:${searchpath}" @@ -333,10 +515,14 @@ update_build() { ndtmpdir=$(create_tmp_directory) cd "$ndtmpdir" || exit 1 + install_build_dependencies + if update_available; then download "${NETDATA_TARBALL_CHECKSUM_URL}" "${ndtmpdir}/sha256sum.txt" >&3 2>&3 download "${NETDATA_TARBALL_URL}" "${ndtmpdir}/netdata-latest.tar.gz" - if [ -n "${NETDATA_TARBALL_CHECKSUM}" ] && grep "${NETDATA_TARBALL_CHECKSUM}" sha256sum.txt >&3 2>&3; then + if [ -n "${NETDATA_TARBALL_CHECKSUM}" ] && + grep "${NETDATA_TARBALL_CHECKSUM}" sha256sum.txt >&3 2>&3 && + [ "$NETDATA_FORCE_UPDATE" != "1" ]; then info "Newest version is already installed" else if ! grep netdata-latest.tar.gz sha256sum.txt | safe_sha256sum -c - >&3 2>&3; then @@ -382,6 +568,10 @@ update_build() { install_type="INSTALL_TYPE='legacy-build'" fi + if [ "${INSTALL_TYPE}" = "custom" ] && [ -f "${NETDATA_PREFIX}" ]; then + install_type="INSTALL_TYPE='legacy-build'" + fi + info "Re-installing netdata..." eval "${env} ./netdata-installer.sh ${REINSTALL_OPTIONS} --dont-wait ${do_not_start}" >&3 2>&3 || fatal "FAILED TO COMPILE/INSTALL NETDATA" @@ -488,7 +678,7 @@ update_binpkg() { upgrade_cmd="upgrade" pkg_install_opts="${interactive_opts}" repo_update_opts="${interactive_opts}" - pkg_installed_check="dpkg -l" + pkg_installed_check="dpkg -s" INSTALL_TYPE="binpkg-deb" ;; ubuntu) @@ -497,7 +687,7 @@ update_binpkg() { upgrade_cmd="upgrade" pkg_install_opts="${interactive_opts}" repo_update_opts="${interactive_opts}" - pkg_installed_check="dpkg -l" + pkg_installed_check="dpkg -s" INSTALL_TYPE="binpkg-deb" ;; centos) @@ -574,6 +764,50 @@ ndtmpdir= trap cleanup EXIT +if [ -t 2 ]; then + # we are running on a terminal + # open fd 3 and send it to stderr + exec 3>&2 +else + # we are headless + # create a temporary file for the log + logfile="$(mktemp -t netdata-updater.log.XXXXXX)" + # open fd 3 and send it to logfile + exec 3> "${logfile}" +fi + +: "${ENVIRONMENT_FILE:=THIS_SHOULD_BE_REPLACED_BY_INSTALLER_SCRIPT}" + +if [ "${ENVIRONMENT_FILE}" = "THIS_SHOULD_BE_REPLACED_BY_INSTALLER_SCRIPT" ]; then + if [ -r "${script_dir}/../../../etc/netdata/.environment" ] || [ -r "${script_dir}/../../../etc/netdata/.install-type" ]; then + ENVIRONMENT_FILE="${script_dir}/../../../etc/netdata/.environment" + elif [ -r "/etc/netdata/.environment" ] || [ -r "/etc/netdata/.install-type" ]; then + ENVIRONMENT_FILE="/etc/netdata/.environment" + elif [ -r "/opt/netdata/etc/netdata/.environment" ] || [ -r "/opt/netdata/etc/netdata/.install-type" ]; then + ENVIRONMENT_FILE="/opt/netdata/etc/netdata/.environment" + else + envpath="$(find / -type d \( -path /sys -o -path /proc -o -path /dev \) -prune -false -o -path '*netdata/.environment' -type f 2> /dev/null | head -n 1)" + itpath="$(find / -type d \( -path /sys -o -path /proc -o -path /dev \) -prune -false -o -path '*netdata/.install-type' -type f 2> /dev/null | head -n 1)" + if [ -r "${envpath}" ]; then + ENVIRONMENT_FILE="${envpath}" + elif [ -r "${itpath}" ]; then + ENVIRONMENT_FILE="$(dirname "${itpath}")/.environment" + else + fatal "Cannot find environment file or install type file, unable to update." + fi + fi +fi + +if [ -r "${ENVIRONMENT_FILE}" ] ; then + # shellcheck source=/dev/null + . "${ENVIRONMENT_FILE}" || exit 1 +fi + +if [ -r "$(dirname "${ENVIRONMENT_FILE}")/.install-type" ]; then + # shellcheck source=/dev/null + . "$(dirname "${ENVIRONMENT_FILE}")/.install-type" || exit 1 +fi + while [ -n "${1}" ]; do if [ "${1}" = "--not-running-from-cron" ]; then NETDATA_NOT_RUNNING_FROM_CRON=1 @@ -581,9 +815,18 @@ while [ -n "${1}" ]; do elif [ "${1}" = "--no-updater-self-update" ]; then NETDATA_NO_UPDATER_SELF_UPDATE=1 shift 1 + elif [ "${1}" = "--force-update" ]; then + NETDATA_FORCE_UPDATE=1 + shift 1 elif [ "${1}" = "--tmpdir-path" ]; then NETDATA_TMPDIR_PATH="${2}" shift 2 + elif [ "${1}" = "--enable-auto-updates" ]; then + enable_netdata_updater "${2}" + exit $? + elif [ "${1}" = "--disable-auto-updates" ]; then + disable_netdata_updater + exit $? else break fi @@ -601,14 +844,6 @@ if [ ! -t 1 ] && [ -z "${NETDATA_NOT_RUNNING_FROM_CRON}" ]; then sleep $(((rnd % 3600) + 1)) fi -# shellcheck source=/dev/null -. "${ENVIRONMENT_FILE}" || exit 1 - -if [ -f "$(dirname "${ENVIRONMENT_FILE}")/.install-type" ]; then - # shellcheck source=/dev/null - . "$(dirname "${ENVIRONMENT_FILE}")/.install-type" || exit 1 -fi - # We dont expect to find lib dir variable on older installations, so load this path if none found export NETDATA_LIB_DIR="${NETDATA_LIB_DIR:-${NETDATA_PREFIX}/var/lib/netdata}" @@ -618,31 +853,21 @@ export NETDATA_LIB_DIR="${NETDATA_LIB_DIR:-${NETDATA_PREFIX}/var/lib/netdata}" # Grab the nightlies baseurl (defaulting to our Google Storage bucket) export NETDATA_NIGHTLIES_BASEURL="${NETDATA_NIGHTLIES_BASEURL:-https://storage.googleapis.com/netdata-nightlies}" -if [ "${INSTALL_UID}" != "$(id -u)" ]; then +if echo "$INSTALL_TYPE" | grep -qv ^binpkg && [ "${INSTALL_UID}" != "$(id -u)" ]; then fatal "You are running this script as user with uid $(id -u). We recommend to run this script as root (user with uid 0)" fi -if [ -t 2 ]; then - # we are running on a terminal - # open fd 3 and send it to stderr - exec 3>&2 -else - # we are headless - # create a temporary file for the log - logfile="$(mktemp -t netdata-updater.log.XXXXXX)" - # open fd 3 and send it to logfile - exec 3> "${logfile}" -fi - self_update # shellcheck disable=SC2153 case "${INSTALL_TYPE}" in *-build) + validate_environment_file || exit 1 set_tarball_urls "${RELEASE_CHANNEL}" "${IS_NETDATA_STATIC_BINARY}" update_build && exit 0 ;; *-static*) + validate_environment_file || exit 1 set_tarball_urls "${RELEASE_CHANNEL}" "${IS_NETDATA_STATIC_BINARY}" update_static && exit 0 ;; @@ -650,15 +875,16 @@ case "${INSTALL_TYPE}" in update_binpkg && exit 0 ;; "") # Fallback case for no `.install-type` file. This just works like the old install type detection. + validate_environment_file || exit 1 update_legacy ;; custom) - # At this point, we _should_ have a valid `.environment` file, but it0s best to just check. + # At this point, we _should_ have a valid `.environment` file, but it's best to just check. # If we do, then behave like the legacy updater. - if [ -n "${RELEASE_CHANNEL}" ] && [ -n "${NETDATA_PREFIX}" ] && [ -n "${REINSTALL_OPTIONS}" ]; then + if validate_environment_file; then update_legacy else - fatal "This script does not support updating custom installations." + fatal "This script does not support updating custom installations without valid environment files." fi ;; oci) diff --git a/packaging/libbpf.checksums b/packaging/libbpf.checksums index 4b6ed4580..1e545cc47 100644 --- a/packaging/libbpf.checksums +++ b/packaging/libbpf.checksums @@ -1 +1 @@ -de0a406ca56b73597a95a96cc0c5bf523161f69517fc5f2f5096fbaef7f223b5 v0.6.1_netdata.tar.gz +d8f935cfdd9256c0902112fc949c9d5d23f1687c66ed359a9a18f06cc71dc676 v0.7_netdata.tar.gz diff --git a/packaging/libbpf.version b/packaging/libbpf.version index 4263286b6..08c143919 100644 --- a/packaging/libbpf.version +++ b/packaging/libbpf.version @@ -1 +1 @@ -0.6.1_netdata +0.7_netdata diff --git a/packaging/maintainers/README.md b/packaging/maintainers/README.md index 903c37d5f..249436d6b 100644 --- a/packaging/maintainers/README.md +++ b/packaging/maintainers/README.md @@ -83,4 +83,4 @@ This page tracks the package maintainers for Netdata, for various operating syst [![Packaging status](https://repology.org/badge/vertical-allrepos/netdata.svg)](https://repology.org/metapackage/netdata/versions) -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fpackaging%2Fmaintainers%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/packaging/makeself/README.md b/packaging/makeself/README.md index c898a9404..055b6c18b 100644 --- a/packaging/makeself/README.md +++ b/packaging/makeself/README.md @@ -51,4 +51,4 @@ To stop Netdata while it runs under `valgrind`, press Control-C on the console. > If you omit the parameter `--undef-value-errors=no` to valgrind, you will get hundreds of errors about conditional jumps that depend on uninitialized values. This is normal. Valgrind has heuristics to prevent it from printing such errors for system libraries, but for the static Netdata binary, all the required libraries are built into Netdata. So, valgrind cannot apply its heuristics and prints them. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fmakeself%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/packaging/makeself/build-static.sh b/packaging/makeself/build-static.sh index e4c92a7ba..f38353721 100755 --- a/packaging/makeself/build-static.sh +++ b/packaging/makeself/build-static.sh @@ -45,8 +45,8 @@ if ! docker inspect "${DOCKER_CONTAINER_NAME}" > /dev/null 2>&1; then run docker pull --platform=${platform} alpine:3.15 fi - run docker run --platform=${platform} -v "$(pwd)":/usr/src/netdata.git:rw alpine:3.15 \ - /bin/sh /usr/src/netdata.git/packaging/makeself/install-alpine-packages.sh + run docker run --platform=${platform} -v "$(pwd)":/netdata:rw alpine:3.15 \ + /bin/sh /netdata/packaging/makeself/install-alpine-packages.sh # save the changes made permanently id=$(docker ps -l -q) @@ -55,15 +55,11 @@ fi # Run the build script inside the container if [ -t 1 ]; then - run docker run -e BUILDARCH="${BUILDARCH}" -a stdin -a stdout -a stderr -i -t -v "$(pwd)":/usr/src/netdata.git:rw \ + run docker run -e BUILDARCH="${BUILDARCH}" -a stdin -a stdout -a stderr -i -t -v "$(pwd)":/netdata:rw \ "${DOCKER_CONTAINER_NAME}" \ - /bin/sh /usr/src/netdata.git/packaging/makeself/build.sh "${@}" + /bin/sh /netdata/packaging/makeself/build.sh "${@}" else - run docker run -e BUILDARCH="${BUILDARCH}" -v "$(pwd)":/usr/src/netdata.git:rw \ + run docker run -e BUILDARCH="${BUILDARCH}" -v "$(pwd)":/netdata:rw \ -e GITHUB_ACTIONS="${GITHUB_ACTIONS}" "${DOCKER_CONTAINER_NAME}" \ - /bin/sh /usr/src/netdata.git/packaging/makeself/build.sh "${@}" -fi - -if [ "${USER}" ]; then - sudo chown -R "${USER}" . + /bin/sh /netdata/packaging/makeself/build.sh "${@}" fi diff --git a/packaging/makeself/build.sh b/packaging/makeself/build.sh index 4eb2c9f41..3ac600ed4 100755 --- a/packaging/makeself/build.sh +++ b/packaging/makeself/build.sh @@ -27,16 +27,11 @@ done # the required packages. build-x86_64-static.sh will do this for you # using docker. -cd "$(dirname "$0")" || exit 1 - -# if we don't run inside the netdata repo -# download it and run from it -if [ ! -f ../../netdata-installer.sh ]; then - git clone https://github.com/netdata/netdata.git netdata.git || exit 1 - cd netdata.git/makeself || exit 1 - ./build.sh "$@" - exit $? -fi +mkdir -p /usr/src +cp -va /netdata /usr/src/netdata +chown -R root:root /usr/src/netdata + +cd /usr/src/netdata/packaging/makeself || exit 1 git clean -dxf git submodule foreach --recursive git clean -dxf @@ -64,3 +59,7 @@ if ! ./run-all-jobs.sh "$@"; then printf >&2 "Build failed." exit 1 fi + +mkdir -p /netdata/artifacts +cp -va /usr/src/netdata/artifacts/* /netdata/artifacts/ +chown -R "$(stat -c '%u:%g' /netdata)" /netdata/artifacts/ diff --git a/packaging/makeself/install-alpine-packages.sh b/packaging/makeself/install-alpine-packages.sh index 6258d5dda..06bcd5622 100755 --- a/packaging/makeself/install-alpine-packages.sh +++ b/packaging/makeself/install-alpine-packages.sh @@ -7,6 +7,9 @@ # # Author: Paul Emm. Katsoulakis +apk update || exit 1 +apk upgrade || exit 1 + # Add required APK packages apk add --no-cache -U \ alpine-sdk \ diff --git a/packaging/makeself/install-or-update.sh b/packaging/makeself/install-or-update.sh index 13d178d31..6a4cd5b97 100755 --- a/packaging/makeself/install-or-update.sh +++ b/packaging/makeself/install-or-update.sh @@ -26,7 +26,6 @@ if [ -d /opt/netdata/etc/netdata.old ]; then fi STARTIT=1 -AUTOUPDATE=0 REINSTALL_OPTIONS="" RELEASE_CHANNEL="nightly" # check .travis/create_artifacts.sh before modifying @@ -36,10 +35,7 @@ while [ "${1}" ]; do STARTIT=0 REINSTALL_OPTIONS="${REINSTALL_OPTIONS} ${1}" ;; - "--auto-update" | "-u") - AUTOUPDATE=1 - REINSTALL_OPTIONS="${REINSTALL_OPTIONS} ${1}" - ;; + "--auto-update" | "-u") ;; "--stable-channel") RELEASE_CHANNEL="stable" REINSTALL_OPTIONS="${REINSTALL_OPTIONS} ${1}" @@ -58,7 +54,10 @@ while [ "${1}" ]; do shift 1 done -if [ ! "${DO_NOT_TRACK:-0}" -eq 0 ] || [ -n "$DO_NOT_TRACK" ]; then +if [ ! "${DISABLE_TELEMETRY:-0}" -eq 0 ] || + [ -n "$DISABLE_TELEMETRY" ] || + [ ! "${DO_NOT_TRACK:-0}" -eq 0 ] || + [ -n "$DO_NOT_TRACK" ]; then NETDATA_DISABLE_TELEMETRY=1 REINSTALL_OPTIONS="${REINSTALL_OPTIONS} --disable-telemetry" fi @@ -158,13 +157,6 @@ progress "Install (but not enable) netdata updater tool" cleanup_old_netdata_updater || run_failed "Cannot cleanup old netdata updater tool." install_netdata_updater || run_failed "Cannot install netdata updater tool." -progress "Check if we must enable/disable the netdata updater tool" -if [ "${AUTOUPDATE}" = "1" ]; then - enable_netdata_updater || run_failed "Cannot enable netdata updater tool" -else - disable_netdata_updater || run_failed "Cannot disable netdata updater tool" -fi - # ----------------------------------------------------------------------------- progress "creating quick links" diff --git a/packaging/makeself/jobs/50-bash-5.1.16.install.sh b/packaging/makeself/jobs/50-bash-5.1.16.install.sh new file mode 100755 index 000000000..d5cdfff1c --- /dev/null +++ b/packaging/makeself/jobs/50-bash-5.1.16.install.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: GPL-3.0-or-later + +# shellcheck source=packaging/makeself/functions.sh +. "$(dirname "${0}")/../functions.sh" "${@}" || exit 1 + +# shellcheck disable=SC2015 +[ "${GITHUB_ACTIONS}" = "true" ] && echo "::group::building bash" || true + +fetch "bash-5.1.16" "http://ftp.gnu.org/gnu/bash/bash-5.1.16.tar.gz" \ + 5bac17218d3911834520dad13cd1f85ab944e1c09ae1aba55906be1f8192f558 + +export PKG_CONFIG_PATH="/openssl-static/lib/pkgconfig" + +run ./configure \ + --prefix="${NETDATA_INSTALL_PATH}" \ + --without-bash-malloc \ + --enable-static-link \ + --enable-net-redirections \ + --enable-array-variables \ + --disable-progcomp \ + --disable-profiling \ + --disable-nls + +run make clean +run make -j "$(nproc)" + +cat > examples/loadables/Makefile << EOF +all: +clean: +install: +EOF + +run make install + +if [ "${NETDATA_BUILD_WITH_DEBUG}" -eq 0 ]; then + run strip "${NETDATA_INSTALL_PATH}"/bin/bash +fi + +# shellcheck disable=SC2015 +[ "${GITHUB_ACTIONS}" = "true" ] && echo "::endgroup::" || true diff --git a/packaging/makeself/jobs/50-bash-5.1.8.install.sh b/packaging/makeself/jobs/50-bash-5.1.8.install.sh deleted file mode 100755 index 22c9286af..000000000 --- a/packaging/makeself/jobs/50-bash-5.1.8.install.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env bash -# SPDX-License-Identifier: GPL-3.0-or-later - -# shellcheck source=packaging/makeself/functions.sh -. "$(dirname "${0}")/../functions.sh" "${@}" || exit 1 - -# shellcheck disable=SC2015 -[ "${GITHUB_ACTIONS}" = "true" ] && echo "::group::building bash" || true - -fetch "bash-5.1.8" "http://ftp.gnu.org/gnu/bash/bash-5.1.8.tar.gz" \ - 0cfb5c9bb1a29f800a97bd242d19511c997a1013815b805e0fdd32214113d6be - -export PKG_CONFIG_PATH="/openssl-static/lib/pkgconfig" - -run ./configure \ - --prefix="${NETDATA_INSTALL_PATH}" \ - --without-bash-malloc \ - --enable-static-link \ - --enable-net-redirections \ - --enable-array-variables \ - --disable-progcomp \ - --disable-profiling \ - --disable-nls - -run make clean -run make -j "$(nproc)" - -cat > examples/loadables/Makefile << EOF -all: -clean: -install: -EOF - -run make install - -if [ "${NETDATA_BUILD_WITH_DEBUG}" -eq 0 ]; then - run strip "${NETDATA_INSTALL_PATH}"/bin/bash -fi - -# shellcheck disable=SC2015 -[ "${GITHUB_ACTIONS}" = "true" ] && echo "::endgroup::" || true diff --git a/packaging/makeself/jobs/50-curl-7.78.0.install.sh b/packaging/makeself/jobs/50-curl-7.78.0.install.sh deleted file mode 100755 index aeab1af68..000000000 --- a/packaging/makeself/jobs/50-curl-7.78.0.install.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env bash -# SPDX-License-Identifier: GPL-3.0-or-later - -# shellcheck source=packaging/makeself/functions.sh -. "$(dirname "${0}")/../functions.sh" "${@}" || exit 1 - -# shellcheck disable=SC2015 -[ "${GITHUB_ACTIONS}" = "true" ] && echo "::group::Building cURL" || true - -fetch "curl-7.78.0" "https://curl.haxx.se/download/curl-7.78.0.tar.gz" \ - ed936c0b02c06d42cf84b39dd12bb14b62d77c7c4e875ade022280df5dcc81d7 - -export CFLAGS="-I/openssl-static/include" -export LDFLAGS="-static -L/openssl-static/lib" -export PKG_CONFIG="pkg-config --static" -export PKG_CONFIG_PATH="/openssl-static/lib/pkgconfig" - -run autoreconf -fi - -run ./configure \ - --prefix="${NETDATA_INSTALL_PATH}" \ - --enable-optimize \ - --disable-shared \ - --enable-static \ - --enable-http \ - --disable-ldap \ - --disable-ldaps \ - --enable-proxy \ - --disable-dict \ - --disable-telnet \ - --disable-tftp \ - --disable-pop3 \ - --disable-imap \ - --disable-smb \ - --disable-smtp \ - --disable-gopher \ - --enable-ipv6 \ - --enable-cookies \ - --with-ca-fallback \ - --with-openssl - -# Curl autoconf does not honour the curl_LDFLAGS environment variable -run sed -i -e "s/LDFLAGS =/LDFLAGS = -all-static/" src/Makefile - -run make clean -run make -j "$(nproc)" -run make install - -if [ "${NETDATA_BUILD_WITH_DEBUG}" -eq 0 ]; then - run strip "${NETDATA_INSTALL_PATH}"/bin/curl -fi - -# shellcheck disable=SC2015 -[ "${GITHUB_ACTIONS}" = "true" ] && echo "::group::Preparing build environment" || true diff --git a/packaging/makeself/jobs/50-curl-7.82.0.install.sh b/packaging/makeself/jobs/50-curl-7.82.0.install.sh new file mode 100755 index 000000000..f8fa4042c --- /dev/null +++ b/packaging/makeself/jobs/50-curl-7.82.0.install.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: GPL-3.0-or-later + +# shellcheck source=packaging/makeself/functions.sh +. "$(dirname "${0}")/../functions.sh" "${@}" || exit 1 + +# shellcheck disable=SC2015 +[ "${GITHUB_ACTIONS}" = "true" ] && echo "::group::Building cURL" || true + +fetch "curl-7.82.0" "https://curl.haxx.se/download/curl-7.82.0.tar.gz" \ + 910cc5fe279dc36e2cca534172c94364cf3fcf7d6494ba56e6c61a390881ddce + +export CFLAGS="-I/openssl-static/include" +export LDFLAGS="-static -L/openssl-static/lib" +export PKG_CONFIG="pkg-config --static" +export PKG_CONFIG_PATH="/openssl-static/lib/pkgconfig" + +run autoreconf -fi + +run ./configure \ + --prefix="${NETDATA_INSTALL_PATH}" \ + --enable-optimize \ + --disable-shared \ + --enable-static \ + --enable-http \ + --disable-ldap \ + --disable-ldaps \ + --enable-proxy \ + --disable-dict \ + --disable-telnet \ + --disable-tftp \ + --disable-pop3 \ + --disable-imap \ + --disable-smb \ + --disable-smtp \ + --disable-gopher \ + --enable-ipv6 \ + --enable-cookies \ + --with-ca-fallback \ + --with-openssl + +# Curl autoconf does not honour the curl_LDFLAGS environment variable +run sed -i -e "s/LDFLAGS =/LDFLAGS = -all-static/" src/Makefile + +run make clean +run make -j "$(nproc)" +run make install + +if [ "${NETDATA_BUILD_WITH_DEBUG}" -eq 0 ]; then + run strip "${NETDATA_INSTALL_PATH}"/bin/curl +fi + +# shellcheck disable=SC2015 +[ "${GITHUB_ACTIONS}" = "true" ] && echo "::group::Preparing build environment" || true diff --git a/packaging/makeself/jobs/50-fping-5.0.install.sh b/packaging/makeself/jobs/50-fping-5.0.install.sh deleted file mode 100755 index 8bef27d4d..000000000 --- a/packaging/makeself/jobs/50-fping-5.0.install.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env bash -# SPDX-License-Identifier: GPL-3.0-or-later - -# shellcheck source=packaging/makeself/functions.sh -. "$(dirname "${0}")/../functions.sh" "${@}" || exit 1 - -# shellcheck disable=SC2015 -[ "${GITHUB_ACTIONS}" = "true" ] && echo "::group::Building fping" || true - -fetch "fping-5.0" "https://fping.org/dist/fping-5.0.tar.gz" \ - ed38c0b9b64686a05d1b3bc1d66066114a492e04e44eef1821d43b1263cd57b8 - -export CFLAGS="-static -I/openssl-static/include" -export LDFLAGS="-static -L/openssl-static/lib" -export PKG_CONFIG_PATH="/openssl-static/lib/pkgconfig" - -run ./configure \ - --prefix="${NETDATA_INSTALL_PATH}" \ - --enable-ipv4 \ - --enable-ipv6 - -cat > doc/Makefile << EOF -all: -clean: -install: -EOF - -run make clean -run make -j "$(nproc)" -run make install - -if [ "${NETDATA_BUILD_WITH_DEBUG}" -eq 0 ]; then - run strip "${NETDATA_INSTALL_PATH}"/bin/fping -fi - -# shellcheck disable=SC2015 -[ "${GITHUB_ACTIONS}" = "true" ] && echo "::endgroup::" || true diff --git a/packaging/makeself/jobs/50-fping-5.1.install.sh b/packaging/makeself/jobs/50-fping-5.1.install.sh new file mode 100755 index 000000000..e1435e944 --- /dev/null +++ b/packaging/makeself/jobs/50-fping-5.1.install.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: GPL-3.0-or-later + +# shellcheck source=packaging/makeself/functions.sh +. "$(dirname "${0}")/../functions.sh" "${@}" || exit 1 + +# shellcheck disable=SC2015 +[ "${GITHUB_ACTIONS}" = "true" ] && echo "::group::Building fping" || true + +fetch "fping-5.1" "https://fping.org/dist/fping-5.1.tar.gz" \ + 1ee5268c063d76646af2b4426052e7d81a42b657e6a77d8e7d3d2e60fd7409fe + +export CFLAGS="-static -I/openssl-static/include" +export LDFLAGS="-static -L/openssl-static/lib" +export PKG_CONFIG_PATH="/openssl-static/lib/pkgconfig" + +run ./configure \ + --prefix="${NETDATA_INSTALL_PATH}" \ + --enable-ipv4 \ + --enable-ipv6 + +cat > doc/Makefile << EOF +all: +clean: +install: +EOF + +run make clean +run make -j "$(nproc)" +run make install + +if [ "${NETDATA_BUILD_WITH_DEBUG}" -eq 0 ]; then + run strip "${NETDATA_INSTALL_PATH}"/bin/fping +fi + +# shellcheck disable=SC2015 +[ "${GITHUB_ACTIONS}" = "true" ] && echo "::endgroup::" || true diff --git a/packaging/makeself/jobs/99-makeself.install.sh b/packaging/makeself/jobs/99-makeself.install.sh index 9dfcfbed7..d29d0580a 100755 --- a/packaging/makeself/jobs/99-makeself.install.sh +++ b/packaging/makeself/jobs/99-makeself.install.sh @@ -12,10 +12,7 @@ run cd "${NETDATA_SOURCE_PATH}" || exit 1 # ----------------------------------------------------------------------------- # find the netdata version -VERSION="$(git describe 2> /dev/null)" -if [ -z "${VERSION}" ]; then - VERSION=$(cat packaging/version) -fi +VERSION="$("${NETDATA_INSTALL_PARENT}/netdata/bin/netdata" -v | cut -f 2 -d ' ')" if [ "${VERSION}" == "" ]; then echo >&2 "Cannot find version number. Create makeself executable from source code with git tree structure." diff --git a/packaging/makeself/makeself-help-header.txt b/packaging/makeself/makeself-help-header.txt index 9bcbf4518..8ed15e2e7 100644 --- a/packaging/makeself/makeself-help-header.txt +++ b/packaging/makeself/makeself-help-header.txt @@ -45,5 +45,5 @@ Anonymous stat collection and reporting to Netdata is enabled by default. To disable, pass --disable-telemetry option to the installer - or export the environment variable DO_NOT_TRACK to a non-zero or non-empty - value (e.g export DO_NOT_TRACK=1). + or export the environment variable DISABLE_TELEMETRY to a non-zero or non-empty + value (e.g export DISABLE_TELEMETRY=1). diff --git a/packaging/makeself/makeself-license.txt b/packaging/makeself/makeself-license.txt index 518d85d95..b844e9a9a 100644 --- a/packaging/makeself/makeself-license.txt +++ b/packaging/makeself/makeself-license.txt @@ -41,4 +41,4 @@ netdata re-distributes a lot of open source software components. Check its full license at: - https://github.com/netdata/netdata/blob/master/LICENSE.md + https://github.com/netdata/netdata/blob/master/LICENSE diff --git a/packaging/makeself/openssl.version b/packaging/makeself/openssl.version index 5b309eb4f..ad1bcee8f 100644 --- a/packaging/makeself/openssl.version +++ b/packaging/makeself/openssl.version @@ -1 +1 @@ -OpenSSL_1_1_1l +OpenSSL_1_1_1n diff --git a/packaging/protobuf.checksums b/packaging/protobuf.checksums index b901a0be4..4a025c5fb 100644 --- a/packaging/protobuf.checksums +++ b/packaging/protobuf.checksums @@ -1 +1 @@ -51cec99f108b83422b7af1170afd7aeb2dd77d2bcbb7b6bad1f92509e9ccf8cb protobuf-cpp-3.17.3.tar.gz +89ac31a93832e204db6d73b1e80f39f142d5747b290f17340adce5be5b122f94 protobuf-cpp-3.19.4.tar.gz diff --git a/packaging/protobuf.version b/packaging/protobuf.version index 56cc1b61f..de24deecf 100644 --- a/packaging/protobuf.version +++ b/packaging/protobuf.version @@ -1 +1 @@ -3.17.3 +3.19.4 diff --git a/packaging/repoconfig/netdata-edge.repo.centos b/packaging/repoconfig/netdata-edge.repo.centos index 124cf612e..af56384f3 100644 --- a/packaging/repoconfig/netdata-edge.repo.centos +++ b/packaging/repoconfig/netdata-edge.repo.centos @@ -7,6 +7,7 @@ gpgkey=https://packagecloud.io/netdata/netdata-edge/gpgkey enabled=1 sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt +priority=50 [netdata-repoconfig] name=Netdata Repository Config @@ -17,3 +18,4 @@ gpgkey=https://packagecloud.io/netdata/netdata-repoconfig/gpgkey enabled=1 sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt +priority=50 diff --git a/packaging/repoconfig/netdata-edge.repo.fedora b/packaging/repoconfig/netdata-edge.repo.fedora index 636fba6e4..902e00c13 100644 --- a/packaging/repoconfig/netdata-edge.repo.fedora +++ b/packaging/repoconfig/netdata-edge.repo.fedora @@ -7,6 +7,7 @@ gpgkey=https://packagecloud.io/netdata/netdata-edge/gpgkey enabled=1 sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt +priority=50 [netdata-repoconfig] name=Netdata Repository Config @@ -17,3 +18,4 @@ gpgkey=https://packagecloud.io/netdata/netdata-repoconfig/gpgkey enabled=1 sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt +priority=50 diff --git a/packaging/repoconfig/netdata-edge.repo.ol b/packaging/repoconfig/netdata-edge.repo.ol index d6da7d356..1d1ea407b 100644 --- a/packaging/repoconfig/netdata-edge.repo.ol +++ b/packaging/repoconfig/netdata-edge.repo.ol @@ -7,6 +7,7 @@ gpgkey=https://packagecloud.io/netdata/netdata-edge/gpgkey enabled=1 sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt +priority=50 [netdata-repoconfig] name=Netdata Repository Config @@ -17,3 +18,4 @@ gpgkey=https://packagecloud.io/netdata/netdata-repoconfig/gpgkey enabled=1 sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt +priority=50 diff --git a/packaging/repoconfig/netdata-repo.spec b/packaging/repoconfig/netdata-repo.spec index eaee0eba5..0a26b97c3 100644 --- a/packaging/repoconfig/netdata-repo.spec +++ b/packaging/repoconfig/netdata-repo.spec @@ -19,6 +19,10 @@ Source7: netdata-edge.repo.ol BuildArch: noarch +%if 0%{?centos_ver} && 0%{?centos_ver} < 8 +Requires: yum-plugin-priorities +%endif + # Overlapping file installs Conflicts: netdata-repo-edge diff --git a/packaging/repoconfig/netdata.repo.centos b/packaging/repoconfig/netdata.repo.centos index 1eb2f2616..d9cb2bca8 100644 --- a/packaging/repoconfig/netdata.repo.centos +++ b/packaging/repoconfig/netdata.repo.centos @@ -7,6 +7,7 @@ gpgkey=https://packagecloud.io/netdata/netdata/gpgkey enabled=1 sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt +priority=50 [netdata-repoconfig] name=Netdata Repository Config @@ -17,3 +18,4 @@ gpgkey=https://packagecloud.io/netdata/netdata-repoconfig/gpgkey enabled=1 sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt +priority=50 diff --git a/packaging/repoconfig/netdata.repo.fedora b/packaging/repoconfig/netdata.repo.fedora index 5efb5c73a..82ec6ea57 100644 --- a/packaging/repoconfig/netdata.repo.fedora +++ b/packaging/repoconfig/netdata.repo.fedora @@ -7,6 +7,7 @@ gpgkey=https://packagecloud.io/netdata/netdata/gpgkey enabled=1 sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt +priority=50 [netdata-repoconfig] name=Netdata Repository Config @@ -17,3 +18,4 @@ gpgkey=https://packagecloud.io/netdata/netdata-repoconfig/gpgkey enabled=1 sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt +priority=50 diff --git a/packaging/repoconfig/netdata.repo.ol b/packaging/repoconfig/netdata.repo.ol index 4b3d61997..763504b29 100644 --- a/packaging/repoconfig/netdata.repo.ol +++ b/packaging/repoconfig/netdata.repo.ol @@ -7,6 +7,7 @@ gpgkey=https://packagecloud.io/netdata/netdata/gpgkey enabled=1 sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt +priority=50 [netdata-repoconfig] name=Netdata Repository Config @@ -17,3 +18,4 @@ gpgkey=https://packagecloud.io/netdata/netdata-repoconfig/gpgkey enabled=1 sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt +priority=50 diff --git a/packaging/version b/packaging/version index 9efd800d4..995ab8e3f 100644 --- a/packaging/version +++ b/packaging/version @@ -1 +1 @@ -v1.33.1 +v1.34.0 diff --git a/parser/README.md b/parser/README.md index 50d55e3d6..c01972df6 100644 --- a/parser/README.md +++ b/parser/README.md @@ -145,5 +145,3 @@ Output Returns - none - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fparser%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]() diff --git a/registry/README.md b/registry/README.md index 1544a57d1..df618ffc5 100644 --- a/registry/README.md +++ b/registry/README.md @@ -211,4 +211,4 @@ ERROR 409: Cannot ACCESS netdata registry: https://registry.my-netdata.io respon This error is printed on your web browser console (press F12 on your browser to see it). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fregistry%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/streaming/README.md b/streaming/README.md index 71c1dc289..57c392f40 100644 --- a/streaming/README.md +++ b/streaming/README.md @@ -67,18 +67,18 @@ Alerts for the child can be triggered by any of the involved hosts that maintain You can daisy-chain any number of Netdata, each with or without a database and with or without alerts for the child metrics. -### Mix and match with backends +### Mix and match with exporting engine -All nodes that maintain a database can also send their data to a backend database. +All nodes that maintain a database can also send their data to an external database. This allows quite complex setups. Example: 1. Netdata nodes `A` and `B` do not maintain a database and stream metrics to Netdata node `C`(live streaming functionality). -2. Netdata node `C` maintains a database for `A`, `B`, `C` and archives all metrics to `graphite` with 10 second detail (backends functionality). +2. Netdata node `C` maintains a database for `A`, `B`, `C` and archives all metrics to `graphite` with 10 second detail (exporting functionality). 3. Netdata node `C` also streams data for `A`, `B`, `C` to Netdata `D`, which also collects data from `E`, `F` and `G` from another DMZ (live streaming functionality). 4. Netdata node `D` is just a proxy, without a database, that streams all data to a remote site at Netdata `H`. -5. Netdata node `H` maintains a database for `A`, `B`, `C`, `D`, `E`, `F`, `G`, `H` and sends all data to `opentsdb` with 5 seconds detail (backends functionality) +5. Netdata node `H` maintains a database for `A`, `B`, `C`, `D`, `E`, `F`, `G`, `H` and sends all data to `opentsdb` with 5 seconds detail (exporting functionality) 6. Alerts are triggered by `H` for all hosts. 7. Users can use all Netdata nodes that maintain a database to view metrics (i.e. at `H` all hosts can be viewed). @@ -107,15 +107,7 @@ This also disables the registry (there cannot be a registry without an API). requests from its child nodes. 0 sets no limit, 1 means maximum once every second. If this is set, you may see error log entries "... too busy to accept new streaming request. Will be allowed in X secs". -``` -[backend] - enabled = yes | no - type = graphite | opentsdb - destination = IP:PORT ... - update every = 10 -``` - -`[backend]` configures data archiving to a backend (it archives all databases maintained on +You can [use](/exporting/README.md#configuration) the exporting engine to configure data archiving to an external database (it archives all databases maintained on this host). ### Streaming configuration @@ -156,7 +148,7 @@ a proxy). ``` This is an overview of how these options can be combined: -| target|memory
mode|web
mode|stream
enabled|backend|alarms|dashboard| +| target|memory
mode|web
mode|stream
enabled|exporting|alarms|dashboard| |------|:-------------:|:----------:|:----------------:|:-----:|:----:|:-------:| | headless collector|`none`|`none`|`yes`|only for `data source = as collected`|not possible|no| | headless proxy|`none`|not `none`|`yes`|only for `data source = as collected`|not possible|no| @@ -211,7 +203,6 @@ that use `*` as wildcard (any number of times) and a `!` prefix for a negative m So: `allow from = !10.1.2.3 10.*` will allow all IPs in `10.*` except `10.1.2.3`. The order is important: left to right, the first positive or negative match is used. -`allow from` is available in Netdata v1.9+ ##### Tracing @@ -366,16 +357,30 @@ Note: The `stream-compression` status can be `"enabled" | "disabled" | "N/A"`. A compressed data packet is determined and decompressed on the fly. #### Limitations - This limitation will be withdrawn asap and is work-in-progress. - -The current implementation of streaming data compression can support only a few number of dimensions in a chart with names that cannot exceed the size of 16384 bytes. In case you experience stream connection problems or gaps in the charts please disable stream compresssion in the `stream.conf` file. This limitation can be seen in the error.log file with the sequence of the following messages: -``` -Compression error - data discarded -Message size above limit: +This limitation will be withdrawn asap and is work-in-progress. + +The current implementation of streaming data compression can support only a few number of dimensions in a chart with names that cannot exceed the size of 16384 bytes. In case your instance hit this limitation, the agent will deactivate compression during runtime to avoid stream corruption. This limitation can be seen in the error.log file with the sequence of the following messages: +``` +netdata INFO : STREAM_SENDER[child01] : STREAM child01 [send to my.parent.IP]: connecting... +netdata INFO : STREAM_SENDER[child01] : STREAM child01 [send to my.parent.IP]: initializing communication... +netdata INFO : STREAM_SENDER[child01] : STREAM child01 [send to my.parent.IP]: waiting response from remote netdata... +netdata INFO : STREAM_SENDER[child01] : STREAM_COMPRESSION: Compressor Reset +netdata INFO : STREAM_SENDER[child01] : STREAM child01 [send to my.parent.IP]: established communication with a parent using protocol version 5 - ready to send metrics... +... +netdata ERROR : PLUGINSD[go.d] : STREAM_COMPRESSION: Compression Failed - Message size 27847 above compression buffer limit: 16384 (errno 9, Bad file descriptor) +netdata ERROR : PLUGINSD[go.d] : STREAM_COMPRESSION: Deactivating compression to avoid stream corruption +netdata ERROR : PLUGINSD[go.d] : STREAM_COMPRESSION child01 [send to my.parent.IP]: Restarting connection without compression +... +netdata INFO : STREAM_SENDER[child01] : STREAM child01 [send to my.parent.IP]: connecting... +netdata INFO : STREAM_SENDER[child01] : STREAM child01 [send to my.parent.IP]: initializing communication... +netdata INFO : STREAM_SENDER[child01] : STREAM child01 [send to my.parent.IP]: waiting response from remote netdata... +netdata INFO : STREAM_SENDER[child01] : Stream is uncompressed! One of the agents (my.parent.IP <-> child01) does not support compression OR compression is disabled. +netdata INFO : STREAM_SENDER[child01] : STREAM child01 [send to my.parent.IP]: established communication with a parent using protocol version 4 - ready to send metrics... +netdata INFO : WEB_SERVER[static4] : STREAM child01 [send]: sending metrics... ``` #### How to enable stream compression -Netdata Agents are shipped with data compression disabled by default. You can also configure which streams will use compression. +Netdata Agents are shipped with data compression enabled by default. You can also configure which streams will use compression. With enabled stream compression, a Netdata Agent can negotiate streaming compression with other Netdata Agents. During the negotiation of streaming compression both Netdata Agents should support and enable compression in order to communicate over a compressed stream. The negotiation will result into an uncompressed stream, if one of the Netdata Agents doesn't support **or** has compression disabled. @@ -727,4 +732,4 @@ file descriptor given is not a valid stream After logging this error, Netdata will close the stream. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fstreaming%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/streaming/compression.c b/streaming/compression.c index 93810aaed..d6178d6c3 100644 --- a/streaming/compression.c +++ b/streaming/compression.c @@ -3,6 +3,8 @@ #ifdef ENABLE_COMPRESSION #include "lz4.h" +#define STREAM_COMPRESSION_MSG "STREAM_COMPRESSION" + #define LZ4_MAX_MSG_SIZE 0x4000 #define LZ4_STREAM_BUFFER_SIZE (0x10000 + LZ4_MAX_MSG_SIZE) @@ -29,7 +31,7 @@ static void lz4_compressor_reset(struct compressor_state *state) if (state->data) { if (state->data->stream) { LZ4_resetStream_fast(state->data->stream); - info("STREAM_COMPRESSION: Compressor resets stream fast!"); + info("%s: Compressor Reset", STREAM_COMPRESSION_MSG); } state->data->stream_buffer_pos = 0; } @@ -46,18 +48,19 @@ static void lz4_compressor_destroy(struct compressor_state **state) if (s->data->stream) LZ4_freeStream(s->data->stream); freez(s->data->stream_buffer); + freez(s->data); } freez(s->buffer); freez(s); *state = NULL; - debug(D_STREAM, "STREAM_COMPRESSION: Compressor destroyed!"); + debug(D_STREAM, "%s: Compressor Destroyed.", STREAM_COMPRESSION_MSG); } } /* * Compress the given block of data - * Comprecced data will remain in the internal buffer until the next invokation - * Return the size of compressed data block as result and the pointer to internal buffer using the last argument + * Compressed data will remain in the internal buffer until the next invocation + * Return the size of compressed data block as result and the pointer to internal buffer using the last argument * or 0 in case of error */ static size_t lz4_compressor_compress(struct compressor_state *state, const char *data, size_t size, char **out) @@ -65,7 +68,7 @@ static size_t lz4_compressor_compress(struct compressor_state *state, const char if (!state || !size || !out) return 0; if (size > LZ4_MAX_MSG_SIZE) { - error("Message size above limit: %lu", size); + error("%s: Compression Failed - Message size %lu above compression buffer limit: %d", STREAM_COMPRESSION_MSG, size, LZ4_MAX_MSG_SIZE); return 0; } size_t max_dst_size = LZ4_COMPRESSBOUND(size); @@ -84,7 +87,7 @@ static size_t lz4_compressor_compress(struct compressor_state *state, const char state->data->stream_buffer + state->data->stream_buffer_pos, state->buffer + SIGNATURE_SIZE, size, max_dst_size, 1); if (compressed_data_size < 0) { - error("Date compression error: %ld", compressed_data_size); + error("Data compression error: %ld", compressed_data_size); return 0; } state->data->stream_buffer_pos += size; @@ -93,12 +96,12 @@ static size_t lz4_compressor_compress(struct compressor_state *state, const char uint32_t len = ((compressed_data_size & 0x7f) | 0x80 | (((compressed_data_size & (0x7f << 7)) << 1) | 0x8000)) << 8; *(uint32_t *)state->buffer = len | SIGNATURE; *out = state->buffer; - debug(D_STREAM, "STREAM: Compressed data header: %ld", compressed_data_size); + debug(D_STREAM, "%s: Compressed data header: %ld", STREAM_COMPRESSION_MSG, compressed_data_size); return compressed_data_size + SIGNATURE_SIZE; } /* - * Create and initalize compressor state + * Create and initialize compressor state * Return the pointer to compressor_state structure created */ struct compressor_state *create_compressor() @@ -114,7 +117,7 @@ struct compressor_state *create_compressor() state->data->stream_buffer = callocz(1, LZ4_DECODER_RING_BUFFER_SIZE(LZ4_MAX_MSG_SIZE)); state->buffer_size = LZ4_STREAM_BUFFER_SIZE; state->reset(state); - debug(D_STREAM, "STREAM_COMPRESSION: Initialize streaming compression!"); + debug(D_STREAM, "%s: Initialize streaming compression!", STREAM_COMPRESSION_MSG); return state; } @@ -150,10 +153,11 @@ static void lz4_decompressor_destroy(struct decompressor_state **state) if (state && *state) { struct decompressor_state *s = *state; if (s->data) { - debug(D_STREAM, "STREAM_COMPRESSION: Destroying decompressor."); + debug(D_STREAM, "%s: Destroying decompressor.", STREAM_COMPRESSION_MSG); if (s->data->stream) LZ4_freeStreamDecode(s->data->stream); freez(s->data->stream_buffer); + freez(s->data); } freez(s->buffer); freez(s); @@ -246,7 +250,7 @@ static size_t lz4_decompressor_decompress(struct decompressor_state *state) if (!state) return 0; if (!state->buffer) { - error("STREAM: No decompressor buffer allocated"); + error("%s: No decompressor buffer allocated", STREAM_COMPRESSION_MSG); return 0; } @@ -254,7 +258,7 @@ static size_t lz4_decompressor_decompress(struct decompressor_state *state) state->data->stream_buffer + state->data->stream_buffer_pos, state->buffer_len, state->data->stream_buffer_size - state->data->stream_buffer_pos); if (decompressed_size < 0) { - error("STREAM: Decompressor error %ld", decompressed_size); + error("%s: Decompressor error %ld", STREAM_COMPRESSION_MSG, decompressed_size); return 0; } @@ -278,7 +282,7 @@ static size_t lz4_decompressor_decompress(struct decompressor_state *state) size_t avg_size = state->total_uncompressed / state->packet_count; if (old_avg_saving != avg_saving || old_avg_size != avg_size){ - debug(D_STREAM, "STREAM: Saving: %lu%% (avg. %lu%%), avg.size: %lu", saving, avg_saving, avg_size); + debug(D_STREAM, "%s: Saving: %lu%% (avg. %lu%%), avg.size: %lu", STREAM_COMPRESSION_MSG, saving, avg_saving, avg_size); } return decompressed_size; } @@ -301,7 +305,7 @@ static size_t lz4_decompressor_get(struct decompressor_state *state, char *data, if (!state || !size || !data) return 0; if (!state->out_buffer) - fatal("STREAM: No decompressor output buffer allocated"); + fatal("%s: No decompressor output buffer allocated", STREAM_COMPRESSION_MSG); if (state->out_buffer_pos + size > state->out_buffer_len) size = state->out_buffer_len - state->out_buffer_pos; @@ -318,7 +322,7 @@ static size_t lz4_decompressor_get(struct decompressor_state *state, char *data, } /* - * Create and initalize decompressor state + * Create and initialize decompressor state * Return the pointer to decompressor_state structure created */ struct decompressor_state *create_decompressor() @@ -339,7 +343,7 @@ struct decompressor_state *create_decompressor() state->data->stream_buffer = mallocz(state->data->stream_buffer_size); fatal_assert(state->data->stream_buffer); state->reset(state); - debug(D_STREAM, "STREAM_COMPRESSION: Initialize streaming decompression!"); + debug(D_STREAM, "%s: Initialize streaming decompression!", STREAM_COMPRESSION_MSG); return state; } #endif diff --git a/streaming/rrdpush.c b/streaming/rrdpush.c index ebd8327f0..8829d1eea 100644 --- a/streaming/rrdpush.c +++ b/streaming/rrdpush.c @@ -41,7 +41,7 @@ struct config stream_config = { unsigned int default_rrdpush_enabled = 0; #ifdef ENABLE_COMPRESSION -unsigned int default_compression_enabled = 0; +unsigned int default_compression_enabled = 1; #endif char *default_rrdpush_destination = NULL; char *default_rrdpush_api_key = NULL; @@ -129,6 +129,13 @@ unsigned int remote_clock_resync_iterations = 60; static inline int should_send_chart_matching(RRDSET *st) { + // Do not stream anomaly rates charts. + if (unlikely(st->state->is_ar_chart)) + return false; + + if (rrdset_flag_check(st, RRDSET_FLAG_ANOMALY_DETECTION)) + return ml_streaming_enabled(); + if(unlikely(!rrdset_flag_check(st, RRDSET_FLAG_ENABLED))) { rrdset_flag_clear(st, RRDSET_FLAG_UPSTREAM_SEND); rrdset_flag_set(st, RRDSET_FLAG_UPSTREAM_IGNORE); @@ -781,4 +788,4 @@ int rrdpush_receiver_thread_spawn(struct web_client *w, char *url) { buffer_flush(w->response.data); return 200; -} \ No newline at end of file +} diff --git a/streaming/rrdpush.h b/streaming/rrdpush.h index 937ead6fa..7eb2c6e58 100644 --- a/streaming/rrdpush.h +++ b/streaming/rrdpush.h @@ -62,7 +62,7 @@ struct decompressor_state { size_t total_compressed; size_t total_uncompressed; size_t packet_count; - struct decompressor_data *data; // Deompression API specific data + struct decompressor_data *data; // Decompression API specific data void (*reset)(struct decompressor_state *state); size_t (*start)(struct decompressor_state *state, const char *header, size_t header_size); size_t (*put)(struct decompressor_state *state, const char *data, size_t size); diff --git a/streaming/sender.c b/streaming/sender.c index 916d809a9..72259c3ab 100644 --- a/streaming/sender.c +++ b/streaming/sender.c @@ -13,24 +13,43 @@ void sender_start(struct sender_state *s) { buffer_flush(s->build); } +static inline void rrdpush_sender_thread_close_socket(RRDHOST *host); + +#ifdef ENABLE_COMPRESSION +/* +* In case of stream compression buffer oveflow +* Inform the user through the error log file and +* deactivate compression by downgrading the stream protocol. +*/ +static inline void deactivate_compression(struct sender_state *s) +{ + error("STREAM_COMPRESSION: Deactivating compression to avoid stream corruption"); + default_compression_enabled = 0; + s->rrdpush_compression = 0; + s->version = STREAM_VERSION_CLABELS; + error("STREAM_COMPRESSION %s [send to %s]: Restarting connection without compression", s->host->hostname, s->connected_to); + rrdpush_sender_thread_close_socket(s->host); +} +#endif + // Collector thread finishing a transmission void sender_commit(struct sender_state *s) { char *src = (char *)buffer_tostring(s->host->sender->build); size_t src_len = s->host->sender->build->len; #ifdef ENABLE_COMPRESSION - do { - if (src && src_len) { - if (s->compressor && s->rrdpush_compression) { - src_len = s->compressor->compress(s->compressor, src, src_len, &src); - if (!src_len) { - error("Compression error - data discarded"); - break; - } + if (src && src_len) { + if (s->compressor && s->rrdpush_compression) { + src_len = s->compressor->compress(s->compressor, src, src_len, &src); + if (!src_len) { + deactivate_compression(s); + buffer_flush(s->build); + netdata_mutex_unlock(&s->mutex); + return; } - if(cbuffer_add_unsafe(s->host->sender->buffer, src, src_len)) - s->overflow = 1; } - } while (0); + if(cbuffer_add_unsafe(s->host->sender->buffer, src, src_len)) + s->overflow = 1; + } #else if(cbuffer_add_unsafe(s->host->sender->buffer, src, src_len)) s->overflow = 1; @@ -252,6 +271,13 @@ static int rrdpush_sender_thread_connect_to_parent(RRDHOST *host, int default_po } #endif +#ifdef ENABLE_COMPRESSION +// Negotiate stream VERSION_CLABELS if stream compression is not supported +s->rrdpush_compression = (default_compression_enabled && (s->version >= STREAM_VERSION_COMPRESSION)); +if(!s->rrdpush_compression) + s->version = STREAM_VERSION_CLABELS; +#endif //ENABLE_COMPRESSION + /* TODO: During the implementation of #7265 switch the set of variables to HOST_* and CONTAINER_* if the version negotiation resulted in a high enough version. */ @@ -274,7 +300,10 @@ static int rrdpush_sender_thread_connect_to_parent(RRDHOST *host, int default_po "&ml_capable=%d" "&ml_enabled=%d" "&tags=%s" - "&ver=%u" + "&ver=%d" + "&NETDATA_INSTANCE_CLOUD_TYPE=%s" + "&NETDATA_INSTANCE_CLOUD_INSTANCE_TYPE=%s" + "&NETDATA_INSTANCE_CLOUD_INSTANCE_REGION=%s" "&NETDATA_SYSTEM_OS_NAME=%s" "&NETDATA_SYSTEM_OS_ID=%s" "&NETDATA_SYSTEM_OS_ID_LIKE=%s" @@ -316,7 +345,10 @@ static int rrdpush_sender_thread_connect_to_parent(RRDHOST *host, int default_po , host->system_info->ml_capable , host->system_info->ml_enabled , (host->tags) ? host->tags : "" - , STREAMING_PROTOCOL_CURRENT_VERSION + , s->version + , (host->system_info->cloud_provider_type) ? host->system_info->cloud_provider_type : "" + , (host->system_info->cloud_instance_type) ? host->system_info->cloud_instance_type : "" + , (host->system_info->cloud_instance_region) ? host->system_info->cloud_instance_region : "" , se.os_name , se.os_id , (host->system_info->host_os_id_like) ? host->system_info->host_os_id_like : "" @@ -410,7 +442,7 @@ static int rrdpush_sender_thread_connect_to_parent(RRDHOST *host, int default_po s->version = version; #ifdef ENABLE_COMPRESSION - s->rrdpush_compression = (default_compression_enabled && (s->version >= STREAM_VERSION_COMPRESSION)); + s->rrdpush_compression = (s->rrdpush_compression && (s->version >= STREAM_VERSION_COMPRESSION)); if(s->rrdpush_compression) { // parent supports compression @@ -420,6 +452,7 @@ static int rrdpush_sender_thread_connect_to_parent(RRDHOST *host, int default_po else { //parent does not support compression or has compression disabled debug(D_STREAM, "Stream is uncompressed! One of the agents (%s <-> %s) does not support compression OR compression is disabled.", s->connected_to, s->host->hostname); + infoerr("Stream is uncompressed! One of the agents (%s <-> %s) does not support compression OR compression is disabled.", s->connected_to, s->host->hostname); s->version = STREAM_VERSION_CLABELS; } #endif //ENABLE_COMPRESSION @@ -664,6 +697,7 @@ void *rrdpush_sender_thread(void *ptr) { error("STREAM %s [send]: cannot create required pipe. DISABLING STREAMING THREAD", s->host->hostname); return NULL; } + s->version = STREAMING_PROTOCOL_CURRENT_VERSION; enum { Collector, diff --git a/streaming/stream.conf b/streaming/stream.conf index 3c363fad6..e65e76fa4 100644 --- a/streaming/stream.conf +++ b/streaming/stream.conf @@ -60,7 +60,7 @@ # The API_KEY to use (as the sender) api key = - # Stream Compresssion + # Stream Compression # # The netdata child is configurated to enable stream compression by default. # You can control stream compression in this agent with options: yes | no @@ -162,7 +162,7 @@ #default proxy api key = API_KEY #default proxy send charts matching = * - # Stream Compresssion + # Stream Compression # # The stream with the child can be configurated to enable stream compression. # You can control stream compression in this parent agent stream with options: yes | no @@ -216,7 +216,7 @@ #proxy api key = API_KEY #proxy send charts matching = * - # Stream Compresssion + # Stream Compression # # The stream with the child can be configurated to enable stream compression. # You can control stream compression in this parent agent stream with options: yes | no diff --git a/system/netdata.conf b/system/netdata.conf index 6341fcaf6..3fb6ebffc 100644 --- a/system/netdata.conf +++ b/system/netdata.conf @@ -16,13 +16,3 @@ # the default database size - 1 hour history = 3600 - # some defaults to run netdata with least priority - process scheduling policy = idle - OOM score = 1000 - -[web] - web files owner = root - web files group = netdata - - # by default do not expose the netdata port - bind to = localhost diff --git a/system/netdata.service.in b/system/netdata.service.in index 291f4490b..1683a0a09 100644 --- a/system/netdata.service.in +++ b/system/netdata.service.in @@ -26,22 +26,16 @@ TimeoutStopSec=150 Restart=on-failure RestartSec=30 -# The minimum netdata Out-Of-Memory (OOM) score. -# netdata (via [global].OOM score in netdata.conf) can only increase the value set here. -# To decrease it, set the minimum here and set the same or a higher value in netdata.conf. -# Valid values: -1000 (never kill netdata) to 1000 (always kill netdata). -OOMScoreAdjust=1000 - # Valid policies: other (the system default) | batch | idle | fifo | rr # To give netdata the max priority, set CPUSchedulingPolicy=rr and CPUSchedulingPriority=99 -CPUSchedulingPolicy=idle +CPUSchedulingPolicy=batch # This sets the scheduling priority (for policies: rr and fifo). # Priority gets values 1 (lowest) to 99 (highest). #CPUSchedulingPriority=1 # For scheduling policy 'other' and 'batch', this sets the lowest niceness of netdata (-20 highest to 19 lowest). -#Nice=0 +Nice=0 # Capabilities # is required for freeipmi and slabinfo plugins @@ -64,6 +58,8 @@ CapabilityBoundingSet=CAP_NET_RAW CapabilityBoundingSet=CAP_SYS_CHROOT # is required for nfacct plugin (bandwidth accounting) CapabilityBoundingSet=CAP_NET_ADMIN +# is required for plugins that use sudo +CapabilityBoundingSet=CAP_SETGID CAP_SETUID # Sandboxing ProtectSystem=full diff --git a/system/netdata.service.v235.in b/system/netdata.service.v235.in index 664c583f3..dfdf88b69 100644 --- a/system/netdata.service.v235.in +++ b/system/netdata.service.v235.in @@ -27,22 +27,16 @@ TimeoutStopSec=150 Restart=on-failure RestartSec=30 -# The minimum netdata Out-Of-Memory (OOM) score. -# netdata (via [global].OOM score in netdata.conf) can only increase the value set here. -# To decrease it, set the minimum here and set the same or a higher value in netdata.conf. -# Valid values: -1000 (never kill netdata) to 1000 (always kill netdata). -OOMScoreAdjust=1000 - # Valid policies: other (the system default) | batch | idle | fifo | rr # To give netdata the max priority, set CPUSchedulingPolicy=rr and CPUSchedulingPriority=99 -CPUSchedulingPolicy=idle +CPUSchedulingPolicy=batch # This sets the scheduling priority (for policies: rr and fifo). # Priority gets values 1 (lowest) to 99 (highest). #CPUSchedulingPriority=1 # For scheduling policy 'other' and 'batch', this sets the lowest niceness of netdata (-20 highest to 19 lowest). -#Nice=0 +Nice=0 [Install] WantedBy=multi-user.target diff --git a/tests/Makefile.am b/tests/Makefile.am index 29fe7ee60..eb8b5e26e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,16 +15,6 @@ include $(top_srcdir)/build/subst.inc SUFFIXES = .in dist_noinst_DATA = \ - README.md \ - web/lib/jasmine-jquery.js \ - web/easypiechart.chart.spec.js \ - web/easypiechart.percentage.spec.js \ - web/karma.conf.js \ - web/fixtures/easypiechart.chart.fixture1.html \ - node.d/fronius.chart.spec.js \ - node.d/fronius.parse.spec.js \ - node.d/fronius.process.spec.js \ - node.d/fronius.validation.spec.js \ health_mgmtapi/health-cmdapi-test.sh.in \ acls/acl.sh.in \ urls/request.sh.in \ diff --git a/tests/README.md b/tests/README.md deleted file mode 100644 index 256b482cf..000000000 --- a/tests/README.md +++ /dev/null @@ -1,148 +0,0 @@ - - -# Testing - -This readme is a manual on how to get started with unit testing on javascript and nodejs - -Original author: BrainDoctor (github), July 2017 - -## Installation - -Tested on Linux Mint 18.2 Sara (Ubuntu/debian derivative) - -Make sure you are the user who is developer (permissions, except sudo ofc) - -```sh -sudo apt-get install nodejs npm chromium-browser - -cd /path/to/your/netdata -npm install -``` - -That should install the necessary node modules. - -Other browsers work too (Chrome, Firefox). However, only the Chromium Browser 59 has been tested for headless unit testing. - -### Versions - -The commands above leave me with the following versions (July 2017): - -- nodejs: v4.2.6 -- npm: 3.5.2 -- chromium-browser: 59.0.3071.109 -- WebStorm (optional): 2017.1.4 - -## Configuration - -### NPM - -The dependencies are installed in `netdata/package.json`. If you install a new NPM module, it gets added here. Future developers just need to execute `npm install` and every dep gets added automatically. - -### Karma - -Karma configuration is in `tests/web/karma.conf.js`. Documentation is provided via comments. - -### WebStorm - -If you use the JetBrains WebStorm IDE, you can integrate the karma runtime. - -#### for Karma (Client side testing) - -Headless Chromium: - -1. Run > Edit Configurations -2. "+" > Karma -3. - Name: Karma Headless Chromium - - Configuration file: /path/to/your/netdata/tests/web/karma.conf.js - - Browsers to start: ChromiumHeadless - - Node interpreter: /usr/bin/nodejs (MUST be absolute, NVM works too) - - Karma package: /path/to/your/netdata/node_modules/karma - -GUI Chromium is similar: - -1. Run > Edit Configurations -2. "+" > Karma -3. - Name: Karma Chromium - - Configuration file: /path/to/your/netdata/tests/web/karma.conf.js - - Browsers to start: Chromium - - Node interpreter: /usr/bin/nodejs (MUST be absolute, NVM works too) - - Karma package: /path/to/your/netdata/node_modules/karma - -You may add other browsers too (comma separated). With the "Browsers to start" field you can override any settings in karma.conf.js. - -Also it is recommended to install WebStorm IDE Extension/Addon to Chrome/Chromium for awesome debugging. - -#### for node.d plugins (nodejs) - -1. Run > Edit Configurations -2. "+" > Node.js -3. - Name: Node.d plugins - - Node interpreter: /usr/bin/nodejs (MUST be absolute, NVM works too) - - JavaScript file: node_modules/jasmine-node/bin/jasmine-node - - Application parameters: --captureExceptions tests/node.d - -## Running - -### In WebStorm - -#### Karma - -Just run the configured run configurations and they produce nice test trees: - -![karma_run_2](https://user-images.githubusercontent.com/12159026/28277789-559149f6-6b1b-11e7-9cc7-a81d81d12c35.png) - -#### node.js - -Debugging is awesome too! -![node_debug](https://user-images.githubusercontent.com/12159026/28277879-8beee5ee-6b1b-11e7-9356-3156956f2282.png) - -### From CLI - -#### Karma - -```sh -cd /path/to/your/netdata - -nodejs ./node_modules/karma/bin/karma start tests/web/karma.conf.js --single-run=true --browsers=ChromiumHeadless -``` - -will start the karma server, start chromium in headless mode and exit. - -If a test fails, it produces even a stack trace: -![karma_run_1](https://user-images.githubusercontent.com/12159026/28277754-3682bebe-6b1b-11e7-8b7e-66b23d87177d.png) - -#### Node.d plugins - -```sh -cd /path/to/your/netdata - -nodejs node_modules/jasmine-node/bin/jasmine-node --captureExceptions tests/node.d -``` - -will run the tests in `tests/node.d` and produce a stacktrace too on error: -![node_run](https://user-images.githubusercontent.com/12159026/28277812-65bb69b0-6b1b-11e7-8500-bcdbb3436574.png) - -### Coverage - -#### Karma - -A nice HTML is produced from Karma which shows which code paths were executed. It is located somewhere in `/path/to/your/netdata/coverage/` - -![coverage_2](https://user-images.githubusercontent.com/12159026/28277719-142146c4-6b1b-11e7-9992-3e88dee2efd2.png) -and -![coverage_1](https://user-images.githubusercontent.com/12159026/28277687-fa93e360-6b1a-11e7-995f-cbb4c5d012a7.png) - -#### Node.d - -Apparently, jasmine-node can produce a junit report with the `--junitreport` flag. But that output was not very useful. Maybe it's configurable? - -### CI - -The karma and node.d runners can be integrated in Travis (AFAIK), but that is outside my ability. - -Note: Karma is for browser-testing. On a build server, no GUI or browser might by available, unless browsers support headless mode. - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Ftests%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) diff --git a/tests/alarm_repetition/netdata.conf_with_repetition b/tests/alarm_repetition/netdata.conf_with_repetition index 808a11c56..cb5da3110 100644 --- a/tests/alarm_repetition/netdata.conf_with_repetition +++ b/tests/alarm_repetition/netdata.conf_with_repetition @@ -22,8 +22,6 @@ # listen backlog = 4096 default port = 19999 #bind to = *=dashboard|registry|streaming|netdata.conf|badges|management *:20000=dashboard|registry|streaming|netdata.conf|badges|management^SSL=optional *:20001=dashboard|registry|streaming|netdata.conf|badges|management^SSL=force unix:/tmp/netdata/netdata.sock - # web files owner = netdata - # web files group = netdata #accept a streaming request every seconds = 2 [plugins] diff --git a/tests/alarm_repetition/netdata.conf_without_repetition b/tests/alarm_repetition/netdata.conf_without_repetition index 978db8d20..6a728c926 100644 --- a/tests/alarm_repetition/netdata.conf_without_repetition +++ b/tests/alarm_repetition/netdata.conf_without_repetition @@ -22,8 +22,6 @@ # listen backlog = 4096 default port = 19999 #bind to = *=dashboard|registry|streaming|netdata.conf|badges|management *:20000=dashboard|registry|streaming|netdata.conf|badges|management^SSL=optional *:20001=dashboard|registry|streaming|netdata.conf|badges|management^SSL=force unix:/tmp/netdata/netdata.sock - # web files owner = netdata - # web files group = netdata #accept a streaming request every seconds = 2 [plugins] diff --git a/tests/backends/prometheus-avg-oldunits.txt b/tests/backends/prometheus-avg-oldunits.txt deleted file mode 100644 index 53ee8ffa9..000000000 --- a/tests/backends/prometheus-avg-oldunits.txt +++ /dev/null @@ -1,148 +0,0 @@ -nd_apps_cpu_percent_average -nd_apps_cpu_system_percent_average -nd_apps_cpu_user_percent_average -nd_apps_files_open_files_average -nd_apps_lreads_kilobytes_persec_average -nd_apps_lwrites_kilobytes_persec_average -nd_apps_major_faults_page_faults_persec_average -nd_apps_mem_MB_average -nd_apps_minor_faults_page_faults_persec_average -nd_apps_pipes_open_pipes_average -nd_apps_preads_kilobytes_persec_average -nd_apps_processes_processes_average -nd_apps_pwrites_kilobytes_persec_average -nd_apps_sockets_open_sockets_average -nd_apps_swap_MB_average -nd_apps_threads_threads_average -nd_apps_vmem_MB_average -nd_cpu_core_throttling_events_persec_average -nd_cpu_cpu_percent_average -nd_cpu_interrupts_interrupts_persec_average -nd_cpu_softirqs_softirqs_persec_average -nd_cpu_softnet_stat_events_persec_average -nd_disk_avgsz_kilobytes_per_operation_average -nd_disk_await_ms_per_operation_average -nd_disk_backlog_milliseconds_average -nd_disk_inodes_Inodes_average -nd_disk_io_kilobytes_persec_average -nd_disk_iotime_milliseconds_persec_average -nd_disk_mops_merged_operations_persec_average -nd_disk_ops_operations_persec_average -nd_disk_space_GB_average -nd_disk_svctm_ms_per_operation_average -nd_disk_util___of_time_working_average -nd_ip_bcast_kilobits_persec_average -nd_ip_bcastpkts_packets_persec_average -nd_ip_ecnpkts_packets_persec_average -nd_ip_inerrors_packets_persec_average -nd_ip_mcast_kilobits_persec_average -nd_ip_mcastpkts_packets_persec_average -nd_ip_tcp_accept_queue_packets_persec_average -nd_ip_tcpconnaborts_connections_persec_average -nd_ip_tcpofo_packets_persec_average -nd_ip_tcpreorders_packets_persec_average -nd_ipv4_errors_packets_persec_average -nd_ipv4_icmp_errors_packets_persec_average -nd_ipv4_icmpmsg_packets_persec_average -nd_ipv4_icmp_packets_persec_average -nd_ipv4_packets_packets_persec_average -nd_ipv4_sockstat_sockets_sockets_average -nd_ipv4_sockstat_tcp_mem_KB_average -nd_ipv4_sockstat_tcp_sockets_sockets_average -nd_ipv4_sockstat_udp_mem_KB_average -nd_ipv4_sockstat_udp_sockets_sockets_average -nd_ipv4_tcperrors_packets_persec_average -nd_ipv4_tcphandshake_events_persec_average -nd_ipv4_tcpopens_connections_persec_average -nd_ipv4_tcppackets_packets_persec_average -nd_ipv4_tcpsock_active_connections_average -nd_ipv4_udperrors_events_persec_average -nd_ipv4_udppackets_packets_persec_average -nd_ipv6_ect_packets_persec_average -nd_ipv6_errors_packets_persec_average -nd_ipv6_icmperrors_errors_persec_average -nd_ipv6_icmp_messages_persec_average -nd_ipv6_icmpmldv2_reports_persec_average -nd_ipv6_icmpneighbor_messages_persec_average -nd_ipv6_icmprouter_messages_persec_average -nd_ipv6_icmptypes_messages_persec_average -nd_ipv6_mcast_kilobits_persec_average -nd_ipv6_mcastpkts_packets_persec_average -nd_ipv6_packets_packets_persec_average -nd_ipv6_sockstat6_raw_sockets_sockets_average -nd_ipv6_sockstat6_tcp_sockets_sockets_average -nd_ipv6_sockstat6_udp_sockets_sockets_average -nd_ipv6_udperrors_events_persec_average -nd_ipv6_udppackets_packets_persec_average -nd_mem_available_MB_average -nd_mem_committed_MB_average -nd_mem_kernel_MB_average -nd_mem_pgfaults_page_faults_persec_average -nd_mem_slab_MB_average -nd_mem_transparent_hugepages_MB_average -nd_mem_writeback_MB_average -nd_netdata_apps_children_fix_percent_average -nd_netdata_apps_cpu_milliseconds_persec_average -nd_netdata_apps_fix_percent_average -nd_netdata_apps_sizes_files_persec_average -nd_netdata_clients_connected_clients_average -nd_netdata_compression_ratio_percent_average -nd_netdata_go_plugin_execution_time_ms_average -nd_netdata_net_kilobits_persec_average -nd_netdata_plugin_cgroups_cpu_milliseconds_persec_average -nd_netdata_plugin_diskspace_dt_milliseconds_run_average -nd_netdata_plugin_diskspace_milliseconds_persec_average -nd_netdata_plugin_proc_cpu_milliseconds_persec_average -nd_netdata_plugin_proc_modules_milliseconds_run_average -nd_netdata_plugin_tc_cpu_milliseconds_persec_average -nd_netdata_plugin_tc_time_milliseconds_run_average -nd_netdata_private_charts_charts_average -nd_netdata_pythond_runtime_ms_average -nd_netdata_requests_requests_persec_average -nd_netdata_response_time_milliseconds_request_average -nd_netdata_server_cpu_milliseconds_persec_average -nd_netdata_statsd_bytes_kilobits_persec_average -nd_netdata_statsd_cpu_milliseconds_persec_average -nd_netdata_statsd_events_events_persec_average -nd_netdata_statsd_metrics_metrics_average -nd_netdata_statsd_packets_packets_persec_average -nd_netdata_statsd_reads_reads_persec_average -nd_netdata_statsd_useful_metrics_metrics_average -nd_netdata_tcp_connected_sockets_average -nd_netdata_tcp_connects_events_average -nd_netdata_web_cpu_milliseconds_persec_average -nd_net_drops_drops_persec_average -nd_net_net_kilobits_persec_average -nd_net_packets_packets_persec_average -nd_services_cpu_percent_average -nd_services_mem_usage_MB_average -nd_services_swap_usage_MB_average -nd_services_throttle_io_ops_read_operations_persec_average -nd_services_throttle_io_ops_write_operations_persec_average -nd_services_throttle_io_read_kilobytes_persec_average -nd_services_throttle_io_write_kilobytes_persec_average -nd_system_active_processes_processes_average -nd_system_cpu_percent_average -nd_system_ctxt_context_switches_persec_average -nd_system_entropy_entropy_average -nd_system_forks_processes_persec_average -nd_system_idlejitter_microseconds_lost_persec_average -nd_system_interrupts_interrupts_persec_average -nd_system_intr_interrupts_persec_average -nd_system_io_kilobytes_persec_average -nd_system_ipc_semaphore_arrays_arrays_average -nd_system_ipc_semaphores_semaphores_average -nd_system_ip_kilobits_persec_average -nd_system_ipv6_kilobits_persec_average -nd_system_load_load_average -nd_system_net_kilobits_persec_average -nd_system_pgpgio_kilobytes_persec_average -nd_system_processes_processes_average -nd_system_ram_MB_average -nd_system_shared_memory_bytes_bytes_average -nd_system_shared_memory_segments_segments_average -nd_system_softirqs_softirqs_persec_average -nd_system_softnet_stat_events_persec_average -nd_system_swapio_kilobytes_persec_average -nd_system_swap_MB_average -nd_system_uptime_seconds_average diff --git a/tests/backends/prometheus-avg.txt b/tests/backends/prometheus-avg.txt deleted file mode 100644 index 1aedff2b5..000000000 --- a/tests/backends/prometheus-avg.txt +++ /dev/null @@ -1,148 +0,0 @@ -nd_apps_cpu_percentage_average -nd_apps_cpu_system_percentage_average -nd_apps_cpu_user_percentage_average -nd_apps_files_open_files_average -nd_apps_lreads_KiB_persec_average -nd_apps_lwrites_KiB_persec_average -nd_apps_major_faults_page_faults_persec_average -nd_apps_mem_MiB_average -nd_apps_minor_faults_page_faults_persec_average -nd_apps_pipes_open_pipes_average -nd_apps_preads_KiB_persec_average -nd_apps_processes_processes_average -nd_apps_pwrites_KiB_persec_average -nd_apps_sockets_open_sockets_average -nd_apps_swap_MiB_average -nd_apps_threads_threads_average -nd_apps_vmem_MiB_average -nd_cpu_core_throttling_events_persec_average -nd_cpu_cpu_percentage_average -nd_cpu_interrupts_interrupts_persec_average -nd_cpu_softirqs_softirqs_persec_average -nd_cpu_softnet_stat_events_persec_average -nd_disk_avgsz_KiB_operation_average -nd_disk_await_milliseconds_operation_average -nd_disk_backlog_milliseconds_average -nd_disk_inodes_inodes_average -nd_disk_io_KiB_persec_average -nd_disk_iotime_milliseconds_persec_average -nd_disk_mops_merged_operations_persec_average -nd_disk_ops_operations_persec_average -nd_disk_space_GiB_average -nd_disk_svctm_milliseconds_operation_average -nd_disk_util___of_time_working_average -nd_ip_bcast_kilobits_persec_average -nd_ip_bcastpkts_packets_persec_average -nd_ip_ecnpkts_packets_persec_average -nd_ip_inerrors_packets_persec_average -nd_ip_mcast_kilobits_persec_average -nd_ip_mcastpkts_packets_persec_average -nd_ip_tcp_accept_queue_packets_persec_average -nd_ip_tcpconnaborts_connections_persec_average -nd_ip_tcpofo_packets_persec_average -nd_ip_tcpreorders_packets_persec_average -nd_ipv4_errors_packets_persec_average -nd_ipv4_icmp_errors_packets_persec_average -nd_ipv4_icmpmsg_packets_persec_average -nd_ipv4_icmp_packets_persec_average -nd_ipv4_packets_packets_persec_average -nd_ipv4_sockstat_sockets_sockets_average -nd_ipv4_sockstat_tcp_mem_KiB_average -nd_ipv4_sockstat_tcp_sockets_sockets_average -nd_ipv4_sockstat_udp_mem_KiB_average -nd_ipv4_sockstat_udp_sockets_sockets_average -nd_ipv4_tcperrors_packets_persec_average -nd_ipv4_tcphandshake_events_persec_average -nd_ipv4_tcpopens_connections_persec_average -nd_ipv4_tcppackets_packets_persec_average -nd_ipv4_tcpsock_active_connections_average -nd_ipv4_udperrors_events_persec_average -nd_ipv4_udppackets_packets_persec_average -nd_ipv6_ect_packets_persec_average -nd_ipv6_errors_packets_persec_average -nd_ipv6_icmperrors_errors_persec_average -nd_ipv6_icmp_messages_persec_average -nd_ipv6_icmpmldv2_reports_persec_average -nd_ipv6_icmpneighbor_messages_persec_average -nd_ipv6_icmprouter_messages_persec_average -nd_ipv6_icmptypes_messages_persec_average -nd_ipv6_mcast_kilobits_persec_average -nd_ipv6_mcastpkts_packets_persec_average -nd_ipv6_packets_packets_persec_average -nd_ipv6_sockstat6_raw_sockets_sockets_average -nd_ipv6_sockstat6_tcp_sockets_sockets_average -nd_ipv6_sockstat6_udp_sockets_sockets_average -nd_ipv6_udperrors_events_persec_average -nd_ipv6_udppackets_packets_persec_average -nd_mem_available_MiB_average -nd_mem_committed_MiB_average -nd_mem_kernel_MiB_average -nd_mem_pgfaults_faults_persec_average -nd_mem_slab_MiB_average -nd_mem_transparent_hugepages_MiB_average -nd_mem_writeback_MiB_average -nd_netdata_apps_children_fix_percentage_average -nd_netdata_apps_cpu_milliseconds_persec_average -nd_netdata_apps_fix_percentage_average -nd_netdata_apps_sizes_files_persec_average -nd_netdata_clients_connected_clients_average -nd_netdata_compression_ratio_percentage_average -nd_netdata_go_plugin_execution_time_ms_average -nd_netdata_net_kilobits_persec_average -nd_netdata_plugin_cgroups_cpu_milliseconds_persec_average -nd_netdata_plugin_diskspace_dt_milliseconds_run_average -nd_netdata_plugin_diskspace_milliseconds_persec_average -nd_netdata_plugin_proc_cpu_milliseconds_persec_average -nd_netdata_plugin_proc_modules_milliseconds_run_average -nd_netdata_plugin_tc_cpu_milliseconds_persec_average -nd_netdata_plugin_tc_time_milliseconds_run_average -nd_netdata_private_charts_charts_average -nd_netdata_pythond_runtime_ms_average -nd_netdata_requests_requests_persec_average -nd_netdata_response_time_milliseconds_request_average -nd_netdata_server_cpu_milliseconds_persec_average -nd_netdata_statsd_bytes_kilobits_persec_average -nd_netdata_statsd_cpu_milliseconds_persec_average -nd_netdata_statsd_events_events_persec_average -nd_netdata_statsd_metrics_metrics_average -nd_netdata_statsd_packets_packets_persec_average -nd_netdata_statsd_reads_reads_persec_average -nd_netdata_statsd_useful_metrics_metrics_average -nd_netdata_tcp_connected_sockets_average -nd_netdata_tcp_connects_events_average -nd_netdata_web_cpu_milliseconds_persec_average -nd_net_drops_drops_persec_average -nd_net_net_kilobits_persec_average -nd_net_packets_packets_persec_average -nd_services_cpu_percentage_average -nd_services_mem_usage_MiB_average -nd_services_swap_usage_MiB_average -nd_services_throttle_io_ops_read_operations_persec_average -nd_services_throttle_io_ops_write_operations_persec_average -nd_services_throttle_io_read_KiB_persec_average -nd_services_throttle_io_write_KiB_persec_average -nd_system_active_processes_processes_average -nd_system_cpu_percentage_average -nd_system_ctxt_context_switches_persec_average -nd_system_entropy_entropy_average -nd_system_forks_processes_persec_average -nd_system_idlejitter_microseconds_lost_persec_average -nd_system_interrupts_interrupts_persec_average -nd_system_intr_interrupts_persec_average -nd_system_io_KiB_persec_average -nd_system_ipc_semaphore_arrays_arrays_average -nd_system_ipc_semaphores_semaphores_average -nd_system_ip_kilobits_persec_average -nd_system_ipv6_kilobits_persec_average -nd_system_load_load_average -nd_system_net_kilobits_persec_average -nd_system_pgpgio_KiB_persec_average -nd_system_processes_processes_average -nd_system_ram_MiB_average -nd_system_shared_memory_bytes_bytes_average -nd_system_shared_memory_segments_segments_average -nd_system_softirqs_softirqs_persec_average -nd_system_softnet_stat_events_persec_average -nd_system_swapio_KiB_persec_average -nd_system_swap_MiB_average -nd_system_uptime_seconds_average diff --git a/tests/backends/prometheus-raw.txt b/tests/backends/prometheus-raw.txt deleted file mode 100644 index 2ac4c2c7a..000000000 --- a/tests/backends/prometheus-raw.txt +++ /dev/null @@ -1,156 +0,0 @@ -nd_apps_cpu -nd_apps_cpu_system -nd_apps_cpu_user -nd_apps_files -nd_apps_lreads -nd_apps_lwrites -nd_apps_major_faults -nd_apps_mem -nd_apps_minor_faults -nd_apps_pipes -nd_apps_preads -nd_apps_processes -nd_apps_pwrites -nd_apps_sockets -nd_apps_swap -nd_apps_threads -nd_apps_vmem -nd_cpu_core_throttling_total -nd_cpu_cpu_total -nd_cpu_interrupts_total -nd_cpu_softirqs_total -nd_cpu_softnet_stat_total -nd_disk_avgsz -nd_disk_await -nd_disk_backlog_total -nd_disk_inodes -nd_disk_iotime_total -nd_disk_io_total -nd_disk_mops_total -nd_disk_ops_total -nd_disk_space -nd_disk_svctm -nd_disk_util_total -nd_ip_bcastpkts_total -nd_ip_bcast_total -nd_ip_ecnpkts_total -nd_ip_inerrors_total -nd_ip_mcastpkts_total -nd_ip_mcast_total -nd_ip_tcp_accept_queue_total -nd_ip_tcpconnaborts_total -nd_ip_tcpofo_total -nd_ip_tcpreorders_total -nd_ipv4_errors_total -nd_ipv4_icmp_errors_total -nd_ipv4_icmpmsg_total -nd_ipv4_icmp_total -nd_ipv4_packets_total -nd_ipv4_sockstat_sockets -nd_ipv4_sockstat_tcp_mem -nd_ipv4_sockstat_tcp_sockets -nd_ipv4_sockstat_udp_mem -nd_ipv4_sockstat_udp_sockets -nd_ipv4_tcperrors_total -nd_ipv4_tcphandshake_total -nd_ipv4_tcpopens_total -nd_ipv4_tcppackets_total -nd_ipv4_tcpsock -nd_ipv4_udperrors_total -nd_ipv4_udppackets_total -nd_ipv6_ect_total -nd_ipv6_errors_total -nd_ipv6_icmperrors_total -nd_ipv6_icmpmldv2_total -nd_ipv6_icmpneighbor_total -nd_ipv6_icmprouter_total -nd_ipv6_icmp_total -nd_ipv6_icmptypes_total -nd_ipv6_mcastpkts_total -nd_ipv6_mcast_total -nd_ipv6_packets_total -nd_ipv6_sockstat6_raw_sockets -nd_ipv6_sockstat6_tcp_sockets -nd_ipv6_sockstat6_udp_sockets -nd_ipv6_udperrors_total -nd_ipv6_udppackets_total -nd_mem_available -nd_mem_committed -nd_mem_kernel -nd_mem_pgfaults_total -nd_mem_slab -nd_mem_transparent_hugepages -nd_mem_writeback -nd_netdata_apps_children_fix -nd_netdata_apps_cpu_total -nd_netdata_apps_fix -nd_netdata_apps_sizes_calls_total -nd_netdata_apps_sizes_fds -nd_netdata_apps_sizes_filenames_total -nd_netdata_apps_sizes_files_total -nd_netdata_apps_sizes_inode_changes_total -nd_netdata_apps_sizes_link_changes_total -nd_netdata_apps_sizes_new_pids_total -nd_netdata_apps_sizes_pids -nd_netdata_apps_sizes_targets -nd_netdata_clients -nd_netdata_compression_ratio -nd_netdata_go_plugin_execution_time -nd_netdata_net_total -nd_netdata_plugin_cgroups_cpu_total -nd_netdata_plugin_diskspace_dt -nd_netdata_plugin_diskspace_total -nd_netdata_plugin_proc_cpu_total -nd_netdata_plugin_proc_modules -nd_netdata_plugin_tc_cpu_total -nd_netdata_plugin_tc_time -nd_netdata_private_charts -nd_netdata_pythond_runtime -nd_netdata_requests_total -nd_netdata_response_time -nd_netdata_server_cpu_total -nd_netdata_statsd_bytes_total -nd_netdata_statsd_cpu_total -nd_netdata_statsd_events_total -nd_netdata_statsd_metrics -nd_netdata_statsd_packets_total -nd_netdata_statsd_reads_total -nd_netdata_statsd_useful_metrics -nd_netdata_tcp_connected -nd_netdata_tcp_connects_total -nd_netdata_web_cpu_total -nd_net_drops_total -nd_net_net_total -nd_net_packets_total -nd_services_cpu_total -nd_services_mem_usage -nd_services_swap_usage -nd_services_throttle_io_ops_read_total -nd_services_throttle_io_ops_write_total -nd_services_throttle_io_read_total -nd_services_throttle_io_write_total -nd_system_active_processes -nd_system_cpu_total -nd_system_ctxt_total -nd_system_entropy -nd_system_forks_total -nd_system_idlejitter -nd_system_interrupts_total -nd_system_intr_total -nd_system_io_total -nd_system_ipc_semaphore_arrays -nd_system_ipc_semaphores -nd_system_ip_total -nd_system_ipv6_total -nd_system_load -nd_system_net_total -nd_system_pgpgio_total -nd_system_processes -nd_system_ram -nd_system_shared_memory_bytes -nd_system_shared_memory_segments -nd_system_softirqs_total -nd_system_softnet_stat_total -nd_system_swap -nd_system_swapio_total -nd_system_uptime diff --git a/tests/backends/prometheus.bats b/tests/backends/prometheus.bats deleted file mode 100755 index d52f39d54..000000000 --- a/tests/backends/prometheus.bats +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env bats - -validate_metrics() { - fname="${1}" - params="${2}" - - curl -sS "http://localhost:19999/api/v1/allmetrics?format=prometheus&prefix=nd×tamps=no${params}" | - grep -E 'nd_system_|nd_cpu_|nd_system_|nd_net_|nd_disk_|nd_ip_|nd_ipv4_|nd_ipv6_|nd_mem_|nd_netdata_|nd_apps_|nd_services_' | - sed -ne 's/{.*//p' | sort | uniq > tests/backends/new-${fname} - diff tests/backends/${fname} tests/backends/new-${fname} - rm tests/backends/new-${fname} -} - - -if [ ! -f .gitignore ]; then - echo "Need to run as ./tests/backends/$(basename "$0") from top level directory of git repository" >&2 - exit 1 -fi - - -@test "prometheus raw" { - validate_metrics prometheus-raw.txt "&data=raw" -} - -@test "prometheus avg" { - validate_metrics prometheus-avg.txt "" -} - -@test "prometheus avg oldunits" { - validate_metrics prometheus-avg-oldunits.txt "&oldunits=yes" -} diff --git a/tests/exporting/prometheus-avg-oldunits.txt b/tests/exporting/prometheus-avg-oldunits.txt new file mode 100644 index 000000000..53ee8ffa9 --- /dev/null +++ b/tests/exporting/prometheus-avg-oldunits.txt @@ -0,0 +1,148 @@ +nd_apps_cpu_percent_average +nd_apps_cpu_system_percent_average +nd_apps_cpu_user_percent_average +nd_apps_files_open_files_average +nd_apps_lreads_kilobytes_persec_average +nd_apps_lwrites_kilobytes_persec_average +nd_apps_major_faults_page_faults_persec_average +nd_apps_mem_MB_average +nd_apps_minor_faults_page_faults_persec_average +nd_apps_pipes_open_pipes_average +nd_apps_preads_kilobytes_persec_average +nd_apps_processes_processes_average +nd_apps_pwrites_kilobytes_persec_average +nd_apps_sockets_open_sockets_average +nd_apps_swap_MB_average +nd_apps_threads_threads_average +nd_apps_vmem_MB_average +nd_cpu_core_throttling_events_persec_average +nd_cpu_cpu_percent_average +nd_cpu_interrupts_interrupts_persec_average +nd_cpu_softirqs_softirqs_persec_average +nd_cpu_softnet_stat_events_persec_average +nd_disk_avgsz_kilobytes_per_operation_average +nd_disk_await_ms_per_operation_average +nd_disk_backlog_milliseconds_average +nd_disk_inodes_Inodes_average +nd_disk_io_kilobytes_persec_average +nd_disk_iotime_milliseconds_persec_average +nd_disk_mops_merged_operations_persec_average +nd_disk_ops_operations_persec_average +nd_disk_space_GB_average +nd_disk_svctm_ms_per_operation_average +nd_disk_util___of_time_working_average +nd_ip_bcast_kilobits_persec_average +nd_ip_bcastpkts_packets_persec_average +nd_ip_ecnpkts_packets_persec_average +nd_ip_inerrors_packets_persec_average +nd_ip_mcast_kilobits_persec_average +nd_ip_mcastpkts_packets_persec_average +nd_ip_tcp_accept_queue_packets_persec_average +nd_ip_tcpconnaborts_connections_persec_average +nd_ip_tcpofo_packets_persec_average +nd_ip_tcpreorders_packets_persec_average +nd_ipv4_errors_packets_persec_average +nd_ipv4_icmp_errors_packets_persec_average +nd_ipv4_icmpmsg_packets_persec_average +nd_ipv4_icmp_packets_persec_average +nd_ipv4_packets_packets_persec_average +nd_ipv4_sockstat_sockets_sockets_average +nd_ipv4_sockstat_tcp_mem_KB_average +nd_ipv4_sockstat_tcp_sockets_sockets_average +nd_ipv4_sockstat_udp_mem_KB_average +nd_ipv4_sockstat_udp_sockets_sockets_average +nd_ipv4_tcperrors_packets_persec_average +nd_ipv4_tcphandshake_events_persec_average +nd_ipv4_tcpopens_connections_persec_average +nd_ipv4_tcppackets_packets_persec_average +nd_ipv4_tcpsock_active_connections_average +nd_ipv4_udperrors_events_persec_average +nd_ipv4_udppackets_packets_persec_average +nd_ipv6_ect_packets_persec_average +nd_ipv6_errors_packets_persec_average +nd_ipv6_icmperrors_errors_persec_average +nd_ipv6_icmp_messages_persec_average +nd_ipv6_icmpmldv2_reports_persec_average +nd_ipv6_icmpneighbor_messages_persec_average +nd_ipv6_icmprouter_messages_persec_average +nd_ipv6_icmptypes_messages_persec_average +nd_ipv6_mcast_kilobits_persec_average +nd_ipv6_mcastpkts_packets_persec_average +nd_ipv6_packets_packets_persec_average +nd_ipv6_sockstat6_raw_sockets_sockets_average +nd_ipv6_sockstat6_tcp_sockets_sockets_average +nd_ipv6_sockstat6_udp_sockets_sockets_average +nd_ipv6_udperrors_events_persec_average +nd_ipv6_udppackets_packets_persec_average +nd_mem_available_MB_average +nd_mem_committed_MB_average +nd_mem_kernel_MB_average +nd_mem_pgfaults_page_faults_persec_average +nd_mem_slab_MB_average +nd_mem_transparent_hugepages_MB_average +nd_mem_writeback_MB_average +nd_netdata_apps_children_fix_percent_average +nd_netdata_apps_cpu_milliseconds_persec_average +nd_netdata_apps_fix_percent_average +nd_netdata_apps_sizes_files_persec_average +nd_netdata_clients_connected_clients_average +nd_netdata_compression_ratio_percent_average +nd_netdata_go_plugin_execution_time_ms_average +nd_netdata_net_kilobits_persec_average +nd_netdata_plugin_cgroups_cpu_milliseconds_persec_average +nd_netdata_plugin_diskspace_dt_milliseconds_run_average +nd_netdata_plugin_diskspace_milliseconds_persec_average +nd_netdata_plugin_proc_cpu_milliseconds_persec_average +nd_netdata_plugin_proc_modules_milliseconds_run_average +nd_netdata_plugin_tc_cpu_milliseconds_persec_average +nd_netdata_plugin_tc_time_milliseconds_run_average +nd_netdata_private_charts_charts_average +nd_netdata_pythond_runtime_ms_average +nd_netdata_requests_requests_persec_average +nd_netdata_response_time_milliseconds_request_average +nd_netdata_server_cpu_milliseconds_persec_average +nd_netdata_statsd_bytes_kilobits_persec_average +nd_netdata_statsd_cpu_milliseconds_persec_average +nd_netdata_statsd_events_events_persec_average +nd_netdata_statsd_metrics_metrics_average +nd_netdata_statsd_packets_packets_persec_average +nd_netdata_statsd_reads_reads_persec_average +nd_netdata_statsd_useful_metrics_metrics_average +nd_netdata_tcp_connected_sockets_average +nd_netdata_tcp_connects_events_average +nd_netdata_web_cpu_milliseconds_persec_average +nd_net_drops_drops_persec_average +nd_net_net_kilobits_persec_average +nd_net_packets_packets_persec_average +nd_services_cpu_percent_average +nd_services_mem_usage_MB_average +nd_services_swap_usage_MB_average +nd_services_throttle_io_ops_read_operations_persec_average +nd_services_throttle_io_ops_write_operations_persec_average +nd_services_throttle_io_read_kilobytes_persec_average +nd_services_throttle_io_write_kilobytes_persec_average +nd_system_active_processes_processes_average +nd_system_cpu_percent_average +nd_system_ctxt_context_switches_persec_average +nd_system_entropy_entropy_average +nd_system_forks_processes_persec_average +nd_system_idlejitter_microseconds_lost_persec_average +nd_system_interrupts_interrupts_persec_average +nd_system_intr_interrupts_persec_average +nd_system_io_kilobytes_persec_average +nd_system_ipc_semaphore_arrays_arrays_average +nd_system_ipc_semaphores_semaphores_average +nd_system_ip_kilobits_persec_average +nd_system_ipv6_kilobits_persec_average +nd_system_load_load_average +nd_system_net_kilobits_persec_average +nd_system_pgpgio_kilobytes_persec_average +nd_system_processes_processes_average +nd_system_ram_MB_average +nd_system_shared_memory_bytes_bytes_average +nd_system_shared_memory_segments_segments_average +nd_system_softirqs_softirqs_persec_average +nd_system_softnet_stat_events_persec_average +nd_system_swapio_kilobytes_persec_average +nd_system_swap_MB_average +nd_system_uptime_seconds_average diff --git a/tests/exporting/prometheus-avg.txt b/tests/exporting/prometheus-avg.txt new file mode 100644 index 000000000..1aedff2b5 --- /dev/null +++ b/tests/exporting/prometheus-avg.txt @@ -0,0 +1,148 @@ +nd_apps_cpu_percentage_average +nd_apps_cpu_system_percentage_average +nd_apps_cpu_user_percentage_average +nd_apps_files_open_files_average +nd_apps_lreads_KiB_persec_average +nd_apps_lwrites_KiB_persec_average +nd_apps_major_faults_page_faults_persec_average +nd_apps_mem_MiB_average +nd_apps_minor_faults_page_faults_persec_average +nd_apps_pipes_open_pipes_average +nd_apps_preads_KiB_persec_average +nd_apps_processes_processes_average +nd_apps_pwrites_KiB_persec_average +nd_apps_sockets_open_sockets_average +nd_apps_swap_MiB_average +nd_apps_threads_threads_average +nd_apps_vmem_MiB_average +nd_cpu_core_throttling_events_persec_average +nd_cpu_cpu_percentage_average +nd_cpu_interrupts_interrupts_persec_average +nd_cpu_softirqs_softirqs_persec_average +nd_cpu_softnet_stat_events_persec_average +nd_disk_avgsz_KiB_operation_average +nd_disk_await_milliseconds_operation_average +nd_disk_backlog_milliseconds_average +nd_disk_inodes_inodes_average +nd_disk_io_KiB_persec_average +nd_disk_iotime_milliseconds_persec_average +nd_disk_mops_merged_operations_persec_average +nd_disk_ops_operations_persec_average +nd_disk_space_GiB_average +nd_disk_svctm_milliseconds_operation_average +nd_disk_util___of_time_working_average +nd_ip_bcast_kilobits_persec_average +nd_ip_bcastpkts_packets_persec_average +nd_ip_ecnpkts_packets_persec_average +nd_ip_inerrors_packets_persec_average +nd_ip_mcast_kilobits_persec_average +nd_ip_mcastpkts_packets_persec_average +nd_ip_tcp_accept_queue_packets_persec_average +nd_ip_tcpconnaborts_connections_persec_average +nd_ip_tcpofo_packets_persec_average +nd_ip_tcpreorders_packets_persec_average +nd_ipv4_errors_packets_persec_average +nd_ipv4_icmp_errors_packets_persec_average +nd_ipv4_icmpmsg_packets_persec_average +nd_ipv4_icmp_packets_persec_average +nd_ipv4_packets_packets_persec_average +nd_ipv4_sockstat_sockets_sockets_average +nd_ipv4_sockstat_tcp_mem_KiB_average +nd_ipv4_sockstat_tcp_sockets_sockets_average +nd_ipv4_sockstat_udp_mem_KiB_average +nd_ipv4_sockstat_udp_sockets_sockets_average +nd_ipv4_tcperrors_packets_persec_average +nd_ipv4_tcphandshake_events_persec_average +nd_ipv4_tcpopens_connections_persec_average +nd_ipv4_tcppackets_packets_persec_average +nd_ipv4_tcpsock_active_connections_average +nd_ipv4_udperrors_events_persec_average +nd_ipv4_udppackets_packets_persec_average +nd_ipv6_ect_packets_persec_average +nd_ipv6_errors_packets_persec_average +nd_ipv6_icmperrors_errors_persec_average +nd_ipv6_icmp_messages_persec_average +nd_ipv6_icmpmldv2_reports_persec_average +nd_ipv6_icmpneighbor_messages_persec_average +nd_ipv6_icmprouter_messages_persec_average +nd_ipv6_icmptypes_messages_persec_average +nd_ipv6_mcast_kilobits_persec_average +nd_ipv6_mcastpkts_packets_persec_average +nd_ipv6_packets_packets_persec_average +nd_ipv6_sockstat6_raw_sockets_sockets_average +nd_ipv6_sockstat6_tcp_sockets_sockets_average +nd_ipv6_sockstat6_udp_sockets_sockets_average +nd_ipv6_udperrors_events_persec_average +nd_ipv6_udppackets_packets_persec_average +nd_mem_available_MiB_average +nd_mem_committed_MiB_average +nd_mem_kernel_MiB_average +nd_mem_pgfaults_faults_persec_average +nd_mem_slab_MiB_average +nd_mem_transparent_hugepages_MiB_average +nd_mem_writeback_MiB_average +nd_netdata_apps_children_fix_percentage_average +nd_netdata_apps_cpu_milliseconds_persec_average +nd_netdata_apps_fix_percentage_average +nd_netdata_apps_sizes_files_persec_average +nd_netdata_clients_connected_clients_average +nd_netdata_compression_ratio_percentage_average +nd_netdata_go_plugin_execution_time_ms_average +nd_netdata_net_kilobits_persec_average +nd_netdata_plugin_cgroups_cpu_milliseconds_persec_average +nd_netdata_plugin_diskspace_dt_milliseconds_run_average +nd_netdata_plugin_diskspace_milliseconds_persec_average +nd_netdata_plugin_proc_cpu_milliseconds_persec_average +nd_netdata_plugin_proc_modules_milliseconds_run_average +nd_netdata_plugin_tc_cpu_milliseconds_persec_average +nd_netdata_plugin_tc_time_milliseconds_run_average +nd_netdata_private_charts_charts_average +nd_netdata_pythond_runtime_ms_average +nd_netdata_requests_requests_persec_average +nd_netdata_response_time_milliseconds_request_average +nd_netdata_server_cpu_milliseconds_persec_average +nd_netdata_statsd_bytes_kilobits_persec_average +nd_netdata_statsd_cpu_milliseconds_persec_average +nd_netdata_statsd_events_events_persec_average +nd_netdata_statsd_metrics_metrics_average +nd_netdata_statsd_packets_packets_persec_average +nd_netdata_statsd_reads_reads_persec_average +nd_netdata_statsd_useful_metrics_metrics_average +nd_netdata_tcp_connected_sockets_average +nd_netdata_tcp_connects_events_average +nd_netdata_web_cpu_milliseconds_persec_average +nd_net_drops_drops_persec_average +nd_net_net_kilobits_persec_average +nd_net_packets_packets_persec_average +nd_services_cpu_percentage_average +nd_services_mem_usage_MiB_average +nd_services_swap_usage_MiB_average +nd_services_throttle_io_ops_read_operations_persec_average +nd_services_throttle_io_ops_write_operations_persec_average +nd_services_throttle_io_read_KiB_persec_average +nd_services_throttle_io_write_KiB_persec_average +nd_system_active_processes_processes_average +nd_system_cpu_percentage_average +nd_system_ctxt_context_switches_persec_average +nd_system_entropy_entropy_average +nd_system_forks_processes_persec_average +nd_system_idlejitter_microseconds_lost_persec_average +nd_system_interrupts_interrupts_persec_average +nd_system_intr_interrupts_persec_average +nd_system_io_KiB_persec_average +nd_system_ipc_semaphore_arrays_arrays_average +nd_system_ipc_semaphores_semaphores_average +nd_system_ip_kilobits_persec_average +nd_system_ipv6_kilobits_persec_average +nd_system_load_load_average +nd_system_net_kilobits_persec_average +nd_system_pgpgio_KiB_persec_average +nd_system_processes_processes_average +nd_system_ram_MiB_average +nd_system_shared_memory_bytes_bytes_average +nd_system_shared_memory_segments_segments_average +nd_system_softirqs_softirqs_persec_average +nd_system_softnet_stat_events_persec_average +nd_system_swapio_KiB_persec_average +nd_system_swap_MiB_average +nd_system_uptime_seconds_average diff --git a/tests/exporting/prometheus-raw.txt b/tests/exporting/prometheus-raw.txt new file mode 100644 index 000000000..2ac4c2c7a --- /dev/null +++ b/tests/exporting/prometheus-raw.txt @@ -0,0 +1,156 @@ +nd_apps_cpu +nd_apps_cpu_system +nd_apps_cpu_user +nd_apps_files +nd_apps_lreads +nd_apps_lwrites +nd_apps_major_faults +nd_apps_mem +nd_apps_minor_faults +nd_apps_pipes +nd_apps_preads +nd_apps_processes +nd_apps_pwrites +nd_apps_sockets +nd_apps_swap +nd_apps_threads +nd_apps_vmem +nd_cpu_core_throttling_total +nd_cpu_cpu_total +nd_cpu_interrupts_total +nd_cpu_softirqs_total +nd_cpu_softnet_stat_total +nd_disk_avgsz +nd_disk_await +nd_disk_backlog_total +nd_disk_inodes +nd_disk_iotime_total +nd_disk_io_total +nd_disk_mops_total +nd_disk_ops_total +nd_disk_space +nd_disk_svctm +nd_disk_util_total +nd_ip_bcastpkts_total +nd_ip_bcast_total +nd_ip_ecnpkts_total +nd_ip_inerrors_total +nd_ip_mcastpkts_total +nd_ip_mcast_total +nd_ip_tcp_accept_queue_total +nd_ip_tcpconnaborts_total +nd_ip_tcpofo_total +nd_ip_tcpreorders_total +nd_ipv4_errors_total +nd_ipv4_icmp_errors_total +nd_ipv4_icmpmsg_total +nd_ipv4_icmp_total +nd_ipv4_packets_total +nd_ipv4_sockstat_sockets +nd_ipv4_sockstat_tcp_mem +nd_ipv4_sockstat_tcp_sockets +nd_ipv4_sockstat_udp_mem +nd_ipv4_sockstat_udp_sockets +nd_ipv4_tcperrors_total +nd_ipv4_tcphandshake_total +nd_ipv4_tcpopens_total +nd_ipv4_tcppackets_total +nd_ipv4_tcpsock +nd_ipv4_udperrors_total +nd_ipv4_udppackets_total +nd_ipv6_ect_total +nd_ipv6_errors_total +nd_ipv6_icmperrors_total +nd_ipv6_icmpmldv2_total +nd_ipv6_icmpneighbor_total +nd_ipv6_icmprouter_total +nd_ipv6_icmp_total +nd_ipv6_icmptypes_total +nd_ipv6_mcastpkts_total +nd_ipv6_mcast_total +nd_ipv6_packets_total +nd_ipv6_sockstat6_raw_sockets +nd_ipv6_sockstat6_tcp_sockets +nd_ipv6_sockstat6_udp_sockets +nd_ipv6_udperrors_total +nd_ipv6_udppackets_total +nd_mem_available +nd_mem_committed +nd_mem_kernel +nd_mem_pgfaults_total +nd_mem_slab +nd_mem_transparent_hugepages +nd_mem_writeback +nd_netdata_apps_children_fix +nd_netdata_apps_cpu_total +nd_netdata_apps_fix +nd_netdata_apps_sizes_calls_total +nd_netdata_apps_sizes_fds +nd_netdata_apps_sizes_filenames_total +nd_netdata_apps_sizes_files_total +nd_netdata_apps_sizes_inode_changes_total +nd_netdata_apps_sizes_link_changes_total +nd_netdata_apps_sizes_new_pids_total +nd_netdata_apps_sizes_pids +nd_netdata_apps_sizes_targets +nd_netdata_clients +nd_netdata_compression_ratio +nd_netdata_go_plugin_execution_time +nd_netdata_net_total +nd_netdata_plugin_cgroups_cpu_total +nd_netdata_plugin_diskspace_dt +nd_netdata_plugin_diskspace_total +nd_netdata_plugin_proc_cpu_total +nd_netdata_plugin_proc_modules +nd_netdata_plugin_tc_cpu_total +nd_netdata_plugin_tc_time +nd_netdata_private_charts +nd_netdata_pythond_runtime +nd_netdata_requests_total +nd_netdata_response_time +nd_netdata_server_cpu_total +nd_netdata_statsd_bytes_total +nd_netdata_statsd_cpu_total +nd_netdata_statsd_events_total +nd_netdata_statsd_metrics +nd_netdata_statsd_packets_total +nd_netdata_statsd_reads_total +nd_netdata_statsd_useful_metrics +nd_netdata_tcp_connected +nd_netdata_tcp_connects_total +nd_netdata_web_cpu_total +nd_net_drops_total +nd_net_net_total +nd_net_packets_total +nd_services_cpu_total +nd_services_mem_usage +nd_services_swap_usage +nd_services_throttle_io_ops_read_total +nd_services_throttle_io_ops_write_total +nd_services_throttle_io_read_total +nd_services_throttle_io_write_total +nd_system_active_processes +nd_system_cpu_total +nd_system_ctxt_total +nd_system_entropy +nd_system_forks_total +nd_system_idlejitter +nd_system_interrupts_total +nd_system_intr_total +nd_system_io_total +nd_system_ipc_semaphore_arrays +nd_system_ipc_semaphores +nd_system_ip_total +nd_system_ipv6_total +nd_system_load +nd_system_net_total +nd_system_pgpgio_total +nd_system_processes +nd_system_ram +nd_system_shared_memory_bytes +nd_system_shared_memory_segments +nd_system_softirqs_total +nd_system_softnet_stat_total +nd_system_swap +nd_system_swapio_total +nd_system_uptime diff --git a/tests/exporting/prometheus.bats b/tests/exporting/prometheus.bats new file mode 100755 index 000000000..40f87b0d5 --- /dev/null +++ b/tests/exporting/prometheus.bats @@ -0,0 +1,31 @@ +#!/usr/bin/env bats + +validate_metrics() { + fname="${1}" + params="${2}" + + curl -sS "http://localhost:19999/api/v1/allmetrics?format=prometheus&prefix=nd×tamps=no${params}" | + grep -E 'nd_system_|nd_cpu_|nd_system_|nd_net_|nd_disk_|nd_ip_|nd_ipv4_|nd_ipv6_|nd_mem_|nd_netdata_|nd_apps_|nd_services_' | + sed -ne 's/{.*//p' | sort | uniq > tests/exportings/new-${fname} + diff tests/exportings/${fname} tests/exportings/new-${fname} + rm tests/exportings/new-${fname} +} + + +if [ ! -f .gitignore ]; then + echo "Need to run as ./tests/exportings/$(basename "$0") from top level directory of git repository" >&2 + exit 1 +fi + + +@test "prometheus raw" { + validate_metrics prometheus-raw.txt "&data=raw" +} + +@test "prometheus avg" { + validate_metrics prometheus-avg.txt "" +} + +@test "prometheus avg oldunits" { + validate_metrics prometheus-avg-oldunits.txt "&oldunits=yes" +} diff --git a/tests/health_mgmtapi/README.md b/tests/health_mgmtapi/README.md index 1a4b2b146..e19b612a5 100644 --- a/tests/health_mgmtapi/README.md +++ b/tests/health_mgmtapi/README.md @@ -12,4 +12,4 @@ The script can be executed with options to prepare the system for the tests, run It depends on the management API being accessible on localhost:19999 and on the responses to the api/v1/alarms?all requests being functional. It also requires read access to the management API key that is usually under `/var/lib/netdata/netdata.api.key` (`@varlibdir_POST@/netdata.api.key`). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Ftests%2Fhealth_mgmtapi%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/tests/node.d/fronius.chart.spec.js b/tests/node.d/fronius.chart.spec.js deleted file mode 100644 index 92e88d2ee..000000000 --- a/tests/node.d/fronius.chart.spec.js +++ /dev/null @@ -1,162 +0,0 @@ -"use strict"; -// SPDX-License-Identifier: GPL-3.0-or-later - -var netdata = require("../../node.d/node_modules/netdata"); -// remember: subject will be a singleton! -var subject = require("../../node.d/fronius.node"); - -var service = netdata.service({ - name: "chart", - module: this -}); - -describe("fronius chart creation", function () { - - var chartPrefix = "fronius_chart."; - - beforeAll(function () { - // change this to enable debug log - netdata.options.DEBUG = false; - }); - - afterAll(function () { - deleteProperties(subject.charts) - }); - - it("should return a basic chart dimension", function () { - var result = subject.createBasicDimension("id", "name", 2); - - expect(result.divisor).toBe(2); - expect(result.id).toBe("id"); - expect(result.algorithm).toEqual(netdata.chartAlgorithms.absolute); - expect(result.multiplier).toBe(1); - }); - - it("should return the power chart definition", function () { - var suffix = "power"; - var result = subject.getSitePowerChart(service, suffix); - - expect(result.id).toBe(chartPrefix + suffix); - expect(result.units).toBe("W"); - expect(result.type).toBe(netdata.chartTypes.area); - expect(result.family).toBe("power"); - expect(result.context).toBe("fronius.power"); - expect(result.dimensions[subject.powerGridId].name).toBe("grid"); - expect(result.dimensions[subject.powerPvId].name).toBe("photovoltaics"); - expect(result.dimensions[subject.powerAccuId].name).toBe("accumulator"); - expect(Object.keys(result.dimensions).length).toBe(3); - }); - - it("should return the consumption chart definition", function () { - var suffix = "Load"; - var result = subject.getSiteConsumptionChart(service, suffix); - - expect(result.id).toBe(chartPrefix + suffix); - expect(result.units).toBe("W"); - expect(result.type).toBe(netdata.chartTypes.area); - expect(result.family).toBe("consumption"); - expect(result.context).toBe("fronius.consumption"); - expect(Object.keys(result.dimensions).length).toBe(1); - expect(result.dimensions[subject.consumptionLoadId].name).toBe("load"); - }); - - it("should return the autonomy chart definition", function () { - var suffix = "Autonomy"; - var result = subject.getSiteAutonomyChart(service, suffix); - - expect(result.id).toBe(chartPrefix + suffix); - expect(result.units).toBe("%"); - expect(result.type).toBe(netdata.chartTypes.area); - expect(result.family).toBe("autonomy"); - expect(result.context).toBe("fronius.autonomy"); - expect(Object.keys(result.dimensions).length).toBe(3); - expect(result.dimensions[subject.autonomyId].name).toBe("autonomy"); - expect(result.dimensions[subject.consumptionSelfId].name).toBe("self_consumption"); - }); - - it("should return the energy today chart definition", function () { - var suffix = "Energy today"; - var result = subject.getSiteEnergyTodayChart(service, suffix); - - expect(result.id).toBe(chartPrefix + suffix); - expect(result.units).toBe("kWh"); - expect(result.type).toBe(netdata.chartTypes.area); - expect(result.family).toBe("energy"); - expect(result.context).toBe("fronius.energy.today"); - expect(Object.keys(result.dimensions).length).toBe(1); - expect(result.dimensions[subject.energyTodayId].name).toBe("today"); - }); - - it("should return the energy year chart definition", function () { - var suffix = "Energy year"; - var result = subject.getSiteEnergyYearChart(service, suffix); - - expect(result.id).toBe(chartPrefix + suffix); - expect(result.units).toBe("kWh"); - expect(result.type).toBe(netdata.chartTypes.area); - expect(result.family).toBe("energy"); - expect(result.context).toBe("fronius.energy.year"); - expect(Object.keys(result.dimensions).length).toBe(1); - expect(result.dimensions[subject.energyYearId].name).toBe("year"); - }); - - it("should return the inverter chart definition with a single numerical inverter", function () { - var inverters = { - "1": {} - }; - var suffix = "numerical"; - var result = subject.getInverterPowerChart(service, suffix, inverters); - - expect(result.id).toBe(chartPrefix + suffix); - expect(result.units).toBe("W"); - expect(result.type).toBe(netdata.chartTypes.stacked); - expect(result.family).toBe("inverters"); - expect(result.context).toBe("fronius.inverter.output"); - expect(Object.keys(result.dimensions).length).toBe(1); - expect(result.dimensions["1"].name).toBe("inverter_1"); - }); - - it("should return the inverter chart definition with a single alphabetical inverter", function () { - var key = "Cellar"; - var inverters = { - "Cellar": {} - }; - var suffix = "alphabetical"; - var result = subject.getInverterPowerChart(service, suffix, inverters); - - expect(result.id).toBe(chartPrefix + suffix); - expect(result.units).toBe("W"); - expect(result.type).toBe(netdata.chartTypes.stacked); - expect(result.family).toBe("inverters"); - expect(result.context).toBe("fronius.inverter.output"); - expect(Object.keys(result.dimensions).length).toBe(1); - expect(result.dimensions[key].name).toBe(key); - }); - - it("should return the inverter chart definition with multiple alphanumerical inverter", function () { - var alpha = "Cellar"; - var numerical = 1; - var inverters = { - "Cellar": {}, - "1": {} - }; - var suffix = "alphanumerical"; - var result = subject.getInverterPowerChart(service, suffix, inverters); - - expect(result.id).toBe(chartPrefix + suffix); - expect(result.units).toBe("W"); - expect(result.type).toBe(netdata.chartTypes.stacked); - expect(result.family).toBe("inverters"); - expect(result.context).toBe("fronius.inverter.output"); - expect(Object.keys(result.dimensions).length).toBe(2); - expect(result.dimensions[alpha].name).toBe(alpha); - expect(result.dimensions[numerical].name).toBe("inverter_" + numerical); - }); - - it("should return the same chart definition on second call for lazy loading", function () { - var first = subject.getSitePowerChart(service, "id"); - var second = subject.getSitePowerChart(service, "id"); - - expect(first).toBe(second); - }); -}); diff --git a/tests/node.d/fronius.parse.spec.js b/tests/node.d/fronius.parse.spec.js deleted file mode 100644 index 01fb38666..000000000 --- a/tests/node.d/fronius.parse.spec.js +++ /dev/null @@ -1,333 +0,0 @@ -"use strict"; -// SPDX-License-Identifier: GPL-3.0-or-later - -var netdata = require("../../node.d/node_modules/netdata"); -// remember: subject will be a singleton! -var subject = require("../../node.d/fronius.node"); - -var service = netdata.service({ - name: "parse", - module: this -}); - -var root = { - "Body": { - "Data": { - "Site": {}, - "Inverters": {} - } - } -}; - -describe("fronius parsing for power chart", function () { - - var site = root.Body.Data.Site; - - afterEach(function () { - deleteProperties(site); - }); - - it("should return 3000 for P_Grid when rounded", function () { - site.P_Grid = 2999.501; - var result = subject.parsePowerChart(service, site).dimensions[0]; - - expect(result.name).toBe(subject.powerGridId); - expect(result.value).toBe(3000); - }); - - it("should return -3000 for P_Grid", function () { - site.P_Grid = -3000; - var result = subject.parsePowerChart(service, site).dimensions[0]; - - expect(result.name).toBe(subject.powerGridId); - expect(result.value).toBe(-3000); - }); - - it("should return 0 for P_Grid if it is null", function () { - site.P_Grid = null; - var result = subject.parsePowerChart(service, site).dimensions[0]; - - expect(result.name).toBe(subject.powerGridId); - expect(result.value).toBe(0); - }); - - it("should return 0 for P_Grid if it is zero", function () { - site.P_Grid = 0; - var result = subject.parsePowerChart(service, site).dimensions[0]; - - expect(result.name).toBe(subject.powerGridId); - expect(result.value).toBe(0); - }); - - it("should return -100 for P_Akku", function () { - // it is unclear whether negative values are possible for p_akku (couldn't test, nor any API docs found). - site.P_Akku = -100; - var result = subject.parsePowerChart(service, site).dimensions[2]; - - expect(result.name).toBe(subject.powerAccuId); - expect(result.value).toBe(-100); - }); - - it("should return 0 for P_Akku if it is null", function () { - site.P_Akku = null; - var result = subject.parsePowerChart(service, site).dimensions[2]; - - expect(result.name).toBe(subject.powerAccuId); - expect(result.value).toBe(0); - }); - - it("should return 0 for P_Akku if it is zero", function () { - site.P_Akku = 0; - var result = subject.parsePowerChart(service, site).dimensions[2]; - - expect(result.name).toBe(subject.powerAccuId); - expect(result.value).toBe(0); - }); - - it("should return 100 for P_PV", function () { - site.P_PV = 100; - var result = subject.parsePowerChart(service, site).dimensions[1]; - - expect(result.name).toBe(subject.powerPvId); - expect(result.value).toBe(100); - }); - - it("should return 0 for P_PV if it is zero", function () { - site.P_PV = 0; - var result = subject.parsePowerChart(service, site).dimensions[1]; - - expect(result.name).toBe(subject.powerPvId); - expect(result.value).toBe(0); - }); - - it("should return 0 for P_PV if it is null", function () { - site.P_PV = null; - var result = subject.parsePowerChart(service, site).dimensions[1]; - - expect(result.name).toBe(subject.powerPvId); - expect(result.value).toBe(0); - }); - - it("should return 0 for P_PV if it is negative", function () { - // solar panels shouldn't consume anything, only produce. - site.P_PV = -1; - var result = subject.parsePowerChart(service, site).dimensions[1]; - - expect(result.name).toBe(subject.powerPvId); - expect(result.value).toBe(0); - }); - -}); - -describe("fronius parsing for consumption", function () { - - var site = root.Body.Data.Site; - - afterEach(function () { - deleteProperties(site); - }); - - it("should return 1000 for P_Load when rounded", function () { - site.P_Load = 1000.499; - var result = subject.parseConsumptionChart(service, site).dimensions[0]; - - expect(result.name).toBe(subject.consumptionLoadId); - expect(result.value).toBe(1000); - }); - - it("should return absolute value for P_Load when negative", function () { - /* - with firmware 3.7.4 it is sometimes possible that negative values are returned for P_Load, - which makes absolutely no sense. There is always a device that consumes some electricity around the clock. - Best we can do is to make it a positive value, since 0 also doesn't make much sense. - This "workaround" seems to work, as there couldn't be any strange peaks observed during long-time testing. - */ - site.P_Load = -50; - var result = subject.parseConsumptionChart(service, site).dimensions[0]; - - expect(result.name).toBe(subject.consumptionLoadId); - expect(result.value).toBe(50); - }); - - it("should return 0 for P_Load if it is null", function () { - site.P_Load = null; - var result = subject.parseConsumptionChart(service, site).dimensions[0]; - - expect(result.name).toBe(subject.consumptionLoadId); - expect(result.value).toBe(0); - }); - - it("should return 0 for P_Load if it is zero", function () { - site.P_Load = 0; - var result = subject.parseConsumptionChart(service, site).dimensions[0]; - - expect(result.name).toBe(subject.consumptionLoadId); - expect(result.value).toBe(0); - }); - -}); - -describe("fronius parsing for autonomy", function () { - - var site = root.Body.Data.Site; - - afterEach(function () { - deleteProperties(site); - }); - - it("should return 100 for rel_Autonomy", function () { - site.rel_Autonomy = 100; - var result = subject.parseAutonomyChart(service, site).dimensions[0]; - - expect(result.name).toBe(subject.autonomyId); - expect(result.value).toBe(100); - }); - - it("should return 0 for rel_Autonomy if it is zero", function () { - site.rel_Autonomy = 0; - var result = subject.parseAutonomyChart(service, site).dimensions[0]; - - expect(result.name).toBe(subject.autonomyId); - expect(result.value).toBe(0); - }); - - it("should return 0 for rel_Autonomy if it is null", function () { - site.rel_Autonomy = null; - var result = subject.parseAutonomyChart(service, site).dimensions[0]; - - expect(result.name).toBe(subject.autonomyId); - expect(result.value).toBe(0); - }); - - it("should return 20 for rel_Autonomy if it is 20", function () { - site.rel_Autonomy = 20.1; - var result = subject.parseAutonomyChart(service, site).dimensions[0]; - - expect(result.name).toBe(subject.autonomyId); - expect(result.value).toBe(20); - }); - - it("should return 20 for rel_SelfConsumption if it is 19.5", function () { - site.rel_SelfConsumption = 19.5; - var result = subject.parseAutonomyChart(service, site).dimensions[1]; - - expect(result.name).toBe(subject.consumptionSelfId); - expect(result.value).toBe(20); - }); - - it("should return 100 for rel_SelfConsumption if it is null", function () { - /* - During testing it could be observed that the API is delivering null if the solar panels - do not produce enough energy to supply the local load. But in this case it should be 100, since all - the produced energy is directly consumed. - */ - site.rel_SelfConsumption = null; - var result = subject.parseAutonomyChart(service, site).dimensions[1]; - - expect(result.name).toBe(subject.consumptionSelfId); - expect(result.value).toBe(100); - }); - - it("should return 0 for rel_SelfConsumption if it is zero", function () { - site.rel_SelfConsumption = 0; - var result = subject.parseAutonomyChart(service, site).dimensions[1]; - - expect(result.name).toBe(subject.consumptionSelfId); - expect(result.value).toBe(0); - }); - - it("should return 0 for solarConsumption if PV is null", function () { - site.P_PV = null; - site.P_Load = -1000; - var result = subject.parseAutonomyChart(service, site).dimensions[2]; - - expect(result.name).toBe(subject.solarConsumptionId); - expect(result.value).toBe(0); - }); - - it("should return 100 for solarConsumption if Load is higher than solar power", function () { - site.P_PV = 500; - site.P_Load = -1500; - var result = subject.parseAutonomyChart(service, site).dimensions[2]; - - expect(result.name).toBe(subject.solarConsumptionId); - expect(result.value).toBe(100); - }); - - it("should return 50 for solarConsumption if Load is half than solar power", function () { - site.P_PV = 3000; - site.P_Load = -1500; - var result = subject.parseAutonomyChart(service, site).dimensions[2]; - - expect(result.name).toBe(subject.solarConsumptionId); - expect(result.value).toBe(50); - }); -}); - -describe("fronius parsing for energy", function () { - - var site = root.Body.Data.Site; - - afterEach(function () { - deleteProperties(site); - }); - - it("should return 10000 for E_Day", function () { - site.E_Day = 10000; - var result = subject.parseEnergyTodayChart(service, site).dimensions[0]; - - expect(result.name).toBe(subject.energyTodayId); - expect(result.value).toBe(10000); - }); - - it("should return 0 for E_Day if it is negative", function () { - /* - The solar panels can't produce negative energy, really. It would be a fault of the API. - */ - site.E_Day = -0.4; - var result = subject.parseEnergyTodayChart(service, site).dimensions[0]; - - expect(result.name).toBe(subject.energyTodayId); - expect(result.value).toBe(0); - }); - - it("should return 100'000 for E_Year", function () { - site.E_Year = 100000.4; - var result = subject.parseEnergyYearChart(service, site).dimensions[0]; - - expect(result.name).toBe(subject.energyYearId); - expect(result.value).toBe(100000); - }); - - it("should return 0 for E_Year if it is negative", function () { - /* - A return value of 0 only makes sense in the silvester night anyway, when the counter is being reset. - A negative value is a fault from the API though. It wouldn't make sense. - */ - site.E_Year = -1; - var result = subject.parseEnergyYearChart(service, site).dimensions[0]; - - expect(result.name).toBe(subject.energyYearId); - expect(result.value).toBe(0); - }); -}); - -describe("fronius parsing for inverters", function () { - - var inverters = root.Body.Data.Inverters; - - afterEach(function () { - deleteProperties(inverters); - }); - - it("should return 1000 for P for inverter with name", function () { - inverters["cellar"] = { - P: 1000 - }; - var result = subject.parseInverterChart(service, inverters).dimensions[0]; - - expect(result.name).toBe("cellar"); - expect(result.value).toBe(1000); - }); - -}); diff --git a/tests/node.d/fronius.process.spec.js b/tests/node.d/fronius.process.spec.js deleted file mode 100644 index 141fa8a6a..000000000 --- a/tests/node.d/fronius.process.spec.js +++ /dev/null @@ -1,75 +0,0 @@ -"use strict"; -// SPDX-License-Identifier: GPL-3.0-or-later - -var netdata = require("../../node.d/node_modules/netdata"); -// remember: subject will be a singleton! -var subject = require("../../node.d/fronius.node"); - -var service = netdata.service({ - name: "process", - module: this -}); - -var exampleResponse = { - "Body": { - "Data": { - "Site": { - "Mode": "meter", - "P_Grid": -3430.729923, - "P_Load": -910.270077, - "P_Akku": null, - "P_PV": 4341, - "rel_SelfConsumption": 20.969133, - "rel_Autonomy": 100, - "E_Day": 57230, - "E_Year": 6425915.5, - "E_Total": 15388710, - "Meter_Location": "grid" - }, - "Inverters": { - "1": { - "DT": 123, - "P": 4341, - "E_Day": 57230, - "E_Year": 6425915.5, - "E_Total": 15388710 - } - } - } - } -}; - -describe("fronius main processing", function () { - - beforeAll(function () { - // change this to enable debug log - netdata.options.DEBUG = false; - }); - - beforeEach(function () { - deleteProperties(subject.charts); - }); - - it("should send parsed values to netdata", function () { - netdata.send = jasmine.createSpy("send"); - - subject.processResponse(service, exampleResponse); - - expect(netdata.send.calls.count()).toBe(6); - - // check if some parsed values were sent. - var powerChart = netdata.send.calls.argsFor(5)[0]; - - expect(powerChart).toContain("SET p_grid = -3431"); - expect(powerChart).toContain("SET p_pv = 4341"); - - var inverterChart = netdata.send.calls.argsFor(0)[0]; - - expect(inverterChart).toContain("SET 1 = 4341"); - - var autonomyChart = netdata.send.calls.argsFor(3)[0]; - expect(autonomyChart).toContain("SET rel_selfconsumption = 21"); - }); - - -}); diff --git a/tests/node.d/fronius.validation.spec.js b/tests/node.d/fronius.validation.spec.js deleted file mode 100644 index b7938d52f..000000000 --- a/tests/node.d/fronius.validation.spec.js +++ /dev/null @@ -1,155 +0,0 @@ -"use strict"; -// SPDX-License-Identifier: GPL-3.0-or-later - -var netdata = require("../../node.d/node_modules/netdata"); -// remember: subject will be a singleton! -var subject = require("../../node.d/fronius.node"); - -var service = netdata.service({ - name: "validation", - module: this -}); - -describe("fronius response validation", function () { - - it("should do nothing if response is null", function () { - netdata.send = jasmine.createSpy("send"); - - subject.processResponse(service, null); - var result = netdata.send.calls.count(); - - expect(result).toBe(0); - }); - - it("should return null if response is null", function () { - var result = subject.convertToJson(null); - - expect(result).toBeNull(); - }); - - it("should return null and log error if response cannot be parsed", function () { - netdata.error = jasmine.createSpy("error"); - - // trailing commas are enough to create syntax exceptions - var result = subject.convertToJson("{name,}"); - - expect(result).toBeNull(); - expect(netdata.error.calls.count()).toBe(1); - }); - - it("should return true if response is valid", function () { - var result = subject.isResponseValid({ - "Body": { - "Data": { - "Site": { - "Mode": "meter" - }, - "Inverters": { - "1": {} - } - } - } - }); - - expect(result).toBeTruthy(); - }); - - it("should return false if response is missing data", function () { - var result = subject.isResponseValid({ - "Body": {} - }); - - expect(result).toBeFalsy(); - }); - - it("should return false if response is missing inverter", function () { - var result = subject.isResponseValid({ - "Body": { - "Data": { - "Site": {} - } - } - }); - - expect(result).toBeFalsy(); - }); - - it("should return false if response is missing inverter", function () { - var result = subject.isResponseValid({ - "Body": { - "Data": { - "Inverters": {} - } - } - }); - - expect(result).toBeFalsy(); - }); - -}); - -describe("fronius configuration validation", function () { - - it("should return 0 if there are no servers configured", function () { - var result = subject.configure({}); - - expect(result).toBe(0); - }); - - it("should return 0 if the servers array is empty", function () { - var result = subject.configure({ - "servers": [] - }); - - expect(result).toBe(0); - }); - - it("should return 0 if there is one server configured incorrectly", function () { - var result = subject.configure({ - "servers": [{}] - }); - - expect(result).toBe(0); - }); - - it("should return 1 if there is one server configured", function () { - subject.serviceExecute = jasmine.createSpy("serviceExecute"); - var name = "solar1"; - var result = subject.configure({ - "servers": [{ - "name": name, - "api_path": "/api/", - "hostname": "solar1.local" - }] - }); - - expect(result).toBe(1); - expect(subject.serviceExecute).toHaveBeenCalledWith(name, "solar1.local/api/", 5); - }); - - it("should return 2 if there are two servers configured", function () { - subject.serviceExecute = jasmine.createSpy("serviceExecute"); - var name1 = "solar 1"; - var name2 = "solar 2"; - var result = subject.configure({ - "servers": [ - { - "name": name1, - "api_path": "/", - "hostname": "solar1.local" - }, - { - "name": name2, - "api_path": "/", - "hostname": "solar2.local", - "update_every": 3 - } - ] - }); - - expect(result).toBe(2); - expect(subject.serviceExecute).toHaveBeenCalledWith(name1, "solar1.local/", 5); - expect(subject.serviceExecute).toHaveBeenCalledWith(name2, "solar2.local/", 3); - }); - -}); diff --git a/tests/web/easypiechart.chart.spec.js b/tests/web/easypiechart.chart.spec.js deleted file mode 100644 index 23bf33d69..000000000 --- a/tests/web/easypiechart.chart.spec.js +++ /dev/null @@ -1,39 +0,0 @@ -"use strict"; - - -// with xdescribe, this is skipped. -describe("creation of easy pie charts", function () { - - beforeAll(function () { - // karma stores the loaded files relative to "base/". - // This command is needed to load HTML fixtures - jasmine.getFixtures().fixturesPath = "base/tests/web/fixtures"; - }); - - it("should create new chart, but it's failure is expected for demonstration purpose", function () { - // arrange - // Theoretically we can load some html. What about jquery? could this work? - // https://stackoverflow.com/questions/5337481/spying-on-jquery-selectors-in-jasmine - loadFixtures("easypiechart.chart.fixture1.html"); - - // for easy pie chart, we can fake the data result: - var data = { - result: [5] - }; - // act - var result = NETDATA.easypiechartChartCreate(createState(), data); - // assert - expect(result).toBe(true); - }); - - function createState(min, max) { - // create a fake state with only needed properties. - return { - tmp: { - easyPieChartMin: min, - easyPieChartMax: max - } - }; - } - -}); diff --git a/tests/web/easypiechart.percentage.spec.js b/tests/web/easypiechart.percentage.spec.js deleted file mode 100644 index 976b33964..000000000 --- a/tests/web/easypiechart.percentage.spec.js +++ /dev/null @@ -1,142 +0,0 @@ -"use strict"; - - -describe("percentage calculations for easy pie charts with dynamic range", function () { - - it("should return positive value, if value greater than dynamic max", function () { - var state = createState(null, null); - - var result = NETDATA.easypiechartPercentFromValueMinMax(state, 6, 2, 10); - - expect(result).toBe(60); - }); - - it("should return negative value, if value lesser than dynamic min", function () { - var state = createState(null, null); - - var result = NETDATA.easypiechartPercentFromValueMinMax(state, -6, -10, 10); - - expect(result).toBe(-60); - }); - - it("should return 0 if value is zero and min negative, max positive", function () { - var state = createState(null, null); - - var result = NETDATA.easypiechartPercentFromValueMinMax(state, 0, -1, 2); - - expect(result).toBe(0); - }); - - it("should return 0.1 if value and min are zero and max positive", function () { - var state = createState(null, null); - - var result = NETDATA.easypiechartPercentFromValueMinMax(state, 0, 0, 2); - - expect(result).toBe(0.1); - }); - - it("should return -0.1 if value is zero, max and min negative", function () { - var state = createState(null, null); - - var result = NETDATA.easypiechartPercentFromValueMinMax(state, 0, -2, -1); - - expect(result).toBe(-0.1); - }); - - it("should return positive value, if max is user-defined", function () { - var state = createState(null, 50); - - var result = NETDATA.easypiechartPercentFromValueMinMax(state, 46, -40, 50); - - expect(result).toBe(92); - }); - - it("should return negative value, if min is user-defined", function () { - var state = createState(-50, null); - - var result = NETDATA.easypiechartPercentFromValueMinMax(state, -46, -50, 40); - - expect(result).toBe(-92); - }); - -}); - -describe("percentage calculations for easy pie charts with fixed range", function () { - - it("should return positive value, if min and max are user-defined", function () { - var state = createState(40, 50); - - var result = NETDATA.easypiechartPercentFromValueMinMax(state, 46, 40, 50); - - expect(result).toBe(60); - }); - - it("should return 100 if positive min and max are user-defined, but value is greater than max", function () { - var state = createState(40, 50); - - var result = NETDATA.easypiechartPercentFromValueMinMax(state, 60, 40, 50); - - expect(result).toBe(100); - }); - - it("should return 0.1 if positive min and max are user-defined, but value is smaller than min", function () { - var state = createState(40, 50); - - var result = NETDATA.easypiechartPercentFromValueMinMax(state, 39.9, 42, 48); - - expect(result).toBe(0.1); - }); - - it("should return -100 if negative min and max are user-defined, but value is smaller than min", function () { - var state = createState(-40, -50); - - var result = NETDATA.easypiechartPercentFromValueMinMax(state, -50.1, -40, -50); - - expect(result).toBe(-100); - }); - - it("should return 0.1 if negative min and max are user-defined, but value is smaller than min", function () { - var state = createState(-40, -50); - - var result = NETDATA.easypiechartPercentFromValueMinMax(state, -50.1, -20, -45); - - expect(result).toBe(-100); - }); -}); - -describe("percentage calculations for easy pie charts with invalid input", function () { - - it("should return 0.1 if value undefined", function () { - var state = createState(null, null); - - var result = NETDATA.easypiechartPercentFromValueMinMax(state, null, 40, 50); - - expect(result).toBe(0.1); - }); - - it("should return positive value if min is undefined", function () { - var state = createState(null, null); - - var result = NETDATA.easypiechartPercentFromValueMinMax(state, 1, null, 2); - - expect(result).toBe(50); - }); - - it("should return positive if max is undefined", function () { - var state = createState(null, null); - - var result = NETDATA.easypiechartPercentFromValueMinMax(state, 21, 42, null); - - expect(result).toBe(50); - }); -}); - -function createState(min, max) { - // create a fake state with only the needed properties. - return { - tmp: { - easyPieChartMin: min, - easyPieChartMax: max - } - }; -} diff --git a/tests/web/fixtures/easypiechart.chart.fixture1.html b/tests/web/fixtures/easypiechart.chart.fixture1.html deleted file mode 100644 index f0f4eb777..000000000 --- a/tests/web/fixtures/easypiechart.chart.fixture1.html +++ /dev/null @@ -1,6 +0,0 @@ -
\ No newline at end of file diff --git a/tests/web/karma.conf.js b/tests/web/karma.conf.js deleted file mode 100644 index b3ee0943d..000000000 --- a/tests/web/karma.conf.js +++ /dev/null @@ -1,110 +0,0 @@ -// Karma configuration -// Generated on Sun Jul 16 2017 02:28:05 GMT+0200 (CEST) - -module.exports = function (config) { - config.set({ - - // base path that will be used to resolve all patterns (eg. files, exclude) - // this path should always resolve so that "." is the "netdata" root folder. - basePath: '../../', - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ['jasmine'], - - - // list of files / patterns to load in the browser - files: [ - // order matters! load jquery libraries first - 'web/lib/jquery*.js', - // our jasmine libs and fixtures - 'tests/web/lib/*.js', - 'tests/web/fixtures/*.html', - // then bootstrap - 'web/lib/bootstrap*.js', - // then the rest - 'web/lib/perfect-scrollbar*.js', - 'web/lib/dygraph*.js', - 'web/lib/gauge*.js', - 'web/lib/morris*.js', - 'web/lib/raphael*.js', - 'web/lib/tableExport*.js', - 'web/lib/d3*.js', - 'web/lib/c3*.js', - // some CSS - 'web/css/*.css', - 'web/dashboard.css', - // our dashboard - 'web/dashboard.js', - // finally our test specs - 'tests/web/*.spec.js', - ], - - - // list of files to exclude - exclude: [], - - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - 'web/dashboard.js': ['coverage'] - }, - - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ['progress', 'coverage'], - - // optionally, configure the reporter - coverageReporter: { - type : 'html', - dir : 'coverage/' - }, - - // web server port - port: 9876, - - - // enable / disable colors in the output (reporters and logs) - colors: true, - - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: false, - // not needed with WebStorm. Just hit Alt+Shift+R to rerun. - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - browsers: ['Chromium', 'ChromiumHeadless'], - - customLaunchers: { - // Headless browsers could be useful for CI integration, if installed. - ChromiumHeadless: { - // needs Chrome/Chromium version >= 59 - // see https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md - base: "Chromium", - flags: [ - "--headless", - "--disable-gpu", - // Without a remote debugging port, Chromium exits immediately. - "--remote-debugging-port=9222" - ] - } - }, - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: false, - - // Concurrency level - // how many browser should be started simultaneous - concurrency: Infinity - }) -}; diff --git a/tests/web/lib/jasmine-jquery.js b/tests/web/lib/jasmine-jquery.js deleted file mode 100644 index 6e4611c19..000000000 --- a/tests/web/lib/jasmine-jquery.js +++ /dev/null @@ -1,841 +0,0 @@ -/*! - Jasmine-jQuery: a set of jQuery helpers for Jasmine tests. - - Version 2.1.1 - - https://github.com/velesin/jasmine-jquery - - Copyright (c) 2010-2014 Wojciech Zawistowski, Travis Jeffery - - 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. - */ - -(function (root, factory) { - if (typeof module !== 'undefined' && module.exports && typeof exports !== 'undefined') { - factory(root, root.jasmine, require('jquery')); - } else { - factory(root, root.jasmine, root.jQuery); - } -}((function() {return this; })(), function (window, jasmine, $) { "use strict"; - - jasmine.spiedEventsKey = function (selector, eventName) { - return [$(selector).selector, eventName].toString() - } - - jasmine.getFixtures = function () { - return jasmine.currentFixtures_ = jasmine.currentFixtures_ || new jasmine.Fixtures() - } - - jasmine.getStyleFixtures = function () { - return jasmine.currentStyleFixtures_ = jasmine.currentStyleFixtures_ || new jasmine.StyleFixtures() - } - - jasmine.Fixtures = function () { - this.containerId = 'jasmine-fixtures' - this.fixturesCache_ = {} - this.fixturesPath = 'spec/javascripts/fixtures' - } - - jasmine.Fixtures.prototype.set = function (html) { - this.cleanUp() - return this.createContainer_(html) - } - - jasmine.Fixtures.prototype.appendSet= function (html) { - this.addToContainer_(html) - } - - jasmine.Fixtures.prototype.preload = function () { - this.read.apply(this, arguments) - } - - jasmine.Fixtures.prototype.load = function () { - this.cleanUp() - this.createContainer_(this.read.apply(this, arguments)) - } - - jasmine.Fixtures.prototype.appendLoad = function () { - this.addToContainer_(this.read.apply(this, arguments)) - } - - jasmine.Fixtures.prototype.read = function () { - var htmlChunks = [] - , fixtureUrls = arguments - - for(var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) { - htmlChunks.push(this.getFixtureHtml_(fixtureUrls[urlIndex])) - } - - return htmlChunks.join('') - } - - jasmine.Fixtures.prototype.clearCache = function () { - this.fixturesCache_ = {} - } - - jasmine.Fixtures.prototype.cleanUp = function () { - $('#' + this.containerId).remove() - } - - jasmine.Fixtures.prototype.sandbox = function (attributes) { - var attributesToSet = attributes || {} - return $('
').attr(attributesToSet) - } - - jasmine.Fixtures.prototype.createContainer_ = function (html) { - var container = $('
') - .attr('id', this.containerId) - .html(html) - - $(document.body).append(container) - return container - } - - jasmine.Fixtures.prototype.addToContainer_ = function (html){ - var container = $(document.body).find('#'+this.containerId).append(html) - - if (!container.length) { - this.createContainer_(html) - } - } - - jasmine.Fixtures.prototype.getFixtureHtml_ = function (url) { - if (typeof this.fixturesCache_[url] === 'undefined') { - this.loadFixtureIntoCache_(url) - } - return this.fixturesCache_[url] - } - - jasmine.Fixtures.prototype.loadFixtureIntoCache_ = function (relativeUrl) { - var self = this - , url = this.makeFixtureUrl_(relativeUrl) - , htmlText = '' - , request = $.ajax({ - async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded - cache: false, - url: url, - dataType: 'html', - success: function (data, status, $xhr) { - htmlText = $xhr.responseText - } - }).fail(function ($xhr, status, err) { - throw new Error('Fixture could not be loaded: ' + url + ' (status: ' + status + ', message: ' + err.message + ')') - }) - - var scripts = $($.parseHTML(htmlText, true)).find('script[src]') || []; - - scripts.each(function(){ - $.ajax({ - async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded - cache: false, - dataType: 'script', - url: $(this).attr('src'), - success: function (data, status, $xhr) { - htmlText += '' - }, - error: function ($xhr, status, err) { - throw new Error('Script could not be loaded: ' + url + ' (status: ' + status + ', message: ' + err.message + ')') - } - }); - }) - - self.fixturesCache_[relativeUrl] = htmlText; - } - - jasmine.Fixtures.prototype.makeFixtureUrl_ = function (relativeUrl){ - return this.fixturesPath.match('/$') ? this.fixturesPath + relativeUrl : this.fixturesPath + '/' + relativeUrl - } - - jasmine.Fixtures.prototype.proxyCallTo_ = function (methodName, passedArguments) { - return this[methodName].apply(this, passedArguments) - } - - - jasmine.StyleFixtures = function () { - this.fixturesCache_ = {} - this.fixturesNodes_ = [] - this.fixturesPath = 'spec/javascripts/fixtures' - } - - jasmine.StyleFixtures.prototype.set = function (css) { - this.cleanUp() - this.createStyle_(css) - } - - jasmine.StyleFixtures.prototype.appendSet = function (css) { - this.createStyle_(css) - } - - jasmine.StyleFixtures.prototype.preload = function () { - this.read_.apply(this, arguments) - } - - jasmine.StyleFixtures.prototype.load = function () { - this.cleanUp() - this.createStyle_(this.read_.apply(this, arguments)) - } - - jasmine.StyleFixtures.prototype.appendLoad = function () { - this.createStyle_(this.read_.apply(this, arguments)) - } - - jasmine.StyleFixtures.prototype.cleanUp = function () { - while(this.fixturesNodes_.length) { - this.fixturesNodes_.pop().remove() - } - } - - jasmine.StyleFixtures.prototype.createStyle_ = function (html) { - var styleText = $('
').html(html).text() - , style = $('') - - this.fixturesNodes_.push(style) - $('head').append(style) - } - - jasmine.StyleFixtures.prototype.clearCache = jasmine.Fixtures.prototype.clearCache - jasmine.StyleFixtures.prototype.read_ = jasmine.Fixtures.prototype.read - jasmine.StyleFixtures.prototype.getFixtureHtml_ = jasmine.Fixtures.prototype.getFixtureHtml_ - jasmine.StyleFixtures.prototype.loadFixtureIntoCache_ = jasmine.Fixtures.prototype.loadFixtureIntoCache_ - jasmine.StyleFixtures.prototype.makeFixtureUrl_ = jasmine.Fixtures.prototype.makeFixtureUrl_ - jasmine.StyleFixtures.prototype.proxyCallTo_ = jasmine.Fixtures.prototype.proxyCallTo_ - - jasmine.getJSONFixtures = function () { - return jasmine.currentJSONFixtures_ = jasmine.currentJSONFixtures_ || new jasmine.JSONFixtures() - } - - jasmine.JSONFixtures = function () { - this.fixturesCache_ = {} - this.fixturesPath = 'spec/javascripts/fixtures/json' - } - - jasmine.JSONFixtures.prototype.load = function () { - this.read.apply(this, arguments) - return this.fixturesCache_ - } - - jasmine.JSONFixtures.prototype.read = function () { - var fixtureUrls = arguments - - for(var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) { - this.getFixtureData_(fixtureUrls[urlIndex]) - } - - return this.fixturesCache_ - } - - jasmine.JSONFixtures.prototype.clearCache = function () { - this.fixturesCache_ = {} - } - - jasmine.JSONFixtures.prototype.getFixtureData_ = function (url) { - if (!this.fixturesCache_[url]) this.loadFixtureIntoCache_(url) - return this.fixturesCache_[url] - } - - jasmine.JSONFixtures.prototype.loadFixtureIntoCache_ = function (relativeUrl) { - var self = this - , url = this.fixturesPath.match('/$') ? this.fixturesPath + relativeUrl : this.fixturesPath + '/' + relativeUrl - - $.ajax({ - async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded - cache: false, - dataType: 'json', - url: url, - success: function (data) { - self.fixturesCache_[relativeUrl] = data - }, - error: function ($xhr, status, err) { - throw new Error('JSONFixture could not be loaded: ' + url + ' (status: ' + status + ', message: ' + err.message + ')') - } - }) - } - - jasmine.JSONFixtures.prototype.proxyCallTo_ = function (methodName, passedArguments) { - return this[methodName].apply(this, passedArguments) - } - - jasmine.jQuery = function () {} - - jasmine.jQuery.browserTagCaseIndependentHtml = function (html) { - return $('
').append(html).html() - } - - jasmine.jQuery.elementToString = function (element) { - return $(element).map(function () { return this.outerHTML; }).toArray().join(', ') - } - - var data = { - spiedEvents: {} - , handlers: [] - } - - jasmine.jQuery.events = { - spyOn: function (selector, eventName) { - var handler = function (e) { - var calls = (typeof data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] !== 'undefined') ? data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)].calls : 0 - data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] = { - args: jasmine.util.argsToArray(arguments), - calls: ++calls - } - } - - $(selector).on(eventName, handler) - data.handlers.push(handler) - - return { - selector: selector, - eventName: eventName, - handler: handler, - reset: function (){ - delete data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] - }, - calls: { - count: function () { - return data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] ? - data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)].calls : 0; - }, - any: function () { - return data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] ? - !!data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)].calls : false; - } - } - } - }, - - args: function (selector, eventName) { - var actualArgs = data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)].args - - if (!actualArgs) { - throw "There is no spy for " + eventName + " on " + selector.toString() + ". Make sure to create a spy using spyOnEvent." - } - - return actualArgs - }, - - wasTriggered: function (selector, eventName) { - return !!(data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)]) - }, - - wasTriggeredWith: function (selector, eventName, expectedArgs, util, customEqualityTesters) { - var actualArgs = jasmine.jQuery.events.args(selector, eventName).slice(1) - - if (Object.prototype.toString.call(expectedArgs) !== '[object Array]') - actualArgs = actualArgs[0] - - return util.equals(actualArgs, expectedArgs, customEqualityTesters) - }, - - wasPrevented: function (selector, eventName) { - var spiedEvent = data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] - , args = (jasmine.util.isUndefined(spiedEvent)) ? {} : spiedEvent.args - , e = args ? args[0] : undefined - - return e && e.isDefaultPrevented() - }, - - wasStopped: function (selector, eventName) { - var spiedEvent = data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] - , args = (jasmine.util.isUndefined(spiedEvent)) ? {} : spiedEvent.args - , e = args ? args[0] : undefined - - return e && e.isPropagationStopped() - }, - - cleanUp: function () { - data.spiedEvents = {} - data.handlers = [] - } - } - - var hasProperty = function (actualValue, expectedValue) { - if (expectedValue === undefined) - return actualValue !== undefined - - return actualValue === expectedValue - } - - beforeEach(function () { - jasmine.addMatchers({ - toHaveClass: function () { - return { - compare: function (actual, className) { - return { pass: $(actual).hasClass(className) } - } - } - }, - - toHaveCss: function () { - return { - compare: function (actual, css) { - var stripCharsRegex = /[\s;\"\']/g - for (var prop in css) { - var value = css[prop] - // see issue #147 on gh - ;if ((value === 'auto') && ($(actual).get(0).style[prop] === 'auto')) continue - var actualStripped = $(actual).css(prop).replace(stripCharsRegex, '') - var valueStripped = value.replace(stripCharsRegex, '') - if (actualStripped !== valueStripped) return { pass: false } - } - return { pass: true } - } - } - }, - - toBeVisible: function () { - return { - compare: function (actual) { - return { pass: $(actual).is(':visible') } - } - } - }, - - toBeHidden: function () { - return { - compare: function (actual) { - return { pass: $(actual).is(':hidden') } - } - } - }, - - toBeSelected: function () { - return { - compare: function (actual) { - return { pass: $(actual).is(':selected') } - } - } - }, - - toBeChecked: function () { - return { - compare: function (actual) { - return { pass: $(actual).is(':checked') } - } - } - }, - - toBeEmpty: function () { - return { - compare: function (actual) { - return { pass: $(actual).is(':empty') } - } - } - }, - - toBeInDOM: function () { - return { - compare: function (actual) { - return { pass: $.contains(document.documentElement, $(actual)[0]) } - } - } - }, - - toExist: function () { - return { - compare: function (actual) { - return { pass: $(actual).length } - } - } - }, - - toHaveLength: function () { - return { - compare: function (actual, length) { - return { pass: $(actual).length === length } - } - } - }, - - toHaveAttr: function () { - return { - compare: function (actual, attributeName, expectedAttributeValue) { - return { pass: hasProperty($(actual).attr(attributeName), expectedAttributeValue) } - } - } - }, - - toHaveProp: function () { - return { - compare: function (actual, propertyName, expectedPropertyValue) { - return { pass: hasProperty($(actual).prop(propertyName), expectedPropertyValue) } - } - } - }, - - toHaveId: function () { - return { - compare: function (actual, id) { - return { pass: $(actual).attr('id') == id } - } - } - }, - - toHaveHtml: function () { - return { - compare: function (actual, html) { - return { pass: $(actual).html() == jasmine.jQuery.browserTagCaseIndependentHtml(html) } - } - } - }, - - toContainHtml: function () { - return { - compare: function (actual, html) { - var actualHtml = $(actual).html() - , expectedHtml = jasmine.jQuery.browserTagCaseIndependentHtml(html) - - return { pass: (actualHtml.indexOf(expectedHtml) >= 0) } - } - } - }, - - toHaveText: function () { - return { - compare: function (actual, text) { - var actualText = $(actual).text() - var trimmedText = $.trim(actualText) - - if (text && $.isFunction(text.test)) { - return { pass: text.test(actualText) || text.test(trimmedText) } - } else { - return { pass: (actualText == text || trimmedText == text) } - } - } - } - }, - - toContainText: function () { - return { - compare: function (actual, text) { - var trimmedText = $.trim($(actual).text()) - - if (text && $.isFunction(text.test)) { - return { pass: text.test(trimmedText) } - } else { - return { pass: trimmedText.indexOf(text) != -1 } - } - } - } - }, - - toHaveValue: function () { - return { - compare: function (actual, value) { - return { pass: $(actual).val() === value } - } - } - }, - - toHaveData: function () { - return { - compare: function (actual, key, expectedValue) { - return { pass: hasProperty($(actual).data(key), expectedValue) } - } - } - }, - - toContainElement: function () { - return { - compare: function (actual, selector) { - return { pass: $(actual).find(selector).length } - } - } - }, - - toBeMatchedBy: function () { - return { - compare: function (actual, selector) { - return { pass: $(actual).filter(selector).length } - } - } - }, - - toBeDisabled: function () { - return { - compare: function (actual, selector) { - return { pass: $(actual).is(':disabled') } - } - } - }, - - toBeFocused: function (selector) { - return { - compare: function (actual, selector) { - return { pass: $(actual)[0] === $(actual)[0].ownerDocument.activeElement } - } - } - }, - - toHandle: function () { - return { - compare: function (actual, event) { - if ( !actual || actual.length === 0 ) return { pass: false }; - var events = $._data($(actual).get(0), "events") - - if (!events || !event || typeof event !== "string") { - return { pass: false } - } - - var namespaces = event.split(".") - , eventType = namespaces.shift() - , sortedNamespaces = namespaces.slice(0).sort() - , namespaceRegExp = new RegExp("(^|\\.)" + sortedNamespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") - - if (events[eventType] && namespaces.length) { - for (var i = 0; i < events[eventType].length; i++) { - var namespace = events[eventType][i].namespace - - if (namespaceRegExp.test(namespace)) - return { pass: true } - } - } else { - return { pass: (events[eventType] && events[eventType].length > 0) } - } - - return { pass: false } - } - } - }, - - toHandleWith: function () { - return { - compare: function (actual, eventName, eventHandler) { - if ( !actual || actual.length === 0 ) return { pass: false }; - var normalizedEventName = eventName.split('.')[0] - , stack = $._data($(actual).get(0), "events")[normalizedEventName] - - for (var i = 0; i < stack.length; i++) { - if (stack[i].handler == eventHandler) return { pass: true } - } - - return { pass: false } - } - } - }, - - toHaveBeenTriggeredOn: function () { - return { - compare: function (actual, selector) { - var result = { pass: jasmine.jQuery.events.wasTriggered(selector, actual) } - - result.message = result.pass ? - "Expected event " + $(actual) + " not to have been triggered on " + selector : - "Expected event " + $(actual) + " to have been triggered on " + selector - - return result; - } - } - }, - - toHaveBeenTriggered: function (){ - return { - compare: function (actual) { - var eventName = actual.eventName - , selector = actual.selector - , result = { pass: jasmine.jQuery.events.wasTriggered(selector, eventName) } - - result.message = result.pass ? - "Expected event " + eventName + " not to have been triggered on " + selector : - "Expected event " + eventName + " to have been triggered on " + selector - - return result - } - } - }, - - toHaveBeenTriggeredOnAndWith: function (j$, customEqualityTesters) { - return { - compare: function (actual, selector, expectedArgs) { - var wasTriggered = jasmine.jQuery.events.wasTriggered(selector, actual) - , result = { pass: wasTriggered && jasmine.jQuery.events.wasTriggeredWith(selector, actual, expectedArgs, j$, customEqualityTesters) } - - if (wasTriggered) { - var actualArgs = jasmine.jQuery.events.args(selector, actual, expectedArgs)[1] - result.message = result.pass ? - "Expected event " + actual + " not to have been triggered with " + jasmine.pp(expectedArgs) + " but it was triggered with " + jasmine.pp(actualArgs) : - "Expected event " + actual + " to have been triggered with " + jasmine.pp(expectedArgs) + " but it was triggered with " + jasmine.pp(actualArgs) - - } else { - // todo check on this - result.message = result.pass ? - "Expected event " + actual + " not to have been triggered on " + selector : - "Expected event " + actual + " to have been triggered on " + selector - } - - return result - } - } - }, - - toHaveBeenPreventedOn: function () { - return { - compare: function (actual, selector) { - var result = { pass: jasmine.jQuery.events.wasPrevented(selector, actual) } - - result.message = result.pass ? - "Expected event " + actual + " not to have been prevented on " + selector : - "Expected event " + actual + " to have been prevented on " + selector - - return result - } - } - }, - - toHaveBeenPrevented: function () { - return { - compare: function (actual) { - var eventName = actual.eventName - , selector = actual.selector - , result = { pass: jasmine.jQuery.events.wasPrevented(selector, eventName) } - - result.message = result.pass ? - "Expected event " + eventName + " not to have been prevented on " + selector : - "Expected event " + eventName + " to have been prevented on " + selector - - return result - } - } - }, - - toHaveBeenStoppedOn: function () { - return { - compare: function (actual, selector) { - var result = { pass: jasmine.jQuery.events.wasStopped(selector, actual) } - - result.message = result.pass ? - "Expected event " + actual + " not to have been stopped on " + selector : - "Expected event " + actual + " to have been stopped on " + selector - - return result; - } - } - }, - - toHaveBeenStopped: function () { - return { - compare: function (actual) { - var eventName = actual.eventName - , selector = actual.selector - , result = { pass: jasmine.jQuery.events.wasStopped(selector, eventName) } - - result.message = result.pass ? - "Expected event " + eventName + " not to have been stopped on " + selector : - "Expected event " + eventName + " to have been stopped on " + selector - - return result - } - } - } - }) - - jasmine.getEnv().addCustomEqualityTester(function(a, b) { - if (a && b) { - if (a instanceof $ || jasmine.isDomNode(a)) { - var $a = $(a) - - if (b instanceof $) - return $a.length == b.length && $a.is(b) - - return $a.is(b); - } - - if (b instanceof $ || jasmine.isDomNode(b)) { - var $b = $(b) - - if (a instanceof $) - return a.length == $b.length && $b.is(a) - - return $b.is(a); - } - } - }) - - jasmine.getEnv().addCustomEqualityTester(function (a, b) { - if (a instanceof $ && b instanceof $ && a.size() == b.size()) - return a.is(b) - }) - }) - - afterEach(function () { - jasmine.getFixtures().cleanUp() - jasmine.getStyleFixtures().cleanUp() - jasmine.jQuery.events.cleanUp() - }) - - window.readFixtures = function () { - return jasmine.getFixtures().proxyCallTo_('read', arguments) - } - - window.preloadFixtures = function () { - jasmine.getFixtures().proxyCallTo_('preload', arguments) - } - - window.loadFixtures = function () { - jasmine.getFixtures().proxyCallTo_('load', arguments) - } - - window.appendLoadFixtures = function () { - jasmine.getFixtures().proxyCallTo_('appendLoad', arguments) - } - - window.setFixtures = function (html) { - return jasmine.getFixtures().proxyCallTo_('set', arguments) - } - - window.appendSetFixtures = function () { - jasmine.getFixtures().proxyCallTo_('appendSet', arguments) - } - - window.sandbox = function (attributes) { - return jasmine.getFixtures().sandbox(attributes) - } - - window.spyOnEvent = function (selector, eventName) { - return jasmine.jQuery.events.spyOn(selector, eventName) - } - - window.preloadStyleFixtures = function () { - jasmine.getStyleFixtures().proxyCallTo_('preload', arguments) - } - - window.loadStyleFixtures = function () { - jasmine.getStyleFixtures().proxyCallTo_('load', arguments) - } - - window.appendLoadStyleFixtures = function () { - jasmine.getStyleFixtures().proxyCallTo_('appendLoad', arguments) - } - - window.setStyleFixtures = function (html) { - jasmine.getStyleFixtures().proxyCallTo_('set', arguments) - } - - window.appendSetStyleFixtures = function (html) { - jasmine.getStyleFixtures().proxyCallTo_('appendSet', arguments) - } - - window.loadJSONFixtures = function () { - return jasmine.getJSONFixtures().proxyCallTo_('load', arguments) - } - - window.getJSONFixture = function (url) { - return jasmine.getJSONFixtures().proxyCallTo_('read', arguments)[url] - } -})); diff --git a/web/README.md b/web/README.md index 6a7aa68ff..7093ca18f 100644 --- a/web/README.md +++ b/web/README.md @@ -232,5 +232,3 @@ make If you make any changes to the `src` directory when developing Netdata, you should regenerate the `dashboard.js` file before you commit to the Netdata repository. - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]() diff --git a/web/api/README.md b/web/api/README.md index 1cc3439c2..89a953002 100644 --- a/web/api/README.md +++ b/web/api/README.md @@ -11,4 +11,4 @@ The complete documentation of the Netdata API is available at the **[Swagger Edi If your prefer it over the Swagger Editor, you can also use **[Swagger UI](https://registry.my-netdata.io/swagger/#!/default/get_data)**. This however does not provide all the information available. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fapi%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/api/badges/README.md b/web/api/badges/README.md index b5fc53468..601eae479 100644 --- a/web/api/badges/README.md +++ b/web/api/badges/README.md @@ -360,4 +360,4 @@ You can refresh them from your browser console though. Press F12 to open the web var len = document.images.length; while(len--) { document.images[len].src = document.images[len].src.replace(/\?cacheBuster=\d*/, "") + "?cacheBuster=" + new Date().getTime().toString(); }; ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fapi%2Fbadges%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/api/badges/web_buffer_svg.c b/web/api/badges/web_buffer_svg.c index f8c0a17a6..65ca21d19 100644 --- a/web/api/badges/web_buffer_svg.c +++ b/web/api/badges/web_buffer_svg.c @@ -1102,7 +1102,7 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u // if the collected value is too old, don't calculate its value if (rrdset_last_entry_t(st) >= (now_realtime_sec() - (st->update_every * st->gap_when_lost_iterations_above))) ret = rrdset2value_api_v1(st, w->response.data, &n, (dimensions) ? buffer_tostring(dimensions) : NULL - , points, after, before, group, 0, options, NULL, &latest_timestamp, &value_is_null); + , points, after, before, group, 0, options, NULL, &latest_timestamp, &value_is_null, 0); // if the value cannot be calculated, show empty badge if (ret != HTTP_RESP_OK) { diff --git a/web/api/exporters/README.md b/web/api/exporters/README.md index 401964744..1d517a91e 100644 --- a/web/api/exporters/README.md +++ b/web/api/exporters/README.md @@ -7,4 +7,4 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/web/api/exporter TBD -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fapi%2Fexporters%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/api/exporters/allmetrics.c b/web/api/exporters/allmetrics.c index d10de3d3c..1eba815c3 100644 --- a/web/api/exporters/allmetrics.c +++ b/web/api/exporters/allmetrics.c @@ -25,17 +25,17 @@ inline int web_client_api_request_v1_allmetrics(RRDHOST *host, struct web_client if (prometheus_exporter_instance) prometheus_exporting_options = prometheus_exporter_instance->config.options; else - prometheus_exporting_options = global_backend_options; + prometheus_exporting_options = global_exporting_options; PROMETHEUS_OUTPUT_OPTIONS prometheus_output_options = PROMETHEUS_OUTPUT_TIMESTAMPS | - ((prometheus_exporting_options & BACKEND_OPTION_SEND_NAMES) ? PROMETHEUS_OUTPUT_NAMES : 0); + ((prometheus_exporting_options & EXPORTING_OPTION_SEND_NAMES) ? PROMETHEUS_OUTPUT_NAMES : 0); const char *prometheus_prefix; if (prometheus_exporter_instance) prometheus_prefix = prometheus_exporter_instance->config.prefix; else - prometheus_prefix = global_backend_prefix; + prometheus_prefix = global_exporting_prefix; while(url) { char *value = mystrsep(&url, "&"); @@ -64,7 +64,7 @@ inline int web_client_api_request_v1_allmetrics(RRDHOST *host, struct web_client prometheus_prefix = value; } else if(!strcmp(name, "data") || !strcmp(name, "source") || !strcmp(name, "data source") || !strcmp(name, "data-source") || !strcmp(name, "data_source") || !strcmp(name, "datasource")) { - prometheus_exporting_options = backend_parse_data_source(value, prometheus_exporting_options); + prometheus_exporting_options = exporting_parse_data_source(value, prometheus_exporting_options); } else { int i; diff --git a/web/api/exporters/prometheus/README.md b/web/api/exporters/prometheus/README.md index 48b85555e..cf7e2caa8 100644 --- a/web/api/exporters/prometheus/README.md +++ b/web/api/exporters/prometheus/README.md @@ -7,4 +7,4 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/web/api/exporter Read the Prometheus exporter documentation: [Using Netdata with Prometheus](/exporting/prometheus/README.md). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fapi%2Fexporters%2Fprometheus%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/api/exporters/shell/README.md b/web/api/exporters/shell/README.md index 9d44a3707..a41326c9d 100644 --- a/web/api/exporters/shell/README.md +++ b/web/api/exporters/shell/README.md @@ -66,4 +66,4 @@ NETDATA_${chart_id^^}_${dimension_id^^}="${value}" The value is rounded to the closest integer, since shell script cannot process decimal numbers. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fapi%2Fexporters%2Fshell%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/api/formatters/README.md b/web/api/formatters/README.md index 1fd2b3029..3e67ac6ee 100644 --- a/web/api/formatters/README.md +++ b/web/api/formatters/README.md @@ -75,4 +75,4 @@ For example, to download a CSV file with CPU utilization of the last hour, This is done by appending `&tqx=outFileName:FILENAME` to any data query. The output will be in the format given with `&format=`. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fapi%2Fformatters%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/api/formatters/csv/README.md b/web/api/formatters/csv/README.md index 2a859e249..df7c11efa 100644 --- a/web/api/formatters/csv/README.md +++ b/web/api/formatters/csv/README.md @@ -141,4 +141,4 @@ And this is how it looks when formatted: | 2018-10-27 03:44:00 | 7026.9852167 | | 2018-10-27 03:43:00 | 205.9904794 | -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fapi%2Fformatters%2Fcsv%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/api/formatters/json/README.md b/web/api/formatters/json/README.md index 685a3f2df..a0f8108e7 100644 --- a/web/api/formatters/json/README.md +++ b/web/api/formatters/json/README.md @@ -153,4 +153,4 @@ google.visualization.Query.setResponse({version:'0.6',reqId:'0',status:'ok',sig: }}); ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fapi%2Fformatters%2Fjson%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/api/formatters/rrd2json.c b/web/api/formatters/rrd2json.c index 29bb4beb5..1a8b07c7c 100644 --- a/web/api/formatters/rrd2json.c +++ b/web/api/formatters/rrd2json.c @@ -167,9 +167,10 @@ int rrdset2value_api_v1( , time_t *db_after , time_t *db_before , int *value_is_null + , int timeout ) { - RRDR *r = rrd2rrdr(st, points, after, before, group_method, group_time, options, dimensions, NULL); + RRDR *r = rrd2rrdr(st, points, after, before, group_method, group_time, options, dimensions, NULL, timeout); if(!r) { if(value_is_null) *value_is_null = 1; @@ -197,7 +198,7 @@ int rrdset2value_api_v1( if(db_before) *db_before = r->before; long i = (!(options & RRDR_OPTION_REVERSED))?rrdr_rows(r) - 1:0; - *n = rrdr2value(r, i, options, value_is_null); + *n = rrdr2value(r, i, options, value_is_null, NULL); rrdr_free(r); return HTTP_RESP_OK; @@ -217,17 +218,27 @@ int rrdset2anything_api_v1( , time_t *latest_timestamp , struct context_param *context_param_list , char *chart_label_key -) { - + , int max_anomaly_rates + , int timeout +) +{ if (context_param_list && !(context_param_list->flags & CONTEXT_FLAGS_ARCHIVE)) st->last_accessed_time = now_realtime_sec(); - RRDR *r = rrd2rrdr(st, points, after, before, group_method, group_time, options, dimensions?buffer_tostring(dimensions):NULL, context_param_list); + RRDR *r = rrd2rrdr(st, points, after, before, group_method, group_time, options, dimensions?buffer_tostring(dimensions):NULL, context_param_list, timeout); if(!r) { buffer_strcat(wb, "Cannot generate output with these parameters on this chart."); return HTTP_RESP_INTERNAL_SERVER_ERROR; } + if (r->result_options & RRDR_RESULT_OPTION_CANCEL) { + rrdr_free(r); + return HTTP_RESP_BACKEND_FETCH_FAILED; + } + + if (st && st->state && st->state->is_ar_chart) + ml_process_rrdr(r, max_anomaly_rates); + RRDDIM *temp_rd = context_param_list ? context_param_list->rd : NULL; if(r->result_options & RRDR_RESULT_OPTION_RELATIVE) @@ -243,12 +254,12 @@ int rrdset2anything_api_v1( if(options & RRDR_OPTION_JSON_WRAP) { wb->contenttype = CT_APPLICATION_JSON; rrdr_json_wrapper_begin(r, wb, format, options, 1, context_param_list, chart_label_key); - rrdr2ssv(r, wb, options, "", " ", ""); + rrdr2ssv(r, wb, options, "", " ", "", temp_rd); rrdr_json_wrapper_end(r, wb, format, options, 1); } else { wb->contenttype = CT_TEXT_PLAIN; - rrdr2ssv(r, wb, options, "", " ", ""); + rrdr2ssv(r, wb, options, "", " ", "", temp_rd); } break; @@ -256,12 +267,12 @@ int rrdset2anything_api_v1( if(options & RRDR_OPTION_JSON_WRAP) { wb->contenttype = CT_APPLICATION_JSON; rrdr_json_wrapper_begin(r, wb, format, options, 1, context_param_list, chart_label_key); - rrdr2ssv(r, wb, options, "", ",", ""); + rrdr2ssv(r, wb, options, "", ",", "", temp_rd); rrdr_json_wrapper_end(r, wb, format, options, 1); } else { wb->contenttype = CT_TEXT_PLAIN; - rrdr2ssv(r, wb, options, "", ",", ""); + rrdr2ssv(r, wb, options, "", ",", "", temp_rd); } break; @@ -269,12 +280,12 @@ int rrdset2anything_api_v1( if(options & RRDR_OPTION_JSON_WRAP) { wb->contenttype = CT_APPLICATION_JSON; rrdr_json_wrapper_begin(r, wb, format, options, 0, context_param_list, chart_label_key); - rrdr2ssv(r, wb, options, "[", ",", "]"); + rrdr2ssv(r, wb, options, "[", ",", "]", temp_rd); rrdr_json_wrapper_end(r, wb, format, options, 0); } else { wb->contenttype = CT_APPLICATION_JSON; - rrdr2ssv(r, wb, options, "[", ",", "]"); + rrdr2ssv(r, wb, options, "[", ",", "]", temp_rd); } break; diff --git a/web/api/formatters/rrd2json.h b/web/api/formatters/rrd2json.h index 3dc598973..af809c54f 100644 --- a/web/api/formatters/rrd2json.h +++ b/web/api/formatters/rrd2json.h @@ -67,6 +67,8 @@ extern int rrdset2anything_api_v1( , time_t *latest_timestamp , struct context_param *context_param_list , char *chart_label_key + , int max_anomaly_rates + , int timeout ); extern int rrdset2value_api_v1( @@ -83,6 +85,7 @@ extern int rrdset2value_api_v1( , time_t *db_after , time_t *db_before , int *value_is_null + , int timeout ); extern void build_context_param_list(struct context_param **param_list, RRDSET *st); diff --git a/web/api/formatters/ssv/README.md b/web/api/formatters/ssv/README.md index d439949a5..d9e193d66 100644 --- a/web/api/formatters/ssv/README.md +++ b/web/api/formatters/ssv/README.md @@ -56,4 +56,4 @@ in a JSON array: [278,258,268,239,259,260,243,266,278,318,264,258] ``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fapi%2Fformatters%2Fssv%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/api/formatters/ssv/ssv.c b/web/api/formatters/ssv/ssv.c index eeba0283d..8d3ddbfdf 100644 --- a/web/api/formatters/ssv/ssv.c +++ b/web/api/formatters/ssv/ssv.c @@ -2,7 +2,7 @@ #include "ssv.h" -void rrdr2ssv(RRDR *r, BUFFER *wb, RRDR_OPTIONS options, const char *prefix, const char *separator, const char *suffix) { +void rrdr2ssv(RRDR *r, BUFFER *wb, RRDR_OPTIONS options, const char *prefix, const char *separator, const char *suffix, RRDDIM *temp_rd) { //info("RRD2SSV(): %s: BEGIN", r->st->id); long i; @@ -17,7 +17,7 @@ void rrdr2ssv(RRDR *r, BUFFER *wb, RRDR_OPTIONS options, const char *prefix, con // for each line in the array for(i = start; i != end ;i += step) { int all_values_are_null = 0; - calculated_number v = rrdr2value(r, i, options, &all_values_are_null); + calculated_number v = rrdr2value(r, i, options, &all_values_are_null, temp_rd); if(likely(i != start)) { if(r->min > v) r->min = v; diff --git a/web/api/formatters/ssv/ssv.h b/web/api/formatters/ssv/ssv.h index 6963dcf6e..66716b9c9 100644 --- a/web/api/formatters/ssv/ssv.h +++ b/web/api/formatters/ssv/ssv.h @@ -5,6 +5,6 @@ #include "../rrd2json.h" -extern void rrdr2ssv(RRDR *r, BUFFER *wb, RRDR_OPTIONS options, const char *prefix, const char *separator, const char *suffix); +extern void rrdr2ssv(RRDR *r, BUFFER *wb, RRDR_OPTIONS options, const char *prefix, const char *separator, const char *suffix, RRDDIM *temp_rd); #endif //NETDATA_API_FORMATTER_SSV_H diff --git a/web/api/formatters/value/README.md b/web/api/formatters/value/README.md index 21c937080..a51e32de7 100644 --- a/web/api/formatters/value/README.md +++ b/web/api/formatters/value/README.md @@ -21,4 +21,4 @@ The Value formatter is not exposed by the API by itself. Instead it is used by the [`ssv`](/web/api/formatters/ssv/README.md) formatter and [health monitoring queries](/health/README.md). -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fapi%2Fformatters%2Fvalue%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/api/formatters/value/value.c b/web/api/formatters/value/value.c index a69af6165..9ac91f509 100644 --- a/web/api/formatters/value/value.c +++ b/web/api/formatters/value/value.c @@ -3,7 +3,7 @@ #include "value.h" -inline calculated_number rrdr2value(RRDR *r, long i, RRDR_OPTIONS options, int *all_values_are_null) { +inline calculated_number rrdr2value(RRDR *r, long i, RRDR_OPTIONS options, int *all_values_are_null, RRDDIM *temp_rd) { if (r->st_needs_lock) rrdset_check_rdlock(r->st); @@ -20,7 +20,7 @@ inline calculated_number rrdr2value(RRDR *r, long i, RRDR_OPTIONS options, int * int set_min_max = 0; if(unlikely(options & RRDR_OPTION_PERCENTAGE)) { total = 0; - for(c = 0, d = r->st->dimensions; d && c < r->d ;c++, d = d->next) { + for (c = 0, d = temp_rd ? temp_rd : r->st->dimensions; d && c < r->d; c++, d = d->next) { calculated_number n = cn[c]; if(likely((options & RRDR_OPTION_ABSOLUTE) && n < 0)) @@ -34,7 +34,7 @@ inline calculated_number rrdr2value(RRDR *r, long i, RRDR_OPTIONS options, int * } // for each dimension - for(c = 0, d = r->st->dimensions; d && c < r->d ;c++, d = d->next) { + for (c = 0, d = temp_rd ? temp_rd : r->st->dimensions; d && c < r->d; c++, d = d->next) { if(unlikely(r->od[c] & RRDR_DIMENSION_HIDDEN)) continue; if(unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_DIMENSION_NONZERO))) continue; diff --git a/web/api/formatters/value/value.h b/web/api/formatters/value/value.h index d9e981f88..2d6bd1242 100644 --- a/web/api/formatters/value/value.h +++ b/web/api/formatters/value/value.h @@ -5,6 +5,6 @@ #include "../rrd2json.h" -extern calculated_number rrdr2value(RRDR *r, long i, RRDR_OPTIONS options, int *all_values_are_null); +extern calculated_number rrdr2value(RRDR *r, long i, RRDR_OPTIONS options, int *all_values_are_null, RRDDIM *temp_rd); #endif //NETDATA_API_FORMATTER_VALUE_H diff --git a/web/api/health/README.md b/web/api/health/README.md index b6e8b5c23..9ec8f31c0 100644 --- a/web/api/health/README.md +++ b/web/api/health/README.md @@ -222,4 +222,4 @@ The file's location is configurable in `netdata.conf`. The default is shown belo The test script under [tests/health_mgmtapi](/tests/health_mgmtapi/README.md) contains a series of tests that you can either run or read through to understand the various calls and responses better. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fapi%2Fhealth%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/api/netdata-swagger.json b/web/api/netdata-swagger.json index 7786b333a..4952e6116 100644 --- a/web/api/netdata-swagger.json +++ b/web/api/netdata-swagger.json @@ -3,13 +3,13 @@ "info": { "title": "Netdata API", "description": "Real-time performance and health monitoring.", - "version": "1.11.1_rolling" + "version": "1.33.1" }, "paths": { "/info": { "get": { "summary": "Get netdata basic information", - "description": "The info endpoint returns basic information about netdata. It provides:\n* netdata version\n* netdata unique id\n* list of hosts mirrored (includes itself)\n* Operating System, Virtualization, K8s nodes and Container technology information\n* List of active collector plugins and modules\n* number of alarms in the host\n * number of alarms in normal state\n * number of alarms in warning state\n * number of alarms in critical state\n", + "description": "The info endpoint returns basic information about netdata. It provides:\n* netdata version\n* netdata unique id\n* list of hosts mirrored (includes itself)\n* Operating System, Virtualization, K8s nodes and Container technology information\n* List of active collector plugins and modules\n* Streaming information\n* number of alarms in the host\n * number of alarms in normal state\n * number of alarms in warning state\n * number of alarms in critical state\n", "responses": { "200": { "description": "netdata basic information.", @@ -199,6 +199,28 @@ "default": 20 } }, + { + "name": "chart_label_key", + "in": "query", + "description": "Specify the chart label keys that need to match for context queries as comma separated values. At least one matching key is needed to match the corresponding chart.", + "required": false, + "allowEmptyValue": false, + "schema": { + "type": "string", + "format": "key1,key2,key3" + } + }, + { + "name": "chart_labels_filter", + "in": "query", + "description": "Specify the chart label keys and values to match for context queries. All keys/values need to match for the chart to be included in the query. The labels are specified as key1:value1,key2:value2", + "required": false, + "allowEmptyValue": false, + "schema": { + "type": "string", + "format": "key1:value1,key2:value2,key3:value3" + } + }, { "name": "group", "in": "query", @@ -231,6 +253,18 @@ "default": 0 } }, + { + "name": "timeout", + "in": "query", + "description": "Specify a timeout value in milliseconds after which the agent will abort the query and return a 503 error. A value of 0 indicates no timeout.", + "required": false, + "allowEmptyValue": false, + "schema": { + "type": "number", + "format": "integer", + "default": 0 + } + }, { "name": "format", "in": "query", @@ -1220,6 +1254,11 @@ "description": "Container technology detection method.", "example": "dockerenv" }, + "stream_compression": { + "type": "boolean", + "description": "Stream transmission compression method.", + "example": "true" + }, "labels": { "type": "object", "description": "List of host labels.", @@ -2085,21 +2124,20 @@ "type": "boolean", "description": "Describes whether this agent is capable of connection to the Cloud. False means agent has been built without ACLK component either on purpose (user choice) or due to missing dependency." }, - "aclk-implementation": { - "type": "string", - "description": "Describes which ACLK implementation is currently used.", - "enum": [ - "Next Generation", - "Legacy" - ] + "aclk-version": { + "type": "integer", + "description": "Describes which ACLK version is currently used." }, - "new-cloud-protocol-supported": { - "type": "boolean", - "description": "Informs about new protobuf based Cloud/Agent protocol support of this agent. If false agent has to be compiled with protobuf and protoc available." + "protocols-supported": { + "type": "array", + "description": "List of supported protocols for communication with Cloud.", + "items": { + "type": "string" + } }, "agent-claimed": { "type": "boolean", - "description": "Informs whether this agent has been added to a space in the cloud (User has to perform claiming). If false (user didnt perform claiming) agent will never attempt any cloud connection." + "description": "Informs whether this agent has been added to a space in the cloud (User has to perform claiming). If false (user didn't perform claiming) agent will never attempt any cloud connection." }, "claimed-id": { "type": "string", @@ -2122,4 +2160,4 @@ } } } -} \ No newline at end of file +} diff --git a/web/api/netdata-swagger.yaml b/web/api/netdata-swagger.yaml index 83487bda8..1e20ad0f5 100644 --- a/web/api/netdata-swagger.yaml +++ b/web/api/netdata-swagger.yaml @@ -2,7 +2,7 @@ openapi: 3.0.0 info: title: Netdata API description: Real-time performance and health monitoring. - version: 1.11.1_rolling + version: 1.33.1 paths: /info: get: @@ -14,6 +14,7 @@ paths: * list of hosts mirrored (includes itself) * Operating System, Virtualization, K8s nodes and Container technology information * List of active collector plugins and modules + * Streaming information * number of alarms in the host * number of alarms in normal state * number of alarms in warning state @@ -169,6 +170,24 @@ paths: type: number format: integer default: 20 + - name: chart_label_key + in: query + description: Specify the chart label keys that need to match for context queries as comma separated values. + At least one matching key is needed to match the corresponding chart. + required: false + allowEmptyValue: false + schema: + type: string + format: key1,key2,key3 + - name: chart_labels_filter + in: query + description: Specify the chart label keys and values to match for context queries. All keys/values need to + match for the chart to be included in the query. The labels are specified as key1:value1,key2:value2 + required: false + allowEmptyValue: false + schema: + type: string + format: key1:value1,key2:value2,key3:value3 - name: group in: query description: The grouping method. If multiple collected values are to be grouped @@ -201,6 +220,16 @@ paths: type: number format: integer default: 0 + - name: timeout + in: query + description: Specify a timeout value in milliseconds after which the agent will + abort the query and return a 503 error. A value of 0 indicates no timeout. + required: false + allowEmptyValue: false + schema: + type: number + format: integer + default: 0 - name: format in: query description: The format of the data to be returned. @@ -984,6 +1013,10 @@ components: type: string description: Container technology detection method. example: dockerenv + stream_compression: + type: boolean + description: Stream transmission compression method. + example: true labels: type: object description: List of host labels. @@ -1628,20 +1661,18 @@ components: type: string description: Describes whether this agent is capable of connection to the Cloud. False means agent has been built without ACLK component either on purpose (user choice) or due to missing dependency. - aclk-implementation: - type: string - description: Describes which ACLK implementation is currently used. - enum: - - Next Generation - - Legacy - new-cloud-protocol-supported: - type: boolean - description: Informs about new protobuf based Cloud/Agent protocol support of this agent. - If false agent has to be compiled with protobuf and protoc available. + aclk-version: + type: integer + description: Describes which ACLK version is currently used. + protocols-supported: + type: array + description: List of supported protocols for communication with Cloud. + items: + type: string agent-claimed: type: boolean description: Informs whether this agent has been added to a space in the cloud (User has to perform claiming). - If false (user didnt perform claiming) agent will never attempt any cloud connection. + If false (user didn't perform claiming) agent will never attempt any cloud connection. claimed_id: type: string format: uuid diff --git a/web/api/queries/README.md b/web/api/queries/README.md index 31ec49655..44cdd05b4 100644 --- a/web/api/queries/README.md +++ b/web/api/queries/README.md @@ -173,4 +173,4 @@ So, the proper way to query the database is to also set at least `after`. The fo When you keep calling this URL, you will see that it returns one new value every 10 seconds, and the timestamp always ends with zero. Similarly, if you say `points=1&after=-5` it will always return timestamps ending with 0 or 5. -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fapi%2Fqueries%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/api/queries/average/README.md b/web/api/queries/average/README.md index f32a67571..b8d4ba7e7 100644 --- a/web/api/queries/average/README.md +++ b/web/api/queries/average/README.md @@ -43,4 +43,4 @@ Examining last 1 minute `successful` web server responses: - . -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fapi%2Fqueries%2Faverage%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/api/queries/des/README.md b/web/api/queries/des/README.md index 5505de5a6..33c5f1a0c 100644 --- a/web/api/queries/des/README.md +++ b/web/api/queries/des/README.md @@ -70,4 +70,4 @@ Examining last 1 minute `successful` web server responses: - . -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fapi%2Fqueries%2Fdes%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/api/queries/incremental_sum/README.md b/web/api/queries/incremental_sum/README.md index e5f3dfc0c..44301172e 100644 --- a/web/api/queries/incremental_sum/README.md +++ b/web/api/queries/incremental_sum/README.md @@ -38,4 +38,4 @@ Examining last 1 minute `successful` web server responses: - none -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fapi%2Fqueries%2Fincremental_sum%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/api/queries/max/README.md b/web/api/queries/max/README.md index 32b1d434c..48da7cf08 100644 --- a/web/api/queries/max/README.md +++ b/web/api/queries/max/README.md @@ -35,4 +35,4 @@ Examining last 1 minute `successful` web server responses: - . -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fapi%2Fqueries%2Fmax%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/api/queries/median/README.md b/web/api/queries/median/README.md index 25ce8b8d6..bb7d4c66b 100644 --- a/web/api/queries/median/README.md +++ b/web/api/queries/median/README.md @@ -42,4 +42,4 @@ Examining last 1 minute `successful` web server responses: - . -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fapi%2Fqueries%2Fmedian%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/api/queries/min/README.md b/web/api/queries/min/README.md index 69ef4ea12..495523c04 100644 --- a/web/api/queries/min/README.md +++ b/web/api/queries/min/README.md @@ -35,4 +35,4 @@ Examining last 1 minute `successful` web server responses: - . -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fapi%2Fqueries%2Fmin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/api/queries/query.c b/web/api/queries/query.c index 216417ae8..c55a97060 100644 --- a/web/api/queries/query.c +++ b/web/api/queries/query.c @@ -347,11 +347,11 @@ static void rrdr_disable_not_selected_dimensions(RRDR *r, RRDR_OPTIONS options, // ---------------------------------------------------------------------------- // helpers to find our way in RRDR -static inline RRDR_VALUE_FLAGS *rrdr_line_options(RRDR *r, long rrdr_line) { +static inline RRDR_VALUE_FLAGS *UNUSED_FUNCTION(rrdr_line_options)(RRDR *r, long rrdr_line) { return &r->o[ rrdr_line * r->d ]; } -static inline calculated_number *rrdr_line_values(RRDR *r, long rrdr_line) { +static inline calculated_number *UNUSED_FUNCTION(rrdr_line_values)(RRDR *r, long rrdr_line) { return &r->v[ rrdr_line * r->d ]; } @@ -562,7 +562,7 @@ static inline void do_dimension_fixedstep( calculated_number min = r->min, max = r->max; size_t db_points_read = 0; time_t db_now = now; - + time_t first_time_t = rrddim_first_entry_t(rd); for(rd->state->query_ops.init(rd, &handle, now, before_wanted) ; points_added < points_wanted ; now += dt) { // make sure we return data in the proper time range if(unlikely(now > before_wanted)) { @@ -586,7 +586,11 @@ static inline void do_dimension_fixedstep( } #endif db_now = now; // this is needed to set db_now in case the next_metric implementation does not set it - storage_number n = rd->state->query_ops.next_metric(&handle, &db_now); + storage_number n; + if (rd->rrd_memory_mode != RRD_MEMORY_MODE_DBENGINE && now <= first_time_t) + n = SN_EMPTY_SLOT; + else + n = rd->state->query_ops.next_metric(&handle, &db_now); if(unlikely(db_now > before_wanted)) { #ifdef NETDATA_INTERNAL_CHECKS r->internal.log = "stopped, because attempted to access the db after 'wanted before'"; @@ -840,6 +844,7 @@ static RRDR *rrd2rrdr_fixedstep( , time_t last_entry_t , int absolute_period_requested , struct context_param *context_param_list + , int timeout ) { int aligned = !(options & RRDR_OPTION_NOT_ALIGNED); @@ -1093,6 +1098,10 @@ static RRDR *rrd2rrdr_fixedstep( RRDDIM *rd; long c, dimensions_used = 0, dimensions_nonzero = 0; + struct timeval query_start_time; + struct timeval query_current_time; + if (timeout) + now_realtime_timeval(&query_start_time); for(rd = temp_rd?temp_rd:st->dimensions, c = 0 ; rd && c < dimensions_count ; rd = rd->next, c++) { // if we need a percentage, we need to calculate all dimensions @@ -1114,6 +1123,8 @@ static RRDR *rrd2rrdr_fixedstep( , before_wanted , options ); + if (timeout) + now_realtime_timeval(&query_current_time); if(r->od[c] & RRDR_DIMENSION_NONZERO) dimensions_nonzero++; @@ -1151,6 +1162,12 @@ static RRDR *rrd2rrdr_fixedstep( } dimensions_used++; + if (timeout && (dt_usec(&query_start_time, &query_current_time) / 1000.0) > timeout) { + log_access("QUERY CANCELED RUNTIME EXCEEDED %0.2f ms (LIMIT %d ms)", + dt_usec(&query_start_time, &query_current_time) / 1000.0, timeout); + r->result_options |= RRDR_RESULT_OPTION_CANCEL; + break; + } } #ifdef NETDATA_INTERNAL_CHECKS @@ -1184,7 +1201,7 @@ static RRDR *rrd2rrdr_fixedstep( r->internal.grouping_free(r); // when all the dimensions are zero, we should return all of them - if(unlikely(options & RRDR_OPTION_NONZERO && !dimensions_nonzero)) { + if(unlikely(options & RRDR_OPTION_NONZERO && !dimensions_nonzero && !(r->result_options & RRDR_RESULT_OPTION_CANCEL))) { // all the dimensions are zero // mark them as NONZERO to send them all for(rd = temp_rd?temp_rd:st->dimensions, c = 0 ; rd && c < dimensions_count ; rd = rd->next, c++) { @@ -1213,6 +1230,7 @@ static RRDR *rrd2rrdr_variablestep( , int absolute_period_requested , struct rrdeng_region_info *region_info_array , struct context_param *context_param_list + , int timeout ) { int aligned = !(options & RRDR_OPTION_NOT_ALIGNED); @@ -1470,6 +1488,10 @@ static RRDR *rrd2rrdr_variablestep( RRDDIM *rd; long c, dimensions_used = 0, dimensions_nonzero = 0; + struct timeval query_start_time; + struct timeval query_current_time; + if (timeout) + now_realtime_timeval(&query_start_time); for(rd = temp_rd?temp_rd:st->dimensions, c = 0 ; rd && c < dimensions_count ; rd = rd->next, c++) { // if we need a percentage, we need to calculate all dimensions @@ -1491,6 +1513,8 @@ static RRDR *rrd2rrdr_variablestep( , before_wanted , options ); + if (timeout) + now_realtime_timeval(&query_current_time); if(r->od[c] & RRDR_DIMENSION_NONZERO) dimensions_nonzero++; @@ -1528,6 +1552,12 @@ static RRDR *rrd2rrdr_variablestep( } dimensions_used++; + if (timeout && (dt_usec(&query_start_time, &query_current_time) / 1000.0) > timeout) { + log_access("QUERY CANCELED RUNTIME EXCEEDED %0.2f ms (LIMIT %d ms)", + dt_usec(&query_start_time, &query_current_time) / 1000.0, timeout); + r->result_options |= RRDR_RESULT_OPTION_CANCEL; + break; + } } #ifdef NETDATA_INTERNAL_CHECKS @@ -1562,7 +1592,7 @@ static RRDR *rrd2rrdr_variablestep( r->internal.grouping_free(r); // when all the dimensions are zero, we should return all of them - if(unlikely(options & RRDR_OPTION_NONZERO && !dimensions_nonzero)) { + if(unlikely(options & RRDR_OPTION_NONZERO && !dimensions_nonzero && !(r->result_options & RRDR_RESULT_OPTION_CANCEL))) { // all the dimensions are zero // mark them as NONZERO to send them all for(rd = temp_rd?temp_rd:st->dimensions, c = 0 ; rd && c < dimensions_count ; rd = rd->next, c++) { @@ -1587,6 +1617,7 @@ RRDR *rrd2rrdr( , RRDR_OPTIONS options , const char *dimensions , struct context_param *context_param_list + , int timeout ) { int rrd_update_every; @@ -1640,7 +1671,7 @@ RRDR *rrd2rrdr( } return rrd2rrdr_fixedstep(st, points_requested, after_requested, before_requested, group_method, resampling_time_requested, options, dimensions, rrd_update_every, - first_entry_t, last_entry_t, absolute_period_requested, context_param_list); + first_entry_t, last_entry_t, absolute_period_requested, context_param_list, timeout); } else { if (rrd_update_every != (uint16_t)max_interval) { rrd_update_every = (uint16_t) max_interval; @@ -1651,11 +1682,11 @@ RRDR *rrd2rrdr( } return rrd2rrdr_variablestep(st, points_requested, after_requested, before_requested, group_method, resampling_time_requested, options, dimensions, rrd_update_every, - first_entry_t, last_entry_t, absolute_period_requested, region_info_array, context_param_list); + first_entry_t, last_entry_t, absolute_period_requested, region_info_array, context_param_list, timeout); } } #endif return rrd2rrdr_fixedstep(st, points_requested, after_requested, before_requested, group_method, resampling_time_requested, options, dimensions, - rrd_update_every, first_entry_t, last_entry_t, absolute_period_requested, context_param_list); + rrd_update_every, first_entry_t, last_entry_t, absolute_period_requested, context_param_list, timeout); } diff --git a/web/api/queries/rrdr.h b/web/api/queries/rrdr.h index 3637df687..bd94e56e2 100644 --- a/web/api/queries/rrdr.h +++ b/web/api/queries/rrdr.h @@ -47,6 +47,7 @@ typedef enum rrdr_result_flags { RRDR_RESULT_OPTION_RELATIVE = 0x00000002, // the query uses relative time-frames // (should not to be cached by browsers and proxies) RRDR_RESULT_OPTION_VARIABLE_STEP = 0x00000004, // the query uses variable-step time-frames + RRDR_RESULT_OPTION_CANCEL = 0x00000008, // the query needs to be cancelled } RRDR_RESULT_FLAGS; typedef struct rrdresult { @@ -110,7 +111,7 @@ extern RRDR *rrdr_create(struct rrdset *st, long n, struct context_param *contex extern RRDR *rrd2rrdr( RRDSET *st, long points_requested, long long after_requested, long long before_requested, RRDR_GROUPING group_method, long resampling_time_requested, RRDR_OPTIONS options, const char *dimensions, - struct context_param *context_param_list); + struct context_param *context_param_list, int timeout); #include "query.h" diff --git a/web/api/queries/ses/README.md b/web/api/queries/ses/README.md index c27970135..b835b8120 100644 --- a/web/api/queries/ses/README.md +++ b/web/api/queries/ses/README.md @@ -58,4 +58,4 @@ Examining last 1 minute `successful` web server responses: - - . -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fapi%2Fqueries%2Fses%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/api/queries/stddev/README.md b/web/api/queries/stddev/README.md index 7cd7d62af..2fca47d5e 100644 --- a/web/api/queries/stddev/README.md +++ b/web/api/queries/stddev/README.md @@ -90,4 +90,4 @@ Examining last 1 minute `successful` web server responses: Check . -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fapi%2Fqueries%2Fstddev%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/api/queries/sum/README.md b/web/api/queries/sum/README.md index aeace0a16..d4465bd82 100644 --- a/web/api/queries/sum/README.md +++ b/web/api/queries/sum/README.md @@ -38,4 +38,4 @@ Examining last 1 minute `successful` web server responses: - . -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fapi%2Fqueries%2Fsum%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/api/tests/valid_urls.c b/web/api/tests/valid_urls.c index 30ae23247..30dc29828 100644 --- a/web/api/tests/valid_urls.c +++ b/web/api/tests/valid_urls.c @@ -75,9 +75,9 @@ void __wrap_finished_web_request_statistics( char *__wrap_config_get(struct config *root, const char *section, const char *name, const char *default_value) { - if (!strcmp(section, CONFIG_SECTION_WEB) && !strcmp(name, "web files owner")) - return "netdata"; (void)root; + (void)section; + (void)name; (void)default_value; return "UNKNOWN FIX ME"; } diff --git a/web/api/tests/web_api.c b/web/api/tests/web_api.c index b96213255..df4efdabd 100644 --- a/web/api/tests/web_api.c +++ b/web/api/tests/web_api.c @@ -75,9 +75,9 @@ void __wrap_finished_web_request_statistics( char *__wrap_config_get(struct config *root, const char *section, const char *name, const char *default_value) { - if (!strcmp(section, CONFIG_SECTION_WEB) && !strcmp(name, "web files owner")) - return "netdata"; (void)root; + (void)section; + (void)name; (void)default_value; return "UNKNOWN FIX ME"; } diff --git a/web/api/web_api_v1.c b/web/api/web_api_v1.c index 6361f9970..8cf89d38d 100644 --- a/web/api/web_api_v1.c +++ b/web/api/web_api_v1.c @@ -137,16 +137,25 @@ char *get_mgmt_api_key(void) { // save it fd = open(api_key_filename, O_WRONLY|O_CREAT|O_TRUNC, 444); - if(fd == -1) - fatal("Cannot create unique management API key file '%s'. Please fix this.", api_key_filename); + if(fd == -1) { + error("Cannot create unique management API key file '%s'. Please adjust config parameter 'netdata management api key file' to a proper path and file.", api_key_filename); + goto temp_key; + } - if(write(fd, guid, GUID_LEN) != GUID_LEN) - fatal("Cannot write the unique management API key file '%s'. Please fix this.", api_key_filename); + if(write(fd, guid, GUID_LEN) != GUID_LEN) { + error("Cannot write the unique management API key file '%s'. Please adjust config parameter 'netdata management api key file' to a proper path and file with enough space left.", api_key_filename); + close(fd); + goto temp_key; + } close(fd); } return guid; + +temp_key: + info("You can still continue to use the alarm management API using the authorization token %s during this Netdata session only.", guid); + return guid; } void web_client_api_v1_management_init(void) { @@ -401,13 +410,16 @@ inline int web_client_api_request_v1_data(RRDHOST *host, struct web_client *w, c time_t last_timestamp_in_data = 0, google_timestamp = 0; - char *chart = NULL - , *before_str = NULL - , *after_str = NULL - , *group_time_str = NULL - , *points_str = NULL - , *context = NULL - , *chart_label_key = NULL; + char *chart = NULL; + char *before_str = NULL; + char *after_str = NULL; + char *group_time_str = NULL; + char *points_str = NULL; + char *timeout_str = NULL; + char *max_anomaly_rates_str = NULL; + char *context = NULL; + char *chart_label_key = NULL; + char *chart_labels_filter = NULL; int group = RRDR_GROUPING_AVERAGE; uint32_t format = DATASOURCE_JSON; @@ -428,6 +440,7 @@ inline int web_client_api_request_v1_data(RRDHOST *host, struct web_client *w, c if(!strcmp(name, "context")) context = value; else if(!strcmp(name, "chart_label_key")) chart_label_key = value; + else if(!strcmp(name, "chart_labels_filter")) chart_labels_filter = value; else if(!strcmp(name, "chart")) chart = value; else if(!strcmp(name, "dimension") || !strcmp(name, "dim") || !strcmp(name, "dimensions") || !strcmp(name, "dims")) { if(!dimensions) dimensions = buffer_create(100); @@ -437,6 +450,7 @@ inline int web_client_api_request_v1_data(RRDHOST *host, struct web_client *w, c else if(!strcmp(name, "after")) after_str = value; else if(!strcmp(name, "before")) before_str = value; else if(!strcmp(name, "points")) points_str = value; + else if(!strcmp(name, "timeout")) timeout_str = value; else if(!strcmp(name, "gtime")) group_time_str = value; else if(!strcmp(name, "group")) { group = web_client_api_request_v1_data_group(value, RRDR_GROUPING_AVERAGE); @@ -484,6 +498,9 @@ inline int web_client_api_request_v1_data(RRDHOST *host, struct web_client *w, c outFileName = tqx_value; } } + else if(!strcmp(name, "max_anomaly_rates")) { + max_anomaly_rates_str = value; + } } // validate the google parameters given @@ -507,16 +524,21 @@ inline int web_client_api_request_v1_data(RRDHOST *host, struct web_client *w, c uint32_t context_hash = simple_hash(context); rrdhost_rdlock(host); + char *words[MAX_CHART_LABELS_FILTER]; + uint32_t hash_key_list[MAX_CHART_LABELS_FILTER]; + int word_count = 0; rrdset_foreach_read(st1, host) { if (st1->hash_context == context_hash && !strcmp(st1->context, context) && - (!chart_label_key || rrdset_contains_label_keylist(st1, chart_label_key))) - build_context_param_list(&context_param_list, st1); + (!chart_label_key || rrdset_contains_label_keylist(st1, chart_label_key)) && + (!chart_labels_filter || + rrdset_matches_label_keys(st1, chart_labels_filter, words, hash_key_list, &word_count, MAX_CHART_LABELS_FILTER))) + build_context_param_list(&context_param_list, st1); } rrdhost_unlock(host); if (likely(context_param_list && context_param_list->rd)) // Just set the first one st = context_param_list->rd->rrdset; else { - if (!chart_label_key) + if (!chart_label_key && !chart_labels_filter) sql_build_context_param_list(&context_param_list, host, context, NULL); } } @@ -563,7 +585,9 @@ inline int web_client_api_request_v1_data(RRDHOST *host, struct web_client *w, c long long before = (before_str && *before_str)?str2l(before_str):0; long long after = (after_str && *after_str) ?str2l(after_str):-600; int points = (points_str && *points_str)?str2i(points_str):0; + int timeout = (timeout_str && *timeout_str)?str2i(timeout_str): 0; long group_time = (group_time_str && *group_time_str)?str2l(group_time_str):0; + int max_anomaly_rates = (max_anomaly_rates_str && *max_anomaly_rates_str) ? str2i(max_anomaly_rates_str) : 0; debug(D_WEB_CLIENT, "%llu: API command 'data' for chart '%s', dimensions '%s', after '%lld', before '%lld', points '%d', group '%d', format '%u', options '0x%08x'" , w->id @@ -606,8 +630,10 @@ inline int web_client_api_request_v1_data(RRDHOST *host, struct web_client *w, c buffer_strcat(w->response.data, "("); } - ret = rrdset2anything_api_v1(st, w->response.data, dimensions, format, points, after, before, group, group_time - , options, &last_timestamp_in_data, context_param_list, chart_label_key); + ret = rrdset2anything_api_v1(st, w->response.data, dimensions, format, + points, after, before, group, group_time, + options, &last_timestamp_in_data, context_param_list, + chart_label_key, max_anomaly_rates, timeout); free_context_param_list(&context_param_list); @@ -879,11 +905,18 @@ static inline void web_client_api_request_v1_info_mirrored_hosts(BUFFER *wb) { rrdhost_aclk_state_lock(host); if (host->aclk_state.claimed_id) - buffer_sprintf(wb, "\"%s\" }", host->aclk_state.claimed_id); + buffer_sprintf(wb, "\"%s\", ", host->aclk_state.claimed_id); else - buffer_strcat(wb, "null }"); + buffer_strcat(wb, "null, "); rrdhost_aclk_state_unlock(host); + if (host->node_id) { + char node_id_str[GUID_LEN + 1]; + uuid_unparse_lower(*host->node_id, node_id_str); + buffer_sprintf(wb, "\"node_id\": \"%s\" }", node_id_str); + } else + buffer_strcat(wb, "\"node_id\": null }"); + count++; } rrd_unlock(); @@ -968,6 +1001,13 @@ inline int web_client_api_request_v1_info_fill_buffer(RRDHOST *host, BUFFER *wb) buffer_sprintf(wb, "\t\"container\": \"%s\",\n", (host->system_info->container) ? host->system_info->container : ""); buffer_sprintf(wb, "\t\"container_detection\": \"%s\",\n", (host->system_info->container_detection) ? host->system_info->container_detection : ""); + if (host->system_info->cloud_provider_type) + buffer_sprintf(wb, "\t\"cloud_provider_type\": \"%s\",\n", host->system_info->cloud_provider_type); + if (host->system_info->cloud_instance_type) + buffer_sprintf(wb, "\t\"cloud_instance_type\": \"%s\",\n", host->system_info->cloud_instance_type); + if (host->system_info->cloud_instance_region) + buffer_sprintf(wb, "\t\"cloud_instance_region\": \"%s\",\n", host->system_info->cloud_instance_region); + buffer_strcat(wb, "\t\"host_labels\": {\n"); host_labels2json(host, wb, 2); buffer_strcat(wb, "\t},\n"); @@ -1036,11 +1076,15 @@ inline int web_client_api_request_v1_info_fill_buffer(RRDHOST *host, BUFFER *wb) buffer_strcat(wb, ",\n"); #ifdef ENABLE_COMPRESSION - buffer_strcat(wb, "\t\"stream-compression\": "); - buffer_strcat(wb, (default_compression_enabled ? "\"enabled\"" : "\"disabled\"")); - buffer_strcat(wb, ",\n"); + if(host->sender){ + buffer_strcat(wb, "\t\"stream-compression\": "); + buffer_strcat(wb, (host->sender->rrdpush_compression ? "true" : "false")); + buffer_strcat(wb, ",\n"); + }else{ + buffer_strcat(wb, "\t\"stream-compression\": null,\n"); + } #else - buffer_strcat(wb, "\t\"stream-compression\": \"N/A\",\n"); + buffer_strcat(wb, "\t\"stream-compression\": null,\n"); #endif //ENABLE_COMPRESSION buffer_strcat(wb, "\t\"hosts-available\": "); diff --git a/web/api/web_api_v1.h b/web/api/web_api_v1.h index 445b0e4a5..a88c511ad 100644 --- a/web/api/web_api_v1.h +++ b/web/api/web_api_v1.h @@ -8,6 +8,7 @@ #include "web/api/formatters/rrd2json.h" #include "web/api/health/health_cmdapi.h" +#define MAX_CHART_LABELS_FILTER (32) extern uint32_t web_client_api_request_v1_data_options(char *o); extern uint32_t web_client_api_request_v1_data_format(char *name); extern uint32_t web_client_api_request_v1_data_google_format(char *name); diff --git a/web/gui/README.md b/web/gui/README.md index 166cea7b2..69db6becb 100644 --- a/web/gui/README.md +++ b/web/gui/README.md @@ -165,5 +165,3 @@ file](https://user-images.githubusercontent.com/1153921/62798924-570e6c80-ba94-1 For information on creating custom dashboards from scratch, see the [custom dashboards](/web/gui/custom/README.md) or [Atlassian Confluence dashboards](/web/gui/confluence/README.md) guides. - -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fgui%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]() diff --git a/web/gui/confluence/README.md b/web/gui/confluence/README.md index 2e929e7d1..64dacdf38 100644 --- a/web/gui/confluence/README.md +++ b/web/gui/confluence/README.md @@ -1016,4 +1016,4 @@ NETDATA.options.current.eliminate_zero_dimensions = false;
``` -[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fgui%2Fconfluence%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) + diff --git a/web/gui/custom/README.md b/web/gui/custom/README.md index a646e4b5c..cdd5d4260 100644 --- a/web/gui/custom/README.md +++ b/web/gui/custom/README.md @@ -581,7 +581,7 @@ Negative values are rendered counter-clockwise. This is a chart that displays the hotwater temperature in the given range of 40 to 50. ```html -
netdata dashboard
You must enable JavaScript in order to use Netdata!
You can do this in your browser settings.
\ No newline at end of file + overlayEl.style = theme == 'slate' ? "background-color: #272b30; color: #373b40;" : "background-color: #fff; color: #ddd;";
\ No newline at end of file diff --git a/web/gui/dashboard/precache-manifest.34ebb83b69a8a6741865723124721c81.js b/web/gui/dashboard/precache-manifest.34ebb83b69a8a6741865723124721c81.js new file mode 100644 index 000000000..9fd751a75 --- /dev/null +++ b/web/gui/dashboard/precache-manifest.34ebb83b69a8a6741865723124721c81.js @@ -0,0 +1,190 @@ +self.__precacheManifest = (self.__precacheManifest || []).concat([ + { + "revision": "bd3599de81a6651f07aeeaf9ef2aa2e8", + "url": "./index.html" + }, + { + "revision": "b93ac7cde7cbaf1bdcad", + "url": "./static/css/2.20fd0a40.chunk.css" + }, + { + "revision": "212d45239fd5f6814421", + "url": "./static/css/4.a36e3b73.chunk.css" + }, + { + "revision": "7be982396d42269d6e7d", + "url": "./static/css/main.102ce44c.chunk.css" + }, + { + "revision": "c45bd47abb091dfda126", + "url": "./static/js/10.44d9d40b.chunk.js" + }, + { + "revision": "b93ac7cde7cbaf1bdcad", + "url": "./static/js/2.d50fa4b3.chunk.js" + }, + { + "revision": "766a5a832af1f575ad69e0e14fd2915f", + "url": "./static/js/2.d50fa4b3.chunk.js.LICENSE" + }, + { + "revision": "b7798b669b1966ed23ec", + "url": "./static/js/3.d49f0857.chunk.js" + }, + { + "revision": "212d45239fd5f6814421", + "url": "./static/js/4.8b70c754.chunk.js" + }, + { + "revision": "2555e37b8dd72102b21e", + "url": "./static/js/5.29dab1cd.chunk.js" + }, + { + "revision": "f05f27d89effd681fe0717b6a67b9a0d", + "url": "./static/js/5.29dab1cd.chunk.js.LICENSE" + }, + { + "revision": "a20d9477721b5236a011", + "url": "./static/js/6.7b15cdf3.chunk.js" + }, + { + "revision": "58e2d9966bc46cb2f6e7", + "url": "./static/js/7.cf6bc66f.chunk.js" + }, + { + "revision": "f58cbc2f5fd752800e1c", + "url": "./static/js/8.b1a4b595.chunk.js" + }, + { + "revision": "74e97210cbd08c0b3ff1", + "url": "./static/js/9.50358509.chunk.js" + }, + { + "revision": "7be982396d42269d6e7d", + "url": "./static/js/main.485cc284.chunk.js" + }, + { + "revision": "19356475904bddb45614eb6ff7f6cd44", + "url": "./static/js/main.485cc284.chunk.js.LICENSE" + }, + { + "revision": "904a84c9f2c6baa9dabe", + "url": "./static/js/runtime-main.b352aa47.js" + }, + { + "revision": "245539db8ee56425757ef728eda8194e", + "url": "./static/media/ibm-plex-sans-latin-100.245539db.woff2" + }, + { + "revision": "9a582f3a304f421eca4027517706843c", + "url": "./static/media/ibm-plex-sans-latin-100.9a582f3a.woff" + }, + { + "revision": "1ea7c5d21b5956b602bdf9656cfb353f", + "url": "./static/media/ibm-plex-sans-latin-100italic.1ea7c5d2.woff" + }, + { + "revision": "3c34cf080b38f5fb1d4c59ffa45b3967", + "url": "./static/media/ibm-plex-sans-latin-100italic.3c34cf08.woff2" + }, + { + "revision": "67524c36348a323f78f2845e3aafc2d4", + "url": "./static/media/ibm-plex-sans-latin-200.67524c36.woff" + }, + { + "revision": "bf72c8412ab06c393f52efc5beb26ea7", + "url": "./static/media/ibm-plex-sans-latin-200.bf72c841.woff2" + }, + { + "revision": "52df25607ec284ca361ae50ba24b3580", + "url": "./static/media/ibm-plex-sans-latin-200italic.52df2560.woff" + }, + { + "revision": "bbc2d55223638ce450424a917e1104b2", + "url": "./static/media/ibm-plex-sans-latin-200italic.bbc2d552.woff2" + }, + { + "revision": "10bb6a0ae6dc8000d999ab622a45e281", + "url": "./static/media/ibm-plex-sans-latin-300.10bb6a0a.woff" + }, + { + "revision": "9e1c48af24191f6ea8aede14957c5d01", + "url": "./static/media/ibm-plex-sans-latin-300.9e1c48af.woff2" + }, + { + "revision": "c76f2ab53673e964b6e6734c1c455761", + "url": "./static/media/ibm-plex-sans-latin-300italic.c76f2ab5.woff2" + }, + { + "revision": "d3566d5bb4f31d86bfb9fda09563b416", + "url": "./static/media/ibm-plex-sans-latin-300italic.d3566d5b.woff" + }, + { + "revision": "263d6267533501f58c33b12b382e3abb", + "url": "./static/media/ibm-plex-sans-latin-400.263d6267.woff2" + }, + { + "revision": "a2c56f946488a9a267ba6ba21471a217", + "url": "./static/media/ibm-plex-sans-latin-400.a2c56f94.woff" + }, + { + "revision": "272f86114c980c52c131dfc3b4ae3276", + "url": "./static/media/ibm-plex-sans-latin-400italic.272f8611.woff" + }, + { + "revision": "89a93a1bdde48c7bb104150de88affce", + "url": "./static/media/ibm-plex-sans-latin-400italic.89a93a1b.woff2" + }, + { + "revision": "0866c24487514ad726738fb24f8e015b", + "url": "./static/media/ibm-plex-sans-latin-500.0866c244.woff2" + }, + { + "revision": "f6d5c5d5b849796d6a8f5a2953b60753", + "url": "./static/media/ibm-plex-sans-latin-500.f6d5c5d5.woff" + }, + { + "revision": "ccd41bd1a5bfa8bad2cd8d35fdaeb3d1", + "url": "./static/media/ibm-plex-sans-latin-500italic.ccd41bd1.woff" + }, + { + "revision": "ffd12d59339823b8cf53b9f99b47d87c", + "url": "./static/media/ibm-plex-sans-latin-500italic.ffd12d59.woff2" + }, + { + "revision": "337b16517a230dc830b84dc6e6167b68", + "url": "./static/media/ibm-plex-sans-latin-600.337b1651.woff" + }, + { + "revision": "7852d4dc26ef44df58e23dc0b9722d6f", + "url": "./static/media/ibm-plex-sans-latin-600.7852d4dc.woff2" + }, + { + "revision": "17e5379fd9a99b9bcb26ea983f391b6a", + "url": "./static/media/ibm-plex-sans-latin-600italic.17e5379f.woff2" + }, + { + "revision": "6f4ba6aa87fa99d5bc2b90a7b40a0ded", + "url": "./static/media/ibm-plex-sans-latin-600italic.6f4ba6aa.woff" + }, + { + "revision": "b8809d619a33eb825b0450281ff752e7", + "url": "./static/media/ibm-plex-sans-latin-700.b8809d61.woff" + }, + { + "revision": "c9983d3d04f3ed6c2eafee1db1d24e06", + "url": "./static/media/ibm-plex-sans-latin-700.c9983d3d.woff2" + }, + { + "revision": "02954beec9e742bb1f3ae27b7e7cb71f", + "url": "./static/media/ibm-plex-sans-latin-700italic.02954bee.woff2" + }, + { + "revision": "72e9af409ddafc63a5dd380e34758560", + "url": "./static/media/ibm-plex-sans-latin-700italic.72e9af40.woff" + }, + { + "revision": "0509ab09c1b0d2200a4135803c91d6ce", + "url": "./static/media/material-icons.0509ab09.woff2" + } +]); \ No newline at end of file diff --git a/web/gui/dashboard/precache-manifest.55bf0765e4092267255469aff90b2f26.js b/web/gui/dashboard/precache-manifest.55bf0765e4092267255469aff90b2f26.js deleted file mode 100644 index 09100ddee..000000000 --- a/web/gui/dashboard/precache-manifest.55bf0765e4092267255469aff90b2f26.js +++ /dev/null @@ -1,190 +0,0 @@ -self.__precacheManifest = (self.__precacheManifest || []).concat([ - { - "revision": "54d95957cab6b9e0ff62227e819144b1", - "url": "./index.html" - }, - { - "revision": "b14737814eaaac8a593c", - "url": "./static/css/2.20fd0a40.chunk.css" - }, - { - "revision": "6b4b3bf9ec6775a71c1a", - "url": "./static/css/4.a36e3b73.chunk.css" - }, - { - "revision": "930ba58fe8daebf2abf9", - "url": "./static/css/main.a46a34fa.chunk.css" - }, - { - "revision": "7440db77cd4ae70414ee", - "url": "./static/js/10.eb10af4d.chunk.js" - }, - { - "revision": "b14737814eaaac8a593c", - "url": "./static/js/2.da522cd4.chunk.js" - }, - { - "revision": "766a5a832af1f575ad69e0e14fd2915f", - "url": "./static/js/2.da522cd4.chunk.js.LICENSE" - }, - { - "revision": "31d497d4814a0565baae", - "url": "./static/js/3.6267b47a.chunk.js" - }, - { - "revision": "6b4b3bf9ec6775a71c1a", - "url": "./static/js/4.89bcbd92.chunk.js" - }, - { - "revision": "2fa0b37b461863582a83", - "url": "./static/js/5.8d493428.chunk.js" - }, - { - "revision": "f05f27d89effd681fe0717b6a67b9a0d", - "url": "./static/js/5.8d493428.chunk.js.LICENSE" - }, - { - "revision": "595abde79fe8158f3a88", - "url": "./static/js/6.fd3732fc.chunk.js" - }, - { - "revision": "43643e72f8b26270af68", - "url": "./static/js/7.c4cdb9f0.chunk.js" - }, - { - "revision": "b081d8788885e9b02059", - "url": "./static/js/8.11ff05e7.chunk.js" - }, - { - "revision": "ab768f6bbd490cb3ab14", - "url": "./static/js/9.84b7c771.chunk.js" - }, - { - "revision": "930ba58fe8daebf2abf9", - "url": "./static/js/main.e3f3d31b.chunk.js" - }, - { - "revision": "19356475904bddb45614eb6ff7f6cd44", - "url": "./static/js/main.e3f3d31b.chunk.js.LICENSE" - }, - { - "revision": "e0bde152f66fb47d9483", - "url": "./static/js/runtime-main.ec4d2459.js" - }, - { - "revision": "245539db8ee56425757ef728eda8194e", - "url": "./static/media/ibm-plex-sans-latin-100.245539db.woff2" - }, - { - "revision": "9a582f3a304f421eca4027517706843c", - "url": "./static/media/ibm-plex-sans-latin-100.9a582f3a.woff" - }, - { - "revision": "1ea7c5d21b5956b602bdf9656cfb353f", - "url": "./static/media/ibm-plex-sans-latin-100italic.1ea7c5d2.woff" - }, - { - "revision": "3c34cf080b38f5fb1d4c59ffa45b3967", - "url": "./static/media/ibm-plex-sans-latin-100italic.3c34cf08.woff2" - }, - { - "revision": "67524c36348a323f78f2845e3aafc2d4", - "url": "./static/media/ibm-plex-sans-latin-200.67524c36.woff" - }, - { - "revision": "bf72c8412ab06c393f52efc5beb26ea7", - "url": "./static/media/ibm-plex-sans-latin-200.bf72c841.woff2" - }, - { - "revision": "52df25607ec284ca361ae50ba24b3580", - "url": "./static/media/ibm-plex-sans-latin-200italic.52df2560.woff" - }, - { - "revision": "bbc2d55223638ce450424a917e1104b2", - "url": "./static/media/ibm-plex-sans-latin-200italic.bbc2d552.woff2" - }, - { - "revision": "10bb6a0ae6dc8000d999ab622a45e281", - "url": "./static/media/ibm-plex-sans-latin-300.10bb6a0a.woff" - }, - { - "revision": "9e1c48af24191f6ea8aede14957c5d01", - "url": "./static/media/ibm-plex-sans-latin-300.9e1c48af.woff2" - }, - { - "revision": "c76f2ab53673e964b6e6734c1c455761", - "url": "./static/media/ibm-plex-sans-latin-300italic.c76f2ab5.woff2" - }, - { - "revision": "d3566d5bb4f31d86bfb9fda09563b416", - "url": "./static/media/ibm-plex-sans-latin-300italic.d3566d5b.woff" - }, - { - "revision": "263d6267533501f58c33b12b382e3abb", - "url": "./static/media/ibm-plex-sans-latin-400.263d6267.woff2" - }, - { - "revision": "a2c56f946488a9a267ba6ba21471a217", - "url": "./static/media/ibm-plex-sans-latin-400.a2c56f94.woff" - }, - { - "revision": "272f86114c980c52c131dfc3b4ae3276", - "url": "./static/media/ibm-plex-sans-latin-400italic.272f8611.woff" - }, - { - "revision": "89a93a1bdde48c7bb104150de88affce", - "url": "./static/media/ibm-plex-sans-latin-400italic.89a93a1b.woff2" - }, - { - "revision": "0866c24487514ad726738fb24f8e015b", - "url": "./static/media/ibm-plex-sans-latin-500.0866c244.woff2" - }, - { - "revision": "f6d5c5d5b849796d6a8f5a2953b60753", - "url": "./static/media/ibm-plex-sans-latin-500.f6d5c5d5.woff" - }, - { - "revision": "ccd41bd1a5bfa8bad2cd8d35fdaeb3d1", - "url": "./static/media/ibm-plex-sans-latin-500italic.ccd41bd1.woff" - }, - { - "revision": "ffd12d59339823b8cf53b9f99b47d87c", - "url": "./static/media/ibm-plex-sans-latin-500italic.ffd12d59.woff2" - }, - { - "revision": "337b16517a230dc830b84dc6e6167b68", - "url": "./static/media/ibm-plex-sans-latin-600.337b1651.woff" - }, - { - "revision": "7852d4dc26ef44df58e23dc0b9722d6f", - "url": "./static/media/ibm-plex-sans-latin-600.7852d4dc.woff2" - }, - { - "revision": "17e5379fd9a99b9bcb26ea983f391b6a", - "url": "./static/media/ibm-plex-sans-latin-600italic.17e5379f.woff2" - }, - { - "revision": "6f4ba6aa87fa99d5bc2b90a7b40a0ded", - "url": "./static/media/ibm-plex-sans-latin-600italic.6f4ba6aa.woff" - }, - { - "revision": "b8809d619a33eb825b0450281ff752e7", - "url": "./static/media/ibm-plex-sans-latin-700.b8809d61.woff" - }, - { - "revision": "c9983d3d04f3ed6c2eafee1db1d24e06", - "url": "./static/media/ibm-plex-sans-latin-700.c9983d3d.woff2" - }, - { - "revision": "02954beec9e742bb1f3ae27b7e7cb71f", - "url": "./static/media/ibm-plex-sans-latin-700italic.02954bee.woff2" - }, - { - "revision": "72e9af409ddafc63a5dd380e34758560", - "url": "./static/media/ibm-plex-sans-latin-700italic.72e9af40.woff" - }, - { - "revision": "0509ab09c1b0d2200a4135803c91d6ce", - "url": "./static/media/material-icons.0509ab09.woff2" - } -]); \ No newline at end of file diff --git a/web/gui/dashboard/service-worker.js b/web/gui/dashboard/service-worker.js index 66f1940cf..fd23f1a17 100644 --- a/web/gui/dashboard/service-worker.js +++ b/web/gui/dashboard/service-worker.js @@ -14,7 +14,7 @@ importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js"); importScripts( - "./precache-manifest.55bf0765e4092267255469aff90b2f26.js" + "./precache-manifest.34ebb83b69a8a6741865723124721c81.js" ); self.addEventListener('message', (event) => { diff --git a/web/gui/dashboard/static/css/main.102ce44c.chunk.css b/web/gui/dashboard/static/css/main.102ce44c.chunk.css new file mode 100644 index 000000000..ae00a0e22 --- /dev/null +++ b/web/gui/dashboard/static/css/main.102ce44c.chunk.css @@ -0,0 +1,2 @@ +.netdata-reset-button{padding:0;border:none;font:inherit;background-color:transparent;cursor:pointer}.netdata-reset-button:focus{outline:none}.netdata-reset-button::-moz-focus-inner{border:none}html{overflow-y:hidden;font-size:16px!important}body{padding-top:50px}.navbar-highlight{display:none;position:fixed;margin-top:10px;height:26px;width:100%;text-align:center;overflow:hidden;z-index:30;pointer-events:none!important}.navbar-highlight-content{position:relative;display:inline-block;margin:0 auto;height:26px;min-width:500px;background-color:rgba(0,0,0,.7);padding:2px 15px;border-radius:10px;color:#d3d3d3;pointer-events:auto!important}.navbar-highlight-bar{cursor:pointer}.navbar-highlight-button-right{cursor:pointer;padding-left:10px}.modal-wide .modal-dialog{width:80%}h1{z-index:-1}h1,h2{position:relative}h2{z-index:-2}h1:before,h2:before{display:block;content:" ";margin-top:-70px;height:70px;visibility:hidden}.p{display:block;margin-top:15px}.option-control,.option-row{vertical-align:top;padding:30px 10px 10px 30px}.option-info{padding:10px}.dashboard-context-info,.dashboard-submenu-info{display:block;margin-top:10px}.dashboard-context-info{color:#878b90;color:var(--color-border,#878b90)}.dashboard-context-info a{color:#00ab44;color:var(--color-primary,#00ab44)}#masthead h1{line-height:1;padding-top:30px}#masthead .well{margin-top:4%}body.modal-open{width:100%!important;padding-right:0!important;overflow:visible}.panel-title a{display:block;padding:10px 15px;margin:-10px -15px}.affix{position:static}.sidebar-body{margin-top:0}.dashboard-sidebar{max-height:calc(100% - 24px)!important;overflow-y:auto}.dashboard-sidebar.affix{position:static}.dashboard-sidenav{margin-top:20px;margin-bottom:20px}.dashboard-sidenav.affix{position:static}.dashboard-sidebar .nav>li>a{display:block;padding:4px 8px;font-size:13px;font-weight:500;color:#767676}.dashboard-sidebar .nav>li>.nav>li>a{padding:2px 12px}.dashboard-sidebar .nav>li>a>.svg-inline--fa{width:20px;text-align:center}.dashboard-sidebar .nav>li>a:focus,.dashboard-sidebar .nav>li>a:hover{padding-left:7px;color:#563d7c;text-decoration:none;background-color:transparent;border-left:1px solid #563d7c}.dashboard-sidebar .nav>.active:focus>a,.dashboard-sidebar .nav>.active:hover>a,.dashboard-sidebar .nav>.active>a{padding-left:6px;font-weight:700;color:#563d7c;background-color:transparent;border-left:2px solid #563d7c}.dashboard-sidebar .nav .nav{display:none;padding-bottom:10px}.dashboard-sidebar .nav .nav>li>a{padding-top:1px;padding-bottom:1px;font-size:12px;font-weight:400}.dashboard-sidebar .nav .nav>li>a:focus,.dashboard-sidebar .nav .nav>li>a:hover{padding-left:11px}.dashboard-sidebar .nav .nav>.active:focus>a,.dashboard-sidebar .nav .nav>.active:hover>a,.dashboard-sidebar .nav .nav>.active>a{padding-left:6px;font-weight:500}.multi-column-dropdown{list-style:none;padding:0}.multi-column-dropdown li a{display:inline-block;clear:both;line-height:1.428571429;white-space:normal}.multi-column-dropdown li a:hover{text-decoration:none;color:#f5f5f5;background-color:#262626}.scrollable-menu-50{height:auto;max-height:50vh;overflow-x:hidden}.container{width:calc(100% - 20px)!important}.charts-body{display:inline-block;width:100%}.sidebar-body{position:absolute;display:none;height:100vh}.terms-and-privacy a{color:inherit;text-decoration:underline;display:block}.dashboard-section-container{page-break-inside:auto}.dashboard-print-row,.dashboard-section-container{display:block;width:100%;page-break-before:auto;page-break-after:auto}.dashboard-print-row{page-break-inside:avoid}.netdata-chartblock-container{display:inline-block}.tooltip{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.action-button{position:relative;display:inline-block;color:grey;cursor:pointer;margin:0 auto;width:30px;height:30px;font-size:25px}.ripple{position:relative;-webkit-transform:translateZ(0);transform:translateZ(0)}.ripple:after{content:"";display:block;position:absolute;width:100%;height:100%;top:0;left:0;pointer-events:none;background-image:radial-gradient(circle,#000 10%,transparent 10.01%);background-repeat:no-repeat;background-position:50%;-webkit-transform:scale(18);transform:scale(18);opacity:0;-webkit-transition:opacity 1s,-webkit-transform .5s;transition:opacity 1s,-webkit-transform .5s;transition:transform .5s,opacity 1s;transition:transform .5s,opacity 1s,-webkit-transform .5s}.ripple:active:after{-webkit-transform:scale(0);transform:scale(0);opacity:.2;-webkit-transition:0s;transition:0s}#alarms_log_table tbody tr{cursor:pointer}.agent-item--separated{border-top:1px solid #333}.agent-item--alternate a{color:#999}#sign-in-iframe{background-color:#fff;border:none}.filter-control{position:relative}.sign-in-btn{background-color:#1e2126}.sign-in-btn.theme-white{background-color:#e6e6e6}.sign-in-btn.theme-white span{color:#000}.beta{color:#fc0}@media (min-width:1360px){.container{padding-left:3%!important}.charts-body{width:calc(100% - 263px)!important;padding-left:1%!important;padding-right:2%!important}.sidebar-body{display:inline-block!important}.dashboard-sidebar.affix,.dashboard-sidebar.affix-bottom,.dashboard-sidebar.affix-top,.sidebar-body{width:263px!important}}@media (min-width:1200px){.container{padding-left:2%!important}.charts-body{width:calc(100% - 233px)!important;padding-left:1%!important;padding-right:1%!important}.sidebar-body{display:inline-block!important}.dashboard-sidebar.affix,.dashboard-sidebar.affix-bottom,.dashboard-sidebar.affix-top,.sidebar-body{width:233px!important}}@media (min-width:992px){.container{padding-left:0!important}.charts-body{width:calc(100% - 213px)!important;padding-left:1%!important;padding-right:0!important}.sidebar-body{display:inline-block!important;width:213px!important}.dashboard-sidebar .nav>.active>ul{display:block}.dashboard-sidebar.affix,.dashboard-sidebar.affix-bottom,.dashboard-sidebar.affix-top{width:213px!important}.dashboard-sidebar.affix{position:fixed}.dashboard-sidebar.affix-bottom{position:absolute}}@media (min-width:860px){.dashboard-sidebar{padding-left:20px}}@media (min-width:768px){.dashboard-sidebar{padding-left:20px}.charts-body{padding-left:0;padding-right:0}}@media print{body{overflow:visible!important;-webkit-print-color-adjust:exact}.dashboard-section,body{page-break-inside:auto;page-break-before:auto;page-break-after:auto}.dashboard-subsection{page-break-before:avoid}.charts-body,.dashboard-subsection{page-break-after:auto;page-break-inside:auto}.charts-body{padding-left:0;padding-right:0;display:block;page-break-before:auto}}#ssoifrm{display:none}@font-face{font-family:Material Icons;font-style:normal;font-weight:400;src:url(../../static/media/material-icons.0509ab09.woff2) format("woff2")}.material-icons{font-family:Material Icons;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-feature-settings:"liga";-webkit-font-smoothing:antialiased}.dygraph-chart__labels-hidden{display:none}.chart-container__loader{position:absolute}.print-modal__close-button--disabled{pointer-events:none}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;padding-left:74px;-webkit-transition:padding-left .2s ease-out;transition:padding-left .2s ease-out}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}@media (min-width:1200px){.with-panel{padding-left:372px}} +/*# sourceMappingURL=main.102ce44c.chunk.css.map */ \ No newline at end of file diff --git a/web/gui/dashboard/static/css/main.102ce44c.chunk.css.map b/web/gui/dashboard/static/css/main.102ce44c.chunk.css.map new file mode 100644 index 000000000..fef4c77ed --- /dev/null +++ b/web/gui/dashboard/static/css/main.102ce44c.chunk.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["button.css","main.css","fonts.css","dygraph-chart.css","chart-with-loader.css","print-modal.scss","index.css"],"names":[],"mappings":"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","file":"main.102ce44c.chunk.css","sourcesContent":[".netdata-reset-button {\n padding: 0;\n border: none;\n font: inherit;\n /*color: inherit;*/\n background-color: transparent;\n /* show a hand cursor on hover; some argue that we\n should keep the default arrow cursor for buttons */\n cursor: pointer;\n}\n\n.netdata-reset-button:focus {\n outline: none;\n}\n\n/* Firefox: remove the inner border shown on focus */\n.netdata-reset-button::-moz-focus-inner {\n border: none;\n}\n","/* force the vertical window scrollbar */\nhtml {\n overflow-y: hidden;\n font-size: 16px !important; /* To override nasty bootstrap.css default! */\n}\n\n/* prevent body from hiding under the navbar */\nbody {\n padding-top: 50px;\n}\n\n.navbar-highlight {\n display: none;\n position: fixed;\n margin-top: 10px;\n height: 26px;\n width: 100%;\n text-align: center;\n overflow: hidden;\n z-index: 30;\n pointer-events: none !important;\n}\n\n.navbar-highlight-content {\n position: relative;\n display: inline-block;\n margin: 0 auto;\n height: 26px;\n min-width: 500px;\n background-color: rgba(0, 0, 0, 0.7);\n padding-top: 2px;\n padding-bottom: 2px;\n padding-left: 15px;\n padding-right: 15px;\n border-radius: 10px;\n color: lightgrey;\n pointer-events: auto !important;\n}\n\n.navbar-highlight-bar {\n cursor: pointer;\n}\n\n.navbar-highlight-button-right {\n cursor: pointer;\n padding-left: 10px;\n}\n\n.modal-wide .modal-dialog {\n width: 80%;\n}\n\n/* fix # anchors scrolling under the navbar\n https://github.com/twbs/bootstrap/issues/1768#issuecomment-46519033\n */\nh1 {\n position: relative;\n z-index: -1;\n}\n\nh2 {\n position: relative;\n z-index: -2;\n}\n\nh1:before,\nh2:before {\n display: block;\n content: \" \";\n margin-top: -70px;\n height: 70px;\n visibility: hidden;\n}\n\n.p {\n display: block;\n margin-top: 15px;\n}\n\n.option-row,\n.option-control {\n vertical-align: top;\n padding: 10px;\n padding-top: 30px;\n padding-left: 30px;\n}\n\n.option-info {\n padding: 10px;\n}\n\n.dashboard-submenu-info {\n display: block;\n margin-top: 10px;\n}\n\n.dashboard-context-info {\n display: block;\n margin-top: 10px;\n color: var(--color-border, #878b90);\n}\n\n.dashboard-context-info a {\n color: var(--color-primary, #00ab44);\n}\n\n#masthead h1 {\n /*font-size: 30px;*/\n line-height: 1;\n padding-top: 30px;\n}\n\n#masthead .well {\n margin-top: 4%;\n}\n\n/* fix the navbar shifting when a modal is open */\n/* https://github.com/twbs/bootstrap/issues/14040#issuecomment-159891033 */\nbody.modal-open {\n width: 100% !important;\n padding-right: 0 !important;\n /* overflow-y: scroll !important; */\n /* position: fixed !important;*/\n overflow: visible;\n}\n\n/* make accordion use the whole header bar for expand/collapse */\n.panel-title a {\n display: block;\n padding: 10px 15px;\n margin: -10px -15px;\n}\n\n/*\n * Side navigation\n *\n * Scrollspy and affixed enhanced navigation to highlight sections and secondary\n * sections of docs content.\n */\n\n.affix {\n position: static;\n /* top: 140px !important; */\n /*width: 220px;*/\n}\n\n.sidebar-body {\n margin-top: 0;\n}\n\n.dashboard-sidebar {\n max-height: calc(100% - 24px) !important;\n overflow-y: auto;\n /*width: 220px !important;*/\n}\n\n/* By default it's not affixed in mobile views, so undo that */\n.dashboard-sidebar.affix {\n position: static;\n}\n\n/* First level of nav */\n.dashboard-sidenav {\n margin-top: 20px;\n margin-bottom: 20px;\n}\n\n.dashboard-sidenav.affix {\n position: static;\n}\n\n/* All levels of nav */\n.dashboard-sidebar .nav > li > a {\n display: block;\n padding: 4px 8px;\n font-size: 13px;\n font-weight: 500;\n color: #767676;\n}\n\n.dashboard-sidebar .nav > li > .nav > li > a {\n padding: 2px 12px;\n}\n\n.dashboard-sidebar .nav > li > a > .svg-inline--fa {\n width: 20px;\n text-align: center;\n}\n\n.dashboard-sidebar .nav > li > a:hover,\n.dashboard-sidebar .nav > li > a:focus {\n padding-left: 7px;\n color: #563d7c;\n text-decoration: none;\n background-color: transparent;\n border-left: 1px solid #563d7c;\n}\n\n.dashboard-sidebar .nav > .active > a,\n.dashboard-sidebar .nav > .active:hover > a,\n.dashboard-sidebar .nav > .active:focus > a {\n padding-left: 6px;\n font-weight: bold;\n color: #563d7c;\n background-color: transparent;\n border-left: 2px solid #563d7c;\n}\n\n/* Nav: second level (shown on .active) */\n.dashboard-sidebar .nav .nav {\n display: none; /* Hide by default, but at >768px, show it */\n padding-bottom: 10px;\n}\n\n.dashboard-sidebar .nav .nav > li > a {\n padding-top: 1px;\n padding-bottom: 1px;\n font-size: 12px;\n font-weight: normal;\n}\n\n.dashboard-sidebar .nav .nav > li > a:hover,\n.dashboard-sidebar .nav .nav > li > a:focus {\n padding-left: 11px;\n}\n\n.dashboard-sidebar .nav .nav > .active > a,\n.dashboard-sidebar .nav .nav > .active:hover > a,\n.dashboard-sidebar .nav .nav > .active:focus > a {\n padding-left: 6px;\n font-weight: 500;\n}\n\n.multi-column-dropdown {\n list-style: none;\n padding: 0;\n}\n\n.multi-column-dropdown li a {\n display: inline-block;\n clear: both;\n line-height: 1.428571429;\n white-space: normal;\n}\n\n.multi-column-dropdown li a:hover {\n text-decoration: none;\n color: #f5f5f5;\n background-color: #262626;\n}\n\n.scrollable-menu-50 {\n height: auto;\n max-height: 50vh;\n overflow-x: hidden;\n}\n\n.container {\n width: calc(100% - 20px) !important;\n}\n\n.charts-body {\n display: inline-block;\n width: 100%;\n}\n\n.sidebar-body {\n position: absolute;\n display: none;\n height: 100vh;\n}\n\n.terms-and-privacy a {\n color: inherit;\n text-decoration: underline;\n display: block;\n}\n\n.dashboard-section-container {\n display: block;\n width: 100%;\n page-break-before: auto;\n page-break-after: auto;\n page-break-inside: auto;\n}\n\n.dashboard-print-row {\n display: block;\n width: 100%;\n page-break-before: auto;\n page-break-after: auto;\n page-break-inside: avoid;\n}\n\n.netdata-chartblock-container {\n display: inline-block;\n}\n\n/* https://github.com/seiyria/bootstrap-slider/issues/746 */\n.tooltip {\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.action-button {\n position: relative;\n display: inline-block;\n color: gray;\n cursor: pointer;\n margin: 0 auto;\n width: 30px;\n height: 30px;\n font-size: 25px;\n}\n\n.ripple {\n position: relative;\n /*overflow: hidden;*/\n transform: translate3d(0, 0, 0);\n}\n\n.ripple:after {\n content: \"\";\n display: block;\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n pointer-events: none;\n background-image: radial-gradient(circle, #000 10%, transparent 10.01%);\n background-repeat: no-repeat;\n background-position: 50%;\n transform: scale(18, 18); /* the size of the ripple */\n opacity: 0;\n transition: transform 0.5s, opacity 1s;\n}\n\n.ripple:active:after {\n transform: scale(0, 0);\n opacity: 0.2;\n transition: 0s;\n}\n\n/* -------------------------------------------------------------------------- */\n\n#alarms_log_table tbody tr {\n cursor: pointer;\n}\n\n.agent-item--separated {\n border-top: 1px solid #333;\n}\n\n.agent-item--alternate a {\n color: #999;\n}\n\n/* white theme overrides */\n\n#sign-in-iframe {\n background-color: #fff;\n border: none;\n}\n\n.filter-control {\n position: relative;\n}\n\n.sign-in-btn {\n background-color: #1e2126;\n}\n\n.sign-in-btn.theme-white {\n background-color: #e6e6e6;\n}\n\n.sign-in-btn.theme-white span {\n color: #000;\n}\n\n.beta {\n color: #ffcc00;\n}\n\n@media (min-width: 1360px) {\n .container {\n padding-left: 3% !important;\n }\n\n .charts-body {\n width: calc(100% - 263px) !important;\n padding-left: 1% !important;\n padding-right: 2% !important;\n }\n\n .sidebar-body {\n display: inline-block !important;\n width: 263px !important;\n }\n\n /* Widen the fixed sidebar again */\n .dashboard-sidebar.affix,\n .dashboard-sidebar.affix-top,\n .dashboard-sidebar.affix-bottom {\n width: 263px !important;\n }\n}\n\n@media (min-width: 1200px) {\n .container {\n padding-left: 2% !important;\n }\n\n .charts-body {\n width: calc(100% - 233px) !important;\n padding-left: 1% !important;\n padding-right: 1% !important;\n }\n\n .sidebar-body {\n display: inline-block !important;\n width: 233px !important;\n }\n\n /* Widen the fixed sidebar again */\n .dashboard-sidebar.affix,\n .dashboard-sidebar.affix-top,\n .dashboard-sidebar.affix-bottom {\n width: 233px !important;\n }\n}\n\n@media (min-width: 992px) {\n .container {\n padding-left: 0% !important;\n }\n\n .charts-body {\n width: calc(100% - 213px) !important;\n padding-left: 1% !important;\n padding-right: 0% !important;\n }\n\n .sidebar-body {\n display: inline-block !important;\n width: 213px !important;\n }\n\n .dashboard-sidebar .nav > .active > ul {\n display: block;\n }\n\n /* Widen the fixed sidebar */\n .dashboard-sidebar.affix,\n .dashboard-sidebar.affix-top,\n .dashboard-sidebar.affix-bottom {\n width: 213px !important;\n }\n\n .dashboard-sidebar.affix {\n position: fixed; /* Undo the static from mobile first approach */\n /* top: 20px; */\n }\n\n .dashboard-sidebar.affix-bottom {\n position: absolute; /* Undo the static from mobile first approach */\n }\n}\n\n@media (min-width: 860px) {\n .dashboard-sidebar {\n padding-left: 20px;\n }\n}\n\n@media (min-width: 768px) {\n .dashboard-sidebar {\n padding-left: 20px;\n }\n\n .charts-body {\n padding-left: 0%;\n padding-right: 0%;\n }\n}\n\n@media print {\n body {\n overflow: visible !important;\n -webkit-print-color-adjust: exact;\n page-break-inside: auto;\n page-break-before: auto;\n page-break-after: auto;\n }\n\n .dashboard-section {\n page-break-inside: auto;\n page-break-before: auto;\n page-break-after: auto;\n }\n\n .dashboard-subsection {\n page-break-before: avoid;\n page-break-after: auto;\n page-break-inside: auto;\n }\n\n .charts-body {\n padding-left: 0%;\n padding-right: 0%;\n display: block;\n page-break-inside: auto;\n page-break-before: auto;\n page-break-after: auto;\n }\n}\n\n#ssoifrm {\n display: none;\n}\n","/* fallback */\n@font-face {\n font-family: 'Material Icons';\n font-style: normal;\n font-weight: 400;\n src: url(\"../fonts/material-icons.woff2\") format('woff2');\n}\n\n.material-icons {\n font-family: 'Material Icons';\n font-weight: normal;\n font-style: normal;\n font-size: 24px;\n line-height: 1;\n letter-spacing: normal;\n text-transform: none;\n display: inline-block;\n white-space: nowrap;\n word-wrap: normal;\n direction: ltr;\n -webkit-font-feature-settings: 'liga';\n -webkit-font-smoothing: antialiased;\n}\n",".dygraph-chart__labels-hidden {\n display: none;\n}\n",".chart-container__loader {\n /* absolute, because to create GaugeChart the height of container is calculated during loading of data\n and loader cannot have any impact on chart size\n */\n position: absolute;\n}\n",".print-modal {\n &__close-button {\n &--disabled {\n pointer-events: none;\n }\n }\n}\n","body {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\", \"Ubuntu\",\n \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n padding-left: 74px;\n transition: padding-left 0.2s ease-out;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\n\n@media (min-width: 1200px) {\n .with-panel {\n padding-left: 372px;\n }\n}\n"]} \ No newline at end of file diff --git a/web/gui/dashboard/static/css/main.a46a34fa.chunk.css b/web/gui/dashboard/static/css/main.a46a34fa.chunk.css deleted file mode 100644 index 7cbb483e1..000000000 --- a/web/gui/dashboard/static/css/main.a46a34fa.chunk.css +++ /dev/null @@ -1,2 +0,0 @@ -.netdata-reset-button{padding:0;border:none;font:inherit;background-color:transparent;cursor:pointer}.netdata-reset-button:focus{outline:none}.netdata-reset-button::-moz-focus-inner{border:none}html{overflow-y:hidden;font-size:16px!important}body{padding-top:50px}.navbar-highlight{display:none;position:fixed;margin-top:10px;height:26px;width:100%;text-align:center;overflow:hidden;z-index:30;pointer-events:none!important}.navbar-highlight-content{position:relative;display:inline-block;margin:0 auto;height:26px;min-width:500px;background-color:rgba(0,0,0,.7);padding:2px 15px;border-radius:10px;color:#d3d3d3;pointer-events:auto!important}.navbar-highlight-bar{cursor:pointer}.navbar-highlight-button-right{cursor:pointer;padding-left:10px}.modal-wide .modal-dialog{width:80%}h1{z-index:-1}h1,h2{position:relative}h2{z-index:-2}h1:before,h2:before{display:block;content:" ";margin-top:-70px;height:70px;visibility:hidden}.p{display:block;margin-top:15px}.option-control,.option-row{vertical-align:top;padding:30px 10px 10px 30px}.option-info{padding:10px}.dashboard-context-info,.dashboard-submenu-info{display:block;margin-top:10px}.dashboard-context-info{color:#878b90;color:var(--color-border,#878b90)}.dashboard-context-info a{color:#00ab44;color:var(--color-primary,#00ab44)}#masthead h1{line-height:1;padding-top:30px}#masthead .well{margin-top:4%}body.modal-open{width:100%!important;padding-right:0!important;overflow:visible}.panel-title a{display:block;padding:10px 15px;margin:-10px -15px}.affix{position:static}.sidebar-body{margin-top:0}.dashboard-sidebar{max-height:calc(100% - 24px)!important;overflow-y:auto}.dashboard-sidebar.affix{position:static}.dashboard-sidenav{margin-top:20px;margin-bottom:20px}.dashboard-sidenav.affix{position:static}.dashboard-sidebar .nav>li>a{display:block;padding:4px 20px;font-size:13px;font-weight:500;color:#767676}.dashboard-sidebar .nav>li>a>.svg-inline--fa{width:20px;text-align:center}.dashboard-sidebar .nav>li>a:focus,.dashboard-sidebar .nav>li>a:hover{padding-left:19px;color:#563d7c;text-decoration:none;background-color:transparent;border-left:1px solid #563d7c}.dashboard-sidebar .nav>.active:focus>a,.dashboard-sidebar .nav>.active:hover>a,.dashboard-sidebar .nav>.active>a{padding-left:18px;font-weight:700;color:#563d7c;background-color:transparent;border-left:2px solid #563d7c}.dashboard-sidebar .nav .nav{display:none;padding-bottom:10px}.dashboard-sidebar .nav .nav>li>a{padding-top:1px;padding-bottom:1px;padding-left:30px;font-size:12px;font-weight:400}.dashboard-sidebar .nav .nav>li>a:focus,.dashboard-sidebar .nav .nav>li>a:hover{padding-left:29px}.dashboard-sidebar .nav .nav>.active:focus>a,.dashboard-sidebar .nav .nav>.active:hover>a,.dashboard-sidebar .nav .nav>.active>a{padding-left:28px;font-weight:500}.multi-column-dropdown{list-style:none;padding:0}.multi-column-dropdown li a{display:inline-block;clear:both;line-height:1.428571429;white-space:normal}.multi-column-dropdown li a:hover{text-decoration:none;color:#f5f5f5;background-color:#262626}.scrollable-menu-50{height:auto;max-height:50vh;overflow-x:hidden}.container{width:calc(100% - 20px)!important}.charts-body{display:inline-block;width:100%}.sidebar-body{position:absolute;display:none;height:100vh}.terms-and-privacy a{color:inherit;text-decoration:underline;display:block}.dashboard-section-container{page-break-inside:auto}.dashboard-print-row,.dashboard-section-container{display:block;width:100%;page-break-before:auto;page-break-after:auto}.dashboard-print-row{page-break-inside:avoid}.netdata-chartblock-container{display:inline-block}.tooltip{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.action-button{position:relative;display:inline-block;color:grey;cursor:pointer;margin:0 auto;width:30px;height:30px;font-size:25px}.ripple{position:relative;-webkit-transform:translateZ(0);transform:translateZ(0)}.ripple:after{content:"";display:block;position:absolute;width:100%;height:100%;top:0;left:0;pointer-events:none;background-image:radial-gradient(circle,#000 10%,transparent 10.01%);background-repeat:no-repeat;background-position:50%;-webkit-transform:scale(18);transform:scale(18);opacity:0;-webkit-transition:opacity 1s,-webkit-transform .5s;transition:opacity 1s,-webkit-transform .5s;transition:transform .5s,opacity 1s;transition:transform .5s,opacity 1s,-webkit-transform .5s}.ripple:active:after{-webkit-transform:scale(0);transform:scale(0);opacity:.2;-webkit-transition:0s;transition:0s}#alarms_log_table tbody tr{cursor:pointer}.agent-item--separated{border-top:1px solid #333}.agent-item--alternate a{color:#999}#sign-in-iframe{background-color:#fff;border:none}.filter-control{position:relative}.sign-in-btn{background-color:#1e2126}.sign-in-btn.theme-white{background-color:#e6e6e6}.sign-in-btn.theme-white span{color:#000}.beta{color:#fc0}@media (min-width:1360px){.container{padding-left:3%!important}.charts-body{width:calc(100% - 263px)!important;padding-left:1%!important;padding-right:2%!important}.sidebar-body{display:inline-block!important}.dashboard-sidebar.affix,.dashboard-sidebar.affix-bottom,.dashboard-sidebar.affix-top,.sidebar-body{width:263px!important}}@media (min-width:1200px){.container{padding-left:2%!important}.charts-body{width:calc(100% - 233px)!important;padding-left:1%!important;padding-right:1%!important}.sidebar-body{display:inline-block!important}.dashboard-sidebar.affix,.dashboard-sidebar.affix-bottom,.dashboard-sidebar.affix-top,.sidebar-body{width:233px!important}}@media (min-width:992px){.container{padding-left:0!important}.charts-body{width:calc(100% - 213px)!important;padding-left:1%!important;padding-right:0!important}.sidebar-body{display:inline-block!important;width:213px!important}.dashboard-sidebar .nav>.active>ul{display:block}.dashboard-sidebar.affix,.dashboard-sidebar.affix-bottom,.dashboard-sidebar.affix-top{width:213px!important}.dashboard-sidebar.affix{position:fixed}.dashboard-sidebar.affix-bottom{position:absolute}}@media (min-width:860px){.dashboard-sidebar{padding-left:20px}}@media (min-width:768px){.dashboard-sidebar{padding-left:20px}.charts-body{padding-left:0;padding-right:0}}@media print{body{overflow:visible!important;-webkit-print-color-adjust:exact}.dashboard-section,body{page-break-inside:auto;page-break-before:auto;page-break-after:auto}.dashboard-subsection{page-break-before:avoid}.charts-body,.dashboard-subsection{page-break-after:auto;page-break-inside:auto}.charts-body{padding-left:0;padding-right:0;display:block;page-break-before:auto}}#ssoifrm{display:none}@font-face{font-family:Material Icons;font-style:normal;font-weight:400;src:url(../../static/media/material-icons.0509ab09.woff2) format("woff2")}.material-icons{font-family:Material Icons;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-feature-settings:"liga";-webkit-font-smoothing:antialiased}.dygraph-chart__labels-hidden{display:none}.chart-container__loader{position:absolute}.print-modal__close-button--disabled{pointer-events:none}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;padding-left:74px;-webkit-transition:padding-left .2s ease-out;transition:padding-left .2s ease-out}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}@media (min-width:1200px){.with-panel{padding-left:372px}} -/*# sourceMappingURL=main.a46a34fa.chunk.css.map */ \ No newline at end of file diff --git a/web/gui/dashboard/static/css/main.a46a34fa.chunk.css.map b/web/gui/dashboard/static/css/main.a46a34fa.chunk.css.map deleted file mode 100644 index e4688384b..000000000 --- a/web/gui/dashboard/static/css/main.a46a34fa.chunk.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["button.css","main.css","fonts.css","dygraph-chart.css","chart-with-loader.css","print-modal.scss","index.css"],"names":[],"mappings":"AAAA,sBACE,SAAU,CACV,WAAY,CACZ,YAAa,CAEb,4BAA6B,CAG7B,cACF,CAEA,4BACE,YACF,CAGA,wCACE,WACF,CCjBA,KACI,iBAAkB,CAClB,wBACJ,CAGA,KACI,gBACJ,CAEA,kBACI,YAAa,CACb,cAAe,CACf,eAAgB,CAChB,WAAY,CACZ,UAAW,CACX,iBAAkB,CAClB,eAAgB,CAChB,UAAW,CACX,6BACJ,CAEA,0BACI,iBAAkB,CAClB,oBAAqB,CACrB,aAAc,CACd,WAAY,CACZ,eAAgB,CAChB,+BAAoC,CAIpC,gBAAmB,CACnB,kBAAmB,CACnB,aAAgB,CAChB,6BACJ,CAEA,sBACI,cACJ,CAEA,+BACI,cAAe,CACf,iBACJ,CAEA,0BACI,SACJ,CAKA,GAEI,UACJ,CAEA,MAJI,iBAOJ,CAHA,GAEI,UACJ,CAEA,oBAEI,aAAc,CACd,WAAY,CACZ,gBAAiB,CACjB,WAAY,CACZ,iBACJ,CAEA,GACI,aAAc,CACd,eACJ,CAEA,4BAEI,kBAAmB,CAGnB,2BACJ,CAEA,aACI,YACJ,CAOA,gDAJI,aAAc,CACd,eAOJ,CAJA,wBAGI,aAAmC,CAAnC,iCACJ,CAEA,0BACI,aAAoC,CAApC,kCACJ,CAEA,aAEI,aAAc,CACd,gBACJ,CAEA,gBACI,aACJ,CAIA,gBACI,oBAAsB,CACtB,yBAA2B,CAG3B,gBACJ,CAGA,eACI,aAAc,CACd,iBAAkB,CAClB,kBACJ,CASA,OACI,eAGJ,CAEA,cACI,YACJ,CAEA,mBACI,sCAAwC,CACxC,eAEJ,CAGA,yBACI,eACJ,CAGA,mBACI,eAAgB,CAChB,kBACJ,CAEA,yBACI,eACJ,CAGA,6BACI,aAAc,CACd,gBAAiB,CACjB,cAAe,CACf,eAAgB,CAChB,aACJ,CAEA,6CACI,UAAW,CACX,iBACJ,CAEA,sEAEI,iBAAkB,CAClB,aAAc,CACd,oBAAqB,CACrB,4BAA6B,CAC7B,6BACJ,CAEA,kHAGI,iBAAkB,CAClB,eAAiB,CACjB,aAAc,CACd,4BAA6B,CAC7B,6BACJ,CAGA,6BACI,YAAa,CACb,mBACJ,CAEA,kCACI,eAAgB,CAChB,kBAAmB,CACnB,iBAAkB,CAClB,cAAe,CACf,eACJ,CAEA,gFAEI,iBACJ,CAEA,iIAGI,iBAAkB,CAClB,eACJ,CAEA,uBACI,eAAgB,CAChB,SACJ,CAEA,4BACI,oBAAqB,CACrB,UAAW,CACX,uBAAwB,CACxB,kBACJ,CAEA,kCACI,oBAAqB,CACrB,aAAc,CACd,wBACJ,CAEA,oBACI,WAAY,CACZ,eAAgB,CAChB,iBACJ,CAEA,WACI,iCACJ,CAEA,aACI,oBAAqB,CACrB,UACJ,CAEA,cACI,iBAAkB,CAClB,YAAa,CACb,YACJ,CAEA,qBACI,aAAc,CACd,yBAA0B,CAC1B,aACJ,CAEA,6BAKI,sBACJ,CAEA,kDAPI,aAAc,CACd,UAAW,CACX,sBAAuB,CACvB,qBAUJ,CANA,qBAKI,uBACJ,CAEA,8BACI,oBACJ,CAGA,SACI,wBAAyB,CACzB,qBAAsB,CACtB,oBAAqB,CACrB,gBACJ,CAEA,eACI,iBAAkB,CAClB,oBAAqB,CACrB,UAAW,CACX,cAAe,CACf,aAAc,CACd,UAAW,CACX,WAAY,CACZ,cACJ,CAEA,QACI,iBAAkB,CAElB,+BAA+B,CAA/B,uBACJ,CAEA,cACI,UAAW,CACX,aAAc,CACd,iBAAkB,CAClB,UAAW,CACX,WAAY,CACZ,KAAM,CACN,MAAO,CACP,mBAAoB,CACpB,oEAAuE,CACvE,2BAA4B,CAC5B,uBAAwB,CACxB,2BAAwB,CAAxB,mBAAwB,CACxB,SAAU,CACV,mDAAsC,CAAtC,2CAAsC,CAAtC,mCAAsC,CAAtC,yDACJ,CAEA,qBACI,0BAAsB,CAAtB,kBAAsB,CACtB,UAAY,CACZ,qBAAc,CAAd,aACJ,CAIA,2BACI,cACJ,CAEA,uBACI,yBACJ,CAEA,yBACI,UACJ,CAIA,gBACI,qBAAsB,CACtB,WACJ,CAEA,gBACI,iBACJ,CAEA,aACI,wBACJ,CAEA,yBACI,wBACJ,CAEA,8BACI,UACJ,CAEA,MACI,UACJ,CAEA,0BACI,WACI,yBACJ,CAEA,aACI,kCAAoC,CACpC,yBAA2B,CAC3B,0BACJ,CAEA,cACI,8BAEJ,CAGA,oGAJI,qBAQJ,CACJ,CAEA,0BACI,WACI,yBACJ,CAEA,aACI,kCAAoC,CACpC,yBAA2B,CAC3B,0BACJ,CAEA,cACI,8BAEJ,CAGA,oGAJI,qBAQJ,CACJ,CAEA,yBACI,WACI,wBACJ,CAEA,aACI,kCAAoC,CACpC,yBAA2B,CAC3B,yBACJ,CAEA,cACI,8BAAgC,CAChC,qBACJ,CAEA,mCACI,aACJ,CAGA,sFAGI,qBACJ,CAEA,yBACI,cAEJ,CAEA,gCACI,iBACJ,CACJ,CAEA,yBACI,mBACI,iBACJ,CACJ,CAEA,yBACI,mBACI,iBACJ,CAEA,aACI,cAAgB,CAChB,eACJ,CACJ,CAEA,aACI,KACI,0BAA4B,CAC5B,gCAIJ,CAEA,wBALI,sBAAuB,CACvB,sBAAuB,CACvB,qBAOJ,CAEA,sBACI,uBAGJ,CAEA,mCAJI,qBAAsB,CACtB,sBAUJ,CAPA,aACI,cAAgB,CAChB,eAAiB,CACjB,aAAc,CAEd,sBAEJ,CACJ,CAEA,SACI,YACJ,CCtgBA,WACE,0BAA6B,CAC7B,iBAAkB,CAClB,eAAgB,CAChB,yEACF,CAEA,gBACE,0BAA6B,CAC7B,eAAmB,CACnB,iBAAkB,CAClB,cAAe,CACf,aAAc,CACd,qBAAsB,CACtB,mBAAoB,CACpB,oBAAqB,CACrB,kBAAmB,CACnB,gBAAiB,CACjB,aAAc,CACd,oCAAqC,CACrC,kCACF,CCtBA,8BACE,YACF,CCFA,yBAIE,iBACF,CCHI,qCACE,mBAAoB,CCH1B,KACE,QAAS,CACT,mIACsE,CACtE,kCAAmC,CACnC,iCAAkC,CAClC,iBAAkB,CAClB,4CAAsC,CAAtC,oCACF,CAEA,KACE,uEACF,CAEA,0BACE,YACE,kBACF,CACF","file":"main.a46a34fa.chunk.css","sourcesContent":[".netdata-reset-button {\n padding: 0;\n border: none;\n font: inherit;\n /*color: inherit;*/\n background-color: transparent;\n /* show a hand cursor on hover; some argue that we\n should keep the default arrow cursor for buttons */\n cursor: pointer;\n}\n\n.netdata-reset-button:focus {\n outline: none;\n}\n\n/* Firefox: remove the inner border shown on focus */\n.netdata-reset-button::-moz-focus-inner {\n border: none;\n}\n","/* force the vertical window scrollbar */\nhtml {\n overflow-y: hidden;\n font-size: 16px !important; /* To override nasty bootstrap.css default! */\n}\n\n/* prevent body from hiding under the navbar */\nbody {\n padding-top: 50px;\n}\n\n.navbar-highlight {\n display: none;\n position: fixed;\n margin-top: 10px;\n height: 26px;\n width: 100%;\n text-align: center;\n overflow: hidden;\n z-index: 30;\n pointer-events: none !important;\n}\n\n.navbar-highlight-content {\n position: relative;\n display: inline-block;\n margin: 0 auto;\n height: 26px;\n min-width: 500px;\n background-color: rgba(0, 0, 0, 0.7);\n padding-top: 2px;\n padding-bottom: 2px;\n padding-left: 15px;\n padding-right: 15px;\n border-radius: 10px;\n color: lightgrey;\n pointer-events: auto !important;\n}\n\n.navbar-highlight-bar {\n cursor: pointer;\n}\n\n.navbar-highlight-button-right {\n cursor: pointer;\n padding-left: 10px;\n}\n\n.modal-wide .modal-dialog {\n width: 80%;\n}\n\n/* fix # anchors scrolling under the navbar\n https://github.com/twbs/bootstrap/issues/1768#issuecomment-46519033\n */\nh1 {\n position: relative;\n z-index: -1;\n}\n\nh2 {\n position: relative;\n z-index: -2;\n}\n\nh1:before,\nh2:before {\n display: block;\n content: \" \";\n margin-top: -70px;\n height: 70px;\n visibility: hidden;\n}\n\n.p {\n display: block;\n margin-top: 15px;\n}\n\n.option-row,\n.option-control {\n vertical-align: top;\n padding: 10px;\n padding-top: 30px;\n padding-left: 30px;\n}\n\n.option-info {\n padding: 10px;\n}\n\n.dashboard-submenu-info {\n display: block;\n margin-top: 10px;\n}\n\n.dashboard-context-info {\n display: block;\n margin-top: 10px;\n color: var(--color-border, #878b90);\n}\n\n.dashboard-context-info a {\n color: var(--color-primary, #00ab44);\n}\n\n#masthead h1 {\n /*font-size: 30px;*/\n line-height: 1;\n padding-top: 30px;\n}\n\n#masthead .well {\n margin-top: 4%;\n}\n\n/* fix the navbar shifting when a modal is open */\n/* https://github.com/twbs/bootstrap/issues/14040#issuecomment-159891033 */\nbody.modal-open {\n width: 100% !important;\n padding-right: 0 !important;\n /* overflow-y: scroll !important; */\n /* position: fixed !important;*/\n overflow: visible;\n}\n\n/* make accordion use the whole header bar for expand/collapse */\n.panel-title a {\n display: block;\n padding: 10px 15px;\n margin: -10px -15px;\n}\n\n/*\n * Side navigation\n *\n * Scrollspy and affixed enhanced navigation to highlight sections and secondary\n * sections of docs content.\n */\n\n.affix {\n position: static;\n /* top: 140px !important; */\n /*width: 220px;*/\n}\n\n.sidebar-body {\n margin-top: 0;\n}\n\n.dashboard-sidebar {\n max-height: calc(100% - 24px) !important;\n overflow-y: auto;\n /*width: 220px !important;*/\n}\n\n/* By default it's not affixed in mobile views, so undo that */\n.dashboard-sidebar.affix {\n position: static;\n}\n\n/* First level of nav */\n.dashboard-sidenav {\n margin-top: 20px;\n margin-bottom: 20px;\n}\n\n.dashboard-sidenav.affix {\n position: static;\n}\n\n/* All levels of nav */\n.dashboard-sidebar .nav > li > a {\n display: block;\n padding: 4px 20px;\n font-size: 13px;\n font-weight: 500;\n color: #767676;\n}\n\n.dashboard-sidebar .nav > li > a > .svg-inline--fa {\n width: 20px;\n text-align: center;\n}\n\n.dashboard-sidebar .nav > li > a:hover,\n.dashboard-sidebar .nav > li > a:focus {\n padding-left: 19px;\n color: #563d7c;\n text-decoration: none;\n background-color: transparent;\n border-left: 1px solid #563d7c;\n}\n\n.dashboard-sidebar .nav > .active > a,\n.dashboard-sidebar .nav > .active:hover > a,\n.dashboard-sidebar .nav > .active:focus > a {\n padding-left: 18px;\n font-weight: bold;\n color: #563d7c;\n background-color: transparent;\n border-left: 2px solid #563d7c;\n}\n\n/* Nav: second level (shown on .active) */\n.dashboard-sidebar .nav .nav {\n display: none; /* Hide by default, but at >768px, show it */\n padding-bottom: 10px;\n}\n\n.dashboard-sidebar .nav .nav > li > a {\n padding-top: 1px;\n padding-bottom: 1px;\n padding-left: 30px;\n font-size: 12px;\n font-weight: normal;\n}\n\n.dashboard-sidebar .nav .nav > li > a:hover,\n.dashboard-sidebar .nav .nav > li > a:focus {\n padding-left: 29px;\n}\n\n.dashboard-sidebar .nav .nav > .active > a,\n.dashboard-sidebar .nav .nav > .active:hover > a,\n.dashboard-sidebar .nav .nav > .active:focus > a {\n padding-left: 28px;\n font-weight: 500;\n}\n\n.multi-column-dropdown {\n list-style: none;\n padding: 0;\n}\n\n.multi-column-dropdown li a {\n display: inline-block;\n clear: both;\n line-height: 1.428571429;\n white-space: normal;\n}\n\n.multi-column-dropdown li a:hover {\n text-decoration: none;\n color: #f5f5f5;\n background-color: #262626;\n}\n\n.scrollable-menu-50 {\n height: auto;\n max-height: 50vh;\n overflow-x: hidden;\n}\n\n.container {\n width: calc(100% - 20px) !important;\n}\n\n.charts-body {\n display: inline-block;\n width: 100%;\n}\n\n.sidebar-body {\n position: absolute;\n display: none;\n height: 100vh;\n}\n\n.terms-and-privacy a {\n color: inherit;\n text-decoration: underline;\n display: block;\n}\n\n.dashboard-section-container {\n display: block;\n width: 100%;\n page-break-before: auto;\n page-break-after: auto;\n page-break-inside: auto;\n}\n\n.dashboard-print-row {\n display: block;\n width: 100%;\n page-break-before: auto;\n page-break-after: auto;\n page-break-inside: avoid;\n}\n\n.netdata-chartblock-container {\n display: inline-block;\n}\n\n/* https://github.com/seiyria/bootstrap-slider/issues/746 */\n.tooltip {\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.action-button {\n position: relative;\n display: inline-block;\n color: gray;\n cursor: pointer;\n margin: 0 auto;\n width: 30px;\n height: 30px;\n font-size: 25px;\n}\n\n.ripple {\n position: relative;\n /*overflow: hidden;*/\n transform: translate3d(0, 0, 0);\n}\n\n.ripple:after {\n content: \"\";\n display: block;\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n pointer-events: none;\n background-image: radial-gradient(circle, #000 10%, transparent 10.01%);\n background-repeat: no-repeat;\n background-position: 50%;\n transform: scale(18, 18); /* the size of the ripple */\n opacity: 0;\n transition: transform 0.5s, opacity 1s;\n}\n\n.ripple:active:after {\n transform: scale(0, 0);\n opacity: 0.2;\n transition: 0s;\n}\n\n/* -------------------------------------------------------------------------- */\n\n#alarms_log_table tbody tr {\n cursor: pointer;\n}\n\n.agent-item--separated {\n border-top: 1px solid #333;\n}\n\n.agent-item--alternate a {\n color: #999;\n}\n\n/* white theme overrides */\n\n#sign-in-iframe {\n background-color: #fff;\n border: none;\n}\n\n.filter-control {\n position: relative;\n}\n\n.sign-in-btn {\n background-color: #1e2126;\n}\n\n.sign-in-btn.theme-white {\n background-color: #e6e6e6;\n}\n\n.sign-in-btn.theme-white span {\n color: #000;\n}\n\n.beta {\n color: #ffcc00;\n}\n\n@media (min-width: 1360px) {\n .container {\n padding-left: 3% !important;\n }\n\n .charts-body {\n width: calc(100% - 263px) !important;\n padding-left: 1% !important;\n padding-right: 2% !important;\n }\n\n .sidebar-body {\n display: inline-block !important;\n width: 263px !important;\n }\n\n /* Widen the fixed sidebar again */\n .dashboard-sidebar.affix,\n .dashboard-sidebar.affix-top,\n .dashboard-sidebar.affix-bottom {\n width: 263px !important;\n }\n}\n\n@media (min-width: 1200px) {\n .container {\n padding-left: 2% !important;\n }\n\n .charts-body {\n width: calc(100% - 233px) !important;\n padding-left: 1% !important;\n padding-right: 1% !important;\n }\n\n .sidebar-body {\n display: inline-block !important;\n width: 233px !important;\n }\n\n /* Widen the fixed sidebar again */\n .dashboard-sidebar.affix,\n .dashboard-sidebar.affix-top,\n .dashboard-sidebar.affix-bottom {\n width: 233px !important;\n }\n}\n\n@media (min-width: 992px) {\n .container {\n padding-left: 0% !important;\n }\n\n .charts-body {\n width: calc(100% - 213px) !important;\n padding-left: 1% !important;\n padding-right: 0% !important;\n }\n\n .sidebar-body {\n display: inline-block !important;\n width: 213px !important;\n }\n\n .dashboard-sidebar .nav > .active > ul {\n display: block;\n }\n\n /* Widen the fixed sidebar */\n .dashboard-sidebar.affix,\n .dashboard-sidebar.affix-top,\n .dashboard-sidebar.affix-bottom {\n width: 213px !important;\n }\n\n .dashboard-sidebar.affix {\n position: fixed; /* Undo the static from mobile first approach */\n /* top: 20px; */\n }\n\n .dashboard-sidebar.affix-bottom {\n position: absolute; /* Undo the static from mobile first approach */\n }\n}\n\n@media (min-width: 860px) {\n .dashboard-sidebar {\n padding-left: 20px;\n }\n}\n\n@media (min-width: 768px) {\n .dashboard-sidebar {\n padding-left: 20px;\n }\n\n .charts-body {\n padding-left: 0%;\n padding-right: 0%;\n }\n}\n\n@media print {\n body {\n overflow: visible !important;\n -webkit-print-color-adjust: exact;\n page-break-inside: auto;\n page-break-before: auto;\n page-break-after: auto;\n }\n\n .dashboard-section {\n page-break-inside: auto;\n page-break-before: auto;\n page-break-after: auto;\n }\n\n .dashboard-subsection {\n page-break-before: avoid;\n page-break-after: auto;\n page-break-inside: auto;\n }\n\n .charts-body {\n padding-left: 0%;\n padding-right: 0%;\n display: block;\n page-break-inside: auto;\n page-break-before: auto;\n page-break-after: auto;\n }\n}\n\n#ssoifrm {\n display: none;\n}\n","/* fallback */\n@font-face {\n font-family: 'Material Icons';\n font-style: normal;\n font-weight: 400;\n src: url(\"../fonts/material-icons.woff2\") format('woff2');\n}\n\n.material-icons {\n font-family: 'Material Icons';\n font-weight: normal;\n font-style: normal;\n font-size: 24px;\n line-height: 1;\n letter-spacing: normal;\n text-transform: none;\n display: inline-block;\n white-space: nowrap;\n word-wrap: normal;\n direction: ltr;\n -webkit-font-feature-settings: 'liga';\n -webkit-font-smoothing: antialiased;\n}\n",".dygraph-chart__labels-hidden {\n display: none;\n}\n",".chart-container__loader {\n /* absolute, because to create GaugeChart the height of container is calculated during loading of data\n and loader cannot have any impact on chart size\n */\n position: absolute;\n}\n",".print-modal {\n &__close-button {\n &--disabled {\n pointer-events: none;\n }\n }\n}\n","body {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\", \"Ubuntu\",\n \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n padding-left: 74px;\n transition: padding-left 0.2s ease-out;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\n\n@media (min-width: 1200px) {\n .with-panel {\n padding-left: 372px;\n }\n}\n"]} \ No newline at end of file diff --git a/web/gui/dashboard/static/js/10.44d9d40b.chunk.js b/web/gui/dashboard/static/js/10.44d9d40b.chunk.js new file mode 100644 index 000000000..8d30dd9f7 --- /dev/null +++ b/web/gui/dashboard/static/js/10.44d9d40b.chunk.js @@ -0,0 +1,2 @@ +(this["webpackJsonp@netdata/dashboard"]=this["webpackJsonp@netdata/dashboard"]||[]).push([[10],{507:function(t,e){var n;(n=jQuery).fn.extend({tableExport:function(t){function e(t){var e=[];return n(t).find("thead").first().find("th").each((function(t,o){void 0!==n(o).attr("data-field")?e[t]=n(o).attr("data-field"):e[t]=t.toString()})),e}function o(t,e,o,i,a){if(-1==n.inArray(o,b.ignoreRow)&&-1==n.inArray(o-i,b.ignoreRow)){var l=n(t).filter((function(){return"none"!=n(this).data("tableexport-display")&&(n(this).is(":visible")||"always"==n(this).data("tableexport-display")||"always"==n(this).closest("table").data("tableexport-display"))})).find(e),r=0;if(l.each((function(t){if("always"==n(this).data("tableexport-display")||"none"!=n(this).css("display")&&"hidden"!=n(this).css("visibility")&&"none"!=n(this).data("tableexport-display")){var e=t,i=!1;if(0e&&"undefined"!=typeof k[e]&&-1!=n.inArray(k[e],b.ignoreColumn)&&(i=!0):"number"!=typeof b.ignoreColumn[0]||-1==n.inArray(e,b.ignoreColumn)&&-1==n.inArray(e-l.length,b.ignoreColumn)||(i=!0)),!1===i&&"function"===typeof a){i=0;var s,d=0;if("undefined"!=typeof A[o]&&0a&&(d=Math.min(t.width,this.width),y=this.height*d/this.width),y/gi,"\u2060");if(t=n("
").html(s).contents(),s="",n.each(t.text().split("\u2028"),(function(t,e){0t?"-":"")+(b.numbers.output.thousandsSeparator?(h?d[0].substr(0,h)+b.numbers.output.thousandsSeparator:"")+d[0].substr(h).replace(/(\d{3})(?=\d)/g,"$1"+b.numbers.output.thousandsSeparator):d[0])+(d[1].length?b.numbers.output.decimalMark+d[1]:"")}}!0===b.escape&&(i=escape(i)),"function"===typeof b.onCellData&&(i=b.onCellData(l,e,o,i))}return i}function d(t,e,n){return e+"-"+n.toLowerCase()}function h(t,e){var n=/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/.exec(t),o=e;return n&&(o=[parseInt(n[1]),parseInt(n[2]),parseInt(n[3])]),o}function f(t){var e=c(t,"text-align"),o=c(t,"font-weight"),i=c(t,"font-style"),a="";return"start"==e&&(e="rtl"==c(t,"direction")?"right":"left"),700<=o&&(a="bold"),"italic"==i&&(a+=i),""===a&&(a="normal"),e={style:{align:e,bcolor:h(c(t,"background-color"),[255,255,255]),color:h(c(t,"color"),[0,0,0]),fstyle:a},colspan:parseInt(n(t).attr("colspan"))||0,rowspan:parseInt(n(t).attr("rowspan"))||0},null!==t&&(t=t.getBoundingClientRect(),e.rect={width:t.width,height:t.height}),e}function c(t,e){try{return window.getComputedStyle?(e=e.replace(/([a-z])([A-Z])/,d),window.getComputedStyle(t,null).getPropertyValue(e)):t.currentStyle?t.currentStyle[e]:t.style[e]}catch(n){}return""}function u(t,e,n){if(null!==(e=c(t,e).match(/\d+/))){e=e[0],t=t.parentElement;var o=document.createElement("div");return o.style.overflow="hidden",o.style.visibility="hidden",t.appendChild(o),o.style.width=100+n,n=100/o.offsetWidth,t.removeChild(o),e*n}return 0}function p(t){var e,n,o=0;if(0===t.length)return o;for(e=0,n=t.length;e(i=t.charCodeAt(o))?n+=String.fromCharCode(i):(127i?n+=String.fromCharCode(i>>6|192):(n+=String.fromCharCode(i>>12|224),n+=String.fromCharCode(i>>6&63|128)),n+=String.fromCharCode(63&i|128));for(t=n;s>2,e=(3&e)<<4|(n=t.charCodeAt(s++))>>4,a=(15&n)<<2|(o=t.charCodeAt(s++))>>6,l=63&o,isNaN(n)?a=l=64:isNaN(o)&&(l=64),r=r+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(i)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(e)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(a)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(l);return r}var m,b={consoleLog:!1,csvEnclosure:'"',csvSeparator:",",csvUseBOM:!0,displayTableName:!1,escape:!1,excelstyles:[],fileName:"tableExport",htmlContent:!1,ignoreColumn:[],ignoreRow:[],jsonScope:"all",jspdf:{orientation:"p",unit:"pt",format:"a4",margins:{left:20,right:10,top:10,bottom:10},autotable:{styles:{cellPadding:2,rowHeight:12,fontSize:8,fillColor:255,textColor:50,fontStyle:"normal",overflow:"ellipsize",halign:"left",valign:"middle"},headerStyles:{fillColor:[52,73,94],textColor:255,fontStyle:"bold",halign:"center"},alternateRowStyles:{fillColor:245},tableExport:{onAfterAutotable:null,onBeforeAutotable:null,onTable:null,outputImages:!0}}},numbers:{html:{decimalMark:".",thousandsSeparator:","},output:{decimalMark:".",thousandsSeparator:","}},onCellData:null,onCellHtmlData:null,outputMode:"file",pdfmake:{enabled:!1},tbodySelector:"tr",tfootSelector:"tr",theadSelector:"tr",tableName:"myTableName",type:"csv",worksheetName:"xlsWorksheetName"},w=this,v=null,x=[],S=[],C=0,A=[],N="",k=[];if(n.extend(!0,b,t),k=e(w),"csv"==b.type||"tsv"==b.type||"txt"==b.type){var E="",j=(C=0,function(t,e,i){return t.each((function(){N="",o(this,e,C,i+t.length,(function(t,e,n){var o=N,i="";null!==t&&(e=null===(t=s(t,e,n))||""===t?"":t.toString(),"tsv"==b.type?(t instanceof Date&&t.toLocaleString(),i=r(e,"\t"," ")):t instanceof Date?i=b.csvEnclosure+t.toLocaleString()+b.csvEnclosure:(0<=(i=r(e,b.csvEnclosure,b.csvEnclosure+b.csvEnclosure)).indexOf(b.csvSeparator)||/[\r\n ]/g.test(i))&&(i=b.csvEnclosure+i+b.csvEnclosure)),N=o+(i+("tsv"==b.type?"\t":b.csvSeparator))})),0<(N=n.trim(N).substring(0,N.length-1)).length&&(0')+"";(x=n(w).find("thead").first().find(b.theadSelector)).each((function(){o(this,"th,td",C,x.length,(function(t,e,n){T+=""+s(t,e,n)+""})),C++})),T+="";var B=1;if(n(w).find("tbody").each((function(){S.push.apply(S,n(this).find(b.tbodySelector))})),b.tfootSelector.length&&S.push.apply(S,n(w).find("tfoot").find(b.tfootSelector)),n(S).each((function(){var t=1;N="",o(this,"td,th",C,x.length+S.length,(function(e,n,o){N+=""+s(e,n,o)+"",t++})),0"!=N&&(T+=''+N+"",B++),C++})),T+="",!0===b.consoleLog&&console.log(T),"string"===b.outputMode)return T;if("base64"===b.outputMode)return g(T);try{m=new Blob([T],{type:"application/xml;charset=utf-8"}),saveAs(m,b.fileName+".xml")}catch(V){y(b.fileName+".xml","data:application/xml;charset=utf-8;base64,",T)}}else if("excel"==b.type||"xls"==b.type||"word"==b.type||"doc"==b.type){var P="excel"==(t="excel"==b.type||"xls"==b.type?"excel":"word")?"xls":"doc",R='xmlns:x="urn:schemas-microsoft-com:office:'+t+'"',I="";if(n(w).filter((function(){return"none"!=n(this).data("tableexport-display")&&(n(this).is(":visible")||"always"==n(this).data("tableexport-display"))})).each((function(){var t=n(this);C=0,k=e(this),I+="",(x=t.find("thead").first().find(b.theadSelector)).each((function(){N="",o(this,"th,td",C,x.length,(function(t,e,o){if(null!==t){var i="";for(var a in N+=""}})),0"+N+""),C++})),I+="",t.find("tbody").each((function(){S.push.apply(S,n(this).find(b.tbodySelector))})),b.tfootSelector.length&&S.push.apply(S,t.find("tfoot").find(b.tfootSelector)),n(S).each((function(){var t=n(this);N="",o(this,"td,th",C,x.length+S.length,(function(e,o,i){if(null!==e){var a="",l=n(e).data("tableexport-msonumberformat");for(var r in"undefined"==typeof l&&"function"===typeof b.onMsoNumberFormat&&(l=b.onMsoNumberFormat(e,o,i)),"undefined"!=typeof l&&""!==l&&(a="style=\"mso-number-format:'"+l+"'"),b.excelstyles)b.excelstyles.hasOwnProperty(r)&&(""===(l=n(e).css(b.excelstyles[r]))&&(l=t.css(b.excelstyles[r])),""!==l&&"0px none rgb(0, 0, 0)"!=l&&"rgba(0, 0, 0, 0)"!=l&&(a+=""===a?'style="':";",a+=b.excelstyles[r]+":"+l));N+="")+""}})),0"+N+""),C++})),b.displayTableName&&(I+=""),I+="
"+s(n("

"+b.tableName+"

"))+"
",!0===b.consoleLog&&console.log(I)})),R='',"excel"===t&&(R+="\x3c!--[if gte mso 9]>",R+="",R+="",R+="",R+="",R+="",R+=b.worksheetName,R+="",R+="",R+="",R+="",R+="",R+="",R+="",R+="",R+="br {mso-data-placement:same-cell;}",R+="",R+="",R+=I,R+="",R+="",!0===b.consoleLog&&console.log(R),"string"===b.outputMode)return R;if("base64"===b.outputMode)return g(R);try{m=new Blob([R],{type:"application/vnd.ms-"+b.type}),saveAs(m,b.fileName+"."+P)}catch(V){y(b.fileName+"."+P,"data:application/vnd.ms-"+t+";base64,",R)}}else if("xlsx"==b.type){var U=[],H=[];C=0,S=n(w).find("thead").first().find(b.theadSelector),n(w).find("tbody").each((function(){S.push.apply(S,n(this).find(b.tbodySelector))})),b.tfootSelector.length&&S.push.apply(S,n(w).find("tfoot").find(b.tfootSelector)),n(S).each((function(){var t=[];o(this,"th,td",C,S.length,(function(e,n,o){if("undefined"!==typeof e&&null!==e){var i=parseInt(e.getAttribute("colspan")),a=parseInt(e.getAttribute("rowspan"));if(""!==(e=s(e,n,o))&&e==+e&&(e=+e),H.forEach((function(e){if(C>=e.s.r&&C<=e.e.r&&t.length>=e.s.c&&t.length<=e.e.c)for(var n=0;n<=e.e.c-e.s.c;++n)t.push(null)})),(a||i)&&(i=i||1,H.push({s:{r:C,c:t.length},e:{r:C+(a||1)-1,c:t.length+i-1}})),t.push(""!==e?e:null),i)for(a=0;ao&&(n.s.r=o),n.s.c>i&&(n.s.c=i),n.e.rn.s.c&&(e["!ref"]=XLSX.utils.encode_range(n)),e}(U))["!merges"]=H,t.SheetNames.push(b.worksheetName),t.Sheets[b.worksheetName]=P,t=XLSX.write(t,{bookType:b.type,bookSST:!1,type:"binary"});try{m=new Blob([function(t){for(var e=new ArrayBuffer(t.length),n=new Uint8Array(e),o=0;o!=t.length;++o)n[o]=255&t.charCodeAt(o);return e}(t)],{type:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=UTF-8"}),saveAs(m,b.fileName+"."+b.type)}catch(V){y(b.fileName+"."+b.type,"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=UTF-8",U)}}else if("png"==b.type)html2canvas(n(w)[0]).then((function(t){t=t.toDataURL();for(var e=atob(t.substring(22)),n=new ArrayBuffer(e.length),o=new Uint8Array(n),i=0;iQ){for(var e in t>z.a0[0]&&(q="a0",J="l"),z)z.hasOwnProperty(e)&&z[e][1]>t&&(q=e,J="l",z[e][0]>t&&(J="p"));Q=t}}})),b.jspdf.format=""===q?"a4":q,b.jspdf.orientation=""===J?"w":J}X.doc=new jsPDF(b.jspdf.orientation,b.jspdf.unit,b.jspdf.format),!0===X.outputImages&&(X.images={}),"undefined"!=typeof X.images&&(n(w).filter((function(){return"none"!=n(this).data("tableexport-display")&&(n(this).is(":visible")||"always"==n(this).data("tableexport-display"))})).each((function(){var t=0;x=n(this).find("thead").find(b.theadSelector),n(this).find("tbody").each((function(){S.push.apply(S,n(this).find(b.tbodySelector))})),b.tfootSelector.length&&S.push.apply(S,n(this).find("tfoot").find(b.tfootSelector)),n(S).each((function(){o(this,"td,th",x.length+t,x.length+S.length,(function(t,e,o){"undefined"!==typeof t&&null!==t&&"undefined"!=typeof(e=n(t).children())&&0t.styles.rowHeight&&(t.styles.rowHeight=o)),"undefined"!=typeof i.style&&!0!==i.style.hidden&&(t.styles.halign=i.style.align,"inherit"===r.styles.fillColor&&(t.styles.fillColor=i.style.bcolor),"inherit"===r.styles.textColor&&(t.styles.textColor=i.style.color),"inherit"===r.styles.fontStyle&&(t.styles.fontStyle=i.style.fstyle))}}),"function"!==typeof r.createdCell&&(r.createdCell=function(t,e){var n=X.rowoptions[e.row.index+":"+e.column.dataKey];"undefined"!=typeof n&&"undefined"!=typeof n.style&&!0!==n.style.hidden&&(t.styles.halign=n.style.align,"inherit"===r.styles.fillColor&&(t.styles.fillColor=n.style.bcolor),"inherit"===r.styles.textColor&&(t.styles.textColor=n.style.color),"inherit"===r.styles.fontStyle&&(t.styles.fontStyle=n.style.fstyle))}),"function"!==typeof r.drawHeaderCell&&(r.drawHeaderCell=function(t,e){var n=X.columns[e.column.dataKey];return(!0!==n.style.hasOwnProperty("hidden")||!0!==n.style.hidden)&&0<=n.rowIndex&&a(t,e,n)}),"function"!==typeof r.drawCell&&(r.drawCell=function(t,e){var n=X.rowoptions[e.row.index+":"+e.column.dataKey];if(a(t,e,n)){if(X.doc.rect(t.x,t.y,t.width,t.height,t.styles.fillStyle),"undefined"!=typeof n&&"undefined"!=typeof n.kids&&0X.dh||"undefined"==typeof X.dh)&&(X.dh=o),X.dw=t.width/n.rect.width,l(t,n.kids,X)}X.doc.autoTableText(t.text,t.textPos.x,t.textPos.y,{halign:t.styles.halign,valign:t.styles.valign})}return!1}),X.headerrows=[],(x=n(this).find("thead").find(b.theadSelector)).each((function(){t=0,X.headerrows[i]=[],o(this,"th,td",i,x.length,(function(e,n,o){var a=f(e);a.title=s(e,n,o),a.key=t++,a.rowIndex=i,X.headerrows[i].push(a)})),i++})),0d&&\"undefined\"!=typeof H[d]&&-1!=c.inArray(H[d],a.ignoreColumn)&&(k=!0):\"number\"!=typeof a.ignoreColumn[0]||-1==c.inArray(d,a.ignoreColumn)&&-1==c.inArray(d-g.length,a.ignoreColumn)||(k=!0));if(!1===k&&\"function\"===typeof w){var k=\r\n0,m,f=0;if(\"undefined\"!=typeof A[e]&&0g&&(f=Math.min(b.width,this.width),l=this.height*f/this.width),l/gi,\"\\u2060\");b=c(\"
\").html(t).contents();t=\"\";c.each(b.text().split(\"\\u2028\"),function(b,a){0b?\"-\":\"\")+(a.numbers.output.thousandsSeparator?(f?m[0].substr(0,f)+a.numbers.output.thousandsSeparator:\"\")+m[0].substr(f).replace(/(\\d{3})(?=\\d)/g,\"$1\"+a.numbers.output.thousandsSeparator):m[0])+(m[1].length?\r\na.numbers.output.decimalMark+m[1]:\"\")}}!0===a.escape&&(d=escape(d));\"function\"===typeof a.onCellData&&(d=a.onCellData(w,k,e,d))}return d}function la(b,a,e){return a+\"-\"+e.toLowerCase()}function N(b,a){var k=/^rgb\\((\\d{1,3}),\\s*(\\d{1,3}),\\s*(\\d{1,3})\\)$/.exec(b),d=a;k&&(d=[parseInt(k[1]),parseInt(k[2]),parseInt(k[3])]);return d}function fa(b){var a=E(b,\"text-align\"),e=E(b,\"font-weight\"),d=E(b,\"font-style\"),w=\"\";\"start\"==a&&(a=\"rtl\"==E(b,\"direction\")?\"right\":\"left\");700<=e&&(w=\"bold\");\"italic\"==d&&\r\n(w+=d);\"\"===w&&(w=\"normal\");a={style:{align:a,bcolor:N(E(b,\"background-color\"),[255,255,255]),color:N(E(b,\"color\"),[0,0,0]),fstyle:w},colspan:parseInt(c(b).attr(\"colspan\"))||0,rowspan:parseInt(c(b).attr(\"rowspan\"))||0};null!==b&&(b=b.getBoundingClientRect(),a.rect={width:b.width,height:b.height});return a}function E(b,a){try{return window.getComputedStyle?(a=a.replace(/([a-z])([A-Z])/,la),window.getComputedStyle(b,null).getPropertyValue(a)):b.currentStyle?b.currentStyle[a]:b.style[a]}catch(e){}return\"\"}\r\nfunction O(b,a,e){a=E(b,a).match(/\\d+/);if(null!==a){a=a[0];b=b.parentElement;var d=document.createElement(\"div\");d.style.overflow=\"hidden\";d.style.visibility=\"hidden\";b.appendChild(d);d.style.width=100+e;e=100/d.offsetWidth;b.removeChild(d);return a*e}return 0}function T(){if(!(this instanceof T))return new T;this.SheetNames=[];this.Sheets={}}function ma(a){for(var b=new ArrayBuffer(a.length),e=new Uint8Array(b),d=0;d!=a.length;++d)e[d]=a.charCodeAt(d)&255;return b}function na(a){for(var b={},e=\r\n{s:{c:1E7,r:1E7},e:{c:0,r:0}},d=0;d!=a.length;++d)for(var c=0;c!=a[d].length;++c){e.s.r>d&&(e.s.r=d);e.s.c>c&&(e.s.c=c);e.e.re.s.c&&(b[\"!ref\"]=XLSX.utils.encode_range(e));\r\nreturn b}function da(a){var b=0,c,d,f;if(0===a.length)return b;c=0;for(f=a.length;cg?d+=String.fromCharCode(g):(127g?d+=String.fromCharCode(g>>6|192):(d+=String.fromCharCode(g>>12|224),d+=String.fromCharCode(g>>6&63|128)),d+=String.fromCharCode(g&63|128));for(a=d;h>2,c=(c&3)<<4|d>>4,t=(d&15)<<2|f>>6,m=f&63,isNaN(d)?t=m=64:\r\nisNaN(f)&&(m=64),b=b+\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\".charAt(g)+\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\".charAt(c)+\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\".charAt(t)+\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\".charAt(m);return b}var a={consoleLog:!1,csvEnclosure:'\"',csvSeparator:\",\",csvUseBOM:!0,displayTableName:!1,escape:!1,excelstyles:[],fileName:\"tableExport\",htmlContent:!1,ignoreColumn:[],\r\nignoreRow:[],jsonScope:\"all\",jspdf:{orientation:\"p\",unit:\"pt\",format:\"a4\",margins:{left:20,right:10,top:10,bottom:10},autotable:{styles:{cellPadding:2,rowHeight:12,fontSize:8,fillColor:255,textColor:50,fontStyle:\"normal\",overflow:\"ellipsize\",halign:\"left\",valign:\"middle\"},headerStyles:{fillColor:[52,73,94],textColor:255,fontStyle:\"bold\",halign:\"center\"},alternateRowStyles:{fillColor:245},tableExport:{onAfterAutotable:null,onBeforeAutotable:null,onTable:null,outputImages:!0}}},numbers:{html:{decimalMark:\".\",\r\nthousandsSeparator:\",\"},output:{decimalMark:\".\",thousandsSeparator:\",\"}},onCellData:null,onCellHtmlData:null,outputMode:\"file\",pdfmake:{enabled:!1},tbodySelector:\"tr\",tfootSelector:\"tr\",theadSelector:\"tr\",tableName:\"myTableName\",type:\"csv\",worksheetName:\"xlsWorksheetName\"},r=this,Q=null,p=[],h=[],l=0,A=[],n=\"\",H=[],z;c.extend(!0,a,u);H=S(r);if(\"csv\"==a.type||\"tsv\"==a.type||\"txt\"==a.type){var D=\"\",I=0,l=0,U=function(b,k,e){b.each(function(){n=\"\";y(this,k,l,e+b.length,function(b,c,e){var d=n,g=\"\";if(null!==\r\nb)if(b=x(b,c,e),c=null===b||\"\"===b?\"\":b.toString(),\"tsv\"==a.type)b instanceof Date&&b.toLocaleString(),g=P(c,\"\\t\",\" \");else if(b instanceof Date)g=a.csvEnclosure+b.toLocaleString()+a.csvEnclosure;else if(g=P(c,a.csvEnclosure,a.csvEnclosure+a.csvEnclosure),0<=g.indexOf(a.csvSeparator)||/[\\r\\n ]/g.test(g))g=a.csvEnclosure+g+a.csvEnclosure;n=d+(g+(\"tsv\"==a.type?\"\\t\":a.csvSeparator))});n=c.trim(n).substring(0,n.length-1);0',B=B+\"\",p=c(r).find(\"thead\").first().find(a.theadSelector);p.each(function(){y(this,\"th,td\",l,p.length,function(a,c,e){B+=\"\"+x(a,c,e)+\"\"});l++});var B=B+\"\",ga=1;c(r).find(\"tbody\").each(function(){h.push.apply(h,c(this).find(a.tbodySelector))});a.tfootSelector.length&&h.push.apply(h,c(r).find(\"tfoot\").find(a.tfootSelector));c(h).each(function(){var a=1;n=\"\";y(this,\"td,th\",\r\nl,p.length+h.length,function(b,c,d){n+=\"\"+x(b,c,d)+\"\";a++});0\"!=n&&(B+=''+n+\"\",ga++);l++});B+=\"\";!0===a.consoleLog&&console.log(B);if(\"string\"===a.outputMode)return B;if(\"base64\"===a.outputMode)return F(B);try{z=new Blob([B],{type:\"application/xml;charset=utf-8\"}),saveAs(z,a.fileName+\".xml\")}catch(b){C(a.fileName+\".xml\",\"data:application/xml;charset=utf-8;base64,\",B)}}else if(\"excel\"==a.type||\"xls\"==\r\na.type||\"word\"==a.type||\"doc\"==a.type){u=\"excel\"==a.type||\"xls\"==a.type?\"excel\":\"word\";var K=\"excel\"==u?\"xls\":\"doc\",q='xmlns:x=\"urn:schemas-microsoft-com:office:'+u+'\"',G=\"\";c(r).filter(function(){return\"none\"!=c(this).data(\"tableexport-display\")&&(c(this).is(\":visible\")||\"always\"==c(this).data(\"tableexport-display\"))}).each(function(){var b=c(this);l=0;H=S(this);G+=\"\";p=b.find(\"thead\").first().find(a.theadSelector);p.each(function(){n=\"\";y(this,\"th,td\",l,p.length,function(b,e,d){if(null!==\r\nb){var k=\"\";n+=\"\"+x(b,e,d)+\"\"}});0\"+n+\"\");l++});G+=\"\";b.find(\"tbody\").each(function(){h.push.apply(h,\r\nc(this).find(a.tbodySelector))});a.tfootSelector.length&&h.push.apply(h,b.find(\"tfoot\").find(a.tfootSelector));c(h).each(function(){var b=c(this);n=\"\";y(this,\"td,th\",l,p.length+h.length,function(e,d,k){if(null!==e){var g=\"\",f=c(e).data(\"tableexport-msonumberformat\");\"undefined\"==typeof f&&\"function\"===typeof a.onMsoNumberFormat&&(f=a.onMsoNumberFormat(e,d,k));\"undefined\"!=typeof f&&\"\"!==f&&(g=\"style=\\\"mso-number-format:'\"+f+\"'\");for(var m in a.excelstyles)a.excelstyles.hasOwnProperty(m)&&(f=c(e).css(a.excelstyles[m]),\r\n\"\"===f&&(f=b.css(a.excelstyles[m])),\"\"!==f&&\"0px none rgb(0, 0, 0)\"!=f&&\"rgba(0, 0, 0, 0)\"!=f&&(g+=\"\"===g?'style=\"':\";\",g+=a.excelstyles[m]+\":\"+f));n+=\"\"+x(e,d,k).replace(/\\n/g,\"
\")+\"\"}});0\"+n+\"\");l++});a.displayTableName&&(G+=\"
\");G+=\"
\"+x(c(\"

\"+a.tableName+\"

\"))+\r\n\"
\";!0===a.consoleLog&&console.log(G)});q=''+('')+\"\";\"excel\"===u&&(q+=\"\\x3c!--[if gte mso 9]>\",q+=\"\",q+=\"\",q+=\"\",q+=\"\",q+=\"\",q+=a.worksheetName,q+=\"\",q+=\"\",q+=\"\",\r\nq+=\"\",q+=\"\",q+=\"\",q+=\"\",q+=\"\",q+=\"br {mso-data-placement:same-cell;}\";q+=\"\";q+=\"\";q+=G;q+=\"\";q+=\"\";!0===a.consoleLog&&console.log(q);if(\"string\"===a.outputMode)return q;if(\"base64\"===a.outputMode)return F(q);try{z=new Blob([q],{type:\"application/vnd.ms-\"+a.type}),saveAs(z,a.fileName+\".\"+K)}catch(b){C(a.fileName+\".\"+K,\"data:application/vnd.ms-\"+u+\";base64,\",\r\nq)}}else if(\"xlsx\"==a.type){var W=[],X=[],l=0,h=c(r).find(\"thead\").first().find(a.theadSelector);c(r).find(\"tbody\").each(function(){h.push.apply(h,c(this).find(a.tbodySelector))});a.tfootSelector.length&&h.push.apply(h,c(r).find(\"tfoot\").find(a.tfootSelector));c(h).each(function(){var a=[];y(this,\"th,td\",l,h.length,function(b,c,d){if(\"undefined\"!==typeof b&&null!==b){var e=parseInt(b.getAttribute(\"colspan\")),g=parseInt(b.getAttribute(\"rowspan\"));b=x(b,c,d);\"\"!==b&&b==+b&&(b=+b);X.forEach(function(b){if(l>=\r\nb.s.r&&l<=b.e.r&&a.length>=b.s.c&&a.length<=b.e.c)for(var c=0;c<=b.e.c-b.s.c;++c)a.push(null)});if(g||e)e=e||1,X.push({s:{r:l,c:a.length},e:{r:l+(g||1)-1,c:a.length+e-1}});a.push(\"\"!==b?b:null);if(e)for(g=0;gia){a>L.a0[0]&&(R=\"a0\",M=\"l\");for(var f in L)L.hasOwnProperty(f)&&L[f][1]>a&&(R=f,M=\"l\",L[f][0]>a&&(M=\"p\"));ia=a}}});a.jspdf.format=\"\"===R?\"a4\":R;a.jspdf.orientation=\"\"===M?\"w\":M}f.doc=new jsPDF(a.jspdf.orientation,a.jspdf.unit,a.jspdf.format);!0===f.outputImages&&(f.images={});\"undefined\"!=typeof f.images&&(c(r).filter(function(){return\"none\"!=c(this).data(\"tableexport-display\")&&(c(this).is(\":visible\")||\"always\"==c(this).data(\"tableexport-display\"))}).each(function(){var b=\r\n0;p=c(this).find(\"thead\").find(a.theadSelector);c(this).find(\"tbody\").each(function(){h.push.apply(h,c(this).find(a.tbodySelector))});a.tfootSelector.length&&h.push.apply(h,c(this).find(\"tfoot\").find(a.tfootSelector));c(h).each(function(){y(this,\"td,th\",p.length+b,p.length+h.length,function(a,b,d){\"undefined\"!==typeof a&&null!==a&&(b=c(a).children(),\"undefined\"!=typeof b&&0a.styles.rowHeight&&(a.styles.rowHeight=g)}\"undefined\"!=typeof e.style&&!0!==e.style.hidden&&(a.styles.halign=e.style.align,\"inherit\"===d.styles.fillColor&&(a.styles.fillColor=e.style.bcolor),\"inherit\"===d.styles.textColor&&(a.styles.textColor=e.style.color),\"inherit\"===d.styles.fontStyle&&(a.styles.fontStyle=e.style.fstyle))}});\"function\"!==typeof d.createdCell&&(d.createdCell=\r\nfunction(a,b){var c=f.rowoptions[b.row.index+\":\"+b.column.dataKey];\"undefined\"!=typeof c&&\"undefined\"!=typeof c.style&&!0!==c.style.hidden&&(a.styles.halign=c.style.align,\"inherit\"===d.styles.fillColor&&(a.styles.fillColor=c.style.bcolor),\"inherit\"===d.styles.textColor&&(a.styles.textColor=c.style.color),\"inherit\"===d.styles.fontStyle&&(a.styles.fontStyle=c.style.fstyle))});\"function\"!==typeof d.drawHeaderCell&&(d.drawHeaderCell=function(a,b){var c=f.columns[b.column.dataKey];return(!0!==c.style.hasOwnProperty(\"hidden\")||\r\n!0!==c.style.hidden)&&0<=c.rowIndex?ba(a,b,c):!1});\"function\"!==typeof d.drawCell&&(d.drawCell=function(a,b){var c=f.rowoptions[b.row.index+\":\"+b.column.dataKey];if(ba(a,b,c)){f.doc.rect(a.x,a.y,a.width,a.height,a.styles.fillStyle);if(\"undefined\"!=typeof c&&\"undefined\"!=typeof c.kids&&0f.dh||\"undefined\"==typeof f.dh)f.dh=d;f.dw=a.width/c.rect.width;ea(a,c.kids,f)}f.doc.autoTableText(a.text,a.textPos.x,a.textPos.y,{halign:a.styles.halign,valign:a.styles.valign})}return!1});\r\nf.headerrows=[];p=c(this).find(\"thead\").find(a.theadSelector);p.each(function(){b=0;f.headerrows[e]=[];y(this,\"th,td\",e,p.length,function(a,c,d){var g=fa(a);g.title=x(a,c,d);g.key=b++;g.rowIndex=e;f.headerrows[e].push(g)});e++});0e&&"undefined"!=typeof k[e]&&-1!=n.inArray(k[e],b.ignoreColumn)&&(i=!0):"number"!=typeof b.ignoreColumn[0]||-1==n.inArray(e,b.ignoreColumn)&&-1==n.inArray(e-l.length,b.ignoreColumn)||(i=!0)),!1===i&&"function"===typeof a){i=0;var s,d=0;if("undefined"!=typeof A[o]&&0a&&(d=Math.min(t.width,this.width),y=this.height*d/this.width),y/gi,"\u2060");if(t=n("
").html(s).contents(),s="",n.each(t.text().split("\u2028"),(function(t,e){0t?"-":"")+(b.numbers.output.thousandsSeparator?(h?d[0].substr(0,h)+b.numbers.output.thousandsSeparator:"")+d[0].substr(h).replace(/(\d{3})(?=\d)/g,"$1"+b.numbers.output.thousandsSeparator):d[0])+(d[1].length?b.numbers.output.decimalMark+d[1]:"")}}!0===b.escape&&(i=escape(i)),"function"===typeof b.onCellData&&(i=b.onCellData(l,e,o,i))}return i}function d(t,e,n){return e+"-"+n.toLowerCase()}function h(t,e){var n=/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/.exec(t),o=e;return n&&(o=[parseInt(n[1]),parseInt(n[2]),parseInt(n[3])]),o}function f(t){var e=c(t,"text-align"),o=c(t,"font-weight"),i=c(t,"font-style"),a="";return"start"==e&&(e="rtl"==c(t,"direction")?"right":"left"),700<=o&&(a="bold"),"italic"==i&&(a+=i),""===a&&(a="normal"),e={style:{align:e,bcolor:h(c(t,"background-color"),[255,255,255]),color:h(c(t,"color"),[0,0,0]),fstyle:a},colspan:parseInt(n(t).attr("colspan"))||0,rowspan:parseInt(n(t).attr("rowspan"))||0},null!==t&&(t=t.getBoundingClientRect(),e.rect={width:t.width,height:t.height}),e}function c(t,e){try{return window.getComputedStyle?(e=e.replace(/([a-z])([A-Z])/,d),window.getComputedStyle(t,null).getPropertyValue(e)):t.currentStyle?t.currentStyle[e]:t.style[e]}catch(n){}return""}function u(t,e,n){if(null!==(e=c(t,e).match(/\d+/))){e=e[0],t=t.parentElement;var o=document.createElement("div");return o.style.overflow="hidden",o.style.visibility="hidden",t.appendChild(o),o.style.width=100+n,n=100/o.offsetWidth,t.removeChild(o),e*n}return 0}function p(t){var e,n,o=0;if(0===t.length)return o;for(e=0,n=t.length;e(i=t.charCodeAt(o))?n+=String.fromCharCode(i):(127i?n+=String.fromCharCode(i>>6|192):(n+=String.fromCharCode(i>>12|224),n+=String.fromCharCode(i>>6&63|128)),n+=String.fromCharCode(63&i|128));for(t=n;s>2,e=(3&e)<<4|(n=t.charCodeAt(s++))>>4,a=(15&n)<<2|(o=t.charCodeAt(s++))>>6,l=63&o,isNaN(n)?a=l=64:isNaN(o)&&(l=64),r=r+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(i)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(e)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(a)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(l);return r}var m,b={consoleLog:!1,csvEnclosure:'"',csvSeparator:",",csvUseBOM:!0,displayTableName:!1,escape:!1,excelstyles:[],fileName:"tableExport",htmlContent:!1,ignoreColumn:[],ignoreRow:[],jsonScope:"all",jspdf:{orientation:"p",unit:"pt",format:"a4",margins:{left:20,right:10,top:10,bottom:10},autotable:{styles:{cellPadding:2,rowHeight:12,fontSize:8,fillColor:255,textColor:50,fontStyle:"normal",overflow:"ellipsize",halign:"left",valign:"middle"},headerStyles:{fillColor:[52,73,94],textColor:255,fontStyle:"bold",halign:"center"},alternateRowStyles:{fillColor:245},tableExport:{onAfterAutotable:null,onBeforeAutotable:null,onTable:null,outputImages:!0}}},numbers:{html:{decimalMark:".",thousandsSeparator:","},output:{decimalMark:".",thousandsSeparator:","}},onCellData:null,onCellHtmlData:null,outputMode:"file",pdfmake:{enabled:!1},tbodySelector:"tr",tfootSelector:"tr",theadSelector:"tr",tableName:"myTableName",type:"csv",worksheetName:"xlsWorksheetName"},w=this,v=null,x=[],S=[],C=0,A=[],N="",k=[];if(n.extend(!0,b,t),k=e(w),"csv"==b.type||"tsv"==b.type||"txt"==b.type){var E="",j=(C=0,function(t,e,i){return t.each((function(){N="",o(this,e,C,i+t.length,(function(t,e,n){var o=N,i="";null!==t&&(e=null===(t=s(t,e,n))||""===t?"":t.toString(),"tsv"==b.type?(t instanceof Date&&t.toLocaleString(),i=r(e,"\t"," ")):t instanceof Date?i=b.csvEnclosure+t.toLocaleString()+b.csvEnclosure:(0<=(i=r(e,b.csvEnclosure,b.csvEnclosure+b.csvEnclosure)).indexOf(b.csvSeparator)||/[\r\n ]/g.test(i))&&(i=b.csvEnclosure+i+b.csvEnclosure)),N=o+(i+("tsv"==b.type?"\t":b.csvSeparator))})),0<(N=n.trim(N).substring(0,N.length-1)).length&&(0')+"";(x=n(w).find("thead").first().find(b.theadSelector)).each((function(){o(this,"th,td",C,x.length,(function(t,e,n){T+=""+s(t,e,n)+""})),C++})),T+="";var B=1;if(n(w).find("tbody").each((function(){S.push.apply(S,n(this).find(b.tbodySelector))})),b.tfootSelector.length&&S.push.apply(S,n(w).find("tfoot").find(b.tfootSelector)),n(S).each((function(){var t=1;N="",o(this,"td,th",C,x.length+S.length,(function(e,n,o){N+=""+s(e,n,o)+"",t++})),0"!=N&&(T+=''+N+"",B++),C++})),T+="",!0===b.consoleLog&&console.log(T),"string"===b.outputMode)return T;if("base64"===b.outputMode)return g(T);try{m=new Blob([T],{type:"application/xml;charset=utf-8"}),saveAs(m,b.fileName+".xml")}catch(V){y(b.fileName+".xml","data:application/xml;charset=utf-8;base64,",T)}}else if("excel"==b.type||"xls"==b.type||"word"==b.type||"doc"==b.type){var P="excel"==(t="excel"==b.type||"xls"==b.type?"excel":"word")?"xls":"doc",R='xmlns:x="urn:schemas-microsoft-com:office:'+t+'"',I="";if(n(w).filter((function(){return"none"!=n(this).data("tableexport-display")&&(n(this).is(":visible")||"always"==n(this).data("tableexport-display"))})).each((function(){var t=n(this);C=0,k=e(this),I+="",(x=t.find("thead").first().find(b.theadSelector)).each((function(){N="",o(this,"th,td",C,x.length,(function(t,e,o){if(null!==t){var i="";for(var a in N+=""}})),0"+N+""),C++})),I+="",t.find("tbody").each((function(){S.push.apply(S,n(this).find(b.tbodySelector))})),b.tfootSelector.length&&S.push.apply(S,t.find("tfoot").find(b.tfootSelector)),n(S).each((function(){var t=n(this);N="",o(this,"td,th",C,x.length+S.length,(function(e,o,i){if(null!==e){var a="",l=n(e).data("tableexport-msonumberformat");for(var r in"undefined"==typeof l&&"function"===typeof b.onMsoNumberFormat&&(l=b.onMsoNumberFormat(e,o,i)),"undefined"!=typeof l&&""!==l&&(a="style=\"mso-number-format:'"+l+"'"),b.excelstyles)b.excelstyles.hasOwnProperty(r)&&(""===(l=n(e).css(b.excelstyles[r]))&&(l=t.css(b.excelstyles[r])),""!==l&&"0px none rgb(0, 0, 0)"!=l&&"rgba(0, 0, 0, 0)"!=l&&(a+=""===a?'style="':";",a+=b.excelstyles[r]+":"+l));N+="")+""}})),0"+N+""),C++})),b.displayTableName&&(I+=""),I+="
"+s(n("

"+b.tableName+"

"))+"
",!0===b.consoleLog&&console.log(I)})),R='',"excel"===t&&(R+="\x3c!--[if gte mso 9]>",R+="",R+="",R+="",R+="",R+="",R+=b.worksheetName,R+="",R+="",R+="",R+="",R+="",R+="",R+="",R+="",R+="br {mso-data-placement:same-cell;}",R+="",R+="",R+=I,R+="",R+="",!0===b.consoleLog&&console.log(R),"string"===b.outputMode)return R;if("base64"===b.outputMode)return g(R);try{m=new Blob([R],{type:"application/vnd.ms-"+b.type}),saveAs(m,b.fileName+"."+P)}catch(V){y(b.fileName+"."+P,"data:application/vnd.ms-"+t+";base64,",R)}}else if("xlsx"==b.type){var U=[],H=[];C=0,S=n(w).find("thead").first().find(b.theadSelector),n(w).find("tbody").each((function(){S.push.apply(S,n(this).find(b.tbodySelector))})),b.tfootSelector.length&&S.push.apply(S,n(w).find("tfoot").find(b.tfootSelector)),n(S).each((function(){var t=[];o(this,"th,td",C,S.length,(function(e,n,o){if("undefined"!==typeof e&&null!==e){var i=parseInt(e.getAttribute("colspan")),a=parseInt(e.getAttribute("rowspan"));if(""!==(e=s(e,n,o))&&e==+e&&(e=+e),H.forEach((function(e){if(C>=e.s.r&&C<=e.e.r&&t.length>=e.s.c&&t.length<=e.e.c)for(var n=0;n<=e.e.c-e.s.c;++n)t.push(null)})),(a||i)&&(i=i||1,H.push({s:{r:C,c:t.length},e:{r:C+(a||1)-1,c:t.length+i-1}})),t.push(""!==e?e:null),i)for(a=0;ao&&(n.s.r=o),n.s.c>i&&(n.s.c=i),n.e.rn.s.c&&(e["!ref"]=XLSX.utils.encode_range(n)),e}(U))["!merges"]=H,t.SheetNames.push(b.worksheetName),t.Sheets[b.worksheetName]=P,t=XLSX.write(t,{bookType:b.type,bookSST:!1,type:"binary"});try{m=new Blob([function(t){for(var e=new ArrayBuffer(t.length),n=new Uint8Array(e),o=0;o!=t.length;++o)n[o]=255&t.charCodeAt(o);return e}(t)],{type:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=UTF-8"}),saveAs(m,b.fileName+"."+b.type)}catch(V){y(b.fileName+"."+b.type,"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=UTF-8",U)}}else if("png"==b.type)html2canvas(n(w)[0]).then((function(t){t=t.toDataURL();for(var e=atob(t.substring(22)),n=new ArrayBuffer(e.length),o=new Uint8Array(n),i=0;iQ){for(var e in t>z.a0[0]&&(q="a0",J="l"),z)z.hasOwnProperty(e)&&z[e][1]>t&&(q=e,J="l",z[e][0]>t&&(J="p"));Q=t}}})),b.jspdf.format=""===q?"a4":q,b.jspdf.orientation=""===J?"w":J}X.doc=new jsPDF(b.jspdf.orientation,b.jspdf.unit,b.jspdf.format),!0===X.outputImages&&(X.images={}),"undefined"!=typeof X.images&&(n(w).filter((function(){return"none"!=n(this).data("tableexport-display")&&(n(this).is(":visible")||"always"==n(this).data("tableexport-display"))})).each((function(){var t=0;x=n(this).find("thead").find(b.theadSelector),n(this).find("tbody").each((function(){S.push.apply(S,n(this).find(b.tbodySelector))})),b.tfootSelector.length&&S.push.apply(S,n(this).find("tfoot").find(b.tfootSelector)),n(S).each((function(){o(this,"td,th",x.length+t,x.length+S.length,(function(t,e,o){"undefined"!==typeof t&&null!==t&&"undefined"!=typeof(e=n(t).children())&&0t.styles.rowHeight&&(t.styles.rowHeight=o)),"undefined"!=typeof i.style&&!0!==i.style.hidden&&(t.styles.halign=i.style.align,"inherit"===r.styles.fillColor&&(t.styles.fillColor=i.style.bcolor),"inherit"===r.styles.textColor&&(t.styles.textColor=i.style.color),"inherit"===r.styles.fontStyle&&(t.styles.fontStyle=i.style.fstyle))}}),"function"!==typeof r.createdCell&&(r.createdCell=function(t,e){var n=X.rowoptions[e.row.index+":"+e.column.dataKey];"undefined"!=typeof n&&"undefined"!=typeof n.style&&!0!==n.style.hidden&&(t.styles.halign=n.style.align,"inherit"===r.styles.fillColor&&(t.styles.fillColor=n.style.bcolor),"inherit"===r.styles.textColor&&(t.styles.textColor=n.style.color),"inherit"===r.styles.fontStyle&&(t.styles.fontStyle=n.style.fstyle))}),"function"!==typeof r.drawHeaderCell&&(r.drawHeaderCell=function(t,e){var n=X.columns[e.column.dataKey];return(!0!==n.style.hasOwnProperty("hidden")||!0!==n.style.hidden)&&0<=n.rowIndex&&a(t,e,n)}),"function"!==typeof r.drawCell&&(r.drawCell=function(t,e){var n=X.rowoptions[e.row.index+":"+e.column.dataKey];if(a(t,e,n)){if(X.doc.rect(t.x,t.y,t.width,t.height,t.styles.fillStyle),"undefined"!=typeof n&&"undefined"!=typeof n.kids&&0X.dh||"undefined"==typeof X.dh)&&(X.dh=o),X.dw=t.width/n.rect.width,l(t,n.kids,X)}X.doc.autoTableText(t.text,t.textPos.x,t.textPos.y,{halign:t.styles.halign,valign:t.styles.valign})}return!1}),X.headerrows=[],(x=n(this).find("thead").find(b.theadSelector)).each((function(){t=0,X.headerrows[i]=[],o(this,"th,td",i,x.length,(function(e,n,o){var a=f(e);a.title=s(e,n,o),a.key=t++,a.rowIndex=i,X.headerrows[i].push(a)})),i++})),0d&&\"undefined\"!=typeof H[d]&&-1!=c.inArray(H[d],a.ignoreColumn)&&(k=!0):\"number\"!=typeof a.ignoreColumn[0]||-1==c.inArray(d,a.ignoreColumn)&&-1==c.inArray(d-g.length,a.ignoreColumn)||(k=!0));if(!1===k&&\"function\"===typeof w){var k=\r\n0,m,f=0;if(\"undefined\"!=typeof A[e]&&0g&&(f=Math.min(b.width,this.width),l=this.height*f/this.width),l/gi,\"\\u2060\");b=c(\"
\").html(t).contents();t=\"\";c.each(b.text().split(\"\\u2028\"),function(b,a){0b?\"-\":\"\")+(a.numbers.output.thousandsSeparator?(f?m[0].substr(0,f)+a.numbers.output.thousandsSeparator:\"\")+m[0].substr(f).replace(/(\\d{3})(?=\\d)/g,\"$1\"+a.numbers.output.thousandsSeparator):m[0])+(m[1].length?\r\na.numbers.output.decimalMark+m[1]:\"\")}}!0===a.escape&&(d=escape(d));\"function\"===typeof a.onCellData&&(d=a.onCellData(w,k,e,d))}return d}function la(b,a,e){return a+\"-\"+e.toLowerCase()}function N(b,a){var k=/^rgb\\((\\d{1,3}),\\s*(\\d{1,3}),\\s*(\\d{1,3})\\)$/.exec(b),d=a;k&&(d=[parseInt(k[1]),parseInt(k[2]),parseInt(k[3])]);return d}function fa(b){var a=E(b,\"text-align\"),e=E(b,\"font-weight\"),d=E(b,\"font-style\"),w=\"\";\"start\"==a&&(a=\"rtl\"==E(b,\"direction\")?\"right\":\"left\");700<=e&&(w=\"bold\");\"italic\"==d&&\r\n(w+=d);\"\"===w&&(w=\"normal\");a={style:{align:a,bcolor:N(E(b,\"background-color\"),[255,255,255]),color:N(E(b,\"color\"),[0,0,0]),fstyle:w},colspan:parseInt(c(b).attr(\"colspan\"))||0,rowspan:parseInt(c(b).attr(\"rowspan\"))||0};null!==b&&(b=b.getBoundingClientRect(),a.rect={width:b.width,height:b.height});return a}function E(b,a){try{return window.getComputedStyle?(a=a.replace(/([a-z])([A-Z])/,la),window.getComputedStyle(b,null).getPropertyValue(a)):b.currentStyle?b.currentStyle[a]:b.style[a]}catch(e){}return\"\"}\r\nfunction O(b,a,e){a=E(b,a).match(/\\d+/);if(null!==a){a=a[0];b=b.parentElement;var d=document.createElement(\"div\");d.style.overflow=\"hidden\";d.style.visibility=\"hidden\";b.appendChild(d);d.style.width=100+e;e=100/d.offsetWidth;b.removeChild(d);return a*e}return 0}function T(){if(!(this instanceof T))return new T;this.SheetNames=[];this.Sheets={}}function ma(a){for(var b=new ArrayBuffer(a.length),e=new Uint8Array(b),d=0;d!=a.length;++d)e[d]=a.charCodeAt(d)&255;return b}function na(a){for(var b={},e=\r\n{s:{c:1E7,r:1E7},e:{c:0,r:0}},d=0;d!=a.length;++d)for(var c=0;c!=a[d].length;++c){e.s.r>d&&(e.s.r=d);e.s.c>c&&(e.s.c=c);e.e.re.s.c&&(b[\"!ref\"]=XLSX.utils.encode_range(e));\r\nreturn b}function da(a){var b=0,c,d,f;if(0===a.length)return b;c=0;for(f=a.length;cg?d+=String.fromCharCode(g):(127g?d+=String.fromCharCode(g>>6|192):(d+=String.fromCharCode(g>>12|224),d+=String.fromCharCode(g>>6&63|128)),d+=String.fromCharCode(g&63|128));for(a=d;h>2,c=(c&3)<<4|d>>4,t=(d&15)<<2|f>>6,m=f&63,isNaN(d)?t=m=64:\r\nisNaN(f)&&(m=64),b=b+\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\".charAt(g)+\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\".charAt(c)+\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\".charAt(t)+\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\".charAt(m);return b}var a={consoleLog:!1,csvEnclosure:'\"',csvSeparator:\",\",csvUseBOM:!0,displayTableName:!1,escape:!1,excelstyles:[],fileName:\"tableExport\",htmlContent:!1,ignoreColumn:[],\r\nignoreRow:[],jsonScope:\"all\",jspdf:{orientation:\"p\",unit:\"pt\",format:\"a4\",margins:{left:20,right:10,top:10,bottom:10},autotable:{styles:{cellPadding:2,rowHeight:12,fontSize:8,fillColor:255,textColor:50,fontStyle:\"normal\",overflow:\"ellipsize\",halign:\"left\",valign:\"middle\"},headerStyles:{fillColor:[52,73,94],textColor:255,fontStyle:\"bold\",halign:\"center\"},alternateRowStyles:{fillColor:245},tableExport:{onAfterAutotable:null,onBeforeAutotable:null,onTable:null,outputImages:!0}}},numbers:{html:{decimalMark:\".\",\r\nthousandsSeparator:\",\"},output:{decimalMark:\".\",thousandsSeparator:\",\"}},onCellData:null,onCellHtmlData:null,outputMode:\"file\",pdfmake:{enabled:!1},tbodySelector:\"tr\",tfootSelector:\"tr\",theadSelector:\"tr\",tableName:\"myTableName\",type:\"csv\",worksheetName:\"xlsWorksheetName\"},r=this,Q=null,p=[],h=[],l=0,A=[],n=\"\",H=[],z;c.extend(!0,a,u);H=S(r);if(\"csv\"==a.type||\"tsv\"==a.type||\"txt\"==a.type){var D=\"\",I=0,l=0,U=function(b,k,e){b.each(function(){n=\"\";y(this,k,l,e+b.length,function(b,c,e){var d=n,g=\"\";if(null!==\r\nb)if(b=x(b,c,e),c=null===b||\"\"===b?\"\":b.toString(),\"tsv\"==a.type)b instanceof Date&&b.toLocaleString(),g=P(c,\"\\t\",\" \");else if(b instanceof Date)g=a.csvEnclosure+b.toLocaleString()+a.csvEnclosure;else if(g=P(c,a.csvEnclosure,a.csvEnclosure+a.csvEnclosure),0<=g.indexOf(a.csvSeparator)||/[\\r\\n ]/g.test(g))g=a.csvEnclosure+g+a.csvEnclosure;n=d+(g+(\"tsv\"==a.type?\"\\t\":a.csvSeparator))});n=c.trim(n).substring(0,n.length-1);0',B=B+\"\",p=c(r).find(\"thead\").first().find(a.theadSelector);p.each(function(){y(this,\"th,td\",l,p.length,function(a,c,e){B+=\"\"+x(a,c,e)+\"\"});l++});var B=B+\"\",ga=1;c(r).find(\"tbody\").each(function(){h.push.apply(h,c(this).find(a.tbodySelector))});a.tfootSelector.length&&h.push.apply(h,c(r).find(\"tfoot\").find(a.tfootSelector));c(h).each(function(){var a=1;n=\"\";y(this,\"td,th\",\r\nl,p.length+h.length,function(b,c,d){n+=\"\"+x(b,c,d)+\"\";a++});0\"!=n&&(B+=''+n+\"\",ga++);l++});B+=\"\";!0===a.consoleLog&&console.log(B);if(\"string\"===a.outputMode)return B;if(\"base64\"===a.outputMode)return F(B);try{z=new Blob([B],{type:\"application/xml;charset=utf-8\"}),saveAs(z,a.fileName+\".xml\")}catch(b){C(a.fileName+\".xml\",\"data:application/xml;charset=utf-8;base64,\",B)}}else if(\"excel\"==a.type||\"xls\"==\r\na.type||\"word\"==a.type||\"doc\"==a.type){u=\"excel\"==a.type||\"xls\"==a.type?\"excel\":\"word\";var K=\"excel\"==u?\"xls\":\"doc\",q='xmlns:x=\"urn:schemas-microsoft-com:office:'+u+'\"',G=\"\";c(r).filter(function(){return\"none\"!=c(this).data(\"tableexport-display\")&&(c(this).is(\":visible\")||\"always\"==c(this).data(\"tableexport-display\"))}).each(function(){var b=c(this);l=0;H=S(this);G+=\"\";p=b.find(\"thead\").first().find(a.theadSelector);p.each(function(){n=\"\";y(this,\"th,td\",l,p.length,function(b,e,d){if(null!==\r\nb){var k=\"\";n+=\"\"+x(b,e,d)+\"\"}});0\"+n+\"\");l++});G+=\"\";b.find(\"tbody\").each(function(){h.push.apply(h,\r\nc(this).find(a.tbodySelector))});a.tfootSelector.length&&h.push.apply(h,b.find(\"tfoot\").find(a.tfootSelector));c(h).each(function(){var b=c(this);n=\"\";y(this,\"td,th\",l,p.length+h.length,function(e,d,k){if(null!==e){var g=\"\",f=c(e).data(\"tableexport-msonumberformat\");\"undefined\"==typeof f&&\"function\"===typeof a.onMsoNumberFormat&&(f=a.onMsoNumberFormat(e,d,k));\"undefined\"!=typeof f&&\"\"!==f&&(g=\"style=\\\"mso-number-format:'\"+f+\"'\");for(var m in a.excelstyles)a.excelstyles.hasOwnProperty(m)&&(f=c(e).css(a.excelstyles[m]),\r\n\"\"===f&&(f=b.css(a.excelstyles[m])),\"\"!==f&&\"0px none rgb(0, 0, 0)\"!=f&&\"rgba(0, 0, 0, 0)\"!=f&&(g+=\"\"===g?'style=\"':\";\",g+=a.excelstyles[m]+\":\"+f));n+=\"\"+x(e,d,k).replace(/\\n/g,\"
\")+\"\"}});0\"+n+\"\");l++});a.displayTableName&&(G+=\"
\");G+=\"
\"+x(c(\"

\"+a.tableName+\"

\"))+\r\n\"
\";!0===a.consoleLog&&console.log(G)});q=''+('')+\"\";\"excel\"===u&&(q+=\"\\x3c!--[if gte mso 9]>\",q+=\"\",q+=\"\",q+=\"\",q+=\"\",q+=\"\",q+=a.worksheetName,q+=\"\",q+=\"\",q+=\"\",\r\nq+=\"\",q+=\"\",q+=\"\",q+=\"\",q+=\"\",q+=\"br {mso-data-placement:same-cell;}\";q+=\"\";q+=\"\";q+=G;q+=\"\";q+=\"\";!0===a.consoleLog&&console.log(q);if(\"string\"===a.outputMode)return q;if(\"base64\"===a.outputMode)return F(q);try{z=new Blob([q],{type:\"application/vnd.ms-\"+a.type}),saveAs(z,a.fileName+\".\"+K)}catch(b){C(a.fileName+\".\"+K,\"data:application/vnd.ms-\"+u+\";base64,\",\r\nq)}}else if(\"xlsx\"==a.type){var W=[],X=[],l=0,h=c(r).find(\"thead\").first().find(a.theadSelector);c(r).find(\"tbody\").each(function(){h.push.apply(h,c(this).find(a.tbodySelector))});a.tfootSelector.length&&h.push.apply(h,c(r).find(\"tfoot\").find(a.tfootSelector));c(h).each(function(){var a=[];y(this,\"th,td\",l,h.length,function(b,c,d){if(\"undefined\"!==typeof b&&null!==b){var e=parseInt(b.getAttribute(\"colspan\")),g=parseInt(b.getAttribute(\"rowspan\"));b=x(b,c,d);\"\"!==b&&b==+b&&(b=+b);X.forEach(function(b){if(l>=\r\nb.s.r&&l<=b.e.r&&a.length>=b.s.c&&a.length<=b.e.c)for(var c=0;c<=b.e.c-b.s.c;++c)a.push(null)});if(g||e)e=e||1,X.push({s:{r:l,c:a.length},e:{r:l+(g||1)-1,c:a.length+e-1}});a.push(\"\"!==b?b:null);if(e)for(g=0;gia){a>L.a0[0]&&(R=\"a0\",M=\"l\");for(var f in L)L.hasOwnProperty(f)&&L[f][1]>a&&(R=f,M=\"l\",L[f][0]>a&&(M=\"p\"));ia=a}}});a.jspdf.format=\"\"===R?\"a4\":R;a.jspdf.orientation=\"\"===M?\"w\":M}f.doc=new jsPDF(a.jspdf.orientation,a.jspdf.unit,a.jspdf.format);!0===f.outputImages&&(f.images={});\"undefined\"!=typeof f.images&&(c(r).filter(function(){return\"none\"!=c(this).data(\"tableexport-display\")&&(c(this).is(\":visible\")||\"always\"==c(this).data(\"tableexport-display\"))}).each(function(){var b=\r\n0;p=c(this).find(\"thead\").find(a.theadSelector);c(this).find(\"tbody\").each(function(){h.push.apply(h,c(this).find(a.tbodySelector))});a.tfootSelector.length&&h.push.apply(h,c(this).find(\"tfoot\").find(a.tfootSelector));c(h).each(function(){y(this,\"td,th\",p.length+b,p.length+h.length,function(a,b,d){\"undefined\"!==typeof a&&null!==a&&(b=c(a).children(),\"undefined\"!=typeof b&&0a.styles.rowHeight&&(a.styles.rowHeight=g)}\"undefined\"!=typeof e.style&&!0!==e.style.hidden&&(a.styles.halign=e.style.align,\"inherit\"===d.styles.fillColor&&(a.styles.fillColor=e.style.bcolor),\"inherit\"===d.styles.textColor&&(a.styles.textColor=e.style.color),\"inherit\"===d.styles.fontStyle&&(a.styles.fontStyle=e.style.fstyle))}});\"function\"!==typeof d.createdCell&&(d.createdCell=\r\nfunction(a,b){var c=f.rowoptions[b.row.index+\":\"+b.column.dataKey];\"undefined\"!=typeof c&&\"undefined\"!=typeof c.style&&!0!==c.style.hidden&&(a.styles.halign=c.style.align,\"inherit\"===d.styles.fillColor&&(a.styles.fillColor=c.style.bcolor),\"inherit\"===d.styles.textColor&&(a.styles.textColor=c.style.color),\"inherit\"===d.styles.fontStyle&&(a.styles.fontStyle=c.style.fstyle))});\"function\"!==typeof d.drawHeaderCell&&(d.drawHeaderCell=function(a,b){var c=f.columns[b.column.dataKey];return(!0!==c.style.hasOwnProperty(\"hidden\")||\r\n!0!==c.style.hidden)&&0<=c.rowIndex?ba(a,b,c):!1});\"function\"!==typeof d.drawCell&&(d.drawCell=function(a,b){var c=f.rowoptions[b.row.index+\":\"+b.column.dataKey];if(ba(a,b,c)){f.doc.rect(a.x,a.y,a.width,a.height,a.styles.fillStyle);if(\"undefined\"!=typeof c&&\"undefined\"!=typeof c.kids&&0f.dh||\"undefined\"==typeof f.dh)f.dh=d;f.dw=a.width/c.rect.width;ea(a,c.kids,f)}f.doc.autoTableText(a.text,a.textPos.x,a.textPos.y,{halign:a.styles.halign,valign:a.styles.valign})}return!1});\r\nf.headerrows=[];p=c(this).find(\"thead\").find(a.theadSelector);p.each(function(){b=0;f.headerrows[e]=[];y(this,\"th,td\",e,p.length,function(a,c,d){var g=fa(a);g.title=x(a,c,d);g.key=b++;g.rowIndex=e;f.headerrows[e].push(g)});e++});0"+e+""};return function(e){function t(){e.apply(this,arguments)}e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t;var n={isMounted:{}};return n.isMounted.get=function(){return!!this.node},t.createFromExistingNode=function(e){return new t({id:e.getAttribute("id"),viewBox:e.getAttribute("viewBox"),content:e.outerHTML})},t.prototype.destroy=function(){this.isMounted&&this.unmount(),e.prototype.destroy.call(this)},t.prototype.mount=function(e){if(this.isMounted)return this.node;var t="string"===typeof e?document.querySelector(e):e,n=this.render();return this.node=n,t.appendChild(n),n},t.prototype.render=function(){var e=this.stringify();return function(e){var t=!!document.importNode,n=(new DOMParser).parseFromString(e,"image/svg+xml").documentElement;return t?document.importNode(n,!0):n}(s(e)).childNodes[0]},t.prototype.unmount=function(){this.node.parentNode.removeChild(this.node)},Object.defineProperties(t.prototype,n),t}(e)},e.exports=n()}).call(this,n(90))},function(e,t,n){(function(t){var n;n=function(){"use strict";function e(e,t){return e(t={exports:{}},t.exports),t.exports}"undefined"!==typeof window?window:"undefined"!==typeof t||"undefined"!==typeof self&&self;var n=e((function(e,t){e.exports=function(){function e(e){return e&&"object"===typeof e&&"[object RegExp]"!==Object.prototype.toString.call(e)&&"[object Date]"!==Object.prototype.toString.call(e)}function t(t,n){var i;return n&&!0===n.clone&&e(t)?r((i=t,Array.isArray(i)?[]:{}),t,n):t}function n(n,i,o){var a=n.slice();return i.forEach((function(i,c){"undefined"===typeof a[c]?a[c]=t(i,o):e(i)?a[c]=r(n[c],i,o):-1===n.indexOf(i)&&a.push(t(i,o))})),a}function r(i,o,a){var c=Array.isArray(o),s=(a||{arrayMerge:n}).arrayMerge||n;return c?Array.isArray(i)?s(i,o,a):t(o,a):function(n,i,o){var a={};return e(n)&&Object.keys(n).forEach((function(e){a[e]=t(n[e],o)})),Object.keys(i).forEach((function(c){e(i[c])&&n[c]?a[c]=r(n[c],i[c],o):a[c]=t(i[c],o)})),a}(i,o,a)}return r.all=function(e,t){if(!Array.isArray(e)||e.length<2)throw new Error("first argument should be an array with at least two elements");return e.reduce((function(e,n){return r(e,n,t)}))},r}()})),r=e((function(e,t){t.default={svg:{name:"xmlns",uri:"http://www.w3.org/2000/svg"},xlink:{name:"xmlns:xlink",uri:"http://www.w3.org/1999/xlink"}},e.exports=t.default})),i=r.svg,o=r.xlink,a={};a[i.name]=i.uri,a[o.name]=o.uri;var c,s=function(e,t){return void 0===e&&(e=""),""+e+""},l=r.svg,u=r.xlink,f={attrs:(c={style:["position: absolute","width: 0","height: 0"].join("; ")},c[l.name]=l.uri,c[u.name]=u.uri,c)},h=function(e){this.config=n(f,e||{}),this.symbols=[]};h.prototype.add=function(e){var t=this.symbols,n=this.find(e.id);return n?(t[t.indexOf(n)]=e,!1):(t.push(e),!0)},h.prototype.remove=function(e){var t=this.symbols,n=this.find(e);return!!n&&(t.splice(t.indexOf(n),1),n.destroy(),!0)},h.prototype.find=function(e){return this.symbols.filter((function(t){return t.id===e}))[0]||null},h.prototype.has=function(e){return null!==this.find(e)},h.prototype.stringify=function(){var e=this.config.attrs,t=this.symbols.map((function(e){return e.stringify()})).join("");return s(t,e)},h.prototype.toString=function(){return this.stringify()},h.prototype.destroy=function(){this.symbols.forEach((function(e){return e.destroy()}))};var d=function(e){var t=e.id,n=e.viewBox,r=e.content;this.id=t,this.viewBox=n,this.content=r};d.prototype.stringify=function(){return this.content},d.prototype.toString=function(){return this.stringify()},d.prototype.destroy=function(){var e=this;["id","viewBox","content"].forEach((function(t){return delete e[t]}))};var p=function(e){var t=!!document.importNode,n=(new DOMParser).parseFromString(e,"image/svg+xml").documentElement;return t?document.importNode(n,!0):n},z=function(e){function t(){e.apply(this,arguments)}e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t;var n={isMounted:{}};return n.isMounted.get=function(){return!!this.node},t.createFromExistingNode=function(e){return new t({id:e.getAttribute("id"),viewBox:e.getAttribute("viewBox"),content:e.outerHTML})},t.prototype.destroy=function(){this.isMounted&&this.unmount(),e.prototype.destroy.call(this)},t.prototype.mount=function(e){if(this.isMounted)return this.node;var t="string"===typeof e?document.querySelector(e):e,n=this.render();return this.node=n,t.appendChild(n),n},t.prototype.render=function(){var e=this.stringify();return p(s(e)).childNodes[0]},t.prototype.unmount=function(){this.node.parentNode.removeChild(this.node)},Object.defineProperties(t.prototype,n),t}(d),v={autoConfigure:!0,mountTo:"body",syncUrlsWithBaseTag:!1,listenLocationChangeEvent:!0,locationChangeEvent:"locationChange",locationChangeAngularEmitter:!1,usagesToUpdate:"use[*|href]",moveGradientsOutsideSymbol:!1},g=function(e){return Array.prototype.slice.call(e,0)},m={isChrome:function(){return/chrome/i.test(navigator.userAgent)},isFirefox:function(){return/firefox/i.test(navigator.userAgent)},isIE:function(){return/msie/i.test(navigator.userAgent)||/trident/i.test(navigator.userAgent)},isEdge:function(){return/edge/i.test(navigator.userAgent)}},y=function(e){var t=[];return g(e.querySelectorAll("style")).forEach((function(e){e.textContent+="",t.push(e)})),t},b=function(e){return(e||window.location.href).split("#")[0]},w=function(e){angular.module("ng").run(["$rootScope",function(t){t.$on("$locationChangeSuccess",(function(t,n,r){!function(e,t){var n=document.createEvent("CustomEvent");n.initCustomEvent(e,!1,!1,t),window.dispatchEvent(n)}(e,{oldUrl:r,newUrl:n})}))}])},k=function(e,t){return void 0===t&&(t="linearGradient, radialGradient, pattern"),g(e.querySelectorAll("symbol")).forEach((function(e){g(e.querySelectorAll(t)).forEach((function(t){e.parentNode.insertBefore(t,e)}))})),e},x=r.xlink.uri,j="xlink:href",M=/[{}|\\\^\[\]`"<>]/g;function _(e){return e.replace(M,(function(e){return"%"+e[0].charCodeAt(0).toString(16).toUpperCase()}))}var C,q=["clipPath","colorProfile","src","cursor","fill","filter","marker","markerStart","markerMid","markerEnd","mask","stroke","style"],S=q.map((function(e){return"["+e+"]"})).join(","),T=function(e,t,n,r){var i=_(n),o=_(r);(function(e,t){return g(e).reduce((function(e,n){if(!n.attributes)return e;var r=g(n.attributes),i=t?r.filter(t):r;return e.concat(i)}),[])})(e.querySelectorAll(S),(function(e){var t=e.localName,n=e.value;return-1!==q.indexOf(t)&&-1!==n.indexOf("url("+i)})).forEach((function(e){return e.value=e.value.replace(new RegExp(i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g"),o)})),function(e,t,n){g(e).forEach((function(e){var r=e.getAttribute(j);if(r&&0===r.indexOf(t)){var i=r.replace(t,n);e.setAttributeNS(x,j,i)}}))}(t,i,o)},O={MOUNT:"mount",SYMBOL_MOUNT:"symbol_mount"},E=function(e){function t(t){var r=this;void 0===t&&(t={}),e.call(this,n(v,t));var i,o=(i=i||Object.create(null),{on:function(e,t){(i[e]||(i[e]=[])).push(t)},off:function(e,t){i[e]&&i[e].splice(i[e].indexOf(t)>>>0,1)},emit:function(e,t){(i[e]||[]).map((function(e){e(t)})),(i["*"]||[]).map((function(n){n(e,t)}))}});this._emitter=o,this.node=null;var a=this.config;if(a.autoConfigure&&this._autoConfigure(t),a.syncUrlsWithBaseTag){var c=document.getElementsByTagName("base")[0].getAttribute("href");o.on(O.MOUNT,(function(){return r.updateUrls("#",c)}))}var s=this._handleLocationChange.bind(this);this._handleLocationChange=s,a.listenLocationChangeEvent&&window.addEventListener(a.locationChangeEvent,s),a.locationChangeAngularEmitter&&w(a.locationChangeEvent),o.on(O.MOUNT,(function(e){a.moveGradientsOutsideSymbol&&k(e)})),o.on(O.SYMBOL_MOUNT,(function(e){a.moveGradientsOutsideSymbol&&k(e.parentNode),(m.isIE()||m.isEdge())&&y(e)}))}e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t;var r={isMounted:{}};return r.isMounted.get=function(){return!!this.node},t.prototype._autoConfigure=function(e){var t=this.config;"undefined"===typeof e.syncUrlsWithBaseTag&&(t.syncUrlsWithBaseTag="undefined"!==typeof document.getElementsByTagName("base")[0]),"undefined"===typeof e.locationChangeAngularEmitter&&(t.locationChangeAngularEmitter="angular"in window),"undefined"===typeof e.moveGradientsOutsideSymbol&&(t.moveGradientsOutsideSymbol=m.isFirefox())},t.prototype._handleLocationChange=function(e){var t=e.detail,n=t.oldUrl,r=t.newUrl;this.updateUrls(n,r)},t.prototype.add=function(t){var n=e.prototype.add.call(this,t);return this.isMounted&&n&&(t.mount(this.node),this._emitter.emit(O.SYMBOL_MOUNT,t.node)),n},t.prototype.attach=function(e){var t=this,n=this;if(n.isMounted)return n.node;var r="string"===typeof e?document.querySelector(e):e;return n.node=r,this.symbols.forEach((function(e){e.mount(n.node),t._emitter.emit(O.SYMBOL_MOUNT,e.node)})),g(r.querySelectorAll("symbol")).forEach((function(e){var t=z.createFromExistingNode(e);t.node=e,n.add(t)})),this._emitter.emit(O.MOUNT,r),r},t.prototype.destroy=function(){var e=this.config,t=this.symbols,n=this._emitter;t.forEach((function(e){return e.destroy()})),n.off("*"),window.removeEventListener(e.locationChangeEvent,this._handleLocationChange),this.isMounted&&this.unmount()},t.prototype.mount=function(e,t){if(void 0===e&&(e=this.config.mountTo),void 0===t&&(t=!1),this.isMounted)return this.node;var n="string"===typeof e?document.querySelector(e):e,r=this.render();return this.node=r,t&&n.childNodes[0]?n.insertBefore(r,n.childNodes[0]):n.appendChild(r),this._emitter.emit(O.MOUNT,r),r},t.prototype.render=function(){return p(this.stringify())},t.prototype.unmount=function(){this.node.parentNode.removeChild(this.node)},t.prototype.updateUrls=function(e,t){if(!this.isMounted)return!1;var n=document.querySelectorAll(this.config.usagesToUpdate);return T(this.node,n,b(e)+"#",b(t)+"#"),!0},Object.defineProperties(t.prototype,r),t}(h),A=e((function(e){e.exports=function(){var e,t=[],n=document,r=n.documentElement.doScroll,i=(r?/^loaded|^c/:/^loaded|^i|^c/).test(n.readyState);return i||n.addEventListener("DOMContentLoaded",e=function(){for(n.removeEventListener("DOMContentLoaded",e),i=1;e=t.shift();)e()}),function(e){i?setTimeout(e,0):t.push(e)}}()}));window.__SVG_SPRITE__?C=window.__SVG_SPRITE__:(C=new E({attrs:{id:"__SVG_SPRITE_NODE__"}}),window.__SVG_SPRITE__=C);var L=function(){var e=document.getElementById("__SVG_SPRITE_NODE__");e?C.attach(e):C.mount(document.body,!0)};return document.body?L():A(L),C},e.exports=n()}).call(this,n(90))},function(e,t,n){"use strict";var r={};n.r(r),n.d(r,"SIZE_SUB_UNIT",(function(){return d})),n.d(r,"SIZE_UNIT",(function(){return p})),n.d(r,"GUTTER_HEIGHT",(function(){return z}));var i={};n.r(i),n.d(i,"findFilterValues",(function(){return Vm})),n.d(i,"removeSingleFilterValue",(function(){return Nm})),n.d(i,"markSelectedFacetValuesFromFilters",(function(){return Im})),n.d(i,"doFilterValuesMatch",(function(){return Rm})),n.d(i,"mergeFilters",(function(){return Fm})),n.d(i,"isFilterValueRange",(function(){return Bm}));var o={};n.r(o),n.d(o,"addFilter",(function(){return Ny})),n.d(o,"trackAutocompleteClickThrough",(function(){return Iy})),n.d(o,"clearFilters",(function(){return Ry})),n.d(o,"removeFilter",(function(){return Fy})),n.d(o,"reset",(function(){return By})),n.d(o,"setCurrent",(function(){return Uy})),n.d(o,"setFilter",(function(){return Wy})),n.d(o,"setResultsPerPage",(function(){return Gy})),n.d(o,"setSearchTerm",(function(){return Yy})),n.d(o,"setSort",(function(){return Zy})),n.d(o,"trackClickThrough",(function(){return $y})),n.d(o,"a11yNotify",(function(){return tb}));var a=n(0),c=n.n(a),s=n(4),l={transparent:{full:"rgba(255, 255, 255, 0.0)",semi:"rgba(255, 255, 255, 0.5)",popover:"rgba(18, 36, 50, 0.9)"},green:{chateau:"#42B861",netdata:"#00AB44",deyork:"#68C47D",vista:"#96D4A2",fringyFlower:"#BFE5C6",frostee:"#E5F5E8"},red:{pomegranate:"#FF4136",carnation:"#F95251",apricot:"#ED7374",wewak:"#F59B9B",pastelpink:"#FFCED3",lavender:"#FFEBEF"},yellow:{amber:"#FFC300",sunglow:"#FFCC26",seaBuckthorn:"#F9A825",mustard:"#FFD74F",salomie:"#FFE182",buttermilk:"#FFEDB3",ginfizz:"#FFF8E1"},neutral:{white:"#FFF",black:"#000",limedSpruce:"#35414A",regentgrey:"#8F9EAA",blackhaze:"#F7F8F8",iron:"#CFD5DA",porcelain:"#ECEEEF",bluebayoux:"#536775",shark:"#1C1E22",tuna:"#383B40",outerSpace:"#2B3136"},purple:{mauve:"#DB94F4",daisy:"#563D7C"}},u=function(){return(u=Object.assign||function(e){for(var t,n=1,r=arguments.length;n>16&255)+", "+(o>>8&255)+", "+(255&o)+", "+t+")"}},Z=function(e){return void 0===e&&(e=1),function(t){return(W(t)||0)*e+"px"}},$=function(e,t){return void 0===e&&(e="border"),void 0===t&&(t="disabled"),function(n){var r=n.theme,i=n.success,o=n.error,a=n.disabled;return i?G(["success"])({theme:r}):o?G(["error"])({theme:r}):a?G([t])({theme:r}):G([e])({theme:r})}},X=function(e,t){return"number"===typeof t?0===(n=e.constants.SIZE_SUB_UNIT*t)?"0":n+"px":"auto";var n},K=function(e,t){return t.map((function(t){return X(e,t)})).join(" ")},Q=function(e){var t=e.theme,n=e.margin;return n?Array.isArray(n)&&n.length>=1&&n.length<=4?"margin: "+K(t,n)+";":(console.error("Please provide an array (max 4 elements) for `margin` style helper."),""):""},J=function(e){var t=e.theme,n=e.padding;return n?Array.isArray(n)&&n.length>=1&&n.length<=4?"padding: "+K(t,n)+";":(console.error("Please provide an array (max 4 elements) for `padding` style helper."),""):""},ee={end:"flex-end",start:"flex-start",center:"center",stretch:"stretch"},te=function(e){var t=e.alignSelf;return t in ee&&"align-self: "+ee[t]+";"},ne={none:"none",capitalize:"capitalize",uppercase:"uppercase",lowercase:"lowercase",firstLetter:"firstLetter",fullWidth:"full-width"},re=function(e){var t=(void 0===e?{}:e).textTransform,n=void 0===t?"none":t;return n===ne.firstLetter?"text-transform: lowercase;\n &::first-letter {\n text-transform: uppercase;\n }\n":n in ne?"text-transform: "+ne[n]+";":"text-transform: "+ne.none+";"},ie=function(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e},oe=function(){return(oe=Object.assign||function(e){for(var t,n=1,r=arguments.length;n span {\n ","\n margin-left: ",";\n }\n\n &:hover {\n border-color: ",";\n background-color: ",";\n color: ",";\n text-decoration: none;\n\n .button-icon {\n fill: ",";\n }\n }\n\n &:active {\n ","\n }\n ","\n\n &:focus {\n outline: none;\n }\n\n .button-icon {\n height: ",";\n width: ",";\n fill: ",";\n }\n\n .ntd-spinner {\n fill: none;\n stroke-width: 17px;\n stroke-dasharray: 100;\n stroke-dashoffset: 100;\n animation: ntd-draw 1s linear infinite;\n stroke: ",";\n width: 24px;\n }\n\n .path {\n stroke: ",";\n }\n\n @keyframes ntd-draw {\n to {\n stroke-dashoffset: 0;\n }\n }\n }\n"],["\n && {\n display: flex;\n justify-content: center;\n align-items: center;\n position: relative;\n ","\n\n width: ",";\n height: ",";\n\n font-weight: 500;\n font-size: ",";\n line-height: ",";\n white-space: nowrap;\n word-break: keep-all;\n\n cursor: pointer;\n opacity: ",";\n pointer-events: ",";\n\n ","\n ","\n transition: all 150ms;\n\n background-color: ",";\n color: ",";\n\n border-width: 1px;\n border-style: solid;\n border-color: ",";\n border-radius: 4px;\n box-sizing: border-box;\n\n text-decoration: none;\n & > span {\n ","\n margin-left: ",";\n }\n\n &:hover {\n border-color: ",";\n background-color: ",";\n color: ",";\n text-decoration: none;\n\n .button-icon {\n fill: ",";\n }\n }\n\n &:active {\n ","\n }\n ","\n\n &:focus {\n outline: none;\n }\n\n .button-icon {\n height: ",";\n width: ",";\n fill: ",";\n }\n\n .ntd-spinner {\n fill: none;\n stroke-width: 17px;\n stroke-dasharray: 100;\n stroke-dashoffset: 100;\n animation: ntd-draw 1s linear infinite;\n stroke: ",";\n width: 24px;\n }\n\n .path {\n stroke: ",";\n }\n\n @keyframes ntd-draw {\n to {\n stroke-dashoffset: 0;\n }\n }\n }\n"])),te,(function(e){return e.width?e.width:e.hasLabel?Z(16):Z(e.small?3:4)}),(function(e){return e.hasLabel?Z(e.small?4:5):Z(e.small?3:4)}),(function(e){return e.small?"12px":"14px"}),Z(2),(function(e){var t=e.disabled;return e.neutral?1:t?.4:1}),(function(e){return e.disabled?"none":"auto"}),Q,J,(function(e){return e.colors.bg(e)}),(function(e){return e.colors.color(e)}),(function(e){return e.colors.border(e)}),re,(function(e){return e.hasIcon?Z(1.5):"0px"}),(function(e){return e.colors.borderHover(e)}),(function(e){return e.colors.bgHover(e)}),(function(e){return e.colors.colorHover(e)}),(function(e){return e.colors.colorHover(e)}),ce,(function(e){return e.active&&"\n "+ce+"\n "}),Z(2),Z(2),(function(e){return e.colors.color(e)}),(function(e){return e.colors.color(e)}),(function(e){return e.colors.color(e)})),ge=function(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e},me=s.d.svg.withConfig({displayName:"loader__StyledSvg",componentId:"sc-1mq98qd-0"})(A||(A=ge(["\n fill: none;\n stroke-width: 17px;\n stroke-dasharray: 100;\n stroke-dashoffset: 100;\n animation: ntd-draw 1s linear infinite;\n stroke: ",";\n width: 24px;\n .path {\n stroke: ",";\n }\n\n @keyframes ntd-draw {\n to {\n stroke-dashoffset: 0;\n }\n }\n"],["\n fill: none;\n stroke-width: 17px;\n stroke-dasharray: 100;\n stroke-dashoffset: 100;\n animation: ntd-draw 1s linear infinite;\n stroke: ",";\n width: 24px;\n .path {\n stroke: ",";\n }\n\n @keyframes ntd-draw {\n to {\n stroke-dashoffset: 0;\n }\n }\n"])),G("bright"),G("bright")),ye=function(e){var t=e.className;return c.a.createElement(me,{className:t,viewBox:"0 0 21 17",version:"1.1",xmlns:"http://www.w3.org/2000/svg"},c.a.createElement("g",{className:"path",stroke:"none",strokeWidth:"1",fill:"none",fillRule:"evenodd"},c.a.createElement("path",{d:"M2,1 C8.25086152,1 11.9367136,1 13.0575562,1 C14.73882,1 19.6834591,2 19.9614325,7.72050108 C20.239406,13.4410022 15.7459591,15.1224845 13.6463763,15.1224845 C12.2466545,15.1224845 10.0279195,15.1224845 6.9901715,15.1224845 L2,1 Z",id:"Path-2",strokeWidth:"2"})))},be=n(1),we=n.n(be),ke=n(2),xe=n.n(ke),je=new we.a({id:"add_node",use:"add_node-usage",viewBox:"0 0 18 18",content:''}),Me=(xe.a.add(je),je),_e=new we.a({id:"add_user",use:"add_user-usage",viewBox:"0 0 15 16",content:''}),Ce=(xe.a.add(_e),_e),qe=new we.a({id:"aggregation_avg",use:"aggregation_avg-usage",viewBox:"0 0 16 12",content:''}),Se=(xe.a.add(qe),qe),Te=new we.a({id:"aggregation_max",use:"aggregation_max-usage",viewBox:"0 0 15 16",content:''}),Oe=(xe.a.add(Te),Te),Ee=new we.a({id:"aggregation_med",use:"aggregation_med-usage",viewBox:"0 0 14 14",content:''}),Ae=(xe.a.add(Ee),Ee),Le=new we.a({id:"aggregation_min",use:"aggregation_min-usage",viewBox:"0 0 15 16",content:''}),He=(xe.a.add(Le),Le),De=new we.a({id:"aggregation_sum",use:"aggregation_sum-usage",viewBox:"0 0 12 14",content:''}),Pe=(xe.a.add(De),De),Ve=new we.a({id:"aggregation_sum_abs",use:"aggregation_sum_abs-usage",viewBox:"0 0 14 14",content:''}),Ne=(xe.a.add(Ve),Ve),Ie=new we.a({id:"alarm",use:"alarm-usage",viewBox:"0 0 18 21",content:''}),Re=(xe.a.add(Ie),Ie),Fe=new we.a({id:"alarm_c",use:"alarm_c-usage",viewBox:"0 0 24 24",content:''}),Be=(xe.a.add(Fe),Fe),Ue=new we.a({id:"alarm_cw",use:"alarm_cw-usage",viewBox:"0 0 24 24",content:''}),We=(xe.a.add(Ue),Ue),Ge=new we.a({id:"alarm_w",use:"alarm_w-usage",viewBox:"0 0 24 24",content:''}),Ye=(xe.a.add(Ge),Ge),Ze=new we.a({id:"alarm_bell",use:"alarm_bell-usage",viewBox:"0 0 12 14",content:''}),$e=(xe.a.add(Ze),Ze),Xe=new we.a({id:"alarms_new",use:"alarms_new-usage",viewBox:"0 0 22 20",content:''}),Ke=(xe.a.add(Xe),Xe),Qe=new we.a({id:"anomalies_brain",use:"anomalies_brain-usage",viewBox:"0 0 18 18",content:''}),Je=(xe.a.add(Qe),Qe),et=new we.a({id:"anomalies_lens",use:"anomalies_lens-usage",viewBox:"0 0 18 18",content:''}),tt=(xe.a.add(et),et),nt=new we.a({id:"around_clock",use:"around_clock-usage",viewBox:"0 0 16 16",content:''}),rt=(xe.a.add(nt),nt),it=new we.a({id:"arrow_down",use:"arrow_down-usage",viewBox:"0 0 16 16",content:''}),ot=(xe.a.add(it),it),at=new we.a({id:"arrow_w_line_left",use:"arrow_w_line_left-usage",viewBox:"0 0 26 24",content:''}),ct=(xe.a.add(at),at),st=new we.a({id:"arrow_w_line_right",use:"arrow_w_line_right-usage",viewBox:"0 0 24 13",content:''}),lt=(xe.a.add(st),st),ut=new we.a({id:"arrow_left",use:"arrow_left-usage",viewBox:"0 0 24 24",content:''}),ft=(xe.a.add(ut),ut),ht=new we.a({id:"arrow-s_down",use:"arrow-s_down-usage",viewBox:"0 0 8 9",content:''}),dt=(xe.a.add(ht),ht),pt=new we.a({id:"arrow-s_left",use:"arrow-s_left-usage",viewBox:"0 0 8 9",content:''}),zt=(xe.a.add(pt),pt),vt=new we.a({id:"arrows_vertical",use:"arrows_vertical-usage",viewBox:"0 0 6 10",content:''}),gt=(xe.a.add(vt),vt),mt=new we.a({id:"bookmark",use:"bookmark-usage",viewBox:"0 0 12 14",content:''}),yt=(xe.a.add(mt),mt),bt=new we.a({id:"bullet_one",use:"bullet_one-usage",viewBox:"0 0 10 10",content:''}),wt=(xe.a.add(bt),bt),kt=new we.a({id:"bullet_three",use:"bullet_three-usage",viewBox:"0 0 10 10",content:''}),xt=(xe.a.add(kt),kt),jt=new we.a({id:"bullet_two",use:"bullet_two-usage",viewBox:"0 0 10 10",content:''}),Mt=(xe.a.add(jt),jt),_t=new we.a({id:"calendar_full",use:"calendar_full-usage",viewBox:"0 0 18 18",content:''}),Ct=(xe.a.add(_t),_t),qt=new we.a({id:"calendar_full_press",use:"calendar_full_press-usage",viewBox:"0 0 18 18",content:''}),St=(xe.a.add(qt),qt),Tt=new we.a({id:"chart_added",use:"chart_added-usage",viewBox:"0 0 17 17",content:''}),Ot=(xe.a.add(Tt),Tt),Et=new we.a({id:"charts",use:"charts-usage",viewBox:"0 0 20 20",content:''}),At=(xe.a.add(Et),Et),Lt=new we.a({id:"check",use:"check-usage",viewBox:"0 0 24 24",content:''}),Ht=(xe.a.add(Lt),Lt),Dt=new we.a({id:"checkmark_partial_s",use:"checkmark_partial_s-usage",viewBox:"0 0 16 16",content:''}),Pt=(xe.a.add(Dt),Dt),Vt=new we.a({id:"checkmark_s",use:"checkmark_s-usage",viewBox:"0 0 16 16",content:''}),Nt=(xe.a.add(Vt),Vt),It=new we.a({id:"checkmark",use:"checkmark-usage",viewBox:"0 0 168 168",content:''}),Rt=(xe.a.add(It),It),Ft=new we.a({id:"chevron_double",use:"chevron_double-usage",viewBox:"0 0 6 10",content:''}),Bt=(xe.a.add(Ft),Ft),Ut=new we.a({id:"chevron_down",use:"chevron_down-usage",viewBox:"0 0 12 12",content:''}),Wt=(xe.a.add(Ut),Ut),Gt=new we.a({id:"chevron_left",use:"chevron_left-usage",viewBox:"0 0 24 24",content:''}),Yt=(xe.a.add(Gt),Gt),Zt=new we.a({id:"chevron_right_s",use:"chevron_right_s-usage",viewBox:"0 0 5 6",content:''}),$t=(xe.a.add(Zt),Zt),Xt=new we.a({id:"class_error",use:"class_error-usage",viewBox:"0 0 21 22",content:''}),Kt=(xe.a.add(Xt),Xt),Qt=new we.a({id:"class_latency",use:"class_latency-usage",viewBox:"0 0 21 20",content:''}),Jt=(xe.a.add(Qt),Qt),en=new we.a({id:"class_utilization",use:"class_utilization-usage",viewBox:"0 0 25 19",content:''}),tn=(xe.a.add(en),en),nn=new we.a({id:"class_workload",use:"class_workload-usage",viewBox:"0 0 22 21",content:''}),rn=(xe.a.add(nn),nn),on=new we.a({id:"clock_5_min",use:"clock_5_min-usage",viewBox:"0 0 18 18",content:''}),an=(xe.a.add(on),on),cn=new we.a({id:"clock_5_min_press",use:"clock_5_min_press-usage",viewBox:"0 0 18 18",content:''}),sn=(xe.a.add(cn),cn),ln=new we.a({id:"cluster",use:"cluster-usage",viewBox:"0 0 22 22",content:''}),un=(xe.a.add(ln),ln),fn=new we.a({id:"cluster_spaces",use:"cluster_spaces-usage",viewBox:"0 0 22 22",content:''}),hn=(xe.a.add(fn),fn),dn=new we.a({id:"code",use:"code-usage",viewBox:"0 0 16 16",content:''}),pn=(xe.a.add(dn),dn),zn=new we.a({id:"collapse",use:"collapse-usage",viewBox:"0 0 16 2",content:''}),vn=(xe.a.add(zn),zn),gn=new we.a({id:"community",use:"community-usage",viewBox:"0 0 18 18",content:''}),mn=(xe.a.add(gn),gn),yn=new we.a({id:"connectivity_status_live",use:"connectivity_status_live-usage",viewBox:"0 0 18 18",content:''}),bn=(xe.a.add(yn),yn),wn=new we.a({id:"connectivity_status_offline",use:"connectivity_status_offline-usage",viewBox:"0 0 18 18",content:''}),kn=(xe.a.add(wn),wn),xn=new we.a({id:"connectivity_status_stale",use:"connectivity_status_stale-usage",viewBox:"0 0 18 18",content:''}),jn=(xe.a.add(xn),xn),Mn=new we.a({id:"container",use:"container-usage",viewBox:"0 0 22 22",content:''}),_n=(xe.a.add(Mn),Mn),Cn=new we.a({id:"controller_kind",use:"controller_kind-usage",viewBox:"0 0 22 22",content:''}),qn=(xe.a.add(Cn),Cn),Sn=new we.a({id:"controller_name",use:"controller_name-usage",viewBox:"0 0 22 22",content:''}),Tn=(xe.a.add(Sn),Sn),On=new we.a({id:"copy",use:"copy-usage",viewBox:"0 0 14 14",content:''}),En=(xe.a.add(On),On),An=new we.a({id:"correlation",use:"correlation-usage",viewBox:"0 0 28 28",content:''}),Ln=(xe.a.add(An),An),Hn=new we.a({id:"correlation_inv",use:"correlation_inv-usage",viewBox:"0 0 24 24",content:''}),Dn=(xe.a.add(Hn),Hn),Pn=new we.a({id:"cpu",use:"cpu-usage",viewBox:"0 0 18 18",content:''}),Vn=(xe.a.add(Pn),Pn),Nn=new we.a({id:"cross_s",use:"cross_s-usage",viewBox:"0 0 16 16",content:''}),In=(xe.a.add(Nn),Nn),Rn=new we.a({id:"database",use:"database-usage",viewBox:"0 0 24 24",content:''}),Fn=(xe.a.add(Rn),Rn),Bn=new we.a({id:"dashboard",use:"dashboard-usage",viewBox:"0 0 22 18",content:''}),Un=(xe.a.add(Bn),Bn),Wn=new we.a({id:"dashboard_add",use:"dashboard_add-usage",viewBox:"0 0 16 16",content:''}),Gn=(xe.a.add(Wn),Wn),Yn=new we.a({id:"dashboards",use:"dashboards-usage",viewBox:"0 0 16 10",content:''}),Zn=(xe.a.add(Yn),Yn),$n=new we.a({id:"disk",use:"disk-usage",viewBox:"0 0 18 18",content:''}),Xn=(xe.a.add($n),$n),Kn=new we.a({id:"documentation",use:"documentation-usage",viewBox:"0 0 24 24",content:''}),Qn=(xe.a.add(Kn),Kn),Jn=new we.a({id:"dot",use:"dot-usage",viewBox:"0 0 10 10",content:''}),er=(xe.a.add(Jn),Jn),tr=new we.a({id:"dots_2x3",use:"dots_2x3-usage",viewBox:"0 0 6 10",content:''}),nr=(xe.a.add(tr),tr),rr=new we.a({id:"download",use:"download-usage",viewBox:"0 0 20 20",content:''}),ir=(xe.a.add(rr),rr),or=new we.a({id:"error",use:"error-usage",viewBox:"0 0 24 24",content:''}),ar=(xe.a.add(or),or),cr=new we.a({id:"exclamation",use:"exclamation-usage",viewBox:"0 0 24 24",content:''}),sr=(xe.a.add(cr),cr),lr=new we.a({id:"expand",use:"expand-usage",viewBox:"0 0 24 24",content:''}),ur=(xe.a.add(lr),lr),fr=new we.a({id:"filterList",use:"filterList-usage",viewBox:"0 0 18 18",content:''}),hr=(xe.a.add(fr),fr),dr=new we.a({id:"force_play",use:"force_play-usage",viewBox:"0 0 18 18",content:''}),pr=(xe.a.add(dr),dr),zr=new we.a({id:"force_play_outline",use:"force_play_outline-usage",viewBox:"0 0 18 18",content:''}),vr=(xe.a.add(zr),zr),gr=new we.a({id:"gear",use:"gear-usage",viewBox:"0 0 20 20",content:''}),mr=(xe.a.add(gr),gr),yr=new we.a({id:"github",use:"github-usage",viewBox:"0 0 24 24",content:''}),br=(xe.a.add(yr),yr),wr=new we.a({id:"go_to_node",use:"go_to_node-usage",viewBox:"0 0 18 18",content:''}),kr=(xe.a.add(wr),wr),xr=new we.a({id:"google",use:"google-usage",viewBox:"0 0 24 24",content:''}),jr=(xe.a.add(xr),xr),Mr=new we.a({id:"group_by",use:"group_by-usage",viewBox:"0 0 18 18",content:''}),_r=(xe.a.add(Mr),Mr),Cr=new we.a({id:"hamburger",use:"hamburger-usage",viewBox:"0 0 24 24",content:''}),qr=(xe.a.add(Cr),Cr),Sr=new we.a({id:"help",use:"help-usage",viewBox:"0 0 20 21",content:''}),Tr=(xe.a.add(Sr),Sr),Or=new we.a({id:"hide",use:"hide-usage",viewBox:"0 0 18 18",content:''}),Er=(xe.a.add(Or),Or),Ar=new we.a({id:"holder",use:"holder-usage",viewBox:"0 0 24 24",content:''}),Lr=(xe.a.add(Ar),Ar),Hr=new we.a({id:"information",use:"information-usage",viewBox:"0 0 18 18",content:''}),Dr=(xe.a.add(Hr),Hr),Pr=new we.a({id:"information_press",use:"information_press-usage",viewBox:"0 0 18 18",content:''}),Vr=(xe.a.add(Pr),Pr),Nr=new we.a({id:"insights",use:"insights-usage",viewBox:"0 0 18 18",content:''}),Ir=(xe.a.add(Nr),Nr),Rr=new we.a({id:"integrations",use:"integrations-usage",viewBox:"0 0 16 16",content:''}),Fr=(xe.a.add(Rr),Rr),Br=new we.a({id:"line_chart",use:"line_chart-usage",viewBox:"0 0 15 15",content:''}),Ur=(xe.a.add(Br),Br),Wr=new we.a({id:"logo_s",use:"logo_s-usage",viewBox:"0 0 14 13",content:''}),Gr=(xe.a.add(Wr),Wr),Yr=new we.a({id:"loading",use:"loading-usage",viewBox:"0 0 24 24",content:''}),Zr=(xe.a.add(Yr),Yr),$r=new we.a({id:"magnify",use:"magnify-usage",viewBox:"0 0 24 24",content:''}),Xr=(xe.a.add($r),$r),Kr=new we.a({id:"metrics_explorer",use:"metrics_explorer-usage",viewBox:"0 0 18 18",content:''}),Qr=(xe.a.add(Kr),Kr),Jr=new we.a({id:"more",use:"more-usage",viewBox:"0 0 18 4",content:''}),ei=(xe.a.add(Jr),Jr),ti=new we.a({id:"nav_left",use:"nav_left-usage",viewBox:"0 0 8 10",content:''}),ni=(xe.a.add(ti),ti),ri=new we.a({id:"nav_right",use:"nav_right-usage",viewBox:"0 0 8 10",content:''}),ii=(xe.a.add(ri),ri),oi=new we.a({id:"nav_arrow_goto",use:"nav_arrow_goto-usage",viewBox:"0 0 10 10",content:''}),ai=(xe.a.add(oi),oi),ci=new we.a({id:"nav_dots",use:"nav_dots-usage",viewBox:"0 0 24 24",content:''}),si=(xe.a.add(ci),ci),li=new we.a({id:"netdata",use:"netdata-usage",viewBox:"0 0 24 24",content:''}),ui=(xe.a.add(li),li),fi=new we.a({id:"netdata-press",use:"netdata-press-usage",viewBox:"0 0 18 18",content:''}),hi=(xe.a.add(fi),fi),di=new we.a({id:"node",use:"node-usage",viewBox:"0 0 24 24",content:''}),pi=(xe.a.add(di),di),zi=new we.a({id:"node_child",use:"node_child-usage",viewBox:"0 0 18 18",content:''}),vi=(xe.a.add(zi),zi),gi=new we.a({id:"node_default_l",use:"node_default_l-usage",viewBox:"0 0 40 40",content:''}),mi=(xe.a.add(gi),gi),yi=new we.a({id:"node_hollow",use:"node_hollow-usage",viewBox:"0 0 22 12",content:''}),bi=(xe.a.add(yi),yi),wi=new we.a({id:"node_import_export",use:"node_import_export-usage",viewBox:"0 0 24 24",content:''}),ki=(xe.a.add(wi),wi),xi=new we.a({id:"node_notification_l",use:"node_notification_l-usage",viewBox:"0 0 40 40",content:''}),ji=(xe.a.add(xi),xi),Mi=new we.a({id:"node_parent",use:"node_parent-usage",viewBox:"0 0 18 18",content:''}),_i=(xe.a.add(Mi),Mi),Ci=new we.a({id:"node_selected_l",use:"node_selected_l-usage",viewBox:"0 0 40 40",content:''}),qi=(xe.a.add(Ci),Ci),Si=new we.a({id:"nodes",use:"nodes-usage",viewBox:"0 0 16 16",content:''}),Ti=(xe.a.add(Si),Si),Oi=new we.a({id:"nodes_hollow",use:"nodes_hollow-usage",viewBox:"0 0 18 18",content:''}),Ei=(xe.a.add(Oi),Oi),Ai=new we.a({id:"none_selected",use:"none_selected-usage",viewBox:"0 0 16 16",content:''}),Li=(xe.a.add(Ai),Ai),Hi=new we.a({id:"os",use:"os-usage",viewBox:"0 0 18 18",content:''}),Di=(xe.a.add(Hi),Hi),Pi=new we.a({id:"alpine_linux",use:"alpine_linux-usage",viewBox:"0 0 18 18",content:''}),Vi=(xe.a.add(Pi),Pi),Ni=new we.a({id:"amazon_linux",use:"amazon_linux-usage",viewBox:"0 0 18 18",content:''}),Ii=(xe.a.add(Ni),Ni),Ri=new we.a({id:"arch_linux",use:"arch_linux-usage",viewBox:"0 0 18 18",content:''}),Fi=(xe.a.add(Ri),Ri),Bi=new we.a({id:"celarOS",use:"celarOS-usage",viewBox:"0 0 18 18",content:''}),Ui=(xe.a.add(Bi),Bi),Wi=new we.a({id:"centos",use:"centos-usage",viewBox:"0 0 18 18",content:''}),Gi=(xe.a.add(Wi),Wi),Yi=new we.a({id:"centos_color",use:"centos_color-usage",viewBox:"0 0 18 18",content:''}),Zi=(xe.a.add(Yi),Yi),$i=new we.a({id:"coreOS",use:"coreOS-usage",viewBox:"0 0 18 18",content:''}),Xi=(xe.a.add($i),$i),Ki=new we.a({id:"debian",use:"debian-usage",viewBox:"0 0 18 18",content:''}),Qi=(xe.a.add(Ki),Ki),Ji=new we.a({id:"debian_color",use:"debian_color-usage",viewBox:"0 0 18 18",content:''}),eo=(xe.a.add(Ji),Ji),to=new we.a({id:"fedora",use:"fedora-usage",viewBox:"0 0 18 18",content:''}),no=(xe.a.add(to),to),ro=new we.a({id:"freeBSD",use:"freeBSD-usage",viewBox:"0 0 18 18",content:''}),io=(xe.a.add(ro),ro),oo=new we.a({id:"gentoo",use:"gentoo-usage",viewBox:"0 0 18 18",content:''}),ao=(xe.a.add(oo),oo),co=new we.a({id:"linux",use:"linux-usage",viewBox:"0 0 18 18",content:''}),so=(xe.a.add(co),co),lo=new we.a({id:"linux_color",use:"linux_color-usage",viewBox:"0 0 18 18",content:''}),uo=(xe.a.add(lo),lo),fo=new we.a({id:"macOSX",use:"macOSX-usage",viewBox:"0 0 18 18",content:''}),ho=(xe.a.add(fo),fo),po=new we.a({id:"oracle",use:"oracle-usage",viewBox:"0 0 18 18",content:''}),zo=(xe.a.add(po),po),vo=new we.a({id:"oracle_color",use:"oracle_color-usage",viewBox:"0 0 18 18",content:''}),go=(xe.a.add(vo),vo),mo=new we.a({id:"os_press",use:"os_press-usage",viewBox:"0 0 18 18",content:''}),yo=(xe.a.add(mo),mo),bo=new we.a({id:"raspbian",use:"raspbian-usage",viewBox:"0 0 18 18",content:''}),wo=(xe.a.add(bo),bo),ko=new we.a({id:"red_hat",use:"red_hat-usage",viewBox:"0 0 18 18",content:''}),xo=(xe.a.add(ko),ko),jo=new we.a({id:"suse_linux",use:"suse_linux-usage",viewBox:"0 0 18 18",content:''}),Mo=(xe.a.add(jo),jo),_o=new we.a({id:"ubuntu",use:"ubuntu-usage",viewBox:"0 0 18 18",content:''}),Co=(xe.a.add(_o),_o),qo=new we.a({id:"ubuntu_color",use:"ubuntu_color-usage",viewBox:"0 0 18 18",content:''}),So=(xe.a.add(qo),qo),To=new we.a({id:"notification",use:"notification-usage",viewBox:"0 0 40 24",content:''}),Oo=(xe.a.add(To),To),Eo=new we.a({id:"padlock",use:"padlock-usage",viewBox:"0 0 18 18",content:''}),Ao=(xe.a.add(Eo),Eo),Lo=new we.a({id:"pause_outline",use:"pause_outline-usage",viewBox:"0 0 18 18",content:''}),Ho=(xe.a.add(Lo),Lo),Do=new we.a({id:"pause_solid",use:"pause_solid-usage",viewBox:"0 0 24 24",content:''}),Po=(xe.a.add(Do),Do),Vo=new we.a({id:"pencil",use:"pencil-usage",viewBox:"0 0 19 19",content:''}),No=(xe.a.add(Vo),Vo),Io=new we.a({id:"pin_element",use:"pin_element-usage",viewBox:"0 0 14 14",content:''}),Ro=(xe.a.add(Io),Io),Fo=new we.a({id:"play_outline",use:"play_outline-usage",viewBox:"0 0 18 18",content:''}),Bo=(xe.a.add(Fo),Fo),Uo=new we.a({id:"play_solid",use:"play_solid-usage",viewBox:"0 0 24 24",content:''}),Wo=(xe.a.add(Uo),Uo),Go=new we.a({id:"plus",use:"plus-usage",viewBox:"0 0 24 24",content:''}),Yo=(xe.a.add(Go),Go),Zo=new we.a({id:"plus_mini_s",use:"plus_mini_s-usage",viewBox:"0 0 24 24",content:''}),$o=(xe.a.add(Zo),Zo),Xo=new we.a({id:"pod",use:"pod-usage",viewBox:"0 0 22 22",content:''}),Ko=(xe.a.add(Xo),Xo),Qo=new we.a({id:"print",use:"print-usage",viewBox:"0 0 21 20",content:''}),Jo=(xe.a.add(Qo),Qo),ea=new we.a({id:"question",use:"question-usage",viewBox:"0 0 20 20",content:''}),ta=(xe.a.add(ea),ea),na=new we.a({id:"questionFilled",use:"questionFilled-usage",viewBox:"0 0 24 24",content:''}),ra=(xe.a.add(na),na),ia=new we.a({id:"ram",use:"ram-usage",viewBox:"0 0 18 18",content:''}),oa=(xe.a.add(ia),ia),aa=new we.a({id:"refresh",use:"refresh-usage",viewBox:"0 0 18 19",content:''}),ca=(xe.a.add(aa),aa),sa=new we.a({id:"reload",use:"reload-usage",viewBox:"0 0 24 24",content:''}),la=(xe.a.add(sa),sa),ua=new we.a({id:"resize_handler",use:"resize_handler-usage",viewBox:"0 0 16 16",content:''}),fa=(xe.a.add(ua),ua),ha=new we.a({id:"room",use:"room-usage",viewBox:"0 0 24 24",content:''}),da=(xe.a.add(ha),ha),pa=new we.a({id:"room_new",use:"room_new-usage",viewBox:"0 0 20 20",content:''}),za=(xe.a.add(pa),pa),va=new we.a({id:"room_overview",use:"room_overview-usage",viewBox:"0 0 24 25",content:''}),ga=(xe.a.add(va),va),ma=new we.a({id:"sad",use:"sad-usage",viewBox:"0 0 24 24",content:''}),ya=(xe.a.add(ma),ma),ba=new we.a({id:"save",use:"save-usage",viewBox:"0 0 14 14",content:''}),wa=(xe.a.add(ba),ba),ka=new we.a({id:"search",use:"search-usage",viewBox:"0 0 18 18",content:''}),xa=(xe.a.add(ka),ka),ja=new we.a({id:"search_s",use:"search_s-usage",viewBox:"0 0 14 14",content:''}),Ma=(xe.a.add(ja),ja),_a=new we.a({id:"search_press",use:"search_press-usage",viewBox:"0 0 18 18",content:''}),Ca=(xe.a.add(_a),_a),qa=new we.a({id:"apache",use:"apache-usage",viewBox:"0 0 18 18",content:''}),Sa=(xe.a.add(qa),qa),Ta=new we.a({id:"apache_tomcat",use:"apache_tomcat-usage",viewBox:"0 0 18 18",content:''}),Oa=(xe.a.add(Ta),Ta),Ea=new we.a({id:"beanstalk",use:"beanstalk-usage",viewBox:"0 0 18 18",content:''}),Aa=(xe.a.add(Ea),Ea),La=new we.a({id:"couchDB",use:"couchDB-usage",viewBox:"0 0 18 18",content:''}),Ha=(xe.a.add(La),La),Da=new we.a({id:"database",use:"database-usage",viewBox:"0 0 18 18",content:''}),Pa=(xe.a.add(Da),Da),Va=new we.a({id:"docker_hub",use:"docker_hub-usage",viewBox:"0 0 18 18",content:''}),Na=(xe.a.add(Va),Va),Ia=new we.a({id:"docker_hub_press",use:"docker_hub_press-usage",viewBox:"0 0 18 18",content:''}),Ra=(xe.a.add(Ia),Ia),Fa=new we.a({id:"eBPF",use:"eBPF-usage",viewBox:"0 0 18 18",content:''}),Ba=(xe.a.add(Fa),Fa),Ua=new we.a({id:"elasticSearch",use:"elasticSearch-usage",viewBox:"0 0 18 18",content:''}),Wa=(xe.a.add(Ua),Ua),Ga=new we.a({id:"freeNAS",use:"freeNAS-usage",viewBox:"0 0 18 18",content:''}),Ya=(xe.a.add(Ga),Ga),Za=new we.a({id:"haProxy",use:"haProxy-usage",viewBox:"0 0 18 18",content:''}),$a=(xe.a.add(Za),Za),Xa=new we.a({id:"httpCheck",use:"httpCheck-usage",viewBox:"0 0 18 18",content:''}),Ka=(xe.a.add(Xa),Xa),Qa=new we.a({id:"iceCast",use:"iceCast-usage",viewBox:"0 0 18 18",content:''}),Ja=(xe.a.add(Qa),Qa),ec=new we.a({id:"influxDB",use:"influxDB-usage",viewBox:"0 0 18 18",content:''}),tc=(xe.a.add(ec),ec),nc=new we.a({id:"ipfs",use:"ipfs-usage",viewBox:"0 0 18 18",content:''}),rc=(xe.a.add(nc),nc),ic=new we.a({id:"ipvs",use:"ipvs-usage",viewBox:"0 0 18 18",content:''}),oc=(xe.a.add(ic),ic),ac=new we.a({id:"kubermetes",use:"kubermetes-usage",viewBox:"0 0 18 18",content:''}),cc=(xe.a.add(ac),ac),sc=new we.a({id:"lighthttpd",use:"lighthttpd-usage",viewBox:"0 0 18 18",content:''}),lc=(xe.a.add(sc),sc),uc=new we.a({id:"lighthttpd2",use:"lighthttpd2-usage",viewBox:"0 0 18 18",content:''}),fc=(xe.a.add(uc),uc),hc=new we.a({id:"liteSpeed",use:"liteSpeed-usage",viewBox:"0 0 18 18",content:''}),dc=(xe.a.add(hc),hc),pc=new we.a({id:"lxc",use:"lxc-usage",viewBox:"0 0 18 18",content:''}),zc=(xe.a.add(pc),pc),vc=new we.a({id:"mariaDB",use:"mariaDB-usage",viewBox:"0 0 18 18",content:''}),gc=(xe.a.add(vc),vc),mc=new we.a({id:"memCached",use:"memCached-usage",viewBox:"0 0 18 18",content:''}),yc=(xe.a.add(mc),mc),bc=new we.a({id:"mongoDB",use:"mongoDB-usage",viewBox:"0 0 18 18",content:''}),wc=(xe.a.add(bc),bc),kc=new we.a({id:"mySQL",use:"mySQL-usage",viewBox:"0 0 18 18",content:''}),xc=(xe.a.add(kc),kc),jc=new we.a({id:"mySQL_press",use:"mySQL_press-usage",viewBox:"0 0 18 18",content:''}),Mc=(xe.a.add(jc),jc),_c=new we.a({id:"nginx",use:"nginx-usage",viewBox:"0 0 18 18",content:''}),Cc=(xe.a.add(_c),_c),qc=new we.a({id:"nginx_local",use:"nginx_local-usage",viewBox:"0 0 18 18",content:''}),Sc=(xe.a.add(qc),qc),Tc=new we.a({id:"nginx_plus",use:"nginx_plus-usage",viewBox:"0 0 18 18",content:''}),Oc=(xe.a.add(Tc),Tc),Ec=new we.a({id:"ntpd",use:"ntpd-usage",viewBox:"0 0 18 18",content:''}),Ac=(xe.a.add(Ec),Ec),Lc=new we.a({id:"ntpd_press",use:"ntpd_press-usage",viewBox:"0 0 18 18",content:''}),Hc=(xe.a.add(Lc),Lc),Dc=new we.a({id:"openStack",use:"openStack-usage",viewBox:"0 0 18 18",content:''}),Pc=(xe.a.add(Dc),Dc),Vc=new we.a({id:"openWrt",use:"openWrt-usage",viewBox:"0 0 18 18",content:''}),Nc=(xe.a.add(Vc),Vc),Ic=new we.a({id:"pan",use:"pan-usage",viewBox:"0 0 18 18",content:''}),Rc=(xe.a.add(Ic),Ic),Fc=new we.a({id:"percona",use:"percona-usage",viewBox:"0 0 18 18",content:''}),Bc=(xe.a.add(Fc),Fc),Uc=new we.a({id:"pfSense",use:"pfSense-usage",viewBox:"0 0 18 18",content:''}),Wc=(xe.a.add(Uc),Uc),Gc=new we.a({id:"php_fpm",use:"php_fpm-usage",viewBox:"0 0 18 18",content:''}),Yc=(xe.a.add(Gc),Gc),Zc=new we.a({id:"postgreSQL",use:"postgreSQL-usage",viewBox:"0 0 18 18",content:''}),$c=(xe.a.add(Zc),Zc),Xc=new we.a({id:"rabbitMQ",use:"rabbitMQ-usage",viewBox:"0 0 18 18",content:''}),Kc=(xe.a.add(Xc),Xc),Qc=new we.a({id:"redis",use:"redis-usage",viewBox:"0 0 18 18",content:''}),Jc=(xe.a.add(Qc),Qc),es=new we.a({id:"rethinkDB",use:"rethinkDB-usage",viewBox:"0 0 18 18",content:''}),ts=(xe.a.add(es),es),ns=new we.a({id:"retroShare",use:"retroShare-usage",viewBox:"0 0 18 18",content:''}),rs=(xe.a.add(ns),ns),is=new we.a({id:"services",use:"services-usage",viewBox:"0 0 18 18",content:''}),os=(xe.a.add(is),is),as=new we.a({id:"selected_area",use:"selected_area-usage",viewBox:"0 0 18 18",content:''}),cs=(xe.a.add(as),as),ss=new we.a({id:"solr",use:"solr-usage",viewBox:"0 0 18 18",content:''}),ls=(xe.a.add(ss),ss),us=new we.a({id:"squid",use:"squid-usage",viewBox:"0 0 18 18",content:''}),fs=(xe.a.add(us),us),hs=new we.a({id:"summary_statistic",use:"summary_statistic-usage",viewBox:"0 0 18 18",content:''}),ds=(xe.a.add(hs),hs),ps=new we.a({id:"traefik",use:"traefik-usage",viewBox:"0 0 18 18",content:''}),zs=(xe.a.add(ps),ps),vs=new we.a({id:"varnish",use:"varnish-usage",viewBox:"0 0 18 18",content:''}),gs=(xe.a.add(vs),vs),ms=new we.a({id:"webLog",use:"webLog-usage",viewBox:"0 0 18 18",content:''}),ys=(xe.a.add(ms),ms),bs=new we.a({id:"webLog_nginx",use:"webLog_nginx-usage",viewBox:"0 0 18 18",content:''}),ws=(xe.a.add(bs),bs),ks=new we.a({id:"x509_check",use:"x509_check-usage",viewBox:"0 0 18 18",content:''}),xs=(xe.a.add(ks),ks),js=new we.a({id:"xen",use:"xen-usage",viewBox:"0 0 18 18",content:''}),Ms=(xe.a.add(js),js),_s=new we.a({id:"settings",use:"settings-usage",viewBox:"0 0 17 15",content:''}),Cs=(xe.a.add(_s),_s),qs=new we.a({id:"settings_h",use:"settings_h-usage",viewBox:"0 0 14 14",content:''}),Ss=(xe.a.add(qs),qs),Ts=new we.a({id:"sorting_vertical",use:"sorting_vertical-usage",viewBox:"0 0 19 18",content:''}),Os=(xe.a.add(Ts),Ts),Es=new we.a({id:"space",use:"space-usage",viewBox:"0 0 24 24",content:''}),As=(xe.a.add(Es),Es),Ls=new we.a({id:"space_new",use:"space_new-usage",viewBox:"0 0 20 20",content:''}),Hs=(xe.a.add(Ls),Ls),Ds=new we.a({id:"switch_off",use:"switch_off-usage",viewBox:"0 0 14 15",content:''}),Ps=(xe.a.add(Ds),Ds),Vs=new we.a({id:"system_overview",use:"system_overview-usage",viewBox:"0 0 32 32",content:''}),Ns=(xe.a.add(Vs),Vs),Is=new we.a({id:"text_add",use:"text_add-usage",viewBox:"0 0 16 16",content:''}),Rs=(xe.a.add(Is),Is),Fs=new we.a({id:"thumb_down",use:"thumb_down-usage",viewBox:"0 0 24 24",content:''}),Bs=(xe.a.add(Fs),Fs),Us=new we.a({id:"thumb_up",use:"thumb_up-usage",viewBox:"0 0 24 24",content:''}),Ws=(xe.a.add(Us),Us),Gs=new we.a({id:"tiny_buttons",use:"tiny_buttons-usage",viewBox:"0 0 22 22",content:''}),Ys=(xe.a.add(Gs),Gs),Zs=new we.a({id:"training",use:"training-usage",viewBox:"0 0 16 16",content:''}),$s=(xe.a.add(Zs),Zs),Xs=new we.a({id:"trashcan",use:"trashcan-usage",viewBox:"0 0 14 15",content:''}),Ks=(xe.a.add(Xs),Xs),Qs=new we.a({id:"triangle",use:"triangle-usage",viewBox:"0 0 24 24",content:''}),Js=(xe.a.add(Qs),Qs),el=new we.a({id:"triangle_down",use:"triangle_down-usage",viewBox:"0 0 10 5",content:''}),tl=(xe.a.add(el),el),nl=new we.a({id:"unknownError",use:"unknownError-usage",viewBox:"0 0 16 16",content:''}),rl=(xe.a.add(nl),nl),il=new we.a({id:"unreachable",use:"unreachable-usage",viewBox:"0 0 12 14",content:''}),ol=(xe.a.add(il),il),al=new we.a({id:"unreachableNode",use:"unreachableNode-usage",viewBox:"0 0 231 230",content:''}),cl=(xe.a.add(al),al),sl=new we.a({id:"update",use:"update-usage",viewBox:"0 0 20 20",content:''}),ll=(xe.a.add(sl),sl),ul=new we.a({id:"update_pending",use:"update_pending-usage",viewBox:"0 0 20 20",content:''}),fl=(xe.a.add(ul),ul),hl=new we.a({id:"upload",use:"upload-usage",viewBox:"0 0 20 21",content:''}),dl=(xe.a.add(hl),hl),pl=new we.a({id:"user",use:"user-usage",viewBox:"0 0 16 18",content:''}),zl=(xe.a.add(pl),pl),vl=new we.a({id:"users",use:"users-usage",viewBox:"0 0 14 14",content:''}),gl=(xe.a.add(vl),vl),ml=new we.a({id:"view_list",use:"view_list-usage",viewBox:"0 0 24 24",content:''}),yl=(xe.a.add(ml),ml),bl=new we.a({id:"single_node_view",use:"single_node_view-usage",viewBox:"0 0 18 18",content:''}),wl=(xe.a.add(bl),bl),kl=new we.a({id:"single_node_view_press",use:"single_node_view_press-usage",viewBox:"0 0 18 18",content:''}),xl=(xe.a.add(kl),kl),jl=new we.a({id:"virtualization",use:"virtualization-usage",viewBox:"0 0 16 16",content:''}),Ml=(xe.a.add(jl),jl),_l=new we.a({id:"warning",use:"warning-usage",viewBox:"0 0 24 24",content:''}),Cl=(xe.a.add(_l),_l),ql=new we.a({id:"warning_triangle",use:"warning_triangle-usage",viewBox:"0 0 12 10",content:''}),Sl=(xe.a.add(ql),ql),Tl=new we.a({id:"warning_triangle_hollow",use:"warning_triangle_hollow-usage",viewBox:"0 0 24 24",content:''}),Ol=(xe.a.add(Tl),Tl),El=new we.a({id:"x",use:"x-usage",viewBox:"0 0 24 24",content:''}),Al=(xe.a.add(El),El),Ll=new we.a({id:"firewall_solid",use:"firewall_solid-usage",viewBox:"0 0 24 24",content:''}),Hl=(xe.a.add(Ll),Ll),Dl=new we.a({id:"qualityOfService_solid",use:"qualityOfService_solid-usage",viewBox:"0 0 24 24",content:''}),Pl=(xe.a.add(Dl),Dl),Vl=new we.a({id:"applications_solid",use:"applications_solid-usage",viewBox:"0 0 24 24",content:''}),Nl=(xe.a.add(Vl),Vl),Il=new we.a({id:"networking_stack",use:"networking_stack-usage",viewBox:"0 0 18 18",content:''}),Rl=(xe.a.add(Il),Il),Fl=new we.a({id:"charts_view",use:"charts_view-usage",viewBox:"0 0 16 15",content:''}),Bl=(xe.a.add(Fl),Fl),Ul=new we.a({id:"nodes_update",use:"nodes_update-usage",viewBox:"0 0 40 40",content:''}),Wl=(xe.a.add(Ul),{add_node:Me,add_user:Ce,aggregation_avg:Se,aggregation_max:Oe,aggregation_med:Ae,aggregation_min:He,aggregation_sum:Pe,aggregation_sum_abs:Ne,alarm:Re,alarmCritical:Be,alarmCriticalWarning:We,alarmWarning:Ye,alarm_bell:$e,alarms_new:Ke,anomaliesBrain:Je,anomaliesLens:tt,applicationsSolid:Nl,around_clock:rt,arrow_down:ot,arrow_w_line_left:ct,arrow_w_line_right:lt,arrow_left:ft,arrow_s_down:dt,arrow_s_left:zt,arrows_vertical:gt,bookmark:yt,bullet_one:wt,bullet_three:xt,bullet_two:Mt,calendarFull:Ct,calendarFullPress:St,chart_added:Ot,charts:At,charts_view:Bl,check:Ht,checkmark_partial_s:Pt,checkmark_s:Nt,checkmark:Rt,chevron_double:Bt,chevron_down:Wt,chevron_left:Yt,chevron_right_s:$t,classError:Kt,classLatency:Jt,classUtilization:tn,classWorkload:rn,clock5Min:an,clock5MinPress:sn,cluster:un,cluster_spaces:hn,code:pn,collapse:vn,community:mn,connectivityStatusLive:bn,connectivityStatusOffline:kn,connectivityStatusStale:jn,container:_n,controller_kind:qn,controller_name:Tn,copy:En,correlation:Ln,correlation_inv:Dn,cpu:Vn,cross_s:In,database:Fn,dashboard:Un,dashboard_add:Gn,dashboards:Zn,disk:Xn,documentation:Qn,dot:er,dots_2x3:nr,download:ir,error:ar,exclamation:sr,expand:ur,filterList:hr,firewallSolid:Hl,forcePlay:pr,forcePlayOutline:vr,gear:mr,github:br,google:jr,goToNode:kr,group_by:_r,hamburger:qr,help:Tr,hide:Er,holder:Lr,information:Dr,informationPress:Vr,insights:Ir,integrations:Fr,line_chart:Ur,logo_s:Gr,loading:Zr,magnify:Xr,metrics_explorer:Qr,more:ei,navLeft:ni,navRight:ii,nav_arrow_goto:ai,nav_dots:si,networkingStack:Rl,netdata:ui,netdataPress:hi,node:pi,node_child:vi,node_default_l:mi,node_hollow:bi,node_import_export:ki,node_notification_l:ji,node_parent:_i,node_selected_l:qi,nodes:Ti,nodes_hollow:Ei,none_selected:Li,nodes_update:Ul,notification:Oo,os:Di,osAlpineLinux:Vi,osAmazonLinux:Ii,osArchLinux:Fi,osCelarOS:Ui,osCentos:Gi,osCentosColor:Zi,osCoreOS:Xi,osDebian:Qi,osDebianColor:eo,osFedora:no,osFreeBSD:io,osGentoo:ao,osLinux:so,osLinuxColor:uo,osMacOSX:ho,osOracle:zo,osOracleColor:go,osPress:yo,osRaspbian:wo,osRedHat:xo,osSuseLinux:Mo,osUbuntu:Co,osUbuntuColor:So,padlock:Ao,pauseOutline:Ho,pauseSolid:Po,pencil:No,pin_element:Ro,playOutline:Bo,playSolid:Wo,plus:Yo,plus_mini_s:$o,pod:Ko,print:Jo,ram:oa,qualityOfServiceSolid:Pl,question:ta,questionFilled:ra,refresh:ca,reload:la,resize_handler:fa,room:da,room_new:za,room_overview:ga,sad:ya,save:wa,search:xa,search_s:Ma,searchPress:Ca,serviceApache:Sa,serviceApacheTomcat:Oa,serviceBeanstalk:Aa,serviceCouchDB:Ha,serviceDatabase:Pa,serviceDockerHub:Na,serviceDockerHubPress:Ra,serviceEBPF:Ba,serviceElasticSearch:Wa,serviceFreeNAS:Ya,serviceHAProxy:$a,serviceHTTPCheck:Ka,serviceIceCast:Ja,serviceInfluxDB:tc,serviceIPFS:rc,serviceIPVS:oc,serviceKubernetes:cc,serviceLighthttpd:lc,serviceLighthttpd2:fc,serviceLiteSpeed:dc,serviceLxc:zc,serviceMariaDB:gc,serviceMemCached:yc,serviceMongoDB:wc,serviceMySQL:xc,serviceMySQLPress:Mc,serviceNginx:Cc,serviceNginxLocal:Sc,serviceNginxPlus:Oc,serviceNtpd:Ac,serviceNtpdPress:Hc,serviceOpenStack:Pc,serviceOpenWrt:Nc,servicePan:Rc,servicePercona:Bc,servicePfSense:Wc,servicePhpFpm:Yc,servicePostgreSQL:$c,serviceProxySQL:$c,serviceRabbitMQ:Kc,serviceRedis:Jc,serviceRethinkDB:ts,serviceRetroShare:rs,services:os,serviceSelectedArea:cs,serviceSolr:ls,serviceSquid:fs,serviceSummaryStatistic:ds,serviceTraefik:zs,serviceVarnish:gs,serviceWebLog:ys,serviceWebLogNginx:ws,serviceX509Check:xs,serviceXen:Ms,settings:Cs,settings_h:Ss,sorting_vertical:Os,space:As,space_new:Hs,switch_off:Ps,system_overview:Ns,text_add:Rs,thumb_down:Bs,thumb_up:Ws,tiny_buttons:Ys,training:$s,trashcan:Ks,triangle:Js,triangle_down:tl,unknownError:rl,unreachable:ol,unreachableNode:cl,update:ll,update_pending:fl,upload:dl,user:zl,users:gl,view_list:yl,viewSingleNode:wl,viewSingleNodePress:xl,virtualization:Ml,warning:Cl,warning_triangle:Sl,warning_triangle_hollow:Ol,x:Al}),Gl=function(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e},Yl={small:"16px",medium:"24px",large:"40px"},Zl=s.d.svg.withConfig({displayName:"styled__StyledIcon",componentId:"sc-1pjn63w-0"})(L||(L=Gl(["\n height: ",";\n width: ",";\n opacity: ",";\n pointer-events: ",";\n ","\n ","\n ","\n ","\n ","\n"],["\n height: ",";\n width: ",";\n opacity: ",";\n pointer-events: ",";\n ","\n ","\n ","\n ","\n ","\n"])),(function(e){var t=e.size;return e.height||Yl[t]}),(function(e){var t=e.size;return e.width||Yl[t]}),(function(e){return e.disabled?.3:1}),(function(e){return e.disabled?"none":"unset"}),(function(e){var t=e.rotate;return!isNaN(t)&&"transform: rotate("+90*t+"deg);"}),(function(e){var t=e.theme,n=e.color;return n&&"fill: "+G(n)({theme:t})+";"}),(function(e){var t=e.theme,n=e.hoverColor;return n&&"&:hover { fill: "+G(n)({theme:t})+"; }"}),Q,te),$l=function(){return($l=Object.assign||function(e){for(var t,n=1,r=arguments.length;n *:not(:last-child) {\n margin-"+(r||i?"bottom":"right")+": "+t*n+"px;\n }\n "},Mu=function(e){return"flex-direction: "+function(e,t,n){return e?"column":t?"column-reverse":n?"row-reverse":"row"}(e.column,e.columnReverse,e.rowReverse)+";"},_u=function(){return(_u=Object.assign||function(e){for(var t,n=1,r=arguments.length;n &",_invalid:"&[aria-invalid=true]",_pressed:"&[aria-pressed=true]",_readOnly:"&[aria-readonly=true], &[readonly]",_first:"&:first-of-type",_last:"&:last-of-type",_expanded:"&[aria-expanded=true]",_grabbed:"&[aria-grabbed=true]",_notFirst:"&:not(:first-of-type)",_notLast:"&:not(:last-of-type)",_groupHover:"[role=group]:hover &",_autofill:"&:-webkit-autofill",_placeholder:"&::placeholder"},Hu=function(e){var t=e.theme,n=Eu(e,["theme"]),r="";for(var i in n)if(i in Lu){var o=i,a=n[o],c=Au(Tu,Su,zu)(Ou({theme:t},a));r=r+"\n "+Lu[o]+"{ \n "+c+" \n }"}return r.replace(/^(?=\n)$|^\s*|\s*$|\n\n+/gm,"")};function Du(){return(Du=Object.assign||function(e){for(var t=1;t=0)return Vu(e,t,t);var n=Math.abs(t),r=Vu(e,n,n);return"string"===typeof r?"-"+r:-1*r},Wu=["margin","marginTop","marginRight","marginBottom","marginLeft","marginX","marginY","top","bottom","left","right"].reduce((function(e,t){var n;return Du({},e,((n={})[t]=Uu,n))}),{}),Gu=function e(t){return function(n){void 0===n&&(n={});var r=Du({},Iu,{},n.theme||n),i={},o=function(e){return function(t){var n={},r=Vu(t,"breakpoints",Nu),i=[null].concat(r.map((function(e){return"@media screen and (min-width: "+e+")"})));for(var o in e){var a="function"===typeof e[o]?e[o](t):e[o];if(null!=a)if(Array.isArray(a))for(var c=0;c=0&&"[object Array]"===Object.prototype.toString.call(e)},md=j((function(e){return!!gd(e)||!!e&&("object"===typeof e&&(!T(e)&&(1===e.nodeType?!!e.length:0===e.length||e.length>0&&(e.hasOwnProperty(0)&&e.hasOwnProperty(e.length-1)))))})),yd=function(){function e(e){this.f=e}return e.prototype["@@transducer/init"]=function(){throw new Error("init not implemented on XWrap")},e.prototype["@@transducer/result"]=function(e){return e},e.prototype["@@transducer/step"]=function(e,t){return this.f(e,t)},e}();var bd=M((function(e,t){return zd(e.length,(function(){return e.apply(t,arguments)}))}));function wd(e,t,n){for(var r=n.next();!r.done;){if((t=e["@@transducer/step"](t,r.value))&&t["@@transducer/reduced"]){t=t["@@transducer/value"];break}r=n.next()}return e["@@transducer/result"](t)}function kd(e,t,n,r){return e["@@transducer/result"](n[r](bd(e["@@transducer/step"],e),t))}var xd="undefined"!==typeof Symbol?Symbol.iterator:"@@iterator";function jd(e,t,n){if("function"===typeof e&&(e=function(e){return new yd(e)}(e)),md(n))return function(e,t,n){for(var r=0,i=n.length;r=arguments.length)?s=n[c]:(s=arguments[o],o+=1),i[c]=s,x(s)||(a-=1),c+=1}return a<=0?r.apply(this,i):zd(a,e(t,i,r))}}(e,[],t))})),Pd=Object.prototype.toString,Vd=function(){return"[object Arguments]"===Pd.call(arguments)?function(e){return"[object Arguments]"===Pd.call(e)}:function(e){return C("callee",e)}}(),Nd=!{toString:null}.propertyIsEnumerable("toString"),Id=["constructor","valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"],Rd=function(){return arguments.propertyIsEnumerable("length")}(),Fd=function(e,t){for(var n=0;n=0;)C(t=Id[n],e)&&!Fd(r,t)&&(r[r.length]=t),n-=1;return r})):j((function(e){return Object(e)!==e?[]:Object.keys(e)})),Ud=M(Td(["fantasy-land/map","map"],Hd,(function(e,t){switch(Object.prototype.toString.call(t)){case"[object Function]":return Dd(t.length,(function(){return e.call(this,t.apply(this,arguments))}));case"[object Object]":return jd((function(n,r){return n[r]=e(t[r]),n}),{},Bd(t));default:return Od(e,t)}})));function Wd(e){for(var t,n=[];!(t=e.next()).done;)n.push(t.value);return n}function Gd(e,t,n){for(var r=0,i=n.length;r=0;){if(n[o]===e)return r[o]===t;o-=1}switch(i){case"Map":return e.size===t.size&&$d(e.entries(),t.entries(),n.concat([e]),r.concat([t]));case"Set":return e.size===t.size&&$d(e.values(),t.values(),n.concat([e]),r.concat([t]));case"Arguments":case"Array":case"Object":case"Boolean":case"Number":case"String":case"Date":case"Error":case"RegExp":case"Int8Array":case"Uint8Array":case"Uint8ClampedArray":case"Int16Array":case"Uint16Array":case"Int32Array":case"Uint32Array":case"Float32Array":case"Float64Array":case"ArrayBuffer":break;default:return!1}var a=Bd(e);if(a.length!==Bd(t).length)return!1;var c=n.concat([e]),s=r.concat([t]);for(o=a.length-1;o>=0;){var l=a[o];if(!C(l,t)||!Xd(t[l],e[l],c,s))return!1;o-=1}return!0}var Kd=M((function(e,t){return Xd(e,t,[],[])}));function Qd(e,t){return function(e,t,n){var r,i;if("function"===typeof e.indexOf)switch(typeof t){case"number":if(0===t){for(r=1/t;n=0}var Jd=function(e){return(e<10?"0":"")+e};Date.prototype.toISOString;var ep,tp,np,rp,ip,op,ap=function(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e},cp=(s.d.tr.withConfig({displayName:"styled__StyledRow",componentId:"ssimnk-0"})(ep||(ep=ap(["\n position: ",";\n"],["\n position: ",";\n"])),(function(e){return e.hasStickyHeader?"static":"relative"})),s.d.div.withConfig({displayName:"styled__StyledBlockRow",componentId:"ssimnk-1"})(tp||(tp=ap(["\n position: relative;\n"],["\n position: relative;\n"]))),function(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e}),sp=s.d.thead.withConfig({displayName:"styled__StyledThead",componentId:"sc-14orp2c-0"})(np||(np=cp(["\n & > tr th {\n border-spacing: 0;\n border-bottom: 1px solid #aeb3b7;\n padding-bottom: 5px;\n }\n"],["\n & > tr th {\n border-spacing: 0;\n border-bottom: 1px solid #aeb3b7;\n padding-bottom: 5px;\n }\n"]))),lp=function(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e},up=function(){return(up=Object.assign||function(e){for(var t,n=1,r=arguments.length;n=t?e.call(null):r.id=requestAnimationFrame(i)}))};return r}var Op=null;function Ep(e){if(void 0===e&&(e=!1),null===Op||e){var t=document.createElement("div"),n=t.style;n.width="50px",n.height="50px",n.overflow="scroll",n.direction="rtl";var r=document.createElement("div"),i=r.style;return i.width="100px",i.height="100px",t.appendChild(r),document.body.appendChild(t),t.scrollLeft>0?Op="positive-descending":(t.scrollLeft=1,Op=0===t.scrollLeft?"negative":"positive-ascending"),document.body.removeChild(t),Op}return Op}var Ap=150,Lp=function(e,t){return e};function Hp(e){var t,n,r=e.getItemOffset,i=e.getEstimatedTotalSize,o=e.getItemSize,c=e.getOffsetForIndexAndAlignment,s=e.getStartIndexForOffset,l=e.getStopIndexForStartIndex,u=e.initInstanceProps,f=e.shouldResetStyleCacheOnItemSizeChange,h=e.validateProps;return n=t=function(e){function t(t){var n;return(n=e.call(this,t)||this)._instanceProps=u(n.props,Object(jp.a)(Object(jp.a)(n))),n._outerRef=void 0,n._resetIsScrollingTimeoutId=null,n.state={instance:Object(jp.a)(Object(jp.a)(n)),isScrolling:!1,scrollDirection:"forward",scrollOffset:"number"===typeof n.props.initialScrollOffset?n.props.initialScrollOffset:0,scrollUpdateWasRequested:!1},n._callOnItemsRendered=void 0,n._callOnItemsRendered=Cp((function(e,t,r,i){return n.props.onItemsRendered({overscanStartIndex:e,overscanStopIndex:t,visibleStartIndex:r,visibleStopIndex:i})})),n._callOnScroll=void 0,n._callOnScroll=Cp((function(e,t,r){return n.props.onScroll({scrollDirection:e,scrollOffset:t,scrollUpdateWasRequested:r})})),n._getItemStyle=void 0,n._getItemStyle=function(e){var t,i=n.props,a=i.direction,c=i.itemSize,s=i.layout,l=n._getItemStyleCache(f&&c,f&&s,f&&a);if(l.hasOwnProperty(e))t=l[e];else{var u=r(n.props,e,n._instanceProps),h=o(n.props,e,n._instanceProps),d="horizontal"===a||"horizontal"===s,p="rtl"===a,z=d?u:0;l[e]=t={position:"absolute",left:p?void 0:z,right:p?z:void 0,top:d?0:u,height:d?"100%":h,width:d?h:"100%"}}return t},n._getItemStyleCache=void 0,n._getItemStyleCache=Cp((function(e,t,n){return{}})),n._onScrollHorizontal=function(e){var t=e.currentTarget,r=t.clientWidth,i=t.scrollLeft,o=t.scrollWidth;n.setState((function(e){if(e.scrollOffset===i)return null;var t=n.props.direction,a=i;if("rtl"===t)switch(Ep()){case"negative":a=-i;break;case"positive-descending":a=o-r-i}return a=Math.max(0,Math.min(a,o-r)),{isScrolling:!0,scrollDirection:e.scrollOffset0)for(var C=j;C<=M;C++)_.push(Object(a.createElement)(t,{data:f,key:d(C,f),index:C,isScrolling:m?b:void 0,style:this._getItemStyle(C)}));var q=i(this.props,this._instanceProps);return Object(a.createElement)(z||v||"div",{className:n,onScroll:k,ref:this._outerRefSetter,style:Object(kp.a)({position:"relative",height:o,width:y,overflow:"auto",WebkitOverflowScrolling:"touch",willChange:"transform",direction:r},g)},Object(a.createElement)(s||l||"div",{children:_,ref:c,style:{height:w?"100%":q,pointerEvents:b?"none":void 0,width:w?q:"100%"}}))},n._callPropsCallbacks=function(){if("function"===typeof this.props.onItemsRendered&&this.props.itemCount>0){var e=this._getRangeToRender(),t=e[0],n=e[1],r=e[2],i=e[3];this._callOnItemsRendered(t,n,r,i)}if("function"===typeof this.props.onScroll){var o=this.state,a=o.scrollDirection,c=o.scrollOffset,s=o.scrollUpdateWasRequested;this._callOnScroll(a,c,s)}},n._getRangeToRender=function(){var e=this.props,t=e.itemCount,n=e.overscanCount,r=this.state,i=r.isScrolling,o=r.scrollDirection,a=r.scrollOffset;if(0===t)return[0,0,0,0];var c=s(this.props,a,this._instanceProps),u=l(this.props,c,a,this._instanceProps),f=i&&"backward"!==o?1:Math.max(1,n),h=i&&"forward"!==o?1:Math.max(1,n);return[Math.max(0,c-f),Math.max(0,Math.min(t-1,u+h)),c,u]},t}(a.PureComponent),t.defaultProps={direction:"ltr",itemData:void 0,layout:"vertical",overscanCount:2,useIsScrolling:!1},n}var Dp=function(e,t){e.children,e.direction,e.height,e.layout,e.innerTagName,e.outerTagName,e.width,t.instance},Pp=function(e,t,n){var r=e.itemSize,i=n.itemMetadataMap,o=n.lastMeasuredIndex;if(t>o){var a=0;if(o>=0){var c=i[o];a=c.offset+c.size}for(var s=o+1;s<=t;s++){var l=r(s);i[s]={offset:a,size:l},a+=l}n.lastMeasuredIndex=t}return i[t]},Vp=function(e,t,n,r,i){for(;r<=n;){var o=r+Math.floor((n-r)/2),a=Pp(e,o,t).offset;if(a===i)return o;ai&&(n=o-1)}return r>0?r-1:0},Np=function(e,t,n,r){for(var i=e.itemCount,o=1;n=n&&(o=n-1),o>=0){var c=r[o];a=c.offset+c.size}return a+(n-o-1)*i},Rp=Hp({getItemOffset:function(e,t,n){return Pp(e,t,n).offset},getItemSize:function(e,t,n){return n.itemMetadataMap[t].size},getEstimatedTotalSize:Ip,getOffsetForIndexAndAlignment:function(e,t,n,r,i){var o=e.direction,a=e.height,c=e.layout,s=e.width,l="horizontal"===o||"horizontal"===c?s:a,u=Pp(e,t,i),f=Ip(e,i),h=Math.max(0,Math.min(f-l,u.offset)),d=Math.max(0,u.offset-l+u.size);switch("smart"===n&&(n=r>=d-l&&r<=h+l?"auto":"center"),n){case"start":return h;case"end":return d;case"center":return Math.round(d+(h-d)/2);case"auto":default:return r>=d&&r<=h?r:r0?r[i].offset:0)>=n?Vp(e,t,i,0,n):Np(e,t,Math.max(0,i),n)}(e,n,t)},getStopIndexForStartIndex:function(e,t,n,r){for(var i=e.direction,o=e.height,a=e.itemCount,c=e.layout,s=e.width,l="horizontal"===i||"horizontal"===c?s:o,u=Pp(e,t,r),f=n+l,h=u.offset+u.size,d=t;d=d-u&&r<=h+u?"auto":"center"),n){case"start":return h;case"end":return d;case"center":var p=Math.round(d+(h-d)/2);return pf+Math.floor(u/2)?f:p;case"auto":default:return r>=d&&r<=h?r:r span {\n font-weight: ",";\n }\n"],["\n border-bottom: "," solid\n ",";\n box-sizing: border-box;\n\n min-width: ",";\n max-width: ",";\n height: ",";\n color: ",";\n font-weight: ",";\n\n cursor: pointer;\n opacity: ",";\n pointer-events: ",";\n\n &:hover {\n border-bottom: "," solid ",";\n }\n\n & > span {\n font-weight: ",";\n }\n"])),(function(e){return e.small?"2px":"4px"}),(function(e){var t=e.active;return G(t?"accent":["transparent","full"])}),(function(e){var t=e.minWidth;return null!==t&&void 0!==t?t:Z(10)}),(function(e){var t=e.maxWidth;return null!==t&&void 0!==t?t:Z(26)}),(function(e){var t=e.small;return Z(t?4:6)}),G("text"),(function(e){return e.active?"bold":"normal"}),(function(e){return e.disabled?.4:1}),(function(e){return e.disabled?"none":"auto"}),(function(e){return e.small?"2px":"4px"}),G("primary"),(function(e){return e.active?"bold":"normal"})),yz=function(){return(yz=Object.assign||function(e){for(var t,n=1,r=arguments.length;ne.clientHeight}));return n.forEach((function(e){return e.addEventListener("scroll",t,{capture:!1,passive:!0})})),function(){return n.forEach((function(e){return e.removeEventListener("scroll",t)}))}};n=r();var i=function(){n(),n=r(),t()};return window.addEventListener("resize",i),function(){n(),window.removeEventListener("resize",i)}}),[e,t])}(n,m),nv(v,l,n),Jz(u);var y=Qz();return sf.a.createPortal(c.a.createElement(uv,fv({ref:g,width:{max:"100%"},column:!0,"data-testid":"drop"},p),f),y)})),zv=function(){return(zv=Object.assign||function(e){for(var t,n=1,r=arguments.length;n1&&i.forEach((function(n){var i;r[n]=e(((i={})[n]=t[n],i))})),r},ig=function(e,t,n,r,i){var o={};return r.slice(0,e.length).forEach((function(r,a){var c,s=e[a],l=t(r,n,i);s?Kv()(o,((c={})[s]=Kv()({},o[s],l),c)):Kv()(o,l)})),o},og=function(e,t,n,r,i){var o={};for(var a in r){var c=e[a],s=t(r[a],n,i);if(c){var l,u=eg(c);Kv()(o,((l={})[u]=Kv()({},o[u],s),l))}else Kv()(o,s)}return o},ag=function(e){var t=e.properties,n=e.property,r=e.scale,i=e.transform,o=void 0===i?tg:i,a=e.defaultScale;t=t||[n];var c=function(e,n,r){var i={},a=o(e,n,r);if(null!==a)return t.forEach((function(e){i[e]=a})),i};return c.scale=r,c.defaults=a,c},cg=function(e){void 0===e&&(e={});var t={};return Object.keys(e).forEach((function(n){var r=e[n];t[n]=!0!==r?"function"!==typeof r?ag(r):r:ag({property:n,scale:n})})),rg(t)},sg=cg({width:{property:"width",scale:"sizes",transform:function(e,t){return ng(t,e,!function(e){return"number"===typeof e&&!isNaN(e)}(e)||e>1?e:100*e+"%")}},height:{property:"height",scale:"sizes"},minWidth:{property:"minWidth",scale:"sizes"},minHeight:{property:"minHeight",scale:"sizes"},maxWidth:{property:"maxWidth",scale:"sizes"},maxHeight:{property:"maxHeight",scale:"sizes"},size:{properties:["width","height"],scale:"sizes"},overflow:!0,overflowX:!0,overflowY:!0,display:!0,verticalAlign:!0}),lg={color:{property:"color",scale:"colors"},backgroundColor:{property:"backgroundColor",scale:"colors"},opacity:!0};lg.bg=lg.backgroundColor;var ug=cg(lg),fg=cg({fontFamily:{property:"fontFamily",scale:"fonts"},fontSize:{property:"fontSize",scale:"fontSizes",defaultScale:[12,14,16,20,24,32,48,64,72]},fontWeight:{property:"fontWeight",scale:"fontWeights"},lineHeight:{property:"lineHeight",scale:"lineHeights"},letterSpacing:{property:"letterSpacing",scale:"letterSpacings"},textAlign:!0,fontStyle:!0}),hg=cg({alignItems:!0,alignContent:!0,justifyItems:!0,justifyContent:!0,flexWrap:!0,flexDirection:!0,flex:!0,flexGrow:!0,flexShrink:!0,flexBasis:!0,justifySelf:!0,alignSelf:!0,order:!0}),dg={space:[0,4,8,16,32,64,128,256,512]},pg=cg({gridGap:{property:"gridGap",scale:"space",defaultScale:dg.space},gridColumnGap:{property:"gridColumnGap",scale:"space",defaultScale:dg.space},gridRowGap:{property:"gridRowGap",scale:"space",defaultScale:dg.space},gridColumn:!0,gridRow:!0,gridAutoFlow:!0,gridAutoColumns:!0,gridAutoRows:!0,gridTemplateColumns:!0,gridTemplateRows:!0,gridTemplateAreas:!0,gridArea:!0}),zg={border:{property:"border",scale:"borders"},borderWidth:{property:"borderWidth",scale:"borderWidths"},borderStyle:{property:"borderStyle",scale:"borderStyles"},borderColor:{property:"borderColor",scale:"colors"},borderRadius:{property:"borderRadius",scale:"radii"},borderTop:{property:"borderTop",scale:"borders"},borderTopLeftRadius:{property:"borderTopLeftRadius",scale:"radii"},borderTopRightRadius:{property:"borderTopRightRadius",scale:"radii"},borderRight:{property:"borderRight",scale:"borders"},borderBottom:{property:"borderBottom",scale:"borders"},borderBottomLeftRadius:{property:"borderBottomLeftRadius",scale:"radii"},borderBottomRightRadius:{property:"borderBottomRightRadius",scale:"radii"},borderLeft:{property:"borderLeft",scale:"borders"},borderX:{properties:["borderLeft","borderRight"],scale:"borders"},borderY:{properties:["borderTop","borderBottom"],scale:"borders"},borderTopWidth:{property:"borderTopWidth",scale:"borderWidths"},borderTopColor:{property:"borderTopColor",scale:"colors"},borderTopStyle:{property:"borderTopStyle",scale:"borderStyles"}};zg.borderTopLeftRadius={property:"borderTopLeftRadius",scale:"radii"},zg.borderTopRightRadius={property:"borderTopRightRadius",scale:"radii"},zg.borderBottomWidth={property:"borderBottomWidth",scale:"borderWidths"},zg.borderBottomColor={property:"borderBottomColor",scale:"colors"},zg.borderBottomStyle={property:"borderBottomStyle",scale:"borderStyles"},zg.borderBottomLeftRadius={property:"borderBottomLeftRadius",scale:"radii"},zg.borderBottomRightRadius={property:"borderBottomRightRadius",scale:"radii"},zg.borderLeftWidth={property:"borderLeftWidth",scale:"borderWidths"},zg.borderLeftColor={property:"borderLeftColor",scale:"colors"},zg.borderLeftStyle={property:"borderLeftStyle",scale:"borderStyles"},zg.borderRightWidth={property:"borderRightWidth",scale:"borderWidths"},zg.borderRightColor={property:"borderRightColor",scale:"colors"},zg.borderRightStyle={property:"borderRightStyle",scale:"borderStyles"};var vg=cg(zg),gg={background:!0,backgroundImage:!0,backgroundSize:!0,backgroundPosition:!0,backgroundRepeat:!0};gg.bgImage=gg.backgroundImage,gg.bgSize=gg.backgroundSize,gg.bgPosition=gg.backgroundPosition,gg.bgRepeat=gg.backgroundRepeat;var mg=cg(gg),yg={space:[0,4,8,16,32,64,128,256,512]},bg=cg({position:!0,zIndex:{property:"zIndex",scale:"zIndices"},top:{property:"top",scale:"space",defaultScale:yg.space},right:{property:"right",scale:"space",defaultScale:yg.space},bottom:{property:"bottom",scale:"space",defaultScale:yg.space},left:{property:"left",scale:"space",defaultScale:yg.space}}),wg=bg,kg={space:[0,4,8,16,32,64,128,256,512]},xg=function(e){return"number"===typeof e&&!isNaN(e)},jg=function(e,t){if(!xg(e))return ng(t,e,e);var n=e<0,r=Math.abs(e),i=ng(t,r,r);return xg(i)?i*(n?-1:1):n?"-"+i:i},Mg={};Mg.margin={margin:{property:"margin",scale:"space",transform:jg,defaultScale:kg.space},marginTop:{property:"marginTop",scale:"space",transform:jg,defaultScale:kg.space},marginRight:{property:"marginRight",scale:"space",transform:jg,defaultScale:kg.space},marginBottom:{property:"marginBottom",scale:"space",transform:jg,defaultScale:kg.space},marginLeft:{property:"marginLeft",scale:"space",transform:jg,defaultScale:kg.space},marginX:{properties:["marginLeft","marginRight"],scale:"space",transform:jg,defaultScale:kg.space},marginY:{properties:["marginTop","marginBottom"],scale:"space",transform:jg,defaultScale:kg.space}},Mg.margin.m=Mg.margin.margin,Mg.margin.mt=Mg.margin.marginTop,Mg.margin.mr=Mg.margin.marginRight,Mg.margin.mb=Mg.margin.marginBottom,Mg.margin.ml=Mg.margin.marginLeft,Mg.margin.mx=Mg.margin.marginX,Mg.margin.my=Mg.margin.marginY,Mg.padding={padding:{property:"padding",scale:"space",defaultScale:kg.space},paddingTop:{property:"paddingTop",scale:"space",defaultScale:kg.space},paddingRight:{property:"paddingRight",scale:"space",defaultScale:kg.space},paddingBottom:{property:"paddingBottom",scale:"space",defaultScale:kg.space},paddingLeft:{property:"paddingLeft",scale:"space",defaultScale:kg.space},paddingX:{properties:["paddingLeft","paddingRight"],scale:"space",defaultScale:kg.space},paddingY:{properties:["paddingTop","paddingBottom"],scale:"space",defaultScale:kg.space}},Mg.padding.p=Mg.padding.padding,Mg.padding.pt=Mg.padding.paddingTop,Mg.padding.pr=Mg.padding.paddingRight,Mg.padding.pb=Mg.padding.paddingBottom,Mg.padding.pl=Mg.padding.paddingLeft,Mg.padding.px=Mg.padding.paddingX,Mg.padding.py=Mg.padding.paddingY;(function(){for(var e={},t=arguments.length,n=new Array(t),r=0;r4)return Pg;var n=t.map((function(t){return X(e,t)}));return 1===n.length?{top:n[0],right:n[0],bottom:n[0],left:n[0]}:2===n.length?{top:n[0],right:n[1],bottom:n[0],left:n[1]}:3===n.length?{top:n[0],right:n[1],bottom:n[2],left:n[1]}:{top:n[0],right:n[1],bottom:n[2],left:n[3]}},Ng=function(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e},Ig=function(e,t){return"0"!==e&&"0"!==t?"calc((100% - "+e+") - "+t+")":"0"===e&&"0"===t?"100%":"calc(100% - "+("0"===e?t:e)+")"},Rg=new Set(["top","center","bottom"]),Fg=new Set(["bottom-left","left","top-left"]),Bg=new Set(["right","center","left"]),Ug=new Set(["top-left","top","top-right"]),Wg=new Set(["top-right","right","bottom-right"]),Gg=new Set(["bottom-right","bottom","bottom-left"]),Yg=s.d.div.attrs((function(e){var t=e.theme,n=e.margin;return{marginDimensions:Vg(t,n)}})).withConfig({displayName:"container__Container",componentId:"sc-7g83tw-0"})(Cg||(Cg=Ng(["\n position: ",";\n display: flex;\n z-index: 35;\n outline: none;\n pointer-events: all;\n\n ","\n ","\n ","\n ","\n ","\n ","\n ","\n\n ","\n"],["\n position: ",";\n display: flex;\n z-index: 35;\n outline: none;\n pointer-events: all;\n\n ","\n ","\n ","\n ","\n ","\n ","\n ","\n\n ","\n"])),(function(e){return e.isAbsolute?"absolute":"fixed"}),(function(e){var t=e.marginDimensions,n=t.top,r=t.bottom;return"max-height: "+Ig(n,r)+";"}),(function(e){var t=e.marginDimensions,n=t.right,r=t.left;return"max-width: "+Ig(r,n)+";"}),(function(e){var t=e.position,n=e.full,r=e.marginDimensions;return"vertical"===n||!0===n||Ug.has(t)?"top: "+r.top+";":Bg.has(t)?"top: 50%;":""}),(function(e){var t=e.position,n=e.full,r=e.marginDimensions;return"horizontal"===n||!0===n||Wg.has(t)?"right: "+r.right+";":""}),(function(e){var t=e.position,n=e.full,r=e.marginDimensions;return"vertical"===n||!0===n||Gg.has(t)?"bottom: "+r.bottom+";":""}),(function(e){var t=e.position,n=e.full,r=e.marginDimensions;return"horizontal"===n||!0===n||Fg.has(t)?"left: "+r.left+";":Rg.has(t)?"left: 50%;":""}),(function(e){var t=e.full,n=e.position,r=function(){var e=!0!==t&&"horizontal"!==t&&Rg.has(n),r=!0!==t&&"vertical"!==t&&Bg.has(n);return e||r?e&&!r?"translateX(-50%)":!e&&r?"translateY(-50%)":"translate(-50%, -50%)":""}();return r&&"transform: "+r+";"}),(function(e){return e.borderShadow&&"box-shadow: 0px 2px 68px rgba(0, 0, 0, 0.288);"})),Zg=function(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e},$g=function(){return($g=Object.assign||function(e){for(var t,n=1,r=arguments.length;n * {\n min-width: initial;\n max-width: initial;\n }\n"],["\n width: 100%;\n\n .tabs > * {\n min-width: initial;\n max-width: initial;\n }\n"]))),_m=function(){return c.a.createElement(Xu,{overflow:{vertical:"auto"},"data-testid":"dashboard"},c.a.createElement(Mm,null,c.a.createElement(wz,{label:"Using a Mouse"},c.a.createElement(km,null)),c.a.createElement(wz,{label:"Using Touch"},c.a.createElement(xm,null))))},Cm=n(21),qm=n.n(Cm);function Sm(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function Tm(e,t){for(var n=0;n0?e.concat(Object.assign({field:o,values:l,type:c},s)):e}return e.concat(i)}),[])}function Im(e,t,n,r){var i=e.data,o=Vm(t,n,r)||[];return Object.assign(Object.assign({},e),{data:i.map((function(e){return Object.assign(Object.assign({},e),{selected:o.some((function(t){return Rm(t,e.value)}))})}))})}function Rm(e,t){return!!(e&&e.name&&t&&t.name&&e.name===t.name)||Dm()(e,t,{strict:!0})}function Fm(e,t){return t?t.reduce((function(e,t){return e.find((function(e){return e.type===t.type&&e.field===t.field}))?e:[].concat(Object(Lm.a)(e),[t])}),e):e}function Bm(e){return void 0!==e.name}var Um=Object.assign({},i),Wm=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"===typeof Object.getOwnPropertySymbols){var i=0;for(r=Object.getOwnPropertySymbols(e);i1)return console.warn("search-ui-site-search-connector: Cannot apply more than 1 none-value filters to a single field"),e;var i=r[0];if(Um.isFilterValueRange(i)){i.name;var o=Wm(i,["name"]);return e[n]=Object.assign({type:"range"},o),e}return e}return e[n]=Object.assign(Object.assign({},"any"===t.type?{}:{type:"and"}),{values:r}),e}),{})}(void 0!==t.filters?t.filters:e.filters),l=void 0!==t.current?t.current:e.current,u=void 0!==t.resultsPerPage?t.resultsPerPage:e.resultsPerPage,f=void 0!==t.sortDirection?t.sortDirection:e.sortDirection,h=void 0!==t.sortField?t.sortField:e.sortField,d=void 0!==t.sortList?t.sortList:e.sortList,p=(o=t.result_fields)?[Object.keys(o),Object.entries(o).reduce((function(e,t){var n=Object(Em.a)(t,2),r=n[0],i=n[1];return i.snippet?Object.assign(Object.assign({},e),Object(Am.a)({},r,i.snippet)):e}),{})]:[],z=Object(Em.a)(p,2),v=z[0],g=z[1],m=(a=t.search_fields)?Object.keys(a):[],y=e.searchTerm;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},u&&{per_page:u}),l&&{page:l}),f&&{sort_direction:Object(Am.a)({},n,f)}),h&&{sort_field:Object(Am.a)({},n,h)}),d&&{sort_list:Object(Am.a)({},n,d)}),s&&{filters:Object(Am.a)({},n,s)}),c&&{facets:Object(Am.a)({},n,c)}),v&&{fetch_fields:Object(Am.a)({},n,v)}),g&&{highlight_fields:Object(Am.a)({},n,g)}),m&&!!m.length&&{search_fields:Object(Am.a)({},n,m)}),{q:y})}var Ym=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"===typeof Object.getOwnPropertySymbols){var i=0;for(r=Object.getOwnPropertySymbols(e);i0&&{facets:a})}var Xm=function(e,t,n,r){return new(n||(n=Promise))((function(i,o){function a(e){try{s(r.next(e))}catch(t){o(t)}}function c(e){try{s(r.throw(e))}catch(t){o(t)}}function s(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,c)}s((r=r.apply(e,t||[])).next())}))};function Km(e,t,n,r){return Xm(this,void 0,void 0,qm.a.mark((function i(){var o,a,c,s;return qm.a.wrap((function(i){for(;;)switch(i.prev=i.next){case 0:return o=new Headers({"Content-Type":"application/json"}),i.next=3,fetch("https://search-api.swiftype.com/api/v1/public/".concat(n),{method:t,headers:o,body:JSON.stringify(Object.assign({engine_key:e},r)),credentials:"include"});case 3:return a=i.sent,i.prev=4,i.next=7,a.json();case 7:c=i.sent,i.next=12;break;case 10:i.prev=10,i.t0=i.catch(4);case 12:if(!(a.status>=200&&a.status<300)){i.next=16;break}return i.abrupt("return",c);case 16:throw s=c&&c.errors&&Object.entries(c.errors).length>0?JSON.stringify(c.errors):a.status,new Error("".concat(s));case 18:case"end":return i.stop()}}),i,null,[[4,10]])})))}var Qm=function(e,t,n,r){return new(n||(n=Promise))((function(i,o){function a(e){try{s(r.next(e))}catch(t){o(t)}}function c(e){try{s(r.throw(e))}catch(t){o(t)}}function s(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,c)}s((r=r.apply(e,t||[])).next())}))};function Jm(e,t,n){var r=Object.entries(Object.assign({engine_key:e},n)).map((function(e){var t=Object(Em.a)(e,2),n=t[0],r=t[1];return"".concat(n,"=").concat(encodeURIComponent(r))})).join("&");return fetch("https://search-api.swiftype.com/api/v1/public/".concat(t,"?").concat(r),{method:"GET",credentials:"include"})}var ey=function(){function e(t){var n=t.documentType,r=t.engineKey,i=t.beforeSearchCall,o=void 0===i?function(e,t){return t(e)}:i,a=t.beforeAutocompleteResultsCall,c=void 0===a?function(e,t){return t(e)}:a;Sm(this,e),this.documentType=n,this.engineKey=r,this.beforeSearchCall=o,this.beforeAutocompleteResultsCall=c,this.request=Km.bind(this,r),this._get=Jm.bind(this,r)}return Om(e,[{key:"onResultClick",value:function(e){var t=e.query,n=e.documentId,r=e.tags;r&&r.length>0&&console.warn("search-ui-site-search-connector: Site Search does not support tags on click"),this._get("analytics/pc",{t:(new Date).getTime(),q:t,doc_id:n})}},{key:"onAutocompleteResultClick",value:function(e){var t=e.query,n=e.documentId;e.tags&&console.warn("search-ui-site-search-connector: Site Search does not support tags on autocompleteClick"),this._get("analytics/pas",{t:(new Date).getTime(),q:t,doc_id:n})}},{key:"onSearch",value:function(e,t){var n=this,r=Gm(e,t,this.documentType);return this.beforeSearchCall(r,(function(e){return n.request("POST","engines/search.json",e).then((function(e){return $m(e,n.documentType)}))}))}},{key:"onAutocomplete",value:function(e,t){var n=e.searchTerm;return Qm(this,void 0,void 0,qm.a.mark((function e(){var r,i=this;return qm.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(!t.results){e.next=3;break}return r=Gm({searchTerm:n},t.results,this.documentType),e.abrupt("return",this.beforeAutocompleteResultsCall(r,(function(e){return i.request("POST","engines/suggest.json",e).then((function(e){return{autocompletedResults:$m(e,i.documentType).results}}))})));case 3:t.suggestions&&console.warn("search-ui-site-search-connector: Site Search does support query suggestions on autocomplete");case 4:case"end":return e.stop()}}),e,this)})))}}]),e}();function ty(e){return"/"===e.charAt(0)}function ny(e,t){for(var n=t,r=n+1,i=e.length;r=0;u--){var f=i[u];"."===f?ny(i,u):".."===f?(ny(i,u),l++):l&&(ny(i,u),l--)}if(!c)for(;l--;l)i.unshift("..");!c||""===i[0]||i[0]&&ty(i[0])||i.unshift("");var h=i.join("/");return n&&"/"!==h.substr(-1)&&(h+="/"),h};var iy=!0,oy="Invariant failed";function ay(e,t){if(!e){if(iy)throw new Error(oy);var n="function"===typeof t?t():t;throw new Error(n?oy+": "+n:oy)}}function cy(e){return"/"===e.charAt(0)?e:"/"+e}function sy(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function ly(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function uy(e){var t=e.pathname,n=e.search,r=e.hash,i=t||"/";return n&&"?"!==n&&(i+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(i+="#"===r.charAt(0)?r:"#"+r),i}function fy(e,t,n,r){var i;"string"===typeof e?(i=function(e){var t=e||"/",n="",r="",i=t.indexOf("#");-1!==i&&(r=t.substr(i),t=t.substr(0,i));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e)).state=t:(void 0===(i=Object(kp.a)({},e)).pathname&&(i.pathname=""),i.search?"?"!==i.search.charAt(0)&&(i.search="?"+i.search):i.search="",i.hash?"#"!==i.hash.charAt(0)&&(i.hash="#"+i.hash):i.hash="",void 0!==t&&void 0===i.state&&(i.state=t));try{i.pathname=decodeURI(i.pathname)}catch(o){throw o instanceof URIError?new URIError('Pathname "'+i.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):o}return n&&(i.key=n),r?i.pathname?"/"!==i.pathname.charAt(0)&&(i.pathname=ry(i.pathname,r.pathname)):i.pathname=r.pathname:i.pathname||(i.pathname="/"),i}function hy(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,i){if(null!=e){var o="function"===typeof e?e(t,n):e;"string"===typeof o?"function"===typeof r?r(o,i):i(!0):i(!1!==o)}else i(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;r1&&(s.current=n),t&&(s.q=t),i&&(s.size=i),r&&r.length>0&&(s.filters=r),c&&c.length>0?s.sort=c:a&&(s["sort-field"]=a,s["sort-direction"]=o),s}(e))}var Ly=function(){function e(){Sm(this,e),this.history="undefined"!==typeof window?my():function(e){void 0===e&&(e={});var t=e,n=t.getUserConfirmation,r=t.initialEntries,i=void 0===r?["/"]:r,o=t.initialIndex,a=void 0===o?0:o,c=t.keyLength,s=void 0===c?6:c,l=hy();function u(e){Object(kp.a)(v,e),v.length=v.entries.length,l.notifyListeners(v.location,v.action)}function f(){return Math.random().toString(36).substr(2,s)}var h=yy(a,0,i.length-1),d=i.map((function(e){return fy(e,void 0,"string"===typeof e?f():e.key||f())})),p=uy;function z(e){var t=yy(v.index+e,0,v.entries.length-1),r=v.entries[t];l.confirmTransitionTo(r,"POP",n,(function(e){e?u({action:"POP",location:r,index:t}):u()}))}var v={length:d.length,action:"POP",location:d[h],index:h,entries:d,createHref:p,push:function(e,t){var r=fy(e,t,f(),v.location);l.confirmTransitionTo(r,"PUSH",n,(function(e){if(e){var t=v.index+1,n=v.entries.slice(0);n.length>t?n.splice(t,n.length-t,r):n.push(r),u({action:"PUSH",location:r,index:t,entries:n})}}))},replace:function(e,t){var r=fy(e,t,f(),v.location);l.confirmTransitionTo(r,"REPLACE",n,(function(e){e&&(v.entries[v.index]=r,u({action:"REPLACE",location:r}))}))},go:z,goBack:function(){z(-1)},goForward:function(){z(1)},canGo:function(e){var t=v.index+e;return t>=0&&t1&&void 0!==arguments[1]?arguments[1]:{},n=t.replaceUrl,r=void 0!==n&&n,i=Ay(e);this.lastPushSearchString=i;var o=r?this.history.replace:this.history.push;o({search:"?".concat(i)})}},{key:"onURLStateChange",value:function(e){var t=this;this.unlisten=this.history.listen((function(n){"?".concat(t.lastPushSearchString)!==n.search&&(t.lastPushSearchString="",e(Ey(xy.parse(n.search))))}))}},{key:"tearDown",value:function(){this.unlisten()}}]),e}(),Hy=function(){function e(){Sm(this,e),this.requestSequence=0,this.lastCompleted=0}return Om(e,[{key:"next",value:function(){return++this.requestSequence}},{key:"isOldRequest",value:function(e){return e3?r-3:0),o=3;o2&&void 0!==arguments[2]?arguments[2]:"all";this.debug&&(n=console).log.apply(n,["Search UI: Action","addFilter"].concat(Array.prototype.slice.call(arguments)));var i=this.state.filters,o=i.find((function(t){return t.field===e&&t.type===r}))||{},a=i.filter((function(t){return t.field!==e||t.type!==r}))||[],c=o.values||[],s=c.find((function(e){return Rm(e,t)}))?c:c.concat(t);this._updateSearchResults({current:1,filters:[].concat(Object(Lm.a)(a),[{field:e,values:s,type:r}])})}function Iy(e){var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];this.debug&&(t=console).log.apply(t,["Search UI: Action","trackAutocompleteClickThrough"].concat(Array.prototype.slice.call(arguments)));var r=this.state,i=r.autocompletedResultsRequestId,o=r.searchTerm;this.events.autocompleteResultClick({query:o,documentId:e,requestId:i,tags:n})}function Ry(){var e,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.debug&&(e=console).log.apply(e,["Search UI: Action","clearFilters"].concat(Array.prototype.slice.call(arguments)));var n=this.state.filters.filter((function(e){var n=e.field;return t.includes(n)}));this._updateSearchResults({current:1,filters:n})}function Fy(e,t,n){var r;this.debug&&(r=console).log.apply(r,["Search UI: Action","removeFilter"].concat(Array.prototype.slice.call(arguments)));var i=this.state.filters,o=i;o=!t&&n?i.filter((function(t){return!(t.field===e&&t.type===n)})):t?Nm(i,e,t,n):i.filter((function(t){return t.field!==e})),this._updateSearchResults({current:1,filters:o})}function By(){var e;this.debug&&(e=console).log.apply(e,["Search UI: Action","reset"].concat(Array.prototype.slice.call(arguments))),this._setState(this.startingState),this.trackUrlState&&this.URLManager.pushStateToURL(this.state)}function Uy(e){var t;this.debug&&(t=console).log.apply(t,["Search UI: Action","setCurrent"].concat(Array.prototype.slice.call(arguments))),this._updateSearchResults({current:e})}function Wy(e,t){var n,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"all";this.debug&&(n=console).log.apply(n,["Search UI: Action","setFilter"].concat(Array.prototype.slice.call(arguments)));var i=this.state.filters;i=i.filter((function(t){return t.field!==e||t.type!==r})),this._updateSearchResults({current:1,filters:[].concat(Object(Lm.a)(i),[{field:e,values:[t],type:r}])})}function Gy(e){var t;this.debug&&(t=console).log.apply(t,["Search UI: Action","setResultsPerPage"].concat(Array.prototype.slice.call(arguments))),this._updateSearchResults({current:1,resultsPerPage:e})}function Yy(e){var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=n.autocompleteMinimumCharacters,i=void 0===r?0:r,o=n.autocompleteResults,a=void 0!==o&&o,c=n.autocompleteSuggestions,s=void 0!==c&&c,l=n.shouldClearFilters,u=void 0===l||l,f=n.refresh,h=void 0===f||f,d=n.debounce,p=void 0===d?0:d;this.debug&&(t=console).log.apply(t,["Search UI: Action","setSearchTerm"].concat(Array.prototype.slice.call(arguments))),this._setState({searchTerm:e}),h&&this.debounceManager.runWithDebounce(p,"_updateSearchResults",this._updateSearchResults,Object.assign({current:1},u&&{filters:[]})),(a||s)&&e.length>=i&&this.debounceManager.runWithDebounce(p,"_updateAutocomplete",this._updateAutocomplete,e,{autocompleteResults:a,autocompleteSuggestions:s})}function Zy(e,t){var n;this.debug&&(n=console).log.apply(n,["Search UI: Action","setSort"].concat(Array.prototype.slice.call(arguments)));var r={current:1,sortList:null,sortField:null,sortDirection:null};Array.isArray(e)?r.sortList=e:(r.sortField=e,r.sortDirection=t),this._updateSearchResults(r)}function $y(e){var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];this.debug&&(t=console).log.apply(t,["Search UI: Action","trackClickThrough"].concat(Array.prototype.slice.call(arguments)));var r=this.state,i=r.requestId,o=r.searchTerm;this.events.resultClick({query:o,documentId:e,requestId:i,tags:n})}var Xy="search-ui-screen-reader-notifications",Ky="undefined"!==typeof document,Qy=function(){if(!Ky)return null;var e=document.getElementById(Xy);return e||((e=document.createElement("div")).id=Xy,e.setAttribute("role","status"),e.setAttribute("aria-live","polite"),e.style.position="absolute",e.style.width="1px",e.style.height="1px",e.style.margin="-1px",e.style.padding="0",e.style.border="0",e.style.overflow="hidden",e.style.clip="rect(0 0 0 0)",document.body.appendChild(e),e)},Jy=function(e){var t=Qy();t&&(t.textContent=e)},eb={searchResults:function(e){var t=e.start,n=e.end,r=e.totalResults,i=e.searchTerm,o="Showing ".concat(t," to ").concat(n," results out of ").concat(r);return i&&(o+=', searching for "'.concat(i,'".')),o}};function tb(e,t){if(this.hasA11yNotifications){var n=this.a11yNotificationMessages[e];if(n){var r=n(t);Jy(r),this.debug&&console.log("Search UI: Action","a11yNotify",{messageFunc:e,messageArgs:t,message:r})}else{var i='Could not find corresponding message function in a11yNotificationMessages: "'.concat(e,'"');console.warn("Action","a11yNotify",i)}}}function nb(e,t,n){if(n){if(t){var r=t[e].bind(t);return function(){for(var e=arguments.length,t=new Array(e),i=0;i0&&void 0!==arguments[0]?arguments[0]:{},n=t.apiConnector,r=t.onSearch,i=t.onAutocomplete,o=t.onResultClick,a=t.onAutocompleteResultClick;Sm(this,e),this.search=nb("onSearch",n,r),this.autocomplete=nb("onAutocomplete",n,i),this.resultClick=nb("onResultClick",n,o),this.autocompleteResultClick=nb("onAutocompleteResultClick",n,a)},ib="Invalid credentials",ob=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"===typeof Object.getOwnPropertySymbols){var i=0;for(r=Object.getOwnPropertySymbols(e);i0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];return Object.entries(e).reduce((function(e,r){var i=Object(Em.a)(r,2),o=i[0],a=i[1];return t[o]&&"function"===typeof t[o]&&!t[o]({filters:n})?e:(e[o]=a,e)}),{})}var lb=function(){function e(t){var n,r=this,i=t.apiConnector,a=t.autocompleteQuery,c=void 0===a?{}:a,s=t.debug,l=t.initialState,u=t.onSearch,f=t.onAutocomplete,h=t.onResultClick,d=t.onAutocompleteResultClick,p=t.searchQuery,z=void 0===p?{}:p,v=t.trackUrlState,g=void 0===v||v,m=t.urlPushDebounceLength,y=void 0===m?500:m,b=t.hasA11yNotifications,w=void 0!==b&&b,k=t.a11yNotificationMessages,x=void 0===k?{}:k,j=t.alwaysSearchOnInitialLoad,M=void 0!==j&&j;Sm(this,e),this.state=cb,this._updateAutocomplete=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.autocompleteResults,i=t.autocompleteSuggestions,o=r.autocompleteRequestSequencer.next(),a=Object.assign(Object.assign({},n&&{results:r.autocompleteQuery.results||{}}),i&&{suggestions:r.autocompleteQuery.suggestions||{}});return r.events.autocomplete({searchTerm:e},a).then((function(e){r.autocompleteRequestSequencer.isOldRequest(o)||(r.autocompleteRequestSequencer.completed(o),r._setState(e))}))},this._updateSearchResults=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.skipPushToUrl,i=void 0!==n&&n,o=t.replaceUrl,a=void 0!==o&&o,c=Object.assign(Object.assign({},r.state),e),s=c.current,l=c.filters,u=c.resultsPerPage,f=c.searchTerm,h=c.sortDirection,d=c.sortField,p=c.sortList;r.debounceManager.cancelByName("_updateSearchResults"),r._setState({current:s,error:"",filters:l,resultsPerPage:u,searchTerm:f,sortDirection:h,sortField:d,sortList:p}),r._makeSearchRequest({skipPushToUrl:i,replaceUrl:a})},this._makeSearchRequest=Vy.debounce(0,(function(e){var t=e.skipPushToUrl,n=e.replaceUrl,i=r.state,o=i.current,a=i.filters,c=i.resultsPerPage,s=i.searchTerm,l=i.sortDirection,u=i.sortField,f=i.sortList;r._setState({isLoading:!0});var h=r.searchRequestSequencer.next(),d=r.searchQuery,p=(d.filters,d.conditionalFacets),z=ob(d,["filters","conditionalFacets"]),v=Object.assign(Object.assign({},z),{facets:sb(r.searchQuery.facets,p,a)}),g=Object.assign(Object.assign({},ab(r.state)),{filters:Fm(a,r.searchQuery.filters)});return r.events.search(g,v).then((function(e){if(!r.searchRequestSequencer.isOldRequest(h)){r.searchRequestSequencer.completed(h);var i=e.totalResults,d=0===i?0:(o-1)*c+1,p=i0||this.alwaysSearchOnInitialLoad)&&this._updateSearchResults(_,{replaceUrl:!0})}return Om(e,[{key:"_setState",value:function(e){var t=Object.assign(Object.assign({},this.state),e);this.debug&&console.log("Search UI: State Update",e,t),this.state=t,this.subscriptions.forEach((function(e){return e(t)}))}},{key:"setSearchQuery",value:function(e){this.searchQuery=e,this._updateSearchResults({})}},{key:"setAutocompleteQuery",value:function(e){this.autocompleteQuery=e}},{key:"subscribeToStateChanges",value:function(e){this.subscriptions.push(e)}},{key:"unsubscribeToStateChanges",value:function(e){this.subscriptions=this.subscriptions.filter((function(t){return t!==e}))}},{key:"tearDown",value:function(){this.subscriptions=[],this.URLManager&&this.URLManager.tearDown()}},{key:"getActions",value:function(){return this.actions}},{key:"getState",value:function(){return Object.assign({},this.state)}}]),e}(),ub=c.a.createContext(null),fb={moreFilters:function(e){var t=e.visibleOptionsCount,n=e.showingAll?"All ":"";return n+="".concat(t," options shown.")}},hb=function(e){var t=e.children,n=e.config,r=e.driver,i=Object(a.useState)(null),o=Object(Em.a)(i,2),s=o[0],l=o[1];if(Object(a.useEffect)((function(){var e=r||new lb(Object.assign(Object.assign({},n),{a11yNotificationMessages:Object.assign(Object.assign({},fb),n.a11yNotificationMessages)}));return l(e),function(){e.tearDown()}}),[]),Object(a.useEffect)((function(){s&&s.setSearchQuery(n.searchQuery)}),[n.searchQuery]),Object(a.useEffect)((function(){s&&s.setAutocompleteQuery(n.autocompleteQuery)}),[n.autocompleteQuery]),!s)return null;var u={driver:s};return c.a.createElement(ub.Provider,{value:u},t)};function db(e){return(db="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function pb(e){return(pb="function"===typeof Symbol&&"symbol"===db(Symbol.iterator)?function(e){return db(e)}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":db(e)})(e)}function zb(e,t){return!t||"object"!==pb(t)&&"function"!==typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}function vb(e){return(vb=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function gb(e,t){return(gb=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}var mb=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"===typeof Object.getOwnPropertySymbols){var i=0;for(r=Object.getOwnPropertySymbols(e);i0&&i[i.length-1])&&(6===o[0]||2===o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]1&&e}));return e[n]=e[n]||[],e[n].push(t),e}),{})},Ib=function(){return(Ib=Object.assign||function(e){for(var t,n=1,r=arguments.length;n * {\n min-width: 160px;\n max-width: 100%;\n }\n"],["\n width: 100%;\n\n .tabs > * {\n min-width: 160px;\n max-width: 100%;\n }\n"]))),Kb=["learn","community"],Qb={learn:"learn.netdata",community:"discourse","github-cloud":"netdata-cloud","github-agent":"netdata"},Jb={learn:"Documentation",community:"Community","github-cloud":"Github / Cloud","github-agent":"Github / Agent"},ew=function(e){var t=e.results;return c.a.createElement(Xu,{overflow:{vertical:"auto"},"data-testid":"searchResults",flex:!0,width:"1000px",height:"60vh"},c.a.createElement(Xb,null,Kb.map((function(e){var n=t[Qb[e]],r=null===n||void 0===n?void 0:n.length;return c.a.createElement(wz,{key:e,label:Jb[e]+(r?" ("+r+")":"")},c.a.createElement($b,null,r?n.map((function(e){var t=e.id,n=e.url,r=e.title,i=e.description;return c.a.createElement(Zb,{key:t.raw,url:n.raw,title:r,description:i})})):c.a.createElement(Xu,{padding:[4]},c.a.createElement(Nf,{strong:!0},"No results"))))}))))},tw=function(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e},nw=Object(s.d)(Xu).attrs({padding:[6],background:"dropdown",gap:6,column:!0,round:!0,overflow:{vertical:"auto"}}).withConfig({displayName:"documentation__Container",componentId:"sc-3qq6g2-0"})(jb||(jb=tw(["\n box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);\n"],["\n box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);\n"]))),rw=function(e){var t=e.children,n=e.onClose;return c.a.createElement(Xu,{width:"100%",alignItems:"center",justifyContent:"between",padding:[0,0,4],border:{side:"bottom",color:"disabled"}},c.a.createElement(Xu,{gap:2,alignItems:"center"},t),c.a.createElement(Ju,{icon:"x",neutral:!0,small:!0,onClick:n,flavour:"borderless","data-testid":"documentation-help-close"}))},iw="general",ow="dashboard",aw="search",cw={general:"Need help?",dashboard:"Need help?"},sw=function(e){var t=e.app,n=void 0===t?"cloud":t,r=e.onCloseClick,i=e.onVisitDocumentClick,o=e.onOpenIssueClick,s=e.onOpenBugClick,l=e.onContributeClick,u=e.onSupportClick,f=e.children,h=um(),d=h[0],p=h[1],z=Object(a.useState)(iw),v=z[0],g=z[1],m=v===iw,y=Object(a.useCallback)((function(){return g(ow)}),[]),b=Object(a.useCallback)((function(){return g(iw)}),[]),w=Object(a.useCallback)((function(){return g(aw)}),[]),k=Object(a.useCallback)((function(){p(),r&&r()}),[]);return c.a.createElement(a.Fragment,null,f(p,d),d&&c.a.createElement(em,{position:"bottom-left",backdrop:!0,margin:[5,17],onClickOutside:p,onEsc:p},c.a.createElement(Bb,null,(function(e){var t=e.searchTerm,r=e.setSearchTerm,f=e.results,h=e.reset;return c.a.createElement(a.Fragment,null,c.a.createElement(nw,{width:{max:m?"325px":v===ow?"600px":"100%"},"data-testid":"documentation-layer"},c.a.createElement(rw,{onClose:k},m&&c.a.createElement(Kl,{color:"text",name:"questionFilled",width:"18px",height:"18px"}),!m&&c.a.createElement(Ju,{icon:"arrow_left",neutral:!0,small:!0,onClick:function(){b(),h()},flavour:"borderless","data-testid":"dashboard-back"}),c.a.createElement(Lf,{margin:[0]},cw[v]||cw.general)),v!==ow&&c.a.createElement(Ub,{defaultValue:t,setSearchTerm:r,setSearchView:w}),m&&c.a.createElement(Xu,{gap:6,overflow:{vertical:"auto"},column:!0,padding:[1]},c.a.createElement(vm,{app:n,onDashboardClick:y,onVisitDocumentClick:i,onOpenIssueClick:o,onOpenBugClick:s,onContributeClick:l,onSupportClick:u})),v===ow&&c.a.createElement(_m,null),v===aw&&c.a.createElement(ew,{results:f})))}))))},lw=n(268),uw="object"===typeof window,fw=(n.n(lw).a,function(){}),hw=function(e,t,n){if(!uw)return[t,fw,fw];if(!e)throw new Error("useLocalStorage key may not be falsy");var r=n?n.raw?function(e){return e}:n.deserializer:JSON.parse,i=Object(a.useState)((function(){try{var o=n?n.raw?String:n.serializer:JSON.stringify,a=localStorage.getItem(e);return null!==a?r(a):(t&&localStorage.setItem(e,o(t)),t)}catch(i){return t}})),o=i[0],c=i[1],s=Object(a.useCallback)((function(t){try{var a="function"===typeof t?t(o):t;if("undefined"===typeof a)return;var s=void 0;s=n?n.raw?"string"===typeof a?a:JSON.stringify(a):n.serializer?n.serializer(a):JSON.stringify(a):JSON.stringify(a),localStorage.setItem(e,s),c(r(s))}catch(i){}}),[e,c]),l=Object(a.useCallback)((function(){try{localStorage.removeItem(e),c(void 0)}catch(i){}}),[e,c]);return[o,s,l]},dw=function(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e},pw=Object(s.d)(Xu).attrs({overflow:{vertical:"auto"},padding:[0,4,0,0]}).withConfig({displayName:"container__Container",componentId:"sc-1v3y9uu-0"})(Mb||(Mb=dw(["\n ","\n"],["\n ","\n"])),Lh),zw=function(e){var t=e.onClose;return c.a.createElement(Xu,{border:{side:"bottom",color:"selected"},justifyContent:"between",alignItems:"center",padding:[0,0,4,0]},c.a.createElement(Xu,{gap:2},c.a.createElement(Kl,{color:"text",name:"insights"}),c.a.createElement(If,{strong:!0},"Netdata News")),c.a.createElement(Ju,{flavour:"borderless",neutral:!0,icon:"x",title:"close news",onClick:t}))},vw=function(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e},gw=Object(s.d)(Xu).attrs({as:"img"}).withConfig({displayName:"image__Image",componentId:"sc-1l0yjz3-0"})(_b||(_b=vw(["\n object-fit: cover;\n"],["\n object-fit: cover;\n"]))),mw=function(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e},yw=Object(s.d)(Xu).attrs({as:"a"}).withConfig({displayName:"anchor__Anchor",componentId:"sc-5t4sos-0"})(Cb||(Cb=mw(["\n text-decoration: none;\n & :hover {\n text-decoration: none;\n }\n"],["\n text-decoration: none;\n & :hover {\n text-decoration: none;\n }\n"]))),bw=function(e){var t=e.item,n=t.last_publication_date,r=t.data,i=r.title,o=r.description,a=r.url,s=r.image,l=r.label,u=s&&s.url,f=new Date(n);return c.a.createElement(Xu,{column:!0,gap:2},c.a.createElement(Xu,{gap:4},u&&c.a.createElement(gw,{src:u,width:"160px"}),c.a.createElement(Xu,{column:!0,gap:2},c.a.createElement(Nf,{strong:!0},i),c.a.createElement(Nf,null,o))),c.a.createElement(Xu,{justifyContent:"between",alignItems:"center"},c.a.createElement(Vf,null,f.toLocaleDateString()),c.a.createElement(yw,{href:a,target:"_blank",rel:"noopener noreferrer",gap:1,alignItems:"center"},c.a.createElement(Nf,{color:"success",strong:!0},l),c.a.createElement(Kl,{color:"success",rotate:2,name:"arrow_left"}))))},ww=n(267),kw=function(e,t){return(kw=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)};function xw(e,t){function n(){this.constructor=e}kw(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var jw=function(){return(jw=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0?this.running[0]:null},e.prototype.refFromCookie=function(e){if(!e||""===e.trim())return null;var t=e.trim().split(" ");if(t.length<2)return null;var n=t[0],r=parseInt(t[1],10),i=this.running.filter((function(e){return e.googleId()===n&&e.variations.length>r}))[0];return i?i.variations[r].ref():null},e}(),qw=function(){function e(e,t){for(var n in this.httpClient=t,this.form=e,this.data={},e.fields)e.fields[n].default&&(this.data[n]=[e.fields[n].default])}return e.prototype.set=function(e,t){var n=this.form.fields[e];if(!n)throw new Error("Unknown field "+e);var r=""===t||void 0===t?null:t,i=this.data[e]||[];i=n.multiple?r?i.concat([r]):i:r?[r]:i,this.data[e]=i},e.prototype.url=function(){var e=this.form.action;if(this.data){var t=e.indexOf("?")>-1?"&":"?";for(var n in this.data)if(Object.prototype.hasOwnProperty.call(this.data,n)){var r=this.data[n];if(r)for(var i=0;i0&&(this.url+=function(e){return e.indexOf("?")>-1?"&":"?"}(e)+n.join("&")),this.apiDataTTL=this.options.apiDataTTL||5,this.httpClient=new gk(this.options.requestHandler,this.options.apiCache,this.options.proxyAgent,this.options.timeoutInMs)}return e.prototype.get=function(e){var t=this;return this.httpClient.cachedRequest(this.url,{ttl:this.apiDataTTL}).then((function(n){var r=new dk(n,t.httpClient,t.options);return e&&e(null,r),r})).catch((function(t){throw e&&e(t),t}))},e}(),yk=function(){function e(e,t){this.id=e,this.api=t,this.fields={}}return e.prototype.set=function(e,t){return this.fields[e]=t,this},e.prototype.ref=function(e){return this.set("ref",e)},e.prototype.query=function(e){return this.set("q",e)},e.prototype.pageSize=function(e){return this.set("pageSize",e)},e.prototype.graphQuery=function(e){return this.set("graphQuery",e)},e.prototype.lang=function(e){return this.set("lang",e)},e.prototype.page=function(e){return this.set("page",e)},e.prototype.after=function(e){return this.set("after",e)},e.prototype.orderings=function(e){return this.set("orderings",e)},e.prototype.url=function(){var t=this;return this.api.get().then((function(n){return e.toSearchForm(t,n).url()}))},e.prototype.submit=function(t){var n=this;return this.api.get().then((function(r){return e.toSearchForm(n,r).submit(t)}))},e.toSearchForm=function(e,t){var n=t.searchForm(e.id);if(n)return Object.keys(e.fields).reduce((function(t,n){var r=e.fields[n];return"q"===n?t.query(r):"pageSize"===n?t.pageSize(r):"graphQuery"===n?t.graphQuery(r):"lang"===n?t.lang(r):"page"===n?t.page(r):"after"===n?t.after(r):"orderings"===n?t.orderings(r):t.set(n,r)}),n);throw new Error("Unable to access to form "+e.id)},e}(),bk=function(){function e(e,t){this.api=new mk(e,t)}return e.prototype.getApi=function(){return this.api.get()},e.prototype.everything=function(){return this.form("everything")},e.prototype.form=function(e){return new yk(e,this.api)},e.prototype.query=function(e,t,n){return this.getApi().then((function(r){return r.query(e,t,n)}))},e.prototype.queryFirst=function(e,t,n){return this.getApi().then((function(r){return r.queryFirst(e,t,n)}))},e.prototype.getByID=function(e,t,n){return this.getApi().then((function(r){return r.getByID(e,t,n)}))},e.prototype.getByIDs=function(e,t,n){return this.getApi().then((function(r){return r.getByIDs(e,t,n)}))},e.prototype.getByUID=function(e,t,n,r){return this.getApi().then((function(i){return i.getByUID(e,t,n,r)}))},e.prototype.getSingle=function(e,t,n){return this.getApi().then((function(r){return r.getSingle(e,t,n)}))},e.prototype.getBookmark=function(e,t,n){return this.getApi().then((function(r){return r.getBookmark(e,t,n)}))},e.prototype.getTags=function(){return this.getApi().then((function(e){return e.getTags()}))},e.prototype.getPreviewResolver=function(e,t){var n=this;return hk(e,t,(function(e,t){return n.getApi().then((function(n){return n.getByID(e,t)}))}))},e.getApi=function(e,t){return new mk(e,t).get()},e}();function wk(e,t){return bk.getApi(e,t)}var kk={experimentCookie:"io.prismic.experiment",previewCookie:"io.prismic.preview",Predicates:lk,predicates:lk,Experiments:Cw,Api:mk,client:function(e,t){return new bk(e,t)},getApi:wk,api:function(e,t){return wk(e,t)}},xk=kk.client("https://netdata-news.cdn.prismic.io/api/v2"),jk=[],Mk=function(e){var t=e.app,n=void 0===t?"cloud":t,r=e.onCloseClick,i=e.children,o=hw("news_last_seen"),s=o[0],l=o[1],u=Object(a.useState)(jk),f=u[0],h=u[1],d=Object(a.useState)(),p=d[0],z=d[1],v=um(),g=v[0],m=v[1];Object(a.useEffect)((function(){!function(e,t,n){xk.query(kk.Predicates.at("document.tags",[e]),{pageSize:100,orderings:"[document.last_publication_date desc]"}).then(t).catch(n)}(n,(function(e){var t=e.results;return h(t)}),(function(){return z(!0)}))}),[]);var y=Object(a.useMemo)((function(){if(!f.length)return!0;var e=f[0].last_publication_date;return new Date(s)>=new Date(e)}),[s,f]),b=Object(a.useCallback)((function(){m(),l(new Date),r&&r()}),[r]);return c.a.createElement(a.Fragment,null,i({toggle:m,isOpen:g,upToDate:y}),g&&c.a.createElement(em,{backdrop:!0,onClickOutside:b,onEsc:b},c.a.createElement(Xu,{background:"dropdown",round:!0,padding:[6],width:"640px",height:{max:"640px"},gap:4,column:!0},c.a.createElement(zw,{onClose:b}),c.a.createElement(pw,{column:!0,gap:6},p&&c.a.createElement(Vf,{textAlign:"center"},"Something went wrong \ud83d\ude14"),!p&&!f.length&&c.a.createElement(Vf,{textAlign:"center"},"There are no latest news"),!p&&f.length>0&&f.map((function(e){return c.a.createElement(bw,{key:e.id,item:e})}))))))},_k=function(){var e=Object(a.useContext)(s.a);return function(t){return G(t)({theme:e})}},Ck=function(){return(Ck=Object.assign||function(e){for(var t,n=1,r=arguments.length;n=0||(i[n]=e[n]);return i}var Wk=n(214),Gk=n.n(Wk),Yk=n(269),Zk=["getDisplayName","methodName","renderCountProp","shouldHandleStateChanges","storeKey","withRef","forwardRef","context"],$k=["reactReduxForwardedRef"],Xk=[],Kk=[null,null];function Qk(e,t){var n=e[1];return[t.payload,n+1]}function Jk(e,t,n){Fk((function(){return e.apply(void 0,t)}),n)}function ex(e,t,n,r,i,o,a){e.current=r,t.current=i,n.current=!1,o.current&&(o.current=null,a())}function tx(e,t,n,r,i,o,a,c,s,l){if(e){var u=!1,f=null,h=function(){if(!u){var e,n,h=t.getState();try{e=r(h,i.current)}catch(d){n=d,f=d}n||(f=null),e===o.current?a.current||s():(o.current=e,c.current=e,a.current=!0,l({type:"STORE_UPDATED",payload:{error:n}}))}};n.onStateChange=h,n.trySubscribe(),h();return function(){if(u=!0,n.tryUnsubscribe(),n.onStateChange=null,f)throw f}}}var nx=function(){return[null,0]};function rx(e,t){void 0===t&&(t={});var n=t,r=n.getDisplayName,i=void 0===r?function(e){return"ConnectAdvanced("+e+")"}:r,o=n.methodName,s=void 0===o?"connectAdvanced":o,l=n.renderCountProp,u=void 0===l?void 0:l,f=n.shouldHandleStateChanges,h=void 0===f||f,d=n.storeKey,p=void 0===d?"store":d,z=(n.withRef,n.forwardRef),v=void 0!==z&&z,g=n.context,m=void 0===g?Pk:g,y=Uk(n,Zk),b=m;return function(t){var n=t.displayName||t.name||"Component",r=i(n),o=Hk({},y,{getDisplayName:i,methodName:s,renderCountProp:u,shouldHandleStateChanges:h,storeKey:p,displayName:r,wrappedComponentName:n,WrappedComponent:t}),l=y.pure;var f=l?a.useMemo:function(e){return e()};function d(n){var r=Object(a.useMemo)((function(){var e=n.reactReduxForwardedRef,t=Uk(n,$k);return[n.context,e,t]}),[n]),i=r[0],s=r[1],l=r[2],u=Object(a.useMemo)((function(){return i&&i.Consumer&&Object(Yk.isContextConsumer)(c.a.createElement(i.Consumer,null))?i:b}),[i,b]),d=Object(a.useContext)(u),p=Boolean(n.store)&&Boolean(n.store.getState)&&Boolean(n.store.dispatch);Boolean(d)&&Boolean(d.store);var z=p?n.store:d.store,v=Object(a.useMemo)((function(){return function(t){return e(t.dispatch,o)}(z)}),[z]),g=Object(a.useMemo)((function(){if(!h)return Kk;var e=Rk(z,p?null:d.subscription),t=e.notifyNestedSubs.bind(e);return[e,t]}),[z,p,d]),m=g[0],y=g[1],w=Object(a.useMemo)((function(){return p?d:Hk({},d,{subscription:m})}),[p,d,m]),k=Object(a.useReducer)(Qk,Xk,nx),x=k[0][0],j=k[1];if(x&&x.error)throw x.error;var M=Object(a.useRef)(),_=Object(a.useRef)(l),C=Object(a.useRef)(),q=Object(a.useRef)(!1),S=f((function(){return C.current&&l===_.current?C.current:v(z.getState(),l)}),[z,x,l]);Jk(ex,[_,M,q,l,S,C,y]),Jk(tx,[h,z,m,v,_,M,q,C,y,j],[z,m,v]);var T=Object(a.useMemo)((function(){return c.a.createElement(t,Hk({},S,{ref:s}))}),[s,t,S]);return Object(a.useMemo)((function(){return h?c.a.createElement(u.Provider,{value:w},T):T}),[u,T,w])}var z=l?c.a.memo(d):d;if(z.WrappedComponent=t,z.displayName=d.displayName=r,v){var g=c.a.forwardRef((function(e,t){return c.a.createElement(z,Hk({},e,{reactReduxForwardedRef:t}))}));return g.displayName=r,g.WrappedComponent=t,Gk()(g,t)}return Gk()(z,t)}}function ix(e,t){return e===t?0!==e||0!==t||1/e===1/t:e!==e&&t!==t}function ox(e,t){if(ix(e,t))return!0;if("object"!==typeof e||null===e||"object"!==typeof t||null===t)return!1;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(var i=0;i=0;r--){var i=t[r](e);if(i)return i}return function(t,r){throw new Error("Invalid value of type "+typeof e+" for "+n+" argument when connecting component "+r.wrappedComponentName+".")}}function yx(e,t){return e===t}function bx(e){var t=void 0===e?{}:e,n=t.connectHOC,r=void 0===n?rx:n,i=t.mapStateToPropsFactories,o=void 0===i?ux:i,a=t.mapDispatchToPropsFactories,c=void 0===a?lx:a,s=t.mergePropsFactories,l=void 0===s?hx:s,u=t.selectorFactory,f=void 0===u?vx:u;return function(e,t,n,i){void 0===i&&(i={});var a=i,s=a.pure,u=void 0===s||s,h=a.areStatesEqual,d=void 0===h?yx:h,p=a.areOwnPropsEqual,z=void 0===p?ox:p,v=a.areStatePropsEqual,g=void 0===v?ox:v,m=a.areMergedPropsEqual,y=void 0===m?ox:m,b=Uk(a,gx),w=mx(e,o,"mapStateToProps"),k=mx(t,c,"mapDispatchToProps"),x=mx(n,l,"mergeProps");return r(f,Hk({methodName:"connect",getDisplayName:function(e){return"Connect("+e+")"},shouldHandleStateChanges:Boolean(e),initMapStateToProps:w,initMapDispatchToProps:k,initMergeProps:x,pure:u,areStatesEqual:d,areOwnPropsEqual:z,areStatePropsEqual:g,areMergedPropsEqual:y},b))}}var wx=bx();var kx;function xx(e,t){var n=Object(a.useState)((function(){return{inputs:t,result:e()}}))[0],r=Object(a.useRef)(!0),i=Object(a.useRef)(n),o=r.current||Boolean(t&&i.current.inputs&&function(e,t){if(e.length!==t.length)return!1;for(var n=0;n");return t.callbacks},t.setCallbacks=function(e){t.callbacks=e},t}Lk(t,e);var n=t.prototype;return n.componentDidMount=function(){this.unbind=Gx(window,[{eventName:"error",fn:this.onWindowError}])},n.componentDidCatch=function(e){if(!(e instanceof $x))throw e;this.setState({})},n.componentWillUnmount=function(){this.unbind()},n.render=function(){return this.props.children(this.setCallbacks)},t}(c.a.Component),Qx=function(e){return e+1},Jx=function(e,t){var n=e.droppableId===t.droppableId,r=Qx(e.index),i=Qx(t.index);return n?"\n You have moved the item from position "+r+"\n to position "+i+"\n ":"\n You have moved the item from position "+r+"\n in list "+e.droppableId+"\n to list "+t.droppableId+"\n in position "+i+"\n "},ej=function(e,t,n){return t.droppableId===n.droppableId?"\n The item "+e+"\n has been combined with "+n.draggableId:"\n The item "+e+"\n in list "+t.droppableId+"\n has been combined with "+n.draggableId+"\n in list "+n.droppableId+"\n "},tj=function(e){return"\n The item has returned to its starting position\n of "+Qx(e.index)+"\n"},nj={dragHandleUsageInstructions:"\n Press space bar to start a drag.\n When dragging you can use the arrow keys to move the item around and escape to cancel.\n Some screen readers may require you to be in focus mode or to use your pass through key\n",onDragStart:function(e){return"\n You have lifted an item in position "+Qx(e.source.index)+"\n"},onDragUpdate:function(e){var t=e.destination;if(t)return Jx(e.source,t);var n=e.combine;return n?ej(e.draggableId,e.source,n):"You are over an area that cannot be dropped on"},onDragEnd:function(e){if("CANCEL"===e.reason)return"\n Movement cancelled.\n "+tj(e.source)+"\n ";var t=e.destination,n=e.combine;return t?"\n You have dropped the item.\n "+Jx(e.source,t)+"\n ":n?"\n You have dropped the item.\n "+ej(e.draggableId,e.source,n)+"\n ":"\n The item has been dropped while not over a drop area.\n "+tj(e.source)+"\n "}},rj={x:0,y:0},ij=function(e,t){return{x:e.x+t.x,y:e.y+t.y}},oj=function(e,t){return{x:e.x-t.x,y:e.y-t.y}},aj=function(e,t){return e.x===t.x&&e.y===t.y},cj=function(e){return{x:0!==e.x?-e.x:0,y:0!==e.y?-e.y:0}},sj=function(e,t,n){var r;return void 0===n&&(n=0),(r={})[e]=t,r["x"===e?"y":"x"]=n,r},lj=function(e,t){return Math.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2))},uj=function(e,t){return Math.min.apply(Math,t.map((function(t){return lj(e,t)})))},fj=function(e){return function(t){return{x:e(t.x),y:e(t.y)}}},hj=function(e,t){return{top:e.top+t.y,left:e.left+t.x,bottom:e.bottom+t.y,right:e.right+t.x}},dj=function(e){return[{x:e.left,y:e.top},{x:e.right,y:e.top},{x:e.left,y:e.bottom},{x:e.right,y:e.bottom}]},pj=function(e,t){return t&&t.shouldClipSubject?function(e,t){var n=_x({top:Math.max(t.top,e.top),right:Math.min(t.right,e.right),bottom:Math.min(t.bottom,e.bottom),left:Math.max(t.left,e.left)});return n.width<=0||n.height<=0?null:n}(t.pageMarginBox,e):_x(e)},zj=function(e){var t=e.page,n=e.withPlaceholder,r=e.axis,i=e.frame,o=function(e,t,n){var r;return n&&n.increasedBy?Hk({},e,((r={})[t.end]=e[t.end]+n.increasedBy[t.line],r)):e}(function(e,t){return t?hj(e,t.scroll.diff.displacement):e}(t.marginBox,i),r,n);return{page:t,withPlaceholder:n,active:pj(o,i)}},vj=function(e,t){e.frame||Xx(!1);var n=e.frame,r=oj(t,n.scroll.initial),i=cj(r),o=Hk({},n,{scroll:{initial:n.scroll.initial,current:t,diff:{value:r,displacement:i},max:n.scroll.max}});return Hk({},e,{frame:o,subject:zj({page:e.subject.page,withPlaceholder:e.subject.withPlaceholder,axis:e.axis,frame:o})})};function gj(e){return Object.values?Object.values(e):Object.keys(e).map((function(t){return e[t]}))}function mj(e,t){if(e.findIndex)return e.findIndex(t);for(var n=0;ne.bottom,c=r.lefte.right;return!(!a||!c)||(a&&o||c&&i)}},Hj=function(e){var t=Aj(e.top,e.bottom),n=Aj(e.left,e.right);return function(e){return t(e.top)&&t(e.bottom)&&n(e.left)&&n(e.right)}},Dj={direction:"vertical",line:"y",crossAxisLine:"x",start:"top",end:"bottom",size:"height",crossAxisStart:"left",crossAxisEnd:"right",crossAxisSize:"width"},Pj={direction:"horizontal",line:"x",crossAxisLine:"y",start:"left",end:"right",size:"width",crossAxisStart:"top",crossAxisEnd:"bottom",crossAxisSize:"height"},Vj=function(e){var t=e.target,n=e.destination,r=e.viewport,i=e.withDroppableDisplacement,o=e.isVisibleThroughFrameFn,a=i?function(e,t){var n=t.frame?t.frame.scroll.diff.displacement:rj;return hj(e,n)}(t,n):t;return function(e,t,n){return!!t.subject.active&&n(t.subject.active)(e)}(a,n,o)&&function(e,t,n){return n(t)(e)}(a,r,o)},Nj=function(e){return Vj(Hk({},e,{isVisibleThroughFrameFn:Lj}))},Ij=function(e){return Vj(Hk({},e,{isVisibleThroughFrameFn:Hj}))},Rj=function(e,t,n){if("boolean"===typeof n)return n;if(!t)return!0;var r=t.invisible,i=t.visible;if(r[e])return!1;var o=i[e];return!o||o.shouldAnimate};function Fj(e){var t=e.afterDragging,n=e.destination,r=e.displacedBy,i=e.viewport,o=e.forceShouldAnimate,a=e.last;return t.reduce((function(e,t){var c=function(e,t){var n=e.page.marginBox,r={top:t.point.y,right:0,bottom:0,left:t.point.x};return _x(Cx(n,r))}(t,r),s=t.descriptor.id;if(e.all.push(s),!Nj({target:c,destination:n,viewport:i,withDroppableDisplacement:!0}))return e.invisible[t.descriptor.id]=!0,e;var l={draggableId:s,shouldAnimate:Rj(s,a,o)};return e.visible[s]=l,e}),{all:[],visible:{},invisible:{}})}function Bj(e){var t=e.insideDestination,n=e.inHomeList,r=e.displacedBy,i=e.destination,o=function(e,t){if(!e.length)return 0;var n=e[e.length-1].descriptor.index;return t.inHomeList?n:n+1}(t,{inHomeList:n});return{displaced:Oj,displacedBy:r,at:{type:"REORDER",destination:{droppableId:i.descriptor.id,index:o}}}}function Uj(e){var t=e.draggable,n=e.insideDestination,r=e.destination,i=e.viewport,o=e.displacedBy,a=e.last,c=e.index,s=e.forceShouldAnimate,l=Sj(t,r);if(null==c)return Bj({insideDestination:n,inHomeList:l,displacedBy:o,destination:r});var u=yj(n,(function(e){return e.descriptor.index===c}));if(!u)return Bj({insideDestination:n,inHomeList:l,displacedBy:o,destination:r});var f=qj(t,n),h=n.indexOf(u);return{displaced:Fj({afterDragging:f.slice(h),destination:r,displacedBy:o,last:a,viewport:i.frame,forceShouldAnimate:s}),displacedBy:o,at:{type:"REORDER",destination:{droppableId:r.descriptor.id,index:c}}}}function Wj(e,t){return Boolean(t.effected[e])}var Gj=function(e){var t=e.isMovingForward,n=e.isInHomeList,r=e.draggable,i=e.draggables,o=e.destination,a=e.insideDestination,c=e.previousImpact,s=e.viewport,l=e.afterCritical,u=c.at;if(u||Xx(!1),"REORDER"===u.type){var f=function(e){var t=e.isMovingForward,n=e.isInHomeList,r=e.insideDestination,i=e.location;if(!r.length)return null;var o=i.index,a=t?o+1:o-1,c=r[0].descriptor.index,s=r[r.length-1].descriptor.index;return a(n?s:s+1)?null:a}({isMovingForward:t,isInHomeList:n,location:u.destination,insideDestination:a});return null==f?null:Uj({draggable:r,insideDestination:a,destination:o,viewport:s,last:c.displaced,displacedBy:c.displacedBy,index:f})}var h=function(e){var t=e.isMovingForward,n=e.destination,r=e.draggables,i=e.combine,o=e.afterCritical;if(!n.isCombineEnabled)return null;var a=i.draggableId,c=r[a].descriptor.index;return Wj(a,o)?t?c:c-1:t?c+1:c}({isMovingForward:t,destination:o,displaced:c.displaced,draggables:i,combine:u.combine,afterCritical:l});return null==h?null:Uj({draggable:r,insideDestination:a,destination:o,viewport:s,last:c.displaced,displacedBy:c.displacedBy,index:h})},Yj=function(e){var t=e.afterCritical,n=e.impact,r=e.draggables,i=Cj(n);i||Xx(!1);var o=i.draggableId,a=r[o].page.borderBox.center,c=function(e){var t=e.displaced,n=e.afterCritical,r=e.combineWith,i=e.displacedBy,o=Boolean(t.visible[r]||t.invisible[r]);return Wj(r,n)?o?rj:cj(i.point):o?i.point:rj}({displaced:n.displaced,afterCritical:t,combineWith:o,displacedBy:n.displacedBy});return ij(a,c)},Zj=function(e,t){return t.margin[e.start]+t.borderBox[e.size]/2},$j=function(e,t,n){return t[e.crossAxisStart]+n.margin[e.crossAxisStart]+n.borderBox[e.crossAxisSize]/2},Xj=function(e){var t=e.axis,n=e.moveRelativeTo,r=e.isMoving;return sj(t.line,n.marginBox[t.end]+Zj(t,r),$j(t,n.marginBox,r))},Kj=function(e){var t=e.axis,n=e.moveRelativeTo,r=e.isMoving;return sj(t.line,n.marginBox[t.start]-function(e,t){return t.margin[e.end]+t.borderBox[e.size]/2}(t,r),$j(t,n.marginBox,r))},Qj=function(e){var t=e.impact,n=e.draggable,r=e.draggables,i=e.droppable,o=e.afterCritical,a=Mj(i.descriptor.id,r),c=n.page,s=i.axis;if(!a.length)return function(e){var t=e.axis,n=e.moveInto,r=e.isMoving;return sj(t.line,n.contentBox[t.start]+Zj(t,r),$j(t,n.contentBox,r))}({axis:s,moveInto:i.page,isMoving:c});var l=t.displaced,u=t.displacedBy,f=l.all[0];if(f){var h=r[f];if(Wj(f,o))return Kj({axis:s,moveRelativeTo:h.page,isMoving:c});var d=Ex(h.page,u.point);return Kj({axis:s,moveRelativeTo:d,isMoving:c})}var p=a[a.length-1];if(p.descriptor.id===n.descriptor.id)return c.borderBox.center;if(Wj(p.descriptor.id,o)){var z=Ex(p.page,cj(o.displacedBy.point));return Xj({axis:s,moveRelativeTo:z,isMoving:c})}return Xj({axis:s,moveRelativeTo:p.page,isMoving:c})},Jj=function(e,t){var n=e.frame;return n?ij(t,n.scroll.diff.displacement):t},eM=function(e){var t=function(e){var t=e.impact,n=e.draggable,r=e.droppable,i=e.draggables,o=e.afterCritical,a=n.page.borderBox.center,c=t.at;return r&&c?"REORDER"===c.type?Qj({impact:t,draggable:n,draggables:i,droppable:r,afterCritical:o}):Yj({impact:t,draggables:i,afterCritical:o}):a}(e),n=e.droppable;return n?Jj(n,t):t},tM=function(e,t){var n=oj(t,e.scroll.initial),r=cj(n);return{frame:_x({top:t.y,bottom:t.y+e.frame.height,left:t.x,right:t.x+e.frame.width}),scroll:{initial:e.scroll.initial,max:e.scroll.max,current:t,diff:{value:n,displacement:r}}}};function nM(e,t){return e.map((function(e){return t[e]}))}var rM=function(e){var t=e.pageBorderBoxCenter,n=e.draggable,r=function(e,t){return ij(e.scroll.diff.displacement,t)}(e.viewport,t),i=oj(r,n.page.borderBox.center);return ij(n.client.borderBox.center,i)},iM=function(e){var t=e.draggable,n=e.destination,r=e.newPageBorderBoxCenter,i=e.viewport,o=e.withDroppableDisplacement,a=e.onlyOnMainAxis,c=void 0!==a&&a,s=oj(r,t.page.borderBox.center),l={target:hj(t.page.borderBox,s),destination:n,withDroppableDisplacement:o,viewport:i};return c?function(e){return Vj(Hk({},e,{isVisibleThroughFrameFn:(t=e.destination.axis,function(e){var n=Aj(e.top,e.bottom),r=Aj(e.left,e.right);return function(e){return t===Dj?n(e.top)&&n(e.bottom):r(e.left)&&r(e.right)}})}));var t}(l):Ij(l)},oM=function(e){var t=e.isMovingForward,n=e.draggable,r=e.destination,i=e.draggables,o=e.previousImpact,a=e.viewport,c=e.previousPageBorderBoxCenter,s=e.previousClientSelection,l=e.afterCritical;if(!r.isEnabled)return null;var u=Mj(r.descriptor.id,i),f=Sj(n,r),h=function(e){var t=e.isMovingForward,n=e.draggable,r=e.destination,i=e.insideDestination,o=e.previousImpact;if(!r.isCombineEnabled)return null;if(!_j(o))return null;function a(e){var t={type:"COMBINE",combine:{draggableId:e,droppableId:r.descriptor.id}};return Hk({},o,{at:t})}var c=o.displaced.all,s=c.length?c[0]:null;if(t)return s?a(s):null;var l=qj(n,i);if(!s)return l.length?a(l[l.length-1].descriptor.id):null;var u=mj(l,(function(e){return e.descriptor.id===s}));-1===u&&Xx(!1);var f=u-1;return f<0?null:a(l[f].descriptor.id)}({isMovingForward:t,draggable:n,destination:r,insideDestination:u,previousImpact:o})||Gj({isMovingForward:t,isInHomeList:f,draggable:n,draggables:i,destination:r,insideDestination:u,previousImpact:o,viewport:a,afterCritical:l});if(!h)return null;var d=eM({impact:h,draggable:n,droppable:r,draggables:i,afterCritical:l});if(iM({draggable:n,destination:r,newPageBorderBoxCenter:d,viewport:a.frame,withDroppableDisplacement:!1,onlyOnMainAxis:!0}))return{clientSelection:rM({pageBorderBoxCenter:d,draggable:n,viewport:a}),impact:h,scrollJumpRequest:null};var p=oj(d,c);return{clientSelection:s,impact:function(e){var t=e.impact,n=e.viewport,r=e.destination,i=e.draggables,o=e.maxScrollChange,a=tM(n,ij(n.scroll.current,o)),c=r.frame?vj(r,ij(r.frame.scroll.current,o)):r,s=t.displaced,l=Fj({afterDragging:nM(s.all,i),destination:r,displacedBy:t.displacedBy,viewport:a.frame,last:s,forceShouldAnimate:!1}),u=Fj({afterDragging:nM(s.all,i),destination:c,displacedBy:t.displacedBy,viewport:n.frame,last:s,forceShouldAnimate:!1}),f={},h={},d=[s,l,u];return s.all.forEach((function(e){var t=function(e,t){for(var n=0;n1?u.sort((function(e,t){return aM(e)[c.start]-aM(t)[c.start]}))[0]:l.sort((function(e,t){var r=uj(n,dj(aM(e))),i=uj(n,dj(aM(t)));return r!==i?r-i:aM(e)[c.start]-aM(t)[c.start]}))[0]}({isMovingForward:t,pageBorderBoxCenter:n,source:i,droppables:a,viewport:c});if(!l)return null;var u=Mj(l.descriptor.id,o),f=function(e){var t=e.previousPageBorderBoxCenter,n=e.moveRelativeTo,r=e.insideDestination,i=e.draggable,o=e.draggables,a=e.destination,c=e.viewport,s=e.afterCritical;if(!n){if(r.length)return null;var l={displaced:Oj,displacedBy:Tj,at:{type:"REORDER",destination:{droppableId:a.descriptor.id,index:0}}},u=eM({impact:l,draggable:i,droppable:a,draggables:o,afterCritical:s}),f=Sj(i,a)?a:fM(a,i,o);return iM({draggable:i,destination:f,newPageBorderBoxCenter:u,viewport:c.frame,withDroppableDisplacement:!1,onlyOnMainAxis:!0})?l:null}var h=Boolean(t[a.axis.line]<=n.page.borderBox.center[a.axis.line]),d=function(){var e=n.descriptor.index;return n.descriptor.id===i.descriptor.id?e:h?e:e+1}(),p=lM(a.axis,i.displaceBy);return Uj({draggable:i,insideDestination:r,destination:a,viewport:c,displacedBy:p,last:Oj,index:d})}({previousPageBorderBoxCenter:n,destination:l,draggable:r,draggables:o,moveRelativeTo:function(e){var t=e.pageBorderBoxCenter,n=e.viewport,r=e.destination,i=e.insideDestination,o=e.afterCritical;return i.filter((function(e){return Ij({target:sM(e,o),destination:r,viewport:n.frame,withDroppableDisplacement:!0})})).sort((function(e,n){var i=lj(t,Jj(r,cM(e,o))),a=lj(t,Jj(r,cM(n,o)));return ir.left&&n.topr.top))return!1;if(vM(i)(t.center))return!0;var o=e.axis,a=i.center[o.crossAxisLine],c=t[o.crossAxisStart],s=t[o.crossAxisEnd],l=Aj(i[o.crossAxisStart],i[o.crossAxisEnd]),u=l(c),f=l(s);return!u&&!f||(u?ca)}));return i.length?1===i.length?i[0].descriptor.id:function(e){var t=e.pageBorderBox,n=e.draggable,r=e.candidates,i=n.page.borderBox.center,o=r.map((function(e){var n=e.axis,r=sj(e.axis.line,t.center[n.line],e.page.borderBox.center[n.crossAxisLine]);return{id:e.descriptor.id,distance:lj(i,r)}})).sort((function(e,t){return t.distance-e.distance}));return o[0]?o[0].id:null}({pageBorderBox:t,draggable:n,candidates:i}):null}var mM=function(e,t){return _x(hj(e,t))};function yM(e){var t=e.displaced,n=e.id;return Boolean(t.visible[n]||t.invisible[n])}var bM=function(e){var t=e.pageOffset,n=e.draggable,r=e.draggables,i=e.droppables,o=e.previousImpact,a=e.viewport,c=e.afterCritical,s=mM(n.page.borderBox,t),l=gM({pageBorderBox:s,draggable:n,droppables:i});if(!l)return Ej;var u=i[l],f=Mj(u.descriptor.id,r),h=function(e,t){var n=e.frame;return n?mM(t,n.scroll.diff.value):t}(u,s);return function(e){var t=e.draggable,n=e.pageBorderBoxWithDroppableScroll,r=e.previousImpact,i=e.destination,o=e.insideDestination,a=e.afterCritical;if(!i.isCombineEnabled)return null;var c=i.axis,s=lM(i.axis,t.displaceBy),l=s.value,u=n[c.start],f=n[c.end],h=yj(qj(t,o),(function(e){var t=e.descriptor.id,n=e.page.borderBox,i=n[c.size]/4,o=Wj(t,a),s=yM({displaced:r.displaced,id:t});return o?s?f>n[c.start]+i&&fn[c.start]-l+i&&un[c.start]+l+i&&fn[c.start]+i&&ut.descriptor.index?n.descriptor.index-1:n.descriptor.index:null}({draggable:n,closest:yj(qj(n,i),(function(e){var t=e.descriptor.id,n=e.page.borderBox.center[s.line],r=Wj(t,c),i=yM({displaced:o,id:t});return r?i?h<=n:f=1500)return a_;var o=o_+c_*(i/1500);return Number(("CANCEL"===r?.6*o:o).toFixed(2))}({current:i.current.client.offset,destination:v,reason:o});n(function(e){return{type:"DROP_ANIMATE",payload:e}}({newHomeClientOffset:v,dropDuration:m,completed:g}))}else n(ZM({completed:g}))}}else n(function(e){return{type:"DROP_PENDING",payload:e}}({reason:o}))}else e(r)}}},l_=function(){return{x:window.pageXOffset,y:window.pageYOffset}};function u_(e){var t=e.onWindowScroll;var n,r=Dx((function(){t(l_())})),i=(n=r,{eventName:"scroll",options:{passive:!0,capture:!1},fn:function(e){e.target!==window&&e.target!==window.document||n()}}),o=Wx;function a(){return o!==Wx}return{start:function(){a()&&Xx(!1),o=Gx(window,[i])},stop:function(){a()||Xx(!1),r.cancel(),o(),o=Wx},isActive:a}}var f_=function(e){var t=u_({onWindowScroll:function(t){e.dispatch({type:"MOVE_BY_WINDOW_SCROLL",payload:{newScroll:t}})}});return function(e){return function(n){t.isActive()||"INITIAL_PUBLISH"!==n.type||t.start(),t.isActive()&&function(e){return"DROP_COMPLETE"===e.type||"DROP_ANIMATE"===e.type||"FLUSH"===e.type}(n)&&t.stop(),e(n)}}},h_=function(){var e=[];return{add:function(t){var n=setTimeout((function(){return function(t){var n=mj(e,(function(e){return e.timerId===t}));-1===n&&Xx(!1),e.splice(n,1)[0].callback()}(n)})),r={timerId:n,callback:t};e.push(r)},flush:function(){if(e.length){var t=[].concat(e);e.length=0,t.forEach((function(e){clearTimeout(e.timerId),e.callback()}))}}}},d_=function(e,t){qM(),t(),SM()},p_=function(e,t){return{draggableId:e.draggable.id,type:e.droppable.type,source:{droppableId:e.droppable.id,index:e.draggable.index},mode:t}},z_=function(e,t,n,r){if(e){var i=function(e){var t=!1,n=!1,r=setTimeout((function(){n=!0})),i=function(i){t||n||(t=!0,e(i),clearTimeout(r))};return i.wasCalled=function(){return t},i}(n);e(t,{announce:i}),i.wasCalled()||n(r(t))}else n(r(t))},v_=function(e,t){var n=function(e,t){var n=h_(),r=null,i=function(n){r||Xx(!1),r=null,d_(0,(function(){return z_(e().onDragEnd,n,t,nj.onDragEnd)}))};return{beforeCapture:function(t,n){r&&Xx(!1),d_(0,(function(){var r=e().onBeforeCapture;r&&r({draggableId:t,mode:n})}))},beforeStart:function(t,n){r&&Xx(!1),d_(0,(function(){var r=e().onBeforeDragStart;r&&r(p_(t,n))}))},start:function(i,o){r&&Xx(!1);var a=p_(i,o);r={mode:o,lastCritical:i,lastLocation:a.source,lastCombine:null},n.add((function(){d_(0,(function(){return z_(e().onDragStart,a,t,nj.onDragStart)}))}))},update:function(i,o){var a=_j(o),c=Cj(o);r||Xx(!1);var s=!function(e,t){if(e===t)return!0;var n=e.draggable.id===t.draggable.id&&e.draggable.droppableId===t.draggable.droppableId&&e.draggable.type===t.draggable.type&&e.draggable.index===t.draggable.index,r=e.droppable.id===t.droppable.id&&e.droppable.type===t.droppable.type;return n&&r}(i,r.lastCritical);s&&(r.lastCritical=i);var l,u,f=(l=r.lastLocation,u=a,!(null==l&&null==u||null!=l&&null!=u&&l.droppableId===u.droppableId&&l.index===u.index));f&&(r.lastLocation=a);var h=!function(e,t){return null==e&&null==t||null!=e&&null!=t&&(e.draggableId===t.draggableId&&e.droppableId===t.droppableId)}(r.lastCombine,c);if(h&&(r.lastCombine=c),s||f||h){var d=Hk({},p_(i,r.mode),{combine:c,destination:a});n.add((function(){d_(0,(function(){return z_(e().onDragUpdate,d,t,nj.onDragUpdate)}))}))}},flush:function(){r||Xx(!1),n.flush()},drop:i,abort:function(){if(r){var e=Hk({},p_(r.lastCritical,r.mode),{combine:null,destination:null,reason:"CANCEL"});i(e)}}}}(e,t);return function(e){return function(t){return function(r){if("BEFORE_INITIAL_CAPTURE"!==r.type){if("INITIAL_PUBLISH"===r.type){var i=r.payload.critical;return n.beforeStart(i,r.payload.movementMode),t(r),void n.start(i,r.payload.movementMode)}if("DROP_COMPLETE"===r.type){var o=r.payload.completed.result;return n.flush(),t(r),void n.drop(o)}if(t(r),"FLUSH"!==r.type){var a=e.getState();"DRAGGING"===a.phase&&n.update(a.critical,a.impact)}else n.abort()}else n.beforeCapture(r.payload.draggableId,r.payload.movementMode)}}}},g_=function(e){return function(t){return function(n){if("DROP_ANIMATION_FINISHED"===n.type){var r=e.getState();"DROP_ANIMATING"!==r.phase&&Xx(!1),e.dispatch(ZM({completed:r.completed}))}else t(n)}}},m_=function(e){var t=null,n=null;return function(r){return function(i){if("FLUSH"!==i.type&&"DROP_COMPLETE"!==i.type&&"DROP_ANIMATION_FINISHED"!==i.type||(n&&(cancelAnimationFrame(n),n=null),t&&(t(),t=null)),r(i),"DROP_ANIMATE"===i.type){var o={eventName:"scroll",options:{capture:!0,passive:!1,once:!0},fn:function(){"DROP_ANIMATING"===e.getState().phase&&e.dispatch({type:"DROP_ANIMATION_FINISHED",payload:null})}};n=requestAnimationFrame((function(){n=null,t=Gx(window,[o])}))}}}},y_=function(e){return function(t){return function(n){if(t(n),"PUBLISH_WHILE_DRAGGING"===n.type){var r=e.getState();"DROP_PENDING"===r.phase&&(r.isWaiting||e.dispatch($M({reason:r.reason})))}}}},b_=Dk.d,w_=function(e){var t,n=e.dimensionMarshal,r=e.focusMarshal,i=e.styleMarshal,o=e.getResponders,a=e.announce,c=e.autoScroller;return Object(Dk.e)(HM,b_(Object(Dk.a)((t=i,function(){return function(e){return function(n){"INITIAL_PUBLISH"===n.type&&t.dragging(),"DROP_ANIMATE"===n.type&&t.dropping(n.payload.completed.result.reason),"FLUSH"!==n.type&&"DROP_COMPLETE"!==n.type||t.resting(),e(n)}}}),function(e){return function(){return function(t){return function(n){"DROP_COMPLETE"!==n.type&&"FLUSH"!==n.type&&"DROP_ANIMATE"!==n.type||e.stopPublishing(),t(n)}}}}(n),function(e){return function(t){var n=t.getState,r=t.dispatch;return function(t){return function(i){if("LIFT"===i.type){var o=i.payload,a=o.id,c=o.clientSelection,s=o.movementMode,l=n();"DROP_ANIMATING"===l.phase&&r(ZM({completed:l.completed})),"IDLE"!==n().phase&&Xx(!1),r(YM()),r({type:"BEFORE_INITIAL_CAPTURE",payload:{draggableId:a,movementMode:s}});var u={draggableId:a,scrollOptions:{shouldPublishImmediately:"SNAP"===s}},f=e.startPublishing(u),h=f.critical,d=f.dimensions,p=f.viewport;r(function(e){return{type:"INITIAL_PUBLISH",payload:e}}({critical:h,dimensions:d,clientSelection:c,movementMode:s,viewport:p}))}else t(i)}}}}(n),s_,g_,m_,y_,function(e){return function(t){return function(n){return function(r){if(function(e){return"DROP_COMPLETE"===e.type||"DROP_ANIMATE"===e.type||"FLUSH"===e.type}(r))return e.stop(),void n(r);if("INITIAL_PUBLISH"===r.type){n(r);var i=t.getState();return"DRAGGING"!==i.phase&&Xx(!1),void e.start(i)}n(r),e.scroll(t.getState())}}}}(c),f_,function(e){var t=!1;return function(){return function(n){return function(r){if("INITIAL_PUBLISH"===r.type)return t=!0,e.tryRecordFocus(r.payload.critical.draggable.id),n(r),void e.tryRestoreFocusRecorded();if(n(r),t){if("FLUSH"===r.type)return t=!1,void e.tryRestoreFocusRecorded();if("DROP_COMPLETE"===r.type){t=!1;var i=r.payload.completed.result;i.combine&&e.tryShiftRecord(i.draggableId,i.combine.draggableId),e.tryRestoreFocusRecorded()}}}}}}(r),v_(o,a))))},k_=function(){return{additions:{},removals:{},modified:{}}};var x_=function(e){var t=e.scrollHeight,n=e.scrollWidth,r=e.height,i=e.width,o=oj({x:n,y:t},{x:i,y:r});return{x:Math.max(0,o.x),y:Math.max(0,o.y)}},j_=function(){var e=document.documentElement;return e||Xx(!1),e},M_=function(){var e=j_();return x_({scrollHeight:e.scrollHeight,scrollWidth:e.scrollWidth,width:e.clientWidth,height:e.clientHeight})},__=function(e){var t=e.critical,n=e.scrollOptions,r=e.registry;qM();var i=function(){var e=l_(),t=M_(),n=e.y,r=e.x,i=j_(),o=i.clientWidth,a=i.clientHeight;return{frame:_x({top:n,left:r,right:r+o,bottom:n+a}),scroll:{initial:e,current:e,max:t,diff:{value:rj,displacement:rj}}}}(),o=i.scroll.current,a=t.droppable,c=r.droppable.getAllByType(a.type).map((function(e){return e.callbacks.getDimensionAndWatchScroll(o,n)})),s=r.draggable.getAllByType(t.draggable.type).map((function(e){return e.getDimension(o)})),l={draggables:kj(s),droppables:wj(c)};return SM(),{dimensions:l,critical:t,viewport:i}};function C_(e,t,n){return n.descriptor.id!==t.id&&(n.descriptor.type===t.type&&"virtual"===e.droppable.getById(n.descriptor.droppableId).descriptor.mode)}var q_=function(e,t){var n=null,r=function(e){var t=e.registry,n=e.callbacks,r=k_(),i=null,o=function(){i||(n.collectionStarting(),i=requestAnimationFrame((function(){i=null,qM();var e=r,o=e.additions,a=e.removals,c=e.modified,s=Object.keys(o).map((function(e){return t.draggable.getById(e).getDimension(rj)})).sort((function(e,t){return e.descriptor.index-t.descriptor.index})),l=Object.keys(c).map((function(e){return{droppableId:e,scroll:t.droppable.getById(e).callbacks.getScrollWhileDragging()}})),u={additions:s,removals:Object.keys(a),modified:l};r=k_(),SM(),n.publish(u)})))};return{add:function(e){var t=e.descriptor.id;r.additions[t]=e,r.modified[e.descriptor.droppableId]=!0,r.removals[t]&&delete r.removals[t],o()},remove:function(e){var t=e.descriptor;r.removals[t.id]=!0,r.modified[t.droppableId]=!0,r.additions[t.id]&&delete r.additions[t.id],o()},stop:function(){i&&(cancelAnimationFrame(i),i=null,r=k_())}}}({callbacks:{publish:t.publishWhileDragging,collectionStarting:t.collectionStarting},registry:e}),i=function(t){n||Xx(!1);var i=n.critical.draggable;"ADDITION"===t.type&&C_(e,i,t.value)&&r.add(t.value),"REMOVAL"===t.type&&C_(e,i,t.value)&&r.remove(t.value)};return{updateDroppableIsEnabled:function(r,i){e.droppable.exists(r)||Xx(!1),n&&t.updateDroppableIsEnabled({id:r,isEnabled:i})},updateDroppableIsCombineEnabled:function(r,i){n&&(e.droppable.exists(r)||Xx(!1),t.updateDroppableIsCombineEnabled({id:r,isCombineEnabled:i}))},scrollDroppable:function(t,r){n&&e.droppable.getById(t).callbacks.scroll(r)},updateDroppableScroll:function(r,i){n&&(e.droppable.exists(r)||Xx(!1),t.updateDroppableScroll({id:r,newScroll:i}))},startPublishing:function(t){n&&Xx(!1);var r=e.draggable.getById(t.draggableId),o=e.droppable.getById(r.descriptor.droppableId),a={draggable:r.descriptor,droppable:o.descriptor},c=e.subscribe(i);return n={critical:a,unsubscribe:c},__({critical:a,registry:e,scrollOptions:t.scrollOptions})},stopPublishing:function(){if(n){r.stop();var t=n.critical.droppable;e.droppable.getAllByType(t.type).forEach((function(e){return e.callbacks.dragStopped()})),n.unsubscribe(),n=null}}}},S_=function(e,t){return"IDLE"===e.phase||"DROP_ANIMATING"===e.phase&&(e.completed.result.draggableId!==t&&"DROP"===e.completed.result.reason)},T_=function(e){window.scrollBy(e.x,e.y)},O_=Cp((function(e){return xj(e).filter((function(e){return!!e.isEnabled&&!!e.frame}))})),E_=function(e){var t=e.center,n=e.destination,r=e.droppables;if(n){var i=r[n];return i.frame?i:null}return function(e,t){return yj(O_(t),(function(t){return t.frame||Xx(!1),vM(t.frame.pageMarginBox)(e)}))}(t,r)},A_=.25,L_=.05,H_=28,D_=function(e){return Math.pow(e,2)},P_={stopDampeningAt:1200,accelerateAt:360},V_=function(e){var t=e.startOfRange,n=e.endOfRange,r=e.current,i=n-t;return 0===i?0:(r-t)/i},N_=P_.accelerateAt,I_=P_.stopDampeningAt,R_=function(e){var t=e.distanceToEdge,n=e.thresholds,r=e.dragStartTime,i=e.shouldUseTimeDampening,o=function(e,t){if(e>t.startScrollingFrom)return 0;if(e<=t.maxScrollValueAt)return H_;if(e===t.startScrollingFrom)return 1;var n=V_({startOfRange:t.maxScrollValueAt,endOfRange:t.startScrollingFrom,current:e}),r=H_*D_(1-n);return Math.ceil(r)}(t,n);return 0===o?0:i?Math.max(function(e,t){var n=t,r=I_,i=Date.now()-n;if(i>=I_)return e;if(it.height,o=n.width>t.width;return o||i?o&&i?null:{x:o?0:r.x,y:i?0:r.y}:r}({container:n,subject:r,proposedScroll:l});return u?aj(u,rj)?null:u:null},W_=fj((function(e){return 0===e?0:e>0?1:-1})),G_=function(){var e=function(e,t){return e<0?e:e>t?e-t:0};return function(t){var n=t.current,r=t.max,i=t.change,o=ij(n,i),a={x:e(o.x,r.x),y:e(o.y,r.y)};return aj(a,rj)?null:a}}(),Y_=function(e){var t=e.max,n=e.current,r=e.change,i={x:Math.max(n.x,t.x),y:Math.max(n.y,t.y)},o=W_(r),a=G_({max:i,current:n,change:o});return!a||(0!==o.x&&0===a.x||0!==o.y&&0===a.y)},Z_=function(e,t){return Y_({current:e.scroll.current,max:e.scroll.max,change:t})},$_=function(e,t){var n=e.frame;return!!n&&Y_({current:n.scroll.current,max:n.scroll.max,change:t})},X_=function(e){var t=e.state,n=e.dragStartTime,r=e.shouldUseTimeDampening,i=e.scrollWindow,o=e.scrollDroppable,a=t.current.page.borderBoxCenter,c=t.dimensions.draggables[t.critical.draggable.id].page.marginBox;if(t.isWindowScrollAllowed){var s=function(e){var t=e.viewport,n=e.subject,r=e.center,i=e.dragStartTime,o=e.shouldUseTimeDampening,a=U_({dragStartTime:i,container:t.frame,subject:n,center:r,shouldUseTimeDampening:o});return a&&Z_(t,a)?a:null}({dragStartTime:n,viewport:t.viewport,subject:c,center:a,shouldUseTimeDampening:r});if(s)return void i(s)}var l=E_({center:a,destination:dM(t.impact),droppables:t.dimensions.droppables});if(l){var u=function(e){var t=e.droppable,n=e.subject,r=e.center,i=e.dragStartTime,o=e.shouldUseTimeDampening,a=t.frame;if(!a)return null;var c=U_({dragStartTime:i,container:a.pageMarginBox,subject:n,center:r,shouldUseTimeDampening:o});return c&&$_(t,c)?c:null}({dragStartTime:n,droppable:l,subject:c,center:a,shouldUseTimeDampening:r});u&&o(l.descriptor.id,u)}},K_=function(e){var t=e.move,n=e.scrollDroppable,r=e.scrollWindow,i=function(e,t){if(!$_(e,t))return t;var r=function(e,t){var n=e.frame;return n&&$_(e,t)?G_({current:n.scroll.current,max:n.scroll.max,change:t}):null}(e,t);if(!r)return n(e.descriptor.id,t),null;var i=oj(t,r);return n(e.descriptor.id,i),oj(t,i)},o=function(e,t,n){if(!e)return n;if(!Z_(t,n))return n;var i=function(e,t){if(!Z_(e,t))return null;var n=e.scroll.max,r=e.scroll.current;return G_({current:r,max:n,change:t})}(t,n);if(!i)return r(n),null;var o=oj(n,i);return r(o),oj(n,o)};return function(e){var n=e.scrollJumpRequest;if(n){var r=dM(e.impact);r||Xx(!1);var a=i(e.dimensions.droppables[r],n);if(a){var c=e.viewport,s=o(e.isWindowScrollAllowed,c,a);s&&function(e,n){var r=ij(e.current.client.selection,n);t({client:r})}(e,s)}}}},Q_=function(e){var t=e.scrollDroppable,n=e.scrollWindow,r=e.move,i=function(e){var t=e.scrollWindow,n=e.scrollDroppable,r=Dx(t),i=Dx(n),o=null,a=function(e){o||Xx(!1);var t=o,n=t.shouldUseTimeDampening,a=t.dragStartTime;X_({state:e,scrollWindow:r,scrollDroppable:i,dragStartTime:a,shouldUseTimeDampening:n})};return{start:function(e){qM(),o&&Xx(!1);var t=Date.now(),n=!1,r=function(){n=!0};X_({state:e,dragStartTime:0,shouldUseTimeDampening:!1,scrollWindow:r,scrollDroppable:r}),o={dragStartTime:t,shouldUseTimeDampening:n},SM(),n&&a(e)},stop:function(){o&&(r.cancel(),i.cancel(),o=null)},scroll:a}}({scrollWindow:n,scrollDroppable:t}),o=K_({move:r,scrollWindow:n,scrollDroppable:t});return{scroll:function(e){"DRAGGING"===e.phase&&("FLUID"!==e.movementMode?e.scrollJumpRequest&&o(e):i.scroll(e))},start:i.start,stop:i.stop}},J_="data-rbd",eC=function(){var e=J_+"-drag-handle";return{base:e,draggableId:e+"-draggable-id",contextId:e+"-context-id"}}(),tC=function(){var e=J_+"-draggable";return{base:e,contextId:e+"-context-id",id:e+"-id"}}(),nC=function(){var e=J_+"-droppable";return{base:e,contextId:e+"-context-id",id:e+"-id"}}(),rC={contextId:J_+"-scroll-container-context-id"},iC=function(e,t){return e.map((function(e){var n=e.styles[t];return n?e.selector+" { "+n+" }":""})).join(" ")},oC=function(e){var t,n=(t=e,function(e){return"["+e+'="'+t+'"]'}),r=function(){var e="\n cursor: -webkit-grab;\n cursor: grab;\n ";return{selector:n(eC.contextId),styles:{always:"\n -webkit-touch-callout: none;\n -webkit-tap-highlight-color: rgba(0,0,0,0);\n touch-action: manipulation;\n ",resting:e,dragging:"pointer-events: none;",dropAnimating:e}}}(),i=[function(){var e="\n transition: "+n_.outOfTheWay+";\n ";return{selector:n(tC.contextId),styles:{dragging:e,dropAnimating:e,userCancel:e}}}(),r,{selector:n(nC.contextId),styles:{always:"overflow-anchor: none;"}},{selector:"body",styles:{dragging:"\n cursor: grabbing;\n cursor: -webkit-grabbing;\n user-select: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n overflow-anchor: none;\n "}}];return{always:iC(i,"always"),resting:iC(i,"resting"),dragging:iC(i,"dragging"),dropAnimating:iC(i,"dropAnimating"),userCancel:iC(i,"userCancel")}},aC="undefined"!==typeof window&&"undefined"!==typeof window.document&&"undefined"!==typeof window.document.createElement?a.useLayoutEffect:a.useEffect,cC=function(){var e=document.querySelector("head");return e||Xx(!1),e},sC=function(e){var t=document.createElement("style");return e&&t.setAttribute("nonce",e),t.type="text/css",t};var lC=function(e){return e&&e.ownerDocument?e.ownerDocument.defaultView:window};function uC(e){return e instanceof lC(e).HTMLElement}function fC(e,t){var n="["+eC.contextId+'="'+e+'"]',r=bj(document.querySelectorAll(n));if(!r.length)return null;var i=yj(r,(function(e){return e.getAttribute(eC.draggableId)===t}));return i&&uC(i)?i:null}function hC(){var e={draggables:{},droppables:{}},t=[];function n(e){t.length&&t.forEach((function(t){return t(e)}))}function r(t){return e.draggables[t]||null}function i(t){return e.droppables[t]||null}return{draggable:{register:function(t){e.draggables[t.descriptor.id]=t,n({type:"ADDITION",value:t})},update:function(t,n){var r=e.draggables[n.descriptor.id];r&&r.uniqueId===t.uniqueId&&(delete e.draggables[n.descriptor.id],e.draggables[t.descriptor.id]=t)},unregister:function(t){var i=t.descriptor.id,o=r(i);o&&t.uniqueId===o.uniqueId&&(delete e.draggables[i],n({type:"REMOVAL",value:t}))},getById:function(e){var t=r(e);return t||Xx(!1),t},findById:r,exists:function(e){return Boolean(r(e))},getAllByType:function(t){return gj(e.draggables).filter((function(e){return e.descriptor.type===t}))}},droppable:{register:function(t){e.droppables[t.descriptor.id]=t},unregister:function(t){var n=i(t.descriptor.id);n&&t.uniqueId===n.uniqueId&&delete e.droppables[t.descriptor.id]},getById:function(e){var t=i(e);return t||Xx(!1),t},findById:i,exists:function(e){return Boolean(i(e))},getAllByType:function(t){return gj(e.droppables).filter((function(e){return e.descriptor.type===t}))}},subscribe:function(e){return t.push(e),function(){var n=t.indexOf(e);-1!==n&&t.splice(n,1)}},clean:function(){e.draggables={},e.droppables={},t.length=0}}}var dC=c.a.createContext(null),pC=function(){var e=document.body;return e||Xx(!1),e},zC={position:"absolute",width:"1px",height:"1px",margin:"-1px",border:"0",padding:"0",overflow:"hidden",clip:"rect(0 0 0 0)","clip-path":"inset(100%)"},vC=function(e){return"rbd-announcement-"+e};var gC=0,mC={separator:"::"};function yC(e,t){return void 0===t&&(t=mC),jx((function(){return""+e+t.separator+gC++}),[t.separator,e])}var bC=c.a.createContext(null);function wC(e){0}function kC(e,t){wC()}function xC(e){var t=Object(a.useRef)(e);return Object(a.useEffect)((function(){t.current=e})),t}var jC,MC=27,_C=32,CC=37,qC=38,SC=39,TC=40,OC=((jC={})[13]=!0,jC[9]=!0,jC),EC=function(e){OC[e.keyCode]&&e.preventDefault()},AC=function(){var e="visibilitychange";return"undefined"===typeof document?e:yj([e,"ms"+e,"webkit"+e,"moz"+e,"o"+e],(function(e){return"on"+e in document}))||e}(),LC=0,HC=5;var DC,PC={type:"IDLE"};function VC(e){var t=e.cancel,n=e.completed,r=e.getPhase,i=e.setPhase;return[{eventName:"mousemove",fn:function(e){var t=e.button,n=e.clientX,o=e.clientY;if(t===LC){var a={x:n,y:o},c=r();if("DRAGGING"===c.type)return e.preventDefault(),void c.actions.move(a);"PENDING"!==c.type&&Xx(!1);var s=c.point;if(l=s,u=a,Math.abs(u.x-l.x)>=HC||Math.abs(u.y-l.y)>=HC){var l,u;e.preventDefault();var f=c.actions.fluidLift(a);i({type:"DRAGGING",actions:f})}}}},{eventName:"mouseup",fn:function(e){var i=r();"DRAGGING"===i.type?(e.preventDefault(),i.actions.drop({shouldBlockNextClick:!0}),n()):t()}},{eventName:"mousedown",fn:function(e){"DRAGGING"===r().type&&e.preventDefault(),t()}},{eventName:"keydown",fn:function(e){if("PENDING"!==r().type)return e.keyCode===MC?(e.preventDefault(),void t()):void EC(e);t()}},{eventName:"resize",fn:t},{eventName:"scroll",options:{passive:!0,capture:!1},fn:function(){"PENDING"===r().type&&t()}},{eventName:"webkitmouseforcedown",fn:function(e){var n=r();"IDLE"===n.type&&Xx(!1),n.actions.shouldRespectForcePress()?t():e.preventDefault()}},{eventName:AC,fn:t}]}function NC(){}var IC=((DC={})[34]=!0,DC[33]=!0,DC[36]=!0,DC[35]=!0,DC);function RC(e,t){function n(){t(),e.cancel()}return[{eventName:"keydown",fn:function(r){return r.keyCode===MC?(r.preventDefault(),void n()):r.keyCode===_C?(r.preventDefault(),t(),void e.drop()):r.keyCode===TC?(r.preventDefault(),void e.moveDown()):r.keyCode===qC?(r.preventDefault(),void e.moveUp()):r.keyCode===SC?(r.preventDefault(),void e.moveRight()):r.keyCode===CC?(r.preventDefault(),void e.moveLeft()):void(IC[r.keyCode]?r.preventDefault():EC(r))}},{eventName:"mousedown",fn:n},{eventName:"mouseup",fn:n},{eventName:"click",fn:n},{eventName:"touchstart",fn:n},{eventName:"resize",fn:n},{eventName:"wheel",fn:n,options:{passive:!0}},{eventName:AC,fn:n}]}var FC={type:"IDLE"},BC=120,UC=.15;var WC={input:!0,button:!0,textarea:!0,select:!0,option:!0,optgroup:!0,video:!0,audio:!0};function GC(e,t){var n=t.target;return!!uC(n)&&function e(t,n){if(null==n)return!1;if(Boolean(WC[n.tagName.toLowerCase()]))return!0;var r=n.getAttribute("contenteditable");return"true"===r||""===r||n!==t&&e(t,n.parentElement)}(e,n)}var YC=function(e){return _x(e.getBoundingClientRect()).center};var ZC="undefined"===typeof document?"matches":yj(["matches","msMatchesSelector","webkitMatchesSelector"],(function(e){return e in Element.prototype}))||"matches";function $C(e,t){return e.closest?e.closest(t):function e(t,n){return null==t?null:t[ZC](n)?t:e(t.parentElement,n)}(e,t)}function XC(e,t){var n,r=t.target;if(!((n=r)instanceof lC(n).Element))return null;var i=$C(r,function(e){return"["+eC.contextId+'="'+e+'"]'}(e));return i&&uC(i)?i:null}function KC(e){e.preventDefault()}function QC(e){var t=e.expected,n=e.phase,r=e.isLockActive;e.shouldWarn;return!!r()&&t===n}function JC(e){var t=e.lockAPI,n=e.store,r=e.registry,i=e.draggableId;if(t.isClaimed())return!1;var o=r.draggable.findById(i);return!!o&&(!!o.options.isEnabled&&!!S_(n.getState(),i))}function eq(e){var t=e.lockAPI,n=e.contextId,r=e.store,i=e.registry,o=e.draggableId,a=e.forceSensorStop,c=e.sourceEvent;if(!JC({lockAPI:t,store:r,registry:i,draggableId:o}))return null;var s=i.draggable.getById(o),l=function(e,t){var n="["+tC.contextId+'="'+e+'"]',r=yj(bj(document.querySelectorAll(n)),(function(e){return e.getAttribute(tC.id)===t}));return r&&uC(r)?r:null}(n,s.descriptor.id);if(!l)return null;if(c&&!s.options.canDragInteractiveElements&&GC(l,c))return null;var u=t.claim(a||Wx),f="PRE_DRAG";function h(){return s.options.shouldRespectForcePress}function d(){return t.isActive(u)}var p=function(e,t){QC({expected:e,phase:f,isLockActive:d,shouldWarn:!0})&&r.dispatch(t())}.bind(null,"DRAGGING");function z(e){function n(){t.release(),f="COMPLETED"}function i(t,i){if(void 0===i&&(i={shouldBlockNextClick:!1}),e.cleanup(),i.shouldBlockNextClick){var o=Gx(window,[{eventName:"click",fn:KC,options:{once:!0,passive:!1,capture:!0}}]);setTimeout(o)}n(),r.dispatch($M({reason:t}))}return"PRE_DRAG"!==f&&(n(),"PRE_DRAG"!==f&&Xx(!1)),r.dispatch(DM(e.liftActionArgs)),f="DRAGGING",Hk({isActive:function(){return QC({expected:"DRAGGING",phase:f,isLockActive:d,shouldWarn:!1})},shouldRespectForcePress:h,drop:function(e){return i("DROP",e)},cancel:function(e){return i("CANCEL",e)}},e.actions)}return{isActive:function(){return QC({expected:"PRE_DRAG",phase:f,isLockActive:d,shouldWarn:!1})},shouldRespectForcePress:h,fluidLift:function(e){var t=Dx((function(e){p((function(){return FM({client:e})}))}));return Hk({},z({liftActionArgs:{id:o,clientSelection:e,movementMode:"FLUID"},cleanup:function(){return t.cancel()},actions:{move:t}}),{move:t})},snapLift:function(){var e={moveUp:function(){return p(BM)},moveRight:function(){return p(WM)},moveDown:function(){return p(UM)},moveLeft:function(){return p(GM)}};return z({liftActionArgs:{id:o,clientSelection:YC(l),movementMode:"SNAP"},cleanup:Wx,actions:e})},abort:function(){QC({expected:"PRE_DRAG",phase:f,isLockActive:d,shouldWarn:!0})&&t.release()}}}var tq=[function(e){var t=Object(a.useRef)(PC),n=Object(a.useRef)(Wx),r=jx((function(){return{eventName:"mousedown",fn:function(t){if(!t.defaultPrevented&&t.button===LC&&!(t.ctrlKey||t.metaKey||t.shiftKey||t.altKey)){var r=e.findClosestDraggableId(t);if(r){var i=e.tryGetLock(r,c,{sourceEvent:t});if(i){t.preventDefault();var o={x:t.clientX,y:t.clientY};n.current(),u(i,o)}}}}}}),[e]),i=jx((function(){return{eventName:"webkitmouseforcewillbegin",fn:function(t){if(!t.defaultPrevented){var n=e.findClosestDraggableId(t);if(n){var r=e.findOptionsForDraggable(n);r&&(r.shouldRespectForcePress||e.canGetLock(n)&&t.preventDefault())}}}}}),[e]),o=Mx((function(){n.current=Gx(window,[i,r],{passive:!1,capture:!0})}),[i,r]),c=Mx((function(){"IDLE"!==t.current.type&&(t.current=PC,n.current(),o())}),[o]),s=Mx((function(){var e=t.current;c(),"DRAGGING"===e.type&&e.actions.cancel({shouldBlockNextClick:!0}),"PENDING"===e.type&&e.actions.abort()}),[c]),l=Mx((function(){var e=VC({cancel:s,completed:c,getPhase:function(){return t.current},setPhase:function(e){t.current=e}});n.current=Gx(window,e,{capture:!0,passive:!1})}),[s,c]),u=Mx((function(e,n){"IDLE"!==t.current.type&&Xx(!1),t.current={type:"PENDING",point:n,actions:e},l()}),[l]);aC((function(){return o(),function(){n.current()}}),[o])},function(e){var t=Object(a.useRef)(NC),n=jx((function(){return{eventName:"keydown",fn:function(n){if(!n.defaultPrevented&&n.keyCode===_C){var i=e.findClosestDraggableId(n);if(i){var o=e.tryGetLock(i,s,{sourceEvent:n});if(o){n.preventDefault();var a=!0,c=o.snapLift();t.current(),t.current=Gx(window,RC(c,s),{capture:!0,passive:!1})}}}function s(){a||Xx(!1),a=!1,t.current(),r()}}}}),[e]),r=Mx((function(){t.current=Gx(window,[n],{passive:!1,capture:!0})}),[n]);aC((function(){return r(),function(){t.current()}}),[r])},function(e){var t=Object(a.useRef)(FC),n=Object(a.useRef)(Wx),r=Mx((function(){return t.current}),[]),i=Mx((function(e){t.current=e}),[]),o=jx((function(){return{eventName:"touchstart",fn:function(t){if(!t.defaultPrevented){var r=e.findClosestDraggableId(t);if(r){var i=e.tryGetLock(r,s,{sourceEvent:t});if(i){var o=t.touches[0],a={x:o.clientX,y:o.clientY};n.current(),h(i,a)}}}}}}),[e]),c=Mx((function(){n.current=Gx(window,[o],{capture:!0,passive:!1})}),[o]),s=Mx((function(){var e=t.current;"IDLE"!==e.type&&("PENDING"===e.type&&clearTimeout(e.longPressTimerId),i(FC),n.current(),c())}),[c,i]),l=Mx((function(){var e=t.current;s(),"DRAGGING"===e.type&&e.actions.cancel({shouldBlockNextClick:!0}),"PENDING"===e.type&&e.actions.abort()}),[s]),u=Mx((function(){var e={capture:!0,passive:!1},t={cancel:l,completed:s,getPhase:r},i=Gx(window,function(e){var t=e.cancel,n=e.completed,r=e.getPhase;return[{eventName:"touchmove",options:{capture:!1},fn:function(e){var n=r();if("DRAGGING"===n.type){n.hasMoved=!0;var i=e.touches[0],o={x:i.clientX,y:i.clientY};e.preventDefault(),n.actions.move(o)}else t()}},{eventName:"touchend",fn:function(e){var i=r();"DRAGGING"===i.type?(e.preventDefault(),i.actions.drop({shouldBlockNextClick:!0}),n()):t()}},{eventName:"touchcancel",fn:function(e){"DRAGGING"===r().type?(e.preventDefault(),t()):t()}},{eventName:"touchforcechange",fn:function(e){var n=r();"IDLE"===n.type&&Xx(!1);var i=e.touches[0];if(i&&i.force>=UC){var o=n.actions.shouldRespectForcePress();if("PENDING"!==n.type)return o?n.hasMoved?void e.preventDefault():void t():void e.preventDefault();o&&t()}}},{eventName:AC,fn:t}]}(t),e),o=Gx(window,function(e){var t=e.cancel,n=e.getPhase;return[{eventName:"orientationchange",fn:t},{eventName:"resize",fn:t},{eventName:"contextmenu",fn:function(e){e.preventDefault()}},{eventName:"keydown",fn:function(e){"DRAGGING"===n().type?(e.keyCode===MC&&e.preventDefault(),t()):t()}},{eventName:AC,fn:t}]}(t),e);n.current=function(){i(),o()}}),[l,r,s]),f=Mx((function(){var e=r();"PENDING"!==e.type&&Xx(!1);var t=e.actions.fluidLift(e.point);i({type:"DRAGGING",actions:t,hasMoved:!1})}),[r,i]),h=Mx((function(e,t){"IDLE"!==r().type&&Xx(!1);var n=setTimeout(f,BC);i({type:"PENDING",point:t,actions:e,longPressTimerId:n}),u()}),[u,r,i,f]);aC((function(){return c(),function(){n.current();var e=r();"PENDING"===e.type&&(clearTimeout(e.longPressTimerId),i(FC))}}),[r,c,i]),aC((function(){return Gx(window,[{eventName:"touchmove",fn:function(){},options:{capture:!1,passive:!1}}])}),[])}];function nq(e){var t=e.contextId,n=e.store,r=e.registry,i=e.customSensors,o=e.enableDefaultSensors,c=[].concat(o?tq:[],i||[]),s=Object(a.useState)((function(){return function(){var e=null;function t(){e||Xx(!1),e=null}return{isClaimed:function(){return Boolean(e)},isActive:function(t){return t===e},claim:function(t){e&&Xx(!1);var n={abandon:t};return e=n,n},release:t,tryAbandon:function(){e&&(e.abandon(),t())}}}()}))[0],l=Mx((function(e,t){e.isDragging&&!t.isDragging&&s.tryAbandon()}),[s]);aC((function(){var e=n.getState();return n.subscribe((function(){var t=n.getState();l(e,t),e=t}))}),[s,n,l]),aC((function(){return s.tryAbandon}),[s.tryAbandon]);var u=Mx((function(e){return JC({lockAPI:s,registry:r,store:n,draggableId:e})}),[s,r,n]),f=Mx((function(e,i,o){return eq({lockAPI:s,registry:r,contextId:t,store:n,draggableId:e,forceSensorStop:i,sourceEvent:o&&o.sourceEvent?o.sourceEvent:null})}),[t,s,r,n]),h=Mx((function(e){return function(e,t){var n=XC(e,t);return n?n.getAttribute(eC.draggableId):null}(t,e)}),[t]),d=Mx((function(e){var t=r.draggable.findById(e);return t?t.options:null}),[r.draggable]),p=Mx((function(){s.isClaimed()&&(s.tryAbandon(),"IDLE"!==n.getState().phase&&n.dispatch(YM()))}),[s,n]),z=Mx(s.isClaimed,[s]),v=jx((function(){return{canGetLock:u,tryGetLock:f,findClosestDraggableId:h,findOptionsForDraggable:d,tryReleaseLock:p,isLockClaimed:z}}),[u,f,h,d,p,z]);wC();for(var g=0;gi))return o.current=Qq(Qq({},o.current),{width:i,tabRight:f,containerRight:s}),f>=s&&!o.current.collapse?(o.current.collapse=!0,r(!0)):f+hs&&u(!0),l<=s&&u(!1),a>0&&c(!0),0===a&&c(!1)}}}),[r,n])]}(l,u,n,s),d=h[0],p=h[1],z=h[2];Object(a.useEffect)((function(){if(l.current){var e=l.current,t=Object(Kq.a)(300,(function(){f(),z()}));return t(),e.addEventListener("scroll",z),window.addEventListener("resize",t),function(){e.removeEventListener("scroll",z),window.removeEventListener("resize",t)}}}),[n,s]);var v=Object(a.useCallback)((function(e){if(e){var t=u.current;n.length>=t.length&&(u.current=cS(t,[e])),n.length0||(i.disconnect(),pS.delete(e),delete hS[r],delete dS[r])}}((function(e){i&&i(e),u(e)}),e,s)}}),[t,n,r,i]);return Object(a.useEffect)((function(){return function(){var e;null===(e=c.current)||void 0===e||e.call(c),c.current=null}}),[]),[f,o,l]},mS=function(){return(mS=Object.assign||function(e){for(var t,n=1,r=arguments.length;n1?t-1:0),r=1;r0?" Args: "+n.join(", "):""))}var M=function(){function e(e){this.groupSizes=new Uint32Array(512),this.length=512,this.tag=e}var t=e.prototype;return t.indexOfGroup=function(e){for(var t=0,n=0;n=this.groupSizes.length){for(var n=this.groupSizes,r=n.length,i=r;e>=i;)(i<<=1)<0&&j(16,""+e);this.groupSizes=new Uint32Array(i),this.groupSizes.set(n),this.length=i;for(var o=r;o=this.length||0===this.groupSizes[e])return t;for(var n=this.groupSizes[e],r=this.indexOfGroup(e),i=r+n,o=r;o=q&&(q=t+1),_.set(e,t),C.set(t,e)},E="style["+w+'][data-styled-version="5.3.5"]',A=new RegExp("^"+w+'\\.g(\\d+)\\[id="([\\w\\d-]+)"\\].*?"([^"]*)'),L=function(e,t,n){for(var r,i=n.split(","),o=0,a=i.length;o=0;n--){var r=t[n];if(r&&1===r.nodeType&&r.hasAttribute(w))return r}}(n),o=void 0!==i?i.nextSibling:null;r.setAttribute(w,"active"),r.setAttribute("data-styled-version","5.3.5");var a=D();return a&&r.setAttribute("nonce",a),n.insertBefore(r,o),r},V=function(){function e(e){var t=this.element=P(e);t.appendChild(document.createTextNode("")),this.sheet=function(e){if(e.sheet)return e.sheet;for(var t=document.styleSheets,n=0,r=t.length;n=0){var n=document.createTextNode(t),r=this.nodes[e];return this.element.insertBefore(n,r||null),this.length++,!0}return!1},t.deleteRule=function(e){this.element.removeChild(this.nodes[e]),this.length--},t.getRule=function(e){return e0&&(l+=e+",")})),r+=""+c+s+'{content:"'+l+'"}/*!sc*/\n'}}}return r}(this)},e}(),U=/(a)(d)/gi,W=function(e){return String.fromCharCode(e+(e>25?39:97))};function G(e){var t,n="";for(t=Math.abs(e);t>52;t=t/52|0)n=W(t%52)+n;return(W(t%52)+n).replace(U,"$1-$2")}var Y=function(e,t){for(var n=t.length;n;)e=33*e^t.charCodeAt(--n);return e},Z=function(e){return Y(5381,e)};function $(e){for(var t=0;t>>0);if(!t.hasNameForId(r,a)){var c=n(o,"."+a,void 0,r);t.insertRules(r,a,c)}i.push(a),this.staticRulesId=a}else{for(var s=this.rules.length,l=Y(this.baseHash,n.hash),u="",f=0;f>>0);if(!t.hasNameForId(r,z)){var v=n(u,"."+z,void 0,r);t.insertRules(r,z,v)}i.push(z)}}return i.join(" ")},e}(),Q=/^\s*\/\/.*$/gm,J=[":","[",".","#"];function ee(e){var t,n,r,i,o=void 0===e?g:e,a=o.options,c=void 0===a?g:a,l=o.plugins,u=void 0===l?v:l,f=new s.a(c),h=[],d=function(e){function t(t){if(t)try{e(t+"}")}catch(e){}}return function(n,r,i,o,a,c,s,l,u,f){switch(n){case 1:if(0===u&&64===r.charCodeAt(0))return e(r+";"),"";break;case 2:if(0===l)return r+"/*|*/";break;case 3:switch(l){case 102:case 112:return e(i[0]+r),"";default:return r+(0===f?"/*|*/":"")}case-2:r.split("/*|*/}").forEach(t)}}}((function(e){h.push(e)})),p=function(e,r,o){return 0===r&&-1!==J.indexOf(o[n.length])||o.match(i)?e:"."+t};function z(e,o,a,c){void 0===c&&(c="&");var s=e.replace(Q,""),l=o&&a?a+" "+o+" { "+s+" }":s;return t=c,n=o,r=new RegExp("\\"+n+"\\b","g"),i=new RegExp("(\\"+n+"\\b){2,}"),f(a||!o?"":o,l)}return f.use([].concat(u,[function(e,t,i){2===e&&i.length&&i[0].lastIndexOf(n)>0&&(i[0]=i[0].replace(r,p))},d,function(e){if(-2===e){var t=h;return h=[],t}}])),z.hash=u.length?u.reduce((function(e,t){return t.name||j(15),Y(e,t.name)}),5381).toString():"",z}var te=o.a.createContext(),ne=(te.Consumer,o.a.createContext()),re=(ne.Consumer,new B),ie=ee();function oe(){return Object(i.useContext)(te)||re}function ae(){return Object(i.useContext)(ne)||ie}function ce(e){var t=Object(i.useState)(e.stylisPlugins),n=t[0],r=t[1],a=oe(),s=Object(i.useMemo)((function(){var t=a;return e.sheet?t=e.sheet:e.target&&(t=t.reconstructWithOptions({target:e.target},!1)),e.disableCSSOMInjection&&(t=t.reconstructWithOptions({useCSSOMInjection:!1})),t}),[e.disableCSSOMInjection,e.sheet,e.target]),l=Object(i.useMemo)((function(){return ee({options:{prefix:!e.disableVendorPrefixes},plugins:n})}),[e.disableVendorPrefixes,n]);return Object(i.useEffect)((function(){c()(n,e.stylisPlugins)||r(e.stylisPlugins)}),[e.stylisPlugins]),o.a.createElement(te.Provider,{value:s},o.a.createElement(ne.Provider,{value:l},e.children))}var se=function(){function e(e,t){var n=this;this.inject=function(e,t){void 0===t&&(t=ie);var r=n.name+t.hash;e.hasNameForId(n.id,r)||e.insertRules(n.id,r,t(n.rules,r,"@keyframes"))},this.toString=function(){return j(12,String(n.name))},this.name=e,this.id="sc-keyframes-"+e,this.rules=t}return e.prototype.getName=function(e){return void 0===e&&(e=ie),this.name+e.hash},e}(),le=/([A-Z])/,ue=/([A-Z])/g,fe=/^ms-/,he=function(e){return"-"+e.toLowerCase()};function de(e){return le.test(e)?e.replace(ue,he).replace(fe,"-ms-"):e}var pe=function(e){return null==e||!1===e||""===e};function ze(e,t,n,r){if(Array.isArray(e)){for(var i,o=[],a=0,c=e.length;a1?t-1:0),r=1;r?@[\\\]^`{|}~-]+/g,be=/(^-|-$)/g;function we(e){return e.replace(ye,"-").replace(be,"")}var ke=function(e){return G(Z(e)>>>0)};function xe(e){return"string"==typeof e&&!0}var je=function(e){return"function"==typeof e||"object"==typeof e&&null!==e&&!Array.isArray(e)},Me=function(e){return"__proto__"!==e&&"constructor"!==e&&"prototype"!==e};function _e(e,t,n){var r=e[n];je(t)&&je(r)?Ce(r,t):e[n]=t}function Ce(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r=0||(i[n]=e[n]);return i}(t,["componentId"]),o=r&&r+"-"+(xe(e)?e:we(y(e)));return Oe(e,d({},i,{attrs:k,componentId:o}),n)},Object.defineProperty(j,"defaultProps",{get:function(){return this._foldedDefaultProps},set:function(t){this._foldedDefaultProps=r?Ce({},e.defaultProps,t):t}}),j.toString=function(){return"."+j.styledComponentId},a&&h()(j,e,{attrs:!0,componentStyle:!0,displayName:!0,foldedComponentIds:!0,shouldForwardProp:!0,styledComponentId:!0,target:!0,withComponent:!0}),j}var Ee=function(e){return function e(t,n,i){if(void 0===i&&(i=g),!Object(r.isValidElementType)(n))return j(1,String(n));var o=function(){return t(n,i,ge.apply(void 0,arguments))};return o.withConfig=function(r){return e(t,n,d({},i,{},r))},o.attrs=function(r){return e(t,n,d({},i,{attrs:Array.prototype.concat(i.attrs,r).filter(Boolean)}))},o}(Oe,e)};["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","big","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","keygen","label","legend","li","link","main","map","mark","marquee","menu","menuitem","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","param","picture","pre","progress","q","rp","rt","ruby","s","samp","script","section","select","small","source","span","strong","style","sub","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr","circle","clipPath","defs","ellipse","foreignObject","g","image","line","linearGradient","marker","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","svg","text","textPath","tspan"].forEach((function(e){Ee[e]=Ee(e)}));!function(){function e(e,t){this.rules=e,this.componentId=t,this.isStatic=$(e),B.registerId(this.componentId+1)}var t=e.prototype;t.createStyles=function(e,t,n,r){var i=r(ze(this.rules,t,n,r).join(""),""),o=this.componentId+e;n.insertRules(o,o,i)},t.removeStyles=function(e,t){t.clearRules(this.componentId+e)},t.renderStyles=function(e,t,n,r){e>2&&B.registerId(this.componentId+e),this.removeStyles(e,n),this.createStyles(e,t,n,r)}}();function Ae(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r"+t+""},this.getStyleTags=function(){return e.sealed?j(2):e._emitSheetCSS()},this.getStyleElement=function(){var t;if(e.sealed)return j(2);var n=((t={})[w]="",t["data-styled-version"]="5.3.5",t.dangerouslySetInnerHTML={__html:e.instance.toString()},t),r=D();return r&&(n.nonce=r),[o.a.createElement("style",d({},n,{key:"sc-0-0"}))]},this.seal=function(){e.sealed=!0},this.instance=new B({isServer:!0}),this.sealed=!1}var t=e.prototype;t.collectStyles=function(e){return this.sealed?j(2):o.a.createElement(ce,{sheet:this.instance},e)},t.interleaveWithNodeStream=function(e){return j(3)}}();t.d=Ee}).call(this,n(102))},function(e,t,n){"use strict";var r=n(158);var i=n(159);function o(e,t){return Object(r.a)(e)||function(e,t){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e)){var n=[],r=!0,i=!1,o=void 0;try{for(var a,c=e[Symbol.iterator]();!(r=(a=c.next()).done)&&(n.push(a.value),!t||n.length!==t);r=!0);}catch(s){i=!0,o=s}finally{try{r||null==c.return||c.return()}finally{if(i)throw o}}return n}}(e,t)||Object(i.a)()}n.d(t,"a",(function(){return o}))},function(e,t,n){"use strict";function r(e,t){if(t.length1?"s":"")+" required, but only "+t.length+" present")}n.d(t,"a",(function(){return r}))},function(e,t,n){"use strict";n.d(t,"a",(function(){return o}));var r=n(14);function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0&&e.splice(n,1)}function p(e){var t=!1;return function(){t||(t=!0,e())}}var z=function(e){throw e},v=function(e){return{value:e,done:!0}};function g(e,t,n){void 0===t&&(t=z),void 0===n&&(n="iterator");var r={meta:{name:n},next:e,throw:t,return:v,isSagaIterator:!0};return"undefined"!==typeof Symbol&&(r[Symbol.iterator]=function(){return r}),r}function m(e,t){var n=t.sagaStack;console.error(e),console.error(n)}var y=function(e){return new Error("\n redux-saga: Error checking hooks detected an inconsistent state. This is likely a bug\n in redux-saga code and not yours. Thanks for reporting this in the project's github repo.\n Error: "+e+"\n")},b=function(e){return Array.apply(null,new Array(e))},w=function(e){return function(t){return e(Object.defineProperty(t,r.f,{value:!0}))}},k=function(e){return e===r.k},x=function(e){return e===r.j},j=function(e){return k(e)||x(e)};function M(e,t){var n=Object.keys(e),r=n.length;var i,a=0,c=Object(o.a)(e)?b(r):{},l={};return n.forEach((function(e){var n=function(n,o){i||(o||j(n)?(t.cancel(),t(n,o)):(c[e]=n,++a===r&&(i=!0,t(c))))};n.cancel=s,l[e]=n})),t.cancel=function(){i||(i=!0,n.forEach((function(e){return l[e].cancel()})))},l}function _(e){return{name:e.name||"anonymous",location:C(e)}}function C(e){return e[r.g]}var q="Channel's Buffer overflow!",S=1,T=3,O=4,E={isEmpty:c,put:s,take:s};function A(e,t){void 0===e&&(e=10);var n=new Array(e),r=0,i=0,o=0,a=function(t){n[i]=t,i=(i+1)%e,r++},c=function(){if(0!=r){var t=n[o];return n[o]=null,r--,o=(o+1)%e,t}},s=function(){for(var e=[];r;)e.push(c());return e};return{isEmpty:function(){return 0==r},put:function(c){var l;if(r1?t-1:0),r=1;r1?t-1:0),r=1;r1?t-1:0),r=1;r1?t-1:0),r=1;r2?n-2:0),o=2;o2?n-2:0),o=2;o1?t-1:0),r=1;r1&&void 0!==arguments[1]?arguments[1]:r,n=null,o=null;return function(){return i(t,n,arguments)||(o=e.apply(null,arguments)),n=arguments,o}}))},,function(e,t,n){"use strict";n.d(t,"a",(function(){return o}));var r=n(30),i=n(38);function o(e){return function t(n,o){switch(arguments.length){case 0:return t;case 1:return Object(i.a)(n)?t:Object(r.a)((function(t){return e(n,t)}));default:return Object(i.a)(n)&&Object(i.a)(o)?t:Object(i.a)(n)?Object(r.a)((function(t){return e(t,o)})):Object(i.a)(o)?Object(r.a)((function(t){return e(n,t)})):e(n,o)}}}},function(e,t,n){"use strict";function r(e,t){if(t.length1?"s":"")+" required, but only "+t.length+" present")}n.d(t,"a",(function(){return r}))},function(e,t,n){e.exports=n(317)},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"createAction",{enumerable:!0,get:function(){return i.default}}),Object.defineProperty(t,"createReducer",{enumerable:!0,get:function(){return o.default}}),Object.defineProperty(t,"assignAll",{enumerable:!0,get:function(){return a.default}}),Object.defineProperty(t,"bindAll",{enumerable:!0,get:function(){return c.default}}),Object.defineProperty(t,"batch",{enumerable:!0,get:function(){return s.default}}),Object.defineProperty(t,"disbatch",{enumerable:!0,get:function(){return l.default}}),Object.defineProperty(t,"loggers",{enumerable:!0,get:function(){return u.default}}),Object.defineProperty(t,"asError",{enumerable:!0,get:function(){return f.default}}),t.types=void 0;var r=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){var r=Object.defineProperty&&Object.getOwnPropertyDescriptor?Object.getOwnPropertyDescriptor(e,n):{};r.get||r.set?Object.defineProperty(t,n,r):t[n]=e[n]}return t.default=e,t}(n(222)),i=h(n(223)),o=h(n(309)),a=h(n(310)),c=h(n(311)),s=h(n(148)),l=h(n(312)),u=h(n(313)),f=h(n(315));function h(e){return e&&e.__esModule?e:{default:e}}var d=r;t.types=d},function(e,t,n){"use strict";n.d(t,"a",(function(){return s})),n.d(t,"b",(function(){return d})),n.d(t,"c",(function(){return g})),n.d(t,"d",(function(){return a})),n.d(t,"e",(function(){return f})),n.d(t,"f",(function(){return v})),n.d(t,"g",(function(){return o})),n.d(t,"h",(function(){return l})),n.d(t,"i",(function(){return h})),n.d(t,"j",(function(){return u})),n.d(t,"k",(function(){return c})),n.d(t,"l",(function(){return p})),n.d(t,"m",(function(){return z})),n.d(t,"n",(function(){return i}));var r=n(33),i=function(e){return null===e||void 0===e},o=function(e){return null!==e&&void 0!==e},a=function(e){return"function"===typeof e},c=function(e){return"string"===typeof e},s=Array.isArray,l=function(e){return e&&!s(e)&&"object"===typeof e},u=function(e){return e&&a(e.then)},f=function(e){return e&&a(e.next)&&a(e.throw)},h=function e(t){return t&&(c(t)||z(t)||a(t)||s(t)&&t.every(e))},d=function(e){return e&&a(e.take)&&a(e.close)},p=function(e){return a(e)&&e.hasOwnProperty("toString")},z=function(e){return Boolean(e)&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype},v=function(e){return d(e)&&e[r.e]},g=function(e){return e&&e[r.c]}},function(e,t,n){"use strict";n.d(t,"a",(function(){return i}));var r=n(20);function i(e){Object(r.a)(1,arguments);var t=Object.prototype.toString.call(e);return e instanceof Date||"object"===typeof e&&"[object Date]"===t?new Date(e.getTime()):"number"===typeof e||"[object Number]"===t?new Date(e):("string"!==typeof e&&"[object String]"!==t||"undefined"===typeof console||(console.warn("Starting with v2.0.0-beta.1 date-fns doesn't accept strings as date arguments. Please use `parseISO` to parse strings. See: https://git.io/fjule"),console.warn((new Error).stack)),new Date(NaN))}},function(e,t,n){"use strict";function r(e){if(null===e||!0===e||!1===e)return NaN;var t=Number(e);return isNaN(t)?t:t<0?Math.ceil(t):Math.floor(t)}n.d(t,"a",(function(){return r}))},,function(e,t,n){"use strict";var r=n(0),i=n.n(r),o=n(13),a=n.n(o),c=i.a.createContext(null);var s=function(e){e()},l=function(){return s},u=null,f={notify:function(){}};var h=function(){function e(e,t){this.store=e,this.parentSub=t,this.unsubscribe=null,this.listeners=f,this.handleChangeWrapper=this.handleChangeWrapper.bind(this)}var t=e.prototype;return t.addNestedSub=function(e){return this.trySubscribe(),this.listeners.subscribe(e)},t.notifyNestedSubs=function(){this.listeners.notify()},t.handleChangeWrapper=function(){this.onStateChange&&this.onStateChange()},t.isSubscribed=function(){return Boolean(this.unsubscribe)},t.trySubscribe=function(){this.unsubscribe||(this.unsubscribe=this.parentSub?this.parentSub.addNestedSub(this.handleChangeWrapper):this.store.subscribe(this.handleChangeWrapper),this.listeners=function(){var e=l(),t=[],n=[];return{clear:function(){n=u,t=u},notify:function(){var r=t=n;e((function(){for(var e=0;e. You may also pass a {context : MyContext} option to connect");var L=E;return function(t){var n=t.displayName||t.name||"Component",o=a(n),c=Object(z.a)({},A,{getDisplayName:a,methodName:l,renderCountProp:f,shouldHandleStateChanges:p,storeKey:y,displayName:o,wrappedComponentName:n,WrappedComponent:t}),s=A.pure;var u=s?r.useMemo:function(e){return e()};function d(n){var a=Object(r.useMemo)((function(){var e=n.forwardedRef,t=Object(v.a)(n,["forwardedRef"]);return[n.context,e,t]}),[n]),s=a[0],l=a[1],f=a[2],d=Object(r.useMemo)((function(){return s&&s.Consumer&&Object(w.isContextConsumer)(i.a.createElement(s.Consumer,null))?s:L}),[s,L]),g=Object(r.useContext)(d),m=Boolean(n.store)&&Boolean(n.store.getState)&&Boolean(n.store.dispatch),y=Boolean(g)&&Boolean(g.store);b()(m||y,'Could not find "store" in the context of "'+o+'". Either wrap the root component in a , or pass a custom React context provider to and the corresponding React context consumer to '+o+" in connect options.");var C=m?n.store:g.store,q=Object(r.useMemo)((function(){return function(t){return e(t.dispatch,c)}(C)}),[C]),S=Object(r.useMemo)((function(){if(!p)return j;var e=new h(C,m?null:g.subscription),t=e.notifyNestedSubs.bind(e);return[e,t]}),[C,m,g]),T=S[0],O=S[1],E=Object(r.useMemo)((function(){return m?g:Object(z.a)({},g,{subscription:T})}),[m,g,T]),A=Object(r.useReducer)(M,x,_),H=A[0][0],D=A[1];if(H&&H.error)throw H.error;var P=Object(r.useRef)(),V=Object(r.useRef)(f),N=Object(r.useRef)(),I=Object(r.useRef)(!1),R=u((function(){return N.current&&f===V.current?N.current:q(C.getState(),f)}),[C,H,f]);k((function(){V.current=f,P.current=R,I.current=!1,N.current&&(N.current=null,O())})),k((function(){if(p){var e=!1,t=null,n=function(){if(!e){var n,r,i=C.getState();try{n=q(i,V.current)}catch(o){r=o,t=o}r||(t=null),n===P.current?I.current||O():(P.current=n,N.current=n,I.current=!0,D({type:"STORE_UPDATED",payload:{error:r}}))}};T.onStateChange=n,T.trySubscribe(),n();return function(){if(e=!0,T.tryUnsubscribe(),T.onStateChange=null,t)throw t}}}),[C,T,q]);var F=Object(r.useMemo)((function(){return i.a.createElement(t,Object(z.a)({},R,{ref:l}))}),[l,t,R]);return Object(r.useMemo)((function(){return p?i.a.createElement(d.Provider,{value:E},F):F}),[d,F,E])}var g=s?i.a.memo(d):d;if(g.WrappedComponent=t,g.displayName=o,T){var C=i.a.forwardRef((function(e,t){return i.a.createElement(g,Object(z.a)({},e,{forwardedRef:t}))}));return C.displayName=o,C.WrappedComponent=t,m()(C,t)}return m()(g,t)}}var q=Object.prototype.hasOwnProperty;function S(e,t){return e===t?0!==e||0!==t||1/e===1/t:e!==e&&t!==t}function T(e,t){if(S(e,t))return!0;if("object"!==typeof e||null===e||"object"!==typeof t||null===t)return!1;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(var i=0;i=0;r--){var i=t[r](e);if(i)return i}return function(t,r){throw new Error("Invalid value of type "+typeof e+" for "+n+" argument when connecting component "+r.wrappedComponentName+".")}}function B(e,t){return e===t}!function(e){var t=void 0===e?{}:e,n=t.connectHOC,r=void 0===n?C:n,i=t.mapStateToPropsFactories,o=void 0===i?D:i,a=t.mapDispatchToPropsFactories,c=void 0===a?H:a,s=t.mergePropsFactories,l=void 0===s?V:s,u=t.selectorFactory,f=void 0===u?R:u}();function U(){var e=Object(r.useContext)(c);return b()(e,"could not find react-redux context value; please ensure the component is wrapped in a "),e}function W(e){void 0===e&&(e=c);var t=e===c?U:function(){return Object(r.useContext)(e)};return function(){return t().store}}var G=W();function Y(e){void 0===e&&(e=c);var t=e===c?G:W(e);return function(){return t().dispatch}}var Z=Y(),$=function(e,t){return e===t};function X(e){void 0===e&&(e=c);var t=e===c?U:function(){return Object(r.useContext)(e)};return function(e,n){void 0===n&&(n=$),b()(e,"You must pass a selector to useSelectors");var i=t();return function(e,t,n,i){var o,a=Object(r.useReducer)((function(e){return e+1}),0)[1],c=Object(r.useMemo)((function(){return new h(n,i)}),[n,i]),s=Object(r.useRef)(),l=Object(r.useRef)(),u=Object(r.useRef)();try{o=e!==l.current||s.current?e(n.getState()):u.current}catch(d){var f="An error occurred while selecting the store state: "+d.message+".";throw s.current&&(f+="\nThe error may be correlated with this previous error:\n"+s.current.stack+"\n\nOriginal stack trace:"),new Error(f)}return k((function(){l.current=e,u.current=o,s.current=void 0})),k((function(){function e(){try{var e=l.current(n.getState());if(t(e,u.current))return;u.current=e}catch(d){s.current=d}a({})}return c.onStateChange=e,c.trySubscribe(),e(),function(){return c.tryUnsubscribe()}}),[n,c]),o}(e,n,i.store,i.subscription)}}var K,Q=X(),J=n(32);n.d(t,"a",(function(){return p})),n.d(t,"d",(function(){return Z})),n.d(t,"b",(function(){return Y})),n.d(t,"e",(function(){return Q})),n.d(t,"c",(function(){return X})),n.d(t,"f",(function(){return G})),K=J.unstable_batchedUpdates,s=K},,function(e,t,n){"use strict";function r(){return(r=Object.assign||function(e){for(var t=1;t=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}}}},function(e,t,n){"use strict";!function e(){if("undefined"!==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"===typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE){0;try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}}(),e.exports=n(302)},function(e,t,n){"use strict";n.d(t,"a",(function(){return i})),n.d(t,"b",(function(){return o})),n.d(t,"c",(function(){return a})),n.d(t,"d",(function(){return c})),n.d(t,"e",(function(){return s})),n.d(t,"f",(function(){return l})),n.d(t,"g",(function(){return p})),n.d(t,"h",(function(){return u})),n.d(t,"i",(function(){return f})),n.d(t,"j",(function(){return h})),n.d(t,"k",(function(){return d}));var r=function(e){return"@@redux-saga/"+e},i=r("CANCEL_PROMISE"),o=r("CHANNEL_END"),a=r("IO"),c=r("MATCH"),s=r("MULTICAST"),l=r("SAGA_ACTION"),u=r("SELF_CANCELLATION"),f=r("TASK"),h=r("TASK_CANCEL"),d=r("TERMINATE"),p=r("LOCATION")},function(e,t,n){var r;!function(){"use strict";var n={}.hasOwnProperty;function i(){for(var e=[],t=0;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}n.d(t,"a",(function(){return r}))},function(e,t,n){"use strict";function r(e){return null!=e&&"object"===typeof e&&!0===e["@@functional/placeholder"]}n.d(t,"a",(function(){return r}))},,function(e,t,n){"use strict";n.d(t,"c",(function(){return o})),n.d(t,"e",(function(){return a})),n.d(t,"d",(function(){return c})),n.d(t,"b",(function(){return r})),n.d(t,"a",(function(){return i}));var r,i,o={ANCHOR:"mdc-menu-surface--anchor",ANIMATING_CLOSED:"mdc-menu-surface--animating-closed",ANIMATING_OPEN:"mdc-menu-surface--animating-open",FIXED:"mdc-menu-surface--fixed",OPEN:"mdc-menu-surface--open",ROOT:"mdc-menu-surface"},a={CLOSED_EVENT:"MDCMenuSurface:closed",OPENED_EVENT:"MDCMenuSurface:opened",FOCUSABLE_ELEMENTS:["button:not(:disabled)",'[href]:not([aria-disabled="true"])',"input:not(:disabled)","select:not(:disabled)","textarea:not(:disabled)",'[tabindex]:not([tabindex="-1"]):not([aria-disabled="true"])'].join(", ")},c={TRANSITION_OPEN_DURATION:120,TRANSITION_CLOSE_DURATION:75,MARGIN_TO_EDGE:32,ANCHOR_TO_MENU_SURFACE_WIDTH_RATIO:.67};!function(e){e[e.BOTTOM=1]="BOTTOM",e[e.CENTER=2]="CENTER",e[e.RIGHT=4]="RIGHT",e[e.FLIP_RTL=8]="FLIP_RTL"}(r||(r={})),function(e){e[e.TOP_LEFT=0]="TOP_LEFT",e[e.TOP_RIGHT=4]="TOP_RIGHT",e[e.BOTTOM_LEFT=1]="BOTTOM_LEFT",e[e.BOTTOM_RIGHT=5]="BOTTOM_RIGHT",e[e.TOP_START=8]="TOP_START",e[e.TOP_END=12]="TOP_END",e[e.BOTTOM_START=9]="BOTTOM_START",e[e.BOTTOM_END=13]="BOTTOM_END"}(i||(i={}))},,,function(e,t,n){"use strict";var r=n(52);var i=n(106),o=n(131);var a=n(77),c=n(76);function s(e){return e?1===e.length?e[0]:function(t){return e.reduce((function(e,t){return t(e)}),t)}:c.a}var l=n(59);n.d(t,"a",(function(){return u}));var u=function(){function e(e){this._isScalar=!1,e&&(this._subscribe=e)}return e.prototype.lift=function(t){var n=new e;return n.source=this,n.operator=t,n},e.prototype.subscribe=function(e,t,n){var a=this.operator,c=function(e,t,n){if(e){if(e instanceof r.a)return e;if(e[i.a])return e[i.a]()}return e||t||n?new r.a(e,t,n):new r.a(o.a)}(e,t,n);if(a?c.add(a.call(c,this.source)):c.add(this.source||l.a.useDeprecatedSynchronousErrorHandling&&!c.syncErrorThrowable?this._subscribe(c):this._trySubscribe(c)),l.a.useDeprecatedSynchronousErrorHandling&&c.syncErrorThrowable&&(c.syncErrorThrowable=!1,c.syncErrorThrown))throw c.syncErrorValue;return c},e.prototype._trySubscribe=function(e){try{return this._subscribe(e)}catch(t){l.a.useDeprecatedSynchronousErrorHandling&&(e.syncErrorThrown=!0,e.syncErrorValue=t),!function(e){for(;e;){var t=e,n=t.closed,i=t.destination,o=t.isStopped;if(n||o)return!1;e=i&&i instanceof r.a?i:null}return!0}(e)?console.warn(t):e.error(t)}},e.prototype.forEach=function(e,t){var n=this;return new(t=f(t))((function(t,r){var i;i=n.subscribe((function(t){try{e(t)}catch(n){r(n),i&&i.unsubscribe()}}),r,t)}))},e.prototype._subscribe=function(e){var t=this.source;return t&&t.subscribe(e)},e.prototype[a.a]=function(){return this},e.prototype.pipe=function(){for(var e=[],t=0;t=0||(i[n]=e[n]);return i}n.d(t,"a",(function(){return r}))},function(e,t,n){"use strict";n.d(t,"a",(function(){return v})),n.d(t,"b",(function(){return f})),n.d(t,"c",(function(){return l})),n.d(t,"d",(function(){return z})),n.d(t,"e",(function(){return c}));var r=n(211),i=function(){return Math.random().toString(36).substring(7).split("").join(".")},o={INIT:"@@redux/INIT"+i(),REPLACE:"@@redux/REPLACE"+i(),PROBE_UNKNOWN_ACTION:function(){return"@@redux/PROBE_UNKNOWN_ACTION"+i()}};function a(e){if("object"!==typeof e||null===e)return!1;for(var t=e;null!==Object.getPrototypeOf(t);)t=Object.getPrototypeOf(t);return Object.getPrototypeOf(e)===t}function c(e,t,n){var i;if("function"===typeof t&&"function"===typeof n||"function"===typeof n&&"function"===typeof arguments[3])throw new Error("It looks like you are passing several store enhancers to createStore(). This is not supported. Instead, compose them together to a single function.");if("function"===typeof t&&"undefined"===typeof n&&(n=t,t=void 0),"undefined"!==typeof n){if("function"!==typeof n)throw new Error("Expected the enhancer to be a function.");return n(c)(e,t)}if("function"!==typeof e)throw new Error("Expected the reducer to be a function.");var s=e,l=t,u=[],f=u,h=!1;function d(){f===u&&(f=u.slice())}function p(){if(h)throw new Error("You may not call store.getState() while the reducer is executing. The reducer has already received the state as an argument. Pass it down from the top reducer instead of reading it from the store.");return l}function z(e){if("function"!==typeof e)throw new Error("Expected the listener to be a function.");if(h)throw new Error("You may not call store.subscribe() while the reducer is executing. If you would like to be notified after the store has been updated, subscribe from a component and invoke store.getState() in the callback to access the latest state. See https://redux.js.org/api-reference/store#subscribe(listener) for more details.");var t=!0;return d(),f.push(e),function(){if(t){if(h)throw new Error("You may not unsubscribe from a store listener while the reducer is executing. See https://redux.js.org/api-reference/store#subscribe(listener) for more details.");t=!1,d();var n=f.indexOf(e);f.splice(n,1)}}}function v(e){if(!a(e))throw new Error("Actions must be plain objects. Use custom middleware for async actions.");if("undefined"===typeof e.type)throw new Error('Actions may not have an undefined "type" property. Have you misspelled a constant?');if(h)throw new Error("Reducers may not dispatch actions.");try{h=!0,l=s(l,e)}finally{h=!1}for(var t=u=f,n=0;n=0;)t=c[n],Object(i.a)(t,e)&&!l(r,t)&&(r[r.length]=t),n-=1;return r})):Object(r.a)((function(e){return Object(e)!==e?[]:Object.keys(e)}));t.a=u},function(e,t,n){"use strict";var r=Object.getOwnPropertySymbols,i=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable;function a(e){if(null===e||void 0===e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(i){return!1}}()?Object.assign:function(e,t){for(var n,c,s=a(e),l=1;l8.64*1e15?NaN:function(e){var t=a(e);if(isNaN(t)||l(t,-0))return 0;if(isFinite(t))return t;var n=Math.floor(Math.abs(t));return t<0&&(n=-n),l(n,-0)?0:n}(e):NaN}function s(e){if(null==e)throw new TypeError("undefined/null cannot be converted to object");return Object(e)}function l(e,t){return Object.is?Object.is(e,t):e===t?0!==e||1/e===1/t:e!==e&&t!==t}function u(e){return new Array(e)}function f(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function h(e){return null===e?"Null":"undefined"===typeof e?"Undefined":"function"===typeof e||"object"===typeof e?"Object":"number"===typeof e?"Number":"boolean"===typeof e?"Boolean":"string"===typeof e?"String":"symbol"===typeof e?"Symbol":"bigint"===typeof e?"BigInt":void 0}n.r(t);var d=864e5;function p(e,t){return e-Math.floor(e/t)*t}function z(e){return Math.floor(e/d)}function v(e){return p(z(e)+4,7)}function g(e){return Date.UTC(e,0)/d}function m(e){return Date.UTC(e,0)}function y(e){return new Date(e).getUTCFullYear()}function b(e){return e%4!==0?365:e%100!==0?366:e%400!==0?365:366}function w(e){return z(e)-g(y(e))}function k(e){return 365===b(y(e))?0:1}function x(e){var t=w(e),n=k(e);if(t>=0&&t<31)return 0;if(t<59+n)return 1;if(t<90+n)return 2;if(t<120+n)return 3;if(t<151+n)return 4;if(t<181+n)return 5;if(t<212+n)return 6;if(t<243+n)return 7;if(t<273+n)return 8;if(t<304+n)return 9;if(t<334+n)return 10;if(t<365+n)return 11;throw new Error("Invalid time")}function j(e){var t=w(e),n=x(e),r=k(e);if(0===n)return t+1;if(1===n)return t-30;if(2===n)return t-58-r;if(3===n)return t-89-r;if(4===n)return t-119-r;if(5===n)return t-150-r;if(6===n)return t-180-r;if(7===n)return t-211-r;if(8===n)return t-242-r;if(9===n)return t-272-r;if(10===n)return t-303-r;if(11===n)return t-333-r;throw new Error("Invalid time")}var M=24,_=60,C=60,q=1e3,S=q*C,T=S*_;function O(e){return p(Math.floor(e/T),M)}function E(e){return p(Math.floor(e/S),_)}function A(e){return p(Math.floor(e/q),C)}function L(e,t,n){if("function"!==typeof e)return!1;if(null===n||void 0===n?void 0:n.boundTargetFunction)return t instanceof(null===n||void 0===n?void 0:n.boundTargetFunction);if("object"!==typeof t)return!1;var r=e.prototype;if("object"!==typeof r)throw new TypeError("OrdinaryHasInstance called on an object with an invalid prototype property.");return Object.prototype.isPrototypeOf.call(r,t)}function H(e){return p(e,q)}function D(e){return"undefined"===typeof e?Object.create(null):s(e)}function P(e,t,n,r){if(void 0!==e){if(e=Number(e),isNaN(e)||en)throw new RangeError(e+" is outside of range ["+t+", "+n+"]");return Math.floor(e)}return r}function V(e,t,n,r,i){return P(e[t],n,r,i)}function N(e,t,n,r,i){if("object"!==typeof e)throw new TypeError("Options must be an object");var a=e[t];if(void 0!==a){if("boolean"!==n&&"string"!==n)throw new TypeError("invalid type");if("boolean"===n&&(a=Boolean(a)),"string"===n&&(a=o(a)),void 0!==r&&!r.filter((function(e){return e==a})).length)throw new RangeError(a+" is not within "+r.join(", "));return a}return i}function I(e){if("undefined"===typeof e)return Object.create(null);if("object"===typeof e)return e;throw new TypeError("Options must be an object")}var R=["angle-degree","area-acre","area-hectare","concentr-percent","digital-bit","digital-byte","digital-gigabit","digital-gigabyte","digital-kilobit","digital-kilobyte","digital-megabit","digital-megabyte","digital-petabyte","digital-terabit","digital-terabyte","duration-day","duration-hour","duration-millisecond","duration-minute","duration-month","duration-second","duration-week","duration-year","length-centimeter","length-foot","length-inch","length-kilometer","length-meter","length-mile-scandinavian","length-mile","length-millimeter","length-yard","mass-gram","mass-kilogram","mass-ounce","mass-pound","mass-stone","temperature-celsius","temperature-fahrenheit","volume-fluid-ounce","volume-gallon","volume-liter","volume-milliliter"];function F(e){return e.slice(e.indexOf("-")+1)}var B=R.map(F);function U(e){return B.indexOf(e)>-1}function W(e,t){var n=t.tzData,r=t.uppercaseLinks,i=e.toUpperCase(),o=new Set,a=new Set;return Object.keys(n).map((function(e){return e.toUpperCase()})).forEach((function(e){return o.add(e)})),Object.keys(r).forEach((function(e){a.add(e.toUpperCase()),o.add(r[e].toUpperCase())})),o.has(i)||a.has(i)}var G=/[^A-Z]/;function Y(e){return 3===(e=e.replace(/([a-z])/g,(function(e,t){return t.toUpperCase()}))).length&&!G.test(e)}function Z(e){if(U(e=e.replace(/([A-Z])/g,(function(e,t){return t.toLowerCase()}))))return!0;var t=e.split("-per-");if(2!==t.length)return!1;var n=t[0],r=t[1];return!(!U(n)||!U(r))}function $(e){return Math.floor(Math.log(e)*Math.LOG10E)}function X(e,t){if("function"===typeof e.repeat)return e.repeat(t);for(var n=new Array(t),r=0;rd[d.length-1])return d[d.length-1].length-1;var p=d.indexOf(h);if(-1===p)return 0;var z=d[p];return"0"===u[z].other?0:z.length-u[z].other.match(/0+/)[0].length}}function oe(e,t,n){var r,i,o,a,c=n;if(0===e)r=X("0",c),i=0,o=0;else{var s=e.toString(),l=s.indexOf("e"),u=s.split("e"),f=u[0],h=u[1],d=f.replace(".","");if(l>=0&&d.length<=c)i=+h,r=d+X("0",c-d.length),o=e;else{var p=(i=$(e))-c+1,z=Math.round(g(e,p));g(z,c-1)>=10&&(i+=1,z=Math.floor(z/10)),r=z.toString(),o=g(z,c-1-i)}}if(i>=c-1?(r+=X("0",i-c+1),a=i+1):i>=0?(r=r.slice(0,i+1)+"."+r.slice(i+1),a=i+1):(r="0."+X("0",-i-1)+r,a=1),r.indexOf(".")>=0&&n>t){for(var v=n-t;v>0&&"0"===r[r.length-1];)r=r.slice(0,-1),v--;"."===r[r.length-1]&&(r=r.slice(0,-1))}return{formattedString:r,roundedNumber:o,integerDigitsCount:a};function g(e,t){return t<0?e*Math.pow(10,-t):e/Math.pow(10,t)}}function ae(e,t,n){var r,i,o=n,a=Math.round(e*Math.pow(10,o)),c=a/Math.pow(10,o);if(a<1e21)r=a.toString();else{var s=(r=a.toString()).split("e"),l=s[0],u=s[1];r=l.replace(".",""),r+=X("0",Math.max(+u-r.length+1,0))}if(0!==o){var f=r.length;if(f<=o)r=X("0",o+1-f)+r,f=o+1;var h=r.slice(0,f-o),d=r.slice(f-o);r=h+"."+d,i=h.length}else i=r.length;for(var p=n-t;p>0&&"0"===r[r.length-1];)r=r.slice(0,-1),p--;return"."===r[r.length-1]&&(r=r.slice(0,-1)),{formattedString:r,roundedNumber:c,integerDigitsCount:i}}function ce(e,t){var n,r=t<0||l(t,-0);switch(r&&(t=-t),e.roundingType){case"significantDigits":n=oe(t,e.minimumSignificantDigits,e.maximumSignificantDigits);break;case"fractionDigits":n=ae(t,e.minimumFractionDigits,e.maximumFractionDigits);break;default:(n=oe(t,1,2)).integerDigitsCount>1&&(n=ae(t,0,0))}t=n.roundedNumber;var i=n.formattedString,o=n.integerDigitsCount,a=e.minimumIntegerDigits;o\^`\|~\xA2-\xA6\xA8\xA9\xAC\xAE-\xB1\xB4\xB8\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0384\u0385\u03F6\u0482\u058D-\u058F\u0606-\u0608\u060B\u060E\u060F\u06DE\u06E9\u06FD\u06FE\u07F6\u07FE\u07FF\u09F2\u09F3\u09FA\u09FB\u0AF1\u0B70\u0BF3-\u0BFA\u0C7F\u0D4F\u0D79\u0E3F\u0F01-\u0F03\u0F13\u0F15-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE\u0FCF\u0FD5-\u0FD8\u109E\u109F\u1390-\u1399\u166D\u17DB\u1940\u19DE-\u19FF\u1B61-\u1B6A\u1B74-\u1B7C\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u2044\u2052\u207A-\u207C\u208A-\u208C\u20A0-\u20BF\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F\u218A\u218B\u2190-\u2307\u230C-\u2328\u232B-\u2426\u2440-\u244A\u249C-\u24E9\u2500-\u2767\u2794-\u27C4\u27C7-\u27E5\u27F0-\u2982\u2999-\u29D7\u29DC-\u29FB\u29FE-\u2B73\u2B76-\u2B95\u2B97-\u2BFF\u2CE5-\u2CEA\u2E50\u2E51\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3004\u3012\u3013\u3020\u3036\u3037\u303E\u303F\u309B\u309C\u3190\u3191\u3196-\u319F\u31C0-\u31E3\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA700-\uA716\uA720\uA721\uA789\uA78A\uA828-\uA82B\uA836-\uA839\uAA77-\uAA79\uAB5B\uAB6A\uAB6B\uFB29\uFBB2-\uFBC1\uFDFC\uFDFD\uFE62\uFE64-\uFE66\uFE69\uFF04\uFF0B\uFF1C-\uFF1E\uFF3E\uFF40\uFF5C\uFF5E\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFFC\uFFFD]|\uD800[\uDD37-\uDD3F\uDD79-\uDD89\uDD8C-\uDD8E\uDD90-\uDD9C\uDDA0\uDDD0-\uDDFC]|\uD802[\uDC77\uDC78\uDEC8]|\uD805\uDF3F|\uD807[\uDFD5-\uDFF1]|\uD81A[\uDF3C-\uDF3F\uDF45]|\uD82F\uDC9C|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDE8\uDE00-\uDE41\uDE45\uDF00-\uDF56]|\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85\uDE86]|\uD838[\uDD4F\uDEFF]|\uD83B[\uDCAC\uDCB0\uDD2E\uDEF0\uDEF1]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD0D-\uDDAD\uDDE6-\uDE02\uDE10-\uDE3B\uDE40-\uDE48\uDE50\uDE51\uDE60-\uDE65\uDF00-\uDFFF]|\uD83D[\uDC00-\uDED7\uDEE0-\uDEEC\uDEF0-\uDEFC\uDF00-\uDF73\uDF80-\uDFD8\uDFE0-\uDFEB]|\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDCB0\uDCB1\uDD00-\uDD78\uDD7A-\uDDCB\uDDCD-\uDE53\uDE60-\uDE6D\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6\uDF00-\uDF92\uDF94-\uDFCA]/,he=new RegExp("^"+fe.source),de=new RegExp(fe.source+"$"),pe=/[#0](?:[\.,][#0]+)*/g;function ze(e,t,n,r){var i,o,a=e.sign,c=e.exponent,s=e.magnitude,l=r.notation,u=r.style,f=r.numberingSystem,h=t.numbers.nu[0],d=null;if("compact"===l&&s&&(d=function(e,t,n,r,i,o,a){var c,s,l=e.roundedNumber,u=e.sign,f=e.magnitude,h=String(Math.pow(10,f)),d=n.numbers.nu[0];if("currency"===r&&"name"!==o){var p=(v=n.numbers.currency)[a]||v[d],z=null===(c=p.short)||void 0===c?void 0:c[h];if(!z)return null;s=me(t,l,z)}else{var v,g=((v=n.numbers.decimal)[a]||v[d])[i][h];if(!g)return null;s=me(t,l,g)}if("0"===s)return null;return s=ge(s,u).replace(/([^\s;\-\+\d\xa4]+)/g,"{c:$1}").replace(/0+/,"0")}(e,n,t,u,r.compactDisplay,r.currencyDisplay,f)),"currency"===u&&"name"!==r.currencyDisplay){var p=t.currencies[r.currency];if(p)switch(r.currencyDisplay){case"code":i=r.currency;break;case"symbol":i=p.symbol;break;default:i=p.narrow}else i=r.currency}if(d)o=d;else if("decimal"===u||"unit"===u||"currency"===u&&"name"===r.currencyDisplay)o=ge((t.numbers.decimal[f]||t.numbers.decimal[h]).standard,a);else if("currency"===u){o=ge((v=t.numbers.currency[f]||t.numbers.currency[h])[r.currencySign],a)}else{o=ge(t.numbers.percent[f]||t.numbers.percent[h],a)}var z=pe.exec(o)[0];if(o=o.replace(pe,"{0}").replace(/'(.)'/g,"$1"),"currency"===u&&"name"!==r.currencyDisplay){var v,g=(v=t.numbers.currency[f]||t.numbers.currency[h]).currencySpacing.afterInsertBetween;g&&!de.test(i)&&(o=o.replace("\xa4{0}","\xa4"+g+"{0}"));var m=v.currencySpacing.beforeInsertBetween;m&&!he.test(i)&&(o=o.replace("{0}\xa4","{0}"+m+"\xa4"))}for(var y=o.split(/({c:[^}]+}|\{0\}|[\xa4%\-\+])/g),b=[],w=t.numbers.symbols[f]||t.numbers.symbols[h],k=0,x=y;k0?(f=s.slice(0,d),h=s.slice(d+1)):f=s,o&&("compact"!==n||l>=1e4)){var p=e.group,z=[],v=a.split(".")[0].split(","),g=3,m=3;v.length>1&&(g=v[v.length-1].length),v.length>2&&(m=v[v.length-2].length);var y=f.length-g;if(y>0){for(z.push(f.slice(y,y+g)),y-=m;y>0;y-=m)z.push(f.slice(y,y+m));z.push(f.slice(0,y+m))}else z.push(f);for(;z.length>0;){var b=z.pop();c.push({type:"integer",value:b}),z.length>0&&c.push({type:"group",value:p})}}else c.push({type:"integer",value:f});if(void 0!==h&&c.push({type:"decimal",value:e.decimal},{type:"fraction",value:h}),("scientific"===n||"engineering"===n)&&isFinite(l)){c.push({type:"exponentSeparator",value:e.exponential}),r<0&&(c.push({type:"exponentMinusSign",value:e.minusSign}),r=-r);var w=ae(r,0,0);c.push({type:"exponentInteger",value:w.formattedString})}return c}function ge(e,t){e.indexOf(";")<0&&(e=e+";-"+e);var n=e.split(";"),r=n[0],i=n[1];switch(t){case 0:return r;case-1:return i;default:return i.indexOf("-")>=0?i.replace(/-/g,"+"):"+"+r}}function me(e,t,n){return n[e.select(t)]||n.other}function ye(e,t,n){var r,i,o,a=n.getInternalSlots,c=a(e),s=c.pl,u=c.dataLocaleData,f=c.numberingSystem,h=u.numbers.symbols[f]||u.numbers.symbols[u.numbers.nu[0]],d=0,p=0;if(isNaN(t))i=h.nan;else if(isFinite(t)){"percent"===c.style&&(t*=100),p=(r=se(e,t,{getInternalSlots:a}))[0],d=r[1];var z=ce(c,t=p<0?t*Math.pow(10,-p):t/Math.pow(10,p));i=z.formattedString,t=z.roundedNumber}else i=h.infinity;switch(c.signDisplay){case"never":o=0;break;case"auto":o=l(t,0)||t>0||isNaN(t)?0:-1;break;case"always":o=l(t,0)||t>0||isNaN(t)?1:-1;break;default:o=0===t||isNaN(t)?0:t>0?1:-1}return ze({roundedNumber:t,formattedString:i,exponent:p,magnitude:d,sign:o},c.dataLocaleData,s,c)}function be(e,t,n){for(var r=ye(e,t,n),i=u(0),o=0,a=r;o-1;)re((r=e.indexOf("}",n))>n,"Invalid pattern "+e),n>i&&t.push({type:"literal",value:e.substring(i,n)}),t.push({type:e.substring(n+1,r),value:void 0}),i=r+1,n=e.indexOf("{",i);return iu)return-1;null!==s&&void 0!==s||(s=0);var f,h=function(e){return e>=0&&ea){if(s>0&&h(f=d-1)&&c[f]a)return d;e=a,t=c,n=s,r=d+1,i=u,o=!0,h=d=p=f=void 0}}},t.dateParser=function(e){var t,n;if((-1==e.search("-")||-1!=e.search("T")||-1!=e.search("Z"))&&(n=z(e))&&!isNaN(n))return n;if(-1!=e.search("-")){for(t=e.replace("-","/","g");-1!=t.search("-");)t=t.replace("-","/");n=z(t)}else 8==e.length?(t=e.substr(0,4)+"/"+e.substr(4,2)+"/"+e.substr(6,2),n=z(t)):n=z(e);n&&!isNaN(n)||console.error("Couldn't parse "+e+" as a date");return n},t.dateStrToMillis=z,t.update=function(e,t){if("undefined"!=typeof t&&null!==t)for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e},t.updateDeep=function e(t,n){function r(e){return"object"===typeof Node?e instanceof Node:"object"===typeof e&&"number"===typeof e.nodeType&&"string"===typeof e.nodeName}if("undefined"!=typeof n&&null!==n)for(var i in n)n.hasOwnProperty(i)&&(null===n[i]?t[i]=null:v(n[i])?t[i]=n[i].slice():r(n[i])?t[i]=n[i]:"object"==typeof n[i]?("object"==typeof t[i]&&null!==t[i]||(t[i]={}),e(t[i],n[i])):t[i]=n[i]);return t},t.isArrayLike=v,t.isDateLike=function(e){if("object"!=typeof e||null===e||"function"!=typeof e.getTime)return!1;return!0},t.clone=function e(t){for(var n=[],r=0;r=t||m.call(window,(function(){var t=(new Date).getTime()-a;i=o;var l=(o=Math.floor(t/n))-i;o+l>c||o>=c?(e(c),r()):(0!==l&&e(o),s())}))}()},t.isPixelChangingOptionList=function(e,t){var n={};if(e)for(var r=1;r=r.Granularity.DECADAL)return""+o;if(t>=r.Granularity.MONTHLY)return q[a]+" "+o;if(0===3600*s+60*d+p+.001*z||t>=r.Granularity.DAILY)return l(c)+" "+q[a];if(tr.Granularity.MINUTELY?h(s,d,p,0):h(s,d,p,z)},t.dateValueFormatter=function(e,t){return d(e,t("labelsUTC"))};var r=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t}(n(202));t.LOG_SCALE=10;var i=Math.log(10);t.LN_TEN=i;var o=function(e){return Math.log(e)/i};t.log10=o;t.logRangeFraction=function(e,t,n){var r=o(e),i=r+n*(o(t)-r);return Math.pow(10,i)};t.DOTTED_LINE=[2,2];t.DASHED_LINE=[7,3];t.DOT_DASH_LINE=[7,2,2,2];t.HORIZONTAL=1;t.VERTICAL=2;t.getContext=function(e){return e.getContext("2d")};function a(e){return!e.pageX||e.pageX<0?0:e.pageX}function c(e){return!e.pageY||e.pageY<0?0:e.pageY}function s(e,t){var n=Math.min(Math.max(1,t||2),21);return Math.abs(e)<.001&&0!==e?e.toExponential(n-1):e.toPrecision(n)}function l(e){return e<10?"0"+e:""+e}t.addEvent=function(e,t,n){e.addEventListener(t,n,!1)};var u={getFullYear:function(e){return e.getFullYear()},getMonth:function(e){return e.getMonth()},getDate:function(e){return e.getDate()},getHours:function(e){return e.getHours()},getMinutes:function(e){return e.getMinutes()},getSeconds:function(e){return e.getSeconds()},getMilliseconds:function(e){return e.getMilliseconds()},getDay:function(e){return e.getDay()},makeDate:function(e,t,n,r,i,o,a){return new Date(e,t,n,r,i,o,a)}};t.DateAccessorsLocal=u;var f={getFullYear:function(e){return e.getUTCFullYear()},getMonth:function(e){return e.getUTCMonth()},getDate:function(e){return e.getUTCDate()},getHours:function(e){return e.getUTCHours()},getMinutes:function(e){return e.getUTCMinutes()},getSeconds:function(e){return e.getUTCSeconds()},getMilliseconds:function(e){return e.getUTCMilliseconds()},getDay:function(e){return e.getUTCDay()},makeDate:function(e,t,n,r,i,o,a){return new Date(Date.UTC(e,t,n,r,i,o,a))}};function h(e,t,n,r){var i=l(e)+":"+l(t);if(n&&(i+=":"+l(n),r)){var o=""+r;i+="."+("000"+o).substring(o.length)}return i}function d(e,t){var n=t?f:u,r=new Date(e),i=n.getFullYear(r),o=n.getMonth(r),a=n.getDate(r),c=n.getHours(r),s=n.getMinutes(r),d=n.getSeconds(r),p=n.getMilliseconds(r),z=""+i+"/"+l(o+1)+"/"+l(a);return 3600*c+60*s+d+.001*p&&(z+=" "+h(c,s,d,p)),z}function p(e,t){var n=Math.pow(10,t);return Math.round(e*n)/n}function z(e){return new Date(e).getTime()}function v(e){var t=typeof e;return("object"==t||"function"==t&&"function"==typeof e.item)&&null!==e&&"number"==typeof e.length&&3!==e.nodeType}function g(e,t,n,r){t=t||0,n=n||e.length,this.hasNext=!0,this.peek=null,this.start_=t,this.array_=e,this.predicate_=r,this.end_=Math.min(e.length,t+n),this.nextIdx_=t-1,this.next()}t.DateAccessorsUTC=f,g.prototype.next=function(){if(!this.hasNext)return null;for(var e=this.peek,t=this.nextIdx_+1,n=!1;t=Math.pow(10,o)||Math.abs(e)=0;z--,d/=l)if(h>=d){r=p(e/d,i)+u[z];break}if(c){var v=String(e.toExponential()).split("e-");2===v.length&&v[1]>=3&&v[1]<=24&&(r=v[1]%3>0?p(v[0]/w(10,v[1]%3),i):Number(v[0]).toFixed(2),r+=f[Math.floor(v[1]/3)-1])}}return r}var q=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]},function(e,t,n){"use strict";t.a=Array.isArray||function(e){return null!=e&&e.length>=0&&"[object Array]"===Object.prototype.toString.call(e)}},function(e,t,n){"use strict";function r(e){return"[object String]"===Object.prototype.toString.call(e)}n.d(t,"a",(function(){return r}))},function(e,t,n){"use strict";n.d(t,"a",(function(){return a}));var r=n(25),i=n(24),o=n(20);function a(e,t){Object(o.a)(1,arguments);var n=t||{},a=n.locale,c=a&&a.options&&a.options.weekStartsOn,s=null==c?0:Object(r.a)(c),l=null==n.weekStartsOn?s:Object(r.a)(n.weekStartsOn);if(!(l>=0&&l<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");var u=Object(i.a)(e),f=u.getUTCDay(),h=(f=0&&l<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");var u=Object(i.default)(e),f=u.getUTCDay(),h=(f0&&t.forEach((function(e){o.remove(e)})),o.appendTo(n.scrollbarXRail,e)),e.contains(n.scrollbarYRail)||((t=o.queryChildren(e,".ps-scrollbar-y-rail")).length>0&&t.forEach((function(e){o.remove(e)})),o.appendTo(n.scrollbarYRail,e)),!n.settings.suppressScrollX&&n.containerWidth+n.settings.scrollXMarginOffset=n.railXWidth-n.scrollbarXWidth&&(n.scrollbarXLeft=n.railXWidth-n.scrollbarXWidth),n.scrollbarYTop>=n.railYHeight-n.scrollbarYHeight&&(n.scrollbarYTop=n.railYHeight-n.scrollbarYHeight),function(e,t){var n={width:t.railXWidth};t.isRtl?n.left=t.negativeScrollAdjustment+e.scrollLeft+t.containerWidth-t.contentWidth:n.left=e.scrollLeft,t.isScrollbarXUsingBottom?n.bottom=t.scrollbarXBottom-e.scrollTop:n.top=t.scrollbarXTop+e.scrollTop,o.css(t.scrollbarXRail,n);var r={top:e.scrollTop,height:t.railYHeight};t.isScrollbarYUsingRight?t.isRtl?r.right=t.contentWidth-(t.negativeScrollAdjustment+e.scrollLeft)-t.scrollbarYRight-t.scrollbarYOuterWidth:r.right=t.scrollbarYRight-e.scrollLeft:t.isRtl?r.left=t.negativeScrollAdjustment+e.scrollLeft+2*t.containerWidth-t.contentWidth-t.scrollbarYLeft-t.scrollbarYOuterWidth:r.left=t.scrollbarYLeft+e.scrollLeft,o.css(t.scrollbarYRail,r),o.css(t.scrollbarX,{left:t.scrollbarXLeft,width:t.scrollbarXWidth-t.railBorderXWidth}),o.css(t.scrollbarY,{top:t.scrollbarYTop,height:t.scrollbarYHeight-t.railBorderYWidth})}(e,n),n.scrollbarXActive?i.add(e,"ps-active-x"):(i.remove(e,"ps-active-x"),n.scrollbarXWidth=0,n.scrollbarXLeft=0,c(e,"left",0)),n.scrollbarYActive?i.add(e,"ps-active-y"):(i.remove(e,"ps-active-y"),n.scrollbarYHeight=0,n.scrollbarYTop=0,c(e,"top",0))}},function(e,t,n){"use strict";e.exports=function(e,t,n,r,i,o,a,c){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var l=[n,r,i,o,a,c],u=0;(s=new Error(t.replace(/%s/g,(function(){return l[u++]})))).name="Invariant Violation"}throw s.framesToPop=1,s}}},function(e,t,n){"use strict";function r(e){setTimeout((function(){throw e}),0)}n.d(t,"a",(function(){return r}))},,function(e,t){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(r){"object"===typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";var r,i,o=n(62),a=function(e){var t=document.createEvent("Event");return t.initEvent(e,!0,!0),t};e.exports=function(e,t,n){if("undefined"===typeof e)throw"You must provide an element to the update-scroll function";if("undefined"===typeof t)throw"You must provide an axis to the update-scroll function";if("undefined"===typeof n)throw"You must provide a value to the update-scroll function";"top"===t&&n<=0&&(e.scrollTop=n=0,e.dispatchEvent(a("ps-y-reach-start"))),"left"===t&&n<=0&&(e.scrollLeft=n=0,e.dispatchEvent(a("ps-x-reach-start")));var c=o.get(e);"top"===t&&n>=c.contentHeight-c.containerHeight&&((n=c.contentHeight-c.containerHeight)-e.scrollTop<=1?n=e.scrollTop:e.scrollTop=n,e.dispatchEvent(a("ps-y-reach-end"))),"left"===t&&n>=c.contentWidth-c.containerWidth&&((n=c.contentWidth-c.containerWidth)-e.scrollLeft<=1?n=e.scrollLeft:e.scrollLeft=n,e.dispatchEvent(a("ps-x-reach-end"))),r||(r=e.scrollTop),i||(i=e.scrollLeft),"top"===t&&nr&&e.dispatchEvent(a("ps-scroll-down")),"left"===t&&ni&&e.dispatchEvent(a("ps-scroll-right")),"top"===t&&(e.scrollTop=r=n,e.dispatchEvent(a("ps-scroll-y"))),"left"===t&&(e.scrollLeft=i=n,e.dispatchEvent(a("ps-scroll-x")))}},function(e,t,n){e.exports=n(318)},function(e,t,n){"use strict";function r(){return"function"===typeof Symbol&&Symbol.iterator?Symbol.iterator:"@@iterator"}n.d(t,"a",(function(){return i}));var i=r()},function(e,t,n){"use strict";n.d(t,"a",(function(){return i}));var r=n(31),i=function(e){function t(t,n,r){var i=e.call(this)||this;return i.parent=t,i.outerValue=n,i.outerIndex=r,i.index=0,i}return r.b(t,e),t.prototype._next=function(e){this.parent.notifyNext(this.outerValue,e,this.outerIndex,this.index++,this)},t.prototype._error=function(e){this.parent.notifyError(e,this),this.unsubscribe()},t.prototype._complete=function(){this.parent.notifyComplete(this),this.unsubscribe()},t}(n(52).a)},function(e,t,n){"use strict";n.d(t,"a",(function(){return r}));var r=function(){function e(e){void 0===e&&(e={}),this.adapter_=e}return Object.defineProperty(e,"cssClasses",{get:function(){return{}},enumerable:!0,configurable:!0}),Object.defineProperty(e,"strings",{get:function(){return{}},enumerable:!0,configurable:!0}),Object.defineProperty(e,"numbers",{get:function(){return{}},enumerable:!0,configurable:!0}),Object.defineProperty(e,"defaultAdapter",{get:function(){return{}},enumerable:!0,configurable:!0}),e.prototype.init=function(){},e.prototype.destroy=function(){},e}()},function(e,t,n){"use strict";var r=n(30),i=n(69),o=n(70),a=Object(r.a)((function(e){return!!Object(i.a)(e)||!!e&&("object"===typeof e&&(!Object(o.a)(e)&&(1===e.nodeType?!!e.length:0===e.length||e.length>0&&(e.hasOwnProperty(0)&&e.hasOwnProperty(e.length-1)))))})),c=function(){function e(e){this.f=e}return e.prototype["@@transducer/init"]=function(){throw new Error("init not implemented on XWrap")},e.prototype["@@transducer/result"]=function(e){return e},e.prototype["@@transducer/step"]=function(e,t){return this.f(e,t)},e}();var s=n(65),l=n(19),u=Object(l.a)((function(e,t){return Object(s.a)(e.length,(function(){return e.apply(t,arguments)}))}));function f(e,t,n){for(var r=n.next();!r.done;){if((t=e["@@transducer/step"](t,r.value))&&t["@@transducer/reduced"]){t=t["@@transducer/value"];break}r=n.next()}return e["@@transducer/result"](t)}function h(e,t,n,r){return e["@@transducer/result"](n[r](u(e["@@transducer/step"],e),t))}n.d(t,"a",(function(){return p}));var d="undefined"!==typeof Symbol?Symbol.iterator:"@@iterator";function p(e,t,n){if("function"===typeof e&&(e=function(e){return new c(e)}(e)),a(n))return function(e,t,n){for(var r=0,i=n.length;r>>0;for(t=0;t0)for(n=0;n=0?n?"+":"":"-")+Math.pow(10,Math.max(0,i)).toString().substr(1)+r}r.suppressDeprecationWarnings=!1,r.deprecationHandler=null,j=Object.keys?Object.keys:function(e){var t,n=[];for(t in e)a(e,t)&&n.push(t);return n};var O=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,E=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,A={},L={};function H(e,t,n,r){var i=r;"string"===typeof r&&(i=function(){return this[r]()}),e&&(L[e]=i),t&&(L[t[0]]=function(){return T(i.apply(this,arguments),t[1],t[2])}),n&&(L[n]=function(){return this.localeData().ordinal(i.apply(this,arguments),e)})}function D(e,t){return e.isValid()?(t=P(t,e.localeData()),A[t]=A[t]||function(e){var t,n,r,i=e.match(O);for(t=0,n=i.length;t=0&&E.test(e);)e=e.replace(E,r),E.lastIndex=0,n-=1;return e}var V={};function N(e,t){var n=e.toLowerCase();V[n]=V[n+"s"]=V[t]=e}function I(e){return"string"===typeof e?V[e]||V[e.toLowerCase()]:void 0}function R(e){var t,n,r={};for(n in e)a(e,n)&&(t=I(n))&&(r[t]=e[n]);return r}var F={};function B(e,t){F[e]=t}function U(e){return e%4===0&&e%100!==0||e%400===0}function W(e){return e<0?Math.ceil(e)||0:Math.floor(e)}function G(e){var t=+e,n=0;return 0!==t&&isFinite(t)&&(n=W(t)),n}function Y(e,t){return function(n){return null!=n?($(this,e,n),r.updateOffset(this,t),this):Z(this,e)}}function Z(e,t){return e.isValid()?e._d["get"+(e._isUTC?"UTC":"")+t]():NaN}function $(e,t,n){e.isValid()&&!isNaN(n)&&("FullYear"===t&&U(e.year())&&1===e.month()&&29===e.date()?(n=G(n),e._d["set"+(e._isUTC?"UTC":"")+t](n,e.month(),Te(n,e.month()))):e._d["set"+(e._isUTC?"UTC":"")+t](n))}var X,K=/\d/,Q=/\d\d/,J=/\d{3}/,ee=/\d{4}/,te=/[+-]?\d{6}/,ne=/\d\d?/,re=/\d\d\d\d?/,ie=/\d\d\d\d\d\d?/,oe=/\d{1,3}/,ae=/\d{1,4}/,ce=/[+-]?\d{1,6}/,se=/\d+/,le=/[+-]?\d+/,ue=/Z|[+-]\d\d:?\d\d/gi,fe=/Z|[+-]\d\d(?::?\d\d)?/gi,he=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i;function de(e,t,n){X[e]=C(t)?t:function(e,r){return e&&n?n:t}}function pe(e,t){return a(X,e)?X[e](t._strict,t._locale):new RegExp(ze(e.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,(function(e,t,n,r,i){return t||n||r||i}))))}function ze(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}X={};var ve={};function ge(e,t){var n,r=t;for("string"===typeof e&&(e=[e]),l(t)&&(r=function(e,n){n[t]=G(e)}),n=0;n68?1900:2e3)};var Re=Y("FullYear",!0);function Fe(e,t,n,r,i,o,a){var c;return e<100&&e>=0?(c=new Date(e+400,t,n,r,i,o,a),isFinite(c.getFullYear())&&c.setFullYear(e)):c=new Date(e,t,n,r,i,o,a),c}function Be(e){var t,n;return e<100&&e>=0?((n=Array.prototype.slice.call(arguments))[0]=e+400,t=new Date(Date.UTC.apply(null,n)),isFinite(t.getUTCFullYear())&&t.setUTCFullYear(e)):t=new Date(Date.UTC.apply(null,arguments)),t}function Ue(e,t,n){var r=7+t-n;return-(7+Be(e,0,r).getUTCDay()-t)%7+r-1}function We(e,t,n,r,i){var o,a,c=1+7*(t-1)+(7+n-r)%7+Ue(e,r,i);return c<=0?a=Ie(o=e-1)+c:c>Ie(e)?(o=e+1,a=c-Ie(e)):(o=e,a=c),{year:o,dayOfYear:a}}function Ge(e,t,n){var r,i,o=Ue(e.year(),t,n),a=Math.floor((e.dayOfYear()-o-1)/7)+1;return a<1?r=a+Ye(i=e.year()-1,t,n):a>Ye(e.year(),t,n)?(r=a-Ye(e.year(),t,n),i=e.year()+1):(i=e.year(),r=a),{week:r,year:i}}function Ye(e,t,n){var r=Ue(e,t,n),i=Ue(e+1,t,n);return(Ie(e)-r+i)/7}function Ze(e,t){return e.slice(t,7).concat(e.slice(0,t))}H("w",["ww",2],"wo","week"),H("W",["WW",2],"Wo","isoWeek"),N("week","w"),N("isoWeek","W"),B("week",5),B("isoWeek",5),de("w",ne),de("ww",ne,Q),de("W",ne),de("WW",ne,Q),me(["w","ww","W","WW"],(function(e,t,n,r){t[r.substr(0,1)]=G(e)})),H("d",0,"do","day"),H("dd",0,0,(function(e){return this.localeData().weekdaysMin(this,e)})),H("ddd",0,0,(function(e){return this.localeData().weekdaysShort(this,e)})),H("dddd",0,0,(function(e){return this.localeData().weekdays(this,e)})),H("e",0,0,"weekday"),H("E",0,0,"isoWeekday"),N("day","d"),N("weekday","e"),N("isoWeekday","E"),B("day",11),B("weekday",11),B("isoWeekday",11),de("d",ne),de("e",ne),de("E",ne),de("dd",(function(e,t){return t.weekdaysMinRegex(e)})),de("ddd",(function(e,t){return t.weekdaysShortRegex(e)})),de("dddd",(function(e,t){return t.weekdaysRegex(e)})),me(["dd","ddd","dddd"],(function(e,t,n,r){var i=n._locale.weekdaysParse(e,r,n._strict);null!=i?t.d=i:p(n).invalidWeekday=e})),me(["d","e","E"],(function(e,t,n,r){t[r]=G(e)}));var $e="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Xe="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Ke="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),Qe=he,Je=he,et=he;function tt(e,t,n){var r,i,o,a=e.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],r=0;r<7;++r)o=d([2e3,1]).day(r),this._minWeekdaysParse[r]=this.weekdaysMin(o,"").toLocaleLowerCase(),this._shortWeekdaysParse[r]=this.weekdaysShort(o,"").toLocaleLowerCase(),this._weekdaysParse[r]=this.weekdays(o,"").toLocaleLowerCase();return n?"dddd"===t?-1!==(i=be.call(this._weekdaysParse,a))?i:null:"ddd"===t?-1!==(i=be.call(this._shortWeekdaysParse,a))?i:null:-1!==(i=be.call(this._minWeekdaysParse,a))?i:null:"dddd"===t?-1!==(i=be.call(this._weekdaysParse,a))?i:-1!==(i=be.call(this._shortWeekdaysParse,a))?i:-1!==(i=be.call(this._minWeekdaysParse,a))?i:null:"ddd"===t?-1!==(i=be.call(this._shortWeekdaysParse,a))?i:-1!==(i=be.call(this._weekdaysParse,a))?i:-1!==(i=be.call(this._minWeekdaysParse,a))?i:null:-1!==(i=be.call(this._minWeekdaysParse,a))?i:-1!==(i=be.call(this._weekdaysParse,a))?i:-1!==(i=be.call(this._shortWeekdaysParse,a))?i:null}function nt(){function e(e,t){return t.length-e.length}var t,n,r,i,o,a=[],c=[],s=[],l=[];for(t=0;t<7;t++)n=d([2e3,1]).day(t),r=ze(this.weekdaysMin(n,"")),i=ze(this.weekdaysShort(n,"")),o=ze(this.weekdays(n,"")),a.push(r),c.push(i),s.push(o),l.push(r),l.push(i),l.push(o);a.sort(e),c.sort(e),s.sort(e),l.sort(e),this._weekdaysRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+c.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+a.join("|")+")","i")}function rt(){return this.hours()%12||12}function it(e,t){H(e,0,0,(function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)}))}function ot(e,t){return t._meridiemParse}H("H",["HH",2],0,"hour"),H("h",["hh",2],0,rt),H("k",["kk",2],0,(function(){return this.hours()||24})),H("hmm",0,0,(function(){return""+rt.apply(this)+T(this.minutes(),2)})),H("hmmss",0,0,(function(){return""+rt.apply(this)+T(this.minutes(),2)+T(this.seconds(),2)})),H("Hmm",0,0,(function(){return""+this.hours()+T(this.minutes(),2)})),H("Hmmss",0,0,(function(){return""+this.hours()+T(this.minutes(),2)+T(this.seconds(),2)})),it("a",!0),it("A",!1),N("hour","h"),B("hour",13),de("a",ot),de("A",ot),de("H",ne),de("h",ne),de("k",ne),de("HH",ne,Q),de("hh",ne,Q),de("kk",ne,Q),de("hmm",re),de("hmmss",ie),de("Hmm",re),de("Hmmss",ie),ge(["H","HH"],je),ge(["k","kk"],(function(e,t,n){var r=G(e);t[je]=24===r?0:r})),ge(["a","A"],(function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e})),ge(["h","hh"],(function(e,t,n){t[je]=G(e),p(n).bigHour=!0})),ge("hmm",(function(e,t,n){var r=e.length-2;t[je]=G(e.substr(0,r)),t[Me]=G(e.substr(r)),p(n).bigHour=!0})),ge("hmmss",(function(e,t,n){var r=e.length-4,i=e.length-2;t[je]=G(e.substr(0,r)),t[Me]=G(e.substr(r,2)),t[_e]=G(e.substr(i)),p(n).bigHour=!0})),ge("Hmm",(function(e,t,n){var r=e.length-2;t[je]=G(e.substr(0,r)),t[Me]=G(e.substr(r))})),ge("Hmmss",(function(e,t,n){var r=e.length-4,i=e.length-2;t[je]=G(e.substr(0,r)),t[Me]=G(e.substr(r,2)),t[_e]=G(e.substr(i))}));var at,ct=Y("Hours",!0),st={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",w:"a week",ww:"%d weeks",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Oe,monthsShort:Ee,week:{dow:0,doy:6},weekdays:$e,weekdaysMin:Ke,weekdaysShort:Xe,meridiemParse:/[ap]\.?m?\.?/i},lt={},ut={};function ft(e,t){var n,r=Math.min(e.length,t.length);for(n=0;n0;){if(r=dt(i.slice(0,t).join("-")))return r;if(n&&n.length>=t&&ft(i,n)>=t-1)break;t--}o++}return at}(e)}function gt(e){var t,n=e._a;return n&&-2===p(e).overflow&&(t=n[ke]<0||n[ke]>11?ke:n[xe]<1||n[xe]>Te(n[we],n[ke])?xe:n[je]<0||n[je]>24||24===n[je]&&(0!==n[Me]||0!==n[_e]||0!==n[Ce])?je:n[Me]<0||n[Me]>59?Me:n[_e]<0||n[_e]>59?_e:n[Ce]<0||n[Ce]>999?Ce:-1,p(e)._overflowDayOfYear&&(txe)&&(t=xe),p(e)._overflowWeeks&&-1===t&&(t=qe),p(e)._overflowWeekday&&-1===t&&(t=Se),p(e).overflow=t),e}var mt=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,yt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,bt=/Z|[+-]\d\d(?::?\d\d)?/,wt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/],["YYYYMM",/\d{6}/,!1],["YYYY",/\d{4}/,!1]],kt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],xt=/^\/?Date\((-?\d+)/i,jt=/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/,Mt={UT:0,GMT:0,EDT:-240,EST:-300,CDT:-300,CST:-360,MDT:-360,MST:-420,PDT:-420,PST:-480};function _t(e){var t,n,r,i,o,a,c=e._i,s=mt.exec(c)||yt.exec(c);if(s){for(p(e).iso=!0,t=0,n=wt.length;t7)&&(s=!0)):(o=e._locale._week.dow,a=e._locale._week.doy,l=Ge(Lt(),o,a),n=St(t.gg,e._a[we],l.year),r=St(t.w,l.week),null!=t.d?((i=t.d)<0||i>6)&&(s=!0):null!=t.e?(i=t.e+o,(t.e<0||t.e>6)&&(s=!0)):i=o),r<1||r>Ye(n,o,a)?p(e)._overflowWeeks=!0:null!=s?p(e)._overflowWeekday=!0:(c=We(n,r,i,o,a),e._a[we]=c.year,e._dayOfYear=c.dayOfYear)}(e),null!=e._dayOfYear&&(a=St(e._a[we],i[we]),(e._dayOfYear>Ie(a)||0===e._dayOfYear)&&(p(e)._overflowDayOfYear=!0),n=Be(a,0,e._dayOfYear),e._a[ke]=n.getUTCMonth(),e._a[xe]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=c[t]=i[t];for(;t<7;t++)e._a[t]=c[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[je]&&0===e._a[Me]&&0===e._a[_e]&&0===e._a[Ce]&&(e._nextDay=!0,e._a[je]=0),e._d=(e._useUTC?Be:Fe).apply(null,c),o=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[je]=24),e._w&&"undefined"!==typeof e._w.d&&e._w.d!==o&&(p(e).weekdayMismatch=!0)}}function Ot(e){if(e._f!==r.ISO_8601)if(e._f!==r.RFC_2822){e._a=[],p(e).empty=!0;var t,n,i,o,a,c,s=""+e._i,l=s.length,u=0;for(i=P(e._f,e._locale).match(O)||[],t=0;t0&&p(e).unusedInput.push(a),s=s.slice(s.indexOf(n)+n.length),u+=n.length),L[o]?(n?p(e).empty=!1:p(e).unusedTokens.push(o),ye(o,n,e)):e._strict&&!n&&p(e).unusedTokens.push(o);p(e).charsLeftOver=l-u,s.length>0&&p(e).unusedInput.push(s),e._a[je]<=12&&!0===p(e).bigHour&&e._a[je]>0&&(p(e).bigHour=void 0),p(e).parsedDateParts=e._a.slice(0),p(e).meridiem=e._meridiem,e._a[je]=function(e,t,n){var r;return null==n?t:null!=e.meridiemHour?e.meridiemHour(t,n):null!=e.isPM?((r=e.isPM(n))&&t<12&&(t+=12),r||12!==t||(t=0),t):t}(e._locale,e._a[je],e._meridiem),null!==(c=p(e).era)&&(e._a[we]=e._locale.erasConvertYear(c,e._a[we])),Tt(e),gt(e)}else qt(e);else _t(e)}function Et(e){var t=e._i,n=e._f;return e._locale=e._locale||vt(e._l),null===t||void 0===n&&""===t?v({nullInput:!0}):("string"===typeof t&&(e._i=t=e._locale.preparse(t)),w(t)?new b(gt(t)):(u(t)?e._d=t:i(n)?function(e){var t,n,r,i,o,a,c=!1;if(0===e._f.length)return p(e).invalidFormat=!0,void(e._d=new Date(NaN));for(i=0;ithis?this:e:v()}));function Pt(e,t){var n,r;if(1===t.length&&i(t[0])&&(t=t[0]),!t.length)return Lt();for(n=t[0],r=1;r=0?new Date(e+400,t,n)-hn:new Date(e,t,n).valueOf()}function zn(e,t,n){return e<100&&e>=0?Date.UTC(e+400,t,n)-hn:Date.UTC(e,t,n)}function vn(e,t){return t.erasAbbrRegex(e)}function gn(){var e,t,n=[],r=[],i=[],o=[],a=this.eras();for(e=0,t=a.length;e(o=Ye(e,r,i))&&(t=o),bn.call(this,e,t,n,r,i))}function bn(e,t,n,r,i){var o=We(e,t,n,r,i),a=Be(o.year,0,o.dayOfYear);return this.year(a.getUTCFullYear()),this.month(a.getUTCMonth()),this.date(a.getUTCDate()),this}H("N",0,0,"eraAbbr"),H("NN",0,0,"eraAbbr"),H("NNN",0,0,"eraAbbr"),H("NNNN",0,0,"eraName"),H("NNNNN",0,0,"eraNarrow"),H("y",["y",1],"yo","eraYear"),H("y",["yy",2],0,"eraYear"),H("y",["yyy",3],0,"eraYear"),H("y",["yyyy",4],0,"eraYear"),de("N",vn),de("NN",vn),de("NNN",vn),de("NNNN",(function(e,t){return t.erasNameRegex(e)})),de("NNNNN",(function(e,t){return t.erasNarrowRegex(e)})),ge(["N","NN","NNN","NNNN","NNNNN"],(function(e,t,n,r){var i=n._locale.erasParse(e,r,n._strict);i?p(n).era=i:p(n).invalidEra=e})),de("y",se),de("yy",se),de("yyy",se),de("yyyy",se),de("yo",(function(e,t){return t._eraYearOrdinalRegex||se})),ge(["y","yy","yyy","yyyy"],we),ge(["yo"],(function(e,t,n,r){var i;n._locale._eraYearOrdinalRegex&&(i=e.match(n._locale._eraYearOrdinalRegex)),n._locale.eraYearOrdinalParse?t[we]=n._locale.eraYearOrdinalParse(e,i):t[we]=parseInt(e,10)})),H(0,["gg",2],0,(function(){return this.weekYear()%100})),H(0,["GG",2],0,(function(){return this.isoWeekYear()%100})),mn("gggg","weekYear"),mn("ggggg","weekYear"),mn("GGGG","isoWeekYear"),mn("GGGGG","isoWeekYear"),N("weekYear","gg"),N("isoWeekYear","GG"),B("weekYear",1),B("isoWeekYear",1),de("G",le),de("g",le),de("GG",ne,Q),de("gg",ne,Q),de("GGGG",ae,ee),de("gggg",ae,ee),de("GGGGG",ce,te),de("ggggg",ce,te),me(["gggg","ggggg","GGGG","GGGGG"],(function(e,t,n,r){t[r.substr(0,2)]=G(e)})),me(["gg","GG"],(function(e,t,n,i){t[i]=r.parseTwoDigitYear(e)})),H("Q",0,"Qo","quarter"),N("quarter","Q"),B("quarter",7),de("Q",K),ge("Q",(function(e,t){t[ke]=3*(G(e)-1)})),H("D",["DD",2],"Do","date"),N("date","D"),B("date",9),de("D",ne),de("DD",ne,Q),de("Do",(function(e,t){return e?t._dayOfMonthOrdinalParse||t._ordinalParse:t._dayOfMonthOrdinalParseLenient})),ge(["D","DD"],xe),ge("Do",(function(e,t){t[xe]=G(e.match(ne)[0])}));var wn=Y("Date",!0);H("DDD",["DDDD",3],"DDDo","dayOfYear"),N("dayOfYear","DDD"),B("dayOfYear",4),de("DDD",oe),de("DDDD",J),ge(["DDD","DDDD"],(function(e,t,n){n._dayOfYear=G(e)})),H("m",["mm",2],0,"minute"),N("minute","m"),B("minute",14),de("m",ne),de("mm",ne,Q),ge(["m","mm"],Me);var kn=Y("Minutes",!1);H("s",["ss",2],0,"second"),N("second","s"),B("second",15),de("s",ne),de("ss",ne,Q),ge(["s","ss"],_e);var xn,jn,Mn=Y("Seconds",!1);for(H("S",0,0,(function(){return~~(this.millisecond()/100)})),H(0,["SS",2],0,(function(){return~~(this.millisecond()/10)})),H(0,["SSS",3],0,"millisecond"),H(0,["SSSS",4],0,(function(){return 10*this.millisecond()})),H(0,["SSSSS",5],0,(function(){return 100*this.millisecond()})),H(0,["SSSSSS",6],0,(function(){return 1e3*this.millisecond()})),H(0,["SSSSSSS",7],0,(function(){return 1e4*this.millisecond()})),H(0,["SSSSSSSS",8],0,(function(){return 1e5*this.millisecond()})),H(0,["SSSSSSSSS",9],0,(function(){return 1e6*this.millisecond()})),N("millisecond","ms"),B("millisecond",16),de("S",oe,K),de("SS",oe,Q),de("SSS",oe,J),xn="SSSS";xn.length<=9;xn+="S")de(xn,se);function _n(e,t){t[Ce]=G(1e3*("0."+e))}for(xn="S";xn.length<=9;xn+="S")ge(xn,_n);jn=Y("Milliseconds",!1),H("z",0,0,"zoneAbbr"),H("zz",0,0,"zoneName");var Cn=b.prototype;function qn(e){return e}Cn.add=tn,Cn.calendar=function(e,t){var n;1===arguments.length&&(arguments[0]?w(n=arguments[0])||u(n)||rn(n)||l(n)||function(e){var t=i(e),n=!1;return t&&(n=0===e.filter((function(t){return!l(t)&&rn(e)})).length),t&&n}(n)||function(e){var t,n,r=o(e)&&!c(e),i=!1,s=["years","year","y","months","month","M","days","day","d","dates","date","D","hours","hour","h","minutes","minute","m","seconds","second","s","milliseconds","millisecond","ms"];for(t=0;tn.valueOf():n.valueOf()9999?D(n,t?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):C(Date.prototype.toISOString)?t?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",D(n,"Z")):D(n,t?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},Cn.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var e,t,n,r="moment",i="";return this.isLocal()||(r=0===this.utcOffset()?"moment.utc":"moment.parseZone",i="Z"),e="["+r+'("]',t=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",n=i+'[")]',this.format(e+t+"-MM-DD[T]HH:mm:ss.SSS"+n)},"undefined"!==typeof Symbol&&null!=Symbol.for&&(Cn[Symbol.for("nodejs.util.inspect.custom")]=function(){return"Moment<"+this.format()+">"}),Cn.toJSON=function(){return this.isValid()?this.toISOString():null},Cn.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},Cn.unix=function(){return Math.floor(this.valueOf()/1e3)},Cn.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},Cn.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},Cn.eraName=function(){var e,t,n,r=this.localeData().eras();for(e=0,t=r.length;ethis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},Cn.isLocal=function(){return!!this.isValid()&&!this._isUTC},Cn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},Cn.isUtc=Yt,Cn.isUTC=Yt,Cn.zoneAbbr=function(){return this._isUTC?"UTC":""},Cn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},Cn.dates=x("dates accessor is deprecated. Use date instead.",wn),Cn.months=x("months accessor is deprecated. Use month instead",Ve),Cn.years=x("years accessor is deprecated. Use year instead",Re),Cn.zone=x("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",(function(e,t){return null!=e?("string"!==typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()})),Cn.isDSTShifted=x("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",(function(){if(!s(this._isDSTShifted))return this._isDSTShifted;var e,t={};return y(t,this),(t=Et(t))._a?(e=t._isUTC?d(t._a):Lt(t._a),this._isDSTShifted=this.isValid()&&function(e,t,n){var r,i=Math.min(e.length,t.length),o=Math.abs(e.length-t.length),a=0;for(r=0;r0):this._isDSTShifted=!1,this._isDSTShifted}));var Sn=S.prototype;function Tn(e,t,n,r){var i=vt(),o=d().set(r,t);return i[n](o,e)}function On(e,t,n){if(l(e)&&(t=e,e=void 0),e=e||"",null!=t)return Tn(e,t,n,"month");var r,i=[];for(r=0;r<12;r++)i[r]=Tn(e,r,n,"month");return i}function En(e,t,n,r){"boolean"===typeof e?(l(t)&&(n=t,t=void 0),t=t||""):(n=t=e,e=!1,l(t)&&(n=t,t=void 0),t=t||"");var i,o=vt(),a=e?o._week.dow:0,c=[];if(null!=n)return Tn(t,(n+a)%7,r,"day");for(i=0;i<7;i++)c[i]=Tn(t,(i+a)%7,r,"day");return c}Sn.calendar=function(e,t,n){var r=this._calendar[e]||this._calendar.sameElse;return C(r)?r.call(t,n):r},Sn.longDateFormat=function(e){var t=this._longDateFormat[e],n=this._longDateFormat[e.toUpperCase()];return t||!n?t:(this._longDateFormat[e]=n.match(O).map((function(e){return"MMMM"===e||"MM"===e||"DD"===e||"dddd"===e?e.slice(1):e})).join(""),this._longDateFormat[e])},Sn.invalidDate=function(){return this._invalidDate},Sn.ordinal=function(e){return this._ordinal.replace("%d",e)},Sn.preparse=qn,Sn.postformat=qn,Sn.relativeTime=function(e,t,n,r){var i=this._relativeTime[n];return C(i)?i(e,t,n,r):i.replace(/%d/i,e)},Sn.pastFuture=function(e,t){var n=this._relativeTime[e>0?"future":"past"];return C(n)?n(t):n.replace(/%s/i,t)},Sn.set=function(e){var t,n;for(n in e)a(e,n)&&(C(t=e[n])?this[n]=t:this["_"+n]=t);this._config=e,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},Sn.eras=function(e,t){var n,i,o,a=this._eras||vt("en")._eras;for(n=0,i=a.length;n=0)return s[r]},Sn.erasConvertYear=function(e,t){var n=e.since<=e.until?1:-1;return void 0===t?r(e.since).year():r(e.since).year()+(t-e.offset)*n},Sn.erasAbbrRegex=function(e){return a(this,"_erasAbbrRegex")||gn.call(this),e?this._erasAbbrRegex:this._erasRegex},Sn.erasNameRegex=function(e){return a(this,"_erasNameRegex")||gn.call(this),e?this._erasNameRegex:this._erasRegex},Sn.erasNarrowRegex=function(e){return a(this,"_erasNarrowRegex")||gn.call(this),e?this._erasNarrowRegex:this._erasRegex},Sn.months=function(e,t){return e?i(this._months)?this._months[e.month()]:this._months[(this._months.isFormat||Ae).test(t)?"format":"standalone"][e.month()]:i(this._months)?this._months:this._months.standalone},Sn.monthsShort=function(e,t){return e?i(this._monthsShort)?this._monthsShort[e.month()]:this._monthsShort[Ae.test(t)?"format":"standalone"][e.month()]:i(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},Sn.monthsParse=function(e,t,n){var r,i,o;if(this._monthsParseExact)return De.call(this,e,t,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),r=0;r<12;r++){if(i=d([2e3,r]),n&&!this._longMonthsParse[r]&&(this._longMonthsParse[r]=new RegExp("^"+this.months(i,"").replace(".","")+"$","i"),this._shortMonthsParse[r]=new RegExp("^"+this.monthsShort(i,"").replace(".","")+"$","i")),n||this._monthsParse[r]||(o="^"+this.months(i,"")+"|^"+this.monthsShort(i,""),this._monthsParse[r]=new RegExp(o.replace(".",""),"i")),n&&"MMMM"===t&&this._longMonthsParse[r].test(e))return r;if(n&&"MMM"===t&&this._shortMonthsParse[r].test(e))return r;if(!n&&this._monthsParse[r].test(e))return r}},Sn.monthsRegex=function(e){return this._monthsParseExact?(a(this,"_monthsRegex")||Ne.call(this),e?this._monthsStrictRegex:this._monthsRegex):(a(this,"_monthsRegex")||(this._monthsRegex=He),this._monthsStrictRegex&&e?this._monthsStrictRegex:this._monthsRegex)},Sn.monthsShortRegex=function(e){return this._monthsParseExact?(a(this,"_monthsRegex")||Ne.call(this),e?this._monthsShortStrictRegex:this._monthsShortRegex):(a(this,"_monthsShortRegex")||(this._monthsShortRegex=Le),this._monthsShortStrictRegex&&e?this._monthsShortStrictRegex:this._monthsShortRegex)},Sn.week=function(e){return Ge(e,this._week.dow,this._week.doy).week},Sn.firstDayOfYear=function(){return this._week.doy},Sn.firstDayOfWeek=function(){return this._week.dow},Sn.weekdays=function(e,t){var n=i(this._weekdays)?this._weekdays:this._weekdays[e&&!0!==e&&this._weekdays.isFormat.test(t)?"format":"standalone"];return!0===e?Ze(n,this._week.dow):e?n[e.day()]:n},Sn.weekdaysMin=function(e){return!0===e?Ze(this._weekdaysMin,this._week.dow):e?this._weekdaysMin[e.day()]:this._weekdaysMin},Sn.weekdaysShort=function(e){return!0===e?Ze(this._weekdaysShort,this._week.dow):e?this._weekdaysShort[e.day()]:this._weekdaysShort},Sn.weekdaysParse=function(e,t,n){var r,i,o;if(this._weekdaysParseExact)return tt.call(this,e,t,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),r=0;r<7;r++){if(i=d([2e3,1]).day(r),n&&!this._fullWeekdaysParse[r]&&(this._fullWeekdaysParse[r]=new RegExp("^"+this.weekdays(i,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[r]=new RegExp("^"+this.weekdaysShort(i,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[r]=new RegExp("^"+this.weekdaysMin(i,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[r]||(o="^"+this.weekdays(i,"")+"|^"+this.weekdaysShort(i,"")+"|^"+this.weekdaysMin(i,""),this._weekdaysParse[r]=new RegExp(o.replace(".",""),"i")),n&&"dddd"===t&&this._fullWeekdaysParse[r].test(e))return r;if(n&&"ddd"===t&&this._shortWeekdaysParse[r].test(e))return r;if(n&&"dd"===t&&this._minWeekdaysParse[r].test(e))return r;if(!n&&this._weekdaysParse[r].test(e))return r}},Sn.weekdaysRegex=function(e){return this._weekdaysParseExact?(a(this,"_weekdaysRegex")||nt.call(this),e?this._weekdaysStrictRegex:this._weekdaysRegex):(a(this,"_weekdaysRegex")||(this._weekdaysRegex=Qe),this._weekdaysStrictRegex&&e?this._weekdaysStrictRegex:this._weekdaysRegex)},Sn.weekdaysShortRegex=function(e){return this._weekdaysParseExact?(a(this,"_weekdaysRegex")||nt.call(this),e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(a(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=Je),this._weekdaysShortStrictRegex&&e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},Sn.weekdaysMinRegex=function(e){return this._weekdaysParseExact?(a(this,"_weekdaysRegex")||nt.call(this),e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(a(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=et),this._weekdaysMinStrictRegex&&e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},Sn.isPM=function(e){return"p"===(e+"").toLowerCase().charAt(0)},Sn.meridiem=function(e,t,n){return e>11?n?"pm":"PM":n?"am":"AM"},pt("en",{eras:[{since:"0001-01-01",until:1/0,offset:1,name:"Anno Domini",narrow:"AD",abbr:"AD"},{since:"0000-12-31",until:-1/0,offset:1,name:"Before Christ",narrow:"BC",abbr:"BC"}],dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var t=e%10;return e+(1===G(e%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th")}}),r.lang=x("moment.lang is deprecated. Use moment.locale instead.",pt),r.langData=x("moment.langData is deprecated. Use moment.localeData instead.",vt);var An=Math.abs;function Ln(e,t,n,r){var i=Xt(t,n);return e._milliseconds+=r*i._milliseconds,e._days+=r*i._days,e._months+=r*i._months,e._bubble()}function Hn(e){return e<0?Math.floor(e):Math.ceil(e)}function Dn(e){return 4800*e/146097}function Pn(e){return 146097*e/4800}function Vn(e){return function(){return this.as(e)}}var Nn=Vn("ms"),In=Vn("s"),Rn=Vn("m"),Fn=Vn("h"),Bn=Vn("d"),Un=Vn("w"),Wn=Vn("M"),Gn=Vn("Q"),Yn=Vn("y");function Zn(e){return function(){return this.isValid()?this._data[e]:NaN}}var $n=Zn("milliseconds"),Xn=Zn("seconds"),Kn=Zn("minutes"),Qn=Zn("hours"),Jn=Zn("days"),er=Zn("months"),tr=Zn("years"),nr=Math.round,rr={ss:44,s:45,m:45,h:22,d:26,w:null,M:11};function ir(e,t,n,r,i){return i.relativeTime(t||1,!!n,e,r)}var or=Math.abs;function ar(e){return(e>0)-(e<0)||+e}function cr(){if(!this.isValid())return this.localeData().invalidDate();var e,t,n,r,i,o,a,c,s=or(this._milliseconds)/1e3,l=or(this._days),u=or(this._months),f=this.asSeconds();return f?(e=W(s/60),t=W(e/60),s%=60,e%=60,n=W(u/12),u%=12,r=s?s.toFixed(3).replace(/\.?0+$/,""):"",i=f<0?"-":"",o=ar(this._months)!==ar(f)?"-":"",a=ar(this._days)!==ar(f)?"-":"",c=ar(this._milliseconds)!==ar(f)?"-":"",i+"P"+(n?o+n+"Y":"")+(u?o+u+"M":"")+(l?a+l+"D":"")+(t||e||s?"T":"")+(t?c+t+"H":"")+(e?c+e+"M":"")+(s?c+r+"S":"")):"P0D"}var sr=Nt.prototype;return sr.isValid=function(){return this._isValid},sr.abs=function(){var e=this._data;return this._milliseconds=An(this._milliseconds),this._days=An(this._days),this._months=An(this._months),e.milliseconds=An(e.milliseconds),e.seconds=An(e.seconds),e.minutes=An(e.minutes),e.hours=An(e.hours),e.months=An(e.months),e.years=An(e.years),this},sr.add=function(e,t){return Ln(this,e,t,1)},sr.subtract=function(e,t){return Ln(this,e,t,-1)},sr.as=function(e){if(!this.isValid())return NaN;var t,n,r=this._milliseconds;if("month"===(e=I(e))||"quarter"===e||"year"===e)switch(t=this._days+r/864e5,n=this._months+Dn(t),e){case"month":return n;case"quarter":return n/3;case"year":return n/12}else switch(t=this._days+Math.round(Pn(this._months)),e){case"week":return t/7+r/6048e5;case"day":return t+r/864e5;case"hour":return 24*t+r/36e5;case"minute":return 1440*t+r/6e4;case"second":return 86400*t+r/1e3;case"millisecond":return Math.floor(864e5*t)+r;default:throw new Error("Unknown unit "+e)}},sr.asMilliseconds=Nn,sr.asSeconds=In,sr.asMinutes=Rn,sr.asHours=Fn,sr.asDays=Bn,sr.asWeeks=Un,sr.asMonths=Wn,sr.asQuarters=Gn,sr.asYears=Yn,sr.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*G(this._months/12):NaN},sr._bubble=function(){var e,t,n,r,i,o=this._milliseconds,a=this._days,c=this._months,s=this._data;return o>=0&&a>=0&&c>=0||o<=0&&a<=0&&c<=0||(o+=864e5*Hn(Pn(c)+a),a=0,c=0),s.milliseconds=o%1e3,e=W(o/1e3),s.seconds=e%60,t=W(e/60),s.minutes=t%60,n=W(t/60),s.hours=n%24,a+=W(n/24),i=W(Dn(a)),c+=i,a-=Hn(Pn(i)),r=W(c/12),c%=12,s.days=a,s.months=c,s.years=r,this},sr.clone=function(){return Xt(this)},sr.get=function(e){return e=I(e),this.isValid()?this[e+"s"]():NaN},sr.milliseconds=$n,sr.seconds=Xn,sr.minutes=Kn,sr.hours=Qn,sr.days=Jn,sr.weeks=function(){return W(this.days()/7)},sr.months=er,sr.years=tr,sr.humanize=function(e,t){if(!this.isValid())return this.localeData().invalidDate();var n,r,i=!1,o=rr;return"object"===typeof e&&(t=e,e=!1),"boolean"===typeof e&&(i=e),"object"===typeof t&&(o=Object.assign({},rr,t),null!=t.s&&null==t.ss&&(o.ss=t.s-1)),n=this.localeData(),r=function(e,t,n,r){var i=Xt(e).abs(),o=nr(i.as("s")),a=nr(i.as("m")),c=nr(i.as("h")),s=nr(i.as("d")),l=nr(i.as("M")),u=nr(i.as("w")),f=nr(i.as("y")),h=o<=n.ss&&["s",o]||o0,h[4]=r,ir.apply(null,h)}(this,!i,o,n),i&&(r=n.pastFuture(+this,r)),n.postformat(r)},sr.toISOString=cr,sr.toString=cr,sr.toJSON=cr,sr.locale=an,sr.localeData=sn,sr.toIsoString=x("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",cr),sr.lang=cn,H("X",0,0,"unix"),H("x",0,0,"valueOf"),de("x",le),de("X",/[+-]?\d+(\.\d{1,3})?/),ge("X",(function(e,t,n){n._d=new Date(1e3*parseFloat(e))})),ge("x",(function(e,t,n){n._d=new Date(G(e))})),r.version="2.29.1",t=Lt,r.fn=Cn,r.min=function(){return Pt("isBefore",[].slice.call(arguments,0))},r.max=function(){return Pt("isAfter",[].slice.call(arguments,0))},r.now=function(){return Date.now?Date.now():+new Date},r.utc=d,r.unix=function(e){return Lt(1e3*e)},r.months=function(e,t){return On(e,t,"months")},r.isDate=u,r.locale=pt,r.invalid=v,r.duration=Xt,r.isMoment=w,r.weekdays=function(e,t,n){return En(e,t,n,"weekdays")},r.parseZone=function(){return Lt.apply(null,arguments).parseZone()},r.localeData=vt,r.isDuration=It,r.monthsShort=function(e,t){return On(e,t,"monthsShort")},r.weekdaysMin=function(e,t,n){return En(e,t,n,"weekdaysMin")},r.defineLocale=zt,r.updateLocale=function(e,t){if(null!=t){var n,r,i=st;null!=lt[e]&&null!=lt[e].parentLocale?lt[e].set(q(lt[e]._config,t)):(null!=(r=dt(e))&&(i=r._config),t=q(i,t),null==r&&(t.abbr=e),(n=new S(t)).parentLocale=lt[e],lt[e]=n),pt(e)}else null!=lt[e]&&(null!=lt[e].parentLocale?(lt[e]=lt[e].parentLocale,e===pt()&&pt(e)):null!=lt[e]&&delete lt[e]);return lt[e]},r.locales=function(){return j(lt)},r.weekdaysShort=function(e,t,n){return En(e,t,n,"weekdaysShort")},r.normalizeUnits=I,r.relativeTimeRounding=function(e){return void 0===e?nr:"function"===typeof e&&(nr=e,!0)},r.relativeTimeThreshold=function(e,t){return void 0!==rr[e]&&(void 0===t?rr[e]:(rr[e]=t,"s"===e&&(rr.ss=t-1),!0))},r.calendarFormat=function(e,t){var n=e.diff(t,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"},r.prototype=Cn,r.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"GGGG-[W]WW",MONTH:"YYYY-MM"},r}()}).call(this,n(417)(e))},,,function(e,t){var n,r,i=e.exports={};function o(){throw new Error("setTimeout has not been defined")}function a(){throw new Error("clearTimeout has not been defined")}function c(e){if(n===setTimeout)return setTimeout(e,0);if((n===o||!n)&&setTimeout)return n=setTimeout,setTimeout(e,0);try{return n(e,0)}catch(t){try{return n.call(null,e,0)}catch(t){return n.call(this,e,0)}}}!function(){try{n="function"===typeof setTimeout?setTimeout:o}catch(e){n=o}try{r="function"===typeof clearTimeout?clearTimeout:a}catch(e){r=a}}();var s,l=[],u=!1,f=-1;function h(){u&&s&&(u=!1,s.length?l=s.concat(l):f=-1,l.length&&d())}function d(){if(!u){var e=c(h);u=!0;for(var t=l.length;t;){for(s=l,l=[];++f1)for(var n=1;n=0;c--)(i=e[c])&&(a=(o<3?i(a):o>3?i(t,n,a):i(t,n))||a);return o>3&&a&&Object.defineProperty(t,n,a),a}function s(e,t){return function(n,r){t(n,r,e)}}function l(e,t){if("object"===typeof Reflect&&"function"===typeof Reflect.metadata)return Reflect.metadata(e,t)}function u(e,t,n,r){return new(n||(n=Promise))((function(i,o){function a(e){try{s(r.next(e))}catch(t){o(t)}}function c(e){try{s(r.throw(e))}catch(t){o(t)}}function s(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,c)}s((r=r.apply(e,t||[])).next())}))}function f(e,t){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:c(0),throw:c(1),return:c(2)},"function"===typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function c(o){return function(c){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(i=2&o[0]?r.return:o[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return a.label++,{value:o[1],done:!1};case 5:a.label++,r=o[1],o=[0];continue;case 7:o=a.ops.pop(),a.trys.pop();continue;default:if(!(i=(i=a.trys).length>0&&i[i.length-1])&&(6===o[0]||2===o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function z(e,t){var n="function"===typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,i,o=n.call(e),a=[];try{for(;(void 0===t||t-- >0)&&!(r=o.next()).done;)a.push(r.value)}catch(c){i={error:c}}finally{try{r&&!r.done&&(n=o.return)&&n.call(o)}finally{if(i)throw i.error}}return a}function v(){for(var e=[],t=0;t1||c(e,t)}))})}function c(e,t){try{(n=i[e](t)).value instanceof y?Promise.resolve(n.value.v).then(s,l):u(o[0][2],n)}catch(r){u(o[0][3],r)}var n}function s(e){c("next",e)}function l(e){c("throw",e)}function u(e,t){e(t),o.shift(),o.length&&c(o[0][0],o[0][1])}}function w(e){var t,n;return t={},r("next"),r("throw",(function(e){throw e})),r("return"),t[Symbol.iterator]=function(){return this},t;function r(r,i){t[r]=e[r]?function(t){return(n=!n)?{value:y(e[r](t)),done:"return"===r}:i?i(t):t}:i}}function k(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t,n=e[Symbol.asyncIterator];return n?n.call(e):(e=p(e),t={},r("next"),r("throw"),r("return"),t[Symbol.asyncIterator]=function(){return this},t);function r(n){t[n]=e[n]&&function(t){return new Promise((function(r,i){(function(e,t,n,r){Promise.resolve(r).then((function(t){e({value:t,done:n})}),t)})(r,i,(t=e[n](t)).done,t.value)}))}}}function x(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e}var j=Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t};function M(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&h(t,e,n);return j(t,e),t}function _(e){return e&&e.__esModule?e:{default:e}}function C(e,t,n,r){if("a"===n&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"===typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===n?r:"a"===n?r.call(e):r?r.value:t.get(e)}function q(e,t,n,r,i){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!i)throw new TypeError("Private accessor was defined without a setter");if("function"===typeof t?e!==t||!i:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?i.call(e,n):i?i.value=n:t.set(e,n),n}},function(e,t,n){"use strict";e.exports=n(307)},function(e,t,n){"use strict";var r=n(64),i=n(96),o=Object(r.a)(i.a);t.a=o},function(e,t,n){"use strict";var r=n(160),i=n(64),o=Object(i.a)(Object(r.a)("slice",(function(e,t,n){return Array.prototype.slice.call(n,e,t)})));t.a=o},function(e,t,n){"use strict";n.d(t,"a",(function(){return o}));var r=n(43),i=n(53);function o(e,t){return new r.a((function(n){var r=new i.a,o=0;return r.add(t.schedule((function(){o!==e.length?(n.next(e[o++]),n.closed||r.add(this.schedule())):n.complete()}))),r}))}},function(e,t,n){"use strict";n.d(t,"a",(function(){return a}));var r=n(94),i=n(185),o=n(43);function a(e,t,n,a,c){if(void 0===c&&(c=new r.a(e,n,a)),!c.closed)return t instanceof o.a?t.subscribe(c):Object(i.a)(t)(c)}},function(e,t,n){"use strict";n.d(t,"a",(function(){return i}));var r=n(31),i=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r.b(t,e),t.prototype.notifyNext=function(e,t,n,r,i){this.destination.next(t)},t.prototype.notifyError=function(e,t){this.destination.error(e)},t.prototype.notifyComplete=function(e){this.destination.complete()},t}(n(52).a)},function(e,t,n){var r,i;window,e.exports=(r=n(0),i=n(32),function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=9)}([function(e,t,n){(function(e,r){var i;(function(){var o="Expected a function",a="__lodash_placeholder__",c=[["ary",128],["bind",1],["bindKey",2],["curry",8],["curryRight",16],["flip",512],["partial",32],["partialRight",64],["rearg",256]],s="[object Arguments]",l="[object Array]",u="[object Boolean]",f="[object Date]",h="[object Error]",d="[object Function]",p="[object GeneratorFunction]",z="[object Map]",v="[object Number]",g="[object Object]",m="[object RegExp]",y="[object Set]",b="[object String]",w="[object Symbol]",k="[object WeakMap]",x="[object ArrayBuffer]",j="[object DataView]",M="[object Float32Array]",_="[object Float64Array]",C="[object Int8Array]",q="[object Int16Array]",S="[object Int32Array]",T="[object Uint8Array]",O="[object Uint16Array]",E="[object Uint32Array]",A=/\b__p \+= '';/g,L=/\b(__p \+=) '' \+/g,H=/(__e\(.*?\)|\b__t\)) \+\n'';/g,D=/&(?:amp|lt|gt|quot|#39);/g,P=/[&<>"']/g,V=RegExp(D.source),N=RegExp(P.source),I=/<%-([\s\S]+?)%>/g,R=/<%([\s\S]+?)%>/g,F=/<%=([\s\S]+?)%>/g,B=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,U=/^\w*$/,W=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,G=/[\\^$.*+?()[\]{}|]/g,Y=RegExp(G.source),Z=/^\s+|\s+$/g,$=/^\s+/,X=/\s+$/,K=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,Q=/\{\n\/\* \[wrapped with (.+)\] \*/,J=/,? & /,ee=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,te=/\\(\\)?/g,ne=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,re=/\w*$/,ie=/^[-+]0x[0-9a-f]+$/i,oe=/^0b[01]+$/i,ae=/^\[object .+?Constructor\]$/,ce=/^0o[0-7]+$/i,se=/^(?:0|[1-9]\d*)$/,le=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,ue=/($^)/,fe=/['\n\r\u2028\u2029\\]/g,he="\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff",de="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",pe="["+de+"]",ze="["+he+"]",ve="\\d+",ge="[a-z\\xdf-\\xf6\\xf8-\\xff]",me="[^\\ud800-\\udfff"+de+ve+"\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde]",ye="\\ud83c[\\udffb-\\udfff]",be="[^\\ud800-\\udfff]",we="(?:\\ud83c[\\udde6-\\uddff]){2}",ke="[\\ud800-\\udbff][\\udc00-\\udfff]",xe="[A-Z\\xc0-\\xd6\\xd8-\\xde]",je="(?:"+ge+"|"+me+")",Me="(?:"+xe+"|"+me+")",_e="(?:"+ze+"|"+ye+")?",Ce="[\\ufe0e\\ufe0f]?"+_e+"(?:\\u200d(?:"+[be,we,ke].join("|")+")[\\ufe0e\\ufe0f]?"+_e+")*",qe="(?:"+["[\\u2700-\\u27bf]",we,ke].join("|")+")"+Ce,Se="(?:"+[be+ze+"?",ze,we,ke,"[\\ud800-\\udfff]"].join("|")+")",Te=RegExp("['\u2019]","g"),Oe=RegExp(ze,"g"),Ee=RegExp(ye+"(?="+ye+")|"+Se+Ce,"g"),Ae=RegExp([xe+"?"+ge+"+(?:['\u2019](?:d|ll|m|re|s|t|ve))?(?="+[pe,xe,"$"].join("|")+")",Me+"+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?(?="+[pe,xe+je,"$"].join("|")+")",xe+"?"+je+"+(?:['\u2019](?:d|ll|m|re|s|t|ve))?",xe+"+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?","\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])","\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",ve,qe].join("|"),"g"),Le=RegExp("[\\u200d\\ud800-\\udfff"+he+"\\ufe0e\\ufe0f]"),He=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,De=["Array","Buffer","DataView","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Map","Math","Object","Promise","RegExp","Set","String","Symbol","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","_","clearTimeout","isFinite","parseInt","setTimeout"],Pe=-1,Ve={};Ve[M]=Ve[_]=Ve[C]=Ve[q]=Ve[S]=Ve[T]=Ve["[object Uint8ClampedArray]"]=Ve[O]=Ve[E]=!0,Ve[s]=Ve[l]=Ve[x]=Ve[u]=Ve[j]=Ve[f]=Ve[h]=Ve[d]=Ve[z]=Ve[v]=Ve[g]=Ve[m]=Ve[y]=Ve[b]=Ve[k]=!1;var Ne={};Ne[s]=Ne[l]=Ne[x]=Ne[j]=Ne[u]=Ne[f]=Ne[M]=Ne[_]=Ne[C]=Ne[q]=Ne[S]=Ne[z]=Ne[v]=Ne[g]=Ne[m]=Ne[y]=Ne[b]=Ne[w]=Ne[T]=Ne["[object Uint8ClampedArray]"]=Ne[O]=Ne[E]=!0,Ne[h]=Ne[d]=Ne[k]=!1;var Ie={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Re=parseFloat,Fe=parseInt,Be="object"==typeof e&&e&&e.Object===Object&&e,Ue="object"==typeof self&&self&&self.Object===Object&&self,We=Be||Ue||Function("return this")(),Ge=t&&!t.nodeType&&t,Ye=Ge&&"object"==typeof r&&r&&!r.nodeType&&r,Ze=Ye&&Ye.exports===Ge,$e=Ze&&Be.process,Xe=function(){try{return Ye&&Ye.require&&Ye.require("util").types||$e&&$e.binding&&$e.binding("util")}catch(e){}}(),Ke=Xe&&Xe.isArrayBuffer,Qe=Xe&&Xe.isDate,Je=Xe&&Xe.isMap,et=Xe&&Xe.isRegExp,tt=Xe&&Xe.isSet,nt=Xe&&Xe.isTypedArray;function rt(e,t,n){switch(n.length){case 0:return e.call(t);case 1:return e.call(t,n[0]);case 2:return e.call(t,n[0],n[1]);case 3:return e.call(t,n[0],n[1],n[2])}return e.apply(t,n)}function it(e,t,n,r){for(var i=-1,o=null==e?0:e.length;++i-1}function ut(e,t,n){for(var r=-1,i=null==e?0:e.length;++r-1;);return n}function Et(e,t){for(var n=e.length;n--&&yt(t,e[n],0)>-1;);return n}function At(e,t){for(var n=e.length,r=0;n--;)e[n]===t&&++r;return r}var Lt=jt({"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss","\u0100":"A","\u0102":"A","\u0104":"A","\u0101":"a","\u0103":"a","\u0105":"a","\u0106":"C","\u0108":"C","\u010a":"C","\u010c":"C","\u0107":"c","\u0109":"c","\u010b":"c","\u010d":"c","\u010e":"D","\u0110":"D","\u010f":"d","\u0111":"d","\u0112":"E","\u0114":"E","\u0116":"E","\u0118":"E","\u011a":"E","\u0113":"e","\u0115":"e","\u0117":"e","\u0119":"e","\u011b":"e","\u011c":"G","\u011e":"G","\u0120":"G","\u0122":"G","\u011d":"g","\u011f":"g","\u0121":"g","\u0123":"g","\u0124":"H","\u0126":"H","\u0125":"h","\u0127":"h","\u0128":"I","\u012a":"I","\u012c":"I","\u012e":"I","\u0130":"I","\u0129":"i","\u012b":"i","\u012d":"i","\u012f":"i","\u0131":"i","\u0134":"J","\u0135":"j","\u0136":"K","\u0137":"k","\u0138":"k","\u0139":"L","\u013b":"L","\u013d":"L","\u013f":"L","\u0141":"L","\u013a":"l","\u013c":"l","\u013e":"l","\u0140":"l","\u0142":"l","\u0143":"N","\u0145":"N","\u0147":"N","\u014a":"N","\u0144":"n","\u0146":"n","\u0148":"n","\u014b":"n","\u014c":"O","\u014e":"O","\u0150":"O","\u014d":"o","\u014f":"o","\u0151":"o","\u0154":"R","\u0156":"R","\u0158":"R","\u0155":"r","\u0157":"r","\u0159":"r","\u015a":"S","\u015c":"S","\u015e":"S","\u0160":"S","\u015b":"s","\u015d":"s","\u015f":"s","\u0161":"s","\u0162":"T","\u0164":"T","\u0166":"T","\u0163":"t","\u0165":"t","\u0167":"t","\u0168":"U","\u016a":"U","\u016c":"U","\u016e":"U","\u0170":"U","\u0172":"U","\u0169":"u","\u016b":"u","\u016d":"u","\u016f":"u","\u0171":"u","\u0173":"u","\u0174":"W","\u0175":"w","\u0176":"Y","\u0177":"y","\u0178":"Y","\u0179":"Z","\u017b":"Z","\u017d":"Z","\u017a":"z","\u017c":"z","\u017e":"z","\u0132":"IJ","\u0133":"ij","\u0152":"Oe","\u0153":"oe","\u0149":"'n","\u017f":"s"}),Ht=jt({"&":"&","<":"<",">":">",'"':""","'":"'"});function Dt(e){return"\\"+Ie[e]}function Pt(e){return Le.test(e)}function Vt(e){var t=-1,n=Array(e.size);return e.forEach((function(e,r){n[++t]=[r,e]})),n}function Nt(e,t){return function(n){return e(t(n))}}function It(e,t){for(var n=-1,r=e.length,i=0,o=[];++n",""":'"',"'":"'"}),Wt=function e(t){var n,r=(t=null==t?We:Wt.defaults(We.Object(),t,Wt.pick(We,De))).Array,i=t.Date,he=t.Error,de=t.Function,pe=t.Math,ze=t.Object,ve=t.RegExp,ge=t.String,me=t.TypeError,ye=r.prototype,be=de.prototype,we=ze.prototype,ke=t["__core-js_shared__"],xe=be.toString,je=we.hasOwnProperty,Me=0,_e=(n=/[^.]+$/.exec(ke&&ke.keys&&ke.keys.IE_PROTO||""))?"Symbol(src)_1."+n:"",Ce=we.toString,qe=xe.call(ze),Se=We._,Ee=ve("^"+xe.call(je).replace(G,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),Le=Ze?t.Buffer:void 0,Ie=t.Symbol,Be=t.Uint8Array,Ue=Le?Le.allocUnsafe:void 0,Ge=Nt(ze.getPrototypeOf,ze),Ye=ze.create,$e=we.propertyIsEnumerable,Xe=ye.splice,vt=Ie?Ie.isConcatSpreadable:void 0,jt=Ie?Ie.iterator:void 0,Gt=Ie?Ie.toStringTag:void 0,Yt=function(){try{var e=Ki(ze,"defineProperty");return e({},"",{}),e}catch(e){}}(),Zt=t.clearTimeout!==We.clearTimeout&&t.clearTimeout,$t=i&&i.now!==We.Date.now&&i.now,Xt=t.setTimeout!==We.setTimeout&&t.setTimeout,Kt=pe.ceil,Qt=pe.floor,Jt=ze.getOwnPropertySymbols,en=Le?Le.isBuffer:void 0,tn=t.isFinite,nn=ye.join,rn=Nt(ze.keys,ze),on=pe.max,an=pe.min,cn=i.now,sn=t.parseInt,ln=pe.random,un=ye.reverse,fn=Ki(t,"DataView"),hn=Ki(t,"Map"),dn=Ki(t,"Promise"),pn=Ki(t,"Set"),zn=Ki(t,"WeakMap"),vn=Ki(ze,"create"),gn=zn&&new zn,mn={},yn=Mo(fn),bn=Mo(hn),wn=Mo(dn),kn=Mo(pn),xn=Mo(zn),jn=Ie?Ie.prototype:void 0,Mn=jn?jn.valueOf:void 0,_n=jn?jn.toString:void 0;function Cn(e){if(Fa(e)&&!Oa(e)&&!(e instanceof On)){if(e instanceof Tn)return e;if(je.call(e,"__wrapped__"))return _o(e)}return new Tn(e)}var qn=function(){function e(){}return function(t){if(!Ra(t))return{};if(Ye)return Ye(t);e.prototype=t;var n=new e;return e.prototype=void 0,n}}();function Sn(){}function Tn(e,t){this.__wrapped__=e,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=void 0}function On(e){this.__wrapped__=e,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}function En(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t=t?e:t)),e}function $n(e,t,n,r,i,o){var a,c=1&t,l=2&t,h=4&t;if(n&&(a=i?n(e,r,i,o):n(e)),void 0!==a)return a;if(!Ra(e))return e;var k=Oa(e);if(k){if(a=function(e){var t=e.length,n=new e.constructor(t);return t&&"string"==typeof e[0]&&je.call(e,"index")&&(n.index=e.index,n.input=e.input),n}(e),!c)return zi(e,a)}else{var A=eo(e),L=A==d||A==p;if(Ha(e))return li(e,c);if(A==g||A==s||L&&!i){if(a=l||L?{}:no(e),!c)return l?function(e,t){return vi(e,Ji(e),t)}(e,function(e,t){return e&&vi(t,yc(t),e)}(a,e)):function(e,t){return vi(e,Qi(e),t)}(e,Wn(a,e))}else{if(!Ne[A])return i?e:{};a=function(e,t,n){var r,i=e.constructor;switch(t){case x:return ui(e);case u:case f:return new i(+e);case j:return function(e,t){var n=t?ui(e.buffer):e.buffer;return new e.constructor(n,e.byteOffset,e.byteLength)}(e,n);case M:case _:case C:case q:case S:case T:case"[object Uint8ClampedArray]":case O:case E:return fi(e,n);case z:return new i;case v:case b:return new i(e);case m:return function(e){var t=new e.constructor(e.source,re.exec(e));return t.lastIndex=e.lastIndex,t}(e);case y:return new i;case w:return r=e,Mn?ze(Mn.call(r)):{}}}(e,A,c)}}o||(o=new Dn);var H=o.get(e);if(H)return H;o.set(e,a),Ya(e)?e.forEach((function(r){a.add($n(r,t,n,r,e,o))})):Ba(e)&&e.forEach((function(r,i){a.set(i,$n(r,t,n,i,e,o))}));var D=k?void 0:(h?l?Ui:Bi:l?yc:mc)(e);return ot(D||e,(function(r,i){D&&(r=e[i=r]),Fn(a,i,$n(r,t,n,i,e,o))})),a}function Xn(e,t,n){var r=n.length;if(null==e)return!r;for(e=ze(e);r--;){var i=n[r],o=t[i],a=e[i];if(void 0===a&&!(i in e)||!o(a))return!1}return!0}function Kn(e,t,n){if("function"!=typeof e)throw new me(o);return mo((function(){e.apply(void 0,n)}),t)}function Qn(e,t,n,r){var i=-1,o=lt,a=!0,c=e.length,s=[],l=t.length;if(!c)return s;n&&(t=ft(t,qt(n))),r?(o=ut,a=!1):t.length>=200&&(o=Tt,a=!1,t=new Hn(t));e:for(;++i-1},An.prototype.set=function(e,t){var n=this.__data__,r=Bn(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this},Ln.prototype.clear=function(){this.size=0,this.__data__={hash:new En,map:new(hn||An),string:new En}},Ln.prototype.delete=function(e){var t=$i(this,e).delete(e);return this.size-=t?1:0,t},Ln.prototype.get=function(e){return $i(this,e).get(e)},Ln.prototype.has=function(e){return $i(this,e).has(e)},Ln.prototype.set=function(e,t){var n=$i(this,e),r=n.size;return n.set(e,t),this.size+=n.size==r?0:1,this},Hn.prototype.add=Hn.prototype.push=function(e){return this.__data__.set(e,"__lodash_hash_undefined__"),this},Hn.prototype.has=function(e){return this.__data__.has(e)},Dn.prototype.clear=function(){this.__data__=new An,this.size=0},Dn.prototype.delete=function(e){var t=this.__data__,n=t.delete(e);return this.size=t.size,n},Dn.prototype.get=function(e){return this.__data__.get(e)},Dn.prototype.has=function(e){return this.__data__.has(e)},Dn.prototype.set=function(e,t){var n=this.__data__;if(n instanceof An){var r=n.__data__;if(!hn||r.length<199)return r.push([e,t]),this.size=++n.size,this;n=this.__data__=new Ln(r)}return n.set(e,t),this.size=n.size,this};var Jn=yi(cr),er=yi(sr,!0);function tr(e,t){var n=!0;return Jn(e,(function(e,r,i){return n=!!t(e,r,i)})),n}function nr(e,t,n){for(var r=-1,i=e.length;++r0&&n(c)?t>1?ir(c,t-1,n,r,i):ht(i,c):r||(i[i.length]=c)}return i}var or=bi(),ar=bi(!0);function cr(e,t){return e&&or(e,t,mc)}function sr(e,t){return e&&ar(e,t,mc)}function lr(e,t){return st(t,(function(t){return Va(e[t])}))}function ur(e,t){for(var n=0,r=(t=oi(t,e)).length;null!=e&&nt}function pr(e,t){return null!=e&&je.call(e,t)}function zr(e,t){return null!=e&&t in ze(e)}function vr(e,t,n){for(var i=n?ut:lt,o=e[0].length,a=e.length,c=a,s=r(a),l=1/0,u=[];c--;){var f=e[c];c&&t&&(f=ft(f,qt(t))),l=an(f.length,l),s[c]=!n&&(t||o>=120&&f.length>=120)?new Hn(c&&f):void 0}f=e[0];var h=-1,d=s[0];e:for(;++h=c?s:s*("desc"==n[r]?-1:1)}return e.index-t.index}(e,t,n)}))}function Or(e,t,n){for(var r=-1,i=t.length,o={};++r-1;)c!==e&&Xe.call(c,s,1),Xe.call(e,s,1);return e}function Ar(e,t){for(var n=e?t.length:0,r=n-1;n--;){var i=t[n];if(n==r||i!==o){var o=i;io(i)?Xe.call(e,i,1):Kr(e,i)}}return e}function Lr(e,t){return e+Qt(ln()*(t-e+1))}function Hr(e,t){var n="";if(!e||t<1||t>9007199254740991)return n;do{t%2&&(n+=e),(t=Qt(t/2))&&(e+=e)}while(t);return n}function Dr(e,t){return yo(ho(e,t,Uc),e+"")}function Pr(e){return Vn(Cc(e))}function Vr(e,t){var n=Cc(e);return ko(n,Zn(t,0,n.length))}function Nr(e,t,n,r){if(!Ra(e))return e;for(var i=-1,o=(t=oi(t,e)).length,a=o-1,c=e;null!=c&&++io?0:o+t),(n=n>o?o:n)<0&&(n+=o),o=t>n?0:n-t>>>0,t>>>=0;for(var a=r(o);++i>>1,a=e[o];null!==a&&!$a(a)&&(n?a<=t:a=200){var l=t?null:Hi(e);if(l)return Rt(l);a=!1,i=Tt,s=new Hn}else s=t?[]:c;e:for(;++r=r?e:Br(e,t,n)}var si=Zt||function(e){return We.clearTimeout(e)};function li(e,t){if(t)return e.slice();var n=e.length,r=Ue?Ue(n):new e.constructor(n);return e.copy(r),r}function ui(e){var t=new e.constructor(e.byteLength);return new Be(t).set(new Be(e)),t}function fi(e,t){var n=t?ui(e.buffer):e.buffer;return new e.constructor(n,e.byteOffset,e.length)}function hi(e,t){if(e!==t){var n=void 0!==e,r=null===e,i=e==e,o=$a(e),a=void 0!==t,c=null===t,s=t==t,l=$a(t);if(!c&&!l&&!o&&e>t||o&&a&&s&&!c&&!l||r&&a&&s||!n&&s||!i)return 1;if(!r&&!o&&!l&&e1?n[i-1]:void 0,a=i>2?n[2]:void 0;for(o=e.length>3&&"function"==typeof o?(i--,o):void 0,a&&oo(n[0],n[1],a)&&(o=i<3?void 0:o,i=1),t=ze(t);++r-1?i[o?t[a]:a]:void 0}}function Mi(e){return Fi((function(t){var n=t.length,r=n,i=Tn.prototype.thru;for(e&&t.reverse();r--;){var a=t[r];if("function"!=typeof a)throw new me(o);if(i&&!c&&"wrapper"==Gi(a))var c=new Tn([],!0)}for(r=c?r:n;++r1&&y.reverse(),f&&lc))return!1;var l=o.get(e),u=o.get(t);if(l&&u)return l==t&&u==e;var f=-1,h=!0,d=2&n?new Hn:void 0;for(o.set(e,t),o.set(t,e);++f-1&&e%1==0&&e1?"& ":"")+t[r],t=t.join(n>2?", ":" "),e.replace(K,"{\n/* [wrapped with "+t+"] */\n")}(r,function(e,t){return ot(c,(function(n){var r="_."+n[0];t&n[1]&&!lt(e,r)&&e.push(r)})),e.sort()}(function(e){var t=e.match(Q);return t?t[1].split(J):[]}(r),n)))}function wo(e){var t=0,n=0;return function(){var r=cn(),i=16-(r-n);if(n=r,i>0){if(++t>=800)return arguments[0]}else t=0;return e.apply(void 0,arguments)}}function ko(e,t){var n=-1,r=e.length,i=r-1;for(t=void 0===t?r:t;++n1?e[t-1]:void 0;return n="function"==typeof n?(e.pop(),n):void 0,Go(e,n)}));function Jo(e){var t=Cn(e);return t.__chain__=!0,t}function ea(e,t){return t(e)}var ta=Fi((function(e){var t=e.length,n=t?e[0]:0,r=this.__wrapped__,i=function(t){return Yn(t,e)};return!(t>1||this.__actions__.length)&&r instanceof On&&io(n)?((r=r.slice(n,+n+(t?1:0))).__actions__.push({func:ea,args:[i],thisArg:void 0}),new Tn(r,this.__chain__).thru((function(e){return t&&!e.length&&e.push(void 0),e}))):this.thru(i)})),na=gi((function(e,t,n){je.call(e,n)?++e[n]:Gn(e,n,1)})),ra=ji(To),ia=ji(Oo);function oa(e,t){return(Oa(e)?ot:Jn)(e,Zi(t,3))}function aa(e,t){return(Oa(e)?at:er)(e,Zi(t,3))}var ca=gi((function(e,t,n){je.call(e,n)?e[n].push(t):Gn(e,n,[t])})),sa=Dr((function(e,t,n){var i=-1,o="function"==typeof t,a=Aa(e)?r(e.length):[];return Jn(e,(function(e){a[++i]=o?rt(t,e,n):gr(e,t,n)})),a})),la=gi((function(e,t,n){Gn(e,n,t)}));function ua(e,t){return(Oa(e)?ft:Mr)(e,Zi(t,3))}var fa=gi((function(e,t,n){e[n?0:1].push(t)}),(function(){return[[],[]]})),ha=Dr((function(e,t){if(null==e)return[];var n=t.length;return n>1&&oo(e,t[0],t[1])?t=[]:n>2&&oo(t[0],t[1],t[2])&&(t=[t[0]]),Tr(e,ir(t,1),[])})),da=$t||function(){return We.Date.now()};function pa(e,t,n){return t=n?void 0:t,Pi(e,128,void 0,void 0,void 0,void 0,t=e&&null==t?e.length:t)}function za(e,t){var n;if("function"!=typeof t)throw new me(o);return e=tc(e),function(){return--e>0&&(n=t.apply(this,arguments)),e<=1&&(t=void 0),n}}var va=Dr((function(e,t,n){var r=1;if(n.length){var i=It(n,Yi(va));r|=32}return Pi(e,r,t,n,i)})),ga=Dr((function(e,t,n){var r=3;if(n.length){var i=It(n,Yi(ga));r|=32}return Pi(t,r,e,n,i)}));function ma(e,t,n){var r,i,a,c,s,l,u=0,f=!1,h=!1,d=!0;if("function"!=typeof e)throw new me(o);function p(t){var n=r,o=i;return r=i=void 0,u=t,c=e.apply(o,n)}function z(e){var n=e-l;return void 0===l||n>=t||n<0||h&&e-u>=a}function v(){var e=da();if(z(e))return g(e);s=mo(v,function(e){var n=t-(e-l);return h?an(n,a-(e-u)):n}(e))}function g(e){return s=void 0,d&&r?p(e):(r=i=void 0,c)}function m(){var e=da(),n=z(e);if(r=arguments,i=this,l=e,n){if(void 0===s)return function(e){return u=e,s=mo(v,t),f?p(e):c}(l);if(h)return si(s),s=mo(v,t),p(l)}return void 0===s&&(s=mo(v,t)),c}return t=rc(t)||0,Ra(n)&&(f=!!n.leading,a=(h="maxWait"in n)?on(rc(n.maxWait)||0,t):a,d="trailing"in n?!!n.trailing:d),m.cancel=function(){void 0!==s&&si(s),u=0,r=l=i=s=void 0},m.flush=function(){return void 0===s?c:g(da())},m}var ya=Dr((function(e,t){return Kn(e,1,t)})),ba=Dr((function(e,t,n){return Kn(e,rc(t)||0,n)}));function wa(e,t){if("function"!=typeof e||null!=t&&"function"!=typeof t)throw new me(o);var n=function n(){var r=arguments,i=t?t.apply(this,r):r[0],o=n.cache;if(o.has(i))return o.get(i);var a=e.apply(this,r);return n.cache=o.set(i,a)||o,a};return n.cache=new(wa.Cache||Ln),n}function ka(e){if("function"!=typeof e)throw new me(o);return function(){var t=arguments;switch(t.length){case 0:return!e.call(this);case 1:return!e.call(this,t[0]);case 2:return!e.call(this,t[0],t[1]);case 3:return!e.call(this,t[0],t[1],t[2])}return!e.apply(this,t)}}wa.Cache=Ln;var xa=ai((function(e,t){var n=(t=1==t.length&&Oa(t[0])?ft(t[0],qt(Zi())):ft(ir(t,1),qt(Zi()))).length;return Dr((function(r){for(var i=-1,o=an(r.length,n);++i=t})),Ta=mr(function(){return arguments}())?mr:function(e){return Fa(e)&&je.call(e,"callee")&&!$e.call(e,"callee")},Oa=r.isArray,Ea=Ke?qt(Ke):function(e){return Fa(e)&&hr(e)==x};function Aa(e){return null!=e&&Ia(e.length)&&!Va(e)}function La(e){return Fa(e)&&Aa(e)}var Ha=en||rs,Da=Qe?qt(Qe):function(e){return Fa(e)&&hr(e)==f};function Pa(e){if(!Fa(e))return!1;var t=hr(e);return t==h||"[object DOMException]"==t||"string"==typeof e.message&&"string"==typeof e.name&&!Wa(e)}function Va(e){if(!Ra(e))return!1;var t=hr(e);return t==d||t==p||"[object AsyncFunction]"==t||"[object Proxy]"==t}function Na(e){return"number"==typeof e&&e==tc(e)}function Ia(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=9007199254740991}function Ra(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}function Fa(e){return null!=e&&"object"==typeof e}var Ba=Je?qt(Je):function(e){return Fa(e)&&eo(e)==z};function Ua(e){return"number"==typeof e||Fa(e)&&hr(e)==v}function Wa(e){if(!Fa(e)||hr(e)!=g)return!1;var t=Ge(e);if(null===t)return!0;var n=je.call(t,"constructor")&&t.constructor;return"function"==typeof n&&n instanceof n&&xe.call(n)==qe}var Ga=et?qt(et):function(e){return Fa(e)&&hr(e)==m},Ya=tt?qt(tt):function(e){return Fa(e)&&eo(e)==y};function Za(e){return"string"==typeof e||!Oa(e)&&Fa(e)&&hr(e)==b}function $a(e){return"symbol"==typeof e||Fa(e)&&hr(e)==w}var Xa=nt?qt(nt):function(e){return Fa(e)&&Ia(e.length)&&!!Ve[hr(e)]},Ka=Ei(jr),Qa=Ei((function(e,t){return e<=t}));function Ja(e){if(!e)return[];if(Aa(e))return Za(e)?Bt(e):zi(e);if(jt&&e[jt])return function(e){for(var t,n=[];!(t=e.next()).done;)n.push(t.value);return n}(e[jt]());var t=eo(e);return(t==z?Vt:t==y?Rt:Cc)(e)}function ec(e){return e?(e=rc(e))===1/0||e===-1/0?17976931348623157e292*(e<0?-1:1):e==e?e:0:0===e?e:0}function tc(e){var t=ec(e),n=t%1;return t==t?n?t-n:t:0}function nc(e){return e?Zn(tc(e),0,4294967295):0}function rc(e){if("number"==typeof e)return e;if($a(e))return NaN;if(Ra(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=Ra(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(Z,"");var n=oe.test(e);return n||ce.test(e)?Fe(e.slice(2),n?2:8):ie.test(e)?NaN:+e}function ic(e){return vi(e,yc(e))}function oc(e){return null==e?"":$r(e)}var ac=mi((function(e,t){if(lo(t)||Aa(t))vi(t,mc(t),e);else for(var n in t)je.call(t,n)&&Fn(e,n,t[n])})),cc=mi((function(e,t){vi(t,yc(t),e)})),sc=mi((function(e,t,n,r){vi(t,yc(t),e,r)})),lc=mi((function(e,t,n,r){vi(t,mc(t),e,r)})),uc=Fi(Yn),fc=Dr((function(e,t){e=ze(e);var n=-1,r=t.length,i=r>2?t[2]:void 0;for(i&&oo(t[0],t[1],i)&&(r=1);++n1),t})),vi(e,Ui(e),n),r&&(n=$n(n,7,Ii));for(var i=t.length;i--;)Kr(n,t[i]);return n})),xc=Fi((function(e,t){return null==e?{}:function(e,t){return Or(e,t,(function(t,n){return pc(e,n)}))}(e,t)}));function jc(e,t){if(null==e)return{};var n=ft(Ui(e),(function(e){return[e]}));return t=Zi(t),Or(e,n,(function(e,n){return t(e,n[0])}))}var Mc=Di(mc),_c=Di(yc);function Cc(e){return null==e?[]:St(e,mc(e))}var qc=ki((function(e,t,n){return t=t.toLowerCase(),e+(n?Sc(t):t)}));function Sc(e){return Pc(oc(e).toLowerCase())}function Tc(e){return(e=oc(e))&&e.replace(le,Lt).replace(Oe,"")}var Oc=ki((function(e,t,n){return e+(n?"-":"")+t.toLowerCase()})),Ec=ki((function(e,t,n){return e+(n?" ":"")+t.toLowerCase()})),Ac=wi("toLowerCase"),Lc=ki((function(e,t,n){return e+(n?"_":"")+t.toLowerCase()})),Hc=ki((function(e,t,n){return e+(n?" ":"")+Pc(t)})),Dc=ki((function(e,t,n){return e+(n?" ":"")+t.toUpperCase()})),Pc=wi("toUpperCase");function Vc(e,t,n){return e=oc(e),void 0===(t=n?void 0:t)?function(e){return He.test(e)}(e)?function(e){return e.match(Ae)||[]}(e):function(e){return e.match(ee)||[]}(e):e.match(t)||[]}var Nc=Dr((function(e,t){try{return rt(e,void 0,t)}catch(e){return Pa(e)?e:new he(e)}})),Ic=Fi((function(e,t){return ot(t,(function(t){t=jo(t),Gn(e,t,va(e[t],e))})),e}));function Rc(e){return function(){return e}}var Fc=Mi(),Bc=Mi(!0);function Uc(e){return e}function Wc(e){return kr("function"==typeof e?e:$n(e,1))}var Gc=Dr((function(e,t){return function(n){return gr(n,e,t)}})),Yc=Dr((function(e,t){return function(n){return gr(e,n,t)}}));function Zc(e,t,n){var r=mc(t),i=lr(t,r);null!=n||Ra(t)&&(i.length||!r.length)||(n=t,t=e,e=this,i=lr(t,mc(t)));var o=!(Ra(n)&&"chain"in n&&!n.chain),a=Va(e);return ot(i,(function(n){var r=t[n];e[n]=r,a&&(e.prototype[n]=function(){var t=this.__chain__;if(o||t){var n=e(this.__wrapped__),i=n.__actions__=zi(this.__actions__);return i.push({func:r,args:arguments,thisArg:e}),n.__chain__=t,n}return r.apply(e,ht([this.value()],arguments))})})),e}function $c(){}var Xc=Si(ft),Kc=Si(ct),Qc=Si(zt);function Jc(e){return ao(e)?xt(jo(e)):function(e){return function(t){return ur(t,e)}}(e)}var es=Oi(),ts=Oi(!0);function ns(){return[]}function rs(){return!1}var is,os=qi((function(e,t){return e+t}),0),as=Li("ceil"),cs=qi((function(e,t){return e/t}),1),ss=Li("floor"),ls=qi((function(e,t){return e*t}),1),us=Li("round"),fs=qi((function(e,t){return e-t}),0);return Cn.after=function(e,t){if("function"!=typeof t)throw new me(o);return e=tc(e),function(){if(--e<1)return t.apply(this,arguments)}},Cn.ary=pa,Cn.assign=ac,Cn.assignIn=cc,Cn.assignInWith=sc,Cn.assignWith=lc,Cn.at=uc,Cn.before=za,Cn.bind=va,Cn.bindAll=Ic,Cn.bindKey=ga,Cn.castArray=function(){if(!arguments.length)return[];var e=arguments[0];return Oa(e)?e:[e]},Cn.chain=Jo,Cn.chunk=function(e,t,n){t=(n?oo(e,t,n):void 0===t)?1:on(tc(t),0);var i=null==e?0:e.length;if(!i||t<1)return[];for(var o=0,a=0,c=r(Kt(i/t));oi?0:i+n),(r=void 0===r||r>i?i:tc(r))<0&&(r+=i),r=n>r?0:nc(r);n>>0)?(e=oc(e))&&("string"==typeof t||null!=t&&!Ga(t))&&!(t=$r(t))&&Pt(e)?ci(Bt(e),0,n):e.split(t,n):[]},Cn.spread=function(e,t){if("function"!=typeof e)throw new me(o);return t=null==t?0:on(tc(t),0),Dr((function(n){var r=n[t],i=ci(n,0,t);return r&&ht(i,r),rt(e,this,i)}))},Cn.tail=function(e){var t=null==e?0:e.length;return t?Br(e,1,t):[]},Cn.take=function(e,t,n){return e&&e.length?Br(e,0,(t=n||void 0===t?1:tc(t))<0?0:t):[]},Cn.takeRight=function(e,t,n){var r=null==e?0:e.length;return r?Br(e,(t=r-(t=n||void 0===t?1:tc(t)))<0?0:t,r):[]},Cn.takeRightWhile=function(e,t){return e&&e.length?Jr(e,Zi(t,3),!1,!0):[]},Cn.takeWhile=function(e,t){return e&&e.length?Jr(e,Zi(t,3)):[]},Cn.tap=function(e,t){return t(e),e},Cn.throttle=function(e,t,n){var r=!0,i=!0;if("function"!=typeof e)throw new me(o);return Ra(n)&&(r="leading"in n?!!n.leading:r,i="trailing"in n?!!n.trailing:i),ma(e,t,{leading:r,maxWait:t,trailing:i})},Cn.thru=ea,Cn.toArray=Ja,Cn.toPairs=Mc,Cn.toPairsIn=_c,Cn.toPath=function(e){return Oa(e)?ft(e,jo):$a(e)?[e]:zi(xo(oc(e)))},Cn.toPlainObject=ic,Cn.transform=function(e,t,n){var r=Oa(e),i=r||Ha(e)||Xa(e);if(t=Zi(t,4),null==n){var o=e&&e.constructor;n=i?r?new o:[]:Ra(e)&&Va(o)?qn(Ge(e)):{}}return(i?ot:cr)(e,(function(e,r,i){return t(n,e,r,i)})),n},Cn.unary=function(e){return pa(e,1)},Cn.union=Fo,Cn.unionBy=Bo,Cn.unionWith=Uo,Cn.uniq=function(e){return e&&e.length?Xr(e):[]},Cn.uniqBy=function(e,t){return e&&e.length?Xr(e,Zi(t,2)):[]},Cn.uniqWith=function(e,t){return t="function"==typeof t?t:void 0,e&&e.length?Xr(e,void 0,t):[]},Cn.unset=function(e,t){return null==e||Kr(e,t)},Cn.unzip=Wo,Cn.unzipWith=Go,Cn.update=function(e,t,n){return null==e?e:Qr(e,t,ii(n))},Cn.updateWith=function(e,t,n,r){return r="function"==typeof r?r:void 0,null==e?e:Qr(e,t,ii(n),r)},Cn.values=Cc,Cn.valuesIn=function(e){return null==e?[]:St(e,yc(e))},Cn.without=Yo,Cn.words=Vc,Cn.wrap=function(e,t){return ja(ii(t),e)},Cn.xor=Zo,Cn.xorBy=$o,Cn.xorWith=Xo,Cn.zip=Ko,Cn.zipObject=function(e,t){return ni(e||[],t||[],Fn)},Cn.zipObjectDeep=function(e,t){return ni(e||[],t||[],Nr)},Cn.zipWith=Qo,Cn.entries=Mc,Cn.entriesIn=_c,Cn.extend=cc,Cn.extendWith=sc,Zc(Cn,Cn),Cn.add=os,Cn.attempt=Nc,Cn.camelCase=qc,Cn.capitalize=Sc,Cn.ceil=as,Cn.clamp=function(e,t,n){return void 0===n&&(n=t,t=void 0),void 0!==n&&(n=(n=rc(n))==n?n:0),void 0!==t&&(t=(t=rc(t))==t?t:0),Zn(rc(e),t,n)},Cn.clone=function(e){return $n(e,4)},Cn.cloneDeep=function(e){return $n(e,5)},Cn.cloneDeepWith=function(e,t){return $n(e,5,t="function"==typeof t?t:void 0)},Cn.cloneWith=function(e,t){return $n(e,4,t="function"==typeof t?t:void 0)},Cn.conformsTo=function(e,t){return null==t||Xn(e,t,mc(t))},Cn.deburr=Tc,Cn.defaultTo=function(e,t){return null==e||e!=e?t:e},Cn.divide=cs,Cn.endsWith=function(e,t,n){e=oc(e),t=$r(t);var r=e.length,i=n=void 0===n?r:Zn(tc(n),0,r);return(n-=t.length)>=0&&e.slice(n,i)==t},Cn.eq=Ca,Cn.escape=function(e){return(e=oc(e))&&N.test(e)?e.replace(P,Ht):e},Cn.escapeRegExp=function(e){return(e=oc(e))&&Y.test(e)?e.replace(G,"\\$&"):e},Cn.every=function(e,t,n){var r=Oa(e)?ct:tr;return n&&oo(e,t,n)&&(t=void 0),r(e,Zi(t,3))},Cn.find=ra,Cn.findIndex=To,Cn.findKey=function(e,t){return gt(e,Zi(t,3),cr)},Cn.findLast=ia,Cn.findLastIndex=Oo,Cn.findLastKey=function(e,t){return gt(e,Zi(t,3),sr)},Cn.floor=ss,Cn.forEach=oa,Cn.forEachRight=aa,Cn.forIn=function(e,t){return null==e?e:or(e,Zi(t,3),yc)},Cn.forInRight=function(e,t){return null==e?e:ar(e,Zi(t,3),yc)},Cn.forOwn=function(e,t){return e&&cr(e,Zi(t,3))},Cn.forOwnRight=function(e,t){return e&&sr(e,Zi(t,3))},Cn.get=dc,Cn.gt=qa,Cn.gte=Sa,Cn.has=function(e,t){return null!=e&&to(e,t,pr)},Cn.hasIn=pc,Cn.head=Ao,Cn.identity=Uc,Cn.includes=function(e,t,n,r){e=Aa(e)?e:Cc(e),n=n&&!r?tc(n):0;var i=e.length;return n<0&&(n=on(i+n,0)),Za(e)?n<=i&&e.indexOf(t,n)>-1:!!i&&yt(e,t,n)>-1},Cn.indexOf=function(e,t,n){var r=null==e?0:e.length;if(!r)return-1;var i=null==n?0:tc(n);return i<0&&(i=on(r+i,0)),yt(e,t,i)},Cn.inRange=function(e,t,n){return t=ec(t),void 0===n?(n=t,t=0):n=ec(n),function(e,t,n){return e>=an(t,n)&&e=-9007199254740991&&e<=9007199254740991},Cn.isSet=Ya,Cn.isString=Za,Cn.isSymbol=$a,Cn.isTypedArray=Xa,Cn.isUndefined=function(e){return void 0===e},Cn.isWeakMap=function(e){return Fa(e)&&eo(e)==k},Cn.isWeakSet=function(e){return Fa(e)&&"[object WeakSet]"==hr(e)},Cn.join=function(e,t){return null==e?"":nn.call(e,t)},Cn.kebabCase=Oc,Cn.last=Po,Cn.lastIndexOf=function(e,t,n){var r=null==e?0:e.length;if(!r)return-1;var i=r;return void 0!==n&&(i=(i=tc(n))<0?on(r+i,0):an(i,r-1)),t==t?function(e,t,n){for(var r=n+1;r--;)if(e[r]===t)return r;return r}(e,t,i):mt(e,wt,i,!0)},Cn.lowerCase=Ec,Cn.lowerFirst=Ac,Cn.lt=Ka,Cn.lte=Qa,Cn.max=function(e){return e&&e.length?nr(e,Uc,dr):void 0},Cn.maxBy=function(e,t){return e&&e.length?nr(e,Zi(t,2),dr):void 0},Cn.mean=function(e){return kt(e,Uc)},Cn.meanBy=function(e,t){return kt(e,Zi(t,2))},Cn.min=function(e){return e&&e.length?nr(e,Uc,jr):void 0},Cn.minBy=function(e,t){return e&&e.length?nr(e,Zi(t,2),jr):void 0},Cn.stubArray=ns,Cn.stubFalse=rs,Cn.stubObject=function(){return{}},Cn.stubString=function(){return""},Cn.stubTrue=function(){return!0},Cn.multiply=ls,Cn.nth=function(e,t){return e&&e.length?Sr(e,tc(t)):void 0},Cn.noConflict=function(){return We._===this&&(We._=Se),this},Cn.noop=$c,Cn.now=da,Cn.pad=function(e,t,n){e=oc(e);var r=(t=tc(t))?Ft(e):0;if(!t||r>=t)return e;var i=(t-r)/2;return Ti(Qt(i),n)+e+Ti(Kt(i),n)},Cn.padEnd=function(e,t,n){e=oc(e);var r=(t=tc(t))?Ft(e):0;return t&&rt){var r=e;e=t,t=r}if(n||e%1||t%1){var i=ln();return an(e+i*(t-e+Re("1e-"+((i+"").length-1))),t)}return Lr(e,t)},Cn.reduce=function(e,t,n){var r=Oa(e)?dt:Mt,i=arguments.length<3;return r(e,Zi(t,4),n,i,Jn)},Cn.reduceRight=function(e,t,n){var r=Oa(e)?pt:Mt,i=arguments.length<3;return r(e,Zi(t,4),n,i,er)},Cn.repeat=function(e,t,n){return t=(n?oo(e,t,n):void 0===t)?1:tc(t),Hr(oc(e),t)},Cn.replace=function(){var e=arguments,t=oc(e[0]);return e.length<3?t:t.replace(e[1],e[2])},Cn.result=function(e,t,n){var r=-1,i=(t=oi(t,e)).length;for(i||(i=1,e=void 0);++r9007199254740991)return[];var n=4294967295,r=an(e,4294967295);e-=4294967295;for(var i=Ct(r,t=Zi(t));++n=o)return e;var c=n-Ft(r);if(c<1)return r;var s=a?ci(a,0,c).join(""):e.slice(0,c);if(void 0===i)return s+r;if(a&&(c+=s.length-c),Ga(i)){if(e.slice(c).search(i)){var l,u=s;for(i.global||(i=ve(i.source,oc(re.exec(i))+"g")),i.lastIndex=0;l=i.exec(u);)var f=l.index;s=s.slice(0,void 0===f?c:f)}}else if(e.indexOf($r(i),c)!=c){var h=s.lastIndexOf(i);h>-1&&(s=s.slice(0,h))}return s+r},Cn.unescape=function(e){return(e=oc(e))&&V.test(e)?e.replace(D,Ut):e},Cn.uniqueId=function(e){var t=++Me;return oc(e)+t},Cn.upperCase=Dc,Cn.upperFirst=Pc,Cn.each=oa,Cn.eachRight=aa,Cn.first=Ao,Zc(Cn,(is={},cr(Cn,(function(e,t){je.call(Cn.prototype,t)||(is[t]=e)})),is),{chain:!1}),Cn.VERSION="4.17.20",ot(["bind","bindKey","curry","curryRight","partial","partialRight"],(function(e){Cn[e].placeholder=Cn})),ot(["drop","take"],(function(e,t){On.prototype[e]=function(n){n=void 0===n?1:on(tc(n),0);var r=this.__filtered__&&!t?new On(this):this.clone();return r.__filtered__?r.__takeCount__=an(n,r.__takeCount__):r.__views__.push({size:an(n,4294967295),type:e+(r.__dir__<0?"Right":"")}),r},On.prototype[e+"Right"]=function(t){return this.reverse()[e](t).reverse()}})),ot(["filter","map","takeWhile"],(function(e,t){var n=t+1,r=1==n||3==n;On.prototype[e]=function(e){var t=this.clone();return t.__iteratees__.push({iteratee:Zi(e,3),type:n}),t.__filtered__=t.__filtered__||r,t}})),ot(["head","last"],(function(e,t){var n="take"+(t?"Right":"");On.prototype[e]=function(){return this[n](1).value()[0]}})),ot(["initial","tail"],(function(e,t){var n="drop"+(t?"":"Right");On.prototype[e]=function(){return this.__filtered__?new On(this):this[n](1)}})),On.prototype.compact=function(){return this.filter(Uc)},On.prototype.find=function(e){return this.filter(e).head()},On.prototype.findLast=function(e){return this.reverse().find(e)},On.prototype.invokeMap=Dr((function(e,t){return"function"==typeof e?new On(this):this.map((function(n){return gr(n,e,t)}))})),On.prototype.reject=function(e){return this.filter(ka(Zi(e)))},On.prototype.slice=function(e,t){e=tc(e);var n=this;return n.__filtered__&&(e>0||t<0)?new On(n):(e<0?n=n.takeRight(-e):e&&(n=n.drop(e)),void 0!==t&&(n=(t=tc(t))<0?n.dropRight(-t):n.take(t-e)),n)},On.prototype.takeRightWhile=function(e){return this.reverse().takeWhile(e).reverse()},On.prototype.toArray=function(){return this.take(4294967295)},cr(On.prototype,(function(e,t){var n=/^(?:filter|find|map|reject)|While$/.test(t),r=/^(?:head|last)$/.test(t),i=Cn[r?"take"+("last"==t?"Right":""):t],o=r||/^find/.test(t);i&&(Cn.prototype[t]=function(){var t=this.__wrapped__,a=r?[1]:arguments,c=t instanceof On,s=a[0],l=c||Oa(t),u=function(e){var t=i.apply(Cn,ht([e],a));return r&&f?t[0]:t};l&&n&&"function"==typeof s&&1!=s.length&&(c=l=!1);var f=this.__chain__,h=!!this.__actions__.length,d=o&&!f,p=c&&!h;if(!o&&l){t=p?t:new On(this);var z=e.apply(t,a);return z.__actions__.push({func:ea,args:[u],thisArg:void 0}),new Tn(z,f)}return d&&p?e.apply(this,a):(z=this.thru(u),d?r?z.value()[0]:z.value():z)})})),ot(["pop","push","shift","sort","splice","unshift"],(function(e){var t=ye[e],n=/^(?:push|sort|unshift)$/.test(e)?"tap":"thru",r=/^(?:pop|shift)$/.test(e);Cn.prototype[e]=function(){var e=arguments;if(r&&!this.__chain__){var i=this.value();return t.apply(Oa(i)?i:[],e)}return this[n]((function(n){return t.apply(Oa(n)?n:[],e)}))}})),cr(On.prototype,(function(e,t){var n=Cn[t];if(n){var r=n.name+"";je.call(mn,r)||(mn[r]=[]),mn[r].push({name:t,func:n})}})),mn[_i(void 0,2).name]=[{name:"wrapper",func:void 0}],On.prototype.clone=function(){var e=new On(this.__wrapped__);return e.__actions__=zi(this.__actions__),e.__dir__=this.__dir__,e.__filtered__=this.__filtered__,e.__iteratees__=zi(this.__iteratees__),e.__takeCount__=this.__takeCount__,e.__views__=zi(this.__views__),e},On.prototype.reverse=function(){if(this.__filtered__){var e=new On(this);e.__dir__=-1,e.__filtered__=!0}else(e=this.clone()).__dir__*=-1;return e},On.prototype.value=function(){var e=this.__wrapped__.value(),t=this.__dir__,n=Oa(e),r=t<0,i=n?e.length:0,o=function(e,t,n){for(var r=-1,i=n.length;++r=this.__values__.length;return{done:e,value:e?void 0:this.__values__[this.__index__++]}},Cn.prototype.plant=function(e){for(var t,n=this;n instanceof Sn;){var r=_o(n);r.__index__=0,r.__values__=void 0,t?i.__wrapped__=r:t=r;var i=r;n=n.__wrapped__}return i.__wrapped__=e,t},Cn.prototype.reverse=function(){var e=this.__wrapped__;if(e instanceof On){var t=e;return this.__actions__.length&&(t=new On(this)),(t=t.reverse()).__actions__.push({func:ea,args:[Ro],thisArg:void 0}),new Tn(t,this.__chain__)}return this.thru(Ro)},Cn.prototype.toJSON=Cn.prototype.valueOf=Cn.prototype.value=function(){return ei(this.__wrapped__,this.__actions__)},Cn.prototype.first=Cn.prototype.head,jt&&(Cn.prototype[jt]=function(){return this}),Cn}();We._=Wt,void 0===(i=function(){return Wt}.call(t,n,t,r))||(r.exports=i)}).call(this)}).call(this,n(7),n(21)(e))},function(e,t){e.exports=r},function(e,t,n){e.exports=function(){"use strict";var e=navigator.userAgent,t=navigator.platform,n=/gecko\/\d/i.test(e),r=/MSIE \d/.test(e),i=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(e),o=/Edge\/(\d+)/.exec(e),a=r||i||o,c=a&&(r?document.documentMode||6:+(o||i)[1]),s=!o&&/WebKit\//.test(e),l=s&&/Qt\/\d+\.\d+/.test(e),u=!o&&/Chrome\//.test(e),f=/Opera\//.test(e),h=/Apple Computer/.test(navigator.vendor),d=/Mac OS X 1\d\D([8-9]|\d\d)\D/.test(e),p=/PhantomJS/.test(e),z=!o&&/AppleWebKit/.test(e)&&/Mobile\/\w+/.test(e),v=/Android/.test(e),g=z||v||/webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(e),m=z||/Mac/.test(t),y=/\bCrOS\b/.test(e),b=/win/i.test(t),w=f&&e.match(/Version\/(\d*\.\d*)/);w&&(w=Number(w[1])),w&&w>=15&&(f=!1,s=!0);var k=m&&(l||f&&(null==w||w<12.11)),x=n||a&&c>=9;function j(e){return new RegExp("(^|\\s)"+e+"(?:$|\\s)\\s*")}var M,_=function(e,t){var n=e.className,r=j(t).exec(n);if(r){var i=n.slice(r.index+r[0].length);e.className=n.slice(0,r.index)+(i?r[1]+i:"")}};function C(e){for(var t=e.childNodes.length;t>0;--t)e.removeChild(e.firstChild);return e}function q(e,t){return C(e).appendChild(t)}function S(e,t,n,r){var i=document.createElement(e);if(n&&(i.className=n),r&&(i.style.cssText=r),"string"==typeof t)i.appendChild(document.createTextNode(t));else if(t)for(var o=0;o=t)return a+(t-o);a+=c-o,a+=n-a%n,o=c+1}}z?H=function(e){e.selectionStart=0,e.selectionEnd=e.value.length}:a&&(H=function(e){try{e.select()}catch(e){}});var N=function(){this.id=null,this.f=null,this.time=0,this.handler=D(this.onTimeout,this)};function I(e,t){for(var n=0;n=t)return r+Math.min(a,t-i);if(i+=o-r,r=o+1,(i+=n-i%n)>=t)return r}}var G=[""];function Y(e){for(;G.length<=e;)G.push(Z(G)+" ");return G[e]}function Z(e){return e[e.length-1]}function $(e,t){for(var n=[],r=0;r"\x80"&&(e.toUpperCase()!=e.toLowerCase()||Q.test(e))}function ee(e,t){return t?!!(t.source.indexOf("\\w")>-1&&J(e))||t.test(e):J(e)}function te(e){for(var t in e)if(e.hasOwnProperty(t)&&e[t])return!1;return!0}var ne=/[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;function re(e){return e.charCodeAt(0)>=768&&ne.test(e)}function ie(e,t,n){for(;(n<0?t>0:tn?-1:1;;){if(t==n)return t;var i=(t+n)/2,o=r<0?Math.ceil(i):Math.floor(i);if(o==t)return e(o)?t:n;e(o)?n=o:t=o+r}}var ae=null;function ce(e,t,n){var r;ae=null;for(var i=0;it)return i;o.to==t&&(o.from!=o.to&&"before"==n?r=i:ae=i),o.from==t&&(o.from!=o.to&&"before"!=n?r=i:ae=i)}return null!=r?r:ae}var se=function(){var e=/[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/,t=/[stwN]/,n=/[LRr]/,r=/[Lb1n]/,i=/[1n]/;function o(e,t,n){this.level=e,this.from=t,this.to=n}return function(a,c){var s="ltr"==c?"L":"R";if(0==a.length||"ltr"==c&&!e.test(a))return!1;for(var l,u=a.length,f=[],h=0;h-1&&(r[t]=i.slice(0,o).concat(i.slice(o+1)))}}}function pe(e,t){var n=he(e,t);if(n.length)for(var r=Array.prototype.slice.call(arguments,2),i=0;i0}function me(e){e.prototype.on=function(e,t){fe(this,e,t)},e.prototype.off=function(e,t){de(this,e,t)}}function ye(e){e.preventDefault?e.preventDefault():e.returnValue=!1}function be(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0}function we(e){return null!=e.defaultPrevented?e.defaultPrevented:0==e.returnValue}function ke(e){ye(e),be(e)}function xe(e){return e.target||e.srcElement}function je(e){var t=e.which;return null==t&&(1&e.button?t=1:2&e.button?t=3:4&e.button&&(t=2)),m&&e.ctrlKey&&1==t&&(t=3),t}var Me,_e,Ce=function(){if(a&&c<9)return!1;var e=S("div");return"draggable"in e||"dragDrop"in e}();function qe(e){if(null==Me){var t=S("span","\u200b");q(e,S("span",[t,document.createTextNode("x")])),0!=e.firstChild.offsetHeight&&(Me=t.offsetWidth<=1&&t.offsetHeight>2&&!(a&&c<8))}var n=Me?S("span","\u200b"):S("span","\xa0",null,"display: inline-block; width: 1px; margin-right: -1px");return n.setAttribute("cm-text",""),n}function Se(e){if(null!=_e)return _e;var t=q(e,document.createTextNode("A\u062eA")),n=M(t,0,1).getBoundingClientRect(),r=M(t,1,2).getBoundingClientRect();return C(e),!(!n||n.left==n.right)&&(_e=r.right-n.right<3)}var Te,Oe=3!="\n\nb".split(/\n/).length?function(e){for(var t=0,n=[],r=e.length;t<=r;){var i=e.indexOf("\n",t);-1==i&&(i=e.length);var o=e.slice(t,"\r"==e.charAt(i-1)?i-1:i),a=o.indexOf("\r");-1!=a?(n.push(o.slice(0,a)),t+=a+1):(n.push(o),t=i+1)}return n}:function(e){return e.split(/\r\n?|\n/)},Ee=window.getSelection?function(e){try{return e.selectionStart!=e.selectionEnd}catch(e){return!1}}:function(e){var t;try{t=e.ownerDocument.selection.createRange()}catch(e){}return!(!t||t.parentElement()!=e)&&0!=t.compareEndPoints("StartToEnd",t)},Ae="oncopy"in(Te=S("div"))||(Te.setAttribute("oncopy","return;"),"function"==typeof Te.oncopy),Le=null,He={},De={};function Pe(e,t){arguments.length>2&&(t.dependencies=Array.prototype.slice.call(arguments,2)),He[e]=t}function Ve(e){if("string"==typeof e&&De.hasOwnProperty(e))e=De[e];else if(e&&"string"==typeof e.name&&De.hasOwnProperty(e.name)){var t=De[e.name];"string"==typeof t&&(t={name:t}),(e=K(t,e)).name=t.name}else{if("string"==typeof e&&/^[\w\-]+\/[\w\-]+\+xml$/.test(e))return Ve("application/xml");if("string"==typeof e&&/^[\w\-]+\/[\w\-]+\+json$/.test(e))return Ve("application/json")}return"string"==typeof e?{name:e}:e||{name:"null"}}function Ne(e,t){t=Ve(t);var n=He[t.name];if(!n)return Ne(e,"text/plain");var r=n(e,t);if(Ie.hasOwnProperty(t.name)){var i=Ie[t.name];for(var o in i)i.hasOwnProperty(o)&&(r.hasOwnProperty(o)&&(r["_"+o]=r[o]),r[o]=i[o])}if(r.name=t.name,t.helperType&&(r.helperType=t.helperType),t.modeProps)for(var a in t.modeProps)r[a]=t.modeProps[a];return r}var Ie={};function Re(e,t){P(t,Ie.hasOwnProperty(e)?Ie[e]:Ie[e]={})}function Fe(e,t){if(!0===t)return t;if(e.copyState)return e.copyState(t);var n={};for(var r in t){var i=t[r];i instanceof Array&&(i=i.concat([])),n[r]=i}return n}function Be(e,t){for(var n;e.innerMode&&(n=e.innerMode(t))&&n.mode!=e;)t=n.state,e=n.mode;return n||{mode:e,state:t}}function Ue(e,t,n){return!e.startState||e.startState(t,n)}var We=function(e,t,n){this.pos=this.start=0,this.string=e,this.tabSize=t||8,this.lastColumnPos=this.lastColumnValue=0,this.lineStart=0,this.lineOracle=n};function Ge(e,t){if((t-=e.first)<0||t>=e.size)throw new Error("There is no line "+(t+e.first)+" in the document.");for(var n=e;!n.lines;)for(var r=0;;++r){var i=n.children[r],o=i.chunkSize();if(t=e.first&&tn?et(n,Ge(e,n).text.length):function(e,t){var n=e.ch;return null==n||n>t?et(e.line,t):n<0?et(e.line,0):e}(t,Ge(e,t.line).text.length)}function st(e,t){for(var n=[],r=0;r=this.string.length},We.prototype.sol=function(){return this.pos==this.lineStart},We.prototype.peek=function(){return this.string.charAt(this.pos)||void 0},We.prototype.next=function(){if(this.post},We.prototype.eatSpace=function(){for(var e=this.pos;/[\s\u00a0]/.test(this.string.charAt(this.pos));)++this.pos;return this.pos>e},We.prototype.skipToEnd=function(){this.pos=this.string.length},We.prototype.skipTo=function(e){var t=this.string.indexOf(e,this.pos);if(t>-1)return this.pos=t,!0},We.prototype.backUp=function(e){this.pos-=e},We.prototype.column=function(){return this.lastColumnPos0?null:(r&&!1!==t&&(this.pos+=r[0].length),r)}var i=function(e){return n?e.toLowerCase():e};if(i(this.string.substr(this.pos,e.length))==i(e))return!1!==t&&(this.pos+=e.length),!0},We.prototype.current=function(){return this.string.slice(this.start,this.pos)},We.prototype.hideFirstChars=function(e,t){this.lineStart+=e;try{return t()}finally{this.lineStart-=e}},We.prototype.lookAhead=function(e){var t=this.lineOracle;return t&&t.lookAhead(e)},We.prototype.baseToken=function(){var e=this.lineOracle;return e&&e.baseToken(this.pos)};var lt=function(e,t){this.state=e,this.lookAhead=t},ut=function(e,t,n,r){this.state=t,this.doc=e,this.line=n,this.maxLookAhead=r||0,this.baseTokens=null,this.baseTokenPos=1};function ft(e,t,n,r){var i=[e.state.modeGen],o={};bt(e,t.text,e.doc.mode,n,(function(e,t){return i.push(e,t)}),o,r);for(var a=n.state,c=function(r){n.baseTokens=i;var c=e.state.overlays[r],s=1,l=0;n.state=!0,bt(e,t.text,c.mode,n,(function(e,t){for(var n=s;le&&i.splice(s,1,e,i[s+1],r),s+=2,l=Math.min(e,r)}if(t)if(c.opaque)i.splice(n,s-n,e,"overlay "+t),s=n+2;else for(;ne.options.maxHighlightLength&&Fe(e.doc.mode,r.state),o=ft(e,t,r);i&&(r.state=i),t.stateAfter=r.save(!i),t.styles=o.styles,o.classes?t.styleClasses=o.classes:t.styleClasses&&(t.styleClasses=null),n===e.doc.highlightFrontier&&(e.doc.modeFrontier=Math.max(e.doc.modeFrontier,++e.doc.highlightFrontier))}return t.styles}function dt(e,t,n){var r=e.doc,i=e.display;if(!r.mode.startState)return new ut(r,!0,t);var o=function(e,t,n){for(var r,i,o=e.doc,a=n?-1:t-(e.doc.mode.innerMode?1e3:100),c=t;c>a;--c){if(c<=o.first)return o.first;var s=Ge(o,c-1),l=s.stateAfter;if(l&&(!n||c+(l instanceof lt?l.lookAhead:0)<=o.modeFrontier))return c;var u=V(s.text,null,e.options.tabSize);(null==i||r>u)&&(i=c-1,r=u)}return i}(e,t,n),a=o>r.first&&Ge(r,o-1).stateAfter,c=a?ut.fromSaved(r,a,o):new ut(r,Ue(r.mode),o);return r.iter(o,t,(function(n){pt(e,n.text,c);var r=c.line;n.stateAfter=r==t-1||r%5==0||r>=i.viewFrom&&rt.start)return o}throw new Error("Mode "+e.name+" failed to advance stream.")}ut.prototype.lookAhead=function(e){var t=this.doc.getLine(this.line+e);return null!=t&&e>this.maxLookAhead&&(this.maxLookAhead=e),t},ut.prototype.baseToken=function(e){if(!this.baseTokens)return null;for(;this.baseTokens[this.baseTokenPos]<=e;)this.baseTokenPos+=2;var t=this.baseTokens[this.baseTokenPos+1];return{type:t&&t.replace(/( |^)overlay .*/,""),size:this.baseTokens[this.baseTokenPos]-e}},ut.prototype.nextLine=function(){this.line++,this.maxLookAhead>0&&this.maxLookAhead--},ut.fromSaved=function(e,t,n){return t instanceof lt?new ut(e,Fe(e.mode,t.state),n,t.lookAhead):new ut(e,Fe(e.mode,t),n)},ut.prototype.save=function(e){var t=!1!==e?Fe(this.doc.mode,this.state):this.state;return this.maxLookAhead>0?new lt(t,this.maxLookAhead):t};var gt=function(e,t,n){this.start=e.start,this.end=e.pos,this.string=e.current(),this.type=t||null,this.state=n};function mt(e,t,n,r){var i,o,a=e.doc,c=a.mode,s=Ge(a,(t=ct(a,t)).line),l=dt(e,t.line,n),u=new We(s.text,e.options.tabSize,l);for(r&&(o=[]);(r||u.pose.options.maxHighlightLength?(c=!1,a&&pt(e,t,r,f.pos),f.pos=t.length,s=null):s=yt(vt(n,f,r.state,h),o),h){var d=h[0].name;d&&(s="m-"+(s?d+" "+s:d))}if(!c||u!=s){for(;l=t:o.to>t);(r||(r=[])).push(new xt(a,o.from,c?null:o.to))}}return r}(n,i,a),s=function(e,t,n){var r;if(e)for(var i=0;i=t:o.to>t)||o.from==t&&"bookmark"==a.type&&(!n||o.marker.insertLeft)){var c=null==o.from||(a.inclusiveLeft?o.from<=t:o.from0&&c)for(var y=0;yt)&&(!n||Et(n,o.marker)<0)&&(n=o.marker)}return n}function Pt(e,t,n,r,i){var o=Ge(e,t),a=kt&&o.markedSpans;if(a)for(var c=0;c=0&&f<=0||u<=0&&f>=0)&&(u<=0&&(s.marker.inclusiveRight&&i.inclusiveLeft?tt(l.to,n)>=0:tt(l.to,n)>0)||u>=0&&(s.marker.inclusiveRight&&i.inclusiveLeft?tt(l.from,r)<=0:tt(l.from,r)<0)))return!0}}}function Vt(e){for(var t;t=Lt(e);)e=t.find(-1,!0).line;return e}function Nt(e,t){var n=Ge(e,t),r=Vt(n);return n==r?t:Xe(r)}function It(e,t){if(t>e.lastLine())return t;var n,r=Ge(e,t);if(!Rt(e,r))return t;for(;n=Ht(r);)r=n.find(1,!0).line;return Xe(r)+1}function Rt(e,t){var n=kt&&t.markedSpans;if(n)for(var r=void 0,i=0;it.maxLineLength&&(t.maxLineLength=n,t.maxLine=e)}))}var Gt=function(e,t,n){this.text=e,St(this,t),this.height=n?n(this):1};function Yt(e){e.parent=null,qt(e)}Gt.prototype.lineNo=function(){return Xe(this)},me(Gt);var Zt={},$t={};function Xt(e,t){if(!e||/^\s*$/.test(e))return null;var n=t.addModeClass?$t:Zt;return n[e]||(n[e]=e.replace(/\S+/g,"cm-$&"))}function Kt(e,t){var n=T("span",null,null,s?"padding-right: .1px":null),r={pre:T("pre",[n],"CodeMirror-line"),content:n,col:0,pos:0,cm:e,trailingSpace:!1,splitSpaces:e.getOption("lineWrapping")};t.measure={};for(var i=0;i<=(t.rest?t.rest.length:0);i++){var o=i?t.rest[i-1]:t.line,a=void 0;r.pos=0,r.addToken=Jt,Se(e.display.measure)&&(a=le(o,e.doc.direction))&&(r.addToken=en(r.addToken,a)),r.map=[],nn(o,r,ht(e,o,t!=e.display.externalMeasured&&Xe(o))),o.styleClasses&&(o.styleClasses.bgClass&&(r.bgClass=L(o.styleClasses.bgClass,r.bgClass||"")),o.styleClasses.textClass&&(r.textClass=L(o.styleClasses.textClass,r.textClass||""))),0==r.map.length&&r.map.push(0,0,r.content.appendChild(qe(e.display.measure))),0==i?(t.measure.map=r.map,t.measure.cache={}):((t.measure.maps||(t.measure.maps=[])).push(r.map),(t.measure.caches||(t.measure.caches=[])).push({}))}if(s){var c=r.content.lastChild;(/\bcm-tab\b/.test(c.className)||c.querySelector&&c.querySelector(".cm-tab"))&&(r.content.className="cm-tab-wrap-hack")}return pe(e,"renderLine",e,t.line,r.pre),r.pre.className&&(r.textClass=L(r.pre.className,r.textClass||"")),r}function Qt(e){var t=S("span","\u2022","cm-invalidchar");return t.title="\\u"+e.charCodeAt(0).toString(16),t.setAttribute("aria-label",t.title),t}function Jt(e,t,n,r,i,o,s){if(t){var l,u=e.splitSpaces?function(e,t){if(e.length>1&&!/ /.test(e))return e;for(var n=t,r="",i=0;il&&f.from<=l);h++);if(f.to>=u)return e(n,r,i,o,a,c,s);e(n,r.slice(0,f.to-l),i,o,null,c,s),o=null,r=r.slice(f.to-l),l=f.to}}}function tn(e,t,n,r){var i=!r&&n.widgetNode;i&&e.map.push(e.pos,e.pos+t,i),!r&&e.cm.display.input.needsContentAttribute&&(i||(i=e.content.appendChild(document.createElement("span"))),i.setAttribute("cm-marker",n.id)),i&&(e.cm.display.input.setUneditable(i),e.content.appendChild(i)),e.pos+=t,e.trailingSpace=!1}function nn(e,t,n){var r=e.markedSpans,i=e.text,o=0;if(r)for(var a,c,s,l,u,f,h,d=i.length,p=0,z=1,v="",g=0;;){if(g==p){s=l=u=c="",h=null,f=null,g=1/0;for(var m=[],y=void 0,b=0;bp||k.collapsed&&w.to==p&&w.from==p)){if(null!=w.to&&w.to!=p&&g>w.to&&(g=w.to,l=""),k.className&&(s+=" "+k.className),k.css&&(c=(c?c+";":"")+k.css),k.startStyle&&w.from==p&&(u+=" "+k.startStyle),k.endStyle&&w.to==g&&(y||(y=[])).push(k.endStyle,w.to),k.title&&((h||(h={})).title=k.title),k.attributes)for(var x in k.attributes)(h||(h={}))[x]=k.attributes[x];k.collapsed&&(!f||Et(f.marker,k)<0)&&(f=w)}else w.from>p&&g>w.from&&(g=w.from)}if(y)for(var j=0;j=d)break;for(var _=Math.min(d,g);;){if(v){var C=p+v.length;if(!f){var q=C>_?v.slice(0,_-p):v;t.addToken(t,q,a?a+s:s,u,p+q.length==g?l:"",c,h)}if(C>=_){v=v.slice(_-p),p=_;break}p=C,u=""}v=i.slice(o,o=n[z++]),a=Xt(n[z++],t.cm.options)}}else for(var S=1;Sn)return{map:e.measure.maps[i],cache:e.measure.caches[i],before:!0}}function Tn(e,t,n,r){return An(e,En(e,t),n,r)}function On(e,t){if(t>=e.display.viewFrom&&t=n.lineN&&t2&&o.push((s.bottom+l.top)/2-n.top)}}o.push(n.bottom-n.top)}}(e,t.view,t.rect),t.hasHeights=!0),(o=function(e,t,n,r){var i,o=Dn(t.map,n,r),s=o.node,l=o.start,u=o.end,f=o.collapse;if(3==s.nodeType){for(var h=0;h<4;h++){for(;l&&re(t.line.text.charAt(o.coverStart+l));)--l;for(;o.coverStart+u1}(e))return t;var n=screen.logicalXDPI/screen.deviceXDPI,r=screen.logicalYDPI/screen.deviceYDPI;return{left:t.left*n,right:t.right*n,top:t.top*r,bottom:t.bottom*r}}(e.display.measure,i))}else{var d;l>0&&(f=r="right"),i=e.options.lineWrapping&&(d=s.getClientRects()).length>1?d["right"==r?d.length-1:0]:s.getBoundingClientRect()}if(a&&c<9&&!l&&(!i||!i.left&&!i.right)){var p=s.parentNode.getClientRects()[0];i=p?{left:p.left,right:p.left+ir(e.display),top:p.top,bottom:p.bottom}:Hn}for(var z=i.top-t.rect.top,v=i.bottom-t.rect.top,g=(z+v)/2,m=t.view.measure.heights,y=0;yt)&&(i=(o=s-c)-1,t>=s&&(a="right")),null!=i){if(r=e[l+2],c==s&&n==(r.insertLeft?"left":"right")&&(a=n),"left"==n&&0==i)for(;l&&e[l-2]==e[l-3]&&e[l-1].insertLeft;)r=e[2+(l-=3)],a="left";if("right"==n&&i==s-c)for(;l=0&&(n=e[i]).left==n.right;i--);return n}function Vn(e){if(e.measure&&(e.measure.cache={},e.measure.heights=null,e.rest))for(var t=0;t=r.text.length?(s=r.text.length,l="before"):s<=0&&(s=0,l="after"),!c)return a("before"==l?s-1:s,"before"==l);function u(e,t,n){return a(n?e-1:e,1==c[t].level!=n)}var f=ce(c,s,l),h=ae,d=u(s,f,"before"==l);return null!=h&&(d.other=u(s,h,"before"!=l)),d}function Zn(e,t){var n=0;t=ct(e.doc,t),e.options.lineWrapping||(n=ir(e.display)*t.ch);var r=Ge(e.doc,t.line),i=Bt(r)+xn(e.display);return{left:n,right:n,top:i,bottom:i+r.height}}function $n(e,t,n,r,i){var o=et(e,t,n);return o.xRel=i,r&&(o.outside=r),o}function Xn(e,t,n){var r=e.doc;if((n+=e.display.viewOffset)<0)return $n(r.first,0,null,-1,-1);var i=Ke(r,n),o=r.first+r.size-1;if(i>o)return $n(r.first+r.size-1,Ge(r,o).text.length,null,1,1);t<0&&(t=0);for(var a=Ge(r,i);;){var c=er(e,a,i,t,n),s=Dt(a,c.ch+(c.xRel>0||c.outside>0?1:0));if(!s)return c;var l=s.find(1);if(l.line==i)return l;a=Ge(r,i=l.line)}}function Kn(e,t,n,r){r-=Bn(t);var i=t.text.length,o=oe((function(t){return An(e,n,t-1).bottom<=r}),i,0);return{begin:o,end:i=oe((function(t){return An(e,n,t).top>r}),o,i)}}function Qn(e,t,n,r){return n||(n=En(e,t)),Kn(e,t,n,Un(e,t,An(e,n,r),"line").top)}function Jn(e,t,n,r){return!(e.bottom<=n)&&(e.top>n||(r?e.left:e.right)>t)}function er(e,t,n,r,i){i-=Bt(t);var o=En(e,t),a=Bn(t),c=0,s=t.text.length,l=!0,u=le(t,e.doc.direction);if(u){var f=(e.options.lineWrapping?nr:tr)(e,t,n,o,u,r,i);c=(l=1!=f.level)?f.from:f.to-1,s=l?f.to:f.from-1}var h,d,p=null,z=null,v=oe((function(t){var n=An(e,o,t);return n.top+=a,n.bottom+=a,!!Jn(n,r,i,!1)&&(n.top<=i&&n.left<=r&&(p=t,z=n),!0)}),c,s),g=!1;if(z){var m=r-z.left=b.bottom?1:0}return $n(n,v=ie(t.text,v,1),d,g,r-h)}function tr(e,t,n,r,i,o,a){var c=oe((function(c){var s=i[c],l=1!=s.level;return Jn(Yn(e,et(n,l?s.to:s.from,l?"before":"after"),"line",t,r),o,a,!0)}),0,i.length-1),s=i[c];if(c>0){var l=1!=s.level,u=Yn(e,et(n,l?s.from:s.to,l?"after":"before"),"line",t,r);Jn(u,o,a,!0)&&u.top>a&&(s=i[c-1])}return s}function nr(e,t,n,r,i,o,a){var c=Kn(e,t,r,a),s=c.begin,l=c.end;/\s/.test(t.text.charAt(l-1))&&l--;for(var u=null,f=null,h=0;h=l||d.to<=s)){var p=An(e,r,1!=d.level?Math.min(l,d.to)-1:Math.max(s,d.from)).right,z=pz)&&(u=d,f=z)}}return u||(u=i[i.length-1]),u.froml&&(u={from:u.from,to:l,level:u.level}),u}function rr(e){if(null!=e.cachedTextHeight)return e.cachedTextHeight;if(null==Ln){Ln=S("pre",null,"CodeMirror-line-like");for(var t=0;t<49;++t)Ln.appendChild(document.createTextNode("x")),Ln.appendChild(S("br"));Ln.appendChild(document.createTextNode("x"))}q(e.measure,Ln);var n=Ln.offsetHeight/50;return n>3&&(e.cachedTextHeight=n),C(e.measure),n||1}function ir(e){if(null!=e.cachedCharWidth)return e.cachedCharWidth;var t=S("span","xxxxxxxxxx"),n=S("pre",[t],"CodeMirror-line-like");q(e.measure,n);var r=t.getBoundingClientRect(),i=(r.right-r.left)/10;return i>2&&(e.cachedCharWidth=i),i||10}function or(e){for(var t=e.display,n={},r={},i=t.gutters.clientLeft,o=t.gutters.firstChild,a=0;o;o=o.nextSibling,++a){var c=e.display.gutterSpecs[a].className;n[c]=o.offsetLeft+o.clientLeft+i,r[c]=o.clientWidth}return{fixedPos:ar(t),gutterTotalWidth:t.gutters.offsetWidth,gutterLeft:n,gutterWidth:r,wrapperWidth:t.wrapper.clientWidth}}function ar(e){return e.scroller.getBoundingClientRect().left-e.sizer.getBoundingClientRect().left}function cr(e){var t=rr(e.display),n=e.options.lineWrapping,r=n&&Math.max(5,e.display.scroller.clientWidth/ir(e.display)-3);return function(i){if(Rt(e.doc,i))return 0;var o=0;if(i.widgets)for(var a=0;a0&&(s=Ge(e.doc,l.line).text).length==l.ch){var u=V(s,s.length,e.options.tabSize)-s.length;l=et(l.line,Math.max(0,Math.round((o-Mn(e.display).left)/ir(e.display))-u))}return l}function ur(e,t){if(t>=e.display.viewTo)return null;if((t-=e.display.viewFrom)<0)return null;for(var n=e.display.view,r=0;rt)&&(i.updateLineNumbers=t),e.curOp.viewChanged=!0,t>=i.viewTo)kt&&Nt(e.doc,t)i.viewFrom?dr(e):(i.viewFrom+=r,i.viewTo+=r);else if(t<=i.viewFrom&&n>=i.viewTo)dr(e);else if(t<=i.viewFrom){var o=pr(e,n,n+r,1);o?(i.view=i.view.slice(o.index),i.viewFrom=o.lineN,i.viewTo+=r):dr(e)}else if(n>=i.viewTo){var a=pr(e,t,t,-1);a?(i.view=i.view.slice(0,a.index),i.viewTo=a.lineN):dr(e)}else{var c=pr(e,t,t,-1),s=pr(e,n,n+r,1);c&&s?(i.view=i.view.slice(0,c.index).concat(on(e,c.lineN,s.lineN)).concat(i.view.slice(s.index)),i.viewTo+=r):dr(e)}var l=i.externalMeasured;l&&(n=i.lineN&&t=r.viewTo)){var o=r.view[ur(e,t)];if(null!=o.node){var a=o.changes||(o.changes=[]);-1==I(a,n)&&a.push(n)}}}function dr(e){e.display.viewFrom=e.display.viewTo=e.doc.first,e.display.view=[],e.display.viewOffset=0}function pr(e,t,n,r){var i,o=ur(e,t),a=e.display.view;if(!kt||n==e.doc.first+e.doc.size)return{index:o,lineN:n};for(var c=e.display.viewFrom,s=0;s0){if(o==a.length-1)return null;i=c+a[o].size-t,o++}else i=c-t;t+=i,n+=i}for(;Nt(e.doc,n)!=n;){if(o==(r<0?0:a.length-1))return null;n+=r*a[o-(r<0?1:0)].size,o+=r}return{index:o,lineN:n}}function zr(e){for(var t=e.display.view,n=0,r=0;r=e.display.viewTo||c.to().linet||t==n&&a.to==t)&&(r(Math.max(a.from,t),Math.min(a.to,n),1==a.level?"rtl":"ltr",o),i=!0)}i||r(t,n,"ltr")}(z,n||0,null==r?h:r,(function(e,t,i,f){var v="ltr"==i,g=d(e,v?"left":"right"),m=d(t-1,v?"right":"left"),y=null==n&&0==e,b=null==r&&t==h,w=0==f,k=!z||f==z.length-1;if(m.top-g.top<=3){var x=(l?b:y)&&k,j=(l?y:b)&&w?c:(v?g:m).left,M=x?s:(v?m:g).right;u(j,g.top,M-j,g.bottom)}else{var _,C,q,S;v?(_=l&&y&&w?c:g.left,C=l?s:p(e,i,"before"),q=l?c:p(t,i,"after"),S=l&&b&&k?s:m.right):(_=l?p(e,i,"before"):c,C=!l&&y&&w?s:g.right,q=!l&&b&&k?c:m.left,S=l?p(t,i,"after"):s),u(_,g.top,C-_,g.bottom),g.bottom0?t.blinker=setInterval((function(){return t.cursorDiv.style.visibility=(n=!n)?"":"hidden"}),e.options.cursorBlinkRate):e.options.cursorBlinkRate<0&&(t.cursorDiv.style.visibility="hidden")}}function kr(e){e.state.focused||(e.display.input.focus(),jr(e))}function xr(e){e.state.delayingBlurEvent=!0,setTimeout((function(){e.state.delayingBlurEvent&&(e.state.delayingBlurEvent=!1,Mr(e))}),100)}function jr(e,t){e.state.delayingBlurEvent&&(e.state.delayingBlurEvent=!1),"nocursor"!=e.options.readOnly&&(e.state.focused||(pe(e,"focus",e,t),e.state.focused=!0,A(e.display.wrapper,"CodeMirror-focused"),e.curOp||e.display.selForContextMenu==e.doc.sel||(e.display.input.reset(),s&&setTimeout((function(){return e.display.input.reset(!0)}),20)),e.display.input.receivedFocus()),wr(e))}function Mr(e,t){e.state.delayingBlurEvent||(e.state.focused&&(pe(e,"blur",e,t),e.state.focused=!1,_(e.display.wrapper,"CodeMirror-focused")),clearInterval(e.display.blinker),setTimeout((function(){e.state.focused||(e.display.shift=!1)}),150))}function _r(e){for(var t=e.display,n=t.lineDiv.offsetTop,r=0;r.005||h<-.005)&&($e(i.line,s),Cr(i.line),i.rest))for(var d=0;de.display.sizerWidth){var p=Math.ceil(l/ir(e.display));p>e.display.maxLineLength&&(e.display.maxLineLength=p,e.display.maxLine=i.line,e.display.maxLineChanged=!0)}}}}function Cr(e){if(e.widgets)for(var t=0;t=a&&(o=Ke(t,Bt(Ge(t,s))-e.wrapper.clientHeight),a=s)}return{from:o,to:Math.max(a,o+1)}}function Sr(e,t){var n=e.display,r=rr(e.display);t.top<0&&(t.top=0);var i=e.curOp&&null!=e.curOp.scrollTop?e.curOp.scrollTop:n.scroller.scrollTop,o=qn(e),a={};t.bottom-t.top>o&&(t.bottom=t.top+o);var c=e.doc.height+jn(n),s=t.topc-r;if(t.topi+o){var u=Math.min(t.top,(l?c:t.bottom)-o);u!=i&&(a.scrollTop=u)}var f=e.curOp&&null!=e.curOp.scrollLeft?e.curOp.scrollLeft:n.scroller.scrollLeft,h=Cn(e)-(e.options.fixedGutter?n.gutters.offsetWidth:0),d=t.right-t.left>h;return d&&(t.right=t.left+h),t.left<10?a.scrollLeft=0:t.lefth+f-3&&(a.scrollLeft=t.right+(d?0:10)-h),a}function Tr(e,t){null!=t&&(Ar(e),e.curOp.scrollTop=(null==e.curOp.scrollTop?e.doc.scrollTop:e.curOp.scrollTop)+t)}function Or(e){Ar(e);var t=e.getCursor();e.curOp.scrollToPos={from:t,to:t,margin:e.options.cursorScrollMargin}}function Er(e,t,n){null==t&&null==n||Ar(e),null!=t&&(e.curOp.scrollLeft=t),null!=n&&(e.curOp.scrollTop=n)}function Ar(e){var t=e.curOp.scrollToPos;t&&(e.curOp.scrollToPos=null,Lr(e,Zn(e,t.from),Zn(e,t.to),t.margin))}function Lr(e,t,n,r){var i=Sr(e,{left:Math.min(t.left,n.left),top:Math.min(t.top,n.top)-r,right:Math.max(t.right,n.right),bottom:Math.max(t.bottom,n.bottom)+r});Er(e,i.scrollLeft,i.scrollTop)}function Hr(e,t){Math.abs(e.doc.scrollTop-t)<2||(n||si(e,{top:t}),Dr(e,t,!0),n&&si(e),ri(e,100))}function Dr(e,t,n){t=Math.max(0,Math.min(e.display.scroller.scrollHeight-e.display.scroller.clientHeight,t)),(e.display.scroller.scrollTop!=t||n)&&(e.doc.scrollTop=t,e.display.scrollbars.setScrollTop(t),e.display.scroller.scrollTop!=t&&(e.display.scroller.scrollTop=t))}function Pr(e,t,n,r){t=Math.max(0,Math.min(t,e.display.scroller.scrollWidth-e.display.scroller.clientWidth)),(n?t==e.doc.scrollLeft:Math.abs(e.doc.scrollLeft-t)<2)&&!r||(e.doc.scrollLeft=t,fi(e),e.display.scroller.scrollLeft!=t&&(e.display.scroller.scrollLeft=t),e.display.scrollbars.setScrollLeft(t))}function Vr(e){var t=e.display,n=t.gutters.offsetWidth,r=Math.round(e.doc.height+jn(e.display));return{clientHeight:t.scroller.clientHeight,viewHeight:t.wrapper.clientHeight,scrollWidth:t.scroller.scrollWidth,clientWidth:t.scroller.clientWidth,viewWidth:t.wrapper.clientWidth,barLeft:e.options.fixedGutter?n:0,docHeight:r,scrollHeight:r+_n(e)+t.barHeight,nativeBarWidth:t.nativeBarWidth,gutterWidth:n}}var Nr=function(e,t,n){this.cm=n;var r=this.vert=S("div",[S("div",null,null,"min-width: 1px")],"CodeMirror-vscrollbar"),i=this.horiz=S("div",[S("div",null,null,"height: 100%; min-height: 1px")],"CodeMirror-hscrollbar");r.tabIndex=i.tabIndex=-1,e(r),e(i),fe(r,"scroll",(function(){r.clientHeight&&t(r.scrollTop,"vertical")})),fe(i,"scroll",(function(){i.clientWidth&&t(i.scrollLeft,"horizontal")})),this.checkedZeroWidth=!1,a&&c<8&&(this.horiz.style.minHeight=this.vert.style.minWidth="18px")};Nr.prototype.update=function(e){var t=e.scrollWidth>e.clientWidth+1,n=e.scrollHeight>e.clientHeight+1,r=e.nativeBarWidth;if(n){this.vert.style.display="block",this.vert.style.bottom=t?r+"px":"0";var i=e.viewHeight-(t?r:0);this.vert.firstChild.style.height=Math.max(0,e.scrollHeight-e.clientHeight+i)+"px"}else this.vert.style.display="",this.vert.firstChild.style.height="0";if(t){this.horiz.style.display="block",this.horiz.style.right=n?r+"px":"0",this.horiz.style.left=e.barLeft+"px";var o=e.viewWidth-e.barLeft-(n?r:0);this.horiz.firstChild.style.width=Math.max(0,e.scrollWidth-e.clientWidth+o)+"px"}else this.horiz.style.display="",this.horiz.firstChild.style.width="0";return!this.checkedZeroWidth&&e.clientHeight>0&&(0==r&&this.zeroWidthHack(),this.checkedZeroWidth=!0),{right:n?r:0,bottom:t?r:0}},Nr.prototype.setScrollLeft=function(e){this.horiz.scrollLeft!=e&&(this.horiz.scrollLeft=e),this.disableHoriz&&this.enableZeroWidthBar(this.horiz,this.disableHoriz,"horiz")},Nr.prototype.setScrollTop=function(e){this.vert.scrollTop!=e&&(this.vert.scrollTop=e),this.disableVert&&this.enableZeroWidthBar(this.vert,this.disableVert,"vert")},Nr.prototype.zeroWidthHack=function(){var e=m&&!d?"12px":"18px";this.horiz.style.height=this.vert.style.width=e,this.horiz.style.pointerEvents=this.vert.style.pointerEvents="none",this.disableHoriz=new N,this.disableVert=new N},Nr.prototype.enableZeroWidthBar=function(e,t,n){e.style.pointerEvents="auto",t.set(1e3,(function r(){var i=e.getBoundingClientRect();("vert"==n?document.elementFromPoint(i.right-1,(i.top+i.bottom)/2):document.elementFromPoint((i.right+i.left)/2,i.bottom-1))!=e?e.style.pointerEvents="none":t.set(1e3,r)}))},Nr.prototype.clear=function(){var e=this.horiz.parentNode;e.removeChild(this.horiz),e.removeChild(this.vert)};var Ir=function(){};function Rr(e,t){t||(t=Vr(e));var n=e.display.barWidth,r=e.display.barHeight;Fr(e,t);for(var i=0;i<4&&n!=e.display.barWidth||r!=e.display.barHeight;i++)n!=e.display.barWidth&&e.options.lineWrapping&&_r(e),Fr(e,Vr(e)),n=e.display.barWidth,r=e.display.barHeight}function Fr(e,t){var n=e.display,r=n.scrollbars.update(t);n.sizer.style.paddingRight=(n.barWidth=r.right)+"px",n.sizer.style.paddingBottom=(n.barHeight=r.bottom)+"px",n.heightForcer.style.borderBottom=r.bottom+"px solid transparent",r.right&&r.bottom?(n.scrollbarFiller.style.display="block",n.scrollbarFiller.style.height=r.bottom+"px",n.scrollbarFiller.style.width=r.right+"px"):n.scrollbarFiller.style.display="",r.bottom&&e.options.coverGutterNextToScrollbar&&e.options.fixedGutter?(n.gutterFiller.style.display="block",n.gutterFiller.style.height=r.bottom+"px",n.gutterFiller.style.width=t.gutterWidth+"px"):n.gutterFiller.style.display=""}Ir.prototype.update=function(){return{bottom:0,right:0}},Ir.prototype.setScrollLeft=function(){},Ir.prototype.setScrollTop=function(){},Ir.prototype.clear=function(){};var Br={native:Nr,null:Ir};function Ur(e){e.display.scrollbars&&(e.display.scrollbars.clear(),e.display.scrollbars.addClass&&_(e.display.wrapper,e.display.scrollbars.addClass)),e.display.scrollbars=new Br[e.options.scrollbarStyle]((function(t){e.display.wrapper.insertBefore(t,e.display.scrollbarFiller),fe(t,"mousedown",(function(){e.state.focused&&setTimeout((function(){return e.display.input.focus()}),0)})),t.setAttribute("cm-not-content","true")}),(function(t,n){"horizontal"==n?Pr(e,t):Hr(e,t)}),e),e.display.scrollbars.addClass&&A(e.display.wrapper,e.display.scrollbars.addClass)}var Wr=0;function Gr(e){var t;e.curOp={cm:e,viewChanged:!1,startHeight:e.doc.height,forceUpdate:!1,updateInput:0,typing:!1,changeObjs:null,cursorActivityHandlers:null,cursorActivityCalled:0,selectionChanged:!1,updateMaxLine:!1,scrollLeft:null,scrollTop:null,scrollToPos:null,focus:!1,id:++Wr},t=e.curOp,an?an.ops.push(t):t.ownsGroup=an={ops:[t],delayedCallbacks:[]}}function Yr(e){var t=e.curOp;t&&function(e,t){var n=e.ownsGroup;if(n)try{!function(e){var t=e.delayedCallbacks,n=0;do{for(;n=n.viewTo)||n.maxLineChanged&&t.options.lineWrapping,e.update=e.mustUpdate&&new oi(t,e.mustUpdate&&{top:e.scrollTop,ensure:e.scrollToPos},e.forceUpdate)}function $r(e){e.updatedDisplay=e.mustUpdate&&ai(e.cm,e.update)}function Xr(e){var t=e.cm,n=t.display;e.updatedDisplay&&_r(t),e.barMeasure=Vr(t),n.maxLineChanged&&!t.options.lineWrapping&&(e.adjustWidthTo=Tn(t,n.maxLine,n.maxLine.text.length).left+3,t.display.sizerWidth=e.adjustWidthTo,e.barMeasure.scrollWidth=Math.max(n.scroller.clientWidth,n.sizer.offsetLeft+e.adjustWidthTo+_n(t)+t.display.barWidth),e.maxScrollLeft=Math.max(0,n.sizer.offsetLeft+e.adjustWidthTo-Cn(t))),(e.updatedDisplay||e.selectionChanged)&&(e.preparedSelection=n.input.prepareSelection())}function Kr(e){var t=e.cm;null!=e.adjustWidthTo&&(t.display.sizer.style.minWidth=e.adjustWidthTo+"px",e.maxScrollLeft(window.innerHeight||document.documentElement.clientHeight)&&(i=!1),null!=i&&!p){var o=S("div","\u200b",null,"position: absolute;\n top: "+(t.top-n.viewOffset-xn(e.display))+"px;\n height: "+(t.bottom-t.top+_n(e)+n.barHeight)+"px;\n left: "+t.left+"px; width: "+Math.max(2,t.right-t.left)+"px;");e.display.lineSpace.appendChild(o),o.scrollIntoView(i),e.display.lineSpace.removeChild(o)}}}(t,function(e,t,n,r){var i;null==r&&(r=0),e.options.lineWrapping||t!=n||(n="before"==(t=t.ch?et(t.line,"before"==t.sticky?t.ch-1:t.ch,"after"):t).sticky?et(t.line,t.ch+1,"before"):t);for(var o=0;o<5;o++){var a=!1,c=Yn(e,t),s=n&&n!=t?Yn(e,n):c,l=Sr(e,i={left:Math.min(c.left,s.left),top:Math.min(c.top,s.top)-r,right:Math.max(c.left,s.left),bottom:Math.max(c.bottom,s.bottom)+r}),u=e.doc.scrollTop,f=e.doc.scrollLeft;if(null!=l.scrollTop&&(Hr(e,l.scrollTop),Math.abs(e.doc.scrollTop-u)>1&&(a=!0)),null!=l.scrollLeft&&(Pr(e,l.scrollLeft),Math.abs(e.doc.scrollLeft-f)>1&&(a=!0)),!a)break}return i}(t,ct(r,e.scrollToPos.from),ct(r,e.scrollToPos.to),e.scrollToPos.margin));var i=e.maybeHiddenMarkers,o=e.maybeUnhiddenMarkers;if(i)for(var a=0;a=e.display.viewTo)){var n=+new Date+e.options.workTime,r=dt(e,t.highlightFrontier),i=[];t.iter(r.line,Math.min(t.first+t.size,e.display.viewTo+500),(function(o){if(r.line>=e.display.viewFrom){var a=o.styles,c=o.text.length>e.options.maxHighlightLength?Fe(t.mode,r.state):null,s=ft(e,o,r,!0);c&&(r.state=c),o.styles=s.styles;var l=o.styleClasses,u=s.classes;u?o.styleClasses=u:l&&(o.styleClasses=null);for(var f=!a||a.length!=o.styles.length||l!=u&&(!l||!u||l.bgClass!=u.bgClass||l.textClass!=u.textClass),h=0;!f&&hn)return ri(e,e.options.workDelay),!0})),t.highlightFrontier=r.line,t.modeFrontier=Math.max(t.modeFrontier,r.line),i.length&&Jr(e,(function(){for(var t=0;t=n.viewFrom&&t.visible.to<=n.viewTo&&(null==n.updateLineNumbers||n.updateLineNumbers>=n.viewTo)&&n.renderedView==n.view&&0==zr(e))return!1;hi(e)&&(dr(e),t.dims=or(e));var i=r.first+r.size,o=Math.max(t.visible.from-e.options.viewportMargin,r.first),a=Math.min(i,t.visible.to+e.options.viewportMargin);n.viewFroma&&n.viewTo-a<20&&(a=Math.min(i,n.viewTo)),kt&&(o=Nt(e.doc,o),a=It(e.doc,a));var c=o!=n.viewFrom||a!=n.viewTo||n.lastWrapHeight!=t.wrapperHeight||n.lastWrapWidth!=t.wrapperWidth;!function(e,t,n){var r=e.display;0==r.view.length||t>=r.viewTo||n<=r.viewFrom?(r.view=on(e,t,n),r.viewFrom=t):(r.viewFrom>t?r.view=on(e,t,r.viewFrom).concat(r.view):r.viewFromn&&(r.view=r.view.slice(0,ur(e,n)))),r.viewTo=n}(e,o,a),n.viewOffset=Bt(Ge(e.doc,n.viewFrom)),e.display.mover.style.top=n.viewOffset+"px";var l=zr(e);if(!c&&0==l&&!t.force&&n.renderedView==n.view&&(null==n.updateLineNumbers||n.updateLineNumbers>=n.viewTo))return!1;var u=function(e){if(e.hasFocus())return null;var t=E();if(!t||!O(e.display.lineDiv,t))return null;var n={activeElt:t};if(window.getSelection){var r=window.getSelection();r.anchorNode&&r.extend&&O(e.display.lineDiv,r.anchorNode)&&(n.anchorNode=r.anchorNode,n.anchorOffset=r.anchorOffset,n.focusNode=r.focusNode,n.focusOffset=r.focusOffset)}return n}(e);return l>4&&(n.lineDiv.style.display="none"),function(e,t,n){var r=e.display,i=e.options.lineNumbers,o=r.lineDiv,a=o.firstChild;function c(t){var n=t.nextSibling;return s&&m&&e.display.currentWheelTarget==t?t.style.display="none":t.parentNode.removeChild(t),n}for(var l=r.view,u=r.viewFrom,f=0;f-1&&(d=!1),un(e,h,u,n)),d&&(C(h.lineNumber),h.lineNumber.appendChild(document.createTextNode(Je(e.options,u)))),a=h.node.nextSibling}else{var p=gn(e,h,u,n);o.insertBefore(p,a)}u+=h.size}for(;a;)a=c(a)}(e,n.updateLineNumbers,t.dims),l>4&&(n.lineDiv.style.display=""),n.renderedView=n.view,function(e){if(e&&e.activeElt&&e.activeElt!=E()&&(e.activeElt.focus(),!/^(INPUT|TEXTAREA)$/.test(e.activeElt.nodeName)&&e.anchorNode&&O(document.body,e.anchorNode)&&O(document.body,e.focusNode))){var t=window.getSelection(),n=document.createRange();n.setEnd(e.anchorNode,e.anchorOffset),n.collapse(!1),t.removeAllRanges(),t.addRange(n),t.extend(e.focusNode,e.focusOffset)}}(u),C(n.cursorDiv),C(n.selectionDiv),n.gutters.style.height=n.sizer.style.minHeight=0,c&&(n.lastWrapHeight=t.wrapperHeight,n.lastWrapWidth=t.wrapperWidth,ri(e,400)),n.updateLineNumbers=null,!0}function ci(e,t){for(var n=t.viewport,r=!0;;r=!1){if(r&&e.options.lineWrapping&&t.oldDisplayWidth!=Cn(e))r&&(t.visible=qr(e.display,e.doc,n));else if(n&&null!=n.top&&(n={top:Math.min(e.doc.height+jn(e.display)-qn(e),n.top)}),t.visible=qr(e.display,e.doc,n),t.visible.from>=e.display.viewFrom&&t.visible.to<=e.display.viewTo)break;if(!ai(e,t))break;_r(e);var i=Vr(e);vr(e),Rr(e,i),ui(e,i),t.force=!1}t.signal(e,"update",e),e.display.viewFrom==e.display.reportedViewFrom&&e.display.viewTo==e.display.reportedViewTo||(t.signal(e,"viewportChange",e,e.display.viewFrom,e.display.viewTo),e.display.reportedViewFrom=e.display.viewFrom,e.display.reportedViewTo=e.display.viewTo)}function si(e,t){var n=new oi(e,t);if(ai(e,n)){_r(e),ci(e,n);var r=Vr(e);vr(e),Rr(e,r),ui(e,r),n.finish()}}function li(e){var t=e.gutters.offsetWidth;e.sizer.style.marginLeft=t+"px"}function ui(e,t){e.display.sizer.style.minHeight=t.docHeight+"px",e.display.heightForcer.style.top=t.docHeight+"px",e.display.gutters.style.height=t.docHeight+e.display.barHeight+_n(e)+"px"}function fi(e){var t=e.display,n=t.view;if(t.alignWidgets||t.gutters.firstChild&&e.options.fixedGutter){for(var r=ar(t)-t.scroller.scrollLeft+e.doc.scrollLeft,i=t.gutters.offsetWidth,o=r+"px",a=0;ac.clientWidth,u=c.scrollHeight>c.clientHeight;if(i&&l||o&&u){if(o&&m&&s)e:for(var h=t.target,d=a.view;h!=c;h=h.parentNode)for(var p=0;p=0&&tt(e,r.to())<=0)return n}return-1};var xi=function(e,t){this.anchor=e,this.head=t};function ji(e,t,n){var r=e&&e.options.selectionsMayTouch,i=t[n];t.sort((function(e,t){return tt(e.from(),t.from())})),n=I(t,i);for(var o=1;o0:s>=0){var l=ot(c.from(),a.from()),u=it(c.to(),a.to()),f=c.empty()?a.from()==a.head:c.from()==c.head;o<=n&&--n,t.splice(--o,2,new xi(f?u:l,f?l:u))}}return new ki(t,n)}function Mi(e,t){return new ki([new xi(e,t||e)],0)}function _i(e){return e.text?et(e.from.line+e.text.length-1,Z(e.text).length+(1==e.text.length?e.from.ch:0)):e.to}function Ci(e,t){if(tt(e,t.from)<0)return e;if(tt(e,t.to)<=0)return _i(t);var n=e.line+t.text.length-(t.to.line-t.from.line)-1,r=e.ch;return e.line==t.to.line&&(r+=_i(t).ch-t.to.ch),et(n,r)}function qi(e,t){for(var n=[],r=0;r1&&e.remove(c.line+1,p-1),e.insert(c.line+1,g)}sn(e,"change",e,t)}function Li(e,t,n){!function e(r,i,o){if(r.linked)for(var a=0;ac-(e.cm?e.cm.options.historyEventDelay:500)||"*"==t.origin.charAt(0)))&&(o=function(e,t){return t?(Ni(e.done),Z(e.done)):e.done.length&&!Z(e.done).ranges?Z(e.done):e.done.length>1&&!e.done[e.done.length-2].ranges?(e.done.pop(),Z(e.done)):void 0}(i,i.lastOp==r)))a=Z(o.changes),0==tt(t.from,t.to)&&0==tt(t.from,a.to)?a.to=_i(t):o.changes.push(Vi(e,t));else{var s=Z(i.done);for(s&&s.ranges||Ri(e.sel,i.done),o={changes:[Vi(e,t)],generation:i.generation},i.done.push(o);i.done.length>i.undoDepth;)i.done.shift(),i.done[0].ranges||i.done.shift()}i.done.push(n),i.generation=++i.maxGeneration,i.lastModTime=i.lastSelTime=c,i.lastOp=i.lastSelOp=r,i.lastOrigin=i.lastSelOrigin=t.origin,a||pe(e,"historyAdded")}function Ri(e,t){var n=Z(t);n&&n.ranges&&n.equals(e)||t.push(e)}function Fi(e,t,n,r){var i=t["spans_"+e.id],o=0;e.iter(Math.max(e.first,n),Math.min(e.first+e.size,r),(function(n){n.markedSpans&&((i||(i=t["spans_"+e.id]={}))[o]=n.markedSpans),++o}))}function Bi(e){if(!e)return null;for(var t,n=0;n-1&&(Z(c)[f]=l[f],delete l[f])}}}return r}function Gi(e,t,n,r){if(r){var i=e.anchor;if(n){var o=tt(t,i)<0;o!=tt(n,i)<0?(i=t,t=n):o!=tt(t,n)<0&&(t=n)}return new xi(i,t)}return new xi(n||t,t)}function Yi(e,t,n,r,i){null==i&&(i=e.cm&&(e.cm.display.shift||e.extend)),Qi(e,new ki([Gi(e.sel.primary(),t,n,i)],0),r)}function Zi(e,t,n){for(var r=[],i=e.cm&&(e.cm.display.shift||e.extend),o=0;o=t.ch:c.to>t.ch))){if(i&&(pe(s,"beforeCursorEnter"),s.explicitlyCleared)){if(o.markedSpans){--a;continue}break}if(!s.atomic)continue;if(n){var f=s.find(r<0?1:-1),h=void 0;if((r<0?u:l)&&(f=oo(e,f,-r,f&&f.line==t.line?o:null)),f&&f.line==t.line&&(h=tt(f,n))&&(r<0?h<0:h>0))return ro(e,f,t,r,i)}var d=s.find(r<0?-1:1);return(r<0?l:u)&&(d=oo(e,d,r,d.line==t.line?o:null)),d?ro(e,d,t,r,i):null}}return t}function io(e,t,n,r,i){var o=r||1;return ro(e,t,n,o,i)||!i&&ro(e,t,n,o,!0)||ro(e,t,n,-o,i)||!i&&ro(e,t,n,-o,!0)||(e.cantEdit=!0,et(e.first,0))}function oo(e,t,n,r){return n<0&&0==t.ch?t.line>e.first?ct(e,et(t.line-1)):null:n>0&&t.ch==(r||Ge(e,t.line)).text.length?t.line0)){var u=[s,1],f=tt(l.from,c.from),h=tt(l.to,c.to);(f<0||!a.inclusiveLeft&&!f)&&u.push({from:l.from,to:c.from}),(h>0||!a.inclusiveRight&&!h)&&u.push({from:c.to,to:l.to}),i.splice.apply(i,u),s+=u.length-3}}return i}(e,t.from,t.to);if(r)for(var i=r.length-1;i>=0;--i)lo(e,{from:r[i].from,to:r[i].to,text:i?[""]:t.text,origin:t.origin});else lo(e,t)}}function lo(e,t){if(1!=t.text.length||""!=t.text[0]||0!=tt(t.from,t.to)){var n=qi(e,t);Ii(e,t,n,e.cm?e.cm.curOp.id:NaN),ho(e,t,n,_t(e,t));var r=[];Li(e,(function(e,n){n||-1!=I(r,e.history)||(go(e.history,t),r.push(e.history)),ho(e,t,null,_t(e,t))}))}}function uo(e,t,n){var r=e.cm&&e.cm.state.suppressEdits;if(!r||n){for(var i,o=e.history,a=e.sel,c="undo"==t?o.done:o.undone,s="undo"==t?o.undone:o.done,l=0;l=0;--d){var p=h(d);if(p)return p.v}}}}function fo(e,t){if(0!=t&&(e.first+=t,e.sel=new ki($(e.sel.ranges,(function(e){return new xi(et(e.anchor.line+t,e.anchor.ch),et(e.head.line+t,e.head.ch))})),e.sel.primIndex),e.cm)){fr(e.cm,e.first,e.first-t,t);for(var n=e.cm.display,r=n.viewFrom;re.lastLine())){if(t.from.lineo&&(t={from:t.from,to:et(o,Ge(e,o).text.length),text:[t.text[0]],origin:t.origin}),t.removed=Ye(e,t.from,t.to),n||(n=qi(e,t)),e.cm?function(e,t,n){var r=e.doc,i=e.display,o=t.from,a=t.to,c=!1,s=o.line;e.options.lineWrapping||(s=Xe(Vt(Ge(r,o.line))),r.iter(s,a.line+1,(function(e){if(e==i.maxLine)return c=!0,!0}))),r.sel.contains(t.from,t.to)>-1&&ve(e),Ai(r,t,n,cr(e)),e.options.lineWrapping||(r.iter(s,o.line+t.text.length,(function(e){var t=Ut(e);t>i.maxLineLength&&(i.maxLine=e,i.maxLineLength=t,i.maxLineChanged=!0,c=!1)})),c&&(e.curOp.updateMaxLine=!0)),function(e,t){if(e.modeFrontier=Math.min(e.modeFrontier,t),!(e.highlightFrontiern;r--){var i=Ge(e,r).stateAfter;if(i&&(!(i instanceof lt)||r+i.lookAhead1||!(this.children[0]instanceof yo))){var c=[];this.collapse(c),this.children=[new yo(c)],this.children[0].parent=this}},collapse:function(e){for(var t=0;t50){for(var a=i.lines.length%25+25,c=a;c10);e.parent.maybeSpill()}},iterN:function(e,t,n){for(var r=0;r0||0==a&&!1!==o.clearWhenEmpty)return o;if(o.replacedWith&&(o.collapsed=!0,o.widgetNode=T("span",[o.replacedWith],"CodeMirror-widget"),r.handleMouseEvents||o.widgetNode.setAttribute("cm-ignore-events","true"),r.insertLeft&&(o.widgetNode.insertLeft=!0)),o.collapsed){if(Pt(e,t.line,t,n,o)||t.line!=n.line&&Pt(e,n.line,t,n,o))throw new Error("Inserting collapsed marker partially overlapping an existing one");kt=!0}o.addToHistory&&Ii(e,{from:t,to:n,origin:"markText"},e.sel,NaN);var c,s=t.line,l=e.cm;if(e.iter(s,n.line+1,(function(e){l&&o.collapsed&&!l.options.lineWrapping&&Vt(e)==l.display.maxLine&&(c=!0),o.collapsed&&s!=t.line&&$e(e,0),function(e,t){e.markedSpans=e.markedSpans?e.markedSpans.concat([t]):[t],t.marker.attachLine(e)}(e,new xt(o,s==t.line?t.ch:null,s==n.line?n.ch:null)),++s})),o.collapsed&&e.iter(t.line,n.line+1,(function(t){Rt(e,t)&&$e(t,0)})),o.clearOnEnter&&fe(o,"beforeCursorEnter",(function(){return o.clear()})),o.readOnly&&(wt=!0,(e.history.done.length||e.history.undone.length)&&e.clearHistory()),o.collapsed&&(o.id=++xo,o.atomic=!0),l){if(c&&(l.curOp.updateMaxLine=!0),o.collapsed)fr(l,t.line,n.line+1);else if(o.className||o.startStyle||o.endStyle||o.css||o.attributes||o.title)for(var u=t.line;u<=n.line;u++)hr(l,u,"text");o.atomic&&to(l.doc),sn(l,"markerAdded",l,o)}return o}jo.prototype.clear=function(){if(!this.explicitlyCleared){var e=this.doc.cm,t=e&&!e.curOp;if(t&&Gr(e),ge(this,"clear")){var n=this.find();n&&sn(this,"clear",n.from,n.to)}for(var r=null,i=null,o=0;oe.display.maxLineLength&&(e.display.maxLine=l,e.display.maxLineLength=u,e.display.maxLineChanged=!0)}null!=r&&e&&this.collapsed&&fr(e,r,i+1),this.lines.length=0,this.explicitlyCleared=!0,this.atomic&&this.doc.cantEdit&&(this.doc.cantEdit=!1,e&&to(e.doc)),e&&sn(e,"markerCleared",e,this,r,i),t&&Yr(e),this.parent&&this.parent.clear()}},jo.prototype.find=function(e,t){var n,r;null==e&&"bookmark"==this.type&&(e=1);for(var i=0;i=0;s--)so(this,r[s]);c?Ki(this,c):this.cm&&Or(this.cm)})),undo:ni((function(){uo(this,"undo")})),redo:ni((function(){uo(this,"redo")})),undoSelection:ni((function(){uo(this,"undo",!0)})),redoSelection:ni((function(){uo(this,"redo",!0)})),setExtending:function(e){this.extend=e},getExtending:function(){return this.extend},historySize:function(){for(var e=this.history,t=0,n=0,r=0;r=e.ch)&&t.push(i.marker.parent||i.marker)}return t},findMarks:function(e,t,n){e=ct(this,e),t=ct(this,t);var r=[],i=e.line;return this.iter(e.line,t.line+1,(function(o){var a=o.markedSpans;if(a)for(var c=0;c=s.to||null==s.from&&i!=e.line||null!=s.from&&i==t.line&&s.from>=t.ch||n&&!n(s.marker)||r.push(s.marker.parent||s.marker)}++i})),r},getAllMarks:function(){var e=[];return this.iter((function(t){var n=t.markedSpans;if(n)for(var r=0;re)return t=e,!0;e-=o,++n})),ct(this,et(n,t))},indexFromPos:function(e){var t=(e=ct(this,e)).ch;if(e.linet&&(t=e.from),null!=e.to&&e.to-1)return t.state.draggingText(e),void setTimeout((function(){return t.display.input.focus()}),20);try{var f=e.dataTransfer.getData("Text");if(f){var h;if(t.state.draggingText&&!t.state.draggingText.copy&&(h=t.listSelections()),Ji(t.doc,Mi(n,n)),h)for(var d=0;d=0;t--)po(e.doc,"",r[t].from,r[t].to,"+delete");Or(e)}))}function Xo(e,t,n){var r=ie(e.text,t+n,n);return r<0||r>e.text.length?null:r}function Ko(e,t,n){var r=Xo(e,t.ch,n);return null==r?null:new et(t.line,r,n<0?"after":"before")}function Qo(e,t,n,r,i){if(e){"rtl"==t.doc.direction&&(i=-i);var o=le(n,t.doc.direction);if(o){var a,c=i<0?Z(o):o[0],s=i<0==(1==c.level)?"after":"before";if(c.level>0||"rtl"==t.doc.direction){var l=En(t,n);a=i<0?n.text.length-1:0;var u=An(t,l,a).top;a=oe((function(e){return An(t,l,e).top==u}),i<0==(1==c.level)?c.from:c.to-1,a),"before"==s&&(a=Xo(n,a,1))}else a=i<0?c.to:c.from;return new et(r,a,s)}}return new et(r,i<0?n.text.length:0,i<0?"before":"after")}Ro.basic={Left:"goCharLeft",Right:"goCharRight",Up:"goLineUp",Down:"goLineDown",End:"goLineEnd",Home:"goLineStartSmart",PageUp:"goPageUp",PageDown:"goPageDown",Delete:"delCharAfter",Backspace:"delCharBefore","Shift-Backspace":"delCharBefore",Tab:"defaultTab","Shift-Tab":"indentAuto",Enter:"newlineAndIndent",Insert:"toggleOverwrite",Esc:"singleSelection"},Ro.pcDefault={"Ctrl-A":"selectAll","Ctrl-D":"deleteLine","Ctrl-Z":"undo","Shift-Ctrl-Z":"redo","Ctrl-Y":"redo","Ctrl-Home":"goDocStart","Ctrl-End":"goDocEnd","Ctrl-Up":"goLineUp","Ctrl-Down":"goLineDown","Ctrl-Left":"goGroupLeft","Ctrl-Right":"goGroupRight","Alt-Left":"goLineStart","Alt-Right":"goLineEnd","Ctrl-Backspace":"delGroupBefore","Ctrl-Delete":"delGroupAfter","Ctrl-S":"save","Ctrl-F":"find","Ctrl-G":"findNext","Shift-Ctrl-G":"findPrev","Shift-Ctrl-F":"replace","Shift-Ctrl-R":"replaceAll","Ctrl-[":"indentLess","Ctrl-]":"indentMore","Ctrl-U":"undoSelection","Shift-Ctrl-U":"redoSelection","Alt-U":"redoSelection",fallthrough:"basic"},Ro.emacsy={"Ctrl-F":"goCharRight","Ctrl-B":"goCharLeft","Ctrl-P":"goLineUp","Ctrl-N":"goLineDown","Alt-F":"goWordRight","Alt-B":"goWordLeft","Ctrl-A":"goLineStart","Ctrl-E":"goLineEnd","Ctrl-V":"goPageDown","Shift-Ctrl-V":"goPageUp","Ctrl-D":"delCharAfter","Ctrl-H":"delCharBefore","Alt-D":"delWordAfter","Alt-Backspace":"delWordBefore","Ctrl-K":"killLine","Ctrl-T":"transposeChars","Ctrl-O":"openLine"},Ro.macDefault={"Cmd-A":"selectAll","Cmd-D":"deleteLine","Cmd-Z":"undo","Shift-Cmd-Z":"redo","Cmd-Y":"redo","Cmd-Home":"goDocStart","Cmd-Up":"goDocStart","Cmd-End":"goDocEnd","Cmd-Down":"goDocEnd","Alt-Left":"goGroupLeft","Alt-Right":"goGroupRight","Cmd-Left":"goLineLeft","Cmd-Right":"goLineRight","Alt-Backspace":"delGroupBefore","Ctrl-Alt-Backspace":"delGroupAfter","Alt-Delete":"delGroupAfter","Cmd-S":"save","Cmd-F":"find","Cmd-G":"findNext","Shift-Cmd-G":"findPrev","Cmd-Alt-F":"replace","Shift-Cmd-Alt-F":"replaceAll","Cmd-[":"indentLess","Cmd-]":"indentMore","Cmd-Backspace":"delWrappedLineLeft","Cmd-Delete":"delWrappedLineRight","Cmd-U":"undoSelection","Shift-Cmd-U":"redoSelection","Ctrl-Up":"goDocStart","Ctrl-Down":"goDocEnd",fallthrough:["basic","emacsy"]},Ro.default=m?Ro.macDefault:Ro.pcDefault;var Jo={selectAll:ao,singleSelection:function(e){return e.setSelection(e.getCursor("anchor"),e.getCursor("head"),F)},killLine:function(e){return $o(e,(function(t){if(t.empty()){var n=Ge(e.doc,t.head.line).text.length;return t.head.ch==n&&t.head.line0)i=new et(i.line,i.ch+1),e.replaceRange(o.charAt(i.ch-1)+o.charAt(i.ch-2),et(i.line,i.ch-2),i,"+transpose");else if(i.line>e.doc.first){var a=Ge(e.doc,i.line-1).text;a&&(i=new et(i.line,1),e.replaceRange(o.charAt(0)+e.doc.lineSeparator()+a.charAt(a.length-1),et(i.line-1,a.length-1),i,"+transpose"))}n.push(new xi(i,i))}e.setSelections(n)}))},newlineAndIndent:function(e){return Jr(e,(function(){for(var t=e.listSelections(),n=t.length-1;n>=0;n--)e.replaceRange(e.doc.lineSeparator(),t[n].anchor,t[n].head,"+input");t=e.listSelections();for(var r=0;r-1&&(tt((i=l.ranges[i]).from(),t)<0||t.xRel>0)&&(tt(i.to(),t)>0||t.xRel<0)?function(e,t,n,r){var i=e.display,o=!1,l=ei(e,(function(t){s&&(i.scroller.draggable=!1),e.state.draggingText=!1,de(i.wrapper.ownerDocument,"mouseup",l),de(i.wrapper.ownerDocument,"mousemove",u),de(i.scroller,"dragstart",f),de(i.scroller,"drop",l),o||(ye(t),r.addNew||Yi(e.doc,n,null,null,r.extend),s&&!h||a&&9==c?setTimeout((function(){i.wrapper.ownerDocument.body.focus({preventScroll:!0}),i.input.focus()}),20):i.input.focus())})),u=function(e){o=o||Math.abs(t.clientX-e.clientX)+Math.abs(t.clientY-e.clientY)>=10},f=function(){return o=!0};s&&(i.scroller.draggable=!0),e.state.draggingText=l,l.copy=!r.moveOnDrag,i.scroller.dragDrop&&i.scroller.dragDrop(),fe(i.wrapper.ownerDocument,"mouseup",l),fe(i.wrapper.ownerDocument,"mousemove",u),fe(i.scroller,"dragstart",f),fe(i.scroller,"drop",l),xr(e),setTimeout((function(){return i.input.focus()}),20)}(e,r,t,o):function(e,t,n,r){var i=e.display,o=e.doc;ye(t);var a,c,s=o.sel,l=s.ranges;if(r.addNew&&!r.extend?(c=o.sel.contains(n),a=c>-1?l[c]:new xi(n,n)):(a=o.sel.primary(),c=o.sel.primIndex),"rectangle"==r.unit)r.addNew||(a=new xi(n,n)),n=lr(e,t,!0,!0),c=-1;else{var u=za(e,n,r.unit);a=r.extend?Gi(a,u.anchor,u.head,r.extend):u}r.addNew?-1==c?(c=l.length,Qi(o,ji(e,l.concat([a]),c),{scroll:!1,origin:"*mouse"})):l.length>1&&l[c].empty()&&"char"==r.unit&&!r.extend?(Qi(o,ji(e,l.slice(0,c).concat(l.slice(c+1)),0),{scroll:!1,origin:"*mouse"}),s=o.sel):$i(o,c,a,B):(c=0,Qi(o,new ki([a],0),B),s=o.sel);var f=n;function h(t){if(0!=tt(f,t))if(f=t,"rectangle"==r.unit){for(var i=[],l=e.options.tabSize,u=V(Ge(o,n.line).text,n.ch,l),h=V(Ge(o,t.line).text,t.ch,l),d=Math.min(u,h),p=Math.max(u,h),z=Math.min(n.line,t.line),v=Math.min(e.lastLine(),Math.max(n.line,t.line));z<=v;z++){var g=Ge(o,z).text,m=W(g,d,l);d==p?i.push(new xi(et(z,m),et(z,m))):g.length>m&&i.push(new xi(et(z,m),et(z,W(g,p,l))))}i.length||i.push(new xi(n,n)),Qi(o,ji(e,s.ranges.slice(0,c).concat(i),c),{origin:"*mouse",scroll:!1}),e.scrollIntoView(t)}else{var y,b=a,w=za(e,t,r.unit),k=b.anchor;tt(w.anchor,k)>0?(y=w.head,k=ot(b.from(),w.anchor)):(y=w.anchor,k=it(b.to(),w.head));var x=s.ranges.slice(0);x[c]=function(e,t){var n=t.anchor,r=t.head,i=Ge(e.doc,n.line);if(0==tt(n,r)&&n.sticky==r.sticky)return t;var o=le(i);if(!o)return t;var a=ce(o,n.ch,n.sticky),c=o[a];if(c.from!=n.ch&&c.to!=n.ch)return t;var s,l=a+(c.from==n.ch==(1!=c.level)?0:1);if(0==l||l==o.length)return t;if(r.line!=n.line)s=(r.line-n.line)*("ltr"==e.doc.direction?1:-1)>0;else{var u=ce(o,r.ch,r.sticky),f=u-a||(r.ch-n.ch)*(1==c.level?-1:1);s=u==l-1||u==l?f<0:f>0}var h=o[l+(s?-1:0)],d=s==(1==h.level),p=d?h.from:h.to,z=d?"after":"before";return n.ch==p&&n.sticky==z?t:new xi(new et(n.line,p,z),r)}(e,new xi(ct(o,k),y)),Qi(o,ji(e,x,c),B)}}var d=i.wrapper.getBoundingClientRect(),p=0;function z(t){e.state.selectingText=!1,p=1/0,t&&(ye(t),i.input.focus()),de(i.wrapper.ownerDocument,"mousemove",v),de(i.wrapper.ownerDocument,"mouseup",g),o.history.lastSelOrigin=null}var v=ei(e,(function(t){0!==t.buttons&&je(t)?function t(n){var a=++p,c=lr(e,n,!0,"rectangle"==r.unit);if(c)if(0!=tt(c,f)){e.curOp.focus=E(),h(c);var s=qr(i,o);(c.line>=s.to||c.lined.bottom?20:0;l&&setTimeout(ei(e,(function(){p==a&&(i.scroller.scrollTop+=l,t(n))})),50)}}(t):z(t)})),g=ei(e,z);e.state.selectingText=g,fe(i.wrapper.ownerDocument,"mousemove",v),fe(i.wrapper.ownerDocument,"mouseup",g)}(e,r,t,o)}(t,r,o,e):xe(e)==n.scroller&&ye(e):2==i?(r&&Yi(t.doc,r),setTimeout((function(){return n.input.focus()}),20)):3==i&&(x?t.display.input.onContextMenu(e):xr(t)))}}function za(e,t,n){if("char"==n)return new xi(t,t);if("word"==n)return e.findWordAt(t);if("line"==n)return new xi(et(t.line,0),ct(e.doc,et(t.line+1,0)));var r=n(e,t);return new xi(r.from,r.to)}function va(e,t,n,r){var i,o;if(t.touches)i=t.touches[0].clientX,o=t.touches[0].clientY;else try{i=t.clientX,o=t.clientY}catch(e){return!1}if(i>=Math.floor(e.display.gutters.getBoundingClientRect().right))return!1;r&&ye(t);var a=e.display,c=a.lineDiv.getBoundingClientRect();if(o>c.bottom||!ge(e,n))return we(t);o-=c.top-a.viewOffset;for(var s=0;s=i)return pe(e,n,e,Ke(e.doc,o),e.display.gutterSpecs[s].className,t),we(t)}}function ga(e,t){return va(e,t,"gutterClick",!0)}function ma(e,t){kn(e.display,t)||function(e,t){return!!ge(e,"gutterContextMenu")&&va(e,t,"gutterContextMenu",!1)}(e,t)||ze(e,t,"contextmenu")||x||e.display.input.onContextMenu(t)}function ya(e){e.display.wrapper.className=e.display.wrapper.className.replace(/\s*cm-s-\S+/g,"")+e.options.theme.replace(/(^|\s)\s*/g," cm-s-"),In(e)}da.prototype.compare=function(e,t,n){return this.time+400>e&&0==tt(t,this.pos)&&n==this.button};var ba={toString:function(){return"CodeMirror.Init"}},wa={},ka={};function xa(e,t,n){if(!t!=!(n&&n!=ba)){var r=e.display.dragFunctions,i=t?fe:de;i(e.display.scroller,"dragstart",r.start),i(e.display.scroller,"dragenter",r.enter),i(e.display.scroller,"dragover",r.over),i(e.display.scroller,"dragleave",r.leave),i(e.display.scroller,"drop",r.drop)}}function ja(e){e.options.lineWrapping?(A(e.display.wrapper,"CodeMirror-wrap"),e.display.sizer.style.minWidth="",e.display.sizerWidth=null):(_(e.display.wrapper,"CodeMirror-wrap"),Wt(e)),sr(e),fr(e),In(e),setTimeout((function(){return Rr(e)}),100)}function Ma(e,t){var n=this;if(!(this instanceof Ma))return new Ma(e,t);this.options=t=t?P(t):{},P(wa,t,!1);var r=t.value;"string"==typeof r?r=new To(r,t.mode,null,t.lineSeparator,t.direction):t.mode&&(r.modeOption=t.mode),this.doc=r;var i=new Ma.inputStyles[t.inputStyle](this),o=this.display=new vi(e,r,i,t);for(var l in o.wrapper.CodeMirror=this,ya(this),t.lineWrapping&&(this.display.wrapper.className+=" CodeMirror-wrap"),Ur(this),this.state={keyMaps:[],overlays:[],modeGen:0,overwrite:!1,delayingBlurEvent:!1,focused:!1,suppressEdits:!1,pasteIncoming:-1,cutIncoming:-1,selectingText:!1,draggingText:!1,highlight:new N,keySeq:null,specialChars:null},t.autofocus&&!g&&o.input.focus(),a&&c<11&&setTimeout((function(){return n.display.input.reset(!0)}),20),function(e){var t=e.display;fe(t.scroller,"mousedown",ei(e,pa)),fe(t.scroller,"dblclick",a&&c<11?ei(e,(function(t){if(!ze(e,t)){var n=lr(e,t);if(n&&!ga(e,t)&&!kn(e.display,t)){ye(t);var r=e.findWordAt(n);Yi(e.doc,r.anchor,r.head)}}})):function(t){return ze(e,t)||ye(t)}),fe(t.scroller,"contextmenu",(function(t){return ma(e,t)})),fe(t.input.getField(),"contextmenu",(function(n){t.scroller.contains(n.target)||ma(e,n)}));var n,r={end:0};function i(){t.activeTouch&&(n=setTimeout((function(){return t.activeTouch=null}),1e3),(r=t.activeTouch).end=+new Date)}function o(e,t){if(null==t.left)return!0;var n=t.left-e.left,r=t.top-e.top;return n*n+r*r>400}fe(t.scroller,"touchstart",(function(i){if(!ze(e,i)&&!function(e){if(1!=e.touches.length)return!1;var t=e.touches[0];return t.radiusX<=1&&t.radiusY<=1}(i)&&!ga(e,i)){t.input.ensurePolled(),clearTimeout(n);var o=+new Date;t.activeTouch={start:o,moved:!1,prev:o-r.end<=300?r:null},1==i.touches.length&&(t.activeTouch.left=i.touches[0].pageX,t.activeTouch.top=i.touches[0].pageY)}})),fe(t.scroller,"touchmove",(function(){t.activeTouch&&(t.activeTouch.moved=!0)})),fe(t.scroller,"touchend",(function(n){var r=t.activeTouch;if(r&&!kn(t,n)&&null!=r.left&&!r.moved&&new Date-r.start<300){var a,c=e.coordsChar(t.activeTouch,"page");a=!r.prev||o(r,r.prev)?new xi(c,c):!r.prev.prev||o(r,r.prev.prev)?e.findWordAt(c):new xi(et(c.line,0),ct(e.doc,et(c.line+1,0))),e.setSelection(a.anchor,a.head),e.focus(),ye(n)}i()})),fe(t.scroller,"touchcancel",i),fe(t.scroller,"scroll",(function(){t.scroller.clientHeight&&(Hr(e,t.scroller.scrollTop),Pr(e,t.scroller.scrollLeft,!0),pe(e,"scroll",e))})),fe(t.scroller,"mousewheel",(function(t){return wi(e,t)})),fe(t.scroller,"DOMMouseScroll",(function(t){return wi(e,t)})),fe(t.wrapper,"scroll",(function(){return t.wrapper.scrollTop=t.wrapper.scrollLeft=0})),t.dragFunctions={enter:function(t){ze(e,t)||ke(t)},over:function(t){ze(e,t)||(function(e,t){var n=lr(e,t);if(n){var r=document.createDocumentFragment();mr(e,n,r),e.display.dragCursor||(e.display.dragCursor=S("div",null,"CodeMirror-cursors CodeMirror-dragcursors"),e.display.lineSpace.insertBefore(e.display.dragCursor,e.display.cursorDiv)),q(e.display.dragCursor,r)}}(e,t),ke(t))},start:function(t){return function(e,t){if(a&&(!e.state.draggingText||+new Date-Oo<100))ke(t);else if(!ze(e,t)&&!kn(e.display,t)&&(t.dataTransfer.setData("Text",e.getSelection()),t.dataTransfer.effectAllowed="copyMove",t.dataTransfer.setDragImage&&!h)){var n=S("img",null,null,"position: fixed; left: 0; top: 0;");n.src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",f&&(n.width=n.height=1,e.display.wrapper.appendChild(n),n._top=n.offsetTop),t.dataTransfer.setDragImage(n,0,0),f&&n.parentNode.removeChild(n)}}(e,t)},drop:ei(e,Eo),leave:function(t){ze(e,t)||Ao(e)}};var s=t.input.getField();fe(s,"keyup",(function(t){return la.call(e,t)})),fe(s,"keydown",ei(e,sa)),fe(s,"keypress",ei(e,ua)),fe(s,"focus",(function(t){return jr(e,t)})),fe(s,"blur",(function(t){return Mr(e,t)}))}(this),function(){var e;Ho||(fe(window,"resize",(function(){null==e&&(e=setTimeout((function(){e=null,Lo(Do)}),100))})),fe(window,"blur",(function(){return Lo(Mr)})),Ho=!0)}(),Gr(this),this.curOp.forceUpdate=!0,Hi(this,r),t.autofocus&&!g||this.hasFocus()?setTimeout(D(jr,this),20):Mr(this),ka)ka.hasOwnProperty(l)&&ka[l](this,t[l],ba);hi(this),t.finishInit&&t.finishInit(this);for(var u=0;u<_a.length;++u)_a[u](this);Yr(this),s&&t.lineWrapping&&"optimizelegibility"==getComputedStyle(o.lineDiv).textRendering&&(o.lineDiv.style.textRendering="auto")}Ma.defaults=wa,Ma.optionHandlers=ka;var _a=[];function Ca(e,t,n,r){var i,o=e.doc;null==n&&(n="add"),"smart"==n&&(o.mode.indent?i=dt(e,t).state:n="prev");var a=e.options.tabSize,c=Ge(o,t),s=V(c.text,null,a);c.stateAfter&&(c.stateAfter=null);var l,u=c.text.match(/^\s*/)[0];if(r||/\S/.test(c.text)){if("smart"==n&&((l=o.mode.indent(i,c.text.slice(u.length),c.text))==R||l>150)){if(!r)return;n="prev"}}else l=0,n="not";"prev"==n?l=t>o.first?V(Ge(o,t-1).text,null,a):0:"add"==n?l=s+e.options.indentUnit:"subtract"==n?l=s-e.options.indentUnit:"number"==typeof n&&(l=s+n),l=Math.max(0,l);var f="",h=0;if(e.options.indentWithTabs)for(var d=Math.floor(l/a);d;--d)h+=a,f+="\t";if(ha,s=Oe(t),l=null;if(c&&r.ranges.length>1)if(qa&&qa.text.join("\n")==t){if(r.ranges.length%qa.text.length==0){l=[];for(var u=0;u=0;h--){var d=r.ranges[h],p=d.from(),z=d.to();d.empty()&&(n&&n>0?p=et(p.line,p.ch-n):e.state.overwrite&&!c?z=et(z.line,Math.min(Ge(o,z.line).text.length,z.ch+Z(s).length)):c&&qa&&qa.lineWise&&qa.text.join("\n")==s.join("\n")&&(p=z=et(p.line,0)));var v={from:p,to:z,text:l?l[h%l.length]:s,origin:i||(c?"paste":e.state.cutIncoming>a?"cut":"+input")};so(e.doc,v),sn(e,"inputRead",e,v)}t&&!c&&Ea(e,t),Or(e),e.curOp.updateInput<2&&(e.curOp.updateInput=f),e.curOp.typing=!0,e.state.pasteIncoming=e.state.cutIncoming=-1}function Oa(e,t){var n=e.clipboardData&&e.clipboardData.getData("Text");if(n)return e.preventDefault(),t.isReadOnly()||t.options.disableInput||Jr(t,(function(){return Ta(t,n,0,null,"paste")})),!0}function Ea(e,t){if(e.options.electricChars&&e.options.smartIndent)for(var n=e.doc.sel,r=n.ranges.length-1;r>=0;r--){var i=n.ranges[r];if(!(i.head.ch>100||r&&n.ranges[r-1].head.line==i.head.line)){var o=e.getModeAt(i.head),a=!1;if(o.electricChars){for(var c=0;c-1){a=Ca(e,i.head.line,"smart");break}}else o.electricInput&&o.electricInput.test(Ge(e.doc,i.head.line).text.slice(0,i.head.ch))&&(a=Ca(e,i.head.line,"smart"));a&&sn(e,"electricInput",e,i.head.line)}}}function Aa(e){for(var t=[],n=[],r=0;r=t.text.length?(n.ch=t.text.length,n.sticky="before"):n.ch<=0&&(n.ch=0,n.sticky="after");var o=ce(i,n.ch,n.sticky),a=i[o];if("ltr"==e.doc.direction&&a.level%2==0&&(r>0?a.to>n.ch:a.from=a.from&&h>=u.begin)){var d=f?"before":"after";return new et(n.line,h,d)}}var p=function(e,t,r){for(var o=function(e,t){return t?new et(n.line,s(e,1),"before"):new et(n.line,e,"after")};e>=0&&e0==(1!=a.level),l=c?r.begin:s(r.end,-1);if(a.from<=l&&l0?u.end:s(u.begin,-1);return null==v||r>0&&v==t.text.length||!(z=p(r>0?0:i.length-1,r,l(v)))?null:z}(e.cm,c,t,n):Ko(c,t,n))){if(r||(a=t.line+s)=e.first+e.size||(t=new et(a,t.ch,t.sticky),!(c=Ge(e,a))))return!1;t=Qo(i,e.cm,c,t.line,s)}else t=o;return!0}if("char"==r)l();else if("column"==r)l(!0);else if("word"==r||"group"==r)for(var u=null,f="group"==r,h=e.cm&&e.cm.getHelper(t,"wordChars"),d=!0;!(n<0)||l(!d);d=!1){var p=c.text.charAt(t.ch)||"\n",z=ee(p,h)?"w":f&&"\n"==p?"n":!f||/\s/.test(p)?null:"p";if(!f||d||z||(z="s"),u&&u!=z){n<0&&(n=1,l(),t.sticky="after");break}if(z&&(u=z),n>0&&!l(!d))break}var v=io(e,t,o,a,!0);return nt(o,v)&&(v.hitSide=!0),v}function Pa(e,t,n,r){var i,o,a=e.doc,c=t.left;if("page"==r){var s=Math.min(e.display.wrapper.clientHeight,window.innerHeight||document.documentElement.clientHeight),l=Math.max(s-.5*rr(e.display),3);i=(n>0?t.bottom:t.top)+n*l}else"line"==r&&(i=n>0?t.bottom+3:t.top-3);for(;(o=Xn(e,c,i)).outside;){if(n<0?i<=0:i>=a.height){o.hitSide=!0;break}i+=5*n}return o}var Va=function(e){this.cm=e,this.lastAnchorNode=this.lastAnchorOffset=this.lastFocusNode=this.lastFocusOffset=null,this.polling=new N,this.composing=null,this.gracePeriod=!1,this.readDOMTimeout=null};function Na(e,t){var n=On(e,t.line);if(!n||n.hidden)return null;var r=Ge(e.doc,t.line),i=Sn(n,r,t.line),o=le(r,e.doc.direction),a="left";o&&(a=ce(o,t.ch)%2?"right":"left");var c=Dn(i.map,t.ch,a);return c.offset="right"==c.collapse?c.end:c.start,c}function Ia(e,t){return t&&(e.bad=!0),e}function Ra(e,t,n){var r;if(t==e.display.lineDiv){if(!(r=e.display.lineDiv.childNodes[n]))return Ia(e.clipPos(et(e.display.viewTo-1)),!0);t=null,n=0}else for(r=t;;r=r.parentNode){if(!r||r==e.display.lineDiv)return null;if(r.parentNode&&r.parentNode==e.display.lineDiv)break}for(var i=0;i=t.display.viewTo||o.line=t.display.viewFrom&&Na(t,i)||{node:s[0].measure.map[2],offset:0},u=o.liner.firstLine()&&(a=et(a.line-1,Ge(r.doc,a.line-1).length)),c.ch==Ge(r.doc,c.line).text.length&&c.linei.viewTo-1)return!1;a.line==i.viewFrom||0==(e=ur(r,a.line))?(t=Xe(i.view[0].line),n=i.view[0].node):(t=Xe(i.view[e].line),n=i.view[e-1].node.nextSibling);var s,l,u=ur(r,c.line);if(u==i.view.length-1?(s=i.viewTo-1,l=i.lineDiv.lastChild):(s=Xe(i.view[u+1].line)-1,l=i.view[u+1].node.previousSibling),!n)return!1;for(var f=r.doc.splitLines(function(e,t,n,r,i){var o="",a=!1,c=e.doc.lineSeparator(),s=!1;function l(){a&&(o+=c,s&&(o+=c),a=s=!1)}function u(e){e&&(l(),o+=e)}function f(t){if(1==t.nodeType){var n=t.getAttribute("cm-text");if(n)return void u(n);var o,h=t.getAttribute("cm-marker");if(h){var d=e.findMarks(et(r,0),et(i+1,0),(v=+h,function(e){return e.id==v}));return void(d.length&&(o=d[0].find(0))&&u(Ye(e.doc,o.from,o.to).join(c)))}if("false"==t.getAttribute("contenteditable"))return;var p=/^(pre|div|p|li|table|br)$/i.test(t.nodeName);if(!/^br$/i.test(t.nodeName)&&0==t.textContent.length)return;p&&l();for(var z=0;z1&&h.length>1;)if(Z(f)==Z(h))f.pop(),h.pop(),s--;else{if(f[0]!=h[0])break;f.shift(),h.shift(),t++}for(var d=0,p=0,z=f[0],v=h[0],g=Math.min(z.length,v.length);da.ch&&m.charCodeAt(m.length-p-1)==y.charCodeAt(y.length-p-1);)d--,p++;f[f.length-1]=m.slice(0,m.length-p).replace(/^\u200b+/,""),f[0]=f[0].slice(d).replace(/\u200b+$/,"");var w=et(t,d),k=et(s,h.length?Z(h).length-p:0);return f.length>1||f[0]||tt(w,k)?(po(r.doc,f,w,k,"+input"),!0):void 0},Va.prototype.ensurePolled=function(){this.forceCompositionEnd()},Va.prototype.reset=function(){this.forceCompositionEnd()},Va.prototype.forceCompositionEnd=function(){this.composing&&(clearTimeout(this.readDOMTimeout),this.composing=null,this.updateFromDOM(),this.div.blur(),this.div.focus())},Va.prototype.readFromDOMSoon=function(){var e=this;null==this.readDOMTimeout&&(this.readDOMTimeout=setTimeout((function(){if(e.readDOMTimeout=null,e.composing){if(!e.composing.done)return;e.composing=null}e.updateFromDOM()}),80))},Va.prototype.updateFromDOM=function(){var e=this;!this.cm.isReadOnly()&&this.pollContent()||Jr(this.cm,(function(){return fr(e.cm)}))},Va.prototype.setUneditable=function(e){e.contentEditable="false"},Va.prototype.onKeyPress=function(e){0==e.charCode||this.composing||(e.preventDefault(),this.cm.isReadOnly()||ei(this.cm,Ta)(this.cm,String.fromCharCode(null==e.charCode?e.keyCode:e.charCode),0))},Va.prototype.readOnlyChanged=function(e){this.div.contentEditable=String("nocursor"!=e)},Va.prototype.onContextMenu=function(){},Va.prototype.resetPosition=function(){},Va.prototype.needsContentAttribute=!0;var Ba=function(e){this.cm=e,this.prevInput="",this.pollingFast=!1,this.polling=new N,this.hasSelection=!1,this.composing=null};Ba.prototype.init=function(e){var t=this,n=this,r=this.cm;this.createField(e);var i=this.textarea;function o(e){if(!ze(r,e)){if(r.somethingSelected())Sa({lineWise:!1,text:r.getSelections()});else{if(!r.options.lineWiseCopyCut)return;var t=Aa(r);Sa({lineWise:!0,text:t.text}),"cut"==e.type?r.setSelections(t.ranges,null,F):(n.prevInput="",i.value=t.text.join("\n"),H(i))}"cut"==e.type&&(r.state.cutIncoming=+new Date)}}e.wrapper.insertBefore(this.wrapper,e.wrapper.firstChild),z&&(i.style.width="0px"),fe(i,"input",(function(){a&&c>=9&&t.hasSelection&&(t.hasSelection=null),n.poll()})),fe(i,"paste",(function(e){ze(r,e)||Oa(e,r)||(r.state.pasteIncoming=+new Date,n.fastPoll())})),fe(i,"cut",o),fe(i,"copy",o),fe(e.scroller,"paste",(function(t){if(!kn(e,t)&&!ze(r,t)){if(!i.dispatchEvent)return r.state.pasteIncoming=+new Date,void n.focus();var o=new Event("paste");o.clipboardData=t.clipboardData,i.dispatchEvent(o)}})),fe(e.lineSpace,"selectstart",(function(t){kn(e,t)||ye(t)})),fe(i,"compositionstart",(function(){var e=r.getCursor("from");n.composing&&n.composing.range.clear(),n.composing={start:e,range:r.markText(e,r.getCursor("to"),{className:"CodeMirror-composing"})}})),fe(i,"compositionend",(function(){n.composing&&(n.poll(),n.composing.range.clear(),n.composing=null)}))},Ba.prototype.createField=function(e){this.wrapper=Ha(),this.textarea=this.wrapper.firstChild},Ba.prototype.screenReaderLabelChanged=function(e){e?this.textarea.setAttribute("aria-label",e):this.textarea.removeAttribute("aria-label")},Ba.prototype.prepareSelection=function(){var e=this.cm,t=e.display,n=e.doc,r=gr(e);if(e.options.moveInputWithCursor){var i=Yn(e,n.sel.primary().head,"div"),o=t.wrapper.getBoundingClientRect(),a=t.lineDiv.getBoundingClientRect();r.teTop=Math.max(0,Math.min(t.wrapper.clientHeight-10,i.top+a.top-o.top)),r.teLeft=Math.max(0,Math.min(t.wrapper.clientWidth-10,i.left+a.left-o.left))}return r},Ba.prototype.showSelection=function(e){var t=this.cm.display;q(t.cursorDiv,e.cursors),q(t.selectionDiv,e.selection),null!=e.teTop&&(this.wrapper.style.top=e.teTop+"px",this.wrapper.style.left=e.teLeft+"px")},Ba.prototype.reset=function(e){if(!this.contextMenuPending&&!this.composing){var t=this.cm;if(t.somethingSelected()){this.prevInput="";var n=t.getSelection();this.textarea.value=n,t.state.focused&&H(this.textarea),a&&c>=9&&(this.hasSelection=n)}else e||(this.prevInput=this.textarea.value="",a&&c>=9&&(this.hasSelection=null))}},Ba.prototype.getField=function(){return this.textarea},Ba.prototype.supportsTouch=function(){return!1},Ba.prototype.focus=function(){if("nocursor"!=this.cm.options.readOnly&&(!g||E()!=this.textarea))try{this.textarea.focus()}catch(e){}},Ba.prototype.blur=function(){this.textarea.blur()},Ba.prototype.resetPosition=function(){this.wrapper.style.top=this.wrapper.style.left=0},Ba.prototype.receivedFocus=function(){this.slowPoll()},Ba.prototype.slowPoll=function(){var e=this;this.pollingFast||this.polling.set(this.cm.options.pollInterval,(function(){e.poll(),e.cm.state.focused&&e.slowPoll()}))},Ba.prototype.fastPoll=function(){var e=!1,t=this;t.pollingFast=!0,t.polling.set(20,(function n(){t.poll()||e?(t.pollingFast=!1,t.slowPoll()):(e=!0,t.polling.set(60,n))}))},Ba.prototype.poll=function(){var e=this,t=this.cm,n=this.textarea,r=this.prevInput;if(this.contextMenuPending||!t.state.focused||Ee(n)&&!r&&!this.composing||t.isReadOnly()||t.options.disableInput||t.state.keySeq)return!1;var i=n.value;if(i==r&&!t.somethingSelected())return!1;if(a&&c>=9&&this.hasSelection===i||m&&/[\uf700-\uf7ff]/.test(i))return t.display.input.reset(),!1;if(t.doc.sel==t.display.selForContextMenu){var o=i.charCodeAt(0);if(8203!=o||r||(r="\u200b"),8666==o)return this.reset(),this.cm.execCommand("undo")}for(var s=0,l=Math.min(r.length,i.length);s1e3||i.indexOf("\n")>-1?n.value=e.prevInput="":e.prevInput=i,e.composing&&(e.composing.range.clear(),e.composing.range=t.markText(e.composing.start,t.getCursor("to"),{className:"CodeMirror-composing"}))})),!0},Ba.prototype.ensurePolled=function(){this.pollingFast&&this.poll()&&(this.pollingFast=!1)},Ba.prototype.onKeyPress=function(){a&&c>=9&&(this.hasSelection=null),this.fastPoll()},Ba.prototype.onContextMenu=function(e){var t=this,n=t.cm,r=n.display,i=t.textarea;t.contextMenuPending&&t.contextMenuPending();var o=lr(n,e),l=r.scroller.scrollTop;if(o&&!f){n.options.resetSelectionOnContextMenu&&-1==n.doc.sel.contains(o)&&ei(n,Qi)(n.doc,Mi(o),F);var u,h=i.style.cssText,d=t.wrapper.style.cssText,p=t.wrapper.offsetParent.getBoundingClientRect();t.wrapper.style.cssText="position: static",i.style.cssText="position: absolute; width: 30px; height: 30px;\n top: "+(e.clientY-p.top-5)+"px; left: "+(e.clientX-p.left-5)+"px;\n z-index: 1000; background: "+(a?"rgba(255, 255, 255, .05)":"transparent")+";\n outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);",s&&(u=window.scrollY),r.input.focus(),s&&window.scrollTo(null,u),r.input.reset(),n.somethingSelected()||(i.value=t.prevInput=" "),t.contextMenuPending=v,r.selForContextMenu=n.doc.sel,clearTimeout(r.detectingSelectAll),a&&c>=9&&z(),x?(ke(e),fe(window,"mouseup",(function e(){de(window,"mouseup",e),setTimeout(v,20)}))):setTimeout(v,50)}function z(){if(null!=i.selectionStart){var e=n.somethingSelected(),o="\u200b"+(e?i.value:"");i.value="\u21da",i.value=o,t.prevInput=e?"":"\u200b",i.selectionStart=1,i.selectionEnd=o.length,r.selForContextMenu=n.doc.sel}}function v(){if(t.contextMenuPending==v&&(t.contextMenuPending=!1,t.wrapper.style.cssText=d,i.style.cssText=h,a&&c<9&&r.scrollbars.setScrollTop(r.scroller.scrollTop=l),null!=i.selectionStart)){(!a||a&&c<9)&&z();var e=0;r.detectingSelectAll=setTimeout((function o(){r.selForContextMenu==n.doc.sel&&0==i.selectionStart&&i.selectionEnd>0&&"\u200b"==t.prevInput?ei(n,ao)(n):e++<10?r.detectingSelectAll=setTimeout(o,500):(r.selForContextMenu=null,r.input.reset())}),200)}}},Ba.prototype.readOnlyChanged=function(e){e||this.reset(),this.textarea.disabled="nocursor"==e},Ba.prototype.setUneditable=function(){},Ba.prototype.needsContentAttribute=!1,function(e){var t=e.optionHandlers;function n(n,r,i,o){e.defaults[n]=r,i&&(t[n]=o?function(e,t,n){n!=ba&&i(e,t,n)}:i)}e.defineOption=n,e.Init=ba,n("value","",(function(e,t){return e.setValue(t)}),!0),n("mode",null,(function(e,t){e.doc.modeOption=t,Ti(e)}),!0),n("indentUnit",2,Ti,!0),n("indentWithTabs",!1),n("smartIndent",!0),n("tabSize",4,(function(e){Oi(e),In(e),fr(e)}),!0),n("lineSeparator",null,(function(e,t){if(e.doc.lineSep=t,t){var n=[],r=e.doc.first;e.doc.iter((function(e){for(var i=0;;){var o=e.text.indexOf(t,i);if(-1==o)break;i=o+t.length,n.push(et(r,o))}r++}));for(var i=n.length-1;i>=0;i--)po(e.doc,t,n[i],et(n[i].line,n[i].ch+t.length))}})),n("specialChars",/[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200c\u200e\u200f\u2028\u2029\ufeff\ufff9-\ufffc]/g,(function(e,t,n){e.state.specialChars=new RegExp(t.source+(t.test("\t")?"":"|\t"),"g"),n!=ba&&e.refresh()})),n("specialCharPlaceholder",Qt,(function(e){return e.refresh()}),!0),n("electricChars",!0),n("inputStyle",g?"contenteditable":"textarea",(function(){throw new Error("inputStyle can not (yet) be changed in a running editor")}),!0),n("spellcheck",!1,(function(e,t){return e.getInputField().spellcheck=t}),!0),n("autocorrect",!1,(function(e,t){return e.getInputField().autocorrect=t}),!0),n("autocapitalize",!1,(function(e,t){return e.getInputField().autocapitalize=t}),!0),n("rtlMoveVisually",!b),n("wholeLineUpdateBefore",!0),n("theme","default",(function(e){ya(e),zi(e)}),!0),n("keyMap","default",(function(e,t,n){var r=Zo(t),i=n!=ba&&Zo(n);i&&i.detach&&i.detach(e,r),r.attach&&r.attach(e,i||null)})),n("extraKeys",null),n("configureMouse",null),n("lineWrapping",!1,ja,!0),n("gutters",[],(function(e,t){e.display.gutterSpecs=di(t,e.options.lineNumbers),zi(e)}),!0),n("fixedGutter",!0,(function(e,t){e.display.gutters.style.left=t?ar(e.display)+"px":"0",e.refresh()}),!0),n("coverGutterNextToScrollbar",!1,(function(e){return Rr(e)}),!0),n("scrollbarStyle","native",(function(e){Ur(e),Rr(e),e.display.scrollbars.setScrollTop(e.doc.scrollTop),e.display.scrollbars.setScrollLeft(e.doc.scrollLeft)}),!0),n("lineNumbers",!1,(function(e,t){e.display.gutterSpecs=di(e.options.gutters,t),zi(e)}),!0),n("firstLineNumber",1,zi,!0),n("lineNumberFormatter",(function(e){return e}),zi,!0),n("showCursorWhenSelecting",!1,vr,!0),n("resetSelectionOnContextMenu",!0),n("lineWiseCopyCut",!0),n("pasteLinesPerSelection",!0),n("selectionsMayTouch",!1),n("readOnly",!1,(function(e,t){"nocursor"==t&&(Mr(e),e.display.input.blur()),e.display.input.readOnlyChanged(t)})),n("screenReaderLabel",null,(function(e,t){t=""===t?null:t,e.display.input.screenReaderLabelChanged(t)})),n("disableInput",!1,(function(e,t){t||e.display.input.reset()}),!0),n("dragDrop",!0,xa),n("allowDropFileTypes",null),n("cursorBlinkRate",530),n("cursorScrollMargin",0),n("cursorHeight",1,vr,!0),n("singleCursorHeightPerLine",!0,vr,!0),n("workTime",100),n("workDelay",100),n("flattenSpans",!0,Oi,!0),n("addModeClass",!1,Oi,!0),n("pollInterval",100),n("undoDepth",200,(function(e,t){return e.doc.history.undoDepth=t})),n("historyEventDelay",1250),n("viewportMargin",10,(function(e){return e.refresh()}),!0),n("maxHighlightLength",1e4,Oi,!0),n("moveInputWithCursor",!0,(function(e,t){t||e.display.input.resetPosition()})),n("tabindex",null,(function(e,t){return e.display.input.getField().tabIndex=t||""})),n("autofocus",null),n("direction","ltr",(function(e,t){return e.doc.setDirection(t)}),!0),n("phrases",null)}(Ma),function(e){var t=e.optionHandlers,n=e.helpers={};e.prototype={constructor:e,focus:function(){window.focus(),this.display.input.focus()},setOption:function(e,n){var r=this.options,i=r[e];r[e]==n&&"mode"!=e||(r[e]=n,t.hasOwnProperty(e)&&ei(this,t[e])(this,n,i),pe(this,"optionChange",this,e))},getOption:function(e){return this.options[e]},getDoc:function(){return this.doc},addKeyMap:function(e,t){this.state.keyMaps[t?"push":"unshift"](Zo(e))},removeKeyMap:function(e){for(var t=this.state.keyMaps,n=0;nn&&(Ca(this,i.head.line,e,!0),n=i.head.line,r==this.doc.sel.primIndex&&Or(this));else{var o=i.from(),a=i.to(),c=Math.max(n,o.line);n=Math.min(this.lastLine(),a.line-(a.ch?0:1))+1;for(var s=c;s0&&$i(this.doc,r,new xi(o,l[r].to()),F)}}})),getTokenAt:function(e,t){return mt(this,e,t)},getLineTokens:function(e,t){return mt(this,et(e),t,!0)},getTokenTypeAt:function(e){e=ct(this.doc,e);var t,n=ht(this,Ge(this.doc,e.line)),r=0,i=(n.length-1)/2,o=e.ch;if(0==o)t=n[2];else for(;;){var a=r+i>>1;if((a?n[2*a-1]:0)>=o)i=a;else{if(!(n[2*a+1]o&&(e=o,i=!0),r=Ge(this.doc,e)}else r=e;return Un(this,r,{top:0,left:0},t||"page",n||i).top+(i?this.doc.height-Bt(r):0)},defaultTextHeight:function(){return rr(this.display)},defaultCharWidth:function(){return ir(this.display)},getViewport:function(){return{from:this.display.viewFrom,to:this.display.viewTo}},addWidget:function(e,t,n,r,i){var o,a,c=this.display,s=(e=Yn(this,ct(this.doc,e))).bottom,l=e.left;if(t.style.position="absolute",t.setAttribute("cm-ignore-events","true"),this.display.input.setUneditable(t),c.sizer.appendChild(t),"over"==r)s=e.top;else if("above"==r||"near"==r){var u=Math.max(c.wrapper.clientHeight,this.doc.height),f=Math.max(c.sizer.clientWidth,c.lineSpace.clientWidth);("above"==r||e.bottom+t.offsetHeight>u)&&e.top>t.offsetHeight?s=e.top-t.offsetHeight:e.bottom+t.offsetHeight<=u&&(s=e.bottom),l+t.offsetWidth>f&&(l=f-t.offsetWidth)}t.style.top=s+"px",t.style.left=t.style.right="","right"==i?(l=c.sizer.clientWidth-t.offsetWidth,t.style.right="0px"):("left"==i?l=0:"middle"==i&&(l=(c.sizer.clientWidth-t.offsetWidth)/2),t.style.left=l+"px"),n&&(null!=(a=Sr(o=this,{left:l,top:s,right:l+t.offsetWidth,bottom:s+t.offsetHeight})).scrollTop&&Hr(o,a.scrollTop),null!=a.scrollLeft&&Pr(o,a.scrollLeft))},triggerOnKeyDown:ti(sa),triggerOnKeyPress:ti(ua),triggerOnKeyUp:la,triggerOnMouseDown:ti(pa),execCommand:function(e){if(Jo.hasOwnProperty(e))return Jo[e].call(null,this)},triggerElectric:ti((function(e){Ea(this,e)})),findPosH:function(e,t,n,r){var i=1;t<0&&(i=-1,t=-t);for(var o=ct(this.doc,e),a=0;a0&&a(t.charAt(n-1));)--n;for(;r.5||this.options.lineWrapping)&&sr(this),pe(this,"refresh",this)})),swapDoc:ti((function(e){var t=this.doc;return t.cm=null,this.state.selectingText&&this.state.selectingText(),Hi(this,e),In(this),this.display.input.reset(),Er(this,e.scrollLeft,e.scrollTop),this.curOp.forceScroll=!0,sn(this,"swapDoc",this,t),t})),phrase:function(e){var t=this.options.phrases;return t&&Object.prototype.hasOwnProperty.call(t,e)?t[e]:e},getInputField:function(){return this.display.input.getField()},getWrapperElement:function(){return this.display.wrapper},getScrollerElement:function(){return this.display.scroller},getGutterElement:function(){return this.display.gutters}},me(e),e.registerHelper=function(t,r,i){n.hasOwnProperty(t)||(n[t]=e[t]={_global:[]}),n[t][r]=i},e.registerGlobalHelper=function(t,r,i,o){e.registerHelper(t,r,o),n[t]._global.push({pred:i,val:o})}}(Ma);var Ua="iter insert remove copy getEditor constructor".split(" ");for(var Wa in To.prototype)To.prototype.hasOwnProperty(Wa)&&I(Ua,Wa)<0&&(Ma.prototype[Wa]=function(e){return function(){return e.apply(this.doc,arguments)}}(To.prototype[Wa]));return me(To),Ma.inputStyles={textarea:Ba,contenteditable:Va},Ma.defineMode=function(e){Ma.defaults.mode||"null"==e||(Ma.defaults.mode=e),Pe.apply(this,arguments)},Ma.defineMIME=function(e,t){De[e]=t},Ma.defineMode("null",(function(){return{token:function(e){return e.skipToEnd()}}})),Ma.defineMIME("text/plain","null"),Ma.defineExtension=function(e,t){Ma.prototype[e]=t},Ma.defineDocExtension=function(e,t){To.prototype[e]=t},Ma.fromTextArea=function(e,t){if((t=t?P(t):{}).value=e.value,!t.tabindex&&e.tabIndex&&(t.tabindex=e.tabIndex),!t.placeholder&&e.placeholder&&(t.placeholder=e.placeholder),null==t.autofocus){var n=E();t.autofocus=n==e||null!=e.getAttribute("autofocus")&&n==document.body}function r(){e.value=c.getValue()}var i;if(e.form&&(fe(e.form,"submit",r),!t.leaveSubmitMethodAlone)){var o=e.form;i=o.submit;try{var a=o.submit=function(){r(),o.submit=i,o.submit(),o.submit=a}}catch(e){}}t.finishInit=function(n){n.save=r,n.getTextArea=function(){return e},n.toTextArea=function(){n.toTextArea=isNaN,r(),e.parentNode.removeChild(n.getWrapperElement()),e.style.display="",e.form&&(de(e.form,"submit",r),t.leaveSubmitMethodAlone||"function"!=typeof e.form.submit||(e.form.submit=i))}},e.style.display="none";var c=Ma((function(t){return e.parentNode.insertBefore(t,e.nextSibling)}),t);return c},function(e){e.off=de,e.on=fe,e.wheelEventPixels=bi,e.Doc=To,e.splitLines=Oe,e.countColumn=V,e.findColumn=W,e.isWordChar=J,e.Pass=R,e.signal=pe,e.Line=Gt,e.changeEnd=_i,e.scrollbarModel=Br,e.Pos=et,e.cmpPos=tt,e.modes=He,e.mimeModes=De,e.resolveMode=Ve,e.getMode=Ne,e.modeExtensions=Ie,e.extendMode=Re,e.copyState=Fe,e.startState=Ue,e.innerMode=Be,e.commands=Jo,e.keyMap=Ro,e.keyName=Yo,e.isModifierKey=Wo,e.lookupKey=Uo,e.normalizeKeyMap=Bo,e.StringStream=We,e.SharedTextMarker=_o,e.TextMarker=jo,e.LineWidget=wo,e.e_preventDefault=ye,e.e_stopPropagation=be,e.e_stop=ke,e.addClass=A,e.contains=O,e.rmClass=_,e.keyNames=Po}(Ma),Ma.version="5.57.0",Ma}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(0),i=function(){function e(){}return e.prototype.isSeparator=function(e){return" "==e||"\r"==e||"\n"==e||"\t"==e||"("==e||")"==e},e.prototype.isWhiteSpace=function(e){return" "==e||"\r"==e||"\n"==e||"\t"==e},e.prototype.findLastSeparatorIndex=function(e){var t=this;return r.findLastIndex(e,(function(e){return t.isSeparator(e)}))},e.prototype.needSpaceAfter=function(e){return!("("==e)},e.prototype.isLastCharacterWhiteSpace=function(e){return!!e&&this.isWhiteSpace(e[e.length-1])},e.prototype.stripEndWithNonSeparatorCharacters=function(e){if(!e)return e;if(this.isSeparator(e[e.length-1]))return e;var t=this.findLastSeparatorIndex(e);return t<0?"":e.substr(0,t+1)},e.prototype.getEndNotSeparatorCharacers=function(e){if(!e)return e;if(this.isSeparator(e[e.length-1]))return"";var t=this.findLastSeparatorIndex(e);return t<0?e:e.substr(t+1)},e}();t.default=new i},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(0),i=function(){function e(){}return e.prototype.quote=function(e){return/\s/g.test(e)?'"'+e+'"':e},e.prototype.buildDefaultObjOrGetOriginal=function(e,t){return r.isString(e)?{value:this.quote(e),type:t}:{value:e,type:t}},e.prototype.handleParseError=function(e,t,n){var i=this,o=t;return r.flatMap(n.expected,(function(e){var t=[];if("literal"==e.type&&(t=r.map([e.text||e.value],(function(e){return{value:e,type:"literal"}}))),"other"==e.type){var n=o.getLastTokenType()||"value";"value"==n&&(t=r.map(i.needCategories(),(function(e){return i.buildDefaultObjOrGetOriginal(e,"category")}))),"category"==n&&(t=r.map(i.needOperators(o.getLastCategory()),(function(e){return i.buildDefaultObjOrGetOriginal(e,"operator")}))),"operator"==n&&(t=r.map(i.needValues(o.getLastCategory(),o.getLastOperator()),(function(e){return i.buildDefaultObjOrGetOriginal(e,"value")})))}return t}))},e.prototype.hasCategory=function(e){return!1},e.prototype.hasOperator=function(e,t){return!1},e.prototype.needCategories=function(){return[]},e.prototype.needOperators=function(e){return[]},e.prototype.needValues=function(e,t){return[]},e}();t.default=i},function(e,t){e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var n=function(e,t){var n,r=e[1]||"",i=e[3];if(!i)return r;if(t&&"function"==typeof btoa){var o=(n=i,"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(n))))+" */"),a=i.sources.map((function(e){return"/*# sourceURL="+i.sourceRoot+e+" */"}));return[r].concat(a).concat([o]).join("\n")}return[r].join("\n")}(t,e);return t[2]?"@media "+t[2]+"{"+n+"}":n})).join("")},t.i=function(e,n){"string"==typeof e&&(e=[[null,e,""]]);for(var r={},i=0;i=0&&f.splice(t,1)}function g(e){var t=document.createElement("style");if(void 0===e.attrs.type&&(e.attrs.type="text/css"),void 0===e.attrs.nonce){var r=n.nc;r&&(e.attrs.nonce=r)}return m(t,e.attrs),z(e,t),t}function m(e,t){Object.keys(t).forEach((function(n){e.setAttribute(n,t[n])}))}function y(e,t){var n,r,i,o;if(t.transform&&e.css){if(!(o="function"==typeof t.transform?t.transform(e.css):t.transform.default(e.css)))return function(){};e.css=o}if(t.singleton){var a=u++;n=l||(l=g(t)),r=k.bind(null,n,a,!1),i=k.bind(null,n,a,!0)}else e.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(n=function(e){var t=document.createElement("link");return void 0===e.attrs.type&&(e.attrs.type="text/css"),e.attrs.rel="stylesheet",m(t,e.attrs),z(e,t),t}(t),r=j.bind(null,n,t),i=function(){v(n),n.href&&URL.revokeObjectURL(n.href)}):(n=g(t),r=x.bind(null,n),i=function(){v(n)});return r(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;r(e=t)}else i()}}e.exports=function(e,t){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");(t=t||{}).attrs="object"==typeof t.attrs?t.attrs:{},t.singleton||"boolean"==typeof t.singleton||(t.singleton=a()),t.insertInto||(t.insertInto="head"),t.insertAt||(t.insertAt="bottom");var n=p(e,t);return d(n,t),function(e){for(var r=[],i=0;i1)){if(this.somethingSelected()){if(!n.hint.supportsSelection)return;for(var i=0;il.clientHeight+1,O=a.getScrollInfo();if(S>0){var E=q.bottom-q.top;if(g.top-(g.bottom-q.top)-E>0)l.style.top=(y=g.top-E-k)+"px",b=!1;else if(E>C){l.style.height=C-5+"px",l.style.top=(y=g.bottom-q.top-k)+"px";var A=a.getCursor();n.from.ch!=A.ch&&(g=a.cursorCoords(A),l.style.left=(m=g.left-w)+"px",q=l.getBoundingClientRect())}}var L,H=q.right-_;if(H>0&&(q.right-q.left>_&&(l.style.width=_-5+"px",H-=q.right-q.left-_),l.style.left=(m=g.left-H-w)+"px"),T)for(var D=l.firstChild;D;D=D.nextSibling)D.style.paddingRight=a.display.nativeBarWidth+"px";return a.addKeyMap(this.keyMap=function(e,t){var n={Up:function(){t.moveFocus(-1)},Down:function(){t.moveFocus(1)},PageUp:function(){t.moveFocus(1-t.menuSize(),!0)},PageDown:function(){t.moveFocus(t.menuSize()-1,!0)},Home:function(){t.setFocus(0)},End:function(){t.setFocus(t.length-1)},Enter:t.pick,Tab:t.pick,Esc:t.close};/Mac/.test(navigator.platform)&&(n["Ctrl-P"]=function(){t.moveFocus(-1)},n["Ctrl-N"]=function(){t.moveFocus(1)});var r=e.options.customKeys,i=r?{}:n;function o(e,r){var o;o="string"!=typeof r?function(e){return r(e,t)}:n.hasOwnProperty(r)?n[r]:r,i[e]=o}if(r)for(var a in r)r.hasOwnProperty(a)&&o(a,r[a]);var c=e.options.extraKeys;if(c)for(var a in c)c.hasOwnProperty(a)&&o(a,c[a]);return i}(t,{moveFocus:function(e,t){r.changeActive(r.selectedHint+e,t)},setFocus:function(e){r.changeActive(e)},menuSize:function(){return r.screenAmount()},length:f.length,close:function(){t.close()},pick:function(){r.pick()},data:n})),t.options.closeOnUnfocus&&(a.on("blur",this.onBlur=function(){L=setTimeout((function(){t.close()}),100)}),a.on("focus",this.onFocus=function(){clearTimeout(L)})),a.on("scroll",this.onScroll=function(){var e=a.getScrollInfo(),n=a.getWrapperElement().getBoundingClientRect(),r=y+O.top-e.top,i=r-(s.pageYOffset||(c.documentElement||c.body).scrollTop);if(b||(i+=l.offsetHeight),i<=n.top||i>=n.bottom)return t.close();l.style.top=r+"px",l.style.left=m+O.left-e.left+"px"}),e.on(l,"dblclick",(function(e){var t=o(l,e.target||e.srcElement);t&&null!=t.hintId&&(r.changeActive(t.hintId),r.pick())})),e.on(l,"click",(function(e){var n=o(l,e.target||e.srcElement);n&&null!=n.hintId&&(r.changeActive(n.hintId),t.options.completeOnSingleClick&&r.pick())})),e.on(l,"mousedown",(function(){setTimeout((function(){a.focus()}),20)})),this.scrollToActive(),e.signal(n,"select",f[this.selectedHint],l.childNodes[this.selectedHint]),!0}function c(e,t,n,r){if(e.async)e(t,r,n);else{var i=e(t,n);i&&i.then?i.then(r):r(i)}}t.prototype={close:function(){this.active()&&(this.cm.state.completionActive=null,this.tick=null,this.cm.off("cursorActivity",this.activityFunc),this.widget&&this.data&&e.signal(this.data,"close"),this.widget&&this.widget.close(),e.signal(this.cm,"endCompletion",this.cm))},active:function(){return this.cm.state.completionActive==this},pick:function(t,n){var r=t.list[n],o=this;this.cm.operation((function(){r.hint?r.hint(o.cm,t,r):o.cm.replaceRange(i(r),r.from||t.from,r.to||t.to,"complete"),e.signal(t,"pick",r),o.cm.scrollIntoView()})),this.close()},cursorActivity:function(){this.debounce&&(r(this.debounce),this.debounce=0);var e=this.startPos;this.data&&(e=this.data.from);var t=this.cm.getCursor(),i=this.cm.getLine(t.line);if(t.line!=this.startPos.line||i.length-t.ch!=this.startLen-this.startPos.ch||t.ch=this.data.list.length?t=n?this.data.list.length-1:0:t<0&&(t=n?0:this.data.list.length-1),this.selectedHint!=t){var r=this.hints.childNodes[this.selectedHint];r&&(r.className=r.className.replace(" CodeMirror-hint-active","")),(r=this.hints.childNodes[this.selectedHint=t]).className+=" CodeMirror-hint-active",this.scrollToActive(),e.signal(this.data,"select",this.data.list[this.selectedHint],r)}},scrollToActive:function(){var e=this.completion.options.scrollMargin||0,t=this.hints.childNodes[Math.max(0,this.selectedHint-e)],n=this.hints.childNodes[Math.min(this.data.list.length-1,this.selectedHint+e)],r=this.hints.firstChild;t.offsetTopthis.hints.scrollTop+this.hints.clientHeight&&(this.hints.scrollTop=n.offsetTop+n.offsetHeight-this.hints.clientHeight+r.offsetTop)},screenAmount:function(){return Math.floor(this.hints.clientHeight/this.hints.firstChild.offsetHeight)||1}},e.registerHelper("hint","auto",{resolve:function(t,n){var r,i=t.getHelpers(n,"hint");if(i.length){var o=function(e,t,n){var r=function(e,t){if(!e.somethingSelected())return t;for(var n=[],r=0;r0?t(e):i(o+1)}))}(0)};return o.async=!0,o.supportsSelection=!0,o}return(r=t.getHelper(t.getCursor(),"hintWords"))?function(t){return e.hint.fromList(t,{words:r})}:e.hint.anyword?function(t,n){return e.hint.anyword(t,n)}:function(){}}}),e.registerHelper("hint","fromList",(function(t,n){var r,i=t.getCursor(),o=t.getTokenAt(i),a=e.Pos(i.line,o.start),c=i;o.start,]/,closeOnUnfocus:!0,completeOnSingleClick:!0,container:null,customKeys:null,extraKeys:null};e.defineOption("hintOptions",null)}(n(2))},function(e,t,n){!function(e){function t(e){e.state.placeholder&&(e.state.placeholder.parentNode.removeChild(e.state.placeholder),e.state.placeholder=null)}function n(e){t(e);var n=e.state.placeholder=document.createElement("pre");n.style.cssText="height: 0; overflow: visible",n.style.direction=e.getOption("direction"),n.className="CodeMirror-placeholder CodeMirror-line-like";var r=e.getOption("placeholder");"string"==typeof r&&(r=document.createTextNode(r)),n.appendChild(r),e.display.lineSpace.insertBefore(n,e.display.lineSpace.firstChild)}function r(e){o(e)&&n(e)}function i(e){var r=e.getWrapperElement(),i=o(e);r.className=r.className.replace(" CodeMirror-empty","")+(i?" CodeMirror-empty":""),i?n(e):t(e)}function o(e){return 1===e.lineCount()&&""===e.getLine(0)}e.defineOption("placeholder","",(function(n,o,a){var c=a&&a!=e.Init;if(o&&!c)n.on("blur",r),n.on("change",i),n.on("swapDoc",i),i(n);else if(!o&&c){n.off("blur",r),n.off("change",i),n.off("swapDoc",i),t(n);var s=n.getWrapperElement();s.className=s.className.replace(" CodeMirror-empty","")}o&&!n.hasFocus()&&r(n)}))}(n(2))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n(2).defineMode("filter-mode",(function(e,t){function n(e){var t,n=(t=e.fieldState)==r.category?r.operator:t==r.operator?r.value:t==r.value?r.category:void 0,i=e.fieldState;return e.fieldState=n,i.toString()}return{startState:function(){return{inString:!1,fieldState:r.category}},token:function(e,t){return" "==(r=e.peek())||"\r"==r||"\n"==r||"\t"==r?(e.eatSpace(),null):"("==e.peek()||")"==e.peek()?(e.next(),"bracket"):e.match("AND",!0,!0)||e.match("OR",!0,!0)?"condition":(t.inString||'"'!=e.peek()||(e.next(),t.inString=!0),t.inString?(e.skipTo('"')?(e.next(),t.inString=!1):e.skipToEnd(),n(t)):(e.eatWhile(/[^\r\n\t\s\(\)]+/),n(t)));var r}}}));var r=function(){function e(){}return e.none="none",e.category="category",e.operator="operator",e.value="value",e}()},function(e,t,n){var r=n(16);"string"==typeof r&&(r=[[e.i,r,""]]),n(6)(r,{hmr:!0,transform:void 0,insertInto:void 0}),r.locals&&(e.exports=r.locals)},function(e,t,n){(e.exports=n(5)(!1)).push([e.i,".CodeMirror{font-family:monospace;height:300px;color:black;direction:ltr}.CodeMirror-lines{padding:4px 0}.CodeMirror pre.CodeMirror-line,.CodeMirror pre.CodeMirror-line-like{padding:0 4px}.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{background-color:white}.CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;white-space:nowrap}.CodeMirror-guttermarker{color:black}.CodeMirror-guttermarker-subtle{color:#999}.CodeMirror-cursor{border-left:1px solid black;border-right:none;width:0}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.cm-fat-cursor .CodeMirror-cursor{width:auto;border:0 !important;background:#7e7}.cm-fat-cursor div.CodeMirror-cursors{z-index:1}.cm-fat-cursor-mark{background-color:rgba(20,255,20,0.5);-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite}.cm-animate-fat-cursor{width:auto;border:0;-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite;background-color:#7e7}@-moz-keyframes blink{50%{background-color:transparent}}@-webkit-keyframes blink{50%{background-color:transparent}}@keyframes blink{50%{background-color:transparent}}.cm-tab{display:inline-block;text-decoration:inherit}.CodeMirror-rulers{position:absolute;left:0;right:0;top:-50px;bottom:0;overflow:hidden}.CodeMirror-ruler{border-left:1px solid #ccc;top:0;bottom:0;position:absolute}.cm-s-default .cm-header{color:blue}.cm-s-default .cm-quote{color:#090}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:bold}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-strikethrough{text-decoration:line-through}.cm-s-default .cm-keyword{color:#708}.cm-s-default .cm-atom{color:#219}.cm-s-default .cm-number{color:#164}.cm-s-default .cm-def{color:#00f}.cm-s-default .cm-variable-2{color:#05a}.cm-s-default .cm-variable-3,.cm-s-default .cm-type{color:#085}.cm-s-default .cm-comment{color:#a50}.cm-s-default .cm-string{color:#a11}.cm-s-default .cm-string-2{color:#f50}.cm-s-default .cm-meta{color:#555}.cm-s-default .cm-qualifier{color:#555}.cm-s-default .cm-builtin{color:#30a}.cm-s-default .cm-bracket{color:#997}.cm-s-default .cm-tag{color:#170}.cm-s-default .cm-attribute{color:#00c}.cm-s-default .cm-hr{color:#999}.cm-s-default .cm-link{color:#00c}.cm-s-default .cm-error{color:#f00}.cm-invalidchar{color:#f00}.CodeMirror-composing{border-bottom:2px solid}div.CodeMirror span.CodeMirror-matchingbracket{color:#0b0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#a22}.CodeMirror-matchingtag{background:rgba(255,150,0,0.3)}.CodeMirror-activeline-background{background:#e8f2ff}.CodeMirror{position:relative;overflow:hidden;background:white}.CodeMirror-scroll{overflow:scroll !important;margin-bottom:-50px;margin-right:-50px;padding-bottom:50px;height:100%;outline:none;position:relative}.CodeMirror-sizer{position:relative;border-right:50px solid transparent}.CodeMirror-vscrollbar,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{position:absolute;z-index:6;display:none}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0}.CodeMirror-gutter-filler{left:0;bottom:0}.CodeMirror-gutters{position:absolute;left:0;top:0;min-height:100%;z-index:3}.CodeMirror-gutter{white-space:normal;height:100%;display:inline-block;vertical-align:top;margin-bottom:-50px}.CodeMirror-gutter-wrapper{position:absolute;z-index:4;background:none !important;border:none !important}.CodeMirror-gutter-background{position:absolute;top:0;bottom:0;z-index:4}.CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.CodeMirror-gutter-wrapper ::selection{background-color:transparent}.CodeMirror-gutter-wrapper ::-moz-selection{background-color:transparent}.CodeMirror-lines{cursor:text;min-height:1px}.CodeMirror pre.CodeMirror-line,.CodeMirror pre.CodeMirror-line-like{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;border-width:0;background:transparent;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible;-webkit-tap-highlight-color:transparent;-webkit-font-variant-ligatures:contextual;font-variant-ligatures:contextual}.CodeMirror-wrap pre.CodeMirror-line,.CodeMirror-wrap pre.CodeMirror-line-like{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-index:2;padding:.1px}.CodeMirror-rtl pre{direction:rtl}.CodeMirror-code{outline:none}.CodeMirror-scroll,.CodeMirror-sizer,.CodeMirror-gutter,.CodeMirror-gutters,.CodeMirror-linenumber{-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.CodeMirror-cursor{position:absolute;pointer-events:none}.CodeMirror-measure pre{position:static}div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}div.CodeMirror-dragcursors{visibility:visible}.CodeMirror-focused div.CodeMirror-cursors{visibility:visible}.CodeMirror-selected{background:#d9d9d9}.CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}.CodeMirror-crosshair{cursor:crosshair}.CodeMirror-line::selection,.CodeMirror-line>span::selection,.CodeMirror-line>span>span::selection{background:#d7d4f0}.CodeMirror-line::-moz-selection,.CodeMirror-line>span::-moz-selection,.CodeMirror-line>span>span::-moz-selection{background:#d7d4f0}.cm-searching{background-color:#ffa;background-color:rgba(255,255,0,0.4)}.cm-force-border{padding-right:.1px}@media print{.CodeMirror div.CodeMirror-cursors{visibility:hidden}}.cm-tab-wrap-hack:after{content:''}span.CodeMirror-selectedtext{background:none}",""])},function(e,t){e.exports=function(e){var t="undefined"!=typeof window&&window.location;if(!t)throw new Error("fixUrls requires window.location");if(!e||"string"!=typeof e)return e;var n=t.protocol+"//"+t.host,r=n+t.pathname.replace(/\/[^\/]*$/,"/");return e.replace(/url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi,(function(e,t){var i,o=t.trim().replace(/^"(.*)"$/,(function(e,t){return t})).replace(/^'(.*)'$/,(function(e,t){return t}));return/^(#|data:|http:\/\/|https:\/\/|file:\/\/\/|\s*$)/i.test(o)?e:(i=0===o.indexOf("//")?o:0===o.indexOf("/")?n+o:r+o.replace(/^\.\//,""),"url("+JSON.stringify(i)+")")}))}},function(e,t,n){var r=n(19);"string"==typeof r&&(r=[[e.i,r,""]]),n(6)(r,{hmr:!0,transform:void 0,insertInto:void 0}),r.locals&&(e.exports=r.locals)},function(e,t,n){(e.exports=n(5)(!1)).push([e.i,".CodeMirror-hints{position:absolute;z-index:10;overflow:hidden;list-style:none;margin:0;padding:2px;-webkit-box-shadow:2px 3px 5px rgba(0,0,0,0.2);-moz-box-shadow:2px 3px 5px rgba(0,0,0,0.2);box-shadow:2px 3px 5px rgba(0,0,0,0.2);border-radius:3px;border:1px solid silver;background:white;font-size:90%;font-family:monospace;max-height:20em;overflow-y:auto}.CodeMirror-hint{margin:0;padding:0 4px;border-radius:2px;white-space:pre;color:black;cursor:pointer}li.CodeMirror-hint-active{background:#08f;color:white}",""])},function(e,t,n){"use strict";(function(e){var r,i=Object.assign||function(e){for(var t=1;t=0;case"!contains":return e[i].toLowerCase().indexOf(r.toLowerCase())<0}return!1},t}(n(8).default);t.default=a},function(e,t,n){"use strict";var r,i=this&&this.__extends||(r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)});Object.defineProperty(t,"__esModule",{value:!0});var o=n(4),a=n(0),c=function(e){function t(t,n){var r=e.call(this)||this;return r.data=t,r.options=n,r.cache={},r.parseResult=null,r.categories=a.map(r.options,(function(e){return e.columnText?e.columnText:e.columnField})),r}return i(t,e),t.prototype.hasCategory=function(e){return void 0!==a.find(this.options,(function(t){return e===t.columnField||e===t.columnText}))},t.prototype.hasOperator=function(e,t){return this.needOperators(e).indexOf(t)>=0},t.prototype.needCategories=function(){return this.categories},t.prototype.needOperators=function(e){var t=a.find(this.options,(function(t){return null!=t.customOperatorFunc&&(t.columnText==e||t.columnField==e)}));return t?t.customOperatorFunc(e):["==","!=","contains","!contains"]},t.prototype.needValues=function(e,t){var n=a.find(this.options,(function(t){return t.columnField==e||t.columnText==e}));return null!=n&&"selection"==n.type&&null!=this.data?(this.cache[e]||(this.cache[e]=a.chain(this.data).map((function(t){return t[e]})).uniq().value()),this.cache[e]):null!=n&&n.customValuesFunc?n.customValuesFunc(e,t):[]},t}(o.default);t.default=c},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(28),i=n(0),o=n(4),a=n(29),c=n(3),s=function(){function e(){this.autoCompleteHandler=new o.default,this.lastError=null,this.parseTrace=new a.default}return e.prototype.parse=function(e){if(e=i.trim(e),i.isEmpty(e))return[];try{return this.parseQuery(e)}catch(e){return e.isError=!0,e}},e.prototype.parseQuery=function(e){return this.parseTrace.clear(),r.parse(e,{parseTrace:this.parseTrace})},e.prototype.getSuggestions=function(e){e=c.default.stripEndWithNonSeparatorCharacters(e);try{return this.parseQuery(e),!e||c.default.isLastCharacterWhiteSpace(e)?i.map(["AND","OR"],(function(e){return{value:e,type:"literal"}})):[]}catch(e){return this.autoCompleteHandler.handleParseError(r,this.parseTrace,e)}},e.prototype.setAutoCompleteHandler=function(e){this.autoCompleteHandler=e},e}();t.default=s},function(e,t,n){"use strict";function r(e,t,n,i){this.message=e,this.expected=t,this.found=n,this.location=i,this.name="SyntaxError","function"==typeof Error.captureStackTrace&&Error.captureStackTrace(this,r)}!function(e,t){function n(){this.constructor=e}n.prototype=t.prototype,e.prototype=new n}(r,Error),r.buildMessage=function(e,t){var n={literal:function(e){return'"'+i(e.text)+'"'},class:function(e){var t,n="";for(t=0;t0){for(t=1,r=1;tM&&(M=k,_=[]),_.push(e))}function H(){var t,n,r,o,a,l,u,f;if(t=k,N()!==i)if((n=D())!==i){for(r=[],o=k,(a=V())!==i?("and"===e.substr(k,3).toLowerCase()?(l=e.substr(k,3),k+=3):(l=i,0===C&&L(c)),l===i&&("or"===e.substr(k,2).toLowerCase()?(l=e.substr(k,2),k+=2):(l=i,0===C&&L(s))),l!==i&&(u=V())!==i&&(f=D())!==i?o=a=[a,l,u,f]:(k=o,o=i)):(k=o,o=i);o!==i;)r.push(o),o=k,(a=V())!==i?("and"===e.substr(k,3).toLowerCase()?(l=e.substr(k,3),k+=3):(l=i,0===C&&L(c)),l===i&&("or"===e.substr(k,2).toLowerCase()?(l=e.substr(k,2),k+=2):(l=i,0===C&&L(s))),l!==i&&(u=V())!==i&&(f=D())!==i?o=a=[a,l,u,f]:(k=o,o=i)):(k=o,o=i);r!==i&&(o=N())!==i?(x=t,t=function(e,t){for(var n=[e],r=0;r=1&&h<=7))throw new RangeError("firstWeekContainsDate must be between 1 and 7 inclusively");var d=new Date(0);d.setUTCFullYear(c+1,0,h),d.setUTCHours(0,0,0,0);var p=Object(o.a)(d,t),z=new Date(0);z.setUTCFullYear(c,0,h),z.setUTCHours(0,0,0,0);var v=Object(o.a)(z,t);return n.getTime()>=p.getTime()?c+1:n.getTime()>=v.getTime()?c:c-1}},function(e,t,n){"use strict";n.d(t,"a",(function(){return a}));var r=n(15),i=n(10),o=n(6);function a(e,t){Object(o.a)(2,arguments);var n=Object(i.default)(e).getTime(),a=Object(r.a)(t);return new Date(n+a)}},function(e,t,n){"use strict";n.d(t,"a",(function(){return c}));var r=n(15),i=n(10),o=n(72),a=n(6);function c(e,t){Object(a.a)(1,arguments);var n=Object(i.default)(e,t),c=n.getUTCFullYear(),s=t||{},l=s.locale,u=l&&l.options&&l.options.firstWeekContainsDate,f=null==u?1:Object(r.a)(u),h=null==s.firstWeekContainsDate?f:Object(r.a)(s.firstWeekContainsDate);if(!(h>=1&&h<=7))throw new RangeError("firstWeekContainsDate must be between 1 and 7 inclusively");var d=new Date(0);d.setUTCFullYear(c+1,0,h),d.setUTCHours(0,0,0,0);var p=Object(o.a)(d,t),z=new Date(0);z.setUTCFullYear(c,0,h),z.setUTCHours(0,0,0,0);var v=Object(o.a)(z,t);return n.getTime()>=p.getTime()?c+1:n.getTime()>=v.getTime()?c:c-1}},function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return a}));var r=n(10),i=n(15),o=n(6);function a(e,t){Object(o.a)(1,arguments);var n=t||{},a=n.locale,c=a&&a.options&&a.options.weekStartsOn,s=null==c?0:Object(i.a)(c),l=null==n.weekStartsOn?s:Object(i.a)(n.weekStartsOn);if(!(l>=0&&l<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");var u=Object(r.default)(e),f=u.getDay(),h=(f0&&void 0!==arguments[0]?arguments[0]:{},n=t.width?String(t.width):e.defaultWidth,r=e.formats[n]||e.formats[e.defaultWidth];return r}}var o={date:i({formats:{full:"EEEE, MMMM do, y",long:"MMMM do, y",medium:"MMM d, y",short:"MM/dd/yyyy"},defaultWidth:"full"}),time:i({formats:{full:"h:mm:ss a zzzz",long:"h:mm:ss a z",medium:"h:mm:ss a",short:"h:mm a"},defaultWidth:"full"}),dateTime:i({formats:{full:"{{date}} 'at' {{time}}",long:"{{date}} 'at' {{time}}",medium:"{{date}}, {{time}}",short:"{{date}}, {{time}}"},defaultWidth:"full"})},a={lastWeek:"'last' eeee 'at' p",yesterday:"'yesterday at' p",today:"'today at' p",tomorrow:"'tomorrow at' p",nextWeek:"eeee 'at' p",other:"P"};function c(e){return function(t,n){var r,i=n||{};if("formatting"===(i.context?String(i.context):"standalone")&&e.formattingValues){var o=e.defaultFormattingWidth||e.defaultWidth,a=i.width?String(i.width):o;r=e.formattingValues[a]||e.formattingValues[o]}else{var c=e.defaultWidth,s=i.width?String(i.width):e.defaultWidth;r=e.values[s]||e.values[c]}return r[e.argumentCallback?e.argumentCallback(t):t]}}function s(e){return function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=n.width,i=r&&e.matchPatterns[r]||e.matchPatterns[e.defaultMatchWidth],o=t.match(i);if(!o)return null;var a,c=o[0],s=r&&e.parsePatterns[r]||e.parsePatterns[e.defaultParseWidth],f=Array.isArray(s)?u(s,(function(e){return e.test(c)})):l(s,(function(e){return e.test(c)}));a=e.valueCallback?e.valueCallback(f):f,a=n.valueCallback?n.valueCallback(a):a;var h=t.slice(c.length);return{value:a,rest:h}}}function l(e,t){for(var n in e)if(e.hasOwnProperty(n)&&t(e[n]))return n}function u(e,t){for(var n=0;n0?"in "+i:i+" ago":i},formatLong:o,formatRelative:function(e,t,n,r){return a[e]},localize:{ordinalNumber:function(e,t){var n=Number(e),r=n%100;if(r>20||r<10)switch(r%10){case 1:return n+"st";case 2:return n+"nd";case 3:return n+"rd"}return n+"th"},era:c({values:{narrow:["B","A"],abbreviated:["BC","AD"],wide:["Before Christ","Anno Domini"]},defaultWidth:"wide"}),quarter:c({values:{narrow:["1","2","3","4"],abbreviated:["Q1","Q2","Q3","Q4"],wide:["1st quarter","2nd quarter","3rd quarter","4th quarter"]},defaultWidth:"wide",argumentCallback:function(e){return Number(e)-1}}),month:c({values:{narrow:["J","F","M","A","M","J","J","A","S","O","N","D"],abbreviated:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],wide:["January","February","March","April","May","June","July","August","September","October","November","December"]},defaultWidth:"wide"}),day:c({values:{narrow:["S","M","T","W","T","F","S"],short:["Su","Mo","Tu","We","Th","Fr","Sa"],abbreviated:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],wide:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]},defaultWidth:"wide"}),dayPeriod:c({values:{narrow:{am:"a",pm:"p",midnight:"mi",noon:"n",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"},abbreviated:{am:"AM",pm:"PM",midnight:"midnight",noon:"noon",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"},wide:{am:"a.m.",pm:"p.m.",midnight:"midnight",noon:"noon",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"}},defaultWidth:"wide",formattingValues:{narrow:{am:"a",pm:"p",midnight:"mi",noon:"n",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"},abbreviated:{am:"AM",pm:"PM",midnight:"midnight",noon:"noon",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"},wide:{am:"a.m.",pm:"p.m.",midnight:"midnight",noon:"noon",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"}},defaultFormattingWidth:"wide"})},match:{ordinalNumber:(f={matchPattern:/^(\d+)(th|st|nd|rd)?/i,parsePattern:/\d+/i,valueCallback:function(e){return parseInt(e,10)}},function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=e.match(f.matchPattern);if(!n)return null;var r=n[0],i=e.match(f.parsePattern);if(!i)return null;var o=f.valueCallback?f.valueCallback(i[0]):i[0];o=t.valueCallback?t.valueCallback(o):o;var a=e.slice(r.length);return{value:o,rest:a}}),era:s({matchPatterns:{narrow:/^(b|a)/i,abbreviated:/^(b\.?\s?c\.?|b\.?\s?c\.?\s?e\.?|a\.?\s?d\.?|c\.?\s?e\.?)/i,wide:/^(before christ|before common era|anno domini|common era)/i},defaultMatchWidth:"wide",parsePatterns:{any:[/^b/i,/^(a|c)/i]},defaultParseWidth:"any"}),quarter:s({matchPatterns:{narrow:/^[1234]/i,abbreviated:/^q[1234]/i,wide:/^[1234](th|st|nd|rd)? quarter/i},defaultMatchWidth:"wide",parsePatterns:{any:[/1/i,/2/i,/3/i,/4/i]},defaultParseWidth:"any",valueCallback:function(e){return e+1}}),month:s({matchPatterns:{narrow:/^[jfmasond]/i,abbreviated:/^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i,wide:/^(january|february|march|april|may|june|july|august|september|october|november|december)/i},defaultMatchWidth:"wide",parsePatterns:{narrow:[/^j/i,/^f/i,/^m/i,/^a/i,/^m/i,/^j/i,/^j/i,/^a/i,/^s/i,/^o/i,/^n/i,/^d/i],any:[/^ja/i,/^f/i,/^mar/i,/^ap/i,/^may/i,/^jun/i,/^jul/i,/^au/i,/^s/i,/^o/i,/^n/i,/^d/i]},defaultParseWidth:"any"}),day:s({matchPatterns:{narrow:/^[smtwf]/i,short:/^(su|mo|tu|we|th|fr|sa)/i,abbreviated:/^(sun|mon|tue|wed|thu|fri|sat)/i,wide:/^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i},defaultMatchWidth:"wide",parsePatterns:{narrow:[/^s/i,/^m/i,/^t/i,/^w/i,/^t/i,/^f/i,/^s/i],any:[/^su/i,/^m/i,/^tu/i,/^w/i,/^th/i,/^f/i,/^sa/i]},defaultParseWidth:"any"}),dayPeriod:s({matchPatterns:{narrow:/^(a|p|mi|n|(in the|at) (morning|afternoon|evening|night))/i,any:/^([ap]\.?\s?m\.?|midnight|noon|(in the|at) (morning|afternoon|evening|night))/i},defaultMatchWidth:"any",parsePatterns:{any:{am:/^a/i,pm:/^p/i,midnight:/^mi/i,noon:/^no/i,morning:/morning/i,afternoon:/afternoon/i,evening:/evening/i,night:/night/i}},defaultParseWidth:"any"})},options:{weekStartsOn:0,firstWeekContainsDate:1}};t.a=h},function(e,t,n){"use strict";var r=n(33),i=n(29),o=n(47),a=n(23),c=n(11),s=n(48);function l(){var e={};return e.promise=new Promise((function(t,n){e.resolve=t,e.reject=n})),e}var u=l,f=(n(151),[]),h=0;function d(e){try{v(),e()}finally{g()}}function p(e){f.push(e),h||(v(),m())}function z(e){try{return v(),e()}finally{m()}}function v(){h++}function g(){h--}function m(){var e;for(g();!h&&void 0!==(e=f.shift());)d(e)}var y=function(e){return function(t){return e.some((function(e){return j(e)(t)}))}},b=function(e){return function(t){return e(t)}},w=function(e){return function(t){return t.type===String(e)}},k=function(e){return function(t){return t.type===e}},x=function(){return c.H};function j(e){var t="*"===e?x:Object(a.k)(e)?w:Object(a.a)(e)?y:Object(a.l)(e)?w:Object(a.d)(e)?b:Object(a.m)(e)?k:null;if(null===t)throw new Error("invalid pattern: "+e);return t(e)}var M={type:r.b},_=function(e){return e&&e.type===r.b};function C(e){void 0===e&&(e=Object(c.B)());var t=!1,n=[];return{take:function(r){t&&e.isEmpty()?r(M):e.isEmpty()?(n.push(r),r.cancel=function(){Object(c.O)(n,r)}):r(e.take())},put:function(r){if(!t){if(0===n.length)return e.put(r);n.shift()(r)}},flush:function(n){t&&e.isEmpty()?n(M):n(e.flush())},close:function(){if(!t){t=!0;var e=n;n=[];for(var r=0,i=e.length;r2?p-2:0),g=2;g=arguments.length)?u=n[l]:(u=arguments[c],c+=1),o[l]=u,Object(a.a)(u)||(s-=1),l+=1}return s<=0?i.apply(this,o):Object(r.a)(s,e(t,o,i))}}(e,[],t))}));t.a=c},function(e,t,n){"use strict";var r=n(112),i={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},a={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},c={};function s(e){return r.isMemo(e)?a:c[e.$$typeof]||i}c[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0};var l=Object.defineProperty,u=Object.getOwnPropertyNames,f=Object.getOwnPropertySymbols,h=Object.getOwnPropertyDescriptor,d=Object.getPrototypeOf,p=Object.prototype;e.exports=function e(t,n,r){if("string"!==typeof n){if(p){var i=d(n);i&&i!==p&&e(t,i,r)}var a=u(n);f&&(a=a.concat(f(n)));for(var c=s(t),z=s(n),v=0;v=0;){if(n[o]===e)return r[o]===t;o-=1}switch(i){case"Map":return e.size===t.size&&f(e.entries(),t.entries(),n.concat([e]),r.concat([t]));case"Set":return e.size===t.size&&f(e.values(),t.values(),n.concat([e]),r.concat([t]));case"Arguments":case"Array":case"Object":case"Boolean":case"Number":case"String":case"Date":case"Error":case"RegExp":case"Int8Array":case"Uint8Array":case"Uint8ClampedArray":case"Int16Array":case"Uint16Array":case"Int32Array":case"Uint32Array":case"Float32Array":case"Float64Array":case"ArrayBuffer":break;default:return!1}var l=Object(s.a)(e);if(l.length!==Object(s.a)(t).length)return!1;var d=n.concat([e]),p=r.concat([t]);for(o=l.length-1;o>=0;){var z=l[o];if(!Object(a.a)(z,t)||!h(t[z],e[z],d,p))return!1;o-=1}return!0}var d=Object(r.a)((function(e,t){return h(e,t,[],[])}));t.a=d},function(e,t,n){"use strict";var r=n(30),i=n(145),o=n(130);function a(e){return'"'+e.replace(/\\/g,"\\\\").replace(/[\b]/g,"\\b").replace(/\f/g,"\\f").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t").replace(/\v/g,"\\v").replace(/\0/g,"\\0").replace(/"/g,'\\"')+'"'}var c=function(e){return(e<10?"0":"")+e},s="function"===typeof Date.prototype.toISOString?function(e){return e.toISOString()}:function(e){return e.getUTCFullYear()+"-"+c(e.getUTCMonth()+1)+"-"+c(e.getUTCDate())+"T"+c(e.getUTCHours())+":"+c(e.getUTCMinutes())+":"+c(e.getUTCSeconds())+"."+(e.getUTCMilliseconds()/1e3).toFixed(3).slice(2,5)+"Z"},l=n(57);var u=n(19),f=n(284),h=Object(u.a)((function(e,t){return Object(f.a)((n=e,function(){return!n.apply(this,arguments)}),t);var n}));var d=Object(r.a)((function(e){return function e(t,n){var r=function(r){var o=n.concat([t]);return Object(i.a)(r,o)?"":e(r,o)},c=function(e,t){return Object(o.a)((function(t){return a(t)+": "+r(e[t])}),t.slice().sort())};switch(Object.prototype.toString.call(t)){case"[object Arguments]":return"(function() { return arguments; }("+Object(o.a)(r,t).join(", ")+"))";case"[object Array]":return"["+Object(o.a)(r,t).concat(c(t,h((function(e){return/^\d+$/.test(e)}),Object(l.a)(t)))).join(", ")+"]";case"[object Boolean]":return"object"===typeof t?"new Boolean("+r(t.valueOf())+")":t.toString();case"[object Date]":return"new Date("+(isNaN(t.valueOf())?r(NaN):a(s(t)))+")";case"[object Null]":return"null";case"[object Number]":return"object"===typeof t?"new Number("+r(t.valueOf())+")":1/t===-1/0?"-0":t.toString(10);case"[object String]":return"object"===typeof t?"new String("+r(t.valueOf())+")":a(t);case"[object Undefined]":return"undefined";default:if("function"===typeof t.toString){var u=t.toString();if("[object Object]"!==u)return u}return"{"+c(t,Object(l.a)(t)).join(", ")+"}"}}(e,[])}));t.a=d},function(e,t,n){"use strict";var r=n(29),i=n(47),o=n(79),a=n(0),c=n.n(a),s=n(13),l=n.n(s),u=n(34),f=n.n(u),h=n(32),d=n.n(h),p=!1,z=c.a.createContext(null),v="unmounted",g="exited",m="entering",y="entered",b=function(e){function t(t,n){var r;r=e.call(this,t,n)||this;var i,o=n&&!n.isMounting?t.enter:t.appear;return r.appearStatus=null,t.in?o?(i=g,r.appearStatus=m):i=y:i=t.unmountOnExit||t.mountOnEnter?v:g,r.state={status:i},r.nextCallback=null,r}Object(o.a)(t,e),t.getDerivedStateFromProps=function(e,t){return e.in&&t.status===v?{status:g}:null};var n=t.prototype;return n.componentDidMount=function(){this.updateStatus(!0,this.appearStatus)},n.componentDidUpdate=function(e){var t=null;if(e!==this.props){var n=this.state.status;this.props.in?n!==m&&n!==y&&(t=m):n!==m&&n!==y||(t="exiting")}this.updateStatus(!1,t)},n.componentWillUnmount=function(){this.cancelNextCallback()},n.getTimeouts=function(){var e,t,n,r=this.props.timeout;return e=t=n=r,null!=r&&"number"!==typeof r&&(e=r.exit,t=r.enter,n=void 0!==r.appear?r.appear:t),{exit:e,enter:t,appear:n}},n.updateStatus=function(e,t){if(void 0===e&&(e=!1),null!==t){this.cancelNextCallback();var n=d.a.findDOMNode(this);t===m?this.performEnter(n,e):this.performExit(n)}else this.props.unmountOnExit&&this.state.status===g&&this.setState({status:v})},n.performEnter=function(e,t){var n=this,r=this.props.enter,i=this.context?this.context.isMounting:t,o=this.getTimeouts(),a=i?o.appear:o.enter;!t&&!r||p?this.safeSetState({status:y},(function(){n.props.onEntered(e)})):(this.props.onEnter(e,i),this.safeSetState({status:m},(function(){n.props.onEntering(e,i),n.onTransitionEnd(e,a,(function(){n.safeSetState({status:y},(function(){n.props.onEntered(e,i)}))}))})))},n.performExit=function(e){var t=this,n=this.props.exit,r=this.getTimeouts();n&&!p?(this.props.onExit(e),this.safeSetState({status:"exiting"},(function(){t.props.onExiting(e),t.onTransitionEnd(e,r.exit,(function(){t.safeSetState({status:g},(function(){t.props.onExited(e)}))}))}))):this.safeSetState({status:g},(function(){t.props.onExited(e)}))},n.cancelNextCallback=function(){null!==this.nextCallback&&(this.nextCallback.cancel(),this.nextCallback=null)},n.safeSetState=function(e,t){t=this.setNextCallback(t),this.setState(e,t)},n.setNextCallback=function(e){var t=this,n=!0;return this.nextCallback=function(r){n&&(n=!1,t.nextCallback=null,e(r))},this.nextCallback.cancel=function(){n=!1},this.nextCallback},n.onTransitionEnd=function(e,t,n){this.setNextCallback(n);var r=null==t&&!this.props.addEndListener;e&&!r?(this.props.addEndListener&&this.props.addEndListener(e,this.nextCallback),null!=t&&setTimeout(this.nextCallback,t)):setTimeout(this.nextCallback,0)},n.render=function(){var e=this.state.status;if(e===v)return null;var t=this.props,n=t.children,r=Object(i.a)(t,["children"]);if(delete r.in,delete r.mountOnEnter,delete r.unmountOnExit,delete r.appear,delete r.enter,delete r.exit,delete r.timeout,delete r.addEndListener,delete r.onEnter,delete r.onEntering,delete r.onEntered,delete r.onExit,delete r.onExiting,delete r.onExited,"function"===typeof n)return c.a.createElement(z.Provider,{value:null},n(e,r));var o=c.a.Children.only(n);return(c.a.createElement(z.Provider,{value:null},c.a.cloneElement(o,r)))},t}(c.a.Component);function w(){}b.contextType=z,b.propTypes={},b.defaultProps={in:!1,mountOnEnter:!1,unmountOnExit:!1,appear:!1,enter:!0,exit:!0,onEnter:w,onEntering:w,onEntered:w,onExit:w,onExiting:w,onExited:w},b.UNMOUNTED=0,b.EXITED=1,b.ENTERING=2,b.ENTERED=3,b.EXITING=4;var k=b,x=n(67);function j(e,t){var n=Object.create(null);return e&&a.Children.map(e,(function(e){return e})).forEach((function(e){n[e.key]=function(e){return t&&Object(a.isValidElement)(e)?t(e):e}(e)})),n}function M(e,t,n){return null!=n[t]?n[t]:e.props[t]}function _(e,t,n){var r=j(e.children),i=function(e,t){function n(n){return n in t?t[n]:e[n]}e=e||{},t=t||{};var r,i=Object.create(null),o=[];for(var a in e)a in t?o.length&&(i[a]=o,o=[]):o.push(a);var c={};for(var s in t){if(i[s])for(r=0;r0}function D(e){return Object.keys(e).map((function(t){return e[t]}))}var P=!("undefined"===typeof window||!window.document||!window.document.createElement);var V,N=((V=function(e,t,n){var r=e[t];return!1===r||H(r)?null:new Error(n+" expect "+t+" \n to be a valid Number > 0 or equal to false. "+r+" given.")}).isRequired=function(e,t,n){if("undefined"===typeof e[t])return new Error("The prop "+t+" is marked as required in \n "+n+", but its value is undefined.");V(e,t,n)},V),I={list:new Map,emitQueue:new Map,on:function(e,t){return this.list.has(e)||this.list.set(e,[]),this.list.get(e).push(t),this},off:function(e){return this.list.delete(e),this},cancelEmit:function(e){var t=this.emitQueue.get(e);return t&&(t.forEach((function(e){return clearTimeout(e)})),this.emitQueue.delete(e)),this},emit:function(e){for(var t=this,n=arguments.length,r=new Array(n>1?n-1:0),i=1;i=1?"onTransitionEnd":"onAnimationEnd"]=d&&p<1?null:a,n);return c.a.createElement("div",Object(r.a)({className:g,style:v},m))}function B(e){return e.targetTouches&&e.targetTouches.length>=1?e.targetTouches[0].clientX:e.clientX}F.propTypes={delay:N.isRequired,isRunning:l.a.bool.isRequired,closeToast:l.a.func.isRequired,rtl:l.a.bool.isRequired,type:l.a.string,hide:l.a.bool,className:l.a.oneOfType([l.a.string,l.a.object]),progress:l.a.number,controlledProgress:l.a.bool},F.defaultProps={type:O.DEFAULT,hide:!1};var U=P&&/(msie|trident)/i.test(navigator.userAgent),W=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),i=0;i=1?e.targetTouches[0].clientY:e.clientY}(e),t.drag.start!==t.drag.x&&(t.flag.canCloseOnClick=!1),t.ref.style.transform="translateX("+t.drag.deltaX+"px)",t.ref.style.opacity=1-Math.abs(t.drag.deltaX/t.drag.removalDistance))},t.onDragEnd=function(e){if(t.flag.canDrag){if(t.flag.canDrag=!1,Math.abs(t.drag.deltaX)>t.drag.removalDistance)return void t.setState({preventExitTransition:!0},t.props.closeToast);t.ref.style.transition="transform 0.2s, opacity 0.2s",t.ref.style.transform="translateX(0)",t.ref.style.opacity=1}},t.onDragTransitionEnd=function(){if(t.boundingRect){var e=t.boundingRect,n=e.top,r=e.bottom,i=e.left,o=e.right;t.props.pauseOnHover&&t.drag.x>=i&&t.drag.x<=o&&t.drag.y>=n&&t.drag.y<=r?t.pauseToast():t.playToast()}},t.onExitTransitionEnd=function(){if(U)t.props.onExited();else{var e=t.ref.scrollHeight,n=t.ref.style;requestAnimationFrame((function(){n.minHeight="initial",n.height=e+"px",n.transition="all 0.4s ",requestAnimationFrame((function(){n.height=0,n.padding=0,n.margin=0})),setTimeout((function(){return t.props.onExited()}),400)}))}},t}Object(o.a)(t,e);var n=t.prototype;return n.componentDidMount=function(){this.props.onOpen(this.props.children.props),this.props.draggable&&this.bindDragEvents(),this.props.pauseOnFocusLoss&&this.bindFocusEvents()},n.componentDidUpdate=function(e){e.draggable!==this.props.draggable&&(this.props.draggable?this.bindDragEvents():this.unbindDragEvents()),e.pauseOnFocusLoss!==this.props.pauseOnFocusLoss&&(this.props.pauseOnFocusLoss?this.bindFocusEvents():this.unbindFocusEvents())},n.componentWillUnmount=function(){this.props.onClose(this.props.children.props),this.props.draggable&&this.unbindDragEvents(),this.props.pauseOnFocusLoss&&this.unbindFocusEvents()},n.bindFocusEvents=function(){window.addEventListener("focus",this.playToast),window.addEventListener("blur",this.pauseToast)},n.unbindFocusEvents=function(){window.removeEventListener("focus",this.playToast),window.removeEventListener("blur",this.pauseToast)},n.bindDragEvents=function(){document.addEventListener("mousemove",this.onDragMove),document.addEventListener("mouseup",this.onDragEnd),document.addEventListener("touchmove",this.onDragMove),document.addEventListener("touchend",this.onDragEnd)},n.unbindDragEvents=function(){document.removeEventListener("mousemove",this.onDragMove),document.removeEventListener("mouseup",this.onDragEnd),document.removeEventListener("touchmove",this.onDragMove),document.removeEventListener("touchend",this.onDragEnd)},n.render=function(){var e,t=this,n=this.props,i=n.closeButton,o=n.children,a=n.autoClose,s=n.pauseOnHover,l=n.onClick,u=n.closeOnClick,h=n.type,d=n.hideProgressBar,p=n.closeToast,z=n.transition,v=n.position,g=n.className,m=n.bodyClassName,y=n.progressClassName,b=n.progressStyle,w=n.updateId,k=n.role,x=n.progress,j=n.rtl,M={className:f()(L+"__toast",L+"__toast--"+h,(e={},e[L+"__toast--rtl"]=j,e),g)};a&&s&&(M.onMouseEnter=this.pauseToast,M.onMouseLeave=this.playToast),u&&(M.onClick=function(e){l&&l(e),t.flag.canCloseOnClick&&p()});var _=parseFloat(x)===x;return c.a.createElement(z,{in:this.props.in,appear:!0,onExited:this.onExitTransitionEnd,position:v,preventExitTransition:this.state.preventExitTransition},c.a.createElement("div",Object(r.a)({onClick:l},M,{ref:function(e){return t.ref=e},onMouseDown:this.onDragStart,onTouchStart:this.onDragStart,onMouseUp:this.onDragTransitionEnd,onTouchEnd:this.onDragTransitionEnd}),c.a.createElement("div",Object(r.a)({},this.props.in&&{role:k},{className:f()(L+"__toast-body",m)}),o),i&&i,(a||_)&&c.a.createElement(F,Object(r.a)({},w&&!_?{key:"pb-"+w}:{},{rtl:j,delay:a,isRunning:this.state.isRunning,closeToast:p,hide:d,type:h,style:b,className:y,controlledProgress:_,progress:x}))))},t}(a.Component);function G(e){var t=e.closeToast,n=e.type,r=e.ariaLabel;return c.a.createElement("button",{className:L+"__close-button "+L+"__close-button--"+n,type:"button",onClick:function(e){e.stopPropagation(),t(e)},"aria-label":r},"\u2716\ufe0e")}W.propTypes={closeButton:l.a.oneOfType([l.a.node,l.a.bool]).isRequired,autoClose:N.isRequired,children:l.a.node.isRequired,closeToast:l.a.func.isRequired,position:l.a.oneOf(D(T)).isRequired,pauseOnHover:l.a.bool.isRequired,pauseOnFocusLoss:l.a.bool.isRequired,closeOnClick:l.a.bool.isRequired,transition:l.a.func.isRequired,rtl:l.a.bool.isRequired,hideProgressBar:l.a.bool.isRequired,draggable:l.a.bool.isRequired,draggablePercent:l.a.number.isRequired,in:l.a.bool,onExited:l.a.func,onOpen:l.a.func,onClose:l.a.func,type:l.a.oneOf(D(O)),className:l.a.oneOfType([l.a.string,l.a.object]),bodyClassName:l.a.oneOfType([l.a.string,l.a.object]),progressClassName:l.a.oneOfType([l.a.string,l.a.object]),progressStyle:l.a.object,progress:l.a.number,updateId:l.a.oneOfType([l.a.string,l.a.number]),ariaLabel:l.a.string,containerId:l.a.oneOfType([l.a.string,l.a.number]),role:l.a.string},W.defaultProps={type:O.DEFAULT,in:!0,onOpen:A,onClose:A,className:null,bodyClassName:null,progressClassName:null,updateId:null},G.propTypes={closeToast:l.a.func,arialLabel:l.a.string},G.defaultProps={ariaLabel:"close"};var Y=R({enter:L+"__bounce-enter",exit:L+"__bounce-exit",appendPosition:!0}),Z=(R({enter:L+"__slide-enter",exit:L+"__slide-exit",duration:[450,750],appendPosition:!0}),R({enter:L+"__zoom-enter",exit:L+"__zoom-exit"}),R({enter:L+"__flip-enter",exit:L+"__flip-exit"}),function(e){function t(){for(var t,n=arguments.length,r=new Array(n),i=0;i0}function ne(e,t){var n=function(e){return te()?e?$.get(e):$.get(X):null}(t.containerId);if(!n)return null;var r=n.collection[e];return"undefined"===typeof r?null:r}function re(e,t){return Object(r.a)({},e,{type:t,toastId:oe(e)})}function ie(){return(Math.random().toString(36)+Date.now().toString(36)).substr(2,10)}function oe(e){return e&&("string"===typeof e.toastId||"number"===typeof e.toastId&&!isNaN(e.toastId))?e.toastId:ie()}function ae(e,t){return te()?I.emit(E.SHOW,e,t):(J.push({action:E.SHOW,content:e,options:t}),ee&&P&&(ee=!1,K=document.createElement("div"),document.body.appendChild(K),Object(h.render)(c.a.createElement(Z,Q),K))),t.toastId}var ce=function(e,t){return ae(e,re(t,t&&t.type||O.DEFAULT))},se=function(e){O[e]!==O.DEFAULT&&(ce[O[e].toLowerCase()]=function(t,n){return ae(t,re(n,n&&n.type||O[e]))})};for(var le in O)se(le);ce.warn=ce.warning,ce.dismiss=function(e){return void 0===e&&(e=null),te()&&I.emit(E.CLEAR,e)},ce.isActive=function(e){var t=!1;return $.size>0&&$.forEach((function(n){n.isToastActive(e)&&(t=!0)})),t},ce.update=function(e,t){void 0===t&&(t={}),setTimeout((function(){var n=ne(e,t);if(n){var i=n.options,o=n.content,a=Object(r.a)({},i,{},t,{toastId:t.toastId||e});t.toastId&&t.toastId!==e?a.staleToastId=e:a.updateId=ie();var c="undefined"!==typeof a.render?a.render:o;delete a.render,ae(c,a)}}),0)},ce.done=function(e){ce.update(e,{progress:1})},ce.onChange=function(e){"function"===typeof e&&I.on(E.ON_CHANGE,e)},ce.configure=function(e){ee=!0,Q=e},ce.POSITION=T,ce.TYPE=O,I.on(E.DID_MOUNT,(function(e){X=e.props.containerId||e,$.set(X,e),J.forEach((function(e){I.emit(e.action,e.content,e.options)})),J=[]})).on(E.WILL_UNMOUNT,(function(e){e?$.delete(e.props.containerId||e):$.clear(),0===$.size&&I.off(E.SHOW).off(E.CLEAR),P&&K&&document.body.removeChild(K)}))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.invariant=t.UNICODE_EXTENSION_SEQUENCE_REGEX=void 0,t.UNICODE_EXTENSION_SEQUENCE_REGEX=/-u(?:-[0-9a-z]{2,8})+/gi,t.invariant=function(e,t,n){if(void 0===n&&(n=Error),!e)throw new n(t)}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.shortMorePenalty=t.shortLessPenalty=t.longMorePenalty=t.longLessPenalty=t.differentNumericTypePenalty=t.additionPenalty=t.removalPenalty=t.DATE_TIME_PROPS=void 0,t.DATE_TIME_PROPS=["weekday","era","year","month","day","hour","minute","second","timeZoneName"],t.removalPenalty=120,t.additionPenalty=20,t.differentNumericTypePenalty=15,t.longLessPenalty=8,t.longMorePenalty=6,t.shortLessPenalty=6,t.shortMorePenalty=3},function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return a}));var r=n(15),i=n(10),o=n(6);function a(e,t){Object(o.a)(2,arguments);var n=Object(i.default)(e),a=Object(r.a)(t);return isNaN(a)?new Date(NaN):a?(n.setDate(n.getDate()+a),n):n}},function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return a}));var r=n(15),i=n(10),o=n(6);function a(e,t){Object(o.a)(2,arguments);var n=Object(i.default)(e),a=Object(r.a)(t);if(isNaN(a))return new Date(NaN);if(!a)return n;var c=n.getDate(),s=new Date(n.getTime());return s.setMonth(n.getMonth()+a+1,0),c>=s.getDate()?s:(n.setFullYear(s.getFullYear(),s.getMonth(),c),n)}},,function(e,t,n){"use strict";function r(e){return"[object Function]"===Object.prototype.toString.call(e)}n.d(t,"a",(function(){return r}))},,function(e,t,n){"use strict";(function(e){n.d(t,"a",(function(){return i})),n.d(t,"b",(function(){return o}));var r=function(){return(r=Object.assign||function(e){for(var t,n=1,r=arguments.length;nt?1:e>=t?0:NaN},i=function(e){var t;return 1===e.length&&(t=e,e=function(e,n){return r(t(e),n)}),{left:function(t,n,r,i){for(null==r&&(r=0),null==i&&(i=t.length);r>>1;e(t[o],n)<0?r=o+1:i=o}return r},right:function(t,n,r,i){for(null==r&&(r=0),null==i&&(i=t.length);r>>1;e(t[o],n)>0?i=o:r=o+1}return r}}};var o=i(r),a=o.right,c=o.left,s=a,l=function(e,t){null==t&&(t=u);for(var n=0,r=e.length-1,i=e[0],o=new Array(r<0?0:r);ne?1:t>=e?0:NaN},d=function(e){return null===e?NaN:+e},p=function(e,t){var n,r,i=e.length,o=0,a=-1,c=0,s=0;if(null==t)for(;++a1)return s/(o-1)},z=function(e,t){var n=p(e,t);return n?Math.sqrt(n):n},v=function(e,t){var n,r,i,o=e.length,a=-1;if(null==t){for(;++a=n)for(r=i=n;++an&&(r=n),i=n)for(r=i=n;++an&&(r=n),i0)return[e];if((r=t0)for(e=Math.ceil(e/a),t=Math.floor(t/a),o=new Array(i=Math.ceil(t-e+1));++c=0?(o>=x?10:o>=j?5:o>=M?2:1)*Math.pow(10,i):-Math.pow(10,-i)/(o>=x?10:o>=j?5:o>=M?2:1)}function q(e,t,n){var r=Math.abs(t-e)/Math.max(0,n),i=Math.pow(10,Math.floor(Math.log(r)/Math.LN10)),o=r/i;return o>=x?i*=10:o>=j?i*=5:o>=M&&(i*=2),tf;)h.pop(),--d;var p,z=new Array(d+1);for(i=0;i<=d;++i)(p=z[i]=[]).x0=i>0?h[i-1]:u,p.x1=i=1)return+n(e[r-1],r-1,e);var r,i=(r-1)*t,o=Math.floor(i),a=+n(e[o],o,e);return a+(+n(e[o+1],o+1,e)-a)*(i-o)}},E=function(e,t,n){return e=y.call(e,d).sort(r),Math.ceil((n-t)/(2*(O(e,.75)-O(e,.25))*Math.pow(e.length,-1/3)))},A=function(e,t,n){return Math.ceil((n-t)/(3.5*z(e)*Math.pow(e.length,-1/3)))},L=function(e,t){var n,r,i=e.length,o=-1;if(null==t){for(;++o=n)for(r=n;++or&&(r=n)}else for(;++o=n)for(r=n;++or&&(r=n);return r},H=function(e,t){var n,r=e.length,i=r,o=-1,a=0;if(null==t)for(;++o=0;)for(t=(r=e[i]).length;--t>=0;)n[--a]=r[t];return n},V=function(e,t){var n,r,i=e.length,o=-1;if(null==t){for(;++o=n)for(r=n;++on&&(r=n)}else for(;++o=n)for(r=n;++on&&(r=n);return r},N=function(e,t){for(var n=t.length,r=new Array(n);n--;)r[n]=e[t[n]];return r},I=function(e,t){if(n=e.length){var n,i,o=0,a=0,c=e[a];for(null==t&&(t=r);++o=0&&(n=e.slice(r+1),e=e.slice(0,r)),e&&!t.hasOwnProperty(e))throw new Error("unknown type: "+e);return{type:e,name:n}}))}function de(e,t){for(var n,r=0,i=e.length;r0)for(var n,r,i=new Array(n),o=0;o=0&&"xmlns"!==(t=e.slice(0,n))&&(e=e.slice(n+1)),ge.hasOwnProperty(t)?{space:ge[t],local:e}:e};function ye(e){return function(){var t=this.ownerDocument,n=this.namespaceURI;return n===ve&&t.documentElement.namespaceURI===ve?t.createElement(e):t.createElementNS(n,e)}}function be(e){return function(){return this.ownerDocument.createElementNS(e.space,e.local)}}var we=function(e){var t=me(e);return(t.local?be:ye)(t)},ke=0;function xe(){return new je}function je(){this._="@"+(++ke).toString(36)}je.prototype=xe.prototype={constructor:je,get:function(e){for(var t=this._;!(t in e);)if(!(e=e.parentNode))return;return e[t]},set:function(e,t){return e[this._]=t},remove:function(e){return this._ in e&&delete e[this._]},toString:function(){return this._}};var Me=function(e){return function(){return this.matches(e)}};if("undefined"!==typeof document){var _e=document.documentElement;if(!_e.matches){var Ce=_e.webkitMatchesSelector||_e.msMatchesSelector||_e.mozMatchesSelector||_e.oMatchesSelector;Me=function(e){return function(){return Ce.call(this,e)}}}}var qe=Me,Se={},Te=null;"undefined"!==typeof document&&("onmouseenter"in document.documentElement||(Se={mouseenter:"mouseover",mouseleave:"mouseout"}));function Oe(e,t,n){return e=Ee(e,t,n),function(t){var n=t.relatedTarget;n&&(n===this||8&n.compareDocumentPosition(this))||e.call(this,t)}}function Ee(e,t,n){return function(r){var i=Te;Te=r;try{e.call(this,this.__data__,t,n)}finally{Te=i}}}function Ae(e){return e.trim().split(/^|\s+/).map((function(e){var t="",n=e.indexOf(".");return n>=0&&(t=e.slice(n+1),e=e.slice(0,n)),{type:e,name:t}}))}function Le(e){return function(){var t=this.__on;if(t){for(var n,r=0,i=-1,o=t.length;rt?1:e>=t?0:NaN}function Xe(e){return function(){this.removeAttribute(e)}}function Ke(e){return function(){this.removeAttributeNS(e.space,e.local)}}function Qe(e,t){return function(){this.setAttribute(e,t)}}function Je(e,t){return function(){this.setAttributeNS(e.space,e.local,t)}}function et(e,t){return function(){var n=t.apply(this,arguments);null==n?this.removeAttribute(e):this.setAttribute(e,n)}}function tt(e,t){return function(){var n=t.apply(this,arguments);null==n?this.removeAttributeNS(e.space,e.local):this.setAttributeNS(e.space,e.local,n)}}var nt=function(e){return e.ownerDocument&&e.ownerDocument.defaultView||e.document&&e||e.defaultView};function rt(e){return function(){this.style.removeProperty(e)}}function it(e,t,n){return function(){this.style.setProperty(e,t,n)}}function ot(e,t,n){return function(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(e):this.style.setProperty(e,r,n)}}function at(e,t){return e.style.getPropertyValue(t)||nt(e).getComputedStyle(e,null).getPropertyValue(t)}function ct(e){return function(){delete this[e]}}function st(e,t){return function(){this[e]=t}}function lt(e,t){return function(){var n=t.apply(this,arguments);null==n?delete this[e]:this[e]=n}}function ut(e){return e.trim().split(/^|\s+/)}function ft(e){return e.classList||new ht(e)}function ht(e){this._node=e,this._names=ut(e.getAttribute("class")||"")}function dt(e,t){for(var n=ft(e),r=-1,i=t.length;++r=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};function mt(){this.textContent=""}function yt(e){return function(){this.textContent=e}}function bt(e){return function(){var t=e.apply(this,arguments);this.textContent=null==t?"":t}}function wt(){this.innerHTML=""}function kt(e){return function(){this.innerHTML=e}}function xt(e){return function(){var t=e.apply(this,arguments);this.innerHTML=null==t?"":t}}function jt(){this.nextSibling&&this.parentNode.appendChild(this)}function Mt(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function _t(){return null}function Ct(){var e=this.parentNode;e&&e.removeChild(this)}function qt(e,t,n){var r=nt(e),i=r.CustomEvent;"function"===typeof i?i=new i(t,n):(i=r.document.createEvent("Event"),n?(i.initEvent(t,n.bubbles,n.cancelable),i.detail=n.detail):i.initEvent(t,!1,!1)),e.dispatchEvent(i)}function St(e,t){return function(){return qt(this,e,t)}}function Tt(e,t){return function(){return qt(this,e,t.apply(this,arguments))}}var Ot=[null];function Et(e,t){this._groups=e,this._parents=t}function At(){return new Et([[document.documentElement]],Ot)}Et.prototype=At.prototype={constructor:Et,select:function(e){"function"!==typeof e&&(e=Re(e));for(var t=this._groups,n=t.length,r=new Array(n),i=0;i=w&&(w=b+1);!(y=g[w])&&++w=0;)(r=i[o])&&(a&&a!==r.nextSibling&&a.parentNode.insertBefore(r,a),a=r);return this},sort:function(e){function t(t,n){return t&&n?e(t.__data__,n.__data__):!t-!n}e||(e=$e);for(var n=this._groups,r=n.length,i=new Array(r),o=0;o1?this.each((null==t?rt:"function"===typeof t?ot:it)(e,t,null==n?"":n)):at(this.node(),e)},property:function(e,t){return arguments.length>1?this.each((null==t?ct:"function"===typeof t?lt:st)(e,t)):this.node()[e]},classed:function(e,t){var n=ut(e+"");if(arguments.length<2){for(var r=ft(this.node()),i=-1,o=n.length;++if}s.mouse("drag")}function z(){Ht(Te.view).on("mousemove.drag mouseup.drag",null),Ft(Te.view,n),It(),s.mouse("end")}function v(){if(i.apply(this,arguments)){var e,t,n=Te.changedTouches,r=o.apply(this,arguments),a=n.length;for(e=0;e>8&15|t>>4&240,t>>4&15|240&t,(15&t)<<4|15&t,1):(t=rn.exec(e))?dn(parseInt(t[1],16)):(t=on.exec(e))?new gn(t[1],t[2],t[3],1):(t=an.exec(e))?new gn(255*t[1]/100,255*t[2]/100,255*t[3]/100,1):(t=cn.exec(e))?pn(t[1],t[2],t[3],t[4]):(t=sn.exec(e))?pn(255*t[1]/100,255*t[2]/100,255*t[3]/100,t[4]):(t=ln.exec(e))?mn(t[1],t[2]/100,t[3]/100,1):(t=un.exec(e))?mn(t[1],t[2]/100,t[3]/100,t[4]):fn.hasOwnProperty(e)?dn(fn[e]):"transparent"===e?new gn(NaN,NaN,NaN,0):null}function dn(e){return new gn(e>>16&255,e>>8&255,255&e,1)}function pn(e,t,n,r){return r<=0&&(e=t=n=NaN),new gn(e,t,n,r)}function zn(e){return e instanceof Qt||(e=hn(e)),e?new gn((e=e.rgb()).r,e.g,e.b,e.opacity):new gn}function vn(e,t,n,r){return 1===arguments.length?zn(e):new gn(e,t,n,null==r?1:r)}function gn(e,t,n,r){this.r=+e,this.g=+t,this.b=+n,this.opacity=+r}function mn(e,t,n,r){return r<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new bn(e,t,n,r)}function yn(e,t,n,r){return 1===arguments.length?function(e){if(e instanceof bn)return new bn(e.h,e.s,e.l,e.opacity);if(e instanceof Qt||(e=hn(e)),!e)return new bn;if(e instanceof bn)return e;var t=(e=e.rgb()).r/255,n=e.g/255,r=e.b/255,i=Math.min(t,n,r),o=Math.max(t,n,r),a=NaN,c=o-i,s=(o+i)/2;return c?(a=t===o?(n-r)/c+6*(n0&&s<1?0:a,new bn(a,c,s,e.opacity)}(e):new bn(e,t,n,null==r?1:r)}function bn(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}function wn(e,t,n){return 255*(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)}Xt(Qt,hn,{displayable:function(){return this.rgb().displayable()},toString:function(){return this.rgb()+""}}),Xt(gn,vn,Kt(Qt,{brighter:function(e){return e=null==e?1/.7:Math.pow(1/.7,e),new gn(this.r*e,this.g*e,this.b*e,this.opacity)},darker:function(e){return e=null==e?.7:Math.pow(.7,e),new gn(this.r*e,this.g*e,this.b*e,this.opacity)},rgb:function(){return this},displayable:function(){return 0<=this.r&&this.r<=255&&0<=this.g&&this.g<=255&&0<=this.b&&this.b<=255&&0<=this.opacity&&this.opacity<=1},toString:function(){var e=this.opacity;return(1===(e=isNaN(e)?1:Math.max(0,Math.min(1,e)))?"rgb(":"rgba(")+Math.max(0,Math.min(255,Math.round(this.r)||0))+", "+Math.max(0,Math.min(255,Math.round(this.g)||0))+", "+Math.max(0,Math.min(255,Math.round(this.b)||0))+(1===e?")":", "+e+")")}})),Xt(bn,yn,Kt(Qt,{brighter:function(e){return e=null==e?1/.7:Math.pow(1/.7,e),new bn(this.h,this.s,this.l*e,this.opacity)},darker:function(e){return e=null==e?.7:Math.pow(.7,e),new bn(this.h,this.s,this.l*e,this.opacity)},rgb:function(){var e=this.h%360+360*(this.h<0),t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*t,i=2*n-r;return new gn(wn(e>=240?e-240:e+120,i,r),wn(e,i,r),wn(e<120?e+240:e-120,i,r),this.opacity)},displayable:function(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1}}));var kn=Math.PI/180,xn=180/Math.PI,jn=.95047,Mn=1,_n=1.08883,Cn=4/29,qn=6/29,Sn=3*qn*qn,Tn=qn*qn*qn;function On(e){if(e instanceof An)return new An(e.l,e.a,e.b,e.opacity);if(e instanceof Nn){var t=e.h*kn;return new An(e.l,Math.cos(t)*e.c,Math.sin(t)*e.c,e.opacity)}e instanceof gn||(e=zn(e));var n=Pn(e.r),r=Pn(e.g),i=Pn(e.b),o=Ln((.4124564*n+.3575761*r+.1804375*i)/jn),a=Ln((.2126729*n+.7151522*r+.072175*i)/Mn);return new An(116*a-16,500*(o-a),200*(a-Ln((.0193339*n+.119192*r+.9503041*i)/_n)),e.opacity)}function En(e,t,n,r){return 1===arguments.length?On(e):new An(e,t,n,null==r?1:r)}function An(e,t,n,r){this.l=+e,this.a=+t,this.b=+n,this.opacity=+r}function Ln(e){return e>Tn?Math.pow(e,1/3):e/Sn+Cn}function Hn(e){return e>qn?e*e*e:Sn*(e-Cn)}function Dn(e){return 255*(e<=.0031308?12.92*e:1.055*Math.pow(e,1/2.4)-.055)}function Pn(e){return(e/=255)<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)}function Vn(e,t,n,r){return 1===arguments.length?function(e){if(e instanceof Nn)return new Nn(e.h,e.c,e.l,e.opacity);e instanceof An||(e=On(e));var t=Math.atan2(e.b,e.a)*xn;return new Nn(t<0?t+360:t,Math.sqrt(e.a*e.a+e.b*e.b),e.l,e.opacity)}(e):new Nn(e,t,n,null==r?1:r)}function Nn(e,t,n,r){this.h=+e,this.c=+t,this.l=+n,this.opacity=+r}Xt(An,En,Kt(Qt,{brighter:function(e){return new An(this.l+18*(null==e?1:e),this.a,this.b,this.opacity)},darker:function(e){return new An(this.l-18*(null==e?1:e),this.a,this.b,this.opacity)},rgb:function(){var e=(this.l+16)/116,t=isNaN(this.a)?e:e+this.a/500,n=isNaN(this.b)?e:e-this.b/200;return e=Mn*Hn(e),new gn(Dn(3.2404542*(t=jn*Hn(t))-1.5371385*e-.4985314*(n=_n*Hn(n))),Dn(-.969266*t+1.8760108*e+.041556*n),Dn(.0556434*t-.2040259*e+1.0572252*n),this.opacity)}})),Xt(Nn,Vn,Kt(Qt,{brighter:function(e){return new Nn(this.h,this.c,this.l+18*(null==e?1:e),this.opacity)},darker:function(e){return new Nn(this.h,this.c,this.l-18*(null==e?1:e),this.opacity)},rgb:function(){return On(this).rgb()}}));var In=-.29227,Rn=-.90649,Fn=1.97294,Bn=Fn*Rn,Un=1.78277*Fn,Wn=1.78277*In- -.14861*Rn;function Gn(e,t,n,r){return 1===arguments.length?function(e){if(e instanceof Yn)return new Yn(e.h,e.s,e.l,e.opacity);e instanceof gn||(e=zn(e));var t=e.r/255,n=e.g/255,r=e.b/255,i=(Wn*r+Bn*t-Un*n)/(Wn+Bn-Un),o=r-i,a=(Fn*(n-i)-In*o)/Rn,c=Math.sqrt(a*a+o*o)/(Fn*i*(1-i)),s=c?Math.atan2(a,o)*xn-120:NaN;return new Yn(s<0?s+360:s,c,i,e.opacity)}(e):new Yn(e,t,n,null==r?1:r)}function Yn(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}function Zn(e,t,n,r,i){var o=e*e,a=o*e;return((1-3*e+3*o-a)*t+(4-6*o+3*a)*n+(1+3*e+3*o-3*a)*r+a*i)/6}Xt(Yn,Gn,Kt(Qt,{brighter:function(e){return e=null==e?1/.7:Math.pow(1/.7,e),new Yn(this.h,this.s,this.l*e,this.opacity)},darker:function(e){return e=null==e?.7:Math.pow(.7,e),new Yn(this.h,this.s,this.l*e,this.opacity)},rgb:function(){var e=isNaN(this.h)?0:(this.h+120)*kn,t=+this.l,n=isNaN(this.s)?0:this.s*t*(1-t),r=Math.cos(e),i=Math.sin(e);return new gn(255*(t+n*(-.14861*r+1.78277*i)),255*(t+n*(In*r+Rn*i)),255*(t+n*(Fn*r)),this.opacity)}}));var $n=function(e){var t=e.length-1;return function(n){var r=n<=0?n=0:n>=1?(n=1,t-1):Math.floor(n*t),i=e[r],o=e[r+1],a=r>0?e[r-1]:2*i-o,c=r180||n<-180?n-360*Math.round(n/360):n):Kn(isNaN(e)?t:e)}function er(e){return 1===(e=+e)?tr:function(t,n){return n-t?function(e,t,n){return e=Math.pow(e,n),t=Math.pow(t,n)-e,n=1/n,function(r){return Math.pow(e+r*t,n)}}(t,n,e):Kn(isNaN(t)?n:t)}}function tr(e,t){var n=t-e;return n?Qn(e,n):Kn(isNaN(e)?t:e)}var nr=function e(t){var n=er(t);function r(e,t){var r=n((e=vn(e)).r,(t=vn(t)).r),i=n(e.g,t.g),o=n(e.b,t.b),a=tr(e.opacity,t.opacity);return function(t){return e.r=r(t),e.g=i(t),e.b=o(t),e.opacity=a(t),e+""}}return r.gamma=e,r}(1);function rr(e){return function(t){var n,r,i=t.length,o=new Array(i),a=new Array(i),c=new Array(i);for(n=0;no&&(i=t.slice(o,i),c[a]?c[a]+=i:c[++a]=i),(n=n[0])===(r=r[0])?c[a]?c[a]+=r:c[++a]=r:(c[++a]=null,s.push({i:a,x:sr(n,r)})),o=fr.lastIndex;return o180?t+=360:t-e>180&&(e+=360),o.push({i:n.push(i(n)+"rotate(",null,r)-2,x:sr(e,t)})):t&&n.push(i(n)+"rotate("+t+r)}(o.rotate,a.rotate,c,s),function(e,t,n,o){e!==t?o.push({i:n.push(i(n)+"skewX(",null,r)-2,x:sr(e,t)}):t&&n.push(i(n)+"skewX("+t+r)}(o.skewX,a.skewX,c,s),function(e,t,n,r,o,a){if(e!==n||t!==r){var c=o.push(i(o)+"scale(",null,",",null,")");a.push({i:c-4,x:sr(e,n)},{i:c-2,x:sr(t,r)})}else 1===n&&1===r||o.push(i(o)+"scale("+n+","+r+")")}(o.scaleX,o.scaleY,a.scaleX,a.scaleY,c,s),o=a=null,function(e){for(var t,n=-1,r=s.length;++n=0&&t._call.call(null,e),t=t._next;--Rr}function ti(){Gr=(Wr=Zr.now())+Yr,Rr=Fr=0;try{ei()}finally{Rr=0,function(){var e,t,n=Dr,r=1/0;for(;n;)n._call?(r>n._time&&(r=n._time),e=n,n=n._next):(t=n._next,n._next=null,n=e?e._next=t:Dr=t);Pr=e,ri(r)}(),Gr=0}}function ni(){var e=Zr.now(),t=e-Wr;t>Ur&&(Yr-=t,Wr=e)}function ri(e){Rr||(Fr&&(Fr=clearTimeout(Fr)),e-Gr>24?(e<1/0&&(Fr=setTimeout(ti,e-Zr.now()-Yr)),Br&&(Br=clearInterval(Br))):(Br||(Wr=Zr.now(),Br=setInterval(ni,Ur)),Rr=1,$r(ti)))}Qr.prototype=Jr.prototype={constructor:Qr,restart:function(e,t,n){if("function"!==typeof e)throw new TypeError("callback is not a function");n=(null==n?Xr():+n)+(null==t?0:+t),this._next||Pr===this||(Pr?Pr._next=this:Dr=this,Pr=this),this._call=e,this._time=n,ri()},stop:function(){this._call&&(this._call=null,this._time=1/0,ri())}};var ii=function(e,t,n){var r=new Qr;return t=null==t?0:+t,r.restart((function(n){r.stop(),e(n+t)}),t,n),r},oi=function(e,t,n){var r=new Qr,i=t;return null==t?(r.restart(e,t,n),r):(t=+t,n=null==n?Xr():+n,r.restart((function o(a){a+=i,r.restart(o,i+=t,n),e(a)}),t,n),r)},ai=ze("start","end","interrupt"),ci=[],si=0,li=1,ui=2,fi=3,hi=4,di=5,pi=6,zi=function(e,t,n,r,i,o){var a=e.__transition;if(a){if(n in a)return}else e.__transition={};!function(e,t,n){var r,i=e.__transition;function o(s){var l,u,f,h;if(n.state!==li)return c();for(l in i)if((h=i[l]).name===n.name){if(h.state===fi)return ii(o);h.state===hi?(h.state=pi,h.timer.stop(),h.on.call("interrupt",e,e.__data__,h.index,h.group),delete i[l]):+lsi)throw new Error("too late; already scheduled");return n}function gi(e,t){var n=mi(e,t);if(n.state>ui)throw new Error("too late; already started");return n}function mi(e,t){var n=e.__transition;if(!n||!(n=n[t]))throw new Error("transition not found");return n}var yi=function(e,t){var n,r,i,o=e.__transition,a=!0;if(o){for(i in t=null==t?null:t+"",o)(n=o[i]).name===t?(r=n.state>ui&&n.state=0&&(e=e.slice(0,t)),!e||"start"===e}))}(t)?vi:gi;return function(){var a=o(this,e),c=a.on;c!==r&&(i=(r=c).copy()).on(t,n),a.on=i}}var Vi=Lt.prototype.constructor;function Ni(e,t,n){function r(){var r=this,i=t.apply(r,arguments);return i&&function(t){r.style.setProperty(e,i(t),n)}}return r._value=t,r}var Ii=0;function Ri(e,t,n,r){this._groups=e,this._parents=t,this._name=n,this._id=r}function Fi(e){return Lt().transition(e)}function Bi(){return++Ii}var Ui=Lt.prototype;function Wi(e){return+e}function Gi(e){return e*e}function Yi(e){return e*(2-e)}function Zi(e){return((e*=2)<=1?e*e:--e*(2-e)+1)/2}function $i(e){return e*e*e}function Xi(e){return--e*e*e+1}function Ki(e){return((e*=2)<=1?e*e*e:(e-=2)*e*e+2)/2}Ri.prototype=Fi.prototype={constructor:Ri,select:function(e){var t=this._name,n=this._id;"function"!==typeof e&&(e=Re(e));for(var r=this._groups,i=r.length,o=new Array(i),a=0;ali&&n.name===t)return new Ri([[e]],Ho,t,+r);return null},Po=function(e){return function(){return e}},Vo=function(e,t,n){this.target=e,this.type=t,this.selection=n};function No(){Te.stopImmediatePropagation()}var Io=function(){Te.preventDefault(),Te.stopImmediatePropagation()},Ro={name:"drag"},Fo={name:"space"},Bo={name:"handle"},Uo={name:"center"},Wo={name:"x",handles:["e","w"].map(Jo),input:function(e,t){return e&&[[e[0],t[0][1]],[e[1],t[1][1]]]},output:function(e){return e&&[e[0][0],e[1][0]]}},Go={name:"y",handles:["n","s"].map(Jo),input:function(e,t){return e&&[[t[0][0],e[0]],[t[1][0],e[1]]]},output:function(e){return e&&[e[0][1],e[1][1]]}},Yo={name:"xy",handles:["n","e","s","w","nw","ne","se","sw"].map(Jo),input:function(e){return e},output:function(e){return e}},Zo={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"},$o={e:"w",w:"e",nw:"ne",ne:"nw",se:"sw",sw:"se"},Xo={n:"s",s:"n",nw:"sw",ne:"se",se:"ne",sw:"nw"},Ko={overlay:1,selection:1,n:null,e:1,s:null,w:-1,nw:-1,ne:1,se:1,sw:-1},Qo={overlay:1,selection:1,n:-1,e:null,s:1,w:null,nw:-1,ne:-1,se:1,sw:1};function Jo(e){return{type:e}}function ea(){return!Te.button}function ta(){var e=this.ownerSVGElement||this;return[[0,0],[e.width.baseVal.value,e.height.baseVal.value]]}function na(e){for(;!e.__brush;)if(!(e=e.parentNode))return;return e.__brush}function ra(e){return e[0][0]===e[1][0]||e[0][1]===e[1][1]}function ia(e){var t=e.__brush;return t?t.dim.output(t.selection):null}function oa(){return sa(Wo)}function aa(){return sa(Go)}var ca=function(){return sa(Yo)};function sa(e){var t,n=ta,r=ea,i=ze(a,"start","brush","end"),o=6;function a(t){var n=t.property("__brush",f).selectAll(".overlay").data([Jo("overlay")]);n.enter().append("rect").attr("class","overlay").attr("pointer-events","all").attr("cursor",Zo.overlay).merge(n).each((function(){var e=na(this).extent;Ht(this).attr("x",e[0][0]).attr("y",e[0][1]).attr("width",e[1][0]-e[0][0]).attr("height",e[1][1]-e[0][1])})),t.selectAll(".selection").data([Jo("selection")]).enter().append("rect").attr("class","selection").attr("cursor",Zo.selection).attr("fill","#777").attr("fill-opacity",.3).attr("stroke","#fff").attr("shape-rendering","crispEdges");var r=t.selectAll(".handle").data(e.handles,(function(e){return e.type}));r.exit().remove(),r.enter().append("rect").attr("class",(function(e){return"handle handle--"+e.type})).attr("cursor",(function(e){return Zo[e.type]})),t.each(c).attr("fill","none").attr("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush touchstart.brush",u)}function c(){var e=Ht(this),t=na(this).selection;t?(e.selectAll(".selection").style("display",null).attr("x",t[0][0]).attr("y",t[0][1]).attr("width",t[1][0]-t[0][0]).attr("height",t[1][1]-t[0][1]),e.selectAll(".handle").style("display",null).attr("x",(function(e){return"e"===e.type[e.type.length-1]?t[1][0]-o/2:t[0][0]-o/2})).attr("y",(function(e){return"s"===e.type[0]?t[1][1]-o/2:t[0][1]-o/2})).attr("width",(function(e){return"n"===e.type||"s"===e.type?t[1][0]-t[0][0]+o:o})).attr("height",(function(e){return"e"===e.type||"w"===e.type?t[1][1]-t[0][1]+o:o}))):e.selectAll(".selection,.handle").style("display","none").attr("x",null).attr("y",null).attr("width",null).attr("height",null)}function s(e,t){return e.__brush.emitter||new l(e,t)}function l(e,t){this.that=e,this.args=t,this.state=e.__brush,this.active=0}function u(){if(Te.touches){if(Te.changedTouches.length0&&(n=i-d),k<0?f=h-p:k>0&&(o=a-p),b=Fo,H.attr("cursor",Zo.selection),V());break;default:return}Io()}),!0).on("keyup.brush",(function(){switch(Te.keyCode){case 16:T&&(v=g=T=!1,V());break;case 18:b===Uo&&(w<0?l=u:w>0&&(n=i),k<0?f=h:k>0&&(o=a),b=Bo,V());break;case 32:b===Fo&&(Te.altKey?(w&&(l=u-d*w,n=i+d*w),k&&(f=h-p*k,o=a+p*k),b=Uo):(w<0?l=u:w>0&&(n=i),k<0?f=h:k>0&&(o=a),b=Bo),H.attr("cursor",Zo[y]),V());break;default:return}Io()}),!0).on("mousemove.brush",P,!0).on("mouseup.brush",N,!0);Rt(Te.view)}No(),yi(m),c.call(m),A.start()}function P(){var e=Ne(m);!T||v||g||(Math.abs(e[0]-E[0])>Math.abs(e[1]-E[1])?g=!0:v=!0),E=e,z=!0,Io(),V()}function V(){var e;switch(d=E[0]-O[0],p=E[1]-O[1],b){case Fo:case Ro:w&&(d=Math.max(_-n,Math.min(q-l,d)),i=n+d,u=l+d),k&&(p=Math.max(C-o,Math.min(S-f,p)),a=o+p,h=f+p);break;case Bo:w<0?(d=Math.max(_-n,Math.min(q-n,d)),i=n+d,u=l):w>0&&(d=Math.max(_-l,Math.min(q-l,d)),i=n,u=l+d),k<0?(p=Math.max(C-o,Math.min(S-o,p)),a=o+p,h=f):k>0&&(p=Math.max(C-f,Math.min(S-f,p)),a=o,h=f+p);break;case Uo:w&&(i=Math.max(_,Math.min(q,n-d*w)),u=Math.max(_,Math.min(q,l+d*w))),k&&(a=Math.max(C,Math.min(S,o-p*k)),h=Math.max(C,Math.min(S,f+p*k)))}u1e-6)if(Math.abs(u*c-s*l)>1e-6&&i){var h=n-o,d=r-a,p=c*c+s*s,z=h*h+d*d,v=Math.sqrt(p),g=Math.sqrt(f),m=i*Math.tan((ya-Math.acos((p+f-z)/(2*v*g)))/2),y=m/g,b=m/v;Math.abs(y-1)>1e-6&&(this._+="L"+(e+y*l)+","+(t+y*u)),this._+="A"+i+","+i+",0,0,"+ +(u*h>l*d)+","+(this._x1=e+b*c)+","+(this._y1=t+b*s)}else this._+="L"+(this._x1=e)+","+(this._y1=t);else;},arc:function(e,t,n,r,i,o){e=+e,t=+t;var a=(n=+n)*Math.cos(r),c=n*Math.sin(r),s=e+a,l=t+c,u=1^o,f=o?r-i:i-r;if(n<0)throw new Error("negative radius: "+n);null===this._x1?this._+="M"+s+","+l:(Math.abs(this._x1-s)>1e-6||Math.abs(this._y1-l)>1e-6)&&(this._+="L"+s+","+l),n&&(f<0&&(f=f%ba+ba),f>wa?this._+="A"+n+","+n+",0,1,"+u+","+(e-a)+","+(t-c)+"A"+n+","+n+",0,1,"+u+","+(this._x1=s)+","+(this._y1=l):f>1e-6&&(this._+="A"+n+","+n+",0,"+ +(f>=ya)+","+u+","+(this._x1=e+n*Math.cos(i))+","+(this._y1=t+n*Math.sin(i))))},rect:function(e,t,n,r){this._+="M"+(this._x0=this._x1=+e)+","+(this._y0=this._y1=+t)+"h"+ +n+"v"+ +r+"h"+-n+"Z"},toString:function(){return this._}};var ja=xa;function Ma(e){return e.source}function _a(e){return e.target}function Ca(e){return e.radius}function qa(e){return e.startAngle}function Sa(e){return e.endAngle}var Ta=function(){var e=Ma,t=_a,n=Ca,r=qa,i=Sa,o=null;function a(){var a,c=ga.call(arguments),s=e.apply(this,c),l=t.apply(this,c),u=+n.apply(this,(c[0]=s,c)),f=r.apply(this,c)-ha,h=i.apply(this,c)-ha,d=u*la(f),p=u*ua(f),z=+n.apply(this,(c[0]=l,c)),v=r.apply(this,c)-ha,g=i.apply(this,c)-ha;if(o||(o=a=ja()),o.moveTo(d,p),o.arc(0,0,u,f,h),f===v&&h===g||(o.quadraticCurveTo(0,0,z*la(v),z*ua(v)),o.arc(0,0,z,v,g)),o.quadraticCurveTo(0,0,d,p),o.closePath(),a)return o=null,a+""||null}return a.radius=function(e){return arguments.length?(n="function"===typeof e?e:ma(+e),a):n},a.startAngle=function(e){return arguments.length?(r="function"===typeof e?e:ma(+e),a):r},a.endAngle=function(e){return arguments.length?(i="function"===typeof e?e:ma(+e),a):i},a.source=function(t){return arguments.length?(e=t,a):e},a.target=function(e){return arguments.length?(t=e,a):t},a.context=function(e){return arguments.length?(o=null==e?null:e,a):o},a};function Oa(){}function Ea(e,t){var n=new Oa;if(e instanceof Oa)e.each((function(e,t){n.set(t,e)}));else if(Array.isArray(e)){var r,i=-1,o=e.length;if(null==t)for(;++i=r.length)return null!=e&&n.sort(e),null!=t?t(n):n;for(var s,l,u,f=-1,h=n.length,d=r[i++],p=Aa(),z=a();++fr.length)return n;var a,c=i[o-1];return null!=t&&o>=r.length?a=n.entries():(a=[],n.each((function(t,n){a.push({key:n,values:e(t,o)})}))),null!=c?a.sort((function(e,t){return c(e.key,t.key)})):a}(o(e,0,Pa,Va),0)},key:function(e){return r.push(e),n},sortKeys:function(e){return i[r.length-1]=e,n},sortValues:function(t){return e=t,n},rollup:function(e){return t=e,n}}};function Ha(){return{}}function Da(e,t,n){e[t]=n}function Pa(){return Aa()}function Va(e,t,n){e.set(t,n)}function Na(){}var Ia=Aa.prototype;function Ra(e,t){var n=new Na;if(e instanceof Na)e.each((function(e){n.add(e)}));else if(e){var r=-1,i=e.length;if(null==t)for(;++r=o?s=!0:(r=e.charCodeAt(a++))===$a?l=!0:r===Xa&&(l=!0,e.charCodeAt(a)===$a&&++a),e.slice(i+1,t-1).replace(/""/g,'"')}for(;a=(o=(z+g)/2))?z=o:g=o,(u=n>=(a=(v+m)/2))?v=a:m=a,i=d,!(d=d[f=u<<1|l]))return i[f]=p,e;if(c=+e._x.call(null,d.data),s=+e._y.call(null,d.data),t===c&&n===s)return p.next=d,i?i[f]=p:e._root=p,e;do{i=i?i[f]=new Array(4):e._root=new Array(4),(l=t>=(o=(z+g)/2))?z=o:g=o,(u=n>=(a=(v+m)/2))?v=a:m=a}while((f=u<<1|l)===(h=(s>=a)<<1|c>=o));return i[h]=d,i[f]=p,e}var dc=function(e,t,n,r,i){this.node=e,this.x0=t,this.y0=n,this.x1=r,this.y1=i};function pc(e){return e[0]}function zc(e){return e[1]}function vc(e,t,n){var r=new gc(null==t?pc:t,null==n?zc:n,NaN,NaN,NaN,NaN);return null==e?r:r.addAll(e)}function gc(e,t,n,r,i,o){this._x=e,this._y=t,this._x0=n,this._y0=r,this._x1=i,this._y1=o,this._root=void 0}function mc(e){for(var t={data:e.data},n=t;e=e.next;)n=n.next={data:e.data};return t}var yc=vc.prototype=gc.prototype;function bc(e){return e.x+e.vx}function wc(e){return e.y+e.vy}yc.copy=function(){var e,t,n=new gc(this._x,this._y,this._x0,this._y0,this._x1,this._y1),r=this._root;if(!r)return n;if(!r.length)return n._root=mc(r),n;for(e=[{source:r,target:n._root=new Array(4)}];r=e.pop();)for(var i=0;i<4;++i)(t=r.source[i])&&(t.length?e.push({source:t,target:r.target[i]=new Array(4)}):r.target[i]=mc(t));return n},yc.add=function(e){var t=+this._x.call(null,e),n=+this._y.call(null,e);return hc(this.cover(t,n),t,n,e)},yc.addAll=function(e){var t,n,r,i,o=e.length,a=new Array(o),c=new Array(o),s=1/0,l=1/0,u=-1/0,f=-1/0;for(n=0;nu&&(u=r),if&&(f=i));for(ue||e>i||r>t||t>o))return this;var a,c,s=i-n,l=this._root;switch(c=(t<(r+o)/2)<<1|e<(n+i)/2){case 0:do{(a=new Array(4))[c]=l,l=a}while(o=r+(s*=2),e>(i=n+s)||t>o);break;case 1:do{(a=new Array(4))[c]=l,l=a}while(o=r+(s*=2),(n=i-s)>e||t>o);break;case 2:do{(a=new Array(4))[c]=l,l=a}while(r=o-(s*=2),e>(i=n+s)||r>t);break;case 3:do{(a=new Array(4))[c]=l,l=a}while(r=o-(s*=2),(n=i-s)>e||r>t)}this._root&&this._root.length&&(this._root=l)}return this._x0=n,this._y0=r,this._x1=i,this._y1=o,this},yc.data=function(){var e=[];return this.visit((function(t){if(!t.length)do{e.push(t.data)}while(t=t.next)})),e},yc.extent=function(e){return arguments.length?this.cover(+e[0][0],+e[0][1]).cover(+e[1][0],+e[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]},yc.find=function(e,t,n){var r,i,o,a,c,s,l,u=this._x0,f=this._y0,h=this._x1,d=this._y1,p=[],z=this._root;for(z&&p.push(new dc(z,u,f,h,d)),null==n?n=1/0:(u=e-n,f=t-n,h=e+n,d=t+n,n*=n);s=p.pop();)if(!(!(z=s.node)||(i=s.x0)>h||(o=s.y0)>d||(a=s.x1)=g)<<1|e>=v)&&(s=p[p.length-1],p[p.length-1]=p[p.length-1-l],p[p.length-1-l]=s)}else{var m=e-+this._x.call(null,z.data),y=t-+this._y.call(null,z.data),b=m*m+y*y;if(b=(c=(p+v)/2))?p=c:v=c,(u=a>=(s=(z+g)/2))?z=s:g=s,t=d,!(d=d[f=u<<1|l]))return this;if(!d.length)break;(t[f+1&3]||t[f+2&3]||t[f+3&3])&&(n=t,h=f)}for(;d.data!==e;)if(r=d,!(d=d.next))return this;return(i=d.next)&&delete d.next,r?(i?r.next=i:delete r.next,this):t?(i?t[f]=i:delete t[f],(d=t[0]||t[1]||t[2]||t[3])&&d===(t[3]||t[2]||t[1]||t[0])&&!d.length&&(n?n[h]=d:this._root=d),this):(this._root=i,this)},yc.removeAll=function(e){for(var t=0,n=e.length;ts+d||il+d||oc.index){var p=s-a.x-a.vx,z=l-a.y-a.vy,v=p*p+z*z;ve.r&&(e.r=e[t].r)}function c(){if(t){var r,i,o=t.length;for(n=new Array(o),r=0;r1?(null==n?c.remove(e):c.set(e,d(n)),t):c.get(e)},find:function(t,n,r){var i,o,a,c,s,l=0,u=e.length;for(null==r?r=1/0:r*=r,l=0;l1?(l.on(e,n),t):l.on(e)}}},Ec=function(){var e,t,n,r,i=uc(-30),o=1,a=1/0,c=.81;function s(r){var i,o=e.length,a=vc(e,_c,Cc).visitAfter(u);for(n=r,i=0;i=a)){(e.data!==t||e.next)&&(0===u&&(d+=(u=fc())*u),0===f&&(d+=(f=fc())*f),d1?r[0]+r.slice(2):r,+e.slice(n+1)]},Pc=function(e){return(e=Dc(Math.abs(e)))?e[1]:NaN},Vc=function(e,t){var n=Dc(e,t);if(!n)return e+"";var r=n[0],i=n[1];return i<0?"0."+new Array(-i).join("0")+r:r.length>i+1?r.slice(0,i+1)+"."+r.slice(i+1):r+new Array(i-r.length+2).join("0")},Nc={"":function(e,t){e:for(var n,r=(e=e.toPrecision(t)).length,i=1,o=-1;i0&&(o=0)}return o>0?e.slice(0,o)+e.slice(n+1):e},"%":function(e,t){return(100*e).toFixed(t)},b:function(e){return Math.round(e).toString(2)},c:function(e){return e+""},d:function(e){return Math.round(e).toString(10)},e:function(e,t){return e.toExponential(t)},f:function(e,t){return e.toFixed(t)},g:function(e,t){return e.toPrecision(t)},o:function(e){return Math.round(e).toString(8)},p:function(e,t){return Vc(100*e,t)},r:Vc,s:function(e,t){var n=Dc(e,t);if(!n)return e+"";var r=n[0],i=n[1],o=i-(qc=3*Math.max(-8,Math.min(8,Math.floor(i/3))))+1,a=r.length;return o===a?r:o>a?r+new Array(o-a+1).join("0"):o>0?r.slice(0,o)+"."+r.slice(o):"0."+new Array(1-o).join("0")+Dc(e,Math.max(0,t+o-1))[0]},X:function(e){return Math.round(e).toString(16).toUpperCase()},x:function(e){return Math.round(e).toString(16)}},Ic=/^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i;function Rc(e){return new Fc(e)}function Fc(e){if(!(t=Ic.exec(e)))throw new Error("invalid format: "+e);var t,n=t[1]||" ",r=t[2]||">",i=t[3]||"-",o=t[4]||"",a=!!t[5],c=t[6]&&+t[6],s=!!t[7],l=t[8]&&+t[8].slice(1),u=t[9]||"";"n"===u?(s=!0,u="g"):Nc[u]||(u=""),(a||"0"===n&&"="===r)&&(a=!0,n="0",r="="),this.fill=n,this.align=r,this.sign=i,this.symbol=o,this.zero=a,this.width=c,this.comma=s,this.precision=l,this.type=u}Rc.prototype=Fc.prototype,Fc.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(null==this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(null==this.precision?"":"."+Math.max(0,0|this.precision))+this.type};var Bc,Uc,Wc,Gc=function(e){return e},Yc=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"],Zc=function(e){var t,n,r=e.grouping&&e.thousands?(t=e.grouping,n=e.thousands,function(e,r){for(var i=e.length,o=[],a=0,c=t[0],s=0;i>0&&c>0&&(s+c+1>r&&(c=Math.max(1,r-s)),o.push(e.substring(i-=c,i+c)),!((s+=c+1)>r));)c=t[a=(a+1)%t.length];return o.reverse().join(n)}):Gc,i=e.currency,o=e.decimal,a=e.numerals?function(e){return function(t){return t.replace(/[0-9]/g,(function(t){return e[+t]}))}}(e.numerals):Gc,c=e.percent||"%";function s(e){var t=(e=Rc(e)).fill,n=e.align,s=e.sign,l=e.symbol,u=e.zero,f=e.width,h=e.comma,d=e.precision,p=e.type,z="$"===l?i[0]:"#"===l&&/[boxX]/.test(p)?"0"+p.toLowerCase():"",v="$"===l?i[1]:/[%p]/.test(p)?c:"",g=Nc[p],m=!p||/[defgprs%]/.test(p);function y(e){var i,c,l,y=z,b=v;if("c"===p)b=g(e)+b,e="";else{var w=(e=+e)<0;if(e=g(Math.abs(e),d),w&&0===+e&&(w=!1),y=(w?"("===s?s:"-":"-"===s||"("===s?"":s)+y,b=b+("s"===p?Yc[8+qc/3]:"")+(w&&"("===s?")":""),m)for(i=-1,c=e.length;++i(l=e.charCodeAt(i))||l>57){b=(46===l?o+e.slice(i+1):e.slice(i))+b,e=e.slice(0,i);break}}h&&!u&&(e=r(e,1/0));var k=y.length+e.length+b.length,x=k>1)+y+e+b+x.slice(k);break;default:e=x+y+e+b}return a(e)}return d=null==d?p?6:12:/[gprs]/.test(p)?Math.max(1,Math.min(21,d)):Math.max(0,Math.min(20,d)),y.toString=function(){return e+""},y}return{format:s,formatPrefix:function(e,t){var n=s(((e=Rc(e)).type="f",e)),r=3*Math.max(-8,Math.min(8,Math.floor(Pc(t)/3))),i=Math.pow(10,-r),o=Yc[8+r/3];return function(e){return n(i*e)+o}}}};function $c(e){return Bc=Zc(e),Uc=Bc.format,Wc=Bc.formatPrefix,Bc}$c({decimal:".",thousands:",",grouping:[3],currency:["$",""]});var Xc=function(e){return Math.max(0,-Pc(Math.abs(e)))},Kc=function(e,t){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(Pc(t)/3)))-Pc(Math.abs(e)))},Qc=function(e,t){return e=Math.abs(e),t=Math.abs(t)-e,Math.max(0,Pc(t)-Pc(e))+1},Jc=function(){return new es};function es(){this.reset()}es.prototype={constructor:es,reset:function(){this.s=this.t=0},add:function(e){ns(ts,e,this.t),ns(this,ts.s,this.s),this.s?this.t+=ts.t:this.s=ts.t},valueOf:function(){return this.s}};var ts=new es;function ns(e,t,n){var r=e.s=t+n,i=r-t,o=r-i;e.t=t-o+(n-i)}var rs=1e-6,is=Math.PI,os=is/2,as=is/4,cs=2*is,ss=180/is,ls=is/180,us=Math.abs,fs=Math.atan,hs=Math.atan2,ds=Math.cos,ps=Math.ceil,zs=Math.exp,vs=(Math.floor,Math.log),gs=Math.pow,ms=Math.sin,ys=Math.sign||function(e){return e>0?1:e<0?-1:0},bs=Math.sqrt,ws=Math.tan;function ks(e){return e>1?0:e<-1?is:Math.acos(e)}function xs(e){return e>1?os:e<-1?-os:Math.asin(e)}function js(e){return(e=ms(e/2))*e}function Ms(){}function _s(e,t){e&&qs.hasOwnProperty(e.type)&&qs[e.type](e,t)}var Cs={Feature:function(e,t){_s(e.geometry,t)},FeatureCollection:function(e,t){for(var n=e.features,r=-1,i=n.length;++r=0?1:-1,i=r*n,o=ds(t=(t*=ls)/2+as),a=ms(t),c=Hs*a,s=Ls*o+c*ds(i),l=c*r*ms(i);Ps.add(hs(l,s)),As=e,Ls=o,Hs=a}var Us=function(e){return Vs.reset(),Ds(e,Ns),2*Vs};function Ws(e){return[hs(e[1],e[0]),xs(e[2])]}function Gs(e){var t=e[0],n=e[1],r=ds(n);return[r*ds(t),r*ms(t),ms(n)]}function Ys(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}function Zs(e,t){return[e[1]*t[2]-e[2]*t[1],e[2]*t[0]-e[0]*t[2],e[0]*t[1]-e[1]*t[0]]}function $s(e,t){e[0]+=t[0],e[1]+=t[1],e[2]+=t[2]}function Xs(e,t){return[e[0]*t,e[1]*t,e[2]*t]}function Ks(e){var t=bs(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]);e[0]/=t,e[1]/=t,e[2]/=t}var Qs,Js,el,tl,nl,rl,il,ol,al,cl,sl=Jc(),ll={point:ul,lineStart:hl,lineEnd:dl,polygonStart:function(){ll.point=pl,ll.lineStart=zl,ll.lineEnd=vl,sl.reset(),Ns.polygonStart()},polygonEnd:function(){Ns.polygonEnd(),ll.point=ul,ll.lineStart=hl,ll.lineEnd=dl,Ps<0?(Qs=-(el=180),Js=-(tl=90)):sl>rs?tl=90:sl<-rs&&(Js=-90),cl[0]=Qs,cl[1]=el}};function ul(e,t){al.push(cl=[Qs=e,el=e]),ttl&&(tl=t)}function fl(e,t){var n=Gs([e*ls,t*ls]);if(ol){var r=Zs(ol,n),i=Zs([r[1],-r[0],0],r);Ks(i),i=Ws(i);var o,a=e-nl,c=a>0?1:-1,s=i[0]*ss*c,l=us(a)>180;l^(c*nltl&&(tl=o):l^(c*nl<(s=(s+360)%360-180)&&stl&&(tl=t)),l?egl(Qs,el)&&(el=e):gl(e,el)>gl(Qs,el)&&(Qs=e):el>=Qs?(eel&&(el=e)):e>nl?gl(Qs,e)>gl(Qs,el)&&(el=e):gl(e,el)>gl(Qs,el)&&(Qs=e)}else al.push(cl=[Qs=e,el=e]);ttl&&(tl=t),ol=n,nl=e}function hl(){ll.point=fl}function dl(){cl[0]=Qs,cl[1]=el,ll.point=ul,ol=null}function pl(e,t){if(ol){var n=e-nl;sl.add(us(n)>180?n+(n>0?360:-360):n)}else rl=e,il=t;Ns.point(e,t),fl(e,t)}function zl(){Ns.lineStart()}function vl(){pl(rl,il),Ns.lineEnd(),us(sl)>rs&&(Qs=-(el=180)),cl[0]=Qs,cl[1]=el,ol=null}function gl(e,t){return(t-=e)<0?t+360:t}function ml(e,t){return e[0]-t[0]}function yl(e,t){return e[0]<=e[1]?e[0]<=t&&t<=e[1]:tgl(r[0],r[1])&&(r[1]=i[1]),gl(i[0],r[1])>gl(r[0],r[1])&&(r[0]=i[0])):o.push(r=i);for(a=-1/0,t=0,r=o[n=o.length-1];t<=n;r=i,++t)i=o[t],(c=gl(r[1],i[0]))>a&&(a=c,Qs=i[0],el=r[1])}return al=cl=null,Qs===1/0||Js===1/0?[[NaN,NaN],[NaN,NaN]]:[[Qs,Js],[el,tl]]},Pl={sphere:Ms,point:Vl,lineStart:Il,lineEnd:Bl,polygonStart:function(){Pl.lineStart=Ul,Pl.lineEnd=Wl},polygonEnd:function(){Pl.lineStart=Il,Pl.lineEnd=Bl}};function Vl(e,t){e*=ls;var n=ds(t*=ls);Nl(n*ds(e),n*ms(e),ms(t))}function Nl(e,t,n){++bl,kl+=(e-kl)/bl,xl+=(t-xl)/bl,jl+=(n-jl)/bl}function Il(){Pl.point=Rl}function Rl(e,t){e*=ls;var n=ds(t*=ls);Al=n*ds(e),Ll=n*ms(e),Hl=ms(t),Pl.point=Fl,Nl(Al,Ll,Hl)}function Fl(e,t){e*=ls;var n=ds(t*=ls),r=n*ds(e),i=n*ms(e),o=ms(t),a=hs(bs((a=Ll*o-Hl*i)*a+(a=Hl*r-Al*o)*a+(a=Al*i-Ll*r)*a),Al*r+Ll*i+Hl*o);wl+=a,Ml+=a*(Al+(Al=r)),_l+=a*(Ll+(Ll=i)),Cl+=a*(Hl+(Hl=o)),Nl(Al,Ll,Hl)}function Bl(){Pl.point=Vl}function Ul(){Pl.point=Gl}function Wl(){Yl(Ol,El),Pl.point=Vl}function Gl(e,t){Ol=e,El=t,e*=ls,t*=ls,Pl.point=Yl;var n=ds(t);Al=n*ds(e),Ll=n*ms(e),Hl=ms(t),Nl(Al,Ll,Hl)}function Yl(e,t){e*=ls;var n=ds(t*=ls),r=n*ds(e),i=n*ms(e),o=ms(t),a=Ll*o-Hl*i,c=Hl*r-Al*o,s=Al*i-Ll*r,l=bs(a*a+c*c+s*s),u=xs(l),f=l&&-u/l;ql+=f*a,Sl+=f*c,Tl+=f*s,wl+=u,Ml+=u*(Al+(Al=r)),_l+=u*(Ll+(Ll=i)),Cl+=u*(Hl+(Hl=o)),Nl(Al,Ll,Hl)}var Zl=function(e){bl=wl=kl=xl=jl=Ml=_l=Cl=ql=Sl=Tl=0,Ds(e,Pl);var t=ql,n=Sl,r=Tl,i=t*t+n*n+r*r;return i<1e-12&&(t=Ml,n=_l,r=Cl,wlis?e-cs:e<-is?e+cs:e,t]}function Ql(e,t,n){return(e%=cs)?t||n?Xl(eu(e),tu(t,n)):eu(e):t||n?tu(t,n):Kl}function Jl(e){return function(t,n){return[(t+=e)>is?t-cs:t<-is?t+cs:t,n]}}function eu(e){var t=Jl(e);return t.invert=Jl(-e),t}function tu(e,t){var n=ds(e),r=ms(e),i=ds(t),o=ms(t);function a(e,t){var a=ds(t),c=ds(e)*a,s=ms(e)*a,l=ms(t),u=l*n+c*r;return[hs(s*i-u*o,c*n-l*r),xs(u*i+s*o)]}return a.invert=function(e,t){var a=ds(t),c=ds(e)*a,s=ms(e)*a,l=ms(t),u=l*i-s*o;return[hs(s*i+l*o,c*n+u*r),xs(u*n-c*r)]},a}Kl.invert=Kl;var nu=function(e){function t(t){return(t=e(t[0]*ls,t[1]*ls))[0]*=ss,t[1]*=ss,t}return e=Ql(e[0]*ls,e[1]*ls,e.length>2?e[2]*ls:0),t.invert=function(t){return(t=e.invert(t[0]*ls,t[1]*ls))[0]*=ss,t[1]*=ss,t},t};function ru(e,t,n,r,i,o){if(n){var a=ds(t),c=ms(t),s=r*n;null==i?(i=t+r*cs,o=t-s/2):(i=iu(a,i),o=iu(a,o),(r>0?io)&&(i+=r*cs));for(var l,u=i;r>0?u>o:u1&&t.push(t.pop().concat(t.shift()))},result:function(){var n=t;return t=[],e=null,n}}},cu=function(e,t){return us(e[0]-t[0])=0;--o)i.point((u=l[o])[0],u[1]);else r(h.x,h.p.x,-1,i);h=h.p}l=(h=h.o).z,d=!d}while(!h.v);i.lineEnd()}}};function uu(e){if(t=e.length){for(var t,n,r=0,i=e[0];++r=0?1:-1,j=x*k,M=j>is,_=p*b;if(fu.add(hs(_*x*ms(j),z*w+_*ds(j))),o+=M?k+x*cs:k,M^h>=n^m>=n){var C=Zs(Gs(f),Gs(g));Ks(C);var q=Zs(i,C);Ks(q);var S=(M^k>=0?-1:1)*xs(q[2]);(r>S||r===S&&(C[0]||C[1]))&&(a+=M^k>=0?1:-1)}}return(o<-rs||o0){for(f||(i.polygonStart(),f=!0),i.lineStart(),e=0;e1&&2&s&&h.push(h.pop().concat(h.shift())),a.push(h.filter(pu))}return h}};function pu(e){return e.length>1}function zu(e,t){return((e=e.x)[0]<0?e[1]-os-rs:os-e[1])-((t=t.x)[0]<0?t[1]-os-rs:os-t[1])}var vu=du((function(){return!0}),(function(e){var t,n=NaN,r=NaN,i=NaN;return{lineStart:function(){e.lineStart(),t=1},point:function(o,a){var c=o>0?is:-is,s=us(o-n);us(s-is)0?os:-os),e.point(i,r),e.lineEnd(),e.lineStart(),e.point(c,r),e.point(o,r),t=0):i!==c&&s>=is&&(us(n-i)rs?fs((ms(t)*(o=ds(r))*ms(n)-ms(r)*(i=ds(t))*ms(e))/(i*o*a)):(t+r)/2}(n,r,o,a),e.point(i,r),e.lineEnd(),e.lineStart(),e.point(c,r),t=0),e.point(n=o,r=a),i=c},lineEnd:function(){e.lineEnd(),n=r=NaN},clean:function(){return 2-t}}}),(function(e,t,n,r){var i;if(null==e)i=n*os,r.point(-is,i),r.point(0,i),r.point(is,i),r.point(is,0),r.point(is,-i),r.point(0,-i),r.point(-is,-i),r.point(-is,0),r.point(-is,i);else if(us(e[0]-t[0])>rs){var o=e[0]0,i=us(t)>rs;function o(e,n){return ds(e)*ds(n)>t}function a(e,n,r){var i=[1,0,0],o=Zs(Gs(e),Gs(n)),a=Ys(o,o),c=o[0],s=a-c*c;if(!s)return!r&&e;var l=t*a/s,u=-t*c/s,f=Zs(i,o),h=Xs(i,l);$s(h,Xs(o,u));var d=f,p=Ys(h,d),z=Ys(d,d),v=p*p-z*(Ys(h,h)-1);if(!(v<0)){var g=bs(v),m=Xs(d,(-p-g)/z);if($s(m,h),m=Ws(m),!r)return m;var y,b=e[0],w=n[0],k=e[1],x=n[1];w0^m[1]<(us(m[0]-b)is^(b<=m[0]&&m[0]<=w)){var _=Xs(d,(-p+g)/z);return $s(_,h),[m,Ws(_)]}}}function c(t,n){var i=r?e:is-e,o=0;return t<-i?o|=1:t>i&&(o|=2),n<-i?o|=4:n>i&&(o|=8),o}return du(o,(function(e){var t,n,s,l,u;return{lineStart:function(){l=s=!1,u=1},point:function(f,h){var d,p=[f,h],z=o(f,h),v=r?z?0:c(f,h):z?c(f+(f<0?is:-is),h):0;if(!t&&(l=s=z)&&e.lineStart(),z!==s&&(!(d=a(t,p))||cu(t,d)||cu(p,d))&&(p[0]+=rs,p[1]+=rs,z=o(p[0],p[1])),z!==s)u=0,z?(e.lineStart(),d=a(p,t),e.point(d[0],d[1])):(d=a(t,p),e.point(d[0],d[1]),e.lineEnd()),t=d;else if(i&&t&&r^z){var g;v&n||!(g=a(p,t,!0))||(u=0,r?(e.lineStart(),e.point(g[0][0],g[0][1]),e.point(g[1][0],g[1][1]),e.lineEnd()):(e.point(g[1][0],g[1][1]),e.lineEnd(),e.lineStart(),e.point(g[0][0],g[0][1])))}!z||t&&cu(t,p)||e.point(p[0],p[1]),t=p,s=z,n=v},lineEnd:function(){s&&e.lineEnd(),t=null},clean:function(){return u|(l&&s)<<1}}}),(function(t,r,i,o){ru(o,e,n,i,t,r)}),r?[0,-e]:[-is,e-is])},mu=function(e,t,n,r,i,o){var a,c=e[0],s=e[1],l=0,u=1,f=t[0]-c,h=t[1]-s;if(a=n-c,f||!(a>0)){if(a/=f,f<0){if(a0){if(a>u)return;a>l&&(l=a)}if(a=i-c,f||!(a<0)){if(a/=f,f<0){if(a>u)return;a>l&&(l=a)}else if(f>0){if(a0)){if(a/=h,h<0){if(a0){if(a>u)return;a>l&&(l=a)}if(a=o-s,h||!(a<0)){if(a/=h,h<0){if(a>u)return;a>l&&(l=a)}else if(h>0){if(a0&&(e[0]=c+l*f,e[1]=s+l*h),u<1&&(t[0]=c+u*f,t[1]=s+u*h),!0}}}}},yu=1e9,bu=-yu;function wu(e,t,n,r){function i(i,o){return e<=i&&i<=n&&t<=o&&o<=r}function o(i,o,c,l){var u=0,f=0;if(null==i||(u=a(i,c))!==(f=a(o,c))||s(i,o)<0^c>0)do{l.point(0===u||3===u?e:n,u>1?r:t)}while((u=(u+c+4)%4)!==f);else l.point(o[0],o[1])}function a(r,i){return us(r[0]-e)0?0:3:us(r[0]-n)0?2:1:us(r[1]-t)0?1:0:i>0?3:2}function c(e,t){return s(e.x,t.x)}function s(e,t){var n=a(e,1),r=a(t,1);return n!==r?n-r:0===n?t[1]-e[1]:1===n?e[0]-t[0]:2===n?e[1]-t[1]:t[0]-e[0]}return function(a){var s,l,u,f,h,d,p,z,v,g,m,y=a,b=au(),w={point:k,lineStart:function(){w.point=x,l&&l.push(u=[]);g=!0,v=!1,p=z=NaN},lineEnd:function(){s&&(x(f,h),d&&v&&b.rejoin(),s.push(b.result()));w.point=k,v&&y.lineEnd()},polygonStart:function(){y=b,s=[],l=[],m=!0},polygonEnd:function(){var t=function(){for(var t=0,n=0,i=l.length;nr&&(h-o)*(r-a)>(d-a)*(e-o)&&++t:d<=r&&(h-o)*(r-a)<(d-a)*(e-o)&&--t;return t}(),n=m&&t,i=(s=P(s)).length;(n||i)&&(a.polygonStart(),n&&(a.lineStart(),o(null,null,1,a),a.lineEnd()),i&&lu(s,c,t,o,a),a.polygonEnd());y=a,s=l=u=null}};function k(e,t){i(e,t)&&y.point(e,t)}function x(o,a){var c=i(o,a);if(l&&u.push([o,a]),g)f=o,h=a,d=c,g=!1,c&&(y.lineStart(),y.point(o,a));else if(c&&v)y.point(o,a);else{var s=[p=Math.max(bu,Math.min(yu,p)),z=Math.max(bu,Math.min(yu,z))],b=[o=Math.max(bu,Math.min(yu,o)),a=Math.max(bu,Math.min(yu,a))];mu(s,b,e,t,n,r)?(v||(y.lineStart(),y.point(s[0],s[1])),y.point(b[0],b[1]),c||y.lineEnd(),m=!1):c&&(y.lineStart(),y.point(o,a),m=!1)}p=o,z=a,v=c}return w}}var ku,xu,ju,Mu=function(){var e,t,n,r=0,i=0,o=960,a=500;return n={stream:function(n){return e&&t===n?e:e=wu(r,i,o,a)(t=n)},extent:function(c){return arguments.length?(r=+c[0][0],i=+c[0][1],o=+c[1][0],a=+c[1][1],e=t=null,n):[[r,i],[o,a]]}}},_u=Jc(),Cu={sphere:Ms,point:Ms,lineStart:function(){Cu.point=Su,Cu.lineEnd=qu},lineEnd:Ms,polygonStart:Ms,polygonEnd:Ms};function qu(){Cu.point=Cu.lineEnd=Ms}function Su(e,t){ku=e*=ls,xu=ms(t*=ls),ju=ds(t),Cu.point=Tu}function Tu(e,t){e*=ls;var n=ms(t*=ls),r=ds(t),i=us(e-ku),o=ds(i),a=r*ms(i),c=ju*n-xu*r*o,s=xu*n+ju*r*o;_u.add(hs(bs(a*a+c*c),s)),ku=e,xu=n,ju=r}var Ou=function(e){return _u.reset(),Ds(e,Cu),+_u},Eu=[null,null],Au={type:"LineString",coordinates:Eu},Lu=function(e,t){return Eu[0]=e,Eu[1]=t,Ou(Au)},Hu={Feature:function(e,t){return Pu(e.geometry,t)},FeatureCollection:function(e,t){for(var n=e.features,r=-1,i=n.length;++rrs})).map(s)).concat(k(ps(o/d)*d,i,d).filter((function(e){return us(e%z)>rs})).map(l))}return g.lines=function(){return m().map((function(e){return{type:"LineString",coordinates:e}}))},g.outline=function(){return{type:"Polygon",coordinates:[u(r).concat(f(a).slice(1),u(n).reverse().slice(1),f(c).reverse().slice(1))]}},g.extent=function(e){return arguments.length?g.extentMajor(e).extentMinor(e):g.extentMinor()},g.extentMajor=function(e){return arguments.length?(r=+e[0][0],n=+e[1][0],c=+e[0][1],a=+e[1][1],r>n&&(e=r,r=n,n=e),c>a&&(e=c,c=a,a=e),g.precision(v)):[[r,c],[n,a]]},g.extentMinor=function(n){return arguments.length?(t=+n[0][0],e=+n[1][0],o=+n[0][1],i=+n[1][1],t>e&&(n=t,t=e,e=n),o>i&&(n=o,o=i,i=n),g.precision(v)):[[t,o],[e,i]]},g.step=function(e){return arguments.length?g.stepMajor(e).stepMinor(e):g.stepMinor()},g.stepMajor=function(e){return arguments.length?(p=+e[0],z=+e[1],g):[p,z]},g.stepMinor=function(e){return arguments.length?(h=+e[0],d=+e[1],g):[h,d]},g.precision=function(h){return arguments.length?(v=+h,s=Uu(o,i,90),l=Wu(t,e,v),u=Uu(c,a,90),f=Wu(r,n,v),g):v},g.extentMajor([[-180,-90+rs],[180,90-rs]]).extentMinor([[-180,-80-rs],[180,80+rs]])}function Yu(){return Gu()()}var Zu,$u,Xu,Ku,Qu=function(e,t){var n=e[0]*ls,r=e[1]*ls,i=t[0]*ls,o=t[1]*ls,a=ds(r),c=ms(r),s=ds(o),l=ms(o),u=a*ds(n),f=a*ms(n),h=s*ds(i),d=s*ms(i),p=2*xs(bs(js(o-r)+a*s*js(i-n))),z=ms(p),v=p?function(e){var t=ms(e*=p)/z,n=ms(p-e)/z,r=n*u+t*h,i=n*f+t*d,o=n*c+t*l;return[hs(i,r)*ss,hs(o,bs(r*r+i*i))*ss]}:function(){return[n*ss,r*ss]};return v.distance=p,v},Ju=function(e){return e},ef=Jc(),tf=Jc(),nf={point:Ms,lineStart:Ms,lineEnd:Ms,polygonStart:function(){nf.lineStart=rf,nf.lineEnd=cf},polygonEnd:function(){nf.lineStart=nf.lineEnd=nf.point=Ms,ef.add(us(tf)),tf.reset()},result:function(){var e=ef/2;return ef.reset(),e}};function rf(){nf.point=of}function of(e,t){nf.point=af,Zu=Xu=e,$u=Ku=t}function af(e,t){tf.add(Ku*e-Xu*t),Xu=e,Ku=t}function cf(){af(Zu,$u)}var sf=nf,lf=1/0,uf=lf,ff=-lf,hf=ff;var df,pf,zf,vf,gf={point:function(e,t){eff&&(ff=e);thf&&(hf=t)},lineStart:Ms,lineEnd:Ms,polygonStart:Ms,polygonEnd:Ms,result:function(){var e=[[lf,uf],[ff,hf]];return ff=hf=-(uf=lf=1/0),e}},mf=0,yf=0,bf=0,wf=0,kf=0,xf=0,jf=0,Mf=0,_f=0,Cf={point:qf,lineStart:Sf,lineEnd:Ef,polygonStart:function(){Cf.lineStart=Af,Cf.lineEnd=Lf},polygonEnd:function(){Cf.point=qf,Cf.lineStart=Sf,Cf.lineEnd=Ef},result:function(){var e=_f?[jf/_f,Mf/_f]:xf?[wf/xf,kf/xf]:bf?[mf/bf,yf/bf]:[NaN,NaN];return mf=yf=bf=wf=kf=xf=jf=Mf=_f=0,e}};function qf(e,t){mf+=e,yf+=t,++bf}function Sf(){Cf.point=Tf}function Tf(e,t){Cf.point=Of,qf(zf=e,vf=t)}function Of(e,t){var n=e-zf,r=t-vf,i=bs(n*n+r*r);wf+=i*(zf+e)/2,kf+=i*(vf+t)/2,xf+=i,qf(zf=e,vf=t)}function Ef(){Cf.point=qf}function Af(){Cf.point=Hf}function Lf(){Df(df,pf)}function Hf(e,t){Cf.point=Df,qf(df=zf=e,pf=vf=t)}function Df(e,t){var n=e-zf,r=t-vf,i=bs(n*n+r*r);wf+=i*(zf+e)/2,kf+=i*(vf+t)/2,xf+=i,jf+=(i=vf*e-zf*t)*(zf+e),Mf+=i*(vf+t),_f+=3*i,qf(zf=e,vf=t)}var Pf=Cf;function Vf(e){this._context=e}Vf.prototype={_radius:4.5,pointRadius:function(e){return this._radius=e,this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._context.closePath(),this._point=NaN},point:function(e,t){switch(this._point){case 0:this._context.moveTo(e,t),this._point=1;break;case 1:this._context.lineTo(e,t);break;default:this._context.moveTo(e+this._radius,t),this._context.arc(e,t,this._radius,0,cs)}},result:Ms};var Nf,If,Rf,Ff,Bf,Uf=Jc(),Wf={point:Ms,lineStart:function(){Wf.point=Gf},lineEnd:function(){Nf&&Yf(If,Rf),Wf.point=Ms},polygonStart:function(){Nf=!0},polygonEnd:function(){Nf=null},result:function(){var e=+Uf;return Uf.reset(),e}};function Gf(e,t){Wf.point=Yf,If=Ff=e,Rf=Bf=t}function Yf(e,t){Ff-=e,Bf-=t,Uf.add(bs(Ff*Ff+Bf*Bf)),Ff=e,Bf=t}var Zf=Wf;function $f(){this._string=[]}function Xf(e){return"m0,"+e+"a"+e+","+e+" 0 1,1 0,"+-2*e+"a"+e+","+e+" 0 1,1 0,"+2*e+"z"}$f.prototype={_radius:4.5,_circle:Xf(4.5),pointRadius:function(e){return(e=+e)!==this._radius&&(this._radius=e,this._circle=null),this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._string.push("Z"),this._point=NaN},point:function(e,t){switch(this._point){case 0:this._string.push("M",e,",",t),this._point=1;break;case 1:this._string.push("L",e,",",t);break;default:null==this._circle&&(this._circle=Xf(this._radius)),this._string.push("M",e,",",t,this._circle)}},result:function(){if(this._string.length){var e=this._string.join("");return this._string=[],e}return null}};var Kf=function(e,t){var n,r,i=4.5;function o(e){return e&&("function"===typeof i&&r.pointRadius(+i.apply(this,arguments)),Ds(e,n(r))),r.result()}return o.area=function(e){return Ds(e,n(sf)),sf.result()},o.measure=function(e){return Ds(e,n(Zf)),Zf.result()},o.bounds=function(e){return Ds(e,n(gf)),gf.result()},o.centroid=function(e){return Ds(e,n(Pf)),Pf.result()},o.projection=function(t){return arguments.length?(n=null==t?(e=null,Ju):(e=t).stream,o):e},o.context=function(e){return arguments.length?(r=null==e?(t=null,new $f):new Vf(t=e),"function"!==typeof i&&r.pointRadius(i),o):t},o.pointRadius=function(e){return arguments.length?(i="function"===typeof e?e:(r.pointRadius(+e),+e),o):i},o.projection(e).context(t)},Qf=function(e){return{stream:Jf(e)}};function Jf(e){return function(t){var n=new eh;for(var r in e)n[r]=e[r];return n.stream=t,n}}function eh(){}function th(e,t,n){var r=e.clipExtent&&e.clipExtent();return e.scale(150).translate([0,0]),null!=r&&e.clipExtent(null),Ds(n,e.stream(gf)),t(gf.result()),null!=r&&e.clipExtent(r),e}function nh(e,t,n){return th(e,(function(n){var r=t[1][0]-t[0][0],i=t[1][1]-t[0][1],o=Math.min(r/(n[1][0]-n[0][0]),i/(n[1][1]-n[0][1])),a=+t[0][0]+(r-o*(n[1][0]+n[0][0]))/2,c=+t[0][1]+(i-o*(n[1][1]+n[0][1]))/2;e.scale(150*o).translate([a,c])}),n)}function rh(e,t,n){return nh(e,[[0,0],t],n)}function ih(e,t,n){return th(e,(function(n){var r=+t,i=r/(n[1][0]-n[0][0]),o=(r-i*(n[1][0]+n[0][0]))/2,a=-i*n[0][1];e.scale(150*i).translate([o,a])}),n)}function oh(e,t,n){return th(e,(function(n){var r=+t,i=r/(n[1][1]-n[0][1]),o=-i*n[0][0],a=(r-i*(n[1][1]+n[0][1]))/2;e.scale(150*i).translate([o,a])}),n)}eh.prototype={constructor:eh,point:function(e,t){this.stream.point(e,t)},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()}};var ah=16,ch=ds(30*ls),sh=function(e,t){return+t?function(e,t){function n(r,i,o,a,c,s,l,u,f,h,d,p,z,v){var g=l-r,m=u-i,y=g*g+m*m;if(y>4*t&&z--){var b=a+h,w=c+d,k=s+p,x=bs(b*b+w*w+k*k),j=xs(k/=x),M=us(us(k)-1)t||us((g*S+m*T)/y-.5)>.3||a*h+c*d+s*p2?e[2]%360*ls:0,q()):[v*ss,g*ss,m*ss]},M.precision=function(e){return arguments.length?(j=sh(C,x=e*e),S()):bs(x)},M.fitExtent=function(e,t){return nh(M,e,t)},M.fitSize=function(e,t){return rh(M,e,t)},M.fitWidth=function(e,t){return ih(M,e,t)},M.fitHeight=function(e,t){return oh(M,e,t)},function(){return t=e.apply(this,arguments),M.invert=t.invert&&_,q()}}function hh(e){var t=0,n=is/3,r=fh(e),i=r(t,n);return i.parallels=function(e){return arguments.length?r(t=e[0]*ls,n=e[1]*ls):[t*ss,n*ss]},i}function dh(e,t){var n=ms(e),r=(n+ms(t))/2;if(us(r)=.12&&i<.234&&r>=-.425&&r<-.214?c:i>=.166&&i<.234&&r>=-.214&&r<-.115?s:a).invert(e)},u.stream=function(n){return e&&t===n?e:e=function(e){var t=e.length;return{point:function(n,r){for(var i=-1;++i0?t<-os+rs&&(t=-os+rs):t>os-rs&&(t=os-rs);var n=i/gs(_h(t),r);return[n*ms(r*e),i-n*ds(r*e)]}return o.invert=function(e,t){var n=i-t,o=ys(r)*bs(e*e+n*n);return[hs(e,us(n))/r*ys(n),2*fs(gs(i/o,1/r))-os]},o}var qh=function(){return hh(Ch).scale(109.5).parallels([30,30])};function Sh(e,t){return[e,t]}Sh.invert=Sh;var Th=function(){return uh(Sh).scale(152.63)};function Oh(e,t){var n=ds(e),r=e===t?ms(e):(n-ds(t))/(t-e),i=n/r+e;if(us(r)rs&&--i>0);return[e/(.8707+(o=r*r)*(o*(o*o*o*(.003971-.001529*o)-.013791)-.131979)),r]};var Vh=function(){return uh(Ph).scale(175.295)};function Nh(e,t){return[ds(t)*ms(e),ms(t)]}Nh.invert=mh(xs);var Ih=function(){return uh(Nh).scale(249.5).clipAngle(90+rs)};function Rh(e,t){var n=ds(t),r=1+ds(e)*n;return[n*ms(e)/r,ms(t)/r]}Rh.invert=mh((function(e){return 2*fs(e)}));var Fh=function(){return uh(Rh).scale(250).clipAngle(142)};function Bh(e,t){return[vs(ws((os+t)/2)),-e]}Bh.invert=function(e,t){return[-t,2*fs(zs(e))-os]};var Uh=function(){var e=Mh(Bh),t=e.center,n=e.rotate;return e.center=function(e){return arguments.length?t([-e[1],e[0]]):[(e=t())[1],-e[0]]},e.rotate=function(e){return arguments.length?n([e[0],e[1],e.length>2?e[2]+90:90]):[(e=n())[0],e[1],e[2]-90]},n([0,0,90]).scale(159.155)};function Wh(e,t){return e.parent===t.parent?1:2}function Gh(e,t){return e+t.x}function Yh(e,t){return Math.max(e,t.y)}var Zh=function(){var e=Wh,t=1,n=1,r=!1;function i(i){var o,a=0;i.eachAfter((function(t){var n=t.children;n?(t.x=function(e){return e.reduce(Gh,0)/e.length}(n),t.y=function(e){return 1+e.reduce(Yh,0)}(n)):(t.x=o?a+=e(t,o):0,t.y=0,o=t)}));var c=function(e){for(var t;t=e.children;)e=t[0];return e}(i),s=function(e){for(var t;t=e.children;)e=t[t.length-1];return e}(i),l=c.x-e(c,s)/2,u=s.x+e(s,c)/2;return i.eachAfter(r?function(e){e.x=(e.x-i.x)*t,e.y=(i.y-e.y)*n}:function(e){e.x=(e.x-l)/(u-l)*t,e.y=(1-(i.y?e.y/i.y:1))*n})}return i.separation=function(t){return arguments.length?(e=t,i):e},i.size=function(e){return arguments.length?(r=!1,t=+e[0],n=+e[1],i):r?null:[t,n]},i.nodeSize=function(e){return arguments.length?(r=!0,t=+e[0],n=+e[1],i):r?[t,n]:null},i};function $h(e){var t=0,n=e.children,r=n&&n.length;if(r)for(;--r>=0;)t+=n[r].value;else t=1;e.value=t}function Xh(e,t){var n,r,i,o,a,c=new ed(e),s=+e.value&&(c.value=e.value),l=[c];for(null==t&&(t=Kh);n=l.pop();)if(s&&(n.value=+n.data.value),(i=t(n.data))&&(a=i.length))for(n.children=new Array(a),o=a-1;o>=0;--o)l.push(r=n.children[o]=new ed(i[o])),r.parent=n,r.depth=n.depth+1;return c.eachBefore(Jh)}function Kh(e){return e.children}function Qh(e){e.data=e.data.data}function Jh(e){var t=0;do{e.height=t}while((e=e.parent)&&e.height<++t)}function ed(e){this.data=e,this.depth=this.height=0,this.parent=null}ed.prototype=Xh.prototype={constructor:ed,count:function(){return this.eachAfter($h)},each:function(e){var t,n,r,i,o=this,a=[o];do{for(t=a.reverse(),a=[];o=t.pop();)if(e(o),n=o.children)for(r=0,i=n.length;r=0;--n)i.push(t[n]);return this},sum:function(e){return this.eachAfter((function(t){for(var n=+e(t.data)||0,r=t.children,i=r&&r.length;--i>=0;)n+=r[i].value;t.value=n}))},sort:function(e){return this.eachBefore((function(t){t.children&&t.children.sort(e)}))},path:function(e){for(var t=this,n=function(e,t){if(e===t)return e;var n=e.ancestors(),r=t.ancestors(),i=null;e=n.pop(),t=r.pop();for(;e===t;)i=e,e=n.pop(),t=r.pop();return i}(t,e),r=[t];t!==n;)t=t.parent,r.push(t);for(var i=r.length;e!==n;)r.splice(i,0,e),e=e.parent;return r},ancestors:function(){for(var e=this,t=[e];e=e.parent;)t.push(e);return t},descendants:function(){var e=[];return this.each((function(t){e.push(t)})),e},leaves:function(){var e=[];return this.eachBefore((function(t){t.children||e.push(t)})),e},links:function(){var e=this,t=[];return e.each((function(n){n!==e&&t.push({source:n.parent,target:n})})),t},copy:function(){return Xh(this).eachBefore(Qh)}};var td=Array.prototype.slice;var nd=function(e){for(var t,n,r=0,i=(e=function(e){for(var t,n,r=e.length;r;)n=Math.random()*r--|0,t=e[r],e[r]=e[n],e[n]=t;return e}(td.call(e))).length,o=[];r0&&n*n>r*r+i*i}function ad(e,t){for(var n=0;nn*n+r*r}function hd(e){var t=e._,n=e.next._,r=t.r+n.r,i=(t.x*n.r+n.x*t.r)/r,o=(t.y*n.r+n.y*t.r)/r;return i*i+o*o}function dd(e){this._=e,this.next=null,this.previous=null}function pd(e){if(!(i=e.length))return 0;var t,n,r,i,o,a,c,s,l,u,f;if((t=e[0]).x=0,t.y=0,!(i>1))return t.r;if(n=e[1],t.x=-n.r,n.x=t.r,n.y=0,!(i>2))return t.r+n.r;ud(n,t,r=e[2]),t=new dd(t),n=new dd(n),r=new dd(r),t.next=r.previous=n,n.next=t.previous=r,r.next=n.previous=t;e:for(c=3;c0)throw new Error("cycle");return o}return n.id=function(t){return arguments.length?(e=gd(t),n):e},n.parentId=function(e){return arguments.length?(t=gd(e),n):t},n};function Ld(e,t){return e.parent===t.parent?1:2}function Hd(e){var t=e.children;return t?t[0]:e.t}function Dd(e){var t=e.children;return t?t[t.length-1]:e.t}function Pd(e,t,n){var r=n/(t.i-e.i);t.c-=r,t.s+=n,e.c+=r,t.z+=n,t.m+=n}function Vd(e,t,n){return e.a.parent===t.parent?e.a:n}function Nd(e,t){this._=e,this.parent=null,this.children=null,this.A=null,this.a=this,this.z=0,this.m=0,this.c=0,this.s=0,this.t=null,this.i=t}Nd.prototype=Object.create(ed.prototype);var Id=function(){var e=Ld,t=1,n=1,r=null;function i(i){var s=function(e){for(var t,n,r,i,o,a=new Nd(e,0),c=[a];t=c.pop();)if(r=t._.children)for(t.children=new Array(o=r.length),i=o-1;i>=0;--i)c.push(n=t.children[i]=new Nd(r[i],i)),n.parent=t;return(a.parent=new Nd(null,0)).children=[a],a}(i);if(s.eachAfter(o),s.parent.m=-s.z,s.eachBefore(a),r)i.eachBefore(c);else{var l=i,u=i,f=i;i.eachBefore((function(e){e.xu.x&&(u=e),e.depth>f.depth&&(f=e)}));var h=l===u?1:e(l,u)/2,d=h-l.x,p=t/(u.x+h+d),z=n/(f.depth||1);i.eachBefore((function(e){e.x=(e.x+d)*p,e.y=e.depth*z}))}return i}function o(t){var n=t.children,r=t.parent.children,i=t.i?r[t.i-1]:null;if(n){!function(e){for(var t,n=0,r=0,i=e.children,o=i.length;--o>=0;)(t=i[o]).z+=n,t.m+=n,n+=t.s+(r+=t.c)}(t);var o=(n[0].z+n[n.length-1].z)/2;i?(t.z=i.z+e(t._,i._),t.m=t.z-o):t.z=o}else i&&(t.z=i.z+e(t._,i._));t.parent.A=function(t,n,r){if(n){for(var i,o=t,a=t,c=n,s=o.parent.children[0],l=o.m,u=a.m,f=c.m,h=s.m;c=Dd(c),o=Hd(o),c&&o;)s=Hd(s),(a=Dd(a)).a=t,(i=c.z+f-o.z-l+e(c._,o._))>0&&(Pd(Vd(c,t,r),t,i),l+=i,u+=i),f+=c.m,l+=o.m,h+=s.m,u+=a.m;c&&!Dd(a)&&(a.t=c,a.m+=f-u),o&&!Hd(s)&&(s.t=o,s.m+=l-h,r=t)}return r}(t,i,t.parent.A||r[0])}function a(e){e._.x=e.z+e.parent.m,e.m+=e.parent.m}function c(e){e.x*=t,e.y=e.depth*n}return i.separation=function(t){return arguments.length?(e=t,i):e},i.size=function(e){return arguments.length?(r=!1,t=+e[0],n=+e[1],i):r?null:[t,n]},i.nodeSize=function(e){return arguments.length?(r=!0,t=+e[0],n=+e[1],i):r?[t,n]:null},i},Rd=function(e,t,n,r,i){for(var o,a=e.children,c=-1,s=a.length,l=e.value&&(i-n)/e.value;++ch&&(h=c),v=u*u*z,(d=Math.max(h/v,v/f))>p){u-=c;break}p=d}g.push(a={value:u,dice:s1?t:1)},n}(Fd),Wd=function(){var e=Ud,t=!1,n=1,r=1,i=[0],o=md,a=md,c=md,s=md,l=md;function u(e){return e.x0=e.y0=0,e.x1=n,e.y1=r,e.eachBefore(f),i=[0],t&&e.eachBefore(Md),e}function f(t){var n=i[t.depth],r=t.x0+n,u=t.y0+n,f=t.x1-n,h=t.y1-n;f=n-1){var u=c[t];return u.x0=i,u.y0=o,u.x1=a,void(u.y1=s)}var f=l[t],h=r/2+f,d=t+1,p=n-1;for(;d>>1;l[z]s-o){var m=(i*g+a*v)/r;e(t,d,v,i,o,m,s),e(d,n,g,m,o,a,s)}else{var y=(o*g+s*v)/r;e(t,d,v,i,o,a,y),e(d,n,g,i,y,a,s)}}(0,s,e.value,t,n,r,i)},Yd=function(e,t,n,r,i){(1&e.depth?Rd:_d)(e,t,n,r,i)},Zd=function e(t){function n(e,n,r,i,o){if((a=e._squarify)&&a.ratio===t)for(var a,c,s,l,u,f=-1,h=a.length,d=e.value;++f1?t:1)},n}(Fd),$d=function(e){for(var t,n=-1,r=e.length,i=e[r-1],o=0;++n1&&Kd(e[n[r-2]],e[n[r-1]],e[i])<=0;)--r;n[r++]=i}return n.slice(0,r)}var ep=function(e){if((n=e.length)<3)return null;var t,n,r=new Array(n),i=new Array(n);for(t=0;t=0;--t)l.push(e[r[o[t]][2]]);for(t=+c;tc!==l>c&&a<(s-n)*(c-r)/(l-r)+n&&(u=!u),s=n,l=r;return u},np=function(e){for(var t,n,r=-1,i=e.length,o=e[i-1],a=o[0],c=o[1],s=0;++r=0;)if((n=e._tasks[r])&&(e._tasks[r]=null,n.abort))try{n.abort()}catch(t){}e._active=NaN,lp(e)}function lp(e){if(!e._active&&e._call){var t=e._data;e._data=void 0,e._call(e._error,t)}}function up(e){if(null==e)e=1/0;else if(!((e=+e)>=1))throw new Error("invalid concurrency");return new op(e)}op.prototype=up.prototype={constructor:op,defer:function(e){if("function"!==typeof e)throw new Error("invalid callback");if(this._call)throw new Error("defer after await");if(null!=this._error)return this;var t=rp.call(arguments,1);return t.push(e),++this._waiting,this._tasks.push(t),ap(this),this},abort:function(){return null==this._error&&sp(this,new Error("abort")),this},await:function(e){if("function"!==typeof e)throw new Error("invalid callback");if(this._call)throw new Error("multiple await");return this._call=function(t,n){e.apply(null,[t].concat(n))},lp(this),this},awaitAll:function(e){if("function"!==typeof e)throw new Error("invalid callback");if(this._call)throw new Error("multiple await");return this._call=e,lp(this),this}};var fp=function(){return Math.random()},hp=function e(t){function n(e,n){return e=null==e?0:+e,n=null==n?1:+n,1===arguments.length?(n=e,e=0):n-=e,function(){return t()*n+e}}return n.source=e,n}(fp),dp=function e(t){function n(e,n){var r,i;return e=null==e?0:+e,n=null==n?1:+n,function(){var o;if(null!=r)o=r,r=null;else do{r=2*t()-1,o=2*t()-1,i=r*r+o*o}while(!i||i>1);return e+n*o*Math.sqrt(-2*Math.log(i)/i)}}return n.source=e,n}(fp),pp=function e(t){function n(){var e=dp.source(t).apply(this,arguments);return function(){return Math.exp(e())}}return n.source=e,n}(fp),zp=function e(t){function n(e){return function(){for(var n=0,r=0;r=200&&r<300||304===r){if(i)try{t=i.call(n,s)}catch(o){return void a.call("error",n,o)}else t=s;a.call("load",n,t)}else a.call("error",n,e)}if("undefined"===typeof XDomainRequest||"withCredentials"in s||!/^(http(s)?:)?\/\//.test(e)||(s=new XDomainRequest),"onload"in s?s.onload=s.onerror=s.ontimeout=h:s.onreadystatechange=function(e){s.readyState>3&&h(e)},s.onprogress=function(e){a.call("progress",n,e)},n={header:function(e,t){return e=(e+"").toLowerCase(),arguments.length<2?c.get(e):(null==t?c.remove(e):c.set(e,t+""),n)},mimeType:function(e){return arguments.length?(r=null==e?null:e+"",n):r},responseType:function(e){return arguments.length?(o=e,n):o},timeout:function(e){return arguments.length?(f=+e,n):f},user:function(e){return arguments.length<1?l:(l=null==e?null:e+"",n)},password:function(e){return arguments.length<1?u:(u=null==e?null:e+"",n)},response:function(e){return i=e,n},get:function(e,t){return n.send("GET",e,t)},post:function(e,t){return n.send("POST",e,t)},send:function(t,i,h){return s.open(t,e,!0,l,u),null==r||c.has("accept")||c.set("accept",r+",*/*"),s.setRequestHeader&&c.each((function(e,t){s.setRequestHeader(t,e)})),null!=r&&s.overrideMimeType&&s.overrideMimeType(r),null!=o&&(s.responseType=o),f>0&&(s.timeout=f),null==h&&"function"===typeof i&&(h=i,i=null),null!=h&&1===h.length&&(h=function(e){return function(t,n){e(null==t?n:null)}}(h)),null!=h&&n.on("error",h).on("load",(function(e){h(null,e)})),a.call("beforesend",n,s),s.send(null==i?null:i),n},abort:function(){return s.abort(),n},on:function(){var e=a.on.apply(a,arguments);return e===a?n:e}},null!=t){if("function"!==typeof t)throw new Error("invalid callback: "+t);return n.get(t)}return n};var yp=function(e,t){return function(n,r){var i=mp(n).mimeType(e).response(t);if(null!=r){if("function"!==typeof r)throw new Error("invalid callback: "+r);return i.get(r)}return i}},bp=yp("text/html",(function(e){return document.createRange().createContextualFragment(e.responseText)})),wp=yp("application/json",(function(e){return JSON.parse(e.responseText)})),kp=yp("text/plain",(function(e){return e.responseText})),xp=yp("application/xml",(function(e){var t=e.responseXML;if(!t)throw new Error("parse error");return t})),jp=function(e,t){return function(n,r,i){arguments.length<3&&(i=r,r=null);var o=mp(n).mimeType(e);return o.row=function(e){return arguments.length?o.response(Mp(t,r=e)):r},o.row(r),i?o.get(i):o}};function Mp(e,t){return function(n){return e(n.responseText,t)}}var _p=jp("text/csv",ec),Cp=jp("text/tab-separated-values",oc),qp=Array.prototype,Sp=qp.map,Tp=qp.slice,Op={name:"implicit"};function Ep(e){var t=Aa(),n=[],r=Op;function i(i){var o=i+"",a=t.get(o);if(!a){if(r!==Op)return r;t.set(o,a=n.push(i))}return e[(a-1)%e.length]}return e=null==e?[]:Tp.call(e),i.domain=function(e){if(!arguments.length)return n.slice();n=[],t=Aa();for(var r,o,a=-1,c=e.length;++a2?Ip:Np,r=i=null,u}function u(t){return(r||(r=n(o,a,s?function(e){return function(t,n){var r=e(t=+t,n=+n);return function(e){return e<=t?0:e>=n?1:r(e)}}}(e):e,c)))(+t)}return u.invert=function(e){return(i||(i=n(a,o,Vp,s?function(e){return function(t,n){var r=e(t=+t,n=+n);return function(e){return e<=0?t:e>=1?n:r(e)}}}(t):t)))(+e)},u.domain=function(e){return arguments.length?(o=Sp.call(e,Dp),l()):o.slice()},u.range=function(e){return arguments.length?(a=Tp.call(e),l()):a.slice()},u.rangeRound=function(e){return a=Tp.call(e),c=mr,l()},u.clamp=function(e){return arguments.length?(s=!!e,l()):s},u.interpolate=function(e){return arguments.length?(c=e,l()):c},l()}var Bp=function(e,t,n){var r,i=e[0],o=e[e.length-1],a=q(i,o,null==t?10:t);switch((n=Rc(null==n?",f":n)).type){case"s":var c=Math.max(Math.abs(i),Math.abs(o));return null!=n.precision||isNaN(r=Kc(a,c))||(n.precision=r),Wc(n,c);case"":case"e":case"g":case"p":case"r":null!=n.precision||isNaN(r=Qc(a,Math.max(Math.abs(i),Math.abs(o))))||(n.precision=r-("e"===n.type));break;case"f":case"%":null!=n.precision||isNaN(r=Xc(a))||(n.precision=r-2*("%"===n.type))}return Uc(n)};function Up(e){var t=e.domain;return e.ticks=function(e){var n=t();return _(n[0],n[n.length-1],null==e?10:e)},e.tickFormat=function(e,n){return Bp(t(),e,n)},e.nice=function(n){null==n&&(n=10);var r,i=t(),o=0,a=i.length-1,c=i[o],s=i[a];return s0?r=C(c=Math.floor(c/r)*r,s=Math.ceil(s/r)*r,n):r<0&&(r=C(c=Math.ceil(c*r)/r,s=Math.floor(s*r)/r,n)),r>0?(i[o]=Math.floor(c/r)*r,i[a]=Math.ceil(s/r)*r,t(i)):r<0&&(i[o]=Math.ceil(c*r)/r,i[a]=Math.floor(s*r)/r,t(i)),e},e}function Wp(){var e=Fp(Vp,sr);return e.copy=function(){return Rp(e,Wp())},Up(e)}function Gp(){var e=[0,1];function t(e){return+e}return t.invert=t,t.domain=t.range=function(n){return arguments.length?(e=Sp.call(n,Dp),t):e.slice()},t.copy=function(){return Gp().domain(e)},Up(t)}var Yp=function(e,t){var n,r=0,i=(e=e.slice()).length-1,o=e[r],a=e[i];return a0){for(;hs)break;z.push(f)}}else for(;h=1;--u)if(!((f=l*u)s)break;z.push(f)}}else z=_(h,d,Math.min(d-h,p)).map(i);return o?z.reverse():z},e.tickFormat=function(t,o){if(null==o&&(o=10===n?".0e":","),"function"!==typeof o&&(o=Uc(o)),t===1/0)return o;null==t&&(t=10);var a=Math.max(1,n*t/e.ticks().length);return function(e){var t=e/i(Math.round(r(e)));return t*n0?n[i-1]:e[0],i=n?[r[n-1],t]:[r[a-1],r[a]]},o.copy=function(){return oz().domain([e,t]).range(i)},Up(o)}function az(){var e=[.5],t=[0,1],n=1;function r(r){if(r<=r)return t[s(e,r,0,n)]}return r.domain=function(i){return arguments.length?(e=Tp.call(i),n=Math.min(e.length,t.length-1),r):e.slice()},r.range=function(i){return arguments.length?(t=Tp.call(i),n=Math.min(e.length,t.length-1),r):t.slice()},r.invertExtent=function(n){var r=t.indexOf(n);return[e[r-1],e[r]]},r.copy=function(){return az().domain(e).range(t)},r}var cz=new Date,sz=new Date;function lz(e,t,n,r){function i(t){return e(t=new Date(+t)),t}return i.floor=i,i.ceil=function(n){return e(n=new Date(n-1)),t(n,1),e(n),n},i.round=function(e){var t=i(e),n=i.ceil(e);return e-t0))return c;do{c.push(a=new Date(+n)),t(n,o),e(n)}while(a=t)for(;e(t),!n(t);)t.setTime(t-1)}),(function(e,r){if(e>=e)if(r<0)for(;++r<=0;)for(;t(e,-1),!n(e););else for(;--r>=0;)for(;t(e,1),!n(e););}))},n&&(i.count=function(t,r){return cz.setTime(+t),sz.setTime(+r),e(cz),e(sz),Math.floor(n(cz,sz))},i.every=function(e){return e=Math.floor(e),isFinite(e)&&e>0?e>1?i.filter(r?function(t){return r(t)%e===0}:function(t){return i.count(0,t)%e===0}):i:null}),i}var uz=lz((function(){}),(function(e,t){e.setTime(+e+t)}),(function(e,t){return t-e}));uz.every=function(e){return e=Math.floor(e),isFinite(e)&&e>0?e>1?lz((function(t){t.setTime(Math.floor(t/e)*e)}),(function(t,n){t.setTime(+t+n*e)}),(function(t,n){return(n-t)/e})):uz:null};var fz=uz,hz=uz.range,dz=6e4,pz=6048e5,zz=lz((function(e){e.setTime(1e3*Math.floor(e/1e3))}),(function(e,t){e.setTime(+e+1e3*t)}),(function(e,t){return(t-e)/1e3}),(function(e){return e.getUTCSeconds()})),vz=zz,gz=zz.range,mz=lz((function(e){e.setTime(Math.floor(e/dz)*dz)}),(function(e,t){e.setTime(+e+t*dz)}),(function(e,t){return(t-e)/dz}),(function(e){return e.getMinutes()})),yz=mz,bz=mz.range,wz=lz((function(e){var t=e.getTimezoneOffset()*dz%36e5;t<0&&(t+=36e5),e.setTime(36e5*Math.floor((+e-t)/36e5)+t)}),(function(e,t){e.setTime(+e+36e5*t)}),(function(e,t){return(t-e)/36e5}),(function(e){return e.getHours()})),kz=wz,xz=wz.range,jz=lz((function(e){e.setHours(0,0,0,0)}),(function(e,t){e.setDate(e.getDate()+t)}),(function(e,t){return(t-e-(t.getTimezoneOffset()-e.getTimezoneOffset())*dz)/864e5}),(function(e){return e.getDate()-1})),Mz=jz,_z=jz.range;function Cz(e){return lz((function(t){t.setDate(t.getDate()-(t.getDay()+7-e)%7),t.setHours(0,0,0,0)}),(function(e,t){e.setDate(e.getDate()+7*t)}),(function(e,t){return(t-e-(t.getTimezoneOffset()-e.getTimezoneOffset())*dz)/pz}))}var qz=Cz(0),Sz=Cz(1),Tz=Cz(2),Oz=Cz(3),Ez=Cz(4),Az=Cz(5),Lz=Cz(6),Hz=qz.range,Dz=Sz.range,Pz=Tz.range,Vz=Oz.range,Nz=Ez.range,Iz=Az.range,Rz=Lz.range,Fz=lz((function(e){e.setDate(1),e.setHours(0,0,0,0)}),(function(e,t){e.setMonth(e.getMonth()+t)}),(function(e,t){return t.getMonth()-e.getMonth()+12*(t.getFullYear()-e.getFullYear())}),(function(e){return e.getMonth()})),Bz=Fz,Uz=Fz.range,Wz=lz((function(e){e.setMonth(0,1),e.setHours(0,0,0,0)}),(function(e,t){e.setFullYear(e.getFullYear()+t)}),(function(e,t){return t.getFullYear()-e.getFullYear()}),(function(e){return e.getFullYear()}));Wz.every=function(e){return isFinite(e=Math.floor(e))&&e>0?lz((function(t){t.setFullYear(Math.floor(t.getFullYear()/e)*e),t.setMonth(0,1),t.setHours(0,0,0,0)}),(function(t,n){t.setFullYear(t.getFullYear()+n*e)})):null};var Gz=Wz,Yz=Wz.range,Zz=lz((function(e){e.setUTCSeconds(0,0)}),(function(e,t){e.setTime(+e+t*dz)}),(function(e,t){return(t-e)/dz}),(function(e){return e.getUTCMinutes()})),$z=Zz,Xz=Zz.range,Kz=lz((function(e){e.setUTCMinutes(0,0,0)}),(function(e,t){e.setTime(+e+36e5*t)}),(function(e,t){return(t-e)/36e5}),(function(e){return e.getUTCHours()})),Qz=Kz,Jz=Kz.range,ev=lz((function(e){e.setUTCHours(0,0,0,0)}),(function(e,t){e.setUTCDate(e.getUTCDate()+t)}),(function(e,t){return(t-e)/864e5}),(function(e){return e.getUTCDate()-1})),tv=ev,nv=ev.range;function rv(e){return lz((function(t){t.setUTCDate(t.getUTCDate()-(t.getUTCDay()+7-e)%7),t.setUTCHours(0,0,0,0)}),(function(e,t){e.setUTCDate(e.getUTCDate()+7*t)}),(function(e,t){return(t-e)/pz}))}var iv=rv(0),ov=rv(1),av=rv(2),cv=rv(3),sv=rv(4),lv=rv(5),uv=rv(6),fv=iv.range,hv=ov.range,dv=av.range,pv=cv.range,zv=sv.range,vv=lv.range,gv=uv.range,mv=lz((function(e){e.setUTCDate(1),e.setUTCHours(0,0,0,0)}),(function(e,t){e.setUTCMonth(e.getUTCMonth()+t)}),(function(e,t){return t.getUTCMonth()-e.getUTCMonth()+12*(t.getUTCFullYear()-e.getUTCFullYear())}),(function(e){return e.getUTCMonth()})),yv=mv,bv=mv.range,wv=lz((function(e){e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)}),(function(e,t){e.setUTCFullYear(e.getUTCFullYear()+t)}),(function(e,t){return t.getUTCFullYear()-e.getUTCFullYear()}),(function(e){return e.getUTCFullYear()}));wv.every=function(e){return isFinite(e=Math.floor(e))&&e>0?lz((function(t){t.setUTCFullYear(Math.floor(t.getUTCFullYear()/e)*e),t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)}),(function(t,n){t.setUTCFullYear(t.getUTCFullYear()+n*e)})):null};var kv=wv,xv=wv.range;function jv(e){if(0<=e.y&&e.y<100){var t=new Date(-1,e.m,e.d,e.H,e.M,e.S,e.L);return t.setFullYear(e.y),t}return new Date(e.y,e.m,e.d,e.H,e.M,e.S,e.L)}function Mv(e){if(0<=e.y&&e.y<100){var t=new Date(Date.UTC(-1,e.m,e.d,e.H,e.M,e.S,e.L));return t.setUTCFullYear(e.y),t}return new Date(Date.UTC(e.y,e.m,e.d,e.H,e.M,e.S,e.L))}function _v(e){return{y:e,m:0,d:1,H:0,M:0,S:0,L:0}}function Cv(e){var t=e.dateTime,n=e.date,r=e.time,i=e.periods,o=e.days,a=e.shortDays,c=e.months,s=e.shortMonths,l=Nv(i),u=Iv(i),f=Nv(o),h=Iv(o),d=Nv(a),p=Iv(a),z=Nv(c),v=Iv(c),g=Nv(s),m=Iv(s),y={a:function(e){return a[e.getDay()]},A:function(e){return o[e.getDay()]},b:function(e){return s[e.getMonth()]},B:function(e){return c[e.getMonth()]},c:null,d:ag,e:ag,f:fg,H:cg,I:sg,j:lg,L:ug,m:hg,M:dg,p:function(e){return i[+(e.getHours()>=12)]},Q:Rg,s:Fg,S:pg,u:zg,U:vg,V:gg,w:mg,W:yg,x:null,X:null,y:bg,Y:wg,Z:kg,"%":Ig},b={a:function(e){return a[e.getUTCDay()]},A:function(e){return o[e.getUTCDay()]},b:function(e){return s[e.getUTCMonth()]},B:function(e){return c[e.getUTCMonth()]},c:null,d:xg,e:xg,f:qg,H:jg,I:Mg,j:_g,L:Cg,m:Sg,M:Tg,p:function(e){return i[+(e.getUTCHours()>=12)]},Q:Rg,s:Fg,S:Og,u:Eg,U:Ag,V:Lg,w:Hg,W:Dg,x:null,X:null,y:Pg,Y:Vg,Z:Ng,"%":Ig},w={a:function(e,t,n){var r=d.exec(t.slice(n));return r?(e.w=p[r[0].toLowerCase()],n+r[0].length):-1},A:function(e,t,n){var r=f.exec(t.slice(n));return r?(e.w=h[r[0].toLowerCase()],n+r[0].length):-1},b:function(e,t,n){var r=g.exec(t.slice(n));return r?(e.m=m[r[0].toLowerCase()],n+r[0].length):-1},B:function(e,t,n){var r=z.exec(t.slice(n));return r?(e.m=v[r[0].toLowerCase()],n+r[0].length):-1},c:function(e,n,r){return j(e,t,n,r)},d:Xv,e:Xv,f:ng,H:Qv,I:Qv,j:Kv,L:tg,m:$v,M:Jv,p:function(e,t,n){var r=l.exec(t.slice(n));return r?(e.p=u[r[0].toLowerCase()],n+r[0].length):-1},Q:ig,s:og,S:eg,u:Fv,U:Bv,V:Uv,w:Rv,W:Wv,x:function(e,t,r){return j(e,n,t,r)},X:function(e,t,n){return j(e,r,t,n)},y:Yv,Y:Gv,Z:Zv,"%":rg};function k(e,t){return function(n){var r,i,o,a=[],c=-1,s=0,l=e.length;for(n instanceof Date||(n=new Date(+n));++c53)return null;"w"in o||(o.w=1),"Z"in o?(i=(r=Mv(_v(o.y))).getUTCDay(),r=i>4||0===i?ov.ceil(r):ov(r),r=tv.offset(r,7*(o.V-1)),o.y=r.getUTCFullYear(),o.m=r.getUTCMonth(),o.d=r.getUTCDate()+(o.w+6)%7):(i=(r=t(_v(o.y))).getDay(),r=i>4||0===i?Sz.ceil(r):Sz(r),r=Mz.offset(r,7*(o.V-1)),o.y=r.getFullYear(),o.m=r.getMonth(),o.d=r.getDate()+(o.w+6)%7)}else("W"in o||"U"in o)&&("w"in o||(o.w="u"in o?o.u%7:"W"in o?1:0),i="Z"in o?Mv(_v(o.y)).getUTCDay():t(_v(o.y)).getDay(),o.m=0,o.d="W"in o?(o.w+6)%7+7*o.W-(i+5)%7:o.w+7*o.U-(i+6)%7);return"Z"in o?(o.H+=o.Z/100|0,o.M+=o.Z%100,Mv(o)):t(o)}}function j(e,t,n,r){for(var i,o,a=0,c=t.length,s=n.length;a=s)return-1;if(37===(i=t.charCodeAt(a++))){if(i=t.charAt(a++),!(o=w[i in Av?t.charAt(a++):i])||(r=o(e,n,r))<0)return-1}else if(i!=n.charCodeAt(r++))return-1}return r}return(y.x=k(n,y),y.X=k(r,y),y.c=k(t,y),b.x=k(n,b),b.X=k(r,b),b.c=k(t,b),{format:function(e){var t=k(e+="",y);return t.toString=function(){return e},t},parse:function(e){var t=x(e+="",jv);return t.toString=function(){return e},t},utcFormat:function(e){var t=k(e+="",b);return t.toString=function(){return e},t},utcParse:function(e){var t=x(e,Mv);return t.toString=function(){return e},t}})}var qv,Sv,Tv,Ov,Ev,Av={"-":"",_:" ",0:"0"},Lv=/^\s*\d+/,Hv=/^%/,Dv=/[\\^$*+?|[\]().{}]/g;function Pv(e,t,n){var r=e<0?"-":"",i=(r?-e:e)+"",o=i.length;return r+(o68?1900:2e3),n+r[0].length):-1}function Zv(e,t,n){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(t.slice(n,n+6));return r?(e.Z=r[1]?0:-(r[2]+(r[3]||"00")),n+r[0].length):-1}function $v(e,t,n){var r=Lv.exec(t.slice(n,n+2));return r?(e.m=r[0]-1,n+r[0].length):-1}function Xv(e,t,n){var r=Lv.exec(t.slice(n,n+2));return r?(e.d=+r[0],n+r[0].length):-1}function Kv(e,t,n){var r=Lv.exec(t.slice(n,n+3));return r?(e.m=0,e.d=+r[0],n+r[0].length):-1}function Qv(e,t,n){var r=Lv.exec(t.slice(n,n+2));return r?(e.H=+r[0],n+r[0].length):-1}function Jv(e,t,n){var r=Lv.exec(t.slice(n,n+2));return r?(e.M=+r[0],n+r[0].length):-1}function eg(e,t,n){var r=Lv.exec(t.slice(n,n+2));return r?(e.S=+r[0],n+r[0].length):-1}function tg(e,t,n){var r=Lv.exec(t.slice(n,n+3));return r?(e.L=+r[0],n+r[0].length):-1}function ng(e,t,n){var r=Lv.exec(t.slice(n,n+6));return r?(e.L=Math.floor(r[0]/1e3),n+r[0].length):-1}function rg(e,t,n){var r=Hv.exec(t.slice(n,n+1));return r?n+r[0].length:-1}function ig(e,t,n){var r=Lv.exec(t.slice(n));return r?(e.Q=+r[0],n+r[0].length):-1}function og(e,t,n){var r=Lv.exec(t.slice(n));return r?(e.Q=1e3*+r[0],n+r[0].length):-1}function ag(e,t){return Pv(e.getDate(),t,2)}function cg(e,t){return Pv(e.getHours(),t,2)}function sg(e,t){return Pv(e.getHours()%12||12,t,2)}function lg(e,t){return Pv(1+Mz.count(Gz(e),e),t,3)}function ug(e,t){return Pv(e.getMilliseconds(),t,3)}function fg(e,t){return ug(e,t)+"000"}function hg(e,t){return Pv(e.getMonth()+1,t,2)}function dg(e,t){return Pv(e.getMinutes(),t,2)}function pg(e,t){return Pv(e.getSeconds(),t,2)}function zg(e){var t=e.getDay();return 0===t?7:t}function vg(e,t){return Pv(qz.count(Gz(e),e),t,2)}function gg(e,t){var n=e.getDay();return e=n>=4||0===n?Ez(e):Ez.ceil(e),Pv(Ez.count(Gz(e),e)+(4===Gz(e).getDay()),t,2)}function mg(e){return e.getDay()}function yg(e,t){return Pv(Sz.count(Gz(e),e),t,2)}function bg(e,t){return Pv(e.getFullYear()%100,t,2)}function wg(e,t){return Pv(e.getFullYear()%1e4,t,4)}function kg(e){var t=e.getTimezoneOffset();return(t>0?"-":(t*=-1,"+"))+Pv(t/60|0,"0",2)+Pv(t%60,"0",2)}function xg(e,t){return Pv(e.getUTCDate(),t,2)}function jg(e,t){return Pv(e.getUTCHours(),t,2)}function Mg(e,t){return Pv(e.getUTCHours()%12||12,t,2)}function _g(e,t){return Pv(1+tv.count(kv(e),e),t,3)}function Cg(e,t){return Pv(e.getUTCMilliseconds(),t,3)}function qg(e,t){return Cg(e,t)+"000"}function Sg(e,t){return Pv(e.getUTCMonth()+1,t,2)}function Tg(e,t){return Pv(e.getUTCMinutes(),t,2)}function Og(e,t){return Pv(e.getUTCSeconds(),t,2)}function Eg(e){var t=e.getUTCDay();return 0===t?7:t}function Ag(e,t){return Pv(iv.count(kv(e),e),t,2)}function Lg(e,t){var n=e.getUTCDay();return e=n>=4||0===n?sv(e):sv.ceil(e),Pv(sv.count(kv(e),e)+(4===kv(e).getUTCDay()),t,2)}function Hg(e){return e.getUTCDay()}function Dg(e,t){return Pv(ov.count(kv(e),e),t,2)}function Pg(e,t){return Pv(e.getUTCFullYear()%100,t,2)}function Vg(e,t){return Pv(e.getUTCFullYear()%1e4,t,4)}function Ng(){return"+0000"}function Ig(){return"%"}function Rg(e){return+e}function Fg(e){return Math.floor(+e/1e3)}function Bg(e){return qv=Cv(e),Sv=qv.format,Tv=qv.parse,Ov=qv.utcFormat,Ev=qv.utcParse,qv}Bg({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"]});var Ug=Date.prototype.toISOString?function(e){return e.toISOString()}:Ov("%Y-%m-%dT%H:%M:%S.%LZ");var Wg=+new Date("2000-01-01T00:00:00.000Z")?function(e){var t=new Date(e);return isNaN(t)?null:t}:Ev("%Y-%m-%dT%H:%M:%S.%LZ"),Gg=1e3,Yg=60*Gg,Zg=60*Yg,$g=24*Zg,Xg=7*$g,Kg=30*$g,Qg=365*$g;function Jg(e){return new Date(e)}function em(e){return e instanceof Date?+e:+new Date(+e)}function tm(e,t,n,r,o,a,c,s,l){var u=Fp(Vp,sr),f=u.invert,h=u.domain,d=l(".%L"),p=l(":%S"),z=l("%I:%M"),v=l("%I %p"),g=l("%a %d"),m=l("%b %d"),y=l("%B"),b=l("%Y"),w=[[c,1,Gg],[c,5,5*Gg],[c,15,15*Gg],[c,30,30*Gg],[a,1,Yg],[a,5,5*Yg],[a,15,15*Yg],[a,30,30*Yg],[o,1,Zg],[o,3,3*Zg],[o,6,6*Zg],[o,12,12*Zg],[r,1,$g],[r,2,2*$g],[n,1,Xg],[t,1,Kg],[t,3,3*Kg],[e,1,Qg]];function k(i){return(c(i)1)&&(e-=Math.floor(e));var t=Math.abs(e-.5);return hm.h=360*e-100,hm.s=1.5-1.5*t,hm.l=.8-.9*t,hm+""};function pm(e){var t=e.length;return function(n){return e[Math.max(0,Math.min(t-1,Math.floor(n*t)))]}}var zm=pm(im("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725")),vm=pm(im("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")),gm=pm(im("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")),mm=pm(im("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921"));function ym(e){var t=0,n=1,r=!1;function i(i){var o=(i-t)/(n-t);return e(r?Math.max(0,Math.min(1,o)):o)}return i.domain=function(e){return arguments.length?(t=+e[0],n=+e[1],i):[t,n]},i.clamp=function(e){return arguments.length?(r=!!e,i):r},i.interpolator=function(t){return arguments.length?(e=t,i):e},i.copy=function(){return ym(e).domain([t,n]).clamp(r)},Up(i)}var bm=function(e){return function(){return e}},wm=Math.abs,km=Math.atan2,xm=Math.cos,jm=Math.max,Mm=Math.min,_m=Math.sin,Cm=Math.sqrt,qm=1e-12,Sm=Math.PI,Tm=Sm/2,Om=2*Sm;function Em(e){return e>=1?Tm:e<=-1?-Tm:Math.asin(e)}function Am(e){return e.innerRadius}function Lm(e){return e.outerRadius}function Hm(e){return e.startAngle}function Dm(e){return e.endAngle}function Pm(e){return e&&e.padAngle}function Vm(e,t,n,r,i,o,a){var c=e-n,s=t-r,l=(a?o:-o)/Cm(c*c+s*s),u=l*s,f=-l*c,h=e+u,d=t+f,p=n+u,z=r+f,v=(h+p)/2,g=(d+z)/2,m=p-h,y=z-d,b=m*m+y*y,w=i-o,k=h*z-p*d,x=(y<0?-1:1)*Cm(jm(0,w*w*b-k*k)),j=(k*y-m*x)/b,M=(-k*m-y*x)/b,_=(k*y+m*x)/b,C=(-k*m+y*x)/b,q=j-v,S=M-g,T=_-v,O=C-g;return q*q+S*S>T*T+O*O&&(j=_,M=C),{cx:j,cy:M,x01:-u,y01:-f,x11:j*(i/w-1),y11:M*(i/w-1)}}var Nm=function(){var e=Am,t=Lm,n=bm(0),r=null,i=Hm,o=Dm,a=Pm,c=null;function s(){var s,l,u,f=+e.apply(this,arguments),h=+t.apply(this,arguments),d=i.apply(this,arguments)-Tm,p=o.apply(this,arguments)-Tm,z=wm(p-d),v=p>d;if(c||(c=s=ja()),hqm)if(z>Om-qm)c.moveTo(h*xm(d),h*_m(d)),c.arc(0,0,h,d,p,!v),f>qm&&(c.moveTo(f*xm(p),f*_m(p)),c.arc(0,0,f,p,d,v));else{var g,m,y=d,b=p,w=d,k=p,x=z,j=z,M=a.apply(this,arguments)/2,_=M>qm&&(r?+r.apply(this,arguments):Cm(f*f+h*h)),C=Mm(wm(h-f)/2,+n.apply(this,arguments)),q=C,S=C;if(_>qm){var T=Em(_/f*_m(M)),O=Em(_/h*_m(M));(x-=2*T)>qm?(w+=T*=v?1:-1,k-=T):(x=0,w=k=(d+p)/2),(j-=2*O)>qm?(y+=O*=v?1:-1,b-=O):(j=0,y=b=(d+p)/2)}var E=h*xm(y),A=h*_m(y),L=f*xm(k),H=f*_m(k);if(C>qm){var D=h*xm(b),P=h*_m(b),V=f*xm(w),N=f*_m(w);if(zqm?function(e,t,n,r,i,o,a,c){var s=n-e,l=r-t,u=a-i,f=c-o,h=(u*(t-o)-f*(e-i))/(f*s-u*l);return[e+h*s,t+h*l]}(E,A,V,N,D,P,L,H):[L,H],R=E-I[0],F=A-I[1],B=D-I[0],U=P-I[1],W=1/_m(((u=(R*B+F*U)/(Cm(R*R+F*F)*Cm(B*B+U*U)))>1?0:u<-1?Sm:Math.acos(u))/2),G=Cm(I[0]*I[0]+I[1]*I[1]);q=Mm(C,(f-G)/(W-1)),S=Mm(C,(h-G)/(W+1))}}j>qm?S>qm?(g=Vm(V,N,E,A,h,S,v),m=Vm(D,P,L,H,h,S,v),c.moveTo(g.cx+g.x01,g.cy+g.y01),Sqm&&x>qm?q>qm?(g=Vm(L,H,D,P,f,-q,v),m=Vm(E,A,V,N,f,-q,v),c.lineTo(g.cx+g.x01,g.cy+g.y01),q=u;--f)c.point(v[f],g[f]);c.lineEnd(),c.areaEnd()}z&&(v[l]=+e(h,l,s),g[l]=+n(h,l,s),c.point(t?+t(h,l,s):v[l],r?+r(h,l,s):g[l]))}if(d)return c=null,d+""||null}function l(){return Um().defined(i).curve(a).context(o)}return s.x=function(n){return arguments.length?(e="function"===typeof n?n:bm(+n),t=null,s):e},s.x0=function(t){return arguments.length?(e="function"===typeof t?t:bm(+t),s):e},s.x1=function(e){return arguments.length?(t=null==e?null:"function"===typeof e?e:bm(+e),s):t},s.y=function(e){return arguments.length?(n="function"===typeof e?e:bm(+e),r=null,s):n},s.y0=function(e){return arguments.length?(n="function"===typeof e?e:bm(+e),s):n},s.y1=function(e){return arguments.length?(r=null==e?null:"function"===typeof e?e:bm(+e),s):r},s.lineX0=s.lineY0=function(){return l().x(e).y(n)},s.lineY1=function(){return l().x(e).y(r)},s.lineX1=function(){return l().x(t).y(n)},s.defined=function(e){return arguments.length?(i="function"===typeof e?e:bm(!!e),s):i},s.curve=function(e){return arguments.length?(a=e,null!=o&&(c=a(o)),s):a},s.context=function(e){return arguments.length?(null==e?o=c=null:c=a(o=e),s):o},s},Gm=function(e,t){return te?1:t>=e?0:NaN},Ym=function(e){return e},Zm=function(){var e=Ym,t=Gm,n=null,r=bm(0),i=bm(Om),o=bm(0);function a(a){var c,s,l,u,f,h=a.length,d=0,p=new Array(h),z=new Array(h),v=+r.apply(this,arguments),g=Math.min(Om,Math.max(-Om,i.apply(this,arguments)-v)),m=Math.min(Math.abs(g)/h,o.apply(this,arguments)),y=m*(g<0?-1:1);for(c=0;c0&&(d+=f);for(null!=t?p.sort((function(e,n){return t(z[e],z[n])})):null!=n&&p.sort((function(e,t){return n(a[e],a[t])})),c=0,l=d?(g-h*y)/d:0;c0?f*l:0)+y,z[s]={data:a[s],index:c,value:f,startAngle:v,endAngle:u,padAngle:m};return z}return a.value=function(t){return arguments.length?(e="function"===typeof t?t:bm(+t),a):e},a.sortValues=function(e){return arguments.length?(t=e,n=null,a):t},a.sort=function(e){return arguments.length?(n=e,t=null,a):n},a.startAngle=function(e){return arguments.length?(r="function"===typeof e?e:bm(+e),a):r},a.endAngle=function(e){return arguments.length?(i="function"===typeof e?e:bm(+e),a):i},a.padAngle=function(e){return arguments.length?(o="function"===typeof e?e:bm(+e),a):o},a},$m=Km(Rm);function Xm(e){this._curve=e}function Km(e){function t(t){return new Xm(e(t))}return t._curve=e,t}function Qm(e){var t=e.curve;return e.angle=e.x,delete e.x,e.radius=e.y,delete e.y,e.curve=function(e){return arguments.length?t(Km(e)):t()._curve},e}Xm.prototype={areaStart:function(){this._curve.areaStart()},areaEnd:function(){this._curve.areaEnd()},lineStart:function(){this._curve.lineStart()},lineEnd:function(){this._curve.lineEnd()},point:function(e,t){this._curve.point(t*Math.sin(e),t*-Math.cos(e))}};var Jm=function(){return Qm(Um().curve($m))},ey=function(){var e=Wm().curve($m),t=e.curve,n=e.lineX0,r=e.lineX1,i=e.lineY0,o=e.lineY1;return e.angle=e.x,delete e.x,e.startAngle=e.x0,delete e.x0,e.endAngle=e.x1,delete e.x1,e.radius=e.y,delete e.y,e.innerRadius=e.y0,delete e.y0,e.outerRadius=e.y1,delete e.y1,e.lineStartAngle=function(){return Qm(n())},delete e.lineX0,e.lineEndAngle=function(){return Qm(r())},delete e.lineX1,e.lineInnerRadius=function(){return Qm(i())},delete e.lineY0,e.lineOuterRadius=function(){return Qm(o())},delete e.lineY1,e.curve=function(e){return arguments.length?t(Km(e)):t()._curve},e},ty=function(e,t){return[(t=+t)*Math.cos(e-=Math.PI/2),t*Math.sin(e)]},ny=Array.prototype.slice;function ry(e){return e.source}function iy(e){return e.target}function oy(e){var t=ry,n=iy,r=Fm,i=Bm,o=null;function a(){var a,c=ny.call(arguments),s=t.apply(this,c),l=n.apply(this,c);if(o||(o=a=ja()),e(o,+r.apply(this,(c[0]=s,c)),+i.apply(this,c),+r.apply(this,(c[0]=l,c)),+i.apply(this,c)),a)return o=null,a+""||null}return a.source=function(e){return arguments.length?(t=e,a):t},a.target=function(e){return arguments.length?(n=e,a):n},a.x=function(e){return arguments.length?(r="function"===typeof e?e:bm(+e),a):r},a.y=function(e){return arguments.length?(i="function"===typeof e?e:bm(+e),a):i},a.context=function(e){return arguments.length?(o=null==e?null:e,a):o},a}function ay(e,t,n,r,i){e.moveTo(t,n),e.bezierCurveTo(t=(t+r)/2,n,t,i,r,i)}function cy(e,t,n,r,i){e.moveTo(t,n),e.bezierCurveTo(t,n=(n+i)/2,r,n,r,i)}function sy(e,t,n,r,i){var o=ty(t,n),a=ty(t,n=(n+i)/2),c=ty(r,n),s=ty(r,i);e.moveTo(o[0],o[1]),e.bezierCurveTo(a[0],a[1],c[0],c[1],s[0],s[1])}function ly(){return oy(ay)}function uy(){return oy(cy)}function fy(){var e=oy(sy);return e.angle=e.x,delete e.x,e.radius=e.y,delete e.y,e}var hy={draw:function(e,t){var n=Math.sqrt(t/Sm);e.moveTo(n,0),e.arc(0,0,n,0,Om)}},dy={draw:function(e,t){var n=Math.sqrt(t/5)/2;e.moveTo(-3*n,-n),e.lineTo(-n,-n),e.lineTo(-n,-3*n),e.lineTo(n,-3*n),e.lineTo(n,-n),e.lineTo(3*n,-n),e.lineTo(3*n,n),e.lineTo(n,n),e.lineTo(n,3*n),e.lineTo(-n,3*n),e.lineTo(-n,n),e.lineTo(-3*n,n),e.closePath()}},py=Math.sqrt(1/3),zy=2*py,vy={draw:function(e,t){var n=Math.sqrt(t/zy),r=n*py;e.moveTo(0,-n),e.lineTo(r,0),e.lineTo(0,n),e.lineTo(-r,0),e.closePath()}},gy=Math.sin(Sm/10)/Math.sin(7*Sm/10),my=Math.sin(Om/10)*gy,yy=-Math.cos(Om/10)*gy,by={draw:function(e,t){var n=Math.sqrt(.8908130915292852*t),r=my*n,i=yy*n;e.moveTo(0,-n),e.lineTo(r,i);for(var o=1;o<5;++o){var a=Om*o/5,c=Math.cos(a),s=Math.sin(a);e.lineTo(s*n,-c*n),e.lineTo(c*r-s*i,s*r+c*i)}e.closePath()}},wy={draw:function(e,t){var n=Math.sqrt(t),r=-n/2;e.rect(r,r,n,n)}},ky=Math.sqrt(3),xy={draw:function(e,t){var n=-Math.sqrt(t/(3*ky));e.moveTo(0,2*n),e.lineTo(-ky*n,-n),e.lineTo(ky*n,-n),e.closePath()}},jy=Math.sqrt(3)/2,My=1/Math.sqrt(12),_y=3*(My/2+1),Cy={draw:function(e,t){var n=Math.sqrt(t/_y),r=n/2,i=n*My,o=r,a=n*My+n,c=-o,s=a;e.moveTo(r,i),e.lineTo(o,a),e.lineTo(c,s),e.lineTo(-.5*r-jy*i,jy*r+-.5*i),e.lineTo(-.5*o-jy*a,jy*o+-.5*a),e.lineTo(-.5*c-jy*s,jy*c+-.5*s),e.lineTo(-.5*r+jy*i,-.5*i-jy*r),e.lineTo(-.5*o+jy*a,-.5*a-jy*o),e.lineTo(-.5*c+jy*s,-.5*s-jy*c),e.closePath()}},qy=[hy,dy,vy,wy,by,xy,Cy],Sy=function(){var e=bm(hy),t=bm(64),n=null;function r(){var r;if(n||(n=r=ja()),e.apply(this,arguments).draw(n,+t.apply(this,arguments)),r)return n=null,r+""||null}return r.type=function(t){return arguments.length?(e="function"===typeof t?t:bm(t),r):e},r.size=function(e){return arguments.length?(t="function"===typeof e?e:bm(+e),r):t},r.context=function(e){return arguments.length?(n=null==e?null:e,r):n},r},Ty=function(){};function Oy(e,t,n){e._context.bezierCurveTo((2*e._x0+e._x1)/3,(2*e._y0+e._y1)/3,(e._x0+2*e._x1)/3,(e._y0+2*e._y1)/3,(e._x0+4*e._x1+t)/6,(e._y0+4*e._y1+n)/6)}function Ey(e){this._context=e}Ey.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:Oy(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);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);default:Oy(this,e,t)}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};var Ay=function(e){return new Ey(e)};function Ly(e){this._context=e}Ly.prototype={areaStart:Ty,areaEnd:Ty,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)}},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._x2=e,this._y2=t;break;case 1:this._point=2,this._x3=e,this._y3=t;break;case 2:this._point=3,this._x4=e,this._y4=t,this._context.moveTo((this._x0+4*this._x1+e)/6,(this._y0+4*this._y1+t)/6);break;default:Oy(this,e,t)}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};var Hy=function(e){return new Ly(e)};function Dy(e){this._context=e}Dy.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(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var n=(this._x0+4*this._x1+e)/6,r=(this._y0+4*this._y1+t)/6;this._line?this._context.lineTo(n,r):this._context.moveTo(n,r);break;case 3:this._point=4;default:Oy(this,e,t)}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};var Py=function(e){return new Dy(e)};function Vy(e,t){this._basis=new Ey(e),this._beta=t}Vy.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var e=this._x,t=this._y,n=e.length-1;if(n>0)for(var r,i=e[0],o=t[0],a=e[n]-i,c=t[n]-o,s=-1;++s<=n;)r=s/n,this._basis.point(this._beta*e[s]+(1-this._beta)*(i+r*a),this._beta*t[s]+(1-this._beta)*(o+r*c));this._x=this._y=null,this._basis.lineEnd()},point:function(e,t){this._x.push(+e),this._y.push(+t)}};var Ny=function e(t){function n(e){return 1===t?new Ey(e):new Vy(e,t)}return n.beta=function(t){return e(+t)},n}(.85);function Iy(e,t,n){e._context.bezierCurveTo(e._x1+e._k*(e._x2-e._x0),e._y1+e._k*(e._y2-e._y0),e._x2+e._k*(e._x1-t),e._y2+e._k*(e._y1-n),e._x2,e._y2)}function Ry(e,t){this._context=e,this._k=(1-t)/6}Ry.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:Iy(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2,this._x1=e,this._y1=t;break;case 2:this._point=3;default:Iy(this,e,t)}this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};var Fy=function e(t){function n(e){return new Ry(e,t)}return n.tension=function(t){return e(+t)},n}(0);function By(e,t){this._context=e,this._k=(1-t)/6}By.prototype={areaStart:Ty,areaEnd:Ty,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)}},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._x3=e,this._y3=t;break;case 1:this._point=2,this._context.moveTo(this._x4=e,this._y4=t);break;case 2:this._point=3,this._x5=e,this._y5=t;break;default:Iy(this,e,t)}this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};var Uy=function e(t){function n(e){return new By(e,t)}return n.tension=function(t){return e(+t)},n}(0);function Wy(e,t){this._context=e,this._k=(1-t)/6}Wy.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(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,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;default:Iy(this,e,t)}this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};var Gy=function e(t){function n(e){return new Wy(e,t)}return n.tension=function(t){return e(+t)},n}(0);function Yy(e,t,n){var r=e._x1,i=e._y1,o=e._x2,a=e._y2;if(e._l01_a>qm){var c=2*e._l01_2a+3*e._l01_a*e._l12_a+e._l12_2a,s=3*e._l01_a*(e._l01_a+e._l12_a);r=(r*c-e._x0*e._l12_2a+e._x2*e._l01_2a)/s,i=(i*c-e._y0*e._l12_2a+e._y2*e._l01_2a)/s}if(e._l23_a>qm){var l=2*e._l23_2a+3*e._l23_a*e._l12_a+e._l12_2a,u=3*e._l23_a*(e._l23_a+e._l12_a);o=(o*l+e._x1*e._l23_2a-t*e._l12_2a)/u,a=(a*l+e._y1*e._l23_2a-n*e._l12_2a)/u}e._context.bezierCurveTo(r,i,o,a,e._x2,e._y2)}function Zy(e,t){this._context=e,this._alpha=t}Zy.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)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){if(e=+e,t=+t,this._point){var n=this._x2-e,r=this._y2-t;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;break;case 2:this._point=3;default:Yy(this,e,t)}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=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};var $y=function e(t){function n(e){return t?new Zy(e,t):new Ry(e,0)}return n.alpha=function(t){return e(+t)},n}(.5);function Xy(e,t){this._context=e,this._alpha=t}Xy.prototype={areaStart:Ty,areaEnd:Ty,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)}},point:function(e,t){if(e=+e,t=+t,this._point){var n=this._x2-e,r=this._y2-t;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=e,this._y3=t;break;case 1:this._point=2,this._context.moveTo(this._x4=e,this._y4=t);break;case 2:this._point=3,this._x5=e,this._y5=t;break;default:Yy(this,e,t)}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=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};var Ky=function e(t){function n(e){return t?new Xy(e,t):new By(e,0)}return n.alpha=function(t){return e(+t)},n}(.5);function Qy(e,t){this._context=e,this._alpha=t}Qy.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(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){if(e=+e,t=+t,this._point){var n=this._x2-e,r=this._y2-t;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,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;default:Yy(this,e,t)}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=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};var Jy=function e(t){function n(e){return t?new Qy(e,t):new Wy(e,0)}return n.alpha=function(t){return e(+t)},n}(.5);function eb(e){this._context=e}eb.prototype={areaStart:Ty,areaEnd:Ty,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(e,t){e=+e,t=+t,this._point?this._context.lineTo(e,t):(this._point=1,this._context.moveTo(e,t))}};var tb=function(e){return new eb(e)};function nb(e){return e<0?-1:1}function rb(e,t,n){var r=e._x1-e._x0,i=t-e._x1,o=(e._y1-e._y0)/(r||i<0&&-0),a=(n-e._y1)/(i||r<0&&-0),c=(o*i+a*r)/(r+i);return(nb(o)+nb(a))*Math.min(Math.abs(o),Math.abs(a),.5*Math.abs(c))||0}function ib(e,t){var n=e._x1-e._x0;return n?(3*(e._y1-e._y0)/n-t)/2:t}function ob(e,t,n){var r=e._x0,i=e._y0,o=e._x1,a=e._y1,c=(o-r)/3;e._context.bezierCurveTo(r+c,i+c*t,o-c,a-c*n,o,a)}function ab(e){this._context=e}function cb(e){this._context=new sb(e)}function sb(e){this._context=e}function lb(e){return new ab(e)}function ub(e){return new cb(e)}function fb(e){this._context=e}function hb(e){var t,n,r=e.length-1,i=new Array(r),o=new Array(r),a=new Array(r);for(i[0]=0,o[0]=2,a[0]=e[0]+2*e[1],t=1;t=0;--t)i[t]=(a[t]-i[t+1])/o[t];for(o[r-1]=(e[r]+i[r-1])/2,t=0;t=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,t),this._context.lineTo(e,t);else{var n=this._x*(1-this._t)+e*this._t;this._context.lineTo(n,this._y),this._context.lineTo(n,t)}}this._x=e,this._y=t}};var zb=function(e){return new pb(e,.5)};function vb(e){return new pb(e,0)}function gb(e){return new pb(e,1)}var mb=function(e,t){if((i=e.length)>1)for(var n,r,i,o=1,a=e[t[0]],c=a.length;o=0;)n[t]=t;return n};function bb(e,t){return e[t]}var wb=function(){var e=bm([]),t=yb,n=mb,r=bb;function i(i){var o,a,c=e.apply(this,arguments),s=i.length,l=c.length,u=new Array(l);for(o=0;o0){for(var n,r,i,o=0,a=e[0].length;o1)for(var n,r,i,o,a,c,s=0,l=e[t[0]].length;s=0?(r[0]=o,r[1]=o+=i):i<0?(r[1]=a,r[0]=a+=i):r[0]=o},jb=function(e,t){if((n=e.length)>0){for(var n,r=0,i=e[t[0]],o=i.length;r0&&(r=(n=e[t[0]]).length)>0){for(var n,r,i,o=0,a=1;a0)){if(o/=h,h<0){if(o0){if(o>f)return;o>u&&(u=o)}if(o=r-s,h||!(o<0)){if(o/=h,h<0){if(o>f)return;o>u&&(u=o)}else if(h>0){if(o0)){if(o/=d,d<0){if(o0){if(o>f)return;o>u&&(u=o)}if(o=i-l,d||!(o<0)){if(o/=d,d<0){if(o>f)return;o>u&&(u=o)}else if(d>0){if(o0||f<1)||(u>0&&(e[0]=[s+u*h,l+u*d]),f<1&&(e[1]=[s+f*h,l+f*d]),!0)}}}}}function Ub(e,t,n,r,i){var o=e[1];if(o)return!0;var a,c,s=e[0],l=e.left,u=e.right,f=l[0],h=l[1],d=u[0],p=u[1],z=(f+d)/2,v=(h+p)/2;if(p===h){if(z=r)return;if(f>d){if(s){if(s[1]>=i)return}else s=[z,n];o=[z,i]}else{if(s){if(s[1]1)if(f>d){if(s){if(s[1]>=i)return}else s=[(n-c)/a,n];o=[(i-c)/a,i]}else{if(s){if(s[1]=r)return}else s=[t,a*t+c];o=[r,a*r+c]}else{if(s){if(s[0]=-hw)){var d=s*s+l*l,p=u*u+f*f,z=(f*d-l*p)/h,v=(s*p-u*d)/h,g=$b.pop()||new Xb;g.arc=e,g.site=i,g.x=z+a,g.y=(g.cy=v+c)+Math.sqrt(z*z+v*v),e.circle=g;for(var m=null,y=lw._;y;)if(g.yfw)c=c.L;else{if(!((i=o-aw(c,a))>fw)){r>-fw?(t=c.P,n=c):i>-fw?(t=c,n=c.N):t=n=c;break}if(!c.R){t=c;break}c=c.R}!function(e){sw[e.index]={site:e,halfedges:[]}}(e);var s=tw(e);if(cw.insert(t,s),t||n){if(t===n)return Qb(t),n=tw(t.site),cw.insert(s,n),s.edge=n.edge=Ib(t.site,s.site),Kb(t),void Kb(n);if(n){Qb(t),Qb(n);var l=t.site,u=l[0],f=l[1],h=e[0]-u,d=e[1]-f,p=n.site,z=p[0]-u,v=p[1]-f,g=2*(h*v-d*z),m=h*h+d*d,y=z*z+v*v,b=[(v*m-d*y)/g+u,(h*y-z*m)/g+f];Fb(n.edge,l,p,b),s.edge=Ib(l,e,null,b),n.edge=Ib(e,p,null,b),Kb(t),Kb(n)}else s.edge=Ib(t.site,s.site)}}function ow(e,t){var n=e.site,r=n[0],i=n[1],o=i-t;if(!o)return r;var a=e.P;if(!a)return-1/0;var c=(n=a.site)[0],s=n[1],l=s-t;if(!l)return c;var u=c-r,f=1/o-1/l,h=u/l;return f?(-h+Math.sqrt(h*h-2*f*(u*u/(-2*l)-s+l/2+i-o/2)))/f+r:(r+c)/2}function aw(e,t){var n=e.N;if(n)return ow(n,t);var r=e.site;return r[1]===t?r[0]:1/0}var cw,sw,lw,uw,fw=1e-6,hw=1e-12;function dw(e,t){return t[1]-e[1]||t[0]-e[0]}function pw(e,t){var n,r,i,o=e.sort(dw).pop();for(uw=[],sw=new Array(e.length),cw=new Nb,lw=new Nb;;)if(i=Zb,o&&(!i||o[1]fw||Math.abs(i[0][1]-i[1][1])>fw)||delete uw[o]}(a,c,s,l),function(e,t,n,r){var i,o,a,c,s,l,u,f,h,d,p,z,v=sw.length,g=!0;for(i=0;ifw||Math.abs(z-h)>fw)&&(s.splice(c,0,uw.push(Rb(a,d,Math.abs(p-e)fw?[e,Math.abs(f-e)fw?[Math.abs(h-r)fw?[n,Math.abs(f-n)fw?[Math.abs(h-t)=c)return null;var s=e-i.site[0],l=t-i.site[1],u=s*s+l*l;do{i=o.cells[r=a],a=null,i.halfedges.forEach((function(n){var r=o.edges[n],c=r.left;if(c!==i.site&&c||(c=r.right)){var s=e-c[0],l=t-c[1],f=s*s+l*l;fr?(r+i)/2:Math.min(0,r)||Math.max(0,i),a>o?(o+a)/2:Math.min(0,o)||Math.max(0,a))}var Sw=function(){var e,t,n=xw,r=jw,i=qw,o=_w,a=Cw,c=[0,1/0],s=[[-1/0,-1/0],[1/0,1/0]],l=250,u=Cr,f=[],h=ze("start","zoom","end"),d=500,p=150,z=0;function v(e){e.property("__zoom",Mw).on("wheel.zoom",x).on("mousedown.zoom",j).on("dblclick.zoom",M).filter(a).on("touchstart.zoom",_).on("touchmove.zoom",C).on("touchend.zoom touchcancel.zoom",q).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function g(e,t){return(t=Math.max(c[0],Math.min(c[1],t)))===e.k?e:new mw(t,e.x,e.y)}function m(e,t,n){var r=t[0]-n[0]*e.k,i=t[1]-n[1]*e.k;return r===e.x&&i===e.y?e:new mw(e.k,r,i)}function y(e){return[(+e[0][0]+ +e[1][0])/2,(+e[0][1]+ +e[1][1])/2]}function b(e,t,n){e.on("start.zoom",(function(){w(this,arguments).start()})).on("interrupt.zoom end.zoom",(function(){w(this,arguments).end()})).tween("zoom",(function(){var e=this,i=arguments,o=w(e,i),a=r.apply(e,i),c=n||y(a),s=Math.max(a[1][0]-a[0][0],a[1][1]-a[0][1]),l=e.__zoom,f="function"===typeof t?t.apply(e,i):t,h=u(l.invert(c).concat(s/l.k),f.invert(c).concat(s/f.k));return function(e){if(1===e)e=f;else{var t=h(e),n=s/t[2];e=new mw(n,c[0]-t[0]*n,c[1]-t[1]*n)}o.zoom(null,e)}}))}function w(e,t){for(var n,r=0,i=f.length;rz}e.zoom("mouse",i(m(e.that.__zoom,e.mouse[0]=Ne(e.that),e.mouse[1]),e.extent,s))}),!0).on("mouseup.zoom",(function(){r.on("mousemove.zoom mouseup.zoom",null),Ft(Te.view,e.moved),kw(),e.end()}),!0),o=Ne(this),a=Te.clientX,c=Te.clientY;Rt(Te.view),ww(),e.mouse=[o,this.__zoom.invert(o)],yi(this),e.start()}}function M(){if(n.apply(this,arguments)){var e=this.__zoom,t=Ne(this),o=e.invert(t),a=e.k*(Te.shiftKey?.5:2),c=i(m(g(e,a),t,o),r.apply(this,arguments),s);kw(),l>0?Ht(this).transition().duration(l).call(b,c,t):Ht(this).call(v.transform,c)}}function _(){if(n.apply(this,arguments)){var t,r,i,o,a=w(this,arguments),c=Te.changedTouches,s=c.length;for(ww(),r=0;r=0}n.d(t,"a",(function(){return i}))},function(e,t,n){"use strict";var r=n(30);function i(e){return e}var o=Object(r.a)(i);t.a=o},,function(e,t,n){"use strict";var r;Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var i=(0,((r=n(223))&&r.__esModule?r:{default:r}).default)("Batch",(function(){for(var e=arguments.length,t=new Array(e),n=0;n=0&&n.splice(r,1),e.className=n.join(" ")}(e,t)},t.list=function(e){return e.classList?Array.prototype.slice.apply(e.classList):e.className.split(" ")}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var i=r(n(204)),o=r(n(246)),a=function(){i.default.call(this)};(a.prototype=new i.default).extractSeries=function(e,t,n){},a.prototype.rollingAverage=function(e,t,n){},a.prototype.onPointsCreated_=function(e,t){for(var n=0;nr&&(s=r),lo)&&(o=l),(null===i||s0&&t-1 in e)}x.fn=x.prototype={jquery:"3.6.0",constructor:x,length:0,toArray:function(){return c.call(this)},get:function(e){return null==e?c.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return x.each(this,e)},map:function(e){return this.pushStack(x.map(this,(function(t,n){return e.call(t,n,t)})))},slice:function(){return this.pushStack(c.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(x.grep(this,(function(e,t){return(t+1)%2})))},odd:function(){return this.pushStack(x.grep(this,(function(e,t){return t%2})))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n+~]|"+P+")"+P+"*"),W=new RegExp(P+"|>"),G=new RegExp(I),Y=new RegExp("^"+V+"$"),Z={ID:new RegExp("^#("+V+")"),CLASS:new RegExp("^\\.("+V+")"),TAG:new RegExp("^("+V+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+I),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+P+"*(even|odd|(([+-]|)(\\d*)n|)"+P+"*(?:([+-]|)"+P+"*(\\d+)|))"+P+"*\\)|)","i"),bool:new RegExp("^(?:"+D+")$","i"),needsContext:new RegExp("^"+P+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+P+"*((?:-\\d)?\\d*)"+P+"*\\)|)(?=[^-]|$)","i")},$=/HTML$/i,X=/^(?:input|select|textarea|button)$/i,K=/^h\d$/i,Q=/^[^{]+\{\s*\[native \w/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+P+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){h()},ae=be((function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()}),{dir:"parentNode",next:"legend"});try{A.apply(T=L.call(w.childNodes),w.childNodes),T[w.childNodes.length].nodeType}catch(Me){A={apply:T.length?function(e,t){E.apply(e,L.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}function ce(e,t,r,i){var o,c,l,u,f,p,g,m=t&&t.ownerDocument,w=t?t.nodeType:9;if(r=r||[],"string"!==typeof e||!e||1!==w&&9!==w&&11!==w)return r;if(!i&&(h(t),t=t||d,z)){if(11!==w&&(f=J.exec(e)))if(o=f[1]){if(9===w){if(!(l=t.getElementById(o)))return r;if(l.id===o)return r.push(l),r}else if(m&&(l=m.getElementById(o))&&y(t,l)&&l.id===o)return r.push(l),r}else{if(f[2])return A.apply(r,t.getElementsByTagName(e)),r;if((o=f[3])&&n.getElementsByClassName&&t.getElementsByClassName)return A.apply(r,t.getElementsByClassName(o)),r}if(n.qsa&&!C[e+" "]&&(!v||!v.test(e))&&(1!==w||"object"!==t.nodeName.toLowerCase())){if(g=e,m=t,1===w&&(W.test(e)||U.test(e))){for((m=ee.test(e)&&ge(t.parentNode)||t)===t&&n.scope||((u=t.getAttribute("id"))?u=u.replace(re,ie):t.setAttribute("id",u=b)),c=(p=a(e)).length;c--;)p[c]=(u?"#"+u:":scope")+" "+ye(p[c]);g=p.join(",")}try{return A.apply(r,m.querySelectorAll(g)),r}catch(k){C(e,!0)}finally{u===b&&t.removeAttribute("id")}}}return s(e.replace(F,"$1"),t,r,i)}function se(){var e=[];return function t(n,i){return e.push(n+" ")>r.cacheLength&&delete t[e.shift()],t[n+" "]=i}}function le(e){return e[b]=!0,e}function ue(e){var t=d.createElement("fieldset");try{return!!e(t)}catch(Me){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){for(var n=e.split("|"),i=n.length;i--;)r.attrHandle[n[i]]=t}function he(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function de(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function pe(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function ze(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ae(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function ve(e){return le((function(t){return t=+t,le((function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))}))}))}function ge(e){return e&&"undefined"!==typeof e.getElementsByTagName&&e}for(t in n=ce.support={},o=ce.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!$.test(t||n&&n.nodeName||"HTML")},h=ce.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:w;return a!=d&&9===a.nodeType&&a.documentElement?(p=(d=a).documentElement,z=!o(d),w!=d&&(i=d.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",oe,!1):i.attachEvent&&i.attachEvent("onunload",oe)),n.scope=ue((function(e){return p.appendChild(e).appendChild(d.createElement("div")),"undefined"!==typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length})),n.attributes=ue((function(e){return e.className="i",!e.getAttribute("className")})),n.getElementsByTagName=ue((function(e){return e.appendChild(d.createComment("")),!e.getElementsByTagName("*").length})),n.getElementsByClassName=Q.test(d.getElementsByClassName),n.getById=ue((function(e){return p.appendChild(e).id=b,!d.getElementsByName||!d.getElementsByName(b).length})),n.getById?(r.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},r.find.ID=function(e,t){if("undefined"!==typeof t.getElementById&&z){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter.ID=function(e){var t=e.replace(te,ne);return function(e){var n="undefined"!==typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},r.find.ID=function(e,t){if("undefined"!==typeof t.getElementById&&z){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];for(i=t.getElementsByName(e),r=0;o=i[r++];)if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),r.find.TAG=n.getElementsByTagName?function(e,t){return"undefined"!==typeof t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=n.getElementsByClassName&&function(e,t){if("undefined"!==typeof t.getElementsByClassName&&z)return t.getElementsByClassName(e)},g=[],v=[],(n.qsa=Q.test(d.querySelectorAll))&&(ue((function(e){var t;p.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+P+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+P+"*(?:value|"+D+")"),e.querySelectorAll("[id~="+b+"-]").length||v.push("~="),(t=d.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+P+"*name"+P+"*="+P+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+b+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")})),ue((function(e){e.innerHTML="";var t=d.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+P+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),p.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")}))),(n.matchesSelector=Q.test(m=p.matches||p.webkitMatchesSelector||p.mozMatchesSelector||p.oMatchesSelector||p.msMatchesSelector))&&ue((function(e){n.disconnectedMatch=m.call(e,"*"),m.call(e,"[s!='']:x"),g.push("!=",I)})),v=v.length&&new RegExp(v.join("|")),g=g.length&&new RegExp(g.join("|")),t=Q.test(p.compareDocumentPosition),y=t||Q.test(p.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},q=t?function(e,t){if(e===t)return f=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===r?e==d||e.ownerDocument==w&&y(w,e)?-1:t==d||t.ownerDocument==w&&y(w,t)?1:u?H(u,e)-H(u,t):0:4&r?-1:1)}:function(e,t){if(e===t)return f=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],c=[t];if(!i||!o)return e==d?-1:t==d?1:i?-1:o?1:u?H(u,e)-H(u,t):0;if(i===o)return he(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)c.unshift(n);for(;a[r]===c[r];)r++;return r?he(a[r],c[r]):a[r]==w?-1:c[r]==w?1:0},d):d},ce.matches=function(e,t){return ce(e,null,null,t)},ce.matchesSelector=function(e,t){if(h(e),n.matchesSelector&&z&&!C[t+" "]&&(!g||!g.test(t))&&(!v||!v.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(Me){C(t,!0)}return ce(t,d,null,[e]).length>0},ce.contains=function(e,t){return(e.ownerDocument||e)!=d&&h(e),y(e,t)},ce.attr=function(e,t){(e.ownerDocument||e)!=d&&h(e);var i=r.attrHandle[t.toLowerCase()],o=i&&S.call(r.attrHandle,t.toLowerCase())?i(e,t,!z):void 0;return void 0!==o?o:n.attributes||!z?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null},ce.escape=function(e){return(e+"").replace(re,ie)},ce.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},ce.uniqueSort=function(e){var t,r=[],i=0,o=0;if(f=!n.detectDuplicates,u=!n.sortStable&&e.slice(0),e.sort(q),f){for(;t=e[o++];)t===e[o]&&(i=r.push(o));for(;i--;)e.splice(r[i],1)}return u=null,e},i=ce.getText=function(e){var t,n="",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"===typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=i(e)}else if(3===o||4===o)return e.nodeValue}else for(;t=e[r++];)n+=i(t);return n},(r=ce.selectors={cacheLength:50,createPseudo:le,match:Z,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||ce.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&ce.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Z.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&G.test(n)&&(t=a(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=j[e+" "];return t||(t=new RegExp("(^|"+P+")"+e+"("+P+"|$)"))&&j(e,(function(e){return t.test("string"===typeof e.className&&e.className||"undefined"!==typeof e.getAttribute&&e.getAttribute("class")||"")}))},ATTR:function(e,t,n){return function(r){var i=ce.attr(r,e);return null==i?"!="===t:!t||(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i.replace(R," ")+" ").indexOf(n)>-1:"|="===t&&(i===n||i.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),c="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,s){var l,u,f,h,d,p,z=o!==a?"nextSibling":"previousSibling",v=t.parentNode,g=c&&t.nodeName.toLowerCase(),m=!s&&!c,y=!1;if(v){if(o){for(;z;){for(h=t;h=h[z];)if(c?h.nodeName.toLowerCase()===g:1===h.nodeType)return!1;p=z="only"===e&&!p&&"nextSibling"}return!0}if(p=[a?v.firstChild:v.lastChild],a&&m){for(y=(d=(l=(u=(f=(h=v)[b]||(h[b]={}))[h.uniqueID]||(f[h.uniqueID]={}))[e]||[])[0]===k&&l[1])&&l[2],h=d&&v.childNodes[d];h=++d&&h&&h[z]||(y=d=0)||p.pop();)if(1===h.nodeType&&++y&&h===t){u[e]=[k,d,y];break}}else if(m&&(y=d=(l=(u=(f=(h=t)[b]||(h[b]={}))[h.uniqueID]||(f[h.uniqueID]={}))[e]||[])[0]===k&&l[1]),!1===y)for(;(h=++d&&h&&h[z]||(y=d=0)||p.pop())&&((c?h.nodeName.toLowerCase()!==g:1!==h.nodeType)||!++y||(m&&((u=(f=h[b]||(h[b]={}))[h.uniqueID]||(f[h.uniqueID]={}))[e]=[k,y]),h!==t)););return(y-=i)===r||y%r===0&&y/r>=0}}},PSEUDO:function(e,t){var n,i=r.pseudos[e]||r.setFilters[e.toLowerCase()]||ce.error("unsupported pseudo: "+e);return i[b]?i(t):i.length>1?(n=[e,e,"",t],r.setFilters.hasOwnProperty(e.toLowerCase())?le((function(e,n){for(var r,o=i(e,t),a=o.length;a--;)e[r=H(e,o[a])]=!(n[r]=o[a])})):function(e){return i(e,0,n)}):i}},pseudos:{not:le((function(e){var t=[],n=[],r=c(e.replace(F,"$1"));return r[b]?le((function(e,t,n,i){for(var o,a=r(e,null,i,[]),c=e.length;c--;)(o=a[c])&&(e[c]=!(t[c]=o))})):function(e,i,o){return t[0]=e,r(t,null,o,n),t[0]=null,!n.pop()}})),has:le((function(e){return function(t){return ce(e,t).length>0}})),contains:le((function(e){return e=e.replace(te,ne),function(t){return(t.textContent||i(t)).indexOf(e)>-1}})),lang:le((function(e){return Y.test(e||"")||ce.error("unsupported lang: "+e),e=e.replace(te,ne).toLowerCase(),function(t){var n;do{if(n=z?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}})),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===p},focus:function(e){return e===d.activeElement&&(!d.hasFocus||d.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ze(!1),disabled:ze(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!r.pseudos.empty(e)},header:function(e){return K.test(e.nodeName)},input:function(e){return X.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ve((function(){return[0]})),last:ve((function(e,t){return[t-1]})),eq:ve((function(e,t,n){return[n<0?n+t:n]})),even:ve((function(e,t){for(var n=0;nt?t:n;--r>=0;)e.push(r);return e})),gt:ve((function(e,t,n){for(var r=n<0?n+t:n;++r1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function ke(e,t,n,r,i){for(var o,a=[],c=0,s=e.length,l=null!=t;c-1&&(o[l]=!(a[l]=f))}}else g=ke(g===a?g.splice(p,g.length):g),i?i(null,a,g,s):A.apply(a,g)}))}function je(e){for(var t,n,i,o=e.length,a=r.relative[e[0].type],c=a||r.relative[" "],s=a?1:0,u=be((function(e){return e===t}),c,!0),f=be((function(e){return H(t,e)>-1}),c,!0),h=[function(e,n,r){var i=!a&&(r||n!==l)||((t=n).nodeType?u(e,n,r):f(e,n,r));return t=null,i}];s1&&we(h),s>1&&ye(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace(F,"$1"),n,s0,i=e.length>0,o=function(o,a,c,s,u){var f,p,v,g=0,m="0",y=o&&[],b=[],w=l,x=o||i&&r.find.TAG("*",u),j=k+=null==w?1:Math.random()||.1,M=x.length;for(u&&(l=a==d||a||u);m!==M&&null!=(f=x[m]);m++){if(i&&f){for(p=0,a||f.ownerDocument==d||(h(f),c=!z);v=e[p++];)if(v(f,a||d,c)){s.push(f);break}u&&(k=j)}n&&((f=!v&&f)&&g--,o&&y.push(f))}if(g+=m,n&&m!==g){for(p=0;v=t[p++];)v(y,b,a,c);if(o){if(g>0)for(;m--;)y[m]||b[m]||(b[m]=O.call(s));b=ke(b)}A.apply(s,b),u&&!o&&b.length>0&&g+t.length>1&&ce.uniqueSort(s)}return u&&(k=j,l=w),y};return n?le(o):o}(o,i))).selector=e}return c},s=ce.select=function(e,t,n,i){var o,s,l,u,f,h="function"===typeof e&&e,d=!i&&a(e=h.selector||e);if(n=n||[],1===d.length){if((s=d[0]=d[0].slice(0)).length>2&&"ID"===(l=s[0]).type&&9===t.nodeType&&z&&r.relative[s[1].type]){if(!(t=(r.find.ID(l.matches[0].replace(te,ne),t)||[])[0]))return n;h&&(t=t.parentNode),e=e.slice(s.shift().value.length)}for(o=Z.needsContext.test(e)?0:s.length;o--&&(l=s[o],!r.relative[u=l.type]);)if((f=r.find[u])&&(i=f(l.matches[0].replace(te,ne),ee.test(s[0].type)&&ge(t.parentNode)||t))){if(s.splice(o,1),!(e=i.length&&ye(s)))return A.apply(n,i),n;break}}return(h||c(e,d))(i,t,!z,n,!t||ee.test(e)&&ge(t.parentNode)||t),n},n.sortStable=b.split("").sort(q).join("")===b,n.detectDuplicates=!!f,h(),n.sortDetached=ue((function(e){return 1&e.compareDocumentPosition(d.createElement("fieldset"))})),ue((function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")}))||fe("type|href|height|width",(function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)})),n.attributes&&ue((function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")}))||fe("value",(function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue})),ue((function(e){return null==e.getAttribute("disabled")}))||fe(D,(function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null})),ce}(n);x.find=M,x.expr=M.selectors,x.expr[":"]=x.expr.pseudos,x.uniqueSort=x.unique=M.uniqueSort,x.text=M.getText,x.isXMLDoc=M.isXML,x.contains=M.contains,x.escapeSelector=M.escape;var _=function(e,t,n){for(var r=[],i=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&x(e).is(n))break;r.push(e)}return r},C=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},q=x.expr.match.needsContext;function S(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var T=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function O(e,t,n){return g(t)?x.grep(e,(function(e,r){return!!t.call(e,r,e)!==n})):t.nodeType?x.grep(e,(function(e){return e===t!==n})):"string"!==typeof t?x.grep(e,(function(e){return u.call(t,e)>-1!==n})):x.filter(t,e,n)}x.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,(function(e){return 1===e.nodeType})))},x.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!==typeof e)return this.pushStack(x(e).filter((function(){for(t=0;t1?x.uniqueSort(n):n},filter:function(e){return this.pushStack(O(this,e||[],!1))},not:function(e){return this.pushStack(O(this,e||[],!0))},is:function(e){return!!O(this,"string"===typeof e&&q.test(e)?x(e):e||[],!1).length}});var E,A=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(x.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||E,"string"===typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:A.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof x?t[0]:t,x.merge(this,x.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:y,!0)),T.test(r[1])&&x.isPlainObject(t))for(r in t)g(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=y.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):g(e)?void 0!==n.ready?n.ready(e):e(x):x.makeArray(e,this)}).prototype=x.fn,E=x(y);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function D(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}x.fn.extend({has:function(e){var t=x(e,this),n=t.length;return this.filter((function(){for(var e=0;e-1:1===n.nodeType&&x.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?x.uniqueSort(o):o)},index:function(e){return e?"string"===typeof e?u.call(x(e),this[0]):u.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(x.uniqueSort(x.merge(this.get(),x(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return _(e,"parentNode")},parentsUntil:function(e,t,n){return _(e,"parentNode",n)},next:function(e){return D(e,"nextSibling")},prev:function(e){return D(e,"previousSibling")},nextAll:function(e){return _(e,"nextSibling")},prevAll:function(e){return _(e,"previousSibling")},nextUntil:function(e,t,n){return _(e,"nextSibling",n)},prevUntil:function(e,t,n){return _(e,"previousSibling",n)},siblings:function(e){return C((e.parentNode||{}).firstChild,e)},children:function(e){return C(e.firstChild)},contents:function(e){return null!=e.contentDocument&&a(e.contentDocument)?e.contentDocument:(S(e,"template")&&(e=e.content||e),x.merge([],e.childNodes))}},(function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"===typeof r&&(i=x.filter(r,i)),this.length>1&&(H[e]||x.uniqueSort(i),L.test(e)&&i.reverse()),this.pushStack(i)}}));var P=/[^\x20\t\r\n\f]+/g;function V(e){return e}function N(e){throw e}function I(e,t,n,r){var i;try{e&&g(i=e.promise)?i.call(e).done(t).fail(n):e&&g(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}x.Callbacks=function(e){e="string"===typeof e?function(e){var t={};return x.each(e.match(P)||[],(function(e,n){t[n]=!0})),t}(e):x.extend({},e);var t,n,r,i,o=[],a=[],c=-1,s=function(){for(i=i||e.once,r=t=!0;a.length;c=-1)for(n=a.shift();++c-1;)o.splice(n,1),n<=c&&c--})),this},has:function(e){return e?x.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=n="",this},disabled:function(){return!o},lock:function(){return i=a=[],n||t||(o=n=""),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=[e,(n=n||[]).slice?n.slice():n],a.push(n),t||s()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l},x.extend({Deferred:function(e){var t=[["notify","progress",x.Callbacks("memory"),x.Callbacks("memory"),2],["resolve","done",x.Callbacks("once memory"),x.Callbacks("once memory"),0,"resolved"],["reject","fail",x.Callbacks("once memory"),x.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},catch:function(e){return i.then(null,e)},pipe:function(){var e=arguments;return x.Deferred((function(n){x.each(t,(function(t,r){var i=g(e[r[4]])&&e[r[4]];o[r[1]]((function(){var e=i&&i.apply(this,arguments);e&&g(e.promise)?e.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[r[0]+"With"](this,i?[e]:arguments)}))})),e=null})).promise()},then:function(e,r,i){var o=0;function a(e,t,r,i){return function(){var c=this,s=arguments,l=function(){var n,l;if(!(e=o&&(r!==N&&(c=void 0,s=[n]),t.rejectWith(c,s))}};e?u():(x.Deferred.getStackHook&&(u.stackTrace=x.Deferred.getStackHook()),n.setTimeout(u))}}return x.Deferred((function(n){t[0][3].add(a(0,n,g(i)?i:V,n.notifyWith)),t[1][3].add(a(0,n,g(e)?e:V)),t[2][3].add(a(0,n,g(r)?r:N))})).promise()},promise:function(e){return null!=e?x.extend(e,i):i}},o={};return x.each(t,(function(e,n){var a=n[2],c=n[5];i[n[1]]=a.add,c&&a.add((function(){r=c}),t[3-e][2].disable,t[3-e][3].disable,t[0][2].lock,t[0][3].lock),a.add(n[3].fire),o[n[0]]=function(){return o[n[0]+"With"](this===o?void 0:this,arguments),this},o[n[0]+"With"]=a.fireWith})),i.promise(o),e&&e.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),i=c.call(arguments),o=x.Deferred(),a=function(e){return function(n){r[e]=this,i[e]=arguments.length>1?c.call(arguments):n,--t||o.resolveWith(r,i)}};if(t<=1&&(I(e,o.done(a(n)).resolve,o.reject,!t),"pending"===o.state()||g(i[n]&&i[n].then)))return o.then();for(;n--;)I(i[n],a(n),o.reject);return o.promise()}});var R=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;x.Deferred.exceptionHook=function(e,t){n.console&&n.console.warn&&e&&R.test(e.name)&&n.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},x.readyException=function(e){n.setTimeout((function(){throw e}))};var F=x.Deferred();function B(){y.removeEventListener("DOMContentLoaded",B),n.removeEventListener("load",B),x.ready()}x.fn.ready=function(e){return F.then(e).catch((function(e){x.readyException(e)})),this},x.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--x.readyWait:x.isReady)||(x.isReady=!0,!0!==e&&--x.readyWait>0||F.resolveWith(y,[x]))}}),x.ready.then=F.then,"complete"===y.readyState||"loading"!==y.readyState&&!y.documentElement.doScroll?n.setTimeout(x.ready):(y.addEventListener("DOMContentLoaded",B),n.addEventListener("load",B));var U=function e(t,n,r,i,o,a,c){var s=0,l=t.length,u=null==r;if("object"===k(r))for(s in o=!0,r)e(t,n,s,r[s],!0,a,c);else if(void 0!==i&&(o=!0,g(i)||(c=!0),u&&(c?(n.call(t,i),n=null):(u=n,n=function(e,t,n){return u.call(x(e),n)})),n))for(;s1,null,!0)},removeData:function(e){return this.each((function(){Q.remove(this,e)}))}}),x.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=K.get(e,t),n&&(!r||Array.isArray(n)?r=K.access(e,t,x.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,(function(){x.dequeue(e,t)}),o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return K.get(e,n)||K.access(e,n,{empty:x.Callbacks("once memory").add((function(){K.remove(e,[t+"queue",n])}))})}}),x.fn.extend({queue:function(e,t){var n=2;return"string"!==typeof e&&(t=e,e="fx",n--),arguments.length\x20\t\r\n\f]*)/i,ze=/^$|^module$|\/(?:java|ecma)script/i;!function(){var e=y.createDocumentFragment().appendChild(y.createElement("div")),t=y.createElement("input");t.setAttribute("type","radio"),t.setAttribute("checked","checked"),t.setAttribute("name","t"),e.appendChild(t),v.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,e.innerHTML="",v.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue,e.innerHTML="",v.option=!!e.lastChild}();var ve={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ge(e,t){var n;return n="undefined"!==typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!==typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&S(e,t)?x.merge([e],n):n}function me(e,t){for(var n=0,r=e.length;n",""]);var ye=/<|&#?\w+;/;function be(e,t,n,r,i){for(var o,a,c,s,l,u,f=t.createDocumentFragment(),h=[],d=0,p=e.length;d-1)i&&i.push(o);else if(l=ae(o),a=ge(f.appendChild(o),"script"),l&&me(a),n)for(u=0;o=a[u++];)ze.test(o.type||"")&&n.push(o);return f}var we=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function xe(){return!1}function je(e,t){return e===function(){try{return y.activeElement}catch(e){}}()===("focus"===t)}function Me(e,t,n,r,i,o){var a,c;if("object"===typeof t){for(c in"string"!==typeof n&&(r=r||n,n=void 0),t)Me(e,c,n,r,t[c],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"===typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=xe;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return x().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=x.guid++)),e.each((function(){x.event.add(this,t,i,r,n)}))}function _e(e,t,n){n?(K.set(e,t,!1),x.event.add(e,t,{namespace:!1,handler:function(e){var r,i,o=K.get(this,t);if(1&e.isTrigger&&this[t]){if(o.length)(x.event.special[t]||{}).delegateType&&e.stopPropagation();else if(o=c.call(arguments),K.set(this,t,o),r=n(this,t),this[t](),o!==(i=K.get(this,t))||r?K.set(this,t,!1):i={},o!==i)return e.stopImmediatePropagation(),e.preventDefault(),i&&i.value}else o.length&&(K.set(this,t,{value:x.event.trigger(x.extend(o[0],x.Event.prototype),o.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===K.get(e,t)&&x.event.add(e,t,ke)}x.event={global:{},add:function(e,t,n,r,i){var o,a,c,s,l,u,f,h,d,p,z,v=K.get(e);if($(e))for(n.handler&&(n=(o=n).handler,i=o.selector),i&&x.find.matchesSelector(oe,i),n.guid||(n.guid=x.guid++),(s=v.events)||(s=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(t){return"undefined"!==typeof x&&x.event.triggered!==t.type?x.event.dispatch.apply(e,arguments):void 0}),l=(t=(t||"").match(P)||[""]).length;l--;)d=z=(c=we.exec(t[l])||[])[1],p=(c[2]||"").split(".").sort(),d&&(f=x.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=x.event.special[d]||{},u=x.extend({type:d,origType:z,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&x.expr.match.needsContext.test(i),namespace:p.join(".")},o),(h=s[d])||((h=s[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(e,r,p,a)||e.addEventListener&&e.addEventListener(d,a)),f.add&&(f.add.call(e,u),u.handler.guid||(u.handler.guid=n.guid)),i?h.splice(h.delegateCount++,0,u):h.push(u),x.event.global[d]=!0)},remove:function(e,t,n,r,i){var o,a,c,s,l,u,f,h,d,p,z,v=K.hasData(e)&&K.get(e);if(v&&(s=v.events)){for(l=(t=(t||"").match(P)||[""]).length;l--;)if(d=z=(c=we.exec(t[l])||[])[1],p=(c[2]||"").split(".").sort(),d){for(f=x.event.special[d]||{},h=s[d=(r?f.delegateType:f.bindType)||d]||[],c=c[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=h.length;o--;)u=h[o],!i&&z!==u.origType||n&&n.guid!==u.guid||c&&!c.test(u.namespace)||r&&r!==u.selector&&("**"!==r||!u.selector)||(h.splice(o,1),u.selector&&h.delegateCount--,f.remove&&f.remove.call(e,u));a&&!h.length&&(f.teardown&&!1!==f.teardown.call(e,p,v.handle)||x.removeEvent(e,d,v.handle),delete s[d])}else for(d in s)x.event.remove(e,d+t[l],n,r,!0);x.isEmptyObject(s)&&K.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,c=new Array(arguments.length),s=x.event.fix(e),l=(K.get(this,"events")||Object.create(null))[s.type]||[],u=x.event.special[s.type]||{};for(c[0]=s,t=1;t=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n-1:x.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&c.push({elem:l,handlers:o})}return l=this,s\s*$/g;function Te(e,t){return S(e,"table")&&S(11!==t.nodeType?t:t.firstChild,"tr")&&x(e).children("tbody")[0]||e}function Oe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Ee(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Ae(e,t){var n,r,i,o,a,c;if(1===t.nodeType){if(K.hasData(e)&&(c=K.get(e).events))for(i in K.remove(t,"handle events"),c)for(n=0,r=c[i].length;n1&&"string"===typeof p&&!v.checkClone&&qe.test(p))return e.each((function(i){var o=e.eq(i);z&&(t[0]=p.call(this,i,o.html())),He(o,t,n,r)}));if(h&&(o=(i=be(t,e[0].ownerDocument,!1,e,r)).firstChild,1===i.childNodes.length&&(i=o),o||r)){for(c=(a=x.map(ge(i,"script"),Oe)).length;f0&&me(a,!s&&ge(e,"script")),c},cleanData:function(e){for(var t,n,r,i=x.event.special,o=0;void 0!==(n=e[o]);o++)if($(n)){if(t=n[K.expando]){if(t.events)for(r in t.events)i[r]?x.event.remove(n,r):x.removeEvent(n,r,t.handle);n[K.expando]=void 0}n[Q.expando]&&(n[Q.expando]=void 0)}}}),x.fn.extend({detach:function(e){return De(this,e,!0)},remove:function(e){return De(this,e)},text:function(e){return U(this,(function(e){return void 0===e?x.text(this):this.empty().each((function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)}))}),null,e,arguments.length)},append:function(){return He(this,arguments,(function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Te(this,e).appendChild(e)}))},prepend:function(){return He(this,arguments,(function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Te(this,e);t.insertBefore(e,t.firstChild)}}))},before:function(){return He(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this)}))},after:function(){return He(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)}))},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(x.cleanData(ge(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map((function(){return x.clone(this,e,t)}))},html:function(e){return U(this,(function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"===typeof e&&!Ce.test(e)&&!ve[(pe.exec(e)||["",""])[1].toLowerCase()]){e=x.htmlPrefilter(e);try{for(;n=0&&(s+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-s-c-.5))||0),s}function Je(e,t,n){var r=Ve(e),i=(!v.boxSizingReliable()||n)&&"border-box"===x.css(e,"boxSizing",!1,r),o=i,a=Re(e,t,r),c="offset"+t[0].toUpperCase()+t.slice(1);if(Pe.test(a)){if(!n)return a;a="auto"}return(!v.boxSizingReliable()&&i||!v.reliableTrDimensions()&&S(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===x.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===x.css(e,"boxSizing",!1,r),(o=c in e)&&(a=e[c])),(a=parseFloat(a)||0)+Qe(e,t,n||(i?"border":"content"),o,r,a)+"px"}function et(e,t,n,r,i){return new et.prototype.init(e,t,n,r,i)}x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Re(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,c=Z(t),s=Ze.test(t),l=e.style;if(s||(t=Ge(c)),a=x.cssHooks[t]||x.cssHooks[c],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=re.exec(n))&&i[1]&&(n=le(e,t,i),o="number"),null!=n&&n===n&&("number"!==o||s||(n+=i&&i[3]||(x.cssNumber[c]?"":"px")),v.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(s?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,c=Z(t);return Ze.test(t)||(t=Ge(c)),(a=x.cssHooks[t]||x.cssHooks[c])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Re(e,t,r)),"normal"===i&&t in Xe&&(i=Xe[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),x.each(["height","width"],(function(e,t){x.cssHooks[t]={get:function(e,n,r){if(n)return!Ye.test(x.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?Je(e,t,r):Ne(e,$e,(function(){return Je(e,t,r)}))},set:function(e,n,r){var i,o=Ve(e),a=!v.scrollboxSize()&&"absolute"===o.position,c=(a||r)&&"border-box"===x.css(e,"boxSizing",!1,o),s=r?Qe(e,t,r,c,o):0;return c&&a&&(s-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-Qe(e,t,"border",!1,o)-.5)),s&&(i=re.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=x.css(e,t)),Ke(0,n,s)}}})),x.cssHooks.marginLeft=Fe(v.reliableMarginLeft,(function(e,t){if(t)return(parseFloat(Re(e,"marginLeft"))||e.getBoundingClientRect().left-Ne(e,{marginLeft:0},(function(){return e.getBoundingClientRect().left})))+"px"})),x.each({margin:"",padding:"",border:"Width"},(function(e,t){x.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"===typeof n?n.split(" "):[n];r<4;r++)i[e+ie[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(x.cssHooks[e+t].set=Ke)})),x.fn.extend({css:function(e,t){return U(this,(function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Ve(e),i=t.length;a1)}}),x.Tween=et,et.prototype={constructor:et,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||x.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(x.cssNumber[n]?"":"px")},cur:function(){var e=et.propHooks[this.prop];return e&&e.get?e.get(this):et.propHooks._default.get(this)},run:function(e){var t,n=et.propHooks[this.prop];return this.options.duration?this.pos=t=x.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):et.propHooks._default.set(this),this}},et.prototype.init.prototype=et.prototype,et.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=x.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){x.fx.step[e.prop]?x.fx.step[e.prop](e):1!==e.elem.nodeType||!x.cssHooks[e.prop]&&null==e.elem.style[Ge(e.prop)]?e.elem[e.prop]=e.now:x.style(e.elem,e.prop,e.now+e.unit)}}},et.propHooks.scrollTop=et.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},x.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},x.fx=et.prototype.init,x.fx.step={};var tt,nt,rt=/^(?:toggle|show|hide)$/,it=/queueHooks$/;function ot(){nt&&(!1===y.hidden&&n.requestAnimationFrame?n.requestAnimationFrame(ot):n.setTimeout(ot,x.fx.interval),x.fx.tick())}function at(){return n.setTimeout((function(){tt=void 0})),tt=Date.now()}function ct(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=ie[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function st(e,t,n){for(var r,i=(lt.tweeners[t]||[]).concat(lt.tweeners["*"]),o=0,a=i.length;o1)},removeAttr:function(e){return this.each((function(){x.removeAttr(this,e)}))}}),x.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"===typeof e.getAttribute?x.prop(e,t,n):(1===o&&x.isXMLDoc(e)||(i=x.attrHooks[t.toLowerCase()]||(x.expr.match.bool.test(t)?ut:void 0)),void 0!==n?null===n?void x.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=x.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!v.radioValue&&"radio"===t&&S(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(P);if(i&&1===e.nodeType)for(;n=i[r++];)e.removeAttribute(n)}}),ut={set:function(e,t,n){return!1===t?x.removeAttr(e,n):e.setAttribute(n,n),n}},x.each(x.expr.match.bool.source.match(/\w+/g),(function(e,t){var n=ft[t]||x.find.attr;ft[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=ft[a],ft[a]=i,i=null!=n(e,t,r)?a:null,ft[a]=o),i}}));var ht=/^(?:input|select|textarea|button)$/i,dt=/^(?:a|area)$/i;function pt(e){return(e.match(P)||[]).join(" ")}function zt(e){return e.getAttribute&&e.getAttribute("class")||""}function vt(e){return Array.isArray(e)?e:"string"===typeof e&&e.match(P)||[]}x.fn.extend({prop:function(e,t){return U(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each((function(){delete this[x.propFix[e]||e]}))}}),x.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&x.isXMLDoc(e)||(t=x.propFix[t]||t,i=x.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=x.find.attr(e,"tabindex");return t?parseInt(t,10):ht.test(e.nodeName)||dt.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),v.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],(function(){x.propFix[this.toLowerCase()]=this})),x.fn.extend({addClass:function(e){var t,n,r,i,o,a,c,s=0;if(g(e))return this.each((function(t){x(this).addClass(e.call(this,t,zt(this)))}));if((t=vt(e)).length)for(;n=this[s++];)if(i=zt(n),r=1===n.nodeType&&" "+pt(i)+" "){for(a=0;o=t[a++];)r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(c=pt(r))&&n.setAttribute("class",c)}return this},removeClass:function(e){var t,n,r,i,o,a,c,s=0;if(g(e))return this.each((function(t){x(this).removeClass(e.call(this,t,zt(this)))}));if(!arguments.length)return this.attr("class","");if((t=vt(e)).length)for(;n=this[s++];)if(i=zt(n),r=1===n.nodeType&&" "+pt(i)+" "){for(a=0;o=t[a++];)for(;r.indexOf(" "+o+" ")>-1;)r=r.replace(" "+o+" "," ");i!==(c=pt(r))&&n.setAttribute("class",c)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"===typeof t&&r?t?this.addClass(e):this.removeClass(e):g(e)?this.each((function(n){x(this).toggleClass(e.call(this,n,zt(this),t),t)})):this.each((function(){var t,i,o,a;if(r)for(i=0,o=x(this),a=vt(e);t=a[i++];)o.hasClass(t)?o.removeClass(t):o.addClass(t);else void 0!==e&&"boolean"!==n||((t=zt(this))&&K.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":K.get(this,"__className__")||""))}))},hasClass:function(e){var t,n,r=0;for(t=" "+e+" ";n=this[r++];)if(1===n.nodeType&&(" "+pt(zt(n))+" ").indexOf(t)>-1)return!0;return!1}});var gt=/\r/g;x.fn.extend({val:function(e){var t,n,r,i=this[0];return arguments.length?(r=g(e),this.each((function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,x(this).val()):e)?i="":"number"===typeof i?i+="":Array.isArray(i)&&(i=x.map(i,(function(e){return null==e?"":e+""}))),(t=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))}))):i?(t=x.valHooks[i.type]||x.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:"string"===typeof(n=i.value)?n.replace(gt,""):null==n?"":n:void 0}}),x.extend({valHooks:{option:{get:function(e){var t=x.find.attr(e,"value");return null!=t?t:pt(x.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,c=a?null:[],s=a?o+1:i.length;for(r=o<0?s:a?o:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),x.each(["radio","checkbox"],(function(){x.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=x.inArray(x(e).val(),t)>-1}},v.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})})),v.focusin="onfocusin"in n;var mt=/^(?:focusinfocus|focusoutblur)$/,yt=function(e){e.stopPropagation()};x.extend(x.event,{trigger:function(e,t,r,i){var o,a,c,s,l,u,f,h,p=[r||y],z=d.call(e,"type")?e.type:e,v=d.call(e,"namespace")?e.namespace.split("."):[];if(a=h=c=r=r||y,3!==r.nodeType&&8!==r.nodeType&&!mt.test(z+x.event.triggered)&&(z.indexOf(".")>-1&&(v=z.split("."),z=v.shift(),v.sort()),l=z.indexOf(":")<0&&"on"+z,(e=e[x.expando]?e:new x.Event(z,"object"===typeof e&&e)).isTrigger=i?2:3,e.namespace=v.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+v.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=r),t=null==t?[e]:x.makeArray(t,[e]),f=x.event.special[z]||{},i||!f.trigger||!1!==f.trigger.apply(r,t))){if(!i&&!f.noBubble&&!m(r)){for(s=f.delegateType||z,mt.test(s+z)||(a=a.parentNode);a;a=a.parentNode)p.push(a),c=a;c===(r.ownerDocument||y)&&p.push(c.defaultView||c.parentWindow||n)}for(o=0;(a=p[o++])&&!e.isPropagationStopped();)h=a,e.type=o>1?s:f.bindType||z,(u=(K.get(a,"events")||Object.create(null))[e.type]&&K.get(a,"handle"))&&u.apply(a,t),(u=l&&a[l])&&u.apply&&$(a)&&(e.result=u.apply(a,t),!1===e.result&&e.preventDefault());return e.type=z,i||e.isDefaultPrevented()||f._default&&!1!==f._default.apply(p.pop(),t)||!$(r)||l&&g(r[z])&&!m(r)&&((c=r[l])&&(r[l]=null),x.event.triggered=z,e.isPropagationStopped()&&h.addEventListener(z,yt),r[z](),e.isPropagationStopped()&&h.removeEventListener(z,yt),x.event.triggered=void 0,c&&(r[l]=c)),e.result}},simulate:function(e,t,n){var r=x.extend(new x.Event,n,{type:e,isSimulated:!0});x.event.trigger(r,null,t)}}),x.fn.extend({trigger:function(e,t){return this.each((function(){x.event.trigger(e,t,this)}))},triggerHandler:function(e,t){var n=this[0];if(n)return x.event.trigger(e,t,n,!0)}}),v.focusin||x.each({focus:"focusin",blur:"focusout"},(function(e,t){var n=function(e){x.event.simulate(t,e.target,x.event.fix(e))};x.event.special[t]={setup:function(){var r=this.ownerDocument||this.document||this,i=K.access(r,t);i||r.addEventListener(e,n,!0),K.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this.document||this,i=K.access(r,t)-1;i?K.access(r,t,i):(r.removeEventListener(e,n,!0),K.remove(r,t))}}}));var bt=n.location,wt={guid:Date.now()},kt=/\?/;x.parseXML=function(e){var t,r;if(!e||"string"!==typeof e)return null;try{t=(new n.DOMParser).parseFromString(e,"text/xml")}catch(i){}return r=t&&t.getElementsByTagName("parsererror")[0],t&&!r||x.error("Invalid XML: "+(r?x.map(r.childNodes,(function(e){return e.textContent})).join("\n"):e)),t};var xt=/\[\]$/,jt=/\r?\n/g,Mt=/^(?:submit|button|image|reset|file)$/i,_t=/^(?:input|select|textarea|keygen)/i;function Ct(e,t,n,r){var i;if(Array.isArray(t))x.each(t,(function(t,i){n||xt.test(e)?r(e,i):Ct(e+"["+("object"===typeof i&&null!=i?t:"")+"]",i,n,r)}));else if(n||"object"!==k(t))r(e,t);else for(i in t)Ct(e+"["+i+"]",t[i],n,r)}x.param=function(e,t){var n,r=[],i=function(e,t){var n=g(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!x.isPlainObject(e))x.each(e,(function(){i(this.name,this.value)}));else for(n in e)Ct(n,e[n],t,i);return r.join("&")},x.fn.extend({serialize:function(){return x.param(this.serializeArray())},serializeArray:function(){return this.map((function(){var e=x.prop(this,"elements");return e?x.makeArray(e):this})).filter((function(){var e=this.type;return this.name&&!x(this).is(":disabled")&&_t.test(this.nodeName)&&!Mt.test(e)&&(this.checked||!de.test(e))})).map((function(e,t){var n=x(this).val();return null==n?null:Array.isArray(n)?x.map(n,(function(e){return{name:t.name,value:e.replace(jt,"\r\n")}})):{name:t.name,value:n.replace(jt,"\r\n")}})).get()}});var qt=/%20/g,St=/#.*$/,Tt=/([?&])_=[^&]*/,Ot=/^(.*?):[ \t]*([^\r\n]*)$/gm,Et=/^(?:GET|HEAD)$/,At=/^\/\//,Lt={},Ht={},Dt="*/".concat("*"),Pt=y.createElement("a");function Vt(e){return function(t,n){"string"!==typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(P)||[];if(g(n))for(;r=o[i++];)"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function Nt(e,t,n,r){var i={},o=e===Ht;function a(c){var s;return i[c]=!0,x.each(e[c]||[],(function(e,c){var l=c(t,n,r);return"string"!==typeof l||o||i[l]?o?!(s=l):void 0:(t.dataTypes.unshift(l),a(l),!1)})),s}return a(t.dataTypes[0])||!i["*"]&&a("*")}function It(e,t){var n,r,i=x.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&x.extend(!0,e,r),e}Pt.href=bt.href,x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:bt.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(bt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?It(It(e,x.ajaxSettings),t):It(x.ajaxSettings,e)},ajaxPrefilter:Vt(Lt),ajaxTransport:Vt(Ht),ajax:function(e,t){"object"===typeof e&&(t=e,e=void 0),t=t||{};var r,i,o,a,c,s,l,u,f,h,d=x.ajaxSetup({},t),p=d.context||d,z=d.context&&(p.nodeType||p.jquery)?x(p):x.event,v=x.Deferred(),g=x.Callbacks("once memory"),m=d.statusCode||{},b={},w={},k="canceled",j={readyState:0,getResponseHeader:function(e){var t;if(l){if(!a)for(a={};t=Ot.exec(o);)a[t[1].toLowerCase()+" "]=(a[t[1].toLowerCase()+" "]||[]).concat(t[2]);t=a[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return l?o:null},setRequestHeader:function(e,t){return null==l&&(e=w[e.toLowerCase()]=w[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==l&&(d.mimeType=e),this},statusCode:function(e){var t;if(e)if(l)j.always(e[j.status]);else for(t in e)m[t]=[m[t],e[t]];return this},abort:function(e){var t=e||k;return r&&r.abort(t),M(0,t),this}};if(v.promise(j),d.url=((e||d.url||bt.href)+"").replace(At,bt.protocol+"//"),d.type=t.method||t.type||d.method||d.type,d.dataTypes=(d.dataType||"*").toLowerCase().match(P)||[""],null==d.crossDomain){s=y.createElement("a");try{s.href=d.url,s.href=s.href,d.crossDomain=Pt.protocol+"//"+Pt.host!==s.protocol+"//"+s.host}catch(_){d.crossDomain=!0}}if(d.data&&d.processData&&"string"!==typeof d.data&&(d.data=x.param(d.data,d.traditional)),Nt(Lt,d,t,j),l)return j;for(f in(u=x.event&&d.global)&&0===x.active++&&x.event.trigger("ajaxStart"),d.type=d.type.toUpperCase(),d.hasContent=!Et.test(d.type),i=d.url.replace(St,""),d.hasContent?d.data&&d.processData&&0===(d.contentType||"").indexOf("application/x-www-form-urlencoded")&&(d.data=d.data.replace(qt,"+")):(h=d.url.slice(i.length),d.data&&(d.processData||"string"===typeof d.data)&&(i+=(kt.test(i)?"&":"?")+d.data,delete d.data),!1===d.cache&&(i=i.replace(Tt,"$1"),h=(kt.test(i)?"&":"?")+"_="+wt.guid+++h),d.url=i+h),d.ifModified&&(x.lastModified[i]&&j.setRequestHeader("If-Modified-Since",x.lastModified[i]),x.etag[i]&&j.setRequestHeader("If-None-Match",x.etag[i])),(d.data&&d.hasContent&&!1!==d.contentType||t.contentType)&&j.setRequestHeader("Content-Type",d.contentType),j.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+("*"!==d.dataTypes[0]?", "+Dt+"; q=0.01":""):d.accepts["*"]),d.headers)j.setRequestHeader(f,d.headers[f]);if(d.beforeSend&&(!1===d.beforeSend.call(p,j,d)||l))return j.abort();if(k="abort",g.add(d.complete),j.done(d.success),j.fail(d.error),r=Nt(Ht,d,t,j)){if(j.readyState=1,u&&z.trigger("ajaxSend",[j,d]),l)return j;d.async&&d.timeout>0&&(c=n.setTimeout((function(){j.abort("timeout")}),d.timeout));try{l=!1,r.send(b,M)}catch(_){if(l)throw _;M(-1,_)}}else M(-1,"No Transport");function M(e,t,a,s){var f,h,y,b,w,k=t;l||(l=!0,c&&n.clearTimeout(c),r=void 0,o=s||"",j.readyState=e>0?4:0,f=e>=200&&e<300||304===e,a&&(b=function(e,t,n){for(var r,i,o,a,c=e.contents,s=e.dataTypes;"*"===s[0];)s.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in c)if(c[i]&&c[i].test(r)){s.unshift(i);break}if(s[0]in n)o=s[0];else{for(i in n){if(!s[0]||e.converters[i+" "+s[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==s[0]&&s.unshift(o),n[o]}(d,j,a)),!f&&x.inArray("script",d.dataTypes)>-1&&x.inArray("json",d.dataTypes)<0&&(d.converters["text script"]=function(){}),b=function(e,t,n,r){var i,o,a,c,s,l={},u=e.dataTypes.slice();if(u[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];for(o=u.shift();o;)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!s&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),s=o,o=u.shift())if("*"===o)o=s;else if("*"!==s&&s!==o){if(!(a=l[s+" "+o]||l["* "+o]))for(i in l)if((c=i.split(" "))[1]===o&&(a=l[s+" "+c[0]]||l["* "+c[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=c[0],u.unshift(c[1]));break}if(!0!==a)if(a&&e.throws)t=a(t);else try{t=a(t)}catch(_){return{state:"parsererror",error:a?_:"No conversion from "+s+" to "+o}}}return{state:"success",data:t}}(d,b,j,f),f?(d.ifModified&&((w=j.getResponseHeader("Last-Modified"))&&(x.lastModified[i]=w),(w=j.getResponseHeader("etag"))&&(x.etag[i]=w)),204===e||"HEAD"===d.type?k="nocontent":304===e?k="notmodified":(k=b.state,h=b.data,f=!(y=b.error))):(y=k,!e&&k||(k="error",e<0&&(e=0))),j.status=e,j.statusText=(t||k)+"",f?v.resolveWith(p,[h,k,j]):v.rejectWith(p,[j,k,y]),j.statusCode(m),m=void 0,u&&z.trigger(f?"ajaxSuccess":"ajaxError",[j,d,f?h:y]),g.fireWith(p,[j,k]),u&&(z.trigger("ajaxComplete",[j,d]),--x.active||x.event.trigger("ajaxStop")))}return j},getJSON:function(e,t,n){return x.get(e,t,n,"json")},getScript:function(e,t){return x.get(e,void 0,t,"script")}}),x.each(["get","post"],(function(e,t){x[t]=function(e,n,r,i){return g(n)&&(i=i||r,r=n,n=void 0),x.ajax(x.extend({url:e,type:t,dataType:i,data:n,success:r},x.isPlainObject(e)&&e))}})),x.ajaxPrefilter((function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")})),x._evalUrl=function(e,t,n){return x.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){x.globalEval(e,t,n)}})},x.fn.extend({wrapAll:function(e){var t;return this[0]&&(g(e)&&(e=e.call(this[0])),t=x(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map((function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e})).append(this)),this},wrapInner:function(e){return g(e)?this.each((function(t){x(this).wrapInner(e.call(this,t))})):this.each((function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)}))},wrap:function(e){var t=g(e);return this.each((function(n){x(this).wrapAll(t?e.call(this,n):e)}))},unwrap:function(e){return this.parent(e).not("body").each((function(){x(this).replaceWith(this.childNodes)})),this}}),x.expr.pseudos.hidden=function(e){return!x.expr.pseudos.visible(e)},x.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},x.ajaxSettings.xhr=function(){try{return new n.XMLHttpRequest}catch(e){}};var Rt={0:200,1223:204},Ft=x.ajaxSettings.xhr();v.cors=!!Ft&&"withCredentials"in Ft,v.ajax=Ft=!!Ft,x.ajaxTransport((function(e){var t,r;if(v.cors||Ft&&!e.crossDomain)return{send:function(i,o){var a,c=e.xhr();if(c.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(a in e.xhrFields)c[a]=e.xhrFields[a];for(a in e.mimeType&&c.overrideMimeType&&c.overrideMimeType(e.mimeType),e.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest"),i)c.setRequestHeader(a,i[a]);t=function(e){return function(){t&&(t=r=c.onload=c.onerror=c.onabort=c.ontimeout=c.onreadystatechange=null,"abort"===e?c.abort():"error"===e?"number"!==typeof c.status?o(0,"error"):o(c.status,c.statusText):o(Rt[c.status]||c.status,c.statusText,"text"!==(c.responseType||"text")||"string"!==typeof c.responseText?{binary:c.response}:{text:c.responseText},c.getAllResponseHeaders()))}},c.onload=t(),r=c.onerror=c.ontimeout=t("error"),void 0!==c.onabort?c.onabort=r:c.onreadystatechange=function(){4===c.readyState&&n.setTimeout((function(){t&&r()}))},t=t("abort");try{c.send(e.hasContent&&e.data||null)}catch(s){if(t)throw s}},abort:function(){t&&t()}}})),x.ajaxPrefilter((function(e){e.crossDomain&&(e.contents.script=!1)})),x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return x.globalEval(e),e}}}),x.ajaxPrefilter("script",(function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")})),x.ajaxTransport("script",(function(e){var t,n;if(e.crossDomain||e.scriptAttrs)return{send:function(r,i){t=x("\n\n The CSV file is of the form\n\n Date,SeriesA,SeriesB,SeriesC\n YYYYMMDD,A1,B1,C1\n YYYYMMDD,A2,B2,C2\n\n If the 'errorBars' option is set in the constructor, the input should be of\n the form\n Date,SeriesA,SeriesB,...\n YYYYMMDD,A1,sigmaA1,B1,sigmaB1,...\n YYYYMMDD,A2,sigmaA2,B2,sigmaB2,...\n\n If the 'fractions' option is set, the input should be of the form:\n\n Date,SeriesA,SeriesB,...\n YYYYMMDD,A1/B1,A2/B2,...\n YYYYMMDD,A1/B1,A2/B2,...\n\n And error bars will be calculated automatically using a binomial distribution.\n\n For further documentation and examples, see http://dygraphs.com/\n */\n\n'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\n\nvar _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar _dygraphLayout = require('./dygraph-layout');\n\nvar _dygraphLayout2 = _interopRequireDefault(_dygraphLayout);\n\nvar _dygraphCanvas = require('./dygraph-canvas');\n\nvar _dygraphCanvas2 = _interopRequireDefault(_dygraphCanvas);\n\nvar _dygraphOptions = require('./dygraph-options');\n\nvar _dygraphOptions2 = _interopRequireDefault(_dygraphOptions);\n\nvar _dygraphInteractionModel = require('./dygraph-interaction-model');\n\nvar _dygraphInteractionModel2 = _interopRequireDefault(_dygraphInteractionModel);\n\nvar _dygraphTickers = require('./dygraph-tickers');\n\nvar DygraphTickers = _interopRequireWildcard(_dygraphTickers);\n\nvar _dygraphUtils = require('./dygraph-utils');\n\nvar utils = _interopRequireWildcard(_dygraphUtils);\n\nvar _dygraphDefaultAttrs = require('./dygraph-default-attrs');\n\nvar _dygraphDefaultAttrs2 = _interopRequireDefault(_dygraphDefaultAttrs);\n\nvar _dygraphOptionsReference = require('./dygraph-options-reference');\n\nvar _dygraphOptionsReference2 = _interopRequireDefault(_dygraphOptionsReference);\n\nvar _iframeTarp = require('./iframe-tarp');\n\nvar _iframeTarp2 = _interopRequireDefault(_iframeTarp);\n\nvar _datahandlerDefault = require('./datahandler/default');\n\nvar _datahandlerDefault2 = _interopRequireDefault(_datahandlerDefault);\n\nvar _datahandlerBarsError = require('./datahandler/bars-error');\n\nvar _datahandlerBarsError2 = _interopRequireDefault(_datahandlerBarsError);\n\nvar _datahandlerBarsCustom = require('./datahandler/bars-custom');\n\nvar _datahandlerBarsCustom2 = _interopRequireDefault(_datahandlerBarsCustom);\n\nvar _datahandlerDefaultFractions = require('./datahandler/default-fractions');\n\nvar _datahandlerDefaultFractions2 = _interopRequireDefault(_datahandlerDefaultFractions);\n\nvar _datahandlerBarsFractions = require('./datahandler/bars-fractions');\n\nvar _datahandlerBarsFractions2 = _interopRequireDefault(_datahandlerBarsFractions);\n\nvar _datahandlerBars = require('./datahandler/bars');\n\nvar _datahandlerBars2 = _interopRequireDefault(_datahandlerBars);\n\nvar _pluginsAnnotations = require('./plugins/annotations');\n\nvar _pluginsAnnotations2 = _interopRequireDefault(_pluginsAnnotations);\n\nvar _pluginsAxes = require('./plugins/axes');\n\nvar _pluginsAxes2 = _interopRequireDefault(_pluginsAxes);\n\nvar _pluginsChartLabels = require('./plugins/chart-labels');\n\nvar _pluginsChartLabels2 = _interopRequireDefault(_pluginsChartLabels);\n\nvar _pluginsGrid = require('./plugins/grid');\n\nvar _pluginsGrid2 = _interopRequireDefault(_pluginsGrid);\n\nvar _pluginsLegend = require('./plugins/legend');\n\nvar _pluginsLegend2 = _interopRequireDefault(_pluginsLegend);\n\nvar _pluginsRangeSelector = require('./plugins/range-selector');\n\nvar _pluginsRangeSelector2 = _interopRequireDefault(_pluginsRangeSelector);\n\nvar _dygraphGviz = require('./dygraph-gviz');\n\nvar _dygraphGviz2 = _interopRequireDefault(_dygraphGviz);\n\n\"use strict\";\n\n/**\n * Creates an interactive, zoomable chart.\n *\n * @constructor\n * @param {div | String} div A div or the id of a div into which to construct\n * the chart.\n * @param {String | Function} file A file containing CSV data or a function\n * that returns this data. The most basic expected format for each line is\n * \"YYYY/MM/DD,val1,val2,...\". For more information, see\n * http://dygraphs.com/data.html.\n * @param {Object} attrs Various other attributes, e.g. errorBars determines\n * whether the input data contains error ranges. For a complete list of\n * options, see http://dygraphs.com/options.html.\n */\nvar Dygraph = function Dygraph(div, data, opts) {\n this.__init__(div, data, opts);\n};\n\nDygraph.NAME = \"Dygraph\";\nDygraph.VERSION = \"2.0.0\";\n\n// Various default values\nDygraph.DEFAULT_ROLL_PERIOD = 1;\nDygraph.DEFAULT_WIDTH = 480;\nDygraph.DEFAULT_HEIGHT = 320;\n\n// For max 60 Hz. animation:\nDygraph.ANIMATION_STEPS = 12;\nDygraph.ANIMATION_DURATION = 200;\n\n/**\n * Standard plotters. These may be used by clients.\n * Available plotters are:\n * - Dygraph.Plotters.linePlotter: draws central lines (most common)\n * - Dygraph.Plotters.errorPlotter: draws error bars\n * - Dygraph.Plotters.fillPlotter: draws fills under lines (used with fillGraph)\n *\n * By default, the plotter is [fillPlotter, errorPlotter, linePlotter].\n * This causes all the lines to be drawn over all the fills/error bars.\n */\nDygraph.Plotters = _dygraphCanvas2['default']._Plotters;\n\n// Used for initializing annotation CSS rules only once.\nDygraph.addedAnnotationCSS = false;\n\n/**\n * Initializes the Dygraph. This creates a new DIV and constructs the PlotKit\n * and context <canvas> inside of it. See the constructor for details.\n * on the parameters.\n * @param {Element} div the Element to render the graph into.\n * @param {string | Function} file Source data\n * @param {Object} attrs Miscellaneous other options\n * @private\n */\nDygraph.prototype.__init__ = function (div, file, attrs) {\n this.is_initial_draw_ = true;\n this.readyFns_ = [];\n\n // Support two-argument constructor\n if (attrs === null || attrs === undefined) {\n attrs = {};\n }\n\n attrs = Dygraph.copyUserAttrs_(attrs);\n\n if (typeof div == 'string') {\n div = document.getElementById(div);\n }\n\n if (!div) {\n throw new Error('Constructing dygraph with a non-existent div!');\n }\n\n // Copy the important bits into the object\n // TODO(danvk): most of these should just stay in the attrs_ dictionary.\n this.maindiv_ = div;\n this.file_ = file;\n this.rollPeriod_ = attrs.rollPeriod || Dygraph.DEFAULT_ROLL_PERIOD;\n this.previousVerticalX_ = -1;\n this.fractions_ = attrs.fractions || false;\n this.dateWindow_ = attrs.dateWindow || null;\n\n this.annotations_ = [];\n\n // Clear the div. This ensure that, if multiple dygraphs are passed the same\n // div, then only one will be drawn.\n div.innerHTML = \"\";\n\n // For historical reasons, the 'width' and 'height' options trump all CSS\n // rules _except_ for an explicit 'width' or 'height' on the div.\n // As an added convenience, if the div has zero height (like
does\n // without any styles), then we use a default height/width.\n if (div.style.width === '' && attrs.width) {\n div.style.width = attrs.width + \"px\";\n }\n if (div.style.height === '' && attrs.height) {\n div.style.height = attrs.height + \"px\";\n }\n if (div.style.height === '' && div.clientHeight === 0) {\n div.style.height = Dygraph.DEFAULT_HEIGHT + \"px\";\n if (div.style.width === '') {\n div.style.width = Dygraph.DEFAULT_WIDTH + \"px\";\n }\n }\n // These will be zero if the dygraph's div is hidden. In that case,\n // use the user-specified attributes if present. If not, use zero\n // and assume the user will call resize to fix things later.\n this.width_ = div.clientWidth || attrs.width || 0;\n this.height_ = div.clientHeight || attrs.height || 0;\n\n // TODO(danvk): set fillGraph to be part of attrs_ here, not user_attrs_.\n if (attrs.stackedGraph) {\n attrs.fillGraph = true;\n // TODO(nikhilk): Add any other stackedGraph checks here.\n }\n\n // DEPRECATION WARNING: All option processing should be moved from\n // attrs_ and user_attrs_ to options_, which holds all this information.\n //\n // Dygraphs has many options, some of which interact with one another.\n // To keep track of everything, we maintain two sets of options:\n //\n // this.user_attrs_ only options explicitly set by the user.\n // this.attrs_ defaults, options derived from user_attrs_, data.\n //\n // Options are then accessed this.attr_('attr'), which first looks at\n // user_attrs_ and then computed attrs_. This way Dygraphs can set intelligent\n // defaults without overriding behavior that the user specifically asks for.\n this.user_attrs_ = {};\n utils.update(this.user_attrs_, attrs);\n\n // This sequence ensures that Dygraph.DEFAULT_ATTRS is never modified.\n this.attrs_ = {};\n utils.updateDeep(this.attrs_, _dygraphDefaultAttrs2['default']);\n\n this.boundaryIds_ = [];\n this.setIndexByName_ = {};\n this.datasetIndex_ = [];\n\n this.registeredEvents_ = [];\n this.eventListeners_ = {};\n\n this.attributes_ = new _dygraphOptions2['default'](this);\n\n // Create the containing DIV and other interactive elements\n this.createInterface_();\n\n // Activate plugins.\n this.plugins_ = [];\n var plugins = Dygraph.PLUGINS.concat(this.getOption('plugins'));\n for (var i = 0; i < plugins.length; i++) {\n // the plugins option may contain either plugin classes or instances.\n // Plugin instances contain an activate method.\n var Plugin = plugins[i]; // either a constructor or an instance.\n var pluginInstance;\n if (typeof Plugin.activate !== 'undefined') {\n pluginInstance = Plugin;\n } else {\n pluginInstance = new Plugin();\n }\n\n var pluginDict = {\n plugin: pluginInstance,\n events: {},\n options: {},\n pluginOptions: {}\n };\n\n var handlers = pluginInstance.activate(this);\n for (var eventName in handlers) {\n if (!handlers.hasOwnProperty(eventName)) continue;\n // TODO(danvk): validate eventName.\n pluginDict.events[eventName] = handlers[eventName];\n }\n\n this.plugins_.push(pluginDict);\n }\n\n // At this point, plugins can no longer register event handlers.\n // Construct a map from event -> ordered list of [callback, plugin].\n for (var i = 0; i < this.plugins_.length; i++) {\n var plugin_dict = this.plugins_[i];\n for (var eventName in plugin_dict.events) {\n if (!plugin_dict.events.hasOwnProperty(eventName)) continue;\n var callback = plugin_dict.events[eventName];\n\n var pair = [plugin_dict.plugin, callback];\n if (!(eventName in this.eventListeners_)) {\n this.eventListeners_[eventName] = [pair];\n } else {\n this.eventListeners_[eventName].push(pair);\n }\n }\n }\n\n this.createDragInterface_();\n\n this.start_();\n};\n\n/**\n * Triggers a cascade of events to the various plugins which are interested in them.\n * Returns true if the \"default behavior\" should be prevented, i.e. if one\n * of the event listeners called event.preventDefault().\n * @private\n */\nDygraph.prototype.cascadeEvents_ = function (name, extra_props) {\n if (!(name in this.eventListeners_)) return false;\n\n // QUESTION: can we use objects & prototypes to speed this up?\n var e = {\n dygraph: this,\n cancelable: false,\n defaultPrevented: false,\n preventDefault: function preventDefault() {\n if (!e.cancelable) throw \"Cannot call preventDefault on non-cancelable event.\";\n e.defaultPrevented = true;\n },\n propagationStopped: false,\n stopPropagation: function stopPropagation() {\n e.propagationStopped = true;\n }\n };\n utils.update(e, extra_props);\n\n var callback_plugin_pairs = this.eventListeners_[name];\n if (callback_plugin_pairs) {\n for (var i = callback_plugin_pairs.length - 1; i >= 0; i--) {\n var plugin = callback_plugin_pairs[i][0];\n var callback = callback_plugin_pairs[i][1];\n callback.call(plugin, e);\n if (e.propagationStopped) break;\n }\n }\n return e.defaultPrevented;\n};\n\n/**\n * Fetch a plugin instance of a particular class. Only for testing.\n * @private\n * @param {!Class} type The type of the plugin.\n * @return {Object} Instance of the plugin, or null if there is none.\n */\nDygraph.prototype.getPluginInstance_ = function (type) {\n for (var i = 0; i < this.plugins_.length; i++) {\n var p = this.plugins_[i];\n if (p.plugin instanceof type) {\n return p.plugin;\n }\n }\n return null;\n};\n\n/**\n * Returns the zoomed status of the chart for one or both axes.\n *\n * Axis is an optional parameter. Can be set to 'x' or 'y'.\n *\n * The zoomed status for an axis is set whenever a user zooms using the mouse\n * or when the dateWindow or valueRange are updated. Double-clicking or calling\n * resetZoom() resets the zoom status for the chart.\n */\nDygraph.prototype.isZoomed = function (axis) {\n var isZoomedX = !!this.dateWindow_;\n if (axis === 'x') return isZoomedX;\n\n var isZoomedY = this.axes_.map(function (axis) {\n return !!axis.valueRange;\n }).indexOf(true) >= 0;\n if (axis === null || axis === undefined) {\n return isZoomedX || isZoomedY;\n }\n if (axis === 'y') return isZoomedY;\n\n throw new Error('axis parameter is [' + axis + '] must be null, \\'x\\' or \\'y\\'.');\n};\n\n/**\n * Returns information about the Dygraph object, including its containing ID.\n */\nDygraph.prototype.toString = function () {\n var maindiv = this.maindiv_;\n var id = maindiv && maindiv.id ? maindiv.id : maindiv;\n return \"[Dygraph \" + id + \"]\";\n};\n\n/**\n * @private\n * Returns the value of an option. This may be set by the user (either in the\n * constructor or by calling updateOptions) or by dygraphs, and may be set to a\n * per-series value.\n * @param {string} name The name of the option, e.g. 'rollPeriod'.\n * @param {string} [seriesName] The name of the series to which the option\n * will be applied. If no per-series value of this option is available, then\n * the global value is returned. This is optional.\n * @return { ... } The value of the option.\n */\nDygraph.prototype.attr_ = function (name, seriesName) {\n // For \"production\" code, this gets removed by uglifyjs.\n if (typeof process !== 'undefined') {\n if (process.env.NODE_ENV != 'production') {\n if (typeof _dygraphOptionsReference2['default'] === 'undefined') {\n console.error('Must include options reference JS for testing');\n } else if (!_dygraphOptionsReference2['default'].hasOwnProperty(name)) {\n console.error('Dygraphs is using property ' + name + ', which has no ' + 'entry in the Dygraphs.OPTIONS_REFERENCE listing.');\n // Only log this error once.\n _dygraphOptionsReference2['default'][name] = true;\n }\n }\n }\n return seriesName ? this.attributes_.getForSeries(name, seriesName) : this.attributes_.get(name);\n};\n\n/**\n * Returns the current value for an option, as set in the constructor or via\n * updateOptions. You may pass in an (optional) series name to get per-series\n * values for the option.\n *\n * All values returned by this method should be considered immutable. If you\n * modify them, there is no guarantee that the changes will be honored or that\n * dygraphs will remain in a consistent state. If you want to modify an option,\n * use updateOptions() instead.\n *\n * @param {string} name The name of the option (e.g. 'strokeWidth')\n * @param {string=} opt_seriesName Series name to get per-series values.\n * @return {*} The value of the option.\n */\nDygraph.prototype.getOption = function (name, opt_seriesName) {\n return this.attr_(name, opt_seriesName);\n};\n\n/**\n * Like getOption(), but specifically returns a number.\n * This is a convenience function for working with the Closure Compiler.\n * @param {string} name The name of the option (e.g. 'strokeWidth')\n * @param {string=} opt_seriesName Series name to get per-series values.\n * @return {number} The value of the option.\n * @private\n */\nDygraph.prototype.getNumericOption = function (name, opt_seriesName) {\n return (/** @type{number} */this.getOption(name, opt_seriesName)\n );\n};\n\n/**\n * Like getOption(), but specifically returns a string.\n * This is a convenience function for working with the Closure Compiler.\n * @param {string} name The name of the option (e.g. 'strokeWidth')\n * @param {string=} opt_seriesName Series name to get per-series values.\n * @return {string} The value of the option.\n * @private\n */\nDygraph.prototype.getStringOption = function (name, opt_seriesName) {\n return (/** @type{string} */this.getOption(name, opt_seriesName)\n );\n};\n\n/**\n * Like getOption(), but specifically returns a boolean.\n * This is a convenience function for working with the Closure Compiler.\n * @param {string} name The name of the option (e.g. 'strokeWidth')\n * @param {string=} opt_seriesName Series name to get per-series values.\n * @return {boolean} The value of the option.\n * @private\n */\nDygraph.prototype.getBooleanOption = function (name, opt_seriesName) {\n return (/** @type{boolean} */this.getOption(name, opt_seriesName)\n );\n};\n\n/**\n * Like getOption(), but specifically returns a function.\n * This is a convenience function for working with the Closure Compiler.\n * @param {string} name The name of the option (e.g. 'strokeWidth')\n * @param {string=} opt_seriesName Series name to get per-series values.\n * @return {function(...)} The value of the option.\n * @private\n */\nDygraph.prototype.getFunctionOption = function (name, opt_seriesName) {\n return (/** @type{function(...)} */this.getOption(name, opt_seriesName)\n );\n};\n\nDygraph.prototype.getOptionForAxis = function (name, axis) {\n return this.attributes_.getForAxis(name, axis);\n};\n\n/**\n * @private\n * @param {string} axis The name of the axis (i.e. 'x', 'y' or 'y2')\n * @return { ... } A function mapping string -> option value\n */\nDygraph.prototype.optionsViewForAxis_ = function (axis) {\n var self = this;\n return function (opt) {\n var axis_opts = self.user_attrs_.axes;\n if (axis_opts && axis_opts[axis] && axis_opts[axis].hasOwnProperty(opt)) {\n return axis_opts[axis][opt];\n }\n\n // I don't like that this is in a second spot.\n if (axis === 'x' && opt === 'logscale') {\n // return the default value.\n // TODO(konigsberg): pull the default from a global default.\n return false;\n }\n\n // user-specified attributes always trump defaults, even if they're less\n // specific.\n if (typeof self.user_attrs_[opt] != 'undefined') {\n return self.user_attrs_[opt];\n }\n\n axis_opts = self.attrs_.axes;\n if (axis_opts && axis_opts[axis] && axis_opts[axis].hasOwnProperty(opt)) {\n return axis_opts[axis][opt];\n }\n // check old-style axis options\n // TODO(danvk): add a deprecation warning if either of these match.\n if (axis == 'y' && self.axes_[0].hasOwnProperty(opt)) {\n return self.axes_[0][opt];\n } else if (axis == 'y2' && self.axes_[1].hasOwnProperty(opt)) {\n return self.axes_[1][opt];\n }\n return self.attr_(opt);\n };\n};\n\n/**\n * Returns the current rolling period, as set by the user or an option.\n * @return {number} The number of points in the rolling window\n */\nDygraph.prototype.rollPeriod = function () {\n return this.rollPeriod_;\n};\n\n/**\n * Returns the currently-visible x-range. This can be affected by zooming,\n * panning or a call to updateOptions.\n * Returns a two-element array: [left, right].\n * If the Dygraph has dates on the x-axis, these will be millis since epoch.\n */\nDygraph.prototype.xAxisRange = function () {\n return this.dateWindow_ ? this.dateWindow_ : this.xAxisExtremes();\n};\n\n/**\n * Returns the lower- and upper-bound x-axis values of the data set.\n */\nDygraph.prototype.xAxisExtremes = function () {\n var pad = this.getNumericOption('xRangePad') / this.plotter_.area.w;\n if (this.numRows() === 0) {\n return [0 - pad, 1 + pad];\n }\n var left = this.rawData_[0][0];\n var right = this.rawData_[this.rawData_.length - 1][0];\n if (pad) {\n // Must keep this in sync with dygraph-layout _evaluateLimits()\n var range = right - left;\n left -= range * pad;\n right += range * pad;\n }\n return [left, right];\n};\n\n/**\n * Returns the lower- and upper-bound y-axis values for each axis. These are\n * the ranges you'll get if you double-click to zoom out or call resetZoom().\n * The return value is an array of [low, high] tuples, one for each y-axis.\n */\nDygraph.prototype.yAxisExtremes = function () {\n // TODO(danvk): this is pretty inefficient\n var packed = this.gatherDatasets_(this.rolledSeries_, null);\n var extremes = packed.extremes;\n\n var saveAxes = this.axes_;\n this.computeYAxisRanges_(extremes);\n var newAxes = this.axes_;\n this.axes_ = saveAxes;\n return newAxes.map(function (axis) {\n return axis.extremeRange;\n });\n};\n\n/**\n * Returns the currently-visible y-range for an axis. This can be affected by\n * zooming, panning or a call to updateOptions. Axis indices are zero-based. If\n * called with no arguments, returns the range of the first axis.\n * Returns a two-element array: [bottom, top].\n */\nDygraph.prototype.yAxisRange = function (idx) {\n if (typeof idx == \"undefined\") idx = 0;\n if (idx < 0 || idx >= this.axes_.length) {\n return null;\n }\n var axis = this.axes_[idx];\n return [axis.computedValueRange[0], axis.computedValueRange[1]];\n};\n\n/**\n * Returns the currently-visible y-ranges for each axis. This can be affected by\n * zooming, panning, calls to updateOptions, etc.\n * Returns an array of [bottom, top] pairs, one for each y-axis.\n */\nDygraph.prototype.yAxisRanges = function () {\n var ret = [];\n for (var i = 0; i < this.axes_.length; i++) {\n ret.push(this.yAxisRange(i));\n }\n return ret;\n};\n\n// TODO(danvk): use these functions throughout dygraphs.\n/**\n * Convert from data coordinates to canvas/div X/Y coordinates.\n * If specified, do this conversion for the coordinate system of a particular\n * axis. Uses the first axis by default.\n * Returns a two-element array: [X, Y]\n *\n * Note: use toDomXCoord instead of toDomCoords(x, null) and use toDomYCoord\n * instead of toDomCoords(null, y, axis).\n */\nDygraph.prototype.toDomCoords = function (x, y, axis) {\n return [this.toDomXCoord(x), this.toDomYCoord(y, axis)];\n};\n\n/**\n * Convert from data x coordinates to canvas/div X coordinate.\n * If specified, do this conversion for the coordinate system of a particular\n * axis.\n * Returns a single value or null if x is null.\n */\nDygraph.prototype.toDomXCoord = function (x) {\n if (x === null) {\n return null;\n }\n\n var area = this.plotter_.area;\n var xRange = this.xAxisRange();\n return area.x + (x - xRange[0]) / (xRange[1] - xRange[0]) * area.w;\n};\n\n/**\n * Convert from data x coordinates to canvas/div Y coordinate and optional\n * axis. Uses the first axis by default.\n *\n * returns a single value or null if y is null.\n */\nDygraph.prototype.toDomYCoord = function (y, axis) {\n var pct = this.toPercentYCoord(y, axis);\n\n if (pct === null) {\n return null;\n }\n var area = this.plotter_.area;\n return area.y + pct * area.h;\n};\n\n/**\n * Convert from canvas/div coords to data coordinates.\n * If specified, do this conversion for the coordinate system of a particular\n * axis. Uses the first axis by default.\n * Returns a two-element array: [X, Y].\n *\n * Note: use toDataXCoord instead of toDataCoords(x, null) and use toDataYCoord\n * instead of toDataCoords(null, y, axis).\n */\nDygraph.prototype.toDataCoords = function (x, y, axis) {\n return [this.toDataXCoord(x), this.toDataYCoord(y, axis)];\n};\n\n/**\n * Convert from canvas/div x coordinate to data coordinate.\n *\n * If x is null, this returns null.\n */\nDygraph.prototype.toDataXCoord = function (x) {\n if (x === null) {\n return null;\n }\n\n var area = this.plotter_.area;\n var xRange = this.xAxisRange();\n\n if (!this.attributes_.getForAxis(\"logscale\", 'x')) {\n return xRange[0] + (x - area.x) / area.w * (xRange[1] - xRange[0]);\n } else {\n var pct = (x - area.x) / area.w;\n return utils.logRangeFraction(xRange[0], xRange[1], pct);\n }\n};\n\n/**\n * Convert from canvas/div y coord to value.\n *\n * If y is null, this returns null.\n * if axis is null, this uses the first axis.\n */\nDygraph.prototype.toDataYCoord = function (y, axis) {\n if (y === null) {\n return null;\n }\n\n var area = this.plotter_.area;\n var yRange = this.yAxisRange(axis);\n\n if (typeof axis == \"undefined\") axis = 0;\n if (!this.attributes_.getForAxis(\"logscale\", axis)) {\n return yRange[0] + (area.y + area.h - y) / area.h * (yRange[1] - yRange[0]);\n } else {\n // Computing the inverse of toDomCoord.\n var pct = (y - area.y) / area.h;\n // Note reversed yRange, y1 is on top with pct==0.\n return utils.logRangeFraction(yRange[1], yRange[0], pct);\n }\n};\n\n/**\n * Converts a y for an axis to a percentage from the top to the\n * bottom of the drawing area.\n *\n * If the coordinate represents a value visible on the canvas, then\n * the value will be between 0 and 1, where 0 is the top of the canvas.\n * However, this method will return values outside the range, as\n * values can fall outside the canvas.\n *\n * If y is null, this returns null.\n * if axis is null, this uses the first axis.\n *\n * @param {number} y The data y-coordinate.\n * @param {number} [axis] The axis number on which the data coordinate lives.\n * @return {number} A fraction in [0, 1] where 0 = the top edge.\n */\nDygraph.prototype.toPercentYCoord = function (y, axis) {\n if (y === null) {\n return null;\n }\n if (typeof axis == \"undefined\") axis = 0;\n\n var yRange = this.yAxisRange(axis);\n\n var pct;\n var logscale = this.attributes_.getForAxis(\"logscale\", axis);\n if (logscale) {\n var logr0 = utils.log10(yRange[0]);\n var logr1 = utils.log10(yRange[1]);\n pct = (logr1 - utils.log10(y)) / (logr1 - logr0);\n } else {\n // yRange[1] - y is unit distance from the bottom.\n // yRange[1] - yRange[0] is the scale of the range.\n // (yRange[1] - y) / (yRange[1] - yRange[0]) is the % from the bottom.\n pct = (yRange[1] - y) / (yRange[1] - yRange[0]);\n }\n return pct;\n};\n\n/**\n * Converts an x value to a percentage from the left to the right of\n * the drawing area.\n *\n * If the coordinate represents a value visible on the canvas, then\n * the value will be between 0 and 1, where 0 is the left of the canvas.\n * However, this method will return values outside the range, as\n * values can fall outside the canvas.\n *\n * If x is null, this returns null.\n * @param {number} x The data x-coordinate.\n * @return {number} A fraction in [0, 1] where 0 = the left edge.\n */\nDygraph.prototype.toPercentXCoord = function (x) {\n if (x === null) {\n return null;\n }\n\n var xRange = this.xAxisRange();\n var pct;\n var logscale = this.attributes_.getForAxis(\"logscale\", 'x');\n if (logscale === true) {\n // logscale can be null so we test for true explicitly.\n var logr0 = utils.log10(xRange[0]);\n var logr1 = utils.log10(xRange[1]);\n pct = (utils.log10(x) - logr0) / (logr1 - logr0);\n } else {\n // x - xRange[0] is unit distance from the left.\n // xRange[1] - xRange[0] is the scale of the range.\n // The full expression below is the % from the left.\n pct = (x - xRange[0]) / (xRange[1] - xRange[0]);\n }\n return pct;\n};\n\n/**\n * Returns the number of columns (including the independent variable).\n * @return {number} The number of columns.\n */\nDygraph.prototype.numColumns = function () {\n if (!this.rawData_) return 0;\n return this.rawData_[0] ? this.rawData_[0].length : this.attr_(\"labels\").length;\n};\n\n/**\n * Returns the number of rows (excluding any header/label row).\n * @return {number} The number of rows, less any header.\n */\nDygraph.prototype.numRows = function () {\n if (!this.rawData_) return 0;\n return this.rawData_.length;\n};\n\n/**\n * Returns the value in the given row and column. If the row and column exceed\n * the bounds on the data, returns null. Also returns null if the value is\n * missing.\n * @param {number} row The row number of the data (0-based). Row 0 is the\n * first row of data, not a header row.\n * @param {number} col The column number of the data (0-based)\n * @return {number} The value in the specified cell or null if the row/col\n * were out of range.\n */\nDygraph.prototype.getValue = function (row, col) {\n if (row < 0 || row > this.rawData_.length) return null;\n if (col < 0 || col > this.rawData_[row].length) return null;\n\n return this.rawData_[row][col];\n};\n\n/**\n * Generates interface elements for the Dygraph: a containing div, a div to\n * display the current point, and a textbox to adjust the rolling average\n * period. Also creates the Renderer/Layout elements.\n * @private\n */\nDygraph.prototype.createInterface_ = function () {\n // Create the all-enclosing graph div\n var enclosing = this.maindiv_;\n\n this.graphDiv = document.createElement(\"div\");\n\n // TODO(danvk): any other styles that are useful to set here?\n this.graphDiv.style.textAlign = 'left'; // This is a CSS \"reset\"\n this.graphDiv.style.position = 'relative';\n enclosing.appendChild(this.graphDiv);\n\n // Create the canvas for interactive parts of the chart.\n this.canvas_ = utils.createCanvas();\n this.canvas_.style.position = \"absolute\";\n\n // ... and for static parts of the chart.\n this.hidden_ = this.createPlotKitCanvas_(this.canvas_);\n\n this.canvas_ctx_ = utils.getContext(this.canvas_);\n this.hidden_ctx_ = utils.getContext(this.hidden_);\n\n this.resizeElements_();\n\n // The interactive parts of the graph are drawn on top of the chart.\n this.graphDiv.appendChild(this.hidden_);\n this.graphDiv.appendChild(this.canvas_);\n this.mouseEventElement_ = this.createMouseEventElement_();\n\n // Create the grapher\n this.layout_ = new _dygraphLayout2['default'](this);\n\n var dygraph = this;\n\n this.mouseMoveHandler_ = function (e) {\n dygraph.mouseMove_(e);\n };\n\n this.mouseOutHandler_ = function (e) {\n // The mouse has left the chart if:\n // 1. e.target is inside the chart\n // 2. e.relatedTarget is outside the chart\n var target = e.target || e.fromElement;\n var relatedTarget = e.relatedTarget || e.toElement;\n if (utils.isNodeContainedBy(target, dygraph.graphDiv) && !utils.isNodeContainedBy(relatedTarget, dygraph.graphDiv)) {\n dygraph.mouseOut_(e);\n }\n };\n\n this.addAndTrackEvent(window, 'mouseout', this.mouseOutHandler_);\n this.addAndTrackEvent(this.mouseEventElement_, 'mousemove', this.mouseMoveHandler_);\n\n // Don't recreate and register the resize handler on subsequent calls.\n // This happens when the graph is resized.\n if (!this.resizeHandler_) {\n this.resizeHandler_ = function (e) {\n dygraph.resize();\n };\n\n // Update when the window is resized.\n // TODO(danvk): drop frames depending on complexity of the chart.\n this.addAndTrackEvent(window, 'resize', this.resizeHandler_);\n }\n};\n\nDygraph.prototype.resizeElements_ = function () {\n this.graphDiv.style.width = this.width_ + \"px\";\n this.graphDiv.style.height = this.height_ + \"px\";\n\n var pixelRatioOption = this.getNumericOption('pixelRatio');\n\n var canvasScale = pixelRatioOption || utils.getContextPixelRatio(this.canvas_ctx_);\n this.canvas_.width = this.width_ * canvasScale;\n this.canvas_.height = this.height_ * canvasScale;\n this.canvas_.style.width = this.width_ + \"px\"; // for IE\n this.canvas_.style.height = this.height_ + \"px\"; // for IE\n if (canvasScale !== 1) {\n this.canvas_ctx_.scale(canvasScale, canvasScale);\n }\n\n var hiddenScale = pixelRatioOption || utils.getContextPixelRatio(this.hidden_ctx_);\n this.hidden_.width = this.width_ * hiddenScale;\n this.hidden_.height = this.height_ * hiddenScale;\n this.hidden_.style.width = this.width_ + \"px\"; // for IE\n this.hidden_.style.height = this.height_ + \"px\"; // for IE\n if (hiddenScale !== 1) {\n this.hidden_ctx_.scale(hiddenScale, hiddenScale);\n }\n};\n\n/**\n * Detach DOM elements in the dygraph and null out all data references.\n * Calling this when you're done with a dygraph can dramatically reduce memory\n * usage. See, e.g., the tests/perf.html example.\n */\nDygraph.prototype.destroy = function () {\n this.canvas_ctx_.restore();\n this.hidden_ctx_.restore();\n\n // Destroy any plugins, in the reverse order that they were registered.\n for (var i = this.plugins_.length - 1; i >= 0; i--) {\n var p = this.plugins_.pop();\n if (p.plugin.destroy) p.plugin.destroy();\n }\n\n var removeRecursive = function removeRecursive(node) {\n while (node.hasChildNodes()) {\n removeRecursive(node.firstChild);\n node.removeChild(node.firstChild);\n }\n };\n\n this.removeTrackedEvents_();\n\n // remove mouse event handlers (This may not be necessary anymore)\n utils.removeEvent(window, 'mouseout', this.mouseOutHandler_);\n utils.removeEvent(this.mouseEventElement_, 'mousemove', this.mouseMoveHandler_);\n\n // remove window handlers\n utils.removeEvent(window, 'resize', this.resizeHandler_);\n this.resizeHandler_ = null;\n\n removeRecursive(this.maindiv_);\n\n var nullOut = function nullOut(obj) {\n for (var n in obj) {\n if (typeof obj[n] === 'object') {\n obj[n] = null;\n }\n }\n };\n // These may not all be necessary, but it can't hurt...\n nullOut(this.layout_);\n nullOut(this.plotter_);\n nullOut(this);\n};\n\n/**\n * Creates the canvas on which the chart will be drawn. Only the Renderer ever\n * draws on this particular canvas. All Dygraph work (i.e. drawing hover dots\n * or the zoom rectangles) is done on this.canvas_.\n * @param {Object} canvas The Dygraph canvas over which to overlay the plot\n * @return {Object} The newly-created canvas\n * @private\n */\nDygraph.prototype.createPlotKitCanvas_ = function (canvas) {\n var h = utils.createCanvas();\n h.style.position = \"absolute\";\n // TODO(danvk): h should be offset from canvas. canvas needs to include\n // some extra area to make it easier to zoom in on the far left and far\n // right. h needs to be precisely the plot area, so that clipping occurs.\n h.style.top = canvas.style.top;\n h.style.left = canvas.style.left;\n h.width = this.width_;\n h.height = this.height_;\n h.style.width = this.width_ + \"px\"; // for IE\n h.style.height = this.height_ + \"px\"; // for IE\n return h;\n};\n\n/**\n * Creates an overlay element used to handle mouse events.\n * @return {Object} The mouse event element.\n * @private\n */\nDygraph.prototype.createMouseEventElement_ = function () {\n return this.canvas_;\n};\n\n/**\n * Generate a set of distinct colors for the data series. This is done with a\n * color wheel. Saturation/Value are customizable, and the hue is\n * equally-spaced around the color wheel. If a custom set of colors is\n * specified, that is used instead.\n * @private\n */\nDygraph.prototype.setColors_ = function () {\n var labels = this.getLabels();\n var num = labels.length - 1;\n this.colors_ = [];\n this.colorsMap_ = {};\n\n // These are used for when no custom colors are specified.\n var sat = this.getNumericOption('colorSaturation') || 1.0;\n var val = this.getNumericOption('colorValue') || 0.5;\n var half = Math.ceil(num / 2);\n\n var colors = this.getOption('colors');\n var visibility = this.visibility();\n for (var i = 0; i < num; i++) {\n if (!visibility[i]) {\n continue;\n }\n var label = labels[i + 1];\n var colorStr = this.attributes_.getForSeries('color', label);\n if (!colorStr) {\n if (colors) {\n colorStr = colors[i % colors.length];\n } else {\n // alternate colors for high contrast.\n var idx = i % 2 ? half + (i + 1) / 2 : Math.ceil((i + 1) / 2);\n var hue = 1.0 * idx / (1 + num);\n colorStr = utils.hsvToRGB(hue, sat, val);\n }\n }\n this.colors_.push(colorStr);\n this.colorsMap_[label] = colorStr;\n }\n};\n\n/**\n * Return the list of colors. This is either the list of colors passed in the\n * attributes or the autogenerated list of rgb(r,g,b) strings.\n * This does not return colors for invisible series.\n * @return {Array.} The list of colors.\n */\nDygraph.prototype.getColors = function () {\n return this.colors_;\n};\n\n/**\n * Returns a few attributes of a series, i.e. its color, its visibility, which\n * axis it's assigned to, and its column in the original data.\n * Returns null if the series does not exist.\n * Otherwise, returns an object with column, visibility, color and axis properties.\n * The \"axis\" property will be set to 1 for y1 and 2 for y2.\n * The \"column\" property can be fed back into getValue(row, column) to get\n * values for this series.\n */\nDygraph.prototype.getPropertiesForSeries = function (series_name) {\n var idx = -1;\n var labels = this.getLabels();\n for (var i = 1; i < labels.length; i++) {\n if (labels[i] == series_name) {\n idx = i;\n break;\n }\n }\n if (idx == -1) return null;\n\n return {\n name: series_name,\n column: idx,\n visible: this.visibility()[idx - 1],\n color: this.colorsMap_[series_name],\n axis: 1 + this.attributes_.axisForSeries(series_name)\n };\n};\n\n/**\n * Create the text box to adjust the averaging period\n * @private\n */\nDygraph.prototype.createRollInterface_ = function () {\n var _this = this;\n\n // Create a roller if one doesn't exist already.\n var roller = this.roller_;\n if (!roller) {\n this.roller_ = roller = document.createElement(\"input\");\n roller.type = \"text\";\n roller.style.display = \"none\";\n roller.className = 'dygraph-roller';\n this.graphDiv.appendChild(roller);\n }\n\n var display = this.getBooleanOption('showRoller') ? 'block' : 'none';\n\n var area = this.getArea();\n var textAttr = {\n \"top\": area.y + area.h - 25 + \"px\",\n \"left\": area.x + 1 + \"px\",\n \"display\": display\n };\n roller.size = \"2\";\n roller.value = this.rollPeriod_;\n utils.update(roller.style, textAttr);\n\n roller.onchange = function () {\n return _this.adjustRoll(roller.value);\n };\n};\n\n/**\n * Set up all the mouse handlers needed to capture dragging behavior for zoom\n * events.\n * @private\n */\nDygraph.prototype.createDragInterface_ = function () {\n var context = {\n // Tracks whether the mouse is down right now\n isZooming: false,\n isPanning: false, // is this drag part of a pan?\n is2DPan: false, // if so, is that pan 1- or 2-dimensional?\n dragStartX: null, // pixel coordinates\n dragStartY: null, // pixel coordinates\n dragEndX: null, // pixel coordinates\n dragEndY: null, // pixel coordinates\n dragDirection: null,\n prevEndX: null, // pixel coordinates\n prevEndY: null, // pixel coordinates\n prevDragDirection: null,\n cancelNextDblclick: false, // see comment in dygraph-interaction-model.js\n\n // The value on the left side of the graph when a pan operation starts.\n initialLeftmostDate: null,\n\n // The number of units each pixel spans. (This won't be valid for log\n // scales)\n xUnitsPerPixel: null,\n\n // TODO(danvk): update this comment\n // The range in second/value units that the viewport encompasses during a\n // panning operation.\n dateRange: null,\n\n // Top-left corner of the canvas, in DOM coords\n // TODO(konigsberg): Rename topLeftCanvasX, topLeftCanvasY.\n px: 0,\n py: 0,\n\n // Values for use with panEdgeFraction, which limit how far outside the\n // graph's data boundaries it can be panned.\n boundedDates: null, // [minDate, maxDate]\n boundedValues: null, // [[minValue, maxValue] ...]\n\n // We cover iframes during mouse interactions. See comments in\n // dygraph-utils.js for more info on why this is a good idea.\n tarp: new _iframeTarp2['default'](),\n\n // contextB is the same thing as this context object but renamed.\n initializeMouseDown: function initializeMouseDown(event, g, contextB) {\n // prevents mouse drags from selecting page text.\n if (event.preventDefault) {\n event.preventDefault(); // Firefox, Chrome, etc.\n } else {\n event.returnValue = false; // IE\n event.cancelBubble = true;\n }\n\n var canvasPos = utils.findPos(g.canvas_);\n contextB.px = canvasPos.x;\n contextB.py = canvasPos.y;\n contextB.dragStartX = utils.dragGetX_(event, contextB);\n contextB.dragStartY = utils.dragGetY_(event, contextB);\n contextB.cancelNextDblclick = false;\n contextB.tarp.cover();\n },\n destroy: function destroy() {\n var context = this;\n if (context.isZooming || context.isPanning) {\n context.isZooming = false;\n context.dragStartX = null;\n context.dragStartY = null;\n }\n\n if (context.isPanning) {\n context.isPanning = false;\n context.draggingDate = null;\n context.dateRange = null;\n for (var i = 0; i < self.axes_.length; i++) {\n delete self.axes_[i].draggingValue;\n delete self.axes_[i].dragValueRange;\n }\n }\n\n context.tarp.uncover();\n }\n };\n\n var interactionModel = this.getOption(\"interactionModel\");\n\n // Self is the graph.\n var self = this;\n\n // Function that binds the graph and context to the handler.\n var bindHandler = function bindHandler(handler) {\n return function (event) {\n handler(event, self, context);\n };\n };\n\n for (var eventName in interactionModel) {\n if (!interactionModel.hasOwnProperty(eventName)) continue;\n this.addAndTrackEvent(this.mouseEventElement_, eventName, bindHandler(interactionModel[eventName]));\n }\n\n // If the user releases the mouse button during a drag, but not over the\n // canvas, then it doesn't count as a zooming action.\n if (!interactionModel.willDestroyContextMyself) {\n var mouseUpHandler = function mouseUpHandler(event) {\n context.destroy();\n };\n\n this.addAndTrackEvent(document, 'mouseup', mouseUpHandler);\n }\n};\n\n/**\n * Draw a gray zoom rectangle over the desired area of the canvas. Also clears\n * up any previous zoom rectangles that were drawn. This could be optimized to\n * avoid extra redrawing, but it's tricky to avoid interactions with the status\n * dots.\n *\n * @param {number} direction the direction of the zoom rectangle. Acceptable\n * values are utils.HORIZONTAL and utils.VERTICAL.\n * @param {number} startX The X position where the drag started, in canvas\n * coordinates.\n * @param {number} endX The current X position of the drag, in canvas coords.\n * @param {number} startY The Y position where the drag started, in canvas\n * coordinates.\n * @param {number} endY The current Y position of the drag, in canvas coords.\n * @param {number} prevDirection the value of direction on the previous call to\n * this function. Used to avoid excess redrawing\n * @param {number} prevEndX The value of endX on the previous call to this\n * function. Used to avoid excess redrawing\n * @param {number} prevEndY The value of endY on the previous call to this\n * function. Used to avoid excess redrawing\n * @private\n */\nDygraph.prototype.drawZoomRect_ = function (direction, startX, endX, startY, endY, prevDirection, prevEndX, prevEndY) {\n var ctx = this.canvas_ctx_;\n\n // Clean up from the previous rect if necessary\n if (prevDirection == utils.HORIZONTAL) {\n ctx.clearRect(Math.min(startX, prevEndX), this.layout_.getPlotArea().y, Math.abs(startX - prevEndX), this.layout_.getPlotArea().h);\n } else if (prevDirection == utils.VERTICAL) {\n ctx.clearRect(this.layout_.getPlotArea().x, Math.min(startY, prevEndY), this.layout_.getPlotArea().w, Math.abs(startY - prevEndY));\n }\n\n // Draw a light-grey rectangle to show the new viewing area\n if (direction == utils.HORIZONTAL) {\n if (endX && startX) {\n ctx.fillStyle = \"rgba(128,128,128,0.33)\";\n ctx.fillRect(Math.min(startX, endX), this.layout_.getPlotArea().y, Math.abs(endX - startX), this.layout_.getPlotArea().h);\n }\n } else if (direction == utils.VERTICAL) {\n if (endY && startY) {\n ctx.fillStyle = \"rgba(128,128,128,0.33)\";\n ctx.fillRect(this.layout_.getPlotArea().x, Math.min(startY, endY), this.layout_.getPlotArea().w, Math.abs(endY - startY));\n }\n }\n};\n\n/**\n * Clear the zoom rectangle (and perform no zoom).\n * @private\n */\nDygraph.prototype.clearZoomRect_ = function () {\n this.currentZoomRectArgs_ = null;\n this.canvas_ctx_.clearRect(0, 0, this.width_, this.height_);\n};\n\n/**\n * Zoom to something containing [lowX, highX]. These are pixel coordinates in\n * the canvas. The exact zoom window may be slightly larger if there are no data\n * points near lowX or highX. Don't confuse this function with doZoomXDates,\n * which accepts dates that match the raw data. This function redraws the graph.\n *\n * @param {number} lowX The leftmost pixel value that should be visible.\n * @param {number} highX The rightmost pixel value that should be visible.\n * @private\n */\nDygraph.prototype.doZoomX_ = function (lowX, highX) {\n this.currentZoomRectArgs_ = null;\n // Find the earliest and latest dates contained in this canvasx range.\n // Convert the call to date ranges of the raw data.\n var minDate = this.toDataXCoord(lowX);\n var maxDate = this.toDataXCoord(highX);\n this.doZoomXDates_(minDate, maxDate);\n};\n\n/**\n * Zoom to something containing [minDate, maxDate] values. Don't confuse this\n * method with doZoomX which accepts pixel coordinates. This function redraws\n * the graph.\n *\n * @param {number} minDate The minimum date that should be visible.\n * @param {number} maxDate The maximum date that should be visible.\n * @private\n */\nDygraph.prototype.doZoomXDates_ = function (minDate, maxDate) {\n var _this2 = this;\n\n // TODO(danvk): when xAxisRange is null (i.e. \"fit to data\", the animation\n // can produce strange effects. Rather than the x-axis transitioning slowly\n // between values, it can jerk around.)\n var old_window = this.xAxisRange();\n var new_window = [minDate, maxDate];\n var zoomCallback = this.getFunctionOption('zoomCallback');\n this.doAnimatedZoom(old_window, new_window, null, null, function () {\n if (zoomCallback) {\n zoomCallback.call(_this2, minDate, maxDate, _this2.yAxisRanges());\n }\n });\n};\n\n/**\n * Zoom to something containing [lowY, highY]. These are pixel coordinates in\n * the canvas. This function redraws the graph.\n *\n * @param {number} lowY The topmost pixel value that should be visible.\n * @param {number} highY The lowest pixel value that should be visible.\n * @private\n */\nDygraph.prototype.doZoomY_ = function (lowY, highY) {\n var _this3 = this;\n\n this.currentZoomRectArgs_ = null;\n // Find the highest and lowest values in pixel range for each axis.\n // Note that lowY (in pixels) corresponds to the max Value (in data coords).\n // This is because pixels increase as you go down on the screen, whereas data\n // coordinates increase as you go up the screen.\n var oldValueRanges = this.yAxisRanges();\n var newValueRanges = [];\n for (var i = 0; i < this.axes_.length; i++) {\n var hi = this.toDataYCoord(lowY, i);\n var low = this.toDataYCoord(highY, i);\n newValueRanges.push([low, hi]);\n }\n\n var zoomCallback = this.getFunctionOption('zoomCallback');\n this.doAnimatedZoom(null, null, oldValueRanges, newValueRanges, function () {\n if (zoomCallback) {\n var _xAxisRange = _this3.xAxisRange();\n\n var _xAxisRange2 = _slicedToArray(_xAxisRange, 2);\n\n var minX = _xAxisRange2[0];\n var maxX = _xAxisRange2[1];\n\n zoomCallback.call(_this3, minX, maxX, _this3.yAxisRanges());\n }\n });\n};\n\n/**\n * Transition function to use in animations. Returns values between 0.0\n * (totally old values) and 1.0 (totally new values) for each frame.\n * @private\n */\nDygraph.zoomAnimationFunction = function (frame, numFrames) {\n var k = 1.5;\n return (1.0 - Math.pow(k, -frame)) / (1.0 - Math.pow(k, -numFrames));\n};\n\n/**\n * Reset the zoom to the original view coordinates. This is the same as\n * double-clicking on the graph.\n */\nDygraph.prototype.resetZoom = function () {\n var _this4 = this;\n\n var dirtyX = this.isZoomed('x');\n var dirtyY = this.isZoomed('y');\n var dirty = dirtyX || dirtyY;\n\n // Clear any selection, since it's likely to be drawn in the wrong place.\n this.clearSelection();\n\n if (!dirty) return;\n\n // Calculate extremes to avoid lack of padding on reset.\n\n var _xAxisExtremes = this.xAxisExtremes();\n\n var _xAxisExtremes2 = _slicedToArray(_xAxisExtremes, 2);\n\n var minDate = _xAxisExtremes2[0];\n var maxDate = _xAxisExtremes2[1];\n\n var animatedZooms = this.getBooleanOption('animatedZooms');\n var zoomCallback = this.getFunctionOption('zoomCallback');\n\n // TODO(danvk): merge this block w/ the code below.\n // TODO(danvk): factor out a generic, public zoomTo method.\n if (!animatedZooms) {\n this.dateWindow_ = null;\n this.axes_.forEach(function (axis) {\n if (axis.valueRange) delete axis.valueRange;\n });\n\n this.drawGraph_();\n if (zoomCallback) {\n zoomCallback.call(this, minDate, maxDate, this.yAxisRanges());\n }\n return;\n }\n\n var oldWindow = null,\n newWindow = null,\n oldValueRanges = null,\n newValueRanges = null;\n if (dirtyX) {\n oldWindow = this.xAxisRange();\n newWindow = [minDate, maxDate];\n }\n\n if (dirtyY) {\n oldValueRanges = this.yAxisRanges();\n newValueRanges = this.yAxisExtremes();\n }\n\n this.doAnimatedZoom(oldWindow, newWindow, oldValueRanges, newValueRanges, function () {\n _this4.dateWindow_ = null;\n _this4.axes_.forEach(function (axis) {\n if (axis.valueRange) delete axis.valueRange;\n });\n if (zoomCallback) {\n zoomCallback.call(_this4, minDate, maxDate, _this4.yAxisRanges());\n }\n });\n};\n\n/**\n * Combined animation logic for all zoom functions.\n * either the x parameters or y parameters may be null.\n * @private\n */\nDygraph.prototype.doAnimatedZoom = function (oldXRange, newXRange, oldYRanges, newYRanges, callback) {\n var _this5 = this;\n\n var steps = this.getBooleanOption(\"animatedZooms\") ? Dygraph.ANIMATION_STEPS : 1;\n\n var windows = [];\n var valueRanges = [];\n var step, frac;\n\n if (oldXRange !== null && newXRange !== null) {\n for (step = 1; step <= steps; step++) {\n frac = Dygraph.zoomAnimationFunction(step, steps);\n windows[step - 1] = [oldXRange[0] * (1 - frac) + frac * newXRange[0], oldXRange[1] * (1 - frac) + frac * newXRange[1]];\n }\n }\n\n if (oldYRanges !== null && newYRanges !== null) {\n for (step = 1; step <= steps; step++) {\n frac = Dygraph.zoomAnimationFunction(step, steps);\n var thisRange = [];\n for (var j = 0; j < this.axes_.length; j++) {\n thisRange.push([oldYRanges[j][0] * (1 - frac) + frac * newYRanges[j][0], oldYRanges[j][1] * (1 - frac) + frac * newYRanges[j][1]]);\n }\n valueRanges[step - 1] = thisRange;\n }\n }\n\n utils.repeatAndCleanup(function (step) {\n if (valueRanges.length) {\n for (var i = 0; i < _this5.axes_.length; i++) {\n var w = valueRanges[step][i];\n _this5.axes_[i].valueRange = [w[0], w[1]];\n }\n }\n if (windows.length) {\n _this5.dateWindow_ = windows[step];\n }\n _this5.drawGraph_();\n }, steps, Dygraph.ANIMATION_DURATION / steps, callback);\n};\n\n/**\n * Get the current graph's area object.\n *\n * Returns: {x, y, w, h}\n */\nDygraph.prototype.getArea = function () {\n return this.plotter_.area;\n};\n\n/**\n * Convert a mouse event to DOM coordinates relative to the graph origin.\n *\n * Returns a two-element array: [X, Y].\n */\nDygraph.prototype.eventToDomCoords = function (event) {\n if (event.offsetX && event.offsetY) {\n return [event.offsetX, event.offsetY];\n } else {\n var eventElementPos = utils.findPos(this.mouseEventElement_);\n var canvasx = utils.pageX(event) - eventElementPos.x;\n var canvasy = utils.pageY(event) - eventElementPos.y;\n return [canvasx, canvasy];\n }\n};\n\n/**\n * Given a canvas X coordinate, find the closest row.\n * @param {number} domX graph-relative DOM X coordinate\n * Returns {number} row number.\n * @private\n */\nDygraph.prototype.findClosestRow = function (domX) {\n var minDistX = Infinity;\n var closestRow = -1;\n var sets = this.layout_.points;\n for (var i = 0; i < sets.length; i++) {\n var points = sets[i];\n var len = points.length;\n for (var j = 0; j < len; j++) {\n var point = points[j];\n if (!utils.isValidPoint(point, true)) continue;\n var dist = Math.abs(point.canvasx - domX);\n if (dist < minDistX) {\n minDistX = dist;\n closestRow = point.idx;\n }\n }\n }\n\n return closestRow;\n};\n\n/**\n * Given canvas X,Y coordinates, find the closest point.\n *\n * This finds the individual data point across all visible series\n * that's closest to the supplied DOM coordinates using the standard\n * Euclidean X,Y distance.\n *\n * @param {number} domX graph-relative DOM X coordinate\n * @param {number} domY graph-relative DOM Y coordinate\n * Returns: {row, seriesName, point}\n * @private\n */\nDygraph.prototype.findClosestPoint = function (domX, domY) {\n var minDist = Infinity;\n var dist, dx, dy, point, closestPoint, closestSeries, closestRow;\n for (var setIdx = this.layout_.points.length - 1; setIdx >= 0; --setIdx) {\n var points = this.layout_.points[setIdx];\n for (var i = 0; i < points.length; ++i) {\n point = points[i];\n if (!utils.isValidPoint(point)) continue;\n dx = point.canvasx - domX;\n dy = point.canvasy - domY;\n dist = dx * dx + dy * dy;\n if (dist < minDist) {\n minDist = dist;\n closestPoint = point;\n closestSeries = setIdx;\n closestRow = point.idx;\n }\n }\n }\n var name = this.layout_.setNames[closestSeries];\n return {\n row: closestRow,\n seriesName: name,\n point: closestPoint\n };\n};\n\n/**\n * Given canvas X,Y coordinates, find the touched area in a stacked graph.\n *\n * This first finds the X data point closest to the supplied DOM X coordinate,\n * then finds the series which puts the Y coordinate on top of its filled area,\n * using linear interpolation between adjacent point pairs.\n *\n * @param {number} domX graph-relative DOM X coordinate\n * @param {number} domY graph-relative DOM Y coordinate\n * Returns: {row, seriesName, point}\n * @private\n */\nDygraph.prototype.findStackedPoint = function (domX, domY) {\n var row = this.findClosestRow(domX);\n var closestPoint, closestSeries;\n for (var setIdx = 0; setIdx < this.layout_.points.length; ++setIdx) {\n var boundary = this.getLeftBoundary_(setIdx);\n var rowIdx = row - boundary;\n var points = this.layout_.points[setIdx];\n if (rowIdx >= points.length) continue;\n var p1 = points[rowIdx];\n if (!utils.isValidPoint(p1)) continue;\n var py = p1.canvasy;\n if (domX > p1.canvasx && rowIdx + 1 < points.length) {\n // interpolate series Y value using next point\n var p2 = points[rowIdx + 1];\n if (utils.isValidPoint(p2)) {\n var dx = p2.canvasx - p1.canvasx;\n if (dx > 0) {\n var r = (domX - p1.canvasx) / dx;\n py += r * (p2.canvasy - p1.canvasy);\n }\n }\n } else if (domX < p1.canvasx && rowIdx > 0) {\n // interpolate series Y value using previous point\n var p0 = points[rowIdx - 1];\n if (utils.isValidPoint(p0)) {\n var dx = p1.canvasx - p0.canvasx;\n if (dx > 0) {\n var r = (p1.canvasx - domX) / dx;\n py += r * (p0.canvasy - p1.canvasy);\n }\n }\n }\n // Stop if the point (domX, py) is above this series' upper edge\n if (setIdx === 0 || py < domY) {\n closestPoint = p1;\n closestSeries = setIdx;\n }\n }\n var name = this.layout_.setNames[closestSeries];\n return {\n row: row,\n seriesName: name,\n point: closestPoint\n };\n};\n\n/**\n * When the mouse moves in the canvas, display information about a nearby data\n * point and draw dots over those points in the data series. This function\n * takes care of cleanup of previously-drawn dots.\n * @param {Object} event The mousemove event from the browser.\n * @private\n */\nDygraph.prototype.mouseMove_ = function (event) {\n // This prevents JS errors when mousing over the canvas before data loads.\n var points = this.layout_.points;\n if (points === undefined || points === null) return;\n\n var canvasCoords = this.eventToDomCoords(event);\n var canvasx = canvasCoords[0];\n var canvasy = canvasCoords[1];\n\n var highlightSeriesOpts = this.getOption(\"highlightSeriesOpts\");\n var selectionChanged = false;\n if (highlightSeriesOpts && !this.isSeriesLocked()) {\n var closest;\n if (this.getBooleanOption(\"stackedGraph\")) {\n closest = this.findStackedPoint(canvasx, canvasy);\n } else {\n closest = this.findClosestPoint(canvasx, canvasy);\n }\n selectionChanged = this.setSelection(closest.row, closest.seriesName);\n } else {\n var idx = this.findClosestRow(canvasx);\n selectionChanged = this.setSelection(idx);\n }\n\n var callback = this.getFunctionOption(\"highlightCallback\");\n if (callback && selectionChanged) {\n callback.call(this, event, this.lastx_, this.selPoints_, this.lastRow_, this.highlightSet_);\n }\n};\n\n/**\n * Fetch left offset from the specified set index or if not passed, the\n * first defined boundaryIds record (see bug #236).\n * @private\n */\nDygraph.prototype.getLeftBoundary_ = function (setIdx) {\n if (this.boundaryIds_[setIdx]) {\n return this.boundaryIds_[setIdx][0];\n } else {\n for (var i = 0; i < this.boundaryIds_.length; i++) {\n if (this.boundaryIds_[i] !== undefined) {\n return this.boundaryIds_[i][0];\n }\n }\n return 0;\n }\n};\n\nDygraph.prototype.animateSelection_ = function (direction) {\n var totalSteps = 10;\n var millis = 30;\n if (this.fadeLevel === undefined) this.fadeLevel = 0;\n if (this.animateId === undefined) this.animateId = 0;\n var start = this.fadeLevel;\n var steps = direction < 0 ? start : totalSteps - start;\n if (steps <= 0) {\n if (this.fadeLevel) {\n this.updateSelection_(1.0);\n }\n return;\n }\n\n var thisId = ++this.animateId;\n var that = this;\n var cleanupIfClearing = function cleanupIfClearing() {\n // if we haven't reached fadeLevel 0 in the max frame time,\n // ensure that the clear happens and just go to 0\n if (that.fadeLevel !== 0 && direction < 0) {\n that.fadeLevel = 0;\n that.clearSelection();\n }\n };\n utils.repeatAndCleanup(function (n) {\n // ignore simultaneous animations\n if (that.animateId != thisId) return;\n\n that.fadeLevel += direction;\n if (that.fadeLevel === 0) {\n that.clearSelection();\n } else {\n that.updateSelection_(that.fadeLevel / totalSteps);\n }\n }, steps, millis, cleanupIfClearing);\n};\n\n/**\n * Draw dots over the selectied points in the data series. This function\n * takes care of cleanup of previously-drawn dots.\n * @private\n */\nDygraph.prototype.updateSelection_ = function (opt_animFraction) {\n /*var defaultPrevented = */\n this.cascadeEvents_('select', {\n selectedRow: this.lastRow_ === -1 ? undefined : this.lastRow_,\n selectedX: this.lastx_ === -1 ? undefined : this.lastx_,\n selectedPoints: this.selPoints_\n });\n // TODO(danvk): use defaultPrevented here?\n\n // Clear the previously drawn vertical, if there is one\n var i;\n var ctx = this.canvas_ctx_;\n if (this.getOption('highlightSeriesOpts')) {\n ctx.clearRect(0, 0, this.width_, this.height_);\n var alpha = 1.0 - this.getNumericOption('highlightSeriesBackgroundAlpha');\n var backgroundColor = utils.toRGB_(this.getOption('highlightSeriesBackgroundColor'));\n\n if (alpha) {\n // Activating background fade includes an animation effect for a gradual\n // fade. TODO(klausw): make this independently configurable if it causes\n // issues? Use a shared preference to control animations?\n var animateBackgroundFade = true;\n if (animateBackgroundFade) {\n if (opt_animFraction === undefined) {\n // start a new animation\n this.animateSelection_(1);\n return;\n }\n alpha *= opt_animFraction;\n }\n ctx.fillStyle = 'rgba(' + backgroundColor.r + ',' + backgroundColor.g + ',' + backgroundColor.b + ',' + alpha + ')';\n ctx.fillRect(0, 0, this.width_, this.height_);\n }\n\n // Redraw only the highlighted series in the interactive canvas (not the\n // static plot canvas, which is where series are usually drawn).\n this.plotter_._renderLineChart(this.highlightSet_, ctx);\n } else if (this.previousVerticalX_ >= 0) {\n // Determine the maximum highlight circle size.\n var maxCircleSize = 0;\n var labels = this.attr_('labels');\n for (i = 1; i < labels.length; i++) {\n var r = this.getNumericOption('highlightCircleSize', labels[i]);\n if (r > maxCircleSize) maxCircleSize = r;\n }\n var px = this.previousVerticalX_;\n ctx.clearRect(px - maxCircleSize - 1, 0, 2 * maxCircleSize + 2, this.height_);\n }\n\n if (this.selPoints_.length > 0) {\n // Draw colored circles over the center of each selected point\n var canvasx = this.selPoints_[0].canvasx;\n ctx.save();\n for (i = 0; i < this.selPoints_.length; i++) {\n var pt = this.selPoints_[i];\n if (isNaN(pt.canvasy)) continue;\n\n var circleSize = this.getNumericOption('highlightCircleSize', pt.name);\n var callback = this.getFunctionOption(\"drawHighlightPointCallback\", pt.name);\n var color = this.plotter_.colors[pt.name];\n if (!callback) {\n callback = utils.Circles.DEFAULT;\n }\n ctx.lineWidth = this.getNumericOption('strokeWidth', pt.name);\n ctx.strokeStyle = color;\n ctx.fillStyle = color;\n callback.call(this, this, pt.name, ctx, canvasx, pt.canvasy, color, circleSize, pt.idx);\n }\n ctx.restore();\n\n this.previousVerticalX_ = canvasx;\n }\n};\n\n/**\n * Manually set the selected points and display information about them in the\n * legend. The selection can be cleared using clearSelection() and queried\n * using getSelection().\n *\n * To set a selected series but not a selected point, call setSelection with\n * row=false and the selected series name.\n *\n * @param {number} row Row number that should be highlighted (i.e. appear with\n * hover dots on the chart).\n * @param {seriesName} optional series name to highlight that series with the\n * the highlightSeriesOpts setting.\n * @param { locked } optional If true, keep seriesName selected when mousing\n * over the graph, disabling closest-series highlighting. Call clearSelection()\n * to unlock it.\n */\nDygraph.prototype.setSelection = function (row, opt_seriesName, opt_locked) {\n // Extract the points we've selected\n this.selPoints_ = [];\n\n var changed = false;\n if (row !== false && row >= 0) {\n if (row != this.lastRow_) changed = true;\n this.lastRow_ = row;\n for (var setIdx = 0; setIdx < this.layout_.points.length; ++setIdx) {\n var points = this.layout_.points[setIdx];\n // Check if the point at the appropriate index is the point we're looking\n // for. If it is, just use it, otherwise search the array for a point\n // in the proper place.\n var setRow = row - this.getLeftBoundary_(setIdx);\n if (setRow >= 0 && setRow < points.length && points[setRow].idx == row) {\n var point = points[setRow];\n if (point.yval !== null) this.selPoints_.push(point);\n } else {\n for (var pointIdx = 0; pointIdx < points.length; ++pointIdx) {\n var point = points[pointIdx];\n if (point.idx == row) {\n if (point.yval !== null) {\n this.selPoints_.push(point);\n }\n break;\n }\n }\n }\n }\n } else {\n if (this.lastRow_ >= 0) changed = true;\n this.lastRow_ = -1;\n }\n\n if (this.selPoints_.length) {\n this.lastx_ = this.selPoints_[0].xval;\n } else {\n this.lastx_ = -1;\n }\n\n if (opt_seriesName !== undefined) {\n if (this.highlightSet_ !== opt_seriesName) changed = true;\n this.highlightSet_ = opt_seriesName;\n }\n\n if (opt_locked !== undefined) {\n this.lockedSet_ = opt_locked;\n }\n\n if (changed) {\n this.updateSelection_(undefined);\n }\n return changed;\n};\n\n/**\n * The mouse has left the canvas. Clear out whatever artifacts remain\n * @param {Object} event the mouseout event from the browser.\n * @private\n */\nDygraph.prototype.mouseOut_ = function (event) {\n if (this.getFunctionOption(\"unhighlightCallback\")) {\n this.getFunctionOption(\"unhighlightCallback\").call(this, event);\n }\n\n if (this.getBooleanOption(\"hideOverlayOnMouseOut\") && !this.lockedSet_) {\n this.clearSelection();\n }\n};\n\n/**\n * Clears the current selection (i.e. points that were highlighted by moving\n * the mouse over the chart).\n */\nDygraph.prototype.clearSelection = function () {\n this.cascadeEvents_('deselect', {});\n\n this.lockedSet_ = false;\n // Get rid of the overlay data\n if (this.fadeLevel) {\n this.animateSelection_(-1);\n return;\n }\n this.canvas_ctx_.clearRect(0, 0, this.width_, this.height_);\n this.fadeLevel = 0;\n this.selPoints_ = [];\n this.lastx_ = -1;\n this.lastRow_ = -1;\n this.highlightSet_ = null;\n};\n\n/**\n * Returns the number of the currently selected row. To get data for this row,\n * you can use the getValue method.\n * @return {number} row number, or -1 if nothing is selected\n */\nDygraph.prototype.getSelection = function () {\n if (!this.selPoints_ || this.selPoints_.length < 1) {\n return -1;\n }\n\n for (var setIdx = 0; setIdx < this.layout_.points.length; setIdx++) {\n var points = this.layout_.points[setIdx];\n for (var row = 0; row < points.length; row++) {\n if (points[row].x == this.selPoints_[0].x) {\n return points[row].idx;\n }\n }\n }\n return -1;\n};\n\n/**\n * Returns the name of the currently-highlighted series.\n * Only available when the highlightSeriesOpts option is in use.\n */\nDygraph.prototype.getHighlightSeries = function () {\n return this.highlightSet_;\n};\n\n/**\n * Returns true if the currently-highlighted series was locked\n * via setSelection(..., seriesName, true).\n */\nDygraph.prototype.isSeriesLocked = function () {\n return this.lockedSet_;\n};\n\n/**\n * Fires when there's data available to be graphed.\n * @param {string} data Raw CSV data to be plotted\n * @private\n */\nDygraph.prototype.loadedEvent_ = function (data) {\n this.rawData_ = this.parseCSV_(data);\n this.cascadeDataDidUpdateEvent_();\n this.predraw_();\n};\n\n/**\n * Add ticks on the x-axis representing years, months, quarters, weeks, or days\n * @private\n */\nDygraph.prototype.addXTicks_ = function () {\n // Determine the correct ticks scale on the x-axis: quarterly, monthly, ...\n var range;\n if (this.dateWindow_) {\n range = [this.dateWindow_[0], this.dateWindow_[1]];\n } else {\n range = this.xAxisExtremes();\n }\n\n var xAxisOptionsView = this.optionsViewForAxis_('x');\n var xTicks = xAxisOptionsView('ticker')(range[0], range[1], this.plotter_.area.w, // TODO(danvk): should be area.width\n xAxisOptionsView, this);\n // var msg = 'ticker(' + range[0] + ', ' + range[1] + ', ' + this.width_ + ', ' + this.attr_('pixelsPerXLabel') + ') -> ' + JSON.stringify(xTicks);\n // console.log(msg);\n this.layout_.setXTicks(xTicks);\n};\n\n/**\n * Returns the correct handler class for the currently set options.\n * @private\n */\nDygraph.prototype.getHandlerClass_ = function () {\n var handlerClass;\n if (this.attr_('dataHandler')) {\n handlerClass = this.attr_('dataHandler');\n } else if (this.fractions_) {\n if (this.getBooleanOption('errorBars')) {\n handlerClass = _datahandlerBarsFractions2['default'];\n } else {\n handlerClass = _datahandlerDefaultFractions2['default'];\n }\n } else if (this.getBooleanOption('customBars')) {\n handlerClass = _datahandlerBarsCustom2['default'];\n } else if (this.getBooleanOption('errorBars')) {\n handlerClass = _datahandlerBarsError2['default'];\n } else {\n handlerClass = _datahandlerDefault2['default'];\n }\n return handlerClass;\n};\n\n/**\n * @private\n * This function is called once when the chart's data is changed or the options\n * dictionary is updated. It is _not_ called when the user pans or zooms. The\n * idea is that values derived from the chart's data can be computed here,\n * rather than every time the chart is drawn. This includes things like the\n * number of axes, rolling averages, etc.\n */\nDygraph.prototype.predraw_ = function () {\n var start = new Date();\n\n // Create the correct dataHandler\n this.dataHandler_ = new (this.getHandlerClass_())();\n\n this.layout_.computePlotArea();\n\n // TODO(danvk): move more computations out of drawGraph_ and into here.\n this.computeYAxes_();\n\n if (!this.is_initial_draw_) {\n this.canvas_ctx_.restore();\n this.hidden_ctx_.restore();\n }\n\n this.canvas_ctx_.save();\n this.hidden_ctx_.save();\n\n // Create a new plotter.\n this.plotter_ = new _dygraphCanvas2['default'](this, this.hidden_, this.hidden_ctx_, this.layout_);\n\n // The roller sits in the bottom left corner of the chart. We don't know where\n // this will be until the options are available, so it's positioned here.\n this.createRollInterface_();\n\n this.cascadeEvents_('predraw');\n\n // Convert the raw data (a 2D array) into the internal format and compute\n // rolling averages.\n this.rolledSeries_ = [null]; // x-axis is the first series and it's special\n for (var i = 1; i < this.numColumns(); i++) {\n // var logScale = this.attr_('logscale', i); // TODO(klausw): this looks wrong // konigsberg thinks so too.\n var series = this.dataHandler_.extractSeries(this.rawData_, i, this.attributes_);\n if (this.rollPeriod_ > 1) {\n series = this.dataHandler_.rollingAverage(series, this.rollPeriod_, this.attributes_);\n }\n\n this.rolledSeries_.push(series);\n }\n\n // If the data or options have changed, then we'd better redraw.\n this.drawGraph_();\n\n // This is used to determine whether to do various animations.\n var end = new Date();\n this.drawingTimeMs_ = end - start;\n};\n\n/**\n * Point structure.\n *\n * xval_* and yval_* are the original unscaled data values,\n * while x_* and y_* are scaled to the range (0.0-1.0) for plotting.\n * yval_stacked is the cumulative Y value used for stacking graphs,\n * and bottom/top/minus/plus are used for error bar graphs.\n *\n * @typedef {{\n * idx: number,\n * name: string,\n * x: ?number,\n * xval: ?number,\n * y_bottom: ?number,\n * y: ?number,\n * y_stacked: ?number,\n * y_top: ?number,\n * yval_minus: ?number,\n * yval: ?number,\n * yval_plus: ?number,\n * yval_stacked\n * }}\n */\nDygraph.PointType = undefined;\n\n/**\n * Calculates point stacking for stackedGraph=true.\n *\n * For stacking purposes, interpolate or extend neighboring data across\n * NaN values based on stackedGraphNaNFill settings. This is for display\n * only, the underlying data value as shown in the legend remains NaN.\n *\n * @param {Array.} points Point array for a single series.\n * Updates each Point's yval_stacked property.\n * @param {Array.} cumulativeYval Accumulated top-of-graph stacked Y\n * values for the series seen so far. Index is the row number. Updated\n * based on the current series's values.\n * @param {Array.} seriesExtremes Min and max values, updated\n * to reflect the stacked values.\n * @param {string} fillMethod Interpolation method, one of 'all', 'inside', or\n * 'none'.\n * @private\n */\nDygraph.stackPoints_ = function (points, cumulativeYval, seriesExtremes, fillMethod) {\n var lastXval = null;\n var prevPoint = null;\n var nextPoint = null;\n var nextPointIdx = -1;\n\n // Find the next stackable point starting from the given index.\n var updateNextPoint = function updateNextPoint(idx) {\n // If we've previously found a non-NaN point and haven't gone past it yet,\n // just use that.\n if (nextPointIdx >= idx) return;\n\n // We haven't found a non-NaN point yet or have moved past it,\n // look towards the right to find a non-NaN point.\n for (var j = idx; j < points.length; ++j) {\n // Clear out a previously-found point (if any) since it's no longer\n // valid, we shouldn't use it for interpolation anymore.\n nextPoint = null;\n if (!isNaN(points[j].yval) && points[j].yval !== null) {\n nextPointIdx = j;\n nextPoint = points[j];\n break;\n }\n }\n };\n\n for (var i = 0; i < points.length; ++i) {\n var point = points[i];\n var xval = point.xval;\n if (cumulativeYval[xval] === undefined) {\n cumulativeYval[xval] = 0;\n }\n\n var actualYval = point.yval;\n if (isNaN(actualYval) || actualYval === null) {\n if (fillMethod == 'none') {\n actualYval = 0;\n } else {\n // Interpolate/extend for stacking purposes if possible.\n updateNextPoint(i);\n if (prevPoint && nextPoint && fillMethod != 'none') {\n // Use linear interpolation between prevPoint and nextPoint.\n actualYval = prevPoint.yval + (nextPoint.yval - prevPoint.yval) * ((xval - prevPoint.xval) / (nextPoint.xval - prevPoint.xval));\n } else if (prevPoint && fillMethod == 'all') {\n actualYval = prevPoint.yval;\n } else if (nextPoint && fillMethod == 'all') {\n actualYval = nextPoint.yval;\n } else {\n actualYval = 0;\n }\n }\n } else {\n prevPoint = point;\n }\n\n var stackedYval = cumulativeYval[xval];\n if (lastXval != xval) {\n // If an x-value is repeated, we ignore the duplicates.\n stackedYval += actualYval;\n cumulativeYval[xval] = stackedYval;\n }\n lastXval = xval;\n\n point.yval_stacked = stackedYval;\n\n if (stackedYval > seriesExtremes[1]) {\n seriesExtremes[1] = stackedYval;\n }\n if (stackedYval < seriesExtremes[0]) {\n seriesExtremes[0] = stackedYval;\n }\n }\n};\n\n/**\n * Loop over all fields and create datasets, calculating extreme y-values for\n * each series and extreme x-indices as we go.\n *\n * dateWindow is passed in as an explicit parameter so that we can compute\n * extreme values \"speculatively\", i.e. without actually setting state on the\n * dygraph.\n *\n * @param {Array.)>>} rolledSeries, where\n * rolledSeries[seriesIndex][row] = raw point, where\n * seriesIndex is the column number starting with 1, and\n * rawPoint is [x,y] or [x, [y, err]] or [x, [y, yminus, yplus]].\n * @param {?Array.} dateWindow [xmin, xmax] pair, or null.\n * @return {{\n * points: Array.>,\n * seriesExtremes: Array.>,\n * boundaryIds: Array.}}\n * @private\n */\nDygraph.prototype.gatherDatasets_ = function (rolledSeries, dateWindow) {\n var boundaryIds = [];\n var points = [];\n var cumulativeYval = []; // For stacked series.\n var extremes = {}; // series name -> [low, high]\n var seriesIdx, sampleIdx;\n var firstIdx, lastIdx;\n var axisIdx;\n\n // Loop over the fields (series). Go from the last to the first,\n // because if they're stacked that's how we accumulate the values.\n var num_series = rolledSeries.length - 1;\n var series;\n for (seriesIdx = num_series; seriesIdx >= 1; seriesIdx--) {\n if (!this.visibility()[seriesIdx - 1]) continue;\n\n // Prune down to the desired range, if necessary (for zooming)\n // Because there can be lines going to points outside of the visible area,\n // we actually prune to visible points, plus one on either side.\n if (dateWindow) {\n series = rolledSeries[seriesIdx];\n var low = dateWindow[0];\n var high = dateWindow[1];\n\n // TODO(danvk): do binary search instead of linear search.\n // TODO(danvk): pass firstIdx and lastIdx directly to the renderer.\n firstIdx = null;\n lastIdx = null;\n for (sampleIdx = 0; sampleIdx < series.length; sampleIdx++) {\n if (series[sampleIdx][0] >= low && firstIdx === null) {\n firstIdx = sampleIdx;\n }\n if (series[sampleIdx][0] <= high) {\n lastIdx = sampleIdx;\n }\n }\n\n if (firstIdx === null) firstIdx = 0;\n var correctedFirstIdx = firstIdx;\n var isInvalidValue = true;\n while (isInvalidValue && correctedFirstIdx > 0) {\n correctedFirstIdx--;\n // check if the y value is null.\n isInvalidValue = series[correctedFirstIdx][1] === null;\n }\n\n if (lastIdx === null) lastIdx = series.length - 1;\n var correctedLastIdx = lastIdx;\n isInvalidValue = true;\n while (isInvalidValue && correctedLastIdx < series.length - 1) {\n correctedLastIdx++;\n isInvalidValue = series[correctedLastIdx][1] === null;\n }\n\n if (correctedFirstIdx !== firstIdx) {\n firstIdx = correctedFirstIdx;\n }\n if (correctedLastIdx !== lastIdx) {\n lastIdx = correctedLastIdx;\n }\n\n boundaryIds[seriesIdx - 1] = [firstIdx, lastIdx];\n\n // .slice's end is exclusive, we want to include lastIdx.\n series = series.slice(firstIdx, lastIdx + 1);\n } else {\n series = rolledSeries[seriesIdx];\n boundaryIds[seriesIdx - 1] = [0, series.length - 1];\n }\n\n var seriesName = this.attr_(\"labels\")[seriesIdx];\n var seriesExtremes = this.dataHandler_.getExtremeYValues(series, dateWindow, this.getBooleanOption(\"stepPlot\", seriesName));\n\n var seriesPoints = this.dataHandler_.seriesToPoints(series, seriesName, boundaryIds[seriesIdx - 1][0]);\n\n if (this.getBooleanOption(\"stackedGraph\")) {\n axisIdx = this.attributes_.axisForSeries(seriesName);\n if (cumulativeYval[axisIdx] === undefined) {\n cumulativeYval[axisIdx] = [];\n }\n Dygraph.stackPoints_(seriesPoints, cumulativeYval[axisIdx], seriesExtremes, this.getBooleanOption(\"stackedGraphNaNFill\"));\n }\n\n extremes[seriesName] = seriesExtremes;\n points[seriesIdx] = seriesPoints;\n }\n\n return { points: points, extremes: extremes, boundaryIds: boundaryIds };\n};\n\n/**\n * Update the graph with new data. This method is called when the viewing area\n * has changed. If the underlying data or options have changed, predraw_ will\n * be called before drawGraph_ is called.\n *\n * @private\n */\nDygraph.prototype.drawGraph_ = function () {\n var start = new Date();\n\n // This is used to set the second parameter to drawCallback, below.\n var is_initial_draw = this.is_initial_draw_;\n this.is_initial_draw_ = false;\n\n this.layout_.removeAllDatasets();\n this.setColors_();\n this.attrs_.pointSize = 0.5 * this.getNumericOption('highlightCircleSize');\n\n var packed = this.gatherDatasets_(this.rolledSeries_, this.dateWindow_);\n var points = packed.points;\n var extremes = packed.extremes;\n this.boundaryIds_ = packed.boundaryIds;\n\n this.setIndexByName_ = {};\n var labels = this.attr_(\"labels\");\n var dataIdx = 0;\n for (var i = 1; i < points.length; i++) {\n if (!this.visibility()[i - 1]) continue;\n this.layout_.addDataset(labels[i], points[i]);\n this.datasetIndex_[i] = dataIdx++;\n }\n for (var i = 0; i < labels.length; i++) {\n this.setIndexByName_[labels[i]] = i;\n }\n\n this.computeYAxisRanges_(extremes);\n this.layout_.setYAxes(this.axes_);\n\n this.addXTicks_();\n\n // Tell PlotKit to use this new data and render itself\n this.layout_.evaluate();\n this.renderGraph_(is_initial_draw);\n\n if (this.getStringOption(\"timingName\")) {\n var end = new Date();\n console.log(this.getStringOption(\"timingName\") + \" - drawGraph: \" + (end - start) + \"ms\");\n }\n};\n\n/**\n * This does the work of drawing the chart. It assumes that the layout and axis\n * scales have already been set (e.g. by predraw_).\n *\n * @private\n */\nDygraph.prototype.renderGraph_ = function (is_initial_draw) {\n this.cascadeEvents_('clearChart');\n this.plotter_.clear();\n\n var underlayCallback = this.getFunctionOption('underlayCallback');\n if (underlayCallback) {\n // NOTE: we pass the dygraph object to this callback twice to avoid breaking\n // users who expect a deprecated form of this callback.\n underlayCallback.call(this, this.hidden_ctx_, this.layout_.getPlotArea(), this, this);\n }\n\n var e = {\n canvas: this.hidden_,\n drawingContext: this.hidden_ctx_\n };\n this.cascadeEvents_('willDrawChart', e);\n this.plotter_.render();\n this.cascadeEvents_('didDrawChart', e);\n this.lastRow_ = -1; // because plugins/legend.js clears the legend\n\n // TODO(danvk): is this a performance bottleneck when panning?\n // The interaction canvas should already be empty in that situation.\n this.canvas_.getContext('2d').clearRect(0, 0, this.width_, this.height_);\n\n var drawCallback = this.getFunctionOption(\"drawCallback\");\n if (drawCallback !== null) {\n drawCallback.call(this, this, is_initial_draw);\n }\n if (is_initial_draw) {\n this.readyFired_ = true;\n while (this.readyFns_.length > 0) {\n var fn = this.readyFns_.pop();\n fn(this);\n }\n }\n};\n\n/**\n * @private\n * Determine properties of the y-axes which are independent of the data\n * currently being displayed. This includes things like the number of axes and\n * the style of the axes. It does not include the range of each axis and its\n * tick marks.\n * This fills in this.axes_.\n * axes_ = [ { options } ]\n * indices are into the axes_ array.\n */\nDygraph.prototype.computeYAxes_ = function () {\n var axis, index, opts, v;\n\n // this.axes_ doesn't match this.attributes_.axes_.options. It's used for\n // data computation as well as options storage.\n // Go through once and add all the axes.\n this.axes_ = [];\n\n for (axis = 0; axis < this.attributes_.numAxes(); axis++) {\n // Add a new axis, making a copy of its per-axis options.\n opts = { g: this };\n utils.update(opts, this.attributes_.axisOptions(axis));\n this.axes_[axis] = opts;\n }\n\n for (axis = 0; axis < this.axes_.length; axis++) {\n if (axis === 0) {\n opts = this.optionsViewForAxis_('y' + (axis ? '2' : ''));\n v = opts(\"valueRange\");\n if (v) this.axes_[axis].valueRange = v;\n } else {\n // To keep old behavior\n var axes = this.user_attrs_.axes;\n if (axes && axes.y2) {\n v = axes.y2.valueRange;\n if (v) this.axes_[axis].valueRange = v;\n }\n }\n }\n};\n\n/**\n * Returns the number of y-axes on the chart.\n * @return {number} the number of axes.\n */\nDygraph.prototype.numAxes = function () {\n return this.attributes_.numAxes();\n};\n\n/**\n * @private\n * Returns axis properties for the given series.\n * @param {string} setName The name of the series for which to get axis\n * properties, e.g. 'Y1'.\n * @return {Object} The axis properties.\n */\nDygraph.prototype.axisPropertiesForSeries = function (series) {\n // TODO(danvk): handle errors.\n return this.axes_[this.attributes_.axisForSeries(series)];\n};\n\n/**\n * @private\n * Determine the value range and tick marks for each axis.\n * @param {Object} extremes A mapping from seriesName -> [low, high]\n * This fills in the valueRange and ticks fields in each entry of this.axes_.\n */\nDygraph.prototype.computeYAxisRanges_ = function (extremes) {\n var isNullUndefinedOrNaN = function isNullUndefinedOrNaN(num) {\n return isNaN(parseFloat(num));\n };\n var numAxes = this.attributes_.numAxes();\n var ypadCompat, span, series, ypad;\n\n var p_axis;\n\n // Compute extreme values, a span and tick marks for each axis.\n for (var i = 0; i < numAxes; i++) {\n var axis = this.axes_[i];\n var logscale = this.attributes_.getForAxis(\"logscale\", i);\n var includeZero = this.attributes_.getForAxis(\"includeZero\", i);\n var independentTicks = this.attributes_.getForAxis(\"independentTicks\", i);\n series = this.attributes_.seriesForAxis(i);\n\n // Add some padding. This supports two Y padding operation modes:\n //\n // - backwards compatible (yRangePad not set):\n // 10% padding for automatic Y ranges, but not for user-supplied\n // ranges, and move a close-to-zero edge to zero, since drawing at the edge\n // results in invisible lines. Unfortunately lines drawn at the edge of a\n // user-supplied range will still be invisible. If logscale is\n // set, add a variable amount of padding at the top but\n // none at the bottom.\n //\n // - new-style (yRangePad set by the user):\n // always add the specified Y padding.\n //\n ypadCompat = true;\n ypad = 0.1; // add 10%\n var yRangePad = this.getNumericOption('yRangePad');\n if (yRangePad !== null) {\n ypadCompat = false;\n // Convert pixel padding to ratio\n ypad = yRangePad / this.plotter_.area.h;\n }\n\n if (series.length === 0) {\n // If no series are defined or visible then use a reasonable default\n axis.extremeRange = [0, 1];\n } else {\n // Calculate the extremes of extremes.\n var minY = Infinity; // extremes[series[0]][0];\n var maxY = -Infinity; // extremes[series[0]][1];\n var extremeMinY, extremeMaxY;\n\n for (var j = 0; j < series.length; j++) {\n // this skips invisible series\n if (!extremes.hasOwnProperty(series[j])) continue;\n\n // Only use valid extremes to stop null data series' from corrupting the scale.\n extremeMinY = extremes[series[j]][0];\n if (extremeMinY !== null) {\n minY = Math.min(extremeMinY, minY);\n }\n extremeMaxY = extremes[series[j]][1];\n if (extremeMaxY !== null) {\n maxY = Math.max(extremeMaxY, maxY);\n }\n }\n\n // Include zero if requested by the user.\n if (includeZero && !logscale) {\n if (minY > 0) minY = 0;\n if (maxY < 0) maxY = 0;\n }\n\n // Ensure we have a valid scale, otherwise default to [0, 1] for safety.\n if (minY == Infinity) minY = 0;\n if (maxY == -Infinity) maxY = 1;\n\n span = maxY - minY;\n // special case: if we have no sense of scale, center on the sole value.\n if (span === 0) {\n if (maxY !== 0) {\n span = Math.abs(maxY);\n } else {\n // ... and if the sole value is zero, use range 0-1.\n maxY = 1;\n span = 1;\n }\n }\n\n var maxAxisY = maxY,\n minAxisY = minY;\n if (ypadCompat) {\n if (logscale) {\n maxAxisY = maxY + ypad * span;\n minAxisY = minY;\n } else {\n maxAxisY = maxY + ypad * span;\n minAxisY = minY - ypad * span;\n\n // Backwards-compatible behavior: Move the span to start or end at zero if it's\n // close to zero.\n if (minAxisY < 0 && minY >= 0) minAxisY = 0;\n if (maxAxisY > 0 && maxY <= 0) maxAxisY = 0;\n }\n }\n axis.extremeRange = [minAxisY, maxAxisY];\n }\n if (axis.valueRange) {\n // This is a user-set value range for this axis.\n var y0 = isNullUndefinedOrNaN(axis.valueRange[0]) ? axis.extremeRange[0] : axis.valueRange[0];\n var y1 = isNullUndefinedOrNaN(axis.valueRange[1]) ? axis.extremeRange[1] : axis.valueRange[1];\n axis.computedValueRange = [y0, y1];\n } else {\n axis.computedValueRange = axis.extremeRange;\n }\n if (!ypadCompat) {\n // When using yRangePad, adjust the upper/lower bounds to add\n // padding unless the user has zoomed/panned the Y axis range.\n if (logscale) {\n y0 = axis.computedValueRange[0];\n y1 = axis.computedValueRange[1];\n var y0pct = ypad / (2 * ypad - 1);\n var y1pct = (ypad - 1) / (2 * ypad - 1);\n axis.computedValueRange[0] = utils.logRangeFraction(y0, y1, y0pct);\n axis.computedValueRange[1] = utils.logRangeFraction(y0, y1, y1pct);\n } else {\n y0 = axis.computedValueRange[0];\n y1 = axis.computedValueRange[1];\n span = y1 - y0;\n axis.computedValueRange[0] = y0 - span * ypad;\n axis.computedValueRange[1] = y1 + span * ypad;\n }\n }\n\n if (independentTicks) {\n axis.independentTicks = independentTicks;\n var opts = this.optionsViewForAxis_('y' + (i ? '2' : ''));\n var ticker = opts('ticker');\n axis.ticks = ticker(axis.computedValueRange[0], axis.computedValueRange[1], this.plotter_.area.h, opts, this);\n // Define the first independent axis as primary axis.\n if (!p_axis) p_axis = axis;\n }\n }\n if (p_axis === undefined) {\n throw \"Configuration Error: At least one axis has to have the \\\"independentTicks\\\" option activated.\";\n }\n // Add ticks. By default, all axes inherit the tick positions of the\n // primary axis. However, if an axis is specifically marked as having\n // independent ticks, then that is permissible as well.\n for (var i = 0; i < numAxes; i++) {\n var axis = this.axes_[i];\n\n if (!axis.independentTicks) {\n var opts = this.optionsViewForAxis_('y' + (i ? '2' : ''));\n var ticker = opts('ticker');\n var p_ticks = p_axis.ticks;\n var p_scale = p_axis.computedValueRange[1] - p_axis.computedValueRange[0];\n var scale = axis.computedValueRange[1] - axis.computedValueRange[0];\n var tick_values = [];\n for (var k = 0; k < p_ticks.length; k++) {\n var y_frac = (p_ticks[k].v - p_axis.computedValueRange[0]) / p_scale;\n var y_val = axis.computedValueRange[0] + y_frac * scale;\n tick_values.push(y_val);\n }\n\n axis.ticks = ticker(axis.computedValueRange[0], axis.computedValueRange[1], this.plotter_.area.h, opts, this, tick_values);\n }\n }\n};\n\n/**\n * Detects the type of the str (date or numeric) and sets the various\n * formatting attributes in this.attrs_ based on this type.\n * @param {string} str An x value.\n * @private\n */\nDygraph.prototype.detectTypeFromString_ = function (str) {\n var isDate = false;\n var dashPos = str.indexOf('-'); // could be 2006-01-01 _or_ 1.0e-2\n if (dashPos > 0 && str[dashPos - 1] != 'e' && str[dashPos - 1] != 'E' || str.indexOf('/') >= 0 || isNaN(parseFloat(str))) {\n isDate = true;\n } else if (str.length == 8 && str > '19700101' && str < '20371231') {\n // TODO(danvk): remove support for this format.\n isDate = true;\n }\n\n this.setXAxisOptions_(isDate);\n};\n\nDygraph.prototype.setXAxisOptions_ = function (isDate) {\n if (isDate) {\n this.attrs_.xValueParser = utils.dateParser;\n this.attrs_.axes.x.valueFormatter = utils.dateValueFormatter;\n this.attrs_.axes.x.ticker = DygraphTickers.dateTicker;\n this.attrs_.axes.x.axisLabelFormatter = utils.dateAxisLabelFormatter;\n } else {\n /** @private (shut up, jsdoc!) */\n this.attrs_.xValueParser = function (x) {\n return parseFloat(x);\n };\n // TODO(danvk): use Dygraph.numberValueFormatter here?\n /** @private (shut up, jsdoc!) */\n this.attrs_.axes.x.valueFormatter = function (x) {\n return x;\n };\n this.attrs_.axes.x.ticker = DygraphTickers.numericTicks;\n this.attrs_.axes.x.axisLabelFormatter = this.attrs_.axes.x.valueFormatter;\n }\n};\n\n/**\n * @private\n * Parses a string in a special csv format. We expect a csv file where each\n * line is a date point, and the first field in each line is the date string.\n * We also expect that all remaining fields represent series.\n * if the errorBars attribute is set, then interpret the fields as:\n * date, series1, stddev1, series2, stddev2, ...\n * @param {[Object]} data See above.\n *\n * @return [Object] An array with one entry for each row. These entries\n * are an array of cells in that row. The first entry is the parsed x-value for\n * the row. The second, third, etc. are the y-values. These can take on one of\n * three forms, depending on the CSV and constructor parameters:\n * 1. numeric value\n * 2. [ value, stddev ]\n * 3. [ low value, center value, high value ]\n */\nDygraph.prototype.parseCSV_ = function (data) {\n var ret = [];\n var line_delimiter = utils.detectLineDelimiter(data);\n var lines = data.split(line_delimiter || \"\\n\");\n var vals, j;\n\n // Use the default delimiter or fall back to a tab if that makes sense.\n var delim = this.getStringOption('delimiter');\n if (lines[0].indexOf(delim) == -1 && lines[0].indexOf('\\t') >= 0) {\n delim = '\\t';\n }\n\n var start = 0;\n if (!('labels' in this.user_attrs_)) {\n // User hasn't explicitly set labels, so they're (presumably) in the CSV.\n start = 1;\n this.attrs_.labels = lines[0].split(delim); // NOTE: _not_ user_attrs_.\n this.attributes_.reparseSeries();\n }\n var line_no = 0;\n\n var xParser;\n var defaultParserSet = false; // attempt to auto-detect x value type\n var expectedCols = this.attr_(\"labels\").length;\n var outOfOrder = false;\n for (var i = start; i < lines.length; i++) {\n var line = lines[i];\n line_no = i;\n if (line.length === 0) continue; // skip blank lines\n if (line[0] == '#') continue; // skip comment lines\n var inFields = line.split(delim);\n if (inFields.length < 2) continue;\n\n var fields = [];\n if (!defaultParserSet) {\n this.detectTypeFromString_(inFields[0]);\n xParser = this.getFunctionOption(\"xValueParser\");\n defaultParserSet = true;\n }\n fields[0] = xParser(inFields[0], this);\n\n // If fractions are expected, parse the numbers as \"A/B\"\n if (this.fractions_) {\n for (j = 1; j < inFields.length; j++) {\n // TODO(danvk): figure out an appropriate way to flag parse errors.\n vals = inFields[j].split(\"/\");\n if (vals.length != 2) {\n console.error('Expected fractional \"num/den\" values in CSV data ' + \"but found a value '\" + inFields[j] + \"' on line \" + (1 + i) + \" ('\" + line + \"') which is not of this form.\");\n fields[j] = [0, 0];\n } else {\n fields[j] = [utils.parseFloat_(vals[0], i, line), utils.parseFloat_(vals[1], i, line)];\n }\n }\n } else if (this.getBooleanOption(\"errorBars\")) {\n // If there are error bars, values are (value, stddev) pairs\n if (inFields.length % 2 != 1) {\n console.error('Expected alternating (value, stdev.) pairs in CSV data ' + 'but line ' + (1 + i) + ' has an odd number of values (' + (inFields.length - 1) + \"): '\" + line + \"'\");\n }\n for (j = 1; j < inFields.length; j += 2) {\n fields[(j + 1) / 2] = [utils.parseFloat_(inFields[j], i, line), utils.parseFloat_(inFields[j + 1], i, line)];\n }\n } else if (this.getBooleanOption(\"customBars\")) {\n // Bars are a low;center;high tuple\n for (j = 1; j < inFields.length; j++) {\n var val = inFields[j];\n if (/^ *$/.test(val)) {\n fields[j] = [null, null, null];\n } else {\n vals = val.split(\";\");\n if (vals.length == 3) {\n fields[j] = [utils.parseFloat_(vals[0], i, line), utils.parseFloat_(vals[1], i, line), utils.parseFloat_(vals[2], i, line)];\n } else {\n console.warn('When using customBars, values must be either blank ' + 'or \"low;center;high\" tuples (got \"' + val + '\" on line ' + (1 + i));\n }\n }\n }\n } else {\n // Values are just numbers\n for (j = 1; j < inFields.length; j++) {\n fields[j] = utils.parseFloat_(inFields[j], i, line);\n }\n }\n if (ret.length > 0 && fields[0] < ret[ret.length - 1][0]) {\n outOfOrder = true;\n }\n\n if (fields.length != expectedCols) {\n console.error(\"Number of columns in line \" + i + \" (\" + fields.length + \") does not agree with number of labels (\" + expectedCols + \") \" + line);\n }\n\n // If the user specified the 'labels' option and none of the cells of the\n // first row parsed correctly, then they probably double-specified the\n // labels. We go with the values set in the option, discard this row and\n // log a warning to the JS console.\n if (i === 0 && this.attr_('labels')) {\n var all_null = true;\n for (j = 0; all_null && j < fields.length; j++) {\n if (fields[j]) all_null = false;\n }\n if (all_null) {\n console.warn(\"The dygraphs 'labels' option is set, but the first row \" + \"of CSV data ('\" + line + \"') appears to also contain \" + \"labels. Will drop the CSV labels and use the option \" + \"labels.\");\n continue;\n }\n }\n ret.push(fields);\n }\n\n if (outOfOrder) {\n console.warn(\"CSV is out of order; order it correctly to speed loading.\");\n ret.sort(function (a, b) {\n return a[0] - b[0];\n });\n }\n\n return ret;\n};\n\n// In native format, all values must be dates or numbers.\n// This check isn't perfect but will catch most mistaken uses of strings.\nfunction validateNativeFormat(data) {\n var firstRow = data[0];\n var firstX = firstRow[0];\n if (typeof firstX !== 'number' && !utils.isDateLike(firstX)) {\n throw new Error('Expected number or date but got ' + typeof firstX + ': ' + firstX + '.');\n }\n for (var i = 1; i < firstRow.length; i++) {\n var val = firstRow[i];\n if (val === null || val === undefined) continue;\n if (typeof val === 'number') continue;\n if (utils.isArrayLike(val)) continue; // e.g. error bars or custom bars.\n throw new Error('Expected number or array but got ' + typeof val + ': ' + val + '.');\n }\n}\n\n/**\n * The user has provided their data as a pre-packaged JS array. If the x values\n * are numeric, this is the same as dygraphs' internal format. If the x values\n * are dates, we need to convert them from Date objects to ms since epoch.\n * @param {!Array} data\n * @return {Object} data with numeric x values.\n * @private\n */\nDygraph.prototype.parseArray_ = function (data) {\n // Peek at the first x value to see if it's numeric.\n if (data.length === 0) {\n console.error(\"Can't plot empty data set\");\n return null;\n }\n if (data[0].length === 0) {\n console.error(\"Data set cannot contain an empty row\");\n return null;\n }\n\n validateNativeFormat(data);\n\n var i;\n if (this.attr_(\"labels\") === null) {\n console.warn(\"Using default labels. Set labels explicitly via 'labels' \" + \"in the options parameter\");\n this.attrs_.labels = [\"X\"];\n for (i = 1; i < data[0].length; i++) {\n this.attrs_.labels.push(\"Y\" + i); // Not user_attrs_.\n }\n this.attributes_.reparseSeries();\n } else {\n var num_labels = this.attr_(\"labels\");\n if (num_labels.length != data[0].length) {\n console.error(\"Mismatch between number of labels (\" + num_labels + \")\" + \" and number of columns in array (\" + data[0].length + \")\");\n return null;\n }\n }\n\n if (utils.isDateLike(data[0][0])) {\n // Some intelligent defaults for a date x-axis.\n this.attrs_.axes.x.valueFormatter = utils.dateValueFormatter;\n this.attrs_.axes.x.ticker = DygraphTickers.dateTicker;\n this.attrs_.axes.x.axisLabelFormatter = utils.dateAxisLabelFormatter;\n\n // Assume they're all dates.\n var parsedData = utils.clone(data);\n for (i = 0; i < data.length; i++) {\n if (parsedData[i].length === 0) {\n console.error(\"Row \" + (1 + i) + \" of data is empty\");\n return null;\n }\n if (parsedData[i][0] === null || typeof parsedData[i][0].getTime != 'function' || isNaN(parsedData[i][0].getTime())) {\n console.error(\"x value in row \" + (1 + i) + \" is not a Date\");\n return null;\n }\n parsedData[i][0] = parsedData[i][0].getTime();\n }\n return parsedData;\n } else {\n // Some intelligent defaults for a numeric x-axis.\n /** @private (shut up, jsdoc!) */\n this.attrs_.axes.x.valueFormatter = function (x) {\n return x;\n };\n this.attrs_.axes.x.ticker = DygraphTickers.numericTicks;\n this.attrs_.axes.x.axisLabelFormatter = utils.numberAxisLabelFormatter;\n return data;\n }\n};\n\n/**\n * Parses a DataTable object from gviz.\n * The data is expected to have a first column that is either a date or a\n * number. All subsequent columns must be numbers. If there is a clear mismatch\n * between this.xValueParser_ and the type of the first column, it will be\n * fixed. Fills out rawData_.\n * @param {!google.visualization.DataTable} data See above.\n * @private\n */\nDygraph.prototype.parseDataTable_ = function (data) {\n var shortTextForAnnotationNum = function shortTextForAnnotationNum(num) {\n // converts [0-9]+ [A-Z][a-z]*\n // example: 0=A, 1=B, 25=Z, 26=Aa, 27=Ab\n // and continues like.. Ba Bb .. Za .. Zz..Aaa...Zzz Aaaa Zzzz\n var shortText = String.fromCharCode(65 /* A */ + num % 26);\n num = Math.floor(num / 26);\n while (num > 0) {\n shortText = String.fromCharCode(65 /* A */ + (num - 1) % 26) + shortText.toLowerCase();\n num = Math.floor((num - 1) / 26);\n }\n return shortText;\n };\n\n var cols = data.getNumberOfColumns();\n var rows = data.getNumberOfRows();\n\n var indepType = data.getColumnType(0);\n if (indepType == 'date' || indepType == 'datetime') {\n this.attrs_.xValueParser = utils.dateParser;\n this.attrs_.axes.x.valueFormatter = utils.dateValueFormatter;\n this.attrs_.axes.x.ticker = DygraphTickers.dateTicker;\n this.attrs_.axes.x.axisLabelFormatter = utils.dateAxisLabelFormatter;\n } else if (indepType == 'number') {\n this.attrs_.xValueParser = function (x) {\n return parseFloat(x);\n };\n this.attrs_.axes.x.valueFormatter = function (x) {\n return x;\n };\n this.attrs_.axes.x.ticker = DygraphTickers.numericTicks;\n this.attrs_.axes.x.axisLabelFormatter = this.attrs_.axes.x.valueFormatter;\n } else {\n throw new Error(\"only 'date', 'datetime' and 'number' types are supported \" + \"for column 1 of DataTable input (Got '\" + indepType + \"')\");\n }\n\n // Array of the column indices which contain data (and not annotations).\n var colIdx = [];\n var annotationCols = {}; // data index -> [annotation cols]\n var hasAnnotations = false;\n var i, j;\n for (i = 1; i < cols; i++) {\n var type = data.getColumnType(i);\n if (type == 'number') {\n colIdx.push(i);\n } else if (type == 'string' && this.getBooleanOption('displayAnnotations')) {\n // This is OK -- it's an annotation column.\n var dataIdx = colIdx[colIdx.length - 1];\n if (!annotationCols.hasOwnProperty(dataIdx)) {\n annotationCols[dataIdx] = [i];\n } else {\n annotationCols[dataIdx].push(i);\n }\n hasAnnotations = true;\n } else {\n throw new Error(\"Only 'number' is supported as a dependent type with Gviz.\" + \" 'string' is only supported if displayAnnotations is true\");\n }\n }\n\n // Read column labels\n // TODO(danvk): add support back for errorBars\n var labels = [data.getColumnLabel(0)];\n for (i = 0; i < colIdx.length; i++) {\n labels.push(data.getColumnLabel(colIdx[i]));\n if (this.getBooleanOption(\"errorBars\")) i += 1;\n }\n this.attrs_.labels = labels;\n cols = labels.length;\n\n var ret = [];\n var outOfOrder = false;\n var annotations = [];\n for (i = 0; i < rows; i++) {\n var row = [];\n if (typeof data.getValue(i, 0) === 'undefined' || data.getValue(i, 0) === null) {\n console.warn(\"Ignoring row \" + i + \" of DataTable because of undefined or null first column.\");\n continue;\n }\n\n if (indepType == 'date' || indepType == 'datetime') {\n row.push(data.getValue(i, 0).getTime());\n } else {\n row.push(data.getValue(i, 0));\n }\n if (!this.getBooleanOption(\"errorBars\")) {\n for (j = 0; j < colIdx.length; j++) {\n var col = colIdx[j];\n row.push(data.getValue(i, col));\n if (hasAnnotations && annotationCols.hasOwnProperty(col) && data.getValue(i, annotationCols[col][0]) !== null) {\n var ann = {};\n ann.series = data.getColumnLabel(col);\n ann.xval = row[0];\n ann.shortText = shortTextForAnnotationNum(annotations.length);\n ann.text = '';\n for (var k = 0; k < annotationCols[col].length; k++) {\n if (k) ann.text += \"\\n\";\n ann.text += data.getValue(i, annotationCols[col][k]);\n }\n annotations.push(ann);\n }\n }\n\n // Strip out infinities, which give dygraphs problems later on.\n for (j = 0; j < row.length; j++) {\n if (!isFinite(row[j])) row[j] = null;\n }\n } else {\n for (j = 0; j < cols - 1; j++) {\n row.push([data.getValue(i, 1 + 2 * j), data.getValue(i, 2 + 2 * j)]);\n }\n }\n if (ret.length > 0 && row[0] < ret[ret.length - 1][0]) {\n outOfOrder = true;\n }\n ret.push(row);\n }\n\n if (outOfOrder) {\n console.warn(\"DataTable is out of order; order it correctly to speed loading.\");\n ret.sort(function (a, b) {\n return a[0] - b[0];\n });\n }\n this.rawData_ = ret;\n\n if (annotations.length > 0) {\n this.setAnnotations(annotations, true);\n }\n this.attributes_.reparseSeries();\n};\n\n/**\n * Signals to plugins that the chart data has updated.\n * This happens after the data has updated but before the chart has redrawn.\n * @private\n */\nDygraph.prototype.cascadeDataDidUpdateEvent_ = function () {\n // TODO(danvk): there are some issues checking xAxisRange() and using\n // toDomCoords from handlers of this event. The visible range should be set\n // when the chart is drawn, not derived from the data.\n this.cascadeEvents_('dataDidUpdate', {});\n};\n\n/**\n * Get the CSV data. If it's in a function, call that function. If it's in a\n * file, do an XMLHttpRequest to get it.\n * @private\n */\nDygraph.prototype.start_ = function () {\n var data = this.file_;\n\n // Functions can return references of all other types.\n if (typeof data == 'function') {\n data = data();\n }\n\n if (utils.isArrayLike(data)) {\n this.rawData_ = this.parseArray_(data);\n this.cascadeDataDidUpdateEvent_();\n this.predraw_();\n } else if (typeof data == 'object' && typeof data.getColumnRange == 'function') {\n // must be a DataTable from gviz.\n this.parseDataTable_(data);\n this.cascadeDataDidUpdateEvent_();\n this.predraw_();\n } else if (typeof data == 'string') {\n // Heuristic: a newline means it's CSV data. Otherwise it's an URL.\n var line_delimiter = utils.detectLineDelimiter(data);\n if (line_delimiter) {\n this.loadedEvent_(data);\n } else {\n // REMOVE_FOR_IE\n var req;\n if (window.XMLHttpRequest) {\n // Firefox, Opera, IE7, and other browsers will use the native object\n req = new XMLHttpRequest();\n } else {\n // IE 5 and 6 will use the ActiveX control\n req = new ActiveXObject(\"Microsoft.XMLHTTP\");\n }\n\n var caller = this;\n req.onreadystatechange = function () {\n if (req.readyState == 4) {\n if (req.status === 200 || // Normal http\n req.status === 0) {\n // Chrome w/ --allow-file-access-from-files\n caller.loadedEvent_(req.responseText);\n }\n }\n };\n\n req.open(\"GET\", data, true);\n req.send(null);\n }\n } else {\n console.error(\"Unknown data format: \" + typeof data);\n }\n};\n\n/**\n * Changes various properties of the graph. These can include:\n *
    \n *
  • file: changes the source data for the graph
  • \n *
  • errorBars: changes whether the data contains stddev
  • \n *
\n *\n * There's a huge variety of options that can be passed to this method. For a\n * full list, see http://dygraphs.com/options.html.\n *\n * @param {Object} input_attrs The new properties and values\n * @param {boolean} block_redraw Usually the chart is redrawn after every\n * call to updateOptions(). If you know better, you can pass true to\n * explicitly block the redraw. This can be useful for chaining\n * updateOptions() calls, avoiding the occasional infinite loop and\n * preventing redraws when it's not necessary (e.g. when updating a\n * callback).\n */\nDygraph.prototype.updateOptions = function (input_attrs, block_redraw) {\n if (typeof block_redraw == 'undefined') block_redraw = false;\n\n // copyUserAttrs_ drops the \"file\" parameter as a convenience to us.\n var file = input_attrs.file;\n var attrs = Dygraph.copyUserAttrs_(input_attrs);\n\n // TODO(danvk): this is a mess. Move these options into attr_.\n if ('rollPeriod' in attrs) {\n this.rollPeriod_ = attrs.rollPeriod;\n }\n if ('dateWindow' in attrs) {\n this.dateWindow_ = attrs.dateWindow;\n }\n\n // TODO(danvk): validate per-series options.\n // Supported:\n // strokeWidth\n // pointSize\n // drawPoints\n // highlightCircleSize\n\n // Check if this set options will require new points.\n var requiresNewPoints = utils.isPixelChangingOptionList(this.attr_(\"labels\"), attrs);\n\n utils.updateDeep(this.user_attrs_, attrs);\n\n this.attributes_.reparseSeries();\n\n if (file) {\n // This event indicates that the data is about to change, but hasn't yet.\n // TODO(danvk): support cancellation of the update via this event.\n this.cascadeEvents_('dataWillUpdate', {});\n\n this.file_ = file;\n if (!block_redraw) this.start_();\n } else {\n if (!block_redraw) {\n if (requiresNewPoints) {\n this.predraw_();\n } else {\n this.renderGraph_(false);\n }\n }\n }\n};\n\n/**\n * Make a copy of input attributes, removing file as a convenience.\n * @private\n */\nDygraph.copyUserAttrs_ = function (attrs) {\n var my_attrs = {};\n for (var k in attrs) {\n if (!attrs.hasOwnProperty(k)) continue;\n if (k == 'file') continue;\n if (attrs.hasOwnProperty(k)) my_attrs[k] = attrs[k];\n }\n return my_attrs;\n};\n\n/**\n * Resizes the dygraph. If no parameters are specified, resizes to fill the\n * containing div (which has presumably changed size since the dygraph was\n * instantiated. If the width/height are specified, the div will be resized.\n *\n * This is far more efficient than destroying and re-instantiating a\n * Dygraph, since it doesn't have to reparse the underlying data.\n *\n * @param {number} width Width (in pixels)\n * @param {number} height Height (in pixels)\n */\nDygraph.prototype.resize = function (width, height) {\n if (this.resize_lock) {\n return;\n }\n this.resize_lock = true;\n\n if (width === null != (height === null)) {\n console.warn(\"Dygraph.resize() should be called with zero parameters or \" + \"two non-NULL parameters. Pretending it was zero.\");\n width = height = null;\n }\n\n var old_width = this.width_;\n var old_height = this.height_;\n\n if (width) {\n this.maindiv_.style.width = width + \"px\";\n this.maindiv_.style.height = height + \"px\";\n this.width_ = width;\n this.height_ = height;\n } else {\n this.width_ = this.maindiv_.clientWidth;\n this.height_ = this.maindiv_.clientHeight;\n }\n\n if (old_width != this.width_ || old_height != this.height_) {\n // Resizing a canvas erases it, even when the size doesn't change, so\n // any resize needs to be followed by a redraw.\n this.resizeElements_();\n this.predraw_();\n }\n\n this.resize_lock = false;\n};\n\n/**\n * Adjusts the number of points in the rolling average. Updates the graph to\n * reflect the new averaging period.\n * @param {number} length Number of points over which to average the data.\n */\nDygraph.prototype.adjustRoll = function (length) {\n this.rollPeriod_ = length;\n this.predraw_();\n};\n\n/**\n * Returns a boolean array of visibility statuses.\n */\nDygraph.prototype.visibility = function () {\n // Do lazy-initialization, so that this happens after we know the number of\n // data series.\n if (!this.getOption(\"visibility\")) {\n this.attrs_.visibility = [];\n }\n // TODO(danvk): it looks like this could go into an infinite loop w/ user_attrs.\n while (this.getOption(\"visibility\").length < this.numColumns() - 1) {\n this.attrs_.visibility.push(true);\n }\n return this.getOption(\"visibility\");\n};\n\n/**\n * Changes the visibility of one or more series.\n *\n * @param {number|number[]|object} num the series index or an array of series indices\n * or a boolean array of visibility states by index\n * or an object mapping series numbers, as keys, to\n * visibility state (boolean values)\n * @param {boolean} value the visibility state expressed as a boolean\n */\nDygraph.prototype.setVisibility = function (num, value) {\n var x = this.visibility();\n var numIsObject = false;\n\n if (!Array.isArray(num)) {\n if (num !== null && typeof num === 'object') {\n numIsObject = true;\n } else {\n num = [num];\n }\n }\n\n if (numIsObject) {\n for (var i in num) {\n if (num.hasOwnProperty(i)) {\n if (i < 0 || i >= x.length) {\n console.warn(\"Invalid series number in setVisibility: \" + i);\n } else {\n x[i] = num[i];\n }\n }\n }\n } else {\n for (var i = 0; i < num.length; i++) {\n if (typeof num[i] === 'boolean') {\n if (i >= x.length) {\n console.warn(\"Invalid series number in setVisibility: \" + i);\n } else {\n x[i] = num[i];\n }\n } else {\n if (num[i] < 0 || num[i] >= x.length) {\n console.warn(\"Invalid series number in setVisibility: \" + num[i]);\n } else {\n x[num[i]] = value;\n }\n }\n }\n }\n\n this.predraw_();\n};\n\n/**\n * How large of an area will the dygraph render itself in?\n * This is used for testing.\n * @return A {width: w, height: h} object.\n * @private\n */\nDygraph.prototype.size = function () {\n return { width: this.width_, height: this.height_ };\n};\n\n/**\n * Update the list of annotations and redraw the chart.\n * See dygraphs.com/annotations.html for more info on how to use annotations.\n * @param ann {Array} An array of annotation objects.\n * @param suppressDraw {Boolean} Set to \"true\" to block chart redraw (optional).\n */\nDygraph.prototype.setAnnotations = function (ann, suppressDraw) {\n // Only add the annotation CSS rule once we know it will be used.\n this.annotations_ = ann;\n if (!this.layout_) {\n console.warn(\"Tried to setAnnotations before dygraph was ready. \" + \"Try setting them in a ready() block. See \" + \"dygraphs.com/tests/annotation.html\");\n return;\n }\n\n this.layout_.setAnnotations(this.annotations_);\n if (!suppressDraw) {\n this.predraw_();\n }\n};\n\n/**\n * Return the list of annotations.\n */\nDygraph.prototype.annotations = function () {\n return this.annotations_;\n};\n\n/**\n * Get the list of label names for this graph. The first column is the\n * x-axis, so the data series names start at index 1.\n *\n * Returns null when labels have not yet been defined.\n */\nDygraph.prototype.getLabels = function () {\n var labels = this.attr_(\"labels\");\n return labels ? labels.slice() : null;\n};\n\n/**\n * Get the index of a series (column) given its name. The first column is the\n * x-axis, so the data series start with index 1.\n */\nDygraph.prototype.indexFromSetName = function (name) {\n return this.setIndexByName_[name];\n};\n\n/**\n * Find the row number corresponding to the given x-value.\n * Returns null if there is no such x-value in the data.\n * If there are multiple rows with the same x-value, this will return the\n * first one.\n * @param {number} xVal The x-value to look for (e.g. millis since epoch).\n * @return {?number} The row number, which you can pass to getValue(), or null.\n */\nDygraph.prototype.getRowForX = function (xVal) {\n var low = 0,\n high = this.numRows() - 1;\n\n while (low <= high) {\n var idx = high + low >> 1;\n var x = this.getValue(idx, 0);\n if (x < xVal) {\n low = idx + 1;\n } else if (x > xVal) {\n high = idx - 1;\n } else if (low != idx) {\n // equal, but there may be an earlier match.\n high = idx;\n } else {\n return idx;\n }\n }\n\n return null;\n};\n\n/**\n * Trigger a callback when the dygraph has drawn itself and is ready to be\n * manipulated. This is primarily useful when dygraphs has to do an XHR for the\n * data (i.e. a URL is passed as the data source) and the chart is drawn\n * asynchronously. If the chart has already drawn, the callback will fire\n * immediately.\n *\n * This is a good place to call setAnnotation().\n *\n * @param {function(!Dygraph)} callback The callback to trigger when the chart\n * is ready.\n */\nDygraph.prototype.ready = function (callback) {\n if (this.is_initial_draw_) {\n this.readyFns_.push(callback);\n } else {\n callback.call(this, this);\n }\n};\n\n/**\n * Add an event handler. This event handler is kept until the graph is\n * destroyed with a call to graph.destroy().\n *\n * @param {!Node} elem The element to add the event to.\n * @param {string} type The type of the event, e.g. 'click' or 'mousemove'.\n * @param {function(Event):(boolean|undefined)} fn The function to call\n * on the event. The function takes one parameter: the event object.\n * @private\n */\nDygraph.prototype.addAndTrackEvent = function (elem, type, fn) {\n utils.addEvent(elem, type, fn);\n this.registeredEvents_.push({ elem: elem, type: type, fn: fn });\n};\n\nDygraph.prototype.removeTrackedEvents_ = function () {\n if (this.registeredEvents_) {\n for (var idx = 0; idx < this.registeredEvents_.length; idx++) {\n var reg = this.registeredEvents_[idx];\n utils.removeEvent(reg.elem, reg.type, reg.fn);\n }\n }\n\n this.registeredEvents_ = [];\n};\n\n// Installed plugins, in order of precedence (most-general to most-specific).\nDygraph.PLUGINS = [_pluginsLegend2['default'], _pluginsAxes2['default'], _pluginsRangeSelector2['default'], // Has to be before ChartLabels so that its callbacks are called after ChartLabels' callbacks.\n_pluginsChartLabels2['default'], _pluginsAnnotations2['default'], _pluginsGrid2['default']];\n\n// There are many symbols which have historically been available through the\n// Dygraph class. These are exported here for backwards compatibility.\nDygraph.GVizChart = _dygraphGviz2['default'];\nDygraph.DASHED_LINE = utils.DASHED_LINE;\nDygraph.DOT_DASH_LINE = utils.DOT_DASH_LINE;\nDygraph.dateAxisLabelFormatter = utils.dateAxisLabelFormatter;\nDygraph.toRGB_ = utils.toRGB_;\nDygraph.findPos = utils.findPos;\nDygraph.pageX = utils.pageX;\nDygraph.pageY = utils.pageY;\nDygraph.dateString_ = utils.dateString_;\nDygraph.defaultInteractionModel = _dygraphInteractionModel2['default'].defaultModel;\nDygraph.nonInteractiveModel = Dygraph.nonInteractiveModel_ = _dygraphInteractionModel2['default'].nonInteractiveModel_;\nDygraph.Circles = utils.Circles;\n\nDygraph.Plugins = {\n Legend: _pluginsLegend2['default'],\n Axes: _pluginsAxes2['default'],\n Annotations: _pluginsAnnotations2['default'],\n ChartLabels: _pluginsChartLabels2['default'],\n Grid: _pluginsGrid2['default'],\n RangeSelector: _pluginsRangeSelector2['default']\n};\n\nDygraph.DataHandlers = {\n DefaultHandler: _datahandlerDefault2['default'],\n BarsHandler: _datahandlerBars2['default'],\n CustomBarsHandler: _datahandlerBarsCustom2['default'],\n DefaultFractionHandler: _datahandlerDefaultFractions2['default'],\n ErrorBarsHandler: _datahandlerBarsError2['default'],\n FractionsBarsHandler: _datahandlerBarsFractions2['default']\n};\n\nDygraph.startPan = _dygraphInteractionModel2['default'].startPan;\nDygraph.startZoom = _dygraphInteractionModel2['default'].startZoom;\nDygraph.movePan = _dygraphInteractionModel2['default'].movePan;\nDygraph.moveZoom = _dygraphInteractionModel2['default'].moveZoom;\nDygraph.endPan = _dygraphInteractionModel2['default'].endPan;\nDygraph.endZoom = _dygraphInteractionModel2['default'].endZoom;\n\nDygraph.numericLinearTicks = DygraphTickers.numericLinearTicks;\nDygraph.numericTicks = DygraphTickers.numericTicks;\nDygraph.dateTicker = DygraphTickers.dateTicker;\nDygraph.Granularity = DygraphTickers.Granularity;\nDygraph.getDateAxis = DygraphTickers.getDateAxis;\nDygraph.floatFormat = utils.floatFormat;\n\nexports['default'] = Dygraph;\nmodule.exports = exports['default'];","/**\n * @license\n * Copyright 2011 Dan Vanderkam (danvdk@gmail.com)\n * MIT-licensed (http://opensource.org/licenses/MIT)\n */\n\n/**\n * @fileoverview Description of this file.\n * @author danvk@google.com (Dan Vanderkam)\n *\n * A ticker is a function with the following interface:\n *\n * function(a, b, pixels, options_view, dygraph, forced_values);\n * -> [ { v: tick1_v, label: tick1_label[, label_v: label_v1] },\n * { v: tick2_v, label: tick2_label[, label_v: label_v2] },\n * ...\n * ]\n *\n * The returned value is called a \"tick list\".\n *\n * Arguments\n * ---------\n *\n * [a, b] is the range of the axis for which ticks are being generated. For a\n * numeric axis, these will simply be numbers. For a date axis, these will be\n * millis since epoch (convertable to Date objects using \"new Date(a)\" and \"new\n * Date(b)\").\n *\n * opts provides access to chart- and axis-specific options. It can be used to\n * access number/date formatting code/options, check for a log scale, etc.\n *\n * pixels is the length of the axis in pixels. opts('pixelsPerLabel') is the\n * minimum amount of space to be allotted to each label. For instance, if\n * pixels=400 and opts('pixelsPerLabel')=40 then the ticker should return\n * between zero and ten (400/40) ticks.\n *\n * dygraph is the Dygraph object for which an axis is being constructed.\n *\n * forced_values is used for secondary y-axes. The tick positions are typically\n * set by the primary y-axis, so the secondary y-axis has no choice in where to\n * put these. It simply has to generate labels for these data values.\n *\n * Tick lists\n * ----------\n * Typically a tick will have both a grid/tick line and a label at one end of\n * that line (at the bottom for an x-axis, at left or right for the y-axis).\n *\n * A tick may be missing one of these two components:\n * - If \"label_v\" is specified instead of \"v\", then there will be no tick or\n * gridline, just a label.\n * - Similarly, if \"label\" is not specified, then there will be a gridline\n * without a label.\n *\n * This flexibility is useful in a few situations:\n * - For log scales, some of the tick lines may be too close to all have labels.\n * - For date scales where years are being displayed, it is desirable to display\n * tick marks at the beginnings of years but labels (e.g. \"2006\") in the\n * middle of the years.\n */\n\n/*jshint sub:true */\n/*global Dygraph:false */\n\"use strict\";\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }\n\nvar _dygraphUtils = require('./dygraph-utils');\n\nvar utils = _interopRequireWildcard(_dygraphUtils);\n\n/** @typedef {Array.<{v:number, label:string, label_v:(string|undefined)}>} */\nvar TickList = undefined; // the ' = undefined' keeps jshint happy.\n\n/** @typedef {function(\n * number,\n * number,\n * number,\n * function(string):*,\n * Dygraph=,\n * Array.=\n * ): TickList}\n */\nvar Ticker = undefined; // the ' = undefined' keeps jshint happy.\n\n/** @type {Ticker} */\nvar numericLinearTicks = function numericLinearTicks(a, b, pixels, opts, dygraph, vals) {\n var nonLogscaleOpts = function nonLogscaleOpts(opt) {\n if (opt === 'logscale') return false;\n return opts(opt);\n };\n return numericTicks(a, b, pixels, nonLogscaleOpts, dygraph, vals);\n};\n\nexports.numericLinearTicks = numericLinearTicks;\n/** @type {Ticker} */\nvar numericTicks = function numericTicks(a, b, pixels, opts, dygraph, vals) {\n var pixels_per_tick = /** @type{number} */opts('pixelsPerLabel');\n var ticks = [];\n var i, j, tickV, nTicks;\n if (vals) {\n for (i = 0; i < vals.length; i++) {\n ticks.push({ v: vals[i] });\n }\n } else {\n // TODO(danvk): factor this log-scale block out into a separate function.\n if (opts(\"logscale\")) {\n nTicks = Math.floor(pixels / pixels_per_tick);\n var minIdx = utils.binarySearch(a, PREFERRED_LOG_TICK_VALUES, 1);\n var maxIdx = utils.binarySearch(b, PREFERRED_LOG_TICK_VALUES, -1);\n if (minIdx == -1) {\n minIdx = 0;\n }\n if (maxIdx == -1) {\n maxIdx = PREFERRED_LOG_TICK_VALUES.length - 1;\n }\n // Count the number of tick values would appear, if we can get at least\n // nTicks / 4 accept them.\n var lastDisplayed = null;\n if (maxIdx - minIdx >= nTicks / 4) {\n for (var idx = maxIdx; idx >= minIdx; idx--) {\n var tickValue = PREFERRED_LOG_TICK_VALUES[idx];\n var pixel_coord = Math.log(tickValue / a) / Math.log(b / a) * pixels;\n var tick = { v: tickValue };\n if (lastDisplayed === null) {\n lastDisplayed = {\n tickValue: tickValue,\n pixel_coord: pixel_coord\n };\n } else {\n if (Math.abs(pixel_coord - lastDisplayed.pixel_coord) >= pixels_per_tick) {\n lastDisplayed = {\n tickValue: tickValue,\n pixel_coord: pixel_coord\n };\n } else {\n tick.label = \"\";\n }\n }\n ticks.push(tick);\n }\n // Since we went in backwards order.\n ticks.reverse();\n }\n }\n\n // ticks.length won't be 0 if the log scale function finds values to insert.\n if (ticks.length === 0) {\n // Basic idea:\n // Try labels every 1, 2, 5, 10, 20, 50, 100, etc.\n // Calculate the resulting tick spacing (i.e. this.height_ / nTicks).\n // The first spacing greater than pixelsPerYLabel is what we use.\n // TODO(danvk): version that works on a log scale.\n var kmg2 = opts(\"labelsKMG2\");\n var mults, base;\n if (kmg2) {\n mults = [1, 2, 4, 8, 16, 32, 64, 128, 256];\n base = 16;\n } else {\n mults = [1, 2, 5, 10, 20, 50, 100];\n base = 10;\n }\n\n // Get the maximum number of permitted ticks based on the\n // graph's pixel size and pixels_per_tick setting.\n var max_ticks = Math.ceil(pixels / pixels_per_tick);\n\n // Now calculate the data unit equivalent of this tick spacing.\n // Use abs() since graphs may have a reversed Y axis.\n var units_per_tick = Math.abs(b - a) / max_ticks;\n\n // Based on this, get a starting scale which is the largest\n // integer power of the chosen base (10 or 16) that still remains\n // below the requested pixels_per_tick spacing.\n var base_power = Math.floor(Math.log(units_per_tick) / Math.log(base));\n var base_scale = Math.pow(base, base_power);\n\n // Now try multiples of the starting scale until we find one\n // that results in tick marks spaced sufficiently far apart.\n // The \"mults\" array should cover the range 1 .. base^2 to\n // adjust for rounding and edge effects.\n var scale, low_val, high_val, spacing;\n for (j = 0; j < mults.length; j++) {\n scale = base_scale * mults[j];\n low_val = Math.floor(a / scale) * scale;\n high_val = Math.ceil(b / scale) * scale;\n nTicks = Math.abs(high_val - low_val) / scale;\n spacing = pixels / nTicks;\n if (spacing > pixels_per_tick) break;\n }\n\n // Construct the set of ticks.\n // Allow reverse y-axis if it's explicitly requested.\n if (low_val > high_val) scale *= -1;\n for (i = 0; i <= nTicks; i++) {\n tickV = low_val + i * scale;\n ticks.push({ v: tickV });\n }\n }\n }\n\n var formatter = /**@type{AxisLabelFormatter}*/opts('axisLabelFormatter');\n\n // Add labels to the ticks.\n for (i = 0; i < ticks.length; i++) {\n if (ticks[i].label !== undefined) continue; // Use current label.\n // TODO(danvk): set granularity to something appropriate here.\n ticks[i].label = formatter.call(dygraph, ticks[i].v, 0, opts, dygraph);\n }\n\n return ticks;\n};\n\nexports.numericTicks = numericTicks;\n/** @type {Ticker} */\nvar dateTicker = function dateTicker(a, b, pixels, opts, dygraph, vals) {\n var chosen = pickDateTickGranularity(a, b, pixels, opts);\n\n if (chosen >= 0) {\n return getDateAxis(a, b, chosen, opts, dygraph);\n } else {\n // this can happen if self.width_ is zero.\n return [];\n }\n};\n\nexports.dateTicker = dateTicker;\n// Time granularity enumeration\nvar Granularity = {\n MILLISECONDLY: 0,\n TWO_MILLISECONDLY: 1,\n FIVE_MILLISECONDLY: 2,\n TEN_MILLISECONDLY: 3,\n FIFTY_MILLISECONDLY: 4,\n HUNDRED_MILLISECONDLY: 5,\n FIVE_HUNDRED_MILLISECONDLY: 6,\n SECONDLY: 7,\n TWO_SECONDLY: 8,\n FIVE_SECONDLY: 9,\n TEN_SECONDLY: 10,\n THIRTY_SECONDLY: 11,\n MINUTELY: 12,\n TWO_MINUTELY: 13,\n FIVE_MINUTELY: 14,\n TEN_MINUTELY: 15,\n THIRTY_MINUTELY: 16,\n HOURLY: 17,\n TWO_HOURLY: 18,\n SIX_HOURLY: 19,\n DAILY: 20,\n TWO_DAILY: 21,\n WEEKLY: 22,\n MONTHLY: 23,\n QUARTERLY: 24,\n BIANNUAL: 25,\n ANNUAL: 26,\n DECADAL: 27,\n CENTENNIAL: 28,\n NUM_GRANULARITIES: 29\n};\n\nexports.Granularity = Granularity;\n// Date components enumeration (in the order of the arguments in Date)\n// TODO: make this an @enum\nvar DateField = {\n DATEFIELD_Y: 0,\n DATEFIELD_M: 1,\n DATEFIELD_D: 2,\n DATEFIELD_HH: 3,\n DATEFIELD_MM: 4,\n DATEFIELD_SS: 5,\n DATEFIELD_MS: 6,\n NUM_DATEFIELDS: 7\n};\n\n/**\n * The value of datefield will start at an even multiple of \"step\", i.e.\n * if datefield=SS and step=5 then the first tick will be on a multiple of 5s.\n *\n * For granularities <= HOURLY, ticks are generated every `spacing` ms.\n *\n * At coarser granularities, ticks are generated by incrementing `datefield` by\n * `step`. In this case, the `spacing` value is only used to estimate the\n * number of ticks. It should roughly correspond to the spacing between\n * adjacent ticks.\n *\n * @type {Array.<{datefield:number, step:number, spacing:number}>}\n */\nvar TICK_PLACEMENT = [];\nTICK_PLACEMENT[Granularity.MILLISECONDLY] = { datefield: DateField.DATEFIELD_MS, step: 1, spacing: 1 };\nTICK_PLACEMENT[Granularity.TWO_MILLISECONDLY] = { datefield: DateField.DATEFIELD_MS, step: 2, spacing: 2 };\nTICK_PLACEMENT[Granularity.FIVE_MILLISECONDLY] = { datefield: DateField.DATEFIELD_MS, step: 5, spacing: 5 };\nTICK_PLACEMENT[Granularity.TEN_MILLISECONDLY] = { datefield: DateField.DATEFIELD_MS, step: 10, spacing: 10 };\nTICK_PLACEMENT[Granularity.FIFTY_MILLISECONDLY] = { datefield: DateField.DATEFIELD_MS, step: 50, spacing: 50 };\nTICK_PLACEMENT[Granularity.HUNDRED_MILLISECONDLY] = { datefield: DateField.DATEFIELD_MS, step: 100, spacing: 100 };\nTICK_PLACEMENT[Granularity.FIVE_HUNDRED_MILLISECONDLY] = { datefield: DateField.DATEFIELD_MS, step: 500, spacing: 500 };\nTICK_PLACEMENT[Granularity.SECONDLY] = { datefield: DateField.DATEFIELD_SS, step: 1, spacing: 1000 * 1 };\nTICK_PLACEMENT[Granularity.TWO_SECONDLY] = { datefield: DateField.DATEFIELD_SS, step: 2, spacing: 1000 * 2 };\nTICK_PLACEMENT[Granularity.FIVE_SECONDLY] = { datefield: DateField.DATEFIELD_SS, step: 5, spacing: 1000 * 5 };\nTICK_PLACEMENT[Granularity.TEN_SECONDLY] = { datefield: DateField.DATEFIELD_SS, step: 10, spacing: 1000 * 10 };\nTICK_PLACEMENT[Granularity.THIRTY_SECONDLY] = { datefield: DateField.DATEFIELD_SS, step: 30, spacing: 1000 * 30 };\nTICK_PLACEMENT[Granularity.MINUTELY] = { datefield: DateField.DATEFIELD_MM, step: 1, spacing: 1000 * 60 };\nTICK_PLACEMENT[Granularity.TWO_MINUTELY] = { datefield: DateField.DATEFIELD_MM, step: 2, spacing: 1000 * 60 * 2 };\nTICK_PLACEMENT[Granularity.FIVE_MINUTELY] = { datefield: DateField.DATEFIELD_MM, step: 5, spacing: 1000 * 60 * 5 };\nTICK_PLACEMENT[Granularity.TEN_MINUTELY] = { datefield: DateField.DATEFIELD_MM, step: 10, spacing: 1000 * 60 * 10 };\nTICK_PLACEMENT[Granularity.THIRTY_MINUTELY] = { datefield: DateField.DATEFIELD_MM, step: 30, spacing: 1000 * 60 * 30 };\nTICK_PLACEMENT[Granularity.HOURLY] = { datefield: DateField.DATEFIELD_HH, step: 1, spacing: 1000 * 3600 };\nTICK_PLACEMENT[Granularity.TWO_HOURLY] = { datefield: DateField.DATEFIELD_HH, step: 2, spacing: 1000 * 3600 * 2 };\nTICK_PLACEMENT[Granularity.SIX_HOURLY] = { datefield: DateField.DATEFIELD_HH, step: 6, spacing: 1000 * 3600 * 6 };\nTICK_PLACEMENT[Granularity.DAILY] = { datefield: DateField.DATEFIELD_D, step: 1, spacing: 1000 * 86400 };\nTICK_PLACEMENT[Granularity.TWO_DAILY] = { datefield: DateField.DATEFIELD_D, step: 2, spacing: 1000 * 86400 * 2 };\nTICK_PLACEMENT[Granularity.WEEKLY] = { datefield: DateField.DATEFIELD_D, step: 7, spacing: 1000 * 604800 };\nTICK_PLACEMENT[Granularity.MONTHLY] = { datefield: DateField.DATEFIELD_M, step: 1, spacing: 1000 * 7200 * 365.2524 }; // 1e3 * 60 * 60 * 24 * 365.2524 / 12\nTICK_PLACEMENT[Granularity.QUARTERLY] = { datefield: DateField.DATEFIELD_M, step: 3, spacing: 1000 * 21600 * 365.2524 }; // 1e3 * 60 * 60 * 24 * 365.2524 / 4\nTICK_PLACEMENT[Granularity.BIANNUAL] = { datefield: DateField.DATEFIELD_M, step: 6, spacing: 1000 * 43200 * 365.2524 }; // 1e3 * 60 * 60 * 24 * 365.2524 / 2\nTICK_PLACEMENT[Granularity.ANNUAL] = { datefield: DateField.DATEFIELD_Y, step: 1, spacing: 1000 * 86400 * 365.2524 }; // 1e3 * 60 * 60 * 24 * 365.2524 * 1\nTICK_PLACEMENT[Granularity.DECADAL] = { datefield: DateField.DATEFIELD_Y, step: 10, spacing: 1000 * 864000 * 365.2524 }; // 1e3 * 60 * 60 * 24 * 365.2524 * 10\nTICK_PLACEMENT[Granularity.CENTENNIAL] = { datefield: DateField.DATEFIELD_Y, step: 100, spacing: 1000 * 8640000 * 365.2524 }; // 1e3 * 60 * 60 * 24 * 365.2524 * 100\n\n/**\n * This is a list of human-friendly values at which to show tick marks on a log\n * scale. It is k * 10^n, where k=1..9 and n=-39..+39, so:\n * ..., 1, 2, 3, 4, 5, ..., 9, 10, 20, 30, ..., 90, 100, 200, 300, ...\n * NOTE: this assumes that utils.LOG_SCALE = 10.\n * @type {Array.}\n */\nvar PREFERRED_LOG_TICK_VALUES = (function () {\n var vals = [];\n for (var power = -39; power <= 39; power++) {\n var range = Math.pow(10, power);\n for (var mult = 1; mult <= 9; mult++) {\n var val = range * mult;\n vals.push(val);\n }\n }\n return vals;\n})();\n\n/**\n * Determine the correct granularity of ticks on a date axis.\n *\n * @param {number} a Left edge of the chart (ms)\n * @param {number} b Right edge of the chart (ms)\n * @param {number} pixels Size of the chart in the relevant dimension (width).\n * @param {function(string):*} opts Function mapping from option name -> value.\n * @return {number} The appropriate axis granularity for this chart. See the\n * enumeration of possible values in dygraph-tickers.js.\n */\nvar pickDateTickGranularity = function pickDateTickGranularity(a, b, pixels, opts) {\n var pixels_per_tick = /** @type{number} */opts('pixelsPerLabel');\n for (var i = 0; i < Granularity.NUM_GRANULARITIES; i++) {\n var num_ticks = numDateTicks(a, b, i);\n if (pixels / num_ticks >= pixels_per_tick) {\n return i;\n }\n }\n return -1;\n};\n\n/**\n * Compute the number of ticks on a date axis for a given granularity.\n * @param {number} start_time\n * @param {number} end_time\n * @param {number} granularity (one of the granularities enumerated above)\n * @return {number} (Approximate) number of ticks that would result.\n */\nvar numDateTicks = function numDateTicks(start_time, end_time, granularity) {\n var spacing = TICK_PLACEMENT[granularity].spacing;\n return Math.round(1.0 * (end_time - start_time) / spacing);\n};\n\n/**\n * Compute the positions and labels of ticks on a date axis for a given granularity.\n * @param {number} start_time\n * @param {number} end_time\n * @param {number} granularity (one of the granularities enumerated above)\n * @param {function(string):*} opts Function mapping from option name -> value.\n * @param {Dygraph=} dg\n * @return {!TickList}\n */\nvar getDateAxis = function getDateAxis(start_time, end_time, granularity, opts, dg) {\n var formatter = /** @type{AxisLabelFormatter} */opts(\"axisLabelFormatter\");\n var utc = opts(\"labelsUTC\");\n var accessors = utc ? utils.DateAccessorsUTC : utils.DateAccessorsLocal;\n\n var datefield = TICK_PLACEMENT[granularity].datefield;\n var step = TICK_PLACEMENT[granularity].step;\n var spacing = TICK_PLACEMENT[granularity].spacing;\n\n // Choose a nice tick position before the initial instant.\n // Currently, this code deals properly with the existent daily granularities:\n // DAILY (with step of 1) and WEEKLY (with step of 7 but specially handled).\n // Other daily granularities (say TWO_DAILY) should also be handled specially\n // by setting the start_date_offset to 0.\n var start_date = new Date(start_time);\n var date_array = [];\n date_array[DateField.DATEFIELD_Y] = accessors.getFullYear(start_date);\n date_array[DateField.DATEFIELD_M] = accessors.getMonth(start_date);\n date_array[DateField.DATEFIELD_D] = accessors.getDate(start_date);\n date_array[DateField.DATEFIELD_HH] = accessors.getHours(start_date);\n date_array[DateField.DATEFIELD_MM] = accessors.getMinutes(start_date);\n date_array[DateField.DATEFIELD_SS] = accessors.getSeconds(start_date);\n date_array[DateField.DATEFIELD_MS] = accessors.getMilliseconds(start_date);\n\n var start_date_offset = date_array[datefield] % step;\n if (granularity == Granularity.WEEKLY) {\n // This will put the ticks on Sundays.\n start_date_offset = accessors.getDay(start_date);\n }\n\n date_array[datefield] -= start_date_offset;\n for (var df = datefield + 1; df < DateField.NUM_DATEFIELDS; df++) {\n // The minimum value is 1 for the day of month, and 0 for all other fields.\n date_array[df] = df === DateField.DATEFIELD_D ? 1 : 0;\n }\n\n // Generate the ticks.\n // For granularities not coarser than HOURLY we use the fact that:\n // the number of milliseconds between ticks is constant\n // and equal to the defined spacing.\n // Otherwise we rely on the 'roll over' property of the Date functions:\n // when some date field is set to a value outside of its logical range,\n // the excess 'rolls over' the next (more significant) field.\n // However, when using local time with DST transitions,\n // there are dates that do not represent any time value at all\n // (those in the hour skipped at the 'spring forward'),\n // and the JavaScript engines usually return an equivalent value.\n // Hence we have to check that the date is properly increased at each step,\n // returning a date at a nice tick position.\n var ticks = [];\n var tick_date = accessors.makeDate.apply(null, date_array);\n var tick_time = tick_date.getTime();\n if (granularity <= Granularity.HOURLY) {\n if (tick_time < start_time) {\n tick_time += spacing;\n tick_date = new Date(tick_time);\n }\n while (tick_time <= end_time) {\n ticks.push({ v: tick_time,\n label: formatter.call(dg, tick_date, granularity, opts, dg)\n });\n tick_time += spacing;\n tick_date = new Date(tick_time);\n }\n } else {\n if (tick_time < start_time) {\n date_array[datefield] += step;\n tick_date = accessors.makeDate.apply(null, date_array);\n tick_time = tick_date.getTime();\n }\n while (tick_time <= end_time) {\n if (granularity >= Granularity.DAILY || accessors.getHours(tick_date) % step === 0) {\n ticks.push({ v: tick_time,\n label: formatter.call(dg, tick_date, granularity, opts, dg)\n });\n }\n date_array[datefield] += step;\n tick_date = accessors.makeDate.apply(null, date_array);\n tick_time = tick_date.getTime();\n }\n }\n return ticks;\n};\nexports.getDateAxis = getDateAxis;","/**\n * @license\n * Copyright 2011 Robert Konigsberg (konigsberg@google.com)\n * MIT-licensed (http://opensource.org/licenses/MIT)\n */\n\n/**\n * @fileoverview The default interaction model for Dygraphs. This is kept out\n * of dygraph.js for better navigability.\n * @author Robert Konigsberg (konigsberg@google.com)\n */\n\n/*global Dygraph:false */\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj[\"default\"] = obj; return newObj; } }\n\nvar _dygraphUtils = require('./dygraph-utils');\n\nvar utils = _interopRequireWildcard(_dygraphUtils);\n\n/**\n * You can drag this many pixels past the edge of the chart and still have it\n * be considered a zoom. This makes it easier to zoom to the exact edge of the\n * chart, a fairly common operation.\n */\nvar DRAG_EDGE_MARGIN = 100;\n\n/**\n * A collection of functions to facilitate build custom interaction models.\n * @class\n */\nvar DygraphInteraction = {};\n\n/**\n * Checks whether the beginning & ending of an event were close enough that it\n * should be considered a click. If it should, dispatch appropriate events.\n * Returns true if the event was treated as a click.\n *\n * @param {Event} event\n * @param {Dygraph} g\n * @param {Object} context\n */\nDygraphInteraction.maybeTreatMouseOpAsClick = function (event, g, context) {\n context.dragEndX = utils.dragGetX_(event, context);\n context.dragEndY = utils.dragGetY_(event, context);\n var regionWidth = Math.abs(context.dragEndX - context.dragStartX);\n var regionHeight = Math.abs(context.dragEndY - context.dragStartY);\n\n if (regionWidth < 2 && regionHeight < 2 && g.lastx_ !== undefined && g.lastx_ != -1) {\n DygraphInteraction.treatMouseOpAsClick(g, event, context);\n }\n\n context.regionWidth = regionWidth;\n context.regionHeight = regionHeight;\n};\n\n/**\n * Called in response to an interaction model operation that\n * should start the default panning behavior.\n *\n * It's used in the default callback for \"mousedown\" operations.\n * Custom interaction model builders can use it to provide the default\n * panning behavior.\n *\n * @param {Event} event the event object which led to the startPan call.\n * @param {Dygraph} g The dygraph on which to act.\n * @param {Object} context The dragging context object (with\n * dragStartX/dragStartY/etc. properties). This function modifies the\n * context.\n */\nDygraphInteraction.startPan = function (event, g, context) {\n var i, axis;\n context.isPanning = true;\n var xRange = g.xAxisRange();\n\n if (g.getOptionForAxis(\"logscale\", \"x\")) {\n context.initialLeftmostDate = utils.log10(xRange[0]);\n context.dateRange = utils.log10(xRange[1]) - utils.log10(xRange[0]);\n } else {\n context.initialLeftmostDate = xRange[0];\n context.dateRange = xRange[1] - xRange[0];\n }\n context.xUnitsPerPixel = context.dateRange / (g.plotter_.area.w - 1);\n\n if (g.getNumericOption(\"panEdgeFraction\")) {\n var maxXPixelsToDraw = g.width_ * g.getNumericOption(\"panEdgeFraction\");\n var xExtremes = g.xAxisExtremes(); // I REALLY WANT TO CALL THIS xTremes!\n\n var boundedLeftX = g.toDomXCoord(xExtremes[0]) - maxXPixelsToDraw;\n var boundedRightX = g.toDomXCoord(xExtremes[1]) + maxXPixelsToDraw;\n\n var boundedLeftDate = g.toDataXCoord(boundedLeftX);\n var boundedRightDate = g.toDataXCoord(boundedRightX);\n context.boundedDates = [boundedLeftDate, boundedRightDate];\n\n var boundedValues = [];\n var maxYPixelsToDraw = g.height_ * g.getNumericOption(\"panEdgeFraction\");\n\n for (i = 0; i < g.axes_.length; i++) {\n axis = g.axes_[i];\n var yExtremes = axis.extremeRange;\n\n var boundedTopY = g.toDomYCoord(yExtremes[0], i) + maxYPixelsToDraw;\n var boundedBottomY = g.toDomYCoord(yExtremes[1], i) - maxYPixelsToDraw;\n\n var boundedTopValue = g.toDataYCoord(boundedTopY, i);\n var boundedBottomValue = g.toDataYCoord(boundedBottomY, i);\n\n boundedValues[i] = [boundedTopValue, boundedBottomValue];\n }\n context.boundedValues = boundedValues;\n }\n\n // Record the range of each y-axis at the start of the drag.\n // If any axis has a valueRange, then we want a 2D pan.\n // We can't store data directly in g.axes_, because it does not belong to us\n // and could change out from under us during a pan (say if there's a data\n // update).\n context.is2DPan = false;\n context.axes = [];\n for (i = 0; i < g.axes_.length; i++) {\n axis = g.axes_[i];\n var axis_data = {};\n var yRange = g.yAxisRange(i);\n // TODO(konigsberg): These values should be in |context|.\n // In log scale, initialTopValue, dragValueRange and unitsPerPixel are log scale.\n var logscale = g.attributes_.getForAxis(\"logscale\", i);\n if (logscale) {\n axis_data.initialTopValue = utils.log10(yRange[1]);\n axis_data.dragValueRange = utils.log10(yRange[1]) - utils.log10(yRange[0]);\n } else {\n axis_data.initialTopValue = yRange[1];\n axis_data.dragValueRange = yRange[1] - yRange[0];\n }\n axis_data.unitsPerPixel = axis_data.dragValueRange / (g.plotter_.area.h - 1);\n context.axes.push(axis_data);\n\n // While calculating axes, set 2dpan.\n if (axis.valueRange) context.is2DPan = true;\n }\n};\n\n/**\n * Called in response to an interaction model operation that\n * responds to an event that pans the view.\n *\n * It's used in the default callback for \"mousemove\" operations.\n * Custom interaction model builders can use it to provide the default\n * panning behavior.\n *\n * @param {Event} event the event object which led to the movePan call.\n * @param {Dygraph} g The dygraph on which to act.\n * @param {Object} context The dragging context object (with\n * dragStartX/dragStartY/etc. properties). This function modifies the\n * context.\n */\nDygraphInteraction.movePan = function (event, g, context) {\n context.dragEndX = utils.dragGetX_(event, context);\n context.dragEndY = utils.dragGetY_(event, context);\n\n var minDate = context.initialLeftmostDate - (context.dragEndX - context.dragStartX) * context.xUnitsPerPixel;\n if (context.boundedDates) {\n minDate = Math.max(minDate, context.boundedDates[0]);\n }\n var maxDate = minDate + context.dateRange;\n if (context.boundedDates) {\n if (maxDate > context.boundedDates[1]) {\n // Adjust minDate, and recompute maxDate.\n minDate = minDate - (maxDate - context.boundedDates[1]);\n maxDate = minDate + context.dateRange;\n }\n }\n\n if (g.getOptionForAxis(\"logscale\", \"x\")) {\n g.dateWindow_ = [Math.pow(utils.LOG_SCALE, minDate), Math.pow(utils.LOG_SCALE, maxDate)];\n } else {\n g.dateWindow_ = [minDate, maxDate];\n }\n\n // y-axis scaling is automatic unless this is a full 2D pan.\n if (context.is2DPan) {\n\n var pixelsDragged = context.dragEndY - context.dragStartY;\n\n // Adjust each axis appropriately.\n for (var i = 0; i < g.axes_.length; i++) {\n var axis = g.axes_[i];\n var axis_data = context.axes[i];\n var unitsDragged = pixelsDragged * axis_data.unitsPerPixel;\n\n var boundedValue = context.boundedValues ? context.boundedValues[i] : null;\n\n // In log scale, maxValue and minValue are the logs of those values.\n var maxValue = axis_data.initialTopValue + unitsDragged;\n if (boundedValue) {\n maxValue = Math.min(maxValue, boundedValue[1]);\n }\n var minValue = maxValue - axis_data.dragValueRange;\n if (boundedValue) {\n if (minValue < boundedValue[0]) {\n // Adjust maxValue, and recompute minValue.\n maxValue = maxValue - (minValue - boundedValue[0]);\n minValue = maxValue - axis_data.dragValueRange;\n }\n }\n if (g.attributes_.getForAxis(\"logscale\", i)) {\n axis.valueRange = [Math.pow(utils.LOG_SCALE, minValue), Math.pow(utils.LOG_SCALE, maxValue)];\n } else {\n axis.valueRange = [minValue, maxValue];\n }\n }\n }\n\n g.drawGraph_(false);\n};\n\n/**\n * Called in response to an interaction model operation that\n * responds to an event that ends panning.\n *\n * It's used in the default callback for \"mouseup\" operations.\n * Custom interaction model builders can use it to provide the default\n * panning behavior.\n *\n * @param {Event} event the event object which led to the endPan call.\n * @param {Dygraph} g The dygraph on which to act.\n * @param {Object} context The dragging context object (with\n * dragStartX/dragStartY/etc. properties). This function modifies the\n * context.\n */\nDygraphInteraction.endPan = DygraphInteraction.maybeTreatMouseOpAsClick;\n\n/**\n * Called in response to an interaction model operation that\n * responds to an event that starts zooming.\n *\n * It's used in the default callback for \"mousedown\" operations.\n * Custom interaction model builders can use it to provide the default\n * zooming behavior.\n *\n * @param {Event} event the event object which led to the startZoom call.\n * @param {Dygraph} g The dygraph on which to act.\n * @param {Object} context The dragging context object (with\n * dragStartX/dragStartY/etc. properties). This function modifies the\n * context.\n */\nDygraphInteraction.startZoom = function (event, g, context) {\n context.isZooming = true;\n context.zoomMoved = false;\n};\n\n/**\n * Called in response to an interaction model operation that\n * responds to an event that defines zoom boundaries.\n *\n * It's used in the default callback for \"mousemove\" operations.\n * Custom interaction model builders can use it to provide the default\n * zooming behavior.\n *\n * @param {Event} event the event object which led to the moveZoom call.\n * @param {Dygraph} g The dygraph on which to act.\n * @param {Object} context The dragging context object (with\n * dragStartX/dragStartY/etc. properties). This function modifies the\n * context.\n */\nDygraphInteraction.moveZoom = function (event, g, context) {\n context.zoomMoved = true;\n context.dragEndX = utils.dragGetX_(event, context);\n context.dragEndY = utils.dragGetY_(event, context);\n\n var xDelta = Math.abs(context.dragStartX - context.dragEndX);\n var yDelta = Math.abs(context.dragStartY - context.dragEndY);\n\n // drag direction threshold for y axis is twice as large as x axis\n context.dragDirection = xDelta < yDelta / 2 ? utils.VERTICAL : utils.HORIZONTAL;\n\n g.drawZoomRect_(context.dragDirection, context.dragStartX, context.dragEndX, context.dragStartY, context.dragEndY, context.prevDragDirection, context.prevEndX, context.prevEndY);\n\n context.prevEndX = context.dragEndX;\n context.prevEndY = context.dragEndY;\n context.prevDragDirection = context.dragDirection;\n};\n\n/**\n * TODO(danvk): move this logic into dygraph.js\n * @param {Dygraph} g\n * @param {Event} event\n * @param {Object} context\n */\nDygraphInteraction.treatMouseOpAsClick = function (g, event, context) {\n var clickCallback = g.getFunctionOption('clickCallback');\n var pointClickCallback = g.getFunctionOption('pointClickCallback');\n\n var selectedPoint = null;\n\n // Find out if the click occurs on a point.\n var closestIdx = -1;\n var closestDistance = Number.MAX_VALUE;\n\n // check if the click was on a particular point.\n for (var i = 0; i < g.selPoints_.length; i++) {\n var p = g.selPoints_[i];\n var distance = Math.pow(p.canvasx - context.dragEndX, 2) + Math.pow(p.canvasy - context.dragEndY, 2);\n if (!isNaN(distance) && (closestIdx == -1 || distance < closestDistance)) {\n closestDistance = distance;\n closestIdx = i;\n }\n }\n\n // Allow any click within two pixels of the dot.\n var radius = g.getNumericOption('highlightCircleSize') + 2;\n if (closestDistance <= radius * radius) {\n selectedPoint = g.selPoints_[closestIdx];\n }\n\n if (selectedPoint) {\n var e = {\n cancelable: true,\n point: selectedPoint,\n canvasx: context.dragEndX,\n canvasy: context.dragEndY\n };\n var defaultPrevented = g.cascadeEvents_('pointClick', e);\n if (defaultPrevented) {\n // Note: this also prevents click / clickCallback from firing.\n return;\n }\n if (pointClickCallback) {\n pointClickCallback.call(g, event, selectedPoint);\n }\n }\n\n var e = {\n cancelable: true,\n xval: g.lastx_, // closest point by x value\n pts: g.selPoints_,\n canvasx: context.dragEndX,\n canvasy: context.dragEndY\n };\n if (!g.cascadeEvents_('click', e)) {\n if (clickCallback) {\n // TODO(danvk): pass along more info about the points, e.g. 'x'\n clickCallback.call(g, event, g.lastx_, g.selPoints_);\n }\n }\n};\n\n/**\n * Called in response to an interaction model operation that\n * responds to an event that performs a zoom based on previously defined\n * bounds..\n *\n * It's used in the default callback for \"mouseup\" operations.\n * Custom interaction model builders can use it to provide the default\n * zooming behavior.\n *\n * @param {Event} event the event object which led to the endZoom call.\n * @param {Dygraph} g The dygraph on which to end the zoom.\n * @param {Object} context The dragging context object (with\n * dragStartX/dragStartY/etc. properties). This function modifies the\n * context.\n */\nDygraphInteraction.endZoom = function (event, g, context) {\n g.clearZoomRect_();\n context.isZooming = false;\n DygraphInteraction.maybeTreatMouseOpAsClick(event, g, context);\n\n // The zoom rectangle is visibly clipped to the plot area, so its behavior\n // should be as well.\n // See http://code.google.com/p/dygraphs/issues/detail?id=280\n var plotArea = g.getArea();\n if (context.regionWidth >= 10 && context.dragDirection == utils.HORIZONTAL) {\n var left = Math.min(context.dragStartX, context.dragEndX),\n right = Math.max(context.dragStartX, context.dragEndX);\n left = Math.max(left, plotArea.x);\n right = Math.min(right, plotArea.x + plotArea.w);\n if (left < right) {\n g.doZoomX_(left, right);\n }\n context.cancelNextDblclick = true;\n } else if (context.regionHeight >= 10 && context.dragDirection == utils.VERTICAL) {\n var top = Math.min(context.dragStartY, context.dragEndY),\n bottom = Math.max(context.dragStartY, context.dragEndY);\n top = Math.max(top, plotArea.y);\n bottom = Math.min(bottom, plotArea.y + plotArea.h);\n if (top < bottom) {\n g.doZoomY_(top, bottom);\n }\n context.cancelNextDblclick = true;\n }\n context.dragStartX = null;\n context.dragStartY = null;\n};\n\n/**\n * @private\n */\nDygraphInteraction.startTouch = function (event, g, context) {\n event.preventDefault(); // touch browsers are all nice.\n if (event.touches.length > 1) {\n // If the user ever puts two fingers down, it's not a double tap.\n context.startTimeForDoubleTapMs = null;\n }\n\n var touches = [];\n for (var i = 0; i < event.touches.length; i++) {\n var t = event.touches[i];\n // we dispense with 'dragGetX_' because all touchBrowsers support pageX\n touches.push({\n pageX: t.pageX,\n pageY: t.pageY,\n dataX: g.toDataXCoord(t.pageX),\n dataY: g.toDataYCoord(t.pageY)\n // identifier: t.identifier\n });\n }\n context.initialTouches = touches;\n\n if (touches.length == 1) {\n // This is just a swipe.\n context.initialPinchCenter = touches[0];\n context.touchDirections = { x: true, y: true };\n } else if (touches.length >= 2) {\n // It's become a pinch!\n // In case there are 3+ touches, we ignore all but the \"first\" two.\n\n // only screen coordinates can be averaged (data coords could be log scale).\n context.initialPinchCenter = {\n pageX: 0.5 * (touches[0].pageX + touches[1].pageX),\n pageY: 0.5 * (touches[0].pageY + touches[1].pageY),\n\n // TODO(danvk): remove\n dataX: 0.5 * (touches[0].dataX + touches[1].dataX),\n dataY: 0.5 * (touches[0].dataY + touches[1].dataY)\n };\n\n // Make pinches in a 45-degree swath around either axis 1-dimensional zooms.\n var initialAngle = 180 / Math.PI * Math.atan2(context.initialPinchCenter.pageY - touches[0].pageY, touches[0].pageX - context.initialPinchCenter.pageX);\n\n // use symmetry to get it into the first quadrant.\n initialAngle = Math.abs(initialAngle);\n if (initialAngle > 90) initialAngle = 90 - initialAngle;\n\n context.touchDirections = {\n x: initialAngle < 90 - 45 / 2,\n y: initialAngle > 45 / 2\n };\n }\n\n // save the full x & y ranges.\n context.initialRange = {\n x: g.xAxisRange(),\n y: g.yAxisRange()\n };\n};\n\n/**\n * @private\n */\nDygraphInteraction.moveTouch = function (event, g, context) {\n // If the tap moves, then it's definitely not part of a double-tap.\n context.startTimeForDoubleTapMs = null;\n\n var i,\n touches = [];\n for (i = 0; i < event.touches.length; i++) {\n var t = event.touches[i];\n touches.push({\n pageX: t.pageX,\n pageY: t.pageY\n });\n }\n var initialTouches = context.initialTouches;\n\n var c_now;\n\n // old and new centers.\n var c_init = context.initialPinchCenter;\n if (touches.length == 1) {\n c_now = touches[0];\n } else {\n c_now = {\n pageX: 0.5 * (touches[0].pageX + touches[1].pageX),\n pageY: 0.5 * (touches[0].pageY + touches[1].pageY)\n };\n }\n\n // this is the \"swipe\" component\n // we toss it out for now, but could use it in the future.\n var swipe = {\n pageX: c_now.pageX - c_init.pageX,\n pageY: c_now.pageY - c_init.pageY\n };\n var dataWidth = context.initialRange.x[1] - context.initialRange.x[0];\n var dataHeight = context.initialRange.y[0] - context.initialRange.y[1];\n swipe.dataX = swipe.pageX / g.plotter_.area.w * dataWidth;\n swipe.dataY = swipe.pageY / g.plotter_.area.h * dataHeight;\n var xScale, yScale;\n\n // The residual bits are usually split into scale & rotate bits, but we split\n // them into x-scale and y-scale bits.\n if (touches.length == 1) {\n xScale = 1.0;\n yScale = 1.0;\n } else if (touches.length >= 2) {\n var initHalfWidth = initialTouches[1].pageX - c_init.pageX;\n xScale = (touches[1].pageX - c_now.pageX) / initHalfWidth;\n\n var initHalfHeight = initialTouches[1].pageY - c_init.pageY;\n yScale = (touches[1].pageY - c_now.pageY) / initHalfHeight;\n }\n\n // Clip scaling to [1/8, 8] to prevent too much blowup.\n xScale = Math.min(8, Math.max(0.125, xScale));\n yScale = Math.min(8, Math.max(0.125, yScale));\n\n var didZoom = false;\n if (context.touchDirections.x) {\n g.dateWindow_ = [c_init.dataX - swipe.dataX + (context.initialRange.x[0] - c_init.dataX) / xScale, c_init.dataX - swipe.dataX + (context.initialRange.x[1] - c_init.dataX) / xScale];\n didZoom = true;\n }\n\n if (context.touchDirections.y) {\n for (i = 0; i < 1 /*g.axes_.length*/; i++) {\n var axis = g.axes_[i];\n var logscale = g.attributes_.getForAxis(\"logscale\", i);\n if (logscale) {\n // TODO(danvk): implement\n } else {\n axis.valueRange = [c_init.dataY - swipe.dataY + (context.initialRange.y[0] - c_init.dataY) / yScale, c_init.dataY - swipe.dataY + (context.initialRange.y[1] - c_init.dataY) / yScale];\n didZoom = true;\n }\n }\n }\n\n g.drawGraph_(false);\n\n // We only call zoomCallback on zooms, not pans, to mirror desktop behavior.\n if (didZoom && touches.length > 1 && g.getFunctionOption('zoomCallback')) {\n var viewWindow = g.xAxisRange();\n g.getFunctionOption(\"zoomCallback\").call(g, viewWindow[0], viewWindow[1], g.yAxisRanges());\n }\n};\n\n/**\n * @private\n */\nDygraphInteraction.endTouch = function (event, g, context) {\n if (event.touches.length !== 0) {\n // this is effectively a \"reset\"\n DygraphInteraction.startTouch(event, g, context);\n } else if (event.changedTouches.length == 1) {\n // Could be part of a \"double tap\"\n // The heuristic here is that it's a double-tap if the two touchend events\n // occur within 500ms and within a 50x50 pixel box.\n var now = new Date().getTime();\n var t = event.changedTouches[0];\n if (context.startTimeForDoubleTapMs && now - context.startTimeForDoubleTapMs < 500 && context.doubleTapX && Math.abs(context.doubleTapX - t.screenX) < 50 && context.doubleTapY && Math.abs(context.doubleTapY - t.screenY) < 50) {\n g.resetZoom();\n } else {\n context.startTimeForDoubleTapMs = now;\n context.doubleTapX = t.screenX;\n context.doubleTapY = t.screenY;\n }\n }\n};\n\n// Determine the distance from x to [left, right].\nvar distanceFromInterval = function distanceFromInterval(x, left, right) {\n if (x < left) {\n return left - x;\n } else if (x > right) {\n return x - right;\n } else {\n return 0;\n }\n};\n\n/**\n * Returns the number of pixels by which the event happens from the nearest\n * edge of the chart. For events in the interior of the chart, this returns zero.\n */\nvar distanceFromChart = function distanceFromChart(event, g) {\n var chartPos = utils.findPos(g.canvas_);\n var box = {\n left: chartPos.x,\n right: chartPos.x + g.canvas_.offsetWidth,\n top: chartPos.y,\n bottom: chartPos.y + g.canvas_.offsetHeight\n };\n\n var pt = {\n x: utils.pageX(event),\n y: utils.pageY(event)\n };\n\n var dx = distanceFromInterval(pt.x, box.left, box.right),\n dy = distanceFromInterval(pt.y, box.top, box.bottom);\n return Math.max(dx, dy);\n};\n\n/**\n * Default interation model for dygraphs. You can refer to specific elements of\n * this when constructing your own interaction model, e.g.:\n * g.updateOptions( {\n * interactionModel: {\n * mousedown: DygraphInteraction.defaultInteractionModel.mousedown\n * }\n * } );\n */\nDygraphInteraction.defaultModel = {\n // Track the beginning of drag events\n mousedown: function mousedown(event, g, context) {\n // Right-click should not initiate a zoom.\n if (event.button && event.button == 2) return;\n\n context.initializeMouseDown(event, g, context);\n\n if (event.altKey || event.shiftKey) {\n DygraphInteraction.startPan(event, g, context);\n } else {\n DygraphInteraction.startZoom(event, g, context);\n }\n\n // Note: we register mousemove/mouseup on document to allow some leeway for\n // events to move outside of the chart. Interaction model events get\n // registered on the canvas, which is too small to allow this.\n var mousemove = function mousemove(event) {\n if (context.isZooming) {\n // When the mouse moves >200px from the chart edge, cancel the zoom.\n var d = distanceFromChart(event, g);\n if (d < DRAG_EDGE_MARGIN) {\n DygraphInteraction.moveZoom(event, g, context);\n } else {\n if (context.dragEndX !== null) {\n context.dragEndX = null;\n context.dragEndY = null;\n g.clearZoomRect_();\n }\n }\n } else if (context.isPanning) {\n DygraphInteraction.movePan(event, g, context);\n }\n };\n var mouseup = function mouseup(event) {\n if (context.isZooming) {\n if (context.dragEndX !== null) {\n DygraphInteraction.endZoom(event, g, context);\n } else {\n DygraphInteraction.maybeTreatMouseOpAsClick(event, g, context);\n }\n } else if (context.isPanning) {\n DygraphInteraction.endPan(event, g, context);\n }\n\n utils.removeEvent(document, 'mousemove', mousemove);\n utils.removeEvent(document, 'mouseup', mouseup);\n context.destroy();\n };\n\n g.addAndTrackEvent(document, 'mousemove', mousemove);\n g.addAndTrackEvent(document, 'mouseup', mouseup);\n },\n willDestroyContextMyself: true,\n\n touchstart: function touchstart(event, g, context) {\n DygraphInteraction.startTouch(event, g, context);\n },\n touchmove: function touchmove(event, g, context) {\n DygraphInteraction.moveTouch(event, g, context);\n },\n touchend: function touchend(event, g, context) {\n DygraphInteraction.endTouch(event, g, context);\n },\n\n // Disable zooming out if panning.\n dblclick: function dblclick(event, g, context) {\n if (context.cancelNextDblclick) {\n context.cancelNextDblclick = false;\n return;\n }\n\n // Give plugins a chance to grab this event.\n var e = {\n canvasx: context.dragEndX,\n canvasy: context.dragEndY,\n cancelable: true\n };\n if (g.cascadeEvents_('dblclick', e)) {\n return;\n }\n\n if (event.altKey || event.shiftKey) {\n return;\n }\n g.resetZoom();\n }\n};\n\n/*\nDygraph.DEFAULT_ATTRS.interactionModel = DygraphInteraction.defaultModel;\n\n// old ways of accessing these methods/properties\nDygraph.defaultInteractionModel = DygraphInteraction.defaultModel;\nDygraph.endZoom = DygraphInteraction.endZoom;\nDygraph.moveZoom = DygraphInteraction.moveZoom;\nDygraph.startZoom = DygraphInteraction.startZoom;\nDygraph.endPan = DygraphInteraction.endPan;\nDygraph.movePan = DygraphInteraction.movePan;\nDygraph.startPan = DygraphInteraction.startPan;\n*/\n\nDygraphInteraction.nonInteractiveModel_ = {\n mousedown: function mousedown(event, g, context) {\n context.initializeMouseDown(event, g, context);\n },\n mouseup: DygraphInteraction.maybeTreatMouseOpAsClick\n};\n\n// Default interaction model when using the range selector.\nDygraphInteraction.dragIsPanInteractionModel = {\n mousedown: function mousedown(event, g, context) {\n context.initializeMouseDown(event, g, context);\n DygraphInteraction.startPan(event, g, context);\n },\n mousemove: function mousemove(event, g, context) {\n if (context.isPanning) {\n DygraphInteraction.movePan(event, g, context);\n }\n },\n mouseup: function mouseup(event, g, context) {\n if (context.isPanning) {\n DygraphInteraction.endPan(event, g, context);\n }\n }\n};\n\nexports[\"default\"] = DygraphInteraction;\nmodule.exports = exports[\"default\"];","/**\n * @license\n * Copyright 2013 David Eberlein (david.eberlein@ch.sauter-bc.com)\n * MIT-licensed (http://opensource.org/licenses/MIT)\n */\n\n/**\n * @fileoverview This file contains the managment of data handlers\n * @author David Eberlein (david.eberlein@ch.sauter-bc.com)\n *\n * The idea is to define a common, generic data format that works for all data\n * structures supported by dygraphs. To make this possible, the DataHandler\n * interface is introduced. This makes it possible, that dygraph itself can work\n * with the same logic for every data type independent of the actual format and\n * the DataHandler takes care of the data format specific jobs.\n * DataHandlers are implemented for all data types supported by Dygraphs and\n * return Dygraphs compliant formats.\n * By default the correct DataHandler is chosen based on the options set.\n * Optionally the user may use his own DataHandler (similar to the plugin\n * system).\n *\n *\n * The unified data format returend by each handler is defined as so:\n * series[n][point] = [x,y,(extras)]\n *\n * This format contains the common basis that is needed to draw a simple line\n * series extended by optional extras for more complex graphing types. It\n * contains a primitive x value as first array entry, a primitive y value as\n * second array entry and an optional extras object for additional data needed.\n *\n * x must always be a number.\n * y must always be a number, NaN of type number or null.\n * extras is optional and must be interpreted by the DataHandler. It may be of\n * any type.\n *\n * In practice this might look something like this:\n * default: [x, yVal]\n * errorBar / customBar: [x, yVal, [yTopVariance, yBottomVariance] ]\n *\n */\n/*global Dygraph:false */\n/*global DygraphLayout:false */\n\n\"use strict\";\n\n/**\n *\n * The data handler is responsible for all data specific operations. All of the\n * series data it receives and returns is always in the unified data format.\n * Initially the unified data is created by the extractSeries method\n * @constructor\n */\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar DygraphDataHandler = function DygraphDataHandler() {};\n\nvar handler = DygraphDataHandler;\n\n/**\n * X-value array index constant for unified data samples.\n * @const\n * @type {number}\n */\nhandler.X = 0;\n\n/**\n * Y-value array index constant for unified data samples.\n * @const\n * @type {number}\n */\nhandler.Y = 1;\n\n/**\n * Extras-value array index constant for unified data samples.\n * @const\n * @type {number}\n */\nhandler.EXTRAS = 2;\n\n/**\n * Extracts one series from the raw data (a 2D array) into an array of the\n * unified data format.\n * This is where undesirable points (i.e. negative values on log scales and\n * missing values through which we wish to connect lines) are dropped.\n * TODO(danvk): the \"missing values\" bit above doesn't seem right.\n *\n * @param {!Array.} rawData The raw data passed into dygraphs where\n * rawData[i] = [x,ySeries1,...,ySeriesN].\n * @param {!number} seriesIndex Index of the series to extract. All other\n * series should be ignored.\n * @param {!DygraphOptions} options Dygraph options.\n * @return {Array.<[!number,?number,?]>} The series in the unified data format\n * where series[i] = [x,y,{extras}].\n */\nhandler.prototype.extractSeries = function (rawData, seriesIndex, options) {};\n\n/**\n * Converts a series to a Point array. The resulting point array must be\n * returned in increasing order of idx property.\n *\n * @param {!Array.<[!number,?number,?]>} series The series in the unified\n * data format where series[i] = [x,y,{extras}].\n * @param {!string} setName Name of the series.\n * @param {!number} boundaryIdStart Index offset of the first point, equal to the\n * number of skipped points left of the date window minimum (if any).\n * @return {!Array.} List of points for this series.\n */\nhandler.prototype.seriesToPoints = function (series, setName, boundaryIdStart) {\n // TODO(bhs): these loops are a hot-spot for high-point-count charts. In\n // fact,\n // on chrome+linux, they are 6 times more expensive than iterating through\n // the\n // points and drawing the lines. The brunt of the cost comes from allocating\n // the |point| structures.\n var points = [];\n for (var i = 0; i < series.length; ++i) {\n var item = series[i];\n var yraw = item[1];\n var yval = yraw === null ? null : handler.parseFloat(yraw);\n var point = {\n x: NaN,\n y: NaN,\n xval: handler.parseFloat(item[0]),\n yval: yval,\n name: setName, // TODO(danvk): is this really necessary?\n idx: i + boundaryIdStart\n };\n points.push(point);\n }\n this.onPointsCreated_(series, points);\n return points;\n};\n\n/**\n * Callback called for each series after the series points have been generated\n * which will later be used by the plotters to draw the graph.\n * Here data may be added to the seriesPoints which is needed by the plotters.\n * The indexes of series and points are in sync meaning the original data\n * sample for series[i] is points[i].\n *\n * @param {!Array.<[!number,?number,?]>} series The series in the unified\n * data format where series[i] = [x,y,{extras}].\n * @param {!Array.} points The corresponding points passed\n * to the plotter.\n * @protected\n */\nhandler.prototype.onPointsCreated_ = function (series, points) {};\n\n/**\n * Calculates the rolling average of a data set.\n *\n * @param {!Array.<[!number,?number,?]>} series The series in the unified\n * data format where series[i] = [x,y,{extras}].\n * @param {!number} rollPeriod The number of points over which to average the data\n * @param {!DygraphOptions} options The dygraph options.\n * @return {!Array.<[!number,?number,?]>} the rolled series.\n */\nhandler.prototype.rollingAverage = function (series, rollPeriod, options) {};\n\n/**\n * Computes the range of the data series (including confidence intervals).\n *\n * @param {!Array.<[!number,?number,?]>} series The series in the unified\n * data format where series[i] = [x, y, {extras}].\n * @param {!Array.} dateWindow The x-value range to display with\n * the format: [min, max].\n * @param {!DygraphOptions} options The dygraph options.\n * @return {Array.} The low and high extremes of the series in the\n * given window with the format: [low, high].\n */\nhandler.prototype.getExtremeYValues = function (series, dateWindow, options) {};\n\n/**\n * Callback called for each series after the layouting data has been\n * calculated before the series is drawn. Here normalized positioning data\n * should be calculated for the extras of each point.\n *\n * @param {!Array.} points The points passed to\n * the plotter.\n * @param {!Object} axis The axis on which the series will be plotted.\n * @param {!boolean} logscale Weather or not to use a logscale.\n */\nhandler.prototype.onLineEvaluated = function (points, axis, logscale) {};\n\n/**\n * Optimized replacement for parseFloat, which was way too slow when almost\n * all values were type number, with few edge cases, none of which were strings.\n * @param {?number} val\n * @return {number}\n * @protected\n */\nhandler.parseFloat = function (val) {\n // parseFloat(null) is NaN\n if (val === null) {\n return NaN;\n }\n\n // Assume it's a number or NaN. If it's something else, I'll be shocked.\n return val;\n};\n\nexports[\"default\"] = DygraphDataHandler;\nmodule.exports = exports[\"default\"];","import toDate from \"../toDate/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\n/**\n * @name isValid\n * @category Common Helpers\n * @summary Is the given date valid?\n *\n * @description\n * Returns false if argument is Invalid Date and true otherwise.\n * Argument is converted to Date using `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate}\n * Invalid Date is a Date, whose time value is NaN.\n *\n * Time value of Date: http://es5.github.io/#x15.9.1.1\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - Now `isValid` doesn't throw an exception\n * if the first argument is not an instance of Date.\n * Instead, argument is converted beforehand using `toDate`.\n *\n * Examples:\n *\n * | `isValid` argument | Before v2.0.0 | v2.0.0 onward |\n * |---------------------------|---------------|---------------|\n * | `new Date()` | `true` | `true` |\n * | `new Date('2016-01-01')` | `true` | `true` |\n * | `new Date('')` | `false` | `false` |\n * | `new Date(1488370835081)` | `true` | `true` |\n * | `new Date(NaN)` | `false` | `false` |\n * | `'2016-01-01'` | `TypeError` | `false` |\n * | `''` | `TypeError` | `false` |\n * | `1488370835081` | `TypeError` | `true` |\n * | `NaN` | `TypeError` | `false` |\n *\n * We introduce this change to make *date-fns* consistent with ECMAScript behavior\n * that try to coerce arguments to the expected type\n * (which is also the case with other *date-fns* functions).\n *\n * @param {*} date - the date to check\n * @returns {Boolean} the date is valid\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // For the valid date:\n * var result = isValid(new Date(2014, 1, 31))\n * //=> true\n *\n * @example\n * // For the value, convertable into a date:\n * var result = isValid(1393804800000)\n * //=> true\n *\n * @example\n * // For the invalid date:\n * var result = isValid(new Date(''))\n * //=> false\n */\n\nexport default function isValid(dirtyDate) {\n requiredArgs(1, arguments);\n var date = toDate(dirtyDate);\n return !isNaN(date);\n}","import toInteger from \"../_lib/toInteger/index.js\";\nimport addMilliseconds from \"../addMilliseconds/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\nvar MILLISECONDS_IN_MINUTE = 60000;\n/**\n * @name addMinutes\n * @category Minute Helpers\n * @summary Add the specified number of minutes to the given date.\n *\n * @description\n * Add the specified number of minutes to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of minutes to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the minutes added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 30 minutes to 10 July 2014 12:00:00:\n * const result = addMinutes(new Date(2014, 6, 10, 12, 0), 30)\n * //=> Thu Jul 10 2014 12:30:00\n */\n\nexport default function addMinutes(dirtyDate, dirtyAmount) {\n requiredArgs(2, arguments);\n var amount = toInteger(dirtyAmount);\n return addMilliseconds(dirtyDate, amount * MILLISECONDS_IN_MINUTE);\n}","import toInteger from \"../_lib/toInteger/index.js\";\nimport addMilliseconds from \"../addMilliseconds/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\nvar MILLISECONDS_IN_HOUR = 3600000;\n/**\n * @name addHours\n * @category Hour Helpers\n * @summary Add the specified number of hours to the given date.\n *\n * @description\n * Add the specified number of hours to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of hours to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the hours added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 2 hours to 10 July 2014 23:00:00:\n * const result = addHours(new Date(2014, 6, 10, 23, 0), 2)\n * //=> Fri Jul 11 2014 01:00:00\n */\n\nexport default function addHours(dirtyDate, dirtyAmount) {\n requiredArgs(2, arguments);\n var amount = toInteger(dirtyAmount);\n return addMilliseconds(dirtyDate, amount * MILLISECONDS_IN_HOUR);\n}","import toInteger from \"../_lib/toInteger/index.js\";\nimport addDays from \"../addDays/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\n/**\n * @name addWeeks\n * @category Week Helpers\n * @summary Add the specified number of weeks to the given date.\n *\n * @description\n * Add the specified number of week to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of weeks to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the weeks added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 4 weeks to 1 September 2014:\n * const result = addWeeks(new Date(2014, 8, 1), 4)\n * //=> Mon Sep 29 2014 00:00:00\n */\n\nexport default function addWeeks(dirtyDate, dirtyAmount) {\n requiredArgs(2, arguments);\n var amount = toInteger(dirtyAmount);\n var days = amount * 7;\n return addDays(dirtyDate, days);\n}","import toInteger from \"../_lib/toInteger/index.js\";\nimport addMonths from \"../addMonths/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\n/**\n * @name addYears\n * @category Year Helpers\n * @summary Add the specified number of years to the given date.\n *\n * @description\n * Add the specified number of years to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of years to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the years added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 5 years to 1 September 2014:\n * const result = addYears(new Date(2014, 8, 1), 5)\n * //=> Sun Sep 01 2019 00:00:00\n */\n\nexport default function addYears(dirtyDate, dirtyAmount) {\n requiredArgs(2, arguments);\n var amount = toInteger(dirtyAmount);\n return addMonths(dirtyDate, amount * 12);\n}","import toInteger from \"../_lib/toInteger/index.js\";\nimport toDate from \"../toDate/index.js\";\nimport getDaysInMonth from \"../getDaysInMonth/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\n/**\n * @name setMonth\n * @category Month Helpers\n * @summary Set the month to the given date.\n *\n * @description\n * Set the month to the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} month - the month of the new date\n * @returns {Date} the new date with the month set\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Set February to 1 September 2014:\n * const result = setMonth(new Date(2014, 8, 1), 1)\n * //=> Sat Feb 01 2014 00:00:00\n */\n\nexport default function setMonth(dirtyDate, dirtyMonth) {\n requiredArgs(2, arguments);\n var date = toDate(dirtyDate);\n var month = toInteger(dirtyMonth);\n var year = date.getFullYear();\n var day = date.getDate();\n var dateWithDesiredMonth = new Date(0);\n dateWithDesiredMonth.setFullYear(year, month, 15);\n dateWithDesiredMonth.setHours(0, 0, 0, 0);\n var daysInMonth = getDaysInMonth(dateWithDesiredMonth); // Set the last day of the new month\n // if the original date was the last day of the longer month\n\n date.setMonth(month, Math.min(day, daysInMonth));\n return date;\n}","import toDate from \"../toDate/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\n/**\n * @name getDaysInMonth\n * @category Month Helpers\n * @summary Get the number of days in a month of the given date.\n *\n * @description\n * Get the number of days in a month of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the number of days in a month\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // How many days are in February 2000?\n * const result = getDaysInMonth(new Date(2000, 1))\n * //=> 29\n */\n\nexport default function getDaysInMonth(dirtyDate) {\n requiredArgs(1, arguments);\n var date = toDate(dirtyDate);\n var year = date.getFullYear();\n var monthIndex = date.getMonth();\n var lastDayOfMonth = new Date(0);\n lastDayOfMonth.setFullYear(year, monthIndex + 1, 0);\n lastDayOfMonth.setHours(0, 0, 0, 0);\n return lastDayOfMonth.getDate();\n}","/* global window */\nimport ponyfill from './ponyfill.js';\n\nvar root;\n\nif (typeof self !== 'undefined') {\n root = self;\n} else if (typeof window !== 'undefined') {\n root = window;\n} else if (typeof global !== 'undefined') {\n root = global;\n} else if (typeof module !== 'undefined') {\n root = module;\n} else {\n root = Function('return this')();\n}\n\nvar result = ponyfill(root);\nexport default result;\n","import _curry2 from './internal/_curry2.js';\n\n/**\n * Retrieve the value at a given path.\n *\n * @func\n * @memberOf R\n * @since v0.2.0\n * @category Object\n * @typedefn Idx = String | Int\n * @sig [Idx] -> {a} -> a | Undefined\n * @param {Array} path The path to use.\n * @param {Object} obj The object to retrieve the nested property from.\n * @return {*} The data at `path`.\n * @see R.prop\n * @example\n *\n * R.path(['a', 'b'], {a: {b: 2}}); //=> 2\n * R.path(['a', 'b'], {c: {b: 2}}); //=> undefined\n */\nvar path = /*#__PURE__*/_curry2(function path(paths, obj) {\n var val = obj;\n var idx = 0;\n while (idx < paths.length) {\n if (val == null) {\n return;\n }\n val = val[paths[idx]];\n idx += 1;\n }\n return val;\n});\nexport default path;","'use strict';\n\nvar stringify = require('./stringify');\nvar parse = require('./parse');\nvar formats = require('./formats');\n\nmodule.exports = {\n formats: formats,\n parse: parse,\n stringify: stringify\n};\n","'use strict';\n\nvar reactIs = require('react-is');\n\n/**\n * Copyright 2015, Yahoo! Inc.\n * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.\n */\nvar REACT_STATICS = {\n childContextTypes: true,\n contextType: true,\n contextTypes: true,\n defaultProps: true,\n displayName: true,\n getDefaultProps: true,\n getDerivedStateFromError: true,\n getDerivedStateFromProps: true,\n mixins: true,\n propTypes: true,\n type: true\n};\nvar KNOWN_STATICS = {\n name: true,\n length: true,\n prototype: true,\n caller: true,\n callee: true,\n arguments: true,\n arity: true\n};\nvar FORWARD_REF_STATICS = {\n '$$typeof': true,\n render: true,\n defaultProps: true,\n displayName: true,\n propTypes: true\n};\nvar MEMO_STATICS = {\n '$$typeof': true,\n compare: true,\n defaultProps: true,\n displayName: true,\n propTypes: true,\n type: true\n};\nvar TYPE_STATICS = {};\nTYPE_STATICS[reactIs.ForwardRef] = FORWARD_REF_STATICS;\nTYPE_STATICS[reactIs.Memo] = MEMO_STATICS;\n\nfunction getStatics(component) {\n // React v16.11 and below\n if (reactIs.isMemo(component)) {\n return MEMO_STATICS;\n } // React v16.12 and above\n\n\n return TYPE_STATICS[component['$$typeof']] || REACT_STATICS;\n}\n\nvar defineProperty = Object.defineProperty;\nvar getOwnPropertyNames = Object.getOwnPropertyNames;\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\nvar getPrototypeOf = Object.getPrototypeOf;\nvar objectPrototype = Object.prototype;\nfunction hoistNonReactStatics(targetComponent, sourceComponent, blacklist) {\n if (typeof sourceComponent !== 'string') {\n // don't hoist over string (html) components\n if (objectPrototype) {\n var inheritedComponent = getPrototypeOf(sourceComponent);\n\n if (inheritedComponent && inheritedComponent !== objectPrototype) {\n hoistNonReactStatics(targetComponent, inheritedComponent, blacklist);\n }\n }\n\n var keys = getOwnPropertyNames(sourceComponent);\n\n if (getOwnPropertySymbols) {\n keys = keys.concat(getOwnPropertySymbols(sourceComponent));\n }\n\n var targetStatics = getStatics(targetComponent);\n var sourceStatics = getStatics(sourceComponent);\n\n for (var i = 0; i < keys.length; ++i) {\n var key = keys[i];\n\n if (!KNOWN_STATICS[key] && !(blacklist && blacklist[key]) && !(sourceStatics && sourceStatics[key]) && !(targetStatics && targetStatics[key])) {\n var descriptor = getOwnPropertyDescriptor(sourceComponent, key);\n\n try {\n // Avoid failures from read-only properties\n defineProperty(targetComponent, key, descriptor);\n } catch (e) {}\n }\n }\n }\n\n return targetComponent;\n}\n\nmodule.exports = hoistNonReactStatics;\n","'use strict';\n\nvar colorString = require('color-string');\nvar convert = require('color-convert');\n\nvar _slice = [].slice;\n\nvar skippedModels = [\n\t// to be honest, I don't really feel like keyword belongs in color convert, but eh.\n\t'keyword',\n\n\t// gray conflicts with some method names, and has its own method defined.\n\t'gray',\n\n\t// shouldn't really be in color-convert either...\n\t'hex'\n];\n\nvar hashedModelKeys = {};\nObject.keys(convert).forEach(function (model) {\n\thashedModelKeys[_slice.call(convert[model].labels).sort().join('')] = model;\n});\n\nvar limiters = {};\n\nfunction Color(obj, model) {\n\tif (!(this instanceof Color)) {\n\t\treturn new Color(obj, model);\n\t}\n\n\tif (model && model in skippedModels) {\n\t\tmodel = null;\n\t}\n\n\tif (model && !(model in convert)) {\n\t\tthrow new Error('Unknown model: ' + model);\n\t}\n\n\tvar i;\n\tvar channels;\n\n\tif (obj == null) { // eslint-disable-line no-eq-null,eqeqeq\n\t\tthis.model = 'rgb';\n\t\tthis.color = [0, 0, 0];\n\t\tthis.valpha = 1;\n\t} else if (obj instanceof Color) {\n\t\tthis.model = obj.model;\n\t\tthis.color = obj.color.slice();\n\t\tthis.valpha = obj.valpha;\n\t} else if (typeof obj === 'string') {\n\t\tvar result = colorString.get(obj);\n\t\tif (result === null) {\n\t\t\tthrow new Error('Unable to parse color from string: ' + obj);\n\t\t}\n\n\t\tthis.model = result.model;\n\t\tchannels = convert[this.model].channels;\n\t\tthis.color = result.value.slice(0, channels);\n\t\tthis.valpha = typeof result.value[channels] === 'number' ? result.value[channels] : 1;\n\t} else if (obj.length) {\n\t\tthis.model = model || 'rgb';\n\t\tchannels = convert[this.model].channels;\n\t\tvar newArr = _slice.call(obj, 0, channels);\n\t\tthis.color = zeroArray(newArr, channels);\n\t\tthis.valpha = typeof obj[channels] === 'number' ? obj[channels] : 1;\n\t} else if (typeof obj === 'number') {\n\t\t// this is always RGB - can be converted later on.\n\t\tobj &= 0xFFFFFF;\n\t\tthis.model = 'rgb';\n\t\tthis.color = [\n\t\t\t(obj >> 16) & 0xFF,\n\t\t\t(obj >> 8) & 0xFF,\n\t\t\tobj & 0xFF\n\t\t];\n\t\tthis.valpha = 1;\n\t} else {\n\t\tthis.valpha = 1;\n\n\t\tvar keys = Object.keys(obj);\n\t\tif ('alpha' in obj) {\n\t\t\tkeys.splice(keys.indexOf('alpha'), 1);\n\t\t\tthis.valpha = typeof obj.alpha === 'number' ? obj.alpha : 0;\n\t\t}\n\n\t\tvar hashedKeys = keys.sort().join('');\n\t\tif (!(hashedKeys in hashedModelKeys)) {\n\t\t\tthrow new Error('Unable to parse color from object: ' + JSON.stringify(obj));\n\t\t}\n\n\t\tthis.model = hashedModelKeys[hashedKeys];\n\n\t\tvar labels = convert[this.model].labels;\n\t\tvar color = [];\n\t\tfor (i = 0; i < labels.length; i++) {\n\t\t\tcolor.push(obj[labels[i]]);\n\t\t}\n\n\t\tthis.color = zeroArray(color);\n\t}\n\n\t// perform limitations (clamping, etc.)\n\tif (limiters[this.model]) {\n\t\tchannels = convert[this.model].channels;\n\t\tfor (i = 0; i < channels; i++) {\n\t\t\tvar limit = limiters[this.model][i];\n\t\t\tif (limit) {\n\t\t\t\tthis.color[i] = limit(this.color[i]);\n\t\t\t}\n\t\t}\n\t}\n\n\tthis.valpha = Math.max(0, Math.min(1, this.valpha));\n\n\tif (Object.freeze) {\n\t\tObject.freeze(this);\n\t}\n}\n\nColor.prototype = {\n\ttoString: function () {\n\t\treturn this.string();\n\t},\n\n\ttoJSON: function () {\n\t\treturn this[this.model]();\n\t},\n\n\tstring: function (places) {\n\t\tvar self = this.model in colorString.to ? this : this.rgb();\n\t\tself = self.round(typeof places === 'number' ? places : 1);\n\t\tvar args = self.valpha === 1 ? self.color : self.color.concat(this.valpha);\n\t\treturn colorString.to[self.model](args);\n\t},\n\n\tpercentString: function (places) {\n\t\tvar self = this.rgb().round(typeof places === 'number' ? places : 1);\n\t\tvar args = self.valpha === 1 ? self.color : self.color.concat(this.valpha);\n\t\treturn colorString.to.rgb.percent(args);\n\t},\n\n\tarray: function () {\n\t\treturn this.valpha === 1 ? this.color.slice() : this.color.concat(this.valpha);\n\t},\n\n\tobject: function () {\n\t\tvar result = {};\n\t\tvar channels = convert[this.model].channels;\n\t\tvar labels = convert[this.model].labels;\n\n\t\tfor (var i = 0; i < channels; i++) {\n\t\t\tresult[labels[i]] = this.color[i];\n\t\t}\n\n\t\tif (this.valpha !== 1) {\n\t\t\tresult.alpha = this.valpha;\n\t\t}\n\n\t\treturn result;\n\t},\n\n\tunitArray: function () {\n\t\tvar rgb = this.rgb().color;\n\t\trgb[0] /= 255;\n\t\trgb[1] /= 255;\n\t\trgb[2] /= 255;\n\n\t\tif (this.valpha !== 1) {\n\t\t\trgb.push(this.valpha);\n\t\t}\n\n\t\treturn rgb;\n\t},\n\n\tunitObject: function () {\n\t\tvar rgb = this.rgb().object();\n\t\trgb.r /= 255;\n\t\trgb.g /= 255;\n\t\trgb.b /= 255;\n\n\t\tif (this.valpha !== 1) {\n\t\t\trgb.alpha = this.valpha;\n\t\t}\n\n\t\treturn rgb;\n\t},\n\n\tround: function (places) {\n\t\tplaces = Math.max(places || 0, 0);\n\t\treturn new Color(this.color.map(roundToPlace(places)).concat(this.valpha), this.model);\n\t},\n\n\talpha: function (val) {\n\t\tif (arguments.length) {\n\t\t\treturn new Color(this.color.concat(Math.max(0, Math.min(1, val))), this.model);\n\t\t}\n\n\t\treturn this.valpha;\n\t},\n\n\t// rgb\n\tred: getset('rgb', 0, maxfn(255)),\n\tgreen: getset('rgb', 1, maxfn(255)),\n\tblue: getset('rgb', 2, maxfn(255)),\n\n\thue: getset(['hsl', 'hsv', 'hsl', 'hwb', 'hcg'], 0, function (val) { return ((val % 360) + 360) % 360; }), // eslint-disable-line brace-style\n\n\tsaturationl: getset('hsl', 1, maxfn(100)),\n\tlightness: getset('hsl', 2, maxfn(100)),\n\n\tsaturationv: getset('hsv', 1, maxfn(100)),\n\tvalue: getset('hsv', 2, maxfn(100)),\n\n\tchroma: getset('hcg', 1, maxfn(100)),\n\tgray: getset('hcg', 2, maxfn(100)),\n\n\twhite: getset('hwb', 1, maxfn(100)),\n\twblack: getset('hwb', 2, maxfn(100)),\n\n\tcyan: getset('cmyk', 0, maxfn(100)),\n\tmagenta: getset('cmyk', 1, maxfn(100)),\n\tyellow: getset('cmyk', 2, maxfn(100)),\n\tblack: getset('cmyk', 3, maxfn(100)),\n\n\tx: getset('xyz', 0, maxfn(100)),\n\ty: getset('xyz', 1, maxfn(100)),\n\tz: getset('xyz', 2, maxfn(100)),\n\n\tl: getset('lab', 0, maxfn(100)),\n\ta: getset('lab', 1),\n\tb: getset('lab', 2),\n\n\tkeyword: function (val) {\n\t\tif (arguments.length) {\n\t\t\treturn new Color(val);\n\t\t}\n\n\t\treturn convert[this.model].keyword(this.color);\n\t},\n\n\thex: function (val) {\n\t\tif (arguments.length) {\n\t\t\treturn new Color(val);\n\t\t}\n\n\t\treturn colorString.to.hex(this.rgb().round().color);\n\t},\n\n\trgbNumber: function () {\n\t\tvar rgb = this.rgb().color;\n\t\treturn ((rgb[0] & 0xFF) << 16) | ((rgb[1] & 0xFF) << 8) | (rgb[2] & 0xFF);\n\t},\n\n\tluminosity: function () {\n\t\t// http://www.w3.org/TR/WCAG20/#relativeluminancedef\n\t\tvar rgb = this.rgb().color;\n\n\t\tvar lum = [];\n\t\tfor (var i = 0; i < rgb.length; i++) {\n\t\t\tvar chan = rgb[i] / 255;\n\t\t\tlum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4);\n\t\t}\n\n\t\treturn 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2];\n\t},\n\n\tcontrast: function (color2) {\n\t\t// http://www.w3.org/TR/WCAG20/#contrast-ratiodef\n\t\tvar lum1 = this.luminosity();\n\t\tvar lum2 = color2.luminosity();\n\n\t\tif (lum1 > lum2) {\n\t\t\treturn (lum1 + 0.05) / (lum2 + 0.05);\n\t\t}\n\n\t\treturn (lum2 + 0.05) / (lum1 + 0.05);\n\t},\n\n\tlevel: function (color2) {\n\t\tvar contrastRatio = this.contrast(color2);\n\t\tif (contrastRatio >= 7.1) {\n\t\t\treturn 'AAA';\n\t\t}\n\n\t\treturn (contrastRatio >= 4.5) ? 'AA' : '';\n\t},\n\n\tisDark: function () {\n\t\t// YIQ equation from http://24ways.org/2010/calculating-color-contrast\n\t\tvar rgb = this.rgb().color;\n\t\tvar yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000;\n\t\treturn yiq < 128;\n\t},\n\n\tisLight: function () {\n\t\treturn !this.isDark();\n\t},\n\n\tnegate: function () {\n\t\tvar rgb = this.rgb();\n\t\tfor (var i = 0; i < 3; i++) {\n\t\t\trgb.color[i] = 255 - rgb.color[i];\n\t\t}\n\t\treturn rgb;\n\t},\n\n\tlighten: function (ratio) {\n\t\tvar hsl = this.hsl();\n\t\thsl.color[2] += hsl.color[2] * ratio;\n\t\treturn hsl;\n\t},\n\n\tdarken: function (ratio) {\n\t\tvar hsl = this.hsl();\n\t\thsl.color[2] -= hsl.color[2] * ratio;\n\t\treturn hsl;\n\t},\n\n\tsaturate: function (ratio) {\n\t\tvar hsl = this.hsl();\n\t\thsl.color[1] += hsl.color[1] * ratio;\n\t\treturn hsl;\n\t},\n\n\tdesaturate: function (ratio) {\n\t\tvar hsl = this.hsl();\n\t\thsl.color[1] -= hsl.color[1] * ratio;\n\t\treturn hsl;\n\t},\n\n\twhiten: function (ratio) {\n\t\tvar hwb = this.hwb();\n\t\thwb.color[1] += hwb.color[1] * ratio;\n\t\treturn hwb;\n\t},\n\n\tblacken: function (ratio) {\n\t\tvar hwb = this.hwb();\n\t\thwb.color[2] += hwb.color[2] * ratio;\n\t\treturn hwb;\n\t},\n\n\tgrayscale: function () {\n\t\t// http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale\n\t\tvar rgb = this.rgb().color;\n\t\tvar val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11;\n\t\treturn Color.rgb(val, val, val);\n\t},\n\n\tfade: function (ratio) {\n\t\treturn this.alpha(this.valpha - (this.valpha * ratio));\n\t},\n\n\topaquer: function (ratio) {\n\t\treturn this.alpha(this.valpha + (this.valpha * ratio));\n\t},\n\n\trotate: function (degrees) {\n\t\tvar hsl = this.hsl();\n\t\tvar hue = hsl.color[0];\n\t\thue = (hue + degrees) % 360;\n\t\thue = hue < 0 ? 360 + hue : hue;\n\t\thsl.color[0] = hue;\n\t\treturn hsl;\n\t},\n\n\tmix: function (mixinColor, weight) {\n\t\t// ported from sass implementation in C\n\t\t// https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209\n\t\tif (!mixinColor || !mixinColor.rgb) {\n\t\t\tthrow new Error('Argument to \"mix\" was not a Color instance, but rather an instance of ' + typeof mixinColor);\n\t\t}\n\t\tvar color1 = mixinColor.rgb();\n\t\tvar color2 = this.rgb();\n\t\tvar p = weight === undefined ? 0.5 : weight;\n\n\t\tvar w = 2 * p - 1;\n\t\tvar a = color1.alpha() - color2.alpha();\n\n\t\tvar w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;\n\t\tvar w2 = 1 - w1;\n\n\t\treturn Color.rgb(\n\t\t\t\tw1 * color1.red() + w2 * color2.red(),\n\t\t\t\tw1 * color1.green() + w2 * color2.green(),\n\t\t\t\tw1 * color1.blue() + w2 * color2.blue(),\n\t\t\t\tcolor1.alpha() * p + color2.alpha() * (1 - p));\n\t}\n};\n\n// model conversion methods and static constructors\nObject.keys(convert).forEach(function (model) {\n\tif (skippedModels.indexOf(model) !== -1) {\n\t\treturn;\n\t}\n\n\tvar channels = convert[model].channels;\n\n\t// conversion methods\n\tColor.prototype[model] = function () {\n\t\tif (this.model === model) {\n\t\t\treturn new Color(this);\n\t\t}\n\n\t\tif (arguments.length) {\n\t\t\treturn new Color(arguments, model);\n\t\t}\n\n\t\tvar newAlpha = typeof arguments[channels] === 'number' ? channels : this.valpha;\n\t\treturn new Color(assertArray(convert[this.model][model].raw(this.color)).concat(newAlpha), model);\n\t};\n\n\t// 'static' construction methods\n\tColor[model] = function (color) {\n\t\tif (typeof color === 'number') {\n\t\t\tcolor = zeroArray(_slice.call(arguments), channels);\n\t\t}\n\t\treturn new Color(color, model);\n\t};\n});\n\nfunction roundTo(num, places) {\n\treturn Number(num.toFixed(places));\n}\n\nfunction roundToPlace(places) {\n\treturn function (num) {\n\t\treturn roundTo(num, places);\n\t};\n}\n\nfunction getset(model, channel, modifier) {\n\tmodel = Array.isArray(model) ? model : [model];\n\n\tmodel.forEach(function (m) {\n\t\t(limiters[m] || (limiters[m] = []))[channel] = modifier;\n\t});\n\n\tmodel = model[0];\n\n\treturn function (val) {\n\t\tvar result;\n\n\t\tif (arguments.length) {\n\t\t\tif (modifier) {\n\t\t\t\tval = modifier(val);\n\t\t\t}\n\n\t\t\tresult = this[model]();\n\t\t\tresult.color[channel] = val;\n\t\t\treturn result;\n\t\t}\n\n\t\tresult = this[model]().color[channel];\n\t\tif (modifier) {\n\t\t\tresult = modifier(result);\n\t\t}\n\n\t\treturn result;\n\t};\n}\n\nfunction maxfn(max) {\n\treturn function (v) {\n\t\treturn Math.max(0, Math.min(max, v));\n\t};\n}\n\nfunction assertArray(val) {\n\treturn Array.isArray(val) ? val : [val];\n}\n\nfunction zeroArray(arr, length) {\n\tfor (var i = 0; i < length; i++) {\n\t\tif (typeof arr[i] !== 'number') {\n\t\t\tarr[i] = 0;\n\t\t}\n\t}\n\n\treturn arr;\n}\n\nmodule.exports = Color;\n","function memoize(fn) {\n var cache = Object.create(null);\n return function (arg) {\n if (cache[arg] === undefined) cache[arg] = fn(arg);\n return cache[arg];\n };\n}\n\nexport default memoize;\n","import memoize from '@emotion/memoize';\n\nvar reactPropsRegex = /^((children|dangerouslySetInnerHTML|key|ref|autoFocus|defaultValue|defaultChecked|innerHTML|suppressContentEditableWarning|suppressHydrationWarning|valueLink|abbr|accept|acceptCharset|accessKey|action|allow|allowUserMedia|allowPaymentRequest|allowFullScreen|allowTransparency|alt|async|autoComplete|autoPlay|capture|cellPadding|cellSpacing|challenge|charSet|checked|cite|classID|className|cols|colSpan|content|contentEditable|contextMenu|controls|controlsList|coords|crossOrigin|data|dateTime|decoding|default|defer|dir|disabled|disablePictureInPicture|download|draggable|encType|enterKeyHint|form|formAction|formEncType|formMethod|formNoValidate|formTarget|frameBorder|headers|height|hidden|high|href|hrefLang|htmlFor|httpEquiv|id|inputMode|integrity|is|keyParams|keyType|kind|label|lang|list|loading|loop|low|marginHeight|marginWidth|max|maxLength|media|mediaGroup|method|min|minLength|multiple|muted|name|nonce|noValidate|open|optimum|pattern|placeholder|playsInline|poster|preload|profile|radioGroup|readOnly|referrerPolicy|rel|required|reversed|role|rows|rowSpan|sandbox|scope|scoped|scrolling|seamless|selected|shape|size|sizes|slot|span|spellCheck|src|srcDoc|srcLang|srcSet|start|step|style|summary|tabIndex|target|title|translate|type|useMap|value|width|wmode|wrap|about|datatype|inlist|prefix|property|resource|typeof|vocab|autoCapitalize|autoCorrect|autoSave|color|incremental|fallback|inert|itemProp|itemScope|itemType|itemID|itemRef|on|option|results|security|unselectable|accentHeight|accumulate|additive|alignmentBaseline|allowReorder|alphabetic|amplitude|arabicForm|ascent|attributeName|attributeType|autoReverse|azimuth|baseFrequency|baselineShift|baseProfile|bbox|begin|bias|by|calcMode|capHeight|clip|clipPathUnits|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|colorProfile|colorRendering|contentScriptType|contentStyleType|cursor|cx|cy|d|decelerate|descent|diffuseConstant|direction|display|divisor|dominantBaseline|dur|dx|dy|edgeMode|elevation|enableBackground|end|exponent|externalResourcesRequired|fill|fillOpacity|fillRule|filter|filterRes|filterUnits|floodColor|floodOpacity|focusable|fontFamily|fontSize|fontSizeAdjust|fontStretch|fontStyle|fontVariant|fontWeight|format|from|fr|fx|fy|g1|g2|glyphName|glyphOrientationHorizontal|glyphOrientationVertical|glyphRef|gradientTransform|gradientUnits|hanging|horizAdvX|horizOriginX|ideographic|imageRendering|in|in2|intercept|k|k1|k2|k3|k4|kernelMatrix|kernelUnitLength|kerning|keyPoints|keySplines|keyTimes|lengthAdjust|letterSpacing|lightingColor|limitingConeAngle|local|markerEnd|markerMid|markerStart|markerHeight|markerUnits|markerWidth|mask|maskContentUnits|maskUnits|mathematical|mode|numOctaves|offset|opacity|operator|order|orient|orientation|origin|overflow|overlinePosition|overlineThickness|panose1|paintOrder|pathLength|patternContentUnits|patternTransform|patternUnits|pointerEvents|points|pointsAtX|pointsAtY|pointsAtZ|preserveAlpha|preserveAspectRatio|primitiveUnits|r|radius|refX|refY|renderingIntent|repeatCount|repeatDur|requiredExtensions|requiredFeatures|restart|result|rotate|rx|ry|scale|seed|shapeRendering|slope|spacing|specularConstant|specularExponent|speed|spreadMethod|startOffset|stdDeviation|stemh|stemv|stitchTiles|stopColor|stopOpacity|strikethroughPosition|strikethroughThickness|string|stroke|strokeDasharray|strokeDashoffset|strokeLinecap|strokeLinejoin|strokeMiterlimit|strokeOpacity|strokeWidth|surfaceScale|systemLanguage|tableValues|targetX|targetY|textAnchor|textDecoration|textRendering|textLength|to|transform|u1|u2|underlinePosition|underlineThickness|unicode|unicodeBidi|unicodeRange|unitsPerEm|vAlphabetic|vHanging|vIdeographic|vMathematical|values|vectorEffect|version|vertAdvY|vertOriginX|vertOriginY|viewBox|viewTarget|visibility|widths|wordSpacing|writingMode|x|xHeight|x1|x2|xChannelSelector|xlinkActuate|xlinkArcrole|xlinkHref|xlinkRole|xlinkShow|xlinkTitle|xlinkType|xmlBase|xmlns|xmlnsXlink|xmlLang|xmlSpace|y|y1|y2|yChannelSelector|z|zoomAndPan|for|class|autofocus)|(([Dd][Aa][Tt][Aa]|[Aa][Rr][Ii][Aa]|x)-.*))$/; // https://esbench.com/bench/5bfee68a4cd7e6009ef61d23\n\nvar isPropValid = /* #__PURE__ */memoize(function (prop) {\n return reactPropsRegex.test(prop) || prop.charCodeAt(0) === 111\n /* o */\n && prop.charCodeAt(1) === 110\n /* n */\n && prop.charCodeAt(2) < 91;\n}\n/* Z+1 */\n);\n\nexport default isPropValid;\n","import _objectAssign from './internal/_objectAssign.js';\nimport _curry1 from './internal/_curry1.js';\n\n/**\n * Merges a list of objects together into one object.\n *\n * @func\n * @memberOf R\n * @since v0.10.0\n * @category List\n * @sig [{k: v}] -> {k: v}\n * @param {Array} list An array of objects\n * @return {Object} A merged object.\n * @see R.reduce\n * @example\n *\n * R.mergeAll([{foo:1},{bar:2},{baz:3}]); //=> {foo:1,bar:2,baz:3}\n * R.mergeAll([{foo:1},{foo:2},{bar:2}]); //=> {foo:2,bar:2}\n * @symb R.mergeAll([{ x: 1 }, { y: 2 }, { z: 3 }]) = { x: 1, y: 2, z: 3 }\n */\nvar mergeAll = /*#__PURE__*/_curry1(function mergeAll(list) {\n return _objectAssign.apply(null, [{}].concat(list));\n});\nexport default mergeAll;","import nth from './nth.js';\n\n/**\n * Returns the last element of the given list or string.\n *\n * @func\n * @memberOf R\n * @since v0.1.4\n * @category List\n * @sig [a] -> a | Undefined\n * @sig String -> String\n * @param {*} list\n * @return {*}\n * @see R.init, R.head, R.tail\n * @example\n *\n * R.last(['fi', 'fo', 'fum']); //=> 'fum'\n * R.last([]); //=> undefined\n *\n * R.last('abc'); //=> 'c'\n * R.last(''); //=> ''\n */\nvar last = /*#__PURE__*/nth(-1);\nexport default last;","import _curry2 from './internal/_curry2.js';\nimport _isString from './internal/_isString.js';\n\n/**\n * Returns the nth element of the given list or string. If n is negative the\n * element at index length + n is returned.\n *\n * @func\n * @memberOf R\n * @since v0.1.0\n * @category List\n * @sig Number -> [a] -> a | Undefined\n * @sig Number -> String -> String\n * @param {Number} offset\n * @param {*} list\n * @return {*}\n * @example\n *\n * const list = ['foo', 'bar', 'baz', 'quux'];\n * R.nth(1, list); //=> 'bar'\n * R.nth(-1, list); //=> 'quux'\n * R.nth(-99, list); //=> undefined\n *\n * R.nth(2, 'abc'); //=> 'c'\n * R.nth(3, 'abc'); //=> ''\n * @symb R.nth(-1, [a, b, c]) = c\n * @symb R.nth(0, [a, b, c]) = a\n * @symb R.nth(1, [a, b, c]) = b\n */\nvar nth = /*#__PURE__*/_curry2(function nth(offset, list) {\n var idx = offset < 0 ? list.length + offset : offset;\n return _isString(list) ? list.charAt(idx) : list[idx];\n});\nexport default nth;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.add = add;\nexports.remove = remove;\nexports.has = has;\nexports.check = check;\nexports.all = all;\nexports.clear = clear;\nexports.enableChecking = enableChecking;\nexports.disableChecking = disableChecking;\nvar types = {};\nvar config = {\n checkExisting: true\n};\n\nfunction add(name) {\n types[name] = true;\n}\n\nfunction remove(name) {\n types[name] = false;\n}\n\nfunction has(name) {\n return !!types[name];\n}\n\nfunction check(name) {\n if (config.checkExisting && has(name)) {\n throw new TypeError(\"Duplicate action type: \".concat(name));\n }\n}\n\nfunction all() {\n return Object.keys(types).filter(has);\n}\n\nfunction clear() {\n all().forEach(remove);\n}\n\nfunction enableChecking() {\n config.checkExisting = true;\n}\n\nfunction disableChecking() {\n config.checkExisting = false;\n}","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports[\"default\"] = createAction;\n\nvar _types = require(\"./types\");\n\nvar id = 0;\n\nvar identity = function identity(arg) {\n return arg;\n};\n\nvar normalize = function normalize(dispatchOrStore) {\n if (dispatchOrStore && typeof dispatchOrStore.dispatch === 'function') {\n return dispatchOrStore.dispatch;\n } else {\n return dispatchOrStore;\n }\n};\n\nvar normalizeAll = function normalizeAll(dispatchOrStores) {\n if (Array.isArray(dispatchOrStores)) {\n return dispatchOrStores.map(normalize);\n } else {\n return normalize(dispatchOrStores);\n }\n};\n\nfunction createAction(description, payloadReducer, metaReducer) {\n if (typeof description === 'function') {\n metaReducer = payloadReducer;\n payloadReducer = description;\n description = undefined;\n }\n\n if (typeof payloadReducer !== 'function') {\n payloadReducer = identity;\n }\n\n if (typeof metaReducer !== 'function') {\n metaReducer = undefined;\n }\n\n var isSerializable = typeof description === 'string' && /^[0-9A-Z_]+$/.test(description);\n\n if (isSerializable) {\n (0, _types.check)(description);\n (0, _types.add)(description);\n } else {\n ++id;\n }\n\n var type = isSerializable ? description : \"[\".concat(id, \"]\").concat(description ? ' ' + description : '');\n var dispatchFunctions = undefined;\n\n function makeAction() {\n var payload = payloadReducer.apply(void 0, arguments);\n\n if (metaReducer) {\n return {\n type: type,\n payload: payload,\n error: payload instanceof Error,\n meta: metaReducer.apply(void 0, arguments)\n };\n }\n\n return {\n type: type,\n payload: payload,\n error: payload instanceof Error\n };\n }\n\n var makeAndDispatch = function makeAndDispatch(dispatchs, isError) {\n return function () {\n var payloadedAction = makeAction.apply(void 0, arguments);\n\n if (!payloadedAction.error) {\n payloadedAction.error = isError;\n }\n\n if (Array.isArray(dispatchs)) {\n return dispatchs.map(function (dispatch) {\n return dispatch(payloadedAction);\n });\n } else if (dispatchs) {\n return dispatchs(payloadedAction);\n } else {\n return payloadedAction;\n }\n };\n };\n\n function actionCreator() {\n return makeAndDispatch(dispatchFunctions, false).apply(void 0, arguments);\n }\n\n actionCreator.asError = function () {\n return makeAndDispatch(dispatchFunctions, true).apply(void 0, arguments);\n };\n\n actionCreator.getType = function () {\n return type;\n };\n\n actionCreator.toString = function () {\n return type;\n };\n\n actionCreator.raw = makeAction;\n\n actionCreator.assignTo = function (dispatchOrStores) {\n dispatchFunctions = normalizeAll(dispatchOrStores);\n return actionCreator;\n };\n\n actionCreator.assigned = function () {\n return !!dispatchFunctions;\n };\n\n actionCreator.bound = function () {\n return false;\n };\n\n actionCreator.dispatched = actionCreator.assigned;\n\n actionCreator.bindTo = function (dispatchOrStores) {\n var boundActionCreator = makeAndDispatch(normalizeAll(dispatchOrStores, false));\n boundActionCreator.asError = makeAndDispatch(normalizeAll(dispatchOrStores, true));\n boundActionCreator.raw = makeAction;\n boundActionCreator.getType = actionCreator.getType;\n boundActionCreator.toString = actionCreator.toString;\n\n boundActionCreator.assignTo = function () {\n return boundActionCreator;\n };\n\n boundActionCreator.bindTo = function () {\n return boundActionCreator;\n };\n\n boundActionCreator.assigned = function () {\n return false;\n };\n\n boundActionCreator.bound = function () {\n return true;\n };\n\n boundActionCreator.dispatched = boundActionCreator.bound;\n return boundActionCreator;\n };\n\n return actionCreator;\n}\n\n;","'use strict';\n\nmodule.exports = function bind(fn, thisArg) {\n return function wrap() {\n var args = new Array(arguments.length);\n for (var i = 0; i < args.length; i++) {\n args[i] = arguments[i];\n }\n return fn.apply(thisArg, args);\n };\n};\n","'use strict';\n\nvar utils = require('./../utils');\n\nfunction encode(val) {\n return encodeURIComponent(val).\n replace(/%3A/gi, ':').\n replace(/%24/g, '$').\n replace(/%2C/gi, ',').\n replace(/%20/g, '+').\n replace(/%5B/gi, '[').\n replace(/%5D/gi, ']');\n}\n\n/**\n * Build a URL by appending params to the end\n *\n * @param {string} url The base of the url (e.g., http://www.google.com)\n * @param {object} [params] The params to be appended\n * @returns {string} The formatted url\n */\nmodule.exports = function buildURL(url, params, paramsSerializer) {\n /*eslint no-param-reassign:0*/\n if (!params) {\n return url;\n }\n\n var serializedParams;\n if (paramsSerializer) {\n serializedParams = paramsSerializer(params);\n } else if (utils.isURLSearchParams(params)) {\n serializedParams = params.toString();\n } else {\n var parts = [];\n\n utils.forEach(params, function serialize(val, key) {\n if (val === null || typeof val === 'undefined') {\n return;\n }\n\n if (utils.isArray(val)) {\n key = key + '[]';\n } else {\n val = [val];\n }\n\n utils.forEach(val, function parseValue(v) {\n if (utils.isDate(v)) {\n v = v.toISOString();\n } else if (utils.isObject(v)) {\n v = JSON.stringify(v);\n }\n parts.push(encode(key) + '=' + encode(v));\n });\n });\n\n serializedParams = parts.join('&');\n }\n\n if (serializedParams) {\n var hashmarkIndex = url.indexOf('#');\n if (hashmarkIndex !== -1) {\n url = url.slice(0, hashmarkIndex);\n }\n\n url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;\n }\n\n return url;\n};\n","'use strict';\n\n/**\n * Update an Error with the specified config, error code, and response.\n *\n * @param {Error} error The error to update.\n * @param {Object} config The config.\n * @param {string} [code] The error code (for example, 'ECONNABORTED').\n * @param {Object} [request] The request.\n * @param {Object} [response] The response.\n * @returns {Error} The error.\n */\nmodule.exports = function enhanceError(error, config, code, request, response) {\n error.config = config;\n if (code) {\n error.code = code;\n }\n\n error.request = request;\n error.response = response;\n error.isAxiosError = true;\n\n error.toJSON = function toJSON() {\n return {\n // Standard\n message: this.message,\n name: this.name,\n // Microsoft\n description: this.description,\n number: this.number,\n // Mozilla\n fileName: this.fileName,\n lineNumber: this.lineNumber,\n columnNumber: this.columnNumber,\n stack: this.stack,\n // Axios\n config: this.config,\n code: this.code\n };\n };\n return error;\n};\n","'use strict';\n\nvar utils = require('./../utils');\nvar settle = require('./../core/settle');\nvar cookies = require('./../helpers/cookies');\nvar buildURL = require('./../helpers/buildURL');\nvar buildFullPath = require('../core/buildFullPath');\nvar parseHeaders = require('./../helpers/parseHeaders');\nvar isURLSameOrigin = require('./../helpers/isURLSameOrigin');\nvar createError = require('../core/createError');\n\nmodule.exports = function xhrAdapter(config) {\n return new Promise(function dispatchXhrRequest(resolve, reject) {\n var requestData = config.data;\n var requestHeaders = config.headers;\n var responseType = config.responseType;\n\n if (utils.isFormData(requestData)) {\n delete requestHeaders['Content-Type']; // Let the browser set it\n }\n\n var request = new XMLHttpRequest();\n\n // HTTP basic authentication\n if (config.auth) {\n var username = config.auth.username || '';\n var password = config.auth.password ? unescape(encodeURIComponent(config.auth.password)) : '';\n requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password);\n }\n\n var fullPath = buildFullPath(config.baseURL, config.url);\n request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true);\n\n // Set the request timeout in MS\n request.timeout = config.timeout;\n\n function onloadend() {\n if (!request) {\n return;\n }\n // Prepare the response\n var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null;\n var responseData = !responseType || responseType === 'text' || responseType === 'json' ?\n request.responseText : request.response;\n var response = {\n data: responseData,\n status: request.status,\n statusText: request.statusText,\n headers: responseHeaders,\n config: config,\n request: request\n };\n\n settle(resolve, reject, response);\n\n // Clean up request\n request = null;\n }\n\n if ('onloadend' in request) {\n // Use onloadend if available\n request.onloadend = onloadend;\n } else {\n // Listen for ready state to emulate onloadend\n request.onreadystatechange = function handleLoad() {\n if (!request || request.readyState !== 4) {\n return;\n }\n\n // The request errored out and we didn't get a response, this will be\n // handled by onerror instead\n // With one exception: request that using file: protocol, most browsers\n // will return status as 0 even though it's a successful request\n if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {\n return;\n }\n // readystate handler is calling before onerror or ontimeout handlers,\n // so we should call onloadend on the next 'tick'\n setTimeout(onloadend);\n };\n }\n\n // Handle browser request cancellation (as opposed to a manual cancellation)\n request.onabort = function handleAbort() {\n if (!request) {\n return;\n }\n\n reject(createError('Request aborted', config, 'ECONNABORTED', request));\n\n // Clean up request\n request = null;\n };\n\n // Handle low level network errors\n request.onerror = function handleError() {\n // Real errors are hidden from us by the browser\n // onerror should only fire if it's a network error\n reject(createError('Network Error', config, null, request));\n\n // Clean up request\n request = null;\n };\n\n // Handle timeout\n request.ontimeout = function handleTimeout() {\n var timeoutErrorMessage = 'timeout of ' + config.timeout + 'ms exceeded';\n if (config.timeoutErrorMessage) {\n timeoutErrorMessage = config.timeoutErrorMessage;\n }\n reject(createError(\n timeoutErrorMessage,\n config,\n config.transitional && config.transitional.clarifyTimeoutError ? 'ETIMEDOUT' : 'ECONNABORTED',\n request));\n\n // Clean up request\n request = null;\n };\n\n // Add xsrf header\n // This is only done if running in a standard browser environment.\n // Specifically not if we're in a web worker, or react-native.\n if (utils.isStandardBrowserEnv()) {\n // Add xsrf header\n var xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath)) && config.xsrfCookieName ?\n cookies.read(config.xsrfCookieName) :\n undefined;\n\n if (xsrfValue) {\n requestHeaders[config.xsrfHeaderName] = xsrfValue;\n }\n }\n\n // Add headers to the request\n if ('setRequestHeader' in request) {\n utils.forEach(requestHeaders, function setRequestHeader(val, key) {\n if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {\n // Remove Content-Type if data is undefined\n delete requestHeaders[key];\n } else {\n // Otherwise add header to the request\n request.setRequestHeader(key, val);\n }\n });\n }\n\n // Add withCredentials to request if needed\n if (!utils.isUndefined(config.withCredentials)) {\n request.withCredentials = !!config.withCredentials;\n }\n\n // Add responseType to request if needed\n if (responseType && responseType !== 'json') {\n request.responseType = config.responseType;\n }\n\n // Handle progress if needed\n if (typeof config.onDownloadProgress === 'function') {\n request.addEventListener('progress', config.onDownloadProgress);\n }\n\n // Not all browsers support upload events\n if (typeof config.onUploadProgress === 'function' && request.upload) {\n request.upload.addEventListener('progress', config.onUploadProgress);\n }\n\n if (config.cancelToken) {\n // Handle cancellation\n config.cancelToken.promise.then(function onCanceled(cancel) {\n if (!request) {\n return;\n }\n\n request.abort();\n reject(cancel);\n // Clean up request\n request = null;\n });\n }\n\n if (!requestData) {\n requestData = null;\n }\n\n // Send the request\n request.send(requestData);\n });\n};\n","'use strict';\n\nvar enhanceError = require('./enhanceError');\n\n/**\n * Create an Error with the specified message, config, error code, request and response.\n *\n * @param {string} message The error message.\n * @param {Object} config The config.\n * @param {string} [code] The error code (for example, 'ECONNABORTED').\n * @param {Object} [request] The request.\n * @param {Object} [response] The response.\n * @returns {Error} The created error.\n */\nmodule.exports = function createError(message, config, code, request, response) {\n var error = new Error(message);\n return enhanceError(error, config, code, request, response);\n};\n","'use strict';\n\nmodule.exports = function isCancel(value) {\n return !!(value && value.__CANCEL__);\n};\n","'use strict';\n\nvar utils = require('../utils');\n\n/**\n * Config-specific merge-function which creates a new config-object\n * by merging two configuration objects together.\n *\n * @param {Object} config1\n * @param {Object} config2\n * @returns {Object} New object resulting from merging config2 to config1\n */\nmodule.exports = function mergeConfig(config1, config2) {\n // eslint-disable-next-line no-param-reassign\n config2 = config2 || {};\n var config = {};\n\n var valueFromConfig2Keys = ['url', 'method', 'data'];\n var mergeDeepPropertiesKeys = ['headers', 'auth', 'proxy', 'params'];\n var defaultToConfig2Keys = [\n 'baseURL', 'transformRequest', 'transformResponse', 'paramsSerializer',\n 'timeout', 'timeoutMessage', 'withCredentials', 'adapter', 'responseType', 'xsrfCookieName',\n 'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress', 'decompress',\n 'maxContentLength', 'maxBodyLength', 'maxRedirects', 'transport', 'httpAgent',\n 'httpsAgent', 'cancelToken', 'socketPath', 'responseEncoding'\n ];\n var directMergeKeys = ['validateStatus'];\n\n function getMergedValue(target, source) {\n if (utils.isPlainObject(target) && utils.isPlainObject(source)) {\n return utils.merge(target, source);\n } else if (utils.isPlainObject(source)) {\n return utils.merge({}, source);\n } else if (utils.isArray(source)) {\n return source.slice();\n }\n return source;\n }\n\n function mergeDeepProperties(prop) {\n if (!utils.isUndefined(config2[prop])) {\n config[prop] = getMergedValue(config1[prop], config2[prop]);\n } else if (!utils.isUndefined(config1[prop])) {\n config[prop] = getMergedValue(undefined, config1[prop]);\n }\n }\n\n utils.forEach(valueFromConfig2Keys, function valueFromConfig2(prop) {\n if (!utils.isUndefined(config2[prop])) {\n config[prop] = getMergedValue(undefined, config2[prop]);\n }\n });\n\n utils.forEach(mergeDeepPropertiesKeys, mergeDeepProperties);\n\n utils.forEach(defaultToConfig2Keys, function defaultToConfig2(prop) {\n if (!utils.isUndefined(config2[prop])) {\n config[prop] = getMergedValue(undefined, config2[prop]);\n } else if (!utils.isUndefined(config1[prop])) {\n config[prop] = getMergedValue(undefined, config1[prop]);\n }\n });\n\n utils.forEach(directMergeKeys, function merge(prop) {\n if (prop in config2) {\n config[prop] = getMergedValue(config1[prop], config2[prop]);\n } else if (prop in config1) {\n config[prop] = getMergedValue(undefined, config1[prop]);\n }\n });\n\n var axiosKeys = valueFromConfig2Keys\n .concat(mergeDeepPropertiesKeys)\n .concat(defaultToConfig2Keys)\n .concat(directMergeKeys);\n\n var otherKeys = Object\n .keys(config1)\n .concat(Object.keys(config2))\n .filter(function filterAxiosKeys(key) {\n return axiosKeys.indexOf(key) === -1;\n });\n\n utils.forEach(otherKeys, mergeDeepProperties);\n\n return config;\n};\n","'use strict';\n\n/**\n * A `Cancel` is an object that is thrown when an operation is canceled.\n *\n * @class\n * @param {string=} message The message.\n */\nfunction Cancel(message) {\n this.message = message;\n}\n\nCancel.prototype.toString = function toString() {\n return 'Cancel' + (this.message ? ': ' + this.message : '');\n};\n\nCancel.prototype.__CANCEL__ = true;\n\nmodule.exports = Cancel;\n","'use strict';\n\nvar slice = Array.prototype.slice;\nvar isArgs = require('./isArguments');\n\nvar origKeys = Object.keys;\nvar keysShim = origKeys ? function keys(o) { return origKeys(o); } : require('./implementation');\n\nvar originalKeys = Object.keys;\n\nkeysShim.shim = function shimObjectKeys() {\n\tif (Object.keys) {\n\t\tvar keysWorksWithArguments = (function () {\n\t\t\t// Safari 5.0 bug\n\t\t\tvar args = Object.keys(arguments);\n\t\t\treturn args && args.length === arguments.length;\n\t\t}(1, 2));\n\t\tif (!keysWorksWithArguments) {\n\t\t\tObject.keys = function keys(object) { // eslint-disable-line func-name-matching\n\t\t\t\tif (isArgs(object)) {\n\t\t\t\t\treturn originalKeys(slice.call(object));\n\t\t\t\t}\n\t\t\t\treturn originalKeys(object);\n\t\t\t};\n\t\t}\n\t} else {\n\t\tObject.keys = keysShim;\n\t}\n\treturn Object.keys || keysShim;\n};\n\nmodule.exports = keysShim;\n","'use strict';\n\nvar toStr = Object.prototype.toString;\n\nmodule.exports = function isArguments(value) {\n\tvar str = toStr.call(value);\n\tvar isArgs = str === '[object Arguments]';\n\tif (!isArgs) {\n\t\tisArgs = str !== '[object Array]' &&\n\t\t\tvalue !== null &&\n\t\t\ttypeof value === 'object' &&\n\t\t\ttypeof value.length === 'number' &&\n\t\t\tvalue.length >= 0 &&\n\t\t\ttoStr.call(value.callee) === '[object Function]';\n\t}\n\treturn isArgs;\n};\n","'use strict';\n\nvar bind = require('function-bind');\n\nmodule.exports = bind.call(Function.call, Object.prototype.hasOwnProperty);\n","'use strict';\n\nvar toObject = Object;\nvar TypeErr = TypeError;\n\nmodule.exports = function flags() {\n\tif (this != null && this !== toObject(this)) {\n\t\tthrow new TypeErr('RegExp.prototype.flags getter called on non-object');\n\t}\n\tvar result = '';\n\tif (this.global) {\n\t\tresult += 'g';\n\t}\n\tif (this.ignoreCase) {\n\t\tresult += 'i';\n\t}\n\tif (this.multiline) {\n\t\tresult += 'm';\n\t}\n\tif (this.dotAll) {\n\t\tresult += 's';\n\t}\n\tif (this.unicode) {\n\t\tresult += 'u';\n\t}\n\tif (this.sticky) {\n\t\tresult += 'y';\n\t}\n\treturn result;\n};\n","'use strict';\n\nvar implementation = require('./implementation');\n\nvar supportsDescriptors = require('define-properties').supportsDescriptors;\nvar gOPD = Object.getOwnPropertyDescriptor;\nvar TypeErr = TypeError;\n\nmodule.exports = function getPolyfill() {\n\tif (!supportsDescriptors) {\n\t\tthrow new TypeErr('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');\n\t}\n\tif (/a/mig.flags === 'gim') {\n\t\tvar descriptor = gOPD(RegExp.prototype, 'flags');\n\t\tif (descriptor && typeof descriptor.get === 'function' && typeof (/a/).dotAll === 'boolean') {\n\t\t\treturn descriptor.get;\n\t\t}\n\t}\n\treturn implementation;\n};\n","'use strict';\n\nvar formats = require('./formats');\n\nvar has = Object.prototype.hasOwnProperty;\nvar isArray = Array.isArray;\n\nvar hexTable = (function () {\n var array = [];\n for (var i = 0; i < 256; ++i) {\n array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase());\n }\n\n return array;\n}());\n\nvar compactQueue = function compactQueue(queue) {\n while (queue.length > 1) {\n var item = queue.pop();\n var obj = item.obj[item.prop];\n\n if (isArray(obj)) {\n var compacted = [];\n\n for (var j = 0; j < obj.length; ++j) {\n if (typeof obj[j] !== 'undefined') {\n compacted.push(obj[j]);\n }\n }\n\n item.obj[item.prop] = compacted;\n }\n }\n};\n\nvar arrayToObject = function arrayToObject(source, options) {\n var obj = options && options.plainObjects ? Object.create(null) : {};\n for (var i = 0; i < source.length; ++i) {\n if (typeof source[i] !== 'undefined') {\n obj[i] = source[i];\n }\n }\n\n return obj;\n};\n\nvar merge = function merge(target, source, options) {\n /* eslint no-param-reassign: 0 */\n if (!source) {\n return target;\n }\n\n if (typeof source !== 'object') {\n if (isArray(target)) {\n target.push(source);\n } else if (target && typeof target === 'object') {\n if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) {\n target[source] = true;\n }\n } else {\n return [target, source];\n }\n\n return target;\n }\n\n if (!target || typeof target !== 'object') {\n return [target].concat(source);\n }\n\n var mergeTarget = target;\n if (isArray(target) && !isArray(source)) {\n mergeTarget = arrayToObject(target, options);\n }\n\n if (isArray(target) && isArray(source)) {\n source.forEach(function (item, i) {\n if (has.call(target, i)) {\n var targetItem = target[i];\n if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {\n target[i] = merge(targetItem, item, options);\n } else {\n target.push(item);\n }\n } else {\n target[i] = item;\n }\n });\n return target;\n }\n\n return Object.keys(source).reduce(function (acc, key) {\n var value = source[key];\n\n if (has.call(acc, key)) {\n acc[key] = merge(acc[key], value, options);\n } else {\n acc[key] = value;\n }\n return acc;\n }, mergeTarget);\n};\n\nvar assign = function assignSingleSource(target, source) {\n return Object.keys(source).reduce(function (acc, key) {\n acc[key] = source[key];\n return acc;\n }, target);\n};\n\nvar decode = function (str, decoder, charset) {\n var strWithoutPlus = str.replace(/\\+/g, ' ');\n if (charset === 'iso-8859-1') {\n // unescape never throws, no try...catch needed:\n return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape);\n }\n // utf-8\n try {\n return decodeURIComponent(strWithoutPlus);\n } catch (e) {\n return strWithoutPlus;\n }\n};\n\nvar encode = function encode(str, defaultEncoder, charset, kind, format) {\n // This code was originally written by Brian White (mscdex) for the io.js core querystring library.\n // It has been adapted here for stricter adherence to RFC 3986\n if (str.length === 0) {\n return str;\n }\n\n var string = str;\n if (typeof str === 'symbol') {\n string = Symbol.prototype.toString.call(str);\n } else if (typeof str !== 'string') {\n string = String(str);\n }\n\n if (charset === 'iso-8859-1') {\n return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) {\n return '%26%23' + parseInt($0.slice(2), 16) + '%3B';\n });\n }\n\n var out = '';\n for (var i = 0; i < string.length; ++i) {\n var c = string.charCodeAt(i);\n\n if (\n c === 0x2D // -\n || c === 0x2E // .\n || c === 0x5F // _\n || c === 0x7E // ~\n || (c >= 0x30 && c <= 0x39) // 0-9\n || (c >= 0x41 && c <= 0x5A) // a-z\n || (c >= 0x61 && c <= 0x7A) // A-Z\n || (format === formats.RFC1738 && (c === 0x28 || c === 0x29)) // ( )\n ) {\n out += string.charAt(i);\n continue;\n }\n\n if (c < 0x80) {\n out = out + hexTable[c];\n continue;\n }\n\n if (c < 0x800) {\n out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]);\n continue;\n }\n\n if (c < 0xD800 || c >= 0xE000) {\n out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]);\n continue;\n }\n\n i += 1;\n c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));\n /* eslint operator-linebreak: [2, \"before\"] */\n out += hexTable[0xF0 | (c >> 18)]\n + hexTable[0x80 | ((c >> 12) & 0x3F)]\n + hexTable[0x80 | ((c >> 6) & 0x3F)]\n + hexTable[0x80 | (c & 0x3F)];\n }\n\n return out;\n};\n\nvar compact = function compact(value) {\n var queue = [{ obj: { o: value }, prop: 'o' }];\n var refs = [];\n\n for (var i = 0; i < queue.length; ++i) {\n var item = queue[i];\n var obj = item.obj[item.prop];\n\n var keys = Object.keys(obj);\n for (var j = 0; j < keys.length; ++j) {\n var key = keys[j];\n var val = obj[key];\n if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) {\n queue.push({ obj: obj, prop: key });\n refs.push(val);\n }\n }\n }\n\n compactQueue(queue);\n\n return value;\n};\n\nvar isRegExp = function isRegExp(obj) {\n return Object.prototype.toString.call(obj) === '[object RegExp]';\n};\n\nvar isBuffer = function isBuffer(obj) {\n if (!obj || typeof obj !== 'object') {\n return false;\n }\n\n return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));\n};\n\nvar combine = function combine(a, b) {\n return [].concat(a, b);\n};\n\nvar maybeMap = function maybeMap(val, fn) {\n if (isArray(val)) {\n var mapped = [];\n for (var i = 0; i < val.length; i += 1) {\n mapped.push(fn(val[i]));\n }\n return mapped;\n }\n return fn(val);\n};\n\nmodule.exports = {\n arrayToObject: arrayToObject,\n assign: assign,\n combine: combine,\n compact: compact,\n decode: decode,\n encode: encode,\n isBuffer: isBuffer,\n isRegExp: isRegExp,\n maybeMap: maybeMap,\n merge: merge\n};\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.DateTimeFormat = void 0;\nvar tslib_1 = require(\"tslib\");\nvar ecma402_abstract_1 = require(\"@formatjs/ecma402-abstract\");\nvar get_internal_slots_1 = tslib_1.__importDefault(require(\"./get_internal_slots\"));\nvar links_1 = tslib_1.__importDefault(require(\"./data/links\"));\nvar packer_1 = require(\"./packer\");\nvar FormatDateTime_1 = require(\"./abstract/FormatDateTime\");\nvar InitializeDateTimeFormat_1 = require(\"./abstract/InitializeDateTimeFormat\");\nvar utils_1 = require(\"./abstract/utils\");\nvar FormatDateTimeToParts_1 = require(\"./abstract/FormatDateTimeToParts\");\nvar FormatDateTimeRangeToParts_1 = require(\"./abstract/FormatDateTimeRangeToParts\");\nvar FormatDateTimeRange_1 = require(\"./abstract/FormatDateTimeRange\");\nvar skeleton_1 = require(\"./abstract/skeleton\");\nvar UPPERCASED_LINKS = Object.keys(links_1.default).reduce(function (all, l) {\n all[l.toUpperCase()] = links_1.default[l];\n return all;\n}, {});\nvar RESOLVED_OPTIONS_KEYS = [\n 'locale',\n 'calendar',\n 'numberingSystem',\n 'dateStyle',\n 'timeStyle',\n 'timeZone',\n 'hourCycle',\n 'weekday',\n 'era',\n 'year',\n 'month',\n 'day',\n 'hour',\n 'minute',\n 'second',\n 'timeZoneName',\n];\nvar formatDescriptor = {\n enumerable: false,\n configurable: true,\n get: function () {\n if (typeof this !== 'object' ||\n !ecma402_abstract_1.OrdinaryHasInstance(exports.DateTimeFormat, this)) {\n throw TypeError('Intl.DateTimeFormat format property accessor called on incompatible receiver');\n }\n var internalSlots = get_internal_slots_1.default(this);\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n var dtf = this;\n var boundFormat = internalSlots.boundFormat;\n if (boundFormat === undefined) {\n // https://tc39.es/proposal-unified-intl-numberformat/section11/numberformat_diff_out.html#sec-number-format-functions\n boundFormat = function (date) {\n var x;\n if (date === undefined) {\n x = Date.now();\n }\n else {\n x = Number(date);\n }\n return FormatDateTime_1.FormatDateTime(dtf, x, {\n getInternalSlots: get_internal_slots_1.default,\n localeData: exports.DateTimeFormat.localeData,\n tzData: exports.DateTimeFormat.tzData,\n getDefaultTimeZone: exports.DateTimeFormat.getDefaultTimeZone,\n });\n };\n try {\n // https://github.com/tc39/test262/blob/master/test/intl402/NumberFormat/prototype/format/format-function-name.js\n Object.defineProperty(boundFormat, 'name', {\n configurable: true,\n enumerable: false,\n writable: false,\n value: '',\n });\n }\n catch (e) {\n // In older browser (e.g Chrome 36 like polyfill.io)\n // TypeError: Cannot redefine property: name\n }\n internalSlots.boundFormat = boundFormat;\n }\n return boundFormat;\n },\n};\ntry {\n // https://github.com/tc39/test262/blob/master/test/intl402/NumberFormat/prototype/format/name.js\n Object.defineProperty(formatDescriptor.get, 'name', {\n configurable: true,\n enumerable: false,\n writable: false,\n value: 'get format',\n });\n}\ncatch (e) {\n // In older browser (e.g Chrome 36 like polyfill.io)\n // TypeError: Cannot redefine property: name\n}\nexports.DateTimeFormat = function (locales, options) {\n // Cannot use `new.target` bc of IE11 & TS transpiles it to something else\n if (!this || !ecma402_abstract_1.OrdinaryHasInstance(exports.DateTimeFormat, this)) {\n return new exports.DateTimeFormat(locales, options);\n }\n InitializeDateTimeFormat_1.InitializeDateTimeFormat(this, locales, options, {\n tzData: exports.DateTimeFormat.tzData,\n uppercaseLinks: UPPERCASED_LINKS,\n availableLocales: exports.DateTimeFormat.availableLocales,\n relevantExtensionKeys: exports.DateTimeFormat.relevantExtensionKeys,\n getDefaultLocale: exports.DateTimeFormat.getDefaultLocale,\n getDefaultTimeZone: exports.DateTimeFormat.getDefaultTimeZone,\n getInternalSlots: get_internal_slots_1.default,\n localeData: exports.DateTimeFormat.localeData,\n });\n /** IMPL START */\n var internalSlots = get_internal_slots_1.default(this);\n var dataLocale = internalSlots.dataLocale;\n var dataLocaleData = exports.DateTimeFormat.localeData[dataLocale];\n ecma402_abstract_1.invariant(dataLocaleData !== undefined, \"Cannot load locale-dependent data for \" + dataLocale + \".\");\n /** IMPL END */\n};\n// Static properties\necma402_abstract_1.defineProperty(exports.DateTimeFormat, 'supportedLocalesOf', {\n value: function supportedLocalesOf(locales, options) {\n return ecma402_abstract_1.SupportedLocales(exports.DateTimeFormat.availableLocales, ecma402_abstract_1.CanonicalizeLocaleList(locales), options);\n },\n});\necma402_abstract_1.defineProperty(exports.DateTimeFormat.prototype, 'resolvedOptions', {\n value: function resolvedOptions() {\n if (typeof this !== 'object' ||\n !ecma402_abstract_1.OrdinaryHasInstance(exports.DateTimeFormat, this)) {\n throw TypeError('Method Intl.DateTimeFormat.prototype.resolvedOptions called on incompatible receiver');\n }\n var internalSlots = get_internal_slots_1.default(this);\n var ro = {};\n for (var _i = 0, RESOLVED_OPTIONS_KEYS_1 = RESOLVED_OPTIONS_KEYS; _i < RESOLVED_OPTIONS_KEYS_1.length; _i++) {\n var key = RESOLVED_OPTIONS_KEYS_1[_i];\n var value = internalSlots[key];\n if (key === 'hourCycle') {\n var hour12 = value === 'h11' || value === 'h12'\n ? true\n : value === 'h23' || value === 'h24'\n ? false\n : undefined;\n if (hour12 !== undefined) {\n ro.hour12 = hour12;\n }\n }\n if (utils_1.DATE_TIME_PROPS.indexOf(key) > -1) {\n if (internalSlots.dateStyle !== undefined ||\n internalSlots.timeStyle !== undefined) {\n value = undefined;\n }\n }\n if (value !== undefined) {\n ro[key] = value;\n }\n }\n return ro;\n },\n});\necma402_abstract_1.defineProperty(exports.DateTimeFormat.prototype, 'formatToParts', {\n value: function formatToParts(date) {\n if (date === undefined) {\n date = Date.now();\n }\n else {\n date = ecma402_abstract_1.ToNumber(date);\n }\n return FormatDateTimeToParts_1.FormatDateTimeToParts(this, date, {\n getInternalSlots: get_internal_slots_1.default,\n localeData: exports.DateTimeFormat.localeData,\n tzData: exports.DateTimeFormat.tzData,\n getDefaultTimeZone: exports.DateTimeFormat.getDefaultTimeZone,\n });\n },\n});\necma402_abstract_1.defineProperty(exports.DateTimeFormat.prototype, 'formatRangeToParts', {\n value: function formatRangeToParts(startDate, endDate) {\n var dtf = this;\n if (typeof dtf !== 'object') {\n throw new TypeError();\n }\n if (startDate === undefined || endDate === undefined) {\n throw new TypeError('startDate/endDate cannot be undefined');\n }\n var x = ecma402_abstract_1.ToNumber(startDate);\n var y = ecma402_abstract_1.ToNumber(endDate);\n return FormatDateTimeRangeToParts_1.FormatDateTimeRangeToParts(dtf, x, y, {\n getInternalSlots: get_internal_slots_1.default,\n localeData: exports.DateTimeFormat.localeData,\n tzData: exports.DateTimeFormat.tzData,\n getDefaultTimeZone: exports.DateTimeFormat.getDefaultTimeZone,\n });\n },\n});\necma402_abstract_1.defineProperty(exports.DateTimeFormat.prototype, 'formatRange', {\n value: function formatRange(startDate, endDate) {\n var dtf = this;\n if (typeof dtf !== 'object') {\n throw new TypeError();\n }\n if (startDate === undefined || endDate === undefined) {\n throw new TypeError('startDate/endDate cannot be undefined');\n }\n var x = ecma402_abstract_1.ToNumber(startDate);\n var y = ecma402_abstract_1.ToNumber(endDate);\n return FormatDateTimeRange_1.FormatDateTimeRange(dtf, x, y, {\n getInternalSlots: get_internal_slots_1.default,\n localeData: exports.DateTimeFormat.localeData,\n tzData: exports.DateTimeFormat.tzData,\n getDefaultTimeZone: exports.DateTimeFormat.getDefaultTimeZone,\n });\n },\n});\nvar DEFAULT_TIMEZONE = 'UTC';\nexports.DateTimeFormat.__setDefaultTimeZone = function (timeZone) {\n if (timeZone !== undefined) {\n timeZone = String(timeZone);\n if (!ecma402_abstract_1.IsValidTimeZoneName(timeZone, {\n tzData: exports.DateTimeFormat.tzData,\n uppercaseLinks: UPPERCASED_LINKS,\n })) {\n throw new RangeError('Invalid timeZoneName');\n }\n timeZone = ecma402_abstract_1.CanonicalizeTimeZoneName(timeZone, {\n tzData: exports.DateTimeFormat.tzData,\n uppercaseLinks: UPPERCASED_LINKS,\n });\n }\n else {\n timeZone = DEFAULT_TIMEZONE;\n }\n exports.DateTimeFormat.__defaultTimeZone = timeZone;\n};\nexports.DateTimeFormat.relevantExtensionKeys = ['nu', 'ca', 'hc'];\nexports.DateTimeFormat.__defaultTimeZone = DEFAULT_TIMEZONE;\nexports.DateTimeFormat.getDefaultTimeZone = function () { return exports.DateTimeFormat.__defaultTimeZone; };\nexports.DateTimeFormat.__addLocaleData = function __addLocaleData() {\n var data = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n data[_i] = arguments[_i];\n }\n var _loop_1 = function (d, locale) {\n var dateFormat = d.dateFormat, timeFormat = d.timeFormat, dateTimeFormat = d.dateTimeFormat, formats = d.formats, intervalFormats = d.intervalFormats, rawData = tslib_1.__rest(d, [\"dateFormat\", \"timeFormat\", \"dateTimeFormat\", \"formats\", \"intervalFormats\"]);\n var processedData = tslib_1.__assign(tslib_1.__assign({}, rawData), { dateFormat: {\n full: skeleton_1.parseDateTimeSkeleton(dateFormat.full),\n long: skeleton_1.parseDateTimeSkeleton(dateFormat.long),\n medium: skeleton_1.parseDateTimeSkeleton(dateFormat.medium),\n short: skeleton_1.parseDateTimeSkeleton(dateFormat.short),\n }, timeFormat: {\n full: skeleton_1.parseDateTimeSkeleton(timeFormat.full),\n long: skeleton_1.parseDateTimeSkeleton(timeFormat.long),\n medium: skeleton_1.parseDateTimeSkeleton(timeFormat.medium),\n short: skeleton_1.parseDateTimeSkeleton(timeFormat.short),\n }, dateTimeFormat: {\n full: skeleton_1.parseDateTimeSkeleton(dateTimeFormat.full).pattern,\n long: skeleton_1.parseDateTimeSkeleton(dateTimeFormat.long).pattern,\n medium: skeleton_1.parseDateTimeSkeleton(dateTimeFormat.medium).pattern,\n short: skeleton_1.parseDateTimeSkeleton(dateTimeFormat.short).pattern,\n }, formats: {} });\n var _loop_2 = function (calendar) {\n processedData.formats[calendar] = Object.keys(formats[calendar]).map(function (skeleton) {\n return skeleton_1.parseDateTimeSkeleton(skeleton, formats[calendar][skeleton], intervalFormats[skeleton], intervalFormats.intervalFormatFallback);\n });\n };\n for (var calendar in formats) {\n _loop_2(calendar);\n }\n var minimizedLocale = new Intl.Locale(locale)\n .minimize()\n .toString();\n exports.DateTimeFormat.localeData[locale] = exports.DateTimeFormat.localeData[minimizedLocale] = processedData;\n exports.DateTimeFormat.availableLocales.add(locale);\n exports.DateTimeFormat.availableLocales.add(minimizedLocale);\n if (!exports.DateTimeFormat.__defaultLocale) {\n exports.DateTimeFormat.__defaultLocale = minimizedLocale;\n }\n };\n for (var _a = 0, data_1 = data; _a < data_1.length; _a++) {\n var _b = data_1[_a], d = _b.data, locale = _b.locale;\n _loop_1(d, locale);\n }\n};\nObject.defineProperty(exports.DateTimeFormat.prototype, 'format', formatDescriptor);\nexports.DateTimeFormat.__defaultLocale = '';\nexports.DateTimeFormat.localeData = {};\nexports.DateTimeFormat.availableLocales = new Set();\nexports.DateTimeFormat.getDefaultLocale = function () {\n return exports.DateTimeFormat.__defaultLocale;\n};\nexports.DateTimeFormat.polyfilled = true;\nexports.DateTimeFormat.tzData = {};\nexports.DateTimeFormat.__addTZData = function (d) {\n exports.DateTimeFormat.tzData = packer_1.unpack(d);\n};\ntry {\n if (typeof Symbol !== 'undefined') {\n Object.defineProperty(exports.DateTimeFormat.prototype, Symbol.toStringTag, {\n value: 'Intl.DateTimeFormat',\n writable: false,\n enumerable: false,\n configurable: true,\n });\n }\n Object.defineProperty(exports.DateTimeFormat.prototype.constructor, 'length', {\n value: 1,\n writable: false,\n enumerable: false,\n configurable: true,\n });\n}\ncatch (e) {\n // Meta fix so we're test262-compliant, not important\n}\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.ResolveLocale = void 0;\nvar LookupMatcher_1 = require(\"./LookupMatcher\");\nvar BestFitMatcher_1 = require(\"./BestFitMatcher\");\nvar utils_1 = require(\"./utils\");\nvar UnicodeExtensionValue_1 = require(\"./UnicodeExtensionValue\");\n/**\n * https://tc39.es/ecma402/#sec-resolvelocale\n */\nfunction ResolveLocale(availableLocales, requestedLocales, options, relevantExtensionKeys, localeData, getDefaultLocale) {\n var matcher = options.localeMatcher;\n var r;\n if (matcher === 'lookup') {\n r = LookupMatcher_1.LookupMatcher(availableLocales, requestedLocales, getDefaultLocale);\n }\n else {\n r = BestFitMatcher_1.BestFitMatcher(availableLocales, requestedLocales, getDefaultLocale);\n }\n var foundLocale = r.locale;\n var result = { locale: '', dataLocale: foundLocale };\n var supportedExtension = '-u';\n for (var _i = 0, relevantExtensionKeys_1 = relevantExtensionKeys; _i < relevantExtensionKeys_1.length; _i++) {\n var key = relevantExtensionKeys_1[_i];\n utils_1.invariant(foundLocale in localeData, \"Missing locale data for \" + foundLocale);\n var foundLocaleData = localeData[foundLocale];\n utils_1.invariant(typeof foundLocaleData === 'object' && foundLocaleData !== null, \"locale data \" + key + \" must be an object\");\n var keyLocaleData = foundLocaleData[key];\n utils_1.invariant(Array.isArray(keyLocaleData), \"keyLocaleData for \" + key + \" must be an array\");\n var value = keyLocaleData[0];\n utils_1.invariant(typeof value === 'string' || value === null, \"value must be string or null but got \" + typeof value + \" in key \" + key);\n var supportedExtensionAddition = '';\n if (r.extension) {\n var requestedValue = UnicodeExtensionValue_1.UnicodeExtensionValue(r.extension, key);\n if (requestedValue !== undefined) {\n if (requestedValue !== '') {\n if (~keyLocaleData.indexOf(requestedValue)) {\n value = requestedValue;\n supportedExtensionAddition = \"-\" + key + \"-\" + value;\n }\n }\n else if (~requestedValue.indexOf('true')) {\n value = 'true';\n supportedExtensionAddition = \"-\" + key;\n }\n }\n }\n if (key in options) {\n var optionsValue = options[key];\n utils_1.invariant(typeof optionsValue === 'string' ||\n typeof optionsValue === 'undefined' ||\n optionsValue === null, 'optionsValue must be String, Undefined or Null');\n if (~keyLocaleData.indexOf(optionsValue)) {\n if (optionsValue !== value) {\n value = optionsValue;\n supportedExtensionAddition = '';\n }\n }\n }\n result[key] = value;\n supportedExtension += supportedExtensionAddition;\n }\n if (supportedExtension.length > 2) {\n var privateIndex = foundLocale.indexOf('-x-');\n if (privateIndex === -1) {\n foundLocale = foundLocale + supportedExtension;\n }\n else {\n var preExtension = foundLocale.slice(0, privateIndex);\n var postExtension = foundLocale.slice(privateIndex, foundLocale.length);\n foundLocale = preExtension + supportedExtension + postExtension;\n }\n foundLocale = Intl.getCanonicalLocales(foundLocale)[0];\n }\n result.locale = foundLocale;\n return result;\n}\nexports.ResolveLocale = ResolveLocale;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.PartitionDateTimePattern = void 0;\nvar ecma402_abstract_1 = require(\"@formatjs/ecma402-abstract\");\nvar FormatDateTimePattern_1 = require(\"./FormatDateTimePattern\");\n/**\n * https://tc39.es/ecma402/#sec-partitiondatetimepattern\n * @param dtf\n * @param x\n */\nfunction PartitionDateTimePattern(dtf, x, implDetails) {\n x = ecma402_abstract_1.TimeClip(x);\n if (isNaN(x)) {\n throw new RangeError('invalid time');\n }\n /** IMPL START */\n var getInternalSlots = implDetails.getInternalSlots;\n var internalSlots = getInternalSlots(dtf);\n /** IMPL END */\n var pattern = internalSlots.pattern;\n return FormatDateTimePattern_1.FormatDateTimePattern(dtf, ecma402_abstract_1.PartitionPattern(pattern), x, implDetails);\n}\nexports.PartitionDateTimePattern = PartitionDateTimePattern;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.FormatDateTimePattern = void 0;\nvar ecma402_abstract_1 = require(\"@formatjs/ecma402-abstract\");\nvar utils_1 = require(\"./utils\");\nvar ToLocalTime_1 = require(\"./ToLocalTime\");\nfunction pad(n) {\n if (n < 10) {\n return \"0\" + n;\n }\n return String(n);\n}\nfunction offsetToGmtString(gmtFormat, hourFormat, offsetInMs, style) {\n var offsetInMinutes = Math.floor(offsetInMs / 60000);\n var mins = Math.abs(offsetInMinutes) % 60;\n var hours = Math.floor(Math.abs(offsetInMinutes) / 60);\n var _a = hourFormat.split(';'), positivePattern = _a[0], negativePattern = _a[1];\n var offsetStr = '';\n var pattern = offsetInMs < 0 ? negativePattern : positivePattern;\n if (style === 'long') {\n offsetStr = pattern\n .replace('HH', pad(hours))\n .replace('H', String(hours))\n .replace('mm', pad(mins))\n .replace('m', String(mins));\n }\n else if (mins || hours) {\n if (!mins) {\n pattern = pattern.replace(/:?m+/, '');\n }\n offsetStr = pattern.replace(/H+/, String(hours)).replace(/m+/, String(mins));\n }\n return gmtFormat.replace('{0}', offsetStr);\n}\n/**\n * https://tc39.es/ecma402/#sec-partitiondatetimepattern\n * @param dtf\n * @param x\n */\nfunction FormatDateTimePattern(dtf, patternParts, x, _a) {\n var getInternalSlots = _a.getInternalSlots, localeData = _a.localeData, getDefaultTimeZone = _a.getDefaultTimeZone, tzData = _a.tzData;\n x = ecma402_abstract_1.TimeClip(x);\n /** IMPL START */\n var internalSlots = getInternalSlots(dtf);\n var dataLocale = internalSlots.dataLocale;\n var dataLocaleData = localeData[dataLocale];\n /** IMPL END */\n var locale = internalSlots.locale;\n var nfOptions = Object.create(null);\n nfOptions.useGrouping = false;\n var nf = new Intl.NumberFormat(locale, nfOptions);\n var nf2Options = Object.create(null);\n nf2Options.minimumIntegerDigits = 2;\n nf2Options.useGrouping = false;\n var nf2 = new Intl.NumberFormat(locale, nf2Options);\n var fractionalSecondDigits = internalSlots.fractionalSecondDigits;\n var nf3;\n if (fractionalSecondDigits !== undefined) {\n var nf3Options = Object.create(null);\n nf3Options.minimumIntegerDigits = fractionalSecondDigits;\n nf3Options.useGrouping = false;\n nf3 = new Intl.NumberFormat(locale, nf3Options);\n }\n var tm = ToLocalTime_1.ToLocalTime(x, \n // @ts-ignore\n internalSlots.calendar, internalSlots.timeZone, { tzData: tzData });\n var result = [];\n for (var _i = 0, patternParts_1 = patternParts; _i < patternParts_1.length; _i++) {\n var patternPart = patternParts_1[_i];\n var p = patternPart.type;\n if (p === 'literal') {\n result.push({\n type: 'literal',\n value: patternPart.value,\n });\n }\n else if (p === 'fractionalSecondDigits') {\n var v = Math.floor(tm.millisecond * Math.pow(10, ((fractionalSecondDigits || 0) - 3)));\n result.push({\n // @ts-expect-error Spec is not there yet\n type: 'fractionalSecond',\n value: nf3.format(v),\n });\n }\n else if (p === 'dayPeriod') {\n // TODO\n }\n else if (utils_1.DATE_TIME_PROPS.indexOf(p) > -1) {\n var fv = '';\n var f = internalSlots[p];\n // @ts-ignore\n var v = tm[p];\n if (p === 'year' && v <= 0) {\n v = 1 - v;\n }\n if (p === 'month') {\n v++;\n }\n var hourCycle = internalSlots.hourCycle;\n if (p === 'hour' && (hourCycle === 'h11' || hourCycle === 'h12')) {\n v = v % 12;\n if (v === 0 && hourCycle === 'h12') {\n v = 12;\n }\n }\n if (p === 'hour' && hourCycle === 'h24') {\n if (v === 0) {\n v = 24;\n }\n }\n if (f === 'numeric') {\n fv = nf.format(v);\n }\n else if (f === '2-digit') {\n fv = nf2.format(v);\n if (fv.length > 2) {\n fv = fv.slice(fv.length - 2, fv.length);\n }\n }\n else if (f === 'narrow' || f === 'short' || f === 'long') {\n if (p === 'era') {\n fv = dataLocaleData[p][f][v];\n }\n else if (p === 'timeZoneName') {\n var timeZoneName = dataLocaleData.timeZoneName, gmtFormat = dataLocaleData.gmtFormat, hourFormat = dataLocaleData.hourFormat;\n var timeZone = internalSlots.timeZone || getDefaultTimeZone();\n var timeZoneData = timeZoneName[timeZone];\n if (timeZoneData && timeZoneData[f]) {\n fv = timeZoneData[f][+tm.inDST];\n }\n else {\n // Fallback to gmtFormat\n fv = offsetToGmtString(gmtFormat, hourFormat, tm.timeZoneOffset, f);\n }\n }\n else if (p === 'month') {\n fv = dataLocaleData.month[f][v - 1];\n }\n else {\n fv = dataLocaleData[p][f][v];\n }\n }\n result.push({\n type: p,\n value: fv,\n });\n }\n else if (p === 'ampm') {\n var v = tm.hour;\n var fv = void 0;\n if (v > 11) {\n fv = dataLocaleData.pm;\n }\n else {\n fv = dataLocaleData.am;\n }\n result.push({\n type: 'dayPeriod',\n value: fv,\n });\n }\n else if (p === 'relatedYear') {\n var v = tm.relatedYear;\n // @ts-ignore\n var fv = nf.format(v);\n result.push({\n // @ts-ignore TODO: Fix TS type\n type: 'relatedYear',\n value: fv,\n });\n }\n else if (p === 'yearName') {\n var v = tm.yearName;\n // @ts-ignore\n var fv = nf.format(v);\n result.push({\n // @ts-ignore TODO: Fix TS type\n type: 'yearName',\n value: fv,\n });\n }\n }\n return result;\n}\nexports.FormatDateTimePattern = FormatDateTimePattern;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.ToLocalTime = void 0;\nvar ecma402_abstract_1 = require(\"@formatjs/ecma402-abstract\");\nfunction getApplicableZoneData(t, timeZone, tzData) {\n var _a;\n var zoneData = tzData[timeZone];\n // We don't have data for this so just say it's UTC\n if (!zoneData) {\n return [0, false];\n }\n var i = 0;\n var offset = 0;\n var dst = false;\n for (; i <= zoneData.length; i++) {\n if (i === zoneData.length || zoneData[i][0] * 1e3 > t) {\n ;\n _a = zoneData[i - 1], offset = _a[2], dst = _a[3];\n break;\n }\n }\n return [offset * 1e3, dst];\n}\n/**\n * https://tc39.es/ecma402/#sec-tolocaltime\n * @param t\n * @param calendar\n * @param timeZone\n */\nfunction ToLocalTime(t, calendar, timeZone, _a) {\n var tzData = _a.tzData;\n ecma402_abstract_1.invariant(ecma402_abstract_1.Type(t) === 'Number', 'invalid time');\n ecma402_abstract_1.invariant(calendar === 'gregory', 'We only support Gregory calendar right now');\n var _b = getApplicableZoneData(t, timeZone, tzData), timeZoneOffset = _b[0], inDST = _b[1];\n var tz = t + timeZoneOffset;\n var year = ecma402_abstract_1.YearFromTime(tz);\n return {\n weekday: ecma402_abstract_1.WeekDay(tz),\n era: year < 0 ? 'BC' : 'AD',\n year: year,\n relatedYear: undefined,\n yearName: undefined,\n month: ecma402_abstract_1.MonthFromTime(tz),\n day: ecma402_abstract_1.DateFromTime(tz),\n hour: ecma402_abstract_1.HourFromTime(tz),\n minute: ecma402_abstract_1.MinFromTime(tz),\n second: ecma402_abstract_1.SecFromTime(tz),\n millisecond: ecma402_abstract_1.msFromTime(tz),\n inDST: inDST,\n // IMPORTANT: Not in spec\n timeZoneOffset: timeZoneOffset,\n };\n}\nexports.ToLocalTime = ToLocalTime;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.splitRangePattern = exports.splitFallbackRangePattern = exports.parseDateTimeSkeleton = exports.processDateTimePattern = void 0;\nvar tslib_1 = require(\"tslib\");\nvar ecma402_abstract_1 = require(\"@formatjs/ecma402-abstract\");\n/**\n * https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table\n * Credit: https://github.com/caridy/intl-datetimeformat-pattern/blob/master/index.js\n * with some tweaks\n */\nvar DATE_TIME_REGEX = /(?:[Eec]{1,6}|G{1,5}|[Qq]{1,5}|(?:[yYur]+|U{1,5})|[ML]{1,5}|d{1,2}|D{1,3}|F{1}|[abB]{1,5}|[hkHK]{1,2}|w{1,2}|W{1}|m{1,2}|s{1,2}|[zZOvVxX]{1,4})(?=([^']*'[^']*')*[^']*$)/g;\n// trim patterns after transformations\nvar expPatternTrimmer = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;\nfunction matchSkeletonPattern(match, result) {\n var len = match.length;\n switch (match[0]) {\n // Era\n case 'G':\n result.era = len === 4 ? 'long' : len === 5 ? 'narrow' : 'short';\n return '{era}';\n // Year\n case 'y':\n case 'Y':\n case 'u':\n case 'U':\n case 'r':\n result.year = len === 2 ? '2-digit' : 'numeric';\n return '{year}';\n // Quarter\n case 'q':\n case 'Q':\n throw new RangeError('`w/Q` (quarter) patterns are not supported');\n // Month\n case 'M':\n case 'L':\n result.month = ['numeric', '2-digit', 'short', 'long', 'narrow'][len - 1];\n return '{month}';\n // Week\n case 'w':\n case 'W':\n throw new RangeError('`w/W` (week of year) patterns are not supported');\n case 'd':\n result.day = ['numeric', '2-digit'][len - 1];\n return '{day}';\n case 'D':\n case 'F':\n case 'g':\n result.day = 'numeric';\n return '{day}';\n // Weekday\n case 'E':\n result.weekday = len === 4 ? 'long' : len === 5 ? 'narrow' : 'short';\n return '{weekday}';\n case 'e':\n result.weekday = [\n undefined,\n undefined,\n 'short',\n 'long',\n 'narrow',\n 'short',\n ][len - 1];\n return '{weekday}';\n case 'c':\n result.weekday = [\n undefined,\n undefined,\n 'short',\n 'long',\n 'narrow',\n 'short',\n ][len - 1];\n return '{weekday}';\n // Period\n case 'a': // AM, PM\n case 'b': // am, pm, noon, midnight\n case 'B': // flexible day periods\n result.hour12 = true;\n return '{ampm}';\n // Hour\n case 'h':\n result.hour = ['numeric', '2-digit'][len - 1];\n result.hour12 = true;\n return '{hour}';\n case 'H':\n result.hour = ['numeric', '2-digit'][len - 1];\n return '{hour}';\n case 'K':\n result.hour = ['numeric', '2-digit'][len - 1];\n result.hour12 = true;\n return '{hour}';\n case 'k':\n result.hour = ['numeric', '2-digit'][len - 1];\n return '{hour}';\n case 'j':\n case 'J':\n case 'C':\n throw new RangeError('`j/J/C` (hour) patterns are not supported, use `h/H/K/k` instead');\n // Minute\n case 'm':\n result.minute = ['numeric', '2-digit'][len - 1];\n return '{minute}';\n // Second\n case 's':\n result.second = ['numeric', '2-digit'][len - 1];\n return '{second}';\n case 'S':\n case 'A':\n result.second = 'numeric';\n return '{second}';\n // Zone\n case 'z': // 1..3, 4: specific non-location format\n case 'Z': // 1..3, 4, 5: The ISO8601 varios formats\n case 'O': // 1, 4: miliseconds in day short, long\n case 'v': // 1, 4: generic non-location format\n case 'V': // 1, 2, 3, 4: time zone ID or city\n case 'X': // 1, 2, 3, 4: The ISO8601 varios formats\n case 'x': // 1, 2, 3, 4: The ISO8601 varios formats\n result.timeZoneName = len < 4 ? 'short' : 'long';\n return '{timeZoneName}';\n }\n return '';\n}\nfunction skeletonTokenToTable2(c) {\n switch (c) {\n // Era\n case 'G':\n return 'era';\n // Year\n case 'y':\n case 'Y':\n case 'u':\n case 'U':\n case 'r':\n return 'year';\n // Month\n case 'M':\n case 'L':\n return 'month';\n // Day\n case 'd':\n case 'D':\n case 'F':\n case 'g':\n return 'day';\n // Period\n case 'a': // AM, PM\n case 'b': // am, pm, noon, midnight\n case 'B': // flexible day periods\n return 'ampm';\n // Hour\n case 'h':\n case 'H':\n case 'K':\n case 'k':\n return 'hour';\n // Minute\n case 'm':\n return 'minute';\n // Second\n case 's':\n case 'S':\n case 'A':\n return 'second';\n default:\n throw new RangeError('Invalid range pattern token');\n }\n}\nfunction processDateTimePattern(pattern, result) {\n var literals = [];\n // Use skeleton to populate result, but use mapped pattern to populate pattern\n var pattern12 = pattern\n // Double apostrophe\n .replace(/'{2}/g, '{apostrophe}')\n // Apostrophe-escaped\n .replace(/'(.*?)'/g, function (_, literal) {\n literals.push(literal);\n return \"$$\" + (literals.length - 1) + \"$$\";\n })\n .replace(DATE_TIME_REGEX, function (m) { return matchSkeletonPattern(m, result || {}); });\n //Restore literals\n if (literals.length) {\n pattern12 = pattern12\n .replace(/\\$\\$(\\d+)\\$\\$/g, function (_, i) {\n return literals[+i];\n })\n .replace(/\\{apostrophe\\}/g, \"'\");\n }\n // Handle apostrophe-escaped things\n return [\n pattern12\n .replace(/([\\s\\uFEFF\\xA0])\\{ampm\\}([\\s\\uFEFF\\xA0])/, '$1')\n .replace('{ampm}', '')\n .replace(expPatternTrimmer, ''),\n pattern12,\n ];\n}\nexports.processDateTimePattern = processDateTimePattern;\n/**\n * Parse Date time skeleton into Intl.DateTimeFormatOptions\n * Ref: https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table\n * @public\n * @param skeleton skeleton string\n */\nfunction parseDateTimeSkeleton(skeleton, rawPattern, rangePatterns, intervalFormatFallback) {\n if (rawPattern === void 0) { rawPattern = skeleton; }\n var result = {\n pattern: '',\n pattern12: '',\n skeleton: skeleton,\n rawPattern: rawPattern,\n rangePatterns: {},\n rangePatterns12: {},\n };\n if (rangePatterns) {\n for (var k in rangePatterns) {\n var key = skeletonTokenToTable2(k);\n var rawPattern_1 = rangePatterns[k];\n var intervalResult = {\n patternParts: [],\n };\n var _a = processDateTimePattern(rawPattern_1, intervalResult), pattern_1 = _a[0], pattern12_1 = _a[1];\n result.rangePatterns[key] = tslib_1.__assign(tslib_1.__assign({}, intervalResult), { patternParts: splitRangePattern(pattern_1) });\n result.rangePatterns12[key] = tslib_1.__assign(tslib_1.__assign({}, intervalResult), { patternParts: splitRangePattern(pattern12_1) });\n }\n }\n if (intervalFormatFallback) {\n var patternParts = splitFallbackRangePattern(intervalFormatFallback);\n result.rangePatterns.default = {\n patternParts: patternParts,\n };\n result.rangePatterns12.default = {\n patternParts: patternParts,\n };\n }\n // Process skeleton\n skeleton.replace(DATE_TIME_REGEX, function (m) { return matchSkeletonPattern(m, result); });\n var _b = processDateTimePattern(rawPattern), pattern = _b[0], pattern12 = _b[1];\n result.pattern = pattern;\n result.pattern12 = pattern12;\n return result;\n}\nexports.parseDateTimeSkeleton = parseDateTimeSkeleton;\nfunction splitFallbackRangePattern(pattern) {\n var parts = pattern.split(/(\\{[0|1]\\})/g).filter(Boolean);\n return parts.map(function (pattern) {\n switch (pattern) {\n case '{0}':\n return {\n source: ecma402_abstract_1.RangePatternType.startRange,\n pattern: pattern,\n };\n case '{1}':\n return {\n source: ecma402_abstract_1.RangePatternType.endRange,\n pattern: pattern,\n };\n default:\n return {\n source: ecma402_abstract_1.RangePatternType.shared,\n pattern: pattern,\n };\n }\n });\n}\nexports.splitFallbackRangePattern = splitFallbackRangePattern;\nfunction splitRangePattern(pattern) {\n var PART_REGEX = /\\{(.*?)\\}/g;\n // Map of part and index within the string\n var parts = {};\n var match;\n var splitIndex = 0;\n while ((match = PART_REGEX.exec(pattern))) {\n if (!(match[0] in parts)) {\n parts[match[0]] = match.index;\n }\n else {\n splitIndex = match.index;\n break;\n }\n }\n if (!splitIndex) {\n return [\n {\n source: ecma402_abstract_1.RangePatternType.startRange,\n pattern: pattern,\n },\n ];\n }\n return [\n {\n source: ecma402_abstract_1.RangePatternType.startRange,\n pattern: pattern.slice(0, splitIndex),\n },\n {\n source: ecma402_abstract_1.RangePatternType.endRange,\n pattern: pattern.slice(splitIndex),\n },\n ];\n}\nexports.splitRangePattern = splitRangePattern;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.ToDateTimeOptions = void 0;\nvar ecma402_abstract_1 = require(\"@formatjs/ecma402-abstract\");\n/**\n * https://tc39.es/ecma402/#sec-todatetimeoptions\n * @param options\n * @param required\n * @param defaults\n */\nfunction ToDateTimeOptions(options, required, defaults) {\n if (options === undefined) {\n options = null;\n }\n else {\n options = ecma402_abstract_1.ToObject(options);\n }\n options = Object.create(options);\n var needDefaults = true;\n if (required === 'date' || required === 'any') {\n for (var _i = 0, _a = ['weekday', 'year', 'month', 'day']; _i < _a.length; _i++) {\n var prop = _a[_i];\n var value = options[prop];\n if (value !== undefined) {\n needDefaults = false;\n }\n }\n }\n if (required === 'time' || required === 'any') {\n for (var _b = 0, _c = [\n 'dayPeriod',\n 'hour',\n 'minute',\n 'second',\n 'fractionalSecondDigits',\n ]; _b < _c.length; _b++) {\n var prop = _c[_b];\n var value = options[prop];\n if (value !== undefined) {\n needDefaults = false;\n }\n }\n }\n if (options.dateStyle !== undefined || options.timeStyle !== undefined) {\n needDefaults = false;\n }\n if (required === 'date' && options.timeStyle) {\n throw new TypeError('Intl.DateTimeFormat date was required but timeStyle was included');\n }\n if (required === 'time' && options.dateStyle) {\n throw new TypeError('Intl.DateTimeFormat time was required but dateStyle was included');\n }\n if (needDefaults && (defaults === 'date' || defaults === 'all')) {\n for (var _d = 0, _e = ['year', 'month', 'day']; _d < _e.length; _d++) {\n var prop = _e[_d];\n options[prop] = 'numeric';\n }\n }\n if (needDefaults && (defaults === 'time' || defaults === 'all')) {\n for (var _f = 0, _g = ['hour', 'minute', 'second']; _f < _g.length; _f++) {\n var prop = _g[_f];\n options[prop] = 'numeric';\n }\n }\n return options;\n}\nexports.ToDateTimeOptions = ToDateTimeOptions;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.PartitionDateTimeRangePattern = void 0;\nvar ecma402_abstract_1 = require(\"@formatjs/ecma402-abstract\");\nvar ToLocalTime_1 = require(\"./ToLocalTime\");\nvar FormatDateTimePattern_1 = require(\"./FormatDateTimePattern\");\nvar TABLE_2_FIELDS = [\n 'era',\n 'year',\n 'month',\n 'day',\n 'dayPeriod',\n 'ampm',\n 'hour',\n 'minute',\n 'second',\n 'fractionalSecondDigits',\n];\nfunction PartitionDateTimeRangePattern(dtf, x, y, implDetails) {\n x = ecma402_abstract_1.TimeClip(x);\n if (isNaN(x)) {\n throw new RangeError('Invalid start time');\n }\n y = ecma402_abstract_1.TimeClip(y);\n if (isNaN(y)) {\n throw new RangeError('Invalid end time');\n }\n /** IMPL START */\n var getInternalSlots = implDetails.getInternalSlots, tzData = implDetails.tzData;\n var internalSlots = getInternalSlots(dtf);\n /** IMPL END */\n var tm1 = ToLocalTime_1.ToLocalTime(x, \n // @ts-ignore\n internalSlots.calendar, internalSlots.timeZone, { tzData: tzData });\n var tm2 = ToLocalTime_1.ToLocalTime(y, \n // @ts-ignore\n internalSlots.calendar, internalSlots.timeZone, { tzData: tzData });\n var pattern = internalSlots.pattern, rangePatterns = internalSlots.rangePatterns;\n var rangePattern;\n var dateFieldsPracticallyEqual = true;\n var patternContainsLargerDateField = false;\n for (var _i = 0, TABLE_2_FIELDS_1 = TABLE_2_FIELDS; _i < TABLE_2_FIELDS_1.length; _i++) {\n var fieldName = TABLE_2_FIELDS_1[_i];\n if (dateFieldsPracticallyEqual && !patternContainsLargerDateField) {\n var rp = fieldName in rangePatterns ? rangePatterns[fieldName] : undefined;\n if (rangePattern !== undefined && rp === undefined) {\n patternContainsLargerDateField = true;\n }\n else {\n rangePattern = rp;\n if (fieldName === 'ampm') {\n var v1 = tm1.hour;\n var v2 = tm2.hour;\n if ((v1 > 11 && v2 < 11) || (v1 < 11 && v2 > 11)) {\n dateFieldsPracticallyEqual = false;\n }\n }\n else if (fieldName === 'dayPeriod') {\n // TODO\n }\n else if (fieldName === 'fractionalSecondDigits') {\n var fractionalSecondDigits = internalSlots.fractionalSecondDigits;\n if (fractionalSecondDigits === undefined) {\n fractionalSecondDigits = 3;\n }\n var v1 = Math.floor(tm1.millisecond * Math.pow(10, (fractionalSecondDigits - 3)));\n var v2 = Math.floor(tm2.millisecond * Math.pow(10, (fractionalSecondDigits - 3)));\n if (!ecma402_abstract_1.SameValue(v1, v2)) {\n dateFieldsPracticallyEqual = false;\n }\n }\n else {\n var v1 = tm1[fieldName];\n var v2 = tm2[fieldName];\n if (!ecma402_abstract_1.SameValue(v1, v2)) {\n dateFieldsPracticallyEqual = false;\n }\n }\n }\n }\n }\n if (dateFieldsPracticallyEqual) {\n var result_2 = FormatDateTimePattern_1.FormatDateTimePattern(dtf, ecma402_abstract_1.PartitionPattern(pattern), x, implDetails);\n for (var _a = 0, result_1 = result_2; _a < result_1.length; _a++) {\n var r = result_1[_a];\n r.source = ecma402_abstract_1.RangePatternType.shared;\n }\n return result_2;\n }\n var result = [];\n if (rangePattern === undefined) {\n rangePattern = rangePatterns.default;\n /** IMPL DETAILS */\n // Now we have to replace {0} & {1} with actual pattern\n for (var _b = 0, _c = rangePattern.patternParts; _b < _c.length; _b++) {\n var patternPart = _c[_b];\n if (patternPart.pattern === '{0}' || patternPart.pattern === '{1}') {\n patternPart.pattern = pattern;\n }\n }\n }\n for (var _d = 0, _e = rangePattern.patternParts; _d < _e.length; _d++) {\n var rangePatternPart = _e[_d];\n var source = rangePatternPart.source, pattern_1 = rangePatternPart.pattern;\n var z = void 0;\n if (source === ecma402_abstract_1.RangePatternType.startRange ||\n source === ecma402_abstract_1.RangePatternType.shared) {\n z = x;\n }\n else {\n z = y;\n }\n var patternParts = ecma402_abstract_1.PartitionPattern(pattern_1);\n var partResult = FormatDateTimePattern_1.FormatDateTimePattern(dtf, patternParts, z, implDetails);\n for (var _f = 0, partResult_1 = partResult; _f < partResult_1.length; _f++) {\n var r = partResult_1[_f];\n r.source = source;\n }\n result = result.concat(partResult);\n }\n return result;\n}\nexports.PartitionDateTimeRangePattern = PartitionDateTimeRangePattern;\n","/**\n * @license\n * Copyright 2011 Dan Vanderkam (danvdk@gmail.com)\n * MIT-licensed (http://opensource.org/licenses/MIT)\n */\n\n/**\n * @fileoverview Based on PlotKitLayout, but modified to meet the needs of\n * dygraphs.\n */\n\n/*global Dygraph:false */\n\"use strict\";\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }\n\nvar _dygraphUtils = require('./dygraph-utils');\n\nvar utils = _interopRequireWildcard(_dygraphUtils);\n\n/**\n * Creates a new DygraphLayout object.\n *\n * This class contains all the data to be charted.\n * It uses data coordinates, but also records the chart range (in data\n * coordinates) and hence is able to calculate percentage positions ('In this\n * view, Point A lies 25% down the x-axis.')\n *\n * Two things that it does not do are:\n * 1. Record pixel coordinates for anything.\n * 2. (oddly) determine anything about the layout of chart elements.\n *\n * The naming is a vestige of Dygraph's original PlotKit roots.\n *\n * @constructor\n */\nvar DygraphLayout = function DygraphLayout(dygraph) {\n this.dygraph_ = dygraph;\n /**\n * Array of points for each series.\n *\n * [series index][row index in series] = |Point| structure,\n * where series index refers to visible series only, and the\n * point index is for the reduced set of points for the current\n * zoom region (including one point just outside the window).\n * All points in the same row index share the same X value.\n *\n * @type {Array.>}\n */\n this.points = [];\n this.setNames = [];\n this.annotations = [];\n this.yAxes_ = null;\n\n // TODO(danvk): it's odd that xTicks_ and yTicks_ are inputs, but xticks and\n // yticks are outputs. Clean this up.\n this.xTicks_ = null;\n this.yTicks_ = null;\n};\n\n/**\n * Add points for a single series.\n *\n * @param {string} setname Name of the series.\n * @param {Array.} set_xy Points for the series.\n */\nDygraphLayout.prototype.addDataset = function (setname, set_xy) {\n this.points.push(set_xy);\n this.setNames.push(setname);\n};\n\n/**\n * Returns the box which the chart should be drawn in. This is the canvas's\n * box, less space needed for the axis and chart labels.\n *\n * @return {{x: number, y: number, w: number, h: number}}\n */\nDygraphLayout.prototype.getPlotArea = function () {\n return this.area_;\n};\n\n// Compute the box which the chart should be drawn in. This is the canvas's\n// box, less space needed for axis, chart labels, and other plug-ins.\n// NOTE: This should only be called by Dygraph.predraw_().\nDygraphLayout.prototype.computePlotArea = function () {\n var area = {\n // TODO(danvk): per-axis setting.\n x: 0,\n y: 0\n };\n\n area.w = this.dygraph_.width_ - area.x - this.dygraph_.getOption('rightGap');\n area.h = this.dygraph_.height_;\n\n // Let plugins reserve space.\n var e = {\n chart_div: this.dygraph_.graphDiv,\n reserveSpaceLeft: function reserveSpaceLeft(px) {\n var r = {\n x: area.x,\n y: area.y,\n w: px,\n h: area.h\n };\n area.x += px;\n area.w -= px;\n return r;\n },\n reserveSpaceRight: function reserveSpaceRight(px) {\n var r = {\n x: area.x + area.w - px,\n y: area.y,\n w: px,\n h: area.h\n };\n area.w -= px;\n return r;\n },\n reserveSpaceTop: function reserveSpaceTop(px) {\n var r = {\n x: area.x,\n y: area.y,\n w: area.w,\n h: px\n };\n area.y += px;\n area.h -= px;\n return r;\n },\n reserveSpaceBottom: function reserveSpaceBottom(px) {\n var r = {\n x: area.x,\n y: area.y + area.h - px,\n w: area.w,\n h: px\n };\n area.h -= px;\n return r;\n },\n chartRect: function chartRect() {\n return { x: area.x, y: area.y, w: area.w, h: area.h };\n }\n };\n this.dygraph_.cascadeEvents_('layout', e);\n\n this.area_ = area;\n};\n\nDygraphLayout.prototype.setAnnotations = function (ann) {\n // The Dygraph object's annotations aren't parsed. We parse them here and\n // save a copy. If there is no parser, then the user must be using raw format.\n this.annotations = [];\n var parse = this.dygraph_.getOption('xValueParser') || function (x) {\n return x;\n };\n for (var i = 0; i < ann.length; i++) {\n var a = {};\n if (!ann[i].xval && ann[i].x === undefined) {\n console.error(\"Annotations must have an 'x' property\");\n return;\n }\n if (ann[i].icon && !(ann[i].hasOwnProperty('width') && ann[i].hasOwnProperty('height'))) {\n console.error(\"Must set width and height when setting \" + \"annotation.icon property\");\n return;\n }\n utils.update(a, ann[i]);\n if (!a.xval) a.xval = parse(a.x);\n this.annotations.push(a);\n }\n};\n\nDygraphLayout.prototype.setXTicks = function (xTicks) {\n this.xTicks_ = xTicks;\n};\n\n// TODO(danvk): add this to the Dygraph object's API or move it into Layout.\nDygraphLayout.prototype.setYAxes = function (yAxes) {\n this.yAxes_ = yAxes;\n};\n\nDygraphLayout.prototype.evaluate = function () {\n this._xAxis = {};\n this._evaluateLimits();\n this._evaluateLineCharts();\n this._evaluateLineTicks();\n this._evaluateAnnotations();\n};\n\nDygraphLayout.prototype._evaluateLimits = function () {\n var xlimits = this.dygraph_.xAxisRange();\n this._xAxis.minval = xlimits[0];\n this._xAxis.maxval = xlimits[1];\n var xrange = xlimits[1] - xlimits[0];\n this._xAxis.scale = xrange !== 0 ? 1 / xrange : 1.0;\n\n if (this.dygraph_.getOptionForAxis(\"logscale\", 'x')) {\n this._xAxis.xlogrange = utils.log10(this._xAxis.maxval) - utils.log10(this._xAxis.minval);\n this._xAxis.xlogscale = this._xAxis.xlogrange !== 0 ? 1.0 / this._xAxis.xlogrange : 1.0;\n }\n for (var i = 0; i < this.yAxes_.length; i++) {\n var axis = this.yAxes_[i];\n axis.minyval = axis.computedValueRange[0];\n axis.maxyval = axis.computedValueRange[1];\n axis.yrange = axis.maxyval - axis.minyval;\n axis.yscale = axis.yrange !== 0 ? 1.0 / axis.yrange : 1.0;\n\n if (this.dygraph_.getOption(\"logscale\")) {\n axis.ylogrange = utils.log10(axis.maxyval) - utils.log10(axis.minyval);\n axis.ylogscale = axis.ylogrange !== 0 ? 1.0 / axis.ylogrange : 1.0;\n if (!isFinite(axis.ylogrange) || isNaN(axis.ylogrange)) {\n console.error('axis ' + i + ' of graph at ' + axis.g + ' can\\'t be displayed in log scale for range [' + axis.minyval + ' - ' + axis.maxyval + ']');\n }\n }\n }\n};\n\nDygraphLayout.calcXNormal_ = function (value, xAxis, logscale) {\n if (logscale) {\n return (utils.log10(value) - utils.log10(xAxis.minval)) * xAxis.xlogscale;\n } else {\n return (value - xAxis.minval) * xAxis.scale;\n }\n};\n\n/**\n * @param {DygraphAxisType} axis\n * @param {number} value\n * @param {boolean} logscale\n * @return {number}\n */\nDygraphLayout.calcYNormal_ = function (axis, value, logscale) {\n if (logscale) {\n var x = 1.0 - (utils.log10(value) - utils.log10(axis.minyval)) * axis.ylogscale;\n return isFinite(x) ? x : NaN; // shim for v8 issue; see pull request 276\n } else {\n return 1.0 - (value - axis.minyval) * axis.yscale;\n }\n};\n\nDygraphLayout.prototype._evaluateLineCharts = function () {\n var isStacked = this.dygraph_.getOption(\"stackedGraph\");\n var isLogscaleForX = this.dygraph_.getOptionForAxis(\"logscale\", 'x');\n\n for (var setIdx = 0; setIdx < this.points.length; setIdx++) {\n var points = this.points[setIdx];\n var setName = this.setNames[setIdx];\n var connectSeparated = this.dygraph_.getOption('connectSeparatedPoints', setName);\n var axis = this.dygraph_.axisPropertiesForSeries(setName);\n // TODO (konigsberg): use optionsForAxis instead.\n var logscale = this.dygraph_.attributes_.getForSeries(\"logscale\", setName);\n\n for (var j = 0; j < points.length; j++) {\n var point = points[j];\n\n // Range from 0-1 where 0 represents left and 1 represents right.\n point.x = DygraphLayout.calcXNormal_(point.xval, this._xAxis, isLogscaleForX);\n // Range from 0-1 where 0 represents top and 1 represents bottom\n var yval = point.yval;\n if (isStacked) {\n point.y_stacked = DygraphLayout.calcYNormal_(axis, point.yval_stacked, logscale);\n if (yval !== null && !isNaN(yval)) {\n yval = point.yval_stacked;\n }\n }\n if (yval === null) {\n yval = NaN;\n if (!connectSeparated) {\n point.yval = NaN;\n }\n }\n point.y = DygraphLayout.calcYNormal_(axis, yval, logscale);\n }\n\n this.dygraph_.dataHandler_.onLineEvaluated(points, axis, logscale);\n }\n};\n\nDygraphLayout.prototype._evaluateLineTicks = function () {\n var i, tick, label, pos, v, has_tick;\n this.xticks = [];\n for (i = 0; i < this.xTicks_.length; i++) {\n tick = this.xTicks_[i];\n label = tick.label;\n has_tick = !('label_v' in tick);\n v = has_tick ? tick.v : tick.label_v;\n pos = this.dygraph_.toPercentXCoord(v);\n if (pos >= 0.0 && pos < 1.0) {\n this.xticks.push({ pos: pos, label: label, has_tick: has_tick });\n }\n }\n\n this.yticks = [];\n for (i = 0; i < this.yAxes_.length; i++) {\n var axis = this.yAxes_[i];\n for (var j = 0; j < axis.ticks.length; j++) {\n tick = axis.ticks[j];\n label = tick.label;\n has_tick = !('label_v' in tick);\n v = has_tick ? tick.v : tick.label_v;\n pos = this.dygraph_.toPercentYCoord(v, i);\n if (pos > 0.0 && pos <= 1.0) {\n this.yticks.push({ axis: i, pos: pos, label: label, has_tick: has_tick });\n }\n }\n }\n};\n\nDygraphLayout.prototype._evaluateAnnotations = function () {\n // Add the annotations to the point to which they belong.\n // Make a map from (setName, xval) to annotation for quick lookups.\n var i;\n var annotations = {};\n for (i = 0; i < this.annotations.length; i++) {\n var a = this.annotations[i];\n annotations[a.xval + \",\" + a.series] = a;\n }\n\n this.annotated_points = [];\n\n // Exit the function early if there are no annotations.\n if (!this.annotations || !this.annotations.length) {\n return;\n }\n\n // TODO(antrob): loop through annotations not points.\n for (var setIdx = 0; setIdx < this.points.length; setIdx++) {\n var points = this.points[setIdx];\n for (i = 0; i < points.length; i++) {\n var p = points[i];\n var k = p.xval + \",\" + p.name;\n if (k in annotations) {\n p.annotation = annotations[k];\n this.annotated_points.push(p);\n }\n }\n }\n};\n\n/**\n * Convenience function to remove all the data sets from a graph\n */\nDygraphLayout.prototype.removeAllDatasets = function () {\n delete this.points;\n delete this.setNames;\n delete this.setPointsLengths;\n delete this.setPointsOffsets;\n this.points = [];\n this.setNames = [];\n this.setPointsLengths = [];\n this.setPointsOffsets = [];\n};\n\nexports['default'] = DygraphLayout;\nmodule.exports = exports['default'];","/**\n * @license\n * Copyright 2006 Dan Vanderkam (danvdk@gmail.com)\n * MIT-licensed (http://opensource.org/licenses/MIT)\n */\n\n/**\n * @fileoverview Based on PlotKit.CanvasRenderer, but modified to meet the\n * needs of dygraphs.\n *\n * In particular, support for:\n * - grid overlays\n * - error bars\n * - dygraphs attribute system\n */\n\n/**\n * The DygraphCanvasRenderer class does the actual rendering of the chart onto\n * a canvas. It's based on PlotKit.CanvasRenderer.\n * @param {Object} element The canvas to attach to\n * @param {Object} elementContext The 2d context of the canvas (injected so it\n * can be mocked for testing.)\n * @param {Layout} layout The DygraphLayout object for this graph.\n * @constructor\n */\n\n/*global Dygraph:false */\n\"use strict\";\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }\n\nvar _dygraphUtils = require('./dygraph-utils');\n\nvar utils = _interopRequireWildcard(_dygraphUtils);\n\nvar _dygraph = require('./dygraph');\n\nvar _dygraph2 = _interopRequireDefault(_dygraph);\n\n/**\n * @constructor\n *\n * This gets called when there are \"new points\" to chart. This is generally the\n * case when the underlying data being charted has changed. It is _not_ called\n * in the common case that the user has zoomed or is panning the view.\n *\n * The chart canvas has already been created by the Dygraph object. The\n * renderer simply gets a drawing context.\n *\n * @param {Dygraph} dygraph The chart to which this renderer belongs.\n * @param {HTMLCanvasElement} element The <canvas> DOM element on which to draw.\n * @param {CanvasRenderingContext2D} elementContext The drawing context.\n * @param {DygraphLayout} layout The chart's DygraphLayout object.\n *\n * TODO(danvk): remove the elementContext property.\n */\nvar DygraphCanvasRenderer = function DygraphCanvasRenderer(dygraph, element, elementContext, layout) {\n this.dygraph_ = dygraph;\n\n this.layout = layout;\n this.element = element;\n this.elementContext = elementContext;\n\n this.height = dygraph.height_;\n this.width = dygraph.width_;\n\n // --- check whether everything is ok before we return\n if (!utils.isCanvasSupported(this.element)) {\n throw \"Canvas is not supported.\";\n }\n\n // internal state\n this.area = layout.getPlotArea();\n\n // Set up a clipping area for the canvas (and the interaction canvas).\n // This ensures that we don't overdraw.\n var ctx = this.dygraph_.canvas_ctx_;\n ctx.beginPath();\n ctx.rect(this.area.x, this.area.y, this.area.w, this.area.h);\n ctx.clip();\n\n ctx = this.dygraph_.hidden_ctx_;\n ctx.beginPath();\n ctx.rect(this.area.x, this.area.y, this.area.w, this.area.h);\n ctx.clip();\n};\n\n/**\n * Clears out all chart content and DOM elements.\n * This is called immediately before render() on every frame, including\n * during zooms and pans.\n * @private\n */\nDygraphCanvasRenderer.prototype.clear = function () {\n this.elementContext.clearRect(0, 0, this.width, this.height);\n};\n\n/**\n * This method is responsible for drawing everything on the chart, including\n * lines, error bars, fills and axes.\n * It is called immediately after clear() on every frame, including during pans\n * and zooms.\n * @private\n */\nDygraphCanvasRenderer.prototype.render = function () {\n // attaches point.canvas{x,y}\n this._updatePoints();\n\n // actually draws the chart.\n this._renderLineChart();\n};\n\n/**\n * Returns a predicate to be used with an iterator, which will\n * iterate over points appropriately, depending on whether\n * connectSeparatedPoints is true. When it's false, the predicate will\n * skip over points with missing yVals.\n */\nDygraphCanvasRenderer._getIteratorPredicate = function (connectSeparatedPoints) {\n return connectSeparatedPoints ? DygraphCanvasRenderer._predicateThatSkipsEmptyPoints : null;\n};\n\nDygraphCanvasRenderer._predicateThatSkipsEmptyPoints = function (array, idx) {\n return array[idx].yval !== null;\n};\n\n/**\n * Draws a line with the styles passed in and calls all the drawPointCallbacks.\n * @param {Object} e The dictionary passed to the plotter function.\n * @private\n */\nDygraphCanvasRenderer._drawStyledLine = function (e, color, strokeWidth, strokePattern, drawPoints, drawPointCallback, pointSize) {\n var g = e.dygraph;\n // TODO(konigsberg): Compute attributes outside this method call.\n var stepPlot = g.getBooleanOption(\"stepPlot\", e.setName);\n\n if (!utils.isArrayLike(strokePattern)) {\n strokePattern = null;\n }\n\n var drawGapPoints = g.getBooleanOption('drawGapEdgePoints', e.setName);\n\n var points = e.points;\n var setName = e.setName;\n var iter = utils.createIterator(points, 0, points.length, DygraphCanvasRenderer._getIteratorPredicate(g.getBooleanOption(\"connectSeparatedPoints\", setName)));\n\n var stroking = strokePattern && strokePattern.length >= 2;\n\n var ctx = e.drawingContext;\n ctx.save();\n if (stroking) {\n if (ctx.setLineDash) ctx.setLineDash(strokePattern);\n }\n\n var pointsOnLine = DygraphCanvasRenderer._drawSeries(e, iter, strokeWidth, pointSize, drawPoints, drawGapPoints, stepPlot, color);\n DygraphCanvasRenderer._drawPointsOnLine(e, pointsOnLine, drawPointCallback, color, pointSize);\n\n if (stroking) {\n if (ctx.setLineDash) ctx.setLineDash([]);\n }\n\n ctx.restore();\n};\n\n/**\n * This does the actual drawing of lines on the canvas, for just one series.\n * Returns a list of [canvasx, canvasy] pairs for points for which a\n * drawPointCallback should be fired. These include isolated points, or all\n * points if drawPoints=true.\n * @param {Object} e The dictionary passed to the plotter function.\n * @private\n */\nDygraphCanvasRenderer._drawSeries = function (e, iter, strokeWidth, pointSize, drawPoints, drawGapPoints, stepPlot, color) {\n\n var prevCanvasX = null;\n var prevCanvasY = null;\n var nextCanvasY = null;\n var isIsolated; // true if this point is isolated (no line segments)\n var point; // the point being processed in the while loop\n var pointsOnLine = []; // Array of [canvasx, canvasy] pairs.\n var first = true; // the first cycle through the while loop\n\n var ctx = e.drawingContext;\n ctx.beginPath();\n ctx.strokeStyle = color;\n ctx.lineWidth = strokeWidth;\n\n // NOTE: we break the iterator's encapsulation here for about a 25% speedup.\n var arr = iter.array_;\n var limit = iter.end_;\n var predicate = iter.predicate_;\n\n for (var i = iter.start_; i < limit; i++) {\n point = arr[i];\n if (predicate) {\n while (i < limit && !predicate(arr, i)) {\n i++;\n }\n if (i == limit) break;\n point = arr[i];\n }\n\n // FIXME: The 'canvasy != canvasy' test here catches NaN values but the test\n // doesn't catch Infinity values. Could change this to\n // !isFinite(point.canvasy), but I assume it avoids isNaN for performance?\n if (point.canvasy === null || point.canvasy != point.canvasy) {\n if (stepPlot && prevCanvasX !== null) {\n // Draw a horizontal line to the start of the missing data\n ctx.moveTo(prevCanvasX, prevCanvasY);\n ctx.lineTo(point.canvasx, prevCanvasY);\n }\n prevCanvasX = prevCanvasY = null;\n } else {\n isIsolated = false;\n if (drawGapPoints || prevCanvasX === null) {\n iter.nextIdx_ = i;\n iter.next();\n nextCanvasY = iter.hasNext ? iter.peek.canvasy : null;\n\n var isNextCanvasYNullOrNaN = nextCanvasY === null || nextCanvasY != nextCanvasY;\n isIsolated = prevCanvasX === null && isNextCanvasYNullOrNaN;\n if (drawGapPoints) {\n // Also consider a point to be \"isolated\" if it's adjacent to a\n // null point, excluding the graph edges.\n if (!first && prevCanvasX === null || iter.hasNext && isNextCanvasYNullOrNaN) {\n isIsolated = true;\n }\n }\n }\n\n if (prevCanvasX !== null) {\n if (strokeWidth) {\n if (stepPlot) {\n ctx.moveTo(prevCanvasX, prevCanvasY);\n ctx.lineTo(point.canvasx, prevCanvasY);\n }\n\n ctx.lineTo(point.canvasx, point.canvasy);\n }\n } else {\n ctx.moveTo(point.canvasx, point.canvasy);\n }\n if (drawPoints || isIsolated) {\n pointsOnLine.push([point.canvasx, point.canvasy, point.idx]);\n }\n prevCanvasX = point.canvasx;\n prevCanvasY = point.canvasy;\n }\n first = false;\n }\n ctx.stroke();\n return pointsOnLine;\n};\n\n/**\n * This fires the drawPointCallback functions, which draw dots on the points by\n * default. This gets used when the \"drawPoints\" option is set, or when there\n * are isolated points.\n * @param {Object} e The dictionary passed to the plotter function.\n * @private\n */\nDygraphCanvasRenderer._drawPointsOnLine = function (e, pointsOnLine, drawPointCallback, color, pointSize) {\n var ctx = e.drawingContext;\n for (var idx = 0; idx < pointsOnLine.length; idx++) {\n var cb = pointsOnLine[idx];\n ctx.save();\n drawPointCallback.call(e.dygraph, e.dygraph, e.setName, ctx, cb[0], cb[1], color, pointSize, cb[2]);\n ctx.restore();\n }\n};\n\n/**\n * Attaches canvas coordinates to the points array.\n * @private\n */\nDygraphCanvasRenderer.prototype._updatePoints = function () {\n // Update Points\n // TODO(danvk): here\n //\n // TODO(bhs): this loop is a hot-spot for high-point-count charts. These\n // transformations can be pushed into the canvas via linear transformation\n // matrices.\n // NOTE(danvk): this is trickier than it sounds at first. The transformation\n // needs to be done before the .moveTo() and .lineTo() calls, but must be\n // undone before the .stroke() call to ensure that the stroke width is\n // unaffected. An alternative is to reduce the stroke width in the\n // transformed coordinate space, but you can't specify different values for\n // each dimension (as you can with .scale()). The speedup here is ~12%.\n var sets = this.layout.points;\n for (var i = sets.length; i--;) {\n var points = sets[i];\n for (var j = points.length; j--;) {\n var point = points[j];\n point.canvasx = this.area.w * point.x + this.area.x;\n point.canvasy = this.area.h * point.y + this.area.y;\n }\n }\n};\n\n/**\n * Add canvas Actually draw the lines chart, including error bars.\n *\n * This function can only be called if DygraphLayout's points array has been\n * updated with canvas{x,y} attributes, i.e. by\n * DygraphCanvasRenderer._updatePoints.\n *\n * @param {string=} opt_seriesName when specified, only that series will\n * be drawn. (This is used for expedited redrawing with highlightSeriesOpts)\n * @param {CanvasRenderingContext2D} opt_ctx when specified, the drawing\n * context. However, lines are typically drawn on the object's\n * elementContext.\n * @private\n */\nDygraphCanvasRenderer.prototype._renderLineChart = function (opt_seriesName, opt_ctx) {\n var ctx = opt_ctx || this.elementContext;\n var i;\n\n var sets = this.layout.points;\n var setNames = this.layout.setNames;\n var setName;\n\n this.colors = this.dygraph_.colorsMap_;\n\n // Determine which series have specialized plotters.\n var plotter_attr = this.dygraph_.getOption(\"plotter\");\n var plotters = plotter_attr;\n if (!utils.isArrayLike(plotters)) {\n plotters = [plotters];\n }\n\n var setPlotters = {}; // series name -> plotter fn.\n for (i = 0; i < setNames.length; i++) {\n setName = setNames[i];\n var setPlotter = this.dygraph_.getOption(\"plotter\", setName);\n if (setPlotter == plotter_attr) continue; // not specialized.\n\n setPlotters[setName] = setPlotter;\n }\n\n for (i = 0; i < plotters.length; i++) {\n var plotter = plotters[i];\n var is_last = i == plotters.length - 1;\n\n for (var j = 0; j < sets.length; j++) {\n setName = setNames[j];\n if (opt_seriesName && setName != opt_seriesName) continue;\n\n var points = sets[j];\n\n // Only throw in the specialized plotters on the last iteration.\n var p = plotter;\n if (setName in setPlotters) {\n if (is_last) {\n p = setPlotters[setName];\n } else {\n // Don't use the standard plotters in this case.\n continue;\n }\n }\n\n var color = this.colors[setName];\n var strokeWidth = this.dygraph_.getOption(\"strokeWidth\", setName);\n\n ctx.save();\n ctx.strokeStyle = color;\n ctx.lineWidth = strokeWidth;\n p({\n points: points,\n setName: setName,\n drawingContext: ctx,\n color: color,\n strokeWidth: strokeWidth,\n dygraph: this.dygraph_,\n axis: this.dygraph_.axisPropertiesForSeries(setName),\n plotArea: this.area,\n seriesIndex: j,\n seriesCount: sets.length,\n singleSeriesName: opt_seriesName,\n allSeriesPoints: sets\n });\n ctx.restore();\n }\n }\n};\n\n/**\n * Standard plotters. These may be used by clients via Dygraph.Plotters.\n * See comments there for more details.\n */\nDygraphCanvasRenderer._Plotters = {\n linePlotter: function linePlotter(e) {\n DygraphCanvasRenderer._linePlotter(e);\n },\n\n fillPlotter: function fillPlotter(e) {\n DygraphCanvasRenderer._fillPlotter(e);\n },\n\n errorPlotter: function errorPlotter(e) {\n DygraphCanvasRenderer._errorPlotter(e);\n }\n};\n\n/**\n * Plotter which draws the central lines for a series.\n * @private\n */\nDygraphCanvasRenderer._linePlotter = function (e) {\n var g = e.dygraph;\n var setName = e.setName;\n var strokeWidth = e.strokeWidth;\n\n // TODO(danvk): Check if there's any performance impact of just calling\n // getOption() inside of _drawStyledLine. Passing in so many parameters makes\n // this code a bit nasty.\n var borderWidth = g.getNumericOption(\"strokeBorderWidth\", setName);\n var drawPointCallback = g.getOption(\"drawPointCallback\", setName) || utils.Circles.DEFAULT;\n var strokePattern = g.getOption(\"strokePattern\", setName);\n var drawPoints = g.getBooleanOption(\"drawPoints\", setName);\n var pointSize = g.getNumericOption(\"pointSize\", setName);\n\n if (borderWidth && strokeWidth) {\n DygraphCanvasRenderer._drawStyledLine(e, g.getOption(\"strokeBorderColor\", setName), strokeWidth + 2 * borderWidth, strokePattern, drawPoints, drawPointCallback, pointSize);\n }\n\n DygraphCanvasRenderer._drawStyledLine(e, e.color, strokeWidth, strokePattern, drawPoints, drawPointCallback, pointSize);\n};\n\n/**\n * Draws the shaded error bars/confidence intervals for each series.\n * This happens before the center lines are drawn, since the center lines\n * need to be drawn on top of the error bars for all series.\n * @private\n */\nDygraphCanvasRenderer._errorPlotter = function (e) {\n var g = e.dygraph;\n var setName = e.setName;\n var errorBars = g.getBooleanOption(\"errorBars\") || g.getBooleanOption(\"customBars\");\n if (!errorBars) return;\n\n var fillGraph = g.getBooleanOption(\"fillGraph\", setName);\n if (fillGraph) {\n console.warn(\"Can't use fillGraph option with error bars\");\n }\n\n var ctx = e.drawingContext;\n var color = e.color;\n var fillAlpha = g.getNumericOption('fillAlpha', setName);\n var stepPlot = g.getBooleanOption(\"stepPlot\", setName);\n var points = e.points;\n\n var iter = utils.createIterator(points, 0, points.length, DygraphCanvasRenderer._getIteratorPredicate(g.getBooleanOption(\"connectSeparatedPoints\", setName)));\n\n var newYs;\n\n // setup graphics context\n var prevX = NaN;\n var prevY = NaN;\n var prevYs = [-1, -1];\n // should be same color as the lines but only 15% opaque.\n var rgb = utils.toRGB_(color);\n var err_color = 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + fillAlpha + ')';\n ctx.fillStyle = err_color;\n ctx.beginPath();\n\n var isNullUndefinedOrNaN = function isNullUndefinedOrNaN(x) {\n return x === null || x === undefined || isNaN(x);\n };\n\n while (iter.hasNext) {\n var point = iter.next();\n if (!stepPlot && isNullUndefinedOrNaN(point.y) || stepPlot && !isNaN(prevY) && isNullUndefinedOrNaN(prevY)) {\n prevX = NaN;\n continue;\n }\n\n newYs = [point.y_bottom, point.y_top];\n if (stepPlot) {\n prevY = point.y;\n }\n\n // The documentation specifically disallows nulls inside the point arrays,\n // but in case it happens we should do something sensible.\n if (isNaN(newYs[0])) newYs[0] = point.y;\n if (isNaN(newYs[1])) newYs[1] = point.y;\n\n newYs[0] = e.plotArea.h * newYs[0] + e.plotArea.y;\n newYs[1] = e.plotArea.h * newYs[1] + e.plotArea.y;\n if (!isNaN(prevX)) {\n if (stepPlot) {\n ctx.moveTo(prevX, prevYs[0]);\n ctx.lineTo(point.canvasx, prevYs[0]);\n ctx.lineTo(point.canvasx, prevYs[1]);\n } else {\n ctx.moveTo(prevX, prevYs[0]);\n ctx.lineTo(point.canvasx, newYs[0]);\n ctx.lineTo(point.canvasx, newYs[1]);\n }\n ctx.lineTo(prevX, prevYs[1]);\n ctx.closePath();\n }\n prevYs = newYs;\n prevX = point.canvasx;\n }\n ctx.fill();\n};\n\n/**\n * Proxy for CanvasRenderingContext2D which drops moveTo/lineTo calls which are\n * superfluous. It accumulates all movements which haven't changed the x-value\n * and only applies the two with the most extreme y-values.\n *\n * Calls to lineTo/moveTo must have non-decreasing x-values.\n */\nDygraphCanvasRenderer._fastCanvasProxy = function (context) {\n var pendingActions = []; // array of [type, x, y] tuples\n var lastRoundedX = null;\n var lastFlushedX = null;\n\n var LINE_TO = 1,\n MOVE_TO = 2;\n\n var actionCount = 0; // number of moveTos and lineTos passed to context.\n\n // Drop superfluous motions\n // Assumes all pendingActions have the same (rounded) x-value.\n var compressActions = function compressActions(opt_losslessOnly) {\n if (pendingActions.length <= 1) return;\n\n // Lossless compression: drop inconsequential moveTos.\n for (var i = pendingActions.length - 1; i > 0; i--) {\n var action = pendingActions[i];\n if (action[0] == MOVE_TO) {\n var prevAction = pendingActions[i - 1];\n if (prevAction[1] == action[1] && prevAction[2] == action[2]) {\n pendingActions.splice(i, 1);\n }\n }\n }\n\n // Lossless compression: ... drop consecutive moveTos ...\n for (var i = 0; i < pendingActions.length - 1;) /* incremented internally */{\n var action = pendingActions[i];\n if (action[0] == MOVE_TO && pendingActions[i + 1][0] == MOVE_TO) {\n pendingActions.splice(i, 1);\n } else {\n i++;\n }\n }\n\n // Lossy compression: ... drop all but the extreme y-values ...\n if (pendingActions.length > 2 && !opt_losslessOnly) {\n // keep an initial moveTo, but drop all others.\n var startIdx = 0;\n if (pendingActions[0][0] == MOVE_TO) startIdx++;\n var minIdx = null,\n maxIdx = null;\n for (var i = startIdx; i < pendingActions.length; i++) {\n var action = pendingActions[i];\n if (action[0] != LINE_TO) continue;\n if (minIdx === null && maxIdx === null) {\n minIdx = i;\n maxIdx = i;\n } else {\n var y = action[2];\n if (y < pendingActions[minIdx][2]) {\n minIdx = i;\n } else if (y > pendingActions[maxIdx][2]) {\n maxIdx = i;\n }\n }\n }\n var minAction = pendingActions[minIdx],\n maxAction = pendingActions[maxIdx];\n pendingActions.splice(startIdx, pendingActions.length - startIdx);\n if (minIdx < maxIdx) {\n pendingActions.push(minAction);\n pendingActions.push(maxAction);\n } else if (minIdx > maxIdx) {\n pendingActions.push(maxAction);\n pendingActions.push(minAction);\n } else {\n pendingActions.push(minAction);\n }\n }\n };\n\n var flushActions = function flushActions(opt_noLossyCompression) {\n compressActions(opt_noLossyCompression);\n for (var i = 0, len = pendingActions.length; i < len; i++) {\n var action = pendingActions[i];\n if (action[0] == LINE_TO) {\n context.lineTo(action[1], action[2]);\n } else if (action[0] == MOVE_TO) {\n context.moveTo(action[1], action[2]);\n }\n }\n if (pendingActions.length) {\n lastFlushedX = pendingActions[pendingActions.length - 1][1];\n }\n actionCount += pendingActions.length;\n pendingActions = [];\n };\n\n var addAction = function addAction(action, x, y) {\n var rx = Math.round(x);\n if (lastRoundedX === null || rx != lastRoundedX) {\n // if there are large gaps on the x-axis, it's essential to keep the\n // first and last point as well.\n var hasGapOnLeft = lastRoundedX - lastFlushedX > 1,\n hasGapOnRight = rx - lastRoundedX > 1,\n hasGap = hasGapOnLeft || hasGapOnRight;\n flushActions(hasGap);\n lastRoundedX = rx;\n }\n pendingActions.push([action, x, y]);\n };\n\n return {\n moveTo: function moveTo(x, y) {\n addAction(MOVE_TO, x, y);\n },\n lineTo: function lineTo(x, y) {\n addAction(LINE_TO, x, y);\n },\n\n // for major operations like stroke/fill, we skip compression to ensure\n // that there are no artifacts at the right edge.\n stroke: function stroke() {\n flushActions(true);context.stroke();\n },\n fill: function fill() {\n flushActions(true);context.fill();\n },\n beginPath: function beginPath() {\n flushActions(true);context.beginPath();\n },\n closePath: function closePath() {\n flushActions(true);context.closePath();\n },\n\n _count: function _count() {\n return actionCount;\n }\n };\n};\n\n/**\n * Draws the shaded regions when \"fillGraph\" is set. Not to be confused with\n * error bars.\n *\n * For stacked charts, it's more convenient to handle all the series\n * simultaneously. So this plotter plots all the points on the first series\n * it's asked to draw, then ignores all the other series.\n *\n * @private\n */\nDygraphCanvasRenderer._fillPlotter = function (e) {\n // Skip if we're drawing a single series for interactive highlight overlay.\n if (e.singleSeriesName) return;\n\n // We'll handle all the series at once, not one-by-one.\n if (e.seriesIndex !== 0) return;\n\n var g = e.dygraph;\n var setNames = g.getLabels().slice(1); // remove x-axis\n\n // getLabels() includes names for invisible series, which are not included in\n // allSeriesPoints. We remove those to make the two match.\n // TODO(danvk): provide a simpler way to get this information.\n for (var i = setNames.length; i >= 0; i--) {\n if (!g.visibility()[i]) setNames.splice(i, 1);\n }\n\n var anySeriesFilled = (function () {\n for (var i = 0; i < setNames.length; i++) {\n if (g.getBooleanOption(\"fillGraph\", setNames[i])) return true;\n }\n return false;\n })();\n\n if (!anySeriesFilled) return;\n\n var area = e.plotArea;\n var sets = e.allSeriesPoints;\n var setCount = sets.length;\n\n var stackedGraph = g.getBooleanOption(\"stackedGraph\");\n var colors = g.getColors();\n\n // For stacked graphs, track the baseline for filling.\n //\n // The filled areas below graph lines are trapezoids with two\n // vertical edges. The top edge is the line segment being drawn, and\n // the baseline is the bottom edge. Each baseline corresponds to the\n // top line segment from the previous stacked line. In the case of\n // step plots, the trapezoids are rectangles.\n var baseline = {};\n var currBaseline;\n var prevStepPlot; // for different line drawing modes (line/step) per series\n\n // Helper function to trace a line back along the baseline.\n var traceBackPath = function traceBackPath(ctx, baselineX, baselineY, pathBack) {\n ctx.lineTo(baselineX, baselineY);\n if (stackedGraph) {\n for (var i = pathBack.length - 1; i >= 0; i--) {\n var pt = pathBack[i];\n ctx.lineTo(pt[0], pt[1]);\n }\n }\n };\n\n // process sets in reverse order (needed for stacked graphs)\n for (var setIdx = setCount - 1; setIdx >= 0; setIdx--) {\n var ctx = e.drawingContext;\n var setName = setNames[setIdx];\n if (!g.getBooleanOption('fillGraph', setName)) continue;\n\n var fillAlpha = g.getNumericOption('fillAlpha', setName);\n var stepPlot = g.getBooleanOption('stepPlot', setName);\n var color = colors[setIdx];\n var axis = g.axisPropertiesForSeries(setName);\n var axisY = 1.0 + axis.minyval * axis.yscale;\n if (axisY < 0.0) axisY = 0.0;else if (axisY > 1.0) axisY = 1.0;\n axisY = area.h * axisY + area.y;\n\n var points = sets[setIdx];\n var iter = utils.createIterator(points, 0, points.length, DygraphCanvasRenderer._getIteratorPredicate(g.getBooleanOption(\"connectSeparatedPoints\", setName)));\n\n // setup graphics context\n var prevX = NaN;\n var prevYs = [-1, -1];\n var newYs;\n // should be same color as the lines but only 15% opaque.\n var rgb = utils.toRGB_(color);\n var err_color = 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + fillAlpha + ')';\n ctx.fillStyle = err_color;\n ctx.beginPath();\n var last_x,\n is_first = true;\n\n // If the point density is high enough, dropping segments on their way to\n // the canvas justifies the overhead of doing so.\n if (points.length > 2 * g.width_ || _dygraph2['default'].FORCE_FAST_PROXY) {\n ctx = DygraphCanvasRenderer._fastCanvasProxy(ctx);\n }\n\n // For filled charts, we draw points from left to right, then back along\n // the x-axis to complete a shape for filling.\n // For stacked plots, this \"back path\" is a more complex shape. This array\n // stores the [x, y] values needed to trace that shape.\n var pathBack = [];\n\n // TODO(danvk): there are a lot of options at play in this loop.\n // The logic would be much clearer if some (e.g. stackGraph and\n // stepPlot) were split off into separate sub-plotters.\n var point;\n while (iter.hasNext) {\n point = iter.next();\n if (!utils.isOK(point.y) && !stepPlot) {\n traceBackPath(ctx, prevX, prevYs[1], pathBack);\n pathBack = [];\n prevX = NaN;\n if (point.y_stacked !== null && !isNaN(point.y_stacked)) {\n baseline[point.canvasx] = area.h * point.y_stacked + area.y;\n }\n continue;\n }\n if (stackedGraph) {\n if (!is_first && last_x == point.xval) {\n continue;\n } else {\n is_first = false;\n last_x = point.xval;\n }\n\n currBaseline = baseline[point.canvasx];\n var lastY;\n if (currBaseline === undefined) {\n lastY = axisY;\n } else {\n if (prevStepPlot) {\n lastY = currBaseline[0];\n } else {\n lastY = currBaseline;\n }\n }\n newYs = [point.canvasy, lastY];\n\n if (stepPlot) {\n // Step plots must keep track of the top and bottom of\n // the baseline at each point.\n if (prevYs[0] === -1) {\n baseline[point.canvasx] = [point.canvasy, axisY];\n } else {\n baseline[point.canvasx] = [point.canvasy, prevYs[0]];\n }\n } else {\n baseline[point.canvasx] = point.canvasy;\n }\n } else {\n if (isNaN(point.canvasy) && stepPlot) {\n newYs = [area.y + area.h, axisY];\n } else {\n newYs = [point.canvasy, axisY];\n }\n }\n if (!isNaN(prevX)) {\n // Move to top fill point\n if (stepPlot) {\n ctx.lineTo(point.canvasx, prevYs[0]);\n ctx.lineTo(point.canvasx, newYs[0]);\n } else {\n ctx.lineTo(point.canvasx, newYs[0]);\n }\n\n // Record the baseline for the reverse path.\n if (stackedGraph) {\n pathBack.push([prevX, prevYs[1]]);\n if (prevStepPlot && currBaseline) {\n // Draw to the bottom of the baseline\n pathBack.push([point.canvasx, currBaseline[1]]);\n } else {\n pathBack.push([point.canvasx, newYs[1]]);\n }\n }\n } else {\n ctx.moveTo(point.canvasx, newYs[1]);\n ctx.lineTo(point.canvasx, newYs[0]);\n }\n prevYs = newYs;\n prevX = point.canvasx;\n }\n prevStepPlot = stepPlot;\n if (newYs && point) {\n traceBackPath(ctx, point.canvasx, newYs[1], pathBack);\n pathBack = [];\n }\n ctx.fill();\n }\n};\n\nexports['default'] = DygraphCanvasRenderer;\nmodule.exports = exports['default'];","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }\n\nvar _dygraphTickers = require('./dygraph-tickers');\n\nvar DygraphTickers = _interopRequireWildcard(_dygraphTickers);\n\nvar _dygraphInteractionModel = require('./dygraph-interaction-model');\n\nvar _dygraphInteractionModel2 = _interopRequireDefault(_dygraphInteractionModel);\n\nvar _dygraphCanvas = require('./dygraph-canvas');\n\nvar _dygraphCanvas2 = _interopRequireDefault(_dygraphCanvas);\n\nvar _dygraphUtils = require('./dygraph-utils');\n\nvar utils = _interopRequireWildcard(_dygraphUtils);\n\n// Default attribute values.\nvar DEFAULT_ATTRS = {\n highlightCircleSize: 3,\n highlightSeriesOpts: null,\n highlightSeriesBackgroundAlpha: 0.5,\n highlightSeriesBackgroundColor: 'rgb(255, 255, 255)',\n\n labelsSeparateLines: false,\n labelsShowZeroValues: true,\n labelsKMB: false,\n labelsKMG2: false,\n showLabelsOnHighlight: true,\n\n digitsAfterDecimal: 2,\n maxNumberWidth: 6,\n sigFigs: null,\n\n strokeWidth: 1.0,\n strokeBorderWidth: 0,\n strokeBorderColor: \"white\",\n\n axisTickSize: 3,\n axisLabelFontSize: 14,\n rightGap: 5,\n\n showRoller: false,\n xValueParser: undefined,\n\n delimiter: ',',\n\n sigma: 2.0,\n errorBars: false,\n fractions: false,\n wilsonInterval: true, // only relevant if fractions is true\n customBars: false,\n fillGraph: false,\n fillAlpha: 0.15,\n connectSeparatedPoints: false,\n\n stackedGraph: false,\n stackedGraphNaNFill: 'all',\n hideOverlayOnMouseOut: true,\n\n legend: 'onmouseover',\n stepPlot: false,\n xRangePad: 0,\n yRangePad: null,\n drawAxesAtZero: false,\n\n // Sizes of the various chart labels.\n titleHeight: 28,\n xLabelHeight: 18,\n yLabelWidth: 18,\n\n axisLineColor: \"black\",\n axisLineWidth: 0.3,\n gridLineWidth: 0.3,\n axisLabelWidth: 50,\n gridLineColor: \"rgb(128,128,128)\",\n\n interactionModel: _dygraphInteractionModel2['default'].defaultModel,\n animatedZooms: false, // (for now)\n\n // Range selector options\n showRangeSelector: false,\n rangeSelectorHeight: 40,\n rangeSelectorPlotStrokeColor: \"#808FAB\",\n rangeSelectorPlotFillGradientColor: \"white\",\n rangeSelectorPlotFillColor: \"#A7B1C4\",\n rangeSelectorBackgroundStrokeColor: \"gray\",\n rangeSelectorBackgroundLineWidth: 1,\n rangeSelectorPlotLineWidth: 1.5,\n rangeSelectorForegroundStrokeColor: \"black\",\n rangeSelectorForegroundLineWidth: 1,\n rangeSelectorAlpha: 0.6,\n showInRangeSelector: null,\n\n // The ordering here ensures that central lines always appear above any\n // fill bars/error bars.\n plotter: [_dygraphCanvas2['default']._fillPlotter, _dygraphCanvas2['default']._errorPlotter, _dygraphCanvas2['default']._linePlotter],\n\n plugins: [],\n\n // per-axis options\n axes: {\n x: {\n pixelsPerLabel: 70,\n axisLabelWidth: 60,\n axisLabelFormatter: utils.dateAxisLabelFormatter,\n valueFormatter: utils.dateValueFormatter,\n drawGrid: true,\n drawAxis: true,\n independentTicks: true,\n ticker: DygraphTickers.dateTicker\n },\n y: {\n axisLabelWidth: 50,\n pixelsPerLabel: 30,\n valueFormatter: utils.numberValueFormatter,\n axisLabelFormatter: utils.numberAxisLabelFormatter,\n drawGrid: true,\n drawAxis: true,\n independentTicks: true,\n ticker: DygraphTickers.numericTicks\n },\n y2: {\n axisLabelWidth: 50,\n pixelsPerLabel: 30,\n valueFormatter: utils.numberValueFormatter,\n axisLabelFormatter: utils.numberAxisLabelFormatter,\n drawAxis: true, // only applies when there are two axes of data.\n drawGrid: false,\n independentTicks: false,\n ticker: DygraphTickers.numericTicks\n }\n }\n};\n\nexports['default'] = DEFAULT_ATTRS;\nmodule.exports = exports['default'];","/**\n * @license\n * Copyright 2011 Dan Vanderkam (danvdk@gmail.com)\n * MIT-licensed (http://opensource.org/licenses/MIT)\n */\n\n\"use strict\";\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\nvar OPTIONS_REFERENCE = null;\n\n// For \"production\" code, this gets removed by uglifyjs.\nif (typeof process !== 'undefined') {\n if (process.env.NODE_ENV != 'production') {\n\n // NOTE: in addition to parsing as JS, this snippet is expected to be valid\n // JSON. This assumption cannot be checked in JS, but it will be checked when\n // documentation is generated by the generate-documentation.py script. For the\n // most part, this just means that you should always use double quotes.\n OPTIONS_REFERENCE = // \n {\n \"xValueParser\": {\n \"default\": \"parseFloat() or Date.parse()*\",\n \"labels\": [\"CSV parsing\"],\n \"type\": \"function(str) -> number\",\n \"description\": \"A function which parses x-values (i.e. the dependent series). Must return a number, even when the values are dates. In this case, millis since epoch are used. This is used primarily for parsing CSV data. *=Dygraphs is slightly more accepting in the dates which it will parse. See code for details.\"\n },\n \"stackedGraph\": {\n \"default\": \"false\",\n \"labels\": [\"Data Line display\"],\n \"type\": \"boolean\",\n \"description\": \"If set, stack series on top of one another rather than drawing them independently. The first series specified in the input data will wind up on top of the chart and the last will be on bottom. NaN values are drawn as white areas without a line on top, see stackedGraphNaNFill for details.\"\n },\n \"stackedGraphNaNFill\": {\n \"default\": \"all\",\n \"labels\": [\"Data Line display\"],\n \"type\": \"string\",\n \"description\": \"Controls handling of NaN values inside a stacked graph. NaN values are interpolated/extended for stacking purposes, but the actual point value remains NaN in the legend display. Valid option values are \\\"all\\\" (interpolate internally, repeat leftmost and rightmost value as needed), \\\"inside\\\" (interpolate internally only, use zero outside leftmost and rightmost value), and \\\"none\\\" (treat NaN as zero everywhere).\"\n },\n \"pointSize\": {\n \"default\": \"1\",\n \"labels\": [\"Data Line display\"],\n \"type\": \"integer\",\n \"description\": \"The size of the dot to draw on each point in pixels (see drawPoints). A dot is always drawn when a point is \\\"isolated\\\", i.e. there is a missing point on either side of it. This also controls the size of those dots.\"\n },\n \"drawPoints\": {\n \"default\": \"false\",\n \"labels\": [\"Data Line display\"],\n \"type\": \"boolean\",\n \"description\": \"Draw a small dot at each point, in addition to a line going through the point. This makes the individual data points easier to see, but can increase visual clutter in the chart. The small dot can be replaced with a custom rendering by supplying a drawPointCallback.\"\n },\n \"drawGapEdgePoints\": {\n \"default\": \"false\",\n \"labels\": [\"Data Line display\"],\n \"type\": \"boolean\",\n \"description\": \"Draw points at the edges of gaps in the data. This improves visibility of small data segments or other data irregularities.\"\n },\n \"drawPointCallback\": {\n \"default\": \"null\",\n \"labels\": [\"Data Line display\"],\n \"type\": \"function(g, seriesName, canvasContext, cx, cy, color, pointSize)\",\n \"parameters\": [[\"g\", \"the reference graph\"], [\"seriesName\", \"the name of the series\"], [\"canvasContext\", \"the canvas to draw on\"], [\"cx\", \"center x coordinate\"], [\"cy\", \"center y coordinate\"], [\"color\", \"series color\"], [\"pointSize\", \"the radius of the image.\"], [\"idx\", \"the row-index of the point in the data.\"]],\n \"description\": \"Draw a custom item when drawPoints is enabled. Default is a small dot matching the series color. This method should constrain drawing to within pointSize pixels from (cx, cy). Also see drawHighlightPointCallback\"\n },\n \"height\": {\n \"default\": \"320\",\n \"labels\": [\"Overall display\"],\n \"type\": \"integer\",\n \"description\": \"Height, in pixels, of the chart. If the container div has been explicitly sized, this will be ignored.\"\n },\n \"zoomCallback\": {\n \"default\": \"null\",\n \"labels\": [\"Callbacks\"],\n \"type\": \"function(minDate, maxDate, yRanges)\",\n \"parameters\": [[\"minDate\", \"milliseconds since epoch\"], [\"maxDate\", \"milliseconds since epoch.\"], [\"yRanges\", \"is an array of [bottom, top] pairs, one for each y-axis.\"]],\n \"description\": \"A function to call when the zoom window is changed (either by zooming in or out). When animatedZooms is set, zoomCallback is called once at the end of the transition (it will not be called for intermediate frames).\"\n },\n \"pointClickCallback\": {\n \"snippet\": \"function(e, point){
  alert(point);
}\",\n \"default\": \"null\",\n \"labels\": [\"Callbacks\", \"Interactive Elements\"],\n \"type\": \"function(e, point)\",\n \"parameters\": [[\"e\", \"the event object for the click\"], [\"point\", \"the point that was clicked See Point properties for details\"]],\n \"description\": \"A function to call when a data point is clicked. and the point that was clicked.\"\n },\n \"color\": {\n \"default\": \"(see description)\",\n \"labels\": [\"Data Series Colors\"],\n \"type\": \"string\",\n \"example\": \"red\",\n \"description\": \"A per-series color definition. Used in conjunction with, and overrides, the colors option.\"\n },\n \"colors\": {\n \"default\": \"(see description)\",\n \"labels\": [\"Data Series Colors\"],\n \"type\": \"array\",\n \"example\": \"['red', '#00FF00']\",\n \"description\": \"List of colors for the data series. These can be of the form \\\"#AABBCC\\\" or \\\"rgb(255,100,200)\\\" or \\\"yellow\\\", etc. If not specified, equally-spaced points around a color wheel are used. Overridden by the 'color' option.\"\n },\n \"connectSeparatedPoints\": {\n \"default\": \"false\",\n \"labels\": [\"Data Line display\"],\n \"type\": \"boolean\",\n \"description\": \"Usually, when Dygraphs encounters a missing value in a data series, it interprets this as a gap and draws it as such. If, instead, the missing values represents an x-value for which only a different series has data, then you'll want to connect the dots by setting this to true. To explicitly include a gap with this option set, use a value of NaN.\"\n },\n \"highlightCallback\": {\n \"default\": \"null\",\n \"labels\": [\"Callbacks\"],\n \"type\": \"function(event, x, points, row, seriesName)\",\n \"description\": \"When set, this callback gets called every time a new point is highlighted.\",\n \"parameters\": [[\"event\", \"the JavaScript mousemove event\"], [\"x\", \"the x-coordinate of the highlighted points\"], [\"points\", \"an array of highlighted points: [ {name: 'series', yval: y-value}, … ]\"], [\"row\", \"integer index of the highlighted row in the data table, starting from 0\"], [\"seriesName\", \"name of the highlighted series, only present if highlightSeriesOpts is set.\"]]\n },\n \"drawHighlightPointCallback\": {\n \"default\": \"null\",\n \"labels\": [\"Data Line display\"],\n \"type\": \"function(g, seriesName, canvasContext, cx, cy, color, pointSize)\",\n \"parameters\": [[\"g\", \"the reference graph\"], [\"seriesName\", \"the name of the series\"], [\"canvasContext\", \"the canvas to draw on\"], [\"cx\", \"center x coordinate\"], [\"cy\", \"center y coordinate\"], [\"color\", \"series color\"], [\"pointSize\", \"the radius of the image.\"], [\"idx\", \"the row-index of the point in the data.\"]],\n \"description\": \"Draw a custom item when a point is highlighted. Default is a small dot matching the series color. This method should constrain drawing to within pointSize pixels from (cx, cy) Also see drawPointCallback\"\n },\n \"highlightSeriesOpts\": {\n \"default\": \"null\",\n \"labels\": [\"Interactive Elements\"],\n \"type\": \"Object\",\n \"description\": \"When set, the options from this object are applied to the timeseries closest to the mouse pointer for interactive highlighting. See also 'highlightCallback'. Example: highlightSeriesOpts: { strokeWidth: 3 }.\"\n },\n \"highlightSeriesBackgroundAlpha\": {\n \"default\": \"0.5\",\n \"labels\": [\"Interactive Elements\"],\n \"type\": \"float\",\n \"description\": \"Fade the background while highlighting series. 1=fully visible background (disable fading), 0=hiddden background (show highlighted series only).\"\n },\n \"highlightSeriesBackgroundColor\": {\n \"default\": \"rgb(255, 255, 255)\",\n \"labels\": [\"Interactive Elements\"],\n \"type\": \"string\",\n \"description\": \"Sets the background color used to fade out the series in conjunction with 'highlightSeriesBackgroundAlpha'.\"\n },\n \"includeZero\": {\n \"default\": \"false\",\n \"labels\": [\"Axis display\"],\n \"type\": \"boolean\",\n \"description\": \"Usually, dygraphs will use the range of the data plus some padding to set the range of the y-axis. If this option is set, the y-axis will always include zero, typically as the lowest value. This can be used to avoid exaggerating the variance in the data\"\n },\n \"rollPeriod\": {\n \"default\": \"1\",\n \"labels\": [\"Error Bars\", \"Rolling Averages\"],\n \"type\": \"integer >= 1\",\n \"description\": \"Number of days over which to average data. Discussed extensively above.\"\n },\n \"unhighlightCallback\": {\n \"default\": \"null\",\n \"labels\": [\"Callbacks\"],\n \"type\": \"function(event)\",\n \"parameters\": [[\"event\", \"the mouse event\"]],\n \"description\": \"When set, this callback gets called every time the user stops highlighting any point by mousing out of the graph.\"\n },\n \"axisTickSize\": {\n \"default\": \"3.0\",\n \"labels\": [\"Axis display\"],\n \"type\": \"number\",\n \"description\": \"The size of the line to display next to each tick mark on x- or y-axes.\"\n },\n \"labelsSeparateLines\": {\n \"default\": \"false\",\n \"labels\": [\"Legend\"],\n \"type\": \"boolean\",\n \"description\": \"Put <br/> between lines in the label string. Often used in conjunction with labelsDiv.\"\n },\n \"valueFormatter\": {\n \"default\": \"Depends on the type of your data.\",\n \"labels\": [\"Legend\", \"Value display/formatting\"],\n \"type\": \"function(num or millis, opts, seriesName, dygraph, row, col)\",\n \"description\": \"Function to provide a custom display format for the values displayed on mouseover. This does not affect the values that appear on tick marks next to the axes. To format those, see axisLabelFormatter. This is usually set on a per-axis basis. .\",\n \"parameters\": [[\"num_or_millis\", \"The value to be formatted. This is always a number. For date axes, it's millis since epoch. You can call new Date(millis) to get a Date object.\"], [\"opts\", \"This is a function you can call to access various options (e.g. opts('labelsKMB')). It returns per-axis values for the option when available.\"], [\"seriesName\", \"The name of the series from which the point came, e.g. 'X', 'Y', 'A', etc.\"], [\"dygraph\", \"The dygraph object for which the formatting is being done\"], [\"row\", \"The row of the data from which this point comes. g.getValue(row, 0) will return the x-value for this point.\"], [\"col\", \"The column of the data from which this point comes. g.getValue(row, col) will return the original y-value for this point. This can be used to get the full confidence interval for the point, or access un-rolled values for the point.\"]]\n },\n \"annotationMouseOverHandler\": {\n \"default\": \"null\",\n \"labels\": [\"Annotations\"],\n \"type\": \"function(annotation, point, dygraph, event)\",\n \"description\": \"If provided, this function is called whenever the user mouses over an annotation.\"\n },\n \"annotationMouseOutHandler\": {\n \"default\": \"null\",\n \"labels\": [\"Annotations\"],\n \"type\": \"function(annotation, point, dygraph, event)\",\n \"parameters\": [[\"annotation\", \"the annotation left\"], [\"point\", \"the point associated with the annotation\"], [\"dygraph\", \"the reference graph\"], [\"event\", \"the mouse event\"]],\n \"description\": \"If provided, this function is called whenever the user mouses out of an annotation.\"\n },\n \"annotationClickHandler\": {\n \"default\": \"null\",\n \"labels\": [\"Annotations\"],\n \"type\": \"function(annotation, point, dygraph, event)\",\n \"parameters\": [[\"annotation\", \"the annotation left\"], [\"point\", \"the point associated with the annotation\"], [\"dygraph\", \"the reference graph\"], [\"event\", \"the mouse event\"]],\n \"description\": \"If provided, this function is called whenever the user clicks on an annotation.\"\n },\n \"annotationDblClickHandler\": {\n \"default\": \"null\",\n \"labels\": [\"Annotations\"],\n \"type\": \"function(annotation, point, dygraph, event)\",\n \"parameters\": [[\"annotation\", \"the annotation left\"], [\"point\", \"the point associated with the annotation\"], [\"dygraph\", \"the reference graph\"], [\"event\", \"the mouse event\"]],\n \"description\": \"If provided, this function is called whenever the user double-clicks on an annotation.\"\n },\n \"drawCallback\": {\n \"default\": \"null\",\n \"labels\": [\"Callbacks\"],\n \"type\": \"function(dygraph, is_initial)\",\n \"parameters\": [[\"dygraph\", \"The graph being drawn\"], [\"is_initial\", \"True if this is the initial draw, false for subsequent draws.\"]],\n \"description\": \"When set, this callback gets called every time the dygraph is drawn. This includes the initial draw, after zooming and repeatedly while panning.\"\n },\n \"labelsKMG2\": {\n \"default\": \"false\",\n \"labels\": [\"Value display/formatting\"],\n \"type\": \"boolean\",\n \"description\": \"Show k/M/G for kilo/Mega/Giga on y-axis. This is different than labelsKMB in that it uses base 2, not 10.\"\n },\n \"delimiter\": {\n \"default\": \",\",\n \"labels\": [\"CSV parsing\"],\n \"type\": \"string\",\n \"description\": \"The delimiter to look for when separating fields of a CSV file. Setting this to a tab is not usually necessary, since tab-delimited data is auto-detected.\"\n },\n \"axisLabelFontSize\": {\n \"default\": \"14\",\n \"labels\": [\"Axis display\"],\n \"type\": \"integer\",\n \"description\": \"Size of the font (in pixels) to use in the axis labels, both x- and y-axis.\"\n },\n \"underlayCallback\": {\n \"default\": \"null\",\n \"labels\": [\"Callbacks\"],\n \"type\": \"function(context, area, dygraph)\",\n \"parameters\": [[\"context\", \"the canvas drawing context on which to draw\"], [\"area\", \"An object with {x,y,w,h} properties describing the drawing area.\"], [\"dygraph\", \"the reference graph\"]],\n \"description\": \"When set, this callback gets called before the chart is drawn. It details on how to use this.\"\n },\n \"width\": {\n \"default\": \"480\",\n \"labels\": [\"Overall display\"],\n \"type\": \"integer\",\n \"description\": \"Width, in pixels, of the chart. If the container div has been explicitly sized, this will be ignored.\"\n },\n \"pixelRatio\": {\n \"default\": \"(devicePixelRatio / context.backingStoreRatio)\",\n \"labels\": [\"Overall display\"],\n \"type\": \"float\",\n \"description\": \"Overrides the pixel ratio scaling factor for the canvas's 2d context. Ordinarily, this is set to the devicePixelRatio / (context.backingStoreRatio || 1), so on mobile devices, where the devicePixelRatio can be somewhere around 3, performance can be improved by overriding this value to something less precise, like 1, at the expense of resolution.\"\n },\n \"interactionModel\": {\n \"default\": \"...\",\n \"labels\": [\"Interactive Elements\"],\n \"type\": \"Object\",\n \"description\": \"TODO(konigsberg): document this\"\n },\n \"ticker\": {\n \"default\": \"Dygraph.dateTicker or Dygraph.numericTicks\",\n \"labels\": [\"Axis display\"],\n \"type\": \"function(min, max, pixels, opts, dygraph, vals) -> [{v: ..., label: ...}, ...]\",\n \"parameters\": [[\"min\", \"\"], [\"max\", \"\"], [\"pixels\", \"\"], [\"opts\", \"\"], [\"dygraph\", \"the reference graph\"], [\"vals\", \"\"]],\n \"description\": \"This lets you specify an arbitrary function to generate tick marks on an axis. The tick marks are an array of (value, label) pairs. The built-in functions go to great lengths to choose good tick marks so, if you set this option, you'll most likely want to call one of them and modify the result. See dygraph-tickers.js for an extensive discussion. This is set on a per-axis basis.\"\n },\n \"xAxisHeight\": {\n \"default\": \"(null)\",\n \"labels\": [\"Axis display\"],\n \"type\": \"integer\",\n \"description\": \"Height, in pixels, of the x-axis. If not set explicitly, this is computed based on axisLabelFontSize and axisTickSize.\"\n },\n \"showLabelsOnHighlight\": {\n \"default\": \"true\",\n \"labels\": [\"Interactive Elements\", \"Legend\"],\n \"type\": \"boolean\",\n \"description\": \"Whether to show the legend upon mouseover.\"\n },\n \"axis\": {\n \"default\": \"(none)\",\n \"labels\": [\"Axis display\"],\n \"type\": \"string\",\n \"description\": \"Set to either 'y1' or 'y2' to assign a series to a y-axis (primary or secondary). Must be set per-series.\"\n },\n \"pixelsPerLabel\": {\n \"default\": \"70 (x-axis) or 30 (y-axes)\",\n \"labels\": [\"Axis display\", \"Grid\"],\n \"type\": \"integer\",\n \"description\": \"Number of pixels to require between each x- and y-label. Larger values will yield a sparser axis with fewer ticks. This is set on a per-axis basis.\"\n },\n \"labelsDiv\": {\n \"default\": \"null\",\n \"labels\": [\"Legend\"],\n \"type\": \"DOM element or string\",\n \"example\": \"document.getElementById('foo')or'foo'\",\n \"description\": \"Show data labels in an external div, rather than on the graph. This value can either be a div element or a div id.\"\n },\n \"fractions\": {\n \"default\": \"false\",\n \"labels\": [\"CSV parsing\", \"Error Bars\"],\n \"type\": \"boolean\",\n \"description\": \"When set, attempt to parse each cell in the CSV file as \\\"a/b\\\", where a and b are integers. The ratio will be plotted. This allows computation of Wilson confidence intervals (see below).\"\n },\n \"logscale\": {\n \"default\": \"false\",\n \"labels\": [\"Axis display\"],\n \"type\": \"boolean\",\n \"description\": \"When set for the y-axis or x-axis, the graph shows that axis in log scale. Any values less than or equal to zero are not displayed. Showing log scale with ranges that go below zero will result in an unviewable graph.\\n\\n Not compatible with showZero. connectSeparatedPoints is ignored. This is ignored for date-based x-axes.\"\n },\n \"strokeWidth\": {\n \"default\": \"1.0\",\n \"labels\": [\"Data Line display\"],\n \"type\": \"float\",\n \"example\": \"0.5, 2.0\",\n \"description\": \"The width of the lines connecting data points. This can be used to increase the contrast or some graphs.\"\n },\n \"strokePattern\": {\n \"default\": \"null\",\n \"labels\": [\"Data Line display\"],\n \"type\": \"array\",\n \"example\": \"[10, 2, 5, 2]\",\n \"description\": \"A custom pattern array where the even index is a draw and odd is a space in pixels. If null then it draws a solid line. The array should have a even length as any odd lengthed array could be expressed as a smaller even length array. This is used to create dashed lines.\"\n },\n \"strokeBorderWidth\": {\n \"default\": \"null\",\n \"labels\": [\"Data Line display\"],\n \"type\": \"float\",\n \"example\": \"1.0\",\n \"description\": \"Draw a border around graph lines to make crossing lines more easily distinguishable. Useful for graphs with many lines.\"\n },\n \"strokeBorderColor\": {\n \"default\": \"white\",\n \"labels\": [\"Data Line display\"],\n \"type\": \"string\",\n \"example\": \"red, #ccffdd\",\n \"description\": \"Color for the line border used if strokeBorderWidth is set.\"\n },\n \"wilsonInterval\": {\n \"default\": \"true\",\n \"labels\": [\"Error Bars\"],\n \"type\": \"boolean\",\n \"description\": \"Use in conjunction with the \\\"fractions\\\" option. Instead of plotting +/- N standard deviations, dygraphs will compute a Wilson confidence interval and plot that. This has more reasonable behavior for ratios close to 0 or 1.\"\n },\n \"fillGraph\": {\n \"default\": \"false\",\n \"labels\": [\"Data Line display\"],\n \"type\": \"boolean\",\n \"description\": \"Should the area underneath the graph be filled? This option is not compatible with error bars. This may be set on a per-series basis.\"\n },\n \"highlightCircleSize\": {\n \"default\": \"3\",\n \"labels\": [\"Interactive Elements\"],\n \"type\": \"integer\",\n \"description\": \"The size in pixels of the dot drawn over highlighted points.\"\n },\n \"gridLineColor\": {\n \"default\": \"rgb(128,128,128)\",\n \"labels\": [\"Grid\"],\n \"type\": \"red, blue\",\n \"description\": \"The color of the gridlines. This may be set on a per-axis basis to define each axis' grid separately.\"\n },\n \"gridLinePattern\": {\n \"default\": \"null\",\n \"labels\": [\"Grid\"],\n \"type\": \"array\",\n \"example\": \"[10, 2, 5, 2]\",\n \"description\": \"A custom pattern array where the even index is a draw and odd is a space in pixels. If null then it draws a solid line. The array should have a even length as any odd lengthed array could be expressed as a smaller even length array. This is used to create dashed gridlines.\"\n },\n \"visibility\": {\n \"default\": \"[true, true, ...]\",\n \"labels\": [\"Data Line display\"],\n \"type\": \"Array of booleans\",\n \"description\": \"Which series should initially be visible? Once the Dygraph has been constructed, you can access and modify the visibility of each series using the visibility and setVisibility methods.\"\n },\n \"valueRange\": {\n \"default\": \"Full range of the input is shown\",\n \"labels\": [\"Axis display\"],\n \"type\": \"Array of two numbers\",\n \"example\": \"[10, 110]\",\n \"description\": \"Explicitly set the vertical range of the graph to [low, high]. This may be set on a per-axis basis to define each y-axis separately. If either limit is unspecified, it will be calculated automatically (e.g. [null, 30] to automatically calculate just the lower bound)\"\n },\n \"colorSaturation\": {\n \"default\": \"1.0\",\n \"labels\": [\"Data Series Colors\"],\n \"type\": \"float (0.0 - 1.0)\",\n \"description\": \"If colors is not specified, saturation of the automatically-generated data series colors.\"\n },\n \"hideOverlayOnMouseOut\": {\n \"default\": \"true\",\n \"labels\": [\"Interactive Elements\", \"Legend\"],\n \"type\": \"boolean\",\n \"description\": \"Whether to hide the legend when the mouse leaves the chart area.\"\n },\n \"legend\": {\n \"default\": \"onmouseover\",\n \"labels\": [\"Legend\"],\n \"type\": \"string\",\n \"description\": \"When to display the legend. By default, it only appears when a user mouses over the chart. Set it to \\\"always\\\" to always display a legend of some sort. When set to \\\"follow\\\", legend follows highlighted points.\"\n },\n \"legendFormatter\": {\n \"default\": \"null\",\n \"labels\": [\"Legend\"],\n \"type\": \"function(data): string\",\n \"params\": [[\"data\", \"An object containing information about the selection (or lack of a selection). This includes formatted values and series information. See here for sample values.\"]],\n \"description\": \"Set this to supply a custom formatter for the legend. See this comment and the legendFormatter demo for usage.\"\n },\n \"labelsShowZeroValues\": {\n \"default\": \"true\",\n \"labels\": [\"Legend\"],\n \"type\": \"boolean\",\n \"description\": \"Show zero value labels in the labelsDiv.\"\n },\n \"stepPlot\": {\n \"default\": \"false\",\n \"labels\": [\"Data Line display\"],\n \"type\": \"boolean\",\n \"description\": \"When set, display the graph as a step plot instead of a line plot. This option may either be set for the whole graph or for single series.\"\n },\n \"labelsUTC\": {\n \"default\": \"false\",\n \"labels\": [\"Value display/formatting\", \"Axis display\"],\n \"type\": \"boolean\",\n \"description\": \"Show date/time labels according to UTC (instead of local time).\"\n },\n \"labelsKMB\": {\n \"default\": \"false\",\n \"labels\": [\"Value display/formatting\"],\n \"type\": \"boolean\",\n \"description\": \"Show K/M/B for thousands/millions/billions on y-axis.\"\n },\n \"rightGap\": {\n \"default\": \"5\",\n \"labels\": [\"Overall display\"],\n \"type\": \"integer\",\n \"description\": \"Number of pixels to leave blank at the right edge of the Dygraph. This makes it easier to highlight the right-most data point.\"\n },\n \"drawAxesAtZero\": {\n \"default\": \"false\",\n \"labels\": [\"Axis display\"],\n \"type\": \"boolean\",\n \"description\": \"When set, draw the X axis at the Y=0 position and the Y axis at the X=0 position if those positions are inside the graph's visible area. Otherwise, draw the axes at the bottom or left graph edge as usual.\"\n },\n \"xRangePad\": {\n \"default\": \"0\",\n \"labels\": [\"Axis display\"],\n \"type\": \"float\",\n \"description\": \"Add the specified amount of extra space (in pixels) around the X-axis value range to ensure points at the edges remain visible.\"\n },\n \"yRangePad\": {\n \"default\": \"null\",\n \"labels\": [\"Axis display\"],\n \"type\": \"float\",\n \"description\": \"If set, add the specified amount of extra space (in pixels) around the Y-axis value range to ensure points at the edges remain visible. If unset, use the traditional Y padding algorithm.\"\n },\n \"axisLabelFormatter\": {\n \"default\": \"Depends on the data type\",\n \"labels\": [\"Axis display\"],\n \"type\": \"function(number or Date, granularity, opts, dygraph)\",\n \"parameters\": [[\"number or date\", \"Either a number (for a numeric axis) or a Date object (for a date axis)\"], [\"granularity\", \"specifies how fine-grained the axis is. For date axes, this is a reference to the time granularity enumeration, defined in dygraph-tickers.js, e.g. Dygraph.WEEKLY.\"], [\"opts\", \"a function which provides access to various options on the dygraph, e.g. opts('labelsKMB').\"], [\"dygraph\", \"the referenced graph\"]],\n \"description\": \"Function to call to format the tick values that appear along an axis. This is usually set on a per-axis basis.\"\n },\n \"clickCallback\": {\n \"snippet\": \"function(e, date_millis){
  alert(new Date(date_millis));
}\",\n \"default\": \"null\",\n \"labels\": [\"Callbacks\"],\n \"type\": \"function(e, x, points)\",\n \"parameters\": [[\"e\", \"The event object for the click\"], [\"x\", \"The x value that was clicked (for dates, this is milliseconds since epoch)\"], [\"points\", \"The closest points along that date. See Point properties for details.\"]],\n \"description\": \"A function to call when the canvas is clicked.\"\n },\n \"labels\": {\n \"default\": \"[\\\"X\\\", \\\"Y1\\\", \\\"Y2\\\", ...]*\",\n \"labels\": [\"Legend\"],\n \"type\": \"array\",\n \"description\": \"A name for each data series, including the independent (X) series. For CSV files and DataTable objections, this is determined by context. For raw data, this must be specified. If it is not, default values are supplied and a warning is logged.\"\n },\n \"dateWindow\": {\n \"default\": \"Full range of the input is shown\",\n \"labels\": [\"Axis display\"],\n \"type\": \"Array of two numbers\",\n \"example\": \"[
  Date.parse('2006-01-01'),
  (new Date()).valueOf()
]\",\n \"description\": \"Initially zoom in on a section of the graph. Is of the form [earliest, latest], where earliest/latest are milliseconds since epoch. If the data for the x-axis is numeric, the values in dateWindow must also be numbers.\"\n },\n \"showRoller\": {\n \"default\": \"false\",\n \"labels\": [\"Interactive Elements\", \"Rolling Averages\"],\n \"type\": \"boolean\",\n \"description\": \"If the rolling average period text box should be shown.\"\n },\n \"sigma\": {\n \"default\": \"2.0\",\n \"labels\": [\"Error Bars\"],\n \"type\": \"float\",\n \"description\": \"When errorBars is set, shade this many standard deviations above/below each point.\"\n },\n \"customBars\": {\n \"default\": \"false\",\n \"labels\": [\"CSV parsing\", \"Error Bars\"],\n \"type\": \"boolean\",\n \"description\": \"When set, parse each CSV cell as \\\"low;middle;high\\\". Error bars will be drawn for each point between low and high, with the series itself going through middle.\"\n },\n \"colorValue\": {\n \"default\": \"1.0\",\n \"labels\": [\"Data Series Colors\"],\n \"type\": \"float (0.0 - 1.0)\",\n \"description\": \"If colors is not specified, value of the data series colors, as in hue/saturation/value. (0.0-1.0, default 0.5)\"\n },\n \"errorBars\": {\n \"default\": \"false\",\n \"labels\": [\"CSV parsing\", \"Error Bars\"],\n \"type\": \"boolean\",\n \"description\": \"Does the data contain standard deviations? Setting this to true alters the input format (see above).\"\n },\n \"displayAnnotations\": {\n \"default\": \"false\",\n \"labels\": [\"Annotations\"],\n \"type\": \"boolean\",\n \"description\": \"Only applies when Dygraphs is used as a GViz chart. Causes string columns following a data series to be interpreted as annotations on points in that series. This is the same format used by Google's AnnotatedTimeLine chart.\"\n },\n \"panEdgeFraction\": {\n \"default\": \"null\",\n \"labels\": [\"Axis display\", \"Interactive Elements\"],\n \"type\": \"float\",\n \"description\": \"A value representing the farthest a graph may be panned, in percent of the display. For example, a value of 0.1 means that the graph can only be panned 10% passed the edges of the displayed values. null means no bounds.\"\n },\n \"title\": {\n \"labels\": [\"Chart labels\"],\n \"type\": \"string\",\n \"default\": \"null\",\n \"description\": \"Text to display above the chart. You can supply any HTML for this value, not just text. If you wish to style it using CSS, use the 'dygraph-label' or 'dygraph-title' classes.\"\n },\n \"titleHeight\": {\n \"default\": \"18\",\n \"labels\": [\"Chart labels\"],\n \"type\": \"integer\",\n \"description\": \"Height of the chart title, in pixels. This also controls the default font size of the title. If you style the title on your own, this controls how much space is set aside above the chart for the title's div.\"\n },\n \"xlabel\": {\n \"labels\": [\"Chart labels\"],\n \"type\": \"string\",\n \"default\": \"null\",\n \"description\": \"Text to display below the chart's x-axis. You can supply any HTML for this value, not just text. If you wish to style it using CSS, use the 'dygraph-label' or 'dygraph-xlabel' classes.\"\n },\n \"xLabelHeight\": {\n \"labels\": [\"Chart labels\"],\n \"type\": \"integer\",\n \"default\": \"18\",\n \"description\": \"Height of the x-axis label, in pixels. This also controls the default font size of the x-axis label. If you style the label on your own, this controls how much space is set aside below the chart for the x-axis label's div.\"\n },\n \"ylabel\": {\n \"labels\": [\"Chart labels\"],\n \"type\": \"string\",\n \"default\": \"null\",\n \"description\": \"Text to display to the left of the chart's y-axis. You can supply any HTML for this value, not just text. If you wish to style it using CSS, use the 'dygraph-label' or 'dygraph-ylabel' classes. The text will be rotated 90 degrees by default, so CSS rules may behave in unintuitive ways. No additional space is set aside for a y-axis label. If you need more space, increase the width of the y-axis tick labels using the yAxisLabelWidth option. If you need a wider div for the y-axis label, either style it that way with CSS (but remember that it's rotated, so width is controlled by the 'height' property) or set the yLabelWidth option.\"\n },\n \"y2label\": {\n \"labels\": [\"Chart labels\"],\n \"type\": \"string\",\n \"default\": \"null\",\n \"description\": \"Text to display to the right of the chart's secondary y-axis. This label is only displayed if a secondary y-axis is present. See this test for an example of how to do this. The comments for the 'ylabel' option generally apply here as well. This label gets a 'dygraph-y2label' instead of a 'dygraph-ylabel' class.\"\n },\n \"yLabelWidth\": {\n \"labels\": [\"Chart labels\"],\n \"type\": \"integer\",\n \"default\": \"18\",\n \"description\": \"Width of the div which contains the y-axis label. Since the y-axis label appears rotated 90 degrees, this actually affects the height of its div.\"\n },\n \"drawGrid\": {\n \"default\": \"true for x and y, false for y2\",\n \"labels\": [\"Grid\"],\n \"type\": \"boolean\",\n \"description\": \"Whether to display gridlines in the chart. This may be set on a per-axis basis to define the visibility of each axis' grid separately.\"\n },\n \"independentTicks\": {\n \"default\": \"true for y, false for y2\",\n \"labels\": [\"Axis display\", \"Grid\"],\n \"type\": \"boolean\",\n \"description\": \"Only valid for y and y2, has no effect on x: This option defines whether the y axes should align their ticks or if they should be independent. Possible combinations: 1.) y=true, y2=false (default): y is the primary axis and the y2 ticks are aligned to the the ones of y. (only 1 grid) 2.) y=false, y2=true: y2 is the primary axis and the y ticks are aligned to the the ones of y2. (only 1 grid) 3.) y=true, y2=true: Both axis are independent and have their own ticks. (2 grids) 4.) y=false, y2=false: Invalid configuration causes an error.\"\n },\n \"drawAxis\": {\n \"default\": \"true for x and y, false for y2\",\n \"labels\": [\"Axis display\"],\n \"type\": \"boolean\",\n \"description\": \"Whether to draw the specified axis. This may be set on a per-axis basis to define the visibility of each axis separately. Setting this to false also prevents axis ticks from being drawn and reclaims the space for the chart grid/lines.\"\n },\n \"gridLineWidth\": {\n \"default\": \"0.3\",\n \"labels\": [\"Grid\"],\n \"type\": \"float\",\n \"description\": \"Thickness (in pixels) of the gridlines drawn under the chart. The vertical/horizontal gridlines can be turned off entirely by using the drawGrid option. This may be set on a per-axis basis to define each axis' grid separately.\"\n },\n \"axisLineWidth\": {\n \"default\": \"0.3\",\n \"labels\": [\"Axis display\"],\n \"type\": \"float\",\n \"description\": \"Thickness (in pixels) of the x- and y-axis lines.\"\n },\n \"axisLineColor\": {\n \"default\": \"black\",\n \"labels\": [\"Axis display\"],\n \"type\": \"string\",\n \"description\": \"Color of the x- and y-axis lines. Accepts any value which the HTML canvas strokeStyle attribute understands, e.g. 'black' or 'rgb(0, 100, 255)'.\"\n },\n \"fillAlpha\": {\n \"default\": \"0.15\",\n \"labels\": [\"Error Bars\", \"Data Series Colors\"],\n \"type\": \"float (0.0 - 1.0)\",\n \"description\": \"Error bars (or custom bars) for each series are drawn in the same color as the series, but with partial transparency. This sets the transparency. A value of 0.0 means that the error bars will not be drawn, whereas a value of 1.0 means that the error bars will be as dark as the line for the series itself. This can be used to produce chart lines whose thickness varies at each point.\"\n },\n \"axisLabelWidth\": {\n \"default\": \"50 (y-axis), 60 (x-axis)\",\n \"labels\": [\"Axis display\", \"Chart labels\"],\n \"type\": \"integer\",\n \"description\": \"Width (in pixels) of the containing divs for x- and y-axis labels. For the y-axis, this also controls the width of the y-axis. Note that for the x-axis, this is independent from pixelsPerLabel, which controls the spacing between labels.\"\n },\n \"sigFigs\": {\n \"default\": \"null\",\n \"labels\": [\"Value display/formatting\"],\n \"type\": \"integer\",\n \"description\": \"By default, dygraphs displays numbers with a fixed number of digits after the decimal point. If you'd prefer to have a fixed number of significant figures, set this option to that number of sig figs. A value of 2, for instance, would cause 1 to be display as 1.0 and 1234 to be displayed as 1.23e+3.\"\n },\n \"digitsAfterDecimal\": {\n \"default\": \"2\",\n \"labels\": [\"Value display/formatting\"],\n \"type\": \"integer\",\n \"description\": \"Unless it's run in scientific mode (see the sigFigs option), dygraphs displays numbers with digitsAfterDecimal digits after the decimal point. Trailing zeros are not displayed, so with a value of 2 you'll get '0', '0.1', '0.12', '123.45' but not '123.456' (it will be rounded to '123.46'). Numbers with absolute value less than 0.1^digitsAfterDecimal (i.e. those which would show up as '0.00') will be displayed in scientific notation.\"\n },\n \"maxNumberWidth\": {\n \"default\": \"6\",\n \"labels\": [\"Value display/formatting\"],\n \"type\": \"integer\",\n \"description\": \"When displaying numbers in normal (not scientific) mode, large numbers will be displayed with many trailing zeros (e.g. 100000000 instead of 1e9). This can lead to unwieldy y-axis labels. If there are more than maxNumberWidth digits to the left of the decimal in a number, dygraphs will switch to scientific notation, even when not operating in scientific mode. If you'd like to see all those digits, set this to something large, like 20 or 30.\"\n },\n \"file\": {\n \"default\": \"(set when constructed)\",\n \"labels\": [\"Data\"],\n \"type\": \"string (URL of CSV or CSV), GViz DataTable or 2D Array\",\n \"description\": \"Sets the data being displayed in the chart. This can only be set when calling updateOptions; it cannot be set from the constructor. For a full description of valid data formats, see the Data Formats page.\"\n },\n \"timingName\": {\n \"default\": \"null\",\n \"labels\": [\"Debugging\", \"Deprecated\"],\n \"type\": \"string\",\n \"description\": \"Set this option to log timing information. The value of the option will be logged along with the timimg, so that you can distinguish multiple dygraphs on the same page.\"\n },\n \"showRangeSelector\": {\n \"default\": \"false\",\n \"labels\": [\"Range Selector\"],\n \"type\": \"boolean\",\n \"description\": \"Show or hide the range selector widget.\"\n },\n \"rangeSelectorHeight\": {\n \"default\": \"40\",\n \"labels\": [\"Range Selector\"],\n \"type\": \"integer\",\n \"description\": \"Height, in pixels, of the range selector widget. This option can only be specified at Dygraph creation time.\"\n },\n \"rangeSelectorPlotStrokeColor\": {\n \"default\": \"#808FAB\",\n \"labels\": [\"Range Selector\"],\n \"type\": \"string\",\n \"description\": \"The range selector mini plot stroke color. This can be of the form \\\"#AABBCC\\\" or \\\"rgb(255,100,200)\\\" or \\\"yellow\\\". You can also specify null or \\\"\\\" to turn off stroke.\"\n },\n \"rangeSelectorPlotFillColor\": {\n \"default\": \"#A7B1C4\",\n \"labels\": [\"Range Selector\"],\n \"type\": \"string\",\n \"description\": \"The range selector mini plot fill color. This can be of the form \\\"#AABBCC\\\" or \\\"rgb(255,100,200)\\\" or \\\"yellow\\\". You can also specify null or \\\"\\\" to turn off fill.\"\n },\n \"rangeSelectorPlotFillGradientColor\": {\n \"default\": \"white\",\n \"labels\": [\"Range Selector\"],\n \"type\": \"string\",\n \"description\": \"The top color for the range selector mini plot fill color gradient. This can be of the form \\\"#AABBCC\\\" or \\\"rgb(255,100,200)\\\" or \\\"rgba(255,100,200,42)\\\" or \\\"yellow\\\". You can also specify null or \\\"\\\" to disable the gradient and fill with one single color.\"\n },\n \"rangeSelectorBackgroundStrokeColor\": {\n \"default\": \"gray\",\n \"labels\": [\"Range Selector\"],\n \"type\": \"string\",\n \"description\": \"The color of the lines below and on both sides of the range selector mini plot. This can be of the form \\\"#AABBCC\\\" or \\\"rgb(255,100,200)\\\" or \\\"yellow\\\".\"\n },\n \"rangeSelectorBackgroundLineWidth\": {\n \"default\": \"1\",\n \"labels\": [\"Range Selector\"],\n \"type\": \"float\",\n \"description\": \"The width of the lines below and on both sides of the range selector mini plot.\"\n },\n \"rangeSelectorPlotLineWidth\": {\n \"default\": \"1.5\",\n \"labels\": [\"Range Selector\"],\n \"type\": \"float\",\n \"description\": \"The width of the range selector mini plot line.\"\n },\n \"rangeSelectorForegroundStrokeColor\": {\n \"default\": \"black\",\n \"labels\": [\"Range Selector\"],\n \"type\": \"string\",\n \"description\": \"The color of the lines in the interactive layer of the range selector. This can be of the form \\\"#AABBCC\\\" or \\\"rgb(255,100,200)\\\" or \\\"yellow\\\".\"\n },\n \"rangeSelectorForegroundLineWidth\": {\n \"default\": \"1\",\n \"labels\": [\"Range Selector\"],\n \"type\": \"float\",\n \"description\": \"The width the lines in the interactive layer of the range selector.\"\n },\n \"rangeSelectorAlpha\": {\n \"default\": \"0.6\",\n \"labels\": [\"Range Selector\"],\n \"type\": \"float (0.0 - 1.0)\",\n \"description\": \"The transparency of the veil that is drawn over the unselected portions of the range selector mini plot. A value of 0 represents full transparency and the unselected portions of the mini plot will appear as normal. A value of 1 represents full opacity and the unselected portions of the mini plot will be hidden.\"\n },\n \"showInRangeSelector\": {\n \"default\": \"null\",\n \"labels\": [\"Range Selector\"],\n \"type\": \"boolean\",\n \"description\": \"Mark this series for inclusion in the range selector. The mini plot curve will be an average of all such series. If this is not specified for any series, the default behavior is to average all the visible series. Setting it for one series will result in that series being charted alone in the range selector. Once it's set for a single series, it needs to be set for all series which should be included (regardless of visibility).\"\n },\n \"animatedZooms\": {\n \"default\": \"false\",\n \"labels\": [\"Interactive Elements\"],\n \"type\": \"boolean\",\n \"description\": \"Set this option to animate the transition between zoom windows. Applies to programmatic and interactive zooms. Note that if you also set a drawCallback, it will be called several times on each zoom. If you set a zoomCallback, it will only be called after the animation is complete.\"\n },\n \"plotter\": {\n \"default\": \"[DygraphCanvasRenderer.Plotters.fillPlotter, DygraphCanvasRenderer.Plotters.errorPlotter, DygraphCanvasRenderer.Plotters.linePlotter]\",\n \"labels\": [\"Data Line display\"],\n \"type\": \"array or function\",\n \"description\": \"A function (or array of functions) which plot each data series on the chart. TODO(danvk): more details! May be set per-series.\"\n },\n \"axes\": {\n \"default\": \"null\",\n \"labels\": [\"Configuration\"],\n \"type\": \"Object\",\n \"description\": \"Defines per-axis options. Valid keys are 'x', 'y' and 'y2'. Only some options may be set on a per-axis basis. If an option may be set in this way, it will be noted on this page. See also documentation on per-series and per-axis options.\"\n },\n \"series\": {\n \"default\": \"null\",\n \"labels\": [\"Series\"],\n \"type\": \"Object\",\n \"description\": \"Defines per-series options. Its keys match the y-axis label names, and the values are dictionaries themselves that contain options specific to that series.\"\n },\n \"plugins\": {\n \"default\": \"[]\",\n \"labels\": [\"Configuration\"],\n \"type\": \"Array\",\n \"description\": \"Defines per-graph plugins. Useful for per-graph customization\"\n },\n \"dataHandler\": {\n \"default\": \"(depends on data)\",\n \"labels\": [\"Data\"],\n \"type\": \"Dygraph.DataHandler\",\n \"description\": \"Custom DataHandler. This is an advanced customization. See http://bit.ly/151E7Aq.\"\n }\n }; //
\n // NOTE: in addition to parsing as JS, this snippet is expected to be valid\n // JSON. This assumption cannot be checked in JS, but it will be checked when\n // documentation is generated by the generate-documentation.py script. For the\n // most part, this just means that you should always use double quotes.\n\n // Do a quick sanity check on the options reference.\n var warn = function warn(msg) {\n if (window.console) window.console.warn(msg);\n };\n var flds = ['type', 'default', 'description'];\n var valid_cats = ['Annotations', 'Axis display', 'Chart labels', 'CSV parsing', 'Callbacks', 'Data', 'Data Line display', 'Data Series Colors', 'Error Bars', 'Grid', 'Interactive Elements', 'Range Selector', 'Legend', 'Overall display', 'Rolling Averages', 'Series', 'Value display/formatting', 'Zooming', 'Debugging', 'Configuration', 'Deprecated'];\n var i;\n var cats = {};\n for (i = 0; i < valid_cats.length; i++) cats[valid_cats[i]] = true;\n\n for (var k in OPTIONS_REFERENCE) {\n if (!OPTIONS_REFERENCE.hasOwnProperty(k)) continue;\n var op = OPTIONS_REFERENCE[k];\n for (i = 0; i < flds.length; i++) {\n if (!op.hasOwnProperty(flds[i])) {\n warn('Option ' + k + ' missing \"' + flds[i] + '\" property');\n } else if (typeof op[flds[i]] != 'string') {\n warn(k + '.' + flds[i] + ' must be of type string');\n }\n }\n var labels = op.labels;\n if (typeof labels !== 'object') {\n warn('Option \"' + k + '\" is missing a \"labels\": [...] option');\n } else {\n for (i = 0; i < labels.length; i++) {\n if (!cats.hasOwnProperty(labels[i])) {\n warn('Option \"' + k + '\" has label \"' + labels[i] + '\", which is invalid.');\n }\n }\n }\n }\n }\n}\n\nexports['default'] = OPTIONS_REFERENCE;\nmodule.exports = exports['default'];","/**\n * To create a \"drag\" interaction, you typically register a mousedown event\n * handler on the element where the drag begins. In that handler, you register a\n * mouseup handler on the window to determine when the mouse is released,\n * wherever that release happens. This works well, except when the user releases\n * the mouse over an off-domain iframe. In that case, the mouseup event is\n * handled by the iframe and never bubbles up to the window handler.\n *\n * To deal with this issue, we cover iframes with high z-index divs to make sure\n * they don't capture mouseup.\n *\n * Usage:\n * element.addEventListener('mousedown', function() {\n * var tarper = new IFrameTarp();\n * tarper.cover();\n * var mouseUpHandler = function() {\n * ...\n * window.removeEventListener(mouseUpHandler);\n * tarper.uncover();\n * };\n * window.addEventListener('mouseup', mouseUpHandler);\n * };\n *\n * @constructor\n */\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj[\"default\"] = obj; return newObj; } }\n\nvar _dygraphUtils = require('./dygraph-utils');\n\nvar utils = _interopRequireWildcard(_dygraphUtils);\n\nfunction IFrameTarp() {\n /** @type {Array.} */\n this.tarps = [];\n};\n\n/**\n * Find all the iframes in the document and cover them with high z-index\n * transparent divs.\n */\nIFrameTarp.prototype.cover = function () {\n var iframes = document.getElementsByTagName(\"iframe\");\n for (var i = 0; i < iframes.length; i++) {\n var iframe = iframes[i];\n var pos = utils.findPos(iframe),\n x = pos.x,\n y = pos.y,\n width = iframe.offsetWidth,\n height = iframe.offsetHeight;\n\n var div = document.createElement(\"div\");\n div.style.position = \"absolute\";\n div.style.left = x + 'px';\n div.style.top = y + 'px';\n div.style.width = width + 'px';\n div.style.height = height + 'px';\n div.style.zIndex = 999;\n document.body.appendChild(div);\n this.tarps.push(div);\n }\n};\n\n/**\n * Remove all the iframe covers. You should call this in a mouseup handler.\n */\nIFrameTarp.prototype.uncover = function () {\n for (var i = 0; i < this.tarps.length; i++) {\n this.tarps[i].parentNode.removeChild(this.tarps[i]);\n }\n this.tarps = [];\n};\n\nexports[\"default\"] = IFrameTarp;\nmodule.exports = exports[\"default\"];","/**\n * @license\n * Copyright 2013 David Eberlein (david.eberlein@ch.sauter-bc.com)\n * MIT-licensed (http://opensource.org/licenses/MIT)\n */\n\n/**\n * @fileoverview DataHandler default implementation used for simple line charts.\n * @author David Eberlein (david.eberlein@ch.sauter-bc.com)\n */\n\n/*global Dygraph:false */\n\"use strict\";\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar _datahandler = require('./datahandler');\n\nvar _datahandler2 = _interopRequireDefault(_datahandler);\n\n/**\n * @constructor\n * @extends Dygraph.DataHandler\n */\nvar DefaultHandler = function DefaultHandler() {};\n\nDefaultHandler.prototype = new _datahandler2['default']();\n\n/** @inheritDoc */\nDefaultHandler.prototype.extractSeries = function (rawData, i, options) {\n // TODO(danvk): pre-allocate series here.\n var series = [];\n var logScale = options.get('logscale');\n for (var j = 0; j < rawData.length; j++) {\n var x = rawData[j][0];\n var point = rawData[j][i];\n if (logScale) {\n // On the log scale, points less than zero do not exist.\n // This will create a gap in the chart.\n if (point <= 0) {\n point = null;\n }\n }\n series.push([x, point]);\n }\n return series;\n};\n\n/** @inheritDoc */\nDefaultHandler.prototype.rollingAverage = function (originalData, rollPeriod, options) {\n rollPeriod = Math.min(rollPeriod, originalData.length);\n var rollingData = [];\n\n var i, j, y, sum, num_ok;\n // Calculate the rolling average for the first rollPeriod - 1 points\n // where\n // there is not enough data to roll over the full number of points\n if (rollPeriod == 1) {\n return originalData;\n }\n for (i = 0; i < originalData.length; i++) {\n sum = 0;\n num_ok = 0;\n for (j = Math.max(0, i - rollPeriod + 1); j < i + 1; j++) {\n y = originalData[j][1];\n if (y === null || isNaN(y)) continue;\n num_ok++;\n sum += originalData[j][1];\n }\n if (num_ok) {\n rollingData[i] = [originalData[i][0], sum / num_ok];\n } else {\n rollingData[i] = [originalData[i][0], null];\n }\n }\n\n return rollingData;\n};\n\n/** @inheritDoc */\nDefaultHandler.prototype.getExtremeYValues = function (series, dateWindow, options) {\n var minY = null,\n maxY = null,\n y;\n var firstIdx = 0,\n lastIdx = series.length - 1;\n\n for (var j = firstIdx; j <= lastIdx; j++) {\n y = series[j][1];\n if (y === null || isNaN(y)) continue;\n if (maxY === null || y > maxY) {\n maxY = y;\n }\n if (minY === null || y < minY) {\n minY = y;\n }\n }\n return [minY, maxY];\n};\n\nexports['default'] = DefaultHandler;\nmodule.exports = exports['default'];","'use strict'\r\n\r\nmodule.exports = {\r\n\t\"aliceblue\": [240, 248, 255],\r\n\t\"antiquewhite\": [250, 235, 215],\r\n\t\"aqua\": [0, 255, 255],\r\n\t\"aquamarine\": [127, 255, 212],\r\n\t\"azure\": [240, 255, 255],\r\n\t\"beige\": [245, 245, 220],\r\n\t\"bisque\": [255, 228, 196],\r\n\t\"black\": [0, 0, 0],\r\n\t\"blanchedalmond\": [255, 235, 205],\r\n\t\"blue\": [0, 0, 255],\r\n\t\"blueviolet\": [138, 43, 226],\r\n\t\"brown\": [165, 42, 42],\r\n\t\"burlywood\": [222, 184, 135],\r\n\t\"cadetblue\": [95, 158, 160],\r\n\t\"chartreuse\": [127, 255, 0],\r\n\t\"chocolate\": [210, 105, 30],\r\n\t\"coral\": [255, 127, 80],\r\n\t\"cornflowerblue\": [100, 149, 237],\r\n\t\"cornsilk\": [255, 248, 220],\r\n\t\"crimson\": [220, 20, 60],\r\n\t\"cyan\": [0, 255, 255],\r\n\t\"darkblue\": [0, 0, 139],\r\n\t\"darkcyan\": [0, 139, 139],\r\n\t\"darkgoldenrod\": [184, 134, 11],\r\n\t\"darkgray\": [169, 169, 169],\r\n\t\"darkgreen\": [0, 100, 0],\r\n\t\"darkgrey\": [169, 169, 169],\r\n\t\"darkkhaki\": [189, 183, 107],\r\n\t\"darkmagenta\": [139, 0, 139],\r\n\t\"darkolivegreen\": [85, 107, 47],\r\n\t\"darkorange\": [255, 140, 0],\r\n\t\"darkorchid\": [153, 50, 204],\r\n\t\"darkred\": [139, 0, 0],\r\n\t\"darksalmon\": [233, 150, 122],\r\n\t\"darkseagreen\": [143, 188, 143],\r\n\t\"darkslateblue\": [72, 61, 139],\r\n\t\"darkslategray\": [47, 79, 79],\r\n\t\"darkslategrey\": [47, 79, 79],\r\n\t\"darkturquoise\": [0, 206, 209],\r\n\t\"darkviolet\": [148, 0, 211],\r\n\t\"deeppink\": [255, 20, 147],\r\n\t\"deepskyblue\": [0, 191, 255],\r\n\t\"dimgray\": [105, 105, 105],\r\n\t\"dimgrey\": [105, 105, 105],\r\n\t\"dodgerblue\": [30, 144, 255],\r\n\t\"firebrick\": [178, 34, 34],\r\n\t\"floralwhite\": [255, 250, 240],\r\n\t\"forestgreen\": [34, 139, 34],\r\n\t\"fuchsia\": [255, 0, 255],\r\n\t\"gainsboro\": [220, 220, 220],\r\n\t\"ghostwhite\": [248, 248, 255],\r\n\t\"gold\": [255, 215, 0],\r\n\t\"goldenrod\": [218, 165, 32],\r\n\t\"gray\": [128, 128, 128],\r\n\t\"green\": [0, 128, 0],\r\n\t\"greenyellow\": [173, 255, 47],\r\n\t\"grey\": [128, 128, 128],\r\n\t\"honeydew\": [240, 255, 240],\r\n\t\"hotpink\": [255, 105, 180],\r\n\t\"indianred\": [205, 92, 92],\r\n\t\"indigo\": [75, 0, 130],\r\n\t\"ivory\": [255, 255, 240],\r\n\t\"khaki\": [240, 230, 140],\r\n\t\"lavender\": [230, 230, 250],\r\n\t\"lavenderblush\": [255, 240, 245],\r\n\t\"lawngreen\": [124, 252, 0],\r\n\t\"lemonchiffon\": [255, 250, 205],\r\n\t\"lightblue\": [173, 216, 230],\r\n\t\"lightcoral\": [240, 128, 128],\r\n\t\"lightcyan\": [224, 255, 255],\r\n\t\"lightgoldenrodyellow\": [250, 250, 210],\r\n\t\"lightgray\": [211, 211, 211],\r\n\t\"lightgreen\": [144, 238, 144],\r\n\t\"lightgrey\": [211, 211, 211],\r\n\t\"lightpink\": [255, 182, 193],\r\n\t\"lightsalmon\": [255, 160, 122],\r\n\t\"lightseagreen\": [32, 178, 170],\r\n\t\"lightskyblue\": [135, 206, 250],\r\n\t\"lightslategray\": [119, 136, 153],\r\n\t\"lightslategrey\": [119, 136, 153],\r\n\t\"lightsteelblue\": [176, 196, 222],\r\n\t\"lightyellow\": [255, 255, 224],\r\n\t\"lime\": [0, 255, 0],\r\n\t\"limegreen\": [50, 205, 50],\r\n\t\"linen\": [250, 240, 230],\r\n\t\"magenta\": [255, 0, 255],\r\n\t\"maroon\": [128, 0, 0],\r\n\t\"mediumaquamarine\": [102, 205, 170],\r\n\t\"mediumblue\": [0, 0, 205],\r\n\t\"mediumorchid\": [186, 85, 211],\r\n\t\"mediumpurple\": [147, 112, 219],\r\n\t\"mediumseagreen\": [60, 179, 113],\r\n\t\"mediumslateblue\": [123, 104, 238],\r\n\t\"mediumspringgreen\": [0, 250, 154],\r\n\t\"mediumturquoise\": [72, 209, 204],\r\n\t\"mediumvioletred\": [199, 21, 133],\r\n\t\"midnightblue\": [25, 25, 112],\r\n\t\"mintcream\": [245, 255, 250],\r\n\t\"mistyrose\": [255, 228, 225],\r\n\t\"moccasin\": [255, 228, 181],\r\n\t\"navajowhite\": [255, 222, 173],\r\n\t\"navy\": [0, 0, 128],\r\n\t\"oldlace\": [253, 245, 230],\r\n\t\"olive\": [128, 128, 0],\r\n\t\"olivedrab\": [107, 142, 35],\r\n\t\"orange\": [255, 165, 0],\r\n\t\"orangered\": [255, 69, 0],\r\n\t\"orchid\": [218, 112, 214],\r\n\t\"palegoldenrod\": [238, 232, 170],\r\n\t\"palegreen\": [152, 251, 152],\r\n\t\"paleturquoise\": [175, 238, 238],\r\n\t\"palevioletred\": [219, 112, 147],\r\n\t\"papayawhip\": [255, 239, 213],\r\n\t\"peachpuff\": [255, 218, 185],\r\n\t\"peru\": [205, 133, 63],\r\n\t\"pink\": [255, 192, 203],\r\n\t\"plum\": [221, 160, 221],\r\n\t\"powderblue\": [176, 224, 230],\r\n\t\"purple\": [128, 0, 128],\r\n\t\"rebeccapurple\": [102, 51, 153],\r\n\t\"red\": [255, 0, 0],\r\n\t\"rosybrown\": [188, 143, 143],\r\n\t\"royalblue\": [65, 105, 225],\r\n\t\"saddlebrown\": [139, 69, 19],\r\n\t\"salmon\": [250, 128, 114],\r\n\t\"sandybrown\": [244, 164, 96],\r\n\t\"seagreen\": [46, 139, 87],\r\n\t\"seashell\": [255, 245, 238],\r\n\t\"sienna\": [160, 82, 45],\r\n\t\"silver\": [192, 192, 192],\r\n\t\"skyblue\": [135, 206, 235],\r\n\t\"slateblue\": [106, 90, 205],\r\n\t\"slategray\": [112, 128, 144],\r\n\t\"slategrey\": [112, 128, 144],\r\n\t\"snow\": [255, 250, 250],\r\n\t\"springgreen\": [0, 255, 127],\r\n\t\"steelblue\": [70, 130, 180],\r\n\t\"tan\": [210, 180, 140],\r\n\t\"teal\": [0, 128, 128],\r\n\t\"thistle\": [216, 191, 216],\r\n\t\"tomato\": [255, 99, 71],\r\n\t\"turquoise\": [64, 224, 208],\r\n\t\"violet\": [238, 130, 238],\r\n\t\"wheat\": [245, 222, 179],\r\n\t\"white\": [255, 255, 255],\r\n\t\"whitesmoke\": [245, 245, 245],\r\n\t\"yellow\": [255, 255, 0],\r\n\t\"yellowgreen\": [154, 205, 50]\r\n};\r\n","/* MIT license */\nvar cssKeywords = require('color-name');\n\n// NOTE: conversions should only return primitive values (i.e. arrays, or\n// values that give correct `typeof` results).\n// do not use box values types (i.e. Number(), String(), etc.)\n\nvar reverseKeywords = {};\nfor (var key in cssKeywords) {\n\tif (cssKeywords.hasOwnProperty(key)) {\n\t\treverseKeywords[cssKeywords[key]] = key;\n\t}\n}\n\nvar convert = module.exports = {\n\trgb: {channels: 3, labels: 'rgb'},\n\thsl: {channels: 3, labels: 'hsl'},\n\thsv: {channels: 3, labels: 'hsv'},\n\thwb: {channels: 3, labels: 'hwb'},\n\tcmyk: {channels: 4, labels: 'cmyk'},\n\txyz: {channels: 3, labels: 'xyz'},\n\tlab: {channels: 3, labels: 'lab'},\n\tlch: {channels: 3, labels: 'lch'},\n\thex: {channels: 1, labels: ['hex']},\n\tkeyword: {channels: 1, labels: ['keyword']},\n\tansi16: {channels: 1, labels: ['ansi16']},\n\tansi256: {channels: 1, labels: ['ansi256']},\n\thcg: {channels: 3, labels: ['h', 'c', 'g']},\n\tapple: {channels: 3, labels: ['r16', 'g16', 'b16']},\n\tgray: {channels: 1, labels: ['gray']}\n};\n\n// hide .channels and .labels properties\nfor (var model in convert) {\n\tif (convert.hasOwnProperty(model)) {\n\t\tif (!('channels' in convert[model])) {\n\t\t\tthrow new Error('missing channels property: ' + model);\n\t\t}\n\n\t\tif (!('labels' in convert[model])) {\n\t\t\tthrow new Error('missing channel labels property: ' + model);\n\t\t}\n\n\t\tif (convert[model].labels.length !== convert[model].channels) {\n\t\t\tthrow new Error('channel and label counts mismatch: ' + model);\n\t\t}\n\n\t\tvar channels = convert[model].channels;\n\t\tvar labels = convert[model].labels;\n\t\tdelete convert[model].channels;\n\t\tdelete convert[model].labels;\n\t\tObject.defineProperty(convert[model], 'channels', {value: channels});\n\t\tObject.defineProperty(convert[model], 'labels', {value: labels});\n\t}\n}\n\nconvert.rgb.hsl = function (rgb) {\n\tvar r = rgb[0] / 255;\n\tvar g = rgb[1] / 255;\n\tvar b = rgb[2] / 255;\n\tvar min = Math.min(r, g, b);\n\tvar max = Math.max(r, g, b);\n\tvar delta = max - min;\n\tvar h;\n\tvar s;\n\tvar l;\n\n\tif (max === min) {\n\t\th = 0;\n\t} else if (r === max) {\n\t\th = (g - b) / delta;\n\t} else if (g === max) {\n\t\th = 2 + (b - r) / delta;\n\t} else if (b === max) {\n\t\th = 4 + (r - g) / delta;\n\t}\n\n\th = Math.min(h * 60, 360);\n\n\tif (h < 0) {\n\t\th += 360;\n\t}\n\n\tl = (min + max) / 2;\n\n\tif (max === min) {\n\t\ts = 0;\n\t} else if (l <= 0.5) {\n\t\ts = delta / (max + min);\n\t} else {\n\t\ts = delta / (2 - max - min);\n\t}\n\n\treturn [h, s * 100, l * 100];\n};\n\nconvert.rgb.hsv = function (rgb) {\n\tvar rdif;\n\tvar gdif;\n\tvar bdif;\n\tvar h;\n\tvar s;\n\n\tvar r = rgb[0] / 255;\n\tvar g = rgb[1] / 255;\n\tvar b = rgb[2] / 255;\n\tvar v = Math.max(r, g, b);\n\tvar diff = v - Math.min(r, g, b);\n\tvar diffc = function (c) {\n\t\treturn (v - c) / 6 / diff + 1 / 2;\n\t};\n\n\tif (diff === 0) {\n\t\th = s = 0;\n\t} else {\n\t\ts = diff / v;\n\t\trdif = diffc(r);\n\t\tgdif = diffc(g);\n\t\tbdif = diffc(b);\n\n\t\tif (r === v) {\n\t\t\th = bdif - gdif;\n\t\t} else if (g === v) {\n\t\t\th = (1 / 3) + rdif - bdif;\n\t\t} else if (b === v) {\n\t\t\th = (2 / 3) + gdif - rdif;\n\t\t}\n\t\tif (h < 0) {\n\t\t\th += 1;\n\t\t} else if (h > 1) {\n\t\t\th -= 1;\n\t\t}\n\t}\n\n\treturn [\n\t\th * 360,\n\t\ts * 100,\n\t\tv * 100\n\t];\n};\n\nconvert.rgb.hwb = function (rgb) {\n\tvar r = rgb[0];\n\tvar g = rgb[1];\n\tvar b = rgb[2];\n\tvar h = convert.rgb.hsl(rgb)[0];\n\tvar w = 1 / 255 * Math.min(r, Math.min(g, b));\n\n\tb = 1 - 1 / 255 * Math.max(r, Math.max(g, b));\n\n\treturn [h, w * 100, b * 100];\n};\n\nconvert.rgb.cmyk = function (rgb) {\n\tvar r = rgb[0] / 255;\n\tvar g = rgb[1] / 255;\n\tvar b = rgb[2] / 255;\n\tvar c;\n\tvar m;\n\tvar y;\n\tvar k;\n\n\tk = Math.min(1 - r, 1 - g, 1 - b);\n\tc = (1 - r - k) / (1 - k) || 0;\n\tm = (1 - g - k) / (1 - k) || 0;\n\ty = (1 - b - k) / (1 - k) || 0;\n\n\treturn [c * 100, m * 100, y * 100, k * 100];\n};\n\n/**\n * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance\n * */\nfunction comparativeDistance(x, y) {\n\treturn (\n\t\tMath.pow(x[0] - y[0], 2) +\n\t\tMath.pow(x[1] - y[1], 2) +\n\t\tMath.pow(x[2] - y[2], 2)\n\t);\n}\n\nconvert.rgb.keyword = function (rgb) {\n\tvar reversed = reverseKeywords[rgb];\n\tif (reversed) {\n\t\treturn reversed;\n\t}\n\n\tvar currentClosestDistance = Infinity;\n\tvar currentClosestKeyword;\n\n\tfor (var keyword in cssKeywords) {\n\t\tif (cssKeywords.hasOwnProperty(keyword)) {\n\t\t\tvar value = cssKeywords[keyword];\n\n\t\t\t// Compute comparative distance\n\t\t\tvar distance = comparativeDistance(rgb, value);\n\n\t\t\t// Check if its less, if so set as closest\n\t\t\tif (distance < currentClosestDistance) {\n\t\t\t\tcurrentClosestDistance = distance;\n\t\t\t\tcurrentClosestKeyword = keyword;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn currentClosestKeyword;\n};\n\nconvert.keyword.rgb = function (keyword) {\n\treturn cssKeywords[keyword];\n};\n\nconvert.rgb.xyz = function (rgb) {\n\tvar r = rgb[0] / 255;\n\tvar g = rgb[1] / 255;\n\tvar b = rgb[2] / 255;\n\n\t// assume sRGB\n\tr = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92);\n\tg = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92);\n\tb = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92);\n\n\tvar x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);\n\tvar y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);\n\tvar z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);\n\n\treturn [x * 100, y * 100, z * 100];\n};\n\nconvert.rgb.lab = function (rgb) {\n\tvar xyz = convert.rgb.xyz(rgb);\n\tvar x = xyz[0];\n\tvar y = xyz[1];\n\tvar z = xyz[2];\n\tvar l;\n\tvar a;\n\tvar b;\n\n\tx /= 95.047;\n\ty /= 100;\n\tz /= 108.883;\n\n\tx = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116);\n\ty = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116);\n\tz = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116);\n\n\tl = (116 * y) - 16;\n\ta = 500 * (x - y);\n\tb = 200 * (y - z);\n\n\treturn [l, a, b];\n};\n\nconvert.hsl.rgb = function (hsl) {\n\tvar h = hsl[0] / 360;\n\tvar s = hsl[1] / 100;\n\tvar l = hsl[2] / 100;\n\tvar t1;\n\tvar t2;\n\tvar t3;\n\tvar rgb;\n\tvar val;\n\n\tif (s === 0) {\n\t\tval = l * 255;\n\t\treturn [val, val, val];\n\t}\n\n\tif (l < 0.5) {\n\t\tt2 = l * (1 + s);\n\t} else {\n\t\tt2 = l + s - l * s;\n\t}\n\n\tt1 = 2 * l - t2;\n\n\trgb = [0, 0, 0];\n\tfor (var i = 0; i < 3; i++) {\n\t\tt3 = h + 1 / 3 * -(i - 1);\n\t\tif (t3 < 0) {\n\t\t\tt3++;\n\t\t}\n\t\tif (t3 > 1) {\n\t\t\tt3--;\n\t\t}\n\n\t\tif (6 * t3 < 1) {\n\t\t\tval = t1 + (t2 - t1) * 6 * t3;\n\t\t} else if (2 * t3 < 1) {\n\t\t\tval = t2;\n\t\t} else if (3 * t3 < 2) {\n\t\t\tval = t1 + (t2 - t1) * (2 / 3 - t3) * 6;\n\t\t} else {\n\t\t\tval = t1;\n\t\t}\n\n\t\trgb[i] = val * 255;\n\t}\n\n\treturn rgb;\n};\n\nconvert.hsl.hsv = function (hsl) {\n\tvar h = hsl[0];\n\tvar s = hsl[1] / 100;\n\tvar l = hsl[2] / 100;\n\tvar smin = s;\n\tvar lmin = Math.max(l, 0.01);\n\tvar sv;\n\tvar v;\n\n\tl *= 2;\n\ts *= (l <= 1) ? l : 2 - l;\n\tsmin *= lmin <= 1 ? lmin : 2 - lmin;\n\tv = (l + s) / 2;\n\tsv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s);\n\n\treturn [h, sv * 100, v * 100];\n};\n\nconvert.hsv.rgb = function (hsv) {\n\tvar h = hsv[0] / 60;\n\tvar s = hsv[1] / 100;\n\tvar v = hsv[2] / 100;\n\tvar hi = Math.floor(h) % 6;\n\n\tvar f = h - Math.floor(h);\n\tvar p = 255 * v * (1 - s);\n\tvar q = 255 * v * (1 - (s * f));\n\tvar t = 255 * v * (1 - (s * (1 - f)));\n\tv *= 255;\n\n\tswitch (hi) {\n\t\tcase 0:\n\t\t\treturn [v, t, p];\n\t\tcase 1:\n\t\t\treturn [q, v, p];\n\t\tcase 2:\n\t\t\treturn [p, v, t];\n\t\tcase 3:\n\t\t\treturn [p, q, v];\n\t\tcase 4:\n\t\t\treturn [t, p, v];\n\t\tcase 5:\n\t\t\treturn [v, p, q];\n\t}\n};\n\nconvert.hsv.hsl = function (hsv) {\n\tvar h = hsv[0];\n\tvar s = hsv[1] / 100;\n\tvar v = hsv[2] / 100;\n\tvar vmin = Math.max(v, 0.01);\n\tvar lmin;\n\tvar sl;\n\tvar l;\n\n\tl = (2 - s) * v;\n\tlmin = (2 - s) * vmin;\n\tsl = s * vmin;\n\tsl /= (lmin <= 1) ? lmin : 2 - lmin;\n\tsl = sl || 0;\n\tl /= 2;\n\n\treturn [h, sl * 100, l * 100];\n};\n\n// http://dev.w3.org/csswg/css-color/#hwb-to-rgb\nconvert.hwb.rgb = function (hwb) {\n\tvar h = hwb[0] / 360;\n\tvar wh = hwb[1] / 100;\n\tvar bl = hwb[2] / 100;\n\tvar ratio = wh + bl;\n\tvar i;\n\tvar v;\n\tvar f;\n\tvar n;\n\n\t// wh + bl cant be > 1\n\tif (ratio > 1) {\n\t\twh /= ratio;\n\t\tbl /= ratio;\n\t}\n\n\ti = Math.floor(6 * h);\n\tv = 1 - bl;\n\tf = 6 * h - i;\n\n\tif ((i & 0x01) !== 0) {\n\t\tf = 1 - f;\n\t}\n\n\tn = wh + f * (v - wh); // linear interpolation\n\n\tvar r;\n\tvar g;\n\tvar b;\n\tswitch (i) {\n\t\tdefault:\n\t\tcase 6:\n\t\tcase 0: r = v; g = n; b = wh; break;\n\t\tcase 1: r = n; g = v; b = wh; break;\n\t\tcase 2: r = wh; g = v; b = n; break;\n\t\tcase 3: r = wh; g = n; b = v; break;\n\t\tcase 4: r = n; g = wh; b = v; break;\n\t\tcase 5: r = v; g = wh; b = n; break;\n\t}\n\n\treturn [r * 255, g * 255, b * 255];\n};\n\nconvert.cmyk.rgb = function (cmyk) {\n\tvar c = cmyk[0] / 100;\n\tvar m = cmyk[1] / 100;\n\tvar y = cmyk[2] / 100;\n\tvar k = cmyk[3] / 100;\n\tvar r;\n\tvar g;\n\tvar b;\n\n\tr = 1 - Math.min(1, c * (1 - k) + k);\n\tg = 1 - Math.min(1, m * (1 - k) + k);\n\tb = 1 - Math.min(1, y * (1 - k) + k);\n\n\treturn [r * 255, g * 255, b * 255];\n};\n\nconvert.xyz.rgb = function (xyz) {\n\tvar x = xyz[0] / 100;\n\tvar y = xyz[1] / 100;\n\tvar z = xyz[2] / 100;\n\tvar r;\n\tvar g;\n\tvar b;\n\n\tr = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);\n\tg = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);\n\tb = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);\n\n\t// assume sRGB\n\tr = r > 0.0031308\n\t\t? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)\n\t\t: r * 12.92;\n\n\tg = g > 0.0031308\n\t\t? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)\n\t\t: g * 12.92;\n\n\tb = b > 0.0031308\n\t\t? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)\n\t\t: b * 12.92;\n\n\tr = Math.min(Math.max(0, r), 1);\n\tg = Math.min(Math.max(0, g), 1);\n\tb = Math.min(Math.max(0, b), 1);\n\n\treturn [r * 255, g * 255, b * 255];\n};\n\nconvert.xyz.lab = function (xyz) {\n\tvar x = xyz[0];\n\tvar y = xyz[1];\n\tvar z = xyz[2];\n\tvar l;\n\tvar a;\n\tvar b;\n\n\tx /= 95.047;\n\ty /= 100;\n\tz /= 108.883;\n\n\tx = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116);\n\ty = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116);\n\tz = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116);\n\n\tl = (116 * y) - 16;\n\ta = 500 * (x - y);\n\tb = 200 * (y - z);\n\n\treturn [l, a, b];\n};\n\nconvert.lab.xyz = function (lab) {\n\tvar l = lab[0];\n\tvar a = lab[1];\n\tvar b = lab[2];\n\tvar x;\n\tvar y;\n\tvar z;\n\n\ty = (l + 16) / 116;\n\tx = a / 500 + y;\n\tz = y - b / 200;\n\n\tvar y2 = Math.pow(y, 3);\n\tvar x2 = Math.pow(x, 3);\n\tvar z2 = Math.pow(z, 3);\n\ty = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787;\n\tx = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787;\n\tz = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787;\n\n\tx *= 95.047;\n\ty *= 100;\n\tz *= 108.883;\n\n\treturn [x, y, z];\n};\n\nconvert.lab.lch = function (lab) {\n\tvar l = lab[0];\n\tvar a = lab[1];\n\tvar b = lab[2];\n\tvar hr;\n\tvar h;\n\tvar c;\n\n\thr = Math.atan2(b, a);\n\th = hr * 360 / 2 / Math.PI;\n\n\tif (h < 0) {\n\t\th += 360;\n\t}\n\n\tc = Math.sqrt(a * a + b * b);\n\n\treturn [l, c, h];\n};\n\nconvert.lch.lab = function (lch) {\n\tvar l = lch[0];\n\tvar c = lch[1];\n\tvar h = lch[2];\n\tvar a;\n\tvar b;\n\tvar hr;\n\n\thr = h / 360 * 2 * Math.PI;\n\ta = c * Math.cos(hr);\n\tb = c * Math.sin(hr);\n\n\treturn [l, a, b];\n};\n\nconvert.rgb.ansi16 = function (args) {\n\tvar r = args[0];\n\tvar g = args[1];\n\tvar b = args[2];\n\tvar value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization\n\n\tvalue = Math.round(value / 50);\n\n\tif (value === 0) {\n\t\treturn 30;\n\t}\n\n\tvar ansi = 30\n\t\t+ ((Math.round(b / 255) << 2)\n\t\t| (Math.round(g / 255) << 1)\n\t\t| Math.round(r / 255));\n\n\tif (value === 2) {\n\t\tansi += 60;\n\t}\n\n\treturn ansi;\n};\n\nconvert.hsv.ansi16 = function (args) {\n\t// optimization here; we already know the value and don't need to get\n\t// it converted for us.\n\treturn convert.rgb.ansi16(convert.hsv.rgb(args), args[2]);\n};\n\nconvert.rgb.ansi256 = function (args) {\n\tvar r = args[0];\n\tvar g = args[1];\n\tvar b = args[2];\n\n\t// we use the extended greyscale palette here, with the exception of\n\t// black and white. normal palette only has 4 greyscale shades.\n\tif (r === g && g === b) {\n\t\tif (r < 8) {\n\t\t\treturn 16;\n\t\t}\n\n\t\tif (r > 248) {\n\t\t\treturn 231;\n\t\t}\n\n\t\treturn Math.round(((r - 8) / 247) * 24) + 232;\n\t}\n\n\tvar ansi = 16\n\t\t+ (36 * Math.round(r / 255 * 5))\n\t\t+ (6 * Math.round(g / 255 * 5))\n\t\t+ Math.round(b / 255 * 5);\n\n\treturn ansi;\n};\n\nconvert.ansi16.rgb = function (args) {\n\tvar color = args % 10;\n\n\t// handle greyscale\n\tif (color === 0 || color === 7) {\n\t\tif (args > 50) {\n\t\t\tcolor += 3.5;\n\t\t}\n\n\t\tcolor = color / 10.5 * 255;\n\n\t\treturn [color, color, color];\n\t}\n\n\tvar mult = (~~(args > 50) + 1) * 0.5;\n\tvar r = ((color & 1) * mult) * 255;\n\tvar g = (((color >> 1) & 1) * mult) * 255;\n\tvar b = (((color >> 2) & 1) * mult) * 255;\n\n\treturn [r, g, b];\n};\n\nconvert.ansi256.rgb = function (args) {\n\t// handle greyscale\n\tif (args >= 232) {\n\t\tvar c = (args - 232) * 10 + 8;\n\t\treturn [c, c, c];\n\t}\n\n\targs -= 16;\n\n\tvar rem;\n\tvar r = Math.floor(args / 36) / 5 * 255;\n\tvar g = Math.floor((rem = args % 36) / 6) / 5 * 255;\n\tvar b = (rem % 6) / 5 * 255;\n\n\treturn [r, g, b];\n};\n\nconvert.rgb.hex = function (args) {\n\tvar integer = ((Math.round(args[0]) & 0xFF) << 16)\n\t\t+ ((Math.round(args[1]) & 0xFF) << 8)\n\t\t+ (Math.round(args[2]) & 0xFF);\n\n\tvar string = integer.toString(16).toUpperCase();\n\treturn '000000'.substring(string.length) + string;\n};\n\nconvert.hex.rgb = function (args) {\n\tvar match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);\n\tif (!match) {\n\t\treturn [0, 0, 0];\n\t}\n\n\tvar colorString = match[0];\n\n\tif (match[0].length === 3) {\n\t\tcolorString = colorString.split('').map(function (char) {\n\t\t\treturn char + char;\n\t\t}).join('');\n\t}\n\n\tvar integer = parseInt(colorString, 16);\n\tvar r = (integer >> 16) & 0xFF;\n\tvar g = (integer >> 8) & 0xFF;\n\tvar b = integer & 0xFF;\n\n\treturn [r, g, b];\n};\n\nconvert.rgb.hcg = function (rgb) {\n\tvar r = rgb[0] / 255;\n\tvar g = rgb[1] / 255;\n\tvar b = rgb[2] / 255;\n\tvar max = Math.max(Math.max(r, g), b);\n\tvar min = Math.min(Math.min(r, g), b);\n\tvar chroma = (max - min);\n\tvar grayscale;\n\tvar hue;\n\n\tif (chroma < 1) {\n\t\tgrayscale = min / (1 - chroma);\n\t} else {\n\t\tgrayscale = 0;\n\t}\n\n\tif (chroma <= 0) {\n\t\thue = 0;\n\t} else\n\tif (max === r) {\n\t\thue = ((g - b) / chroma) % 6;\n\t} else\n\tif (max === g) {\n\t\thue = 2 + (b - r) / chroma;\n\t} else {\n\t\thue = 4 + (r - g) / chroma + 4;\n\t}\n\n\thue /= 6;\n\thue %= 1;\n\n\treturn [hue * 360, chroma * 100, grayscale * 100];\n};\n\nconvert.hsl.hcg = function (hsl) {\n\tvar s = hsl[1] / 100;\n\tvar l = hsl[2] / 100;\n\tvar c = 1;\n\tvar f = 0;\n\n\tif (l < 0.5) {\n\t\tc = 2.0 * s * l;\n\t} else {\n\t\tc = 2.0 * s * (1.0 - l);\n\t}\n\n\tif (c < 1.0) {\n\t\tf = (l - 0.5 * c) / (1.0 - c);\n\t}\n\n\treturn [hsl[0], c * 100, f * 100];\n};\n\nconvert.hsv.hcg = function (hsv) {\n\tvar s = hsv[1] / 100;\n\tvar v = hsv[2] / 100;\n\n\tvar c = s * v;\n\tvar f = 0;\n\n\tif (c < 1.0) {\n\t\tf = (v - c) / (1 - c);\n\t}\n\n\treturn [hsv[0], c * 100, f * 100];\n};\n\nconvert.hcg.rgb = function (hcg) {\n\tvar h = hcg[0] / 360;\n\tvar c = hcg[1] / 100;\n\tvar g = hcg[2] / 100;\n\n\tif (c === 0.0) {\n\t\treturn [g * 255, g * 255, g * 255];\n\t}\n\n\tvar pure = [0, 0, 0];\n\tvar hi = (h % 1) * 6;\n\tvar v = hi % 1;\n\tvar w = 1 - v;\n\tvar mg = 0;\n\n\tswitch (Math.floor(hi)) {\n\t\tcase 0:\n\t\t\tpure[0] = 1; pure[1] = v; pure[2] = 0; break;\n\t\tcase 1:\n\t\t\tpure[0] = w; pure[1] = 1; pure[2] = 0; break;\n\t\tcase 2:\n\t\t\tpure[0] = 0; pure[1] = 1; pure[2] = v; break;\n\t\tcase 3:\n\t\t\tpure[0] = 0; pure[1] = w; pure[2] = 1; break;\n\t\tcase 4:\n\t\t\tpure[0] = v; pure[1] = 0; pure[2] = 1; break;\n\t\tdefault:\n\t\t\tpure[0] = 1; pure[1] = 0; pure[2] = w;\n\t}\n\n\tmg = (1.0 - c) * g;\n\n\treturn [\n\t\t(c * pure[0] + mg) * 255,\n\t\t(c * pure[1] + mg) * 255,\n\t\t(c * pure[2] + mg) * 255\n\t];\n};\n\nconvert.hcg.hsv = function (hcg) {\n\tvar c = hcg[1] / 100;\n\tvar g = hcg[2] / 100;\n\n\tvar v = c + g * (1.0 - c);\n\tvar f = 0;\n\n\tif (v > 0.0) {\n\t\tf = c / v;\n\t}\n\n\treturn [hcg[0], f * 100, v * 100];\n};\n\nconvert.hcg.hsl = function (hcg) {\n\tvar c = hcg[1] / 100;\n\tvar g = hcg[2] / 100;\n\n\tvar l = g * (1.0 - c) + 0.5 * c;\n\tvar s = 0;\n\n\tif (l > 0.0 && l < 0.5) {\n\t\ts = c / (2 * l);\n\t} else\n\tif (l >= 0.5 && l < 1.0) {\n\t\ts = c / (2 * (1 - l));\n\t}\n\n\treturn [hcg[0], s * 100, l * 100];\n};\n\nconvert.hcg.hwb = function (hcg) {\n\tvar c = hcg[1] / 100;\n\tvar g = hcg[2] / 100;\n\tvar v = c + g * (1.0 - c);\n\treturn [hcg[0], (v - c) * 100, (1 - v) * 100];\n};\n\nconvert.hwb.hcg = function (hwb) {\n\tvar w = hwb[1] / 100;\n\tvar b = hwb[2] / 100;\n\tvar v = 1 - b;\n\tvar c = v - w;\n\tvar g = 0;\n\n\tif (c < 1) {\n\t\tg = (v - c) / (1 - c);\n\t}\n\n\treturn [hwb[0], c * 100, g * 100];\n};\n\nconvert.apple.rgb = function (apple) {\n\treturn [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255];\n};\n\nconvert.rgb.apple = function (rgb) {\n\treturn [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535];\n};\n\nconvert.gray.rgb = function (args) {\n\treturn [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255];\n};\n\nconvert.gray.hsl = convert.gray.hsv = function (args) {\n\treturn [0, 0, args[0]];\n};\n\nconvert.gray.hwb = function (gray) {\n\treturn [0, 100, gray[0]];\n};\n\nconvert.gray.cmyk = function (gray) {\n\treturn [0, 0, 0, gray[0]];\n};\n\nconvert.gray.lab = function (gray) {\n\treturn [gray[0], 0, 0];\n};\n\nconvert.gray.hex = function (gray) {\n\tvar val = Math.round(gray[0] / 100 * 255) & 0xFF;\n\tvar integer = (val << 16) + (val << 8) + val;\n\n\tvar string = integer.toString(16).toUpperCase();\n\treturn '000000'.substring(string.length) + string;\n};\n\nconvert.rgb.gray = function (rgb) {\n\tvar val = (rgb[0] + rgb[1] + rgb[2]) / 3;\n\treturn [val / 255 * 100];\n};\n","/**\n*\n* jquery.sparkline.js\n*\n* v2.4.1\n* (c) Splunk, Inc\n* Contact: Gareth Watts (gareth@splunk.com)\n* http://omnipotent.net/jquery.sparkline/\n*\n* Generates inline sparkline charts from data supplied either to the method\n* or inline in HTML\n*\n* Compatible with Internet Explorer 6.0+ and modern browsers equipped with the canvas tag\n* (Firefox 2.0+, Safari, Opera, etc)\n*\n* License: New BSD License\n*\n* Copyright (c) 2012, Splunk Inc.\n* All rights reserved.\n*\n* Redistribution and use in source and binary forms, with or without modification,\n* are permitted provided that the following conditions are met:\n*\n* * Redistributions of source code must retain the above copyright notice,\n* this list of conditions and the following disclaimer.\n* * Redistributions in binary form must reproduce the above copyright notice,\n* this list of conditions and the following disclaimer in the documentation\n* and/or other materials provided with the distribution.\n* * Neither the name of Splunk Inc nor the names of its contributors may\n* be used to endorse or promote products derived from this software without\n* specific prior written permission.\n*\n* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n* SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\n* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*\n*\n* Usage:\n* $(selector).sparkline(values, options)\n*\n* If values is undefined or set to 'html' then the data values are read from the specified tag:\n*

Sparkline: 1,4,6,6,8,5,3,5

\n* $('.sparkline').sparkline();\n* There must be no spaces in the enclosed data set\n*\n* Otherwise values must be an array of numbers or null values\n*

Sparkline: This text replaced if the browser is compatible

\n* $('#sparkline1').sparkline([1,4,6,6,8,5,3,5])\n* $('#sparkline2').sparkline([1,4,6,null,null,5,3,5])\n*\n* Values can also be specified in an HTML comment, or as a values attribute:\n*

Sparkline:

\n*

Sparkline:

\n* $('.sparkline').sparkline();\n*\n* For line charts, x values can also be specified:\n*

Sparkline: 1:1,2.7:4,3.4:6,5:6,6:8,8.7:5,9:3,10:5

\n* $('#sparkline1').sparkline([ [1,1], [2.7,4], [3.4,6], [5,6], [6,8], [8.7,5], [9,3], [10,5] ])\n*\n* By default, options should be passed in as the second argument to the sparkline function:\n* $('.sparkline').sparkline([1,2,3,4], {type: 'bar'})\n*\n* Options can also be set by passing them on the tag itself. This feature is disabled by default though\n* as there's a slight performance overhead:\n* $('.sparkline').sparkline([1,2,3,4], {enableTagOptions: true})\n*

Sparkline: loading

\n* Prefix all options supplied as tag attribute with \"spark\" (configurable by setting tagOptionsPrefix)\n*\n* Supported options:\n* lineColor - Color of the line used for the chart\n* fillColor - Color used to fill in the chart - Set to '' or false for a transparent chart\n* width - Width of the chart - Defaults to 3 times the number of values in pixels\n* height - Height of the chart - Defaults to the height of the containing element\n* chartRangeMin - Specify the minimum value to use for the Y range of the chart - Defaults to the minimum value supplied\n* chartRangeMax - Specify the maximum value to use for the Y range of the chart - Defaults to the maximum value supplied\n* chartRangeClip - Clip out of range values to the max/min specified by chartRangeMin and chartRangeMax\n* chartRangeMinX - Specify the minimum value to use for the X range of the chart - Defaults to the minimum value supplied\n* chartRangeMaxX - Specify the maximum value to use for the X range of the chart - Defaults to the maximum value supplied\n* composite - If true then don't erase any existing chart attached to the tag, but draw\n* another chart over the top - Note that width and height are ignored if an\n* existing chart is detected.\n* tagValuesAttribute - Name of tag attribute to check for data values - Defaults to 'values'\n* enableTagOptions - Whether to check tags for sparkline options\n* tagOptionsPrefix - Prefix used for options supplied as tag attributes - Defaults to 'spark'\n* disableHiddenCheck - If set to true, then the plugin will assume that charts will never be drawn into a\n* hidden dom element, avoding a browser reflow\n* disableInteraction - If set to true then all mouseover/click interaction behaviour will be disabled,\n* making the plugin perform much like it did in 1.x\n* disableTooltips - If set to true then tooltips will be disabled - Defaults to false (tooltips enabled)\n* disableHighlight - If set to true then highlighting of selected chart elements on mouseover will be disabled\n* defaults to false (highlights enabled)\n* highlightLighten - Factor to lighten/darken highlighted chart values by - Defaults to 1.4 for a 40% increase\n* tooltipContainer - Specify which DOM element the tooltip should be rendered into - defaults to document.body\n* tooltipClassname - Optional CSS classname to apply to tooltips - If not specified then a default style will be applied\n* tooltipOffsetX - How many pixels away from the mouse pointer to render the tooltip on the X axis\n* tooltipOffsetY - How many pixels away from the mouse pointer to render the tooltip on the r axis\n* tooltipFormatter - Optional callback that allows you to override the HTML displayed in the tooltip\n* callback is given arguments of (sparkline, options, fields)\n* tooltipChartTitle - If specified then the tooltip uses the string specified by this setting as a title\n* tooltipFormat - A format string or SPFormat object (or an array thereof for multiple entries)\n* to control the format of the tooltip\n* tooltipPrefix - A string to prepend to each field displayed in a tooltip\n* tooltipSuffix - A string to append to each field displayed in a tooltip\n* tooltipSkipNull - If true then null values will not have a tooltip displayed (defaults to true)\n* tooltipValueLookups - An object or range map to map field values to tooltip strings\n* (eg. to map -1 to \"Lost\", 0 to \"Draw\", and 1 to \"Win\")\n* numberFormatter - Optional callback for formatting numbers in tooltips\n* numberDigitGroupSep - Character to use for group separator in numbers \"1,234\" - Defaults to \",\"\n* numberDecimalMark - Character to use for the decimal point when formatting numbers - Defaults to \".\"\n* numberDigitGroupCount - Number of digits between group separator - Defaults to 3\n*\n* There are 7 types of sparkline, selected by supplying a \"type\" option of 'line' (default),\n* 'bar', 'tristate', 'bullet', 'discrete', 'pie' or 'box'\n* line - Line chart. Options:\n* spotColor - Set to '' to not end each line in a circular spot\n* minSpotColor - If set, color of spot at minimum value\n* maxSpotColor - If set, color of spot at maximum value\n* spotRadius - Radius in pixels\n* lineWidth - Width of line in pixels\n* normalRangeMin\n* normalRangeMax - If set draws a filled horizontal bar between these two values marking the \"normal\"\n* or expected range of values\n* normalRangeColor - Color to use for the above bar\n* drawNormalOnTop - Draw the normal range above the chart fill color if true\n* defaultPixelsPerValue - Defaults to 3 pixels of width for each value in the chart\n* highlightSpotColor - The color to use for drawing a highlight spot on mouseover - Set to null to disable\n* highlightLineColor - The color to use for drawing a highlight line on mouseover - Set to null to disable\n* valueSpots - Specify which points to draw spots on, and in which color. Accepts a range map\n*\n* bar - Bar chart. Options:\n* barColor - Color of bars for postive values\n* negBarColor - Color of bars for negative values\n* zeroColor - Color of bars with zero values\n* nullColor - Color of bars with null values - Defaults to omitting the bar entirely\n* barWidth - Width of bars in pixels\n* colorMap - Optional mappnig of values to colors to override the *BarColor values above\n* can be an Array of values to control the color of individual bars or a range map\n* to specify colors for individual ranges of values\n* barSpacing - Gap between bars in pixels\n* zeroAxis - Centers the y-axis around zero if true\n*\n* tristate - Charts values of win (>0), lose (<0) or draw (=0)\n* posBarColor - Color of win values\n* negBarColor - Color of lose values\n* zeroBarColor - Color of draw values\n* barWidth - Width of bars in pixels\n* barSpacing - Gap between bars in pixels\n* colorMap - Optional mappnig of values to colors to override the *BarColor values above\n* can be an Array of values to control the color of individual bars or a range map\n* to specify colors for individual ranges of values\n*\n* discrete - Options:\n* lineHeight - Height of each line in pixels - Defaults to 30% of the graph height\n* thesholdValue - Values less than this value will be drawn using thresholdColor instead of lineColor\n* thresholdColor\n*\n* bullet - Values for bullet graphs msut be in the order: target, performance, range1, range2, range3, ...\n* options:\n* targetColor - The color of the vertical target marker\n* targetWidth - The width of the target marker in pixels\n* performanceColor - The color of the performance measure horizontal bar\n* rangeColors - Colors to use for each qualitative range background color\n*\n* pie - Pie chart. Options:\n* sliceColors - An array of colors to use for pie slices\n* offset - Angle in degrees to offset the first slice - Try -90 or +90\n* borderWidth - Width of border to draw around the pie chart, in pixels - Defaults to 0 (no border)\n* borderColor - Color to use for the pie chart border - Defaults to #000\n*\n* box - Box plot. Options:\n* raw - Set to true to supply pre-computed plot points as values\n* values should be: low_outlier, low_whisker, q1, median, q3, high_whisker, high_outlier\n* When set to false you can supply any number of values and the box plot will\n* be computed for you. Default is false.\n* showOutliers - Set to true (default) to display outliers as circles\n* outlierIQR - Interquartile range used to determine outliers. Default 1.5\n* boxLineColor - Outline color of the box\n* boxFillColor - Fill color for the box\n* whiskerColor - Line color used for whiskers\n* outlierLineColor - Outline color of outlier circles\n* outlierFillColor - Fill color of the outlier circles\n* spotRadius - Radius of outlier circles\n* medianColor - Line color of the median line\n* target - Draw a target cross hair at the supplied value (default undefined)\n*\n*\n*\n* Examples:\n* $('#sparkline1').sparkline(myvalues, { lineColor: '#f00', fillColor: false });\n* $('.barsparks').sparkline('html', { type:'bar', height:'40px', barWidth:5 });\n* $('#tristate').sparkline([1,1,-1,1,0,0,-1], { type:'tristate' }):\n* $('#discrete').sparkline([1,3,4,5,5,3,4,5], { type:'discrete' });\n* $('#bullet').sparkline([10,12,12,9,7], { type:'bullet' });\n* $('#pie').sparkline([1,1,2], { type:'pie' });\n*/\n\n/*jslint regexp: true, browser: true, jquery: true, white: true, nomen: false, plusplus: false, maxerr: 500, indent: 4 */\n\n(function(document, Math, undefined) { // performance/minified-size optimization\n(function(factory) {\n if(typeof define === 'function' && define.amd) {\n define(['jquery'], factory);\n } else if (jQuery && !jQuery.fn.sparkline) {\n factory(jQuery);\n }\n}\n(function($) {\n 'use strict';\n\n var UNSET_OPTION = {},\n getDefaults, createClass, SPFormat, clipval, quartile, normalizeValue, normalizeValues,\n remove, isNumber, all, sum, addCSS, ensureArray, formatNumber, RangeMap,\n MouseHandler, Tooltip, barHighlightMixin,\n line, bar, tristate, discrete, bullet, pie, box, defaultStyles, initStyles,\n VShape, VCanvas_base, VCanvas_canvas, VCanvas_vml, pending, shapeCount = 0;\n\n /**\n * Default configuration settings\n */\n getDefaults = function () {\n return {\n // Settings common to most/all chart types\n common: {\n type: 'line',\n lineColor: '#00f',\n fillColor: '#cdf',\n defaultPixelsPerValue: 3,\n width: 'auto',\n height: 'auto',\n composite: false,\n tagValuesAttribute: 'values',\n tagOptionsPrefix: 'spark',\n enableTagOptions: false,\n enableHighlight: true,\n highlightLighten: 1.4,\n tooltipSkipNull: true,\n tooltipPrefix: '',\n tooltipSuffix: '',\n disableHiddenCheck: false,\n numberFormatter: false,\n numberDigitGroupCount: 3,\n numberDigitGroupSep: ',',\n numberDecimalMark: '.',\n disableTooltips: false,\n disableInteraction: false\n },\n // Defaults for line charts\n line: {\n spotColor: '#f80',\n highlightSpotColor: '#5f5',\n highlightLineColor: '#f22',\n spotRadius: 1.5,\n minSpotColor: '#f80',\n maxSpotColor: '#f80',\n lineWidth: 1,\n normalRangeMin: undefined,\n normalRangeMax: undefined,\n normalRangeColor: '#ccc',\n drawNormalOnTop: false,\n chartRangeMin: undefined,\n chartRangeMax: undefined,\n chartRangeMinX: undefined,\n chartRangeMaxX: undefined,\n tooltipFormat: new SPFormat(' {{prefix}}{{y}}{{suffix}}')\n },\n // Defaults for bar charts\n bar: {\n barColor: '#3366cc',\n negBarColor: '#f44',\n stackedBarColor: ['#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00',\n '#dd4477', '#0099c6', '#990099'],\n zeroColor: undefined,\n nullColor: undefined,\n zeroAxis: true,\n barWidth: 4,\n barSpacing: 1,\n chartRangeMax: undefined,\n chartRangeMin: undefined,\n chartRangeClip: false,\n colorMap: undefined,\n tooltipFormat: new SPFormat(' {{prefix}}{{value}}{{suffix}}')\n },\n // Defaults for tristate charts\n tristate: {\n barWidth: 4,\n barSpacing: 1,\n posBarColor: '#6f6',\n negBarColor: '#f44',\n zeroBarColor: '#999',\n colorMap: {},\n tooltipFormat: new SPFormat(' {{value:map}}'),\n tooltipValueLookups: { map: { '-1': 'Loss', '0': 'Draw', '1': 'Win' } }\n },\n // Defaults for discrete charts\n discrete: {\n lineHeight: 'auto',\n thresholdColor: undefined,\n thresholdValue: 0,\n chartRangeMax: undefined,\n chartRangeMin: undefined,\n chartRangeClip: false,\n tooltipFormat: new SPFormat('{{prefix}}{{value}}{{suffix}}')\n },\n // Defaults for bullet charts\n bullet: {\n targetColor: '#f33',\n targetWidth: 3, // width of the target bar in pixels\n performanceColor: '#33f',\n rangeColors: ['#d3dafe', '#a8b6ff', '#7f94ff'],\n base: undefined, // set this to a number to change the base start number\n tooltipFormat: new SPFormat('{{fieldkey:fields}} - {{value}}'),\n tooltipValueLookups: { fields: {r: 'Range', p: 'Performance', t: 'Target'} }\n },\n // Defaults for pie charts\n pie: {\n offset: 0,\n sliceColors: ['#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00',\n '#dd4477', '#0099c6', '#990099'],\n borderWidth: 0,\n borderColor: '#000',\n tooltipFormat: new SPFormat(' {{value}} ({{percent.1}}%)')\n },\n // Defaults for box plots\n box: {\n raw: false,\n boxLineColor: '#000',\n boxFillColor: '#cdf',\n whiskerColor: '#000',\n outlierLineColor: '#333',\n outlierFillColor: '#fff',\n medianColor: '#f00',\n showOutliers: true,\n outlierIQR: 1.5,\n spotRadius: 1.5,\n target: undefined,\n targetColor: '#4a2',\n chartRangeMax: undefined,\n chartRangeMin: undefined,\n tooltipFormat: new SPFormat('{{field:fields}}: {{value}}'),\n tooltipFormatFieldlistKey: 'field',\n tooltipValueLookups: { fields: { lq: 'Lower Quartile', med: 'Median',\n uq: 'Upper Quartile', lo: 'Left Outlier', ro: 'Right Outlier',\n lw: 'Left Whisker', rw: 'Right Whisker'} }\n }\n };\n };\n\n // You can have tooltips use a css class other than jqstooltip by specifying tooltipClassname\n defaultStyles = '.jqstooltip { ' +\n 'position: absolute;' +\n 'left: 0px;' +\n 'top: 0px;' +\n 'visibility: hidden;' +\n 'background: rgb(0, 0, 0) transparent;' +\n 'background-color: rgba(0,0,0,0.6);' +\n 'filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000);' +\n '-ms-filter: \"progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000)\";' +\n 'color: white;' +\n 'font: 10px arial, san serif;' +\n 'text-align: left;' +\n 'white-space: nowrap;' +\n 'padding: 5px;' +\n 'border: 1px solid white;' +\n 'box-sizing: content-box;' +\n 'z-index: 10000;' +\n '}' +\n '.jqsfield { ' +\n 'color: white;' +\n 'font: 10px arial, san serif;' +\n 'text-align: left;' +\n '}';\n\n /**\n * Utilities\n */\n\n createClass = function (/* [baseclass, [mixin, ...]], definition */) {\n var Class, args;\n Class = function () {\n this.init.apply(this, arguments);\n };\n if (arguments.length > 1) {\n if (arguments[0]) {\n Class.prototype = $.extend(new arguments[0](), arguments[arguments.length - 1]);\n Class._super = arguments[0].prototype;\n } else {\n Class.prototype = arguments[arguments.length - 1];\n }\n if (arguments.length > 2) {\n args = Array.prototype.slice.call(arguments, 1, -1);\n args.unshift(Class.prototype);\n $.extend.apply($, args);\n }\n } else {\n Class.prototype = arguments[0];\n }\n Class.prototype.cls = Class;\n return Class;\n };\n\n /**\n * Wraps a format string for tooltips\n * {{x}}\n * {{x.2}\n * {{x:months}}\n */\n $.SPFormatClass = SPFormat = createClass({\n fre: /\\{\\{([\\w.]+?)(:(.+?))?\\}\\}/g,\n precre: /(\\w+)\\.(\\d+)/,\n\n init: function (format, fclass) {\n this.format = format;\n this.fclass = fclass;\n },\n\n render: function (fieldset, lookups, options) {\n var self = this,\n fields = fieldset,\n match, token, lookupkey, fieldvalue, prec;\n return this.format.replace(this.fre, function () {\n var lookup;\n token = arguments[1];\n lookupkey = arguments[3];\n match = self.precre.exec(token);\n if (match) {\n prec = match[2];\n token = match[1];\n } else {\n prec = false;\n }\n fieldvalue = fields[token];\n if (fieldvalue === undefined) {\n return '';\n }\n if (lookupkey && lookups && lookups[lookupkey]) {\n lookup = lookups[lookupkey];\n if (lookup.get) { // RangeMap\n return lookups[lookupkey].get(fieldvalue) || fieldvalue;\n } else {\n return lookups[lookupkey][fieldvalue] || fieldvalue;\n }\n }\n if (isNumber(fieldvalue)) {\n if (options.get('numberFormatter')) {\n fieldvalue = options.get('numberFormatter')(fieldvalue);\n } else {\n fieldvalue = formatNumber(fieldvalue, prec,\n options.get('numberDigitGroupCount'),\n options.get('numberDigitGroupSep'),\n options.get('numberDecimalMark'));\n }\n }\n return fieldvalue;\n });\n }\n });\n\n // convience method to avoid needing the new operator\n $.spformat = function(format, fclass) {\n return new SPFormat(format, fclass);\n };\n\n clipval = function (val, min, max) {\n if (val < min) {\n return min;\n }\n if (val > max) {\n return max;\n }\n return val;\n };\n\n quartile = function (values, q) {\n var vl;\n if (q === 2) {\n vl = Math.floor(values.length / 2);\n return values.length % 2 ? values[vl] : (values[vl-1] + values[vl]) / 2;\n } else {\n if (values.length % 2 ) { // odd\n vl = (values.length * q + q) / 4;\n return vl % 1 ? (values[Math.floor(vl)] + values[Math.floor(vl) - 1]) / 2 : values[vl-1];\n } else { //even\n vl = (values.length * q + 2) / 4;\n return vl % 1 ? (values[Math.floor(vl)] + values[Math.floor(vl) - 1]) / 2 : values[vl-1];\n\n }\n }\n };\n\n normalizeValue = function (val) {\n var nf;\n switch (val) {\n case 'undefined':\n val = undefined;\n break;\n case 'null':\n val = null;\n break;\n case 'true':\n val = true;\n break;\n case 'false':\n val = false;\n break;\n default:\n nf = parseFloat(val);\n if (val == nf) {\n val = nf;\n }\n }\n return val;\n };\n\n normalizeValues = function (vals) {\n var i, result = [];\n for (i = vals.length; i--;) {\n result[i] = normalizeValue(vals[i]);\n }\n return result;\n };\n\n remove = function (vals, filter) {\n var i, vl, result = [];\n for (i = 0, vl = vals.length; i < vl; i++) {\n if (vals[i] !== filter) {\n result.push(vals[i]);\n }\n }\n return result;\n };\n\n isNumber = function (num) {\n return !isNaN(parseFloat(num)) && isFinite(num);\n };\n\n formatNumber = function (num, prec, groupsize, groupsep, decsep) {\n var p, i;\n num = (prec === false ? parseFloat(num).toString() : num.toFixed(prec)).split('');\n p = (p = $.inArray('.', num)) < 0 ? num.length : p;\n if (p < num.length) {\n num[p] = decsep;\n }\n for (i = p - groupsize; i > 0; i -= groupsize) {\n num.splice(i, 0, groupsep);\n }\n return num.join('');\n };\n\n // determine if all values of an array match a value\n // returns true if the array is empty\n all = function (val, arr, ignoreNull) {\n var i;\n for (i = arr.length; i--; ) {\n if (ignoreNull && arr[i] === null) continue;\n if (arr[i] !== val) {\n return false;\n }\n }\n return true;\n };\n\n // sums the numeric values in an array, ignoring other values\n sum = function (vals) {\n var total = 0, i;\n for (i = vals.length; i--;) {\n total += typeof vals[i] === 'number' ? vals[i] : 0;\n }\n return total;\n };\n\n ensureArray = function (val) {\n return $.isArray(val) ? val : [val];\n };\n\n // http://paulirish.com/2008/bookmarklet-inject-new-css-rules/\n addCSS = function(css) {\n var tag, iefail;\n if (document.createStyleSheet) {\n try {\n document.createStyleSheet().cssText = css;\n return;\n } catch (e) {\n // IE <= 9 maxes out at 31 stylesheets; inject into page instead.\n iefail = true;\n }\n }\n tag = document.createElement('style');\n tag.type = 'text/css';\n document.getElementsByTagName('head')[0].appendChild(tag);\n if (iefail) {\n document.styleSheets[document.styleSheets.length - 1].cssText = css;\n } else {\n tag[(typeof document.body.style.WebkitAppearance == 'string') /* webkit only */ ? 'innerText' : 'innerHTML'] = css;\n }\n };\n\n // Provide a cross-browser interface to a few simple drawing primitives\n $.fn.simpledraw = function (width, height, useExisting, interact) {\n var target, mhandler;\n if (useExisting && (target = this.data('_jqs_vcanvas'))) {\n return target;\n }\n\n if ($.fn.sparkline.canvas === false) {\n // We've already determined that neither Canvas nor VML are available\n return false;\n\n } else if ($.fn.sparkline.canvas === undefined) {\n // No function defined yet -- need to see if we support Canvas or VML\n var el = document.createElement('canvas');\n if (!!(el.getContext && el.getContext('2d'))) {\n // Canvas is available\n $.fn.sparkline.canvas = function(width, height, target, interact) {\n return new VCanvas_canvas(width, height, target, interact);\n };\n } else if (document.namespaces && !document.namespaces.v) {\n // VML is available\n document.namespaces.add('v', 'urn:schemas-microsoft-com:vml', '#default#VML');\n $.fn.sparkline.canvas = function(width, height, target, interact) {\n return new VCanvas_vml(width, height, target);\n };\n } else {\n // Neither Canvas nor VML are available\n $.fn.sparkline.canvas = false;\n return false;\n }\n }\n\n if (width === undefined) {\n width = $(this).innerWidth();\n }\n if (height === undefined) {\n height = $(this).innerHeight();\n }\n\n target = $.fn.sparkline.canvas(width, height, this, interact);\n\n mhandler = $(this).data('_jqs_mhandler');\n if (mhandler) {\n mhandler.registerCanvas(target);\n }\n return target;\n };\n\n $.fn.cleardraw = function () {\n var target = this.data('_jqs_vcanvas');\n if (target) {\n target.reset();\n }\n };\n\n $.RangeMapClass = RangeMap = createClass({\n init: function (map) {\n var key, range, rangelist = [];\n for (key in map) {\n if (map.hasOwnProperty(key) && typeof key === 'string' && key.indexOf(':') > -1) {\n range = key.split(':');\n range[0] = range[0].length === 0 ? -Infinity : parseFloat(range[0]);\n range[1] = range[1].length === 0 ? Infinity : parseFloat(range[1]);\n range[2] = map[key];\n rangelist.push(range);\n }\n }\n this.map = map;\n this.rangelist = rangelist || false;\n },\n\n get: function (value) {\n var rangelist = this.rangelist,\n i, range, result;\n if ((result = this.map[value]) !== undefined) {\n return result;\n }\n if (rangelist) {\n for (i = rangelist.length; i--;) {\n range = rangelist[i];\n if (range[0] <= value && range[1] >= value) {\n return range[2];\n }\n }\n }\n return undefined;\n }\n });\n\n // Convenience function\n $.range_map = function(map) {\n return new RangeMap(map);\n };\n\n MouseHandler = createClass({\n init: function (el, options) {\n var $el = $(el);\n this.$el = $el;\n this.options = options;\n this.currentPageX = 0;\n this.currentPageY = 0;\n this.el = el;\n this.splist = [];\n this.tooltip = null;\n this.over = false;\n this.displayTooltips = !options.get('disableTooltips');\n this.highlightEnabled = !options.get('disableHighlight');\n },\n\n registerSparkline: function (sp) {\n this.splist.push(sp);\n if (this.over) {\n this.updateDisplay();\n }\n },\n\n registerCanvas: function (canvas) {\n var $canvas = $(canvas.canvas);\n this.canvas = canvas;\n this.$canvas = $canvas;\n $canvas.mouseenter($.proxy(this.mouseenter, this));\n $canvas.mouseleave($.proxy(this.mouseleave, this));\n $canvas.click($.proxy(this.mouseclick, this));\n },\n\n reset: function (removeTooltip) {\n this.splist = [];\n if (this.tooltip && removeTooltip) {\n this.tooltip.remove();\n this.tooltip = undefined;\n }\n },\n\n mouseclick: function (e) {\n var clickEvent = $.Event('sparklineClick');\n clickEvent.originalEvent = e;\n clickEvent.sparklines = this.splist;\n this.$el.trigger(clickEvent);\n },\n\n mouseenter: function (e) {\n $(document.body).unbind('mousemove.jqs');\n $(document.body).bind('mousemove.jqs', $.proxy(this.mousemove, this));\n this.over = true;\n this.currentPageX = e.pageX;\n this.currentPageY = e.pageY;\n this.currentEl = e.target;\n if (!this.tooltip && this.displayTooltips) {\n this.tooltip = new Tooltip(this.options);\n this.tooltip.updatePosition(e.pageX, e.pageY);\n }\n this.updateDisplay();\n },\n\n mouseleave: function () {\n $(document.body).unbind('mousemove.jqs');\n var splist = this.splist,\n spcount = splist.length,\n needsRefresh = false,\n sp, i;\n this.over = false;\n this.currentEl = null;\n\n if (this.tooltip) {\n this.tooltip.remove();\n this.tooltip = null;\n }\n\n for (i = 0; i < spcount; i++) {\n sp = splist[i];\n if (sp.clearRegionHighlight()) {\n needsRefresh = true;\n }\n }\n\n if (needsRefresh) {\n this.canvas.render();\n }\n },\n\n mousemove: function (e) {\n this.currentPageX = e.pageX;\n this.currentPageY = e.pageY;\n this.currentEl = e.target;\n if (this.tooltip) {\n this.tooltip.updatePosition(e.pageX, e.pageY);\n }\n this.updateDisplay();\n },\n\n updateDisplay: function () {\n var splist = this.splist,\n spcount = splist.length,\n needsRefresh = false,\n offset = this.$canvas.offset(),\n localX = this.currentPageX - offset.left,\n localY = this.currentPageY - offset.top,\n tooltiphtml, sp, i, result, changeEvent;\n if (!this.over) {\n return;\n }\n for (i = 0; i < spcount; i++) {\n sp = splist[i];\n result = sp.setRegionHighlight(this.currentEl, localX, localY);\n if (result) {\n needsRefresh = true;\n }\n }\n if (needsRefresh) {\n changeEvent = $.Event('sparklineRegionChange');\n changeEvent.sparklines = this.splist;\n this.$el.trigger(changeEvent);\n if (this.tooltip) {\n tooltiphtml = '';\n for (i = 0; i < spcount; i++) {\n sp = splist[i];\n tooltiphtml += sp.getCurrentRegionTooltip();\n }\n this.tooltip.setContent(tooltiphtml);\n }\n if (!this.disableHighlight) {\n this.canvas.render();\n }\n }\n if (result === null) {\n this.mouseleave();\n }\n }\n });\n\n\n Tooltip = createClass({\n sizeStyle: 'position: static !important;' +\n 'display: block !important;' +\n 'visibility: hidden !important;' +\n 'float: left !important;',\n\n init: function (options) {\n var tooltipClassname = options.get('tooltipClassname', 'jqstooltip'),\n sizetipStyle = this.sizeStyle,\n offset;\n this.container = options.get('tooltipContainer') || document.body;\n this.tooltipOffsetX = options.get('tooltipOffsetX', 10);\n this.tooltipOffsetY = options.get('tooltipOffsetY', 12);\n // remove any previous lingering tooltip\n $('#jqssizetip').remove();\n $('#jqstooltip').remove();\n this.sizetip = $('
', {\n id: 'jqssizetip',\n style: sizetipStyle,\n 'class': tooltipClassname\n });\n this.tooltip = $('
', {\n id: 'jqstooltip',\n 'class': tooltipClassname\n }).appendTo(this.container);\n // account for the container's location\n offset = this.tooltip.offset();\n this.offsetLeft = offset.left;\n this.offsetTop = offset.top;\n this.hidden = true;\n $(window).unbind('resize.jqs scroll.jqs');\n $(window).bind('resize.jqs scroll.jqs', $.proxy(this.updateWindowDims, this));\n this.updateWindowDims();\n },\n\n updateWindowDims: function () {\n this.scrollTop = $(window).scrollTop();\n this.scrollLeft = $(window).scrollLeft();\n this.scrollRight = this.scrollLeft + $(window).width();\n this.updatePosition();\n },\n\n getSize: function (content) {\n this.sizetip.html(content).appendTo(this.container);\n this.width = this.sizetip.width() + 1;\n this.height = this.sizetip.height();\n this.sizetip.remove();\n },\n\n setContent: function (content) {\n if (!content) {\n this.tooltip.css('visibility', 'hidden');\n this.hidden = true;\n return;\n }\n this.getSize(content);\n this.tooltip.html(content)\n .css({\n 'width': this.width,\n 'height': this.height,\n 'visibility': 'visible'\n });\n if (this.hidden) {\n this.hidden = false;\n this.updatePosition();\n }\n },\n\n updatePosition: function (x, y) {\n if (x === undefined) {\n if (this.mousex === undefined) {\n return;\n }\n x = this.mousex - this.offsetLeft;\n y = this.mousey - this.offsetTop;\n\n } else {\n this.mousex = x = x - this.offsetLeft;\n this.mousey = y = y - this.offsetTop;\n }\n if (!this.height || !this.width || this.hidden) {\n return;\n }\n\n y -= this.height + this.tooltipOffsetY;\n x += this.tooltipOffsetX;\n\n if (y < this.scrollTop) {\n y = this.scrollTop;\n }\n if (x < this.scrollLeft) {\n x = this.scrollLeft;\n } else if (x + this.width > this.scrollRight) {\n x = this.scrollRight - this.width;\n }\n\n this.tooltip.css({\n 'left': x,\n 'top': y\n });\n },\n\n remove: function () {\n this.tooltip.remove();\n this.sizetip.remove();\n this.sizetip = this.tooltip = undefined;\n $(window).unbind('resize.jqs scroll.jqs');\n }\n });\n\n initStyles = function() {\n addCSS(defaultStyles);\n };\n\n $(initStyles);\n\n pending = [];\n $.fn.sparkline = function (userValues, userOptions) {\n return this.each(function () {\n var options = new $.fn.sparkline.options(this, userOptions),\n $this = $(this),\n render, i;\n render = function () {\n var values, width, height, tmp, mhandler, sp, vals;\n if (userValues === 'html' || userValues === undefined) {\n vals = this.getAttribute(options.get('tagValuesAttribute'));\n if (vals === undefined || vals === null) {\n vals = $this.html();\n }\n values = vals.replace(/(^\\s*\\s*$)|\\s+/g, '').split(',');\n } else {\n values = userValues;\n }\n\n width = options.get('width') === 'auto' ? values.length * options.get('defaultPixelsPerValue') : options.get('width');\n if (options.get('height') === 'auto') {\n if (!options.get('composite') || !$.data(this, '_jqs_vcanvas')) {\n // must be a better way to get the line height\n tmp = document.createElement('span');\n tmp.innerHTML = 'a';\n $this.html(tmp);\n height = $(tmp).innerHeight() || $(tmp).height();\n $(tmp).remove();\n tmp = null;\n }\n } else {\n height = options.get('height');\n }\n\n if (!options.get('disableInteraction')) {\n mhandler = $.data(this, '_jqs_mhandler');\n if (!mhandler) {\n mhandler = new MouseHandler(this, options);\n $.data(this, '_jqs_mhandler', mhandler);\n } else if (!options.get('composite')) {\n mhandler.reset();\n }\n } else {\n mhandler = false;\n }\n\n if (options.get('composite') && !$.data(this, '_jqs_vcanvas')) {\n if (!$.data(this, '_jqs_errnotify')) {\n alert('Attempted to attach a composite sparkline to an element with no existing sparkline');\n $.data(this, '_jqs_errnotify', true);\n }\n return;\n }\n\n sp = new $.fn.sparkline[options.get('type')](this, values, options, width, height);\n\n sp.render();\n\n if (mhandler) {\n mhandler.registerSparkline(sp);\n }\n };\n if (($(this).html() && !options.get('disableHiddenCheck') && $(this).is(':hidden')) || !$(this).parents('body').length) {\n if (!options.get('composite') && $.data(this, '_jqs_pending')) {\n // remove any existing references to the element\n for (i = pending.length; i; i--) {\n if (pending[i - 1][0] == this) {\n pending.splice(i - 1, 1);\n }\n }\n }\n pending.push([this, render]);\n $.data(this, '_jqs_pending', true);\n } else {\n render.call(this);\n }\n });\n };\n\n $.fn.sparkline.defaults = getDefaults();\n\n\n $.sparkline_display_visible = function () {\n var el, i, pl;\n var done = [];\n for (i = 0, pl = pending.length; i < pl; i++) {\n el = pending[i][0];\n if ($(el).is(':visible') && !$(el).parents().is(':hidden')) {\n pending[i][1].call(el);\n $.data(pending[i][0], '_jqs_pending', false);\n done.push(i);\n } else if (!$(el).closest('html').length && !$.data(el, '_jqs_pending')) {\n // element has been inserted and removed from the DOM\n // If it was not yet inserted into the dom then the .data request\n // will return true.\n // removing from the dom causes the data to be removed.\n $.data(pending[i][0], '_jqs_pending', false);\n done.push(i);\n }\n }\n for (i = done.length; i; i--) {\n pending.splice(done[i - 1], 1);\n }\n };\n\n\n /**\n * User option handler\n */\n $.fn.sparkline.options = createClass({\n init: function (tag, userOptions) {\n var extendedOptions, defaults, base, tagOptionType;\n this.userOptions = userOptions = userOptions || {};\n this.tag = tag;\n this.tagValCache = {};\n defaults = $.fn.sparkline.defaults;\n base = defaults.common;\n this.tagOptionsPrefix = userOptions.enableTagOptions && (userOptions.tagOptionsPrefix || base.tagOptionsPrefix);\n\n tagOptionType = this.getTagSetting('type');\n if (tagOptionType === UNSET_OPTION) {\n extendedOptions = defaults[userOptions.type || base.type];\n } else {\n extendedOptions = defaults[tagOptionType];\n }\n this.mergedOptions = $.extend({}, base, extendedOptions, userOptions);\n },\n\n\n getTagSetting: function (key) {\n var prefix = this.tagOptionsPrefix,\n val, i, pairs, keyval;\n if (prefix === false || prefix === undefined) {\n return UNSET_OPTION;\n }\n if (this.tagValCache.hasOwnProperty(key)) {\n val = this.tagValCache.key;\n } else {\n val = this.tag.getAttribute(prefix + key);\n if (val === undefined || val === null) {\n val = UNSET_OPTION;\n } else if (val.substr(0, 1) === '[') {\n val = val.substr(1, val.length - 2).split(',');\n for (i = val.length; i--;) {\n val[i] = normalizeValue(val[i].replace(/(^\\s*)|(\\s*$)/g, ''));\n }\n } else if (val.substr(0, 1) === '{') {\n pairs = val.substr(1, val.length - 2).split(',');\n val = {};\n for (i = pairs.length; i--;) {\n keyval = pairs[i].split(':', 2);\n val[keyval[0].replace(/(^\\s*)|(\\s*$)/g, '')] = normalizeValue(keyval[1].replace(/(^\\s*)|(\\s*$)/g, ''));\n }\n } else {\n val = normalizeValue(val);\n }\n this.tagValCache.key = val;\n }\n return val;\n },\n\n get: function (key, defaultval) {\n var tagOption = this.getTagSetting(key),\n result;\n if (tagOption !== UNSET_OPTION) {\n return tagOption;\n }\n return (result = this.mergedOptions[key]) === undefined ? defaultval : result;\n }\n });\n\n\n $.fn.sparkline._base = createClass({\n disabled: false,\n\n init: function (el, values, options, width, height) {\n this.el = el;\n this.$el = $(el);\n this.values = values;\n this.options = options;\n this.width = width;\n this.height = height;\n this.currentRegion = undefined;\n },\n\n /**\n * Setup the canvas\n */\n initTarget: function () {\n var interactive = !this.options.get('disableInteraction');\n if (!(this.target = this.$el.simpledraw(this.width, this.height, this.options.get('composite'), interactive))) {\n this.disabled = true;\n } else {\n this.canvasWidth = this.target.pixelWidth;\n this.canvasHeight = this.target.pixelHeight;\n }\n },\n\n /**\n * Actually render the chart to the canvas\n */\n render: function () {\n if (this.disabled) {\n this.el.innerHTML = '';\n return false;\n }\n return true;\n },\n\n /**\n * Return a region id for a given x/y co-ordinate\n */\n getRegion: function (x, y) {\n },\n\n /**\n * Highlight an item based on the moused-over x,y co-ordinate\n */\n setRegionHighlight: function (el, x, y) {\n var currentRegion = this.currentRegion,\n highlightEnabled = !this.options.get('disableHighlight'),\n newRegion;\n if (x > this.canvasWidth || y > this.canvasHeight || x < 0 || y < 0) {\n return null;\n }\n newRegion = this.getRegion(el, x, y);\n if (currentRegion !== newRegion) {\n if (currentRegion !== undefined && highlightEnabled) {\n this.removeHighlight();\n }\n this.currentRegion = newRegion;\n if (newRegion !== undefined && highlightEnabled) {\n this.renderHighlight();\n }\n return true;\n }\n return false;\n },\n\n /**\n * Reset any currently highlighted item\n */\n clearRegionHighlight: function () {\n if (this.currentRegion !== undefined) {\n this.removeHighlight();\n this.currentRegion = undefined;\n return true;\n }\n return false;\n },\n\n renderHighlight: function () {\n this.changeHighlight(true);\n },\n\n removeHighlight: function () {\n this.changeHighlight(false);\n },\n\n changeHighlight: function (highlight) {},\n\n /**\n * Fetch the HTML to display as a tooltip\n */\n getCurrentRegionTooltip: function () {\n var options = this.options,\n header = '',\n entries = [],\n fields, formats, formatlen, fclass, text, i,\n showFields, showFieldsKey, newFields, fv,\n formatter, format, fieldlen, j;\n if (this.currentRegion === undefined) {\n return '';\n }\n fields = this.getCurrentRegionFields();\n formatter = options.get('tooltipFormatter');\n if (formatter) {\n return formatter(this, options, fields);\n }\n if (options.get('tooltipChartTitle')) {\n header += '
' + options.get('tooltipChartTitle') + '
\\n';\n }\n formats = this.options.get('tooltipFormat');\n if (!formats) {\n return '';\n }\n if (!$.isArray(formats)) {\n formats = [formats];\n }\n if (!$.isArray(fields)) {\n fields = [fields];\n }\n showFields = this.options.get('tooltipFormatFieldlist');\n showFieldsKey = this.options.get('tooltipFormatFieldlistKey');\n if (showFields && showFieldsKey) {\n // user-selected ordering of fields\n newFields = [];\n for (i = fields.length; i--;) {\n fv = fields[i][showFieldsKey];\n if ((j = $.inArray(fv, showFields)) != -1) {\n newFields[j] = fields[i];\n }\n }\n fields = newFields;\n }\n formatlen = formats.length;\n fieldlen = fields.length;\n for (i = 0; i < formatlen; i++) {\n format = formats[i];\n if (typeof format === 'string') {\n format = new SPFormat(format);\n }\n fclass = format.fclass || 'jqsfield';\n for (j = 0; j < fieldlen; j++) {\n if (!fields[j].isNull || !options.get('tooltipSkipNull')) {\n $.extend(fields[j], {\n prefix: options.get('tooltipPrefix'),\n suffix: options.get('tooltipSuffix')\n });\n text = format.render(fields[j], options.get('tooltipValueLookups'), options);\n entries.push('
' + text + '
');\n }\n }\n }\n if (entries.length) {\n return header + entries.join('\\n');\n }\n return '';\n },\n\n getCurrentRegionFields: function () {},\n\n calcHighlightColor: function (color, options) {\n var highlightColor = options.get('highlightColor'),\n lighten = options.get('highlightLighten'),\n parse, mult, rgbnew, i;\n if (highlightColor) {\n return highlightColor;\n }\n if (lighten) {\n // extract RGB values\n parse = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(color) || /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(color);\n if (parse) {\n rgbnew = [];\n mult = color.length === 4 ? 16 : 1;\n for (i = 0; i < 3; i++) {\n rgbnew[i] = clipval(Math.round(parseInt(parse[i + 1], 16) * mult * lighten), 0, 255);\n }\n return 'rgb(' + rgbnew.join(',') + ')';\n }\n\n }\n return color;\n }\n\n });\n\n barHighlightMixin = {\n changeHighlight: function (highlight) {\n var currentRegion = this.currentRegion,\n target = this.target,\n shapeids = this.regionShapes[currentRegion],\n newShapes;\n // will be null if the region value was null\n if (shapeids) {\n newShapes = this.renderRegion(currentRegion, highlight);\n if ($.isArray(newShapes) || $.isArray(shapeids)) {\n target.replaceWithShapes(shapeids, newShapes);\n this.regionShapes[currentRegion] = $.map(newShapes, function (newShape) {\n return newShape.id;\n });\n } else {\n target.replaceWithShape(shapeids, newShapes);\n this.regionShapes[currentRegion] = newShapes.id;\n }\n }\n },\n\n render: function () {\n var values = this.values,\n target = this.target,\n regionShapes = this.regionShapes,\n shapes, ids, i, j;\n\n if (!this.cls._super.render.call(this)) {\n return;\n }\n for (i = values.length; i--;) {\n shapes = this.renderRegion(i);\n if (shapes) {\n if ($.isArray(shapes)) {\n ids = [];\n for (j = shapes.length; j--;) {\n shapes[j].append();\n ids.push(shapes[j].id);\n }\n regionShapes[i] = ids;\n } else {\n shapes.append();\n regionShapes[i] = shapes.id; // store just the shapeid\n }\n } else {\n // null value\n regionShapes[i] = null;\n }\n }\n target.render();\n }\n };\n\n /**\n * Line charts\n */\n $.fn.sparkline.line = line = createClass($.fn.sparkline._base, {\n type: 'line',\n\n init: function (el, values, options, width, height) {\n line._super.init.call(this, el, values, options, width, height);\n this.vertices = [];\n this.regionMap = [];\n this.xvalues = [];\n this.yvalues = [];\n this.yminmax = [];\n this.hightlightSpotId = null;\n this.lastShapeId = null;\n this.initTarget();\n },\n\n getRegion: function (el, x, y) {\n var i,\n regionMap = this.regionMap; // maps regions to value positions\n for (i = regionMap.length; i--;) {\n if (regionMap[i] !== null && x >= regionMap[i][0] && x <= regionMap[i][1]) {\n return regionMap[i][2];\n }\n }\n return undefined;\n },\n\n getCurrentRegionFields: function () {\n var currentRegion = this.currentRegion;\n return {\n isNull: this.yvalues[currentRegion] === null,\n x: this.xvalues[currentRegion],\n y: this.yvalues[currentRegion],\n color: this.options.get('lineColor'),\n fillColor: this.options.get('fillColor'),\n offset: currentRegion\n };\n },\n\n renderHighlight: function () {\n var currentRegion = this.currentRegion,\n target = this.target,\n vertex = this.vertices[currentRegion],\n options = this.options,\n spotRadius = options.get('spotRadius'),\n highlightSpotColor = options.get('highlightSpotColor'),\n highlightLineColor = options.get('highlightLineColor'),\n highlightSpot, highlightLine;\n\n if (!vertex) {\n return;\n }\n if (spotRadius && highlightSpotColor) {\n highlightSpot = target.drawCircle(vertex[0], vertex[1],\n spotRadius, undefined, highlightSpotColor);\n this.highlightSpotId = highlightSpot.id;\n target.insertAfterShape(this.lastShapeId, highlightSpot);\n }\n if (highlightLineColor) {\n highlightLine = target.drawLine(vertex[0], this.canvasTop, vertex[0],\n this.canvasTop + this.canvasHeight, highlightLineColor);\n this.highlightLineId = highlightLine.id;\n target.insertAfterShape(this.lastShapeId, highlightLine);\n }\n },\n\n removeHighlight: function () {\n var target = this.target;\n if (this.highlightSpotId) {\n target.removeShapeId(this.highlightSpotId);\n this.highlightSpotId = null;\n }\n if (this.highlightLineId) {\n target.removeShapeId(this.highlightLineId);\n this.highlightLineId = null;\n }\n },\n\n scanValues: function () {\n var values = this.values,\n valcount = values.length,\n xvalues = this.xvalues,\n yvalues = this.yvalues,\n yminmax = this.yminmax,\n i, val, isStr, isArray, sp;\n for (i = 0; i < valcount; i++) {\n val = values[i];\n isStr = typeof(values[i]) === 'string';\n isArray = typeof(values[i]) === 'object' && values[i] instanceof Array;\n sp = isStr && values[i].split(':');\n if (isStr && sp.length === 2) { // x:y\n xvalues.push(Number(sp[0]));\n yvalues.push(Number(sp[1]));\n yminmax.push(Number(sp[1]));\n } else if (isArray) {\n xvalues.push(val[0]);\n yvalues.push(val[1]);\n yminmax.push(val[1]);\n } else {\n xvalues.push(i);\n if (values[i] === null || values[i] === 'null') {\n yvalues.push(null);\n } else {\n yvalues.push(Number(val));\n yminmax.push(Number(val));\n }\n }\n }\n if (this.options.get('xvalues')) {\n xvalues = this.options.get('xvalues');\n }\n\n this.maxy = this.maxyorg = Math.max.apply(Math, yminmax);\n this.miny = this.minyorg = Math.min.apply(Math, yminmax);\n\n this.maxx = Math.max.apply(Math, xvalues);\n this.minx = Math.min.apply(Math, xvalues);\n\n this.xvalues = xvalues;\n this.yvalues = yvalues;\n this.yminmax = yminmax;\n\n },\n\n processRangeOptions: function () {\n var options = this.options,\n normalRangeMin = options.get('normalRangeMin'),\n normalRangeMax = options.get('normalRangeMax');\n\n if (normalRangeMin !== undefined) {\n if (normalRangeMin < this.miny) {\n this.miny = normalRangeMin;\n }\n if (normalRangeMax > this.maxy) {\n this.maxy = normalRangeMax;\n }\n }\n if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < this.miny)) {\n this.miny = options.get('chartRangeMin');\n }\n if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > this.maxy)) {\n this.maxy = options.get('chartRangeMax');\n }\n if (options.get('chartRangeMinX') !== undefined && (options.get('chartRangeClipX') || options.get('chartRangeMinX') < this.minx)) {\n this.minx = options.get('chartRangeMinX');\n }\n if (options.get('chartRangeMaxX') !== undefined && (options.get('chartRangeClipX') || options.get('chartRangeMaxX') > this.maxx)) {\n this.maxx = options.get('chartRangeMaxX');\n }\n\n },\n\n drawNormalRange: function (canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey) {\n var normalRangeMin = this.options.get('normalRangeMin'),\n normalRangeMax = this.options.get('normalRangeMax'),\n ytop = canvasTop + Math.round(canvasHeight - (canvasHeight * ((normalRangeMax - this.miny) / rangey))),\n height = Math.round((canvasHeight * (normalRangeMax - normalRangeMin)) / rangey);\n this.target.drawRect(canvasLeft, ytop, canvasWidth, height, undefined, this.options.get('normalRangeColor')).append();\n },\n\n render: function () {\n var options = this.options,\n target = this.target,\n canvasWidth = this.canvasWidth,\n canvasHeight = this.canvasHeight,\n vertices = this.vertices,\n spotRadius = options.get('spotRadius'),\n regionMap = this.regionMap,\n rangex, rangey, yvallast,\n canvasTop, canvasLeft,\n vertex, path, paths, x, y, xnext, xpos, xposnext,\n last, next, yvalcount, lineShapes, fillShapes, plen,\n valueSpots, hlSpotsEnabled, color, xvalues, yvalues, i;\n\n if (!line._super.render.call(this)) {\n return;\n }\n\n this.scanValues();\n this.processRangeOptions();\n\n xvalues = this.xvalues;\n yvalues = this.yvalues;\n\n if (!this.yminmax.length || this.yvalues.length < 2) {\n // empty or all null valuess\n return;\n }\n\n canvasTop = canvasLeft = 0;\n\n rangex = this.maxx - this.minx === 0 ? 1 : this.maxx - this.minx;\n rangey = this.maxy - this.miny === 0 ? 1 : this.maxy - this.miny;\n yvallast = this.yvalues.length - 1;\n\n if (spotRadius && (canvasWidth < (spotRadius * 4) || canvasHeight < (spotRadius * 4))) {\n spotRadius = 0;\n }\n if (spotRadius) {\n // adjust the canvas size as required so that spots will fit\n hlSpotsEnabled = options.get('highlightSpotColor') && !options.get('disableInteraction');\n if (hlSpotsEnabled || options.get('minSpotColor') || (options.get('spotColor') && yvalues[yvallast] === this.miny)) {\n canvasHeight -= Math.ceil(spotRadius);\n }\n if (hlSpotsEnabled || options.get('maxSpotColor') || (options.get('spotColor') && yvalues[yvallast] === this.maxy)) {\n canvasHeight -= Math.ceil(spotRadius);\n canvasTop += Math.ceil(spotRadius);\n }\n if (hlSpotsEnabled ||\n ((options.get('minSpotColor') || options.get('maxSpotColor')) && (yvalues[0] === this.miny || yvalues[0] === this.maxy))) {\n canvasLeft += Math.ceil(spotRadius);\n canvasWidth -= Math.ceil(spotRadius);\n }\n if (hlSpotsEnabled || options.get('spotColor') ||\n (options.get('minSpotColor') || options.get('maxSpotColor') &&\n (yvalues[yvallast] === this.miny || yvalues[yvallast] === this.maxy))) {\n canvasWidth -= Math.ceil(spotRadius);\n }\n }\n\n\n canvasHeight--;\n\n if (options.get('normalRangeMin') !== undefined && !options.get('drawNormalOnTop')) {\n this.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey);\n }\n\n path = [];\n paths = [path];\n last = next = null;\n yvalcount = yvalues.length;\n for (i = 0; i < yvalcount; i++) {\n x = xvalues[i];\n xnext = xvalues[i + 1];\n y = yvalues[i];\n xpos = canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex));\n xposnext = i < yvalcount - 1 ? canvasLeft + Math.round((xnext - this.minx) * (canvasWidth / rangex)) : canvasWidth;\n next = xpos + ((xposnext - xpos) / 2);\n regionMap[i] = [last || 0, next, i];\n last = next;\n if (y === null) {\n if (i) {\n if (yvalues[i - 1] !== null) {\n path = [];\n paths.push(path);\n }\n vertices.push(null);\n }\n } else {\n if (y < this.miny) {\n y = this.miny;\n }\n if (y > this.maxy) {\n y = this.maxy;\n }\n if (!path.length) {\n // previous value was null\n path.push([xpos, canvasTop + canvasHeight]);\n }\n vertex = [xpos, canvasTop + Math.round(canvasHeight - (canvasHeight * ((y - this.miny) / rangey)))];\n path.push(vertex);\n vertices.push(vertex);\n }\n }\n\n lineShapes = [];\n fillShapes = [];\n plen = paths.length;\n for (i = 0; i < plen; i++) {\n path = paths[i];\n if (path.length) {\n if (options.get('fillColor')) {\n path.push([path[path.length - 1][0], (canvasTop + canvasHeight)]);\n fillShapes.push(path.slice(0));\n path.pop();\n }\n // if there's only a single point in this path, then we want to display it\n // as a vertical line which means we keep path[0] as is\n if (path.length > 2) {\n // else we want the first value\n path[0] = [path[0][0], path[1][1]];\n }\n lineShapes.push(path);\n }\n }\n\n // draw the fill first, then optionally the normal range, then the line on top of that\n plen = fillShapes.length;\n for (i = 0; i < plen; i++) {\n target.drawShape(fillShapes[i],\n options.get('fillColor'), options.get('fillColor')).append();\n }\n\n if (options.get('normalRangeMin') !== undefined && options.get('drawNormalOnTop')) {\n this.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey);\n }\n\n plen = lineShapes.length;\n for (i = 0; i < plen; i++) {\n target.drawShape(lineShapes[i], options.get('lineColor'), undefined,\n options.get('lineWidth')).append();\n }\n\n if (spotRadius && options.get('valueSpots')) {\n valueSpots = options.get('valueSpots');\n if (valueSpots.get === undefined) {\n valueSpots = new RangeMap(valueSpots);\n }\n for (i = 0; i < yvalcount; i++) {\n color = valueSpots.get(yvalues[i]);\n if (color) {\n target.drawCircle(canvasLeft + Math.round((xvalues[i] - this.minx) * (canvasWidth / rangex)),\n canvasTop + Math.round(canvasHeight - (canvasHeight * ((yvalues[i] - this.miny) / rangey))),\n spotRadius, undefined,\n color).append();\n }\n }\n\n }\n if (spotRadius && options.get('spotColor') && yvalues[yvallast] !== null) {\n target.drawCircle(canvasLeft + Math.round((xvalues[xvalues.length - 1] - this.minx) * (canvasWidth / rangex)),\n canvasTop + Math.round(canvasHeight - (canvasHeight * ((yvalues[yvallast] - this.miny) / rangey))),\n spotRadius, undefined,\n options.get('spotColor')).append();\n }\n if (this.maxy !== this.minyorg) {\n if (spotRadius && options.get('minSpotColor')) {\n x = xvalues[$.inArray(this.minyorg, yvalues)];\n target.drawCircle(canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex)),\n canvasTop + Math.round(canvasHeight - (canvasHeight * ((this.minyorg - this.miny) / rangey))),\n spotRadius, undefined,\n options.get('minSpotColor')).append();\n }\n if (spotRadius && options.get('maxSpotColor')) {\n x = xvalues[$.inArray(this.maxyorg, yvalues)];\n target.drawCircle(canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex)),\n canvasTop + Math.round(canvasHeight - (canvasHeight * ((this.maxyorg - this.miny) / rangey))),\n spotRadius, undefined,\n options.get('maxSpotColor')).append();\n }\n }\n\n this.lastShapeId = target.getLastShapeId();\n this.canvasTop = canvasTop;\n target.render();\n }\n });\n\n /**\n * Bar charts\n */\n $.fn.sparkline.bar = bar = createClass($.fn.sparkline._base, barHighlightMixin, {\n type: 'bar',\n\n init: function (el, values, options, width, height) {\n var barWidth = parseInt(options.get('barWidth'), 10),\n barSpacing = parseInt(options.get('barSpacing'), 10),\n chartRangeMin = options.get('chartRangeMin'),\n chartRangeMax = options.get('chartRangeMax'),\n chartRangeClip = options.get('chartRangeClip'),\n stackMin = Infinity,\n stackMax = -Infinity,\n isStackString, groupMin, groupMax, stackRanges,\n numValues, i, vlen, range, zeroAxis, xaxisOffset, min, max, clipMin, clipMax,\n stacked, vlist, j, slen, svals, val, yoffset, yMaxCalc, canvasHeightEf;\n bar._super.init.call(this, el, values, options, width, height);\n\n // scan values to determine whether to stack bars\n for (i = 0, vlen = values.length; i < vlen; i++) {\n val = values[i];\n isStackString = typeof(val) === 'string' && val.indexOf(':') > -1;\n if (isStackString || $.isArray(val)) {\n stacked = true;\n if (isStackString) {\n val = values[i] = normalizeValues(val.split(':'));\n }\n val = remove(val, null); // min/max will treat null as zero\n groupMin = Math.min.apply(Math, val);\n groupMax = Math.max.apply(Math, val);\n if (groupMin < stackMin) {\n stackMin = groupMin;\n }\n if (groupMax > stackMax) {\n stackMax = groupMax;\n }\n }\n }\n\n this.stacked = stacked;\n this.regionShapes = {};\n this.barWidth = barWidth;\n this.barSpacing = barSpacing;\n this.totalBarWidth = barWidth + barSpacing;\n this.width = width = (values.length * barWidth) + ((values.length - 1) * barSpacing);\n\n this.initTarget();\n\n if (chartRangeClip) {\n clipMin = chartRangeMin === undefined ? -Infinity : chartRangeMin;\n clipMax = chartRangeMax === undefined ? Infinity : chartRangeMax;\n }\n\n numValues = [];\n stackRanges = stacked ? [] : numValues;\n var stackTotals = [];\n var stackRangesNeg = [];\n for (i = 0, vlen = values.length; i < vlen; i++) {\n if (stacked) {\n vlist = values[i];\n values[i] = svals = [];\n stackTotals[i] = 0;\n stackRanges[i] = stackRangesNeg[i] = 0;\n for (j = 0, slen = vlist.length; j < slen; j++) {\n val = svals[j] = chartRangeClip ? clipval(vlist[j], clipMin, clipMax) : vlist[j];\n if (val !== null) {\n if (val > 0) {\n stackTotals[i] += val;\n }\n if (stackMin < 0 && stackMax > 0) {\n if (val < 0) {\n stackRangesNeg[i] += Math.abs(val);\n } else {\n stackRanges[i] += val;\n }\n } else {\n stackRanges[i] += Math.abs(val - (val < 0 ? stackMax : stackMin));\n }\n numValues.push(val);\n }\n }\n } else {\n val = chartRangeClip ? clipval(values[i], clipMin, clipMax) : values[i];\n val = values[i] = normalizeValue(val);\n if (val !== null) {\n numValues.push(val);\n }\n }\n }\n this.max = max = Math.max.apply(Math, numValues);\n this.min = min = Math.min.apply(Math, numValues);\n this.stackMax = stackMax = stacked ? Math.max.apply(Math, stackTotals) : max;\n this.stackMin = stackMin = stacked ? Math.min.apply(Math, numValues) : min;\n\n if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < min)) {\n min = options.get('chartRangeMin');\n }\n if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > max)) {\n max = options.get('chartRangeMax');\n }\n\n this.zeroAxis = zeroAxis = options.get('zeroAxis', true);\n if (min <= 0 && max >= 0 && zeroAxis) {\n xaxisOffset = 0;\n } else if (zeroAxis == false) {\n xaxisOffset = min;\n } else if (min > 0) {\n xaxisOffset = min;\n } else {\n xaxisOffset = max;\n }\n this.xaxisOffset = xaxisOffset;\n\n range = stacked ? (Math.max.apply(Math, stackRanges) + Math.max.apply(Math, stackRangesNeg)) : max - min;\n\n // as we plot zero/min values a single pixel line, we add a pixel to all other\n // values - Reduce the effective canvas size to suit\n this.canvasHeightEf = (zeroAxis && min < 0) ? this.canvasHeight - 2 : this.canvasHeight - 1;\n\n if (min < xaxisOffset) {\n yMaxCalc = (stacked && max >= 0) ? stackMax : max;\n yoffset = (yMaxCalc - xaxisOffset) / range * this.canvasHeight;\n if (yoffset !== Math.ceil(yoffset)) {\n this.canvasHeightEf -= 2;\n yoffset = Math.ceil(yoffset);\n }\n } else {\n yoffset = this.canvasHeight;\n }\n this.yoffset = yoffset;\n\n if ($.isArray(options.get('colorMap'))) {\n this.colorMapByIndex = options.get('colorMap');\n this.colorMapByValue = null;\n } else {\n this.colorMapByIndex = null;\n this.colorMapByValue = options.get('colorMap');\n if (this.colorMapByValue && this.colorMapByValue.get === undefined) {\n this.colorMapByValue = new RangeMap(this.colorMapByValue);\n }\n }\n\n this.range = range;\n },\n\n getRegion: function (el, x, y) {\n var result = Math.floor(x / this.totalBarWidth);\n return (result < 0 || result >= this.values.length) ? undefined : result;\n },\n\n getCurrentRegionFields: function () {\n var currentRegion = this.currentRegion,\n values = ensureArray(this.values[currentRegion]),\n result = [],\n value, i;\n for (i = values.length; i--;) {\n value = values[i];\n result.push({\n isNull: value === null,\n value: value,\n color: this.calcColor(i, value, currentRegion),\n offset: currentRegion\n });\n }\n return result;\n },\n\n calcColor: function (stacknum, value, valuenum) {\n var colorMapByIndex = this.colorMapByIndex,\n colorMapByValue = this.colorMapByValue,\n options = this.options,\n color, newColor;\n if (this.stacked) {\n color = options.get('stackedBarColor');\n } else {\n color = (value < 0) ? options.get('negBarColor') : options.get('barColor');\n }\n if (value === 0 && options.get('zeroColor') !== undefined) {\n color = options.get('zeroColor');\n }\n if (colorMapByValue && (newColor = colorMapByValue.get(value))) {\n color = newColor;\n } else if (colorMapByIndex && colorMapByIndex.length > valuenum) {\n color = colorMapByIndex[valuenum];\n }\n return $.isArray(color) ? color[stacknum % color.length] : color;\n },\n\n /**\n * Render bar(s) for a region\n */\n renderRegion: function (valuenum, highlight) {\n var vals = this.values[valuenum],\n options = this.options,\n xaxisOffset = this.xaxisOffset,\n result = [],\n range = this.range,\n stacked = this.stacked,\n target = this.target,\n x = valuenum * this.totalBarWidth,\n canvasHeightEf = this.canvasHeightEf,\n yoffset = this.yoffset,\n y, height, color, isNull, yoffsetNeg, i, valcount, val, minPlotted, allMin;\n\n vals = $.isArray(vals) ? vals : [vals];\n valcount = vals.length;\n val = vals[0];\n isNull = all(null, vals);\n allMin = all(xaxisOffset, vals, true);\n\n if (isNull) {\n if (options.get('nullColor')) {\n color = highlight ? options.get('nullColor') : this.calcHighlightColor(options.get('nullColor'), options);\n y = (yoffset > 0) ? yoffset - 1 : yoffset;\n return target.drawRect(x, y, this.barWidth - 1, 0, color, color);\n } else {\n return undefined;\n }\n }\n yoffsetNeg = yoffset;\n for (i = 0; i < valcount; i++) {\n val = vals[i];\n\n if (stacked && val === xaxisOffset) {\n if (!allMin || minPlotted) {\n continue;\n }\n minPlotted = true;\n }\n\n if (range > 0) {\n height = Math.floor(canvasHeightEf * ((Math.abs(val - xaxisOffset) / range))) + 1;\n } else {\n height = 1;\n }\n if (val < xaxisOffset || (val === xaxisOffset && yoffset === 0)) {\n y = yoffsetNeg;\n yoffsetNeg += height;\n } else {\n y = yoffset - height;\n yoffset -= height;\n }\n color = this.calcColor(i, val, valuenum);\n if (highlight) {\n color = this.calcHighlightColor(color, options);\n }\n result.push(target.drawRect(x, y, this.barWidth - 1, height - 1, color, color));\n }\n if (result.length === 1) {\n return result[0];\n }\n return result;\n }\n });\n\n /**\n * Tristate charts\n */\n $.fn.sparkline.tristate = tristate = createClass($.fn.sparkline._base, barHighlightMixin, {\n type: 'tristate',\n\n init: function (el, values, options, width, height) {\n var barWidth = parseInt(options.get('barWidth'), 10),\n barSpacing = parseInt(options.get('barSpacing'), 10);\n tristate._super.init.call(this, el, values, options, width, height);\n\n this.regionShapes = {};\n this.barWidth = barWidth;\n this.barSpacing = barSpacing;\n this.totalBarWidth = barWidth + barSpacing;\n this.values = $.map(values, Number);\n this.width = width = (values.length * barWidth) + ((values.length - 1) * barSpacing);\n\n if ($.isArray(options.get('colorMap'))) {\n this.colorMapByIndex = options.get('colorMap');\n this.colorMapByValue = null;\n } else {\n this.colorMapByIndex = null;\n this.colorMapByValue = options.get('colorMap');\n if (this.colorMapByValue && this.colorMapByValue.get === undefined) {\n this.colorMapByValue = new RangeMap(this.colorMapByValue);\n }\n }\n this.initTarget();\n },\n\n getRegion: function (el, x, y) {\n return Math.floor(x / this.totalBarWidth);\n },\n\n getCurrentRegionFields: function () {\n var currentRegion = this.currentRegion;\n return {\n isNull: this.values[currentRegion] === undefined,\n value: this.values[currentRegion],\n color: this.calcColor(this.values[currentRegion], currentRegion),\n offset: currentRegion\n };\n },\n\n calcColor: function (value, valuenum) {\n var values = this.values,\n options = this.options,\n colorMapByIndex = this.colorMapByIndex,\n colorMapByValue = this.colorMapByValue,\n color, newColor;\n\n if (colorMapByValue && (newColor = colorMapByValue.get(value))) {\n color = newColor;\n } else if (colorMapByIndex && colorMapByIndex.length > valuenum) {\n color = colorMapByIndex[valuenum];\n } else if (values[valuenum] < 0) {\n color = options.get('negBarColor');\n } else if (values[valuenum] > 0) {\n color = options.get('posBarColor');\n } else {\n color = options.get('zeroBarColor');\n }\n return color;\n },\n\n renderRegion: function (valuenum, highlight) {\n var values = this.values,\n options = this.options,\n target = this.target,\n canvasHeight, height, halfHeight,\n x, y, color;\n\n canvasHeight = target.pixelHeight;\n halfHeight = Math.round(canvasHeight / 2);\n\n x = valuenum * this.totalBarWidth;\n if (values[valuenum] < 0) {\n y = halfHeight;\n height = halfHeight - 1;\n } else if (values[valuenum] > 0) {\n y = 0;\n height = halfHeight - 1;\n } else {\n y = halfHeight - 1;\n height = 2;\n }\n color = this.calcColor(values[valuenum], valuenum);\n if (color === null) {\n return;\n }\n if (highlight) {\n color = this.calcHighlightColor(color, options);\n }\n return target.drawRect(x, y, this.barWidth - 1, height - 1, color, color);\n }\n });\n\n /**\n * Discrete charts\n */\n $.fn.sparkline.discrete = discrete = createClass($.fn.sparkline._base, barHighlightMixin, {\n type: 'discrete',\n\n init: function (el, values, options, width, height) {\n discrete._super.init.call(this, el, values, options, width, height);\n\n this.regionShapes = {};\n this.values = values = $.map(values, Number);\n this.min = Math.min.apply(Math, values);\n this.max = Math.max.apply(Math, values);\n this.range = this.max - this.min;\n this.width = width = options.get('width') === 'auto' ? values.length * 2 : this.width;\n this.interval = Math.floor(width / values.length);\n this.itemWidth = width / values.length;\n if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < this.min)) {\n this.min = options.get('chartRangeMin');\n }\n if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > this.max)) {\n this.max = options.get('chartRangeMax');\n }\n this.initTarget();\n if (this.target) {\n this.lineHeight = options.get('lineHeight') === 'auto' ? Math.round(this.canvasHeight * 0.3) : options.get('lineHeight');\n }\n },\n\n getRegion: function (el, x, y) {\n return Math.floor(x / this.itemWidth);\n },\n\n getCurrentRegionFields: function () {\n var currentRegion = this.currentRegion;\n return {\n isNull: this.values[currentRegion] === undefined,\n value: this.values[currentRegion],\n offset: currentRegion\n };\n },\n\n renderRegion: function (valuenum, highlight) {\n var values = this.values,\n options = this.options,\n min = this.min,\n max = this.max,\n range = this.range,\n interval = this.interval,\n target = this.target,\n canvasHeight = this.canvasHeight,\n lineHeight = this.lineHeight,\n pheight = canvasHeight - lineHeight,\n ytop, val, color, x;\n\n val = clipval(values[valuenum], min, max);\n x = valuenum * interval;\n ytop = Math.round(pheight - pheight * ((val - min) / range));\n color = (options.get('thresholdColor') && val < options.get('thresholdValue')) ? options.get('thresholdColor') : options.get('lineColor');\n if (highlight) {\n color = this.calcHighlightColor(color, options);\n }\n return target.drawLine(x, ytop, x, ytop + lineHeight, color);\n }\n });\n\n /**\n * Bullet charts\n */\n $.fn.sparkline.bullet = bullet = createClass($.fn.sparkline._base, {\n type: 'bullet',\n\n init: function (el, values, options, width, height) {\n var min, max, vals;\n bullet._super.init.call(this, el, values, options, width, height);\n\n // values: target, performance, range1, range2, range3\n this.values = values = normalizeValues(values);\n // target or performance could be null\n vals = values.slice();\n vals[0] = vals[0] === null ? vals[2] : vals[0];\n vals[1] = values[1] === null ? vals[2] : vals[1];\n min = Math.min.apply(Math, values);\n max = Math.max.apply(Math, values);\n if (options.get('base') === undefined) {\n min = min < 0 ? min : 0;\n } else {\n min = options.get('base');\n }\n this.min = min;\n this.max = max;\n this.range = max - min;\n this.shapes = {};\n this.valueShapes = {};\n this.regiondata = {};\n this.width = width = options.get('width') === 'auto' ? '4.0em' : width;\n this.target = this.$el.simpledraw(width, height, options.get('composite'));\n if (!values.length) {\n this.disabled = true;\n }\n this.initTarget();\n },\n\n getRegion: function (el, x, y) {\n var shapeid = this.target.getShapeAt(el, x, y);\n return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined;\n },\n\n getCurrentRegionFields: function () {\n var currentRegion = this.currentRegion;\n return {\n fieldkey: currentRegion.substr(0, 1),\n value: this.values[currentRegion.substr(1)],\n region: currentRegion\n };\n },\n\n changeHighlight: function (highlight) {\n var currentRegion = this.currentRegion,\n shapeid = this.valueShapes[currentRegion],\n shape;\n delete this.shapes[shapeid];\n switch (currentRegion.substr(0, 1)) {\n case 'r':\n shape = this.renderRange(currentRegion.substr(1), highlight);\n break;\n case 'p':\n shape = this.renderPerformance(highlight);\n break;\n case 't':\n shape = this.renderTarget(highlight);\n break;\n }\n this.valueShapes[currentRegion] = shape.id;\n this.shapes[shape.id] = currentRegion;\n this.target.replaceWithShape(shapeid, shape);\n },\n\n renderRange: function (rn, highlight) {\n var rangeval = this.values[rn],\n rangewidth = Math.round(this.canvasWidth * ((rangeval - this.min) / this.range)),\n color = this.options.get('rangeColors')[rn - 2];\n if (highlight) {\n color = this.calcHighlightColor(color, this.options);\n }\n return this.target.drawRect(0, 0, rangewidth - 1, this.canvasHeight - 1, color, color);\n },\n\n renderPerformance: function (highlight) {\n var perfval = this.values[1],\n perfwidth = Math.round(this.canvasWidth * ((perfval - this.min) / this.range)),\n color = this.options.get('performanceColor');\n if (highlight) {\n color = this.calcHighlightColor(color, this.options);\n }\n return this.target.drawRect(0, Math.round(this.canvasHeight * 0.3), perfwidth - 1,\n Math.round(this.canvasHeight * 0.4) - 1, color, color);\n },\n\n renderTarget: function (highlight) {\n var targetval = this.values[0],\n x = Math.round(this.canvasWidth * ((targetval - this.min) / this.range) - (this.options.get('targetWidth') / 2)),\n targettop = Math.round(this.canvasHeight * 0.10),\n targetheight = this.canvasHeight - (targettop * 2),\n color = this.options.get('targetColor');\n if (highlight) {\n color = this.calcHighlightColor(color, this.options);\n }\n return this.target.drawRect(x, targettop, this.options.get('targetWidth') - 1, targetheight - 1, color, color);\n },\n\n render: function () {\n var vlen = this.values.length,\n target = this.target,\n i, shape;\n if (!bullet._super.render.call(this)) {\n return;\n }\n for (i = 2; i < vlen; i++) {\n shape = this.renderRange(i).append();\n this.shapes[shape.id] = 'r' + i;\n this.valueShapes['r' + i] = shape.id;\n }\n if (this.values[1] !== null) {\n shape = this.renderPerformance().append();\n this.shapes[shape.id] = 'p1';\n this.valueShapes.p1 = shape.id;\n }\n if (this.values[0] !== null) {\n shape = this.renderTarget().append();\n this.shapes[shape.id] = 't0';\n this.valueShapes.t0 = shape.id;\n }\n target.render();\n }\n });\n\n /**\n * Pie charts\n */\n $.fn.sparkline.pie = pie = createClass($.fn.sparkline._base, {\n type: 'pie',\n\n init: function (el, values, options, width, height) {\n var total = 0, i;\n\n pie._super.init.call(this, el, values, options, width, height);\n\n this.shapes = {}; // map shape ids to value offsets\n this.valueShapes = {}; // maps value offsets to shape ids\n this.values = values = $.map(values, Number);\n\n if (options.get('width') === 'auto') {\n this.width = this.height;\n }\n\n if (values.length > 0) {\n for (i = values.length; i--;) {\n total += values[i];\n }\n }\n this.total = total;\n this.initTarget();\n this.radius = Math.floor(Math.min(this.canvasWidth, this.canvasHeight) / 2);\n },\n\n getRegion: function (el, x, y) {\n var shapeid = this.target.getShapeAt(el, x, y);\n return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined;\n },\n\n getCurrentRegionFields: function () {\n var currentRegion = this.currentRegion;\n return {\n isNull: this.values[currentRegion] === undefined,\n value: this.values[currentRegion],\n percent: this.values[currentRegion] / this.total * 100,\n color: this.options.get('sliceColors')[currentRegion % this.options.get('sliceColors').length],\n offset: currentRegion\n };\n },\n\n changeHighlight: function (highlight) {\n var currentRegion = this.currentRegion,\n newslice = this.renderSlice(currentRegion, highlight),\n shapeid = this.valueShapes[currentRegion];\n delete this.shapes[shapeid];\n this.target.replaceWithShape(shapeid, newslice);\n this.valueShapes[currentRegion] = newslice.id;\n this.shapes[newslice.id] = currentRegion;\n },\n\n renderSlice: function (valuenum, highlight) {\n var target = this.target,\n options = this.options,\n radius = this.radius,\n borderWidth = options.get('borderWidth'),\n offset = options.get('offset'),\n circle = 2 * Math.PI,\n values = this.values,\n total = this.total,\n next = offset ? (2*Math.PI)*(offset/360) : 0,\n start, end, i, vlen, color;\n\n vlen = values.length;\n for (i = 0; i < vlen; i++) {\n start = next;\n end = next;\n if (total > 0) { // avoid divide by zero\n end = next + (circle * (values[i] / total));\n }\n if (valuenum === i) {\n color = options.get('sliceColors')[i % options.get('sliceColors').length];\n if (highlight) {\n color = this.calcHighlightColor(color, options);\n }\n\n return target.drawPieSlice(radius, radius, radius - borderWidth, start, end, undefined, color);\n }\n next = end;\n }\n },\n\n render: function () {\n var target = this.target,\n values = this.values,\n options = this.options,\n radius = this.radius,\n borderWidth = options.get('borderWidth'),\n donutWidth = options.get('donutWidth'),\n shape, i;\n\n if (!pie._super.render.call(this)) {\n return;\n }\n if (borderWidth) {\n target.drawCircle(radius, radius, Math.floor(radius - (borderWidth / 2)),\n options.get('borderColor'), undefined, borderWidth).append();\n }\n for (i = values.length; i--;) {\n if (values[i]) { // don't render zero values\n shape = this.renderSlice(i).append();\n this.valueShapes[i] = shape.id; // store just the shapeid\n this.shapes[shape.id] = i;\n }\n }\n if (donutWidth) {\n target.drawCircle(radius, radius, radius - donutWidth, options.get('donutColor'), \n options.get('donutColor'), 0).append();\n }\n target.render();\n }\n });\n\n /**\n * Box plots\n */\n $.fn.sparkline.box = box = createClass($.fn.sparkline._base, {\n type: 'box',\n\n init: function (el, values, options, width, height) {\n box._super.init.call(this, el, values, options, width, height);\n this.values = $.map(values, Number);\n this.width = options.get('width') === 'auto' ? '4.0em' : width;\n this.initTarget();\n if (!this.values.length) {\n this.disabled = 1;\n }\n },\n\n /**\n * Simulate a single region\n */\n getRegion: function () {\n return 1;\n },\n\n getCurrentRegionFields: function () {\n var result = [\n { field: 'lq', value: this.quartiles[0] },\n { field: 'med', value: this.quartiles[1] },\n { field: 'uq', value: this.quartiles[2] }\n ];\n if (this.loutlier !== undefined) {\n result.push({ field: 'lo', value: this.loutlier});\n }\n if (this.routlier !== undefined) {\n result.push({ field: 'ro', value: this.routlier});\n }\n if (this.lwhisker !== undefined) {\n result.push({ field: 'lw', value: this.lwhisker});\n }\n if (this.rwhisker !== undefined) {\n result.push({ field: 'rw', value: this.rwhisker});\n }\n return result;\n },\n\n render: function () {\n var target = this.target,\n values = this.values,\n vlen = values.length,\n options = this.options,\n canvasWidth = this.canvasWidth,\n canvasHeight = this.canvasHeight,\n minValue = options.get('chartRangeMin') === undefined ? Math.min.apply(Math, values) : options.get('chartRangeMin'),\n maxValue = options.get('chartRangeMax') === undefined ? Math.max.apply(Math, values) : options.get('chartRangeMax'),\n canvasLeft = 0,\n lwhisker, loutlier, iqr, q1, q2, q3, rwhisker, routlier, i,\n size, unitSize;\n\n if (!box._super.render.call(this)) {\n return;\n }\n\n if (options.get('raw')) {\n if (options.get('showOutliers') && values.length > 5) {\n loutlier = values[0];\n lwhisker = values[1];\n q1 = values[2];\n q2 = values[3];\n q3 = values[4];\n rwhisker = values[5];\n routlier = values[6];\n } else {\n lwhisker = values[0];\n q1 = values[1];\n q2 = values[2];\n q3 = values[3];\n rwhisker = values[4];\n }\n } else {\n values.sort(function (a, b) { return a - b; });\n q1 = quartile(values, 1);\n q2 = quartile(values, 2);\n q3 = quartile(values, 3);\n iqr = q3 - q1;\n if (options.get('showOutliers')) {\n lwhisker = rwhisker = undefined;\n for (i = 0; i < vlen; i++) {\n if (lwhisker === undefined && values[i] > q1 - (iqr * options.get('outlierIQR'))) {\n lwhisker = values[i];\n }\n if (values[i] < q3 + (iqr * options.get('outlierIQR'))) {\n rwhisker = values[i];\n }\n }\n loutlier = values[0];\n routlier = values[vlen - 1];\n } else {\n lwhisker = values[0];\n rwhisker = values[vlen - 1];\n }\n }\n this.quartiles = [q1, q2, q3];\n this.lwhisker = lwhisker;\n this.rwhisker = rwhisker;\n this.loutlier = loutlier;\n this.routlier = routlier;\n\n unitSize = canvasWidth / (maxValue - minValue + 1);\n if (options.get('showOutliers')) {\n canvasLeft = Math.ceil(options.get('spotRadius'));\n canvasWidth -= 2 * Math.ceil(options.get('spotRadius'));\n unitSize = canvasWidth / (maxValue - minValue + 1);\n if (loutlier < lwhisker) {\n target.drawCircle((loutlier - minValue) * unitSize + canvasLeft,\n canvasHeight / 2,\n options.get('spotRadius'),\n options.get('outlierLineColor'),\n options.get('outlierFillColor')).append();\n }\n if (routlier > rwhisker) {\n target.drawCircle((routlier - minValue) * unitSize + canvasLeft,\n canvasHeight / 2,\n options.get('spotRadius'),\n options.get('outlierLineColor'),\n options.get('outlierFillColor')).append();\n }\n }\n\n // box\n target.drawRect(\n Math.round((q1 - minValue) * unitSize + canvasLeft),\n Math.round(canvasHeight * 0.1),\n Math.round((q3 - q1) * unitSize),\n Math.round(canvasHeight * 0.8),\n options.get('boxLineColor'),\n options.get('boxFillColor')).append();\n // left whisker\n target.drawLine(\n Math.round((lwhisker - minValue) * unitSize + canvasLeft),\n Math.round(canvasHeight / 2),\n Math.round((q1 - minValue) * unitSize + canvasLeft),\n Math.round(canvasHeight / 2),\n options.get('lineColor')).append();\n target.drawLine(\n Math.round((lwhisker - minValue) * unitSize + canvasLeft),\n Math.round(canvasHeight / 4),\n Math.round((lwhisker - minValue) * unitSize + canvasLeft),\n Math.round(canvasHeight - canvasHeight / 4),\n options.get('whiskerColor')).append();\n // right whisker\n target.drawLine(Math.round((rwhisker - minValue) * unitSize + canvasLeft),\n Math.round(canvasHeight / 2),\n Math.round((q3 - minValue) * unitSize + canvasLeft),\n Math.round(canvasHeight / 2),\n options.get('lineColor')).append();\n target.drawLine(\n Math.round((rwhisker - minValue) * unitSize + canvasLeft),\n Math.round(canvasHeight / 4),\n Math.round((rwhisker - minValue) * unitSize + canvasLeft),\n Math.round(canvasHeight - canvasHeight / 4),\n options.get('whiskerColor')).append();\n // median line\n target.drawLine(\n Math.round((q2 - minValue) * unitSize + canvasLeft),\n Math.round(canvasHeight * 0.1),\n Math.round((q2 - minValue) * unitSize + canvasLeft),\n Math.round(canvasHeight * 0.9),\n options.get('medianColor')).append();\n if (options.get('target')) {\n size = Math.ceil(options.get('spotRadius'));\n target.drawLine(\n Math.round((options.get('target') - minValue) * unitSize + canvasLeft),\n Math.round((canvasHeight / 2) - size),\n Math.round((options.get('target') - minValue) * unitSize + canvasLeft),\n Math.round((canvasHeight / 2) + size),\n options.get('targetColor')).append();\n target.drawLine(\n Math.round((options.get('target') - minValue) * unitSize + canvasLeft - size),\n Math.round(canvasHeight / 2),\n Math.round((options.get('target') - minValue) * unitSize + canvasLeft + size),\n Math.round(canvasHeight / 2),\n options.get('targetColor')).append();\n }\n target.render();\n }\n });\n\n // Setup a very simple \"virtual canvas\" to make drawing the few shapes we need easier\n // This is accessible as $(foo).simpledraw()\n\n VShape = createClass({\n init: function (target, id, type, args) {\n this.target = target;\n this.id = id;\n this.type = type;\n this.args = args;\n },\n append: function () {\n this.target.appendShape(this);\n return this;\n }\n });\n\n VCanvas_base = createClass({\n _pxregex: /(\\d+)(px)?\\s*$/i,\n\n init: function (width, height, target) {\n if (!width) {\n return;\n }\n this.width = width;\n this.height = height;\n this.target = target;\n this.lastShapeId = null;\n if (target[0]) {\n target = target[0];\n }\n $.data(target, '_jqs_vcanvas', this);\n },\n\n drawLine: function (x1, y1, x2, y2, lineColor, lineWidth) {\n return this.drawShape([[x1, y1], [x2, y2]], lineColor, lineWidth);\n },\n\n drawShape: function (path, lineColor, fillColor, lineWidth) {\n return this._genShape('Shape', [path, lineColor, fillColor, lineWidth]);\n },\n\n drawCircle: function (x, y, radius, lineColor, fillColor, lineWidth) {\n return this._genShape('Circle', [x, y, radius, lineColor, fillColor, lineWidth]);\n },\n\n drawPieSlice: function (x, y, radius, startAngle, endAngle, lineColor, fillColor) {\n return this._genShape('PieSlice', [x, y, radius, startAngle, endAngle, lineColor, fillColor]);\n },\n\n drawRect: function (x, y, width, height, lineColor, fillColor) {\n return this._genShape('Rect', [x, y, width, height, lineColor, fillColor]);\n },\n\n getElement: function () {\n return this.canvas;\n },\n\n /**\n * Return the most recently inserted shape id\n */\n getLastShapeId: function () {\n return this.lastShapeId;\n },\n\n /**\n * Clear and reset the canvas\n */\n reset: function () {\n alert('reset not implemented');\n },\n\n _insert: function (el, target) {\n $(target).html(el);\n },\n\n /**\n * Calculate the pixel dimensions of the canvas\n */\n _calculatePixelDims: function (width, height, canvas) {\n // XXX This should probably be a configurable option\n var match;\n match = this._pxregex.exec(height);\n if (match) {\n this.pixelHeight = match[1];\n } else {\n this.pixelHeight = $(canvas).height();\n }\n match = this._pxregex.exec(width);\n if (match) {\n this.pixelWidth = match[1];\n } else {\n this.pixelWidth = $(canvas).width();\n }\n },\n\n /**\n * Generate a shape object and id for later rendering\n */\n _genShape: function (shapetype, shapeargs) {\n var id = shapeCount++;\n shapeargs.unshift(id);\n return new VShape(this, id, shapetype, shapeargs);\n },\n\n /**\n * Add a shape to the end of the render queue\n */\n appendShape: function (shape) {\n alert('appendShape not implemented');\n },\n\n /**\n * Replace one shape with another\n */\n replaceWithShape: function (shapeid, shape) {\n alert('replaceWithShape not implemented');\n },\n\n /**\n * Insert one shape after another in the render queue\n */\n insertAfterShape: function (shapeid, shape) {\n alert('insertAfterShape not implemented');\n },\n\n /**\n * Remove a shape from the queue\n */\n removeShapeId: function (shapeid) {\n alert('removeShapeId not implemented');\n },\n\n /**\n * Find a shape at the specified x/y co-ordinates\n */\n getShapeAt: function (el, x, y) {\n alert('getShapeAt not implemented');\n },\n\n /**\n * Render all queued shapes onto the canvas\n */\n render: function () {\n alert('render not implemented');\n }\n });\n\n VCanvas_canvas = createClass(VCanvas_base, {\n init: function (width, height, target, interact) {\n VCanvas_canvas._super.init.call(this, width, height, target);\n this.canvas = document.createElement('canvas');\n if (target[0]) {\n target = target[0];\n }\n $.data(target, '_jqs_vcanvas', this);\n $(this.canvas).css({ display: 'inline-block', width: width, height: height, verticalAlign: 'top' });\n this._insert(this.canvas, target);\n this._calculatePixelDims(width, height, this.canvas);\n this.canvas.width = this.pixelWidth;\n this.canvas.height = this.pixelHeight;\n this.interact = interact;\n this.shapes = {};\n this.shapeseq = [];\n this.currentTargetShapeId = undefined;\n $(this.canvas).css({width: this.pixelWidth, height: this.pixelHeight});\n },\n\n _getContext: function (lineColor, fillColor, lineWidth) {\n var context = this.canvas.getContext('2d');\n if (lineColor !== undefined) {\n context.strokeStyle = lineColor;\n }\n context.lineWidth = lineWidth === undefined ? 1 : lineWidth;\n if (fillColor !== undefined) {\n context.fillStyle = fillColor;\n }\n return context;\n },\n\n reset: function () {\n var context = this._getContext();\n context.clearRect(0, 0, this.pixelWidth, this.pixelHeight);\n this.shapes = {};\n this.shapeseq = [];\n this.currentTargetShapeId = undefined;\n },\n\n _drawShape: function (shapeid, path, lineColor, fillColor, lineWidth) {\n var context = this._getContext(lineColor, fillColor, lineWidth),\n i, plen;\n context.beginPath();\n context.moveTo(path[0][0] + 0.5, path[0][1] + 0.5);\n for (i = 1, plen = path.length; i < plen; i++) {\n context.lineTo(path[i][0] + 0.5, path[i][1] + 0.5); // the 0.5 offset gives us crisp pixel-width lines\n }\n if (lineColor !== undefined) {\n context.stroke();\n }\n if (fillColor !== undefined) {\n context.fill();\n }\n if (this.targetX !== undefined && this.targetY !== undefined &&\n context.isPointInPath(this.targetX, this.targetY)) {\n this.currentTargetShapeId = shapeid;\n }\n },\n\n _drawCircle: function (shapeid, x, y, radius, lineColor, fillColor, lineWidth) {\n var context = this._getContext(lineColor, fillColor, lineWidth);\n context.beginPath();\n context.arc(x, y, radius, 0, 2 * Math.PI, false);\n if (this.targetX !== undefined && this.targetY !== undefined &&\n context.isPointInPath(this.targetX, this.targetY)) {\n this.currentTargetShapeId = shapeid;\n }\n if (lineColor !== undefined) {\n context.stroke();\n }\n if (fillColor !== undefined) {\n context.fill();\n }\n },\n\n _drawPieSlice: function (shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) {\n var context = this._getContext(lineColor, fillColor);\n context.beginPath();\n context.moveTo(x, y);\n context.arc(x, y, radius, startAngle, endAngle, false);\n context.lineTo(x, y);\n context.closePath();\n if (lineColor !== undefined) {\n context.stroke();\n }\n if (fillColor) {\n context.fill();\n }\n if (this.targetX !== undefined && this.targetY !== undefined &&\n context.isPointInPath(this.targetX, this.targetY)) {\n this.currentTargetShapeId = shapeid;\n }\n },\n\n _drawRect: function (shapeid, x, y, width, height, lineColor, fillColor) {\n return this._drawShape(shapeid, [[x, y], [x + width, y], [x + width, y + height], [x, y + height], [x, y]], lineColor, fillColor);\n },\n\n appendShape: function (shape) {\n this.shapes[shape.id] = shape;\n this.shapeseq.push(shape.id);\n this.lastShapeId = shape.id;\n return shape.id;\n },\n\n replaceWithShape: function (shapeid, shape) {\n var shapeseq = this.shapeseq,\n i;\n this.shapes[shape.id] = shape;\n for (i = shapeseq.length; i--;) {\n if (shapeseq[i] == shapeid) {\n shapeseq[i] = shape.id;\n }\n }\n delete this.shapes[shapeid];\n },\n\n replaceWithShapes: function (shapeids, shapes) {\n var shapeseq = this.shapeseq,\n shapemap = {},\n sid, i, first;\n\n for (i = shapeids.length; i--;) {\n shapemap[shapeids[i]] = true;\n }\n for (i = shapeseq.length; i--;) {\n sid = shapeseq[i];\n if (shapemap[sid]) {\n shapeseq.splice(i, 1);\n delete this.shapes[sid];\n first = i;\n }\n }\n for (i = shapes.length; i--;) {\n shapeseq.splice(first, 0, shapes[i].id);\n this.shapes[shapes[i].id] = shapes[i];\n }\n\n },\n\n insertAfterShape: function (shapeid, shape) {\n var shapeseq = this.shapeseq,\n i;\n for (i = shapeseq.length; i--;) {\n if (shapeseq[i] === shapeid) {\n shapeseq.splice(i + 1, 0, shape.id);\n this.shapes[shape.id] = shape;\n return;\n }\n }\n },\n\n removeShapeId: function (shapeid) {\n var shapeseq = this.shapeseq,\n i;\n for (i = shapeseq.length; i--;) {\n if (shapeseq[i] === shapeid) {\n shapeseq.splice(i, 1);\n break;\n }\n }\n delete this.shapes[shapeid];\n },\n\n getShapeAt: function (el, x, y) {\n this.targetX = x;\n this.targetY = y;\n this.render();\n return this.currentTargetShapeId;\n },\n\n render: function () {\n var shapeseq = this.shapeseq,\n shapes = this.shapes,\n shapeCount = shapeseq.length,\n context = this._getContext(),\n shapeid, shape, i;\n context.clearRect(0, 0, this.pixelWidth, this.pixelHeight);\n for (i = 0; i < shapeCount; i++) {\n shapeid = shapeseq[i];\n shape = shapes[shapeid];\n this['_draw' + shape.type].apply(this, shape.args);\n }\n if (!this.interact) {\n // not interactive so no need to keep the shapes array\n this.shapes = {};\n this.shapeseq = [];\n }\n }\n\n });\n\n VCanvas_vml = createClass(VCanvas_base, {\n init: function (width, height, target) {\n var groupel;\n VCanvas_vml._super.init.call(this, width, height, target);\n if (target[0]) {\n target = target[0];\n }\n $.data(target, '_jqs_vcanvas', this);\n this.canvas = document.createElement('span');\n $(this.canvas).css({ display: 'inline-block', position: 'relative', overflow: 'hidden', width: width, height: height, margin: '0px', padding: '0px', verticalAlign: 'top'});\n this._insert(this.canvas, target);\n this._calculatePixelDims(width, height, this.canvas);\n this.canvas.width = this.pixelWidth;\n this.canvas.height = this.pixelHeight;\n groupel = '';\n this.canvas.insertAdjacentHTML('beforeEnd', groupel);\n this.group = $(this.canvas).children()[0];\n this.rendered = false;\n this.prerender = '';\n },\n\n _drawShape: function (shapeid, path, lineColor, fillColor, lineWidth) {\n var vpath = [],\n initial, stroke, fill, closed, vel, plen, i;\n for (i = 0, plen = path.length; i < plen; i++) {\n vpath[i] = '' + (path[i][0]) + ',' + (path[i][1]);\n }\n initial = vpath.splice(0, 1);\n lineWidth = lineWidth === undefined ? 1 : lineWidth;\n stroke = lineColor === undefined ? ' stroked=\"false\" ' : ' strokeWeight=\"' + lineWidth + 'px\" strokeColor=\"' + lineColor + '\" ';\n fill = fillColor === undefined ? ' filled=\"false\"' : ' fillColor=\"' + fillColor + '\" filled=\"true\" ';\n closed = vpath[0] === vpath[vpath.length - 1] ? 'x ' : '';\n vel = '' +\n ' ';\n return vel;\n },\n\n _drawCircle: function (shapeid, x, y, radius, lineColor, fillColor, lineWidth) {\n var stroke, fill, vel;\n x -= radius;\n y -= radius;\n stroke = lineColor === undefined ? ' stroked=\"false\" ' : ' strokeWeight=\"' + lineWidth + 'px\" strokeColor=\"' + lineColor + '\" ';\n fill = fillColor === undefined ? ' filled=\"false\"' : ' fillColor=\"' + fillColor + '\" filled=\"true\" ';\n vel = '';\n return vel;\n\n },\n\n _drawPieSlice: function (shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) {\n var vpath, startx, starty, endx, endy, stroke, fill, vel;\n if (startAngle === endAngle) {\n return ''; // VML seems to have problem when start angle equals end angle.\n }\n if ((endAngle - startAngle) === (2 * Math.PI)) {\n startAngle = 0.0; // VML seems to have a problem when drawing a full circle that doesn't start 0\n endAngle = (2 * Math.PI);\n }\n\n startx = x + Math.round(Math.cos(startAngle) * radius);\n starty = y + Math.round(Math.sin(startAngle) * radius);\n endx = x + Math.round(Math.cos(endAngle) * radius);\n endy = y + Math.round(Math.sin(endAngle) * radius);\n\n if (startx === endx && starty === endy) {\n if ((endAngle - startAngle) < Math.PI) {\n // Prevent very small slices from being mistaken as a whole pie\n return '';\n }\n // essentially going to be the entire circle, so ignore startAngle\n startx = endx = x + radius;\n starty = endy = y;\n }\n\n if (startx === endx && starty === endy && (endAngle - startAngle) < Math.PI) {\n return '';\n }\n\n vpath = [x - radius, y - radius, x + radius, y + radius, startx, starty, endx, endy];\n stroke = lineColor === undefined ? ' stroked=\"false\" ' : ' strokeWeight=\"1px\" strokeColor=\"' + lineColor + '\" ';\n fill = fillColor === undefined ? ' filled=\"false\"' : ' fillColor=\"' + fillColor + '\" filled=\"true\" ';\n vel = '' +\n ' ';\n return vel;\n },\n\n _drawRect: function (shapeid, x, y, width, height, lineColor, fillColor) {\n return this._drawShape(shapeid, [[x, y], [x, y + height], [x + width, y + height], [x + width, y], [x, y]], lineColor, fillColor);\n },\n\n reset: function () {\n this.group.innerHTML = '';\n },\n\n appendShape: function (shape) {\n var vel = this['_draw' + shape.type].apply(this, shape.args);\n if (this.rendered) {\n this.group.insertAdjacentHTML('beforeEnd', vel);\n } else {\n this.prerender += vel;\n }\n this.lastShapeId = shape.id;\n return shape.id;\n },\n\n replaceWithShape: function (shapeid, shape) {\n var existing = $('#jqsshape' + shapeid),\n vel = this['_draw' + shape.type].apply(this, shape.args);\n existing[0].outerHTML = vel;\n },\n\n replaceWithShapes: function (shapeids, shapes) {\n // replace the first shapeid with all the new shapes then toast the remaining old shapes\n var existing = $('#jqsshape' + shapeids[0]),\n replace = '',\n slen = shapes.length,\n i;\n for (i = 0; i < slen; i++) {\n replace += this['_draw' + shapes[i].type].apply(this, shapes[i].args);\n }\n existing[0].outerHTML = replace;\n for (i = 1; i < shapeids.length; i++) {\n $('#jqsshape' + shapeids[i]).remove();\n }\n },\n\n insertAfterShape: function (shapeid, shape) {\n var existing = $('#jqsshape' + shapeid),\n vel = this['_draw' + shape.type].apply(this, shape.args);\n existing[0].insertAdjacentHTML('afterEnd', vel);\n },\n\n removeShapeId: function (shapeid) {\n var existing = $('#jqsshape' + shapeid);\n this.group.removeChild(existing[0]);\n },\n\n getShapeAt: function (el, x, y) {\n var shapeid = el.id.substr(8);\n return shapeid;\n },\n\n render: function () {\n if (!this.rendered) {\n // batch the intial render into a single repaint\n this.group.innerHTML = this.prerender;\n this.rendered = true;\n }\n }\n });\n\n}))}(document, Math));\n","var __assign = (this && this.__assign) || function () {\n __assign = Object.assign || function(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\n t[p] = s[p];\n }\n return t;\n };\n return __assign.apply(this, arguments);\n};\nvar __rest = (this && this.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n};\nvar __read = (this && this.__read) || function (o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n};\nvar __spread = (this && this.__spread) || function () {\n for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));\n return ar;\n};\nimport * as React from 'react';\nimport classNamesFunc from 'classnames';\nimport { parseThemeOptions } from './with-theme';\nimport { handleDeprecations } from './utils/deprecation';\n// ALL OF THESE FUNCTIONS MUTATE THE COPY OF PROPS\n// this is intentional and done for speed and memory\nvar handleClassNames = function (props, classNames, className, theme) {\n var finalClassNames = classNamesFunc.apply(void 0, __spread([className], (!!theme ? parseThemeOptions(theme) : []), (typeof classNames === 'function' ? classNames(props) : classNames)));\n props.className = finalClassNames;\n};\nvar handleTag = function (props, defaultTag, tag) {\n // Handle the case where we are extending a component but passing\n // a string as a tag. For instance, extending an Icon but rendering a span\n if (typeof defaultTag !== 'string') {\n props.tag = tag;\n return defaultTag;\n }\n return tag || defaultTag;\n};\nvar handleConsumeProps = function (props, consumeProps) {\n consumeProps.forEach(function (p) {\n delete props[p];\n });\n};\nexport var componentFactory = function (_a) {\n var displayName = _a.displayName, _b = _a.classNames, classNames = _b === void 0 ? [] : _b, _c = _a.tag, defaultTag = _c === void 0 ? 'div' : _c, deprecate = _a.deprecate, defaultProps = _a.defaultProps, _d = _a.consumeProps, consumeProps = _d === void 0 ? [] : _d, render = _a.render;\n var Component = React.forwardRef(function (props, ref) {\n var className = props.className, theme = props.theme, tag = props.tag, rest = __rest(props, [\"className\", \"theme\", \"tag\"]);\n var newProps = rest;\n handleClassNames(newProps, classNames, className, theme);\n var Tag = handleTag(newProps, defaultTag, tag);\n if (deprecate) {\n newProps = handleDeprecations(newProps, deprecate, displayName);\n }\n handleConsumeProps(newProps, consumeProps);\n var finalProps = newProps;\n // @ts-ignore\n return render ? (render(finalProps, ref, Tag)) : (React.createElement(Tag, __assign({}, finalProps, { ref: ref })));\n });\n Component.displayName = displayName;\n Component.defaultProps = defaultProps;\n return Component;\n};\n","/* istanbul ignore file */\nexport var eventsMap = {\n blur: 'onBlur',\n cancel: 'onCancel',\n click: 'onClick',\n close: 'onClose',\n contextmenu: 'onContextMenu',\n copy: 'onCopy',\n cut: 'onCut',\n auxclick: 'onAuxClick',\n doubleclick: 'onDoubleClick',\n dragend: 'onDragEnd',\n dragstart: 'onDragStart',\n drop: 'onDrop',\n focus: 'onFocus',\n input: 'onInput',\n invalid: 'onInvalid',\n keydown: 'onKeyDown',\n keypress: 'onKeyPress',\n keyup: 'onKeyUp',\n mousedown: 'onMouseDown',\n mouseup: 'onMouseUp',\n paste: 'onPaste',\n pause: 'onPause',\n play: 'onPlay',\n pointercancel: 'onPointerCancel',\n pointerdown: 'onPointerDown',\n pointerup: 'onPointerUp',\n ratechange: 'onRateChange',\n reset: 'onReset',\n seeked: 'onSeeked',\n submit: 'onSubmit',\n touchcancel: 'onTouchCancel',\n touchend: 'onTouchEnd',\n touchstart: 'onTouchStart',\n volumechange: 'onVolumeChange',\n abort: 'onAbort',\n animationend: 'onAnimationEnd',\n animationiteration: 'onAnimationIteration',\n animationstart: 'onAnimationStart',\n canplay: 'onCanPlay',\n canplaythrough: 'onCanPlayThrough',\n drag: 'onDrag',\n dragenter: 'onDragEnter',\n dragexit: 'onDragExit',\n dragleave: 'onDragLeave',\n dragover: 'onDragOver',\n durationchange: 'onDurationChange',\n emptied: 'onEmptied',\n encrypted: 'onEncrypted',\n ended: 'onEnded',\n error: 'onError',\n gotpointercapture: 'onGotPointerCapture',\n load: 'onLoad',\n loadeddata: 'onLoadedData',\n loadedmetadata: 'onLoadedMetadata',\n loadstart: 'onLoadStart',\n lostpointercapture: 'onLostPointerCapture',\n mousemove: 'onMouseMove',\n mouseout: 'onMouseOut',\n mouseover: 'onMouseOver',\n playing: 'onPlaying',\n pointermove: 'onPointerMove',\n pointerout: 'onPointerOut',\n pointerover: 'onPointerOver',\n progress: 'onProgress',\n scroll: 'onScroll',\n seeking: 'onSeeking',\n stalled: 'onStalled',\n suspend: 'onSuspend',\n timeupdate: 'onTimeUpdate',\n toggle: 'onToggle',\n touchmove: 'onTouchMove',\n transitionend: 'onTransitionEnd',\n waiting: 'onWaiting',\n wheel: 'onWheel',\n mouseenter: 'onMouseEnter',\n mouseleave: 'onMouseLeave',\n pointerenter: 'onPointerEnter',\n pointerleave: 'onPointerLeave',\n change: 'onChange',\n select: 'onSelect',\n beforeinput: 'onBeforeInput',\n compositionend: 'onCompositionEnd',\n compositionstart: 'onCompositionStart',\n compositionupdate: 'onCompositionUpdate'\n};\n","export var debounce = function (func, wait) {\n var timeout;\n return function () {\n // @ts-ignore\n var context = this, args = arguments;\n var later = function () {\n timeout = null;\n func.apply(context, args);\n };\n timeout !== null && clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n };\n};\n","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nvar __assign = (this && this.__assign) || function () {\n __assign = Object.assign || function(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\n t[p] = s[p];\n }\n return t;\n };\n return __assign.apply(this, arguments);\n};\nvar __read = (this && this.__read) || function (o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n};\nvar __spread = (this && this.__spread) || function () {\n for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));\n return ar;\n};\nimport * as React from 'react';\nimport classNames from 'classnames';\nimport { eventsMap } from './utils/events-map';\nimport { debounce } from './utils/debounce';\nimport { toCamel } from './utils/strings';\nvar reactPropFromEventName = function (evtName) {\n return eventsMap[evtName] || evtName;\n};\nvar FoundationElement = /** @class */ (function () {\n function FoundationElement(onChange) {\n this._classes = new Set();\n this._events = {};\n this._style = {};\n this._props = {};\n this._ref = null;\n this._onChange = null;\n this._onChange = onChange;\n this.onChange = this.onChange.bind(this);\n this.addClass = this.addClass.bind(this);\n this.removeClass = this.removeClass.bind(this);\n this.hasClass = this.hasClass.bind(this);\n this.setProp = this.setProp.bind(this);\n this.getProp = this.getProp.bind(this);\n this.removeProp = this.removeProp.bind(this);\n this.setStyle = this.setStyle.bind(this);\n this.addEventListener = this.addEventListener.bind(this);\n this.removeEventListener = this.removeEventListener.bind(this);\n this.setRef = this.setRef.bind(this);\n }\n FoundationElement.prototype.onChange = function () {\n this._onChange && this._onChange();\n };\n FoundationElement.prototype.destroy = function () {\n this._onChange = null;\n this._ref = null;\n this._events = {};\n this._style = {};\n this._props = {};\n this._classes = new Set();\n };\n /**************************************************\n * Classes\n **************************************************/\n FoundationElement.prototype.addClass = function (className) {\n if (!this._classes.has(className)) {\n this._classes.add(className);\n this.onChange();\n }\n };\n FoundationElement.prototype.removeClass = function (className) {\n if (this._classes.has(className)) {\n this._classes.delete(className);\n this.onChange();\n }\n };\n FoundationElement.prototype.hasClass = function (className) {\n return this._classes.has(className);\n };\n /**************************************************\n * Props\n **************************************************/\n FoundationElement.prototype.setProp = function (propName, value) {\n if (this._props[propName] !== value) {\n this._props[propName] = value;\n this.onChange();\n }\n };\n FoundationElement.prototype.getProp = function (propName) {\n return this._props[propName];\n };\n FoundationElement.prototype.removeProp = function (propName) {\n if (this._props[propName] !== undefined) {\n delete this._props[propName];\n this.onChange();\n }\n };\n FoundationElement.prototype.props = function (propsToMerge) {\n var _this = this;\n var _a = propsToMerge.className, className = _a === void 0 ? '' : _a, _b = propsToMerge.style, style = _b === void 0 ? {} : _b;\n // handle merging events\n // the foundation should be able to pass something onClick as well as a user\n // This wraps them in a function that calls both\n var mergedEvents = Object.entries(propsToMerge).reduce(function (acc, _a) {\n var _b = __read(_a, 2), key = _b[0], possibleCallback = _b[1];\n var existingCallback = _this._events[key];\n if (typeof possibleCallback === 'function' &&\n typeof existingCallback === 'function') {\n var wrappedCallback = function (evt) {\n existingCallback(evt);\n return possibleCallback(evt);\n };\n acc[key] = wrappedCallback;\n }\n return acc;\n }, __assign({}, this._events));\n // handle className\n var mergedClasses = classNames(className, __spread(this._classes));\n // handle styles\n var mergedStyles = __assign({}, this._style, style);\n return __assign({}, propsToMerge, this._props, mergedEvents, { style: mergedStyles, className: mergedClasses });\n };\n /**************************************************\n * Styles\n **************************************************/\n FoundationElement.prototype.setStyle = function (propertyName, value) {\n propertyName = propertyName.startsWith('--')\n ? propertyName\n : toCamel(propertyName);\n if (this._style[propertyName] !== value) {\n this._style[propertyName] = value;\n this.onChange();\n }\n };\n /**************************************************\n * Events\n **************************************************/\n FoundationElement.prototype.addEventListener = function (evtName, callback) {\n var propName = reactPropFromEventName(evtName);\n if (this._events[propName] !== callback) {\n this._events[propName] = callback;\n this.onChange();\n }\n };\n FoundationElement.prototype.removeEventListener = function (evtName, callback) {\n var propName = reactPropFromEventName(evtName);\n if (this._events[propName]) {\n delete this._events[propName];\n this.onChange();\n }\n };\n /**************************************************\n * Refs\n **************************************************/\n FoundationElement.prototype.setRef = function (el) {\n if (el) {\n this._ref = el;\n }\n };\n Object.defineProperty(FoundationElement.prototype, \"ref\", {\n get: function () {\n return this._ref;\n },\n enumerable: true,\n configurable: true\n });\n return FoundationElement;\n}());\nexport { FoundationElement };\nvar FoundationComponent = /** @class */ (function (_super) {\n __extends(FoundationComponent, _super);\n function FoundationComponent(props) {\n var _this = _super.call(this, props) || this;\n _this.elements = {};\n //@ts-ignore\n if (_this.constructor.shouldDebounce) {\n _this.update = debounce(_this.update.bind(_this), 0);\n }\n else {\n _this.update = _this.update.bind(_this);\n }\n return _this;\n }\n FoundationComponent.prototype.componentDidMount = function () {\n this.foundation = this.getDefaultFoundation();\n this.foundation.init();\n this.sync(this.props, {});\n };\n FoundationComponent.prototype.componentDidUpdate = function (prevProps) {\n this.sync(this.props, prevProps);\n };\n FoundationComponent.prototype.componentWillUnmount = function () {\n this.foundation && this.foundation.destroy();\n // @ts-ignore\n this.foundation = undefined;\n Object.values(this.elements).forEach(function (el) { return el.destroy(); });\n };\n FoundationComponent.prototype.createElement = function (elementName) {\n var el = new FoundationElement(this.update);\n this.elements[elementName] = el;\n return el;\n };\n FoundationComponent.prototype.update = function () {\n this.foundation && this.setState({});\n };\n FoundationComponent.prototype.sync = function (props, prevProps) { };\n FoundationComponent.prototype.syncProp = function (prop, prevProp, callback) {\n if ((prop !== undefined || (prevProp !== undefined && prop === undefined)) &&\n prop !== prevProp) {\n callback();\n }\n };\n FoundationComponent.prototype.getDefaultFoundation = function () {\n return {\n init: function () { },\n destroy: function () { }\n };\n };\n /**\n * Fires a cross-browser-compatible custom event from the component root of the given type,\n */\n FoundationComponent.prototype.emit = function (evtType, evtData, shouldBubble) {\n if (shouldBubble === void 0) { shouldBubble = false; }\n var evt;\n evt = new CustomEvent(evtType, {\n detail: evtData,\n bubbles: shouldBubble\n });\n // bugfix for events coming from form elements\n // and also fits with reacts form pattern better...\n // This should always otherwise be null since there is no target\n // for Custom Events\n Object.defineProperty(evt, 'target', {\n value: evtData,\n writable: false\n });\n Object.defineProperty(evt, 'currentTarget', {\n value: evtData,\n writable: false\n });\n // Custom handling for React\n var propName = evtType;\n // check to see if the foundation still exists. If not, we are\n // probably unmounted or destroyed and dont want to call any more handlers\n // This happens when MDC broadcasts certain events on timers\n if (this.foundation) {\n //@ts-ignore\n this.props[propName] && this.props[propName](evt);\n }\n return evt;\n };\n FoundationComponent.shouldDebounce = false;\n return FoundationComponent;\n}(React.Component));\nexport { FoundationComponent };\n","export default function symbolObservablePonyfill(root) {\n\tvar result;\n\tvar Symbol = root.Symbol;\n\n\tif (typeof Symbol === 'function') {\n\t\tif (Symbol.observable) {\n\t\t\tresult = Symbol.observable;\n\t\t} else {\n\t\t\tresult = Symbol('observable');\n\t\t\tSymbol.observable = result;\n\t\t}\n\t} else {\n\t\tresult = '@@observable';\n\t}\n\n\treturn result;\n};\n","import _checkForMethod from './internal/_checkForMethod.js';\nimport _curry1 from './internal/_curry1.js';\nimport slice from './slice.js';\n\n/**\n * Returns all but the first element of the given list or string (or object\n * with a `tail` method).\n *\n * Dispatches to the `slice` method of the first argument, if present.\n *\n * @func\n * @memberOf R\n * @since v0.1.0\n * @category List\n * @sig [a] -> [a]\n * @sig String -> String\n * @param {*} list\n * @return {*}\n * @see R.head, R.init, R.last\n * @example\n *\n * R.tail([1, 2, 3]); //=> [2, 3]\n * R.tail([1, 2]); //=> [2]\n * R.tail([1]); //=> []\n * R.tail([]); //=> []\n *\n * R.tail('abc'); //=> 'bc'\n * R.tail('ab'); //=> 'b'\n * R.tail('a'); //=> ''\n * R.tail(''); //=> ''\n */\nvar tail = /*#__PURE__*/_curry1( /*#__PURE__*/_checkForMethod('tail', /*#__PURE__*/slice(1, Infinity)));\nexport default tail;","/** PURE_IMPORTS_START tslib,_util_subscribeToResult,_OuterSubscriber,_InnerSubscriber,_map,_observable_from PURE_IMPORTS_END */\nimport * as tslib_1 from \"tslib\";\nimport { subscribeToResult } from '../util/subscribeToResult';\nimport { OuterSubscriber } from '../OuterSubscriber';\nimport { InnerSubscriber } from '../InnerSubscriber';\nimport { map } from './map';\nimport { from } from '../observable/from';\nexport function mergeMap(project, resultSelector, concurrent) {\n if (concurrent === void 0) {\n concurrent = Number.POSITIVE_INFINITY;\n }\n if (typeof resultSelector === 'function') {\n return function (source) { return source.pipe(mergeMap(function (a, i) { return from(project(a, i)).pipe(map(function (b, ii) { return resultSelector(a, b, i, ii); })); }, concurrent)); };\n }\n else if (typeof resultSelector === 'number') {\n concurrent = resultSelector;\n }\n return function (source) { return source.lift(new MergeMapOperator(project, concurrent)); };\n}\nvar MergeMapOperator = /*@__PURE__*/ (function () {\n function MergeMapOperator(project, concurrent) {\n if (concurrent === void 0) {\n concurrent = Number.POSITIVE_INFINITY;\n }\n this.project = project;\n this.concurrent = concurrent;\n }\n MergeMapOperator.prototype.call = function (observer, source) {\n return source.subscribe(new MergeMapSubscriber(observer, this.project, this.concurrent));\n };\n return MergeMapOperator;\n}());\nexport { MergeMapOperator };\nvar MergeMapSubscriber = /*@__PURE__*/ (function (_super) {\n tslib_1.__extends(MergeMapSubscriber, _super);\n function MergeMapSubscriber(destination, project, concurrent) {\n if (concurrent === void 0) {\n concurrent = Number.POSITIVE_INFINITY;\n }\n var _this = _super.call(this, destination) || this;\n _this.project = project;\n _this.concurrent = concurrent;\n _this.hasCompleted = false;\n _this.buffer = [];\n _this.active = 0;\n _this.index = 0;\n return _this;\n }\n MergeMapSubscriber.prototype._next = function (value) {\n if (this.active < this.concurrent) {\n this._tryNext(value);\n }\n else {\n this.buffer.push(value);\n }\n };\n MergeMapSubscriber.prototype._tryNext = function (value) {\n var result;\n var index = this.index++;\n try {\n result = this.project(value, index);\n }\n catch (err) {\n this.destination.error(err);\n return;\n }\n this.active++;\n this._innerSub(result, value, index);\n };\n MergeMapSubscriber.prototype._innerSub = function (ish, value, index) {\n var innerSubscriber = new InnerSubscriber(this, value, index);\n var destination = this.destination;\n destination.add(innerSubscriber);\n var innerSubscription = subscribeToResult(this, ish, undefined, undefined, innerSubscriber);\n if (innerSubscription !== innerSubscriber) {\n destination.add(innerSubscription);\n }\n };\n MergeMapSubscriber.prototype._complete = function () {\n this.hasCompleted = true;\n if (this.active === 0 && this.buffer.length === 0) {\n this.destination.complete();\n }\n this.unsubscribe();\n };\n MergeMapSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) {\n this.destination.next(innerValue);\n };\n MergeMapSubscriber.prototype.notifyComplete = function (innerSub) {\n var buffer = this.buffer;\n this.remove(innerSub);\n this.active--;\n if (buffer.length > 0) {\n this._next(buffer.shift());\n }\n else if (this.active === 0 && this.hasCompleted) {\n this.destination.complete();\n }\n };\n return MergeMapSubscriber;\n}(OuterSubscriber));\nexport { MergeMapSubscriber };\n//# sourceMappingURL=mergeMap.js.map\n","\"use strict\";\n\nexports.__esModule = true;\nexports[\"default\"] = math;\n\nvar _defaultSymbols = /*#__PURE__*/_interopRequireDefault( /*#__PURE__*/require(\"./presets/defaultSymbols\"));\n\nvar _errors = /*#__PURE__*/_interopRequireDefault( /*#__PURE__*/require(\"../internalHelpers/_errors\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nvar unitRegExp = /((?!\\w)a|na|hc|mc|dg|me[r]?|xe|ni(?![a-zA-Z])|mm|cp|tp|xp|q(?!s)|hv|xamv|nimv|wv|sm|s(?!\\D|$)|ged|darg?|nrut)/g; // Merges additional math functionality into the defaults.\n\nfunction mergeSymbolMaps(additionalSymbols) {\n var symbolMap = {};\n symbolMap.symbols = additionalSymbols ? _extends({}, _defaultSymbols[\"default\"].symbols, additionalSymbols.symbols) : _extends({}, _defaultSymbols[\"default\"].symbols);\n return symbolMap;\n}\n\nfunction exec(operators, values) {\n var _ref;\n\n var op = operators.pop();\n values.push(op.f.apply(op, (_ref = []).concat.apply(_ref, values.splice(-op.argCount))));\n return op.precedence;\n}\n\nfunction calculate(expression, additionalSymbols) {\n var symbolMap = mergeSymbolMaps(additionalSymbols);\n var match;\n var operators = [symbolMap.symbols['('].prefix];\n var values = [];\n var pattern = new RegExp( // Pattern for numbers\n \"\\\\d+(?:\\\\.\\\\d+)?|\" + // ...and patterns for individual operators/function names\n Object.keys(symbolMap.symbols).map(function (key) {\n return symbolMap.symbols[key];\n }) // longer symbols should be listed first\n // $FlowFixMe\n .sort(function (a, b) {\n return b.symbol.length - a.symbol.length;\n }) // $FlowFixMe\n .map(function (val) {\n return val.regSymbol;\n }).join('|') + \"|(\\\\S)\", 'g');\n pattern.lastIndex = 0; // Reset regular expression object\n\n var afterValue = false;\n\n do {\n match = pattern.exec(expression);\n\n var _ref2 = match || [')', undefined],\n token = _ref2[0],\n bad = _ref2[1];\n\n var notNumber = symbolMap.symbols[token];\n var notNewValue = notNumber && !notNumber.prefix && !notNumber.func;\n var notAfterValue = !notNumber || !notNumber.postfix && !notNumber.infix; // Check for syntax errors:\n\n if (bad || (afterValue ? notAfterValue : notNewValue)) {\n throw new _errors[\"default\"](37, match ? match.index : expression.length, expression);\n }\n\n if (afterValue) {\n // We either have an infix or postfix operator (they should be mutually exclusive)\n var curr = notNumber.postfix || notNumber.infix;\n\n do {\n var prev = operators[operators.length - 1];\n if ((curr.precedence - prev.precedence || prev.rightToLeft) > 0) break; // Apply previous operator, since it has precedence over current one\n } while (exec(operators, values)); // Exit loop after executing an opening parenthesis or function\n\n\n afterValue = curr.notation === 'postfix';\n\n if (curr.symbol !== ')') {\n operators.push(curr); // Postfix always has precedence over any operator that follows after it\n\n if (afterValue) exec(operators, values);\n }\n } else if (notNumber) {\n // prefix operator or function\n operators.push(notNumber.prefix || notNumber.func);\n\n if (notNumber.func) {\n // Require an opening parenthesis\n match = pattern.exec(expression);\n\n if (!match || match[0] !== '(') {\n throw new _errors[\"default\"](38, match ? match.index : expression.length, expression);\n }\n }\n } else {\n // number\n values.push(+token);\n afterValue = true;\n }\n } while (match && operators.length);\n\n if (operators.length) {\n throw new _errors[\"default\"](39, match ? match.index : expression.length, expression);\n } else if (match) {\n throw new _errors[\"default\"](40, match ? match.index : expression.length, expression);\n } else {\n return values.pop();\n }\n}\n\nfunction reverseString(str) {\n return str.split('').reverse().join('');\n}\n/**\n * Helper for doing math with CSS Units. Accepts a formula as a string. All values in the formula must have the same unit (or be unitless). Supports complex formulas utliziing addition, subtraction, multiplication, division, square root, powers, factorial, min, max, as well as parentheses for order of operation.\n *\n *In cases where you need to do calculations with mixed units where one unit is a [relative length unit](https://developer.mozilla.org/en-US/docs/Web/CSS/length#Relative_length_units), you will want to use [CSS Calc](https://developer.mozilla.org/en-US/docs/Web/CSS/calc).\n *\n * *warning* While we've done everything possible to ensure math safely evalutes formulas expressed as strings, you should always use extreme caution when passing `math` user provided values.\n * @example\n * // Styles as object usage\n * const styles = {\n * fontSize: math('12rem + 8rem'),\n * fontSize: math('(12px + 2px) * 3'),\n * fontSize: math('3px^2 + sqrt(4)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * fontSize: ${math('12rem + 8rem')};\n * fontSize: ${math('(12px + 2px) * 3')};\n * fontSize: ${math('3px^2 + sqrt(4)')};\n * `\n *\n * // CSS as JS Output\n *\n * div: {\n * fontSize: '20rem',\n * fontSize: '42px',\n * fontSize: '11px',\n * }\n */\n\n\nfunction math(formula, additionalSymbols) {\n var reversedFormula = reverseString(formula);\n var formulaMatch = reversedFormula.match(unitRegExp); // Check that all units are the same\n\n if (formulaMatch && !formulaMatch.every(function (unit) {\n return unit === formulaMatch[0];\n })) {\n throw new _errors[\"default\"](41);\n }\n\n var cleanFormula = reverseString(reversedFormula.replace(unitRegExp, ''));\n return \"\" + calculate(cleanFormula, additionalSymbols) + (formulaMatch ? reverseString(formulaMatch[0]) : '');\n}\n\nmodule.exports = exports.default;","//\n\nmodule.exports = function shallowEqual(objA, objB, compare, compareContext) {\n var ret = compare ? compare.call(compareContext, objA, objB) : void 0;\n\n if (ret !== void 0) {\n return !!ret;\n }\n\n if (objA === objB) {\n return true;\n }\n\n if (typeof objA !== \"object\" || !objA || typeof objB !== \"object\" || !objB) {\n return false;\n }\n\n var keysA = Object.keys(objA);\n var keysB = Object.keys(objB);\n\n if (keysA.length !== keysB.length) {\n return false;\n }\n\n var bHasOwnProperty = Object.prototype.hasOwnProperty.bind(objB);\n\n // Test for A's keys different from B.\n for (var idx = 0; idx < keysA.length; idx++) {\n var key = keysA[idx];\n\n if (!bHasOwnProperty(key)) {\n return false;\n }\n\n var valueA = objA[key];\n var valueB = objB[key];\n\n ret = compare ? compare.call(compareContext, valueA, valueB, key) : void 0;\n\n if (ret === false || (ret === void 0 && valueA !== valueB)) {\n return false;\n }\n }\n\n return true;\n};\n","function stylis_min (W) {\n function M(d, c, e, h, a) {\n for (var m = 0, b = 0, v = 0, n = 0, q, g, x = 0, K = 0, k, u = k = q = 0, l = 0, r = 0, I = 0, t = 0, B = e.length, J = B - 1, y, f = '', p = '', F = '', G = '', C; l < B;) {\n g = e.charCodeAt(l);\n l === J && 0 !== b + n + v + m && (0 !== b && (g = 47 === b ? 10 : 47), n = v = m = 0, B++, J++);\n\n if (0 === b + n + v + m) {\n if (l === J && (0 < r && (f = f.replace(N, '')), 0 < f.trim().length)) {\n switch (g) {\n case 32:\n case 9:\n case 59:\n case 13:\n case 10:\n break;\n\n default:\n f += e.charAt(l);\n }\n\n g = 59;\n }\n\n switch (g) {\n case 123:\n f = f.trim();\n q = f.charCodeAt(0);\n k = 1;\n\n for (t = ++l; l < B;) {\n switch (g = e.charCodeAt(l)) {\n case 123:\n k++;\n break;\n\n case 125:\n k--;\n break;\n\n case 47:\n switch (g = e.charCodeAt(l + 1)) {\n case 42:\n case 47:\n a: {\n for (u = l + 1; u < J; ++u) {\n switch (e.charCodeAt(u)) {\n case 47:\n if (42 === g && 42 === e.charCodeAt(u - 1) && l + 2 !== u) {\n l = u + 1;\n break a;\n }\n\n break;\n\n case 10:\n if (47 === g) {\n l = u + 1;\n break a;\n }\n\n }\n }\n\n l = u;\n }\n\n }\n\n break;\n\n case 91:\n g++;\n\n case 40:\n g++;\n\n case 34:\n case 39:\n for (; l++ < J && e.charCodeAt(l) !== g;) {\n }\n\n }\n\n if (0 === k) break;\n l++;\n }\n\n k = e.substring(t, l);\n 0 === q && (q = (f = f.replace(ca, '').trim()).charCodeAt(0));\n\n switch (q) {\n case 64:\n 0 < r && (f = f.replace(N, ''));\n g = f.charCodeAt(1);\n\n switch (g) {\n case 100:\n case 109:\n case 115:\n case 45:\n r = c;\n break;\n\n default:\n r = O;\n }\n\n k = M(c, r, k, g, a + 1);\n t = k.length;\n 0 < A && (r = X(O, f, I), C = H(3, k, r, c, D, z, t, g, a, h), f = r.join(''), void 0 !== C && 0 === (t = (k = C.trim()).length) && (g = 0, k = ''));\n if (0 < t) switch (g) {\n case 115:\n f = f.replace(da, ea);\n\n case 100:\n case 109:\n case 45:\n k = f + '{' + k + '}';\n break;\n\n case 107:\n f = f.replace(fa, '$1 $2');\n k = f + '{' + k + '}';\n k = 1 === w || 2 === w && L('@' + k, 3) ? '@-webkit-' + k + '@' + k : '@' + k;\n break;\n\n default:\n k = f + k, 112 === h && (k = (p += k, ''));\n } else k = '';\n break;\n\n default:\n k = M(c, X(c, f, I), k, h, a + 1);\n }\n\n F += k;\n k = I = r = u = q = 0;\n f = '';\n g = e.charCodeAt(++l);\n break;\n\n case 125:\n case 59:\n f = (0 < r ? f.replace(N, '') : f).trim();\n if (1 < (t = f.length)) switch (0 === u && (q = f.charCodeAt(0), 45 === q || 96 < q && 123 > q) && (t = (f = f.replace(' ', ':')).length), 0 < A && void 0 !== (C = H(1, f, c, d, D, z, p.length, h, a, h)) && 0 === (t = (f = C.trim()).length) && (f = '\\x00\\x00'), q = f.charCodeAt(0), g = f.charCodeAt(1), q) {\n case 0:\n break;\n\n case 64:\n if (105 === g || 99 === g) {\n G += f + e.charAt(l);\n break;\n }\n\n default:\n 58 !== f.charCodeAt(t - 1) && (p += P(f, q, g, f.charCodeAt(2)));\n }\n I = r = u = q = 0;\n f = '';\n g = e.charCodeAt(++l);\n }\n }\n\n switch (g) {\n case 13:\n case 10:\n 47 === b ? b = 0 : 0 === 1 + q && 107 !== h && 0 < f.length && (r = 1, f += '\\x00');\n 0 < A * Y && H(0, f, c, d, D, z, p.length, h, a, h);\n z = 1;\n D++;\n break;\n\n case 59:\n case 125:\n if (0 === b + n + v + m) {\n z++;\n break;\n }\n\n default:\n z++;\n y = e.charAt(l);\n\n switch (g) {\n case 9:\n case 32:\n if (0 === n + m + b) switch (x) {\n case 44:\n case 58:\n case 9:\n case 32:\n y = '';\n break;\n\n default:\n 32 !== g && (y = ' ');\n }\n break;\n\n case 0:\n y = '\\\\0';\n break;\n\n case 12:\n y = '\\\\f';\n break;\n\n case 11:\n y = '\\\\v';\n break;\n\n case 38:\n 0 === n + b + m && (r = I = 1, y = '\\f' + y);\n break;\n\n case 108:\n if (0 === n + b + m + E && 0 < u) switch (l - u) {\n case 2:\n 112 === x && 58 === e.charCodeAt(l - 3) && (E = x);\n\n case 8:\n 111 === K && (E = K);\n }\n break;\n\n case 58:\n 0 === n + b + m && (u = l);\n break;\n\n case 44:\n 0 === b + v + n + m && (r = 1, y += '\\r');\n break;\n\n case 34:\n case 39:\n 0 === b && (n = n === g ? 0 : 0 === n ? g : n);\n break;\n\n case 91:\n 0 === n + b + v && m++;\n break;\n\n case 93:\n 0 === n + b + v && m--;\n break;\n\n case 41:\n 0 === n + b + m && v--;\n break;\n\n case 40:\n if (0 === n + b + m) {\n if (0 === q) switch (2 * x + 3 * K) {\n case 533:\n break;\n\n default:\n q = 1;\n }\n v++;\n }\n\n break;\n\n case 64:\n 0 === b + v + n + m + u + k && (k = 1);\n break;\n\n case 42:\n case 47:\n if (!(0 < n + m + v)) switch (b) {\n case 0:\n switch (2 * g + 3 * e.charCodeAt(l + 1)) {\n case 235:\n b = 47;\n break;\n\n case 220:\n t = l, b = 42;\n }\n\n break;\n\n case 42:\n 47 === g && 42 === x && t + 2 !== l && (33 === e.charCodeAt(t + 2) && (p += e.substring(t, l + 1)), y = '', b = 0);\n }\n }\n\n 0 === b && (f += y);\n }\n\n K = x;\n x = g;\n l++;\n }\n\n t = p.length;\n\n if (0 < t) {\n r = c;\n if (0 < A && (C = H(2, p, r, d, D, z, t, h, a, h), void 0 !== C && 0 === (p = C).length)) return G + p + F;\n p = r.join(',') + '{' + p + '}';\n\n if (0 !== w * E) {\n 2 !== w || L(p, 2) || (E = 0);\n\n switch (E) {\n case 111:\n p = p.replace(ha, ':-moz-$1') + p;\n break;\n\n case 112:\n p = p.replace(Q, '::-webkit-input-$1') + p.replace(Q, '::-moz-$1') + p.replace(Q, ':-ms-input-$1') + p;\n }\n\n E = 0;\n }\n }\n\n return G + p + F;\n }\n\n function X(d, c, e) {\n var h = c.trim().split(ia);\n c = h;\n var a = h.length,\n m = d.length;\n\n switch (m) {\n case 0:\n case 1:\n var b = 0;\n\n for (d = 0 === m ? '' : d[0] + ' '; b < a; ++b) {\n c[b] = Z(d, c[b], e).trim();\n }\n\n break;\n\n default:\n var v = b = 0;\n\n for (c = []; b < a; ++b) {\n for (var n = 0; n < m; ++n) {\n c[v++] = Z(d[n] + ' ', h[b], e).trim();\n }\n }\n\n }\n\n return c;\n }\n\n function Z(d, c, e) {\n var h = c.charCodeAt(0);\n 33 > h && (h = (c = c.trim()).charCodeAt(0));\n\n switch (h) {\n case 38:\n return c.replace(F, '$1' + d.trim());\n\n case 58:\n return d.trim() + c.replace(F, '$1' + d.trim());\n\n default:\n if (0 < 1 * e && 0 < c.indexOf('\\f')) return c.replace(F, (58 === d.charCodeAt(0) ? '' : '$1') + d.trim());\n }\n\n return d + c;\n }\n\n function P(d, c, e, h) {\n var a = d + ';',\n m = 2 * c + 3 * e + 4 * h;\n\n if (944 === m) {\n d = a.indexOf(':', 9) + 1;\n var b = a.substring(d, a.length - 1).trim();\n b = a.substring(0, d).trim() + b + ';';\n return 1 === w || 2 === w && L(b, 1) ? '-webkit-' + b + b : b;\n }\n\n if (0 === w || 2 === w && !L(a, 1)) return a;\n\n switch (m) {\n case 1015:\n return 97 === a.charCodeAt(10) ? '-webkit-' + a + a : a;\n\n case 951:\n return 116 === a.charCodeAt(3) ? '-webkit-' + a + a : a;\n\n case 963:\n return 110 === a.charCodeAt(5) ? '-webkit-' + a + a : a;\n\n case 1009:\n if (100 !== a.charCodeAt(4)) break;\n\n case 969:\n case 942:\n return '-webkit-' + a + a;\n\n case 978:\n return '-webkit-' + a + '-moz-' + a + a;\n\n case 1019:\n case 983:\n return '-webkit-' + a + '-moz-' + a + '-ms-' + a + a;\n\n case 883:\n if (45 === a.charCodeAt(8)) return '-webkit-' + a + a;\n if (0 < a.indexOf('image-set(', 11)) return a.replace(ja, '$1-webkit-$2') + a;\n break;\n\n case 932:\n if (45 === a.charCodeAt(4)) switch (a.charCodeAt(5)) {\n case 103:\n return '-webkit-box-' + a.replace('-grow', '') + '-webkit-' + a + '-ms-' + a.replace('grow', 'positive') + a;\n\n case 115:\n return '-webkit-' + a + '-ms-' + a.replace('shrink', 'negative') + a;\n\n case 98:\n return '-webkit-' + a + '-ms-' + a.replace('basis', 'preferred-size') + a;\n }\n return '-webkit-' + a + '-ms-' + a + a;\n\n case 964:\n return '-webkit-' + a + '-ms-flex-' + a + a;\n\n case 1023:\n if (99 !== a.charCodeAt(8)) break;\n b = a.substring(a.indexOf(':', 15)).replace('flex-', '').replace('space-between', 'justify');\n return '-webkit-box-pack' + b + '-webkit-' + a + '-ms-flex-pack' + b + a;\n\n case 1005:\n return ka.test(a) ? a.replace(aa, ':-webkit-') + a.replace(aa, ':-moz-') + a : a;\n\n case 1e3:\n b = a.substring(13).trim();\n c = b.indexOf('-') + 1;\n\n switch (b.charCodeAt(0) + b.charCodeAt(c)) {\n case 226:\n b = a.replace(G, 'tb');\n break;\n\n case 232:\n b = a.replace(G, 'tb-rl');\n break;\n\n case 220:\n b = a.replace(G, 'lr');\n break;\n\n default:\n return a;\n }\n\n return '-webkit-' + a + '-ms-' + b + a;\n\n case 1017:\n if (-1 === a.indexOf('sticky', 9)) break;\n\n case 975:\n c = (a = d).length - 10;\n b = (33 === a.charCodeAt(c) ? a.substring(0, c) : a).substring(d.indexOf(':', 7) + 1).trim();\n\n switch (m = b.charCodeAt(0) + (b.charCodeAt(7) | 0)) {\n case 203:\n if (111 > b.charCodeAt(8)) break;\n\n case 115:\n a = a.replace(b, '-webkit-' + b) + ';' + a;\n break;\n\n case 207:\n case 102:\n a = a.replace(b, '-webkit-' + (102 < m ? 'inline-' : '') + 'box') + ';' + a.replace(b, '-webkit-' + b) + ';' + a.replace(b, '-ms-' + b + 'box') + ';' + a;\n }\n\n return a + ';';\n\n case 938:\n if (45 === a.charCodeAt(5)) switch (a.charCodeAt(6)) {\n case 105:\n return b = a.replace('-items', ''), '-webkit-' + a + '-webkit-box-' + b + '-ms-flex-' + b + a;\n\n case 115:\n return '-webkit-' + a + '-ms-flex-item-' + a.replace(ba, '') + a;\n\n default:\n return '-webkit-' + a + '-ms-flex-line-pack' + a.replace('align-content', '').replace(ba, '') + a;\n }\n break;\n\n case 973:\n case 989:\n if (45 !== a.charCodeAt(3) || 122 === a.charCodeAt(4)) break;\n\n case 931:\n case 953:\n if (!0 === la.test(d)) return 115 === (b = d.substring(d.indexOf(':') + 1)).charCodeAt(0) ? P(d.replace('stretch', 'fill-available'), c, e, h).replace(':fill-available', ':stretch') : a.replace(b, '-webkit-' + b) + a.replace(b, '-moz-' + b.replace('fill-', '')) + a;\n break;\n\n case 962:\n if (a = '-webkit-' + a + (102 === a.charCodeAt(5) ? '-ms-' + a : '') + a, 211 === e + h && 105 === a.charCodeAt(13) && 0 < a.indexOf('transform', 10)) return a.substring(0, a.indexOf(';', 27) + 1).replace(ma, '$1-webkit-$2') + a;\n }\n\n return a;\n }\n\n function L(d, c) {\n var e = d.indexOf(1 === c ? ':' : '{'),\n h = d.substring(0, 3 !== c ? e : 10);\n e = d.substring(e + 1, d.length - 1);\n return R(2 !== c ? h : h.replace(na, '$1'), e, c);\n }\n\n function ea(d, c) {\n var e = P(c, c.charCodeAt(0), c.charCodeAt(1), c.charCodeAt(2));\n return e !== c + ';' ? e.replace(oa, ' or ($1)').substring(4) : '(' + c + ')';\n }\n\n function H(d, c, e, h, a, m, b, v, n, q) {\n for (var g = 0, x = c, w; g < A; ++g) {\n switch (w = S[g].call(B, d, x, e, h, a, m, b, v, n, q)) {\n case void 0:\n case !1:\n case !0:\n case null:\n break;\n\n default:\n x = w;\n }\n }\n\n if (x !== c) return x;\n }\n\n function T(d) {\n switch (d) {\n case void 0:\n case null:\n A = S.length = 0;\n break;\n\n default:\n if ('function' === typeof d) S[A++] = d;else if ('object' === typeof d) for (var c = 0, e = d.length; c < e; ++c) {\n T(d[c]);\n } else Y = !!d | 0;\n }\n\n return T;\n }\n\n function U(d) {\n d = d.prefix;\n void 0 !== d && (R = null, d ? 'function' !== typeof d ? w = 1 : (w = 2, R = d) : w = 0);\n return U;\n }\n\n function B(d, c) {\n var e = d;\n 33 > e.charCodeAt(0) && (e = e.trim());\n V = e;\n e = [V];\n\n if (0 < A) {\n var h = H(-1, c, e, e, D, z, 0, 0, 0, 0);\n void 0 !== h && 'string' === typeof h && (c = h);\n }\n\n var a = M(O, e, c, 0, 0);\n 0 < A && (h = H(-2, a, e, e, D, z, a.length, 0, 0, 0), void 0 !== h && (a = h));\n V = '';\n E = 0;\n z = D = 1;\n return a;\n }\n\n var ca = /^\\0+/g,\n N = /[\\0\\r\\f]/g,\n aa = /: */g,\n ka = /zoo|gra/,\n ma = /([,: ])(transform)/g,\n ia = /,\\r+?/g,\n F = /([\\t\\r\\n ])*\\f?&/g,\n fa = /@(k\\w+)\\s*(\\S*)\\s*/,\n Q = /::(place)/g,\n ha = /:(read-only)/g,\n G = /[svh]\\w+-[tblr]{2}/,\n da = /\\(\\s*(.*)\\s*\\)/g,\n oa = /([\\s\\S]*?);/g,\n ba = /-self|flex-/g,\n na = /[^]*?(:[rp][el]a[\\w-]+)[^]*/,\n la = /stretch|:\\s*\\w+\\-(?:conte|avail)/,\n ja = /([^-])(image-set\\()/,\n z = 1,\n D = 1,\n E = 0,\n w = 1,\n O = [],\n S = [],\n A = 0,\n R = null,\n Y = 0,\n V = '';\n B.use = T;\n B.set = U;\n void 0 !== W && U(W);\n return B;\n}\n\nexport default stylis_min;\n","var unitlessKeys = {\n animationIterationCount: 1,\n borderImageOutset: 1,\n borderImageSlice: 1,\n borderImageWidth: 1,\n boxFlex: 1,\n boxFlexGroup: 1,\n boxOrdinalGroup: 1,\n columnCount: 1,\n columns: 1,\n flex: 1,\n flexGrow: 1,\n flexPositive: 1,\n flexShrink: 1,\n flexNegative: 1,\n flexOrder: 1,\n gridRow: 1,\n gridRowEnd: 1,\n gridRowSpan: 1,\n gridRowStart: 1,\n gridColumn: 1,\n gridColumnEnd: 1,\n gridColumnSpan: 1,\n gridColumnStart: 1,\n msGridRow: 1,\n msGridRowSpan: 1,\n msGridColumn: 1,\n msGridColumnSpan: 1,\n fontWeight: 1,\n lineHeight: 1,\n opacity: 1,\n order: 1,\n orphans: 1,\n tabSize: 1,\n widows: 1,\n zIndex: 1,\n zoom: 1,\n WebkitLineClamp: 1,\n // SVG-related properties\n fillOpacity: 1,\n floodOpacity: 1,\n stopOpacity: 1,\n strokeDasharray: 1,\n strokeDashoffset: 1,\n strokeMiterlimit: 1,\n strokeOpacity: 1,\n strokeWidth: 1\n};\n\nexport default unitlessKeys;\n","var objectKeys = require('object-keys');\nvar isArguments = require('is-arguments');\nvar is = require('object-is');\nvar isRegex = require('is-regex');\nvar flags = require('regexp.prototype.flags');\nvar isDate = require('is-date-object');\n\nvar getTime = Date.prototype.getTime;\n\nfunction deepEqual(actual, expected, options) {\n var opts = options || {};\n\n // 7.1. All identical values are equivalent, as determined by ===.\n if (opts.strict ? is(actual, expected) : actual === expected) {\n return true;\n }\n\n // 7.3. Other pairs that do not both pass typeof value == 'object', equivalence is determined by ==.\n if (!actual || !expected || (typeof actual !== 'object' && typeof expected !== 'object')) {\n return opts.strict ? is(actual, expected) : actual == expected;\n }\n\n /*\n * 7.4. For all other Object pairs, including Array objects, equivalence is\n * determined by having the same number of owned properties (as verified\n * with Object.prototype.hasOwnProperty.call), the same set of keys\n * (although not necessarily the same order), equivalent values for every\n * corresponding key, and an identical 'prototype' property. Note: this\n * accounts for both named and indexed properties on Arrays.\n */\n // eslint-disable-next-line no-use-before-define\n return objEquiv(actual, expected, opts);\n}\n\nfunction isUndefinedOrNull(value) {\n return value === null || value === undefined;\n}\n\nfunction isBuffer(x) {\n if (!x || typeof x !== 'object' || typeof x.length !== 'number') {\n return false;\n }\n if (typeof x.copy !== 'function' || typeof x.slice !== 'function') {\n return false;\n }\n if (x.length > 0 && typeof x[0] !== 'number') {\n return false;\n }\n return true;\n}\n\nfunction objEquiv(a, b, opts) {\n /* eslint max-statements: [2, 50] */\n var i, key;\n if (typeof a !== typeof b) { return false; }\n if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) { return false; }\n\n // an identical 'prototype' property.\n if (a.prototype !== b.prototype) { return false; }\n\n if (isArguments(a) !== isArguments(b)) { return false; }\n\n var aIsRegex = isRegex(a);\n var bIsRegex = isRegex(b);\n if (aIsRegex !== bIsRegex) { return false; }\n if (aIsRegex || bIsRegex) {\n return a.source === b.source && flags(a) === flags(b);\n }\n\n if (isDate(a) && isDate(b)) {\n return getTime.call(a) === getTime.call(b);\n }\n\n var aIsBuffer = isBuffer(a);\n var bIsBuffer = isBuffer(b);\n if (aIsBuffer !== bIsBuffer) { return false; }\n if (aIsBuffer || bIsBuffer) { // && would work too, because both are true or both false here\n if (a.length !== b.length) { return false; }\n for (i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) { return false; }\n }\n return true;\n }\n\n if (typeof a !== typeof b) { return false; }\n\n try {\n var ka = objectKeys(a);\n var kb = objectKeys(b);\n } catch (e) { // happens when one is a string literal and the other isn't\n return false;\n }\n // having the same number of owned properties (keys incorporates hasOwnProperty)\n if (ka.length !== kb.length) { return false; }\n\n // the same set of keys (although not necessarily the same order),\n ka.sort();\n kb.sort();\n // ~~~cheap key test\n for (i = ka.length - 1; i >= 0; i--) {\n if (ka[i] != kb[i]) { return false; }\n }\n // equivalent values for every corresponding key, and ~~~possibly expensive deep test\n for (i = ka.length - 1; i >= 0; i--) {\n key = ka[i];\n if (!deepEqual(a[key], b[key], opts)) { return false; }\n }\n\n return true;\n}\n\nmodule.exports = deepEqual;\n","var global = typeof self !== 'undefined' ? self : this;\nvar __self__ = (function () {\nfunction F() {\nthis.fetch = false;\nthis.DOMException = global.DOMException\n}\nF.prototype = global;\nreturn new F();\n})();\n(function(self) {\n\nvar irrelevant = (function (exports) {\n\n var support = {\n searchParams: 'URLSearchParams' in self,\n iterable: 'Symbol' in self && 'iterator' in Symbol,\n blob:\n 'FileReader' in self &&\n 'Blob' in self &&\n (function() {\n try {\n new Blob();\n return true\n } catch (e) {\n return false\n }\n })(),\n formData: 'FormData' in self,\n arrayBuffer: 'ArrayBuffer' in self\n };\n\n function isDataView(obj) {\n return obj && DataView.prototype.isPrototypeOf(obj)\n }\n\n if (support.arrayBuffer) {\n var viewClasses = [\n '[object Int8Array]',\n '[object Uint8Array]',\n '[object Uint8ClampedArray]',\n '[object Int16Array]',\n '[object Uint16Array]',\n '[object Int32Array]',\n '[object Uint32Array]',\n '[object Float32Array]',\n '[object Float64Array]'\n ];\n\n var isArrayBufferView =\n ArrayBuffer.isView ||\n function(obj) {\n return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1\n };\n }\n\n function normalizeName(name) {\n if (typeof name !== 'string') {\n name = String(name);\n }\n if (/[^a-z0-9\\-#$%&'*+.^_`|~]/i.test(name)) {\n throw new TypeError('Invalid character in header field name')\n }\n return name.toLowerCase()\n }\n\n function normalizeValue(value) {\n if (typeof value !== 'string') {\n value = String(value);\n }\n return value\n }\n\n // Build a destructive iterator for the value list\n function iteratorFor(items) {\n var iterator = {\n next: function() {\n var value = items.shift();\n return {done: value === undefined, value: value}\n }\n };\n\n if (support.iterable) {\n iterator[Symbol.iterator] = function() {\n return iterator\n };\n }\n\n return iterator\n }\n\n function Headers(headers) {\n this.map = {};\n\n if (headers instanceof Headers) {\n headers.forEach(function(value, name) {\n this.append(name, value);\n }, this);\n } else if (Array.isArray(headers)) {\n headers.forEach(function(header) {\n this.append(header[0], header[1]);\n }, this);\n } else if (headers) {\n Object.getOwnPropertyNames(headers).forEach(function(name) {\n this.append(name, headers[name]);\n }, this);\n }\n }\n\n Headers.prototype.append = function(name, value) {\n name = normalizeName(name);\n value = normalizeValue(value);\n var oldValue = this.map[name];\n this.map[name] = oldValue ? oldValue + ', ' + value : value;\n };\n\n Headers.prototype['delete'] = function(name) {\n delete this.map[normalizeName(name)];\n };\n\n Headers.prototype.get = function(name) {\n name = normalizeName(name);\n return this.has(name) ? this.map[name] : null\n };\n\n Headers.prototype.has = function(name) {\n return this.map.hasOwnProperty(normalizeName(name))\n };\n\n Headers.prototype.set = function(name, value) {\n this.map[normalizeName(name)] = normalizeValue(value);\n };\n\n Headers.prototype.forEach = function(callback, thisArg) {\n for (var name in this.map) {\n if (this.map.hasOwnProperty(name)) {\n callback.call(thisArg, this.map[name], name, this);\n }\n }\n };\n\n Headers.prototype.keys = function() {\n var items = [];\n this.forEach(function(value, name) {\n items.push(name);\n });\n return iteratorFor(items)\n };\n\n Headers.prototype.values = function() {\n var items = [];\n this.forEach(function(value) {\n items.push(value);\n });\n return iteratorFor(items)\n };\n\n Headers.prototype.entries = function() {\n var items = [];\n this.forEach(function(value, name) {\n items.push([name, value]);\n });\n return iteratorFor(items)\n };\n\n if (support.iterable) {\n Headers.prototype[Symbol.iterator] = Headers.prototype.entries;\n }\n\n function consumed(body) {\n if (body.bodyUsed) {\n return Promise.reject(new TypeError('Already read'))\n }\n body.bodyUsed = true;\n }\n\n function fileReaderReady(reader) {\n return new Promise(function(resolve, reject) {\n reader.onload = function() {\n resolve(reader.result);\n };\n reader.onerror = function() {\n reject(reader.error);\n };\n })\n }\n\n function readBlobAsArrayBuffer(blob) {\n var reader = new FileReader();\n var promise = fileReaderReady(reader);\n reader.readAsArrayBuffer(blob);\n return promise\n }\n\n function readBlobAsText(blob) {\n var reader = new FileReader();\n var promise = fileReaderReady(reader);\n reader.readAsText(blob);\n return promise\n }\n\n function readArrayBufferAsText(buf) {\n var view = new Uint8Array(buf);\n var chars = new Array(view.length);\n\n for (var i = 0; i < view.length; i++) {\n chars[i] = String.fromCharCode(view[i]);\n }\n return chars.join('')\n }\n\n function bufferClone(buf) {\n if (buf.slice) {\n return buf.slice(0)\n } else {\n var view = new Uint8Array(buf.byteLength);\n view.set(new Uint8Array(buf));\n return view.buffer\n }\n }\n\n function Body() {\n this.bodyUsed = false;\n\n this._initBody = function(body) {\n this._bodyInit = body;\n if (!body) {\n this._bodyText = '';\n } else if (typeof body === 'string') {\n this._bodyText = body;\n } else if (support.blob && Blob.prototype.isPrototypeOf(body)) {\n this._bodyBlob = body;\n } else if (support.formData && FormData.prototype.isPrototypeOf(body)) {\n this._bodyFormData = body;\n } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {\n this._bodyText = body.toString();\n } else if (support.arrayBuffer && support.blob && isDataView(body)) {\n this._bodyArrayBuffer = bufferClone(body.buffer);\n // IE 10-11 can't handle a DataView body.\n this._bodyInit = new Blob([this._bodyArrayBuffer]);\n } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {\n this._bodyArrayBuffer = bufferClone(body);\n } else {\n this._bodyText = body = Object.prototype.toString.call(body);\n }\n\n if (!this.headers.get('content-type')) {\n if (typeof body === 'string') {\n this.headers.set('content-type', 'text/plain;charset=UTF-8');\n } else if (this._bodyBlob && this._bodyBlob.type) {\n this.headers.set('content-type', this._bodyBlob.type);\n } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {\n this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');\n }\n }\n };\n\n if (support.blob) {\n this.blob = function() {\n var rejected = consumed(this);\n if (rejected) {\n return rejected\n }\n\n if (this._bodyBlob) {\n return Promise.resolve(this._bodyBlob)\n } else if (this._bodyArrayBuffer) {\n return Promise.resolve(new Blob([this._bodyArrayBuffer]))\n } else if (this._bodyFormData) {\n throw new Error('could not read FormData body as blob')\n } else {\n return Promise.resolve(new Blob([this._bodyText]))\n }\n };\n\n this.arrayBuffer = function() {\n if (this._bodyArrayBuffer) {\n return consumed(this) || Promise.resolve(this._bodyArrayBuffer)\n } else {\n return this.blob().then(readBlobAsArrayBuffer)\n }\n };\n }\n\n this.text = function() {\n var rejected = consumed(this);\n if (rejected) {\n return rejected\n }\n\n if (this._bodyBlob) {\n return readBlobAsText(this._bodyBlob)\n } else if (this._bodyArrayBuffer) {\n return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer))\n } else if (this._bodyFormData) {\n throw new Error('could not read FormData body as text')\n } else {\n return Promise.resolve(this._bodyText)\n }\n };\n\n if (support.formData) {\n this.formData = function() {\n return this.text().then(decode)\n };\n }\n\n this.json = function() {\n return this.text().then(JSON.parse)\n };\n\n return this\n }\n\n // HTTP methods whose capitalization should be normalized\n var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT'];\n\n function normalizeMethod(method) {\n var upcased = method.toUpperCase();\n return methods.indexOf(upcased) > -1 ? upcased : method\n }\n\n function Request(input, options) {\n options = options || {};\n var body = options.body;\n\n if (input instanceof Request) {\n if (input.bodyUsed) {\n throw new TypeError('Already read')\n }\n this.url = input.url;\n this.credentials = input.credentials;\n if (!options.headers) {\n this.headers = new Headers(input.headers);\n }\n this.method = input.method;\n this.mode = input.mode;\n this.signal = input.signal;\n if (!body && input._bodyInit != null) {\n body = input._bodyInit;\n input.bodyUsed = true;\n }\n } else {\n this.url = String(input);\n }\n\n this.credentials = options.credentials || this.credentials || 'same-origin';\n if (options.headers || !this.headers) {\n this.headers = new Headers(options.headers);\n }\n this.method = normalizeMethod(options.method || this.method || 'GET');\n this.mode = options.mode || this.mode || null;\n this.signal = options.signal || this.signal;\n this.referrer = null;\n\n if ((this.method === 'GET' || this.method === 'HEAD') && body) {\n throw new TypeError('Body not allowed for GET or HEAD requests')\n }\n this._initBody(body);\n }\n\n Request.prototype.clone = function() {\n return new Request(this, {body: this._bodyInit})\n };\n\n function decode(body) {\n var form = new FormData();\n body\n .trim()\n .split('&')\n .forEach(function(bytes) {\n if (bytes) {\n var split = bytes.split('=');\n var name = split.shift().replace(/\\+/g, ' ');\n var value = split.join('=').replace(/\\+/g, ' ');\n form.append(decodeURIComponent(name), decodeURIComponent(value));\n }\n });\n return form\n }\n\n function parseHeaders(rawHeaders) {\n var headers = new Headers();\n // Replace instances of \\r\\n and \\n followed by at least one space or horizontal tab with a space\n // https://tools.ietf.org/html/rfc7230#section-3.2\n var preProcessedHeaders = rawHeaders.replace(/\\r?\\n[\\t ]+/g, ' ');\n preProcessedHeaders.split(/\\r?\\n/).forEach(function(line) {\n var parts = line.split(':');\n var key = parts.shift().trim();\n if (key) {\n var value = parts.join(':').trim();\n headers.append(key, value);\n }\n });\n return headers\n }\n\n Body.call(Request.prototype);\n\n function Response(bodyInit, options) {\n if (!options) {\n options = {};\n }\n\n this.type = 'default';\n this.status = options.status === undefined ? 200 : options.status;\n this.ok = this.status >= 200 && this.status < 300;\n this.statusText = 'statusText' in options ? options.statusText : 'OK';\n this.headers = new Headers(options.headers);\n this.url = options.url || '';\n this._initBody(bodyInit);\n }\n\n Body.call(Response.prototype);\n\n Response.prototype.clone = function() {\n return new Response(this._bodyInit, {\n status: this.status,\n statusText: this.statusText,\n headers: new Headers(this.headers),\n url: this.url\n })\n };\n\n Response.error = function() {\n var response = new Response(null, {status: 0, statusText: ''});\n response.type = 'error';\n return response\n };\n\n var redirectStatuses = [301, 302, 303, 307, 308];\n\n Response.redirect = function(url, status) {\n if (redirectStatuses.indexOf(status) === -1) {\n throw new RangeError('Invalid status code')\n }\n\n return new Response(null, {status: status, headers: {location: url}})\n };\n\n exports.DOMException = self.DOMException;\n try {\n new exports.DOMException();\n } catch (err) {\n exports.DOMException = function(message, name) {\n this.message = message;\n this.name = name;\n var error = Error(message);\n this.stack = error.stack;\n };\n exports.DOMException.prototype = Object.create(Error.prototype);\n exports.DOMException.prototype.constructor = exports.DOMException;\n }\n\n function fetch(input, init) {\n return new Promise(function(resolve, reject) {\n var request = new Request(input, init);\n\n if (request.signal && request.signal.aborted) {\n return reject(new exports.DOMException('Aborted', 'AbortError'))\n }\n\n var xhr = new XMLHttpRequest();\n\n function abortXhr() {\n xhr.abort();\n }\n\n xhr.onload = function() {\n var options = {\n status: xhr.status,\n statusText: xhr.statusText,\n headers: parseHeaders(xhr.getAllResponseHeaders() || '')\n };\n options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL');\n var body = 'response' in xhr ? xhr.response : xhr.responseText;\n resolve(new Response(body, options));\n };\n\n xhr.onerror = function() {\n reject(new TypeError('Network request failed'));\n };\n\n xhr.ontimeout = function() {\n reject(new TypeError('Network request failed'));\n };\n\n xhr.onabort = function() {\n reject(new exports.DOMException('Aborted', 'AbortError'));\n };\n\n xhr.open(request.method, request.url, true);\n\n if (request.credentials === 'include') {\n xhr.withCredentials = true;\n } else if (request.credentials === 'omit') {\n xhr.withCredentials = false;\n }\n\n if ('responseType' in xhr && support.blob) {\n xhr.responseType = 'blob';\n }\n\n request.headers.forEach(function(value, name) {\n xhr.setRequestHeader(name, value);\n });\n\n if (request.signal) {\n request.signal.addEventListener('abort', abortXhr);\n\n xhr.onreadystatechange = function() {\n // DONE (success or failure)\n if (xhr.readyState === 4) {\n request.signal.removeEventListener('abort', abortXhr);\n }\n };\n }\n\n xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit);\n })\n }\n\n fetch.polyfill = true;\n\n if (!self.fetch) {\n self.fetch = fetch;\n self.Headers = Headers;\n self.Request = Request;\n self.Response = Response;\n }\n\n exports.Headers = Headers;\n exports.Request = Request;\n exports.Response = Response;\n exports.fetch = fetch;\n\n Object.defineProperty(exports, '__esModule', { value: true });\n\n return exports;\n\n})({});\n})(__self__);\n__self__.fetch.ponyfill = true;\n// Remove \"polyfill\" property added by whatwg-fetch\ndelete __self__.fetch.polyfill;\n// Choose between native implementation (global) or custom implementation (__self__)\n// var ctx = global.fetch ? global : __self__;\nvar ctx = __self__; // this line disable service worker support temporarily\nexports = ctx.fetch // To enable: import fetch from 'cross-fetch'\nexports.default = ctx.fetch // For TypeScript consumers without esModuleInterop.\nexports.fetch = ctx.fetch // To enable: import {fetch} from 'cross-fetch'\nexports.Headers = ctx.Headers\nexports.Request = ctx.Request\nexports.Response = ctx.Response\nmodule.exports = exports\n","'use strict';\n\n// do not edit .js files directly - edit src/index.jst\n\n\n\nmodule.exports = function equal(a, b) {\n if (a === b) return true;\n\n if (a && b && typeof a == 'object' && typeof b == 'object') {\n if (a.constructor !== b.constructor) return false;\n\n var length, i, keys;\n if (Array.isArray(a)) {\n length = a.length;\n if (length != b.length) return false;\n for (i = length; i-- !== 0;)\n if (!equal(a[i], b[i])) return false;\n return true;\n }\n\n\n\n if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;\n if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();\n if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();\n\n keys = Object.keys(a);\n length = keys.length;\n if (length !== Object.keys(b).length) return false;\n\n for (i = length; i-- !== 0;)\n if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;\n\n for (i = length; i-- !== 0;) {\n var key = keys[i];\n\n if (key === '_owner' && a.$$typeof) {\n // React-specific: avoid traversing React elements' _owner.\n // _owner contains circular references\n // and is not needed when comparing the actual elements (and not their owners)\n continue;\n }\n\n if (!equal(a[key], b[key])) return false;\n }\n\n return true;\n }\n\n // true if both NaN, false otherwise\n return a!==a && b!==b;\n};\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-is.production.min.js');\n} else {\n module.exports = require('./cjs/react-is.development.js');\n}\n","'use strict';\n\nmodule.exports = require('./src/js/main');\n","/**\r\n * A collection of shims that provide minimal functionality of the ES6 collections.\r\n *\r\n * These implementations are not meant to be used outside of the ResizeObserver\r\n * modules as they cover only a limited range of use cases.\r\n */\r\n/* eslint-disable require-jsdoc, valid-jsdoc */\r\nvar MapShim = (function () {\r\n if (typeof Map !== 'undefined') {\r\n return Map;\r\n }\r\n /**\r\n * Returns index in provided array that matches the specified key.\r\n *\r\n * @param {Array} arr\r\n * @param {*} key\r\n * @returns {number}\r\n */\r\n function getIndex(arr, key) {\r\n var result = -1;\r\n arr.some(function (entry, index) {\r\n if (entry[0] === key) {\r\n result = index;\r\n return true;\r\n }\r\n return false;\r\n });\r\n return result;\r\n }\r\n return /** @class */ (function () {\r\n function class_1() {\r\n this.__entries__ = [];\r\n }\r\n Object.defineProperty(class_1.prototype, \"size\", {\r\n /**\r\n * @returns {boolean}\r\n */\r\n get: function () {\r\n return this.__entries__.length;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n /**\r\n * @param {*} key\r\n * @returns {*}\r\n */\r\n class_1.prototype.get = function (key) {\r\n var index = getIndex(this.__entries__, key);\r\n var entry = this.__entries__[index];\r\n return entry && entry[1];\r\n };\r\n /**\r\n * @param {*} key\r\n * @param {*} value\r\n * @returns {void}\r\n */\r\n class_1.prototype.set = function (key, value) {\r\n var index = getIndex(this.__entries__, key);\r\n if (~index) {\r\n this.__entries__[index][1] = value;\r\n }\r\n else {\r\n this.__entries__.push([key, value]);\r\n }\r\n };\r\n /**\r\n * @param {*} key\r\n * @returns {void}\r\n */\r\n class_1.prototype.delete = function (key) {\r\n var entries = this.__entries__;\r\n var index = getIndex(entries, key);\r\n if (~index) {\r\n entries.splice(index, 1);\r\n }\r\n };\r\n /**\r\n * @param {*} key\r\n * @returns {void}\r\n */\r\n class_1.prototype.has = function (key) {\r\n return !!~getIndex(this.__entries__, key);\r\n };\r\n /**\r\n * @returns {void}\r\n */\r\n class_1.prototype.clear = function () {\r\n this.__entries__.splice(0);\r\n };\r\n /**\r\n * @param {Function} callback\r\n * @param {*} [ctx=null]\r\n * @returns {void}\r\n */\r\n class_1.prototype.forEach = function (callback, ctx) {\r\n if (ctx === void 0) { ctx = null; }\r\n for (var _i = 0, _a = this.__entries__; _i < _a.length; _i++) {\r\n var entry = _a[_i];\r\n callback.call(ctx, entry[1], entry[0]);\r\n }\r\n };\r\n return class_1;\r\n }());\r\n})();\n\n/**\r\n * Detects whether window and document objects are available in current environment.\r\n */\r\nvar isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document;\n\n// Returns global object of a current environment.\r\nvar global$1 = (function () {\r\n if (typeof global !== 'undefined' && global.Math === Math) {\r\n return global;\r\n }\r\n if (typeof self !== 'undefined' && self.Math === Math) {\r\n return self;\r\n }\r\n if (typeof window !== 'undefined' && window.Math === Math) {\r\n return window;\r\n }\r\n // eslint-disable-next-line no-new-func\r\n return Function('return this')();\r\n})();\n\n/**\r\n * A shim for the requestAnimationFrame which falls back to the setTimeout if\r\n * first one is not supported.\r\n *\r\n * @returns {number} Requests' identifier.\r\n */\r\nvar requestAnimationFrame$1 = (function () {\r\n if (typeof requestAnimationFrame === 'function') {\r\n // It's required to use a bounded function because IE sometimes throws\r\n // an \"Invalid calling object\" error if rAF is invoked without the global\r\n // object on the left hand side.\r\n return requestAnimationFrame.bind(global$1);\r\n }\r\n return function (callback) { return setTimeout(function () { return callback(Date.now()); }, 1000 / 60); };\r\n})();\n\n// Defines minimum timeout before adding a trailing call.\r\nvar trailingTimeout = 2;\r\n/**\r\n * Creates a wrapper function which ensures that provided callback will be\r\n * invoked only once during the specified delay period.\r\n *\r\n * @param {Function} callback - Function to be invoked after the delay period.\r\n * @param {number} delay - Delay after which to invoke callback.\r\n * @returns {Function}\r\n */\r\nfunction throttle (callback, delay) {\r\n var leadingCall = false, trailingCall = false, lastCallTime = 0;\r\n /**\r\n * Invokes the original callback function and schedules new invocation if\r\n * the \"proxy\" was called during current request.\r\n *\r\n * @returns {void}\r\n */\r\n function resolvePending() {\r\n if (leadingCall) {\r\n leadingCall = false;\r\n callback();\r\n }\r\n if (trailingCall) {\r\n proxy();\r\n }\r\n }\r\n /**\r\n * Callback invoked after the specified delay. It will further postpone\r\n * invocation of the original function delegating it to the\r\n * requestAnimationFrame.\r\n *\r\n * @returns {void}\r\n */\r\n function timeoutCallback() {\r\n requestAnimationFrame$1(resolvePending);\r\n }\r\n /**\r\n * Schedules invocation of the original function.\r\n *\r\n * @returns {void}\r\n */\r\n function proxy() {\r\n var timeStamp = Date.now();\r\n if (leadingCall) {\r\n // Reject immediately following calls.\r\n if (timeStamp - lastCallTime < trailingTimeout) {\r\n return;\r\n }\r\n // Schedule new call to be in invoked when the pending one is resolved.\r\n // This is important for \"transitions\" which never actually start\r\n // immediately so there is a chance that we might miss one if change\r\n // happens amids the pending invocation.\r\n trailingCall = true;\r\n }\r\n else {\r\n leadingCall = true;\r\n trailingCall = false;\r\n setTimeout(timeoutCallback, delay);\r\n }\r\n lastCallTime = timeStamp;\r\n }\r\n return proxy;\r\n}\n\n// Minimum delay before invoking the update of observers.\r\nvar REFRESH_DELAY = 20;\r\n// A list of substrings of CSS properties used to find transition events that\r\n// might affect dimensions of observed elements.\r\nvar transitionKeys = ['top', 'right', 'bottom', 'left', 'width', 'height', 'size', 'weight'];\r\n// Check if MutationObserver is available.\r\nvar mutationObserverSupported = typeof MutationObserver !== 'undefined';\r\n/**\r\n * Singleton controller class which handles updates of ResizeObserver instances.\r\n */\r\nvar ResizeObserverController = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserverController.\r\n *\r\n * @private\r\n */\r\n function ResizeObserverController() {\r\n /**\r\n * Indicates whether DOM listeners have been added.\r\n *\r\n * @private {boolean}\r\n */\r\n this.connected_ = false;\r\n /**\r\n * Tells that controller has subscribed for Mutation Events.\r\n *\r\n * @private {boolean}\r\n */\r\n this.mutationEventsAdded_ = false;\r\n /**\r\n * Keeps reference to the instance of MutationObserver.\r\n *\r\n * @private {MutationObserver}\r\n */\r\n this.mutationsObserver_ = null;\r\n /**\r\n * A list of connected observers.\r\n *\r\n * @private {Array}\r\n */\r\n this.observers_ = [];\r\n this.onTransitionEnd_ = this.onTransitionEnd_.bind(this);\r\n this.refresh = throttle(this.refresh.bind(this), REFRESH_DELAY);\r\n }\r\n /**\r\n * Adds observer to observers list.\r\n *\r\n * @param {ResizeObserverSPI} observer - Observer to be added.\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.addObserver = function (observer) {\r\n if (!~this.observers_.indexOf(observer)) {\r\n this.observers_.push(observer);\r\n }\r\n // Add listeners if they haven't been added yet.\r\n if (!this.connected_) {\r\n this.connect_();\r\n }\r\n };\r\n /**\r\n * Removes observer from observers list.\r\n *\r\n * @param {ResizeObserverSPI} observer - Observer to be removed.\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.removeObserver = function (observer) {\r\n var observers = this.observers_;\r\n var index = observers.indexOf(observer);\r\n // Remove observer if it's present in registry.\r\n if (~index) {\r\n observers.splice(index, 1);\r\n }\r\n // Remove listeners if controller has no connected observers.\r\n if (!observers.length && this.connected_) {\r\n this.disconnect_();\r\n }\r\n };\r\n /**\r\n * Invokes the update of observers. It will continue running updates insofar\r\n * it detects changes.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.refresh = function () {\r\n var changesDetected = this.updateObservers_();\r\n // Continue running updates if changes have been detected as there might\r\n // be future ones caused by CSS transitions.\r\n if (changesDetected) {\r\n this.refresh();\r\n }\r\n };\r\n /**\r\n * Updates every observer from observers list and notifies them of queued\r\n * entries.\r\n *\r\n * @private\r\n * @returns {boolean} Returns \"true\" if any observer has detected changes in\r\n * dimensions of it's elements.\r\n */\r\n ResizeObserverController.prototype.updateObservers_ = function () {\r\n // Collect observers that have active observations.\r\n var activeObservers = this.observers_.filter(function (observer) {\r\n return observer.gatherActive(), observer.hasActive();\r\n });\r\n // Deliver notifications in a separate cycle in order to avoid any\r\n // collisions between observers, e.g. when multiple instances of\r\n // ResizeObserver are tracking the same element and the callback of one\r\n // of them changes content dimensions of the observed target. Sometimes\r\n // this may result in notifications being blocked for the rest of observers.\r\n activeObservers.forEach(function (observer) { return observer.broadcastActive(); });\r\n return activeObservers.length > 0;\r\n };\r\n /**\r\n * Initializes DOM listeners.\r\n *\r\n * @private\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.connect_ = function () {\r\n // Do nothing if running in a non-browser environment or if listeners\r\n // have been already added.\r\n if (!isBrowser || this.connected_) {\r\n return;\r\n }\r\n // Subscription to the \"Transitionend\" event is used as a workaround for\r\n // delayed transitions. This way it's possible to capture at least the\r\n // final state of an element.\r\n document.addEventListener('transitionend', this.onTransitionEnd_);\r\n window.addEventListener('resize', this.refresh);\r\n if (mutationObserverSupported) {\r\n this.mutationsObserver_ = new MutationObserver(this.refresh);\r\n this.mutationsObserver_.observe(document, {\r\n attributes: true,\r\n childList: true,\r\n characterData: true,\r\n subtree: true\r\n });\r\n }\r\n else {\r\n document.addEventListener('DOMSubtreeModified', this.refresh);\r\n this.mutationEventsAdded_ = true;\r\n }\r\n this.connected_ = true;\r\n };\r\n /**\r\n * Removes DOM listeners.\r\n *\r\n * @private\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.disconnect_ = function () {\r\n // Do nothing if running in a non-browser environment or if listeners\r\n // have been already removed.\r\n if (!isBrowser || !this.connected_) {\r\n return;\r\n }\r\n document.removeEventListener('transitionend', this.onTransitionEnd_);\r\n window.removeEventListener('resize', this.refresh);\r\n if (this.mutationsObserver_) {\r\n this.mutationsObserver_.disconnect();\r\n }\r\n if (this.mutationEventsAdded_) {\r\n document.removeEventListener('DOMSubtreeModified', this.refresh);\r\n }\r\n this.mutationsObserver_ = null;\r\n this.mutationEventsAdded_ = false;\r\n this.connected_ = false;\r\n };\r\n /**\r\n * \"Transitionend\" event handler.\r\n *\r\n * @private\r\n * @param {TransitionEvent} event\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.onTransitionEnd_ = function (_a) {\r\n var _b = _a.propertyName, propertyName = _b === void 0 ? '' : _b;\r\n // Detect whether transition may affect dimensions of an element.\r\n var isReflowProperty = transitionKeys.some(function (key) {\r\n return !!~propertyName.indexOf(key);\r\n });\r\n if (isReflowProperty) {\r\n this.refresh();\r\n }\r\n };\r\n /**\r\n * Returns instance of the ResizeObserverController.\r\n *\r\n * @returns {ResizeObserverController}\r\n */\r\n ResizeObserverController.getInstance = function () {\r\n if (!this.instance_) {\r\n this.instance_ = new ResizeObserverController();\r\n }\r\n return this.instance_;\r\n };\r\n /**\r\n * Holds reference to the controller's instance.\r\n *\r\n * @private {ResizeObserverController}\r\n */\r\n ResizeObserverController.instance_ = null;\r\n return ResizeObserverController;\r\n}());\n\n/**\r\n * Defines non-writable/enumerable properties of the provided target object.\r\n *\r\n * @param {Object} target - Object for which to define properties.\r\n * @param {Object} props - Properties to be defined.\r\n * @returns {Object} Target object.\r\n */\r\nvar defineConfigurable = (function (target, props) {\r\n for (var _i = 0, _a = Object.keys(props); _i < _a.length; _i++) {\r\n var key = _a[_i];\r\n Object.defineProperty(target, key, {\r\n value: props[key],\r\n enumerable: false,\r\n writable: false,\r\n configurable: true\r\n });\r\n }\r\n return target;\r\n});\n\n/**\r\n * Returns the global object associated with provided element.\r\n *\r\n * @param {Object} target\r\n * @returns {Object}\r\n */\r\nvar getWindowOf = (function (target) {\r\n // Assume that the element is an instance of Node, which means that it\r\n // has the \"ownerDocument\" property from which we can retrieve a\r\n // corresponding global object.\r\n var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView;\r\n // Return the local global object if it's not possible extract one from\r\n // provided element.\r\n return ownerGlobal || global$1;\r\n});\n\n// Placeholder of an empty content rectangle.\r\nvar emptyRect = createRectInit(0, 0, 0, 0);\r\n/**\r\n * Converts provided string to a number.\r\n *\r\n * @param {number|string} value\r\n * @returns {number}\r\n */\r\nfunction toFloat(value) {\r\n return parseFloat(value) || 0;\r\n}\r\n/**\r\n * Extracts borders size from provided styles.\r\n *\r\n * @param {CSSStyleDeclaration} styles\r\n * @param {...string} positions - Borders positions (top, right, ...)\r\n * @returns {number}\r\n */\r\nfunction getBordersSize(styles) {\r\n var positions = [];\r\n for (var _i = 1; _i < arguments.length; _i++) {\r\n positions[_i - 1] = arguments[_i];\r\n }\r\n return positions.reduce(function (size, position) {\r\n var value = styles['border-' + position + '-width'];\r\n return size + toFloat(value);\r\n }, 0);\r\n}\r\n/**\r\n * Extracts paddings sizes from provided styles.\r\n *\r\n * @param {CSSStyleDeclaration} styles\r\n * @returns {Object} Paddings box.\r\n */\r\nfunction getPaddings(styles) {\r\n var positions = ['top', 'right', 'bottom', 'left'];\r\n var paddings = {};\r\n for (var _i = 0, positions_1 = positions; _i < positions_1.length; _i++) {\r\n var position = positions_1[_i];\r\n var value = styles['padding-' + position];\r\n paddings[position] = toFloat(value);\r\n }\r\n return paddings;\r\n}\r\n/**\r\n * Calculates content rectangle of provided SVG element.\r\n *\r\n * @param {SVGGraphicsElement} target - Element content rectangle of which needs\r\n * to be calculated.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getSVGContentRect(target) {\r\n var bbox = target.getBBox();\r\n return createRectInit(0, 0, bbox.width, bbox.height);\r\n}\r\n/**\r\n * Calculates content rectangle of provided HTMLElement.\r\n *\r\n * @param {HTMLElement} target - Element for which to calculate the content rectangle.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getHTMLElementContentRect(target) {\r\n // Client width & height properties can't be\r\n // used exclusively as they provide rounded values.\r\n var clientWidth = target.clientWidth, clientHeight = target.clientHeight;\r\n // By this condition we can catch all non-replaced inline, hidden and\r\n // detached elements. Though elements with width & height properties less\r\n // than 0.5 will be discarded as well.\r\n //\r\n // Without it we would need to implement separate methods for each of\r\n // those cases and it's not possible to perform a precise and performance\r\n // effective test for hidden elements. E.g. even jQuery's ':visible' filter\r\n // gives wrong results for elements with width & height less than 0.5.\r\n if (!clientWidth && !clientHeight) {\r\n return emptyRect;\r\n }\r\n var styles = getWindowOf(target).getComputedStyle(target);\r\n var paddings = getPaddings(styles);\r\n var horizPad = paddings.left + paddings.right;\r\n var vertPad = paddings.top + paddings.bottom;\r\n // Computed styles of width & height are being used because they are the\r\n // only dimensions available to JS that contain non-rounded values. It could\r\n // be possible to utilize the getBoundingClientRect if only it's data wasn't\r\n // affected by CSS transformations let alone paddings, borders and scroll bars.\r\n var width = toFloat(styles.width), height = toFloat(styles.height);\r\n // Width & height include paddings and borders when the 'border-box' box\r\n // model is applied (except for IE).\r\n if (styles.boxSizing === 'border-box') {\r\n // Following conditions are required to handle Internet Explorer which\r\n // doesn't include paddings and borders to computed CSS dimensions.\r\n //\r\n // We can say that if CSS dimensions + paddings are equal to the \"client\"\r\n // properties then it's either IE, and thus we don't need to subtract\r\n // anything, or an element merely doesn't have paddings/borders styles.\r\n if (Math.round(width + horizPad) !== clientWidth) {\r\n width -= getBordersSize(styles, 'left', 'right') + horizPad;\r\n }\r\n if (Math.round(height + vertPad) !== clientHeight) {\r\n height -= getBordersSize(styles, 'top', 'bottom') + vertPad;\r\n }\r\n }\r\n // Following steps can't be applied to the document's root element as its\r\n // client[Width/Height] properties represent viewport area of the window.\r\n // Besides, it's as well not necessary as the itself neither has\r\n // rendered scroll bars nor it can be clipped.\r\n if (!isDocumentElement(target)) {\r\n // In some browsers (only in Firefox, actually) CSS width & height\r\n // include scroll bars size which can be removed at this step as scroll\r\n // bars are the only difference between rounded dimensions + paddings\r\n // and \"client\" properties, though that is not always true in Chrome.\r\n var vertScrollbar = Math.round(width + horizPad) - clientWidth;\r\n var horizScrollbar = Math.round(height + vertPad) - clientHeight;\r\n // Chrome has a rather weird rounding of \"client\" properties.\r\n // E.g. for an element with content width of 314.2px it sometimes gives\r\n // the client width of 315px and for the width of 314.7px it may give\r\n // 314px. And it doesn't happen all the time. So just ignore this delta\r\n // as a non-relevant.\r\n if (Math.abs(vertScrollbar) !== 1) {\r\n width -= vertScrollbar;\r\n }\r\n if (Math.abs(horizScrollbar) !== 1) {\r\n height -= horizScrollbar;\r\n }\r\n }\r\n return createRectInit(paddings.left, paddings.top, width, height);\r\n}\r\n/**\r\n * Checks whether provided element is an instance of the SVGGraphicsElement.\r\n *\r\n * @param {Element} target - Element to be checked.\r\n * @returns {boolean}\r\n */\r\nvar isSVGGraphicsElement = (function () {\r\n // Some browsers, namely IE and Edge, don't have the SVGGraphicsElement\r\n // interface.\r\n if (typeof SVGGraphicsElement !== 'undefined') {\r\n return function (target) { return target instanceof getWindowOf(target).SVGGraphicsElement; };\r\n }\r\n // If it's so, then check that element is at least an instance of the\r\n // SVGElement and that it has the \"getBBox\" method.\r\n // eslint-disable-next-line no-extra-parens\r\n return function (target) { return (target instanceof getWindowOf(target).SVGElement &&\r\n typeof target.getBBox === 'function'); };\r\n})();\r\n/**\r\n * Checks whether provided element is a document element ().\r\n *\r\n * @param {Element} target - Element to be checked.\r\n * @returns {boolean}\r\n */\r\nfunction isDocumentElement(target) {\r\n return target === getWindowOf(target).document.documentElement;\r\n}\r\n/**\r\n * Calculates an appropriate content rectangle for provided html or svg element.\r\n *\r\n * @param {Element} target - Element content rectangle of which needs to be calculated.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getContentRect(target) {\r\n if (!isBrowser) {\r\n return emptyRect;\r\n }\r\n if (isSVGGraphicsElement(target)) {\r\n return getSVGContentRect(target);\r\n }\r\n return getHTMLElementContentRect(target);\r\n}\r\n/**\r\n * Creates rectangle with an interface of the DOMRectReadOnly.\r\n * Spec: https://drafts.fxtf.org/geometry/#domrectreadonly\r\n *\r\n * @param {DOMRectInit} rectInit - Object with rectangle's x/y coordinates and dimensions.\r\n * @returns {DOMRectReadOnly}\r\n */\r\nfunction createReadOnlyRect(_a) {\r\n var x = _a.x, y = _a.y, width = _a.width, height = _a.height;\r\n // If DOMRectReadOnly is available use it as a prototype for the rectangle.\r\n var Constr = typeof DOMRectReadOnly !== 'undefined' ? DOMRectReadOnly : Object;\r\n var rect = Object.create(Constr.prototype);\r\n // Rectangle's properties are not writable and non-enumerable.\r\n defineConfigurable(rect, {\r\n x: x, y: y, width: width, height: height,\r\n top: y,\r\n right: x + width,\r\n bottom: height + y,\r\n left: x\r\n });\r\n return rect;\r\n}\r\n/**\r\n * Creates DOMRectInit object based on the provided dimensions and the x/y coordinates.\r\n * Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit\r\n *\r\n * @param {number} x - X coordinate.\r\n * @param {number} y - Y coordinate.\r\n * @param {number} width - Rectangle's width.\r\n * @param {number} height - Rectangle's height.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction createRectInit(x, y, width, height) {\r\n return { x: x, y: y, width: width, height: height };\r\n}\n\n/**\r\n * Class that is responsible for computations of the content rectangle of\r\n * provided DOM element and for keeping track of it's changes.\r\n */\r\nvar ResizeObservation = /** @class */ (function () {\r\n /**\r\n * Creates an instance of ResizeObservation.\r\n *\r\n * @param {Element} target - Element to be observed.\r\n */\r\n function ResizeObservation(target) {\r\n /**\r\n * Broadcasted width of content rectangle.\r\n *\r\n * @type {number}\r\n */\r\n this.broadcastWidth = 0;\r\n /**\r\n * Broadcasted height of content rectangle.\r\n *\r\n * @type {number}\r\n */\r\n this.broadcastHeight = 0;\r\n /**\r\n * Reference to the last observed content rectangle.\r\n *\r\n * @private {DOMRectInit}\r\n */\r\n this.contentRect_ = createRectInit(0, 0, 0, 0);\r\n this.target = target;\r\n }\r\n /**\r\n * Updates content rectangle and tells whether it's width or height properties\r\n * have changed since the last broadcast.\r\n *\r\n * @returns {boolean}\r\n */\r\n ResizeObservation.prototype.isActive = function () {\r\n var rect = getContentRect(this.target);\r\n this.contentRect_ = rect;\r\n return (rect.width !== this.broadcastWidth ||\r\n rect.height !== this.broadcastHeight);\r\n };\r\n /**\r\n * Updates 'broadcastWidth' and 'broadcastHeight' properties with a data\r\n * from the corresponding properties of the last observed content rectangle.\r\n *\r\n * @returns {DOMRectInit} Last observed content rectangle.\r\n */\r\n ResizeObservation.prototype.broadcastRect = function () {\r\n var rect = this.contentRect_;\r\n this.broadcastWidth = rect.width;\r\n this.broadcastHeight = rect.height;\r\n return rect;\r\n };\r\n return ResizeObservation;\r\n}());\n\nvar ResizeObserverEntry = /** @class */ (function () {\r\n /**\r\n * Creates an instance of ResizeObserverEntry.\r\n *\r\n * @param {Element} target - Element that is being observed.\r\n * @param {DOMRectInit} rectInit - Data of the element's content rectangle.\r\n */\r\n function ResizeObserverEntry(target, rectInit) {\r\n var contentRect = createReadOnlyRect(rectInit);\r\n // According to the specification following properties are not writable\r\n // and are also not enumerable in the native implementation.\r\n //\r\n // Property accessors are not being used as they'd require to define a\r\n // private WeakMap storage which may cause memory leaks in browsers that\r\n // don't support this type of collections.\r\n defineConfigurable(this, { target: target, contentRect: contentRect });\r\n }\r\n return ResizeObserverEntry;\r\n}());\n\nvar ResizeObserverSPI = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserver.\r\n *\r\n * @param {ResizeObserverCallback} callback - Callback function that is invoked\r\n * when one of the observed elements changes it's content dimensions.\r\n * @param {ResizeObserverController} controller - Controller instance which\r\n * is responsible for the updates of observer.\r\n * @param {ResizeObserver} callbackCtx - Reference to the public\r\n * ResizeObserver instance which will be passed to callback function.\r\n */\r\n function ResizeObserverSPI(callback, controller, callbackCtx) {\r\n /**\r\n * Collection of resize observations that have detected changes in dimensions\r\n * of elements.\r\n *\r\n * @private {Array}\r\n */\r\n this.activeObservations_ = [];\r\n /**\r\n * Registry of the ResizeObservation instances.\r\n *\r\n * @private {Map}\r\n */\r\n this.observations_ = new MapShim();\r\n if (typeof callback !== 'function') {\r\n throw new TypeError('The callback provided as parameter 1 is not a function.');\r\n }\r\n this.callback_ = callback;\r\n this.controller_ = controller;\r\n this.callbackCtx_ = callbackCtx;\r\n }\r\n /**\r\n * Starts observing provided element.\r\n *\r\n * @param {Element} target - Element to be observed.\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.observe = function (target) {\r\n if (!arguments.length) {\r\n throw new TypeError('1 argument required, but only 0 present.');\r\n }\r\n // Do nothing if current environment doesn't have the Element interface.\r\n if (typeof Element === 'undefined' || !(Element instanceof Object)) {\r\n return;\r\n }\r\n if (!(target instanceof getWindowOf(target).Element)) {\r\n throw new TypeError('parameter 1 is not of type \"Element\".');\r\n }\r\n var observations = this.observations_;\r\n // Do nothing if element is already being observed.\r\n if (observations.has(target)) {\r\n return;\r\n }\r\n observations.set(target, new ResizeObservation(target));\r\n this.controller_.addObserver(this);\r\n // Force the update of observations.\r\n this.controller_.refresh();\r\n };\r\n /**\r\n * Stops observing provided element.\r\n *\r\n * @param {Element} target - Element to stop observing.\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.unobserve = function (target) {\r\n if (!arguments.length) {\r\n throw new TypeError('1 argument required, but only 0 present.');\r\n }\r\n // Do nothing if current environment doesn't have the Element interface.\r\n if (typeof Element === 'undefined' || !(Element instanceof Object)) {\r\n return;\r\n }\r\n if (!(target instanceof getWindowOf(target).Element)) {\r\n throw new TypeError('parameter 1 is not of type \"Element\".');\r\n }\r\n var observations = this.observations_;\r\n // Do nothing if element is not being observed.\r\n if (!observations.has(target)) {\r\n return;\r\n }\r\n observations.delete(target);\r\n if (!observations.size) {\r\n this.controller_.removeObserver(this);\r\n }\r\n };\r\n /**\r\n * Stops observing all elements.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.disconnect = function () {\r\n this.clearActive();\r\n this.observations_.clear();\r\n this.controller_.removeObserver(this);\r\n };\r\n /**\r\n * Collects observation instances the associated element of which has changed\r\n * it's content rectangle.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.gatherActive = function () {\r\n var _this = this;\r\n this.clearActive();\r\n this.observations_.forEach(function (observation) {\r\n if (observation.isActive()) {\r\n _this.activeObservations_.push(observation);\r\n }\r\n });\r\n };\r\n /**\r\n * Invokes initial callback function with a list of ResizeObserverEntry\r\n * instances collected from active resize observations.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.broadcastActive = function () {\r\n // Do nothing if observer doesn't have active observations.\r\n if (!this.hasActive()) {\r\n return;\r\n }\r\n var ctx = this.callbackCtx_;\r\n // Create ResizeObserverEntry instance for every active observation.\r\n var entries = this.activeObservations_.map(function (observation) {\r\n return new ResizeObserverEntry(observation.target, observation.broadcastRect());\r\n });\r\n this.callback_.call(ctx, entries, ctx);\r\n this.clearActive();\r\n };\r\n /**\r\n * Clears the collection of active observations.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.clearActive = function () {\r\n this.activeObservations_.splice(0);\r\n };\r\n /**\r\n * Tells whether observer has active observations.\r\n *\r\n * @returns {boolean}\r\n */\r\n ResizeObserverSPI.prototype.hasActive = function () {\r\n return this.activeObservations_.length > 0;\r\n };\r\n return ResizeObserverSPI;\r\n}());\n\n// Registry of internal observers. If WeakMap is not available use current shim\r\n// for the Map collection as it has all required methods and because WeakMap\r\n// can't be fully polyfilled anyway.\r\nvar observers = typeof WeakMap !== 'undefined' ? new WeakMap() : new MapShim();\r\n/**\r\n * ResizeObserver API. Encapsulates the ResizeObserver SPI implementation\r\n * exposing only those methods and properties that are defined in the spec.\r\n */\r\nvar ResizeObserver = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserver.\r\n *\r\n * @param {ResizeObserverCallback} callback - Callback that is invoked when\r\n * dimensions of the observed elements change.\r\n */\r\n function ResizeObserver(callback) {\r\n if (!(this instanceof ResizeObserver)) {\r\n throw new TypeError('Cannot call a class as a function.');\r\n }\r\n if (!arguments.length) {\r\n throw new TypeError('1 argument required, but only 0 present.');\r\n }\r\n var controller = ResizeObserverController.getInstance();\r\n var observer = new ResizeObserverSPI(callback, controller, this);\r\n observers.set(this, observer);\r\n }\r\n return ResizeObserver;\r\n}());\r\n// Expose public methods of ResizeObserver.\r\n[\r\n 'observe',\r\n 'unobserve',\r\n 'disconnect'\r\n].forEach(function (method) {\r\n ResizeObserver.prototype[method] = function () {\r\n var _a;\r\n return (_a = observers.get(this))[method].apply(_a, arguments);\r\n };\r\n});\n\nvar index = (function () {\r\n // Export existing implementation if available.\r\n if (typeof global$1.ResizeObserver !== 'undefined') {\r\n return global$1.ResizeObserver;\r\n }\r\n return ResizeObserver;\r\n})();\n\nexport default index;\n","import arrayWithHoles from \"./arrayWithHoles\";\nimport iterableToArray from \"./iterableToArray\";\nimport nonIterableRest from \"./nonIterableRest\";\nexport default function _toArray(arr) {\n return arrayWithHoles(arr) || iterableToArray(arr) || nonIterableRest();\n}","import { useRef } from 'react';\nimport useEffectOnce from './useEffectOnce';\nvar useUnmount = function (fn) {\n var fnRef = useRef(fn);\n // update the ref each render so if it change the newest callback will be invoked\n fnRef.current = fn;\n useEffectOnce(function () { return function () { return fnRef.current(); }; });\n};\nexport default useUnmount;\n","/**!\n * easy-pie-chart\n * Lightweight plugin to render simple, animated and retina optimized pie charts\n *\n * @license \n * @author Robert Fleischmann (http://robert-fleischmann.de)\n * @version 2.1.7\n **/\n\n(function (root, factory) {\n if (typeof define === 'function' && define.amd) {\n // AMD. Register as an anonymous module unless amdModuleId is set\n define([], function () {\n return (root['EasyPieChart'] = factory());\n });\n } else if (typeof exports === 'object') {\n // Node. Does not work with strict CommonJS, but\n // only CommonJS-like environments that support module.exports,\n // like Node.\n module.exports = factory();\n } else {\n root['EasyPieChart'] = factory();\n }\n}(this, function () {\n\n/**\n * Renderer to render the chart on a canvas object\n * @param {DOMElement} el DOM element to host the canvas (root of the plugin)\n * @param {object} options options object of the plugin\n */\nvar CanvasRenderer = function(el, options) {\n\tvar cachedBackground;\n\tvar canvas = document.createElement('canvas');\n\n\tel.appendChild(canvas);\n\n\tif (typeof(G_vmlCanvasManager) === 'object') {\n\t\tG_vmlCanvasManager.initElement(canvas);\n\t}\n\n\tvar ctx = canvas.getContext('2d');\n\n\tcanvas.width = canvas.height = options.size;\n\n\t// canvas on retina devices\n\tvar scaleBy = 1;\n\tif (window.devicePixelRatio > 1) {\n\t\tscaleBy = window.devicePixelRatio;\n\t\tcanvas.style.width = canvas.style.height = [options.size, 'px'].join('');\n\t\tcanvas.width = canvas.height = options.size * scaleBy;\n\t\tctx.scale(scaleBy, scaleBy);\n\t}\n\n\t// move 0,0 coordinates to the center\n\tctx.translate(options.size / 2, options.size / 2);\n\n\t// rotate canvas -90deg\n\tctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI);\n\n\tvar radius = (options.size - options.lineWidth) / 2;\n\tif (options.scaleColor && options.scaleLength) {\n\t\tradius -= options.scaleLength + 2; // 2 is the distance between scale and bar\n\t}\n\n\t// IE polyfill for Date\n\tDate.now = Date.now || function() {\n\t\treturn +(new Date());\n\t};\n\n\t/**\n\t * Draw a circle around the center of the canvas\n\t * @param {strong} color Valid CSS color string\n\t * @param {number} lineWidth Width of the line in px\n\t * @param {number} percent Percentage to draw (float between -1 and 1)\n\t */\n\tvar drawCircle = function(color, lineWidth, percent) {\n\t\tpercent = Math.min(Math.max(-1, percent || 0), 1);\n\t\tvar isNegative = percent <= 0 ? true : false;\n\n\t\tctx.beginPath();\n\t\tctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, isNegative);\n\n\t\tctx.strokeStyle = color;\n\t\tctx.lineWidth = lineWidth;\n\n\t\tctx.stroke();\n\t};\n\n\t/**\n\t * Draw the scale of the chart\n\t */\n\tvar drawScale = function() {\n\t\tvar offset;\n\t\tvar length;\n\n\t\tctx.lineWidth = 1;\n\t\tctx.fillStyle = options.scaleColor;\n\n\t\tctx.save();\n\t\tfor (var i = 24; i > 0; --i) {\n\t\t\tif (i % 6 === 0) {\n\t\t\t\tlength = options.scaleLength;\n\t\t\t\toffset = 0;\n\t\t\t} else {\n\t\t\t\tlength = options.scaleLength * 0.6;\n\t\t\t\toffset = options.scaleLength - length;\n\t\t\t}\n\t\t\tctx.fillRect(-options.size/2 + offset, 0, length, 1);\n\t\t\tctx.rotate(Math.PI / 12);\n\t\t}\n\t\tctx.restore();\n\t};\n\n\t/**\n\t * Request animation frame wrapper with polyfill\n\t * @return {function} Request animation frame method or timeout fallback\n\t */\n\tvar reqAnimationFrame = (function() {\n\t\treturn window.requestAnimationFrame ||\n\t\t\t\twindow.webkitRequestAnimationFrame ||\n\t\t\t\twindow.mozRequestAnimationFrame ||\n\t\t\t\tfunction(callback) {\n\t\t\t\t\twindow.setTimeout(callback, 1000 / 60);\n\t\t\t\t};\n\t}());\n\n\t/**\n\t * Draw the background of the plugin including the scale and the track\n\t */\n\tvar drawBackground = function() {\n\t\tif(options.scaleColor) drawScale();\n\t\tif(options.trackColor) drawCircle(options.trackColor, options.trackWidth || options.lineWidth, 1);\n\t};\n\n /**\n * Canvas accessor\n */\n this.getCanvas = function() {\n return canvas;\n };\n\n /**\n * Canvas 2D context 'ctx' accessor\n */\n this.getCtx = function() {\n return ctx;\n };\n\n\t/**\n\t * Clear the complete canvas\n\t */\n\tthis.clear = function() {\n\t\tctx.clearRect(options.size / -2, options.size / -2, options.size, options.size);\n\t};\n\n\t/**\n\t * Draw the complete chart\n\t * @param {number} percent Percent shown by the chart between -100 and 100\n\t */\n\tthis.draw = function(percent) {\n\t\t// do we need to render a background\n\t\tif (!!options.scaleColor || !!options.trackColor) {\n\t\t\t// getImageData and putImageData are supported\n\t\t\tif (ctx.getImageData && ctx.putImageData) {\n\t\t\t\tif (!cachedBackground) {\n\t\t\t\t\tdrawBackground();\n\t\t\t\t\tcachedBackground = ctx.getImageData(0, 0, options.size * scaleBy, options.size * scaleBy);\n\t\t\t\t} else {\n\t\t\t\t\tctx.putImageData(cachedBackground, 0, 0);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.clear();\n\t\t\t\tdrawBackground();\n\t\t\t}\n\t\t} else {\n\t\t\tthis.clear();\n\t\t}\n\n\t\tctx.lineCap = options.lineCap;\n\n\t\t// if barcolor is a function execute it and pass the percent as a value\n\t\tvar color;\n\t\tif (typeof(options.barColor) === 'function') {\n\t\t\tcolor = options.barColor(percent);\n\t\t} else {\n\t\t\tcolor = options.barColor;\n\t\t}\n\n\t\t// draw bar\n\t\tdrawCircle(color, options.lineWidth, percent / 100);\n\t}.bind(this);\n\n\t/**\n\t * Animate from some percent to some other percentage\n\t * @param {number} from Starting percentage\n\t * @param {number} to Final percentage\n\t */\n\tthis.animate = function(from, to) {\n\t\tvar startTime = Date.now();\n\t\toptions.onStart(from, to);\n\t\tvar animation = function() {\n\t\t\tvar process = Math.min(Date.now() - startTime, options.animate.duration);\n\t\t\tvar currentValue = options.easing(this, process, from, to - from, options.animate.duration);\n\t\t\tthis.draw(currentValue);\n\t\t\toptions.onStep(from, to, currentValue);\n\t\t\tif (process >= options.animate.duration) {\n\t\t\t\toptions.onStop(from, to);\n\t\t\t} else {\n\t\t\t\treqAnimationFrame(animation);\n\t\t\t}\n\t\t}.bind(this);\n\n\t\treqAnimationFrame(animation);\n\t}.bind(this);\n};\n\nvar EasyPieChart = function(el, opts) {\n\tvar defaultOptions = {\n\t\tbarColor: '#ef1e25',\n\t\ttrackColor: '#f9f9f9',\n\t\tscaleColor: '#dfe0e0',\n\t\tscaleLength: 5,\n\t\tlineCap: 'round',\n\t\tlineWidth: 3,\n\t\ttrackWidth: undefined,\n\t\tsize: 110,\n\t\trotate: 0,\n\t\tanimate: {\n\t\t\tduration: 1000,\n\t\t\tenabled: true\n\t\t},\n\t\teasing: function (x, t, b, c, d) { // more can be found here: http://gsgd.co.uk/sandbox/jquery/easing/\n\t\t\tt = t / (d/2);\n\t\t\tif (t < 1) {\n\t\t\t\treturn c / 2 * t * t + b;\n\t\t\t}\n\t\t\treturn -c/2 * ((--t)*(t-2) - 1) + b;\n\t\t},\n\t\tonStart: function(from, to) {\n\t\t\treturn;\n\t\t},\n\t\tonStep: function(from, to, currentValue) {\n\t\t\treturn;\n\t\t},\n\t\tonStop: function(from, to) {\n\t\t\treturn;\n\t\t}\n\t};\n\n\t// detect present renderer\n\tif (typeof(CanvasRenderer) !== 'undefined') {\n\t\tdefaultOptions.renderer = CanvasRenderer;\n\t} else if (typeof(SVGRenderer) !== 'undefined') {\n\t\tdefaultOptions.renderer = SVGRenderer;\n\t} else {\n\t\tthrow new Error('Please load either the SVG- or the CanvasRenderer');\n\t}\n\n\tvar options = {};\n\tvar currentValue = 0;\n\n\t/**\n\t * Initialize the plugin by creating the options object and initialize rendering\n\t */\n\tvar init = function() {\n\t\tthis.el = el;\n\t\tthis.options = options;\n\n\t\t// merge user options into default options\n\t\tfor (var i in defaultOptions) {\n\t\t\tif (defaultOptions.hasOwnProperty(i)) {\n\t\t\t\toptions[i] = opts && typeof(opts[i]) !== 'undefined' ? opts[i] : defaultOptions[i];\n\t\t\t\tif (typeof(options[i]) === 'function') {\n\t\t\t\t\toptions[i] = options[i].bind(this);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// check for jQuery easing\n\t\tif (typeof(options.easing) === 'string' && typeof(jQuery) !== 'undefined' && jQuery.isFunction(jQuery.easing[options.easing])) {\n\t\t\toptions.easing = jQuery.easing[options.easing];\n\t\t} else {\n\t\t\toptions.easing = defaultOptions.easing;\n\t\t}\n\n\t\t// process earlier animate option to avoid bc breaks\n\t\tif (typeof(options.animate) === 'number') {\n\t\t\toptions.animate = {\n\t\t\t\tduration: options.animate,\n\t\t\t\tenabled: true\n\t\t\t};\n\t\t}\n\n\t\tif (typeof(options.animate) === 'boolean' && !options.animate) {\n\t\t\toptions.animate = {\n\t\t\t\tduration: 1000,\n\t\t\t\tenabled: options.animate\n\t\t\t};\n\t\t}\n\n\t\t// create renderer\n\t\tthis.renderer = new options.renderer(el, options);\n\n\t\t// initial draw\n\t\tthis.renderer.draw(currentValue);\n\n\t\t// initial update\n\t\tif (el.dataset && el.dataset.percent) {\n\t\t\tthis.update(parseFloat(el.dataset.percent));\n\t\t} else if (el.getAttribute && el.getAttribute('data-percent')) {\n\t\t\tthis.update(parseFloat(el.getAttribute('data-percent')));\n\t\t}\n\t}.bind(this);\n\n\t/**\n\t * Update the value of the chart\n\t * @param {number} newValue Number between 0 and 100\n\t * @return {object} Instance of the plugin for method chaining\n\t */\n\tthis.update = function(newValue) {\n\t\tnewValue = parseFloat(newValue);\n\t\tif (options.animate.enabled) {\n\t\t\tthis.renderer.animate(currentValue, newValue);\n\t\t} else {\n\t\t\tthis.renderer.draw(newValue);\n\t\t}\n\t\tcurrentValue = newValue;\n\t\treturn this;\n\t}.bind(this);\n\n\t/**\n\t * Disable animation\n\t * @return {object} Instance of the plugin for method chaining\n\t */\n\tthis.disableAnimation = function() {\n\t\toptions.animate.enabled = false;\n\t\treturn this;\n\t};\n\n\t/**\n\t * Enable animation\n\t * @return {object} Instance of the plugin for method chaining\n\t */\n\tthis.enableAnimation = function() {\n\t\toptions.animate.enabled = true;\n\t\treturn this;\n\t};\n\n\tinit();\n};\n\nreturn EasyPieChart;\n\n}));\n","// Generated by CoffeeScript 1.10.0\n(function() {\n var AnimatedText, AnimatedTextFactory, Bar, BaseDonut, BaseGauge, Donut, Gauge, GaugePointer, TextRenderer, ValueUpdater, addCommas, cutHex, formatNumber, mergeObjects, secondsToString,\n slice = [].slice,\n hasProp = {}.hasOwnProperty,\n extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };\n\n (function() {\n var browserRequestAnimationFrame, isCancelled, j, lastId, len, vendor, vendors;\n vendors = ['ms', 'moz', 'webkit', 'o'];\n for (j = 0, len = vendors.length; j < len; j++) {\n vendor = vendors[j];\n if (window.requestAnimationFrame) {\n break;\n }\n window.requestAnimationFrame = window[vendor + 'RequestAnimationFrame'];\n window.cancelAnimationFrame = window[vendor + 'CancelAnimationFrame'] || window[vendor + 'CancelRequestAnimationFrame'];\n }\n browserRequestAnimationFrame = null;\n lastId = 0;\n isCancelled = {};\n if (!requestAnimationFrame) {\n window.requestAnimationFrame = function(callback, element) {\n var currTime, id, lastTime, timeToCall;\n currTime = new Date().getTime();\n timeToCall = Math.max(0, 16 - (currTime - lastTime));\n id = window.setTimeout(function() {\n return callback(currTime + timeToCall);\n }, timeToCall);\n lastTime = currTime + timeToCall;\n return id;\n };\n return window.cancelAnimationFrame = function(id) {\n return clearTimeout(id);\n };\n } else if (!window.cancelAnimationFrame) {\n browserRequestAnimationFrame = window.requestAnimationFrame;\n window.requestAnimationFrame = function(callback, element) {\n var myId;\n myId = ++lastId;\n browserRequestAnimationFrame(function() {\n if (!isCancelled[myId]) {\n return callback();\n }\n }, element);\n return myId;\n };\n return window.cancelAnimationFrame = function(id) {\n return isCancelled[id] = true;\n };\n }\n })();\n\n secondsToString = function(sec) {\n var hr, min;\n hr = Math.floor(sec / 3600);\n min = Math.floor((sec - (hr * 3600)) / 60);\n sec -= (hr * 3600) + (min * 60);\n sec += '';\n min += '';\n while (min.length < 2) {\n min = '0' + min;\n }\n while (sec.length < 2) {\n sec = '0' + sec;\n }\n hr = hr ? hr + ':' : '';\n return hr + min + ':' + sec;\n };\n\n formatNumber = function() {\n var digits, num, value;\n num = 1 <= arguments.length ? slice.call(arguments, 0) : [];\n value = num[0];\n digits = 0 || num[1];\n return addCommas(value.toFixed(digits));\n };\n\n mergeObjects = function(obj1, obj2) {\n var key, out, val;\n out = {};\n for (key in obj1) {\n if (!hasProp.call(obj1, key)) continue;\n val = obj1[key];\n out[key] = val;\n }\n for (key in obj2) {\n if (!hasProp.call(obj2, key)) continue;\n val = obj2[key];\n out[key] = val;\n }\n return out;\n };\n\n addCommas = function(nStr) {\n var rgx, x, x1, x2;\n nStr += '';\n x = nStr.split('.');\n x1 = x[0];\n x2 = '';\n if (x.length > 1) {\n x2 = '.' + x[1];\n }\n rgx = /(\\d+)(\\d{3})/;\n while (rgx.test(x1)) {\n x1 = x1.replace(rgx, '$1' + ',' + '$2');\n }\n return x1 + x2;\n };\n\n cutHex = function(nStr) {\n if (nStr.charAt(0) === \"#\") {\n return nStr.substring(1, 7);\n }\n return nStr;\n };\n\n ValueUpdater = (function() {\n ValueUpdater.prototype.animationSpeed = 32;\n\n function ValueUpdater(addToAnimationQueue, clear) {\n if (addToAnimationQueue == null) {\n addToAnimationQueue = true;\n }\n this.clear = clear != null ? clear : true;\n if (addToAnimationQueue) {\n AnimationUpdater.add(this);\n }\n }\n\n ValueUpdater.prototype.update = function(force) {\n var diff;\n if (force == null) {\n force = false;\n }\n if (force || this.displayedValue !== this.value) {\n if (this.ctx && this.clear) {\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n diff = this.value - this.displayedValue;\n if (Math.abs(diff / this.animationSpeed) <= 0.001) {\n this.displayedValue = this.value;\n } else {\n this.displayedValue = this.displayedValue + diff / this.animationSpeed;\n }\n this.render();\n return true;\n }\n return false;\n };\n\n return ValueUpdater;\n\n })();\n\n BaseGauge = (function(superClass) {\n extend(BaseGauge, superClass);\n\n function BaseGauge() {\n return BaseGauge.__super__.constructor.apply(this, arguments);\n }\n\n BaseGauge.prototype.displayScale = 1;\n\n BaseGauge.prototype.forceUpdate = true;\n\n BaseGauge.prototype.setTextField = function(textField, fractionDigits) {\n return this.textField = textField instanceof TextRenderer ? textField : new TextRenderer(textField, fractionDigits);\n };\n\n BaseGauge.prototype.setMinValue = function(minValue, updateStartValue) {\n var gauge, j, len, ref, results;\n this.minValue = minValue;\n if (updateStartValue == null) {\n updateStartValue = true;\n }\n if (updateStartValue) {\n this.displayedValue = this.minValue;\n ref = this.gp || [];\n results = [];\n for (j = 0, len = ref.length; j < len; j++) {\n gauge = ref[j];\n results.push(gauge.displayedValue = this.minValue);\n }\n return results;\n }\n };\n\n BaseGauge.prototype.setOptions = function(options) {\n if (options == null) {\n options = null;\n }\n this.options = mergeObjects(this.options, options);\n if (this.textField) {\n this.textField.el.style.fontSize = options.fontSize + 'px';\n }\n if (this.options.angle > .5) {\n this.options.angle = .5;\n }\n this.configDisplayScale();\n return this;\n };\n\n BaseGauge.prototype.configDisplayScale = function() {\n var backingStorePixelRatio, devicePixelRatio, height, prevDisplayScale, width;\n prevDisplayScale = this.displayScale;\n if (this.options.highDpiSupport === false) {\n delete this.displayScale;\n } else {\n devicePixelRatio = window.devicePixelRatio || 1;\n backingStorePixelRatio = this.ctx.webkitBackingStorePixelRatio || this.ctx.mozBackingStorePixelRatio || this.ctx.msBackingStorePixelRatio || this.ctx.oBackingStorePixelRatio || this.ctx.backingStorePixelRatio || 1;\n this.displayScale = devicePixelRatio / backingStorePixelRatio;\n }\n if (this.displayScale !== prevDisplayScale) {\n width = this.canvas.G__width || this.canvas.width;\n height = this.canvas.G__height || this.canvas.height;\n this.canvas.width = width * this.displayScale;\n this.canvas.height = height * this.displayScale;\n this.canvas.style.width = width + \"px\";\n this.canvas.style.height = height + \"px\";\n this.canvas.G__width = width;\n this.canvas.G__height = height;\n }\n return this;\n };\n\n BaseGauge.prototype.parseValue = function(value) {\n value = parseFloat(value) || Number(value);\n if (isFinite(value)) {\n return value;\n } else {\n return 0;\n }\n };\n\n return BaseGauge;\n\n })(ValueUpdater);\n\n TextRenderer = (function() {\n function TextRenderer(el, fractionDigits1) {\n this.el = el;\n this.fractionDigits = fractionDigits1;\n }\n\n TextRenderer.prototype.render = function(gauge) {\n return this.el.innerHTML = formatNumber(gauge.displayedValue, this.fractionDigits);\n };\n\n return TextRenderer;\n\n })();\n\n AnimatedText = (function(superClass) {\n extend(AnimatedText, superClass);\n\n AnimatedText.prototype.displayedValue = 0;\n\n AnimatedText.prototype.value = 0;\n\n AnimatedText.prototype.setVal = function(value) {\n return this.value = 1 * value;\n };\n\n function AnimatedText(elem1, text) {\n this.elem = elem1;\n this.text = text != null ? text : false;\n AnimatedText.__super__.constructor.call(this);\n if (this.elem === void 0) {\n throw new Error('The element isn\\'t defined.');\n }\n this.value = 1 * this.elem.innerHTML;\n if (this.text) {\n this.value = 0;\n }\n }\n\n AnimatedText.prototype.render = function() {\n var textVal;\n if (this.text) {\n textVal = secondsToString(this.displayedValue.toFixed(0));\n } else {\n textVal = addCommas(formatNumber(this.displayedValue));\n }\n return this.elem.innerHTML = textVal;\n };\n\n return AnimatedText;\n\n })(ValueUpdater);\n\n AnimatedTextFactory = {\n create: function(objList) {\n var elem, j, len, out;\n out = [];\n for (j = 0, len = objList.length; j < len; j++) {\n elem = objList[j];\n out.push(new AnimatedText(elem));\n }\n return out;\n }\n };\n\n GaugePointer = (function(superClass) {\n extend(GaugePointer, superClass);\n\n GaugePointer.prototype.displayedValue = 0;\n\n GaugePointer.prototype.value = 0;\n\n GaugePointer.prototype.options = {\n strokeWidth: 0.035,\n length: 0.1,\n color: \"#000000\",\n iconPath: null,\n iconScale: 1.0,\n iconAngle: 0\n };\n\n GaugePointer.prototype.img = null;\n\n function GaugePointer(gauge1) {\n this.gauge = gauge1;\n if (this.gauge === void 0) {\n throw new Error('The element isn\\'t defined.');\n }\n this.ctx = this.gauge.ctx;\n this.canvas = this.gauge.canvas;\n GaugePointer.__super__.constructor.call(this, false, false);\n this.setOptions();\n }\n\n GaugePointer.prototype.setOptions = function(options) {\n if (options == null) {\n options = null;\n }\n this.options = mergeObjects(this.options, options);\n this.length = 2 * this.gauge.radius * this.gauge.options.radiusScale * this.options.length;\n this.strokeWidth = this.canvas.height * this.options.strokeWidth;\n this.maxValue = this.gauge.maxValue;\n this.minValue = this.gauge.minValue;\n this.animationSpeed = this.gauge.animationSpeed;\n this.options.angle = this.gauge.options.angle;\n if (this.options.iconPath) {\n this.img = new Image();\n return this.img.src = this.options.iconPath;\n }\n };\n\n GaugePointer.prototype.render = function() {\n var angle, endX, endY, imgX, imgY, startX, startY, x, y;\n angle = this.gauge.getAngle.call(this, this.displayedValue);\n x = Math.round(this.length * Math.cos(angle));\n y = Math.round(this.length * Math.sin(angle));\n startX = Math.round(this.strokeWidth * Math.cos(angle - Math.PI / 2));\n startY = Math.round(this.strokeWidth * Math.sin(angle - Math.PI / 2));\n endX = Math.round(this.strokeWidth * Math.cos(angle + Math.PI / 2));\n endY = Math.round(this.strokeWidth * Math.sin(angle + Math.PI / 2));\n this.ctx.beginPath();\n this.ctx.fillStyle = this.options.color;\n this.ctx.arc(0, 0, this.strokeWidth, 0, Math.PI * 2, false);\n this.ctx.fill();\n this.ctx.beginPath();\n this.ctx.moveTo(startX, startY);\n this.ctx.lineTo(x, y);\n this.ctx.lineTo(endX, endY);\n this.ctx.fill();\n if (this.img) {\n imgX = Math.round(this.img.width * this.options.iconScale);\n imgY = Math.round(this.img.height * this.options.iconScale);\n this.ctx.save();\n this.ctx.translate(x, y);\n this.ctx.rotate(angle + Math.PI / 180.0 * (90 + this.options.iconAngle));\n this.ctx.drawImage(this.img, -imgX / 2, -imgY / 2, imgX, imgY);\n return this.ctx.restore();\n }\n };\n\n return GaugePointer;\n\n })(ValueUpdater);\n\n Bar = (function() {\n function Bar(elem1) {\n this.elem = elem1;\n }\n\n Bar.prototype.updateValues = function(arrValues) {\n this.value = arrValues[0];\n this.maxValue = arrValues[1];\n this.avgValue = arrValues[2];\n return this.render();\n };\n\n Bar.prototype.render = function() {\n var avgPercent, valPercent;\n if (this.textField) {\n this.textField.text(formatNumber(this.value));\n }\n if (this.maxValue === 0) {\n this.maxValue = this.avgValue * 2;\n }\n valPercent = (this.value / this.maxValue) * 100;\n avgPercent = (this.avgValue / this.maxValue) * 100;\n $(\".bar-value\", this.elem).css({\n \"width\": valPercent + \"%\"\n });\n return $(\".typical-value\", this.elem).css({\n \"width\": avgPercent + \"%\"\n });\n };\n\n return Bar;\n\n })();\n\n Gauge = (function(superClass) {\n extend(Gauge, superClass);\n\n Gauge.prototype.elem = null;\n\n Gauge.prototype.value = [20];\n\n Gauge.prototype.maxValue = 80;\n\n Gauge.prototype.minValue = 0;\n\n Gauge.prototype.displayedAngle = 0;\n\n Gauge.prototype.displayedValue = 0;\n\n Gauge.prototype.lineWidth = 40;\n\n Gauge.prototype.paddingTop = 0.1;\n\n Gauge.prototype.paddingBottom = 0.1;\n\n Gauge.prototype.percentColors = null;\n\n Gauge.prototype.options = {\n colorStart: \"#6fadcf\",\n colorStop: void 0,\n gradientType: 0,\n strokeColor: \"#e0e0e0\",\n pointer: {\n length: 0.8,\n strokeWidth: 0.035,\n iconScale: 1.0\n },\n angle: 0.15,\n lineWidth: 0.44,\n radiusScale: 1.0,\n fontSize: 40,\n limitMax: false,\n limitMin: false\n };\n\n function Gauge(canvas) {\n var h, w;\n this.canvas = canvas;\n Gauge.__super__.constructor.call(this);\n this.percentColors = null;\n if (typeof G_vmlCanvasManager !== 'undefined') {\n this.canvas = window.G_vmlCanvasManager.initElement(this.canvas);\n }\n this.ctx = this.canvas.getContext('2d');\n h = this.canvas.clientHeight;\n w = this.canvas.clientWidth;\n this.canvas.height = h;\n this.canvas.width = w;\n this.gp = [new GaugePointer(this)];\n this.setOptions();\n }\n\n Gauge.prototype.setOptions = function(options) {\n var gauge, j, len, phi, ref;\n if (options == null) {\n options = null;\n }\n Gauge.__super__.setOptions.call(this, options);\n this.configPercentColors();\n this.extraPadding = 0;\n if (this.options.angle < 0) {\n phi = Math.PI * (1 + this.options.angle);\n this.extraPadding = Math.sin(phi);\n }\n this.availableHeight = this.canvas.height * (1 - this.paddingTop - this.paddingBottom);\n this.lineWidth = this.availableHeight * this.options.lineWidth;\n this.radius = (this.availableHeight - this.lineWidth / 2) / (1.0 + this.extraPadding);\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n ref = this.gp;\n for (j = 0, len = ref.length; j < len; j++) {\n gauge = ref[j];\n gauge.setOptions(this.options.pointer);\n gauge.render();\n }\n this.render();\n return this;\n };\n\n Gauge.prototype.configPercentColors = function() {\n var bval, gval, i, j, ref, results, rval;\n this.percentColors = null;\n if (this.options.percentColors !== void 0) {\n this.percentColors = new Array();\n results = [];\n for (i = j = 0, ref = this.options.percentColors.length - 1; 0 <= ref ? j <= ref : j >= ref; i = 0 <= ref ? ++j : --j) {\n rval = parseInt((cutHex(this.options.percentColors[i][1])).substring(0, 2), 16);\n gval = parseInt((cutHex(this.options.percentColors[i][1])).substring(2, 4), 16);\n bval = parseInt((cutHex(this.options.percentColors[i][1])).substring(4, 6), 16);\n results.push(this.percentColors[i] = {\n pct: this.options.percentColors[i][0],\n color: {\n r: rval,\n g: gval,\n b: bval\n }\n });\n }\n return results;\n }\n };\n\n Gauge.prototype.set = function(value) {\n var gp, i, j, k, l, len, ref, ref1, val;\n if (!(value instanceof Array)) {\n value = [value];\n }\n for (i = j = 0, ref = value.length - 1; 0 <= ref ? j <= ref : j >= ref; i = 0 <= ref ? ++j : --j) {\n value[i] = this.parseValue(value[i]);\n }\n if (value.length > this.gp.length) {\n for (i = k = 0, ref1 = value.length - this.gp.length; 0 <= ref1 ? k < ref1 : k > ref1; i = 0 <= ref1 ? ++k : --k) {\n gp = new GaugePointer(this);\n gp.setOptions(this.options.pointer);\n this.gp.push(gp);\n }\n } else if (value.length < this.gp.length) {\n this.gp = this.gp.slice(this.gp.length - value.length);\n }\n i = 0;\n for (l = 0, len = value.length; l < len; l++) {\n val = value[l];\n if (val > this.maxValue) {\n if (this.options.limitMax) {\n val = this.maxValue;\n } else {\n this.maxValue = val + 1;\n }\n } else if (val < this.minValue) {\n if (this.options.limitMin) {\n val = this.minValue;\n } else {\n this.minValue = val - 1;\n }\n }\n this.gp[i].value = val;\n this.gp[i++].setOptions({\n minValue: this.minValue,\n maxValue: this.maxValue,\n angle: this.options.angle\n });\n }\n this.value = Math.max(Math.min(value[value.length - 1], this.maxValue), this.minValue);\n AnimationUpdater.run(this.forceUpdate);\n return this.forceUpdate = false;\n };\n\n Gauge.prototype.getAngle = function(value) {\n return (1 + this.options.angle) * Math.PI + ((value - this.minValue) / (this.maxValue - this.minValue)) * (1 - this.options.angle * 2) * Math.PI;\n };\n\n Gauge.prototype.getColorForPercentage = function(pct, grad) {\n var color, endColor, i, j, rangePct, ref, startColor;\n if (pct === 0) {\n color = this.percentColors[0].color;\n } else {\n color = this.percentColors[this.percentColors.length - 1].color;\n for (i = j = 0, ref = this.percentColors.length - 1; 0 <= ref ? j <= ref : j >= ref; i = 0 <= ref ? ++j : --j) {\n if (pct <= this.percentColors[i].pct) {\n if (grad === true) {\n startColor = this.percentColors[i - 1] || this.percentColors[0];\n endColor = this.percentColors[i];\n rangePct = (pct - startColor.pct) / (endColor.pct - startColor.pct);\n color = {\n r: Math.floor(startColor.color.r * (1 - rangePct) + endColor.color.r * rangePct),\n g: Math.floor(startColor.color.g * (1 - rangePct) + endColor.color.g * rangePct),\n b: Math.floor(startColor.color.b * (1 - rangePct) + endColor.color.b * rangePct)\n };\n } else {\n color = this.percentColors[i].color;\n }\n break;\n }\n }\n }\n return 'rgb(' + [color.r, color.g, color.b].join(',') + ')';\n };\n\n Gauge.prototype.getColorForValue = function(val, grad) {\n var pct;\n pct = (val - this.minValue) / (this.maxValue - this.minValue);\n return this.getColorForPercentage(pct, grad);\n };\n\n Gauge.prototype.renderStaticLabels = function(staticLabels, w, h, radius) {\n var font, fontsize, j, len, match, re, ref, rest, rotationAngle, value;\n this.ctx.save();\n this.ctx.translate(w, h);\n font = staticLabels.font || \"10px Times\";\n re = /\\d+\\.?\\d?/;\n match = font.match(re)[0];\n rest = font.slice(match.length);\n fontsize = parseFloat(match) * this.displayScale;\n this.ctx.font = fontsize + rest;\n this.ctx.fillStyle = staticLabels.color || \"#000000\";\n this.ctx.textBaseline = \"bottom\";\n this.ctx.textAlign = \"center\";\n ref = staticLabels.labels;\n for (j = 0, len = ref.length; j < len; j++) {\n value = ref[j];\n if (value.label !== void 0) {\n if ((!this.options.limitMin || value >= this.minValue) && (!this.options.limitMax || value <= this.maxValue)) {\n font = value.font || staticLabels.font;\n match = font.match(re)[0];\n rest = font.slice(match.length);\n fontsize = parseFloat(match) * this.displayScale;\n this.ctx.font = fontsize + rest;\n rotationAngle = this.getAngle(value.label) - 3 * Math.PI / 2;\n this.ctx.rotate(rotationAngle);\n this.ctx.fillText(formatNumber(value.label, staticLabels.fractionDigits), 0, -radius - this.lineWidth / 2);\n this.ctx.rotate(-rotationAngle);\n }\n } else {\n if ((!this.options.limitMin || value >= this.minValue) && (!this.options.limitMax || value <= this.maxValue)) {\n rotationAngle = this.getAngle(value) - 3 * Math.PI / 2;\n this.ctx.rotate(rotationAngle);\n this.ctx.fillText(formatNumber(value, staticLabels.fractionDigits), 0, -radius - this.lineWidth / 2);\n this.ctx.rotate(-rotationAngle);\n }\n }\n }\n return this.ctx.restore();\n };\n\n Gauge.prototype.renderTicks = function(ticksOptions, w, h, radius) {\n var currentDivision, currentSubDivision, divColor, divLength, divWidth, divisionCount, j, lineWidth, range, rangeDivisions, ref, results, scaleMutate, st, subColor, subDivisions, subLength, subWidth, subdivisionCount, t, tmpRadius;\n if (ticksOptions !== {}) {\n divisionCount = ticksOptions.divisions || 0;\n subdivisionCount = ticksOptions.subDivisions || 0;\n divColor = ticksOptions.divColor || '#fff';\n subColor = ticksOptions.subColor || '#fff';\n divLength = ticksOptions.divLength || 0.7;\n subLength = ticksOptions.subLength || 0.2;\n range = parseFloat(this.maxValue) - parseFloat(this.minValue);\n rangeDivisions = parseFloat(range) / parseFloat(ticksOptions.divisions);\n subDivisions = parseFloat(rangeDivisions) / parseFloat(ticksOptions.subDivisions);\n currentDivision = parseFloat(this.minValue);\n currentSubDivision = 0.0 + subDivisions;\n lineWidth = range / 400;\n divWidth = lineWidth * (ticksOptions.divWidth || 1);\n subWidth = lineWidth * (ticksOptions.subWidth || 1);\n results = [];\n for (t = j = 0, ref = divisionCount + 1; j < ref; t = j += 1) {\n this.ctx.lineWidth = this.lineWidth * divLength;\n scaleMutate = (this.lineWidth / 2) * (1 - divLength);\n tmpRadius = (this.radius * this.options.radiusScale) + scaleMutate;\n this.ctx.strokeStyle = divColor;\n this.ctx.beginPath();\n this.ctx.arc(0, 0, tmpRadius, this.getAngle(currentDivision - divWidth), this.getAngle(currentDivision + divWidth), false);\n this.ctx.stroke();\n currentSubDivision = currentDivision + subDivisions;\n currentDivision += rangeDivisions;\n if (t !== ticksOptions.divisions && subdivisionCount > 0) {\n results.push((function() {\n var k, ref1, results1;\n results1 = [];\n for (st = k = 0, ref1 = subdivisionCount - 1; k < ref1; st = k += 1) {\n this.ctx.lineWidth = this.lineWidth * subLength;\n scaleMutate = (this.lineWidth / 2) * (1 - subLength);\n tmpRadius = (this.radius * this.options.radiusScale) + scaleMutate;\n this.ctx.strokeStyle = subColor;\n this.ctx.beginPath();\n this.ctx.arc(0, 0, tmpRadius, this.getAngle(currentSubDivision - subWidth), this.getAngle(currentSubDivision + subWidth), false);\n this.ctx.stroke();\n results1.push(currentSubDivision += subDivisions);\n }\n return results1;\n }).call(this));\n } else {\n results.push(void 0);\n }\n }\n return results;\n }\n };\n\n Gauge.prototype.render = function() {\n var displayedAngle, fillStyle, gauge, h, j, k, len, len1, max, min, radius, ref, ref1, scaleMutate, tmpRadius, w, zone;\n w = this.canvas.width / 2;\n h = (this.canvas.height * this.paddingTop + this.availableHeight) - ((this.radius + this.lineWidth / 2) * this.extraPadding);\n displayedAngle = this.getAngle(this.displayedValue);\n if (this.textField) {\n this.textField.render(this);\n }\n this.ctx.lineCap = \"butt\";\n radius = this.radius * this.options.radiusScale;\n if (this.options.staticLabels) {\n this.renderStaticLabels(this.options.staticLabels, w, h, radius);\n }\n if (this.options.staticZones) {\n this.ctx.save();\n this.ctx.translate(w, h);\n this.ctx.lineWidth = this.lineWidth;\n ref = this.options.staticZones;\n for (j = 0, len = ref.length; j < len; j++) {\n zone = ref[j];\n min = zone.min;\n if (this.options.limitMin && min < this.minValue) {\n min = this.minValue;\n }\n max = zone.max;\n if (this.options.limitMax && max > this.maxValue) {\n max = this.maxValue;\n }\n tmpRadius = this.radius * this.options.radiusScale;\n if (zone.height) {\n this.ctx.lineWidth = this.lineWidth * zone.height;\n scaleMutate = (this.lineWidth / 2) * (zone.offset || 1 - zone.height);\n tmpRadius = (this.radius * this.options.radiusScale) + scaleMutate;\n }\n this.ctx.strokeStyle = zone.strokeStyle;\n this.ctx.beginPath();\n this.ctx.arc(0, 0, tmpRadius, this.getAngle(min), this.getAngle(max), false);\n this.ctx.stroke();\n }\n } else {\n if (this.options.customFillStyle !== void 0) {\n fillStyle = this.options.customFillStyle(this);\n } else if (this.percentColors !== null) {\n fillStyle = this.getColorForValue(this.displayedValue, this.options.generateGradient);\n } else if (this.options.colorStop !== void 0) {\n if (this.options.gradientType === 0) {\n fillStyle = this.ctx.createRadialGradient(w, h, 9, w, h, 70);\n } else {\n fillStyle = this.ctx.createLinearGradient(0, 0, w, 0);\n }\n fillStyle.addColorStop(0, this.options.colorStart);\n fillStyle.addColorStop(1, this.options.colorStop);\n } else {\n fillStyle = this.options.colorStart;\n }\n this.ctx.strokeStyle = fillStyle;\n this.ctx.beginPath();\n this.ctx.arc(w, h, radius, (1 + this.options.angle) * Math.PI, displayedAngle, false);\n this.ctx.lineWidth = this.lineWidth;\n this.ctx.stroke();\n this.ctx.strokeStyle = this.options.strokeColor;\n this.ctx.beginPath();\n this.ctx.arc(w, h, radius, displayedAngle, (2 - this.options.angle) * Math.PI, false);\n this.ctx.stroke();\n this.ctx.save();\n this.ctx.translate(w, h);\n }\n if (this.options.renderTicks) {\n this.renderTicks(this.options.renderTicks, w, h, radius);\n }\n this.ctx.restore();\n this.ctx.translate(w, h);\n ref1 = this.gp;\n for (k = 0, len1 = ref1.length; k < len1; k++) {\n gauge = ref1[k];\n gauge.update(true);\n }\n return this.ctx.translate(-w, -h);\n };\n\n return Gauge;\n\n })(BaseGauge);\n\n BaseDonut = (function(superClass) {\n extend(BaseDonut, superClass);\n\n BaseDonut.prototype.lineWidth = 15;\n\n BaseDonut.prototype.displayedValue = 0;\n\n BaseDonut.prototype.value = 33;\n\n BaseDonut.prototype.maxValue = 80;\n\n BaseDonut.prototype.minValue = 0;\n\n BaseDonut.prototype.options = {\n lineWidth: 0.10,\n colorStart: \"#6f6ea0\",\n colorStop: \"#c0c0db\",\n strokeColor: \"#eeeeee\",\n shadowColor: \"#d5d5d5\",\n angle: 0.35,\n radiusScale: 1.0\n };\n\n function BaseDonut(canvas) {\n this.canvas = canvas;\n BaseDonut.__super__.constructor.call(this);\n if (typeof G_vmlCanvasManager !== 'undefined') {\n this.canvas = window.G_vmlCanvasManager.initElement(this.canvas);\n }\n this.ctx = this.canvas.getContext('2d');\n this.setOptions();\n this.render();\n }\n\n BaseDonut.prototype.getAngle = function(value) {\n return (1 - this.options.angle) * Math.PI + ((value - this.minValue) / (this.maxValue - this.minValue)) * ((2 + this.options.angle) - (1 - this.options.angle)) * Math.PI;\n };\n\n BaseDonut.prototype.setOptions = function(options) {\n if (options == null) {\n options = null;\n }\n BaseDonut.__super__.setOptions.call(this, options);\n this.lineWidth = this.canvas.height * this.options.lineWidth;\n this.radius = this.options.radiusScale * (this.canvas.height / 2 - this.lineWidth / 2);\n return this;\n };\n\n BaseDonut.prototype.set = function(value) {\n this.value = this.parseValue(value);\n if (this.value > this.maxValue) {\n if (this.options.limitMax) {\n this.value = this.maxValue;\n } else {\n this.maxValue = this.value;\n }\n } else if (this.value < this.minValue) {\n if (this.options.limitMin) {\n this.value = this.minValue;\n } else {\n this.minValue = this.value;\n }\n }\n AnimationUpdater.run(this.forceUpdate);\n return this.forceUpdate = false;\n };\n\n BaseDonut.prototype.render = function() {\n var displayedAngle, grdFill, h, start, stop, w;\n displayedAngle = this.getAngle(this.displayedValue);\n w = this.canvas.width / 2;\n h = this.canvas.height / 2;\n if (this.textField) {\n this.textField.render(this);\n }\n grdFill = this.ctx.createRadialGradient(w, h, 39, w, h, 70);\n grdFill.addColorStop(0, this.options.colorStart);\n grdFill.addColorStop(1, this.options.colorStop);\n start = this.radius - this.lineWidth / 2;\n stop = this.radius + this.lineWidth / 2;\n this.ctx.strokeStyle = this.options.strokeColor;\n this.ctx.beginPath();\n this.ctx.arc(w, h, this.radius, (1 - this.options.angle) * Math.PI, (2 + this.options.angle) * Math.PI, false);\n this.ctx.lineWidth = this.lineWidth;\n this.ctx.lineCap = \"round\";\n this.ctx.stroke();\n this.ctx.strokeStyle = grdFill;\n this.ctx.beginPath();\n this.ctx.arc(w, h, this.radius, (1 - this.options.angle) * Math.PI, displayedAngle, false);\n return this.ctx.stroke();\n };\n\n return BaseDonut;\n\n })(BaseGauge);\n\n Donut = (function(superClass) {\n extend(Donut, superClass);\n\n function Donut() {\n return Donut.__super__.constructor.apply(this, arguments);\n }\n\n Donut.prototype.strokeGradient = function(w, h, start, stop) {\n var grd;\n grd = this.ctx.createRadialGradient(w, h, start, w, h, stop);\n grd.addColorStop(0, this.options.shadowColor);\n grd.addColorStop(0.12, this.options._orgStrokeColor);\n grd.addColorStop(0.88, this.options._orgStrokeColor);\n grd.addColorStop(1, this.options.shadowColor);\n return grd;\n };\n\n Donut.prototype.setOptions = function(options) {\n var h, start, stop, w;\n if (options == null) {\n options = null;\n }\n Donut.__super__.setOptions.call(this, options);\n w = this.canvas.width / 2;\n h = this.canvas.height / 2;\n start = this.radius - this.lineWidth / 2;\n stop = this.radius + this.lineWidth / 2;\n this.options._orgStrokeColor = this.options.strokeColor;\n this.options.strokeColor = this.strokeGradient(w, h, start, stop);\n return this;\n };\n\n return Donut;\n\n })(BaseDonut);\n\n window.AnimationUpdater = {\n elements: [],\n animId: null,\n addAll: function(list) {\n var elem, j, len, results;\n results = [];\n for (j = 0, len = list.length; j < len; j++) {\n elem = list[j];\n results.push(AnimationUpdater.elements.push(elem));\n }\n return results;\n },\n add: function(object) {\n return AnimationUpdater.elements.push(object);\n },\n run: function(force) {\n var elem, finished, isCallback, j, len, ref;\n if (force == null) {\n force = false;\n }\n isCallback = isFinite(parseFloat(force));\n if (isCallback || force === true) {\n finished = true;\n ref = AnimationUpdater.elements;\n for (j = 0, len = ref.length; j < len; j++) {\n elem = ref[j];\n if (elem.update(force === true)) {\n finished = false;\n }\n }\n return AnimationUpdater.animId = finished ? null : requestAnimationFrame(AnimationUpdater.run);\n } else if (force === false) {\n if (AnimationUpdater.animId === !null) {\n cancelAnimationFrame(AnimationUpdater.animId);\n }\n return AnimationUpdater.animId = requestAnimationFrame(AnimationUpdater.run);\n }\n }\n };\n\n if (typeof window.define === 'function' && (window.define.amd != null)) {\n define(function() {\n return {\n Gauge: Gauge,\n Donut: Donut,\n BaseDonut: BaseDonut,\n TextRenderer: TextRenderer\n };\n });\n } else if (typeof module !== 'undefined' && (module.exports != null)) {\n module.exports = {\n Gauge: Gauge,\n Donut: Donut,\n BaseDonut: BaseDonut,\n TextRenderer: TextRenderer\n };\n } else {\n window.Gauge = Gauge;\n window.Donut = Donut;\n window.BaseDonut = BaseDonut;\n window.TextRenderer = TextRenderer;\n }\n\n}).call(this);\n","var tabbable = require('tabbable');\nvar xtend = require('xtend');\n\nvar activeFocusDelay;\n\nvar activeFocusTraps = (function() {\n var trapQueue = [];\n return {\n activateTrap: function(trap) {\n if (trapQueue.length > 0) {\n var activeTrap = trapQueue[trapQueue.length - 1];\n if (activeTrap !== trap) {\n activeTrap.pause();\n }\n }\n\n var trapIndex = trapQueue.indexOf(trap);\n if (trapIndex === -1) {\n trapQueue.push(trap);\n } else {\n // move this existing trap to the front of the queue\n trapQueue.splice(trapIndex, 1);\n trapQueue.push(trap);\n }\n },\n\n deactivateTrap: function(trap) {\n var trapIndex = trapQueue.indexOf(trap);\n if (trapIndex !== -1) {\n trapQueue.splice(trapIndex, 1);\n }\n\n if (trapQueue.length > 0) {\n trapQueue[trapQueue.length - 1].unpause();\n }\n }\n };\n})();\n\nfunction focusTrap(element, userOptions) {\n var doc = document;\n var container =\n typeof element === 'string' ? doc.querySelector(element) : element;\n\n var config = xtend(\n {\n returnFocusOnDeactivate: true,\n escapeDeactivates: true\n },\n userOptions\n );\n\n var state = {\n firstTabbableNode: null,\n lastTabbableNode: null,\n nodeFocusedBeforeActivation: null,\n mostRecentlyFocusedNode: null,\n active: false,\n paused: false\n };\n\n var trap = {\n activate: activate,\n deactivate: deactivate,\n pause: pause,\n unpause: unpause\n };\n\n return trap;\n\n function activate(activateOptions) {\n if (state.active) return;\n\n updateTabbableNodes();\n\n state.active = true;\n state.paused = false;\n state.nodeFocusedBeforeActivation = doc.activeElement;\n\n var onActivate =\n activateOptions && activateOptions.onActivate\n ? activateOptions.onActivate\n : config.onActivate;\n if (onActivate) {\n onActivate();\n }\n\n addListeners();\n return trap;\n }\n\n function deactivate(deactivateOptions) {\n if (!state.active) return;\n\n clearTimeout(activeFocusDelay);\n\n removeListeners();\n state.active = false;\n state.paused = false;\n\n activeFocusTraps.deactivateTrap(trap);\n\n var onDeactivate =\n deactivateOptions && deactivateOptions.onDeactivate !== undefined\n ? deactivateOptions.onDeactivate\n : config.onDeactivate;\n if (onDeactivate) {\n onDeactivate();\n }\n\n var returnFocus =\n deactivateOptions && deactivateOptions.returnFocus !== undefined\n ? deactivateOptions.returnFocus\n : config.returnFocusOnDeactivate;\n if (returnFocus) {\n delay(function() {\n tryFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation));\n });\n }\n\n return trap;\n }\n\n function pause() {\n if (state.paused || !state.active) return;\n state.paused = true;\n removeListeners();\n }\n\n function unpause() {\n if (!state.paused || !state.active) return;\n state.paused = false;\n updateTabbableNodes();\n addListeners();\n }\n\n function addListeners() {\n if (!state.active) return;\n\n // There can be only one listening focus trap at a time\n activeFocusTraps.activateTrap(trap);\n\n // Delay ensures that the focused element doesn't capture the event\n // that caused the focus trap activation.\n activeFocusDelay = delay(function() {\n tryFocus(getInitialFocusNode());\n });\n\n doc.addEventListener('focusin', checkFocusIn, true);\n doc.addEventListener('mousedown', checkPointerDown, {\n capture: true,\n passive: false\n });\n doc.addEventListener('touchstart', checkPointerDown, {\n capture: true,\n passive: false\n });\n doc.addEventListener('click', checkClick, {\n capture: true,\n passive: false\n });\n doc.addEventListener('keydown', checkKey, {\n capture: true,\n passive: false\n });\n\n return trap;\n }\n\n function removeListeners() {\n if (!state.active) return;\n\n doc.removeEventListener('focusin', checkFocusIn, true);\n doc.removeEventListener('mousedown', checkPointerDown, true);\n doc.removeEventListener('touchstart', checkPointerDown, true);\n doc.removeEventListener('click', checkClick, true);\n doc.removeEventListener('keydown', checkKey, true);\n\n return trap;\n }\n\n function getNodeForOption(optionName) {\n var optionValue = config[optionName];\n var node = optionValue;\n if (!optionValue) {\n return null;\n }\n if (typeof optionValue === 'string') {\n node = doc.querySelector(optionValue);\n if (!node) {\n throw new Error('`' + optionName + '` refers to no known node');\n }\n }\n if (typeof optionValue === 'function') {\n node = optionValue();\n if (!node) {\n throw new Error('`' + optionName + '` did not return a node');\n }\n }\n return node;\n }\n\n function getInitialFocusNode() {\n var node;\n if (getNodeForOption('initialFocus') !== null) {\n node = getNodeForOption('initialFocus');\n } else if (container.contains(doc.activeElement)) {\n node = doc.activeElement;\n } else {\n node = state.firstTabbableNode || getNodeForOption('fallbackFocus');\n }\n\n if (!node) {\n throw new Error(\n 'Your focus-trap needs to have at least one focusable element'\n );\n }\n\n return node;\n }\n\n function getReturnFocusNode(previousActiveElement) {\n var node = getNodeForOption('setReturnFocus');\n return node ? node : previousActiveElement;\n }\n\n // This needs to be done on mousedown and touchstart instead of click\n // so that it precedes the focus event.\n function checkPointerDown(e) {\n if (container.contains(e.target)) return;\n if (config.clickOutsideDeactivates) {\n deactivate({\n returnFocus: !tabbable.isFocusable(e.target)\n });\n return;\n }\n // This is needed for mobile devices.\n // (If we'll only let `click` events through,\n // then on mobile they will be blocked anyways if `touchstart` is blocked.)\n if (config.allowOutsideClick && config.allowOutsideClick(e)) {\n return;\n }\n e.preventDefault();\n }\n\n // In case focus escapes the trap for some strange reason, pull it back in.\n function checkFocusIn(e) {\n // In Firefox when you Tab out of an iframe the Document is briefly focused.\n if (container.contains(e.target) || e.target instanceof Document) {\n return;\n }\n e.stopImmediatePropagation();\n tryFocus(state.mostRecentlyFocusedNode || getInitialFocusNode());\n }\n\n function checkKey(e) {\n if (config.escapeDeactivates !== false && isEscapeEvent(e)) {\n e.preventDefault();\n deactivate();\n return;\n }\n if (isTabEvent(e)) {\n checkTab(e);\n return;\n }\n }\n\n // Hijack Tab events on the first and last focusable nodes of the trap,\n // in order to prevent focus from escaping. If it escapes for even a\n // moment it can end up scrolling the page and causing confusion so we\n // kind of need to capture the action at the keydown phase.\n function checkTab(e) {\n updateTabbableNodes();\n if (e.shiftKey && e.target === state.firstTabbableNode) {\n e.preventDefault();\n tryFocus(state.lastTabbableNode);\n return;\n }\n if (!e.shiftKey && e.target === state.lastTabbableNode) {\n e.preventDefault();\n tryFocus(state.firstTabbableNode);\n return;\n }\n }\n\n function checkClick(e) {\n if (config.clickOutsideDeactivates) return;\n if (container.contains(e.target)) return;\n if (config.allowOutsideClick && config.allowOutsideClick(e)) {\n return;\n }\n e.preventDefault();\n e.stopImmediatePropagation();\n }\n\n function updateTabbableNodes() {\n var tabbableNodes = tabbable(container);\n state.firstTabbableNode = tabbableNodes[0] || getInitialFocusNode();\n state.lastTabbableNode =\n tabbableNodes[tabbableNodes.length - 1] || getInitialFocusNode();\n }\n\n function tryFocus(node) {\n if (node === doc.activeElement) return;\n if (!node || !node.focus) {\n tryFocus(getInitialFocusNode());\n return;\n }\n node.focus();\n state.mostRecentlyFocusedNode = node;\n if (isSelectableInput(node)) {\n node.select();\n }\n }\n}\n\nfunction isSelectableInput(node) {\n return (\n node.tagName &&\n node.tagName.toLowerCase() === 'input' &&\n typeof node.select === 'function'\n );\n}\n\nfunction isEscapeEvent(e) {\n return e.key === 'Escape' || e.key === 'Esc' || e.keyCode === 27;\n}\n\nfunction isTabEvent(e) {\n return e.key === 'Tab' || e.keyCode === 9;\n}\n\nfunction delay(fn) {\n return setTimeout(fn, 0);\n}\n\nmodule.exports = focusTrap;\n","import toDate from \"../toDate/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\n/**\n * @name getTime\n * @category Timestamp Helpers\n * @summary Get the milliseconds timestamp of the given date.\n *\n * @description\n * Get the milliseconds timestamp of the given date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the timestamp\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Get the timestamp of 29 February 2012 11:45:05.123:\n * const result = getTime(new Date(2012, 1, 29, 11, 45, 5, 123))\n * //=> 1330515905123\n */\n\nexport default function getTime(dirtyDate) {\n requiredArgs(1, arguments);\n var date = toDate(dirtyDate);\n var timestamp = date.getTime();\n return timestamp;\n}","!function(e,t){\"object\"==typeof exports&&\"undefined\"!=typeof module?t(exports,require(\"react\"),require(\"prop-types\"),require(\"classnames\"),require(\"date-fns/isDate\"),require(\"date-fns/isValid\"),require(\"date-fns/format\"),require(\"date-fns/addMinutes\"),require(\"date-fns/addHours\"),require(\"date-fns/addDays\"),require(\"date-fns/addWeeks\"),require(\"date-fns/addMonths\"),require(\"date-fns/addYears\"),require(\"date-fns/subMinutes\"),require(\"date-fns/subHours\"),require(\"date-fns/subDays\"),require(\"date-fns/subWeeks\"),require(\"date-fns/subMonths\"),require(\"date-fns/subYears\"),require(\"date-fns/getSeconds\"),require(\"date-fns/getMinutes\"),require(\"date-fns/getHours\"),require(\"date-fns/getDay\"),require(\"date-fns/getDate\"),require(\"date-fns/getISOWeek\"),require(\"date-fns/getMonth\"),require(\"date-fns/getQuarter\"),require(\"date-fns/getYear\"),require(\"date-fns/getTime\"),require(\"date-fns/setSeconds\"),require(\"date-fns/setMinutes\"),require(\"date-fns/setHours\"),require(\"date-fns/setMonth\"),require(\"date-fns/setQuarter\"),require(\"date-fns/setYear\"),require(\"date-fns/min\"),require(\"date-fns/max\"),require(\"date-fns/differenceInCalendarDays\"),require(\"date-fns/differenceInCalendarMonths\"),require(\"date-fns/differenceInCalendarWeeks\"),require(\"date-fns/differenceInCalendarYears\"),require(\"date-fns/startOfDay\"),require(\"date-fns/startOfWeek\"),require(\"date-fns/startOfMonth\"),require(\"date-fns/startOfQuarter\"),require(\"date-fns/startOfYear\"),require(\"date-fns/endOfDay\"),require(\"date-fns/endOfWeek\"),require(\"date-fns/endOfMonth\"),require(\"date-fns/isEqual\"),require(\"date-fns/isSameDay\"),require(\"date-fns/isSameMonth\"),require(\"date-fns/isSameYear\"),require(\"date-fns/isSameQuarter\"),require(\"date-fns/isAfter\"),require(\"date-fns/isBefore\"),require(\"date-fns/isWithinInterval\"),require(\"date-fns/toDate\"),require(\"date-fns/parse\"),require(\"date-fns/parseISO\"),require(\"react-onclickoutside\"),require(\"react-dom\"),require(\"react-popper\")):\"function\"==typeof define&&define.amd?define([\"exports\",\"react\",\"prop-types\",\"classnames\",\"date-fns/isDate\",\"date-fns/isValid\",\"date-fns/format\",\"date-fns/addMinutes\",\"date-fns/addHours\",\"date-fns/addDays\",\"date-fns/addWeeks\",\"date-fns/addMonths\",\"date-fns/addYears\",\"date-fns/subMinutes\",\"date-fns/subHours\",\"date-fns/subDays\",\"date-fns/subWeeks\",\"date-fns/subMonths\",\"date-fns/subYears\",\"date-fns/getSeconds\",\"date-fns/getMinutes\",\"date-fns/getHours\",\"date-fns/getDay\",\"date-fns/getDate\",\"date-fns/getISOWeek\",\"date-fns/getMonth\",\"date-fns/getQuarter\",\"date-fns/getYear\",\"date-fns/getTime\",\"date-fns/setSeconds\",\"date-fns/setMinutes\",\"date-fns/setHours\",\"date-fns/setMonth\",\"date-fns/setQuarter\",\"date-fns/setYear\",\"date-fns/min\",\"date-fns/max\",\"date-fns/differenceInCalendarDays\",\"date-fns/differenceInCalendarMonths\",\"date-fns/differenceInCalendarWeeks\",\"date-fns/differenceInCalendarYears\",\"date-fns/startOfDay\",\"date-fns/startOfWeek\",\"date-fns/startOfMonth\",\"date-fns/startOfQuarter\",\"date-fns/startOfYear\",\"date-fns/endOfDay\",\"date-fns/endOfWeek\",\"date-fns/endOfMonth\",\"date-fns/isEqual\",\"date-fns/isSameDay\",\"date-fns/isSameMonth\",\"date-fns/isSameYear\",\"date-fns/isSameQuarter\",\"date-fns/isAfter\",\"date-fns/isBefore\",\"date-fns/isWithinInterval\",\"date-fns/toDate\",\"date-fns/parse\",\"date-fns/parseISO\",\"react-onclickoutside\",\"react-dom\",\"react-popper\"],t):t((e=\"undefined\"!=typeof globalThis?globalThis:e||self).DatePicker={},e.React,e.PropTypes,e.classNames,e.isDate,e.isValidDate,e.format,e.addMinutes,e.addHours,e.addDays,e.addWeeks,e.addMonths,e.addYears,null,null,e.subDays,e.subWeeks,e.subMonths,e.subYears,e.getSeconds,e.getMinutes,e.getHours,e.getDay,e.getDate,e.getISOWeek,e.getMonth,e.getQuarter,e.getYear,e.getTime,e.setSeconds,e.setMinutes,e.setHours,e.setMonth,e.setQuarter,e.setYear,e.min,e.max,e.differenceInCalendarDays,e.differenceInCalendarMonths,null,e.differenceInCalendarYears,e.startOfDay,e.startOfWeek,e.startOfMonth,e.startOfQuarter,e.startOfYear,e.endOfDay,null,null,e.dfIsEqual,e.dfIsSameDay,e.dfIsSameMonth,e.dfIsSameYear,e.dfIsSameQuarter,e.isAfter,e.isBefore,e.isWithinInterval,e.toDate,e.parse,e.parseISO,e.onClickOutside,e.ReactDOM,e.ReactPopper)}(this,(function(e,t,r,a,n,o,s,i,p,l,d,c,u,f,h,m,y,D,v,w,g,k,b,C,S,_,M,P,E,N,O,Y,x,T,I,L,F,R,q,A,W,K,B,j,H,Q,V,U,$,z,G,J,X,Z,ee,te,re,ae,ne,oe,se,ie,pe){\"use strict\";function le(e){return e&&\"object\"==typeof e&&\"default\"in e?e:{default:e}}var de=le(t),ce=le(a),ue=le(n),fe=le(o),he=le(s),me=le(i),ye=le(p),De=le(l),ve=le(d),we=le(c),ge=le(u),ke=le(m),be=le(y),Ce=le(D),Se=le(v),_e=le(w),Me=le(g),Pe=le(k),Ee=le(b),Ne=le(C),Oe=le(S),Ye=le(_),xe=le(M),Te=le(P),Ie=le(E),Le=le(N),Fe=le(O),Re=le(Y),qe=le(x),Ae=le(T),We=le(I),Ke=le(L),Be=le(F),je=le(R),He=le(q),Qe=le(W),Ve=le(K),Ue=le(B),$e=le(j),ze=le(H),Ge=le(Q),Je=le(V),Xe=le(z),Ze=le(G),et=le(J),tt=le(X),rt=le(Z),at=le(ee),nt=le(te),ot=le(re),st=le(ae),it=le(ne),pt=le(oe),lt=le(se),dt=le(ie);function ct(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function ut(e){for(var t=1;te.length)&&(t=e.length);for(var r=0,a=new Array(t);r0&&(o=it.default(e,t.slice(0,e.length),new Date)),It(o)||(o=new Date(e))),It(o)&&i?o:null)}function It(e,t){return t=t||new Date(\"1/1/1000\"),fe.default(e)&&at.default(e,t)}function Lt(e,t,r){if(\"en\"===r)return he.default(e,t,{awareOfUnicodeTokens:!0});var a=Xt(r);return r&&!a&&console.warn('A locale object was not found for the provided string [\"'.concat(r,'\"].')),!a&&Jt()&&Xt(Jt())&&(a=Xt(Jt())),he.default(e,t,{locale:a||null,awareOfUnicodeTokens:!0})}function Ft(e,t){var r=t.dateFormat,a=t.locale;return e&&Lt(e,Array.isArray(r)?r[0]:r,a)||\"\"}function Rt(e,t){var r=t.hour,a=void 0===r?0:r,n=t.minute,o=void 0===n?0:n,s=t.second,i=void 0===s?0:s;return Re.default(Fe.default(Le.default(e,i),o),a)}function qt(e,t){var r=t&&Xt(t)||Jt()&&Xt(Jt());return Oe.default(e,r?{locale:r}:null)}function At(e,t){return Lt(e,\"ddd\",t)}function Wt(e){return Ve.default(e)}function Kt(e,t,r){var a=Xt(t||Jt());return Ue.default(e,{locale:a,weekStartsOn:r})}function Bt(e){return $e.default(e)}function jt(e){return Ge.default(e)}function Ht(e){return ze.default(e)}function Qt(e,t){return e&&t?tt.default(e,t):!e&&!t}function Vt(e,t){return e&&t?et.default(e,t):!e&&!t}function Ut(e,t){return e&&t?rt.default(e,t):!e&&!t}function $t(e,t){return e&&t?Ze.default(e,t):!e&&!t}function zt(e,t){return e&&t?Xe.default(e,t):!e&&!t}function Gt(e,t,r){var a,n=Ve.default(t),o=Je.default(r);try{a=ot.default(e,{start:n,end:o})}catch(e){a=!1}return a}function Jt(){return(\"undefined\"!=typeof window?window:global).__localeId__}function Xt(e){if(\"string\"==typeof e){var t=\"undefined\"!=typeof window?window:global;return t.__localeData__?t.__localeData__[e]:null}return e}function Zt(e,t){return Lt(qe.default(xt(),e),\"LLLL\",t)}function er(e,t){return Lt(qe.default(xt(),e),\"LLL\",t)}function tr(e,t){return Lt(Ae.default(xt(),e),\"QQQ\",t)}function rr(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=t.minDate,a=t.maxDate,n=t.excludeDates,o=t.includeDates,s=t.filterDate;return lr(e,{minDate:r,maxDate:a})||n&&n.some((function(t){return $t(e,t)}))||o&&!o.some((function(t){return $t(e,t)}))||s&&!s(xt(e))||!1}function ar(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=t.excludeDates;return r&&r.some((function(t){return $t(e,t)}))||!1}function nr(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=t.minDate,a=t.maxDate,n=t.excludeDates,o=t.includeDates,s=t.filterDate;return lr(e,{minDate:r,maxDate:a})||n&&n.some((function(t){return Vt(e,t)}))||o&&!o.some((function(t){return Vt(e,t)}))||s&&!s(xt(e))||!1}function or(e,t,r,a){var n=Te.default(e),o=Ye.default(e),s=Te.default(t),i=Ye.default(t),p=Te.default(a);return n===s&&n===p?o<=r&&r<=i:n=r||pn:void 0}function sr(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=t.minDate,a=t.maxDate,n=t.excludeDates,o=t.includeDates,s=t.filterDate;return lr(e,{minDate:r,maxDate:a})||n&&n.some((function(t){return Ut(e,t)}))||o&&!o.some((function(t){return Ut(e,t)}))||s&&!s(xt(e))||!1}function ir(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=t.minDate,a=t.maxDate,n=new Date(e,0,1);return lr(n,{minDate:r,maxDate:a})||!1}function pr(e,t,r,a){var n=Te.default(e),o=xe.default(e),s=Te.default(t),i=xe.default(t),p=Te.default(a);return n===s&&n===p?o<=r&&r<=i:n=r||pn:void 0}function lr(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=t.minDate,a=t.maxDate;return r&&je.default(e,r)<0||a&&je.default(e,a)>0}function dr(e,t){return t.some((function(t){return Pe.default(t)===Pe.default(e)&&Me.default(t)===Me.default(e)}))}function cr(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=t.excludeTimes,a=t.includeTimes,n=t.filterTime;return r&&dr(e,r)||a&&!dr(e,a)||n&&!n(e)||!1}function ur(e,t){var r=t.minTime,a=t.maxTime;if(!r||!a)throw new Error(\"Both minTime and maxTime props required\");var n,o=xt(),s=Re.default(Fe.default(o,Me.default(e)),Pe.default(e)),i=Re.default(Fe.default(o,Me.default(r)),Pe.default(r)),p=Re.default(Fe.default(o,Me.default(a)),Pe.default(a));try{n=!ot.default(s,{start:i,end:p})}catch(e){n=!1}return n}function fr(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=t.minDate,a=t.includeDates,n=Ce.default(e,1);return r&&He.default(r,n)>0||a&&a.every((function(e){return He.default(e,n)>0}))||!1}function hr(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=t.maxDate,a=t.includeDates,n=we.default(e,1);return r&&He.default(n,r)>0||a&&a.every((function(e){return He.default(n,e)>0}))||!1}function mr(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=t.minDate,a=t.includeDates,n=Se.default(e,1);return r&&Qe.default(r,n)>0||a&&a.every((function(e){return Qe.default(e,n)>0}))||!1}function yr(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=t.maxDate,a=t.includeDates,n=ge.default(e,1);return r&&Qe.default(n,r)>0||a&&a.every((function(e){return Qe.default(n,e)>0}))||!1}function Dr(e){var t=e.minDate,r=e.includeDates;if(r&&t){var a=r.filter((function(e){return je.default(e,t)>=0}));return Ke.default(a)}return r?Ke.default(r):t}function vr(e){var t=e.maxDate,r=e.includeDates;if(r&&t){var a=r.filter((function(e){return je.default(e,t)<=0}));return Be.default(a)}return r?Be.default(r):t}function wr(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:\"react-datepicker__day--highlighted\",r=new Map,a=0,n=e.length;a1&&void 0!==arguments[1]?arguments[1]:Ot,r=Math.ceil(Te.default(e)/t)*t,a=r-(t-1);return{startPeriod:a,endPeriod:r}}function Cr(e,t,r,a){for(var n=[],o=0;o<2*t+1;o++){var s=e+t-o,i=!0;r&&(i=Te.default(r)<=s),a&&i&&(i=Te.default(a)>=s),i&&n.push(s)}return n}var Sr=function(e){wt(r,e);var t=St(r);function r(e){var a;ht(this,r),Dt(bt(a=t.call(this,e)),\"renderOptions\",(function(){var e=a.props.year,t=a.state.yearsList.map((function(t){return de.default.createElement(\"div\",{className:e===t?\"react-datepicker__year-option react-datepicker__year-option--selected_year\":\"react-datepicker__year-option\",key:t,onClick:a.onChange.bind(bt(a),t)},e===t?de.default.createElement(\"span\",{className:\"react-datepicker__year-option--selected\"},\"✓\"):\"\",t)})),r=a.props.minDate?Te.default(a.props.minDate):null,n=a.props.maxDate?Te.default(a.props.maxDate):null;return n&&a.state.yearsList.find((function(e){return e===n}))||t.unshift(de.default.createElement(\"div\",{className:\"react-datepicker__year-option\",key:\"upcoming\",onClick:a.incrementYears},de.default.createElement(\"a\",{className:\"react-datepicker__navigation react-datepicker__navigation--years react-datepicker__navigation--years-upcoming\"}))),r&&a.state.yearsList.find((function(e){return e===r}))||t.push(de.default.createElement(\"div\",{className:\"react-datepicker__year-option\",key:\"previous\",onClick:a.decrementYears},de.default.createElement(\"a\",{className:\"react-datepicker__navigation react-datepicker__navigation--years react-datepicker__navigation--years-previous\"}))),t})),Dt(bt(a),\"onChange\",(function(e){a.props.onChange(e)})),Dt(bt(a),\"handleClickOutside\",(function(){a.props.onCancel()})),Dt(bt(a),\"shiftYears\",(function(e){var t=a.state.yearsList.map((function(t){return t+e}));a.setState({yearsList:t})})),Dt(bt(a),\"incrementYears\",(function(){return a.shiftYears(1)})),Dt(bt(a),\"decrementYears\",(function(){return a.shiftYears(-1)}));var n=e.yearDropdownItemNumber,o=e.scrollableYearDropdown,s=n||(o?10:5);return a.state={yearsList:Cr(a.props.year,s,a.props.minDate,a.props.maxDate)},a}return yt(r,[{key:\"render\",value:function(){var e=ce.default({\"react-datepicker__year-dropdown\":!0,\"react-datepicker__year-dropdown--scrollable\":this.props.scrollableYearDropdown});return de.default.createElement(\"div\",{className:e},this.renderOptions())}}]),r}(de.default.Component),_r=lt.default(Sr),Mr=function(e){wt(r,e);var t=St(r);function r(){var e;ht(this,r);for(var a=arguments.length,n=new Array(a),o=0;o0&&void 0!==arguments[0]?arguments[0]:{},r=!1;0===e.getTabIndex()&&!t.isInputFocused&&e.isSameDay(e.props.preSelection)&&(document.activeElement&&document.activeElement!==document.body||(r=!0),e.props.inline&&!e.props.shouldFocusDayInline&&(r=!1),e.props.containerRef&&e.props.containerRef.current&&e.props.containerRef.current.contains(document.activeElement)&&document.activeElement.classList.contains(\"react-datepicker__day\")&&(r=!0)),r&&e.dayEl.current.focus({preventScroll:!0})})),Dt(bt(e),\"renderDayContents\",(function(){if(e.isOutsideMonth()){if(e.props.monthShowsDuplicateDaysEnd&&Ne.default(e.props.day)<10)return null;if(e.props.monthShowsDuplicateDaysStart&&Ne.default(e.props.day)>20)return null}return e.props.renderDayContents?e.props.renderDayContents(Ne.default(e.props.day),e.props.day):Ne.default(e.props.day)})),Dt(bt(e),\"render\",(function(){return de.default.createElement(\"div\",{ref:e.dayEl,className:e.getClassNames(e.props.day),onKeyDown:e.handleOnKeyDown,onClick:e.handleClick,onMouseEnter:e.handleMouseEnter,tabIndex:e.getTabIndex(),\"aria-label\":e.getAriaLabel(),role:\"button\",\"aria-disabled\":e.isDisabled()},e.renderDayContents())})),e}return yt(r,[{key:\"componentDidMount\",value:function(){this.handleFocusDay()}},{key:\"componentDidUpdate\",value:function(e){this.handleFocusDay(e)}}]),r}(de.default.Component),Lr=function(e){wt(r,e);var t=St(r);function r(){var e;ht(this,r);for(var a=arguments.length,n=new Array(a),o=0;o=6,i=!r&&!e.isWeekInMonth(o);if(s||i){if(!e.props.peekNextMonth)break;n=!0}}return t})),Dt(bt(e),\"onMonthClick\",(function(t,r){e.handleDayClick(Bt(qe.default(e.props.day,r)),t)})),Dt(bt(e),\"handleMonthNavigation\",(function(t,r){e.isDisabled(r)||e.isExcluded(r)||(e.props.setPreSelection(r),e.MONTH_REFS[t].current&&e.MONTH_REFS[t].current.focus())})),Dt(bt(e),\"onMonthKeyDown\",(function(t,r){var a=t.key;if(!e.props.disabledKeyboardNavigation)switch(a){case\"Enter\":e.onMonthClick(t,r),e.props.setPreSelection(e.props.selected);break;case\"ArrowRight\":e.handleMonthNavigation(11===r?0:r+1,we.default(e.props.preSelection,1));break;case\"ArrowLeft\":e.handleMonthNavigation(0===r?11:r-1,Ce.default(e.props.preSelection,1))}})),Dt(bt(e),\"onQuarterClick\",(function(t,r){e.handleDayClick(Ht(Ae.default(e.props.day,r)),t)})),Dt(bt(e),\"getMonthClassNames\",(function(t){var r=e.props,a=r.day,n=r.startDate,o=r.endDate,s=r.selected,i=r.minDate,p=r.maxDate,l=r.preSelection,d=r.monthClassName,c=d?d(a):void 0;return ce.default(\"react-datepicker__month-text\",\"react-datepicker__month-\".concat(t),c,{\"react-datepicker__month--disabled\":(i||p)&&nr(qe.default(a,t),e.props),\"react-datepicker__month--selected\":Ye.default(a)===t&&Te.default(a)===Te.default(s),\"react-datepicker__month-text--keyboard-selected\":Ye.default(l)===t,\"react-datepicker__month--in-range\":or(n,o,t,a),\"react-datepicker__month--range-start\":e.isRangeStartMonth(t),\"react-datepicker__month--range-end\":e.isRangeEndMonth(t)})})),Dt(bt(e),\"getTabIndex\",(function(t){var r=Ye.default(e.props.preSelection);return e.props.disabledKeyboardNavigation||t!==r?\"-1\":\"0\"})),Dt(bt(e),\"getAriaLabel\",(function(t){var r=e.props,a=r.ariaLabelPrefix,n=void 0===a?\"Choose\":a,o=r.disabledDayAriaLabelPrefix,s=void 0===o?\"Not available\":o,i=r.day,p=qe.default(i,t),l=e.isDisabled(p)||e.isExcluded(p)?s:n;return\"\".concat(l,\" \").concat(Lt(p,\"MMMM yyyy\"))})),Dt(bt(e),\"getQuarterClassNames\",(function(t){var r=e.props,a=r.day,n=r.startDate,o=r.endDate,s=r.selected,i=r.minDate,p=r.maxDate;return ce.default(\"react-datepicker__quarter-text\",\"react-datepicker__quarter-\".concat(t),{\"react-datepicker__quarter--disabled\":(i||p)&&sr(Ae.default(a,t),e.props),\"react-datepicker__quarter--selected\":xe.default(a)===t&&Te.default(a)===Te.default(s),\"react-datepicker__quarter--in-range\":pr(n,o,t,a),\"react-datepicker__quarter--range-start\":e.isRangeStartQuarter(t),\"react-datepicker__quarter--range-end\":e.isRangeEndQuarter(t)})})),Dt(bt(e),\"renderMonths\",(function(){var t=e.props,r=t.showFullMonthYearPicker,a=t.showTwoColumnMonthYearPicker,n=t.showFourColumnMonthYearPicker,o=t.locale;return(n?[[0,1,2,3],[4,5,6,7],[8,9,10,11]]:a?[[0,1],[2,3],[4,5],[6,7],[8,9],[10,11]]:[[0,1,2],[3,4,5],[6,7,8],[9,10,11]]).map((function(t,a){return de.default.createElement(\"div\",{className:\"react-datepicker__month-wrapper\",key:a},t.map((function(t,a){return de.default.createElement(\"div\",{ref:e.MONTH_REFS[t],key:a,onClick:function(r){e.onMonthClick(r,t)},onKeyDown:function(r){e.onMonthKeyDown(r,t)},tabIndex:e.getTabIndex(t),className:e.getMonthClassNames(t),role:\"button\",\"aria-label\":e.getAriaLabel(t)},r?Zt(t,o):er(t,o))})))}))})),Dt(bt(e),\"renderQuarters\",(function(){return de.default.createElement(\"div\",{className:\"react-datepicker__quarter-wrapper\"},[1,2,3,4].map((function(t,r){return de.default.createElement(\"div\",{key:r,onClick:function(r){e.onQuarterClick(r,t)},className:e.getQuarterClassNames(t)},tr(t,e.props.locale))})))})),Dt(bt(e),\"getClassNames\",(function(){var t=e.props;t.day;var r=t.selectingDate,a=t.selectsStart,n=t.selectsEnd,o=t.showMonthYearPicker,s=t.showQuarterYearPicker;return ce.default(\"react-datepicker__month\",{\"react-datepicker__month--selecting-range\":r&&(a||n)},{\"react-datepicker__monthPicker\":o},{\"react-datepicker__quarterPicker\":s})})),e}return yt(r,[{key:\"render\",value:function(){var e=this.props,t=e.showMonthYearPicker,r=e.showQuarterYearPicker,a=e.day,n=e.ariaLabelPrefix,o=void 0===n?\"month \":n;return de.default.createElement(\"div\",{className:this.getClassNames(),onMouseLeave:this.handleMouseLeave,\"aria-label\":\"\".concat(o,\" \").concat(Lt(a,\"yyyy-MM\"))},t?this.renderMonths():r?this.renderQuarters():this.renderWeeks())}}]),r}(de.default.Component),qr=function(e){wt(r,e);var t=St(r);function r(){var e;ht(this,r);for(var a=arguments.length,n=new Array(a),o=0;o0&&void 0!==arguments[0]?arguments[0]:{}).className||\"\").split(/\\s+/);return Br.some((function(t){return e.indexOf(t)>=0}))})(e.target)&&a.props.onDropdownFocus()})),Dt(bt(a),\"getDateInView\",(function(){var e=a.props,t=e.preSelection,r=e.selected,n=e.openToDate,o=Dr(a.props),s=vr(a.props),i=xt(),p=n||r||t;return p||(o&&nt.default(i,o)?o:s&&at.default(i,s)?s:i)})),Dt(bt(a),\"increaseMonth\",(function(){a.setState((function(e){var t=e.date;return{date:we.default(t,1)}}),(function(){return a.handleMonthChange(a.state.date)}))})),Dt(bt(a),\"decreaseMonth\",(function(){a.setState((function(e){var t=e.date;return{date:Ce.default(t,1)}}),(function(){return a.handleMonthChange(a.state.date)}))})),Dt(bt(a),\"handleDayClick\",(function(e,t,r){a.props.onSelect(e,t,r),a.props.setPreSelection&&a.props.setPreSelection(e)})),Dt(bt(a),\"handleDayMouseEnter\",(function(e){a.setState({selectingDate:e}),a.props.onDayMouseEnter&&a.props.onDayMouseEnter(e)})),Dt(bt(a),\"handleMonthMouseLeave\",(function(){a.setState({selectingDate:null}),a.props.onMonthMouseLeave&&a.props.onMonthMouseLeave()})),Dt(bt(a),\"handleYearChange\",(function(e){a.props.onYearChange&&a.props.onYearChange(e),a.props.adjustDateOnChange&&(a.props.onSelect&&a.props.onSelect(e),a.props.setOpen&&a.props.setOpen(!0)),a.props.setPreSelection&&a.props.setPreSelection(e)})),Dt(bt(a),\"handleMonthChange\",(function(e){a.props.onMonthChange&&a.props.onMonthChange(e),a.props.adjustDateOnChange&&(a.props.onSelect&&a.props.onSelect(e),a.props.setOpen&&a.props.setOpen(!0)),a.props.setPreSelection&&a.props.setPreSelection(e)})),Dt(bt(a),\"handleMonthYearChange\",(function(e){a.handleYearChange(e),a.handleMonthChange(e)})),Dt(bt(a),\"changeYear\",(function(e){a.setState((function(t){var r=t.date;return{date:We.default(r,e)}}),(function(){return a.handleYearChange(a.state.date)}))})),Dt(bt(a),\"changeMonth\",(function(e){a.setState((function(t){var r=t.date;return{date:qe.default(r,e)}}),(function(){return a.handleMonthChange(a.state.date)}))})),Dt(bt(a),\"changeMonthYear\",(function(e){a.setState((function(t){var r=t.date;return{date:We.default(qe.default(r,Ye.default(e)),Te.default(e))}}),(function(){return a.handleMonthYearChange(a.state.date)}))})),Dt(bt(a),\"header\",(function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:a.state.date,t=Kt(e,a.props.locale,a.props.calendarStartDay),r=[];return a.props.showWeekNumbers&&r.push(de.default.createElement(\"div\",{key:\"W\",className:\"react-datepicker__day-name\"},a.props.weekLabel||\"#\")),r.concat([0,1,2,3,4,5,6].map((function(e){var r=De.default(t,e),n=a.formatWeekday(r,a.props.locale),o=a.props.weekDayClassName?a.props.weekDayClassName(r):void 0;return de.default.createElement(\"div\",{key:e,className:ce.default(\"react-datepicker__day-name\",o)},n)})))})),Dt(bt(a),\"formatWeekday\",(function(e,t){return a.props.formatWeekDay?function(e,t,r){return t(Lt(e,\"EEEE\",r))}(e,a.props.formatWeekDay,t):a.props.useWeekdaysShort?function(e,t){return Lt(e,\"EEE\",t)}(e,t):function(e,t){return Lt(e,\"EEEEEE\",t)}(e,t)})),Dt(bt(a),\"decreaseYear\",(function(){a.setState((function(e){var t=e.date;return{date:Se.default(t,a.props.showYearPicker?a.props.yearItemNumber:1)}}),(function(){return a.handleYearChange(a.state.date)}))})),Dt(bt(a),\"renderPreviousButton\",(function(){if(!a.props.renderCustomHeader){var e;switch(!0){case a.props.showMonthYearPicker:e=mr(a.state.date,a.props);break;case a.props.showYearPicker:e=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=t.minDate,a=t.yearItemNumber,n=void 0===a?Ot:a,o=br(jt(Se.default(e,n)),n).endPeriod,s=r&&Te.default(r);return s&&s>o||!1}(a.state.date,a.props);break;default:e=fr(a.state.date,a.props)}if((a.props.forceShowMonthNavigation||a.props.showDisabledMonthNavigation||!e)&&!a.props.showTimeSelectOnly){var t=[\"react-datepicker__navigation\",\"react-datepicker__navigation--previous\"],r=a.decreaseMonth;(a.props.showMonthYearPicker||a.props.showQuarterYearPicker||a.props.showYearPicker)&&(r=a.decreaseYear),e&&a.props.showDisabledMonthNavigation&&(t.push(\"react-datepicker__navigation--previous--disabled\"),r=null);var n=a.props.showMonthYearPicker||a.props.showQuarterYearPicker||a.props.showYearPicker,o=a.props,s=o.previousMonthAriaLabel,i=void 0===s?\"Previous Month\":s,p=o.previousYearAriaLabel,l=void 0===p?\"Previous Year\":p;return de.default.createElement(\"button\",{type:\"button\",className:t.join(\" \"),onClick:r,onKeyDown:a.props.handleOnKeyDown,\"aria-label\":n?l:i},de.default.createElement(\"span\",{className:[\"react-datepicker__navigation-icon\",\"react-datepicker__navigation-icon--previous\"].join(\" \")},n?a.props.previousYearButtonLabel:a.props.previousMonthButtonLabel))}}})),Dt(bt(a),\"increaseYear\",(function(){a.setState((function(e){var t=e.date;return{date:ge.default(t,a.props.showYearPicker?a.props.yearItemNumber:1)}}),(function(){return a.handleYearChange(a.state.date)}))})),Dt(bt(a),\"renderNextButton\",(function(){if(!a.props.renderCustomHeader){var e;switch(!0){case a.props.showMonthYearPicker:e=yr(a.state.date,a.props);break;case a.props.showYearPicker:e=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=t.maxDate,a=t.yearItemNumber,n=void 0===a?Ot:a,o=br(ge.default(e,n),n).startPeriod,s=r&&Te.default(r);return s&&s0&&void 0!==arguments[0]?arguments[0]:a.state.date,t=[\"react-datepicker__current-month\"];return a.props.showYearDropdown&&t.push(\"react-datepicker__current-month--hasYearDropdown\"),a.props.showMonthDropdown&&t.push(\"react-datepicker__current-month--hasMonthDropdown\"),a.props.showMonthYearDropdown&&t.push(\"react-datepicker__current-month--hasMonthYearDropdown\"),de.default.createElement(\"div\",{className:t.join(\" \")},Lt(e,a.props.dateFormat,a.props.locale))})),Dt(bt(a),\"renderYearDropdown\",(function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];if(a.props.showYearDropdown&&!e)return de.default.createElement(Mr,{adjustDateOnChange:a.props.adjustDateOnChange,date:a.state.date,onSelect:a.props.onSelect,setOpen:a.props.setOpen,dropdownMode:a.props.dropdownMode,onChange:a.changeYear,minDate:a.props.minDate,maxDate:a.props.maxDate,year:Te.default(a.state.date),scrollableYearDropdown:a.props.scrollableYearDropdown,yearDropdownItemNumber:a.props.yearDropdownItemNumber})})),Dt(bt(a),\"renderMonthDropdown\",(function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];if(a.props.showMonthDropdown&&!e)return de.default.createElement(Nr,{dropdownMode:a.props.dropdownMode,locale:a.props.locale,onChange:a.changeMonth,month:Ye.default(a.state.date),useShortMonthInDropdown:a.props.useShortMonthInDropdown})})),Dt(bt(a),\"renderMonthYearDropdown\",(function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];if(a.props.showMonthYearDropdown&&!e)return de.default.createElement(Tr,{dropdownMode:a.props.dropdownMode,locale:a.props.locale,dateFormat:a.props.dateFormat,onChange:a.changeMonthYear,minDate:a.props.minDate,maxDate:a.props.maxDate,date:a.state.date,scrollableMonthYearDropdown:a.props.scrollableMonthYearDropdown})})),Dt(bt(a),\"renderTodayButton\",(function(){if(a.props.todayButton&&!a.props.showTimeSelectOnly)return de.default.createElement(\"div\",{className:\"react-datepicker__today-button\",onClick:function(e){return a.props.onSelect(Ve.default(xt()),e)}},a.props.todayButton)})),Dt(bt(a),\"renderDefaultHeader\",(function(e){var t=e.monthDate,r=e.i;return de.default.createElement(\"div\",{className:\"react-datepicker__header \".concat(a.props.showTimeSelect?\"react-datepicker__header--has-time-select\":\"\")},a.renderCurrentMonth(t),de.default.createElement(\"div\",{className:\"react-datepicker__header__dropdown react-datepicker__header__dropdown--\".concat(a.props.dropdownMode),onFocus:a.handleDropdownFocus},a.renderMonthDropdown(0!==r),a.renderMonthYearDropdown(0!==r),a.renderYearDropdown(0!==r)),de.default.createElement(\"div\",{className:\"react-datepicker__day-names\"},a.header(t)))})),Dt(bt(a),\"renderCustomHeader\",(function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.monthDate,r=e.i;if(a.props.showTimeSelect&&!a.state.monthContainer||a.props.showTimeSelectOnly)return null;var n=fr(a.state.date,a.props),o=hr(a.state.date,a.props),s=mr(a.state.date,a.props),i=yr(a.state.date,a.props),p=!a.props.showMonthYearPicker&&!a.props.showQuarterYearPicker&&!a.props.showYearPicker;return de.default.createElement(\"div\",{className:\"react-datepicker__header react-datepicker__header--custom\",onFocus:a.props.onDropdownFocus},a.props.renderCustomHeader(ut(ut({},a.state),{},{customHeaderCount:r,monthDate:t,changeMonth:a.changeMonth,changeYear:a.changeYear,decreaseMonth:a.decreaseMonth,increaseMonth:a.increaseMonth,decreaseYear:a.decreaseYear,increaseYear:a.increaseYear,prevMonthButtonDisabled:n,nextMonthButtonDisabled:o,prevYearButtonDisabled:s,nextYearButtonDisabled:i})),p&&de.default.createElement(\"div\",{className:\"react-datepicker__day-names\"},a.header(t)))})),Dt(bt(a),\"renderYearHeader\",(function(){var e=a.state.date,t=a.props,r=t.showYearPicker,n=br(e,t.yearItemNumber),o=n.startPeriod,s=n.endPeriod;return de.default.createElement(\"div\",{className:\"react-datepicker__header react-datepicker-year-header\"},r?\"\".concat(o,\" - \").concat(s):Te.default(e))})),Dt(bt(a),\"renderHeader\",(function(e){switch(!0){case void 0!==a.props.renderCustomHeader:return a.renderCustomHeader(e);case a.props.showMonthYearPicker||a.props.showQuarterYearPicker||a.props.showYearPicker:return a.renderYearHeader(e);default:return a.renderDefaultHeader(e)}})),Dt(bt(a),\"renderMonths\",(function(){if(!a.props.showTimeSelectOnly&&!a.props.showYearPicker){for(var e=[],t=a.props.showPreviousMonths?a.props.monthsShown-1:0,r=Ce.default(a.state.date,t),n=0;n0;e.push(de.default.createElement(\"div\",{key:i,ref:function(e){a.monthContainer=e},className:\"react-datepicker__month-container\"},a.renderHeader({monthDate:s,i:n}),de.default.createElement(Rr,{chooseDayAriaLabelPrefix:a.props.chooseDayAriaLabelPrefix,disabledDayAriaLabelPrefix:a.props.disabledDayAriaLabelPrefix,weekAriaLabelPrefix:a.props.weekAriaLabelPrefix,onChange:a.changeMonthYear,day:s,dayClassName:a.props.dayClassName,calendarStartDay:a.props.calendarStartDay,monthClassName:a.props.monthClassName,onDayClick:a.handleDayClick,handleOnKeyDown:a.props.handleOnDayKeyDown,onDayMouseEnter:a.handleDayMouseEnter,onMouseLeave:a.handleMonthMouseLeave,onWeekSelect:a.props.onWeekSelect,orderInDisplay:n,formatWeekNumber:a.props.formatWeekNumber,locale:a.props.locale,minDate:a.props.minDate,maxDate:a.props.maxDate,excludeDates:a.props.excludeDates,highlightDates:a.props.highlightDates,selectingDate:a.state.selectingDate,includeDates:a.props.includeDates,inline:a.props.inline,shouldFocusDayInline:a.props.shouldFocusDayInline,fixedHeight:a.props.fixedHeight,filterDate:a.props.filterDate,preSelection:a.props.preSelection,setPreSelection:a.props.setPreSelection,selected:a.props.selected,selectsStart:a.props.selectsStart,selectsEnd:a.props.selectsEnd,selectsRange:a.props.selectsRange,showWeekNumbers:a.props.showWeekNumbers,startDate:a.props.startDate,endDate:a.props.endDate,peekNextMonth:a.props.peekNextMonth,setOpen:a.props.setOpen,shouldCloseOnSelect:a.props.shouldCloseOnSelect,renderDayContents:a.props.renderDayContents,disabledKeyboardNavigation:a.props.disabledKeyboardNavigation,showMonthYearPicker:a.props.showMonthYearPicker,showFullMonthYearPicker:a.props.showFullMonthYearPicker,showTwoColumnMonthYearPicker:a.props.showTwoColumnMonthYearPicker,showFourColumnMonthYearPicker:a.props.showFourColumnMonthYearPicker,showYearPicker:a.props.showYearPicker,showQuarterYearPicker:a.props.showQuarterYearPicker,isInputFocused:a.props.isInputFocused,containerRef:a.containerRef,monthShowsDuplicateDaysEnd:p,monthShowsDuplicateDaysStart:l})))}return e}})),Dt(bt(a),\"renderYears\",(function(){if(!a.props.showTimeSelectOnly)return a.props.showYearPicker?de.default.createElement(\"div\",{className:\"react-datepicker__year--container\"},a.renderHeader(),de.default.createElement(Ar,vt({onDayClick:a.handleDayClick,date:a.state.date},a.props))):void 0})),Dt(bt(a),\"renderTimeSection\",(function(){if(a.props.showTimeSelect&&(a.state.monthContainer||a.props.showTimeSelectOnly))return de.default.createElement(qr,{selected:a.props.selected,openToDate:a.props.openToDate,onChange:a.props.onTimeChange,timeClassName:a.props.timeClassName,format:a.props.timeFormat,includeTimes:a.props.includeTimes,intervals:a.props.timeIntervals,minTime:a.props.minTime,maxTime:a.props.maxTime,excludeTimes:a.props.excludeTimes,filterTime:a.props.filterTime,timeCaption:a.props.timeCaption,todayButton:a.props.todayButton,showMonthDropdown:a.props.showMonthDropdown,showMonthYearDropdown:a.props.showMonthYearDropdown,showYearDropdown:a.props.showYearDropdown,withPortal:a.props.withPortal,monthRef:a.state.monthContainer,injectTimes:a.props.injectTimes,locale:a.props.locale,handleOnKeyDown:a.props.handleOnKeyDown,showTimeSelectOnly:a.props.showTimeSelectOnly})})),Dt(bt(a),\"renderInputTimeSection\",(function(){var e=new Date(a.props.selected),t=It(e)&&Boolean(a.props.selected)?\"\".concat(kr(e.getHours()),\":\").concat(kr(e.getMinutes())):\"\";if(a.props.showTimeInput)return de.default.createElement(Wr,{date:e,timeString:t,timeInputLabel:a.props.timeInputLabel,onChange:a.props.onTimeChange,customTimeInput:a.props.customTimeInput})})),a.containerRef=de.default.createRef(),a.state={date:a.getDateInView(),selectingDate:null,monthContainer:null},a}return yt(r,[{key:\"componentDidMount\",value:function(){var e=this;this.props.showTimeSelect&&(this.assignMonthContainer=void e.setState({monthContainer:e.monthContainer}))}},{key:\"componentDidUpdate\",value:function(e){this.props.preSelection&&!$t(this.props.preSelection,e.preSelection)?this.setState({date:this.props.preSelection}):this.props.openToDate&&!$t(this.props.openToDate,e.openToDate)&&this.setState({date:this.props.openToDate})}},{key:\"render\",value:function(){var e=this.props.container||Kr;return de.default.createElement(\"div\",{ref:this.containerRef},de.default.createElement(e,{className:ce.default(\"react-datepicker\",this.props.className,{\"react-datepicker--time-only\":this.props.showTimeSelectOnly}),showPopperArrow:this.props.showPopperArrow,arrowProps:this.props.arrowProps},this.renderPreviousButton(),this.renderNextButton(),this.renderMonths(),this.renderYears(),this.renderTodayButton(),this.renderTimeSection(),this.renderInputTimeSection(),this.props.children))}}],[{key:\"defaultProps\",get:function(){return{onDropdownFocus:function(){},monthsShown:1,monthSelectedIn:0,forceShowMonthNavigation:!1,timeCaption:\"Time\",previousYearButtonLabel:\"Previous Year\",nextYearButtonLabel:\"Next Year\",previousMonthButtonLabel:\"Previous Month\",nextMonthButtonLabel:\"Next Month\",customTimeInput:null,yearItemNumber:Ot}}}]),r}(de.default.Component),Hr=function(e){wt(r,e);var t=St(r);function r(e){var a;return ht(this,r),(a=t.call(this,e)).el=document.createElement(\"div\"),a}return yt(r,[{key:\"componentDidMount\",value:function(){this.portalRoot=document.getElementById(this.props.portalId),this.portalRoot||(this.portalRoot=document.createElement(\"div\"),this.portalRoot.setAttribute(\"id\",this.props.portalId),document.body.appendChild(this.portalRoot)),this.portalRoot.appendChild(this.el)}},{key:\"componentWillUnmount\",value:function(){this.portalRoot.removeChild(this.el)}},{key:\"render\",value:function(){return dt.default.createPortal(this.props.children,this.el)}}]),r}(de.default.Component),Qr=function(e){return!e.disabled&&-1!==e.tabIndex},Vr=function(e){wt(r,e);var t=St(r);function r(e){var a;return ht(this,r),Dt(bt(a=t.call(this,e)),\"getTabChildren\",(function(){return Array.prototype.slice.call(a.tabLoopRef.current.querySelectorAll(\"[tabindex], a, button, input, select, textarea\"),1,-1).filter(Qr)})),Dt(bt(a),\"handleFocusStart\",(function(e){var t=a.getTabChildren();t&&t.length>1&&t[t.length-1].focus()})),Dt(bt(a),\"handleFocusEnd\",(function(e){var t=a.getTabChildren();t&&t.length>1&&t[0].focus()})),a.tabLoopRef=de.default.createRef(),a}return yt(r,[{key:\"render\",value:function(){return this.props.enableTabLoop?de.default.createElement(\"div\",{className:\"react-datepicker__tab-loop\",ref:this.tabLoopRef},de.default.createElement(\"div\",{className:\"react-datepicker__tab-loop__start\",tabIndex:\"0\",onFocus:this.handleFocusStart}),this.props.children,de.default.createElement(\"div\",{className:\"react-datepicker__tab-loop__end\",tabIndex:\"0\",onFocus:this.handleFocusEnd})):this.props.children}}],[{key:\"defaultProps\",get:function(){return{enableTabLoop:!0}}}]),r}(de.default.Component),Ur=function(e){wt(r,e);var t=St(r);function r(){return ht(this,r),t.apply(this,arguments)}return yt(r,[{key:\"render\",value:function(){var e,t=this.props,r=t.className,a=t.wrapperClassName,n=t.hidePopper,o=t.popperComponent,s=t.popperModifiers,i=t.popperPlacement,p=t.popperProps,l=t.targetComponent,d=t.enableTabLoop,c=t.popperOnKeyDown,u=t.portalId;if(!n){var f=ce.default(\"react-datepicker-popper\",r);e=de.default.createElement(pe.Popper,vt({modifiers:s,placement:i},p),(function(e){var t=e.ref,r=e.style,a=e.placement,n=e.arrowProps;return de.default.createElement(Vr,{enableTabLoop:d},de.default.createElement(\"div\",{ref:t,style:r,className:f,\"data-placement\":a,onKeyDown:c},de.default.cloneElement(o,{arrowProps:n})))}))}this.props.popperContainer&&(e=de.default.createElement(this.props.popperContainer,{},e)),u&&!n&&(e=de.default.createElement(Hr,{portalId:u},e));var h=ce.default(\"react-datepicker-wrapper\",a);return de.default.createElement(pe.Manager,{className:\"react-datepicker-manager\"},de.default.createElement(pe.Reference,null,(function(e){var t=e.ref;return de.default.createElement(\"div\",{ref:t,className:h},l)})),e)}}],[{key:\"defaultProps\",get:function(){return{hidePopper:!0,popperModifiers:[],popperProps:{},popperPlacement:\"bottom-start\"}}}]),r}(de.default.Component),$r=\"react-datepicker-ignore-onclickoutside\",zr=lt.default(jr);var Gr=\"Date input not valid.\",Jr=function(e){wt(r,e);var t=St(r);function r(e){var a;return ht(this,r),Dt(bt(a=t.call(this,e)),\"getPreSelection\",(function(){return a.props.openToDate?a.props.openToDate:a.props.selectsEnd&&a.props.startDate?a.props.startDate:a.props.selectsStart&&a.props.endDate?a.props.endDate:xt()})),Dt(bt(a),\"calcInitialState\",(function(){var e,t=a.getPreSelection(),r=Dr(a.props),n=vr(a.props),o=r&&nt.default(t,Ve.default(r))?r:n&&at.default(t,Je.default(n))?n:t;return{open:a.props.startOpen||!1,preventFocus:!1,preSelection:null!==(e=a.props.selectsRange?a.props.startDate:a.props.selected)&&void 0!==e?e:o,highlightDates:wr(a.props.highlightDates),focused:!1,shouldFocusDayInline:!1}})),Dt(bt(a),\"clearPreventFocusTimeout\",(function(){a.preventFocusTimeout&&clearTimeout(a.preventFocusTimeout)})),Dt(bt(a),\"setFocus\",(function(){a.input&&a.input.focus&&a.input.focus({preventScroll:!0})})),Dt(bt(a),\"setBlur\",(function(){a.input&&a.input.blur&&a.input.blur(),a.cancelFocusInput()})),Dt(bt(a),\"setOpen\",(function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];a.setState({open:e,preSelection:e&&a.state.open?a.state.preSelection:a.calcInitialState().preSelection,lastPreSelectChange:Zr},(function(){e||a.setState((function(e){return{focused:!!t&&e.focused}}),(function(){!t&&a.setBlur(),a.setState({inputValue:null})}))}))})),Dt(bt(a),\"inputOk\",(function(){return ue.default(a.state.preSelection)})),Dt(bt(a),\"isCalendarOpen\",(function(){return void 0===a.props.open?a.state.open&&!a.props.disabled&&!a.props.readOnly:a.props.open})),Dt(bt(a),\"handleFocus\",(function(e){a.state.preventFocus||(a.props.onFocus(e),a.props.preventOpenOnFocus||a.props.readOnly||a.setOpen(!0)),a.setState({focused:!0})})),Dt(bt(a),\"cancelFocusInput\",(function(){clearTimeout(a.inputFocusTimeout),a.inputFocusTimeout=null})),Dt(bt(a),\"deferFocusInput\",(function(){a.cancelFocusInput(),a.inputFocusTimeout=setTimeout((function(){return a.setFocus()}),1)})),Dt(bt(a),\"handleDropdownFocus\",(function(){a.cancelFocusInput()})),Dt(bt(a),\"handleBlur\",(function(e){(!a.state.open||a.props.withPortal||a.props.showTimeInput)&&a.props.onBlur(e),a.setState({focused:!1})})),Dt(bt(a),\"handleCalendarClickOutside\",(function(e){a.props.inline||a.setOpen(!1),a.props.onClickOutside(e),a.props.withPortal&&e.preventDefault()})),Dt(bt(a),\"handleChange\",(function(){for(var e=arguments.length,t=new Array(e),r=0;r &&` helpers in initial condition allow es6 code\n // to co-exist with es5.\n // 2. Replace `for of` with es5 compliant iteration using `for`.\n // Basically, take:\n //\n // ```js\n // for (i of a.entries())\n // if (!b.has(i[0])) return false;\n // ```\n //\n // ... and convert to:\n //\n // ```js\n // it = a.entries();\n // while (!(i = it.next()).done)\n // if (!b.has(i.value[0])) return false;\n // ```\n //\n // **Note**: `i` access switches to `i.value`.\n var it;\n if (hasMap && (a instanceof Map) && (b instanceof Map)) {\n if (a.size !== b.size) return false;\n it = a.entries();\n while (!(i = it.next()).done)\n if (!b.has(i.value[0])) return false;\n it = a.entries();\n while (!(i = it.next()).done)\n if (!equal(i.value[1], b.get(i.value[0]))) return false;\n return true;\n }\n\n if (hasSet && (a instanceof Set) && (b instanceof Set)) {\n if (a.size !== b.size) return false;\n it = a.entries();\n while (!(i = it.next()).done)\n if (!b.has(i.value[0])) return false;\n return true;\n }\n // END: Modifications\n\n if (hasArrayBuffer && ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) {\n length = a.length;\n if (length != b.length) return false;\n for (i = length; i-- !== 0;)\n if (a[i] !== b[i]) return false;\n return true;\n }\n\n if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;\n if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();\n if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();\n\n keys = Object.keys(a);\n length = keys.length;\n if (length !== Object.keys(b).length) return false;\n\n for (i = length; i-- !== 0;)\n if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;\n // END: fast-deep-equal\n\n // START: react-fast-compare\n // custom handling for DOM elements\n if (hasElementType && a instanceof Element) return false;\n\n // custom handling for React/Preact\n for (i = length; i-- !== 0;) {\n if ((keys[i] === '_owner' || keys[i] === '__v' || keys[i] === '__o') && a.$$typeof) {\n // React-specific: avoid traversing React elements' _owner\n // Preact-specific: avoid traversing Preact elements' __v and __o\n // __v = $_original / $_vnode\n // __o = $_owner\n // These properties contain circular references and are not needed when\n // comparing the actual elements (and not their owners)\n // .$$typeof and ._store on just reasonable markers of elements\n\n continue;\n }\n\n // all other properties should be traversed as usual\n if (!equal(a[keys[i]], b[keys[i]])) return false;\n }\n // END: react-fast-compare\n\n // START: fast-deep-equal\n return true;\n }\n\n return a !== a && b !== b;\n}\n// end fast-deep-equal\n\nmodule.exports = function isEqual(a, b) {\n try {\n return equal(a, b);\n } catch (error) {\n if (((error.message || '').match(/stack|recursion/i))) {\n // warn on circular references, don't crash\n // browsers give this different errors name and messages:\n // chrome/safari: \"RangeError\", \"Maximum call stack size exceeded\"\n // firefox: \"InternalError\", too much recursion\"\n // edge: \"Error\", \"Out of stack space\"\n console.warn('react-fast-compare cannot handle circular refs');\n return false;\n }\n // some other error. we should definitely know about these\n throw error;\n }\n};\n","/**\n * Copyright (c) 2014-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\n/**\n * Similar to invariant but only logs a warning if the condition is not met.\n * This can be used to log issues in development environments in critical\n * paths. Removing the logging code for production environments will keep the\n * same logic and follow the same code paths.\n */\n\nvar __DEV__ = process.env.NODE_ENV !== 'production';\n\nvar warning = function() {};\n\nif (__DEV__) {\n var printWarning = function printWarning(format, args) {\n var len = arguments.length;\n args = new Array(len > 1 ? len - 1 : 0);\n for (var key = 1; key < len; key++) {\n args[key - 1] = arguments[key];\n }\n var argIndex = 0;\n var message = 'Warning: ' +\n format.replace(/%s/g, function() {\n return args[argIndex++];\n });\n if (typeof console !== 'undefined') {\n console.error(message);\n }\n try {\n // --- Welcome to debugging React ---\n // This error was thrown as a convenience so that you can use this stack\n // to find the callsite that caused this warning to fire.\n throw new Error(message);\n } catch (x) {}\n }\n\n warning = function(condition, format, args) {\n var len = arguments.length;\n args = new Array(len > 2 ? len - 2 : 0);\n for (var key = 2; key < len; key++) {\n args[key - 2] = arguments[key];\n }\n if (format === undefined) {\n throw new Error(\n '`warning(condition, format, ...args)` requires a warning ' +\n 'message argument'\n );\n }\n if (!condition) {\n printWarning.apply(null, [format].concat(args));\n }\n };\n}\n\nmodule.exports = warning;\n","import toInteger from \"../toInteger/index.js\";\nimport toDate from \"../../toDate/index.js\";\nimport requiredArgs from \"../requiredArgs/index.js\"; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function setUTCDay(dirtyDate, dirtyDay, dirtyOptions) {\n requiredArgs(2, arguments);\n var options = dirtyOptions || {};\n var locale = options.locale;\n var localeWeekStartsOn = locale && locale.options && locale.options.weekStartsOn;\n var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);\n var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN\n\n if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {\n throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');\n }\n\n var date = toDate(dirtyDate);\n var day = toInteger(dirtyDay);\n var currentDay = date.getUTCDay();\n var remainder = day % 7;\n var dayIndex = (remainder + 7) % 7;\n var diff = (dayIndex < weekStartsOn ? 7 : 0) + day - currentDay;\n date.setUTCDate(date.getUTCDate() + diff);\n return date;\n}","import getUTCWeekYear from \"../../../_lib/getUTCWeekYear/index.js\";\nimport setUTCDay from \"../../../_lib/setUTCDay/index.js\";\nimport setUTCISODay from \"../../../_lib/setUTCISODay/index.js\";\nimport setUTCISOWeek from \"../../../_lib/setUTCISOWeek/index.js\";\nimport setUTCWeek from \"../../../_lib/setUTCWeek/index.js\";\nimport startOfUTCISOWeek from \"../../../_lib/startOfUTCISOWeek/index.js\";\nimport startOfUTCWeek from \"../../../_lib/startOfUTCWeek/index.js\";\nvar MILLISECONDS_IN_HOUR = 3600000;\nvar MILLISECONDS_IN_MINUTE = 60000;\nvar MILLISECONDS_IN_SECOND = 1000;\nvar numericPatterns = {\n month: /^(1[0-2]|0?\\d)/,\n // 0 to 12\n date: /^(3[0-1]|[0-2]?\\d)/,\n // 0 to 31\n dayOfYear: /^(36[0-6]|3[0-5]\\d|[0-2]?\\d?\\d)/,\n // 0 to 366\n week: /^(5[0-3]|[0-4]?\\d)/,\n // 0 to 53\n hour23h: /^(2[0-3]|[0-1]?\\d)/,\n // 0 to 23\n hour24h: /^(2[0-4]|[0-1]?\\d)/,\n // 0 to 24\n hour11h: /^(1[0-1]|0?\\d)/,\n // 0 to 11\n hour12h: /^(1[0-2]|0?\\d)/,\n // 0 to 12\n minute: /^[0-5]?\\d/,\n // 0 to 59\n second: /^[0-5]?\\d/,\n // 0 to 59\n singleDigit: /^\\d/,\n // 0 to 9\n twoDigits: /^\\d{1,2}/,\n // 0 to 99\n threeDigits: /^\\d{1,3}/,\n // 0 to 999\n fourDigits: /^\\d{1,4}/,\n // 0 to 9999\n anyDigitsSigned: /^-?\\d+/,\n singleDigitSigned: /^-?\\d/,\n // 0 to 9, -0 to -9\n twoDigitsSigned: /^-?\\d{1,2}/,\n // 0 to 99, -0 to -99\n threeDigitsSigned: /^-?\\d{1,3}/,\n // 0 to 999, -0 to -999\n fourDigitsSigned: /^-?\\d{1,4}/ // 0 to 9999, -0 to -9999\n\n};\nvar timezonePatterns = {\n basicOptionalMinutes: /^([+-])(\\d{2})(\\d{2})?|Z/,\n basic: /^([+-])(\\d{2})(\\d{2})|Z/,\n basicOptionalSeconds: /^([+-])(\\d{2})(\\d{2})((\\d{2}))?|Z/,\n extended: /^([+-])(\\d{2}):(\\d{2})|Z/,\n extendedOptionalSeconds: /^([+-])(\\d{2}):(\\d{2})(:(\\d{2}))?|Z/\n};\n\nfunction parseNumericPattern(pattern, string, valueCallback) {\n var matchResult = string.match(pattern);\n\n if (!matchResult) {\n return null;\n }\n\n var value = parseInt(matchResult[0], 10);\n return {\n value: valueCallback ? valueCallback(value) : value,\n rest: string.slice(matchResult[0].length)\n };\n}\n\nfunction parseTimezonePattern(pattern, string) {\n var matchResult = string.match(pattern);\n\n if (!matchResult) {\n return null;\n } // Input is 'Z'\n\n\n if (matchResult[0] === 'Z') {\n return {\n value: 0,\n rest: string.slice(1)\n };\n }\n\n var sign = matchResult[1] === '+' ? 1 : -1;\n var hours = matchResult[2] ? parseInt(matchResult[2], 10) : 0;\n var minutes = matchResult[3] ? parseInt(matchResult[3], 10) : 0;\n var seconds = matchResult[5] ? parseInt(matchResult[5], 10) : 0;\n return {\n value: sign * (hours * MILLISECONDS_IN_HOUR + minutes * MILLISECONDS_IN_MINUTE + seconds * MILLISECONDS_IN_SECOND),\n rest: string.slice(matchResult[0].length)\n };\n}\n\nfunction parseAnyDigitsSigned(string, valueCallback) {\n return parseNumericPattern(numericPatterns.anyDigitsSigned, string, valueCallback);\n}\n\nfunction parseNDigits(n, string, valueCallback) {\n switch (n) {\n case 1:\n return parseNumericPattern(numericPatterns.singleDigit, string, valueCallback);\n\n case 2:\n return parseNumericPattern(numericPatterns.twoDigits, string, valueCallback);\n\n case 3:\n return parseNumericPattern(numericPatterns.threeDigits, string, valueCallback);\n\n case 4:\n return parseNumericPattern(numericPatterns.fourDigits, string, valueCallback);\n\n default:\n return parseNumericPattern(new RegExp('^\\\\d{1,' + n + '}'), string, valueCallback);\n }\n}\n\nfunction parseNDigitsSigned(n, string, valueCallback) {\n switch (n) {\n case 1:\n return parseNumericPattern(numericPatterns.singleDigitSigned, string, valueCallback);\n\n case 2:\n return parseNumericPattern(numericPatterns.twoDigitsSigned, string, valueCallback);\n\n case 3:\n return parseNumericPattern(numericPatterns.threeDigitsSigned, string, valueCallback);\n\n case 4:\n return parseNumericPattern(numericPatterns.fourDigitsSigned, string, valueCallback);\n\n default:\n return parseNumericPattern(new RegExp('^-?\\\\d{1,' + n + '}'), string, valueCallback);\n }\n}\n\nfunction dayPeriodEnumToHours(enumValue) {\n switch (enumValue) {\n case 'morning':\n return 4;\n\n case 'evening':\n return 17;\n\n case 'pm':\n case 'noon':\n case 'afternoon':\n return 12;\n\n case 'am':\n case 'midnight':\n case 'night':\n default:\n return 0;\n }\n}\n\nfunction normalizeTwoDigitYear(twoDigitYear, currentYear) {\n var isCommonEra = currentYear > 0; // Absolute number of the current year:\n // 1 -> 1 AC\n // 0 -> 1 BC\n // -1 -> 2 BC\n\n var absCurrentYear = isCommonEra ? currentYear : 1 - currentYear;\n var result;\n\n if (absCurrentYear <= 50) {\n result = twoDigitYear || 100;\n } else {\n var rangeEnd = absCurrentYear + 50;\n var rangeEndCentury = Math.floor(rangeEnd / 100) * 100;\n var isPreviousCentury = twoDigitYear >= rangeEnd % 100;\n result = twoDigitYear + rangeEndCentury - (isPreviousCentury ? 100 : 0);\n }\n\n return isCommonEra ? result : 1 - result;\n}\n\nvar DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\nvar DAYS_IN_MONTH_LEAP_YEAR = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // User for validation\n\nfunction isLeapYearIndex(year) {\n return year % 400 === 0 || year % 4 === 0 && year % 100 !== 0;\n}\n/*\n * | | Unit | | Unit |\n * |-----|--------------------------------|-----|--------------------------------|\n * | a | AM, PM | A* | Milliseconds in day |\n * | b | AM, PM, noon, midnight | B | Flexible day period |\n * | c | Stand-alone local day of week | C* | Localized hour w/ day period |\n * | d | Day of month | D | Day of year |\n * | e | Local day of week | E | Day of week |\n * | f | | F* | Day of week in month |\n * | g* | Modified Julian day | G | Era |\n * | h | Hour [1-12] | H | Hour [0-23] |\n * | i! | ISO day of week | I! | ISO week of year |\n * | j* | Localized hour w/ day period | J* | Localized hour w/o day period |\n * | k | Hour [1-24] | K | Hour [0-11] |\n * | l* | (deprecated) | L | Stand-alone month |\n * | m | Minute | M | Month |\n * | n | | N | |\n * | o! | Ordinal number modifier | O* | Timezone (GMT) |\n * | p | | P | |\n * | q | Stand-alone quarter | Q | Quarter |\n * | r* | Related Gregorian year | R! | ISO week-numbering year |\n * | s | Second | S | Fraction of second |\n * | t! | Seconds timestamp | T! | Milliseconds timestamp |\n * | u | Extended year | U* | Cyclic year |\n * | v* | Timezone (generic non-locat.) | V* | Timezone (location) |\n * | w | Local week of year | W* | Week of month |\n * | x | Timezone (ISO-8601 w/o Z) | X | Timezone (ISO-8601) |\n * | y | Year (abs) | Y | Local week-numbering year |\n * | z* | Timezone (specific non-locat.) | Z* | Timezone (aliases) |\n *\n * Letters marked by * are not implemented but reserved by Unicode standard.\n *\n * Letters marked by ! are non-standard, but implemented by date-fns:\n * - `o` modifies the previous token to turn it into an ordinal (see `parse` docs)\n * - `i` is ISO day of week. For `i` and `ii` is returns numeric ISO week days,\n * i.e. 7 for Sunday, 1 for Monday, etc.\n * - `I` is ISO week of year, as opposed to `w` which is local week of year.\n * - `R` is ISO week-numbering year, as opposed to `Y` which is local week-numbering year.\n * `R` is supposed to be used in conjunction with `I` and `i`\n * for universal ISO week-numbering date, whereas\n * `Y` is supposed to be used in conjunction with `w` and `e`\n * for week-numbering date specific to the locale.\n */\n\n\nvar parsers = {\n // Era\n G: {\n priority: 140,\n parse: function (string, token, match, _options) {\n switch (token) {\n // AD, BC\n case 'G':\n case 'GG':\n case 'GGG':\n return match.era(string, {\n width: 'abbreviated'\n }) || match.era(string, {\n width: 'narrow'\n });\n // A, B\n\n case 'GGGGG':\n return match.era(string, {\n width: 'narrow'\n });\n // Anno Domini, Before Christ\n\n case 'GGGG':\n default:\n return match.era(string, {\n width: 'wide'\n }) || match.era(string, {\n width: 'abbreviated'\n }) || match.era(string, {\n width: 'narrow'\n });\n }\n },\n set: function (date, flags, value, _options) {\n flags.era = value;\n date.setUTCFullYear(value, 0, 1);\n date.setUTCHours(0, 0, 0, 0);\n return date;\n },\n incompatibleTokens: ['R', 'u', 't', 'T']\n },\n // Year\n y: {\n // From http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_Patterns\n // | Year | y | yy | yyy | yyyy | yyyyy |\n // |----------|-------|----|-------|-------|-------|\n // | AD 1 | 1 | 01 | 001 | 0001 | 00001 |\n // | AD 12 | 12 | 12 | 012 | 0012 | 00012 |\n // | AD 123 | 123 | 23 | 123 | 0123 | 00123 |\n // | AD 1234 | 1234 | 34 | 1234 | 1234 | 01234 |\n // | AD 12345 | 12345 | 45 | 12345 | 12345 | 12345 |\n priority: 130,\n parse: function (string, token, match, _options) {\n var valueCallback = function (year) {\n return {\n year: year,\n isTwoDigitYear: token === 'yy'\n };\n };\n\n switch (token) {\n case 'y':\n return parseNDigits(4, string, valueCallback);\n\n case 'yo':\n return match.ordinalNumber(string, {\n unit: 'year',\n valueCallback: valueCallback\n });\n\n default:\n return parseNDigits(token.length, string, valueCallback);\n }\n },\n validate: function (_date, value, _options) {\n return value.isTwoDigitYear || value.year > 0;\n },\n set: function (date, flags, value, _options) {\n var currentYear = date.getUTCFullYear();\n\n if (value.isTwoDigitYear) {\n var normalizedTwoDigitYear = normalizeTwoDigitYear(value.year, currentYear);\n date.setUTCFullYear(normalizedTwoDigitYear, 0, 1);\n date.setUTCHours(0, 0, 0, 0);\n return date;\n }\n\n var year = !('era' in flags) || flags.era === 1 ? value.year : 1 - value.year;\n date.setUTCFullYear(year, 0, 1);\n date.setUTCHours(0, 0, 0, 0);\n return date;\n },\n incompatibleTokens: ['Y', 'R', 'u', 'w', 'I', 'i', 'e', 'c', 't', 'T']\n },\n // Local week-numbering year\n Y: {\n priority: 130,\n parse: function (string, token, match, _options) {\n var valueCallback = function (year) {\n return {\n year: year,\n isTwoDigitYear: token === 'YY'\n };\n };\n\n switch (token) {\n case 'Y':\n return parseNDigits(4, string, valueCallback);\n\n case 'Yo':\n return match.ordinalNumber(string, {\n unit: 'year',\n valueCallback: valueCallback\n });\n\n default:\n return parseNDigits(token.length, string, valueCallback);\n }\n },\n validate: function (_date, value, _options) {\n return value.isTwoDigitYear || value.year > 0;\n },\n set: function (date, flags, value, options) {\n var currentYear = getUTCWeekYear(date, options);\n\n if (value.isTwoDigitYear) {\n var normalizedTwoDigitYear = normalizeTwoDigitYear(value.year, currentYear);\n date.setUTCFullYear(normalizedTwoDigitYear, 0, options.firstWeekContainsDate);\n date.setUTCHours(0, 0, 0, 0);\n return startOfUTCWeek(date, options);\n }\n\n var year = !('era' in flags) || flags.era === 1 ? value.year : 1 - value.year;\n date.setUTCFullYear(year, 0, options.firstWeekContainsDate);\n date.setUTCHours(0, 0, 0, 0);\n return startOfUTCWeek(date, options);\n },\n incompatibleTokens: ['y', 'R', 'u', 'Q', 'q', 'M', 'L', 'I', 'd', 'D', 'i', 't', 'T']\n },\n // ISO week-numbering year\n R: {\n priority: 130,\n parse: function (string, token, _match, _options) {\n if (token === 'R') {\n return parseNDigitsSigned(4, string);\n }\n\n return parseNDigitsSigned(token.length, string);\n },\n set: function (_date, _flags, value, _options) {\n var firstWeekOfYear = new Date(0);\n firstWeekOfYear.setUTCFullYear(value, 0, 4);\n firstWeekOfYear.setUTCHours(0, 0, 0, 0);\n return startOfUTCISOWeek(firstWeekOfYear);\n },\n incompatibleTokens: ['G', 'y', 'Y', 'u', 'Q', 'q', 'M', 'L', 'w', 'd', 'D', 'e', 'c', 't', 'T']\n },\n // Extended year\n u: {\n priority: 130,\n parse: function (string, token, _match, _options) {\n if (token === 'u') {\n return parseNDigitsSigned(4, string);\n }\n\n return parseNDigitsSigned(token.length, string);\n },\n set: function (date, _flags, value, _options) {\n date.setUTCFullYear(value, 0, 1);\n date.setUTCHours(0, 0, 0, 0);\n return date;\n },\n incompatibleTokens: ['G', 'y', 'Y', 'R', 'w', 'I', 'i', 'e', 'c', 't', 'T']\n },\n // Quarter\n Q: {\n priority: 120,\n parse: function (string, token, match, _options) {\n switch (token) {\n // 1, 2, 3, 4\n case 'Q':\n case 'QQ':\n // 01, 02, 03, 04\n return parseNDigits(token.length, string);\n // 1st, 2nd, 3rd, 4th\n\n case 'Qo':\n return match.ordinalNumber(string, {\n unit: 'quarter'\n });\n // Q1, Q2, Q3, Q4\n\n case 'QQQ':\n return match.quarter(string, {\n width: 'abbreviated',\n context: 'formatting'\n }) || match.quarter(string, {\n width: 'narrow',\n context: 'formatting'\n });\n // 1, 2, 3, 4 (narrow quarter; could be not numerical)\n\n case 'QQQQQ':\n return match.quarter(string, {\n width: 'narrow',\n context: 'formatting'\n });\n // 1st quarter, 2nd quarter, ...\n\n case 'QQQQ':\n default:\n return match.quarter(string, {\n width: 'wide',\n context: 'formatting'\n }) || match.quarter(string, {\n width: 'abbreviated',\n context: 'formatting'\n }) || match.quarter(string, {\n width: 'narrow',\n context: 'formatting'\n });\n }\n },\n validate: function (_date, value, _options) {\n return value >= 1 && value <= 4;\n },\n set: function (date, _flags, value, _options) {\n date.setUTCMonth((value - 1) * 3, 1);\n date.setUTCHours(0, 0, 0, 0);\n return date;\n },\n incompatibleTokens: ['Y', 'R', 'q', 'M', 'L', 'w', 'I', 'd', 'D', 'i', 'e', 'c', 't', 'T']\n },\n // Stand-alone quarter\n q: {\n priority: 120,\n parse: function (string, token, match, _options) {\n switch (token) {\n // 1, 2, 3, 4\n case 'q':\n case 'qq':\n // 01, 02, 03, 04\n return parseNDigits(token.length, string);\n // 1st, 2nd, 3rd, 4th\n\n case 'qo':\n return match.ordinalNumber(string, {\n unit: 'quarter'\n });\n // Q1, Q2, Q3, Q4\n\n case 'qqq':\n return match.quarter(string, {\n width: 'abbreviated',\n context: 'standalone'\n }) || match.quarter(string, {\n width: 'narrow',\n context: 'standalone'\n });\n // 1, 2, 3, 4 (narrow quarter; could be not numerical)\n\n case 'qqqqq':\n return match.quarter(string, {\n width: 'narrow',\n context: 'standalone'\n });\n // 1st quarter, 2nd quarter, ...\n\n case 'qqqq':\n default:\n return match.quarter(string, {\n width: 'wide',\n context: 'standalone'\n }) || match.quarter(string, {\n width: 'abbreviated',\n context: 'standalone'\n }) || match.quarter(string, {\n width: 'narrow',\n context: 'standalone'\n });\n }\n },\n validate: function (_date, value, _options) {\n return value >= 1 && value <= 4;\n },\n set: function (date, _flags, value, _options) {\n date.setUTCMonth((value - 1) * 3, 1);\n date.setUTCHours(0, 0, 0, 0);\n return date;\n },\n incompatibleTokens: ['Y', 'R', 'Q', 'M', 'L', 'w', 'I', 'd', 'D', 'i', 'e', 'c', 't', 'T']\n },\n // Month\n M: {\n priority: 110,\n parse: function (string, token, match, _options) {\n var valueCallback = function (value) {\n return value - 1;\n };\n\n switch (token) {\n // 1, 2, ..., 12\n case 'M':\n return parseNumericPattern(numericPatterns.month, string, valueCallback);\n // 01, 02, ..., 12\n\n case 'MM':\n return parseNDigits(2, string, valueCallback);\n // 1st, 2nd, ..., 12th\n\n case 'Mo':\n return match.ordinalNumber(string, {\n unit: 'month',\n valueCallback: valueCallback\n });\n // Jan, Feb, ..., Dec\n\n case 'MMM':\n return match.month(string, {\n width: 'abbreviated',\n context: 'formatting'\n }) || match.month(string, {\n width: 'narrow',\n context: 'formatting'\n });\n // J, F, ..., D\n\n case 'MMMMM':\n return match.month(string, {\n width: 'narrow',\n context: 'formatting'\n });\n // January, February, ..., December\n\n case 'MMMM':\n default:\n return match.month(string, {\n width: 'wide',\n context: 'formatting'\n }) || match.month(string, {\n width: 'abbreviated',\n context: 'formatting'\n }) || match.month(string, {\n width: 'narrow',\n context: 'formatting'\n });\n }\n },\n validate: function (_date, value, _options) {\n return value >= 0 && value <= 11;\n },\n set: function (date, _flags, value, _options) {\n date.setUTCMonth(value, 1);\n date.setUTCHours(0, 0, 0, 0);\n return date;\n },\n incompatibleTokens: ['Y', 'R', 'q', 'Q', 'L', 'w', 'I', 'D', 'i', 'e', 'c', 't', 'T']\n },\n // Stand-alone month\n L: {\n priority: 110,\n parse: function (string, token, match, _options) {\n var valueCallback = function (value) {\n return value - 1;\n };\n\n switch (token) {\n // 1, 2, ..., 12\n case 'L':\n return parseNumericPattern(numericPatterns.month, string, valueCallback);\n // 01, 02, ..., 12\n\n case 'LL':\n return parseNDigits(2, string, valueCallback);\n // 1st, 2nd, ..., 12th\n\n case 'Lo':\n return match.ordinalNumber(string, {\n unit: 'month',\n valueCallback: valueCallback\n });\n // Jan, Feb, ..., Dec\n\n case 'LLL':\n return match.month(string, {\n width: 'abbreviated',\n context: 'standalone'\n }) || match.month(string, {\n width: 'narrow',\n context: 'standalone'\n });\n // J, F, ..., D\n\n case 'LLLLL':\n return match.month(string, {\n width: 'narrow',\n context: 'standalone'\n });\n // January, February, ..., December\n\n case 'LLLL':\n default:\n return match.month(string, {\n width: 'wide',\n context: 'standalone'\n }) || match.month(string, {\n width: 'abbreviated',\n context: 'standalone'\n }) || match.month(string, {\n width: 'narrow',\n context: 'standalone'\n });\n }\n },\n validate: function (_date, value, _options) {\n return value >= 0 && value <= 11;\n },\n set: function (date, _flags, value, _options) {\n date.setUTCMonth(value, 1);\n date.setUTCHours(0, 0, 0, 0);\n return date;\n },\n incompatibleTokens: ['Y', 'R', 'q', 'Q', 'M', 'w', 'I', 'D', 'i', 'e', 'c', 't', 'T']\n },\n // Local week of year\n w: {\n priority: 100,\n parse: function (string, token, match, _options) {\n switch (token) {\n case 'w':\n return parseNumericPattern(numericPatterns.week, string);\n\n case 'wo':\n return match.ordinalNumber(string, {\n unit: 'week'\n });\n\n default:\n return parseNDigits(token.length, string);\n }\n },\n validate: function (_date, value, _options) {\n return value >= 1 && value <= 53;\n },\n set: function (date, _flags, value, options) {\n return startOfUTCWeek(setUTCWeek(date, value, options), options);\n },\n incompatibleTokens: ['y', 'R', 'u', 'q', 'Q', 'M', 'L', 'I', 'd', 'D', 'i', 't', 'T']\n },\n // ISO week of year\n I: {\n priority: 100,\n parse: function (string, token, match, _options) {\n switch (token) {\n case 'I':\n return parseNumericPattern(numericPatterns.week, string);\n\n case 'Io':\n return match.ordinalNumber(string, {\n unit: 'week'\n });\n\n default:\n return parseNDigits(token.length, string);\n }\n },\n validate: function (_date, value, _options) {\n return value >= 1 && value <= 53;\n },\n set: function (date, _flags, value, options) {\n return startOfUTCISOWeek(setUTCISOWeek(date, value, options), options);\n },\n incompatibleTokens: ['y', 'Y', 'u', 'q', 'Q', 'M', 'L', 'w', 'd', 'D', 'e', 'c', 't', 'T']\n },\n // Day of the month\n d: {\n priority: 90,\n subPriority: 1,\n parse: function (string, token, match, _options) {\n switch (token) {\n case 'd':\n return parseNumericPattern(numericPatterns.date, string);\n\n case 'do':\n return match.ordinalNumber(string, {\n unit: 'date'\n });\n\n default:\n return parseNDigits(token.length, string);\n }\n },\n validate: function (date, value, _options) {\n var year = date.getUTCFullYear();\n var isLeapYear = isLeapYearIndex(year);\n var month = date.getUTCMonth();\n\n if (isLeapYear) {\n return value >= 1 && value <= DAYS_IN_MONTH_LEAP_YEAR[month];\n } else {\n return value >= 1 && value <= DAYS_IN_MONTH[month];\n }\n },\n set: function (date, _flags, value, _options) {\n date.setUTCDate(value);\n date.setUTCHours(0, 0, 0, 0);\n return date;\n },\n incompatibleTokens: ['Y', 'R', 'q', 'Q', 'w', 'I', 'D', 'i', 'e', 'c', 't', 'T']\n },\n // Day of year\n D: {\n priority: 90,\n subPriority: 1,\n parse: function (string, token, match, _options) {\n switch (token) {\n case 'D':\n case 'DD':\n return parseNumericPattern(numericPatterns.dayOfYear, string);\n\n case 'Do':\n return match.ordinalNumber(string, {\n unit: 'date'\n });\n\n default:\n return parseNDigits(token.length, string);\n }\n },\n validate: function (date, value, _options) {\n var year = date.getUTCFullYear();\n var isLeapYear = isLeapYearIndex(year);\n\n if (isLeapYear) {\n return value >= 1 && value <= 366;\n } else {\n return value >= 1 && value <= 365;\n }\n },\n set: function (date, _flags, value, _options) {\n date.setUTCMonth(0, value);\n date.setUTCHours(0, 0, 0, 0);\n return date;\n },\n incompatibleTokens: ['Y', 'R', 'q', 'Q', 'M', 'L', 'w', 'I', 'd', 'E', 'i', 'e', 'c', 't', 'T']\n },\n // Day of week\n E: {\n priority: 90,\n parse: function (string, token, match, _options) {\n switch (token) {\n // Tue\n case 'E':\n case 'EE':\n case 'EEE':\n return match.day(string, {\n width: 'abbreviated',\n context: 'formatting'\n }) || match.day(string, {\n width: 'short',\n context: 'formatting'\n }) || match.day(string, {\n width: 'narrow',\n context: 'formatting'\n });\n // T\n\n case 'EEEEE':\n return match.day(string, {\n width: 'narrow',\n context: 'formatting'\n });\n // Tu\n\n case 'EEEEEE':\n return match.day(string, {\n width: 'short',\n context: 'formatting'\n }) || match.day(string, {\n width: 'narrow',\n context: 'formatting'\n });\n // Tuesday\n\n case 'EEEE':\n default:\n return match.day(string, {\n width: 'wide',\n context: 'formatting'\n }) || match.day(string, {\n width: 'abbreviated',\n context: 'formatting'\n }) || match.day(string, {\n width: 'short',\n context: 'formatting'\n }) || match.day(string, {\n width: 'narrow',\n context: 'formatting'\n });\n }\n },\n validate: function (_date, value, _options) {\n return value >= 0 && value <= 6;\n },\n set: function (date, _flags, value, options) {\n date = setUTCDay(date, value, options);\n date.setUTCHours(0, 0, 0, 0);\n return date;\n },\n incompatibleTokens: ['D', 'i', 'e', 'c', 't', 'T']\n },\n // Local day of week\n e: {\n priority: 90,\n parse: function (string, token, match, options) {\n var valueCallback = function (value) {\n var wholeWeekDays = Math.floor((value - 1) / 7) * 7;\n return (value + options.weekStartsOn + 6) % 7 + wholeWeekDays;\n };\n\n switch (token) {\n // 3\n case 'e':\n case 'ee':\n // 03\n return parseNDigits(token.length, string, valueCallback);\n // 3rd\n\n case 'eo':\n return match.ordinalNumber(string, {\n unit: 'day',\n valueCallback: valueCallback\n });\n // Tue\n\n case 'eee':\n return match.day(string, {\n width: 'abbreviated',\n context: 'formatting'\n }) || match.day(string, {\n width: 'short',\n context: 'formatting'\n }) || match.day(string, {\n width: 'narrow',\n context: 'formatting'\n });\n // T\n\n case 'eeeee':\n return match.day(string, {\n width: 'narrow',\n context: 'formatting'\n });\n // Tu\n\n case 'eeeeee':\n return match.day(string, {\n width: 'short',\n context: 'formatting'\n }) || match.day(string, {\n width: 'narrow',\n context: 'formatting'\n });\n // Tuesday\n\n case 'eeee':\n default:\n return match.day(string, {\n width: 'wide',\n context: 'formatting'\n }) || match.day(string, {\n width: 'abbreviated',\n context: 'formatting'\n }) || match.day(string, {\n width: 'short',\n context: 'formatting'\n }) || match.day(string, {\n width: 'narrow',\n context: 'formatting'\n });\n }\n },\n validate: function (_date, value, _options) {\n return value >= 0 && value <= 6;\n },\n set: function (date, _flags, value, options) {\n date = setUTCDay(date, value, options);\n date.setUTCHours(0, 0, 0, 0);\n return date;\n },\n incompatibleTokens: ['y', 'R', 'u', 'q', 'Q', 'M', 'L', 'I', 'd', 'D', 'E', 'i', 'c', 't', 'T']\n },\n // Stand-alone local day of week\n c: {\n priority: 90,\n parse: function (string, token, match, options) {\n var valueCallback = function (value) {\n var wholeWeekDays = Math.floor((value - 1) / 7) * 7;\n return (value + options.weekStartsOn + 6) % 7 + wholeWeekDays;\n };\n\n switch (token) {\n // 3\n case 'c':\n case 'cc':\n // 03\n return parseNDigits(token.length, string, valueCallback);\n // 3rd\n\n case 'co':\n return match.ordinalNumber(string, {\n unit: 'day',\n valueCallback: valueCallback\n });\n // Tue\n\n case 'ccc':\n return match.day(string, {\n width: 'abbreviated',\n context: 'standalone'\n }) || match.day(string, {\n width: 'short',\n context: 'standalone'\n }) || match.day(string, {\n width: 'narrow',\n context: 'standalone'\n });\n // T\n\n case 'ccccc':\n return match.day(string, {\n width: 'narrow',\n context: 'standalone'\n });\n // Tu\n\n case 'cccccc':\n return match.day(string, {\n width: 'short',\n context: 'standalone'\n }) || match.day(string, {\n width: 'narrow',\n context: 'standalone'\n });\n // Tuesday\n\n case 'cccc':\n default:\n return match.day(string, {\n width: 'wide',\n context: 'standalone'\n }) || match.day(string, {\n width: 'abbreviated',\n context: 'standalone'\n }) || match.day(string, {\n width: 'short',\n context: 'standalone'\n }) || match.day(string, {\n width: 'narrow',\n context: 'standalone'\n });\n }\n },\n validate: function (_date, value, _options) {\n return value >= 0 && value <= 6;\n },\n set: function (date, _flags, value, options) {\n date = setUTCDay(date, value, options);\n date.setUTCHours(0, 0, 0, 0);\n return date;\n },\n incompatibleTokens: ['y', 'R', 'u', 'q', 'Q', 'M', 'L', 'I', 'd', 'D', 'E', 'i', 'e', 't', 'T']\n },\n // ISO day of week\n i: {\n priority: 90,\n parse: function (string, token, match, _options) {\n var valueCallback = function (value) {\n if (value === 0) {\n return 7;\n }\n\n return value;\n };\n\n switch (token) {\n // 2\n case 'i':\n case 'ii':\n // 02\n return parseNDigits(token.length, string);\n // 2nd\n\n case 'io':\n return match.ordinalNumber(string, {\n unit: 'day'\n });\n // Tue\n\n case 'iii':\n return match.day(string, {\n width: 'abbreviated',\n context: 'formatting',\n valueCallback: valueCallback\n }) || match.day(string, {\n width: 'short',\n context: 'formatting',\n valueCallback: valueCallback\n }) || match.day(string, {\n width: 'narrow',\n context: 'formatting',\n valueCallback: valueCallback\n });\n // T\n\n case 'iiiii':\n return match.day(string, {\n width: 'narrow',\n context: 'formatting',\n valueCallback: valueCallback\n });\n // Tu\n\n case 'iiiiii':\n return match.day(string, {\n width: 'short',\n context: 'formatting',\n valueCallback: valueCallback\n }) || match.day(string, {\n width: 'narrow',\n context: 'formatting',\n valueCallback: valueCallback\n });\n // Tuesday\n\n case 'iiii':\n default:\n return match.day(string, {\n width: 'wide',\n context: 'formatting',\n valueCallback: valueCallback\n }) || match.day(string, {\n width: 'abbreviated',\n context: 'formatting',\n valueCallback: valueCallback\n }) || match.day(string, {\n width: 'short',\n context: 'formatting',\n valueCallback: valueCallback\n }) || match.day(string, {\n width: 'narrow',\n context: 'formatting',\n valueCallback: valueCallback\n });\n }\n },\n validate: function (_date, value, _options) {\n return value >= 1 && value <= 7;\n },\n set: function (date, _flags, value, options) {\n date = setUTCISODay(date, value, options);\n date.setUTCHours(0, 0, 0, 0);\n return date;\n },\n incompatibleTokens: ['y', 'Y', 'u', 'q', 'Q', 'M', 'L', 'w', 'd', 'D', 'E', 'e', 'c', 't', 'T']\n },\n // AM or PM\n a: {\n priority: 80,\n parse: function (string, token, match, _options) {\n switch (token) {\n case 'a':\n case 'aa':\n case 'aaa':\n return match.dayPeriod(string, {\n width: 'abbreviated',\n context: 'formatting'\n }) || match.dayPeriod(string, {\n width: 'narrow',\n context: 'formatting'\n });\n\n case 'aaaaa':\n return match.dayPeriod(string, {\n width: 'narrow',\n context: 'formatting'\n });\n\n case 'aaaa':\n default:\n return match.dayPeriod(string, {\n width: 'wide',\n context: 'formatting'\n }) || match.dayPeriod(string, {\n width: 'abbreviated',\n context: 'formatting'\n }) || match.dayPeriod(string, {\n width: 'narrow',\n context: 'formatting'\n });\n }\n },\n set: function (date, _flags, value, _options) {\n date.setUTCHours(dayPeriodEnumToHours(value), 0, 0, 0);\n return date;\n },\n incompatibleTokens: ['b', 'B', 'H', 'K', 'k', 't', 'T']\n },\n // AM, PM, midnight\n b: {\n priority: 80,\n parse: function (string, token, match, _options) {\n switch (token) {\n case 'b':\n case 'bb':\n case 'bbb':\n return match.dayPeriod(string, {\n width: 'abbreviated',\n context: 'formatting'\n }) || match.dayPeriod(string, {\n width: 'narrow',\n context: 'formatting'\n });\n\n case 'bbbbb':\n return match.dayPeriod(string, {\n width: 'narrow',\n context: 'formatting'\n });\n\n case 'bbbb':\n default:\n return match.dayPeriod(string, {\n width: 'wide',\n context: 'formatting'\n }) || match.dayPeriod(string, {\n width: 'abbreviated',\n context: 'formatting'\n }) || match.dayPeriod(string, {\n width: 'narrow',\n context: 'formatting'\n });\n }\n },\n set: function (date, _flags, value, _options) {\n date.setUTCHours(dayPeriodEnumToHours(value), 0, 0, 0);\n return date;\n },\n incompatibleTokens: ['a', 'B', 'H', 'K', 'k', 't', 'T']\n },\n // in the morning, in the afternoon, in the evening, at night\n B: {\n priority: 80,\n parse: function (string, token, match, _options) {\n switch (token) {\n case 'B':\n case 'BB':\n case 'BBB':\n return match.dayPeriod(string, {\n width: 'abbreviated',\n context: 'formatting'\n }) || match.dayPeriod(string, {\n width: 'narrow',\n context: 'formatting'\n });\n\n case 'BBBBB':\n return match.dayPeriod(string, {\n width: 'narrow',\n context: 'formatting'\n });\n\n case 'BBBB':\n default:\n return match.dayPeriod(string, {\n width: 'wide',\n context: 'formatting'\n }) || match.dayPeriod(string, {\n width: 'abbreviated',\n context: 'formatting'\n }) || match.dayPeriod(string, {\n width: 'narrow',\n context: 'formatting'\n });\n }\n },\n set: function (date, _flags, value, _options) {\n date.setUTCHours(dayPeriodEnumToHours(value), 0, 0, 0);\n return date;\n },\n incompatibleTokens: ['a', 'b', 't', 'T']\n },\n // Hour [1-12]\n h: {\n priority: 70,\n parse: function (string, token, match, _options) {\n switch (token) {\n case 'h':\n return parseNumericPattern(numericPatterns.hour12h, string);\n\n case 'ho':\n return match.ordinalNumber(string, {\n unit: 'hour'\n });\n\n default:\n return parseNDigits(token.length, string);\n }\n },\n validate: function (_date, value, _options) {\n return value >= 1 && value <= 12;\n },\n set: function (date, _flags, value, _options) {\n var isPM = date.getUTCHours() >= 12;\n\n if (isPM && value < 12) {\n date.setUTCHours(value + 12, 0, 0, 0);\n } else if (!isPM && value === 12) {\n date.setUTCHours(0, 0, 0, 0);\n } else {\n date.setUTCHours(value, 0, 0, 0);\n }\n\n return date;\n },\n incompatibleTokens: ['H', 'K', 'k', 't', 'T']\n },\n // Hour [0-23]\n H: {\n priority: 70,\n parse: function (string, token, match, _options) {\n switch (token) {\n case 'H':\n return parseNumericPattern(numericPatterns.hour23h, string);\n\n case 'Ho':\n return match.ordinalNumber(string, {\n unit: 'hour'\n });\n\n default:\n return parseNDigits(token.length, string);\n }\n },\n validate: function (_date, value, _options) {\n return value >= 0 && value <= 23;\n },\n set: function (date, _flags, value, _options) {\n date.setUTCHours(value, 0, 0, 0);\n return date;\n },\n incompatibleTokens: ['a', 'b', 'h', 'K', 'k', 't', 'T']\n },\n // Hour [0-11]\n K: {\n priority: 70,\n parse: function (string, token, match, _options) {\n switch (token) {\n case 'K':\n return parseNumericPattern(numericPatterns.hour11h, string);\n\n case 'Ko':\n return match.ordinalNumber(string, {\n unit: 'hour'\n });\n\n default:\n return parseNDigits(token.length, string);\n }\n },\n validate: function (_date, value, _options) {\n return value >= 0 && value <= 11;\n },\n set: function (date, _flags, value, _options) {\n var isPM = date.getUTCHours() >= 12;\n\n if (isPM && value < 12) {\n date.setUTCHours(value + 12, 0, 0, 0);\n } else {\n date.setUTCHours(value, 0, 0, 0);\n }\n\n return date;\n },\n incompatibleTokens: ['a', 'b', 'h', 'H', 'k', 't', 'T']\n },\n // Hour [1-24]\n k: {\n priority: 70,\n parse: function (string, token, match, _options) {\n switch (token) {\n case 'k':\n return parseNumericPattern(numericPatterns.hour24h, string);\n\n case 'ko':\n return match.ordinalNumber(string, {\n unit: 'hour'\n });\n\n default:\n return parseNDigits(token.length, string);\n }\n },\n validate: function (_date, value, _options) {\n return value >= 1 && value <= 24;\n },\n set: function (date, _flags, value, _options) {\n var hours = value <= 24 ? value % 24 : value;\n date.setUTCHours(hours, 0, 0, 0);\n return date;\n },\n incompatibleTokens: ['a', 'b', 'h', 'H', 'K', 't', 'T']\n },\n // Minute\n m: {\n priority: 60,\n parse: function (string, token, match, _options) {\n switch (token) {\n case 'm':\n return parseNumericPattern(numericPatterns.minute, string);\n\n case 'mo':\n return match.ordinalNumber(string, {\n unit: 'minute'\n });\n\n default:\n return parseNDigits(token.length, string);\n }\n },\n validate: function (_date, value, _options) {\n return value >= 0 && value <= 59;\n },\n set: function (date, _flags, value, _options) {\n date.setUTCMinutes(value, 0, 0);\n return date;\n },\n incompatibleTokens: ['t', 'T']\n },\n // Second\n s: {\n priority: 50,\n parse: function (string, token, match, _options) {\n switch (token) {\n case 's':\n return parseNumericPattern(numericPatterns.second, string);\n\n case 'so':\n return match.ordinalNumber(string, {\n unit: 'second'\n });\n\n default:\n return parseNDigits(token.length, string);\n }\n },\n validate: function (_date, value, _options) {\n return value >= 0 && value <= 59;\n },\n set: function (date, _flags, value, _options) {\n date.setUTCSeconds(value, 0);\n return date;\n },\n incompatibleTokens: ['t', 'T']\n },\n // Fraction of second\n S: {\n priority: 30,\n parse: function (string, token, _match, _options) {\n var valueCallback = function (value) {\n return Math.floor(value * Math.pow(10, -token.length + 3));\n };\n\n return parseNDigits(token.length, string, valueCallback);\n },\n set: function (date, _flags, value, _options) {\n date.setUTCMilliseconds(value);\n return date;\n },\n incompatibleTokens: ['t', 'T']\n },\n // Timezone (ISO-8601. +00:00 is `'Z'`)\n X: {\n priority: 10,\n parse: function (string, token, _match, _options) {\n switch (token) {\n case 'X':\n return parseTimezonePattern(timezonePatterns.basicOptionalMinutes, string);\n\n case 'XX':\n return parseTimezonePattern(timezonePatterns.basic, string);\n\n case 'XXXX':\n return parseTimezonePattern(timezonePatterns.basicOptionalSeconds, string);\n\n case 'XXXXX':\n return parseTimezonePattern(timezonePatterns.extendedOptionalSeconds, string);\n\n case 'XXX':\n default:\n return parseTimezonePattern(timezonePatterns.extended, string);\n }\n },\n set: function (date, flags, value, _options) {\n if (flags.timestampIsSet) {\n return date;\n }\n\n return new Date(date.getTime() - value);\n },\n incompatibleTokens: ['t', 'T', 'x']\n },\n // Timezone (ISO-8601)\n x: {\n priority: 10,\n parse: function (string, token, _match, _options) {\n switch (token) {\n case 'x':\n return parseTimezonePattern(timezonePatterns.basicOptionalMinutes, string);\n\n case 'xx':\n return parseTimezonePattern(timezonePatterns.basic, string);\n\n case 'xxxx':\n return parseTimezonePattern(timezonePatterns.basicOptionalSeconds, string);\n\n case 'xxxxx':\n return parseTimezonePattern(timezonePatterns.extendedOptionalSeconds, string);\n\n case 'xxx':\n default:\n return parseTimezonePattern(timezonePatterns.extended, string);\n }\n },\n set: function (date, flags, value, _options) {\n if (flags.timestampIsSet) {\n return date;\n }\n\n return new Date(date.getTime() - value);\n },\n incompatibleTokens: ['t', 'T', 'X']\n },\n // Seconds timestamp\n t: {\n priority: 40,\n parse: function (string, _token, _match, _options) {\n return parseAnyDigitsSigned(string);\n },\n set: function (_date, _flags, value, _options) {\n return [new Date(value * 1000), {\n timestampIsSet: true\n }];\n },\n incompatibleTokens: '*'\n },\n // Milliseconds timestamp\n T: {\n priority: 20,\n parse: function (string, _token, _match, _options) {\n return parseAnyDigitsSigned(string);\n },\n set: function (_date, _flags, value, _options) {\n return [new Date(value), {\n timestampIsSet: true\n }];\n },\n incompatibleTokens: '*'\n }\n};\nexport default parsers;","import toInteger from \"../toInteger/index.js\";\nimport toDate from \"../../toDate/index.js\";\nimport getUTCWeek from \"../getUTCWeek/index.js\";\nimport requiredArgs from \"../requiredArgs/index.js\"; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function setUTCWeek(dirtyDate, dirtyWeek, options) {\n requiredArgs(2, arguments);\n var date = toDate(dirtyDate);\n var week = toInteger(dirtyWeek);\n var diff = getUTCWeek(date, options) - week;\n date.setUTCDate(date.getUTCDate() - diff * 7);\n return date;\n}","import toInteger from \"../toInteger/index.js\";\nimport toDate from \"../../toDate/index.js\";\nimport getUTCISOWeek from \"../getUTCISOWeek/index.js\";\nimport requiredArgs from \"../requiredArgs/index.js\"; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function setUTCISOWeek(dirtyDate, dirtyISOWeek) {\n requiredArgs(2, arguments);\n var date = toDate(dirtyDate);\n var isoWeek = toInteger(dirtyISOWeek);\n var diff = getUTCISOWeek(date) - isoWeek;\n date.setUTCDate(date.getUTCDate() - diff * 7);\n return date;\n}","import toInteger from \"../toInteger/index.js\";\nimport toDate from \"../../toDate/index.js\";\nimport requiredArgs from \"../requiredArgs/index.js\"; // This function will be a part of public API when UTC function will be implemented.\n// See issue: https://github.com/date-fns/date-fns/issues/376\n\nexport default function setUTCISODay(dirtyDate, dirtyDay) {\n requiredArgs(2, arguments);\n var day = toInteger(dirtyDay);\n\n if (day % 7 === 0) {\n day = day - 7;\n }\n\n var weekStartsOn = 1;\n var date = toDate(dirtyDate);\n var currentDay = date.getUTCDay();\n var remainder = day % 7;\n var dayIndex = (remainder + 7) % 7;\n var diff = (dayIndex < weekStartsOn ? 7 : 0) + day - currentDay;\n date.setUTCDate(date.getUTCDate() + diff);\n return date;\n}","import defaultLocale from \"../locale/en-US/index.js\";\nimport subMilliseconds from \"../subMilliseconds/index.js\";\nimport toDate from \"../toDate/index.js\";\nimport assign from \"../_lib/assign/index.js\";\nimport longFormatters from \"../_lib/format/longFormatters/index.js\";\nimport getTimezoneOffsetInMilliseconds from \"../_lib/getTimezoneOffsetInMilliseconds/index.js\";\nimport { isProtectedDayOfYearToken, isProtectedWeekYearToken, throwProtectedError } from \"../_lib/protectedTokens/index.js\";\nimport toInteger from \"../_lib/toInteger/index.js\";\nimport parsers from \"./_lib/parsers/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\nvar TIMEZONE_UNIT_PRIORITY = 10; // This RegExp consists of three parts separated by `|`:\n// - [yYQqMLwIdDecihHKkms]o matches any available ordinal number token\n// (one of the certain letters followed by `o`)\n// - (\\w)\\1* matches any sequences of the same letter\n// - '' matches two quote characters in a row\n// - '(''|[^'])+('|$) matches anything surrounded by two quote characters ('),\n// except a single quote symbol, which ends the sequence.\n// Two quote characters do not end the sequence.\n// If there is no matching single quote\n// then the sequence will continue until the end of the string.\n// - . matches any single character unmatched by previous parts of the RegExps\n\nvar formattingTokensRegExp = /[yYQqMLwIdDecihHKkms]o|(\\w)\\1*|''|'(''|[^'])+('|$)|./g; // This RegExp catches symbols escaped by quotes, and also\n// sequences of symbols P, p, and the combinations like `PPPPPPPppppp`\n\nvar longFormattingTokensRegExp = /P+p+|P+|p+|''|'(''|[^'])+('|$)|./g;\nvar escapedStringRegExp = /^'([^]*?)'?$/;\nvar doubleQuoteRegExp = /''/g;\nvar notWhitespaceRegExp = /\\S/;\nvar unescapedLatinCharacterRegExp = /[a-zA-Z]/;\n/**\n * @name parse\n * @category Common Helpers\n * @summary Parse the date.\n *\n * @description\n * Return the date parsed from string using the given format string.\n *\n * > ⚠️ Please note that the `format` tokens differ from Moment.js and other libraries.\n * > See: https://git.io/fxCyr\n *\n * The characters in the format string wrapped between two single quotes characters (') are escaped.\n * Two single quotes in a row, whether inside or outside a quoted sequence, represent a 'real' single quote.\n *\n * Format of the format string is based on Unicode Technical Standard #35:\n * https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table\n * with a few additions (see note 5 below the table).\n *\n * Not all tokens are compatible. Combinations that don't make sense or could lead to bugs are prohibited\n * and will throw `RangeError`. For example usage of 24-hour format token with AM/PM token will throw an exception:\n *\n * ```javascript\n * parse('23 AM', 'HH a', new Date())\n * //=> RangeError: The format string mustn't contain `HH` and `a` at the same time\n * ```\n *\n * See the compatibility table: https://docs.google.com/spreadsheets/d/e/2PACX-1vQOPU3xUhplll6dyoMmVUXHKl_8CRDs6_ueLmex3SoqwhuolkuN3O05l4rqx5h1dKX8eb46Ul-CCSrq/pubhtml?gid=0&single=true\n *\n * Accepted format string patterns:\n * | Unit |Prior| Pattern | Result examples | Notes |\n * |---------------------------------|-----|---------|-----------------------------------|-------|\n * | Era | 140 | G..GGG | AD, BC | |\n * | | | GGGG | Anno Domini, Before Christ | 2 |\n * | | | GGGGG | A, B | |\n * | Calendar year | 130 | y | 44, 1, 1900, 2017, 9999 | 4 |\n * | | | yo | 44th, 1st, 1900th, 9999999th | 4,5 |\n * | | | yy | 44, 01, 00, 17 | 4 |\n * | | | yyy | 044, 001, 123, 999 | 4 |\n * | | | yyyy | 0044, 0001, 1900, 2017 | 4 |\n * | | | yyyyy | ... | 2,4 |\n * | Local week-numbering year | 130 | Y | 44, 1, 1900, 2017, 9000 | 4 |\n * | | | Yo | 44th, 1st, 1900th, 9999999th | 4,5 |\n * | | | YY | 44, 01, 00, 17 | 4,6 |\n * | | | YYY | 044, 001, 123, 999 | 4 |\n * | | | YYYY | 0044, 0001, 1900, 2017 | 4,6 |\n * | | | YYYYY | ... | 2,4 |\n * | ISO week-numbering year | 130 | R | -43, 1, 1900, 2017, 9999, -9999 | 4,5 |\n * | | | RR | -43, 01, 00, 17 | 4,5 |\n * | | | RRR | -043, 001, 123, 999, -999 | 4,5 |\n * | | | RRRR | -0043, 0001, 2017, 9999, -9999 | 4,5 |\n * | | | RRRRR | ... | 2,4,5 |\n * | Extended year | 130 | u | -43, 1, 1900, 2017, 9999, -999 | 4 |\n * | | | uu | -43, 01, 99, -99 | 4 |\n * | | | uuu | -043, 001, 123, 999, -999 | 4 |\n * | | | uuuu | -0043, 0001, 2017, 9999, -9999 | 4 |\n * | | | uuuuu | ... | 2,4 |\n * | Quarter (formatting) | 120 | Q | 1, 2, 3, 4 | |\n * | | | Qo | 1st, 2nd, 3rd, 4th | 5 |\n * | | | QQ | 01, 02, 03, 04 | |\n * | | | QQQ | Q1, Q2, Q3, Q4 | |\n * | | | QQQQ | 1st quarter, 2nd quarter, ... | 2 |\n * | | | QQQQQ | 1, 2, 3, 4 | 4 |\n * | Quarter (stand-alone) | 120 | q | 1, 2, 3, 4 | |\n * | | | qo | 1st, 2nd, 3rd, 4th | 5 |\n * | | | qq | 01, 02, 03, 04 | |\n * | | | qqq | Q1, Q2, Q3, Q4 | |\n * | | | qqqq | 1st quarter, 2nd quarter, ... | 2 |\n * | | | qqqqq | 1, 2, 3, 4 | 3 |\n * | Month (formatting) | 110 | M | 1, 2, ..., 12 | |\n * | | | Mo | 1st, 2nd, ..., 12th | 5 |\n * | | | MM | 01, 02, ..., 12 | |\n * | | | MMM | Jan, Feb, ..., Dec | |\n * | | | MMMM | January, February, ..., December | 2 |\n * | | | MMMMM | J, F, ..., D | |\n * | Month (stand-alone) | 110 | L | 1, 2, ..., 12 | |\n * | | | Lo | 1st, 2nd, ..., 12th | 5 |\n * | | | LL | 01, 02, ..., 12 | |\n * | | | LLL | Jan, Feb, ..., Dec | |\n * | | | LLLL | January, February, ..., December | 2 |\n * | | | LLLLL | J, F, ..., D | |\n * | Local week of year | 100 | w | 1, 2, ..., 53 | |\n * | | | wo | 1st, 2nd, ..., 53th | 5 |\n * | | | ww | 01, 02, ..., 53 | |\n * | ISO week of year | 100 | I | 1, 2, ..., 53 | 5 |\n * | | | Io | 1st, 2nd, ..., 53th | 5 |\n * | | | II | 01, 02, ..., 53 | 5 |\n * | Day of month | 90 | d | 1, 2, ..., 31 | |\n * | | | do | 1st, 2nd, ..., 31st | 5 |\n * | | | dd | 01, 02, ..., 31 | |\n * | Day of year | 90 | D | 1, 2, ..., 365, 366 | 7 |\n * | | | Do | 1st, 2nd, ..., 365th, 366th | 5 |\n * | | | DD | 01, 02, ..., 365, 366 | 7 |\n * | | | DDD | 001, 002, ..., 365, 366 | |\n * | | | DDDD | ... | 2 |\n * | Day of week (formatting) | 90 | E..EEE | Mon, Tue, Wed, ..., Sun | |\n * | | | EEEE | Monday, Tuesday, ..., Sunday | 2 |\n * | | | EEEEE | M, T, W, T, F, S, S | |\n * | | | EEEEEE | Mo, Tu, We, Th, Fr, Su, Sa | |\n * | ISO day of week (formatting) | 90 | i | 1, 2, 3, ..., 7 | 5 |\n * | | | io | 1st, 2nd, ..., 7th | 5 |\n * | | | ii | 01, 02, ..., 07 | 5 |\n * | | | iii | Mon, Tue, Wed, ..., Sun | 5 |\n * | | | iiii | Monday, Tuesday, ..., Sunday | 2,5 |\n * | | | iiiii | M, T, W, T, F, S, S | 5 |\n * | | | iiiiii | Mo, Tu, We, Th, Fr, Su, Sa | 5 |\n * | Local day of week (formatting) | 90 | e | 2, 3, 4, ..., 1 | |\n * | | | eo | 2nd, 3rd, ..., 1st | 5 |\n * | | | ee | 02, 03, ..., 01 | |\n * | | | eee | Mon, Tue, Wed, ..., Sun | |\n * | | | eeee | Monday, Tuesday, ..., Sunday | 2 |\n * | | | eeeee | M, T, W, T, F, S, S | |\n * | | | eeeeee | Mo, Tu, We, Th, Fr, Su, Sa | |\n * | Local day of week (stand-alone) | 90 | c | 2, 3, 4, ..., 1 | |\n * | | | co | 2nd, 3rd, ..., 1st | 5 |\n * | | | cc | 02, 03, ..., 01 | |\n * | | | ccc | Mon, Tue, Wed, ..., Sun | |\n * | | | cccc | Monday, Tuesday, ..., Sunday | 2 |\n * | | | ccccc | M, T, W, T, F, S, S | |\n * | | | cccccc | Mo, Tu, We, Th, Fr, Su, Sa | |\n * | AM, PM | 80 | a..aaa | AM, PM | |\n * | | | aaaa | a.m., p.m. | 2 |\n * | | | aaaaa | a, p | |\n * | AM, PM, noon, midnight | 80 | b..bbb | AM, PM, noon, midnight | |\n * | | | bbbb | a.m., p.m., noon, midnight | 2 |\n * | | | bbbbb | a, p, n, mi | |\n * | Flexible day period | 80 | B..BBB | at night, in the morning, ... | |\n * | | | BBBB | at night, in the morning, ... | 2 |\n * | | | BBBBB | at night, in the morning, ... | |\n * | Hour [1-12] | 70 | h | 1, 2, ..., 11, 12 | |\n * | | | ho | 1st, 2nd, ..., 11th, 12th | 5 |\n * | | | hh | 01, 02, ..., 11, 12 | |\n * | Hour [0-23] | 70 | H | 0, 1, 2, ..., 23 | |\n * | | | Ho | 0th, 1st, 2nd, ..., 23rd | 5 |\n * | | | HH | 00, 01, 02, ..., 23 | |\n * | Hour [0-11] | 70 | K | 1, 2, ..., 11, 0 | |\n * | | | Ko | 1st, 2nd, ..., 11th, 0th | 5 |\n * | | | KK | 01, 02, ..., 11, 00 | |\n * | Hour [1-24] | 70 | k | 24, 1, 2, ..., 23 | |\n * | | | ko | 24th, 1st, 2nd, ..., 23rd | 5 |\n * | | | kk | 24, 01, 02, ..., 23 | |\n * | Minute | 60 | m | 0, 1, ..., 59 | |\n * | | | mo | 0th, 1st, ..., 59th | 5 |\n * | | | mm | 00, 01, ..., 59 | |\n * | Second | 50 | s | 0, 1, ..., 59 | |\n * | | | so | 0th, 1st, ..., 59th | 5 |\n * | | | ss | 00, 01, ..., 59 | |\n * | Seconds timestamp | 40 | t | 512969520 | |\n * | | | tt | ... | 2 |\n * | Fraction of second | 30 | S | 0, 1, ..., 9 | |\n * | | | SS | 00, 01, ..., 99 | |\n * | | | SSS | 000, 0001, ..., 999 | |\n * | | | SSSS | ... | 2 |\n * | Milliseconds timestamp | 20 | T | 512969520900 | |\n * | | | TT | ... | 2 |\n * | Timezone (ISO-8601 w/ Z) | 10 | X | -08, +0530, Z | |\n * | | | XX | -0800, +0530, Z | |\n * | | | XXX | -08:00, +05:30, Z | |\n * | | | XXXX | -0800, +0530, Z, +123456 | 2 |\n * | | | XXXXX | -08:00, +05:30, Z, +12:34:56 | |\n * | Timezone (ISO-8601 w/o Z) | 10 | x | -08, +0530, +00 | |\n * | | | xx | -0800, +0530, +0000 | |\n * | | | xxx | -08:00, +05:30, +00:00 | 2 |\n * | | | xxxx | -0800, +0530, +0000, +123456 | |\n * | | | xxxxx | -08:00, +05:30, +00:00, +12:34:56 | |\n * | Long localized date | NA | P | 05/29/1453 | 5,8 |\n * | | | PP | May 29, 1453 | |\n * | | | PPP | May 29th, 1453 | |\n * | | | PPPP | Sunday, May 29th, 1453 | 2,5,8 |\n * | Long localized time | NA | p | 12:00 AM | 5,8 |\n * | | | pp | 12:00:00 AM | |\n * | Combination of date and time | NA | Pp | 05/29/1453, 12:00 AM | |\n * | | | PPpp | May 29, 1453, 12:00:00 AM | |\n * | | | PPPpp | May 29th, 1453 at ... | |\n * | | | PPPPpp | Sunday, May 29th, 1453 at ... | 2,5,8 |\n * Notes:\n * 1. \"Formatting\" units (e.g. formatting quarter) in the default en-US locale\n * are the same as \"stand-alone\" units, but are different in some languages.\n * \"Formatting\" units are declined according to the rules of the language\n * in the context of a date. \"Stand-alone\" units are always nominative singular.\n * In `format` function, they will produce different result:\n *\n * `format(new Date(2017, 10, 6), 'do LLLL', {locale: cs}) //=> '6. listopad'`\n *\n * `format(new Date(2017, 10, 6), 'do MMMM', {locale: cs}) //=> '6. listopadu'`\n *\n * `parse` will try to match both formatting and stand-alone units interchangably.\n *\n * 2. Any sequence of the identical letters is a pattern, unless it is escaped by\n * the single quote characters (see below).\n * If the sequence is longer than listed in table:\n * - for numerical units (`yyyyyyyy`) `parse` will try to match a number\n * as wide as the sequence\n * - for text units (`MMMMMMMM`) `parse` will try to match the widest variation of the unit.\n * These variations are marked with \"2\" in the last column of the table.\n *\n * 3. `QQQQQ` and `qqqqq` could be not strictly numerical in some locales.\n * These tokens represent the shortest form of the quarter.\n *\n * 4. The main difference between `y` and `u` patterns are B.C. years:\n *\n * | Year | `y` | `u` |\n * |------|-----|-----|\n * | AC 1 | 1 | 1 |\n * | BC 1 | 1 | 0 |\n * | BC 2 | 2 | -1 |\n *\n * Also `yy` will try to guess the century of two digit year by proximity with `referenceDate`:\n *\n * `parse('50', 'yy', new Date(2018, 0, 1)) //=> Sat Jan 01 2050 00:00:00`\n *\n * `parse('75', 'yy', new Date(2018, 0, 1)) //=> Wed Jan 01 1975 00:00:00`\n *\n * while `uu` will just assign the year as is:\n *\n * `parse('50', 'uu', new Date(2018, 0, 1)) //=> Sat Jan 01 0050 00:00:00`\n *\n * `parse('75', 'uu', new Date(2018, 0, 1)) //=> Tue Jan 01 0075 00:00:00`\n *\n * The same difference is true for local and ISO week-numbering years (`Y` and `R`),\n * except local week-numbering years are dependent on `options.weekStartsOn`\n * and `options.firstWeekContainsDate` (compare [setISOWeekYear]{@link https://date-fns.org/docs/setISOWeekYear}\n * and [setWeekYear]{@link https://date-fns.org/docs/setWeekYear}).\n *\n * 5. These patterns are not in the Unicode Technical Standard #35:\n * - `i`: ISO day of week\n * - `I`: ISO week of year\n * - `R`: ISO week-numbering year\n * - `o`: ordinal number modifier\n * - `P`: long localized date\n * - `p`: long localized time\n *\n * 6. `YY` and `YYYY` tokens represent week-numbering years but they are often confused with years.\n * You should enable `options.useAdditionalWeekYearTokens` to use them. See: https://git.io/fxCyr\n *\n * 7. `D` and `DD` tokens represent days of the year but they are ofthen confused with days of the month.\n * You should enable `options.useAdditionalDayOfYearTokens` to use them. See: https://git.io/fxCyr\n *\n * 8. `P+` tokens do not have a defined priority since they are merely aliases to other tokens based\n * on the given locale.\n *\n * using `en-US` locale: `P` => `MM/dd/yyyy`\n * using `en-US` locale: `p` => `hh:mm a`\n * using `pt-BR` locale: `P` => `dd/MM/yyyy`\n * using `pt-BR` locale: `p` => `HH:mm`\n *\n * Values will be assigned to the date in the descending order of its unit's priority.\n * Units of an equal priority overwrite each other in the order of appearance.\n *\n * If no values of higher priority are parsed (e.g. when parsing string 'January 1st' without a year),\n * the values will be taken from 3rd argument `referenceDate` which works as a context of parsing.\n *\n * `referenceDate` must be passed for correct work of the function.\n * If you're not sure which `referenceDate` to supply, create a new instance of Date:\n * `parse('02/11/2014', 'MM/dd/yyyy', new Date())`\n * In this case parsing will be done in the context of the current date.\n * If `referenceDate` is `Invalid Date` or a value not convertible to valid `Date`,\n * then `Invalid Date` will be returned.\n *\n * The result may vary by locale.\n *\n * If `formatString` matches with `dateString` but does not provides tokens, `referenceDate` will be returned.\n *\n * If parsing failed, `Invalid Date` will be returned.\n * Invalid Date is a Date, whose time value is NaN.\n * Time value of Date: http://es5.github.io/#x15.9.1.1\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - Old `parse` was renamed to `toDate`.\n * Now `parse` is a new function which parses a string using a provided format.\n *\n * ```javascript\n * // Before v2.0.0\n * parse('2016-01-01')\n *\n * // v2.0.0 onward (toDate no longer accepts a string)\n * toDate(1392098430000) // Unix to timestamp\n * toDate(new Date(2014, 1, 11, 11, 30, 30)) // Cloning the date\n * parse('2016-01-01', 'yyyy-MM-dd', new Date())\n * ```\n *\n * @param {String} dateString - the string to parse\n * @param {String} formatString - the string of tokens\n * @param {Date|Number} referenceDate - defines values missing from the parsed dateString\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year\n * @param {Boolean} [options.useAdditionalWeekYearTokens=false] - if true, allows usage of the week-numbering year tokens `YY` and `YYYY`;\n * see: https://git.io/fxCyr\n * @param {Boolean} [options.useAdditionalDayOfYearTokens=false] - if true, allows usage of the day of year tokens `D` and `DD`;\n * see: https://git.io/fxCyr\n * @returns {Date} the parsed date\n * @throws {TypeError} 3 arguments required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7\n * @throws {RangeError} `options.locale` must contain `match` property\n * @throws {RangeError} use `yyyy` instead of `YYYY` for formatting years using [format provided] to the input [input provided]; see: https://git.io/fxCyr\n * @throws {RangeError} use `yy` instead of `YY` for formatting years using [format provided] to the input [input provided]; see: https://git.io/fxCyr\n * @throws {RangeError} use `d` instead of `D` for formatting days of the month using [format provided] to the input [input provided]; see: https://git.io/fxCyr\n * @throws {RangeError} use `dd` instead of `DD` for formatting days of the month using [format provided] to the input [input provided]; see: https://git.io/fxCyr\n * @throws {RangeError} format string contains an unescaped latin alphabet character\n *\n * @example\n * // Parse 11 February 2014 from middle-endian format:\n * var result = parse('02/11/2014', 'MM/dd/yyyy', new Date())\n * //=> Tue Feb 11 2014 00:00:00\n *\n * @example\n * // Parse 28th of February in Esperanto locale in the context of 2010 year:\n * import eo from 'date-fns/locale/eo'\n * var result = parse('28-a de februaro', \"do 'de' MMMM\", new Date(2010, 0, 1), {\n * locale: eo\n * })\n * //=> Sun Feb 28 2010 00:00:00\n */\n\nexport default function parse(dirtyDateString, dirtyFormatString, dirtyReferenceDate, dirtyOptions) {\n requiredArgs(3, arguments);\n var dateString = String(dirtyDateString);\n var formatString = String(dirtyFormatString);\n var options = dirtyOptions || {};\n var locale = options.locale || defaultLocale;\n\n if (!locale.match) {\n throw new RangeError('locale must contain match property');\n }\n\n var localeFirstWeekContainsDate = locale.options && locale.options.firstWeekContainsDate;\n var defaultFirstWeekContainsDate = localeFirstWeekContainsDate == null ? 1 : toInteger(localeFirstWeekContainsDate);\n var firstWeekContainsDate = options.firstWeekContainsDate == null ? defaultFirstWeekContainsDate : toInteger(options.firstWeekContainsDate); // Test if weekStartsOn is between 1 and 7 _and_ is not NaN\n\n if (!(firstWeekContainsDate >= 1 && firstWeekContainsDate <= 7)) {\n throw new RangeError('firstWeekContainsDate must be between 1 and 7 inclusively');\n }\n\n var localeWeekStartsOn = locale.options && locale.options.weekStartsOn;\n var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);\n var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN\n\n if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {\n throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');\n }\n\n if (formatString === '') {\n if (dateString === '') {\n return toDate(dirtyReferenceDate);\n } else {\n return new Date(NaN);\n }\n }\n\n var subFnOptions = {\n firstWeekContainsDate: firstWeekContainsDate,\n weekStartsOn: weekStartsOn,\n locale: locale\n }; // If timezone isn't specified, it will be set to the system timezone\n\n var setters = [{\n priority: TIMEZONE_UNIT_PRIORITY,\n subPriority: -1,\n set: dateToSystemTimezone,\n index: 0\n }];\n var i;\n var tokens = formatString.match(longFormattingTokensRegExp).map(function (substring) {\n var firstCharacter = substring[0];\n\n if (firstCharacter === 'p' || firstCharacter === 'P') {\n var longFormatter = longFormatters[firstCharacter];\n return longFormatter(substring, locale.formatLong, subFnOptions);\n }\n\n return substring;\n }).join('').match(formattingTokensRegExp);\n var usedTokens = [];\n\n for (i = 0; i < tokens.length; i++) {\n var token = tokens[i];\n\n if (!options.useAdditionalWeekYearTokens && isProtectedWeekYearToken(token)) {\n throwProtectedError(token, formatString, dirtyDateString);\n }\n\n if (!options.useAdditionalDayOfYearTokens && isProtectedDayOfYearToken(token)) {\n throwProtectedError(token, formatString, dirtyDateString);\n }\n\n var firstCharacter = token[0];\n var parser = parsers[firstCharacter];\n\n if (parser) {\n var incompatibleTokens = parser.incompatibleTokens;\n\n if (Array.isArray(incompatibleTokens)) {\n var incompatibleToken = void 0;\n\n for (var _i = 0; _i < usedTokens.length; _i++) {\n var usedToken = usedTokens[_i].token;\n\n if (incompatibleTokens.indexOf(usedToken) !== -1 || usedToken === firstCharacter) {\n incompatibleToken = usedTokens[_i];\n break;\n }\n }\n\n if (incompatibleToken) {\n throw new RangeError(\"The format string mustn't contain `\".concat(incompatibleToken.fullToken, \"` and `\").concat(token, \"` at the same time\"));\n }\n } else if (parser.incompatibleTokens === '*' && usedTokens.length) {\n throw new RangeError(\"The format string mustn't contain `\".concat(token, \"` and any other token at the same time\"));\n }\n\n usedTokens.push({\n token: firstCharacter,\n fullToken: token\n });\n var parseResult = parser.parse(dateString, token, locale.match, subFnOptions);\n\n if (!parseResult) {\n return new Date(NaN);\n }\n\n setters.push({\n priority: parser.priority,\n subPriority: parser.subPriority || 0,\n set: parser.set,\n validate: parser.validate,\n value: parseResult.value,\n index: setters.length\n });\n dateString = parseResult.rest;\n } else {\n if (firstCharacter.match(unescapedLatinCharacterRegExp)) {\n throw new RangeError('Format string contains an unescaped latin alphabet character `' + firstCharacter + '`');\n } // Replace two single quote characters with one single quote character\n\n\n if (token === \"''\") {\n token = \"'\";\n } else if (firstCharacter === \"'\") {\n token = cleanEscapedString(token);\n } // Cut token from string, or, if string doesn't match the token, return Invalid Date\n\n\n if (dateString.indexOf(token) === 0) {\n dateString = dateString.slice(token.length);\n } else {\n return new Date(NaN);\n }\n }\n } // Check if the remaining input contains something other than whitespace\n\n\n if (dateString.length > 0 && notWhitespaceRegExp.test(dateString)) {\n return new Date(NaN);\n }\n\n var uniquePrioritySetters = setters.map(function (setter) {\n return setter.priority;\n }).sort(function (a, b) {\n return b - a;\n }).filter(function (priority, index, array) {\n return array.indexOf(priority) === index;\n }).map(function (priority) {\n return setters.filter(function (setter) {\n return setter.priority === priority;\n }).sort(function (a, b) {\n return b.subPriority - a.subPriority;\n });\n }).map(function (setterArray) {\n return setterArray[0];\n });\n var date = toDate(dirtyReferenceDate);\n\n if (isNaN(date)) {\n return new Date(NaN);\n } // Convert the date in system timezone to the same date in UTC+00:00 timezone.\n // This ensures that when UTC functions will be implemented, locales will be compatible with them.\n // See an issue about UTC functions: https://github.com/date-fns/date-fns/issues/37\n\n\n var utcDate = subMilliseconds(date, getTimezoneOffsetInMilliseconds(date));\n var flags = {};\n\n for (i = 0; i < uniquePrioritySetters.length; i++) {\n var setter = uniquePrioritySetters[i];\n\n if (setter.validate && !setter.validate(utcDate, setter.value, subFnOptions)) {\n return new Date(NaN);\n }\n\n var result = setter.set(utcDate, flags, setter.value, subFnOptions); // Result is tuple (date, flags)\n\n if (result[0]) {\n utcDate = result[0];\n assign(flags, result[1]); // Result is date\n } else {\n utcDate = result;\n }\n }\n\n return utcDate;\n}\n\nfunction dateToSystemTimezone(date, flags) {\n if (flags.timestampIsSet) {\n return date;\n }\n\n var convertedDate = new Date(0);\n convertedDate.setFullYear(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());\n convertedDate.setHours(date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), date.getUTCMilliseconds());\n return convertedDate;\n}\n\nfunction cleanEscapedString(input) {\n return input.match(escapedStringRegExp)[1].replace(doubleQuoteRegExp, \"'\");\n}","import _curry2 from './_curry2.js';\nimport _xfBase from './_xfBase.js';\n\nvar XFilter = /*#__PURE__*/function () {\n function XFilter(f, xf) {\n this.xf = xf;\n this.f = f;\n }\n XFilter.prototype['@@transducer/init'] = _xfBase.init;\n XFilter.prototype['@@transducer/result'] = _xfBase.result;\n XFilter.prototype['@@transducer/step'] = function (result, input) {\n return this.f(input) ? this.xf['@@transducer/step'](result, input) : result;\n };\n\n return XFilter;\n}();\n\nvar _xfilter = /*#__PURE__*/_curry2(function _xfilter(f, xf) {\n return new XFilter(f, xf);\n});\nexport default _xfilter;","import _curry2 from './internal/_curry2.js';\nimport _dispatchable from './internal/_dispatchable.js';\nimport _filter from './internal/_filter.js';\nimport _isObject from './internal/_isObject.js';\nimport _reduce from './internal/_reduce.js';\nimport _xfilter from './internal/_xfilter.js';\nimport keys from './keys.js';\n\n/**\n * Takes a predicate and a `Filterable`, and returns a new filterable of the\n * same type containing the members of the given filterable which satisfy the\n * given predicate. Filterable objects include plain objects or any object\n * that has a filter method such as `Array`.\n *\n * Dispatches to the `filter` method of the second argument, if present.\n *\n * Acts as a transducer if a transformer is given in list position.\n *\n * @func\n * @memberOf R\n * @since v0.1.0\n * @category List\n * @sig Filterable f => (a -> Boolean) -> f a -> f a\n * @param {Function} pred\n * @param {Array} filterable\n * @return {Array} Filterable\n * @see R.reject, R.transduce, R.addIndex\n * @example\n *\n * const isEven = n => n % 2 === 0;\n *\n * R.filter(isEven, [1, 2, 3, 4]); //=> [2, 4]\n *\n * R.filter(isEven, {a: 1, b: 2, c: 3, d: 4}); //=> {b: 2, d: 4}\n */\nvar filter = /*#__PURE__*/_curry2( /*#__PURE__*/_dispatchable(['filter'], _xfilter, function (pred, filterable) {\n return _isObject(filterable) ? _reduce(function (acc, key) {\n if (pred(filterable[key])) {\n acc[key] = filterable[key];\n }\n return acc;\n }, {}, keys(filterable)) :\n // else\n _filter(pred, filterable);\n}));\nexport default filter;","export default function _filter(fn, list) {\n var idx = 0;\n var len = list.length;\n var result = [];\n\n while (idx < len) {\n if (fn(list[idx])) {\n result[result.length] = list[idx];\n }\n idx += 1;\n }\n return result;\n}","\n\n/**\n * A function that always returns `true`. Any passed in parameters are ignored.\n *\n * @func\n * @memberOf R\n * @since v0.9.0\n * @category Function\n * @sig * -> Boolean\n * @param {*}\n * @return {Boolean}\n * @see R.F\n * @example\n *\n * R.T(); //=> true\n */\nvar T = function () {\n return true;\n};\nexport default T;","import _curry2 from './internal/_curry2.js';\n\n/**\n * Returns a partial copy of an object omitting the keys specified.\n *\n * @func\n * @memberOf R\n * @since v0.1.0\n * @category Object\n * @sig [String] -> {String: *} -> {String: *}\n * @param {Array} names an array of String property names to omit from the new object\n * @param {Object} obj The object to copy from\n * @return {Object} A new object with properties from `names` not on it.\n * @see R.pick\n * @example\n *\n * R.omit(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {b: 2, c: 3}\n */\nvar omit = /*#__PURE__*/_curry2(function omit(names, obj) {\n var result = {};\n var index = {};\n var idx = 0;\n var len = names.length;\n\n while (idx < len) {\n index[names[idx]] = 1;\n idx += 1;\n }\n\n for (var prop in obj) {\n if (!index.hasOwnProperty(prop)) {\n result[prop] = obj[prop];\n }\n }\n return result;\n});\nexport default omit;","import _curry2 from './internal/_curry2.js';\n\n/**\n * Returns the larger of its two arguments.\n *\n * @func\n * @memberOf R\n * @since v0.1.0\n * @category Relation\n * @sig Ord a => a -> a -> a\n * @param {*} a\n * @param {*} b\n * @return {*}\n * @see R.maxBy, R.min\n * @example\n *\n * R.max(789, 123); //=> 789\n * R.max('a', 'b'); //=> 'b'\n */\nvar max = /*#__PURE__*/_curry2(function max(a, b) {\n return b > a ? b : a;\n});\nexport default max;","import _arity from './internal/_arity.js';\nimport _curry1 from './internal/_curry1.js';\nimport map from './map.js';\nimport max from './max.js';\nimport reduce from './reduce.js';\n\n/**\n * Returns a function, `fn`, which encapsulates `if/else, if/else, ...` logic.\n * `R.cond` takes a list of [predicate, transformer] pairs. All of the arguments\n * to `fn` are applied to each of the predicates in turn until one returns a\n * \"truthy\" value, at which point `fn` returns the result of applying its\n * arguments to the corresponding transformer. If none of the predicates\n * matches, `fn` returns undefined.\n *\n * @func\n * @memberOf R\n * @since v0.6.0\n * @category Logic\n * @sig [[(*... -> Boolean),(*... -> *)]] -> (*... -> *)\n * @param {Array} pairs A list of [predicate, transformer]\n * @return {Function}\n * @see R.ifElse, R.unless, R.when\n * @example\n *\n * const fn = R.cond([\n * [R.equals(0), R.always('water freezes at 0°C')],\n * [R.equals(100), R.always('water boils at 100°C')],\n * [R.T, temp => 'nothing special happens at ' + temp + '°C']\n * ]);\n * fn(0); //=> 'water freezes at 0°C'\n * fn(50); //=> 'nothing special happens at 50°C'\n * fn(100); //=> 'water boils at 100°C'\n */\nvar cond = /*#__PURE__*/_curry1(function cond(pairs) {\n var arity = reduce(max, 0, map(function (pair) {\n return pair[0].length;\n }, pairs));\n return _arity(arity, function () {\n var idx = 0;\n while (idx < pairs.length) {\n if (pairs[idx][0].apply(this, arguments)) {\n return pairs[idx][1].apply(this, arguments);\n }\n idx += 1;\n }\n });\n});\nexport default cond;","export default function _pipe(f, g) {\n return function () {\n return g.call(this, f.apply(this, arguments));\n };\n}","import _arity from './internal/_arity.js';\nimport _pipe from './internal/_pipe.js';\nimport reduce from './reduce.js';\nimport tail from './tail.js';\n\n/**\n * Performs left-to-right function composition. The leftmost function may have\n * any arity; the remaining functions must be unary.\n *\n * In some libraries this function is named `sequence`.\n *\n * **Note:** The result of pipe is not automatically curried.\n *\n * @func\n * @memberOf R\n * @since v0.1.0\n * @category Function\n * @sig (((a, b, ..., n) -> o), (o -> p), ..., (x -> y), (y -> z)) -> ((a, b, ..., n) -> z)\n * @param {...Function} functions\n * @return {Function}\n * @see R.compose\n * @example\n *\n * const f = R.pipe(Math.pow, R.negate, R.inc);\n *\n * f(3, 4); // -(3^4) + 1\n * @symb R.pipe(f, g, h)(a, b) = h(g(f(a, b)))\n */\nexport default function pipe() {\n if (arguments.length === 0) {\n throw new Error('pipe requires at least one argument');\n }\n return _arity(arguments[0].length, reduce(_pipe, arguments[0], tail(arguments)));\n}","/** @license React v16.12.0\n * react.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';var h=require(\"object-assign\"),n=\"function\"===typeof Symbol&&Symbol.for,p=n?Symbol.for(\"react.element\"):60103,q=n?Symbol.for(\"react.portal\"):60106,r=n?Symbol.for(\"react.fragment\"):60107,t=n?Symbol.for(\"react.strict_mode\"):60108,u=n?Symbol.for(\"react.profiler\"):60114,v=n?Symbol.for(\"react.provider\"):60109,w=n?Symbol.for(\"react.context\"):60110,x=n?Symbol.for(\"react.forward_ref\"):60112,y=n?Symbol.for(\"react.suspense\"):60113;n&&Symbol.for(\"react.suspense_list\");\nvar z=n?Symbol.for(\"react.memo\"):60115,aa=n?Symbol.for(\"react.lazy\"):60116;n&&Symbol.for(\"react.fundamental\");n&&Symbol.for(\"react.responder\");n&&Symbol.for(\"react.scope\");var A=\"function\"===typeof Symbol&&Symbol.iterator;\nfunction B(a){for(var b=\"https://reactjs.org/docs/error-decoder.html?invariant=\"+a,c=1;cP.length&&P.push(a)}\nfunction S(a,b,c,e){var d=typeof a;if(\"undefined\"===d||\"boolean\"===d)a=null;var g=!1;if(null===a)g=!0;else switch(d){case \"string\":case \"number\":g=!0;break;case \"object\":switch(a.$$typeof){case p:case q:g=!0}}if(g)return c(e,a,\"\"===b?\".\"+T(a,0):b),1;g=0;b=\"\"===b?\".\":b+\":\";if(Array.isArray(a))for(var l=0;lb}return!1}function B(a,b,c,d,e,f){this.acceptsBooleans=2===b||3===b||4===b;this.attributeName=d;this.attributeNamespace=e;this.mustUseProperty=c;this.propertyName=a;this.type=b;this.sanitizeURL=f}var D={};\n\"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style\".split(\" \").forEach(function(a){D[a]=new B(a,0,!1,a,null,!1)});[[\"acceptCharset\",\"accept-charset\"],[\"className\",\"class\"],[\"htmlFor\",\"for\"],[\"httpEquiv\",\"http-equiv\"]].forEach(function(a){var b=a[0];D[b]=new B(b,1,!1,a[1],null,!1)});[\"contentEditable\",\"draggable\",\"spellCheck\",\"value\"].forEach(function(a){D[a]=new B(a,2,!1,a.toLowerCase(),null,!1)});\n[\"autoReverse\",\"externalResourcesRequired\",\"focusable\",\"preserveAlpha\"].forEach(function(a){D[a]=new B(a,2,!1,a,null,!1)});\"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope\".split(\" \").forEach(function(a){D[a]=new B(a,3,!1,a.toLowerCase(),null,!1)});\n[\"checked\",\"multiple\",\"muted\",\"selected\"].forEach(function(a){D[a]=new B(a,3,!0,a,null,!1)});[\"capture\",\"download\"].forEach(function(a){D[a]=new B(a,4,!1,a,null,!1)});[\"cols\",\"rows\",\"size\",\"span\"].forEach(function(a){D[a]=new B(a,6,!1,a,null,!1)});[\"rowSpan\",\"start\"].forEach(function(a){D[a]=new B(a,5,!1,a.toLowerCase(),null,!1)});var sb=/[\\-:]([a-z])/g;function tb(a){return a[1].toUpperCase()}\n\"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height\".split(\" \").forEach(function(a){var b=a.replace(sb,\ntb);D[b]=new B(b,1,!1,a,null,!1)});\"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type\".split(\" \").forEach(function(a){var b=a.replace(sb,tb);D[b]=new B(b,1,!1,a,\"http://www.w3.org/1999/xlink\",!1)});[\"xml:base\",\"xml:lang\",\"xml:space\"].forEach(function(a){var b=a.replace(sb,tb);D[b]=new B(b,1,!1,a,\"http://www.w3.org/XML/1998/namespace\",!1)});[\"tabIndex\",\"crossOrigin\"].forEach(function(a){D[a]=new B(a,1,!1,a.toLowerCase(),null,!1)});\nD.xlinkHref=new B(\"xlinkHref\",1,!1,\"xlink:href\",\"http://www.w3.org/1999/xlink\",!0);[\"src\",\"href\",\"action\",\"formAction\"].forEach(function(a){D[a]=new B(a,1,!1,a.toLowerCase(),null,!0)});function ub(a){switch(typeof a){case \"boolean\":case \"number\":case \"object\":case \"string\":case \"undefined\":return a;default:return\"\"}}\nfunction vb(a,b,c,d){var e=D.hasOwnProperty(b)?D[b]:null;var f=null!==e?0===e.type:d?!1:!(2=b.length))throw Error(u(93));b=b[0]}c=b}null==c&&(c=\"\")}a._wrapperState={initialValue:ub(c)}}\nfunction Mb(a,b){var c=ub(b.value),d=ub(b.defaultValue);null!=c&&(c=\"\"+c,c!==a.value&&(a.value=c),null==b.defaultValue&&a.defaultValue!==c&&(a.defaultValue=c));null!=d&&(a.defaultValue=\"\"+d)}function Nb(a){var b=a.textContent;b===a._wrapperState.initialValue&&\"\"!==b&&null!==b&&(a.value=b)}var Ob={html:\"http://www.w3.org/1999/xhtml\",mathml:\"http://www.w3.org/1998/Math/MathML\",svg:\"http://www.w3.org/2000/svg\"};\nfunction Pb(a){switch(a){case \"svg\":return\"http://www.w3.org/2000/svg\";case \"math\":return\"http://www.w3.org/1998/Math/MathML\";default:return\"http://www.w3.org/1999/xhtml\"}}function Qb(a,b){return null==a||\"http://www.w3.org/1999/xhtml\"===a?Pb(b):\"http://www.w3.org/2000/svg\"===a&&\"foreignObject\"===b?\"http://www.w3.org/1999/xhtml\":a}\nvar Rb,Sb=function(a){return\"undefined\"!==typeof MSApp&&MSApp.execUnsafeLocalFunction?function(b,c,d,e){MSApp.execUnsafeLocalFunction(function(){return a(b,c,d,e)})}:a}(function(a,b){if(a.namespaceURI!==Ob.svg||\"innerHTML\"in a)a.innerHTML=b;else{Rb=Rb||document.createElement(\"div\");Rb.innerHTML=\"\"+b.valueOf().toString()+\"\";for(b=Rb.firstChild;a.firstChild;)a.removeChild(a.firstChild);for(;b.firstChild;)a.appendChild(b.firstChild)}});\nfunction Tb(a,b){if(b){var c=a.firstChild;if(c&&c===a.lastChild&&3===c.nodeType){c.nodeValue=b;return}}a.textContent=b}function Ub(a,b){var c={};c[a.toLowerCase()]=b.toLowerCase();c[\"Webkit\"+a]=\"webkit\"+b;c[\"Moz\"+a]=\"moz\"+b;return c}var Vb={animationend:Ub(\"Animation\",\"AnimationEnd\"),animationiteration:Ub(\"Animation\",\"AnimationIteration\"),animationstart:Ub(\"Animation\",\"AnimationStart\"),transitionend:Ub(\"Transition\",\"TransitionEnd\")},Wb={},Xb={};\nYa&&(Xb=document.createElement(\"div\").style,\"AnimationEvent\"in window||(delete Vb.animationend.animation,delete Vb.animationiteration.animation,delete Vb.animationstart.animation),\"TransitionEvent\"in window||delete Vb.transitionend.transition);function Yb(a){if(Wb[a])return Wb[a];if(!Vb[a])return a;var b=Vb[a],c;for(c in b)if(b.hasOwnProperty(c)&&c in Xb)return Wb[a]=b[c];return a}var Zb=Yb(\"animationend\"),$b=Yb(\"animationiteration\"),ac=Yb(\"animationstart\"),bc=Yb(\"transitionend\"),cc=\"abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange seeked seeking stalled suspend timeupdate volumechange waiting\".split(\" \");\nfunction ec(a){var b=a,c=a;if(a.alternate)for(;b.return;)b=b.return;else{a=b;do b=a,0!==(b.effectTag&1026)&&(c=b.return),a=b.return;while(a)}return 3===b.tag?c:null}function fc(a){if(13===a.tag){var b=a.memoizedState;null===b&&(a=a.alternate,null!==a&&(b=a.memoizedState));if(null!==b)return b.dehydrated}return null}function gc(a){if(ec(a)!==a)throw Error(u(188));}\nfunction hc(a){var b=a.alternate;if(!b){b=ec(a);if(null===b)throw Error(u(188));return b!==a?null:a}for(var c=a,d=b;;){var e=c.return;if(null===e)break;var f=e.alternate;if(null===f){d=e.return;if(null!==d){c=d;continue}break}if(e.child===f.child){for(f=e.child;f;){if(f===c)return gc(e),a;if(f===d)return gc(e),b;f=f.sibling}throw Error(u(188));}if(c.return!==d.return)c=e,d=f;else{for(var g=!1,h=e.child;h;){if(h===c){g=!0;c=e;d=f;break}if(h===d){g=!0;d=e;c=f;break}h=h.sibling}if(!g){for(h=f.child;h;){if(h===\nc){g=!0;c=f;d=e;break}if(h===d){g=!0;d=f;c=e;break}h=h.sibling}if(!g)throw Error(u(189));}}if(c.alternate!==d)throw Error(u(190));}if(3!==c.tag)throw Error(u(188));return c.stateNode.current===c?a:b}function ic(a){a=hc(a);if(!a)return null;for(var b=a;;){if(5===b.tag||6===b.tag)return b;if(b.child)b.child.return=b,b=b.child;else{if(b===a)break;for(;!b.sibling;){if(!b.return||b.return===a)return null;b=b.return}b.sibling.return=b.return;b=b.sibling}}return null}\nvar jc,kc,lc,mc=!1,nc=[],oc=null,pc=null,qc=null,rc=new Map,sc=new Map,tc=[],uc=\"mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput close cancel copy cut paste click change contextmenu reset submit\".split(\" \"),vc=\"focus blur dragenter dragleave mouseover mouseout pointerover pointerout gotpointercapture lostpointercapture\".split(\" \");\nfunction wc(a){var b=xc(a);uc.forEach(function(c){yc(c,a,b)});vc.forEach(function(c){yc(c,a,b)})}function zc(a,b,c,d){return{blockedOn:a,topLevelType:b,eventSystemFlags:c|32,nativeEvent:d}}function Ac(a,b){switch(a){case \"focus\":case \"blur\":oc=null;break;case \"dragenter\":case \"dragleave\":pc=null;break;case \"mouseover\":case \"mouseout\":qc=null;break;case \"pointerover\":case \"pointerout\":rc.delete(b.pointerId);break;case \"gotpointercapture\":case \"lostpointercapture\":sc.delete(b.pointerId)}}\nfunction Bc(a,b,c,d,e){if(null===a||a.nativeEvent!==e)return a=zc(b,c,d,e),null!==b&&(b=Cc(b),null!==b&&kc(b)),a;a.eventSystemFlags|=d;return a}function Dc(a,b,c,d){switch(b){case \"focus\":return oc=Bc(oc,a,b,c,d),!0;case \"dragenter\":return pc=Bc(pc,a,b,c,d),!0;case \"mouseover\":return qc=Bc(qc,a,b,c,d),!0;case \"pointerover\":var e=d.pointerId;rc.set(e,Bc(rc.get(e)||null,a,b,c,d));return!0;case \"gotpointercapture\":return e=d.pointerId,sc.set(e,Bc(sc.get(e)||null,a,b,c,d)),!0}return!1}\nfunction Ec(a){var b=Fc(a.target);if(null!==b){var c=ec(b);if(null!==c)if(b=c.tag,13===b){if(b=fc(c),null!==b){a.blockedOn=b;q.unstable_runWithPriority(a.priority,function(){lc(c)});return}}else if(3===b&&c.stateNode.hydrate){a.blockedOn=3===c.tag?c.stateNode.containerInfo:null;return}}a.blockedOn=null}function Gc(a){if(null!==a.blockedOn)return!1;var b=Hc(a.topLevelType,a.eventSystemFlags,a.nativeEvent);if(null!==b){var c=Cc(b);null!==c&&kc(c);a.blockedOn=b;return!1}return!0}\nfunction Ic(a,b,c){Gc(a)&&c.delete(b)}function Jc(){for(mc=!1;0this.eventPool.length&&this.eventPool.push(a)}function Vc(a){a.eventPool=[];a.getPooled=Wc;a.release=Xc}var Yc=E.extend({animationName:null,elapsedTime:null,pseudoElement:null}),Zc=E.extend({clipboardData:function(a){return\"clipboardData\"in a?a.clipboardData:window.clipboardData}}),$c=E.extend({view:null,detail:null}),ad=$c.extend({relatedTarget:null});\nfunction bd(a){var b=a.keyCode;\"charCode\"in a?(a=a.charCode,0===a&&13===b&&(a=13)):a=b;10===a&&(a=13);return 32<=a||13===a?a:0}\nvar cd={Esc:\"Escape\",Spacebar:\" \",Left:\"ArrowLeft\",Up:\"ArrowUp\",Right:\"ArrowRight\",Down:\"ArrowDown\",Del:\"Delete\",Win:\"OS\",Menu:\"ContextMenu\",Apps:\"ContextMenu\",Scroll:\"ScrollLock\",MozPrintableKey:\"Unidentified\"},dd={8:\"Backspace\",9:\"Tab\",12:\"Clear\",13:\"Enter\",16:\"Shift\",17:\"Control\",18:\"Alt\",19:\"Pause\",20:\"CapsLock\",27:\"Escape\",32:\" \",33:\"PageUp\",34:\"PageDown\",35:\"End\",36:\"Home\",37:\"ArrowLeft\",38:\"ArrowUp\",39:\"ArrowRight\",40:\"ArrowDown\",45:\"Insert\",46:\"Delete\",112:\"F1\",113:\"F2\",114:\"F3\",115:\"F4\",\n116:\"F5\",117:\"F6\",118:\"F7\",119:\"F8\",120:\"F9\",121:\"F10\",122:\"F11\",123:\"F12\",144:\"NumLock\",145:\"ScrollLock\",224:\"Meta\"},ed={Alt:\"altKey\",Control:\"ctrlKey\",Meta:\"metaKey\",Shift:\"shiftKey\"};function gd(a){var b=this.nativeEvent;return b.getModifierState?b.getModifierState(a):(a=ed[a])?!!b[a]:!1}function hd(){return gd}\nvar id=$c.extend({key:function(a){if(a.key){var b=cd[a.key]||a.key;if(\"Unidentified\"!==b)return b}return\"keypress\"===a.type?(a=bd(a),13===a?\"Enter\":String.fromCharCode(a)):\"keydown\"===a.type||\"keyup\"===a.type?dd[a.keyCode]||\"Unidentified\":\"\"},location:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,repeat:null,locale:null,getModifierState:hd,charCode:function(a){return\"keypress\"===a.type?bd(a):0},keyCode:function(a){return\"keydown\"===a.type||\"keyup\"===a.type?a.keyCode:0},which:function(a){return\"keypress\"===\na.type?bd(a):\"keydown\"===a.type||\"keyup\"===a.type?a.keyCode:0}}),jd=0,kd=0,ld=!1,md=!1,nd=$c.extend({screenX:null,screenY:null,clientX:null,clientY:null,pageX:null,pageY:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,getModifierState:hd,button:null,buttons:null,relatedTarget:function(a){return a.relatedTarget||(a.fromElement===a.srcElement?a.toElement:a.fromElement)},movementX:function(a){if(\"movementX\"in a)return a.movementX;var b=jd;jd=a.screenX;return ld?\"mousemove\"===a.type?a.screenX-\nb:0:(ld=!0,0)},movementY:function(a){if(\"movementY\"in a)return a.movementY;var b=kd;kd=a.screenY;return md?\"mousemove\"===a.type?a.screenY-b:0:(md=!0,0)}}),od=nd.extend({pointerId:null,width:null,height:null,pressure:null,tangentialPressure:null,tiltX:null,tiltY:null,twist:null,pointerType:null,isPrimary:null}),pd=nd.extend({dataTransfer:null}),qd=$c.extend({touches:null,targetTouches:null,changedTouches:null,altKey:null,metaKey:null,ctrlKey:null,shiftKey:null,getModifierState:hd}),rd=E.extend({propertyName:null,\nelapsedTime:null,pseudoElement:null}),sd=nd.extend({deltaX:function(a){return\"deltaX\"in a?a.deltaX:\"wheelDeltaX\"in a?-a.wheelDeltaX:0},deltaY:function(a){return\"deltaY\"in a?a.deltaY:\"wheelDeltaY\"in a?-a.wheelDeltaY:\"wheelDelta\"in a?-a.wheelDelta:0},deltaZ:null,deltaMode:null}),td=[[\"blur\",\"blur\",0],[\"cancel\",\"cancel\",0],[\"click\",\"click\",0],[\"close\",\"close\",0],[\"contextmenu\",\"contextMenu\",0],[\"copy\",\"copy\",0],[\"cut\",\"cut\",0],[\"auxclick\",\"auxClick\",0],[\"dblclick\",\"doubleClick\",0],[\"dragend\",\"dragEnd\",\n0],[\"dragstart\",\"dragStart\",0],[\"drop\",\"drop\",0],[\"focus\",\"focus\",0],[\"input\",\"input\",0],[\"invalid\",\"invalid\",0],[\"keydown\",\"keyDown\",0],[\"keypress\",\"keyPress\",0],[\"keyup\",\"keyUp\",0],[\"mousedown\",\"mouseDown\",0],[\"mouseup\",\"mouseUp\",0],[\"paste\",\"paste\",0],[\"pause\",\"pause\",0],[\"play\",\"play\",0],[\"pointercancel\",\"pointerCancel\",0],[\"pointerdown\",\"pointerDown\",0],[\"pointerup\",\"pointerUp\",0],[\"ratechange\",\"rateChange\",0],[\"reset\",\"reset\",0],[\"seeked\",\"seeked\",0],[\"submit\",\"submit\",0],[\"touchcancel\",\"touchCancel\",\n0],[\"touchend\",\"touchEnd\",0],[\"touchstart\",\"touchStart\",0],[\"volumechange\",\"volumeChange\",0],[\"drag\",\"drag\",1],[\"dragenter\",\"dragEnter\",1],[\"dragexit\",\"dragExit\",1],[\"dragleave\",\"dragLeave\",1],[\"dragover\",\"dragOver\",1],[\"mousemove\",\"mouseMove\",1],[\"mouseout\",\"mouseOut\",1],[\"mouseover\",\"mouseOver\",1],[\"pointermove\",\"pointerMove\",1],[\"pointerout\",\"pointerOut\",1],[\"pointerover\",\"pointerOver\",1],[\"scroll\",\"scroll\",1],[\"toggle\",\"toggle\",1],[\"touchmove\",\"touchMove\",1],[\"wheel\",\"wheel\",1],[\"abort\",\"abort\",\n2],[Zb,\"animationEnd\",2],[$b,\"animationIteration\",2],[ac,\"animationStart\",2],[\"canplay\",\"canPlay\",2],[\"canplaythrough\",\"canPlayThrough\",2],[\"durationchange\",\"durationChange\",2],[\"emptied\",\"emptied\",2],[\"encrypted\",\"encrypted\",2],[\"ended\",\"ended\",2],[\"error\",\"error\",2],[\"gotpointercapture\",\"gotPointerCapture\",2],[\"load\",\"load\",2],[\"loadeddata\",\"loadedData\",2],[\"loadedmetadata\",\"loadedMetadata\",2],[\"loadstart\",\"loadStart\",2],[\"lostpointercapture\",\"lostPointerCapture\",2],[\"playing\",\"playing\",2],[\"progress\",\n\"progress\",2],[\"seeking\",\"seeking\",2],[\"stalled\",\"stalled\",2],[\"suspend\",\"suspend\",2],[\"timeupdate\",\"timeUpdate\",2],[bc,\"transitionEnd\",2],[\"waiting\",\"waiting\",2]],ud={},vd={},wd=0;for(;wd=b)return{node:c,offset:b-a};a=d}a:{for(;c;){if(c.nextSibling){c=c.nextSibling;break a}c=c.parentNode}c=void 0}c=ce(c)}}\nfunction ee(a,b){return a&&b?a===b?!0:a&&3===a.nodeType?!1:b&&3===b.nodeType?ee(a,b.parentNode):\"contains\"in a?a.contains(b):a.compareDocumentPosition?!!(a.compareDocumentPosition(b)&16):!1:!1}function fe(){for(var a=window,b=be();b instanceof a.HTMLIFrameElement;){try{var c=\"string\"===typeof b.contentWindow.location.href}catch(d){c=!1}if(c)a=b.contentWindow;else break;b=be(a.document)}return b}\nfunction ge(a){var b=a&&a.nodeName&&a.nodeName.toLowerCase();return b&&(\"input\"===b&&(\"text\"===a.type||\"search\"===a.type||\"tel\"===a.type||\"url\"===a.type||\"password\"===a.type)||\"textarea\"===b||\"true\"===a.contentEditable)}var he=\"$\",ie=\"/$\",je=\"$?\",ke=\"$!\",le=null,me=null;function ne(a,b){switch(a){case \"button\":case \"input\":case \"select\":case \"textarea\":return!!b.autoFocus}return!1}\nfunction oe(a,b){return\"textarea\"===a||\"option\"===a||\"noscript\"===a||\"string\"===typeof b.children||\"number\"===typeof b.children||\"object\"===typeof b.dangerouslySetInnerHTML&&null!==b.dangerouslySetInnerHTML&&null!=b.dangerouslySetInnerHTML.__html}var pe=\"function\"===typeof setTimeout?setTimeout:void 0,qe=\"function\"===typeof clearTimeout?clearTimeout:void 0;function re(a){for(;null!=a;a=a.nextSibling){var b=a.nodeType;if(1===b||3===b)break}return a}\nfunction se(a){a=a.previousSibling;for(var b=0;a;){if(8===a.nodeType){var c=a.data;if(c===he||c===ke||c===je){if(0===b)return a;b--}else c===ie&&b++}a=a.previousSibling}return null}var te=Math.random().toString(36).slice(2),ue=\"__reactInternalInstance$\"+te,ve=\"__reactEventHandlers$\"+te,we=\"__reactContainere$\"+te;\nfunction Fc(a){var b=a[ue];if(b)return b;for(var c=a.parentNode;c;){if(b=c[we]||c[ue]){c=b.alternate;if(null!==b.child||null!==c&&null!==c.child)for(a=se(a);null!==a;){if(c=a[ue])return c;a=se(a)}return b}a=c;c=a.parentNode}return null}function Cc(a){a=a[ue]||a[we];return!a||5!==a.tag&&6!==a.tag&&13!==a.tag&&3!==a.tag?null:a}function xe(a){if(5===a.tag||6===a.tag)return a.stateNode;throw Error(u(33));}function ye(a){return a[ve]||null}var ze=null,Ae=null,Be=null;\nfunction Ce(){if(Be)return Be;var a,b=Ae,c=b.length,d,e=\"value\"in ze?ze.value:ze.textContent,f=e.length;for(a=0;a=He),Ke=String.fromCharCode(32),Le={beforeInput:{phasedRegistrationNames:{bubbled:\"onBeforeInput\",captured:\"onBeforeInputCapture\"},dependencies:[\"compositionend\",\"keypress\",\"textInput\",\"paste\"]},compositionEnd:{phasedRegistrationNames:{bubbled:\"onCompositionEnd\",captured:\"onCompositionEndCapture\"},dependencies:\"blur compositionend keydown keypress keyup mousedown\".split(\" \")},compositionStart:{phasedRegistrationNames:{bubbled:\"onCompositionStart\",\ncaptured:\"onCompositionStartCapture\"},dependencies:\"blur compositionstart keydown keypress keyup mousedown\".split(\" \")},compositionUpdate:{phasedRegistrationNames:{bubbled:\"onCompositionUpdate\",captured:\"onCompositionUpdateCapture\"},dependencies:\"blur compositionupdate keydown keypress keyup mousedown\".split(\" \")}},Me=!1;\nfunction Ne(a,b){switch(a){case \"keyup\":return-1!==Fe.indexOf(b.keyCode);case \"keydown\":return 229!==b.keyCode;case \"keypress\":case \"mousedown\":case \"blur\":return!0;default:return!1}}function Oe(a){a=a.detail;return\"object\"===typeof a&&\"data\"in a?a.data:null}var Pe=!1;function Qe(a,b){switch(a){case \"compositionend\":return Oe(b);case \"keypress\":if(32!==b.which)return null;Me=!0;return Ke;case \"textInput\":return a=b.data,a===Ke&&Me?null:a;default:return null}}\nfunction Re(a,b){if(Pe)return\"compositionend\"===a||!Ge&&Ne(a,b)?(a=Ce(),Be=Ae=ze=null,Pe=!1,a):null;switch(a){case \"paste\":return null;case \"keypress\":if(!(b.ctrlKey||b.altKey||b.metaKey)||b.ctrlKey&&b.altKey){if(b.char&&1=document.documentMode,sf={select:{phasedRegistrationNames:{bubbled:\"onSelect\",captured:\"onSelectCapture\"},dependencies:\"blur contextmenu dragend focus keydown keyup mousedown mouseup selectionchange\".split(\" \")}},tf=null,uf=null,vf=null,wf=!1;\nfunction xf(a,b){var c=b.window===b?b.document:9===b.nodeType?b:b.ownerDocument;if(wf||null==tf||tf!==be(c))return null;c=tf;\"selectionStart\"in c&&ge(c)?c={start:c.selectionStart,end:c.selectionEnd}:(c=(c.ownerDocument&&c.ownerDocument.defaultView||window).getSelection(),c={anchorNode:c.anchorNode,anchorOffset:c.anchorOffset,focusNode:c.focusNode,focusOffset:c.focusOffset});return vf&&qf(vf,c)?null:(vf=c,a=E.getPooled(sf.select,uf,a,b),a.type=\"select\",a.target=tf,Sc(a),a)}\nvar yf={eventTypes:sf,extractEvents:function(a,b,c,d){var e=d.window===d?d.document:9===d.nodeType?d:d.ownerDocument,f;if(!(f=!e)){a:{e=xc(e);f=ja.onSelect;for(var g=0;gBf||(a.current=Af[Bf],Af[Bf]=null,Bf--)}\nfunction I(a,b){Bf++;Af[Bf]=a.current;a.current=b}var Cf={},J={current:Cf},K={current:!1},Df=Cf;function Ef(a,b){var c=a.type.contextTypes;if(!c)return Cf;var d=a.stateNode;if(d&&d.__reactInternalMemoizedUnmaskedChildContext===b)return d.__reactInternalMemoizedMaskedChildContext;var e={},f;for(f in c)e[f]=b[f];d&&(a=a.stateNode,a.__reactInternalMemoizedUnmaskedChildContext=b,a.__reactInternalMemoizedMaskedChildContext=e);return e}function L(a){a=a.childContextTypes;return null!==a&&void 0!==a}\nfunction Ff(a){G(K,a);G(J,a)}function Gf(a){G(K,a);G(J,a)}function Hf(a,b,c){if(J.current!==Cf)throw Error(u(168));I(J,b,a);I(K,c,a)}function If(a,b,c){var d=a.stateNode;a=b.childContextTypes;if(\"function\"!==typeof d.getChildContext)return c;d=d.getChildContext();for(var e in d)if(!(e in a))throw Error(u(108,Wa(b)||\"Unknown\",e));return n({},c,{},d)}function Jf(a){var b=a.stateNode;b=b&&b.__reactInternalMemoizedMergedChildContext||Cf;Df=J.current;I(J,b,a);I(K,K.current,a);return!0}\nfunction Kf(a,b,c){var d=a.stateNode;if(!d)throw Error(u(169));c?(b=If(a,b,Df),d.__reactInternalMemoizedMergedChildContext=b,G(K,a),G(J,a),I(J,b,a)):G(K,a);I(K,c,a)}\nvar Lf=q.unstable_runWithPriority,Mf=q.unstable_scheduleCallback,Nf=q.unstable_cancelCallback,Of=q.unstable_shouldYield,Pf=q.unstable_requestPaint,Qf=q.unstable_now,Rf=q.unstable_getCurrentPriorityLevel,Sf=q.unstable_ImmediatePriority,Tf=q.unstable_UserBlockingPriority,Uf=q.unstable_NormalPriority,Vf=q.unstable_LowPriority,Wf=q.unstable_IdlePriority,Xf={},Yf=void 0!==Pf?Pf:function(){},Zf=null,$f=null,ag=!1,bg=Qf(),cg=1E4>bg?Qf:function(){return Qf()-bg};\nfunction dg(){switch(Rf()){case Sf:return 99;case Tf:return 98;case Uf:return 97;case Vf:return 96;case Wf:return 95;default:throw Error(u(332));}}function eg(a){switch(a){case 99:return Sf;case 98:return Tf;case 97:return Uf;case 96:return Vf;case 95:return Wf;default:throw Error(u(332));}}function fg(a,b){a=eg(a);return Lf(a,b)}function gg(a,b,c){a=eg(a);return Mf(a,b,c)}function hg(a){null===Zf?(Zf=[a],$f=Mf(Sf,ig)):Zf.push(a);return Xf}function jg(){if(null!==$f){var a=$f;$f=null;Nf(a)}ig()}\nfunction ig(){if(!ag&&null!==Zf){ag=!0;var a=0;try{var b=Zf;fg(99,function(){for(;a=b&&(wg=!0),a.firstContext=null)}function xg(a,b){if(qg!==a&&!1!==b&&0!==b){if(\"number\"!==typeof b||1073741823===b)qg=a,b=1073741823;b={context:a,observedBits:b,next:null};if(null===pg){if(null===og)throw Error(u(308));pg=b;og.dependencies={expirationTime:0,firstContext:b,responders:null}}else pg=pg.next=b}return a._currentValue}var yg=!1;\nfunction zg(a){return{baseState:a,firstUpdate:null,lastUpdate:null,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null}}function Ag(a){return{baseState:a.baseState,firstUpdate:a.firstUpdate,lastUpdate:a.lastUpdate,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null}}\nfunction Bg(a,b){return{expirationTime:a,suspenseConfig:b,tag:0,payload:null,callback:null,next:null,nextEffect:null}}function Cg(a,b){null===a.lastUpdate?a.firstUpdate=a.lastUpdate=b:(a.lastUpdate.next=b,a.lastUpdate=b)}\nfunction Dg(a,b){var c=a.alternate;if(null===c){var d=a.updateQueue;var e=null;null===d&&(d=a.updateQueue=zg(a.memoizedState))}else d=a.updateQueue,e=c.updateQueue,null===d?null===e?(d=a.updateQueue=zg(a.memoizedState),e=c.updateQueue=zg(c.memoizedState)):d=a.updateQueue=Ag(e):null===e&&(e=c.updateQueue=Ag(d));null===e||d===e?Cg(d,b):null===d.lastUpdate||null===e.lastUpdate?(Cg(d,b),Cg(e,b)):(Cg(d,b),e.lastUpdate=b)}\nfunction Eg(a,b){var c=a.updateQueue;c=null===c?a.updateQueue=zg(a.memoizedState):Fg(a,c);null===c.lastCapturedUpdate?c.firstCapturedUpdate=c.lastCapturedUpdate=b:(c.lastCapturedUpdate.next=b,c.lastCapturedUpdate=b)}function Fg(a,b){var c=a.alternate;null!==c&&b===c.updateQueue&&(b=a.updateQueue=Ag(b));return b}\nfunction Gg(a,b,c,d,e,f){switch(c.tag){case 1:return a=c.payload,\"function\"===typeof a?a.call(f,d,e):a;case 3:a.effectTag=a.effectTag&-4097|64;case 0:a=c.payload;e=\"function\"===typeof a?a.call(f,d,e):a;if(null===e||void 0===e)break;return n({},d,e);case 2:yg=!0}return d}\nfunction Hg(a,b,c,d,e){yg=!1;b=Fg(a,b);for(var f=b.baseState,g=null,h=0,k=b.firstUpdate,l=f;null!==k;){var m=k.expirationTime;mx?(A=r,r=null):A=r.sibling;var p=y(e,r,h[x],k);if(null===p){null===r&&(r=A);break}a&&\nr&&null===p.alternate&&b(e,r);g=f(p,g,x);null===m?l=p:m.sibling=p;m=p;r=A}if(x===h.length)return c(e,r),l;if(null===r){for(;xx?(A=r,r=null):A=r.sibling;var z=y(e,r,p.value,k);if(null===z){null===r&&(r=A);break}a&&r&&null===z.alternate&&b(e,r);g=f(z,g,x);null===m?l=z:m.sibling=z;m=z;r=A}if(p.done)return c(e,r),l;if(null===r){for(;!p.done;x++,p=h.next())p=C(e,p.value,k),null!==p&&(g=f(p,g,x),null===m?l=p:m.sibling=p,m=p);return l}for(r=d(e,r);!p.done;x++,p=h.next())p=H(r,e,x,p.value,k),null!==p&&(a&&null!==\np.alternate&&r.delete(null===p.key?x:p.key),g=f(p,g,x),null===m?l=p:m.sibling=p,m=p);a&&r.forEach(function(a){return b(e,a)});return l}return function(a,d,f,h){var k=\"object\"===typeof f&&null!==f&&f.type===Ia&&null===f.key;k&&(f=f.props.children);var l=\"object\"===typeof f&&null!==f;if(l)switch(f.$$typeof){case Ga:a:{l=f.key;for(k=d;null!==k;){if(k.key===l)if(7===k.tag?f.type===Ia:k.elementType===f.type){c(a,k.sibling);d=e(k,f.type===Ia?f.props.children:f.props,h);d.ref=Yg(a,k,f);d.return=a;a=d;break a}else{c(a,\nk);break}else b(a,k);k=k.sibling}f.type===Ia?(d=eh(f.props.children,a.mode,h,f.key),d.return=a,a=d):(h=ch(f.type,f.key,f.props,null,a.mode,h),h.ref=Yg(a,d,f),h.return=a,a=h)}return g(a);case Ha:a:{for(k=f.key;null!==d;){if(d.key===k)if(4===d.tag&&d.stateNode.containerInfo===f.containerInfo&&d.stateNode.implementation===f.implementation){c(a,d.sibling);d=e(d,f.children||[],h);d.return=a;a=d;break a}else{c(a,d);break}else b(a,d);d=d.sibling}d=dh(f,a.mode,h);d.return=a;a=d}return g(a)}if(\"string\"===\ntypeof f||\"number\"===typeof f)return f=\"\"+f,null!==d&&6===d.tag?(c(a,d.sibling),d=e(d,f,h),d.return=a,a=d):(c(a,d),d=bh(f,a.mode,h),d.return=a,a=d),g(a);if(Xg(f))return z(a,d,f,h);if(Ua(f))return ta(a,d,f,h);l&&Zg(a,f);if(\"undefined\"===typeof f&&!k)switch(a.tag){case 1:case 0:throw a=a.type,Error(u(152,a.displayName||a.name||\"Component\"));}return c(a,d)}}var fh=$g(!0),gh=$g(!1),hh={},ih={current:hh},jh={current:hh},kh={current:hh};function lh(a){if(a===hh)throw Error(u(174));return a}\nfunction mh(a,b){I(kh,b,a);I(jh,a,a);I(ih,hh,a);var c=b.nodeType;switch(c){case 9:case 11:b=(b=b.documentElement)?b.namespaceURI:Qb(null,\"\");break;default:c=8===c?b.parentNode:b,b=c.namespaceURI||null,c=c.tagName,b=Qb(b,c)}G(ih,a);I(ih,b,a)}function nh(a){G(ih,a);G(jh,a);G(kh,a)}function oh(a){lh(kh.current);var b=lh(ih.current);var c=Qb(b,a.type);b!==c&&(I(jh,a,a),I(ih,c,a))}function ph(a){jh.current===a&&(G(ih,a),G(jh,a))}var M={current:0};\nfunction qh(a){for(var b=a;null!==b;){if(13===b.tag){var c=b.memoizedState;if(null!==c&&(c=c.dehydrated,null===c||c.data===je||c.data===ke))return b}else if(19===b.tag&&void 0!==b.memoizedProps.revealOrder){if(0!==(b.effectTag&64))return b}else if(null!==b.child){b.child.return=b;b=b.child;continue}if(b===a)break;for(;null===b.sibling;){if(null===b.return||b.return===a)return null;b=b.return}b.sibling.return=b.return;b=b.sibling}return null}function rh(a,b){return{responder:a,props:b}}\nvar sh=Ea.ReactCurrentDispatcher,N=Ea.ReactCurrentBatchConfig,th=0,uh=null,O=null,vh=null,wh=null,P=null,xh=null,yh=0,zh=null,Ah=0,Bh=!1,Ch=null,Gh=0;function Q(){throw Error(u(321));}function Hh(a,b){if(null===b)return!1;for(var c=0;cyh&&(yh=m,Jg(yh))):(Ig(m,k.suspenseConfig),f=k.eagerReducer===a?k.eagerState:a(f,k.action));g=k;k=k.next}while(null!==k&&k!==d);l||(h=g,e=f);of(f,b.memoizedState)||(wg=!0);b.memoizedState=f;b.baseUpdate=h;b.baseState=e;c.lastRenderedState=f}return[b.memoizedState,c.dispatch]}\nfunction Rh(a){var b=Nh();\"function\"===typeof a&&(a=a());b.memoizedState=b.baseState=a;a=b.queue={last:null,dispatch:null,lastRenderedReducer:Ph,lastRenderedState:a};a=a.dispatch=Sh.bind(null,uh,a);return[b.memoizedState,a]}function Th(a){return Qh(Ph,a)}function Uh(a,b,c,d){a={tag:a,create:b,destroy:c,deps:d,next:null};null===zh?(zh={lastEffect:null},zh.lastEffect=a.next=a):(b=zh.lastEffect,null===b?zh.lastEffect=a.next=a:(c=b.next,b.next=a,a.next=c,zh.lastEffect=a));return a}\nfunction Vh(a,b,c,d){var e=Nh();Ah|=a;e.memoizedState=Uh(b,c,void 0,void 0===d?null:d)}function Wh(a,b,c,d){var e=Oh();d=void 0===d?null:d;var f=void 0;if(null!==O){var g=O.memoizedState;f=g.destroy;if(null!==d&&Hh(d,g.deps)){Uh(0,c,f,d);return}}Ah|=a;e.memoizedState=Uh(b,c,f,d)}function Xh(a,b){return Vh(516,192,a,b)}function Yh(a,b){return Wh(516,192,a,b)}\nfunction Zh(a,b){if(\"function\"===typeof b)return a=a(),b(a),function(){b(null)};if(null!==b&&void 0!==b)return a=a(),b.current=a,function(){b.current=null}}function $h(){}function ai(a,b){Nh().memoizedState=[a,void 0===b?null:b];return a}function bi(a,b){var c=Oh();b=void 0===b?null:b;var d=c.memoizedState;if(null!==d&&null!==b&&Hh(b,d[1]))return d[0];c.memoizedState=[a,b];return a}\nfunction Sh(a,b,c){if(!(25>Gh))throw Error(u(301));var d=a.alternate;if(a===uh||null!==d&&d===uh)if(Bh=!0,a={expirationTime:th,suspenseConfig:null,action:c,eagerReducer:null,eagerState:null,next:null},null===Ch&&(Ch=new Map),c=Ch.get(b),void 0===c)Ch.set(b,a);else{for(b=c;null!==b.next;)b=b.next;b.next=a}else{var e=Pg(),f=Mg.suspense;e=Qg(e,a,f);f={expirationTime:e,suspenseConfig:f,action:c,eagerReducer:null,eagerState:null,next:null};var g=b.last;if(null===g)f.next=f;else{var h=g.next;null!==h&&\n(f.next=h);g.next=f}b.last=f;if(0===a.expirationTime&&(null===d||0===d.expirationTime)&&(d=b.lastRenderedReducer,null!==d))try{var k=b.lastRenderedState,l=d(k,c);f.eagerReducer=d;f.eagerState=l;if(of(l,k))return}catch(m){}finally{}Rg(a,e)}}\nvar Lh={readContext:xg,useCallback:Q,useContext:Q,useEffect:Q,useImperativeHandle:Q,useLayoutEffect:Q,useMemo:Q,useReducer:Q,useRef:Q,useState:Q,useDebugValue:Q,useResponder:Q,useDeferredValue:Q,useTransition:Q},Jh={readContext:xg,useCallback:ai,useContext:xg,useEffect:Xh,useImperativeHandle:function(a,b,c){c=null!==c&&void 0!==c?c.concat([a]):null;return Vh(4,36,Zh.bind(null,b,a),c)},useLayoutEffect:function(a,b){return Vh(4,36,a,b)},useMemo:function(a,b){var c=Nh();b=void 0===b?null:b;a=a();c.memoizedState=\n[a,b];return a},useReducer:function(a,b,c){var d=Nh();b=void 0!==c?c(b):b;d.memoizedState=d.baseState=b;a=d.queue={last:null,dispatch:null,lastRenderedReducer:a,lastRenderedState:b};a=a.dispatch=Sh.bind(null,uh,a);return[d.memoizedState,a]},useRef:function(a){var b=Nh();a={current:a};return b.memoizedState=a},useState:Rh,useDebugValue:$h,useResponder:rh,useDeferredValue:function(a,b){var c=Rh(a),d=c[0],e=c[1];Xh(function(){q.unstable_next(function(){var c=N.suspense;N.suspense=void 0===b?null:b;try{e(a)}finally{N.suspense=\nc}})},[a,b]);return d},useTransition:function(a){var b=Rh(!1),c=b[0],d=b[1];return[ai(function(b){d(!0);q.unstable_next(function(){var c=N.suspense;N.suspense=void 0===a?null:a;try{d(!1),b()}finally{N.suspense=c}})},[a,c]),c]}},Kh={readContext:xg,useCallback:bi,useContext:xg,useEffect:Yh,useImperativeHandle:function(a,b,c){c=null!==c&&void 0!==c?c.concat([a]):null;return Wh(4,36,Zh.bind(null,b,a),c)},useLayoutEffect:function(a,b){return Wh(4,36,a,b)},useMemo:function(a,b){var c=Oh();b=void 0===b?\nnull:b;var d=c.memoizedState;if(null!==d&&null!==b&&Hh(b,d[1]))return d[0];a=a();c.memoizedState=[a,b];return a},useReducer:Qh,useRef:function(){return Oh().memoizedState},useState:Th,useDebugValue:$h,useResponder:rh,useDeferredValue:function(a,b){var c=Th(a),d=c[0],e=c[1];Yh(function(){q.unstable_next(function(){var c=N.suspense;N.suspense=void 0===b?null:b;try{e(a)}finally{N.suspense=c}})},[a,b]);return d},useTransition:function(a){var b=Th(!1),c=b[0],d=b[1];return[bi(function(b){d(!0);q.unstable_next(function(){var c=\nN.suspense;N.suspense=void 0===a?null:a;try{d(!1),b()}finally{N.suspense=c}})},[a,c]),c]}},ci=null,di=null,ei=!1;function fi(a,b){var c=gi(5,null,null,0);c.elementType=\"DELETED\";c.type=\"DELETED\";c.stateNode=b;c.return=a;c.effectTag=8;null!==a.lastEffect?(a.lastEffect.nextEffect=c,a.lastEffect=c):a.firstEffect=a.lastEffect=c}\nfunction hi(a,b){switch(a.tag){case 5:var c=a.type;b=1!==b.nodeType||c.toLowerCase()!==b.nodeName.toLowerCase()?null:b;return null!==b?(a.stateNode=b,!0):!1;case 6:return b=\"\"===a.pendingProps||3!==b.nodeType?null:b,null!==b?(a.stateNode=b,!0):!1;case 13:return!1;default:return!1}}\nfunction ii(a){if(ei){var b=di;if(b){var c=b;if(!hi(a,b)){b=re(c.nextSibling);if(!b||!hi(a,b)){a.effectTag=a.effectTag&-1025|2;ei=!1;ci=a;return}fi(ci,c)}ci=a;di=re(b.firstChild)}else a.effectTag=a.effectTag&-1025|2,ei=!1,ci=a}}function ji(a){for(a=a.return;null!==a&&5!==a.tag&&3!==a.tag&&13!==a.tag;)a=a.return;ci=a}\nfunction ki(a){if(a!==ci)return!1;if(!ei)return ji(a),ei=!0,!1;var b=a.type;if(5!==a.tag||\"head\"!==b&&\"body\"!==b&&!oe(b,a.memoizedProps))for(b=di;b;)fi(a,b),b=re(b.nextSibling);ji(a);if(13===a.tag){a=a.memoizedState;a=null!==a?a.dehydrated:null;if(!a)throw Error(u(317));a:{a=a.nextSibling;for(b=0;a;){if(8===a.nodeType){var c=a.data;if(c===ie){if(0===b){di=re(a.nextSibling);break a}b--}else c!==he&&c!==ke&&c!==je||b++}a=a.nextSibling}di=null}}else di=ci?re(a.stateNode.nextSibling):null;return!0}\nfunction li(){di=ci=null;ei=!1}var mi=Ea.ReactCurrentOwner,wg=!1;function R(a,b,c,d){b.child=null===a?gh(b,null,c,d):fh(b,a.child,c,d)}function ni(a,b,c,d,e){c=c.render;var f=b.ref;vg(b,e);d=Ih(a,b,c,d,f,e);if(null!==a&&!wg)return b.updateQueue=a.updateQueue,b.effectTag&=-517,a.expirationTime<=e&&(a.expirationTime=0),oi(a,b,e);b.effectTag|=1;R(a,b,d,e);return b.child}\nfunction pi(a,b,c,d,e,f){if(null===a){var g=c.type;if(\"function\"===typeof g&&!qi(g)&&void 0===g.defaultProps&&null===c.compare&&void 0===c.defaultProps)return b.tag=15,b.type=g,ri(a,b,g,d,e,f);a=ch(c.type,null,d,null,b.mode,f);a.ref=b.ref;a.return=b;return b.child=a}g=a.child;if(eb)&&Gj.set(a,b)))}}\nfunction Kj(a,b){a.expirationTimea?b:a}\nfunction Z(a){if(0!==a.lastExpiredTime)a.callbackExpirationTime=1073741823,a.callbackPriority=99,a.callbackNode=hg(Lj.bind(null,a));else{var b=Oj(a),c=a.callbackNode;if(0===b)null!==c&&(a.callbackNode=null,a.callbackExpirationTime=0,a.callbackPriority=90);else{var d=Pg();1073741823===b?d=99:1===b||2===b?d=95:(d=10*(1073741821-b)-10*(1073741821-d),d=0>=d?99:250>=d?98:5250>=d?97:95);if(null!==c){var e=a.callbackPriority;if(a.callbackExpirationTime===b&&e>=d)return;c!==Xf&&Nf(c)}a.callbackExpirationTime=\nb;a.callbackPriority=d;b=1073741823===b?hg(Lj.bind(null,a)):gg(d,Qj.bind(null,a),{timeout:10*(1073741821-b)-cg()});a.callbackNode=b}}}\nfunction Qj(a,b){Jj=0;if(b)return b=Pg(),Rj(a,b),Z(a),null;var c=Oj(a);if(0!==c){b=a.callbackNode;if((T&(oj|pj))!==S)throw Error(u(327));Sj();a===U&&c===W||Tj(a,c);if(null!==V){var d=T;T|=oj;var e=Uj(a);do try{Vj();break}catch(h){Wj(a,h)}while(1);rg();T=d;lj.current=e;if(X===rj)throw b=wj,Tj(a,c),Mj(a,c),Z(a),b;if(null===V)switch(e=a.finishedWork=a.current.alternate,a.finishedExpirationTime=c,d=X,U=null,d){case qj:case rj:throw Error(u(345));case sj:Rj(a,2=c){a.lastPingedTime=c;Tj(a,c);break}}f=Oj(a);if(0!==f&&f!==c)break;if(0!==d&&d!==c){a.lastPingedTime=d;break}a.timeoutHandle=pe(Yj.bind(null,a),e);break}Yj(a);break;case uj:Mj(a,c);d=a.lastSuspendedTime;c===d&&(a.nextKnownPendingLevel=Xj(e));if(Bj&&(e=a.lastPingedTime,0===e||e>=c)){a.lastPingedTime=c;Tj(a,c);break}e=Oj(a);if(0!==e&&e!==c)break;if(0!==d&&d!==c){a.lastPingedTime=\nd;break}1073741823!==yj?d=10*(1073741821-yj)-cg():1073741823===xj?d=0:(d=10*(1073741821-xj)-5E3,e=cg(),c=10*(1073741821-c)-e,d=e-d,0>d&&(d=0),d=(120>d?120:480>d?480:1080>d?1080:1920>d?1920:3E3>d?3E3:4320>d?4320:1960*kj(d/1960))-d,c=d?d=0:(e=g.busyDelayMs|0,f=cg()-(10*(1073741821-f)-(g.timeoutMs|0||5E3)),d=f<=e?0:e+d-f);if(10 component higher in the tree to provide a loading indicator or placeholder to display.\"+Xa(e))}X!==vj&&(X=sj);f=Ni(f,e);k=d;do{switch(k.tag){case 3:g=f;k.effectTag|=4096;k.expirationTime=b;var x=fj(k,g,b);Eg(k,x);break a;case 1:g=f;var A=k.type,p=k.stateNode;if(0===(k.effectTag&64)&&(\"function\"===typeof A.getDerivedStateFromError||null!==p&&\"function\"===typeof p.componentDidCatch&&\n(null===jj||!jj.has(p)))){k.effectTag|=4096;k.expirationTime=b;var t=ij(k,g,b);Eg(k,t);break a}}k=k.return}while(null!==k)}V=ek(V)}catch(v){b=v;continue}break}while(1)}function Uj(){var a=lj.current;lj.current=Lh;return null===a?Lh:a}function Ig(a,b){aAj&&(Aj=a)}function Zj(){for(;null!==V;)V=fk(V)}function Vj(){for(;null!==V&&!Of();)V=fk(V)}\nfunction fk(a){var b=gk(a.alternate,a,W);a.memoizedProps=a.pendingProps;null===b&&(b=ek(a));mj.current=null;return b}\nfunction ek(a){V=a;do{var b=V.alternate;a=V.return;if(0===(V.effectTag&2048)){a:{var c=b;b=V;var d=W;var e=b.pendingProps;switch(b.tag){case 2:break;case 16:break;case 15:case 0:break;case 1:L(b.type)&&Ff(b);break;case 3:nh(b);Gf(b);e=b.stateNode;e.pendingContext&&(e.context=e.pendingContext,e.pendingContext=null);(null===c||null===c.child)&&ki(b)&&Ci(b);Ii(b);break;case 5:ph(b);d=lh(kh.current);var f=b.type;if(null!==c&&null!=b.stateNode)Ji(c,b,f,e,d),c.ref!==b.ref&&(b.effectTag|=128);else if(e){var g=\nlh(ih.current);if(ki(b)){e=b;var h=e.stateNode;c=e.type;var k=e.memoizedProps,l=d;h[ue]=e;h[ve]=k;f=void 0;d=h;switch(c){case \"iframe\":case \"object\":case \"embed\":F(\"load\",d);break;case \"video\":case \"audio\":for(h=0;h\\x3c/script>\",h=k.removeChild(k.firstChild)):\"string\"===typeof k.is?h=h.createElement(l,{is:k.is}):(h=h.createElement(l),\"select\"===l&&(l=h,k.multiple?l.multiple=!0:k.size&&(l.size=k.size))):h=h.createElementNS(g,l);k=h;k[ue]=c;k[ve]=e;Hi(k,b,!1,!1);b.stateNode=k;l=f;c=e;var m=d,C=Zd(l,c);switch(l){case \"iframe\":case \"object\":case \"embed\":F(\"load\",\nk);d=c;break;case \"video\":case \"audio\":for(d=0;de.tailExpiration&&1f&&(f=c),k>f&&(f=k),d=d.sibling;e.childExpirationTime=f}if(null!==b)return b;null!==a&&0===(a.effectTag&2048)&&(null===a.firstEffect&&(a.firstEffect=V.firstEffect),null!==V.lastEffect&&(null!==a.lastEffect&&(a.lastEffect.nextEffect=\nV.firstEffect),a.lastEffect=V.lastEffect),1a?b:a}function Yj(a){var b=dg();fg(99,ik.bind(null,a,b));return null}\nfunction ik(a,b){do Sj();while(null!==Ej);if((T&(oj|pj))!==S)throw Error(u(327));var c=a.finishedWork,d=a.finishedExpirationTime;if(null===c)return null;a.finishedWork=null;a.finishedExpirationTime=0;if(c===a.current)throw Error(u(177));a.callbackNode=null;a.callbackExpirationTime=0;a.callbackPriority=90;a.nextKnownPendingLevel=0;var e=Xj(c);a.firstPendingTime=e;d<=a.lastSuspendedTime?a.firstSuspendedTime=a.lastSuspendedTime=a.nextKnownPendingLevel=0:d<=a.firstSuspendedTime&&(a.firstSuspendedTime=\nd-1);d<=a.lastPingedTime&&(a.lastPingedTime=0);d<=a.lastExpiredTime&&(a.lastExpiredTime=0);a===U&&(V=U=null,W=0);1h&&(l=h,h=g,g=l),l=de(p,g),m=de(p,h),l&&m&&(1!==v.rangeCount||v.anchorNode!==l.node||v.anchorOffset!==l.offset||v.focusNode!==m.node||v.focusOffset!==m.offset)&&(t=t.createRange(),t.setStart(l.node,l.offset),v.removeAllRanges(),g>h?(v.addRange(t),v.extend(m.node,m.offset)):(t.setEnd(m.node,m.offset),v.addRange(t))))));t=[];for(v=p;v=v.parentNode;)1===v.nodeType&&t.push({element:v,left:v.scrollLeft,top:v.scrollTop});\n\"function\"===typeof p.focus&&p.focus();for(p=0;p=c)return yi(a,b,c);I(M,M.current&\n1,b);b=oi(a,b,c);return null!==b?b.sibling:null}I(M,M.current&1,b);break;case 19:d=b.childExpirationTime>=c;if(0!==(a.effectTag&64)){if(d)return Bi(a,b,c);b.effectTag|=64}e=b.memoizedState;null!==e&&(e.rendering=null,e.tail=null);I(M,M.current,b);if(!d)return null}return oi(a,b,c)}wg=!1}}else wg=!1;b.expirationTime=0;switch(b.tag){case 2:d=b.type;null!==a&&(a.alternate=null,b.alternate=null,b.effectTag|=2);a=b.pendingProps;e=Ef(b,J.current);vg(b,c);e=Ih(null,b,d,a,e,c);b.effectTag|=1;if(\"object\"===\ntypeof e&&null!==e&&\"function\"===typeof e.render&&void 0===e.$$typeof){b.tag=1;Mh();if(L(d)){var f=!0;Jf(b)}else f=!1;b.memoizedState=null!==e.state&&void 0!==e.state?e.state:null;var g=d.getDerivedStateFromProps;\"function\"===typeof g&&Og(b,d,g,a);e.updater=Sg;b.stateNode=e;e._reactInternalFiber=b;Wg(b,d,a,c);b=vi(null,b,d,!0,f,c)}else b.tag=0,R(null,b,e,c),b=b.child;return b;case 16:e=b.elementType;null!==a&&(a.alternate=null,b.alternate=null,b.effectTag|=2);a=b.pendingProps;Va(e);if(1!==e._status)throw e._result;\ne=e._result;b.type=e;f=b.tag=nk(e);a=mg(e,a);switch(f){case 0:b=si(null,b,e,a,c);break;case 1:b=ui(null,b,e,a,c);break;case 11:b=ni(null,b,e,a,c);break;case 14:b=pi(null,b,e,mg(e.type,a),d,c);break;default:throw Error(u(306,e,\"\"));}return b;case 0:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:mg(d,e),si(a,b,d,e,c);case 1:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:mg(d,e),ui(a,b,d,e,c);case 3:wi(b);d=b.updateQueue;if(null===d)throw Error(u(282));e=b.memoizedState;e=null!==e?e.element:\nnull;Hg(b,d,b.pendingProps,null,c);d=b.memoizedState.element;if(d===e)li(),b=oi(a,b,c);else{if(e=b.stateNode.hydrate)di=re(b.stateNode.containerInfo.firstChild),ci=b,e=ei=!0;if(e)for(c=gh(b,null,d,c),b.child=c;c;)c.effectTag=c.effectTag&-3|1024,c=c.sibling;else R(a,b,d,c),li();b=b.child}return b;case 5:return oh(b),null===a&&ii(b),d=b.type,e=b.pendingProps,f=null!==a?a.memoizedProps:null,g=e.children,oe(d,e)?g=null:null!==f&&oe(d,f)&&(b.effectTag|=16),ti(a,b),b.mode&4&&1!==c&&e.hidden?(b.expirationTime=\nb.childExpirationTime=1,b=null):(R(a,b,g,c),b=b.child),b;case 6:return null===a&&ii(b),null;case 13:return yi(a,b,c);case 4:return mh(b,b.stateNode.containerInfo),d=b.pendingProps,null===a?b.child=fh(b,null,d,c):R(a,b,d,c),b.child;case 11:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:mg(d,e),ni(a,b,d,e,c);case 7:return R(a,b,b.pendingProps,c),b.child;case 8:return R(a,b,b.pendingProps.children,c),b.child;case 12:return R(a,b,b.pendingProps.children,c),b.child;case 10:a:{d=b.type._context;\ne=b.pendingProps;g=b.memoizedProps;f=e.value;sg(b,f);if(null!==g){var h=g.value;f=of(h,f)?0:(\"function\"===typeof d._calculateChangedBits?d._calculateChangedBits(h,f):1073741823)|0;if(0===f){if(g.children===e.children&&!K.current){b=oi(a,b,c);break a}}else for(h=b.child,null!==h&&(h.return=b);null!==h;){var k=h.dependencies;if(null!==k){g=h.child;for(var l=k.firstContext;null!==l;){if(l.context===d&&0!==(l.observedBits&f)){1===h.tag&&(l=Bg(c,null),l.tag=2,Dg(h,l));h.expirationTime=b&&a<=b}function Mj(a,b){var c=a.firstSuspendedTime,d=a.lastSuspendedTime;cb||0===c)a.lastSuspendedTime=b;b<=a.lastPingedTime&&(a.lastPingedTime=0);b<=a.lastExpiredTime&&(a.lastExpiredTime=0)}\nfunction Nj(a,b){b>a.firstPendingTime&&(a.firstPendingTime=b);var c=a.firstSuspendedTime;0!==c&&(b>=c?a.firstSuspendedTime=a.lastSuspendedTime=a.nextKnownPendingLevel=0:b>=a.lastSuspendedTime&&(a.lastSuspendedTime=b+1),b>a.nextKnownPendingLevel&&(a.nextKnownPendingLevel=b))}function Rj(a,b){var c=a.lastExpiredTime;if(0===c||c>b)a.lastExpiredTime=b}\nfunction rk(a,b,c,d){var e=b.current,f=Pg(),g=Mg.suspense;f=Qg(f,e,g);a:if(c){c=c._reactInternalFiber;b:{if(ec(c)!==c||1!==c.tag)throw Error(u(170));var h=c;do{switch(h.tag){case 3:h=h.stateNode.context;break b;case 1:if(L(h.type)){h=h.stateNode.__reactInternalMemoizedMergedChildContext;break b}}h=h.return}while(null!==h);throw Error(u(171));}if(1===c.tag){var k=c.type;if(L(k)){c=If(c,k,h);break a}}c=h}else c=Cf;null===b.context?b.context=c:b.pendingContext=c;b=Bg(f,g);b.payload={element:a};d=void 0===\nd?null:d;null!==d&&(b.callback=d);Dg(e,b);Rg(e,f);return f}function sk(a){a=a.current;if(!a.child)return null;switch(a.child.tag){case 5:return a.child.stateNode;default:return a.child.stateNode}}function tk(a,b){a=a.memoizedState;null!==a&&null!==a.dehydrated&&a.retryTime=G};l=function(){};exports.unstable_forceFrameRate=function(a){0>a||125K(n,c))void 0!==r&&0>K(r,n)?(a[d]=r,a[v]=c,d=v):(a[d]=n,a[m]=c,d=m);else if(void 0!==r&&0>K(r,c))a[d]=r,a[v]=c,d=v;else break a}}return b}return null}function K(a,b){var c=a.sortIndex-b.sortIndex;return 0!==c?c:a.id-b.id}var N=[],O=[],P=1,Q=null,R=3,S=!1,T=!1,U=!1;\nfunction V(a){for(var b=L(O);null!==b;){if(null===b.callback)M(O);else if(b.startTime<=a)M(O),b.sortIndex=b.expirationTime,J(N,b);else break;b=L(O)}}function W(a){U=!1;V(a);if(!T)if(null!==L(N))T=!0,f(X);else{var b=L(O);null!==b&&g(W,b.startTime-a)}}\nfunction X(a,b){T=!1;U&&(U=!1,h());S=!0;var c=R;try{V(b);for(Q=L(N);null!==Q&&(!(Q.expirationTime>b)||a&&!k());){var d=Q.callback;if(null!==d){Q.callback=null;R=Q.priorityLevel;var e=d(Q.expirationTime<=b);b=exports.unstable_now();\"function\"===typeof e?Q.callback=e:Q===L(N)&&M(N);V(b)}else M(N);Q=L(N)}if(null!==Q)var m=!0;else{var n=L(O);null!==n&&g(W,n.startTime-b);m=!1}return m}finally{Q=null,R=c,S=!1}}\nfunction Y(a){switch(a){case 1:return-1;case 2:return 250;case 5:return 1073741823;case 4:return 1E4;default:return 5E3}}var Z=l;exports.unstable_ImmediatePriority=1;exports.unstable_UserBlockingPriority=2;exports.unstable_NormalPriority=3;exports.unstable_IdlePriority=5;exports.unstable_LowPriority=4;exports.unstable_runWithPriority=function(a,b){switch(a){case 1:case 2:case 3:case 4:case 5:break;default:a=3}var c=R;R=a;try{return b()}finally{R=c}};\nexports.unstable_next=function(a){switch(R){case 1:case 2:case 3:var b=3;break;default:b=R}var c=R;R=b;try{return a()}finally{R=c}};\nexports.unstable_scheduleCallback=function(a,b,c){var d=exports.unstable_now();if(\"object\"===typeof c&&null!==c){var e=c.delay;e=\"number\"===typeof e&&0d?(a.sortIndex=e,J(O,a),null===L(N)&&a===L(O)&&(U?h():U=!0,g(W,e-d))):(a.sortIndex=c,J(N,a),T||S||(T=!0,f(X)));return a};exports.unstable_cancelCallback=function(a){a.callback=null};\nexports.unstable_wrapCallback=function(a){var b=R;return function(){var c=R;R=b;try{return a.apply(this,arguments)}finally{R=c}}};exports.unstable_getCurrentPriorityLevel=function(){return R};exports.unstable_shouldYield=function(){var a=exports.unstable_now();V(a);var b=L(N);return b!==Q&&null!==Q&&null!==b&&null!==b.callback&&b.startTime<=a&&b.expirationTime 0 && arguments[0] !== undefined ? arguments[0] : {};\n var defaultState = arguments.length > 1 ? arguments[1] : undefined;\n var opts = {\n payload: true,\n fallback: null\n };\n\n var reducer = _extends(reduce, {\n has: has,\n on: on,\n off: off,\n options: options\n });\n\n function has(typeOrActionCreator) {\n return !!handlers[normalizeType(typeOrActionCreator)];\n }\n\n function on(typeOrActionCreator, handler) {\n if (Array.isArray(typeOrActionCreator)) {\n typeOrActionCreator.forEach(function (action) {\n on(action, handler);\n });\n } else {\n handlers[normalizeType(typeOrActionCreator)] = handler;\n }\n\n return reducer;\n }\n\n function off(typeOrActionCreator) {\n if (Array.isArray(typeOrActionCreator)) {\n typeOrActionCreator.forEach(off);\n } else {\n delete handlers[normalizeType(typeOrActionCreator)];\n }\n\n return reducer;\n }\n\n function options(newOpts) {\n Object.keys(newOpts).forEach(function (name) {\n return opts[name] = newOpts[name];\n });\n return reducer;\n }\n\n if (typeof handlers === 'function') {\n var factory = handlers;\n handlers = {};\n factory(on, off);\n }\n\n if (!has(_batch[\"default\"])) {\n on(_batch[\"default\"], function (state, payload) {\n if (opts.payload) {\n return payload.reduce(reduce, state);\n } else {\n return payload.payload.reduce(reduce, state);\n }\n });\n }\n\n function reduce() {\n var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultState;\n var action = arguments.length > 1 ? arguments[1] : undefined;\n\n if (!action || typeof action.type !== 'string') {\n return state;\n }\n\n if (action.type.startsWith('@@redux/')) {\n return state;\n }\n\n var handler = handlers[action.type] || opts.fallback;\n\n if (handler) {\n if (opts.payload) {\n return handler(state, action.payload, action.meta);\n } else {\n return handler(state, action);\n }\n }\n\n return state;\n }\n\n ;\n return reducer;\n}\n\n;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports[\"default\"] = assignAll;\n\nfunction _defineProperty(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; }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction assignAll(actions, stores) {\n if (Array.isArray(actions)) {\n return actions.map(function (action) {\n return action.assignTo(stores);\n });\n }\n\n return Object.keys(actions).reduce(function (assigns, action) {\n return _extends(assigns, _defineProperty({}, action, actions[action].assignTo(stores)));\n }, {});\n}\n\n;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports[\"default\"] = bindAll;\n\nfunction _defineProperty(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; }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction bindAll(actions, stores) {\n if (Array.isArray(actions)) {\n return actions.map(function (action) {\n return action.bindTo(stores);\n });\n }\n\n return Object.keys(actions).reduce(function (binds, action) {\n return _extends(binds, _defineProperty({}, action, actions[action].bindTo(stores)));\n }, {});\n}\n\n;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports[\"default\"] = disbatch;\n\nvar _batch = _interopRequireDefault(require(\"./batch\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction disbatch(store) {\n for (var _len = arguments.length, actions = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n actions[_key - 1] = arguments[_key];\n }\n\n if (actions && actions.length > 0) {\n if (!store || typeof store !== 'function' && typeof store.dispatch !== 'function') {\n throw new TypeError('disbatch must take either a valid Redux store or a dispatch function as first parameter');\n }\n\n if (typeof store.dispatch === 'function') {\n store = store.dispatch;\n } // store is actually the dispatch function here\n\n\n return store(_batch[\"default\"].apply(void 0, actions));\n } else {\n if (!store || typeof store.dispatch !== 'function') {\n throw new TypeError('disbatch must take a valid Redux store with a dispatch function as first parameter');\n }\n\n return _extends(store, {\n disbatch: disbatch.bind(undefined, store)\n });\n }\n}","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports[\"default\"] = void 0;\n\nvar reduxLogger = _interopRequireWildcard(require(\"./reduxLogger\"));\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj[\"default\"] = obj; return newObj; } }\n\nvar _default = {\n reduxLogger: reduxLogger\n};\nexports[\"default\"] = _default;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.actionTransformer = actionTransformer;\nexports.logger = void 0;\n\nvar _batch = _interopRequireDefault(require(\"../batch\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; }\n\nvar batchType = _batch[\"default\"].getType();\n\nfunction actionTransformer(action) {\n if (action && action.type === batchType) {\n action.payload.type = batchType;\n return action.payload;\n }\n\n return action;\n}\n\nvar logger = {};\nexports.logger = logger;\n\nvar _loop = function _loop(level) {\n if (typeof console[level] === 'function') {\n logger[level] = function levelFn() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n var lastArg = args.pop();\n\n if (Array.isArray(lastArg) && lastArg.type === batchType) {\n lastArg.forEach(function (action) {\n console[level].apply(console, [].concat(args, [action]));\n });\n } else {\n args.push(lastArg);\n console[level].apply(console, args);\n }\n };\n }\n};\n\nfor (var level in console) {\n _loop(level);\n}","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports[\"default\"] = asError;\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction asError(action) {\n if (_typeof(action) === 'object' && action !== null) {\n action.error = true;\n }\n\n return action;\n}\n\n;","/**\n * Copyright (c) 2014-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nvar runtime = (function (exports) {\n \"use strict\";\n\n var Op = Object.prototype;\n var hasOwn = Op.hasOwnProperty;\n var undefined; // More compressible than void 0.\n var $Symbol = typeof Symbol === \"function\" ? Symbol : {};\n var iteratorSymbol = $Symbol.iterator || \"@@iterator\";\n var asyncIteratorSymbol = $Symbol.asyncIterator || \"@@asyncIterator\";\n var toStringTagSymbol = $Symbol.toStringTag || \"@@toStringTag\";\n\n function wrap(innerFn, outerFn, self, tryLocsList) {\n // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.\n var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;\n var generator = Object.create(protoGenerator.prototype);\n var context = new Context(tryLocsList || []);\n\n // The ._invoke method unifies the implementations of the .next,\n // .throw, and .return methods.\n generator._invoke = makeInvokeMethod(innerFn, self, context);\n\n return generator;\n }\n exports.wrap = wrap;\n\n // Try/catch helper to minimize deoptimizations. Returns a completion\n // record like context.tryEntries[i].completion. This interface could\n // have been (and was previously) designed to take a closure to be\n // invoked without arguments, but in all the cases we care about we\n // already have an existing method we want to call, so there's no need\n // to create a new function object. We can even get away with assuming\n // the method takes exactly one argument, since that happens to be true\n // in every case, so we don't have to touch the arguments object. The\n // only additional allocation required is the completion record, which\n // has a stable shape and so hopefully should be cheap to allocate.\n function tryCatch(fn, obj, arg) {\n try {\n return { type: \"normal\", arg: fn.call(obj, arg) };\n } catch (err) {\n return { type: \"throw\", arg: err };\n }\n }\n\n var GenStateSuspendedStart = \"suspendedStart\";\n var GenStateSuspendedYield = \"suspendedYield\";\n var GenStateExecuting = \"executing\";\n var GenStateCompleted = \"completed\";\n\n // Returning this object from the innerFn has the same effect as\n // breaking out of the dispatch switch statement.\n var ContinueSentinel = {};\n\n // Dummy constructor functions that we use as the .constructor and\n // .constructor.prototype properties for functions that return Generator\n // objects. For full spec compliance, you may wish to configure your\n // minifier not to mangle the names of these two functions.\n function Generator() {}\n function GeneratorFunction() {}\n function GeneratorFunctionPrototype() {}\n\n // This is a polyfill for %IteratorPrototype% for environments that\n // don't natively support it.\n var IteratorPrototype = {};\n IteratorPrototype[iteratorSymbol] = function () {\n return this;\n };\n\n var getProto = Object.getPrototypeOf;\n var NativeIteratorPrototype = getProto && getProto(getProto(values([])));\n if (NativeIteratorPrototype &&\n NativeIteratorPrototype !== Op &&\n hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {\n // This environment has a native %IteratorPrototype%; use it instead\n // of the polyfill.\n IteratorPrototype = NativeIteratorPrototype;\n }\n\n var Gp = GeneratorFunctionPrototype.prototype =\n Generator.prototype = Object.create(IteratorPrototype);\n GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;\n GeneratorFunctionPrototype.constructor = GeneratorFunction;\n GeneratorFunctionPrototype[toStringTagSymbol] =\n GeneratorFunction.displayName = \"GeneratorFunction\";\n\n // Helper for defining the .next, .throw, and .return methods of the\n // Iterator interface in terms of a single ._invoke method.\n function defineIteratorMethods(prototype) {\n [\"next\", \"throw\", \"return\"].forEach(function(method) {\n prototype[method] = function(arg) {\n return this._invoke(method, arg);\n };\n });\n }\n\n exports.isGeneratorFunction = function(genFun) {\n var ctor = typeof genFun === \"function\" && genFun.constructor;\n return ctor\n ? ctor === GeneratorFunction ||\n // For the native GeneratorFunction constructor, the best we can\n // do is to check its .name property.\n (ctor.displayName || ctor.name) === \"GeneratorFunction\"\n : false;\n };\n\n exports.mark = function(genFun) {\n if (Object.setPrototypeOf) {\n Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);\n } else {\n genFun.__proto__ = GeneratorFunctionPrototype;\n if (!(toStringTagSymbol in genFun)) {\n genFun[toStringTagSymbol] = \"GeneratorFunction\";\n }\n }\n genFun.prototype = Object.create(Gp);\n return genFun;\n };\n\n // Within the body of any async function, `await x` is transformed to\n // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test\n // `hasOwn.call(value, \"__await\")` to determine if the yielded value is\n // meant to be awaited.\n exports.awrap = function(arg) {\n return { __await: arg };\n };\n\n function AsyncIterator(generator) {\n function invoke(method, arg, resolve, reject) {\n var record = tryCatch(generator[method], generator, arg);\n if (record.type === \"throw\") {\n reject(record.arg);\n } else {\n var result = record.arg;\n var value = result.value;\n if (value &&\n typeof value === \"object\" &&\n hasOwn.call(value, \"__await\")) {\n return Promise.resolve(value.__await).then(function(value) {\n invoke(\"next\", value, resolve, reject);\n }, function(err) {\n invoke(\"throw\", err, resolve, reject);\n });\n }\n\n return Promise.resolve(value).then(function(unwrapped) {\n // When a yielded Promise is resolved, its final value becomes\n // the .value of the Promise<{value,done}> result for the\n // current iteration.\n result.value = unwrapped;\n resolve(result);\n }, function(error) {\n // If a rejected Promise was yielded, throw the rejection back\n // into the async generator function so it can be handled there.\n return invoke(\"throw\", error, resolve, reject);\n });\n }\n }\n\n var previousPromise;\n\n function enqueue(method, arg) {\n function callInvokeWithMethodAndArg() {\n return new Promise(function(resolve, reject) {\n invoke(method, arg, resolve, reject);\n });\n }\n\n return previousPromise =\n // If enqueue has been called before, then we want to wait until\n // all previous Promises have been resolved before calling invoke,\n // so that results are always delivered in the correct order. If\n // enqueue has not been called before, then it is important to\n // call invoke immediately, without waiting on a callback to fire,\n // so that the async generator function has the opportunity to do\n // any necessary setup in a predictable way. This predictability\n // is why the Promise constructor synchronously invokes its\n // executor callback, and why async functions synchronously\n // execute code before the first await. Since we implement simple\n // async functions in terms of async generators, it is especially\n // important to get this right, even though it requires care.\n previousPromise ? previousPromise.then(\n callInvokeWithMethodAndArg,\n // Avoid propagating failures to Promises returned by later\n // invocations of the iterator.\n callInvokeWithMethodAndArg\n ) : callInvokeWithMethodAndArg();\n }\n\n // Define the unified helper method that is used to implement .next,\n // .throw, and .return (see defineIteratorMethods).\n this._invoke = enqueue;\n }\n\n defineIteratorMethods(AsyncIterator.prototype);\n AsyncIterator.prototype[asyncIteratorSymbol] = function () {\n return this;\n };\n exports.AsyncIterator = AsyncIterator;\n\n // Note that simple async functions are implemented on top of\n // AsyncIterator objects; they just return a Promise for the value of\n // the final result produced by the iterator.\n exports.async = function(innerFn, outerFn, self, tryLocsList) {\n var iter = new AsyncIterator(\n wrap(innerFn, outerFn, self, tryLocsList)\n );\n\n return exports.isGeneratorFunction(outerFn)\n ? iter // If outerFn is a generator, return the full iterator.\n : iter.next().then(function(result) {\n return result.done ? result.value : iter.next();\n });\n };\n\n function makeInvokeMethod(innerFn, self, context) {\n var state = GenStateSuspendedStart;\n\n return function invoke(method, arg) {\n if (state === GenStateExecuting) {\n throw new Error(\"Generator is already running\");\n }\n\n if (state === GenStateCompleted) {\n if (method === \"throw\") {\n throw arg;\n }\n\n // Be forgiving, per 25.3.3.3.3 of the spec:\n // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume\n return doneResult();\n }\n\n context.method = method;\n context.arg = arg;\n\n while (true) {\n var delegate = context.delegate;\n if (delegate) {\n var delegateResult = maybeInvokeDelegate(delegate, context);\n if (delegateResult) {\n if (delegateResult === ContinueSentinel) continue;\n return delegateResult;\n }\n }\n\n if (context.method === \"next\") {\n // Setting context._sent for legacy support of Babel's\n // function.sent implementation.\n context.sent = context._sent = context.arg;\n\n } else if (context.method === \"throw\") {\n if (state === GenStateSuspendedStart) {\n state = GenStateCompleted;\n throw context.arg;\n }\n\n context.dispatchException(context.arg);\n\n } else if (context.method === \"return\") {\n context.abrupt(\"return\", context.arg);\n }\n\n state = GenStateExecuting;\n\n var record = tryCatch(innerFn, self, context);\n if (record.type === \"normal\") {\n // If an exception is thrown from innerFn, we leave state ===\n // GenStateExecuting and loop back for another invocation.\n state = context.done\n ? GenStateCompleted\n : GenStateSuspendedYield;\n\n if (record.arg === ContinueSentinel) {\n continue;\n }\n\n return {\n value: record.arg,\n done: context.done\n };\n\n } else if (record.type === \"throw\") {\n state = GenStateCompleted;\n // Dispatch the exception by looping back around to the\n // context.dispatchException(context.arg) call above.\n context.method = \"throw\";\n context.arg = record.arg;\n }\n }\n };\n }\n\n // Call delegate.iterator[context.method](context.arg) and handle the\n // result, either by returning a { value, done } result from the\n // delegate iterator, or by modifying context.method and context.arg,\n // setting context.delegate to null, and returning the ContinueSentinel.\n function maybeInvokeDelegate(delegate, context) {\n var method = delegate.iterator[context.method];\n if (method === undefined) {\n // A .throw or .return when the delegate iterator has no .throw\n // method always terminates the yield* loop.\n context.delegate = null;\n\n if (context.method === \"throw\") {\n // Note: [\"return\"] must be used for ES3 parsing compatibility.\n if (delegate.iterator[\"return\"]) {\n // If the delegate iterator has a return method, give it a\n // chance to clean up.\n context.method = \"return\";\n context.arg = undefined;\n maybeInvokeDelegate(delegate, context);\n\n if (context.method === \"throw\") {\n // If maybeInvokeDelegate(context) changed context.method from\n // \"return\" to \"throw\", let that override the TypeError below.\n return ContinueSentinel;\n }\n }\n\n context.method = \"throw\";\n context.arg = new TypeError(\n \"The iterator does not provide a 'throw' method\");\n }\n\n return ContinueSentinel;\n }\n\n var record = tryCatch(method, delegate.iterator, context.arg);\n\n if (record.type === \"throw\") {\n context.method = \"throw\";\n context.arg = record.arg;\n context.delegate = null;\n return ContinueSentinel;\n }\n\n var info = record.arg;\n\n if (! info) {\n context.method = \"throw\";\n context.arg = new TypeError(\"iterator result is not an object\");\n context.delegate = null;\n return ContinueSentinel;\n }\n\n if (info.done) {\n // Assign the result of the finished delegate to the temporary\n // variable specified by delegate.resultName (see delegateYield).\n context[delegate.resultName] = info.value;\n\n // Resume execution at the desired location (see delegateYield).\n context.next = delegate.nextLoc;\n\n // If context.method was \"throw\" but the delegate handled the\n // exception, let the outer generator proceed normally. If\n // context.method was \"next\", forget context.arg since it has been\n // \"consumed\" by the delegate iterator. If context.method was\n // \"return\", allow the original .return call to continue in the\n // outer generator.\n if (context.method !== \"return\") {\n context.method = \"next\";\n context.arg = undefined;\n }\n\n } else {\n // Re-yield the result returned by the delegate method.\n return info;\n }\n\n // The delegate iterator is finished, so forget it and continue with\n // the outer generator.\n context.delegate = null;\n return ContinueSentinel;\n }\n\n // Define Generator.prototype.{next,throw,return} in terms of the\n // unified ._invoke helper method.\n defineIteratorMethods(Gp);\n\n Gp[toStringTagSymbol] = \"Generator\";\n\n // A Generator should always return itself as the iterator object when the\n // @@iterator function is called on it. Some browsers' implementations of the\n // iterator prototype chain incorrectly implement this, causing the Generator\n // object to not be returned from this call. This ensures that doesn't happen.\n // See https://github.com/facebook/regenerator/issues/274 for more details.\n Gp[iteratorSymbol] = function() {\n return this;\n };\n\n Gp.toString = function() {\n return \"[object Generator]\";\n };\n\n function pushTryEntry(locs) {\n var entry = { tryLoc: locs[0] };\n\n if (1 in locs) {\n entry.catchLoc = locs[1];\n }\n\n if (2 in locs) {\n entry.finallyLoc = locs[2];\n entry.afterLoc = locs[3];\n }\n\n this.tryEntries.push(entry);\n }\n\n function resetTryEntry(entry) {\n var record = entry.completion || {};\n record.type = \"normal\";\n delete record.arg;\n entry.completion = record;\n }\n\n function Context(tryLocsList) {\n // The root entry object (effectively a try statement without a catch\n // or a finally block) gives us a place to store values thrown from\n // locations where there is no enclosing try statement.\n this.tryEntries = [{ tryLoc: \"root\" }];\n tryLocsList.forEach(pushTryEntry, this);\n this.reset(true);\n }\n\n exports.keys = function(object) {\n var keys = [];\n for (var key in object) {\n keys.push(key);\n }\n keys.reverse();\n\n // Rather than returning an object with a next method, we keep\n // things simple and return the next function itself.\n return function next() {\n while (keys.length) {\n var key = keys.pop();\n if (key in object) {\n next.value = key;\n next.done = false;\n return next;\n }\n }\n\n // To avoid creating an additional object, we just hang the .value\n // and .done properties off the next function object itself. This\n // also ensures that the minifier will not anonymize the function.\n next.done = true;\n return next;\n };\n };\n\n function values(iterable) {\n if (iterable) {\n var iteratorMethod = iterable[iteratorSymbol];\n if (iteratorMethod) {\n return iteratorMethod.call(iterable);\n }\n\n if (typeof iterable.next === \"function\") {\n return iterable;\n }\n\n if (!isNaN(iterable.length)) {\n var i = -1, next = function next() {\n while (++i < iterable.length) {\n if (hasOwn.call(iterable, i)) {\n next.value = iterable[i];\n next.done = false;\n return next;\n }\n }\n\n next.value = undefined;\n next.done = true;\n\n return next;\n };\n\n return next.next = next;\n }\n }\n\n // Return an iterator with no values.\n return { next: doneResult };\n }\n exports.values = values;\n\n function doneResult() {\n return { value: undefined, done: true };\n }\n\n Context.prototype = {\n constructor: Context,\n\n reset: function(skipTempReset) {\n this.prev = 0;\n this.next = 0;\n // Resetting context._sent for legacy support of Babel's\n // function.sent implementation.\n this.sent = this._sent = undefined;\n this.done = false;\n this.delegate = null;\n\n this.method = \"next\";\n this.arg = undefined;\n\n this.tryEntries.forEach(resetTryEntry);\n\n if (!skipTempReset) {\n for (var name in this) {\n // Not sure about the optimal order of these conditions:\n if (name.charAt(0) === \"t\" &&\n hasOwn.call(this, name) &&\n !isNaN(+name.slice(1))) {\n this[name] = undefined;\n }\n }\n }\n },\n\n stop: function() {\n this.done = true;\n\n var rootEntry = this.tryEntries[0];\n var rootRecord = rootEntry.completion;\n if (rootRecord.type === \"throw\") {\n throw rootRecord.arg;\n }\n\n return this.rval;\n },\n\n dispatchException: function(exception) {\n if (this.done) {\n throw exception;\n }\n\n var context = this;\n function handle(loc, caught) {\n record.type = \"throw\";\n record.arg = exception;\n context.next = loc;\n\n if (caught) {\n // If the dispatched exception was caught by a catch block,\n // then let that catch block handle the exception normally.\n context.method = \"next\";\n context.arg = undefined;\n }\n\n return !! caught;\n }\n\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n var record = entry.completion;\n\n if (entry.tryLoc === \"root\") {\n // Exception thrown outside of any try block that could handle\n // it, so set the completion value of the entire function to\n // throw the exception.\n return handle(\"end\");\n }\n\n if (entry.tryLoc <= this.prev) {\n var hasCatch = hasOwn.call(entry, \"catchLoc\");\n var hasFinally = hasOwn.call(entry, \"finallyLoc\");\n\n if (hasCatch && hasFinally) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n } else if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else if (hasCatch) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n }\n\n } else if (hasFinally) {\n if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else {\n throw new Error(\"try statement without catch or finally\");\n }\n }\n }\n },\n\n abrupt: function(type, arg) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc <= this.prev &&\n hasOwn.call(entry, \"finallyLoc\") &&\n this.prev < entry.finallyLoc) {\n var finallyEntry = entry;\n break;\n }\n }\n\n if (finallyEntry &&\n (type === \"break\" ||\n type === \"continue\") &&\n finallyEntry.tryLoc <= arg &&\n arg <= finallyEntry.finallyLoc) {\n // Ignore the finally entry if control is not jumping to a\n // location outside the try/catch block.\n finallyEntry = null;\n }\n\n var record = finallyEntry ? finallyEntry.completion : {};\n record.type = type;\n record.arg = arg;\n\n if (finallyEntry) {\n this.method = \"next\";\n this.next = finallyEntry.finallyLoc;\n return ContinueSentinel;\n }\n\n return this.complete(record);\n },\n\n complete: function(record, afterLoc) {\n if (record.type === \"throw\") {\n throw record.arg;\n }\n\n if (record.type === \"break\" ||\n record.type === \"continue\") {\n this.next = record.arg;\n } else if (record.type === \"return\") {\n this.rval = this.arg = record.arg;\n this.method = \"return\";\n this.next = \"end\";\n } else if (record.type === \"normal\" && afterLoc) {\n this.next = afterLoc;\n }\n\n return ContinueSentinel;\n },\n\n finish: function(finallyLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.finallyLoc === finallyLoc) {\n this.complete(entry.completion, entry.afterLoc);\n resetTryEntry(entry);\n return ContinueSentinel;\n }\n }\n },\n\n \"catch\": function(tryLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc === tryLoc) {\n var record = entry.completion;\n if (record.type === \"throw\") {\n var thrown = record.arg;\n resetTryEntry(entry);\n }\n return thrown;\n }\n }\n\n // The context.catch method must only be called with a location\n // argument that corresponds to a known catch block.\n throw new Error(\"illegal catch attempt\");\n },\n\n delegateYield: function(iterable, resultName, nextLoc) {\n this.delegate = {\n iterator: values(iterable),\n resultName: resultName,\n nextLoc: nextLoc\n };\n\n if (this.method === \"next\") {\n // Deliberately forget the last sent value so that we don't\n // accidentally pass it on to the delegate.\n this.arg = undefined;\n }\n\n return ContinueSentinel;\n }\n };\n\n // Regardless of whether this script is executing as a CommonJS module\n // or not, return the runtime object so that we can declare the variable\n // regeneratorRuntime in the outer scope, which allows this module to be\n // injected easily by `bin/regenerator --include-runtime script.js`.\n return exports;\n\n}(\n // If this script is executing as a CommonJS module, use module.exports\n // as the regeneratorRuntime namespace. Otherwise create a new empty\n // object. Either way, the resulting object will be used to initialize\n // the regeneratorRuntime variable at the top of this file.\n typeof module === \"object\" ? module.exports : {}\n));\n\ntry {\n regeneratorRuntime = runtime;\n} catch (accidentalStrictMode) {\n // This module should not be running in strict mode, so the above\n // assignment should always work unless something is misconfigured. Just\n // in case runtime.js accidentally runs in strict mode, we can escape\n // strict mode using a global Function call. This could conceivably fail\n // if a Content Security Policy forbids using Function, but in that case\n // the proper solution is to fix the accidental strict mode problem. If\n // you've misconfigured your bundler to force strict mode and applied a\n // CSP to forbid Function, and you're not willing to fix either of those\n // problems, please detail your unique predicament in a GitHub issue.\n Function(\"r\", \"regeneratorRuntime = r\")(runtime);\n}\n","'use strict';\n\nvar utils = require('./utils');\nvar bind = require('./helpers/bind');\nvar Axios = require('./core/Axios');\nvar mergeConfig = require('./core/mergeConfig');\nvar defaults = require('./defaults');\n\n/**\n * Create an instance of Axios\n *\n * @param {Object} defaultConfig The default config for the instance\n * @return {Axios} A new instance of Axios\n */\nfunction createInstance(defaultConfig) {\n var context = new Axios(defaultConfig);\n var instance = bind(Axios.prototype.request, context);\n\n // Copy axios.prototype to instance\n utils.extend(instance, Axios.prototype, context);\n\n // Copy context to instance\n utils.extend(instance, context);\n\n return instance;\n}\n\n// Create the default instance to be exported\nvar axios = createInstance(defaults);\n\n// Expose Axios class to allow class inheritance\naxios.Axios = Axios;\n\n// Factory for creating new instances\naxios.create = function create(instanceConfig) {\n return createInstance(mergeConfig(axios.defaults, instanceConfig));\n};\n\n// Expose Cancel & CancelToken\naxios.Cancel = require('./cancel/Cancel');\naxios.CancelToken = require('./cancel/CancelToken');\naxios.isCancel = require('./cancel/isCancel');\n\n// Expose all/spread\naxios.all = function all(promises) {\n return Promise.all(promises);\n};\naxios.spread = require('./helpers/spread');\n\n// Expose isAxiosError\naxios.isAxiosError = require('./helpers/isAxiosError');\n\nmodule.exports = axios;\n\n// Allow use of default import syntax in TypeScript\nmodule.exports.default = axios;\n","'use strict';\n\nvar utils = require('./../utils');\nvar buildURL = require('../helpers/buildURL');\nvar InterceptorManager = require('./InterceptorManager');\nvar dispatchRequest = require('./dispatchRequest');\nvar mergeConfig = require('./mergeConfig');\nvar validator = require('../helpers/validator');\n\nvar validators = validator.validators;\n/**\n * Create a new instance of Axios\n *\n * @param {Object} instanceConfig The default config for the instance\n */\nfunction Axios(instanceConfig) {\n this.defaults = instanceConfig;\n this.interceptors = {\n request: new InterceptorManager(),\n response: new InterceptorManager()\n };\n}\n\n/**\n * Dispatch a request\n *\n * @param {Object} config The config specific for this request (merged with this.defaults)\n */\nAxios.prototype.request = function request(config) {\n /*eslint no-param-reassign:0*/\n // Allow for axios('example/url'[, config]) a la fetch API\n if (typeof config === 'string') {\n config = arguments[1] || {};\n config.url = arguments[0];\n } else {\n config = config || {};\n }\n\n config = mergeConfig(this.defaults, config);\n\n // Set config.method\n if (config.method) {\n config.method = config.method.toLowerCase();\n } else if (this.defaults.method) {\n config.method = this.defaults.method.toLowerCase();\n } else {\n config.method = 'get';\n }\n\n var transitional = config.transitional;\n\n if (transitional !== undefined) {\n validator.assertOptions(transitional, {\n silentJSONParsing: validators.transitional(validators.boolean, '1.0.0'),\n forcedJSONParsing: validators.transitional(validators.boolean, '1.0.0'),\n clarifyTimeoutError: validators.transitional(validators.boolean, '1.0.0')\n }, false);\n }\n\n // filter out skipped interceptors\n var requestInterceptorChain = [];\n var synchronousRequestInterceptors = true;\n this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {\n if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) {\n return;\n }\n\n synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous;\n\n requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected);\n });\n\n var responseInterceptorChain = [];\n this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {\n responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);\n });\n\n var promise;\n\n if (!synchronousRequestInterceptors) {\n var chain = [dispatchRequest, undefined];\n\n Array.prototype.unshift.apply(chain, requestInterceptorChain);\n chain.concat(responseInterceptorChain);\n\n promise = Promise.resolve(config);\n while (chain.length) {\n promise = promise.then(chain.shift(), chain.shift());\n }\n\n return promise;\n }\n\n\n var newConfig = config;\n while (requestInterceptorChain.length) {\n var onFulfilled = requestInterceptorChain.shift();\n var onRejected = requestInterceptorChain.shift();\n try {\n newConfig = onFulfilled(newConfig);\n } catch (error) {\n onRejected(error);\n break;\n }\n }\n\n try {\n promise = dispatchRequest(newConfig);\n } catch (error) {\n return Promise.reject(error);\n }\n\n while (responseInterceptorChain.length) {\n promise = promise.then(responseInterceptorChain.shift(), responseInterceptorChain.shift());\n }\n\n return promise;\n};\n\nAxios.prototype.getUri = function getUri(config) {\n config = mergeConfig(this.defaults, config);\n return buildURL(config.url, config.params, config.paramsSerializer).replace(/^\\?/, '');\n};\n\n// Provide aliases for supported request methods\nutils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {\n /*eslint func-names:0*/\n Axios.prototype[method] = function(url, config) {\n return this.request(mergeConfig(config || {}, {\n method: method,\n url: url,\n data: (config || {}).data\n }));\n };\n});\n\nutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n /*eslint func-names:0*/\n Axios.prototype[method] = function(url, data, config) {\n return this.request(mergeConfig(config || {}, {\n method: method,\n url: url,\n data: data\n }));\n };\n});\n\nmodule.exports = Axios;\n","'use strict';\n\nvar utils = require('./../utils');\n\nfunction InterceptorManager() {\n this.handlers = [];\n}\n\n/**\n * Add a new interceptor to the stack\n *\n * @param {Function} fulfilled The function to handle `then` for a `Promise`\n * @param {Function} rejected The function to handle `reject` for a `Promise`\n *\n * @return {Number} An ID used to remove interceptor later\n */\nInterceptorManager.prototype.use = function use(fulfilled, rejected, options) {\n this.handlers.push({\n fulfilled: fulfilled,\n rejected: rejected,\n synchronous: options ? options.synchronous : false,\n runWhen: options ? options.runWhen : null\n });\n return this.handlers.length - 1;\n};\n\n/**\n * Remove an interceptor from the stack\n *\n * @param {Number} id The ID that was returned by `use`\n */\nInterceptorManager.prototype.eject = function eject(id) {\n if (this.handlers[id]) {\n this.handlers[id] = null;\n }\n};\n\n/**\n * Iterate over all the registered interceptors\n *\n * This method is particularly useful for skipping over any\n * interceptors that may have become `null` calling `eject`.\n *\n * @param {Function} fn The function to call for each interceptor\n */\nInterceptorManager.prototype.forEach = function forEach(fn) {\n utils.forEach(this.handlers, function forEachHandler(h) {\n if (h !== null) {\n fn(h);\n }\n });\n};\n\nmodule.exports = InterceptorManager;\n","'use strict';\n\nvar utils = require('./../utils');\nvar transformData = require('./transformData');\nvar isCancel = require('../cancel/isCancel');\nvar defaults = require('../defaults');\n\n/**\n * Throws a `Cancel` if cancellation has been requested.\n */\nfunction throwIfCancellationRequested(config) {\n if (config.cancelToken) {\n config.cancelToken.throwIfRequested();\n }\n}\n\n/**\n * Dispatch a request to the server using the configured adapter.\n *\n * @param {object} config The config that is to be used for the request\n * @returns {Promise} The Promise to be fulfilled\n */\nmodule.exports = function dispatchRequest(config) {\n throwIfCancellationRequested(config);\n\n // Ensure headers exist\n config.headers = config.headers || {};\n\n // Transform request data\n config.data = transformData.call(\n config,\n config.data,\n config.headers,\n config.transformRequest\n );\n\n // Flatten headers\n config.headers = utils.merge(\n config.headers.common || {},\n config.headers[config.method] || {},\n config.headers\n );\n\n utils.forEach(\n ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],\n function cleanHeaderConfig(method) {\n delete config.headers[method];\n }\n );\n\n var adapter = config.adapter || defaults.adapter;\n\n return adapter(config).then(function onAdapterResolution(response) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n response.data = transformData.call(\n config,\n response.data,\n response.headers,\n config.transformResponse\n );\n\n return response;\n }, function onAdapterRejection(reason) {\n if (!isCancel(reason)) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n if (reason && reason.response) {\n reason.response.data = transformData.call(\n config,\n reason.response.data,\n reason.response.headers,\n config.transformResponse\n );\n }\n }\n\n return Promise.reject(reason);\n });\n};\n","'use strict';\n\nvar utils = require('./../utils');\nvar defaults = require('./../defaults');\n\n/**\n * Transform the data for a request or a response\n *\n * @param {Object|String} data The data to be transformed\n * @param {Array} headers The headers for the request or response\n * @param {Array|Function} fns A single function or Array of functions\n * @returns {*} The resulting transformed data\n */\nmodule.exports = function transformData(data, headers, fns) {\n var context = this || defaults;\n /*eslint no-param-reassign:0*/\n utils.forEach(fns, function transform(fn) {\n data = fn.call(context, data, headers);\n });\n\n return data;\n};\n","'use strict';\n\nvar utils = require('../utils');\n\nmodule.exports = function normalizeHeaderName(headers, normalizedName) {\n utils.forEach(headers, function processHeader(value, name) {\n if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) {\n headers[normalizedName] = value;\n delete headers[name];\n }\n });\n};\n","'use strict';\n\nvar createError = require('./createError');\n\n/**\n * Resolve or reject a Promise based on response status.\n *\n * @param {Function} resolve A function that resolves the promise.\n * @param {Function} reject A function that rejects the promise.\n * @param {object} response The response.\n */\nmodule.exports = function settle(resolve, reject, response) {\n var validateStatus = response.config.validateStatus;\n if (!response.status || !validateStatus || validateStatus(response.status)) {\n resolve(response);\n } else {\n reject(createError(\n 'Request failed with status code ' + response.status,\n response.config,\n null,\n response.request,\n response\n ));\n }\n};\n","'use strict';\n\nvar utils = require('./../utils');\n\nmodule.exports = (\n utils.isStandardBrowserEnv() ?\n\n // Standard browser envs support document.cookie\n (function standardBrowserEnv() {\n return {\n write: function write(name, value, expires, path, domain, secure) {\n var cookie = [];\n cookie.push(name + '=' + encodeURIComponent(value));\n\n if (utils.isNumber(expires)) {\n cookie.push('expires=' + new Date(expires).toGMTString());\n }\n\n if (utils.isString(path)) {\n cookie.push('path=' + path);\n }\n\n if (utils.isString(domain)) {\n cookie.push('domain=' + domain);\n }\n\n if (secure === true) {\n cookie.push('secure');\n }\n\n document.cookie = cookie.join('; ');\n },\n\n read: function read(name) {\n var match = document.cookie.match(new RegExp('(^|;\\\\s*)(' + name + ')=([^;]*)'));\n return (match ? decodeURIComponent(match[3]) : null);\n },\n\n remove: function remove(name) {\n this.write(name, '', Date.now() - 86400000);\n }\n };\n })() :\n\n // Non standard browser env (web workers, react-native) lack needed support.\n (function nonStandardBrowserEnv() {\n return {\n write: function write() {},\n read: function read() { return null; },\n remove: function remove() {}\n };\n })()\n);\n","'use strict';\n\nvar isAbsoluteURL = require('../helpers/isAbsoluteURL');\nvar combineURLs = require('../helpers/combineURLs');\n\n/**\n * Creates a new URL by combining the baseURL with the requestedURL,\n * only when the requestedURL is not already an absolute URL.\n * If the requestURL is absolute, this function returns the requestedURL untouched.\n *\n * @param {string} baseURL The base URL\n * @param {string} requestedURL Absolute or relative URL to combine\n * @returns {string} The combined full path\n */\nmodule.exports = function buildFullPath(baseURL, requestedURL) {\n if (baseURL && !isAbsoluteURL(requestedURL)) {\n return combineURLs(baseURL, requestedURL);\n }\n return requestedURL;\n};\n","'use strict';\n\n/**\n * Determines whether the specified URL is absolute\n *\n * @param {string} url The URL to test\n * @returns {boolean} True if the specified URL is absolute, otherwise false\n */\nmodule.exports = function isAbsoluteURL(url) {\n // A URL is considered absolute if it begins with \"://\" or \"//\" (protocol-relative URL).\n // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed\n // by any combination of letters, digits, plus, period, or hyphen.\n return /^([a-z][a-z\\d\\+\\-\\.]*:)?\\/\\//i.test(url);\n};\n","'use strict';\n\n/**\n * Creates a new URL by combining the specified URLs\n *\n * @param {string} baseURL The base URL\n * @param {string} relativeURL The relative URL\n * @returns {string} The combined URL\n */\nmodule.exports = function combineURLs(baseURL, relativeURL) {\n return relativeURL\n ? baseURL.replace(/\\/+$/, '') + '/' + relativeURL.replace(/^\\/+/, '')\n : baseURL;\n};\n","'use strict';\n\nvar utils = require('./../utils');\n\n// Headers whose duplicates are ignored by node\n// c.f. https://nodejs.org/api/http.html#http_message_headers\nvar ignoreDuplicateOf = [\n 'age', 'authorization', 'content-length', 'content-type', 'etag',\n 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',\n 'last-modified', 'location', 'max-forwards', 'proxy-authorization',\n 'referer', 'retry-after', 'user-agent'\n];\n\n/**\n * Parse headers into an object\n *\n * ```\n * Date: Wed, 27 Aug 2014 08:58:49 GMT\n * Content-Type: application/json\n * Connection: keep-alive\n * Transfer-Encoding: chunked\n * ```\n *\n * @param {String} headers Headers needing to be parsed\n * @returns {Object} Headers parsed into an object\n */\nmodule.exports = function parseHeaders(headers) {\n var parsed = {};\n var key;\n var val;\n var i;\n\n if (!headers) { return parsed; }\n\n utils.forEach(headers.split('\\n'), function parser(line) {\n i = line.indexOf(':');\n key = utils.trim(line.substr(0, i)).toLowerCase();\n val = utils.trim(line.substr(i + 1));\n\n if (key) {\n if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) {\n return;\n }\n if (key === 'set-cookie') {\n parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]);\n } else {\n parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;\n }\n }\n });\n\n return parsed;\n};\n","'use strict';\n\nvar utils = require('./../utils');\n\nmodule.exports = (\n utils.isStandardBrowserEnv() ?\n\n // Standard browser envs have full support of the APIs needed to test\n // whether the request URL is of the same origin as current location.\n (function standardBrowserEnv() {\n var msie = /(msie|trident)/i.test(navigator.userAgent);\n var urlParsingNode = document.createElement('a');\n var originURL;\n\n /**\n * Parse a URL to discover it's components\n *\n * @param {String} url The URL to be parsed\n * @returns {Object}\n */\n function resolveURL(url) {\n var href = url;\n\n if (msie) {\n // IE needs attribute set twice to normalize properties\n urlParsingNode.setAttribute('href', href);\n href = urlParsingNode.href;\n }\n\n urlParsingNode.setAttribute('href', href);\n\n // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils\n return {\n href: urlParsingNode.href,\n protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',\n host: urlParsingNode.host,\n search: urlParsingNode.search ? urlParsingNode.search.replace(/^\\?/, '') : '',\n hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',\n hostname: urlParsingNode.hostname,\n port: urlParsingNode.port,\n pathname: (urlParsingNode.pathname.charAt(0) === '/') ?\n urlParsingNode.pathname :\n '/' + urlParsingNode.pathname\n };\n }\n\n originURL = resolveURL(window.location.href);\n\n /**\n * Determine if a URL shares the same origin as the current location\n *\n * @param {String} requestURL The URL to test\n * @returns {boolean} True if URL shares the same origin, otherwise false\n */\n return function isURLSameOrigin(requestURL) {\n var parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL;\n return (parsed.protocol === originURL.protocol &&\n parsed.host === originURL.host);\n };\n })() :\n\n // Non standard browser envs (web workers, react-native) lack needed support.\n (function nonStandardBrowserEnv() {\n return function isURLSameOrigin() {\n return true;\n };\n })()\n);\n","'use strict';\n\nvar pkg = require('./../../package.json');\n\nvar validators = {};\n\n// eslint-disable-next-line func-names\n['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach(function(type, i) {\n validators[type] = function validator(thing) {\n return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type;\n };\n});\n\nvar deprecatedWarnings = {};\nvar currentVerArr = pkg.version.split('.');\n\n/**\n * Compare package versions\n * @param {string} version\n * @param {string?} thanVersion\n * @returns {boolean}\n */\nfunction isOlderVersion(version, thanVersion) {\n var pkgVersionArr = thanVersion ? thanVersion.split('.') : currentVerArr;\n var destVer = version.split('.');\n for (var i = 0; i < 3; i++) {\n if (pkgVersionArr[i] > destVer[i]) {\n return true;\n } else if (pkgVersionArr[i] < destVer[i]) {\n return false;\n }\n }\n return false;\n}\n\n/**\n * Transitional option validator\n * @param {function|boolean?} validator\n * @param {string?} version\n * @param {string} message\n * @returns {function}\n */\nvalidators.transitional = function transitional(validator, version, message) {\n var isDeprecated = version && isOlderVersion(version);\n\n function formatMessage(opt, desc) {\n return '[Axios v' + pkg.version + '] Transitional option \\'' + opt + '\\'' + desc + (message ? '. ' + message : '');\n }\n\n // eslint-disable-next-line func-names\n return function(value, opt, opts) {\n if (validator === false) {\n throw new Error(formatMessage(opt, ' has been removed in ' + version));\n }\n\n if (isDeprecated && !deprecatedWarnings[opt]) {\n deprecatedWarnings[opt] = true;\n // eslint-disable-next-line no-console\n console.warn(\n formatMessage(\n opt,\n ' has been deprecated since v' + version + ' and will be removed in the near future'\n )\n );\n }\n\n return validator ? validator(value, opt, opts) : true;\n };\n};\n\n/**\n * Assert object's properties type\n * @param {object} options\n * @param {object} schema\n * @param {boolean?} allowUnknown\n */\n\nfunction assertOptions(options, schema, allowUnknown) {\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n var keys = Object.keys(options);\n var i = keys.length;\n while (i-- > 0) {\n var opt = keys[i];\n var validator = schema[opt];\n if (validator) {\n var value = options[opt];\n var result = value === undefined || validator(value, opt, options);\n if (result !== true) {\n throw new TypeError('option ' + opt + ' must be ' + result);\n }\n continue;\n }\n if (allowUnknown !== true) {\n throw Error('Unknown option ' + opt);\n }\n }\n}\n\nmodule.exports = {\n isOlderVersion: isOlderVersion,\n assertOptions: assertOptions,\n validators: validators\n};\n","'use strict';\n\nvar Cancel = require('./Cancel');\n\n/**\n * A `CancelToken` is an object that can be used to request cancellation of an operation.\n *\n * @class\n * @param {Function} executor The executor function.\n */\nfunction CancelToken(executor) {\n if (typeof executor !== 'function') {\n throw new TypeError('executor must be a function.');\n }\n\n var resolvePromise;\n this.promise = new Promise(function promiseExecutor(resolve) {\n resolvePromise = resolve;\n });\n\n var token = this;\n executor(function cancel(message) {\n if (token.reason) {\n // Cancellation has already been requested\n return;\n }\n\n token.reason = new Cancel(message);\n resolvePromise(token.reason);\n });\n}\n\n/**\n * Throws a `Cancel` if cancellation has been requested.\n */\nCancelToken.prototype.throwIfRequested = function throwIfRequested() {\n if (this.reason) {\n throw this.reason;\n }\n};\n\n/**\n * Returns an object that contains a new `CancelToken` and a function that, when called,\n * cancels the `CancelToken`.\n */\nCancelToken.source = function source() {\n var cancel;\n var token = new CancelToken(function executor(c) {\n cancel = c;\n });\n return {\n token: token,\n cancel: cancel\n };\n};\n\nmodule.exports = CancelToken;\n","'use strict';\n\n/**\n * Syntactic sugar for invoking a function and expanding an array for arguments.\n *\n * Common use case would be to use `Function.prototype.apply`.\n *\n * ```js\n * function f(x, y, z) {}\n * var args = [1, 2, 3];\n * f.apply(null, args);\n * ```\n *\n * With `spread` this example can be re-written.\n *\n * ```js\n * spread(function(x, y, z) {})([1, 2, 3]);\n * ```\n *\n * @param {Function} callback\n * @returns {Function}\n */\nmodule.exports = function spread(callback) {\n return function wrap(arr) {\n return callback.apply(null, arr);\n };\n};\n","'use strict';\n\n/**\n * Determines whether the payload is an error thrown by Axios\n *\n * @param {*} payload The value to test\n * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false\n */\nmodule.exports = function isAxiosError(payload) {\n return (typeof payload === 'object') && (payload.isAxiosError === true);\n};\n","\"use strict\";\n\nexports.__esModule = true;\nexports[\"default\"] = void 0;\n\nfunction last() {\n var _ref;\n\n return _ref = arguments.length - 1, _ref < 0 || arguments.length <= _ref ? undefined : arguments[_ref];\n}\n\nfunction negation(a) {\n return -a;\n}\n\nfunction addition(a, b) {\n return a + b;\n}\n\nfunction subtraction(a, b) {\n return a - b;\n}\n\nfunction multiplication(a, b) {\n return a * b;\n}\n\nfunction division(a, b) {\n return a / b;\n}\n\nfunction max() {\n return Math.max.apply(Math, arguments);\n}\n\nfunction min() {\n return Math.min.apply(Math, arguments);\n}\n\nfunction comma() {\n return Array.of.apply(Array, arguments);\n}\n\nvar defaultSymbols = {\n symbols: {\n '*': {\n infix: {\n symbol: '*',\n f: multiplication,\n notation: 'infix',\n precedence: 4,\n rightToLeft: 0,\n argCount: 2\n },\n symbol: '*',\n regSymbol: '\\\\*'\n },\n '/': {\n infix: {\n symbol: '/',\n f: division,\n notation: 'infix',\n precedence: 4,\n rightToLeft: 0,\n argCount: 2\n },\n symbol: '/',\n regSymbol: '/'\n },\n '+': {\n infix: {\n symbol: '+',\n f: addition,\n notation: 'infix',\n precedence: 2,\n rightToLeft: 0,\n argCount: 2\n },\n prefix: {\n symbol: '+',\n f: last,\n notation: 'prefix',\n precedence: 3,\n rightToLeft: 0,\n argCount: 1\n },\n symbol: '+',\n regSymbol: '\\\\+'\n },\n '-': {\n infix: {\n symbol: '-',\n f: subtraction,\n notation: 'infix',\n precedence: 2,\n rightToLeft: 0,\n argCount: 2\n },\n prefix: {\n symbol: '-',\n f: negation,\n notation: 'prefix',\n precedence: 3,\n rightToLeft: 0,\n argCount: 1\n },\n symbol: '-',\n regSymbol: '-'\n },\n ',': {\n infix: {\n symbol: ',',\n f: comma,\n notation: 'infix',\n precedence: 1,\n rightToLeft: 0,\n argCount: 2\n },\n symbol: ',',\n regSymbol: ','\n },\n '(': {\n prefix: {\n symbol: '(',\n f: last,\n notation: 'prefix',\n precedence: 0,\n rightToLeft: 0,\n argCount: 1\n },\n symbol: '(',\n regSymbol: '\\\\('\n },\n ')': {\n postfix: {\n symbol: ')',\n f: undefined,\n notation: 'postfix',\n precedence: 0,\n rightToLeft: 0,\n argCount: 1\n },\n symbol: ')',\n regSymbol: '\\\\)'\n },\n min: {\n func: {\n symbol: 'min',\n f: min,\n notation: 'func',\n precedence: 0,\n rightToLeft: 0,\n argCount: 1\n },\n symbol: 'min',\n regSymbol: 'min\\\\b'\n },\n max: {\n func: {\n symbol: 'max',\n f: max,\n notation: 'func',\n precedence: 0,\n rightToLeft: 0,\n argCount: 1\n },\n symbol: 'max',\n regSymbol: 'max\\\\b'\n }\n }\n};\nvar _default = defaultSymbols;\nexports[\"default\"] = _default;\nmodule.exports = exports.default;","\"use strict\";\n\nexports.__esModule = true;\nexports[\"default\"] = void 0;\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\n\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \"function\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \"function\") { throw new TypeError(\"Super expression must either be null or a function\"); } if (typeof _cache !== \"undefined\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\n\nfunction _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\"[native code]\") !== -1; }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n// based on https://github.com/styled-components/styled-components/blob/fcf6f3804c57a14dd7984dfab7bc06ee2edca044/src/utils/error.js\n\n/**\n * Parse errors.md and turn it into a simple hash of code: message\n * @private\n */\nvar ERRORS = {\n \"1\": \"Passed invalid arguments to hsl, please pass multiple numbers e.g. hsl(360, 0.75, 0.4) or an object e.g. rgb({ hue: 255, saturation: 0.4, lightness: 0.75 }).\\n\\n\",\n \"2\": \"Passed invalid arguments to hsla, please pass multiple numbers e.g. hsla(360, 0.75, 0.4, 0.7) or an object e.g. rgb({ hue: 255, saturation: 0.4, lightness: 0.75, alpha: 0.7 }).\\n\\n\",\n \"3\": \"Passed an incorrect argument to a color function, please pass a string representation of a color.\\n\\n\",\n \"4\": \"Couldn't generate valid rgb string from %s, it returned %s.\\n\\n\",\n \"5\": \"Couldn't parse the color string. Please provide the color as a string in hex, rgb, rgba, hsl or hsla notation.\\n\\n\",\n \"6\": \"Passed invalid arguments to rgb, please pass multiple numbers e.g. rgb(255, 205, 100) or an object e.g. rgb({ red: 255, green: 205, blue: 100 }).\\n\\n\",\n \"7\": \"Passed invalid arguments to rgba, please pass multiple numbers e.g. rgb(255, 205, 100, 0.75) or an object e.g. rgb({ red: 255, green: 205, blue: 100, alpha: 0.75 }).\\n\\n\",\n \"8\": \"Passed invalid argument to toColorString, please pass a RgbColor, RgbaColor, HslColor or HslaColor object.\\n\\n\",\n \"9\": \"Please provide a number of steps to the modularScale helper.\\n\\n\",\n \"10\": \"Please pass a number or one of the predefined scales to the modularScale helper as the ratio.\\n\\n\",\n \"11\": \"Invalid value passed as base to modularScale, expected number or em string but got \\\"%s\\\"\\n\\n\",\n \"12\": \"Expected a string ending in \\\"px\\\" or a number passed as the first argument to %s(), got \\\"%s\\\" instead.\\n\\n\",\n \"13\": \"Expected a string ending in \\\"px\\\" or a number passed as the second argument to %s(), got \\\"%s\\\" instead.\\n\\n\",\n \"14\": \"Passed invalid pixel value (\\\"%s\\\") to %s(), please pass a value like \\\"12px\\\" or 12.\\n\\n\",\n \"15\": \"Passed invalid base value (\\\"%s\\\") to %s(), please pass a value like \\\"12px\\\" or 12.\\n\\n\",\n \"16\": \"You must provide a template to this method.\\n\\n\",\n \"17\": \"You passed an unsupported selector state to this method.\\n\\n\",\n \"18\": \"minScreen and maxScreen must be provided as stringified numbers with the same units.\\n\\n\",\n \"19\": \"fromSize and toSize must be provided as stringified numbers with the same units.\\n\\n\",\n \"20\": \"expects either an array of objects or a single object with the properties prop, fromSize, and toSize.\\n\\n\",\n \"21\": \"expects the objects in the first argument array to have the properties `prop`, `fromSize`, and `toSize`.\\n\\n\",\n \"22\": \"expects the first argument object to have the properties `prop`, `fromSize`, and `toSize`.\\n\\n\",\n \"23\": \"fontFace expects a name of a font-family.\\n\\n\",\n \"24\": \"fontFace expects either the path to the font file(s) or a name of a local copy.\\n\\n\",\n \"25\": \"fontFace expects localFonts to be an array.\\n\\n\",\n \"26\": \"fontFace expects fileFormats to be an array.\\n\\n\",\n \"27\": \"radialGradient requries at least 2 color-stops to properly render.\\n\\n\",\n \"28\": \"Please supply a filename to retinaImage() as the first argument.\\n\\n\",\n \"29\": \"Passed invalid argument to triangle, please pass correct pointingDirection e.g. 'right'.\\n\\n\",\n \"30\": \"Passed an invalid value to `height` or `width`. Please provide a pixel based unit.\\n\\n\",\n \"31\": \"The animation shorthand only takes 8 arguments. See the specification for more information: http://mdn.io/animation\\n\\n\",\n \"32\": \"To pass multiple animations please supply them in arrays, e.g. animation(['rotate', '2s'], ['move', '1s'])\\nTo pass a single animation please supply them in simple values, e.g. animation('rotate', '2s')\\n\\n\",\n \"33\": \"The animation shorthand arrays can only have 8 elements. See the specification for more information: http://mdn.io/animation\\n\\n\",\n \"34\": \"borderRadius expects a radius value as a string or number as the second argument.\\n\\n\",\n \"35\": \"borderRadius expects one of \\\"top\\\", \\\"bottom\\\", \\\"left\\\" or \\\"right\\\" as the first argument.\\n\\n\",\n \"36\": \"Property must be a string value.\\n\\n\",\n \"37\": \"Syntax Error at %s.\\n\\n\",\n \"38\": \"Formula contains a function that needs parentheses at %s.\\n\\n\",\n \"39\": \"Formula is missing closing parenthesis at %s.\\n\\n\",\n \"40\": \"Formula has too many closing parentheses at %s.\\n\\n\",\n \"41\": \"All values in a formula must have the same unit or be unitless.\\n\\n\",\n \"42\": \"Please provide a number of steps to the modularScale helper.\\n\\n\",\n \"43\": \"Please pass a number or one of the predefined scales to the modularScale helper as the ratio.\\n\\n\",\n \"44\": \"Invalid value passed as base to modularScale, expected number or em/rem string but got %s.\\n\\n\",\n \"45\": \"Passed invalid argument to hslToColorString, please pass a HslColor or HslaColor object.\\n\\n\",\n \"46\": \"Passed invalid argument to rgbToColorString, please pass a RgbColor or RgbaColor object.\\n\\n\",\n \"47\": \"minScreen and maxScreen must be provided as stringified numbers with the same units.\\n\\n\",\n \"48\": \"fromSize and toSize must be provided as stringified numbers with the same units.\\n\\n\",\n \"49\": \"Expects either an array of objects or a single object with the properties prop, fromSize, and toSize.\\n\\n\",\n \"50\": \"Expects the objects in the first argument array to have the properties prop, fromSize, and toSize.\\n\\n\",\n \"51\": \"Expects the first argument object to have the properties prop, fromSize, and toSize.\\n\\n\",\n \"52\": \"fontFace expects either the path to the font file(s) or a name of a local copy.\\n\\n\",\n \"53\": \"fontFace expects localFonts to be an array.\\n\\n\",\n \"54\": \"fontFace expects fileFormats to be an array.\\n\\n\",\n \"55\": \"fontFace expects a name of a font-family.\\n\\n\",\n \"56\": \"linearGradient requries at least 2 color-stops to properly render.\\n\\n\",\n \"57\": \"radialGradient requries at least 2 color-stops to properly render.\\n\\n\",\n \"58\": \"Please supply a filename to retinaImage() as the first argument.\\n\\n\",\n \"59\": \"Passed invalid argument to triangle, please pass correct pointingDirection e.g. 'right'.\\n\\n\",\n \"60\": \"Passed an invalid value to `height` or `width`. Please provide a pixel based unit.\\n\\n\",\n \"61\": \"Property must be a string value.\\n\\n\",\n \"62\": \"borderRadius expects a radius value as a string or number as the second argument.\\n\\n\",\n \"63\": \"borderRadius expects one of \\\"top\\\", \\\"bottom\\\", \\\"left\\\" or \\\"right\\\" as the first argument.\\n\\n\",\n \"64\": \"The animation shorthand only takes 8 arguments. See the specification for more information: http://mdn.io/animation.\\n\\n\",\n \"65\": \"To pass multiple animations please supply them in arrays, e.g. animation(['rotate', '2s'], ['move', '1s'])\\\\nTo pass a single animation please supply them in simple values, e.g. animation('rotate', '2s').\\n\\n\",\n \"66\": \"The animation shorthand arrays can only have 8 elements. See the specification for more information: http://mdn.io/animation.\\n\\n\",\n \"67\": \"You must provide a template to this method.\\n\\n\",\n \"68\": \"You passed an unsupported selector state to this method.\\n\\n\",\n \"69\": \"Expected a string ending in \\\"px\\\" or a number passed as the first argument to %s(), got %s instead.\\n\\n\",\n \"70\": \"Expected a string ending in \\\"px\\\" or a number passed as the second argument to %s(), got %s instead.\\n\\n\",\n \"71\": \"Passed invalid pixel value %s to %s(), please pass a value like \\\"12px\\\" or 12.\\n\\n\",\n \"72\": \"Passed invalid base value %s to %s(), please pass a value like \\\"12px\\\" or 12.\\n\\n\",\n \"73\": \"Please provide a valid CSS variable.\\n\\n\",\n \"74\": \"CSS variable not found and no default was provided.\\n\\n\",\n \"75\": \"important requires a valid style object, got a %s instead.\\n\\n\",\n \"76\": \"fromSize and toSize must be provided as stringified numbers with the same units as minScreen and maxScreen.\\n\\n\",\n \"77\": \"remToPx expects a value in \\\"rem\\\" but you provided it in \\\"%s\\\".\\n\\n\",\n \"78\": \"base must be set in \\\"px\\\" or \\\"%\\\" but you set it in \\\"%s\\\".\\n\"\n};\n/**\n * super basic version of sprintf\n * @private\n */\n\nfunction format() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n var a = args[0];\n var b = [];\n var c;\n\n for (c = 1; c < args.length; c += 1) {\n b.push(args[c]);\n }\n\n b.forEach(function (d) {\n a = a.replace(/%[a-z]/, d);\n });\n return a;\n}\n/**\n * Create an error file out of errors.md for development and a simple web link to the full errors\n * in production mode.\n * @private\n */\n\n\nvar PolishedError = /*#__PURE__*/function (_Error) {\n _inheritsLoose(PolishedError, _Error);\n\n function PolishedError(code) {\n var _this;\n\n if (process.env.NODE_ENV === 'production') {\n _this = _Error.call(this, \"An error occurred. See https://github.com/styled-components/polished/blob/main/src/internalHelpers/errors.md#\" + code + \" for more information.\") || this;\n } else {\n for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n args[_key2 - 1] = arguments[_key2];\n }\n\n _this = _Error.call(this, format.apply(void 0, [ERRORS[code]].concat(args))) || this;\n }\n\n return _assertThisInitialized(_this);\n }\n\n return PolishedError;\n}( /*#__PURE__*/_wrapNativeSuper(Error));\n\nexports[\"default\"] = PolishedError;\nmodule.exports = exports.default;","import React from 'react'\n\nlet renderErr = 'Renderer Error ☝️'\n\nexport const actions = {\n init: 'init',\n}\n\nexport const defaultRenderer = ({ value = '' }) => value;\nexport const emptyRenderer = () => <> ;\n\nexport const defaultColumn = {\n Cell: defaultRenderer,\n width: 150,\n minWidth: 0,\n maxWidth: Number.MAX_SAFE_INTEGER,\n}\n\nfunction mergeProps(...propList) {\n return propList.reduce((props, next) => {\n const { style, className, ...rest } = next\n\n props = {\n ...props,\n ...rest,\n }\n\n if (style) {\n props.style = props.style\n ? { ...(props.style || {}), ...(style || {}) }\n : style\n }\n\n if (className) {\n props.className = props.className\n ? props.className + ' ' + className\n : className\n }\n\n if (props.className === '') {\n delete props.className\n }\n\n return props\n }, {})\n}\n\nfunction handlePropGetter(prevProps, userProps, meta) {\n // Handle a lambda, pass it the previous props\n if (typeof userProps === 'function') {\n return handlePropGetter({}, userProps(prevProps, meta))\n }\n\n // Handle an array, merge each item as separate props\n if (Array.isArray(userProps)) {\n return mergeProps(prevProps, ...userProps)\n }\n\n // Handle an object by default, merge the two objects\n return mergeProps(prevProps, userProps)\n}\n\nexport const makePropGetter = (hooks, meta = {}) => {\n return (userProps = {}) =>\n [...hooks, userProps].reduce(\n (prev, next) =>\n handlePropGetter(prev, next, {\n ...meta,\n userProps,\n }),\n {}\n )\n}\n\nexport const reduceHooks = (hooks, initial, meta = {}, allowUndefined) =>\n hooks.reduce((prev, next) => {\n const nextValue = next(prev, meta)\n if (process.env.NODE_ENV !== 'production') {\n if (!allowUndefined && typeof nextValue === 'undefined') {\n console.info(next)\n throw new Error(\n 'React Table: A reducer hook ☝️ just returned undefined! This is not allowed.'\n )\n }\n }\n return nextValue\n }, initial)\n\nexport const loopHooks = (hooks, context, meta = {}) =>\n hooks.forEach(hook => {\n const nextValue = hook(context, meta)\n if (process.env.NODE_ENV !== 'production') {\n if (typeof nextValue !== 'undefined') {\n console.info(hook, nextValue)\n throw new Error(\n 'React Table: A loop-type hook ☝️ just returned a value! This is not allowed.'\n )\n }\n }\n })\n\nexport function ensurePluginOrder(plugins, befores, pluginName, afters) {\n if (process.env.NODE_ENV !== 'production' && afters) {\n throw new Error(\n `Defining plugins in the \"after\" section of ensurePluginOrder is no longer supported (see plugin ${pluginName})`\n )\n }\n const pluginIndex = plugins.findIndex(\n plugin => plugin.pluginName === pluginName\n )\n\n if (pluginIndex === -1) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(`The plugin \"${pluginName}\" was not found in the plugin list!\nThis usually means you need to need to name your plugin hook by setting the 'pluginName' property of the hook function, eg:\n\n ${pluginName}.pluginName = '${pluginName}'\n`)\n }\n }\n\n befores.forEach(before => {\n const beforeIndex = plugins.findIndex(\n plugin => plugin.pluginName === before\n )\n if (beforeIndex > -1 && beforeIndex > pluginIndex) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n `React Table: The ${pluginName} plugin hook must be placed after the ${before} plugin hook!`\n )\n }\n }\n })\n}\n\nexport function functionalUpdate(updater, old) {\n return typeof updater === 'function' ? updater(old) : updater\n}\n\nexport function useGetLatest(obj) {\n const ref = React.useRef()\n ref.current = obj\n\n return React.useCallback(() => ref.current, [])\n}\n\n// SSR has issues with useLayoutEffect still, so use useEffect during SSR\nexport const safeUseLayoutEffect =\n typeof document !== 'undefined' ? React.useLayoutEffect : React.useEffect\n\nexport function useMountedLayoutEffect(fn, deps) {\n const mountedRef = React.useRef(false)\n\n safeUseLayoutEffect(() => {\n if (mountedRef.current) {\n fn()\n }\n mountedRef.current = true\n // eslint-disable-next-line\n }, deps)\n}\n\nexport function useAsyncDebounce(defaultFn, defaultWait = 0) {\n const debounceRef = React.useRef({})\n\n const getDefaultFn = useGetLatest(defaultFn)\n const getDefaultWait = useGetLatest(defaultWait)\n\n return React.useCallback(\n async (...args) => {\n if (!debounceRef.current.promise) {\n debounceRef.current.promise = new Promise((resolve, reject) => {\n debounceRef.current.resolve = resolve\n debounceRef.current.reject = reject\n })\n }\n\n if (debounceRef.current.timeout) {\n clearTimeout(debounceRef.current.timeout)\n }\n\n debounceRef.current.timeout = setTimeout(async () => {\n delete debounceRef.current.timeout\n try {\n debounceRef.current.resolve(await getDefaultFn()(...args))\n } catch (err) {\n debounceRef.current.reject(err)\n } finally {\n delete debounceRef.current.promise\n }\n }, getDefaultWait())\n\n return debounceRef.current.promise\n },\n [getDefaultFn, getDefaultWait]\n )\n}\n\nexport function makeRenderer(instance, column, meta = {}) {\n return (type, userProps = {}) => {\n const Comp = typeof type === 'string' ? column[type] : type\n\n if (typeof Comp === 'undefined') {\n console.info(column)\n throw new Error(renderErr)\n }\n\n return flexRender(Comp, { ...instance, column, ...meta, ...userProps })\n }\n}\n\nexport function flexRender(Comp, props) {\n return isReactComponent(Comp) ? : Comp\n}\n\nfunction isReactComponent(component) {\n return (\n isClassComponent(component) ||\n typeof component === 'function' ||\n isExoticComponent(component)\n )\n}\n\nfunction isClassComponent(component) {\n return (\n typeof component === 'function' &&\n (() => {\n const proto = Object.getPrototypeOf(component)\n return proto.prototype && proto.prototype.isReactComponent\n })()\n )\n}\n\nfunction isExoticComponent(component) {\n return (\n typeof component === 'object' &&\n typeof component.$$typeof === 'symbol' &&\n ['react.memo', 'react.forward_ref'].includes(component.$$typeof.description)\n )\n}\n","import { defaultColumn, emptyRenderer } from './publicUtils'\n\n// Find the depth of the columns\nexport function findMaxDepth(columns, depth = 0) {\n return columns.reduce((prev, curr) => {\n if (curr.columns) {\n return Math.max(prev, findMaxDepth(curr.columns, depth + 1))\n }\n return depth\n }, 0)\n}\n\n// Build the visible columns, headers and flat column list\nexport function linkColumnStructure(columns, parent, depth = 0) {\n return columns.map(column => {\n column = {\n ...column,\n parent,\n depth,\n }\n\n assignColumnAccessor(column)\n\n if (column.columns) {\n column.columns = linkColumnStructure(column.columns, column, depth + 1)\n }\n return column\n })\n}\n\nexport function flattenColumns(columns) {\n return flattenBy(columns, 'columns')\n}\n\nexport function assignColumnAccessor(column) {\n // First check for string accessor\n let { id, accessor, Header } = column\n\n if (typeof accessor === 'string') {\n id = id || accessor\n const accessorPath = accessor.split('.')\n accessor = row => getBy(row, accessorPath)\n }\n\n if (!id && typeof Header === 'string' && Header) {\n id = Header\n }\n\n if (!id && column.columns) {\n console.error(column)\n throw new Error('A column ID (or unique \"Header\" value) is required!')\n }\n\n if (!id) {\n console.error(column)\n throw new Error('A column ID (or string accessor) is required!')\n }\n\n Object.assign(column, {\n id,\n accessor,\n })\n\n return column\n}\n\nexport function decorateColumn(column, userDefaultColumn) {\n if (!userDefaultColumn) {\n throw new Error()\n }\n Object.assign(column, {\n // Make sure there is a fallback header, just in case\n Header: emptyRenderer,\n Footer: emptyRenderer,\n ...defaultColumn,\n ...userDefaultColumn,\n ...column,\n })\n\n Object.assign(column, {\n originalWidth: column.width,\n })\n\n return column\n}\n\n// Build the header groups from the bottom up\nexport function makeHeaderGroups(\n allColumns,\n defaultColumn,\n additionalHeaderProperties = () => ({})\n) {\n const headerGroups = []\n\n let scanColumns = allColumns\n\n let uid = 0\n const getUID = () => uid++\n\n while (scanColumns.length) {\n // The header group we are creating\n const headerGroup = {\n headers: [],\n }\n\n // The parent columns we're going to scan next\n const parentColumns = []\n\n const hasParents = scanColumns.some(d => d.parent)\n\n // Scan each column for parents\n scanColumns.forEach(column => {\n // What is the latest (last) parent column?\n let latestParentColumn = [...parentColumns].reverse()[0]\n\n let newParent\n\n if (hasParents) {\n // If the column has a parent, add it if necessary\n if (column.parent) {\n newParent = {\n ...column.parent,\n originalId: column.parent.id,\n id: `${column.parent.id}_${getUID()}`,\n headers: [column],\n ...additionalHeaderProperties(column),\n }\n } else {\n // If other columns have parents, we'll need to add a place holder if necessary\n const originalId = `${column.id}_placeholder`\n newParent = decorateColumn(\n {\n originalId,\n id: `${column.id}_placeholder_${getUID()}`,\n placeholderOf: column,\n headers: [column],\n ...additionalHeaderProperties(column),\n },\n defaultColumn\n )\n }\n\n // If the resulting parent columns are the same, just add\n // the column and increment the header span\n if (\n latestParentColumn &&\n latestParentColumn.originalId === newParent.originalId\n ) {\n latestParentColumn.headers.push(column)\n } else {\n parentColumns.push(newParent)\n }\n }\n\n headerGroup.headers.push(column)\n })\n\n headerGroups.push(headerGroup)\n\n // Start scanning the parent columns\n scanColumns = parentColumns\n }\n\n return headerGroups.reverse()\n}\n\nconst pathObjCache = new Map()\n\nexport function getBy(obj, path, def) {\n if (!path) {\n return obj\n }\n const cacheKey = typeof path === 'function' ? path : JSON.stringify(path)\n\n const pathObj =\n pathObjCache.get(cacheKey) ||\n (() => {\n const pathObj = makePathArray(path)\n pathObjCache.set(cacheKey, pathObj)\n return pathObj\n })()\n\n let val\n\n try {\n val = pathObj.reduce((cursor, pathPart) => cursor[pathPart], obj)\n } catch (e) {\n // continue regardless of error\n }\n return typeof val !== 'undefined' ? val : def\n}\n\nexport function getFirstDefined(...args) {\n for (let i = 0; i < args.length; i += 1) {\n if (typeof args[i] !== 'undefined') {\n return args[i]\n }\n }\n}\n\nexport function getElementDimensions(element) {\n const rect = element.getBoundingClientRect()\n const style = window.getComputedStyle(element)\n const margins = {\n left: parseInt(style.marginLeft),\n right: parseInt(style.marginRight),\n }\n const padding = {\n left: parseInt(style.paddingLeft),\n right: parseInt(style.paddingRight),\n }\n return {\n left: Math.ceil(rect.left),\n width: Math.ceil(rect.width),\n outerWidth: Math.ceil(\n rect.width + margins.left + margins.right + padding.left + padding.right\n ),\n marginLeft: margins.left,\n marginRight: margins.right,\n paddingLeft: padding.left,\n paddingRight: padding.right,\n scrollWidth: element.scrollWidth,\n }\n}\n\nexport function isFunction(a) {\n if (typeof a === 'function') {\n return a\n }\n}\n\nexport function flattenBy(arr, key) {\n const flat = []\n\n const recurse = arr => {\n arr.forEach(d => {\n if (!d[key]) {\n flat.push(d)\n } else {\n recurse(d[key])\n }\n })\n }\n\n recurse(arr)\n\n return flat\n}\n\nexport function expandRows(\n rows,\n { manualExpandedKey, expanded, expandSubRows = true }\n) {\n const expandedRows = []\n\n const handleRow = (row, addToExpandedRows = true) => {\n row.isExpanded =\n (row.original && row.original[manualExpandedKey]) || expanded[row.id]\n\n row.canExpand = row.subRows && !!row.subRows.length\n\n if (addToExpandedRows) {\n expandedRows.push(row)\n }\n\n if (row.subRows && row.subRows.length && row.isExpanded) {\n row.subRows.forEach(row => handleRow(row, expandSubRows))\n }\n }\n\n rows.forEach(row => handleRow(row))\n\n return expandedRows\n}\n\nexport function getFilterMethod(filter, userFilterTypes, filterTypes) {\n return (\n isFunction(filter) ||\n userFilterTypes[filter] ||\n filterTypes[filter] ||\n filterTypes.text\n )\n}\n\nexport function shouldAutoRemoveFilter(autoRemove, value, column) {\n return autoRemove ? autoRemove(value, column) : typeof value === 'undefined'\n}\n\nexport function unpreparedAccessWarning() {\n throw new Error(\n 'React-Table: You have not called prepareRow(row) one or more rows you are attempting to render.'\n )\n}\n\nlet passiveSupported = null\nexport function passiveEventSupported() {\n // memoize support to avoid adding multiple test events\n if (typeof passiveSupported === 'boolean') return passiveSupported\n\n let supported = false\n try {\n const options = {\n get passive() {\n supported = true\n return false\n },\n }\n\n window.addEventListener('test', null, options)\n window.removeEventListener('test', null, options)\n } catch (err) {\n supported = false\n }\n passiveSupported = supported\n return passiveSupported\n}\n\n//\n\nconst reOpenBracket = /\\[/g\nconst reCloseBracket = /\\]/g\n\nfunction makePathArray(obj) {\n return (\n flattenDeep(obj)\n // remove all periods in parts\n .map(d => String(d).replace('.', '_'))\n // join parts using period\n .join('.')\n // replace brackets with periods\n .replace(reOpenBracket, '.')\n .replace(reCloseBracket, '')\n // split it back out on periods\n .split('.')\n )\n}\n\nfunction flattenDeep(arr, newArr = []) {\n if (!Array.isArray(arr)) {\n newArr.push(arr)\n } else {\n for (let i = 0; i < arr.length; i += 1) {\n flattenDeep(arr[i], newArr)\n }\n }\n return newArr\n}\n","const defaultGetTableProps = props => ({\n role: 'table',\n ...props,\n})\n\nconst defaultGetTableBodyProps = props => ({\n role: 'rowgroup',\n ...props,\n})\n\nconst defaultGetHeaderProps = (props, { column }) => ({\n key: `header_${column.id}`,\n colSpan: column.totalVisibleHeaderCount,\n role: 'columnheader',\n ...props,\n})\n\nconst defaultGetFooterProps = (props, { column }) => ({\n key: `footer_${column.id}`,\n colSpan: column.totalVisibleHeaderCount,\n ...props,\n})\n\nconst defaultGetHeaderGroupProps = (props, { index }) => ({\n key: `headerGroup_${index}`,\n role: 'row',\n ...props,\n})\n\nconst defaultGetFooterGroupProps = (props, { index }) => ({\n key: `footerGroup_${index}`,\n ...props,\n})\n\nconst defaultGetRowProps = (props, { row }) => ({\n key: `row_${row.id}`,\n role: 'row',\n ...props,\n})\n\nconst defaultGetCellProps = (props, { cell }) => ({\n key: `cell_${cell.row.id}_${cell.column.id}`,\n role: 'cell',\n ...props,\n})\n\nexport default function makeDefaultPluginHooks() {\n return {\n useOptions: [],\n stateReducers: [],\n useControlledState: [],\n columns: [],\n columnsDeps: [],\n allColumns: [],\n allColumnsDeps: [],\n accessValue: [],\n materializedColumns: [],\n materializedColumnsDeps: [],\n useInstanceAfterData: [],\n visibleColumns: [],\n visibleColumnsDeps: [],\n headerGroups: [],\n headerGroupsDeps: [],\n useInstanceBeforeDimensions: [],\n useInstance: [],\n prepareRow: [],\n getTableProps: [defaultGetTableProps],\n getTableBodyProps: [defaultGetTableBodyProps],\n getHeaderGroupProps: [defaultGetHeaderGroupProps],\n getFooterGroupProps: [defaultGetFooterGroupProps],\n getHeaderProps: [defaultGetHeaderProps],\n getFooterProps: [defaultGetFooterProps],\n getRowProps: [defaultGetRowProps],\n getCellProps: [defaultGetCellProps],\n useFinalInstance: [],\n }\n}\n","import React from 'react'\n\nimport {\n actions,\n functionalUpdate,\n useGetLatest,\n makePropGetter,\n useMountedLayoutEffect,\n} from '../publicUtils'\n\nactions.resetHiddenColumns = 'resetHiddenColumns'\nactions.toggleHideColumn = 'toggleHideColumn'\nactions.setHiddenColumns = 'setHiddenColumns'\nactions.toggleHideAllColumns = 'toggleHideAllColumns'\n\nexport const useColumnVisibility = hooks => {\n hooks.getToggleHiddenProps = [defaultGetToggleHiddenProps]\n hooks.getToggleHideAllColumnsProps = [defaultGetToggleHideAllColumnsProps]\n\n hooks.stateReducers.push(reducer)\n hooks.useInstanceBeforeDimensions.push(useInstanceBeforeDimensions)\n hooks.headerGroupsDeps.push((deps, { instance }) => [\n ...deps,\n instance.state.hiddenColumns,\n ])\n hooks.useInstance.push(useInstance)\n}\n\nuseColumnVisibility.pluginName = 'useColumnVisibility'\n\nconst defaultGetToggleHiddenProps = (props, { column }) => [\n props,\n {\n onChange: e => {\n column.toggleHidden(!e.target.checked)\n },\n style: {\n cursor: 'pointer',\n },\n checked: column.isVisible,\n title: 'Toggle Column Visible',\n },\n]\n\nconst defaultGetToggleHideAllColumnsProps = (props, { instance }) => [\n props,\n {\n onChange: e => {\n instance.toggleHideAllColumns(!e.target.checked)\n },\n style: {\n cursor: 'pointer',\n },\n checked: !instance.allColumnsHidden && !instance.state.hiddenColumns.length,\n title: 'Toggle All Columns Hidden',\n indeterminate:\n !instance.allColumnsHidden && instance.state.hiddenColumns.length,\n },\n]\n\nfunction reducer(state, action, previousState, instance) {\n if (action.type === actions.init) {\n return {\n hiddenColumns: [],\n ...state,\n }\n }\n\n if (action.type === actions.resetHiddenColumns) {\n return {\n ...state,\n hiddenColumns: instance.initialState.hiddenColumns || [],\n }\n }\n\n if (action.type === actions.toggleHideColumn) {\n const should =\n typeof action.value !== 'undefined'\n ? action.value\n : !state.hiddenColumns.includes(action.columnId)\n\n const hiddenColumns = should\n ? [...state.hiddenColumns, action.columnId]\n : state.hiddenColumns.filter(d => d !== action.columnId)\n\n return {\n ...state,\n hiddenColumns,\n }\n }\n\n if (action.type === actions.setHiddenColumns) {\n return {\n ...state,\n hiddenColumns: functionalUpdate(action.value, state.hiddenColumns),\n }\n }\n\n if (action.type === actions.toggleHideAllColumns) {\n const shouldAll =\n typeof action.value !== 'undefined'\n ? action.value\n : !state.hiddenColumns.length\n\n return {\n ...state,\n hiddenColumns: shouldAll ? instance.allColumns.map(d => d.id) : [],\n }\n }\n}\n\nfunction useInstanceBeforeDimensions(instance) {\n const {\n headers,\n state: { hiddenColumns },\n } = instance\n\n const isMountedRef = React.useRef(false)\n\n if (!isMountedRef.current) {\n }\n\n const handleColumn = (column, parentVisible) => {\n column.isVisible = parentVisible && !hiddenColumns.includes(column.id)\n\n let totalVisibleHeaderCount = 0\n\n if (column.headers && column.headers.length) {\n column.headers.forEach(\n subColumn =>\n (totalVisibleHeaderCount += handleColumn(subColumn, column.isVisible))\n )\n } else {\n totalVisibleHeaderCount = column.isVisible ? 1 : 0\n }\n\n column.totalVisibleHeaderCount = totalVisibleHeaderCount\n\n return totalVisibleHeaderCount\n }\n\n let totalVisibleHeaderCount = 0\n\n headers.forEach(\n subHeader => (totalVisibleHeaderCount += handleColumn(subHeader, true))\n )\n}\n\nfunction useInstance(instance) {\n const {\n columns,\n flatHeaders,\n dispatch,\n allColumns,\n getHooks,\n state: { hiddenColumns },\n autoResetHiddenColumns = true,\n } = instance\n\n const getInstance = useGetLatest(instance)\n\n const allColumnsHidden = allColumns.length === hiddenColumns.length\n\n const toggleHideColumn = React.useCallback(\n (columnId, value) =>\n dispatch({ type: actions.toggleHideColumn, columnId, value }),\n [dispatch]\n )\n\n const setHiddenColumns = React.useCallback(\n value => dispatch({ type: actions.setHiddenColumns, value }),\n [dispatch]\n )\n\n const toggleHideAllColumns = React.useCallback(\n value => dispatch({ type: actions.toggleHideAllColumns, value }),\n [dispatch]\n )\n\n const getToggleHideAllColumnsProps = makePropGetter(\n getHooks().getToggleHideAllColumnsProps,\n { instance: getInstance() }\n )\n\n flatHeaders.forEach(column => {\n column.toggleHidden = value => {\n dispatch({\n type: actions.toggleHideColumn,\n columnId: column.id,\n value,\n })\n }\n\n column.getToggleHiddenProps = makePropGetter(\n getHooks().getToggleHiddenProps,\n {\n instance: getInstance(),\n column,\n }\n )\n })\n\n const getAutoResetHiddenColumns = useGetLatest(autoResetHiddenColumns)\n\n useMountedLayoutEffect(() => {\n if (getAutoResetHiddenColumns()) {\n dispatch({ type: actions.resetHiddenColumns })\n }\n }, [dispatch, columns])\n\n Object.assign(instance, {\n allColumnsHidden,\n toggleHideColumn,\n setHiddenColumns,\n toggleHideAllColumns,\n getToggleHideAllColumnsProps,\n })\n}\n","import React from 'react'\n\n//\n\nimport {\n linkColumnStructure,\n flattenColumns,\n assignColumnAccessor,\n unpreparedAccessWarning,\n makeHeaderGroups,\n decorateColumn,\n} from '../utils'\n\nimport {\n useGetLatest,\n reduceHooks,\n actions,\n loopHooks,\n makePropGetter,\n makeRenderer,\n} from '../publicUtils'\n\nimport makeDefaultPluginHooks from '../makeDefaultPluginHooks'\n\nimport { useColumnVisibility } from './useColumnVisibility'\n\nconst defaultInitialState = {}\nconst defaultColumnInstance = {}\nconst defaultReducer = (state, action, prevState) => state\nconst defaultGetSubRows = (row, index) => row.subRows || []\nconst defaultGetRowId = (row, index, parent) =>\n `${parent ? [parent.id, index].join('.') : index}`\nconst defaultUseControlledState = d => d\n\nfunction applyDefaults(props) {\n const {\n initialState = defaultInitialState,\n defaultColumn = defaultColumnInstance,\n getSubRows = defaultGetSubRows,\n getRowId = defaultGetRowId,\n stateReducer = defaultReducer,\n useControlledState = defaultUseControlledState,\n ...rest\n } = props\n\n return {\n ...rest,\n initialState,\n defaultColumn,\n getSubRows,\n getRowId,\n stateReducer,\n useControlledState,\n }\n}\n\nexport const useTable = (props, ...plugins) => {\n // Apply default props\n props = applyDefaults(props)\n\n // Add core plugins\n plugins = [useColumnVisibility, ...plugins]\n\n // Create the table instance\n let instanceRef = React.useRef({})\n\n // Create a getter for the instance (helps avoid a lot of potential memory leaks)\n const getInstance = useGetLatest(instanceRef.current)\n\n // Assign the props, plugins and hooks to the instance\n Object.assign(getInstance(), {\n ...props,\n plugins,\n hooks: makeDefaultPluginHooks(),\n })\n\n // Allow plugins to register hooks as early as possible\n plugins.filter(Boolean).forEach(plugin => {\n plugin(getInstance().hooks)\n })\n\n // Consume all hooks and make a getter for them\n const getHooks = useGetLatest(getInstance().hooks)\n getInstance().getHooks = getHooks\n delete getInstance().hooks\n\n // Allow useOptions hooks to modify the options coming into the table\n Object.assign(\n getInstance(),\n reduceHooks(getHooks().useOptions, applyDefaults(props))\n )\n\n const {\n data,\n columns: userColumns,\n initialState,\n defaultColumn,\n getSubRows,\n getRowId,\n stateReducer,\n useControlledState,\n } = getInstance()\n\n // Setup user reducer ref\n const getStateReducer = useGetLatest(stateReducer)\n\n // Build the reducer\n const reducer = React.useCallback(\n (state, action) => {\n // Detect invalid actions\n if (!action.type) {\n console.info({ action })\n throw new Error('Unknown Action 👆')\n }\n\n // Reduce the state from all plugin reducers\n return [\n ...getHooks().stateReducers,\n // Allow the user to add their own state reducer(s)\n ...(Array.isArray(getStateReducer())\n ? getStateReducer()\n : [getStateReducer()]),\n ].reduce(\n (s, handler) => handler(s, action, state, getInstance()) || s,\n state\n )\n },\n [getHooks, getStateReducer, getInstance]\n )\n\n // Start the reducer\n const [reducerState, dispatch] = React.useReducer(reducer, undefined, () =>\n reducer(initialState, { type: actions.init })\n )\n\n // Allow the user to control the final state with hooks\n const state = reduceHooks(\n [...getHooks().useControlledState, useControlledState],\n reducerState,\n { instance: getInstance() }\n )\n\n Object.assign(getInstance(), {\n state,\n dispatch,\n })\n\n // Decorate All the columns\n const columns = React.useMemo(\n () =>\n linkColumnStructure(\n reduceHooks(getHooks().columns, userColumns, {\n instance: getInstance(),\n })\n ),\n [\n getHooks,\n getInstance,\n userColumns,\n // eslint-disable-next-line react-hooks/exhaustive-deps\n ...reduceHooks(getHooks().columnsDeps, [], { instance: getInstance() }),\n ]\n )\n getInstance().columns = columns\n\n // Get the flat list of all columns and allow hooks to decorate\n // those columns (and trigger this memoization via deps)\n let allColumns = React.useMemo(\n () =>\n reduceHooks(getHooks().allColumns, flattenColumns(columns), {\n instance: getInstance(),\n }).map(assignColumnAccessor),\n [\n columns,\n getHooks,\n getInstance,\n // eslint-disable-next-line react-hooks/exhaustive-deps\n ...reduceHooks(getHooks().allColumnsDeps, [], {\n instance: getInstance(),\n }),\n ]\n )\n getInstance().allColumns = allColumns\n\n // Access the row model using initial columns\n const [rows, flatRows, rowsById] = React.useMemo(() => {\n let rows = []\n let flatRows = []\n const rowsById = {}\n\n const allColumnsQueue = [...allColumns]\n\n while (allColumnsQueue.length) {\n const column = allColumnsQueue.shift()\n accessRowsForColumn({\n data,\n rows,\n flatRows,\n rowsById,\n column,\n getRowId,\n getSubRows,\n accessValueHooks: getHooks().accessValue,\n getInstance,\n })\n }\n\n return [rows, flatRows, rowsById]\n }, [allColumns, data, getRowId, getSubRows, getHooks, getInstance])\n\n Object.assign(getInstance(), {\n rows,\n initialRows: [...rows],\n flatRows,\n rowsById,\n // materializedColumns,\n })\n\n loopHooks(getHooks().useInstanceAfterData, getInstance())\n\n // Get the flat list of all columns AFTER the rows\n // have been access, and allow hooks to decorate\n // those columns (and trigger this memoization via deps)\n let visibleColumns = React.useMemo(\n () =>\n reduceHooks(getHooks().visibleColumns, allColumns, {\n instance: getInstance(),\n }).map(d => decorateColumn(d, defaultColumn)),\n [\n getHooks,\n allColumns,\n getInstance,\n defaultColumn,\n // eslint-disable-next-line react-hooks/exhaustive-deps\n ...reduceHooks(getHooks().visibleColumnsDeps, [], {\n instance: getInstance(),\n }),\n ]\n )\n\n // Combine new visible columns with all columns\n allColumns = React.useMemo(() => {\n const columns = [...visibleColumns]\n\n allColumns.forEach(column => {\n if (!columns.find(d => d.id === column.id)) {\n columns.push(column)\n }\n })\n\n return columns\n }, [allColumns, visibleColumns])\n getInstance().allColumns = allColumns\n\n if (process.env.NODE_ENV !== 'production') {\n const duplicateColumns = allColumns.filter((column, i) => {\n return allColumns.findIndex(d => d.id === column.id) !== i\n })\n\n if (duplicateColumns.length) {\n console.info(allColumns)\n throw new Error(\n `Duplicate columns were found with ids: \"${duplicateColumns\n .map(d => d.id)\n .join(', ')}\" in the columns array above`\n )\n }\n }\n\n // Make the headerGroups\n const headerGroups = React.useMemo(\n () =>\n reduceHooks(\n getHooks().headerGroups,\n makeHeaderGroups(visibleColumns, defaultColumn),\n getInstance()\n ),\n [\n getHooks,\n visibleColumns,\n defaultColumn,\n getInstance,\n // eslint-disable-next-line react-hooks/exhaustive-deps\n ...reduceHooks(getHooks().headerGroupsDeps, [], {\n instance: getInstance(),\n }),\n ]\n )\n getInstance().headerGroups = headerGroups\n\n // Get the first level of headers\n const headers = React.useMemo(\n () => (headerGroups.length ? headerGroups[0].headers : []),\n [headerGroups]\n )\n getInstance().headers = headers\n\n // Provide a flat header list for utilities\n getInstance().flatHeaders = headerGroups.reduce(\n (all, headerGroup) => [...all, ...headerGroup.headers],\n []\n )\n\n loopHooks(getHooks().useInstanceBeforeDimensions, getInstance())\n\n // Filter columns down to visible ones\n const visibleColumnsDep = visibleColumns\n .filter(d => d.isVisible)\n .map(d => d.id)\n .sort()\n .join('_')\n\n visibleColumns = React.useMemo(\n () => visibleColumns.filter(d => d.isVisible),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [visibleColumns, visibleColumnsDep]\n )\n getInstance().visibleColumns = visibleColumns\n\n // Header Visibility is needed by this point\n const [\n totalColumnsMinWidth,\n totalColumnsWidth,\n totalColumnsMaxWidth,\n ] = calculateHeaderWidths(headers)\n\n getInstance().totalColumnsMinWidth = totalColumnsMinWidth\n getInstance().totalColumnsWidth = totalColumnsWidth\n getInstance().totalColumnsMaxWidth = totalColumnsMaxWidth\n\n loopHooks(getHooks().useInstance, getInstance())\n\n // Each materialized header needs to be assigned a render function and other\n // prop getter properties here.\n ;[...getInstance().flatHeaders, ...getInstance().allColumns].forEach(\n column => {\n // Give columns/headers rendering power\n column.render = makeRenderer(getInstance(), column)\n\n // Give columns/headers a default getHeaderProps\n column.getHeaderProps = makePropGetter(getHooks().getHeaderProps, {\n instance: getInstance(),\n column,\n })\n\n // Give columns/headers a default getFooterProps\n column.getFooterProps = makePropGetter(getHooks().getFooterProps, {\n instance: getInstance(),\n column,\n })\n }\n )\n\n getInstance().headerGroups = React.useMemo(\n () =>\n headerGroups.filter((headerGroup, i) => {\n // Filter out any headers and headerGroups that don't have visible columns\n headerGroup.headers = headerGroup.headers.filter(column => {\n const recurse = headers =>\n headers.filter(column => {\n if (column.headers) {\n return recurse(column.headers)\n }\n return column.isVisible\n }).length\n if (column.headers) {\n return recurse(column.headers)\n }\n return column.isVisible\n })\n\n // Give headerGroups getRowProps\n if (headerGroup.headers.length) {\n headerGroup.getHeaderGroupProps = makePropGetter(\n getHooks().getHeaderGroupProps,\n { instance: getInstance(), headerGroup, index: i }\n )\n\n headerGroup.getFooterGroupProps = makePropGetter(\n getHooks().getFooterGroupProps,\n { instance: getInstance(), headerGroup, index: i }\n )\n\n return true\n }\n\n return false\n }),\n [headerGroups, getInstance, getHooks]\n )\n\n getInstance().footerGroups = [...getInstance().headerGroups].reverse()\n\n // The prepareRow function is absolutely necessary and MUST be called on\n // any rows the user wishes to be displayed.\n\n getInstance().prepareRow = React.useCallback(\n row => {\n row.getRowProps = makePropGetter(getHooks().getRowProps, {\n instance: getInstance(),\n row,\n })\n\n // Build the visible cells for each row\n row.allCells = allColumns.map(column => {\n const value = row.values[column.id]\n\n const cell = {\n column,\n row,\n value,\n }\n\n // Give each cell a getCellProps base\n cell.getCellProps = makePropGetter(getHooks().getCellProps, {\n instance: getInstance(),\n cell,\n })\n\n // Give each cell a renderer function (supports multiple renderers)\n cell.render = makeRenderer(getInstance(), column, {\n row,\n cell,\n value,\n })\n\n return cell\n })\n\n row.cells = visibleColumns.map(column =>\n row.allCells.find(cell => cell.column.id === column.id)\n )\n\n // need to apply any row specific hooks (useExpanded requires this)\n loopHooks(getHooks().prepareRow, row, { instance: getInstance() })\n },\n [getHooks, getInstance, allColumns, visibleColumns]\n )\n\n getInstance().getTableProps = makePropGetter(getHooks().getTableProps, {\n instance: getInstance(),\n })\n\n getInstance().getTableBodyProps = makePropGetter(\n getHooks().getTableBodyProps,\n {\n instance: getInstance(),\n }\n )\n\n loopHooks(getHooks().useFinalInstance, getInstance())\n\n return getInstance()\n}\n\nfunction calculateHeaderWidths(headers, left = 0) {\n let sumTotalMinWidth = 0\n let sumTotalWidth = 0\n let sumTotalMaxWidth = 0\n let sumTotalFlexWidth = 0\n\n headers.forEach(header => {\n let { headers: subHeaders } = header\n\n header.totalLeft = left\n\n if (subHeaders && subHeaders.length) {\n const [\n totalMinWidth,\n totalWidth,\n totalMaxWidth,\n totalFlexWidth,\n ] = calculateHeaderWidths(subHeaders, left)\n header.totalMinWidth = totalMinWidth\n header.totalWidth = totalWidth\n header.totalMaxWidth = totalMaxWidth\n header.totalFlexWidth = totalFlexWidth\n } else {\n header.totalMinWidth = header.minWidth\n header.totalWidth = Math.min(\n Math.max(header.minWidth, header.width),\n header.maxWidth\n )\n header.totalMaxWidth = header.maxWidth\n header.totalFlexWidth = header.canResize ? header.totalWidth : 0\n }\n if (header.isVisible) {\n left += header.totalWidth\n sumTotalMinWidth += header.totalMinWidth\n sumTotalWidth += header.totalWidth\n sumTotalMaxWidth += header.totalMaxWidth\n sumTotalFlexWidth += header.totalFlexWidth\n }\n })\n\n return [sumTotalMinWidth, sumTotalWidth, sumTotalMaxWidth, sumTotalFlexWidth]\n}\n\nfunction accessRowsForColumn({\n data,\n rows,\n flatRows,\n rowsById,\n column,\n getRowId,\n getSubRows,\n accessValueHooks,\n getInstance,\n}) {\n // Access the row's data column-by-column\n // We do it this way so we can incrementally add materialized\n // columns after the first pass and avoid excessive looping\n const accessRow = (originalRow, rowIndex, depth = 0, parent, parentRows) => {\n // Keep the original reference around\n const original = originalRow\n\n const id = getRowId(originalRow, rowIndex, parent)\n\n let row = rowsById[id]\n\n // If the row hasn't been created, let's make it\n if (!row) {\n row = {\n id,\n original,\n index: rowIndex,\n depth,\n cells: [{}], // This is a dummy cell\n }\n\n // Override common array functions (and the dummy cell's getCellProps function)\n // to show an error if it is accessed without calling prepareRow\n row.cells.map = unpreparedAccessWarning\n row.cells.filter = unpreparedAccessWarning\n row.cells.forEach = unpreparedAccessWarning\n row.cells[0].getCellProps = unpreparedAccessWarning\n\n // Create the cells and values\n row.values = {}\n\n // Push this row into the parentRows array\n parentRows.push(row)\n // Keep track of every row in a flat array\n flatRows.push(row)\n // Also keep track of every row by its ID\n rowsById[id] = row\n\n // Get the original subrows\n row.originalSubRows = getSubRows(originalRow, rowIndex)\n\n // Then recursively access them\n if (row.originalSubRows) {\n const subRows = []\n row.originalSubRows.forEach((d, i) =>\n accessRow(d, i, depth + 1, row, subRows)\n )\n // Keep the new subRows array on the row\n row.subRows = subRows\n }\n } else if (row.subRows) {\n // If the row exists, then it's already been accessed\n // Keep recursing, but don't worry about passing the\n // accumlator array (those rows already exist)\n row.originalSubRows.forEach((d, i) => accessRow(d, i, depth + 1, row))\n }\n\n // If the column has an accessor, use it to get a value\n if (column.accessor) {\n row.values[column.id] = column.accessor(\n originalRow,\n rowIndex,\n row,\n parentRows,\n data\n )\n }\n\n // Allow plugins to manipulate the column value\n row.values[column.id] = reduceHooks(\n accessValueHooks,\n row.values[column.id],\n {\n row,\n column,\n instance: getInstance(),\n },\n true\n )\n }\n\n data.forEach((originalRow, rowIndex) =>\n accessRow(originalRow, rowIndex, 0, undefined, rows)\n )\n}\n","import React from 'react'\n\nimport { expandRows } from '../utils'\n\nimport {\n useGetLatest,\n actions,\n useMountedLayoutEffect,\n makePropGetter,\n ensurePluginOrder,\n} from '../publicUtils'\n\n// Actions\nactions.resetExpanded = 'resetExpanded'\nactions.toggleRowExpanded = 'toggleRowExpanded'\nactions.toggleAllRowsExpanded = 'toggleAllRowsExpanded'\n\nexport const useExpanded = hooks => {\n hooks.getToggleAllRowsExpandedProps = [defaultGetToggleAllRowsExpandedProps]\n hooks.getToggleRowExpandedProps = [defaultGetToggleRowExpandedProps]\n hooks.stateReducers.push(reducer)\n hooks.useInstance.push(useInstance)\n hooks.prepareRow.push(prepareRow)\n}\n\nuseExpanded.pluginName = 'useExpanded'\n\nconst defaultGetToggleAllRowsExpandedProps = (props, { instance }) => [\n props,\n {\n onClick: e => {\n instance.toggleAllRowsExpanded()\n },\n style: {\n cursor: 'pointer',\n },\n title: 'Toggle All Rows Expanded',\n },\n]\n\nconst defaultGetToggleRowExpandedProps = (props, { row }) => [\n props,\n {\n onClick: () => {\n row.toggleRowExpanded()\n },\n style: {\n cursor: 'pointer',\n },\n title: 'Toggle Row Expanded',\n },\n]\n\n// Reducer\nfunction reducer(state, action, previousState, instance) {\n if (action.type === actions.init) {\n return {\n expanded: {},\n ...state,\n }\n }\n\n if (action.type === actions.resetExpanded) {\n return {\n ...state,\n expanded: instance.initialState.expanded || {},\n }\n }\n\n if (action.type === actions.toggleAllRowsExpanded) {\n const { value } = action\n const { isAllRowsExpanded, rowsById } = instance\n\n const expandAll = typeof value !== 'undefined' ? value : !isAllRowsExpanded\n\n if (expandAll) {\n const expanded = {}\n\n Object.keys(rowsById).forEach(rowId => {\n expanded[rowId] = true\n })\n\n return {\n ...state,\n expanded,\n }\n }\n\n return {\n ...state,\n expanded: {},\n }\n }\n\n if (action.type === actions.toggleRowExpanded) {\n const { id, value: setExpanded } = action\n const exists = state.expanded[id]\n\n const shouldExist =\n typeof setExpanded !== 'undefined' ? setExpanded : !exists\n\n if (!exists && shouldExist) {\n return {\n ...state,\n expanded: {\n ...state.expanded,\n [id]: true,\n },\n }\n } else if (exists && !shouldExist) {\n const { [id]: _, ...rest } = state.expanded\n return {\n ...state,\n expanded: rest,\n }\n } else {\n return state\n }\n }\n}\n\nfunction useInstance(instance) {\n const {\n data,\n rows,\n rowsById,\n manualExpandedKey = 'expanded',\n paginateExpandedRows = true,\n expandSubRows = true,\n autoResetExpanded = true,\n getHooks,\n plugins,\n state: { expanded },\n dispatch,\n } = instance\n\n ensurePluginOrder(\n plugins,\n ['useSortBy', 'useGroupBy', 'usePivotColumns', 'useGlobalFilter'],\n 'useExpanded'\n )\n\n const getAutoResetExpanded = useGetLatest(autoResetExpanded)\n\n let isAllRowsExpanded = Boolean(\n Object.keys(rowsById).length && Object.keys(expanded).length\n )\n\n if (isAllRowsExpanded) {\n if (Object.keys(rowsById).some(id => !expanded[id])) {\n isAllRowsExpanded = false\n }\n }\n\n // Bypass any effects from firing when this changes\n useMountedLayoutEffect(() => {\n if (getAutoResetExpanded()) {\n dispatch({ type: actions.resetExpanded })\n }\n }, [dispatch, data])\n\n const toggleRowExpanded = React.useCallback(\n (id, value) => {\n dispatch({ type: actions.toggleRowExpanded, id, value })\n },\n [dispatch]\n )\n\n const toggleAllRowsExpanded = React.useCallback(\n value => dispatch({ type: actions.toggleAllRowsExpanded, value }),\n [dispatch]\n )\n\n const expandedRows = React.useMemo(() => {\n if (paginateExpandedRows) {\n return expandRows(rows, { manualExpandedKey, expanded, expandSubRows })\n }\n\n return rows\n }, [paginateExpandedRows, rows, manualExpandedKey, expanded, expandSubRows])\n\n const expandedDepth = React.useMemo(() => findExpandedDepth(expanded), [\n expanded,\n ])\n\n const getInstance = useGetLatest(instance)\n\n const getToggleAllRowsExpandedProps = makePropGetter(\n getHooks().getToggleAllRowsExpandedProps,\n { instance: getInstance() }\n )\n\n Object.assign(instance, {\n preExpandedRows: rows,\n expandedRows,\n rows: expandedRows,\n expandedDepth,\n isAllRowsExpanded,\n toggleRowExpanded,\n toggleAllRowsExpanded,\n getToggleAllRowsExpandedProps,\n })\n}\n\nfunction prepareRow(row, { instance: { getHooks }, instance }) {\n row.toggleRowExpanded = set => instance.toggleRowExpanded(row.id, set)\n\n row.getToggleRowExpandedProps = makePropGetter(\n getHooks().getToggleRowExpandedProps,\n {\n instance,\n row,\n }\n )\n}\n\nfunction findExpandedDepth(expanded) {\n let maxDepth = 0\n\n Object.keys(expanded).forEach(id => {\n const splitId = id.split('.')\n maxDepth = Math.max(maxDepth, splitId.length)\n })\n\n return maxDepth\n}\n","export const text = (rows, ids, filterValue) => {\n rows = rows.filter(row => {\n return ids.some(id => {\n const rowValue = row.values[id]\n return String(rowValue)\n .toLowerCase()\n .includes(String(filterValue).toLowerCase())\n })\n })\n return rows\n}\n\ntext.autoRemove = val => !val\n\nexport const exactText = (rows, ids, filterValue) => {\n return rows.filter(row => {\n return ids.some(id => {\n const rowValue = row.values[id]\n return rowValue !== undefined\n ? String(rowValue).toLowerCase() === String(filterValue).toLowerCase()\n : true\n })\n })\n}\n\nexactText.autoRemove = val => !val\n\nexport const exactTextCase = (rows, ids, filterValue) => {\n return rows.filter(row => {\n return ids.some(id => {\n const rowValue = row.values[id]\n return rowValue !== undefined\n ? String(rowValue) === String(filterValue)\n : true\n })\n })\n}\n\nexactTextCase.autoRemove = val => !val\n\nexport const includes = (rows, ids, filterValue) => {\n return rows.filter(row => {\n return ids.some(id => {\n const rowValue = row.values[id]\n return rowValue.includes(filterValue)\n })\n })\n}\n\nincludes.autoRemove = val => !val || !val.length\n\nexport const includesAll = (rows, ids, filterValue) => {\n return rows.filter(row => {\n return ids.some(id => {\n const rowValue = row.values[id]\n return (\n rowValue &&\n rowValue.length &&\n filterValue.every(val => rowValue.includes(val))\n )\n })\n })\n}\n\nincludesAll.autoRemove = val => !val || !val.length\n\nexport const includesSome = (rows, ids, filterValue) => {\n return rows.filter(row => {\n return ids.some(id => {\n const rowValue = row.values[id]\n return (\n rowValue &&\n rowValue.length &&\n filterValue.some(val => rowValue.includes(val))\n )\n })\n })\n}\n\nincludesSome.autoRemove = val => !val || !val.length\n\nexport const includesValue = (rows, ids, filterValue) => {\n return rows.filter(row => {\n return ids.some(id => {\n const rowValue = row.values[id]\n return filterValue.includes(rowValue)\n })\n })\n}\n\nincludesValue.autoRemove = val => !val || !val.length\n\nexport const exact = (rows, ids, filterValue) => {\n return rows.filter(row => {\n return ids.some(id => {\n const rowValue = row.values[id]\n return rowValue === filterValue\n })\n })\n}\n\nexact.autoRemove = val => typeof val === 'undefined'\n\nexport const equals = (rows, ids, filterValue) => {\n return rows.filter(row => {\n return ids.some(id => {\n const rowValue = row.values[id]\n // eslint-disable-next-line eqeqeq\n return rowValue == filterValue\n })\n })\n}\n\nequals.autoRemove = val => val == null\n\nexport const between = (rows, ids, filterValue) => {\n let [min, max] = filterValue || []\n\n min = typeof min === 'number' ? min : -Infinity\n max = typeof max === 'number' ? max : Infinity\n\n if (min > max) {\n const temp = min\n min = max\n max = temp\n }\n\n return rows.filter(row => {\n return ids.some(id => {\n const rowValue = row.values[id]\n return rowValue >= min && rowValue <= max\n })\n })\n}\n\nbetween.autoRemove = val =>\n !val || (typeof val[0] !== 'number' && typeof val[1] !== 'number')\n","import React from 'react'\n\nimport {\n getFirstDefined,\n getFilterMethod,\n shouldAutoRemoveFilter,\n} from '../utils'\n\nimport {\n actions,\n useGetLatest,\n functionalUpdate,\n useMountedLayoutEffect,\n} from '../publicUtils'\n\nimport * as filterTypes from '../filterTypes'\n\n// Actions\nactions.resetFilters = 'resetFilters'\nactions.setFilter = 'setFilter'\nactions.setAllFilters = 'setAllFilters'\n\nexport const useFilters = hooks => {\n hooks.stateReducers.push(reducer)\n hooks.useInstance.push(useInstance)\n}\n\nuseFilters.pluginName = 'useFilters'\n\nfunction reducer(state, action, previousState, instance) {\n if (action.type === actions.init) {\n return {\n filters: [],\n ...state,\n }\n }\n\n if (action.type === actions.resetFilters) {\n return {\n ...state,\n filters: instance.initialState.filters || [],\n }\n }\n\n if (action.type === actions.setFilter) {\n const { columnId, filterValue } = action\n const { allColumns, filterTypes: userFilterTypes } = instance\n\n const column = allColumns.find(d => d.id === columnId)\n\n if (!column) {\n throw new Error(\n `React-Table: Could not find a column with id: ${columnId}`\n )\n }\n\n const filterMethod = getFilterMethod(\n column.filter,\n userFilterTypes || {},\n filterTypes\n )\n\n const previousfilter = state.filters.find(d => d.id === columnId)\n\n const newFilter = functionalUpdate(\n filterValue,\n previousfilter && previousfilter.value\n )\n\n //\n if (shouldAutoRemoveFilter(filterMethod.autoRemove, newFilter, column)) {\n return {\n ...state,\n filters: state.filters.filter(d => d.id !== columnId),\n }\n }\n\n if (previousfilter) {\n return {\n ...state,\n filters: state.filters.map(d => {\n if (d.id === columnId) {\n return { id: columnId, value: newFilter }\n }\n return d\n }),\n }\n }\n\n return {\n ...state,\n filters: [...state.filters, { id: columnId, value: newFilter }],\n }\n }\n\n if (action.type === actions.setAllFilters) {\n const { filters } = action\n const { allColumns, filterTypes: userFilterTypes } = instance\n\n return {\n ...state,\n // Filter out undefined values\n filters: functionalUpdate(filters, state.filters).filter(filter => {\n const column = allColumns.find(d => d.id === filter.id)\n const filterMethod = getFilterMethod(\n column.filter,\n userFilterTypes || {},\n filterTypes\n )\n\n if (\n shouldAutoRemoveFilter(filterMethod.autoRemove, filter.value, column)\n ) {\n return false\n }\n return true\n }),\n }\n }\n}\n\nfunction useInstance(instance) {\n const {\n data,\n rows,\n flatRows,\n rowsById,\n allColumns,\n filterTypes: userFilterTypes,\n manualFilters,\n defaultCanFilter = false,\n disableFilters,\n state: { filters },\n dispatch,\n autoResetFilters = true,\n } = instance\n\n const setFilter = React.useCallback(\n (columnId, filterValue) => {\n dispatch({ type: actions.setFilter, columnId, filterValue })\n },\n [dispatch]\n )\n\n const setAllFilters = React.useCallback(\n filters => {\n dispatch({\n type: actions.setAllFilters,\n filters,\n })\n },\n [dispatch]\n )\n\n allColumns.forEach(column => {\n const {\n id,\n accessor,\n defaultCanFilter: columnDefaultCanFilter,\n disableFilters: columnDisableFilters,\n } = column\n\n // Determine if a column is filterable\n column.canFilter = accessor\n ? getFirstDefined(\n columnDisableFilters === true ? false : undefined,\n disableFilters === true ? false : undefined,\n true\n )\n : getFirstDefined(columnDefaultCanFilter, defaultCanFilter, false)\n\n // Provide the column a way of updating the filter value\n column.setFilter = val => setFilter(column.id, val)\n\n // Provide the current filter value to the column for\n // convenience\n const found = filters.find(d => d.id === id)\n column.filterValue = found && found.value\n })\n\n const [\n filteredRows,\n filteredFlatRows,\n filteredRowsById,\n ] = React.useMemo(() => {\n if (manualFilters || !filters.length) {\n return [rows, flatRows, rowsById]\n }\n\n const filteredFlatRows = []\n const filteredRowsById = {}\n\n // Filters top level and nested rows\n const filterRows = (rows, depth = 0) => {\n let filteredRows = rows\n\n filteredRows = filters.reduce(\n (filteredSoFar, { id: columnId, value: filterValue }) => {\n // Find the filters column\n const column = allColumns.find(d => d.id === columnId)\n\n if (!column) {\n return filteredSoFar\n }\n\n if (depth === 0) {\n column.preFilteredRows = filteredSoFar\n }\n\n const filterMethod = getFilterMethod(\n column.filter,\n userFilterTypes || {},\n filterTypes\n )\n\n if (!filterMethod) {\n console.warn(\n `Could not find a valid 'column.filter' for column with the ID: ${column.id}.`\n )\n return filteredSoFar\n }\n\n // Pass the rows, id, filterValue and column to the filterMethod\n // to get the filtered rows back\n column.filteredRows = filterMethod(\n filteredSoFar,\n [columnId],\n filterValue\n )\n\n return column.filteredRows\n },\n rows\n )\n\n // Apply the filter to any subRows\n // We technically could do this recursively in the above loop,\n // but that would severely hinder the API for the user, since they\n // would be required to do that recursion in some scenarios\n filteredRows.forEach(row => {\n filteredFlatRows.push(row)\n filteredRowsById[row.id] = row\n if (!row.subRows) {\n return\n }\n\n row.subRows =\n row.subRows && row.subRows.length > 0\n ? filterRows(row.subRows, depth + 1)\n : row.subRows\n })\n\n return filteredRows\n }\n\n return [filterRows(rows), filteredFlatRows, filteredRowsById]\n }, [\n manualFilters,\n filters,\n rows,\n flatRows,\n rowsById,\n allColumns,\n userFilterTypes,\n ])\n\n React.useMemo(() => {\n // Now that each filtered column has it's partially filtered rows,\n // lets assign the final filtered rows to all of the other columns\n const nonFilteredColumns = allColumns.filter(\n column => !filters.find(d => d.id === column.id)\n )\n\n // This essentially enables faceted filter options to be built easily\n // using every column's preFilteredRows value\n nonFilteredColumns.forEach(column => {\n column.preFilteredRows = filteredRows\n column.filteredRows = filteredRows\n })\n }, [filteredRows, filters, allColumns])\n\n const getAutoResetFilters = useGetLatest(autoResetFilters)\n\n useMountedLayoutEffect(() => {\n if (getAutoResetFilters()) {\n dispatch({ type: actions.resetFilters })\n }\n }, [dispatch, manualFilters ? null : data])\n\n Object.assign(instance, {\n preFilteredRows: rows,\n preFilteredFlatRows: flatRows,\n preFilteredRowsById: rowsById,\n filteredRows,\n filteredFlatRows,\n filteredRowsById,\n rows: filteredRows,\n flatRows: filteredFlatRows,\n rowsById: filteredRowsById,\n setFilter,\n setAllFilters,\n })\n}\n","import React from 'react'\n\nimport {\n getFilterMethod,\n shouldAutoRemoveFilter,\n getFirstDefined,\n} from '../utils'\n\nimport {\n actions,\n useMountedLayoutEffect,\n functionalUpdate,\n useGetLatest,\n} from '../publicUtils'\n\nimport * as filterTypes from '../filterTypes'\n\n// Actions\nactions.resetGlobalFilter = 'resetGlobalFilter'\nactions.setGlobalFilter = 'setGlobalFilter'\n\nexport const useGlobalFilter = hooks => {\n hooks.stateReducers.push(reducer)\n hooks.useInstance.push(useInstance)\n}\n\nuseGlobalFilter.pluginName = 'useGlobalFilter'\n\nfunction reducer(state, action, previousState, instance) {\n if (action.type === actions.resetGlobalFilter) {\n return {\n ...state,\n globalFilter: instance.initialState.globalFilter || undefined,\n }\n }\n\n if (action.type === actions.setGlobalFilter) {\n const { filterValue } = action\n const { userFilterTypes } = instance\n\n const filterMethod = getFilterMethod(\n instance.globalFilter,\n userFilterTypes || {},\n filterTypes\n )\n\n const newFilter = functionalUpdate(filterValue, state.globalFilter)\n\n //\n if (shouldAutoRemoveFilter(filterMethod.autoRemove, newFilter)) {\n const { globalFilter, ...stateWithoutGlobalFilter } = state\n return stateWithoutGlobalFilter\n }\n\n return {\n ...state,\n globalFilter: newFilter,\n }\n }\n}\n\nfunction useInstance(instance) {\n const {\n data,\n rows,\n flatRows,\n rowsById,\n allColumns,\n filterTypes: userFilterTypes,\n globalFilter,\n manualGlobalFilter,\n state: { globalFilter: globalFilterValue },\n dispatch,\n autoResetGlobalFilter = true,\n disableGlobalFilter,\n } = instance\n\n const setGlobalFilter = React.useCallback(\n filterValue => {\n dispatch({ type: actions.setGlobalFilter, filterValue })\n },\n [dispatch]\n )\n\n // TODO: Create a filter cache for incremental high speed multi-filtering\n // This gets pretty complicated pretty fast, since you have to maintain a\n // cache for each row group (top-level rows, and each row's recursive subrows)\n // This would make multi-filtering a lot faster though. Too far?\n\n const [\n globalFilteredRows,\n globalFilteredFlatRows,\n globalFilteredRowsById,\n ] = React.useMemo(() => {\n if (manualGlobalFilter || typeof globalFilterValue === 'undefined') {\n return [rows, flatRows, rowsById]\n }\n\n const filteredFlatRows = []\n const filteredRowsById = {}\n\n const filterMethod = getFilterMethod(\n globalFilter,\n userFilterTypes || {},\n filterTypes\n )\n\n if (!filterMethod) {\n console.warn(`Could not find a valid 'globalFilter' option.`)\n return rows\n }\n\n allColumns.forEach(column => {\n const { disableGlobalFilter: columnDisableGlobalFilter } = column\n\n column.canFilter = getFirstDefined(\n columnDisableGlobalFilter === true ? false : undefined,\n disableGlobalFilter === true ? false : undefined,\n true\n )\n })\n\n const filterableColumns = allColumns.filter(c => c.canFilter === true)\n\n // Filters top level and nested rows\n const filterRows = filteredRows => {\n filteredRows = filterMethod(\n filteredRows,\n filterableColumns.map(d => d.id),\n globalFilterValue\n )\n\n filteredRows.forEach(row => {\n filteredFlatRows.push(row)\n filteredRowsById[row.id] = row\n\n row.subRows =\n row.subRows && row.subRows.length\n ? filterRows(row.subRows)\n : row.subRows\n })\n\n return filteredRows\n }\n\n return [filterRows(rows), filteredFlatRows, filteredRowsById]\n }, [\n manualGlobalFilter,\n globalFilterValue,\n globalFilter,\n userFilterTypes,\n allColumns,\n rows,\n flatRows,\n rowsById,\n disableGlobalFilter,\n ])\n\n const getAutoResetGlobalFilter = useGetLatest(autoResetGlobalFilter)\n\n useMountedLayoutEffect(() => {\n if (getAutoResetGlobalFilter()) {\n dispatch({ type: actions.resetGlobalFilter })\n }\n }, [dispatch, manualGlobalFilter ? null : data])\n\n Object.assign(instance, {\n preGlobalFilteredRows: rows,\n preGlobalFilteredFlatRows: flatRows,\n preGlobalFilteredRowsById: rowsById,\n globalFilteredRows,\n globalFilteredFlatRows,\n globalFilteredRowsById,\n rows: globalFilteredRows,\n flatRows: globalFilteredFlatRows,\n rowsById: globalFilteredRowsById,\n setGlobalFilter,\n disableGlobalFilter,\n })\n}\n","export function sum(values, aggregatedValues) {\n // It's faster to just add the aggregations together instead of\n // process leaf nodes individually\n return aggregatedValues.reduce(\n (sum, next) => sum + (typeof next === 'number' ? next : 0),\n 0\n )\n}\n\nexport function min(values) {\n let min = values[0] || 0\n\n values.forEach(value => {\n if (typeof value === 'number') {\n min = Math.min(min, value)\n }\n })\n\n return min\n}\n\nexport function max(values) {\n let max = values[0] || 0\n\n values.forEach(value => {\n if (typeof value === 'number') {\n max = Math.max(max, value)\n }\n })\n\n return max\n}\n\nexport function minMax(values) {\n let min = values[0] || 0\n let max = values[0] || 0\n\n values.forEach(value => {\n if (typeof value === 'number') {\n min = Math.min(min, value)\n max = Math.max(max, value)\n }\n })\n\n return `${min}..${max}`\n}\n\nexport function average(values) {\n return sum(null, values) / values.length\n}\n\nexport function median(values) {\n if (!values.length) {\n return null\n }\n\n const mid = Math.floor(values.length / 2)\n const nums = [...values].sort((a, b) => a - b)\n return values.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2\n}\n\nexport function unique(values) {\n return Array.from(new Set(values).values())\n}\n\nexport function uniqueCount(values) {\n return new Set(values).size\n}\n\nexport function count(values) {\n return values.length\n}\n","import React from 'react'\n\nimport * as aggregations from '../aggregations'\n\nimport { getFirstDefined, flattenBy } from '../utils'\n\nimport {\n actions,\n makePropGetter,\n ensurePluginOrder,\n useMountedLayoutEffect,\n useGetLatest,\n} from '../publicUtils'\n\nconst emptyArray = []\nconst emptyObject = {}\n\n// Actions\nactions.resetGroupBy = 'resetGroupBy'\nactions.setGroupBy = 'setGroupBy'\nactions.toggleGroupBy = 'toggleGroupBy'\n\nexport const useGroupBy = hooks => {\n hooks.getGroupByToggleProps = [defaultGetGroupByToggleProps]\n hooks.stateReducers.push(reducer)\n hooks.visibleColumnsDeps.push((deps, { instance }) => [\n ...deps,\n instance.state.groupBy,\n ])\n hooks.visibleColumns.push(visibleColumns)\n hooks.useInstance.push(useInstance)\n hooks.prepareRow.push(prepareRow)\n}\n\nuseGroupBy.pluginName = 'useGroupBy'\n\nconst defaultGetGroupByToggleProps = (props, { header }) => [\n props,\n {\n onClick: header.canGroupBy\n ? e => {\n e.persist()\n header.toggleGroupBy()\n }\n : undefined,\n style: {\n cursor: header.canGroupBy ? 'pointer' : undefined,\n },\n title: 'Toggle GroupBy',\n },\n]\n\n// Reducer\nfunction reducer(state, action, previousState, instance) {\n if (action.type === actions.init) {\n return {\n groupBy: [],\n ...state,\n }\n }\n\n if (action.type === actions.resetGroupBy) {\n return {\n ...state,\n groupBy: instance.initialState.groupBy || [],\n }\n }\n\n if (action.type === actions.setGroupBy) {\n const { value } = action\n return {\n ...state,\n groupBy: value,\n }\n }\n\n if (action.type === actions.toggleGroupBy) {\n const { columnId, value: setGroupBy } = action\n\n const resolvedGroupBy =\n typeof setGroupBy !== 'undefined'\n ? setGroupBy\n : !state.groupBy.includes(columnId)\n\n if (resolvedGroupBy) {\n return {\n ...state,\n groupBy: [...state.groupBy, columnId],\n }\n }\n\n return {\n ...state,\n groupBy: state.groupBy.filter(d => d !== columnId),\n }\n }\n}\n\nfunction visibleColumns(\n columns,\n {\n instance: {\n state: { groupBy },\n },\n }\n) {\n // Sort grouped columns to the start of the column list\n // before the headers are built\n\n const groupByColumns = groupBy\n .map(g => columns.find(col => col.id === g))\n .filter(Boolean)\n\n const nonGroupByColumns = columns.filter(col => !groupBy.includes(col.id))\n\n columns = [...groupByColumns, ...nonGroupByColumns]\n\n columns.forEach(column => {\n column.isGrouped = groupBy.includes(column.id)\n column.groupedIndex = groupBy.indexOf(column.id)\n })\n\n return columns\n}\n\nconst defaultUserAggregations = {}\n\nfunction useInstance(instance) {\n const {\n data,\n rows,\n flatRows,\n rowsById,\n allColumns,\n flatHeaders,\n groupByFn = defaultGroupByFn,\n manualGroupBy,\n aggregations: userAggregations = defaultUserAggregations,\n plugins,\n state: { groupBy },\n dispatch,\n autoResetGroupBy = true,\n disableGroupBy,\n defaultCanGroupBy,\n getHooks,\n } = instance\n\n ensurePluginOrder(plugins, ['useColumnOrder', 'useFilters'], 'useGroupBy')\n\n const getInstance = useGetLatest(instance)\n\n allColumns.forEach(column => {\n const {\n accessor,\n defaultGroupBy: defaultColumnGroupBy,\n disableGroupBy: columnDisableGroupBy,\n } = column\n\n column.canGroupBy = accessor\n ? getFirstDefined(\n column.canGroupBy,\n columnDisableGroupBy === true ? false : undefined,\n disableGroupBy === true ? false : undefined,\n true\n )\n : getFirstDefined(\n column.canGroupBy,\n defaultColumnGroupBy,\n defaultCanGroupBy,\n false\n )\n\n if (column.canGroupBy) {\n column.toggleGroupBy = () => instance.toggleGroupBy(column.id)\n }\n\n column.Aggregated = column.Aggregated || column.Cell\n })\n\n const toggleGroupBy = React.useCallback(\n (columnId, value) => {\n dispatch({ type: actions.toggleGroupBy, columnId, value })\n },\n [dispatch]\n )\n\n const setGroupBy = React.useCallback(\n value => {\n dispatch({ type: actions.setGroupBy, value })\n },\n [dispatch]\n )\n\n flatHeaders.forEach(header => {\n header.getGroupByToggleProps = makePropGetter(\n getHooks().getGroupByToggleProps,\n { instance: getInstance(), header }\n )\n })\n\n const [\n groupedRows,\n groupedFlatRows,\n groupedRowsById,\n onlyGroupedFlatRows,\n onlyGroupedRowsById,\n nonGroupedFlatRows,\n nonGroupedRowsById,\n ] = React.useMemo(() => {\n if (manualGroupBy || !groupBy.length) {\n return [\n rows,\n flatRows,\n rowsById,\n emptyArray,\n emptyObject,\n flatRows,\n rowsById,\n ]\n }\n\n // Ensure that the list of filtered columns exist\n const existingGroupBy = groupBy.filter(g =>\n allColumns.find(col => col.id === g)\n )\n\n // Find the columns that can or are aggregating\n // Uses each column to aggregate rows into a single value\n const aggregateRowsToValues = (leafRows, groupedRows, depth) => {\n const values = {}\n\n allColumns.forEach(column => {\n // Don't aggregate columns that are in the groupBy\n if (existingGroupBy.includes(column.id)) {\n values[column.id] = groupedRows[0]\n ? groupedRows[0].values[column.id]\n : null\n return\n }\n\n // Aggregate the values\n let aggregateFn =\n typeof column.aggregate === 'function'\n ? column.aggregate\n : userAggregations[column.aggregate] ||\n aggregations[column.aggregate]\n\n if (aggregateFn) {\n // Get the columnValues to aggregate\n const groupedValues = groupedRows.map(row => row.values[column.id])\n\n // Get the columnValues to aggregate\n const leafValues = leafRows.map(row => {\n let columnValue = row.values[column.id]\n\n if (!depth && column.aggregateValue) {\n const aggregateValueFn =\n typeof column.aggregateValue === 'function'\n ? column.aggregateValue\n : userAggregations[column.aggregateValue] ||\n aggregations[column.aggregateValue]\n\n if (!aggregateValueFn) {\n console.info({ column })\n throw new Error(\n `React Table: Invalid column.aggregateValue option for column listed above`\n )\n }\n\n columnValue = aggregateValueFn(columnValue, row, column)\n }\n return columnValue\n })\n\n values[column.id] = aggregateFn(leafValues, groupedValues)\n } else if (column.aggregate) {\n console.info({ column })\n throw new Error(\n `React Table: Invalid column.aggregate option for column listed above`\n )\n } else {\n values[column.id] = null\n }\n })\n\n return values\n }\n\n let groupedFlatRows = []\n const groupedRowsById = {}\n const onlyGroupedFlatRows = []\n const onlyGroupedRowsById = {}\n const nonGroupedFlatRows = []\n const nonGroupedRowsById = {}\n\n // Recursively group the data\n const groupUpRecursively = (rows, depth = 0, parentId) => {\n // This is the last level, just return the rows\n if (depth === existingGroupBy.length) {\n return rows\n }\n\n const columnId = existingGroupBy[depth]\n\n // Group the rows together for this level\n let rowGroupsMap = groupByFn(rows, columnId)\n\n // Peform aggregations for each group\n const aggregatedGroupedRows = Object.entries(rowGroupsMap).map(\n ([groupByVal, groupedRows], index) => {\n let id = `${columnId}:${groupByVal}`\n id = parentId ? `${parentId}>${id}` : id\n\n // First, Recurse to group sub rows before aggregation\n const subRows = groupUpRecursively(groupedRows, depth + 1, id)\n\n // Flatten the leaf rows of the rows in this group\n const leafRows = depth\n ? flattenBy(groupedRows, 'leafRows')\n : groupedRows\n\n const values = aggregateRowsToValues(leafRows, groupedRows, depth)\n\n const row = {\n id,\n isGrouped: true,\n groupByID: columnId,\n groupByVal,\n values,\n subRows,\n leafRows,\n depth,\n index,\n }\n\n subRows.forEach(subRow => {\n groupedFlatRows.push(subRow)\n groupedRowsById[subRow.id] = subRow\n if (subRow.isGrouped) {\n onlyGroupedFlatRows.push(subRow)\n onlyGroupedRowsById[subRow.id] = subRow\n } else {\n nonGroupedFlatRows.push(subRow)\n nonGroupedRowsById[subRow.id] = subRow\n }\n })\n\n return row\n }\n )\n\n return aggregatedGroupedRows\n }\n\n const groupedRows = groupUpRecursively(rows)\n\n groupedRows.forEach(subRow => {\n groupedFlatRows.push(subRow)\n groupedRowsById[subRow.id] = subRow\n if (subRow.isGrouped) {\n onlyGroupedFlatRows.push(subRow)\n onlyGroupedRowsById[subRow.id] = subRow\n } else {\n nonGroupedFlatRows.push(subRow)\n nonGroupedRowsById[subRow.id] = subRow\n }\n })\n\n // Assign the new data\n return [\n groupedRows,\n groupedFlatRows,\n groupedRowsById,\n onlyGroupedFlatRows,\n onlyGroupedRowsById,\n nonGroupedFlatRows,\n nonGroupedRowsById,\n ]\n }, [\n manualGroupBy,\n groupBy,\n rows,\n flatRows,\n rowsById,\n allColumns,\n userAggregations,\n groupByFn,\n ])\n\n const getAutoResetGroupBy = useGetLatest(autoResetGroupBy)\n\n useMountedLayoutEffect(() => {\n if (getAutoResetGroupBy()) {\n dispatch({ type: actions.resetGroupBy })\n }\n }, [dispatch, manualGroupBy ? null : data])\n\n Object.assign(instance, {\n preGroupedRows: rows,\n preGroupedFlatRow: flatRows,\n preGroupedRowsById: rowsById,\n groupedRows,\n groupedFlatRows,\n groupedRowsById,\n onlyGroupedFlatRows,\n onlyGroupedRowsById,\n nonGroupedFlatRows,\n nonGroupedRowsById,\n rows: groupedRows,\n flatRows: groupedFlatRows,\n rowsById: groupedRowsById,\n toggleGroupBy,\n setGroupBy,\n })\n}\n\nfunction prepareRow(row) {\n row.allCells.forEach(cell => {\n // Grouped cells are in the groupBy and the pivot cell for the row\n cell.isGrouped = cell.column.isGrouped && cell.column.id === row.groupByID\n // Placeholder cells are any columns in the groupBy that are not grouped\n cell.isPlaceholder = !cell.isGrouped && cell.column.isGrouped\n // Aggregated cells are not grouped, not repeated, but still have subRows\n cell.isAggregated =\n !cell.isGrouped && !cell.isPlaceholder && row.subRows?.length\n })\n}\n\nexport function defaultGroupByFn(rows, columnId) {\n return rows.reduce((prev, row, i) => {\n // TODO: Might want to implement a key serializer here so\n // irregular column values can still be grouped if needed?\n const resKey = `${row.values[columnId]}`\n prev[resKey] = Array.isArray(prev[resKey]) ? prev[resKey] : []\n prev[resKey].push(row)\n return prev\n }, {})\n}\n","const reSplitAlphaNumeric = /([0-9]+)/gm\n\n// Mixed sorting is slow, but very inclusive of many edge cases.\n// It handles numbers, mixed alphanumeric combinations, and even\n// null, undefined, and Infinity\nexport const alphanumeric = (rowA, rowB, columnId) => {\n let [a, b] = getRowValuesByColumnID(rowA, rowB, columnId)\n\n // Force to strings (or \"\" for unsupported types)\n a = toString(a)\n b = toString(b)\n\n // Split on number groups, but keep the delimiter\n // Then remove falsey split values\n a = a.split(reSplitAlphaNumeric).filter(Boolean)\n b = b.split(reSplitAlphaNumeric).filter(Boolean)\n\n // While\n while (a.length && b.length) {\n let aa = a.shift()\n let bb = b.shift()\n\n const an = parseInt(aa, 10)\n const bn = parseInt(bb, 10)\n\n const combo = [an, bn].sort()\n\n // Both are string\n if (isNaN(combo[0])) {\n if (aa > bb) {\n return 1\n }\n if (bb > aa) {\n return -1\n }\n continue\n }\n\n // One is a string, one is a number\n if (isNaN(combo[1])) {\n return isNaN(an) ? -1 : 1\n }\n\n // Both are numbers\n if (an > bn) {\n return 1\n }\n if (bn > an) {\n return -1\n }\n }\n\n return a.length - b.length\n}\nexport function datetime(rowA, rowB, columnId) {\n let [a, b] = getRowValuesByColumnID(rowA, rowB, columnId)\n\n a = a.getTime()\n b = b.getTime()\n\n return compareBasic(a, b)\n}\n\nexport function basic(rowA, rowB, columnId) {\n let [a, b] = getRowValuesByColumnID(rowA, rowB, columnId)\n\n return compareBasic(a, b)\n}\n\nexport function string(rowA, rowB, columnId) {\n let [a, b] = getRowValuesByColumnID(rowA, rowB, columnId)\n\n a = a.split('').filter(Boolean)\n b = b.split('').filter(Boolean)\n\n while (a.length && b.length) {\n let aa = a.shift()\n let bb = b.shift()\n\n let alower = aa.toLowerCase()\n let blower = bb.toLowerCase()\n\n // Case insensitive comparison until characters match\n if (alower > blower) {\n return 1\n }\n if (blower > alower) {\n return -1\n }\n // If lowercase characters are identical\n if (aa > bb) {\n return 1\n }\n if (bb > aa) {\n return -1\n }\n continue\n }\n\n return a.length - b.length\n}\n\nexport function number(rowA, rowB, columnId) {\n let [a, b] = getRowValuesByColumnID(rowA, rowB, columnId)\n\n const replaceNonNumeric = /[^0-9.]/gi\n\n a = Number(String(a).replace(replaceNonNumeric, ''))\n b = Number(String(b).replace(replaceNonNumeric, ''))\n\n return compareBasic(a, b)\n}\n\n// Utils\n\nfunction compareBasic(a, b) {\n return a === b ? 0 : a > b ? 1 : -1\n}\n\nfunction getRowValuesByColumnID(row1, row2, columnId) {\n return [row1.values[columnId], row2.values[columnId]]\n}\n\nfunction toString(a) {\n if (typeof a === 'number') {\n if (isNaN(a) || a === Infinity || a === -Infinity) {\n return ''\n }\n return String(a)\n }\n if (typeof a === 'string') {\n return a\n }\n return ''\n}\n","import React from 'react'\n\nimport {\n actions,\n ensurePluginOrder,\n defaultColumn,\n makePropGetter,\n useGetLatest,\n useMountedLayoutEffect,\n} from '../publicUtils'\n\nimport { getFirstDefined, isFunction } from '../utils'\n\nimport * as sortTypes from '../sortTypes'\n\n// Actions\nactions.resetSortBy = 'resetSortBy'\nactions.setSortBy = 'setSortBy'\nactions.toggleSortBy = 'toggleSortBy'\nactions.clearSortBy = 'clearSortBy'\n\ndefaultColumn.sortType = 'alphanumeric'\ndefaultColumn.sortDescFirst = false\n\nexport const useSortBy = hooks => {\n hooks.getSortByToggleProps = [defaultGetSortByToggleProps]\n hooks.stateReducers.push(reducer)\n hooks.useInstance.push(useInstance)\n}\n\nuseSortBy.pluginName = 'useSortBy'\n\nconst defaultGetSortByToggleProps = (props, { instance, column }) => {\n const { isMultiSortEvent = e => e.shiftKey } = instance\n\n return [\n props,\n {\n onClick: column.canSort\n ? e => {\n e.persist()\n column.toggleSortBy(\n undefined,\n !instance.disableMultiSort && isMultiSortEvent(e)\n )\n }\n : undefined,\n style: {\n cursor: column.canSort ? 'pointer' : undefined,\n },\n title: column.canSort ? 'Toggle SortBy' : undefined,\n },\n ]\n}\n\n// Reducer\nfunction reducer(state, action, previousState, instance) {\n if (action.type === actions.init) {\n return {\n sortBy: [],\n ...state,\n }\n }\n\n if (action.type === actions.resetSortBy) {\n return {\n ...state,\n sortBy: instance.initialState.sortBy || [],\n }\n }\n\n if (action.type === actions.clearSortBy) {\n const { sortBy } = state\n const newSortBy = sortBy.filter(d => d.id !== action.columnId)\n\n return {\n ...state,\n sortBy: newSortBy,\n }\n }\n\n if (action.type === actions.setSortBy) {\n const { sortBy } = action\n return {\n ...state,\n sortBy,\n }\n }\n\n if (action.type === actions.toggleSortBy) {\n const { columnId, desc, multi } = action\n\n const {\n allColumns,\n disableMultiSort,\n disableSortRemove,\n disableMultiRemove,\n maxMultiSortColCount = Number.MAX_SAFE_INTEGER,\n } = instance\n\n const { sortBy } = state\n\n // Find the column for this columnId\n const column = allColumns.find(d => d.id === columnId)\n const { sortDescFirst } = column\n\n // Find any existing sortBy for this column\n const existingSortBy = sortBy.find(d => d.id === columnId)\n const existingIndex = sortBy.findIndex(d => d.id === columnId)\n const hasDescDefined = typeof desc !== 'undefined' && desc !== null\n\n let newSortBy = []\n\n // What should we do with this sort action?\n let sortAction\n\n if (!disableMultiSort && multi) {\n if (existingSortBy) {\n sortAction = 'toggle'\n } else {\n sortAction = 'add'\n }\n } else {\n // Normal mode\n if (existingIndex !== sortBy.length - 1 || sortBy.length !== 1) {\n sortAction = 'replace'\n } else if (existingSortBy) {\n sortAction = 'toggle'\n } else {\n sortAction = 'replace'\n }\n }\n\n // Handle toggle states that will remove the sortBy\n if (\n sortAction === 'toggle' && // Must be toggling\n !disableSortRemove && // If disableSortRemove, disable in general\n !hasDescDefined && // Must not be setting desc\n (multi ? !disableMultiRemove : true) && // If multi, don't allow if disableMultiRemove\n ((existingSortBy && // Finally, detect if it should indeed be removed\n existingSortBy.desc &&\n !sortDescFirst) ||\n (!existingSortBy.desc && sortDescFirst))\n ) {\n sortAction = 'remove'\n }\n\n if (sortAction === 'replace') {\n newSortBy = [\n {\n id: columnId,\n desc: hasDescDefined ? desc : sortDescFirst,\n },\n ]\n } else if (sortAction === 'add') {\n newSortBy = [\n ...sortBy,\n {\n id: columnId,\n desc: hasDescDefined ? desc : sortDescFirst,\n },\n ]\n // Take latest n columns\n newSortBy.splice(0, newSortBy.length - maxMultiSortColCount)\n } else if (sortAction === 'toggle') {\n // This flips (or sets) the\n newSortBy = sortBy.map(d => {\n if (d.id === columnId) {\n return {\n ...d,\n desc: hasDescDefined ? desc : !existingSortBy.desc,\n }\n }\n return d\n })\n } else if (sortAction === 'remove') {\n newSortBy = sortBy.filter(d => d.id !== columnId)\n }\n\n return {\n ...state,\n sortBy: newSortBy,\n }\n }\n}\n\nfunction useInstance(instance) {\n const {\n data,\n rows,\n flatRows,\n allColumns,\n orderByFn = defaultOrderByFn,\n sortTypes: userSortTypes,\n manualSortBy,\n defaultCanSort,\n disableSortBy,\n flatHeaders,\n state: { sortBy },\n dispatch,\n plugins,\n getHooks,\n autoResetSortBy = true,\n } = instance\n\n ensurePluginOrder(\n plugins,\n ['useFilters', 'useGlobalFilter', 'useGroupBy', 'usePivotColumns'],\n 'useSortBy'\n )\n\n const setSortBy = React.useCallback(\n sortBy => {\n dispatch({ type: actions.setSortBy, sortBy })\n },\n [dispatch]\n )\n\n // Updates sorting based on a columnId, desc flag and multi flag\n const toggleSortBy = React.useCallback(\n (columnId, desc, multi) => {\n dispatch({ type: actions.toggleSortBy, columnId, desc, multi })\n },\n [dispatch]\n )\n\n // use reference to avoid memory leak in #1608\n const getInstance = useGetLatest(instance)\n\n // Add the getSortByToggleProps method to columns and headers\n flatHeaders.forEach(column => {\n const {\n accessor,\n canSort: defaultColumnCanSort,\n disableSortBy: columnDisableSortBy,\n id,\n } = column\n\n const canSort = accessor\n ? getFirstDefined(\n columnDisableSortBy === true ? false : undefined,\n disableSortBy === true ? false : undefined,\n true\n )\n : getFirstDefined(defaultCanSort, defaultColumnCanSort, false)\n\n column.canSort = canSort\n\n if (column.canSort) {\n column.toggleSortBy = (desc, multi) =>\n toggleSortBy(column.id, desc, multi)\n\n column.clearSortBy = () => {\n dispatch({ type: actions.clearSortBy, columnId: column.id })\n }\n }\n\n column.getSortByToggleProps = makePropGetter(\n getHooks().getSortByToggleProps,\n {\n instance: getInstance(),\n column,\n }\n )\n\n const columnSort = sortBy.find(d => d.id === id)\n column.isSorted = !!columnSort\n column.sortedIndex = sortBy.findIndex(d => d.id === id)\n column.isSortedDesc = column.isSorted ? columnSort.desc : undefined\n })\n\n const [sortedRows, sortedFlatRows] = React.useMemo(() => {\n if (manualSortBy || !sortBy.length) {\n return [rows, flatRows]\n }\n\n const sortedFlatRows = []\n\n // Filter out sortBys that correspond to non existing columns\n const availableSortBy = sortBy.filter(sort =>\n allColumns.find(col => col.id === sort.id)\n )\n\n const sortData = rows => {\n // Use the orderByFn to compose multiple sortBy's together.\n // This will also perform a stable sorting using the row index\n // if needed.\n const sortedData = orderByFn(\n rows,\n availableSortBy.map(sort => {\n // Support custom sorting methods for each column\n const column = allColumns.find(d => d.id === sort.id)\n\n if (!column) {\n throw new Error(\n `React-Table: Could not find a column with id: ${sort.id} while sorting`\n )\n }\n\n const { sortType } = column\n\n // Look up sortBy functions in this order:\n // column function\n // column string lookup on user sortType\n // column string lookup on built-in sortType\n // default function\n // default string lookup on user sortType\n // default string lookup on built-in sortType\n const sortMethod =\n isFunction(sortType) ||\n (userSortTypes || {})[sortType] ||\n sortTypes[sortType]\n\n if (!sortMethod) {\n throw new Error(\n `React-Table: Could not find a valid sortType of '${sortType}' for column '${sort.id}'.`\n )\n }\n\n // Return the correct sortFn.\n // This function should always return in ascending order\n return (a, b) => sortMethod(a, b, sort.id, sort.desc)\n }),\n // Map the directions\n availableSortBy.map(sort => {\n // Detect and use the sortInverted option\n const column = allColumns.find(d => d.id === sort.id)\n\n if (column && column.sortInverted) {\n return sort.desc\n }\n\n return !sort.desc\n })\n )\n\n // If there are sub-rows, sort them\n sortedData.forEach(row => {\n sortedFlatRows.push(row)\n if (!row.subRows || row.subRows.length === 0) {\n return\n }\n row.subRows = sortData(row.subRows)\n })\n\n return sortedData\n }\n\n return [sortData(rows), sortedFlatRows]\n }, [\n manualSortBy,\n sortBy,\n rows,\n flatRows,\n allColumns,\n orderByFn,\n userSortTypes,\n ])\n\n const getAutoResetSortBy = useGetLatest(autoResetSortBy)\n\n useMountedLayoutEffect(() => {\n if (getAutoResetSortBy()) {\n dispatch({ type: actions.resetSortBy })\n }\n }, [manualSortBy ? null : data])\n\n Object.assign(instance, {\n preSortedRows: rows,\n preSortedFlatRows: flatRows,\n sortedRows,\n sortedFlatRows,\n rows: sortedRows,\n flatRows: sortedFlatRows,\n setSortBy,\n toggleSortBy,\n })\n}\n\nexport function defaultOrderByFn(arr, funcs, dirs) {\n return [...arr].sort((rowA, rowB) => {\n for (let i = 0; i < funcs.length; i += 1) {\n const sortFn = funcs[i]\n const desc = dirs[i] === false || dirs[i] === 'desc'\n const sortInt = sortFn(rowA, rowB)\n if (sortInt !== 0) {\n return desc ? -sortInt : sortInt\n }\n }\n return dirs[0] ? rowA.index - rowB.index : rowB.index - rowA.index\n })\n}\n","import React from 'react'\n\n//\n\nimport {\n actions,\n ensurePluginOrder,\n functionalUpdate,\n useMountedLayoutEffect,\n useGetLatest,\n} from '../publicUtils'\n\nimport { expandRows } from '../utils'\n\nconst pluginName = 'usePagination'\n\n// Actions\nactions.resetPage = 'resetPage'\nactions.gotoPage = 'gotoPage'\nactions.setPageSize = 'setPageSize'\n\nexport const usePagination = hooks => {\n hooks.stateReducers.push(reducer)\n hooks.useInstance.push(useInstance)\n}\n\nusePagination.pluginName = pluginName\n\nfunction reducer(state, action, previousState, instance) {\n if (action.type === actions.init) {\n return {\n pageSize: 10,\n pageIndex: 0,\n ...state,\n }\n }\n\n if (action.type === actions.resetPage) {\n return {\n ...state,\n pageIndex: instance.initialState.pageIndex || 0,\n }\n }\n\n if (action.type === actions.gotoPage) {\n const { pageCount, page } = instance\n const newPageIndex = functionalUpdate(action.pageIndex, state.pageIndex)\n let canNavigate = false\n\n if (newPageIndex > state.pageIndex) {\n // next page\n canNavigate =\n pageCount === -1\n ? page.length >= state.pageSize\n : newPageIndex < pageCount\n } else if (newPageIndex < state.pageIndex) {\n // prev page\n canNavigate = newPageIndex > -1\n }\n\n if (!canNavigate) {\n return state\n }\n\n return {\n ...state,\n pageIndex: newPageIndex,\n }\n }\n\n if (action.type === actions.setPageSize) {\n const { pageSize } = action\n const topRowIndex = state.pageSize * state.pageIndex\n const pageIndex = Math.floor(topRowIndex / pageSize)\n\n return {\n ...state,\n pageIndex,\n pageSize,\n }\n }\n}\n\nfunction useInstance(instance) {\n const {\n rows,\n autoResetPage = true,\n manualExpandedKey = 'expanded',\n plugins,\n pageCount: userPageCount,\n paginateExpandedRows = true,\n expandSubRows = true,\n state: {\n pageSize,\n pageIndex,\n expanded,\n globalFilter,\n filters,\n groupBy,\n sortBy,\n },\n dispatch,\n data,\n manualPagination,\n } = instance\n\n ensurePluginOrder(\n plugins,\n ['useGlobalFilter', 'useFilters', 'useGroupBy', 'useSortBy', 'useExpanded'],\n 'usePagination'\n )\n\n const getAutoResetPage = useGetLatest(autoResetPage)\n\n useMountedLayoutEffect(() => {\n if (getAutoResetPage()) {\n dispatch({ type: actions.resetPage })\n }\n }, [\n dispatch,\n manualPagination ? null : data,\n globalFilter,\n filters,\n groupBy,\n sortBy,\n ])\n\n const pageCount = manualPagination\n ? userPageCount\n : Math.ceil(rows.length / pageSize)\n\n const pageOptions = React.useMemo(\n () =>\n pageCount > 0\n ? [...new Array(pageCount)].fill(null).map((d, i) => i)\n : [],\n [pageCount]\n )\n\n const page = React.useMemo(() => {\n let page\n\n if (manualPagination) {\n page = rows\n } else {\n const pageStart = pageSize * pageIndex\n const pageEnd = pageStart + pageSize\n\n page = rows.slice(pageStart, pageEnd)\n }\n\n if (paginateExpandedRows) {\n return page\n }\n\n return expandRows(page, { manualExpandedKey, expanded, expandSubRows })\n }, [\n expandSubRows,\n expanded,\n manualExpandedKey,\n manualPagination,\n pageIndex,\n pageSize,\n paginateExpandedRows,\n rows,\n ])\n\n const canPreviousPage = pageIndex > 0\n const canNextPage =\n pageCount === -1 ? page.length >= pageSize : pageIndex < pageCount - 1\n\n const gotoPage = React.useCallback(\n pageIndex => {\n dispatch({ type: actions.gotoPage, pageIndex })\n },\n [dispatch]\n )\n\n const previousPage = React.useCallback(() => {\n return gotoPage(old => old - 1)\n }, [gotoPage])\n\n const nextPage = React.useCallback(() => {\n return gotoPage(old => old + 1)\n }, [gotoPage])\n\n const setPageSize = React.useCallback(\n pageSize => {\n dispatch({ type: actions.setPageSize, pageSize })\n },\n [dispatch]\n )\n\n Object.assign(instance, {\n pageOptions,\n pageCount,\n page,\n canPreviousPage,\n canNextPage,\n gotoPage,\n previousPage,\n nextPage,\n setPageSize,\n })\n}\n","/* istanbul ignore file */\n\nimport {\n actions,\n makePropGetter,\n ensurePluginOrder,\n useMountedLayoutEffect,\n useGetLatest,\n} from '../publicUtils'\n\nimport { flattenColumns, getFirstDefined } from '../utils'\n\n// Actions\nactions.resetPivot = 'resetPivot'\nactions.togglePivot = 'togglePivot'\n\nexport const _UNSTABLE_usePivotColumns = hooks => {\n hooks.getPivotToggleProps = [defaultGetPivotToggleProps]\n hooks.stateReducers.push(reducer)\n hooks.useInstanceAfterData.push(useInstanceAfterData)\n hooks.allColumns.push(allColumns)\n hooks.accessValue.push(accessValue)\n hooks.materializedColumns.push(materializedColumns)\n hooks.materializedColumnsDeps.push(materializedColumnsDeps)\n hooks.visibleColumns.push(visibleColumns)\n hooks.visibleColumnsDeps.push(visibleColumnsDeps)\n hooks.useInstance.push(useInstance)\n hooks.prepareRow.push(prepareRow)\n}\n\n_UNSTABLE_usePivotColumns.pluginName = 'usePivotColumns'\n\nconst defaultPivotColumns = []\n\nconst defaultGetPivotToggleProps = (props, { header }) => [\n props,\n {\n onClick: header.canPivot\n ? e => {\n e.persist()\n header.togglePivot()\n }\n : undefined,\n style: {\n cursor: header.canPivot ? 'pointer' : undefined,\n },\n title: 'Toggle Pivot',\n },\n]\n\n// Reducer\nfunction reducer(state, action, previousState, instance) {\n if (action.type === actions.init) {\n return {\n pivotColumns: defaultPivotColumns,\n ...state,\n }\n }\n\n if (action.type === actions.resetPivot) {\n return {\n ...state,\n pivotColumns: instance.initialState.pivotColumns || defaultPivotColumns,\n }\n }\n\n if (action.type === actions.togglePivot) {\n const { columnId, value: setPivot } = action\n\n const resolvedPivot =\n typeof setPivot !== 'undefined'\n ? setPivot\n : !state.pivotColumns.includes(columnId)\n\n if (resolvedPivot) {\n return {\n ...state,\n pivotColumns: [...state.pivotColumns, columnId],\n }\n }\n\n return {\n ...state,\n pivotColumns: state.pivotColumns.filter(d => d !== columnId),\n }\n }\n}\n\nfunction useInstanceAfterData(instance) {\n instance.allColumns.forEach(column => {\n column.isPivotSource = instance.state.pivotColumns.includes(column.id)\n })\n}\n\nfunction allColumns(columns, { instance }) {\n columns.forEach(column => {\n column.isPivotSource = instance.state.pivotColumns.includes(column.id)\n column.uniqueValues = new Set()\n })\n return columns\n}\n\nfunction accessValue(value, { column }) {\n if (column.uniqueValues && typeof value !== 'undefined') {\n column.uniqueValues.add(value)\n }\n return value\n}\n\nfunction materializedColumns(materialized, { instance }) {\n const { allColumns, state } = instance\n\n if (!state.pivotColumns.length || !state.groupBy || !state.groupBy.length) {\n return materialized\n }\n\n const pivotColumns = state.pivotColumns\n .map(id => allColumns.find(d => d.id === id))\n .filter(Boolean)\n\n const sourceColumns = allColumns.filter(\n d =>\n !d.isPivotSource &&\n !state.groupBy.includes(d.id) &&\n !state.pivotColumns.includes(d.id)\n )\n\n const buildPivotColumns = (depth = 0, parent, pivotFilters = []) => {\n const pivotColumn = pivotColumns[depth]\n\n if (!pivotColumn) {\n return sourceColumns.map(sourceColumn => {\n // TODO: We could offer support here for renesting pivoted\n // columns inside copies of their header groups. For now,\n // that seems like it would be (1) overkill on nesting, considering\n // you already get nesting for every pivot level and (2)\n // really hard. :)\n\n return {\n ...sourceColumn,\n canPivot: false,\n isPivoted: true,\n parent,\n depth: depth,\n id: `${parent ? `${parent.id}.${sourceColumn.id}` : sourceColumn.id}`,\n accessor: (originalRow, i, row) => {\n if (pivotFilters.every(filter => filter(row))) {\n return row.values[sourceColumn.id]\n }\n },\n }\n })\n }\n\n const uniqueValues = Array.from(pivotColumn.uniqueValues).sort()\n\n return uniqueValues.map(uniqueValue => {\n const columnGroup = {\n ...pivotColumn,\n Header:\n pivotColumn.PivotHeader || typeof pivotColumn.header === 'string'\n ? `${pivotColumn.Header}: ${uniqueValue}`\n : uniqueValue,\n isPivotGroup: true,\n parent,\n depth,\n id: parent\n ? `${parent.id}.${pivotColumn.id}.${uniqueValue}`\n : `${pivotColumn.id}.${uniqueValue}`,\n pivotValue: uniqueValue,\n }\n\n columnGroup.columns = buildPivotColumns(depth + 1, columnGroup, [\n ...pivotFilters,\n row => row.values[pivotColumn.id] === uniqueValue,\n ])\n\n return columnGroup\n })\n }\n\n const newMaterialized = flattenColumns(buildPivotColumns())\n\n return [...materialized, ...newMaterialized]\n}\n\nfunction materializedColumnsDeps(\n deps,\n {\n instance: {\n state: { pivotColumns, groupBy },\n },\n }\n) {\n return [...deps, pivotColumns, groupBy]\n}\n\nfunction visibleColumns(visibleColumns, { instance: { state } }) {\n visibleColumns = visibleColumns.filter(d => !d.isPivotSource)\n\n if (state.pivotColumns.length && state.groupBy && state.groupBy.length) {\n visibleColumns = visibleColumns.filter(\n column => column.isGrouped || column.isPivoted\n )\n }\n\n return visibleColumns\n}\n\nfunction visibleColumnsDeps(deps, { instance }) {\n return [...deps, instance.state.pivotColumns, instance.state.groupBy]\n}\n\nfunction useInstance(instance) {\n const {\n columns,\n allColumns,\n flatHeaders,\n // pivotFn = defaultPivotFn,\n // manualPivot,\n getHooks,\n plugins,\n dispatch,\n autoResetPivot = true,\n manaulPivot,\n disablePivot,\n defaultCanPivot,\n } = instance\n\n ensurePluginOrder(plugins, ['useGroupBy'], 'usePivotColumns')\n\n const getInstance = useGetLatest(instance)\n\n allColumns.forEach(column => {\n const {\n accessor,\n defaultPivot: defaultColumnPivot,\n disablePivot: columnDisablePivot,\n } = column\n\n column.canPivot = accessor\n ? getFirstDefined(\n column.canPivot,\n columnDisablePivot === true ? false : undefined,\n disablePivot === true ? false : undefined,\n true\n )\n : getFirstDefined(\n column.canPivot,\n defaultColumnPivot,\n defaultCanPivot,\n false\n )\n\n if (column.canPivot) {\n column.togglePivot = () => instance.togglePivot(column.id)\n }\n\n column.Aggregated = column.Aggregated || column.Cell\n })\n\n const togglePivot = (columnId, value) => {\n dispatch({ type: actions.togglePivot, columnId, value })\n }\n\n flatHeaders.forEach(header => {\n header.getPivotToggleProps = makePropGetter(\n getHooks().getPivotToggleProps,\n {\n instance: getInstance(),\n header,\n }\n )\n })\n\n const getAutoResetPivot = useGetLatest(autoResetPivot)\n\n useMountedLayoutEffect(() => {\n if (getAutoResetPivot()) {\n dispatch({ type: actions.resetPivot })\n }\n }, [dispatch, manaulPivot ? null : columns])\n\n Object.assign(instance, {\n togglePivot,\n })\n}\n\nfunction prepareRow(row) {\n row.allCells.forEach(cell => {\n // Grouped cells are in the pivotColumns and the pivot cell for the row\n cell.isPivoted = cell.column.isPivoted\n })\n}\n","import React from 'react'\n\nimport {\n actions,\n makePropGetter,\n ensurePluginOrder,\n useGetLatest,\n useMountedLayoutEffect,\n} from '../publicUtils'\n\nconst pluginName = 'useRowSelect'\n\n// Actions\nactions.resetSelectedRows = 'resetSelectedRows'\nactions.toggleAllRowsSelected = 'toggleAllRowsSelected'\nactions.toggleRowSelected = 'toggleRowSelected'\nactions.toggleAllPageRowsSelected = 'toggleAllPageRowsSelected'\n\nexport const useRowSelect = hooks => {\n hooks.getToggleRowSelectedProps = [defaultGetToggleRowSelectedProps]\n hooks.getToggleAllRowsSelectedProps = [defaultGetToggleAllRowsSelectedProps]\n hooks.getToggleAllPageRowsSelectedProps = [\n defaultGetToggleAllPageRowsSelectedProps,\n ]\n hooks.stateReducers.push(reducer)\n hooks.useInstance.push(useInstance)\n hooks.prepareRow.push(prepareRow)\n}\n\nuseRowSelect.pluginName = pluginName\n\nconst defaultGetToggleRowSelectedProps = (props, { instance, row }) => {\n const { manualRowSelectedKey = 'isSelected' } = instance\n let checked = false\n\n if (row.original && row.original[manualRowSelectedKey]) {\n checked = true\n } else {\n checked = row.isSelected\n }\n\n return [\n props,\n {\n onChange: e => {\n row.toggleRowSelected(e.target.checked)\n },\n style: {\n cursor: 'pointer',\n },\n checked,\n title: 'Toggle Row Selected',\n indeterminate: row.isSomeSelected,\n },\n ]\n}\n\nconst defaultGetToggleAllRowsSelectedProps = (props, { instance }) => [\n props,\n {\n onChange: e => {\n instance.toggleAllRowsSelected(e.target.checked)\n },\n style: {\n cursor: 'pointer',\n },\n checked: instance.isAllRowsSelected,\n title: 'Toggle All Rows Selected',\n indeterminate: Boolean(\n !instance.isAllRowsSelected &&\n Object.keys(instance.state.selectedRowIds).length\n ),\n },\n]\n\nconst defaultGetToggleAllPageRowsSelectedProps = (props, { instance }) => [\n props,\n {\n onChange(e) {\n instance.toggleAllPageRowsSelected(e.target.checked)\n },\n style: {\n cursor: 'pointer',\n },\n checked: instance.isAllPageRowsSelected,\n title: 'Toggle All Current Page Rows Selected',\n indeterminate: Boolean(\n !instance.isAllPageRowsSelected &&\n instance.page.some(({ id }) => instance.state.selectedRowIds[id])\n ),\n },\n]\n\n// eslint-disable-next-line max-params\nfunction reducer(state, action, previousState, instance) {\n if (action.type === actions.init) {\n return {\n selectedRowIds: {},\n ...state,\n }\n }\n\n if (action.type === actions.resetSelectedRows) {\n return {\n ...state,\n selectedRowIds: instance.initialState.selectedRowIds || {},\n }\n }\n\n if (action.type === actions.toggleAllRowsSelected) {\n const { value: setSelected } = action\n const {\n isAllRowsSelected,\n rowsById,\n nonGroupedRowsById = rowsById,\n } = instance\n\n const selectAll =\n typeof setSelected !== 'undefined' ? setSelected : !isAllRowsSelected\n\n // Only remove/add the rows that are visible on the screen\n // Leave all the other rows that are selected alone.\n const selectedRowIds = Object.assign({}, state.selectedRowIds)\n\n if (selectAll) {\n Object.keys(nonGroupedRowsById).forEach(rowId => {\n selectedRowIds[rowId] = true\n })\n } else {\n Object.keys(nonGroupedRowsById).forEach(rowId => {\n delete selectedRowIds[rowId]\n })\n }\n\n return {\n ...state,\n selectedRowIds,\n }\n }\n\n if (action.type === actions.toggleRowSelected) {\n const { id, value: setSelected } = action\n const { rowsById, selectSubRows = true, getSubRows } = instance\n const isSelected = state.selectedRowIds[id]\n const shouldExist =\n typeof setSelected !== 'undefined' ? setSelected : !isSelected\n\n if (isSelected === shouldExist) {\n return state\n }\n\n const newSelectedRowIds = { ...state.selectedRowIds }\n\n const handleRowById = id => {\n const row = rowsById[id]\n\n if (!row.isGrouped) {\n if (shouldExist) {\n newSelectedRowIds[id] = true\n } else {\n delete newSelectedRowIds[id]\n }\n }\n\n if (selectSubRows && getSubRows(row)) {\n return getSubRows(row).forEach(row => handleRowById(row.id))\n }\n }\n\n handleRowById(id)\n\n return {\n ...state,\n selectedRowIds: newSelectedRowIds,\n }\n }\n\n if (action.type === actions.toggleAllPageRowsSelected) {\n const { value: setSelected } = action\n const {\n page,\n rowsById,\n selectSubRows = true,\n isAllPageRowsSelected,\n getSubRows,\n } = instance\n\n const selectAll =\n typeof setSelected !== 'undefined' ? setSelected : !isAllPageRowsSelected\n\n const newSelectedRowIds = { ...state.selectedRowIds }\n\n const handleRowById = id => {\n const row = rowsById[id]\n\n if (!row.isGrouped) {\n if (selectAll) {\n newSelectedRowIds[id] = true\n } else {\n delete newSelectedRowIds[id]\n }\n }\n\n if (selectSubRows && getSubRows(row)) {\n return getSubRows(row).forEach(row => handleRowById(row.id))\n }\n }\n\n page.forEach(row => handleRowById(row.id))\n\n return {\n ...state,\n selectedRowIds: newSelectedRowIds,\n }\n }\n return state\n}\n\nfunction useInstance(instance) {\n const {\n data,\n rows,\n getHooks,\n plugins,\n rowsById,\n nonGroupedRowsById = rowsById,\n autoResetSelectedRows = true,\n state: { selectedRowIds },\n selectSubRows = true,\n dispatch,\n page,\n getSubRows,\n } = instance\n\n ensurePluginOrder(\n plugins,\n ['useFilters', 'useGroupBy', 'useSortBy', 'useExpanded', 'usePagination'],\n 'useRowSelect'\n )\n\n const selectedFlatRows = React.useMemo(() => {\n const selectedFlatRows = []\n\n rows.forEach(row => {\n const isSelected = selectSubRows\n ? getRowIsSelected(row, selectedRowIds, getSubRows)\n : !!selectedRowIds[row.id]\n row.isSelected = !!isSelected\n row.isSomeSelected = isSelected === null\n\n if (isSelected) {\n selectedFlatRows.push(row)\n }\n })\n\n return selectedFlatRows\n }, [rows, selectSubRows, selectedRowIds, getSubRows])\n\n let isAllRowsSelected = Boolean(\n Object.keys(nonGroupedRowsById).length && Object.keys(selectedRowIds).length\n )\n\n let isAllPageRowsSelected = isAllRowsSelected\n\n if (isAllRowsSelected) {\n if (Object.keys(nonGroupedRowsById).some(id => !selectedRowIds[id])) {\n isAllRowsSelected = false\n }\n }\n\n if (!isAllRowsSelected) {\n if (page && page.length && page.some(({ id }) => !selectedRowIds[id])) {\n isAllPageRowsSelected = false\n }\n }\n\n const getAutoResetSelectedRows = useGetLatest(autoResetSelectedRows)\n\n useMountedLayoutEffect(() => {\n if (getAutoResetSelectedRows()) {\n dispatch({ type: actions.resetSelectedRows })\n }\n }, [dispatch, data])\n\n const toggleAllRowsSelected = React.useCallback(\n value => dispatch({ type: actions.toggleAllRowsSelected, value }),\n [dispatch]\n )\n\n const toggleAllPageRowsSelected = React.useCallback(\n value => dispatch({ type: actions.toggleAllPageRowsSelected, value }),\n [dispatch]\n )\n\n const toggleRowSelected = React.useCallback(\n (id, value) => dispatch({ type: actions.toggleRowSelected, id, value }),\n [dispatch]\n )\n\n const getInstance = useGetLatest(instance)\n\n const getToggleAllRowsSelectedProps = makePropGetter(\n getHooks().getToggleAllRowsSelectedProps,\n { instance: getInstance() }\n )\n\n const getToggleAllPageRowsSelectedProps = makePropGetter(\n getHooks().getToggleAllPageRowsSelectedProps,\n { instance: getInstance() }\n )\n\n Object.assign(instance, {\n selectedFlatRows,\n isAllRowsSelected,\n isAllPageRowsSelected,\n toggleRowSelected,\n toggleAllRowsSelected,\n getToggleAllRowsSelectedProps,\n getToggleAllPageRowsSelectedProps,\n toggleAllPageRowsSelected,\n })\n}\n\nfunction prepareRow(row, { instance }) {\n row.toggleRowSelected = set => instance.toggleRowSelected(row.id, set)\n\n row.getToggleRowSelectedProps = makePropGetter(\n instance.getHooks().getToggleRowSelectedProps,\n { instance: instance, row }\n )\n}\n\nfunction getRowIsSelected(row, selectedRowIds, getSubRows) {\n if (selectedRowIds[row.id]) {\n return true\n }\n\n const subRows = getSubRows(row)\n\n if (subRows && subRows.length) {\n let allChildrenSelected = true\n let someSelected = false\n\n subRows.forEach(subRow => {\n // Bail out early if we know both of these\n if (someSelected && !allChildrenSelected) {\n return\n }\n\n if (getRowIsSelected(subRow, selectedRowIds, getSubRows)) {\n someSelected = true\n } else {\n allChildrenSelected = false\n }\n })\n return allChildrenSelected ? true : someSelected ? null : false\n }\n\n return false\n}\n","import React from 'react'\n\nimport {\n actions,\n functionalUpdate,\n useMountedLayoutEffect,\n useGetLatest,\n} from '../publicUtils'\n\nconst defaultInitialRowStateAccessor = row => ({})\nconst defaultInitialCellStateAccessor = cell => ({})\n\n// Actions\nactions.setRowState = 'setRowState'\nactions.setCellState = 'setCellState'\nactions.resetRowState = 'resetRowState'\n\nexport const useRowState = hooks => {\n hooks.stateReducers.push(reducer)\n hooks.useInstance.push(useInstance)\n hooks.prepareRow.push(prepareRow)\n}\n\nuseRowState.pluginName = 'useRowState'\n\nfunction reducer(state, action, previousState, instance) {\n const {\n initialRowStateAccessor = defaultInitialRowStateAccessor,\n initialCellStateAccessor = defaultInitialCellStateAccessor,\n rowsById,\n } = instance\n\n if (action.type === actions.init) {\n return {\n rowState: {},\n ...state,\n }\n }\n\n if (action.type === actions.resetRowState) {\n return {\n ...state,\n rowState: instance.initialState.rowState || {},\n }\n }\n\n if (action.type === actions.setRowState) {\n const { rowId, value } = action\n\n const oldRowState =\n typeof state.rowState[rowId] !== 'undefined'\n ? state.rowState[rowId]\n : initialRowStateAccessor(rowsById[rowId])\n\n return {\n ...state,\n rowState: {\n ...state.rowState,\n [rowId]: functionalUpdate(value, oldRowState),\n },\n }\n }\n\n if (action.type === actions.setCellState) {\n const { rowId, columnId, value } = action\n\n const oldRowState =\n typeof state.rowState[rowId] !== 'undefined'\n ? state.rowState[rowId]\n : initialRowStateAccessor(rowsById[rowId])\n\n const oldCellState =\n typeof oldRowState?.cellState?.[columnId] !== 'undefined'\n ? oldRowState.cellState[columnId]\n : initialCellStateAccessor(\n rowsById[rowId]?.cells?.find(cell => cell.column.id === columnId)\n )\n\n return {\n ...state,\n rowState: {\n ...state.rowState,\n [rowId]: {\n ...oldRowState,\n cellState: {\n ...(oldRowState.cellState || {}),\n [columnId]: functionalUpdate(value, oldCellState),\n },\n },\n },\n }\n }\n}\n\nfunction useInstance(instance) {\n const { autoResetRowState = true, data, dispatch } = instance\n\n const setRowState = React.useCallback(\n (rowId, value) =>\n dispatch({\n type: actions.setRowState,\n rowId,\n value,\n }),\n [dispatch]\n )\n\n const setCellState = React.useCallback(\n (rowId, columnId, value) =>\n dispatch({\n type: actions.setCellState,\n rowId,\n columnId,\n value,\n }),\n [dispatch]\n )\n\n const getAutoResetRowState = useGetLatest(autoResetRowState)\n\n useMountedLayoutEffect(() => {\n if (getAutoResetRowState()) {\n dispatch({ type: actions.resetRowState })\n }\n }, [data])\n\n Object.assign(instance, {\n setRowState,\n setCellState,\n })\n}\n\nfunction prepareRow(row, { instance }) {\n const {\n initialRowStateAccessor = defaultInitialRowStateAccessor,\n initialCellStateAccessor = defaultInitialCellStateAccessor,\n state: { rowState },\n } = instance\n\n if (row) {\n row.state =\n typeof rowState[row.id] !== 'undefined'\n ? rowState[row.id]\n : initialRowStateAccessor(row)\n\n row.setState = updater => {\n return instance.setRowState(row.id, updater)\n }\n\n row.cells.forEach(cell => {\n if (!row.state.cellState) {\n row.state.cellState = {}\n }\n\n cell.state =\n typeof row.state.cellState[cell.column.id] !== 'undefined'\n ? row.state.cellState[cell.column.id]\n : initialCellStateAccessor(cell)\n\n cell.setState = updater => {\n return instance.setCellState(row.id, cell.column.id, updater)\n }\n })\n }\n}\n","import React from 'react'\n\nimport { functionalUpdate, actions } from '../publicUtils'\n\n// Actions\nactions.resetColumnOrder = 'resetColumnOrder'\nactions.setColumnOrder = 'setColumnOrder'\n\nexport const useColumnOrder = hooks => {\n hooks.stateReducers.push(reducer)\n hooks.visibleColumnsDeps.push((deps, { instance }) => {\n return [...deps, instance.state.columnOrder]\n })\n hooks.visibleColumns.push(visibleColumns)\n hooks.useInstance.push(useInstance)\n}\n\nuseColumnOrder.pluginName = 'useColumnOrder'\n\nfunction reducer(state, action, previousState, instance) {\n if (action.type === actions.init) {\n return {\n columnOrder: [],\n ...state,\n }\n }\n\n if (action.type === actions.resetColumnOrder) {\n return {\n ...state,\n columnOrder: instance.initialState.columnOrder || [],\n }\n }\n\n if (action.type === actions.setColumnOrder) {\n return {\n ...state,\n columnOrder: functionalUpdate(action.columnOrder, state.columnOrder),\n }\n }\n}\n\nfunction visibleColumns(\n columns,\n {\n instance: {\n state: { columnOrder },\n },\n }\n) {\n // If there is no order, return the normal columns\n if (!columnOrder || !columnOrder.length) {\n return columns\n }\n\n const columnOrderCopy = [...columnOrder]\n\n // If there is an order, make a copy of the columns\n const columnsCopy = [...columns]\n\n // And make a new ordered array of the columns\n const columnsInOrder = []\n\n // Loop over the columns and place them in order into the new array\n while (columnsCopy.length && columnOrderCopy.length) {\n const targetColumnId = columnOrderCopy.shift()\n const foundIndex = columnsCopy.findIndex(d => d.id === targetColumnId)\n if (foundIndex > -1) {\n columnsInOrder.push(columnsCopy.splice(foundIndex, 1)[0])\n }\n }\n\n // If there are any columns left, add them to the end\n return [...columnsInOrder, ...columnsCopy]\n}\n\nfunction useInstance(instance) {\n const { dispatch } = instance\n\n instance.setColumnOrder = React.useCallback(\n columnOrder => {\n return dispatch({ type: actions.setColumnOrder, columnOrder })\n },\n [dispatch]\n )\n}\n","import React from 'react'\n\nimport {\n actions,\n defaultColumn,\n makePropGetter,\n useGetLatest,\n ensurePluginOrder,\n useMountedLayoutEffect,\n} from '../publicUtils'\n\nimport { getFirstDefined, passiveEventSupported } from '../utils'\n\n// Default Column\ndefaultColumn.canResize = true\n\n// Actions\nactions.columnStartResizing = 'columnStartResizing'\nactions.columnResizing = 'columnResizing'\nactions.columnDoneResizing = 'columnDoneResizing'\nactions.resetResize = 'resetResize'\n\nexport const useResizeColumns = hooks => {\n hooks.getResizerProps = [defaultGetResizerProps]\n hooks.getHeaderProps.push({\n style: {\n position: 'relative',\n },\n })\n hooks.stateReducers.push(reducer)\n hooks.useInstance.push(useInstance)\n hooks.useInstanceBeforeDimensions.push(useInstanceBeforeDimensions)\n}\n\nconst defaultGetResizerProps = (props, { instance, header }) => {\n const { dispatch } = instance\n\n const onResizeStart = (e, header) => {\n let isTouchEvent = false\n if (e.type === 'touchstart') {\n // lets not respond to multiple touches (e.g. 2 or 3 fingers)\n if (e.touches && e.touches.length > 1) {\n return\n }\n isTouchEvent = true\n }\n const headersToResize = getLeafHeaders(header)\n const headerIdWidths = headersToResize.map(d => [d.id, d.totalWidth])\n\n const clientX = isTouchEvent ? Math.round(e.touches[0].clientX) : e.clientX\n\n const dispatchMove = clientXPos => {\n dispatch({ type: actions.columnResizing, clientX: clientXPos })\n }\n const dispatchEnd = () => dispatch({ type: actions.columnDoneResizing })\n\n const handlersAndEvents = {\n mouse: {\n moveEvent: 'mousemove',\n moveHandler: e => dispatchMove(e.clientX),\n upEvent: 'mouseup',\n upHandler: e => {\n document.removeEventListener(\n 'mousemove',\n handlersAndEvents.mouse.moveHandler\n )\n document.removeEventListener(\n 'mouseup',\n handlersAndEvents.mouse.upHandler\n )\n dispatchEnd()\n },\n },\n touch: {\n moveEvent: 'touchmove',\n moveHandler: e => {\n if (e.cancelable) {\n e.preventDefault()\n e.stopPropagation()\n }\n dispatchMove(e.touches[0].clientX)\n return false\n },\n upEvent: 'touchend',\n upHandler: e => {\n document.removeEventListener(\n handlersAndEvents.touch.moveEvent,\n handlersAndEvents.touch.moveHandler\n )\n document.removeEventListener(\n handlersAndEvents.touch.upEvent,\n handlersAndEvents.touch.moveHandler\n )\n dispatchEnd()\n },\n },\n }\n\n const events = isTouchEvent\n ? handlersAndEvents.touch\n : handlersAndEvents.mouse\n const passiveIfSupported = passiveEventSupported()\n ? { passive: false }\n : false\n document.addEventListener(\n events.moveEvent,\n events.moveHandler,\n passiveIfSupported\n )\n document.addEventListener(\n events.upEvent,\n events.upHandler,\n passiveIfSupported\n )\n\n dispatch({\n type: actions.columnStartResizing,\n columnId: header.id,\n columnWidth: header.totalWidth,\n headerIdWidths,\n clientX,\n })\n }\n\n return [\n props,\n {\n onMouseDown: e => e.persist() || onResizeStart(e, header),\n onTouchStart: e => e.persist() || onResizeStart(e, header),\n style: {\n cursor: 'col-resize',\n },\n draggable: false,\n role: 'separator',\n },\n ]\n}\n\nuseResizeColumns.pluginName = 'useResizeColumns'\n\nfunction reducer(state, action) {\n if (action.type === actions.init) {\n return {\n columnResizing: {\n columnWidths: {},\n },\n ...state,\n }\n }\n\n if (action.type === actions.resetResize) {\n return {\n ...state,\n columnResizing: {\n columnWidths: {},\n },\n }\n }\n\n if (action.type === actions.columnStartResizing) {\n const { clientX, columnId, columnWidth, headerIdWidths } = action\n\n return {\n ...state,\n columnResizing: {\n ...state.columnResizing,\n startX: clientX,\n headerIdWidths,\n columnWidth,\n isResizingColumn: columnId,\n },\n }\n }\n\n if (action.type === actions.columnResizing) {\n const { clientX } = action\n const { startX, columnWidth, headerIdWidths = [] } = state.columnResizing\n\n const deltaX = clientX - startX\n const percentageDeltaX = deltaX / columnWidth\n\n const newColumnWidths = {}\n\n headerIdWidths.forEach(([headerId, headerWidth]) => {\n newColumnWidths[headerId] = Math.max(\n headerWidth + headerWidth * percentageDeltaX,\n 0\n )\n })\n\n return {\n ...state,\n columnResizing: {\n ...state.columnResizing,\n columnWidths: {\n ...state.columnResizing.columnWidths,\n ...newColumnWidths,\n },\n },\n }\n }\n\n if (action.type === actions.columnDoneResizing) {\n return {\n ...state,\n columnResizing: {\n ...state.columnResizing,\n startX: null,\n isResizingColumn: null,\n },\n }\n }\n}\n\nconst useInstanceBeforeDimensions = instance => {\n const {\n flatHeaders,\n disableResizing,\n getHooks,\n state: { columnResizing },\n } = instance\n\n const getInstance = useGetLatest(instance)\n\n flatHeaders.forEach(header => {\n const canResize = getFirstDefined(\n header.disableResizing === true ? false : undefined,\n disableResizing === true ? false : undefined,\n true\n )\n\n header.canResize = canResize\n header.width =\n columnResizing.columnWidths[header.id] ||\n header.originalWidth ||\n header.width\n header.isResizing = columnResizing.isResizingColumn === header.id\n\n if (canResize) {\n header.getResizerProps = makePropGetter(getHooks().getResizerProps, {\n instance: getInstance(),\n header,\n })\n }\n })\n}\n\nfunction useInstance(instance) {\n const { plugins, dispatch, autoResetResize = true, columns } = instance\n\n ensurePluginOrder(plugins, ['useAbsoluteLayout'], 'useResizeColumns')\n\n const getAutoResetResize = useGetLatest(autoResetResize)\n useMountedLayoutEffect(() => {\n if (getAutoResetResize()) {\n dispatch({ type: actions.resetResize })\n }\n }, [columns])\n\n const resetResizing = React.useCallback(\n () => dispatch({ type: actions.resetResize }),\n [dispatch]\n )\n\n Object.assign(instance, {\n resetResizing,\n })\n}\n\nfunction getLeafHeaders(header) {\n const leafHeaders = []\n const recurseHeader = header => {\n if (header.columns && header.columns.length) {\n header.columns.map(recurseHeader)\n }\n leafHeaders.push(header)\n }\n recurseHeader(header)\n return leafHeaders\n}\n","const cellStyles = {\n position: 'absolute',\n top: 0,\n}\n\nexport const useAbsoluteLayout = hooks => {\n hooks.getTableBodyProps.push(getRowStyles)\n hooks.getRowProps.push(getRowStyles)\n hooks.getHeaderGroupProps.push(getRowStyles)\n hooks.getFooterGroupProps.push(getRowStyles)\n\n hooks.getHeaderProps.push((props, { column }) => [\n props,\n {\n style: {\n ...cellStyles,\n left: `${column.totalLeft}px`,\n width: `${column.totalWidth}px`,\n },\n },\n ])\n\n hooks.getCellProps.push((props, { cell }) => [\n props,\n {\n style: {\n ...cellStyles,\n left: `${cell.column.totalLeft}px`,\n width: `${cell.column.totalWidth}px`,\n },\n },\n ])\n\n hooks.getFooterProps.push((props, { column }) => [\n props,\n {\n style: {\n ...cellStyles,\n left: `${column.totalLeft}px`,\n width: `${column.totalWidth}px`,\n },\n },\n ])\n}\n\nuseAbsoluteLayout.pluginName = 'useAbsoluteLayout'\n\nconst getRowStyles = (props, { instance }) => [\n props,\n {\n style: {\n position: 'relative',\n width: `${instance.totalColumnsWidth}px`,\n },\n },\n]\n","const cellStyles = {\n display: 'inline-block',\n boxSizing: 'border-box',\n}\n\nconst getRowStyles = (props, { instance }) => [\n props,\n {\n style: {\n display: 'flex',\n width: `${instance.totalColumnsWidth}px`,\n },\n },\n]\n\nexport const useBlockLayout = hooks => {\n hooks.getRowProps.push(getRowStyles)\n hooks.getHeaderGroupProps.push(getRowStyles)\n hooks.getFooterGroupProps.push(getRowStyles)\n\n hooks.getHeaderProps.push((props, { column }) => [\n props,\n {\n style: {\n ...cellStyles,\n width: `${column.totalWidth}px`,\n },\n },\n ])\n\n hooks.getCellProps.push((props, { cell }) => [\n props,\n {\n style: {\n ...cellStyles,\n width: `${cell.column.totalWidth}px`,\n },\n },\n ])\n\n hooks.getFooterProps.push((props, { column }) => [\n props,\n {\n style: {\n ...cellStyles,\n width: `${column.totalWidth}px`,\n },\n },\n ])\n}\n\nuseBlockLayout.pluginName = 'useBlockLayout'\n","export function useFlexLayout(hooks) {\n hooks.getTableProps.push(getTableProps)\n hooks.getRowProps.push(getRowStyles)\n hooks.getHeaderGroupProps.push(getRowStyles)\n hooks.getFooterGroupProps.push(getRowStyles)\n hooks.getHeaderProps.push(getHeaderProps)\n hooks.getCellProps.push(getCellProps)\n hooks.getFooterProps.push(getFooterProps)\n}\n\nuseFlexLayout.pluginName = 'useFlexLayout'\n\nconst getTableProps = (props, { instance }) => [\n props,\n {\n style: {\n minWidth: `${instance.totalColumnsMinWidth}px`,\n },\n },\n]\n\nconst getRowStyles = (props, { instance }) => [\n props,\n {\n style: {\n display: 'flex',\n flex: '1 0 auto',\n minWidth: `${instance.totalColumnsMinWidth}px`,\n },\n },\n]\n\nconst getHeaderProps = (props, { column }) => [\n props,\n {\n style: {\n boxSizing: 'border-box',\n flex: column.totalFlexWidth\n ? `${column.totalFlexWidth} 0 auto`\n : undefined,\n minWidth: `${column.totalMinWidth}px`,\n width: `${column.totalWidth}px`,\n },\n },\n]\n\nconst getCellProps = (props, { cell }) => [\n props,\n {\n style: {\n boxSizing: 'border-box',\n flex: `${cell.column.totalFlexWidth} 0 auto`,\n minWidth: `${cell.column.totalMinWidth}px`,\n width: `${cell.column.totalWidth}px`,\n },\n },\n]\n\nconst getFooterProps = (props, { column }) => [\n props,\n {\n style: {\n boxSizing: 'border-box',\n flex: column.totalFlexWidth\n ? `${column.totalFlexWidth} 0 auto`\n : undefined,\n minWidth: `${column.totalMinWidth}px`,\n width: `${column.totalWidth}px`,\n },\n },\n]\n","export function useGridLayout(hooks) {\n hooks.stateReducers.push(reducer)\n hooks.getTableProps.push(getTableProps)\n hooks.getHeaderProps.push(getHeaderProps)\n}\n\nuseGridLayout.pluginName = 'useGridLayout'\n\nconst getTableProps = (props, { instance }) => [\n props,\n {\n style: {\n display: `grid`,\n gridTemplateColumns: instance.state.gridLayout.columnWidths.map(w => w).join(` `),\n },\n },\n]\n\nconst getHeaderProps = (props, { column }) => [\n props,\n {\n id: `header-cell-${column.id}`,\n style: {\n position: `sticky` //enables a scroll wrapper to be placed around the table and have sticky headers\n },\n },\n]\n\nfunction reducer(state, action, previousState, instance) {\n if (action.type === `init`) {\n return {\n gridLayout: {\n columnWidths: instance.columns.map(() => `auto`),\n },\n ...state,\n }\n }\n\n if (action.type === `columnStartResizing`) {\n const { columnId } = action\n const columnIndex = instance.visibleColumns.findIndex(col => col.id === columnId)\n const elWidth = getElementWidth(columnId)\n\n if (elWidth !== undefined) {\n return {\n ...state,\n gridLayout: {\n ...state.gridLayout,\n columnId,\n columnIndex,\n startingWidth: elWidth\n },\n }\n } else {\n return state\n }\n }\n\n if (action.type === `columnResizing`) {\n const {\n columnIndex,\n startingWidth,\n columnWidths,\n } = state.gridLayout\n\n const change = state.columnResizing.startX - action.clientX\n const newWidth = startingWidth - change\n const columnWidthsCopy = [...columnWidths]\n columnWidthsCopy[columnIndex] = `${newWidth}px`\n\n return {\n ...state,\n gridLayout: {\n ...state.gridLayout,\n columnWidths: columnWidthsCopy,\n },\n }\n }\n}\n\nfunction getElementWidth(columnId) {\n const width = document.getElementById(`header-cell-${columnId}`)?.offsetWidth\n\n if (width !== undefined) {\n return width\n }\n}","'use strict';\n\nvar keysShim;\nif (!Object.keys) {\n\t// modified from https://github.com/es-shims/es5-shim\n\tvar has = Object.prototype.hasOwnProperty;\n\tvar toStr = Object.prototype.toString;\n\tvar isArgs = require('./isArguments'); // eslint-disable-line global-require\n\tvar isEnumerable = Object.prototype.propertyIsEnumerable;\n\tvar hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString');\n\tvar hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype');\n\tvar dontEnums = [\n\t\t'toString',\n\t\t'toLocaleString',\n\t\t'valueOf',\n\t\t'hasOwnProperty',\n\t\t'isPrototypeOf',\n\t\t'propertyIsEnumerable',\n\t\t'constructor'\n\t];\n\tvar equalsConstructorPrototype = function (o) {\n\t\tvar ctor = o.constructor;\n\t\treturn ctor && ctor.prototype === o;\n\t};\n\tvar excludedKeys = {\n\t\t$applicationCache: true,\n\t\t$console: true,\n\t\t$external: true,\n\t\t$frame: true,\n\t\t$frameElement: true,\n\t\t$frames: true,\n\t\t$innerHeight: true,\n\t\t$innerWidth: true,\n\t\t$onmozfullscreenchange: true,\n\t\t$onmozfullscreenerror: true,\n\t\t$outerHeight: true,\n\t\t$outerWidth: true,\n\t\t$pageXOffset: true,\n\t\t$pageYOffset: true,\n\t\t$parent: true,\n\t\t$scrollLeft: true,\n\t\t$scrollTop: true,\n\t\t$scrollX: true,\n\t\t$scrollY: true,\n\t\t$self: true,\n\t\t$webkitIndexedDB: true,\n\t\t$webkitStorageInfo: true,\n\t\t$window: true\n\t};\n\tvar hasAutomationEqualityBug = (function () {\n\t\t/* global window */\n\t\tif (typeof window === 'undefined') { return false; }\n\t\tfor (var k in window) {\n\t\t\ttry {\n\t\t\t\tif (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tequalsConstructorPrototype(window[k]);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}());\n\tvar equalsConstructorPrototypeIfNotBuggy = function (o) {\n\t\t/* global window */\n\t\tif (typeof window === 'undefined' || !hasAutomationEqualityBug) {\n\t\t\treturn equalsConstructorPrototype(o);\n\t\t}\n\t\ttry {\n\t\t\treturn equalsConstructorPrototype(o);\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t};\n\n\tkeysShim = function keys(object) {\n\t\tvar isObject = object !== null && typeof object === 'object';\n\t\tvar isFunction = toStr.call(object) === '[object Function]';\n\t\tvar isArguments = isArgs(object);\n\t\tvar isString = isObject && toStr.call(object) === '[object String]';\n\t\tvar theKeys = [];\n\n\t\tif (!isObject && !isFunction && !isArguments) {\n\t\t\tthrow new TypeError('Object.keys called on a non-object');\n\t\t}\n\n\t\tvar skipProto = hasProtoEnumBug && isFunction;\n\t\tif (isString && object.length > 0 && !has.call(object, 0)) {\n\t\t\tfor (var i = 0; i < object.length; ++i) {\n\t\t\t\ttheKeys.push(String(i));\n\t\t\t}\n\t\t}\n\n\t\tif (isArguments && object.length > 0) {\n\t\t\tfor (var j = 0; j < object.length; ++j) {\n\t\t\t\ttheKeys.push(String(j));\n\t\t\t}\n\t\t} else {\n\t\t\tfor (var name in object) {\n\t\t\t\tif (!(skipProto && name === 'prototype') && has.call(object, name)) {\n\t\t\t\t\ttheKeys.push(String(name));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (hasDontEnumBug) {\n\t\t\tvar skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);\n\n\t\t\tfor (var k = 0; k < dontEnums.length; ++k) {\n\t\t\t\tif (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {\n\t\t\t\t\ttheKeys.push(dontEnums[k]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn theKeys;\n\t};\n}\nmodule.exports = keysShim;\n","'use strict';\n\nvar hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';\nvar toStr = Object.prototype.toString;\n\nvar isStandardArguments = function isArguments(value) {\n\tif (hasToStringTag && value && typeof value === 'object' && Symbol.toStringTag in value) {\n\t\treturn false;\n\t}\n\treturn toStr.call(value) === '[object Arguments]';\n};\n\nvar isLegacyArguments = function isArguments(value) {\n\tif (isStandardArguments(value)) {\n\t\treturn true;\n\t}\n\treturn value !== null &&\n\t\ttypeof value === 'object' &&\n\t\ttypeof value.length === 'number' &&\n\t\tvalue.length >= 0 &&\n\t\ttoStr.call(value) !== '[object Array]' &&\n\t\ttoStr.call(value.callee) === '[object Function]';\n};\n\nvar supportsStandardArguments = (function () {\n\treturn isStandardArguments(arguments);\n}());\n\nisStandardArguments.isLegacyArguments = isLegacyArguments; // for tests\n\nmodule.exports = supportsStandardArguments ? isStandardArguments : isLegacyArguments;\n","\"use strict\";\n\n/* https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.is */\n\nvar NumberIsNaN = function (value) {\n\treturn value !== value;\n};\n\nmodule.exports = function is(a, b) {\n\tif (a === 0 && b === 0) {\n\t\treturn 1 / a === 1 / b;\n\t} else if (a === b) {\n\t\treturn true;\n\t} else if (NumberIsNaN(a) && NumberIsNaN(b)) {\n\t\treturn true;\n\t}\n\treturn false;\n};\n\n","'use strict';\n\nvar has = require('has');\nvar regexExec = RegExp.prototype.exec;\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nvar tryRegexExecCall = function tryRegexExec(value) {\n\ttry {\n\t\tvar lastIndex = value.lastIndex;\n\t\tvalue.lastIndex = 0;\n\n\t\tregexExec.call(value);\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\tvalue.lastIndex = lastIndex;\n\t}\n};\nvar toStr = Object.prototype.toString;\nvar regexClass = '[object RegExp]';\nvar hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';\n\nmodule.exports = function isRegex(value) {\n\tif (!value || typeof value !== 'object') {\n\t\treturn false;\n\t}\n\tif (!hasToStringTag) {\n\t\treturn toStr.call(value) === regexClass;\n\t}\n\n\tvar descriptor = gOPD(value, 'lastIndex');\n\tvar hasLastIndexDataProperty = descriptor && has(descriptor, 'value');\n\tif (!hasLastIndexDataProperty) {\n\t\treturn false;\n\t}\n\n\treturn tryRegexExecCall(value);\n};\n","'use strict';\n\n/* eslint no-invalid-this: 1 */\n\nvar ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';\nvar slice = Array.prototype.slice;\nvar toStr = Object.prototype.toString;\nvar funcType = '[object Function]';\n\nmodule.exports = function bind(that) {\n var target = this;\n if (typeof target !== 'function' || toStr.call(target) !== funcType) {\n throw new TypeError(ERROR_MESSAGE + target);\n }\n var args = slice.call(arguments, 1);\n\n var bound;\n var binder = function () {\n if (this instanceof bound) {\n var result = target.apply(\n this,\n args.concat(slice.call(arguments))\n );\n if (Object(result) === result) {\n return result;\n }\n return this;\n } else {\n return target.apply(\n that,\n args.concat(slice.call(arguments))\n );\n }\n };\n\n var boundLength = Math.max(0, target.length - args.length);\n var boundArgs = [];\n for (var i = 0; i < boundLength; i++) {\n boundArgs.push('$' + i);\n }\n\n bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);\n\n if (target.prototype) {\n var Empty = function Empty() {};\n Empty.prototype = target.prototype;\n bound.prototype = new Empty();\n Empty.prototype = null;\n }\n\n return bound;\n};\n","'use strict';\n\nvar define = require('define-properties');\n\nvar implementation = require('./implementation');\nvar getPolyfill = require('./polyfill');\nvar shim = require('./shim');\n\nvar flagsBound = Function.call.bind(implementation);\n\ndefine(flagsBound, {\n\tgetPolyfill: getPolyfill,\n\timplementation: implementation,\n\tshim: shim\n});\n\nmodule.exports = flagsBound;\n","'use strict';\n\nvar supportsDescriptors = require('define-properties').supportsDescriptors;\nvar getPolyfill = require('./polyfill');\nvar gOPD = Object.getOwnPropertyDescriptor;\nvar defineProperty = Object.defineProperty;\nvar TypeErr = TypeError;\nvar getProto = Object.getPrototypeOf;\nvar regex = /a/;\n\nmodule.exports = function shimFlags() {\n\tif (!supportsDescriptors || !getProto) {\n\t\tthrow new TypeErr('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');\n\t}\n\tvar polyfill = getPolyfill();\n\tvar proto = getProto(regex);\n\tvar descriptor = gOPD(proto, 'flags');\n\tif (!descriptor || descriptor.get !== polyfill) {\n\t\tdefineProperty(proto, 'flags', {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tget: polyfill\n\t\t});\n\t}\n\treturn polyfill;\n};\n","'use strict';\n\nvar getDay = Date.prototype.getDay;\nvar tryDateObject = function tryDateObject(value) {\n\ttry {\n\t\tgetDay.call(value);\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n};\n\nvar toStr = Object.prototype.toString;\nvar dateClass = '[object Date]';\nvar hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';\n\nmodule.exports = function isDateObject(value) {\n\tif (typeof value !== 'object' || value === null) { return false; }\n\treturn hasToStringTag ? tryDateObject(value) : toStr.call(value) === dateClass;\n};\n","'use strict';\n\nvar getSideChannel = require('side-channel');\nvar utils = require('./utils');\nvar formats = require('./formats');\nvar has = Object.prototype.hasOwnProperty;\n\nvar arrayPrefixGenerators = {\n brackets: function brackets(prefix) {\n return prefix + '[]';\n },\n comma: 'comma',\n indices: function indices(prefix, key) {\n return prefix + '[' + key + ']';\n },\n repeat: function repeat(prefix) {\n return prefix;\n }\n};\n\nvar isArray = Array.isArray;\nvar split = String.prototype.split;\nvar push = Array.prototype.push;\nvar pushToArray = function (arr, valueOrArray) {\n push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]);\n};\n\nvar toISO = Date.prototype.toISOString;\n\nvar defaultFormat = formats['default'];\nvar defaults = {\n addQueryPrefix: false,\n allowDots: false,\n charset: 'utf-8',\n charsetSentinel: false,\n delimiter: '&',\n encode: true,\n encoder: utils.encode,\n encodeValuesOnly: false,\n format: defaultFormat,\n formatter: formats.formatters[defaultFormat],\n // deprecated\n indices: false,\n serializeDate: function serializeDate(date) {\n return toISO.call(date);\n },\n skipNulls: false,\n strictNullHandling: false\n};\n\nvar isNonNullishPrimitive = function isNonNullishPrimitive(v) {\n return typeof v === 'string'\n || typeof v === 'number'\n || typeof v === 'boolean'\n || typeof v === 'symbol'\n || typeof v === 'bigint';\n};\n\nvar sentinel = {};\n\nvar stringify = function stringify(\n object,\n prefix,\n generateArrayPrefix,\n strictNullHandling,\n skipNulls,\n encoder,\n filter,\n sort,\n allowDots,\n serializeDate,\n format,\n formatter,\n encodeValuesOnly,\n charset,\n sideChannel\n) {\n var obj = object;\n\n var tmpSc = sideChannel;\n var step = 0;\n var findFlag = false;\n while ((tmpSc = tmpSc.get(sentinel)) !== void undefined && !findFlag) {\n // Where object last appeared in the ref tree\n var pos = tmpSc.get(object);\n step += 1;\n if (typeof pos !== 'undefined') {\n if (pos === step) {\n throw new RangeError('Cyclic object value');\n } else {\n findFlag = true; // Break while\n }\n }\n if (typeof tmpSc.get(sentinel) === 'undefined') {\n step = 0;\n }\n }\n\n if (typeof filter === 'function') {\n obj = filter(prefix, obj);\n } else if (obj instanceof Date) {\n obj = serializeDate(obj);\n } else if (generateArrayPrefix === 'comma' && isArray(obj)) {\n obj = utils.maybeMap(obj, function (value) {\n if (value instanceof Date) {\n return serializeDate(value);\n }\n return value;\n });\n }\n\n if (obj === null) {\n if (strictNullHandling) {\n return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key', format) : prefix;\n }\n\n obj = '';\n }\n\n if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {\n if (encoder) {\n var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format);\n if (generateArrayPrefix === 'comma' && encodeValuesOnly) {\n var valuesArray = split.call(String(obj), ',');\n var valuesJoined = '';\n for (var i = 0; i < valuesArray.length; ++i) {\n valuesJoined += (i === 0 ? '' : ',') + formatter(encoder(valuesArray[i], defaults.encoder, charset, 'value', format));\n }\n return [formatter(keyValue) + '=' + valuesJoined];\n }\n return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))];\n }\n return [formatter(prefix) + '=' + formatter(String(obj))];\n }\n\n var values = [];\n\n if (typeof obj === 'undefined') {\n return values;\n }\n\n var objKeys;\n if (generateArrayPrefix === 'comma' && isArray(obj)) {\n // we need to join elements in\n objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }];\n } else if (isArray(filter)) {\n objKeys = filter;\n } else {\n var keys = Object.keys(obj);\n objKeys = sort ? keys.sort(sort) : keys;\n }\n\n for (var j = 0; j < objKeys.length; ++j) {\n var key = objKeys[j];\n var value = typeof key === 'object' && typeof key.value !== 'undefined' ? key.value : obj[key];\n\n if (skipNulls && value === null) {\n continue;\n }\n\n var keyPrefix = isArray(obj)\n ? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(prefix, key) : prefix\n : prefix + (allowDots ? '.' + key : '[' + key + ']');\n\n sideChannel.set(object, step);\n var valueSideChannel = getSideChannel();\n valueSideChannel.set(sentinel, sideChannel);\n pushToArray(values, stringify(\n value,\n keyPrefix,\n generateArrayPrefix,\n strictNullHandling,\n skipNulls,\n encoder,\n filter,\n sort,\n allowDots,\n serializeDate,\n format,\n formatter,\n encodeValuesOnly,\n charset,\n valueSideChannel\n ));\n }\n\n return values;\n};\n\nvar normalizeStringifyOptions = function normalizeStringifyOptions(opts) {\n if (!opts) {\n return defaults;\n }\n\n if (opts.encoder !== null && typeof opts.encoder !== 'undefined' && typeof opts.encoder !== 'function') {\n throw new TypeError('Encoder has to be a function.');\n }\n\n var charset = opts.charset || defaults.charset;\n if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {\n throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');\n }\n\n var format = formats['default'];\n if (typeof opts.format !== 'undefined') {\n if (!has.call(formats.formatters, opts.format)) {\n throw new TypeError('Unknown format option provided.');\n }\n format = opts.format;\n }\n var formatter = formats.formatters[format];\n\n var filter = defaults.filter;\n if (typeof opts.filter === 'function' || isArray(opts.filter)) {\n filter = opts.filter;\n }\n\n return {\n addQueryPrefix: typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults.addQueryPrefix,\n allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots,\n charset: charset,\n charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,\n delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter,\n encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode,\n encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder,\n encodeValuesOnly: typeof opts.encodeValuesOnly === 'boolean' ? opts.encodeValuesOnly : defaults.encodeValuesOnly,\n filter: filter,\n format: format,\n formatter: formatter,\n serializeDate: typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults.serializeDate,\n skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults.skipNulls,\n sort: typeof opts.sort === 'function' ? opts.sort : null,\n strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling\n };\n};\n\nmodule.exports = function (object, opts) {\n var obj = object;\n var options = normalizeStringifyOptions(opts);\n\n var objKeys;\n var filter;\n\n if (typeof options.filter === 'function') {\n filter = options.filter;\n obj = filter('', obj);\n } else if (isArray(options.filter)) {\n filter = options.filter;\n objKeys = filter;\n }\n\n var keys = [];\n\n if (typeof obj !== 'object' || obj === null) {\n return '';\n }\n\n var arrayFormat;\n if (opts && opts.arrayFormat in arrayPrefixGenerators) {\n arrayFormat = opts.arrayFormat;\n } else if (opts && 'indices' in opts) {\n arrayFormat = opts.indices ? 'indices' : 'repeat';\n } else {\n arrayFormat = 'indices';\n }\n\n var generateArrayPrefix = arrayPrefixGenerators[arrayFormat];\n\n if (!objKeys) {\n objKeys = Object.keys(obj);\n }\n\n if (options.sort) {\n objKeys.sort(options.sort);\n }\n\n var sideChannel = getSideChannel();\n for (var i = 0; i < objKeys.length; ++i) {\n var key = objKeys[i];\n\n if (options.skipNulls && obj[key] === null) {\n continue;\n }\n pushToArray(keys, stringify(\n obj[key],\n key,\n generateArrayPrefix,\n options.strictNullHandling,\n options.skipNulls,\n options.encode ? options.encoder : null,\n options.filter,\n options.sort,\n options.allowDots,\n options.serializeDate,\n options.format,\n options.formatter,\n options.encodeValuesOnly,\n options.charset,\n sideChannel\n ));\n }\n\n var joined = keys.join(options.delimiter);\n var prefix = options.addQueryPrefix === true ? '?' : '';\n\n if (options.charsetSentinel) {\n if (options.charset === 'iso-8859-1') {\n // encodeURIComponent('✓'), the \"numeric entity\" representation of a checkmark\n prefix += 'utf8=%26%2310003%3B&';\n } else {\n // encodeURIComponent('✓')\n prefix += 'utf8=%E2%9C%93&';\n }\n }\n\n return joined.length > 0 ? prefix + joined : '';\n};\n","'use strict';\n\nvar GetIntrinsic = require('get-intrinsic');\nvar callBound = require('call-bind/callBound');\nvar inspect = require('object-inspect');\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $WeakMap = GetIntrinsic('%WeakMap%', true);\nvar $Map = GetIntrinsic('%Map%', true);\n\nvar $weakMapGet = callBound('WeakMap.prototype.get', true);\nvar $weakMapSet = callBound('WeakMap.prototype.set', true);\nvar $weakMapHas = callBound('WeakMap.prototype.has', true);\nvar $mapGet = callBound('Map.prototype.get', true);\nvar $mapSet = callBound('Map.prototype.set', true);\nvar $mapHas = callBound('Map.prototype.has', true);\n\n/*\n * This function traverses the list returning the node corresponding to the\n * given key.\n *\n * That node is also moved to the head of the list, so that if it's accessed\n * again we don't need to traverse the whole list. By doing so, all the recently\n * used nodes can be accessed relatively quickly.\n */\nvar listGetNode = function (list, key) { // eslint-disable-line consistent-return\n\tfor (var prev = list, curr; (curr = prev.next) !== null; prev = curr) {\n\t\tif (curr.key === key) {\n\t\t\tprev.next = curr.next;\n\t\t\tcurr.next = list.next;\n\t\t\tlist.next = curr; // eslint-disable-line no-param-reassign\n\t\t\treturn curr;\n\t\t}\n\t}\n};\n\nvar listGet = function (objects, key) {\n\tvar node = listGetNode(objects, key);\n\treturn node && node.value;\n};\nvar listSet = function (objects, key, value) {\n\tvar node = listGetNode(objects, key);\n\tif (node) {\n\t\tnode.value = value;\n\t} else {\n\t\t// Prepend the new node to the beginning of the list\n\t\tobjects.next = { // eslint-disable-line no-param-reassign\n\t\t\tkey: key,\n\t\t\tnext: objects.next,\n\t\t\tvalue: value\n\t\t};\n\t}\n};\nvar listHas = function (objects, key) {\n\treturn !!listGetNode(objects, key);\n};\n\nmodule.exports = function getSideChannel() {\n\tvar $wm;\n\tvar $m;\n\tvar $o;\n\tvar channel = {\n\t\tassert: function (key) {\n\t\t\tif (!channel.has(key)) {\n\t\t\t\tthrow new $TypeError('Side channel does not contain ' + inspect(key));\n\t\t\t}\n\t\t},\n\t\tget: function (key) { // eslint-disable-line consistent-return\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif ($wm) {\n\t\t\t\t\treturn $weakMapGet($wm, key);\n\t\t\t\t}\n\t\t\t} else if ($Map) {\n\t\t\t\tif ($m) {\n\t\t\t\t\treturn $mapGet($m, key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ($o) { // eslint-disable-line no-lonely-if\n\t\t\t\t\treturn listGet($o, key);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\thas: function (key) {\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif ($wm) {\n\t\t\t\t\treturn $weakMapHas($wm, key);\n\t\t\t\t}\n\t\t\t} else if ($Map) {\n\t\t\t\tif ($m) {\n\t\t\t\t\treturn $mapHas($m, key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ($o) { // eslint-disable-line no-lonely-if\n\t\t\t\t\treturn listHas($o, key);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tset: function (key, value) {\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif (!$wm) {\n\t\t\t\t\t$wm = new $WeakMap();\n\t\t\t\t}\n\t\t\t\t$weakMapSet($wm, key, value);\n\t\t\t} else if ($Map) {\n\t\t\t\tif (!$m) {\n\t\t\t\t\t$m = new $Map();\n\t\t\t\t}\n\t\t\t\t$mapSet($m, key, value);\n\t\t\t} else {\n\t\t\t\tif (!$o) {\n\t\t\t\t\t/*\n\t\t\t\t\t * Initialize the linked list as an empty node, so that we don't have\n\t\t\t\t\t * to special-case handling of the first node: we can always refer to\n\t\t\t\t\t * it as (previous node).next, instead of something like (list).head\n\t\t\t\t\t */\n\t\t\t\t\t$o = { key: {}, next: null };\n\t\t\t\t}\n\t\t\t\tlistSet($o, key, value);\n\t\t\t}\n\t\t}\n\t};\n\treturn channel;\n};\n","'use strict';\n\nvar origSymbol = typeof Symbol !== 'undefined' && Symbol;\nvar hasSymbolSham = require('./shams');\n\nmodule.exports = function hasNativeSymbols() {\n\tif (typeof origSymbol !== 'function') { return false; }\n\tif (typeof Symbol !== 'function') { return false; }\n\tif (typeof origSymbol('foo') !== 'symbol') { return false; }\n\tif (typeof Symbol('bar') !== 'symbol') { return false; }\n\n\treturn hasSymbolSham();\n};\n","'use strict';\n\n/* eslint complexity: [2, 18], max-statements: [2, 33] */\nmodule.exports = function hasSymbols() {\n\tif (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; }\n\tif (typeof Symbol.iterator === 'symbol') { return true; }\n\n\tvar obj = {};\n\tvar sym = Symbol('test');\n\tvar symObj = Object(sym);\n\tif (typeof sym === 'string') { return false; }\n\n\tif (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; }\n\tif (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; }\n\n\t// temp disabled per https://github.com/ljharb/object.assign/issues/17\n\t// if (sym instanceof Symbol) { return false; }\n\t// temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4\n\t// if (!(symObj instanceof Symbol)) { return false; }\n\n\t// if (typeof Symbol.prototype.toString !== 'function') { return false; }\n\t// if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; }\n\n\tvar symVal = 42;\n\tobj[sym] = symVal;\n\tfor (sym in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop\n\tif (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; }\n\n\tif (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; }\n\n\tvar syms = Object.getOwnPropertySymbols(obj);\n\tif (syms.length !== 1 || syms[0] !== sym) { return false; }\n\n\tif (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; }\n\n\tif (typeof Object.getOwnPropertyDescriptor === 'function') {\n\t\tvar descriptor = Object.getOwnPropertyDescriptor(obj, sym);\n\t\tif (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; }\n\t}\n\n\treturn true;\n};\n","'use strict';\n\nvar GetIntrinsic = require('get-intrinsic');\n\nvar callBind = require('./');\n\nvar $indexOf = callBind(GetIntrinsic('String.prototype.indexOf'));\n\nmodule.exports = function callBoundIntrinsic(name, allowMissing) {\n\tvar intrinsic = GetIntrinsic(name, !!allowMissing);\n\tif (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) {\n\t\treturn callBind(intrinsic);\n\t}\n\treturn intrinsic;\n};\n","'use strict';\n\nvar bind = require('function-bind');\nvar GetIntrinsic = require('get-intrinsic');\n\nvar $apply = GetIntrinsic('%Function.prototype.apply%');\nvar $call = GetIntrinsic('%Function.prototype.call%');\nvar $reflectApply = GetIntrinsic('%Reflect.apply%', true) || bind.call($call, $apply);\n\nvar $gOPD = GetIntrinsic('%Object.getOwnPropertyDescriptor%', true);\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\nvar $max = GetIntrinsic('%Math.max%');\n\nif ($defineProperty) {\n\ttry {\n\t\t$defineProperty({}, 'a', { value: 1 });\n\t} catch (e) {\n\t\t// IE 8 has a broken defineProperty\n\t\t$defineProperty = null;\n\t}\n}\n\nmodule.exports = function callBind(originalFunction) {\n\tvar func = $reflectApply(bind, $call, arguments);\n\tif ($gOPD && $defineProperty) {\n\t\tvar desc = $gOPD(func, 'length');\n\t\tif (desc.configurable) {\n\t\t\t// original length, plus the receiver, minus any additional arguments (after the receiver)\n\t\t\t$defineProperty(\n\t\t\t\tfunc,\n\t\t\t\t'length',\n\t\t\t\t{ value: 1 + $max(0, originalFunction.length - (arguments.length - 1)) }\n\t\t\t);\n\t\t}\n\t}\n\treturn func;\n};\n\nvar applyBind = function applyBind() {\n\treturn $reflectApply(bind, $apply, arguments);\n};\n\nif ($defineProperty) {\n\t$defineProperty(module.exports, 'apply', { value: applyBind });\n} else {\n\tmodule.exports.apply = applyBind;\n}\n","var hasMap = typeof Map === 'function' && Map.prototype;\nvar mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null;\nvar mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null;\nvar mapForEach = hasMap && Map.prototype.forEach;\nvar hasSet = typeof Set === 'function' && Set.prototype;\nvar setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null;\nvar setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null;\nvar setForEach = hasSet && Set.prototype.forEach;\nvar hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype;\nvar weakMapHas = hasWeakMap ? WeakMap.prototype.has : null;\nvar hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype;\nvar weakSetHas = hasWeakSet ? WeakSet.prototype.has : null;\nvar hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype;\nvar weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null;\nvar booleanValueOf = Boolean.prototype.valueOf;\nvar objectToString = Object.prototype.toString;\nvar functionToString = Function.prototype.toString;\nvar $match = String.prototype.match;\nvar $slice = String.prototype.slice;\nvar $replace = String.prototype.replace;\nvar $toUpperCase = String.prototype.toUpperCase;\nvar $toLowerCase = String.prototype.toLowerCase;\nvar $test = RegExp.prototype.test;\nvar $concat = Array.prototype.concat;\nvar $join = Array.prototype.join;\nvar $arrSlice = Array.prototype.slice;\nvar $floor = Math.floor;\nvar bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;\nvar gOPS = Object.getOwnPropertySymbols;\nvar symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null;\nvar hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object';\n// ie, `has-tostringtag/shams\nvar toStringTag = typeof Symbol === 'function' && Symbol.toStringTag && (typeof Symbol.toStringTag === hasShammedSymbols ? 'object' : 'symbol')\n ? Symbol.toStringTag\n : null;\nvar isEnumerable = Object.prototype.propertyIsEnumerable;\n\nvar gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || (\n [].__proto__ === Array.prototype // eslint-disable-line no-proto\n ? function (O) {\n return O.__proto__; // eslint-disable-line no-proto\n }\n : null\n);\n\nfunction addNumericSeparator(num, str) {\n if (\n num === Infinity\n || num === -Infinity\n || num !== num\n || (num && num > -1000 && num < 1000)\n || $test.call(/e/, str)\n ) {\n return str;\n }\n var sepRegex = /[0-9](?=(?:[0-9]{3})+(?![0-9]))/g;\n if (typeof num === 'number') {\n var int = num < 0 ? -$floor(-num) : $floor(num); // trunc(num)\n if (int !== num) {\n var intStr = String(int);\n var dec = $slice.call(str, intStr.length + 1);\n return $replace.call(intStr, sepRegex, '$&_') + '.' + $replace.call($replace.call(dec, /([0-9]{3})/g, '$&_'), /_$/, '');\n }\n }\n return $replace.call(str, sepRegex, '$&_');\n}\n\nvar inspectCustom = require('./util.inspect').custom;\nvar inspectSymbol = inspectCustom && isSymbol(inspectCustom) ? inspectCustom : null;\n\nmodule.exports = function inspect_(obj, options, depth, seen) {\n var opts = options || {};\n\n if (has(opts, 'quoteStyle') && (opts.quoteStyle !== 'single' && opts.quoteStyle !== 'double')) {\n throw new TypeError('option \"quoteStyle\" must be \"single\" or \"double\"');\n }\n if (\n has(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number'\n ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity\n : opts.maxStringLength !== null\n )\n ) {\n throw new TypeError('option \"maxStringLength\", if provided, must be a positive integer, Infinity, or `null`');\n }\n var customInspect = has(opts, 'customInspect') ? opts.customInspect : true;\n if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') {\n throw new TypeError('option \"customInspect\", if provided, must be `true`, `false`, or `\\'symbol\\'`');\n }\n\n if (\n has(opts, 'indent')\n && opts.indent !== null\n && opts.indent !== '\\t'\n && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)\n ) {\n throw new TypeError('option \"indent\" must be \"\\\\t\", an integer > 0, or `null`');\n }\n if (has(opts, 'numericSeparator') && typeof opts.numericSeparator !== 'boolean') {\n throw new TypeError('option \"numericSeparator\", if provided, must be `true` or `false`');\n }\n var numericSeparator = opts.numericSeparator;\n\n if (typeof obj === 'undefined') {\n return 'undefined';\n }\n if (obj === null) {\n return 'null';\n }\n if (typeof obj === 'boolean') {\n return obj ? 'true' : 'false';\n }\n\n if (typeof obj === 'string') {\n return inspectString(obj, opts);\n }\n if (typeof obj === 'number') {\n if (obj === 0) {\n return Infinity / obj > 0 ? '0' : '-0';\n }\n var str = String(obj);\n return numericSeparator ? addNumericSeparator(obj, str) : str;\n }\n if (typeof obj === 'bigint') {\n var bigIntStr = String(obj) + 'n';\n return numericSeparator ? addNumericSeparator(obj, bigIntStr) : bigIntStr;\n }\n\n var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth;\n if (typeof depth === 'undefined') { depth = 0; }\n if (depth >= maxDepth && maxDepth > 0 && typeof obj === 'object') {\n return isArray(obj) ? '[Array]' : '[Object]';\n }\n\n var indent = getIndent(opts, depth);\n\n if (typeof seen === 'undefined') {\n seen = [];\n } else if (indexOf(seen, obj) >= 0) {\n return '[Circular]';\n }\n\n function inspect(value, from, noIndent) {\n if (from) {\n seen = $arrSlice.call(seen);\n seen.push(from);\n }\n if (noIndent) {\n var newOpts = {\n depth: opts.depth\n };\n if (has(opts, 'quoteStyle')) {\n newOpts.quoteStyle = opts.quoteStyle;\n }\n return inspect_(value, newOpts, depth + 1, seen);\n }\n return inspect_(value, opts, depth + 1, seen);\n }\n\n if (typeof obj === 'function') {\n var name = nameOf(obj);\n var keys = arrObjKeys(obj, inspect);\n return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + $join.call(keys, ', ') + ' }' : '');\n }\n if (isSymbol(obj)) {\n var symString = hasShammedSymbols ? $replace.call(String(obj), /^(Symbol\\(.*\\))_[^)]*$/, '$1') : symToString.call(obj);\n return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString;\n }\n if (isElement(obj)) {\n var s = '<' + $toLowerCase.call(String(obj.nodeName));\n var attrs = obj.attributes || [];\n for (var i = 0; i < attrs.length; i++) {\n s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts);\n }\n s += '>';\n if (obj.childNodes && obj.childNodes.length) { s += '...'; }\n s += '';\n return s;\n }\n if (isArray(obj)) {\n if (obj.length === 0) { return '[]'; }\n var xs = arrObjKeys(obj, inspect);\n if (indent && !singleLineValues(xs)) {\n return '[' + indentedJoin(xs, indent) + ']';\n }\n return '[ ' + $join.call(xs, ', ') + ' ]';\n }\n if (isError(obj)) {\n var parts = arrObjKeys(obj, inspect);\n if ('cause' in obj && !isEnumerable.call(obj, 'cause')) {\n return '{ [' + String(obj) + '] ' + $join.call($concat.call('[cause]: ' + inspect(obj.cause), parts), ', ') + ' }';\n }\n if (parts.length === 0) { return '[' + String(obj) + ']'; }\n return '{ [' + String(obj) + '] ' + $join.call(parts, ', ') + ' }';\n }\n if (typeof obj === 'object' && customInspect) {\n if (inspectSymbol && typeof obj[inspectSymbol] === 'function') {\n return obj[inspectSymbol]();\n } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') {\n return obj.inspect();\n }\n }\n if (isMap(obj)) {\n var mapParts = [];\n mapForEach.call(obj, function (value, key) {\n mapParts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj));\n });\n return collectionOf('Map', mapSize.call(obj), mapParts, indent);\n }\n if (isSet(obj)) {\n var setParts = [];\n setForEach.call(obj, function (value) {\n setParts.push(inspect(value, obj));\n });\n return collectionOf('Set', setSize.call(obj), setParts, indent);\n }\n if (isWeakMap(obj)) {\n return weakCollectionOf('WeakMap');\n }\n if (isWeakSet(obj)) {\n return weakCollectionOf('WeakSet');\n }\n if (isWeakRef(obj)) {\n return weakCollectionOf('WeakRef');\n }\n if (isNumber(obj)) {\n return markBoxed(inspect(Number(obj)));\n }\n if (isBigInt(obj)) {\n return markBoxed(inspect(bigIntValueOf.call(obj)));\n }\n if (isBoolean(obj)) {\n return markBoxed(booleanValueOf.call(obj));\n }\n if (isString(obj)) {\n return markBoxed(inspect(String(obj)));\n }\n if (!isDate(obj) && !isRegExp(obj)) {\n var ys = arrObjKeys(obj, inspect);\n var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;\n var protoTag = obj instanceof Object ? '' : 'null prototype';\n var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? $slice.call(toStr(obj), 8, -1) : protoTag ? 'Object' : '';\n var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : '';\n var tag = constructorTag + (stringTag || protoTag ? '[' + $join.call($concat.call([], stringTag || [], protoTag || []), ': ') + '] ' : '');\n if (ys.length === 0) { return tag + '{}'; }\n if (indent) {\n return tag + '{' + indentedJoin(ys, indent) + '}';\n }\n return tag + '{ ' + $join.call(ys, ', ') + ' }';\n }\n return String(obj);\n};\n\nfunction wrapQuotes(s, defaultStyle, opts) {\n var quoteChar = (opts.quoteStyle || defaultStyle) === 'double' ? '\"' : \"'\";\n return quoteChar + s + quoteChar;\n}\n\nfunction quote(s) {\n return $replace.call(String(s), /\"/g, '"');\n}\n\nfunction isArray(obj) { return toStr(obj) === '[object Array]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isDate(obj) { return toStr(obj) === '[object Date]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isRegExp(obj) { return toStr(obj) === '[object RegExp]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isError(obj) { return toStr(obj) === '[object Error]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isString(obj) { return toStr(obj) === '[object String]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isNumber(obj) { return toStr(obj) === '[object Number]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isBoolean(obj) { return toStr(obj) === '[object Boolean]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\n\n// Symbol and BigInt do have Symbol.toStringTag by spec, so that can't be used to eliminate false positives\nfunction isSymbol(obj) {\n if (hasShammedSymbols) {\n return obj && typeof obj === 'object' && obj instanceof Symbol;\n }\n if (typeof obj === 'symbol') {\n return true;\n }\n if (!obj || typeof obj !== 'object' || !symToString) {\n return false;\n }\n try {\n symToString.call(obj);\n return true;\n } catch (e) {}\n return false;\n}\n\nfunction isBigInt(obj) {\n if (!obj || typeof obj !== 'object' || !bigIntValueOf) {\n return false;\n }\n try {\n bigIntValueOf.call(obj);\n return true;\n } catch (e) {}\n return false;\n}\n\nvar hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; };\nfunction has(obj, key) {\n return hasOwn.call(obj, key);\n}\n\nfunction toStr(obj) {\n return objectToString.call(obj);\n}\n\nfunction nameOf(f) {\n if (f.name) { return f.name; }\n var m = $match.call(functionToString.call(f), /^function\\s*([\\w$]+)/);\n if (m) { return m[1]; }\n return null;\n}\n\nfunction indexOf(xs, x) {\n if (xs.indexOf) { return xs.indexOf(x); }\n for (var i = 0, l = xs.length; i < l; i++) {\n if (xs[i] === x) { return i; }\n }\n return -1;\n}\n\nfunction isMap(x) {\n if (!mapSize || !x || typeof x !== 'object') {\n return false;\n }\n try {\n mapSize.call(x);\n try {\n setSize.call(x);\n } catch (s) {\n return true;\n }\n return x instanceof Map; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakMap(x) {\n if (!weakMapHas || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakMapHas.call(x, weakMapHas);\n try {\n weakSetHas.call(x, weakSetHas);\n } catch (s) {\n return true;\n }\n return x instanceof WeakMap; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakRef(x) {\n if (!weakRefDeref || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakRefDeref.call(x);\n return true;\n } catch (e) {}\n return false;\n}\n\nfunction isSet(x) {\n if (!setSize || !x || typeof x !== 'object') {\n return false;\n }\n try {\n setSize.call(x);\n try {\n mapSize.call(x);\n } catch (m) {\n return true;\n }\n return x instanceof Set; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakSet(x) {\n if (!weakSetHas || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakSetHas.call(x, weakSetHas);\n try {\n weakMapHas.call(x, weakMapHas);\n } catch (s) {\n return true;\n }\n return x instanceof WeakSet; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isElement(x) {\n if (!x || typeof x !== 'object') { return false; }\n if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) {\n return true;\n }\n return typeof x.nodeName === 'string' && typeof x.getAttribute === 'function';\n}\n\nfunction inspectString(str, opts) {\n if (str.length > opts.maxStringLength) {\n var remaining = str.length - opts.maxStringLength;\n var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : '');\n return inspectString($slice.call(str, 0, opts.maxStringLength), opts) + trailer;\n }\n // eslint-disable-next-line no-control-regex\n var s = $replace.call($replace.call(str, /(['\\\\])/g, '\\\\$1'), /[\\x00-\\x1f]/g, lowbyte);\n return wrapQuotes(s, 'single', opts);\n}\n\nfunction lowbyte(c) {\n var n = c.charCodeAt(0);\n var x = {\n 8: 'b',\n 9: 't',\n 10: 'n',\n 12: 'f',\n 13: 'r'\n }[n];\n if (x) { return '\\\\' + x; }\n return '\\\\x' + (n < 0x10 ? '0' : '') + $toUpperCase.call(n.toString(16));\n}\n\nfunction markBoxed(str) {\n return 'Object(' + str + ')';\n}\n\nfunction weakCollectionOf(type) {\n return type + ' { ? }';\n}\n\nfunction collectionOf(type, size, entries, indent) {\n var joinedEntries = indent ? indentedJoin(entries, indent) : $join.call(entries, ', ');\n return type + ' (' + size + ') {' + joinedEntries + '}';\n}\n\nfunction singleLineValues(xs) {\n for (var i = 0; i < xs.length; i++) {\n if (indexOf(xs[i], '\\n') >= 0) {\n return false;\n }\n }\n return true;\n}\n\nfunction getIndent(opts, depth) {\n var baseIndent;\n if (opts.indent === '\\t') {\n baseIndent = '\\t';\n } else if (typeof opts.indent === 'number' && opts.indent > 0) {\n baseIndent = $join.call(Array(opts.indent + 1), ' ');\n } else {\n return null;\n }\n return {\n base: baseIndent,\n prev: $join.call(Array(depth + 1), baseIndent)\n };\n}\n\nfunction indentedJoin(xs, indent) {\n if (xs.length === 0) { return ''; }\n var lineJoiner = '\\n' + indent.prev + indent.base;\n return lineJoiner + $join.call(xs, ',' + lineJoiner) + '\\n' + indent.prev;\n}\n\nfunction arrObjKeys(obj, inspect) {\n var isArr = isArray(obj);\n var xs = [];\n if (isArr) {\n xs.length = obj.length;\n for (var i = 0; i < obj.length; i++) {\n xs[i] = has(obj, i) ? inspect(obj[i], obj) : '';\n }\n }\n var syms = typeof gOPS === 'function' ? gOPS(obj) : [];\n var symMap;\n if (hasShammedSymbols) {\n symMap = {};\n for (var k = 0; k < syms.length; k++) {\n symMap['$' + syms[k]] = syms[k];\n }\n }\n\n for (var key in obj) { // eslint-disable-line no-restricted-syntax\n if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue\n if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue\n if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) {\n // this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section\n continue; // eslint-disable-line no-restricted-syntax, no-continue\n } else if ($test.call(/[^\\w$]/, key)) {\n xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj));\n } else {\n xs.push(key + ': ' + inspect(obj[key], obj));\n }\n }\n if (typeof gOPS === 'function') {\n for (var j = 0; j < syms.length; j++) {\n if (isEnumerable.call(obj, syms[j])) {\n xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj));\n }\n }\n }\n return xs;\n}\n","'use strict';\n\nvar utils = require('./utils');\n\nvar has = Object.prototype.hasOwnProperty;\nvar isArray = Array.isArray;\n\nvar defaults = {\n allowDots: false,\n allowPrototypes: false,\n allowSparse: false,\n arrayLimit: 20,\n charset: 'utf-8',\n charsetSentinel: false,\n comma: false,\n decoder: utils.decode,\n delimiter: '&',\n depth: 5,\n ignoreQueryPrefix: false,\n interpretNumericEntities: false,\n parameterLimit: 1000,\n parseArrays: true,\n plainObjects: false,\n strictNullHandling: false\n};\n\nvar interpretNumericEntities = function (str) {\n return str.replace(/&#(\\d+);/g, function ($0, numberStr) {\n return String.fromCharCode(parseInt(numberStr, 10));\n });\n};\n\nvar parseArrayValue = function (val, options) {\n if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) {\n return val.split(',');\n }\n\n return val;\n};\n\n// This is what browsers will submit when the ✓ character occurs in an\n// application/x-www-form-urlencoded body and the encoding of the page containing\n// the form is iso-8859-1, or when the submitted form has an accept-charset\n// attribute of iso-8859-1. Presumably also with other charsets that do not contain\n// the ✓ character, such as us-ascii.\nvar isoSentinel = 'utf8=%26%2310003%3B'; // encodeURIComponent('✓')\n\n// These are the percent-encoded utf-8 octets representing a checkmark, indicating that the request actually is utf-8 encoded.\nvar charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓')\n\nvar parseValues = function parseQueryStringValues(str, options) {\n var obj = {};\n var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\\?/, '') : str;\n var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit;\n var parts = cleanStr.split(options.delimiter, limit);\n var skipIndex = -1; // Keep track of where the utf8 sentinel was found\n var i;\n\n var charset = options.charset;\n if (options.charsetSentinel) {\n for (i = 0; i < parts.length; ++i) {\n if (parts[i].indexOf('utf8=') === 0) {\n if (parts[i] === charsetSentinel) {\n charset = 'utf-8';\n } else if (parts[i] === isoSentinel) {\n charset = 'iso-8859-1';\n }\n skipIndex = i;\n i = parts.length; // The eslint settings do not allow break;\n }\n }\n }\n\n for (i = 0; i < parts.length; ++i) {\n if (i === skipIndex) {\n continue;\n }\n var part = parts[i];\n\n var bracketEqualsPos = part.indexOf(']=');\n var pos = bracketEqualsPos === -1 ? part.indexOf('=') : bracketEqualsPos + 1;\n\n var key, val;\n if (pos === -1) {\n key = options.decoder(part, defaults.decoder, charset, 'key');\n val = options.strictNullHandling ? null : '';\n } else {\n key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key');\n val = utils.maybeMap(\n parseArrayValue(part.slice(pos + 1), options),\n function (encodedVal) {\n return options.decoder(encodedVal, defaults.decoder, charset, 'value');\n }\n );\n }\n\n if (val && options.interpretNumericEntities && charset === 'iso-8859-1') {\n val = interpretNumericEntities(val);\n }\n\n if (part.indexOf('[]=') > -1) {\n val = isArray(val) ? [val] : val;\n }\n\n if (has.call(obj, key)) {\n obj[key] = utils.combine(obj[key], val);\n } else {\n obj[key] = val;\n }\n }\n\n return obj;\n};\n\nvar parseObject = function (chain, val, options, valuesParsed) {\n var leaf = valuesParsed ? val : parseArrayValue(val, options);\n\n for (var i = chain.length - 1; i >= 0; --i) {\n var obj;\n var root = chain[i];\n\n if (root === '[]' && options.parseArrays) {\n obj = [].concat(leaf);\n } else {\n obj = options.plainObjects ? Object.create(null) : {};\n var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root;\n var index = parseInt(cleanRoot, 10);\n if (!options.parseArrays && cleanRoot === '') {\n obj = { 0: leaf };\n } else if (\n !isNaN(index)\n && root !== cleanRoot\n && String(index) === cleanRoot\n && index >= 0\n && (options.parseArrays && index <= options.arrayLimit)\n ) {\n obj = [];\n obj[index] = leaf;\n } else if (cleanRoot !== '__proto__') {\n obj[cleanRoot] = leaf;\n }\n }\n\n leaf = obj;\n }\n\n return leaf;\n};\n\nvar parseKeys = function parseQueryStringKeys(givenKey, val, options, valuesParsed) {\n if (!givenKey) {\n return;\n }\n\n // Transform dot notation to bracket notation\n var key = options.allowDots ? givenKey.replace(/\\.([^.[]+)/g, '[$1]') : givenKey;\n\n // The regex chunks\n\n var brackets = /(\\[[^[\\]]*])/;\n var child = /(\\[[^[\\]]*])/g;\n\n // Get the parent\n\n var segment = options.depth > 0 && brackets.exec(key);\n var parent = segment ? key.slice(0, segment.index) : key;\n\n // Stash the parent if it exists\n\n var keys = [];\n if (parent) {\n // If we aren't using plain objects, optionally prefix keys that would overwrite object prototype properties\n if (!options.plainObjects && has.call(Object.prototype, parent)) {\n if (!options.allowPrototypes) {\n return;\n }\n }\n\n keys.push(parent);\n }\n\n // Loop through children appending to the array until we hit depth\n\n var i = 0;\n while (options.depth > 0 && (segment = child.exec(key)) !== null && i < options.depth) {\n i += 1;\n if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) {\n if (!options.allowPrototypes) {\n return;\n }\n }\n keys.push(segment[1]);\n }\n\n // If there's a remainder, just add whatever is left\n\n if (segment) {\n keys.push('[' + key.slice(segment.index) + ']');\n }\n\n return parseObject(keys, val, options, valuesParsed);\n};\n\nvar normalizeParseOptions = function normalizeParseOptions(opts) {\n if (!opts) {\n return defaults;\n }\n\n if (opts.decoder !== null && opts.decoder !== undefined && typeof opts.decoder !== 'function') {\n throw new TypeError('Decoder has to be a function.');\n }\n\n if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {\n throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');\n }\n var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset;\n\n return {\n allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots,\n allowPrototypes: typeof opts.allowPrototypes === 'boolean' ? opts.allowPrototypes : defaults.allowPrototypes,\n allowSparse: typeof opts.allowSparse === 'boolean' ? opts.allowSparse : defaults.allowSparse,\n arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit,\n charset: charset,\n charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,\n comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma,\n decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder,\n delimiter: typeof opts.delimiter === 'string' || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter,\n // eslint-disable-next-line no-implicit-coercion, no-extra-parens\n depth: (typeof opts.depth === 'number' || opts.depth === false) ? +opts.depth : defaults.depth,\n ignoreQueryPrefix: opts.ignoreQueryPrefix === true,\n interpretNumericEntities: typeof opts.interpretNumericEntities === 'boolean' ? opts.interpretNumericEntities : defaults.interpretNumericEntities,\n parameterLimit: typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit,\n parseArrays: opts.parseArrays !== false,\n plainObjects: typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects,\n strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling\n };\n};\n\nmodule.exports = function (str, opts) {\n var options = normalizeParseOptions(opts);\n\n if (str === '' || str === null || typeof str === 'undefined') {\n return options.plainObjects ? Object.create(null) : {};\n }\n\n var tempObj = typeof str === 'string' ? parseValues(str, options) : str;\n var obj = options.plainObjects ? Object.create(null) : {};\n\n // Iterate over the keys and setup the new object\n\n var keys = Object.keys(tempObj);\n for (var i = 0; i < keys.length; ++i) {\n var key = keys[i];\n var newObj = parseKeys(key, tempObj[key], options, typeof str === 'string');\n obj = utils.merge(obj, newObj, options);\n }\n\n if (options.allowSparse === true) {\n return obj;\n }\n\n return utils.compact(obj);\n};\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-is.production.min.js');\n} else {\n module.exports = require('./cjs/react-is.development.js');\n}\n","/** @license React v16.13.1\n * react-is.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';var b=\"function\"===typeof Symbol&&Symbol.for,c=b?Symbol.for(\"react.element\"):60103,d=b?Symbol.for(\"react.portal\"):60106,e=b?Symbol.for(\"react.fragment\"):60107,f=b?Symbol.for(\"react.strict_mode\"):60108,g=b?Symbol.for(\"react.profiler\"):60114,h=b?Symbol.for(\"react.provider\"):60109,k=b?Symbol.for(\"react.context\"):60110,l=b?Symbol.for(\"react.async_mode\"):60111,m=b?Symbol.for(\"react.concurrent_mode\"):60111,n=b?Symbol.for(\"react.forward_ref\"):60112,p=b?Symbol.for(\"react.suspense\"):60113,q=b?\nSymbol.for(\"react.suspense_list\"):60120,r=b?Symbol.for(\"react.memo\"):60115,t=b?Symbol.for(\"react.lazy\"):60116,v=b?Symbol.for(\"react.block\"):60121,w=b?Symbol.for(\"react.fundamental\"):60117,x=b?Symbol.for(\"react.responder\"):60118,y=b?Symbol.for(\"react.scope\"):60119;\nfunction z(a){if(\"object\"===typeof a&&null!==a){var u=a.$$typeof;switch(u){case c:switch(a=a.type,a){case l:case m:case e:case g:case f:case p:return a;default:switch(a=a&&a.$$typeof,a){case k:case n:case t:case r:case h:return a;default:return u}}case d:return u}}}function A(a){return z(a)===m}exports.AsyncMode=l;exports.ConcurrentMode=m;exports.ContextConsumer=k;exports.ContextProvider=h;exports.Element=c;exports.ForwardRef=n;exports.Fragment=e;exports.Lazy=t;exports.Memo=r;exports.Portal=d;\nexports.Profiler=g;exports.StrictMode=f;exports.Suspense=p;exports.isAsyncMode=function(a){return A(a)||z(a)===l};exports.isConcurrentMode=A;exports.isContextConsumer=function(a){return z(a)===k};exports.isContextProvider=function(a){return z(a)===h};exports.isElement=function(a){return\"object\"===typeof a&&null!==a&&a.$$typeof===c};exports.isForwardRef=function(a){return z(a)===n};exports.isFragment=function(a){return z(a)===e};exports.isLazy=function(a){return z(a)===t};\nexports.isMemo=function(a){return z(a)===r};exports.isPortal=function(a){return z(a)===d};exports.isProfiler=function(a){return z(a)===g};exports.isStrictMode=function(a){return z(a)===f};exports.isSuspense=function(a){return z(a)===p};\nexports.isValidElementType=function(a){return\"string\"===typeof a||\"function\"===typeof a||a===e||a===m||a===g||a===f||a===p||a===q||\"object\"===typeof a&&null!==a&&(a.$$typeof===t||a.$$typeof===r||a.$$typeof===h||a.$$typeof===k||a.$$typeof===n||a.$$typeof===w||a.$$typeof===x||a.$$typeof===y||a.$$typeof===v)};exports.typeOf=z;\n","/** @license React v17.0.2\n * react-is.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n'use strict';var b=60103,c=60106,d=60107,e=60108,f=60114,g=60109,h=60110,k=60112,l=60113,m=60120,n=60115,p=60116,q=60121,r=60122,u=60117,v=60129,w=60131;\nif(\"function\"===typeof Symbol&&Symbol.for){var x=Symbol.for;b=x(\"react.element\");c=x(\"react.portal\");d=x(\"react.fragment\");e=x(\"react.strict_mode\");f=x(\"react.profiler\");g=x(\"react.provider\");h=x(\"react.context\");k=x(\"react.forward_ref\");l=x(\"react.suspense\");m=x(\"react.suspense_list\");n=x(\"react.memo\");p=x(\"react.lazy\");q=x(\"react.block\");r=x(\"react.server.block\");u=x(\"react.fundamental\");v=x(\"react.debug_trace_mode\");w=x(\"react.legacy_hidden\")}\nfunction y(a){if(\"object\"===typeof a&&null!==a){var t=a.$$typeof;switch(t){case b:switch(a=a.type,a){case d:case f:case e:case l:case m:return a;default:switch(a=a&&a.$$typeof,a){case h:case k:case p:case n:case g:return a;default:return t}}case c:return t}}}var z=g,A=b,B=k,C=d,D=p,E=n,F=c,G=f,H=e,I=l;exports.ContextConsumer=h;exports.ContextProvider=z;exports.Element=A;exports.ForwardRef=B;exports.Fragment=C;exports.Lazy=D;exports.Memo=E;exports.Portal=F;exports.Profiler=G;exports.StrictMode=H;\nexports.Suspense=I;exports.isAsyncMode=function(){return!1};exports.isConcurrentMode=function(){return!1};exports.isContextConsumer=function(a){return y(a)===h};exports.isContextProvider=function(a){return y(a)===g};exports.isElement=function(a){return\"object\"===typeof a&&null!==a&&a.$$typeof===b};exports.isForwardRef=function(a){return y(a)===k};exports.isFragment=function(a){return y(a)===d};exports.isLazy=function(a){return y(a)===p};exports.isMemo=function(a){return y(a)===n};\nexports.isPortal=function(a){return y(a)===c};exports.isProfiler=function(a){return y(a)===f};exports.isStrictMode=function(a){return y(a)===e};exports.isSuspense=function(a){return y(a)===l};exports.isValidElementType=function(a){return\"string\"===typeof a||\"function\"===typeof a||a===d||a===f||a===v||a===e||a===l||a===m||a===w||\"object\"===typeof a&&null!==a&&(a.$$typeof===p||a.$$typeof===n||a.$$typeof===g||a.$$typeof===h||a.$$typeof===k||a.$$typeof===u||a.$$typeof===q||a[0]===r)?!0:!1};\nexports.typeOf=y;\n","'use strict';\n\nvar destroy = require('./plugin/destroy');\nvar initialize = require('./plugin/initialize');\nvar update = require('./plugin/update');\n\nmodule.exports = {\n initialize: initialize,\n update: update,\n destroy: destroy\n};\n","'use strict';\n\nvar _ = require('../lib/helper');\nvar dom = require('../lib/dom');\nvar instances = require('./instances');\n\nmodule.exports = function (element) {\n var i = instances.get(element);\n\n if (!i) {\n return;\n }\n\n i.event.unbindAll();\n dom.remove(i.scrollbarX);\n dom.remove(i.scrollbarY);\n dom.remove(i.scrollbarXRail);\n dom.remove(i.scrollbarYRail);\n _.removePsClasses(element);\n\n instances.remove(element);\n};\n","'use strict';\n\nmodule.exports = {\n handlers: ['click-rail', 'drag-scrollbar', 'keyboard', 'wheel', 'touch'],\n maxScrollbarLength: null,\n minScrollbarLength: null,\n scrollXMarginOffset: 0,\n scrollYMarginOffset: 0,\n suppressScrollX: false,\n suppressScrollY: false,\n swipePropagation: true,\n useBothWheelAxes: false,\n wheelPropagation: false,\n wheelSpeed: 1,\n theme: 'default'\n};\n","'use strict';\n\nvar EventElement = function (element) {\n this.element = element;\n this.events = {};\n};\n\nEventElement.prototype.bind = function (eventName, handler) {\n if (typeof this.events[eventName] === 'undefined') {\n this.events[eventName] = [];\n }\n this.events[eventName].push(handler);\n this.element.addEventListener(eventName, handler, false);\n};\n\nEventElement.prototype.unbind = function (eventName, handler) {\n var isHandlerProvided = (typeof handler !== 'undefined');\n this.events[eventName] = this.events[eventName].filter(function (hdlr) {\n if (isHandlerProvided && hdlr !== handler) {\n return true;\n }\n this.element.removeEventListener(eventName, hdlr, false);\n return false;\n }, this);\n};\n\nEventElement.prototype.unbindAll = function () {\n for (var name in this.events) {\n this.unbind(name);\n }\n};\n\nvar EventManager = function () {\n this.eventElements = [];\n};\n\nEventManager.prototype.eventElement = function (element) {\n var ee = this.eventElements.filter(function (eventElement) {\n return eventElement.element === element;\n })[0];\n if (typeof ee === 'undefined') {\n ee = new EventElement(element);\n this.eventElements.push(ee);\n }\n return ee;\n};\n\nEventManager.prototype.bind = function (element, eventName, handler) {\n this.eventElement(element).bind(eventName, handler);\n};\n\nEventManager.prototype.unbind = function (element, eventName, handler) {\n this.eventElement(element).unbind(eventName, handler);\n};\n\nEventManager.prototype.unbindAll = function () {\n for (var i = 0; i < this.eventElements.length; i++) {\n this.eventElements[i].unbindAll();\n }\n};\n\nEventManager.prototype.once = function (element, eventName, handler) {\n var ee = this.eventElement(element);\n var onceHandler = function (e) {\n ee.unbind(eventName, onceHandler);\n handler(e);\n };\n ee.bind(eventName, onceHandler);\n};\n\nmodule.exports = EventManager;\n","'use strict';\n\nmodule.exports = (function () {\n function s4() {\n return Math.floor((1 + Math.random()) * 0x10000)\n .toString(16)\n .substring(1);\n }\n return function () {\n return s4() + s4() + '-' + s4() + '-' + s4() + '-' +\n s4() + '-' + s4() + s4() + s4();\n };\n})();\n","'use strict';\n\nvar _ = require('../lib/helper');\nvar cls = require('../lib/class');\nvar instances = require('./instances');\nvar updateGeometry = require('./update-geometry');\n\n// Handlers\nvar handlers = {\n 'click-rail': require('./handler/click-rail'),\n 'drag-scrollbar': require('./handler/drag-scrollbar'),\n 'keyboard': require('./handler/keyboard'),\n 'wheel': require('./handler/mouse-wheel'),\n 'touch': require('./handler/touch'),\n 'selection': require('./handler/selection')\n};\nvar nativeScrollHandler = require('./handler/native-scroll');\n\nmodule.exports = function (element, userSettings) {\n userSettings = typeof userSettings === 'object' ? userSettings : {};\n\n cls.add(element, 'ps-container');\n\n // Create a plugin instance.\n var i = instances.add(element);\n\n i.settings = _.extend(i.settings, userSettings);\n cls.add(element, 'ps-theme-' + i.settings.theme);\n\n i.settings.handlers.forEach(function (handlerName) {\n handlers[handlerName](element);\n });\n\n nativeScrollHandler(element);\n\n updateGeometry(element);\n};\n","'use strict';\n\nvar instances = require('../instances');\nvar updateGeometry = require('../update-geometry');\nvar updateScroll = require('../update-scroll');\n\nfunction bindClickRailHandler(element, i) {\n function pageOffset(el) {\n return el.getBoundingClientRect();\n }\n var stopPropagation = function (e) { e.stopPropagation(); };\n\n i.event.bind(i.scrollbarY, 'click', stopPropagation);\n i.event.bind(i.scrollbarYRail, 'click', function (e) {\n var positionTop = e.pageY - window.pageYOffset - pageOffset(i.scrollbarYRail).top;\n var direction = positionTop > i.scrollbarYTop ? 1 : -1;\n\n updateScroll(element, 'top', element.scrollTop + direction * i.containerHeight);\n updateGeometry(element);\n\n e.stopPropagation();\n });\n\n i.event.bind(i.scrollbarX, 'click', stopPropagation);\n i.event.bind(i.scrollbarXRail, 'click', function (e) {\n var positionLeft = e.pageX - window.pageXOffset - pageOffset(i.scrollbarXRail).left;\n var direction = positionLeft > i.scrollbarXLeft ? 1 : -1;\n\n updateScroll(element, 'left', element.scrollLeft + direction * i.containerWidth);\n updateGeometry(element);\n\n e.stopPropagation();\n });\n}\n\nmodule.exports = function (element) {\n var i = instances.get(element);\n bindClickRailHandler(element, i);\n};\n","'use strict';\n\nvar _ = require('../../lib/helper');\nvar dom = require('../../lib/dom');\nvar instances = require('../instances');\nvar updateGeometry = require('../update-geometry');\nvar updateScroll = require('../update-scroll');\n\nfunction bindMouseScrollXHandler(element, i) {\n var currentLeft = null;\n var currentPageX = null;\n\n function updateScrollLeft(deltaX) {\n var newLeft = currentLeft + (deltaX * i.railXRatio);\n var maxLeft = Math.max(0, i.scrollbarXRail.getBoundingClientRect().left) + (i.railXRatio * (i.railXWidth - i.scrollbarXWidth));\n\n if (newLeft < 0) {\n i.scrollbarXLeft = 0;\n } else if (newLeft > maxLeft) {\n i.scrollbarXLeft = maxLeft;\n } else {\n i.scrollbarXLeft = newLeft;\n }\n\n var scrollLeft = _.toInt(i.scrollbarXLeft * (i.contentWidth - i.containerWidth) / (i.containerWidth - (i.railXRatio * i.scrollbarXWidth))) - i.negativeScrollAdjustment;\n updateScroll(element, 'left', scrollLeft);\n }\n\n var mouseMoveHandler = function (e) {\n updateScrollLeft(e.pageX - currentPageX);\n updateGeometry(element);\n e.stopPropagation();\n e.preventDefault();\n };\n\n var mouseUpHandler = function () {\n _.stopScrolling(element, 'x');\n i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler);\n };\n\n i.event.bind(i.scrollbarX, 'mousedown', function (e) {\n currentPageX = e.pageX;\n currentLeft = _.toInt(dom.css(i.scrollbarX, 'left')) * i.railXRatio;\n _.startScrolling(element, 'x');\n\n i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);\n i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler);\n\n e.stopPropagation();\n e.preventDefault();\n });\n}\n\nfunction bindMouseScrollYHandler(element, i) {\n var currentTop = null;\n var currentPageY = null;\n\n function updateScrollTop(deltaY) {\n var newTop = currentTop + (deltaY * i.railYRatio);\n var maxTop = Math.max(0, i.scrollbarYRail.getBoundingClientRect().top) + (i.railYRatio * (i.railYHeight - i.scrollbarYHeight));\n\n if (newTop < 0) {\n i.scrollbarYTop = 0;\n } else if (newTop > maxTop) {\n i.scrollbarYTop = maxTop;\n } else {\n i.scrollbarYTop = newTop;\n }\n\n var scrollTop = _.toInt(i.scrollbarYTop * (i.contentHeight - i.containerHeight) / (i.containerHeight - (i.railYRatio * i.scrollbarYHeight)));\n updateScroll(element, 'top', scrollTop);\n }\n\n var mouseMoveHandler = function (e) {\n updateScrollTop(e.pageY - currentPageY);\n updateGeometry(element);\n e.stopPropagation();\n e.preventDefault();\n };\n\n var mouseUpHandler = function () {\n _.stopScrolling(element, 'y');\n i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler);\n };\n\n i.event.bind(i.scrollbarY, 'mousedown', function (e) {\n currentPageY = e.pageY;\n currentTop = _.toInt(dom.css(i.scrollbarY, 'top')) * i.railYRatio;\n _.startScrolling(element, 'y');\n\n i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);\n i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler);\n\n e.stopPropagation();\n e.preventDefault();\n });\n}\n\nmodule.exports = function (element) {\n var i = instances.get(element);\n bindMouseScrollXHandler(element, i);\n bindMouseScrollYHandler(element, i);\n};\n","'use strict';\n\nvar _ = require('../../lib/helper');\nvar dom = require('../../lib/dom');\nvar instances = require('../instances');\nvar updateGeometry = require('../update-geometry');\nvar updateScroll = require('../update-scroll');\n\nfunction bindKeyboardHandler(element, i) {\n var hovered = false;\n i.event.bind(element, 'mouseenter', function () {\n hovered = true;\n });\n i.event.bind(element, 'mouseleave', function () {\n hovered = false;\n });\n\n var shouldPrevent = false;\n function shouldPreventDefault(deltaX, deltaY) {\n var scrollTop = element.scrollTop;\n if (deltaX === 0) {\n if (!i.scrollbarYActive) {\n return false;\n }\n if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)) {\n return !i.settings.wheelPropagation;\n }\n }\n\n var scrollLeft = element.scrollLeft;\n if (deltaY === 0) {\n if (!i.scrollbarXActive) {\n return false;\n }\n if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)) {\n return !i.settings.wheelPropagation;\n }\n }\n return true;\n }\n\n i.event.bind(i.ownerDocument, 'keydown', function (e) {\n if ((e.isDefaultPrevented && e.isDefaultPrevented()) || e.defaultPrevented) {\n return;\n }\n\n var focused = dom.matches(i.scrollbarX, ':focus') ||\n dom.matches(i.scrollbarY, ':focus');\n\n if (!hovered && !focused) {\n return;\n }\n\n var activeElement = document.activeElement ? document.activeElement : i.ownerDocument.activeElement;\n if (activeElement) {\n if (activeElement.tagName === 'IFRAME') {\n activeElement = activeElement.contentDocument.activeElement;\n } else {\n // go deeper if element is a webcomponent\n while (activeElement.shadowRoot) {\n activeElement = activeElement.shadowRoot.activeElement;\n }\n }\n if (_.isEditable(activeElement)) {\n return;\n }\n }\n\n var deltaX = 0;\n var deltaY = 0;\n\n switch (e.which) {\n case 37: // left\n if (e.metaKey) {\n deltaX = -i.contentWidth;\n } else if (e.altKey) {\n deltaX = -i.containerWidth;\n } else {\n deltaX = -30;\n }\n break;\n case 38: // up\n if (e.metaKey) {\n deltaY = i.contentHeight;\n } else if (e.altKey) {\n deltaY = i.containerHeight;\n } else {\n deltaY = 30;\n }\n break;\n case 39: // right\n if (e.metaKey) {\n deltaX = i.contentWidth;\n } else if (e.altKey) {\n deltaX = i.containerWidth;\n } else {\n deltaX = 30;\n }\n break;\n case 40: // down\n if (e.metaKey) {\n deltaY = -i.contentHeight;\n } else if (e.altKey) {\n deltaY = -i.containerHeight;\n } else {\n deltaY = -30;\n }\n break;\n case 33: // page up\n deltaY = 90;\n break;\n case 32: // space bar\n if (e.shiftKey) {\n deltaY = 90;\n } else {\n deltaY = -90;\n }\n break;\n case 34: // page down\n deltaY = -90;\n break;\n case 35: // end\n if (e.ctrlKey) {\n deltaY = -i.contentHeight;\n } else {\n deltaY = -i.containerHeight;\n }\n break;\n case 36: // home\n if (e.ctrlKey) {\n deltaY = element.scrollTop;\n } else {\n deltaY = i.containerHeight;\n }\n break;\n default:\n return;\n }\n\n updateScroll(element, 'top', element.scrollTop - deltaY);\n updateScroll(element, 'left', element.scrollLeft + deltaX);\n updateGeometry(element);\n\n shouldPrevent = shouldPreventDefault(deltaX, deltaY);\n if (shouldPrevent) {\n e.preventDefault();\n }\n });\n}\n\nmodule.exports = function (element) {\n var i = instances.get(element);\n bindKeyboardHandler(element, i);\n};\n","'use strict';\n\nvar instances = require('../instances');\nvar updateGeometry = require('../update-geometry');\nvar updateScroll = require('../update-scroll');\n\nfunction bindMouseWheelHandler(element, i) {\n var shouldPrevent = false;\n\n function shouldPreventDefault(deltaX, deltaY) {\n var scrollTop = element.scrollTop;\n if (deltaX === 0) {\n if (!i.scrollbarYActive) {\n return false;\n }\n if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)) {\n return !i.settings.wheelPropagation;\n }\n }\n\n var scrollLeft = element.scrollLeft;\n if (deltaY === 0) {\n if (!i.scrollbarXActive) {\n return false;\n }\n if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)) {\n return !i.settings.wheelPropagation;\n }\n }\n return true;\n }\n\n function getDeltaFromEvent(e) {\n var deltaX = e.deltaX;\n var deltaY = -1 * e.deltaY;\n\n if (typeof deltaX === \"undefined\" || typeof deltaY === \"undefined\") {\n // OS X Safari\n deltaX = -1 * e.wheelDeltaX / 6;\n deltaY = e.wheelDeltaY / 6;\n }\n\n if (e.deltaMode && e.deltaMode === 1) {\n // Firefox in deltaMode 1: Line scrolling\n deltaX *= 10;\n deltaY *= 10;\n }\n\n if (deltaX !== deltaX && deltaY !== deltaY/* NaN checks */) {\n // IE in some mouse drivers\n deltaX = 0;\n deltaY = e.wheelDelta;\n }\n\n if (e.shiftKey) {\n // reverse axis with shift key\n return [-deltaY, -deltaX];\n }\n return [deltaX, deltaY];\n }\n\n function shouldBeConsumedByChild(deltaX, deltaY) {\n var child = element.querySelector('textarea:hover, select[multiple]:hover, .ps-child:hover');\n if (child) {\n if (!window.getComputedStyle(child).overflow.match(/(scroll|auto)/)) {\n // if not scrollable\n return false;\n }\n\n var maxScrollTop = child.scrollHeight - child.clientHeight;\n if (maxScrollTop > 0) {\n if (!(child.scrollTop === 0 && deltaY > 0) && !(child.scrollTop === maxScrollTop && deltaY < 0)) {\n return true;\n }\n }\n var maxScrollLeft = child.scrollLeft - child.clientWidth;\n if (maxScrollLeft > 0) {\n if (!(child.scrollLeft === 0 && deltaX < 0) && !(child.scrollLeft === maxScrollLeft && deltaX > 0)) {\n return true;\n }\n }\n }\n return false;\n }\n\n function mousewheelHandler(e) {\n var delta = getDeltaFromEvent(e);\n\n var deltaX = delta[0];\n var deltaY = delta[1];\n\n if (shouldBeConsumedByChild(deltaX, deltaY)) {\n return;\n }\n\n shouldPrevent = false;\n if (!i.settings.useBothWheelAxes) {\n // deltaX will only be used for horizontal scrolling and deltaY will\n // only be used for vertical scrolling - this is the default\n updateScroll(element, 'top', element.scrollTop - (deltaY * i.settings.wheelSpeed));\n updateScroll(element, 'left', element.scrollLeft + (deltaX * i.settings.wheelSpeed));\n } else if (i.scrollbarYActive && !i.scrollbarXActive) {\n // only vertical scrollbar is active and useBothWheelAxes option is\n // active, so let's scroll vertical bar using both mouse wheel axes\n if (deltaY) {\n updateScroll(element, 'top', element.scrollTop - (deltaY * i.settings.wheelSpeed));\n } else {\n updateScroll(element, 'top', element.scrollTop + (deltaX * i.settings.wheelSpeed));\n }\n shouldPrevent = true;\n } else if (i.scrollbarXActive && !i.scrollbarYActive) {\n // useBothWheelAxes and only horizontal bar is active, so use both\n // wheel axes for horizontal bar\n if (deltaX) {\n updateScroll(element, 'left', element.scrollLeft + (deltaX * i.settings.wheelSpeed));\n } else {\n updateScroll(element, 'left', element.scrollLeft - (deltaY * i.settings.wheelSpeed));\n }\n shouldPrevent = true;\n }\n\n updateGeometry(element);\n\n shouldPrevent = (shouldPrevent || shouldPreventDefault(deltaX, deltaY));\n if (shouldPrevent) {\n e.stopPropagation();\n e.preventDefault();\n }\n }\n\n if (typeof window.onwheel !== \"undefined\") {\n i.event.bind(element, 'wheel', mousewheelHandler);\n } else if (typeof window.onmousewheel !== \"undefined\") {\n i.event.bind(element, 'mousewheel', mousewheelHandler);\n }\n}\n\nmodule.exports = function (element) {\n var i = instances.get(element);\n bindMouseWheelHandler(element, i);\n};\n","'use strict';\n\nvar _ = require('../../lib/helper');\nvar instances = require('../instances');\nvar updateGeometry = require('../update-geometry');\nvar updateScroll = require('../update-scroll');\n\nfunction bindTouchHandler(element, i, supportsTouch, supportsIePointer) {\n function shouldPreventDefault(deltaX, deltaY) {\n var scrollTop = element.scrollTop;\n var scrollLeft = element.scrollLeft;\n var magnitudeX = Math.abs(deltaX);\n var magnitudeY = Math.abs(deltaY);\n\n if (magnitudeY > magnitudeX) {\n // user is perhaps trying to swipe up/down the page\n\n if (((deltaY < 0) && (scrollTop === i.contentHeight - i.containerHeight)) ||\n ((deltaY > 0) && (scrollTop === 0))) {\n return !i.settings.swipePropagation;\n }\n } else if (magnitudeX > magnitudeY) {\n // user is perhaps trying to swipe left/right across the page\n\n if (((deltaX < 0) && (scrollLeft === i.contentWidth - i.containerWidth)) ||\n ((deltaX > 0) && (scrollLeft === 0))) {\n return !i.settings.swipePropagation;\n }\n }\n\n return true;\n }\n\n function applyTouchMove(differenceX, differenceY) {\n updateScroll(element, 'top', element.scrollTop - differenceY);\n updateScroll(element, 'left', element.scrollLeft - differenceX);\n\n updateGeometry(element);\n }\n\n var startOffset = {};\n var startTime = 0;\n var speed = {};\n var easingLoop = null;\n var inGlobalTouch = false;\n var inLocalTouch = false;\n\n function globalTouchStart() {\n inGlobalTouch = true;\n }\n function globalTouchEnd() {\n inGlobalTouch = false;\n }\n\n function getTouch(e) {\n if (e.targetTouches) {\n return e.targetTouches[0];\n } else {\n // Maybe IE pointer\n return e;\n }\n }\n function shouldHandle(e) {\n if (e.targetTouches && e.targetTouches.length === 1) {\n return true;\n }\n if (e.pointerType && e.pointerType !== 'mouse' && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) {\n return true;\n }\n return false;\n }\n function touchStart(e) {\n if (shouldHandle(e)) {\n inLocalTouch = true;\n\n var touch = getTouch(e);\n\n startOffset.pageX = touch.pageX;\n startOffset.pageY = touch.pageY;\n\n startTime = (new Date()).getTime();\n\n if (easingLoop !== null) {\n clearInterval(easingLoop);\n }\n\n e.stopPropagation();\n }\n }\n function touchMove(e) {\n if (!inLocalTouch && i.settings.swipePropagation) {\n touchStart(e);\n }\n if (!inGlobalTouch && inLocalTouch && shouldHandle(e)) {\n var touch = getTouch(e);\n\n var currentOffset = {pageX: touch.pageX, pageY: touch.pageY};\n\n var differenceX = currentOffset.pageX - startOffset.pageX;\n var differenceY = currentOffset.pageY - startOffset.pageY;\n\n applyTouchMove(differenceX, differenceY);\n startOffset = currentOffset;\n\n var currentTime = (new Date()).getTime();\n\n var timeGap = currentTime - startTime;\n if (timeGap > 0) {\n speed.x = differenceX / timeGap;\n speed.y = differenceY / timeGap;\n startTime = currentTime;\n }\n\n if (shouldPreventDefault(differenceX, differenceY)) {\n e.stopPropagation();\n e.preventDefault();\n }\n }\n }\n function touchEnd() {\n if (!inGlobalTouch && inLocalTouch) {\n inLocalTouch = false;\n\n clearInterval(easingLoop);\n easingLoop = setInterval(function () {\n if (!instances.get(element)) {\n clearInterval(easingLoop);\n return;\n }\n\n if (!speed.x && !speed.y) {\n clearInterval(easingLoop);\n return;\n }\n\n if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {\n clearInterval(easingLoop);\n return;\n }\n\n applyTouchMove(speed.x * 30, speed.y * 30);\n\n speed.x *= 0.8;\n speed.y *= 0.8;\n }, 10);\n }\n }\n\n if (supportsTouch) {\n i.event.bind(window, 'touchstart', globalTouchStart);\n i.event.bind(window, 'touchend', globalTouchEnd);\n i.event.bind(element, 'touchstart', touchStart);\n i.event.bind(element, 'touchmove', touchMove);\n i.event.bind(element, 'touchend', touchEnd);\n }\n\n if (supportsIePointer) {\n if (window.PointerEvent) {\n i.event.bind(window, 'pointerdown', globalTouchStart);\n i.event.bind(window, 'pointerup', globalTouchEnd);\n i.event.bind(element, 'pointerdown', touchStart);\n i.event.bind(element, 'pointermove', touchMove);\n i.event.bind(element, 'pointerup', touchEnd);\n } else if (window.MSPointerEvent) {\n i.event.bind(window, 'MSPointerDown', globalTouchStart);\n i.event.bind(window, 'MSPointerUp', globalTouchEnd);\n i.event.bind(element, 'MSPointerDown', touchStart);\n i.event.bind(element, 'MSPointerMove', touchMove);\n i.event.bind(element, 'MSPointerUp', touchEnd);\n }\n }\n}\n\nmodule.exports = function (element) {\n if (!_.env.supportsTouch && !_.env.supportsIePointer) {\n return;\n }\n\n var i = instances.get(element);\n bindTouchHandler(element, i, _.env.supportsTouch, _.env.supportsIePointer);\n};\n","'use strict';\n\nvar _ = require('../../lib/helper');\nvar instances = require('../instances');\nvar updateGeometry = require('../update-geometry');\nvar updateScroll = require('../update-scroll');\n\nfunction bindSelectionHandler(element, i) {\n function getRangeNode() {\n var selection = window.getSelection ? window.getSelection() :\n document.getSelection ? document.getSelection() : '';\n if (selection.toString().length === 0) {\n return null;\n } else {\n return selection.getRangeAt(0).commonAncestorContainer;\n }\n }\n\n var scrollingLoop = null;\n var scrollDiff = {top: 0, left: 0};\n function startScrolling() {\n if (!scrollingLoop) {\n scrollingLoop = setInterval(function () {\n if (!instances.get(element)) {\n clearInterval(scrollingLoop);\n return;\n }\n\n updateScroll(element, 'top', element.scrollTop + scrollDiff.top);\n updateScroll(element, 'left', element.scrollLeft + scrollDiff.left);\n updateGeometry(element);\n }, 50); // every .1 sec\n }\n }\n function stopScrolling() {\n if (scrollingLoop) {\n clearInterval(scrollingLoop);\n scrollingLoop = null;\n }\n _.stopScrolling(element);\n }\n\n var isSelected = false;\n i.event.bind(i.ownerDocument, 'selectionchange', function () {\n if (element.contains(getRangeNode())) {\n isSelected = true;\n } else {\n isSelected = false;\n stopScrolling();\n }\n });\n i.event.bind(window, 'mouseup', function () {\n if (isSelected) {\n isSelected = false;\n stopScrolling();\n }\n });\n i.event.bind(window, 'keyup', function () {\n if (isSelected) {\n isSelected = false;\n stopScrolling();\n }\n });\n\n i.event.bind(window, 'mousemove', function (e) {\n if (isSelected) {\n var mousePosition = {x: e.pageX, y: e.pageY};\n var containerGeometry = {\n left: element.offsetLeft,\n right: element.offsetLeft + element.offsetWidth,\n top: element.offsetTop,\n bottom: element.offsetTop + element.offsetHeight\n };\n\n if (mousePosition.x < containerGeometry.left + 3) {\n scrollDiff.left = -5;\n _.startScrolling(element, 'x');\n } else if (mousePosition.x > containerGeometry.right - 3) {\n scrollDiff.left = 5;\n _.startScrolling(element, 'x');\n } else {\n scrollDiff.left = 0;\n }\n\n if (mousePosition.y < containerGeometry.top + 3) {\n if (containerGeometry.top + 3 - mousePosition.y < 5) {\n scrollDiff.top = -5;\n } else {\n scrollDiff.top = -20;\n }\n _.startScrolling(element, 'y');\n } else if (mousePosition.y > containerGeometry.bottom - 3) {\n if (mousePosition.y - containerGeometry.bottom + 3 < 5) {\n scrollDiff.top = 5;\n } else {\n scrollDiff.top = 20;\n }\n _.startScrolling(element, 'y');\n } else {\n scrollDiff.top = 0;\n }\n\n if (scrollDiff.top === 0 && scrollDiff.left === 0) {\n stopScrolling();\n } else {\n startScrolling();\n }\n }\n });\n}\n\nmodule.exports = function (element) {\n var i = instances.get(element);\n bindSelectionHandler(element, i);\n};\n","'use strict';\n\nvar instances = require('../instances');\nvar updateGeometry = require('../update-geometry');\n\nfunction bindNativeScrollHandler(element, i) {\n i.event.bind(element, 'scroll', function () {\n updateGeometry(element);\n });\n}\n\nmodule.exports = function (element) {\n var i = instances.get(element);\n bindNativeScrollHandler(element, i);\n};\n","'use strict';\n\nvar _ = require('../lib/helper');\nvar dom = require('../lib/dom');\nvar instances = require('./instances');\nvar updateGeometry = require('./update-geometry');\nvar updateScroll = require('./update-scroll');\n\nmodule.exports = function (element) {\n var i = instances.get(element);\n\n if (!i) {\n return;\n }\n\n // Recalcuate negative scrollLeft adjustment\n i.negativeScrollAdjustment = i.isNegativeScroll ? element.scrollWidth - element.clientWidth : 0;\n\n // Recalculate rail margins\n dom.css(i.scrollbarXRail, 'display', 'block');\n dom.css(i.scrollbarYRail, 'display', 'block');\n i.railXMarginWidth = _.toInt(dom.css(i.scrollbarXRail, 'marginLeft')) + _.toInt(dom.css(i.scrollbarXRail, 'marginRight'));\n i.railYMarginHeight = _.toInt(dom.css(i.scrollbarYRail, 'marginTop')) + _.toInt(dom.css(i.scrollbarYRail, 'marginBottom'));\n\n // Hide scrollbars not to affect scrollWidth and scrollHeight\n dom.css(i.scrollbarXRail, 'display', 'none');\n dom.css(i.scrollbarYRail, 'display', 'none');\n\n updateGeometry(element);\n\n // Update top/left scroll to trigger events\n updateScroll(element, 'top', element.scrollTop);\n updateScroll(element, 'left', element.scrollLeft);\n\n dom.css(i.scrollbarXRail, 'display', '');\n dom.css(i.scrollbarYRail, 'display', '');\n};\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar _1 = require(\"./\");\nvar ecma402_abstract_1 = require(\"@formatjs/ecma402-abstract\");\nvar should_polyfill_1 = require(\"./should-polyfill\");\nvar to_locale_string_1 = require(\"./src/to_locale_string\");\nif (should_polyfill_1.shouldPolyfill()) {\n ecma402_abstract_1.defineProperty(Intl, 'DateTimeFormat', { value: _1.DateTimeFormat });\n ecma402_abstract_1.defineProperty(Date.prototype, 'toLocaleString', {\n value: function toLocaleString(locales, options) {\n return to_locale_string_1.toLocaleString(this, locales, options);\n },\n });\n ecma402_abstract_1.defineProperty(Date.prototype, 'toLocaleDateString', {\n value: function toLocaleDateString(locales, options) {\n return to_locale_string_1.toLocaleDateString(this, locales, options);\n },\n });\n ecma402_abstract_1.defineProperty(Date.prototype, 'toLocaleTimeString', {\n value: function toLocaleTimeString(locales, options) {\n return to_locale_string_1.toLocaleTimeString(this, locales, options);\n },\n });\n}\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar tslib_1 = require(\"tslib\");\ntslib_1.__exportStar(require(\"./src/core\"), exports);\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.LookupMatcher = void 0;\nvar utils_1 = require(\"./utils\");\nvar BestAvailableLocale_1 = require(\"./BestAvailableLocale\");\n/**\n * https://tc39.es/ecma402/#sec-lookupmatcher\n * @param availableLocales\n * @param requestedLocales\n * @param getDefaultLocale\n */\nfunction LookupMatcher(availableLocales, requestedLocales, getDefaultLocale) {\n var result = { locale: '' };\n for (var _i = 0, requestedLocales_1 = requestedLocales; _i < requestedLocales_1.length; _i++) {\n var locale = requestedLocales_1[_i];\n var noExtensionLocale = locale.replace(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, '');\n var availableLocale = BestAvailableLocale_1.BestAvailableLocale(availableLocales, noExtensionLocale);\n if (availableLocale) {\n result.locale = availableLocale;\n if (locale !== noExtensionLocale) {\n result.extension = locale.slice(noExtensionLocale.length + 1, locale.length);\n }\n return result;\n }\n }\n result.locale = getDefaultLocale();\n return result;\n}\nexports.LookupMatcher = LookupMatcher;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.BestFitMatcher = void 0;\nvar BestAvailableLocale_1 = require(\"./BestAvailableLocale\");\nvar utils_1 = require(\"./utils\");\n/**\n * https://tc39.es/ecma402/#sec-bestfitmatcher\n * @param availableLocales\n * @param requestedLocales\n * @param getDefaultLocale\n */\nfunction BestFitMatcher(availableLocales, requestedLocales, getDefaultLocale) {\n var minimizedAvailableLocaleMap = Array.from(availableLocales).reduce(function (all, l) {\n all[l] = l;\n return all;\n }, {});\n var minimizedAvailableLocales = new Set();\n availableLocales.forEach(function (locale) {\n var minimizedLocale = new Intl.Locale(locale)\n .minimize()\n .toString();\n minimizedAvailableLocaleMap[minimizedLocale] = locale;\n minimizedAvailableLocales.add(minimizedLocale);\n });\n var foundLocale;\n for (var _i = 0, requestedLocales_1 = requestedLocales; _i < requestedLocales_1.length; _i++) {\n var l = requestedLocales_1[_i];\n if (foundLocale) {\n break;\n }\n var noExtensionLocale = l.replace(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, '');\n if (availableLocales.has(noExtensionLocale)) {\n foundLocale = noExtensionLocale;\n break;\n }\n if (minimizedAvailableLocales.has(noExtensionLocale)) {\n foundLocale = noExtensionLocale;\n break;\n }\n var locale = new Intl.Locale(noExtensionLocale);\n var maximizedRequestedLocale = locale.maximize().toString();\n var minimizedRequestedLocale = locale.minimize().toString();\n // Check minimized locale\n if (minimizedAvailableLocales.has(minimizedRequestedLocale)) {\n foundLocale = minimizedRequestedLocale;\n break;\n }\n // Lookup algo on maximized locale\n foundLocale = BestAvailableLocale_1.BestAvailableLocale(minimizedAvailableLocales, maximizedRequestedLocale);\n }\n return {\n locale: (foundLocale && minimizedAvailableLocaleMap[foundLocale]) ||\n getDefaultLocale(),\n };\n}\nexports.BestFitMatcher = BestFitMatcher;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.UnicodeExtensionValue = void 0;\nvar utils_1 = require(\"./utils\");\n/**\n * https://tc39.es/ecma402/#sec-unicodeextensionvalue\n * @param extension\n * @param key\n */\nfunction UnicodeExtensionValue(extension, key) {\n utils_1.invariant(key.length === 2, 'key must have 2 elements');\n var size = extension.length;\n var searchValue = \"-\" + key + \"-\";\n var pos = extension.indexOf(searchValue);\n if (pos !== -1) {\n var start = pos + 4;\n var end = start;\n var k = start;\n var done = false;\n while (!done) {\n var e = extension.indexOf('-', k);\n var len = void 0;\n if (e === -1) {\n len = size - k;\n }\n else {\n len = e - k;\n }\n if (len === 2) {\n done = true;\n }\n else if (e === -1) {\n end = size;\n done = true;\n }\n else {\n end = e;\n k = e + 1;\n }\n }\n return extension.slice(start, end);\n }\n searchValue = \"-\" + key;\n pos = extension.indexOf(searchValue);\n if (pos !== -1 && pos + 3 === size) {\n return '';\n }\n return undefined;\n}\nexports.UnicodeExtensionValue = UnicodeExtensionValue;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.LookupSupportedLocales = void 0;\nvar utils_1 = require(\"./utils\");\nvar BestAvailableLocale_1 = require(\"./BestAvailableLocale\");\n/**\n * https://tc39.es/ecma402/#sec-lookupsupportedlocales\n * @param availableLocales\n * @param requestedLocales\n */\nfunction LookupSupportedLocales(availableLocales, requestedLocales) {\n var subset = [];\n for (var _i = 0, requestedLocales_1 = requestedLocales; _i < requestedLocales_1.length; _i++) {\n var locale = requestedLocales_1[_i];\n var noExtensionLocale = locale.replace(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, '');\n var availableLocale = BestAvailableLocale_1.BestAvailableLocale(availableLocales, noExtensionLocale);\n if (availableLocale) {\n subset.push(availableLocale);\n }\n }\n return subset;\n}\nexports.LookupSupportedLocales = LookupSupportedLocales;\n","\"use strict\";\n// Type-only circular import\n// eslint-disable-next-line import/no-cycle\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar internalSlotMap = new WeakMap();\nfunction getInternalSlots(x) {\n var internalSlots = internalSlotMap.get(x);\n if (!internalSlots) {\n internalSlots = Object.create(null);\n internalSlotMap.set(x, internalSlots);\n }\n return internalSlots;\n}\nexports.default = getInternalSlots;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @generated\n// prettier-ignore\nexports.default = {\n \"Africa/Asmera\": \"Africa/Nairobi\",\n \"Africa/Timbuktu\": \"Africa/Abidjan\",\n \"America/Argentina/ComodRivadavia\": \"America/Argentina/Catamarca\",\n \"America/Atka\": \"America/Adak\",\n \"America/Buenos_Aires\": \"America/Argentina/Buenos_Aires\",\n \"America/Catamarca\": \"America/Argentina/Catamarca\",\n \"America/Coral_Harbour\": \"America/Atikokan\",\n \"America/Cordoba\": \"America/Argentina/Cordoba\",\n \"America/Ensenada\": \"America/Tijuana\",\n \"America/Fort_Wayne\": \"America/Indiana/Indianapolis\",\n \"America/Godthab\": \"America/Nuuk\",\n \"America/Indianapolis\": \"America/Indiana/Indianapolis\",\n \"America/Jujuy\": \"America/Argentina/Jujuy\",\n \"America/Knox_IN\": \"America/Indiana/Knox\",\n \"America/Louisville\": \"America/Kentucky/Louisville\",\n \"America/Mendoza\": \"America/Argentina/Mendoza\",\n \"America/Montreal\": \"America/Toronto\",\n \"America/Porto_Acre\": \"America/Rio_Branco\",\n \"America/Rosario\": \"America/Argentina/Cordoba\",\n \"America/Santa_Isabel\": \"America/Tijuana\",\n \"America/Shiprock\": \"America/Denver\",\n \"America/Virgin\": \"America/Port_of_Spain\",\n \"Antarctica/South_Pole\": \"Pacific/Auckland\",\n \"Asia/Ashkhabad\": \"Asia/Ashgabat\",\n \"Asia/Calcutta\": \"Asia/Kolkata\",\n \"Asia/Chongqing\": \"Asia/Shanghai\",\n \"Asia/Chungking\": \"Asia/Shanghai\",\n \"Asia/Dacca\": \"Asia/Dhaka\",\n \"Asia/Harbin\": \"Asia/Shanghai\",\n \"Asia/Kashgar\": \"Asia/Urumqi\",\n \"Asia/Katmandu\": \"Asia/Kathmandu\",\n \"Asia/Macao\": \"Asia/Macau\",\n \"Asia/Rangoon\": \"Asia/Yangon\",\n \"Asia/Saigon\": \"Asia/Ho_Chi_Minh\",\n \"Asia/Tel_Aviv\": \"Asia/Jerusalem\",\n \"Asia/Thimbu\": \"Asia/Thimphu\",\n \"Asia/Ujung_Pandang\": \"Asia/Makassar\",\n \"Asia/Ulan_Bator\": \"Asia/Ulaanbaatar\",\n \"Atlantic/Faeroe\": \"Atlantic/Faroe\",\n \"Atlantic/Jan_Mayen\": \"Europe/Oslo\",\n \"Australia/ACT\": \"Australia/Sydney\",\n \"Australia/Canberra\": \"Australia/Sydney\",\n \"Australia/Currie\": \"Australia/Hobart\",\n \"Australia/LHI\": \"Australia/Lord_Howe\",\n \"Australia/NSW\": \"Australia/Sydney\",\n \"Australia/North\": \"Australia/Darwin\",\n \"Australia/Queensland\": \"Australia/Brisbane\",\n \"Australia/South\": \"Australia/Adelaide\",\n \"Australia/Tasmania\": \"Australia/Hobart\",\n \"Australia/Victoria\": \"Australia/Melbourne\",\n \"Australia/West\": \"Australia/Perth\",\n \"Australia/Yancowinna\": \"Australia/Broken_Hill\",\n \"Brazil/Acre\": \"America/Rio_Branco\",\n \"Brazil/DeNoronha\": \"America/Noronha\",\n \"Brazil/East\": \"America/Sao_Paulo\",\n \"Brazil/West\": \"America/Manaus\",\n \"Canada/Atlantic\": \"America/Halifax\",\n \"Canada/Central\": \"America/Winnipeg\",\n \"Canada/Eastern\": \"America/Toronto\",\n \"Canada/Mountain\": \"America/Edmonton\",\n \"Canada/Newfoundland\": \"America/St_Johns\",\n \"Canada/Pacific\": \"America/Vancouver\",\n \"Canada/Saskatchewan\": \"America/Regina\",\n \"Canada/Yukon\": \"America/Whitehorse\",\n \"Chile/Continental\": \"America/Santiago\",\n \"Chile/EasterIsland\": \"Pacific/Easter\",\n \"Cuba\": \"America/Havana\",\n \"Egypt\": \"Africa/Cairo\",\n \"Eire\": \"Europe/Dublin\",\n \"Etc/UCT\": \"Etc/UTC\",\n \"Europe/Belfast\": \"Europe/London\",\n \"Europe/Tiraspol\": \"Europe/Chisinau\",\n \"GB\": \"Europe/London\",\n \"GB-Eire\": \"Europe/London\",\n \"GMT+0\": \"Etc/GMT\",\n \"GMT-0\": \"Etc/GMT\",\n \"GMT0\": \"Etc/GMT\",\n \"Greenwich\": \"Etc/GMT\",\n \"Hongkong\": \"Asia/Hong_Kong\",\n \"Iceland\": \"Atlantic/Reykjavik\",\n \"Iran\": \"Asia/Tehran\",\n \"Israel\": \"Asia/Jerusalem\",\n \"Jamaica\": \"America/Jamaica\",\n \"Japan\": \"Asia/Tokyo\",\n \"Kwajalein\": \"Pacific/Kwajalein\",\n \"Libya\": \"Africa/Tripoli\",\n \"Mexico/BajaNorte\": \"America/Tijuana\",\n \"Mexico/BajaSur\": \"America/Mazatlan\",\n \"Mexico/General\": \"America/Mexico_City\",\n \"NZ\": \"Pacific/Auckland\",\n \"NZ-CHAT\": \"Pacific/Chatham\",\n \"Navajo\": \"America/Denver\",\n \"PRC\": \"Asia/Shanghai\",\n \"Pacific/Johnston\": \"Pacific/Honolulu\",\n \"Pacific/Ponape\": \"Pacific/Pohnpei\",\n \"Pacific/Samoa\": \"Pacific/Pago_Pago\",\n \"Pacific/Truk\": \"Pacific/Chuuk\",\n \"Pacific/Yap\": \"Pacific/Chuuk\",\n \"Poland\": \"Europe/Warsaw\",\n \"Portugal\": \"Europe/Lisbon\",\n \"ROC\": \"Asia/Taipei\",\n \"ROK\": \"Asia/Seoul\",\n \"Singapore\": \"Asia/Singapore\",\n \"Turkey\": \"Europe/Istanbul\",\n \"UCT\": \"Etc/UTC\",\n \"US/Alaska\": \"America/Anchorage\",\n \"US/Aleutian\": \"America/Adak\",\n \"US/Arizona\": \"America/Phoenix\",\n \"US/Central\": \"America/Chicago\",\n \"US/East-Indiana\": \"America/Indiana/Indianapolis\",\n \"US/Eastern\": \"America/New_York\",\n \"US/Hawaii\": \"Pacific/Honolulu\",\n \"US/Indiana-Starke\": \"America/Indiana/Knox\",\n \"US/Michigan\": \"America/Detroit\",\n \"US/Mountain\": \"America/Denver\",\n \"US/Pacific\": \"America/Los_Angeles\",\n \"US/Samoa\": \"Pacific/Pago_Pago\",\n \"UTC\": \"Etc/UTC\",\n \"Universal\": \"Etc/UTC\",\n \"W-SU\": \"Europe/Moscow\",\n \"Zulu\": \"Etc/UTC\"\n};\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.unpack = exports.pack = void 0;\nvar tslib_1 = require(\"tslib\");\nfunction pack(data) {\n var zoneNames = Object.keys(data.zones);\n zoneNames.sort(); // so output is stable\n return {\n zones: zoneNames.map(function (zone) {\n return tslib_1.__spreadArray([\n zone\n ], data.zones[zone].map(function (_a) {\n var ts = _a[0], others = _a.slice(1);\n return tslib_1.__spreadArray([ts === '' ? '' : ts.toString(36)], others).join(',');\n })).join('|');\n }),\n abbrvs: data.abbrvs.join('|'),\n offsets: data.offsets.map(function (o) { return o.toString(36); }).join('|'),\n };\n}\nexports.pack = pack;\nfunction unpack(data) {\n var abbrvs = data.abbrvs.split('|');\n var offsets = data.offsets.split('|').map(function (n) { return parseInt(n, 36); });\n var packedZones = data.zones;\n var zones = {};\n for (var _i = 0, packedZones_1 = packedZones; _i < packedZones_1.length; _i++) {\n var d = packedZones_1[_i];\n var _a = d.split('|'), zone = _a[0], zoneData = _a.slice(1);\n zones[zone] = zoneData\n .map(function (z) { return z.split(','); })\n .map(function (_a) {\n var ts = _a[0], abbrvIndex = _a[1], offsetIndex = _a[2], dst = _a[3];\n return [\n ts === '' ? -Infinity : parseInt(ts, 36),\n abbrvs[+abbrvIndex],\n offsets[+offsetIndex],\n dst === '1',\n ];\n });\n }\n return zones;\n}\nexports.unpack = unpack;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.FormatDateTime = void 0;\nvar PartitionDateTimePattern_1 = require(\"./PartitionDateTimePattern\");\n/**\n * https://tc39.es/ecma402/#sec-formatdatetime\n * @param dtf DateTimeFormat\n * @param x\n */\nfunction FormatDateTime(dtf, x, implDetails) {\n var parts = PartitionDateTimePattern_1.PartitionDateTimePattern(dtf, x, implDetails);\n var result = '';\n for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) {\n var part = parts_1[_i];\n result += part.value;\n }\n return result;\n}\nexports.FormatDateTime = FormatDateTime;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.InitializeDateTimeFormat = void 0;\nvar ecma402_abstract_1 = require(\"@formatjs/ecma402-abstract\");\nvar BasicFormatMatcher_1 = require(\"./BasicFormatMatcher\");\nvar BestFitFormatMatcher_1 = require(\"./BestFitFormatMatcher\");\nvar utils_1 = require(\"./utils\");\nvar DateTimeStyleFormat_1 = require(\"./DateTimeStyleFormat\");\nvar ToDateTimeOptions_1 = require(\"./ToDateTimeOptions\");\nvar intl_localematcher_1 = require(\"@formatjs/intl-localematcher\");\nfunction isTimeRelated(opt) {\n for (var _i = 0, _a = ['hour', 'minute', 'second']; _i < _a.length; _i++) {\n var prop = _a[_i];\n var value = opt[prop];\n if (value !== undefined) {\n return true;\n }\n }\n return false;\n}\nfunction resolveHourCycle(hc, hcDefault, hour12) {\n if (hc == null) {\n hc = hcDefault;\n }\n if (hour12 !== undefined) {\n if (hour12) {\n if (hcDefault === 'h11' || hcDefault === 'h23') {\n hc = 'h11';\n }\n else {\n hc = 'h12';\n }\n }\n else {\n ecma402_abstract_1.invariant(!hour12, 'hour12 must not be set');\n if (hcDefault === 'h11' || hcDefault === 'h23') {\n hc = 'h23';\n }\n else {\n hc = 'h24';\n }\n }\n }\n return hc;\n}\nvar TYPE_REGEX = /^[a-z0-9]{3,8}$/i;\n/**\n * https://tc39.es/ecma402/#sec-initializedatetimeformat\n * @param dtf DateTimeFormat\n * @param locales locales\n * @param opts options\n */\nfunction InitializeDateTimeFormat(dtf, locales, opts, _a) {\n var getInternalSlots = _a.getInternalSlots, availableLocales = _a.availableLocales, localeData = _a.localeData, getDefaultLocale = _a.getDefaultLocale, getDefaultTimeZone = _a.getDefaultTimeZone, relevantExtensionKeys = _a.relevantExtensionKeys, tzData = _a.tzData, uppercaseLinks = _a.uppercaseLinks;\n // @ts-ignore\n var requestedLocales = ecma402_abstract_1.CanonicalizeLocaleList(locales);\n var options = ToDateTimeOptions_1.ToDateTimeOptions(opts, 'any', 'date');\n var opt = Object.create(null);\n var matcher = ecma402_abstract_1.GetOption(options, 'localeMatcher', 'string', ['lookup', 'best fit'], 'best fit');\n opt.localeMatcher = matcher;\n var calendar = ecma402_abstract_1.GetOption(options, 'calendar', 'string', undefined, undefined);\n if (calendar !== undefined && !TYPE_REGEX.test(calendar)) {\n throw new RangeError('Malformed calendar');\n }\n var internalSlots = getInternalSlots(dtf);\n opt.ca = calendar;\n var numberingSystem = ecma402_abstract_1.GetOption(options, 'numberingSystem', 'string', undefined, undefined);\n if (numberingSystem !== undefined && !TYPE_REGEX.test(numberingSystem)) {\n throw new RangeError('Malformed numbering system');\n }\n opt.nu = numberingSystem;\n var hour12 = ecma402_abstract_1.GetOption(options, 'hour12', 'boolean', undefined, undefined);\n var hourCycle = ecma402_abstract_1.GetOption(options, 'hourCycle', 'string', ['h11', 'h12', 'h23', 'h24'], undefined);\n if (hour12 !== undefined) {\n // @ts-ignore\n hourCycle = null;\n }\n opt.hc = hourCycle;\n var r = intl_localematcher_1.ResolveLocale(availableLocales, requestedLocales, opt, relevantExtensionKeys, localeData, getDefaultLocale);\n internalSlots.locale = r.locale;\n calendar = r.ca;\n internalSlots.calendar = calendar;\n internalSlots.hourCycle = r.hc;\n internalSlots.numberingSystem = r.nu;\n var dataLocale = r.dataLocale;\n internalSlots.dataLocale = dataLocale;\n var timeZone = options.timeZone;\n if (timeZone !== undefined) {\n timeZone = String(timeZone);\n if (!ecma402_abstract_1.IsValidTimeZoneName(timeZone, { tzData: tzData, uppercaseLinks: uppercaseLinks })) {\n throw new RangeError('Invalid timeZoneName');\n }\n timeZone = ecma402_abstract_1.CanonicalizeTimeZoneName(timeZone, { tzData: tzData, uppercaseLinks: uppercaseLinks });\n }\n else {\n timeZone = getDefaultTimeZone();\n }\n internalSlots.timeZone = timeZone;\n opt = Object.create(null);\n opt.weekday = ecma402_abstract_1.GetOption(options, 'weekday', 'string', ['narrow', 'short', 'long'], undefined);\n opt.era = ecma402_abstract_1.GetOption(options, 'era', 'string', ['narrow', 'short', 'long'], undefined);\n opt.year = ecma402_abstract_1.GetOption(options, 'year', 'string', ['2-digit', 'numeric'], undefined);\n opt.month = ecma402_abstract_1.GetOption(options, 'month', 'string', ['2-digit', 'numeric', 'narrow', 'short', 'long'], undefined);\n opt.day = ecma402_abstract_1.GetOption(options, 'day', 'string', ['2-digit', 'numeric'], undefined);\n opt.hour = ecma402_abstract_1.GetOption(options, 'hour', 'string', ['2-digit', 'numeric'], undefined);\n opt.minute = ecma402_abstract_1.GetOption(options, 'minute', 'string', ['2-digit', 'numeric'], undefined);\n opt.second = ecma402_abstract_1.GetOption(options, 'second', 'string', ['2-digit', 'numeric'], undefined);\n opt.timeZoneName = ecma402_abstract_1.GetOption(options, 'timeZoneName', 'string', ['short', 'long'], undefined);\n opt.fractionalSecondDigits = ecma402_abstract_1.GetNumberOption(options, 'fractionalSecondDigits', 1, 3, \n // @ts-expect-error\n undefined);\n var dataLocaleData = localeData[dataLocale];\n ecma402_abstract_1.invariant(!!dataLocaleData, \"Missing locale data for \" + dataLocale);\n var formats = dataLocaleData.formats[calendar];\n // UNSPECCED: IMPLEMENTATION DETAILS\n if (!formats) {\n throw new RangeError(\"Calendar \\\"\" + calendar + \"\\\" is not supported. Try setting \\\"calendar\\\" to 1 of the following: \" + Object.keys(dataLocaleData.formats).join(', '));\n }\n var formatMatcher = ecma402_abstract_1.GetOption(options, 'formatMatcher', 'string', ['basic', 'best fit'], 'best fit');\n var dateStyle = ecma402_abstract_1.GetOption(options, 'dateStyle', 'string', ['full', 'long', 'medium', 'short'], undefined);\n internalSlots.dateStyle = dateStyle;\n var timeStyle = ecma402_abstract_1.GetOption(options, 'timeStyle', 'string', ['full', 'long', 'medium', 'short'], undefined);\n internalSlots.timeStyle = timeStyle;\n var bestFormat;\n if (dateStyle === undefined && timeStyle === undefined) {\n if (formatMatcher === 'basic') {\n bestFormat = BasicFormatMatcher_1.BasicFormatMatcher(opt, formats);\n }\n else {\n // IMPL DETAILS START\n if (isTimeRelated(opt)) {\n var hc = resolveHourCycle(internalSlots.hourCycle, dataLocaleData.hourCycle, hour12);\n opt.hour12 = hc === 'h11' || hc === 'h12';\n }\n // IMPL DETAILS END\n bestFormat = BestFitFormatMatcher_1.BestFitFormatMatcher(opt, formats);\n }\n }\n else {\n for (var _i = 0, DATE_TIME_PROPS_1 = utils_1.DATE_TIME_PROPS; _i < DATE_TIME_PROPS_1.length; _i++) {\n var prop = DATE_TIME_PROPS_1[_i];\n var p = opt[prop];\n if (p !== undefined) {\n throw new TypeError(\"Intl.DateTimeFormat can't set option \" + prop + \" when \" + (dateStyle ? 'dateStyle' : 'timeStyle') + \" is used\");\n }\n }\n bestFormat = DateTimeStyleFormat_1.DateTimeStyleFormat(dateStyle, timeStyle, dataLocaleData);\n }\n // IMPL DETAIL START\n // For debugging\n internalSlots.format = bestFormat;\n // IMPL DETAIL END\n for (var prop in opt) {\n var p = bestFormat[prop];\n if (p !== undefined) {\n internalSlots[prop] = p;\n }\n }\n var pattern;\n var rangePatterns;\n if (internalSlots.hour !== undefined) {\n var hc = resolveHourCycle(internalSlots.hourCycle, dataLocaleData.hourCycle, hour12);\n internalSlots.hourCycle = hc;\n if (hc === 'h11' || hc === 'h12') {\n pattern = bestFormat.pattern12;\n rangePatterns = bestFormat.rangePatterns12;\n }\n else {\n pattern = bestFormat.pattern;\n rangePatterns = bestFormat.rangePatterns;\n }\n }\n else {\n // @ts-ignore\n internalSlots.hourCycle = undefined;\n pattern = bestFormat.pattern;\n rangePatterns = bestFormat.rangePatterns;\n }\n internalSlots.pattern = pattern;\n internalSlots.rangePatterns = rangePatterns;\n return dtf;\n}\nexports.InitializeDateTimeFormat = InitializeDateTimeFormat;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.BasicFormatMatcher = void 0;\nvar tslib_1 = require(\"tslib\");\nvar ecma402_abstract_1 = require(\"@formatjs/ecma402-abstract\");\nvar utils_1 = require(\"./utils\");\n/**\n * https://tc39.es/ecma402/#sec-basicformatmatcher\n * @param options\n * @param formats\n */\nfunction BasicFormatMatcher(options, formats) {\n var bestScore = -Infinity;\n var bestFormat = formats[0];\n ecma402_abstract_1.invariant(Array.isArray(formats), 'formats should be a list of things');\n for (var _i = 0, formats_1 = formats; _i < formats_1.length; _i++) {\n var format = formats_1[_i];\n var score = 0;\n for (var _a = 0, DATE_TIME_PROPS_1 = utils_1.DATE_TIME_PROPS; _a < DATE_TIME_PROPS_1.length; _a++) {\n var prop = DATE_TIME_PROPS_1[_a];\n var optionsProp = options[prop];\n var formatProp = format[prop];\n if (optionsProp === undefined && formatProp !== undefined) {\n score -= utils_1.additionPenalty;\n }\n else if (optionsProp !== undefined && formatProp === undefined) {\n score -= utils_1.removalPenalty;\n }\n else if (optionsProp !== formatProp) {\n var values = void 0;\n if (prop === 'fractionalSecondDigits') {\n values = [1, 2, 3];\n }\n else {\n values = ['2-digit', 'numeric', 'narrow', 'short', 'long'];\n }\n var optionsPropIndex = values.indexOf(optionsProp);\n var formatPropIndex = values.indexOf(formatProp);\n var delta = Math.max(-2, Math.min(formatPropIndex - optionsPropIndex, 2));\n if (delta === 2) {\n score -= utils_1.longMorePenalty;\n }\n else if (delta === 1) {\n score -= utils_1.shortMorePenalty;\n }\n else if (delta === -1) {\n score -= utils_1.shortLessPenalty;\n }\n else if (delta === -2) {\n score -= utils_1.longLessPenalty;\n }\n }\n }\n if (score > bestScore) {\n bestScore = score;\n bestFormat = format;\n }\n }\n return tslib_1.__assign({}, bestFormat);\n}\nexports.BasicFormatMatcher = BasicFormatMatcher;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.BestFitFormatMatcher = exports.bestFitFormatMatcherScore = void 0;\nvar tslib_1 = require(\"tslib\");\nvar ecma402_abstract_1 = require(\"@formatjs/ecma402-abstract\");\nvar utils_1 = require(\"./utils\");\nvar skeleton_1 = require(\"./skeleton\");\nfunction isNumericType(t) {\n return t === 'numeric' || t === '2-digit';\n}\n/**\n * Credit: https://github.com/andyearnshaw/Intl.js/blob/0958dc1ad8153f1056653ea22b8208f0df289a4e/src/12.datetimeformat.js#L611\n * with some modifications\n * @param options\n * @param format\n */\nfunction bestFitFormatMatcherScore(options, format) {\n var score = 0;\n if (options.hour12 && !format.hour12) {\n score -= utils_1.removalPenalty;\n }\n else if (!options.hour12 && format.hour12) {\n score -= utils_1.additionPenalty;\n }\n for (var _i = 0, DATE_TIME_PROPS_1 = utils_1.DATE_TIME_PROPS; _i < DATE_TIME_PROPS_1.length; _i++) {\n var prop = DATE_TIME_PROPS_1[_i];\n var optionsProp = options[prop];\n var formatProp = format[prop];\n if (optionsProp === undefined && formatProp !== undefined) {\n score -= utils_1.additionPenalty;\n }\n else if (optionsProp !== undefined && formatProp === undefined) {\n score -= utils_1.removalPenalty;\n }\n else if (optionsProp !== formatProp) {\n // extra penalty for numeric vs non-numeric\n if (isNumericType(optionsProp) !==\n isNumericType(formatProp)) {\n score -= utils_1.differentNumericTypePenalty;\n }\n else {\n var values = ['2-digit', 'numeric', 'narrow', 'short', 'long'];\n var optionsPropIndex = values.indexOf(optionsProp);\n var formatPropIndex = values.indexOf(formatProp);\n var delta = Math.max(-2, Math.min(formatPropIndex - optionsPropIndex, 2));\n if (delta === 2) {\n score -= utils_1.longMorePenalty;\n }\n else if (delta === 1) {\n score -= utils_1.shortMorePenalty;\n }\n else if (delta === -1) {\n score -= utils_1.shortLessPenalty;\n }\n else if (delta === -2) {\n score -= utils_1.longLessPenalty;\n }\n }\n }\n }\n return score;\n}\nexports.bestFitFormatMatcherScore = bestFitFormatMatcherScore;\n/**\n * https://tc39.es/ecma402/#sec-bestfitformatmatcher\n * Just alias to basic for now\n * @param options\n * @param formats\n * @param implDetails Implementation details\n */\nfunction BestFitFormatMatcher(options, formats) {\n var bestScore = -Infinity;\n var bestFormat = formats[0];\n ecma402_abstract_1.invariant(Array.isArray(formats), 'formats should be a list of things');\n for (var _i = 0, formats_1 = formats; _i < formats_1.length; _i++) {\n var format = formats_1[_i];\n var score = bestFitFormatMatcherScore(options, format);\n if (score > bestScore) {\n bestScore = score;\n bestFormat = format;\n }\n }\n var skeletonFormat = tslib_1.__assign({}, bestFormat);\n var patternFormat = { rawPattern: bestFormat.rawPattern };\n skeleton_1.processDateTimePattern(bestFormat.rawPattern, patternFormat);\n // Kinda following https://github.com/unicode-org/icu/blob/dd50e38f459d84e9bf1b0c618be8483d318458ad/icu4j/main/classes/core/src/com/ibm/icu/text/DateTimePatternGenerator.java\n // Method adjustFieldTypes\n for (var prop in skeletonFormat) {\n var skeletonValue = skeletonFormat[prop];\n var patternValue = patternFormat[prop];\n var requestedValue = options[prop];\n // Don't mess with minute/second or we can get in the situation of\n // 7:0:0 which is weird\n if (prop === 'minute' || prop === 'second') {\n continue;\n }\n // Nothing to do here\n if (!requestedValue) {\n continue;\n }\n // https://unicode.org/reports/tr35/tr35-dates.html#Matching_Skeletons\n // Looks like we should not convert numeric to alphabetic but the other way\n // around is ok\n if (isNumericType(patternValue) &&\n !isNumericType(requestedValue)) {\n continue;\n }\n if (skeletonValue === requestedValue) {\n continue;\n }\n patternFormat[prop] = requestedValue;\n }\n // Copy those over\n patternFormat.pattern = skeletonFormat.pattern;\n patternFormat.pattern12 = skeletonFormat.pattern12;\n patternFormat.skeleton = skeletonFormat.skeleton;\n patternFormat.rangePatterns = skeletonFormat.rangePatterns;\n patternFormat.rangePatterns12 = skeletonFormat.rangePatterns12;\n return patternFormat;\n}\nexports.BestFitFormatMatcher = BestFitFormatMatcher;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.DateTimeStyleFormat = void 0;\nvar ecma402_abstract_1 = require(\"@formatjs/ecma402-abstract\");\nfunction DateTimeStyleFormat(dateStyle, timeStyle, dataLocaleData) {\n var dateFormat, timeFormat;\n if (timeStyle !== undefined) {\n ecma402_abstract_1.invariant(timeStyle === 'full' ||\n timeStyle === 'long' ||\n timeStyle === 'medium' ||\n timeStyle === 'short', 'invalid timeStyle');\n timeFormat = dataLocaleData.timeFormat[timeStyle];\n }\n if (dateStyle !== undefined) {\n ecma402_abstract_1.invariant(dateStyle === 'full' ||\n dateStyle === 'long' ||\n dateStyle === 'medium' ||\n dateStyle === 'short', 'invalid dateStyle');\n dateFormat = dataLocaleData.dateFormat[dateStyle];\n }\n if (dateStyle !== undefined && timeStyle !== undefined) {\n var format = {};\n for (var field in dateFormat) {\n if (field !== 'pattern') {\n // @ts-ignore\n format[field] = dateFormat[field];\n }\n }\n for (var field in timeFormat) {\n if (field !== 'pattern' && field !== 'pattern12') {\n // @ts-ignore\n format[field] = timeFormat[field];\n }\n }\n var connector = dataLocaleData.dateTimeFormat[dateStyle];\n var pattern = connector\n .replace('{0}', timeFormat.pattern)\n .replace('{1}', dateFormat.pattern);\n format.pattern = pattern;\n if ('pattern12' in timeFormat) {\n var pattern12 = connector\n .replace('{0}', timeFormat.pattern12)\n .replace('{1}', dateFormat.pattern);\n format.pattern12 = pattern12;\n }\n return format;\n }\n if (timeStyle !== undefined) {\n return timeFormat;\n }\n ecma402_abstract_1.invariant(dateStyle !== undefined, 'dateStyle should not be undefined');\n return dateFormat;\n}\nexports.DateTimeStyleFormat = DateTimeStyleFormat;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.FormatDateTimeToParts = void 0;\nvar PartitionDateTimePattern_1 = require(\"./PartitionDateTimePattern\");\nvar ecma402_abstract_1 = require(\"@formatjs/ecma402-abstract\");\n/**\n * https://tc39.es/ecma402/#sec-formatdatetimetoparts\n *\n * @param dtf\n * @param x\n * @param implDetails\n */\nfunction FormatDateTimeToParts(dtf, x, implDetails) {\n var parts = PartitionDateTimePattern_1.PartitionDateTimePattern(dtf, x, implDetails);\n var result = ecma402_abstract_1.ArrayCreate(0);\n for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) {\n var part = parts_1[_i];\n result.push({\n type: part.type,\n value: part.value,\n });\n }\n return result;\n}\nexports.FormatDateTimeToParts = FormatDateTimeToParts;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.FormatDateTimeRangeToParts = void 0;\nvar PartitionDateTimeRangePattern_1 = require(\"./PartitionDateTimeRangePattern\");\nfunction FormatDateTimeRangeToParts(dtf, x, y, implDetails) {\n var parts = PartitionDateTimeRangePattern_1.PartitionDateTimeRangePattern(dtf, x, y, implDetails);\n var result = new Array(0);\n for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) {\n var part = parts_1[_i];\n result.push({\n type: part.type,\n value: part.value,\n source: part.source,\n });\n }\n return result;\n}\nexports.FormatDateTimeRangeToParts = FormatDateTimeRangeToParts;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.FormatDateTimeRange = void 0;\nvar PartitionDateTimeRangePattern_1 = require(\"./PartitionDateTimeRangePattern\");\nfunction FormatDateTimeRange(dtf, x, y, implDetails) {\n var parts = PartitionDateTimeRangePattern_1.PartitionDateTimeRangePattern(dtf, x, y, implDetails);\n var result = '';\n for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) {\n var part = parts_1[_i];\n result += part.value;\n }\n return result;\n}\nexports.FormatDateTimeRange = FormatDateTimeRange;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.shouldPolyfill = void 0;\nfunction supportsDateStyle() {\n try {\n return !!new Intl.DateTimeFormat(undefined, {\n dateStyle: 'short',\n }).resolvedOptions().dateStyle;\n }\n catch (e) {\n return false;\n }\n}\n/**\n * https://bugs.chromium.org/p/chromium/issues/detail?id=865351\n */\nfunction hasChromeLt71Bug() {\n try {\n return (new Intl.DateTimeFormat('en', {\n hourCycle: 'h11',\n hour: 'numeric',\n }).formatToParts(0)[2].type !== 'dayPeriod');\n }\n catch (e) {\n return false;\n }\n}\n/**\n * Node 14's version of Intl.DateTimeFormat does not throw\n * when dateStyle/timeStyle is used with other options.\n * This was fixed in newer V8 versions\n */\nfunction hasUnthrownDateTimeStyleBug() {\n try {\n return !!new Intl.DateTimeFormat('en', {\n dateStyle: 'short',\n hour: 'numeric',\n }).format(new Date(0));\n }\n catch (e) {\n return false;\n }\n}\nfunction supportedLocalesOf(locale) {\n if (!locale) {\n return true;\n }\n var locales = Array.isArray(locale) ? locale : [locale];\n return (Intl.DateTimeFormat.supportedLocalesOf(locales).length === locales.length);\n}\nfunction shouldPolyfill(locale) {\n return (!('DateTimeFormat' in Intl) ||\n !('formatToParts' in Intl.DateTimeFormat.prototype) ||\n !('formatRange' in Intl.DateTimeFormat.prototype) ||\n hasChromeLt71Bug() ||\n hasUnthrownDateTimeStyleBug() ||\n !supportsDateStyle() ||\n !supportedLocalesOf(locale));\n}\nexports.shouldPolyfill = shouldPolyfill;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.toLocaleTimeString = exports.toLocaleDateString = exports.toLocaleString = void 0;\n// eslint-disable-next-line import/no-cycle\nvar core_1 = require(\"./core\");\nvar ToDateTimeOptions_1 = require(\"./abstract/ToDateTimeOptions\");\n/**\n * Number.prototype.toLocaleString ponyfill\n * https://tc39.es/ecma402/#sup-number.prototype.tolocalestring\n */\nfunction toLocaleString(x, locales, options) {\n var dtf = new core_1.DateTimeFormat(locales, options);\n return dtf.format(x);\n}\nexports.toLocaleString = toLocaleString;\nfunction toLocaleDateString(x, locales, options) {\n var dtf = new core_1.DateTimeFormat(locales, ToDateTimeOptions_1.ToDateTimeOptions(options, 'date', 'date'));\n return dtf.format(x);\n}\nexports.toLocaleDateString = toLocaleDateString;\nfunction toLocaleTimeString(x, locales, options) {\n var dtf = new core_1.DateTimeFormat(locales, ToDateTimeOptions_1.ToDateTimeOptions(options, 'time', 'time'));\n return dtf.format(x);\n}\nexports.toLocaleTimeString = toLocaleTimeString;\n","/* @generated */\t\n\n // prettier-ignore\n if (Intl.DateTimeFormat && typeof Intl.DateTimeFormat.__addLocaleData === 'function') {\n Intl.DateTimeFormat.__addLocaleData({\"data\":{\"am\":\"AM\",\"pm\":\"PM\",\"weekday\":{\"narrow\":[\"S\",\"M\",\"T\",\"W\",\"T\",\"F\",\"S\"],\"short\":[\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"],\"long\":[\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"]},\"era\":{\"narrow\":{\"BC\":\"B\",\"AD\":\"A\"},\"short\":{\"BC\":\"BC\",\"AD\":\"AD\"},\"long\":{\"BC\":\"Before Christ\",\"AD\":\"Anno Domini\"}},\"month\":{\"narrow\":[\"J\",\"F\",\"M\",\"A\",\"M\",\"J\",\"J\",\"A\",\"S\",\"O\",\"N\",\"D\"],\"short\":[\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"],\"long\":[\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"]},\"timeZoneName\":{\"America/Rio_Branco\":{\"long\":[\"Acre Standard Time\",\"Acre Summer Time\"]},\"Asia/Kabul\":{\"long\":[\"Afghanistan Time\",\"Afghanistan Time\"]},\"Africa/Maputo\":{\"long\":[\"Central Africa Time\",\"Central Africa Time\"]},\"Africa/Bujumbura\":{\"long\":[\"Central Africa Time\",\"Central Africa Time\"]},\"Africa/Gaborone\":{\"long\":[\"Central Africa Time\",\"Central Africa Time\"]},\"Africa/Lubumbashi\":{\"long\":[\"Central Africa Time\",\"Central Africa Time\"]},\"Africa/Blantyre\":{\"long\":[\"Central Africa Time\",\"Central Africa Time\"]},\"Africa/Kigali\":{\"long\":[\"Central Africa Time\",\"Central Africa Time\"]},\"Africa/Lusaka\":{\"long\":[\"Central Africa Time\",\"Central Africa Time\"]},\"Africa/Harare\":{\"long\":[\"Central Africa Time\",\"Central Africa Time\"]},\"Africa/Nairobi\":{\"long\":[\"East Africa Time\",\"East Africa Time\"]},\"Africa/Djibouti\":{\"long\":[\"East Africa Time\",\"East Africa Time\"]},\"Africa/Asmera\":{\"long\":[\"East Africa Time\",\"East Africa Time\"]},\"Africa/Addis_Ababa\":{\"long\":[\"East Africa Time\",\"East Africa Time\"]},\"Indian/Comoro\":{\"long\":[\"East Africa Time\",\"East Africa Time\"]},\"Indian/Antananarivo\":{\"long\":[\"East Africa Time\",\"East Africa Time\"]},\"Africa/Mogadishu\":{\"long\":[\"East Africa Time\",\"East Africa Time\"]},\"Africa/Dar_es_Salaam\":{\"long\":[\"East Africa Time\",\"East Africa Time\"]},\"Africa/Kampala\":{\"long\":[\"East Africa Time\",\"East Africa Time\"]},\"Indian/Mayotte\":{\"long\":[\"East Africa Time\",\"East Africa Time\"]},\"Africa/Johannesburg\":{\"long\":[\"South Africa Standard Time\",\"South Africa Standard Time\"]},\"Africa/Maseru\":{\"long\":[\"South Africa Standard Time\",\"South Africa Standard Time\"]},\"Africa/Mbabane\":{\"long\":[\"South Africa Standard Time\",\"South Africa Standard Time\"]},\"Africa/Lagos\":{\"long\":[\"West Africa Standard Time\",\"West Africa Summer Time\"]},\"Africa/Luanda\":{\"long\":[\"West Africa Standard Time\",\"West Africa Summer Time\"]},\"Africa/Porto-Novo\":{\"long\":[\"West Africa Standard Time\",\"West Africa Summer Time\"]},\"Africa/Kinshasa\":{\"long\":[\"West Africa Standard Time\",\"West Africa Summer Time\"]},\"Africa/Bangui\":{\"long\":[\"West Africa Standard Time\",\"West Africa Summer Time\"]},\"Africa/Brazzaville\":{\"long\":[\"West Africa Standard Time\",\"West Africa Summer Time\"]},\"Africa/Douala\":{\"long\":[\"West Africa Standard Time\",\"West Africa Summer Time\"]},\"Africa/Libreville\":{\"long\":[\"West Africa Standard Time\",\"West Africa Summer Time\"]},\"Africa/Malabo\":{\"long\":[\"West Africa Standard Time\",\"West Africa Summer Time\"]},\"Africa/Niamey\":{\"long\":[\"West Africa Standard Time\",\"West Africa Summer Time\"]},\"Africa/Ndjamena\":{\"long\":[\"West Africa Standard Time\",\"West Africa Summer Time\"]},\"Asia/Aqtobe\":{\"long\":[\"West Kazakhstan Time\",\"West Kazakhstan Time\"]},\"America/Juneau\":{\"long\":[\"Alaska Standard Time\",\"Alaska Daylight Time\"],\"short\":[\"AKST\",\"AKDT\"]},\"Asia/Almaty\":{\"long\":[\"East Kazakhstan Time\",\"East Kazakhstan Time\"]},\"America/Manaus\":{\"long\":[\"Amazon Standard Time\",\"Amazon Summer Time\"]},\"America/Chicago\":{\"long\":[\"Central Standard Time\",\"Central Daylight Time\"],\"short\":[\"CST\",\"CDT\"]},\"America/Belize\":{\"long\":[\"Central Standard Time\",\"Central Daylight Time\"],\"short\":[\"CST\",\"CDT\"]},\"America/Winnipeg\":{\"long\":[\"Central Standard Time\",\"Central Daylight Time\"],\"short\":[\"CST\",\"CDT\"]},\"America/Costa_Rica\":{\"long\":[\"Central Standard Time\",\"Central Daylight Time\"],\"short\":[\"CST\",\"CDT\"]},\"America/Guatemala\":{\"long\":[\"Central Standard Time\",\"Central Daylight Time\"],\"short\":[\"CST\",\"CDT\"]},\"America/Tegucigalpa\":{\"long\":[\"Central Standard Time\",\"Central Daylight Time\"],\"short\":[\"CST\",\"CDT\"]},\"America/Mexico_City\":{\"long\":[\"Central Standard Time\",\"Central Daylight Time\"],\"short\":[\"CST\",\"CDT\"]},\"America/El_Salvador\":{\"long\":[\"Central Standard Time\",\"Central Daylight Time\"],\"short\":[\"CST\",\"CDT\"]},\"America/New_York\":{\"long\":[\"Eastern Standard Time\",\"Eastern Daylight Time\"],\"short\":[\"EST\",\"EDT\"]},\"America/Nassau\":{\"long\":[\"Eastern Standard Time\",\"Eastern Daylight Time\"],\"short\":[\"EST\",\"EDT\"]},\"America/Toronto\":{\"long\":[\"Eastern Standard Time\",\"Eastern Daylight Time\"],\"short\":[\"EST\",\"EDT\"]},\"America/Port-au-Prince\":{\"long\":[\"Eastern Standard Time\",\"Eastern Daylight Time\"],\"short\":[\"EST\",\"EDT\"]},\"America/Jamaica\":{\"long\":[\"Eastern Standard Time\",\"Eastern Daylight Time\"],\"short\":[\"EST\",\"EDT\"]},\"America/Cayman\":{\"long\":[\"Eastern Standard Time\",\"Eastern Daylight Time\"],\"short\":[\"EST\",\"EDT\"]},\"America/Panama\":{\"long\":[\"Eastern Standard Time\",\"Eastern Daylight Time\"],\"short\":[\"EST\",\"EDT\"]},\"America/Denver\":{\"long\":[\"Mountain Standard Time\",\"Mountain Daylight Time\"],\"short\":[\"MST\",\"MDT\"]},\"America/Edmonton\":{\"long\":[\"Mountain Standard Time\",\"Mountain Daylight Time\"],\"short\":[\"MST\",\"MDT\"]},\"America/Hermosillo\":{\"long\":[\"Mountain Standard Time\",\"Mountain Daylight Time\"],\"short\":[\"MST\",\"MDT\"]},\"America/Los_Angeles\":{\"long\":[\"Pacific Standard Time\",\"Pacific Daylight Time\"],\"short\":[\"PST\",\"PDT\"]},\"America/Vancouver\":{\"long\":[\"Pacific Standard Time\",\"Pacific Daylight Time\"],\"short\":[\"PST\",\"PDT\"]},\"America/Tijuana\":{\"long\":[\"Pacific Standard Time\",\"Pacific Daylight Time\"],\"short\":[\"PST\",\"PDT\"]},\"Asia/Anadyr\":{\"long\":[\"Anadyr Standard Time\",\"Anadyr Summer Time\"]},\"Pacific/Apia\":{\"long\":[\"Apia Standard Time\",\"Apia Daylight Time\"]},\"Asia/Riyadh\":{\"long\":[\"Arabian Standard Time\",\"Arabian Daylight Time\"]},\"Asia/Bahrain\":{\"long\":[\"Arabian Standard Time\",\"Arabian Daylight Time\"]},\"Asia/Baghdad\":{\"long\":[\"Arabian Standard Time\",\"Arabian Daylight Time\"]},\"Asia/Kuwait\":{\"long\":[\"Arabian Standard Time\",\"Arabian Daylight Time\"]},\"Asia/Qatar\":{\"long\":[\"Arabian Standard Time\",\"Arabian Daylight Time\"]},\"Asia/Aden\":{\"long\":[\"Arabian Standard Time\",\"Arabian Daylight Time\"]},\"America/Buenos_Aires\":{\"long\":[\"Argentina Standard Time\",\"Argentina Summer Time\"]},\"America/Argentina/San_Luis\":{\"long\":[\"Western Argentina Standard Time\",\"Western Argentina Summer Time\"]},\"Asia/Ashgabat\":{\"long\":[\"Turkmenistan Standard Time\",\"Turkmenistan Summer Time\"]},\"America/Halifax\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"America/Antigua\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"America/Anguilla\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"America/Aruba\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"America/Barbados\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"Atlantic/Bermuda\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"America/Kralendijk\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"America/Curacao\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"America/Dominica\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"America/Grenada\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"America/Thule\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"America/Guadeloupe\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"America/St_Kitts\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"America/St_Lucia\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"America/Marigot\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"America/Martinique\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"America/Montserrat\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"America/Puerto_Rico\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"America/Lower_Princes\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"America/Port_of_Spain\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"America/St_Vincent\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"America/Tortola\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"America/St_Thomas\":{\"long\":[\"Atlantic Standard Time\",\"Atlantic Daylight Time\"],\"short\":[\"AST\",\"ADT\"]},\"Australia/Adelaide\":{\"long\":[\"Australian Central Standard Time\",\"Australian Central Daylight Time\"]},\"Australia/Eucla\":{\"long\":[\"Australian Central Western Standard Time\",\"Australian Central Western Daylight Time\"]},\"Australia/Sydney\":{\"long\":[\"Australian Eastern Standard Time\",\"Australian Eastern Daylight Time\"]},\"Australia/Perth\":{\"long\":[\"Australian Western Standard Time\",\"Australian Western Daylight Time\"]},\"Atlantic/Azores\":{\"long\":[\"Azores Standard Time\",\"Azores Summer Time\"]},\"Asia/Thimphu\":{\"long\":[\"Bhutan Time\",\"Bhutan Time\"]},\"America/La_Paz\":{\"long\":[\"Bolivia Time\",\"Bolivia Time\"]},\"Asia/Kuching\":{\"long\":[\"Malaysia Time\",\"Malaysia Time\"]},\"America/Sao_Paulo\":{\"long\":[\"Brasilia Standard Time\",\"Brasilia Summer Time\"]},\"Europe/London\":{\"long\":[\"Greenwich Mean Time\",\"Greenwich Mean Time\"],\"short\":[\"GMT\",\"GMT\"]},\"Asia/Brunei\":{\"long\":[\"Brunei Darussalam Time\",\"Brunei Darussalam Time\"]},\"Atlantic/Cape_Verde\":{\"long\":[\"Cape Verde Standard Time\",\"Cape Verde Summer Time\"]},\"Antarctica/Casey\":{\"long\":[\"Casey Time\",\"Casey Time\"]},\"Pacific/Saipan\":{\"long\":[\"North Mariana Islands Time\",\"North Mariana Islands Time\"]},\"Pacific/Guam\":{\"long\":[\"Guam Standard Time\",\"Guam Standard Time\"]},\"Pacific/Chatham\":{\"long\":[\"Chatham Standard Time\",\"Chatham Daylight Time\"]},\"America/Santiago\":{\"long\":[\"Chile Standard Time\",\"Chile Summer Time\"]},\"Asia/Shanghai\":{\"long\":[\"China Standard Time\",\"China Daylight Time\"]},\"Asia/Choibalsan\":{\"long\":[\"Choibalsan Standard Time\",\"Choibalsan Summer Time\"]},\"Indian/Christmas\":{\"long\":[\"Christmas Island Time\",\"Christmas Island Time\"]},\"Indian/Cocos\":{\"long\":[\"Cocos Islands Time\",\"Cocos Islands Time\"]},\"America/Bogota\":{\"long\":[\"Colombia Standard Time\",\"Colombia Summer Time\"]},\"Pacific/Rarotonga\":{\"long\":[\"Cook Islands Standard Time\",\"Cook Islands Half Summer Time\"]},\"America/Havana\":{\"long\":[\"Cuba Standard Time\",\"Cuba Daylight Time\"]},\"Antarctica/Davis\":{\"long\":[\"Davis Time\",\"Davis Time\"]},\"Antarctica/DumontDUrville\":{\"long\":[\"Dumont-d’Urville Time\",\"Dumont-d’Urville Time\"]},\"Asia/Dushanbe\":{\"long\":[\"Tajikistan Time\",\"Tajikistan Time\"]},\"America/Paramaribo\":{\"long\":[\"Suriname Time\",\"Suriname Time\"]},\"Asia/Dili\":{\"long\":[\"East Timor Time\",\"East Timor Time\"]},\"Pacific/Easter\":{\"long\":[\"Easter Island Standard Time\",\"Easter Island Summer Time\"]},\"America/Guayaquil\":{\"long\":[\"Ecuador Time\",\"Ecuador Time\"]},\"Europe/Paris\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Andorra\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Tirane\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Vienna\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Sarajevo\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Brussels\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Zurich\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Prague\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Berlin\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Copenhagen\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Madrid\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Gibraltar\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Zagreb\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Budapest\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Rome\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Vaduz\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Luxembourg\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Monaco\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Podgorica\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Skopje\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Malta\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Amsterdam\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Oslo\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Warsaw\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Belgrade\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Stockholm\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Ljubljana\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Arctic/Longyearbyen\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Bratislava\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/San_Marino\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Africa/Tunis\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Vatican\":{\"long\":[\"Central European Standard Time\",\"Central European Summer Time\"]},\"Europe/Bucharest\":{\"long\":[\"Eastern European Standard Time\",\"Eastern European Summer Time\"]},\"Europe/Mariehamn\":{\"long\":[\"Eastern European Standard Time\",\"Eastern European Summer Time\"]},\"Europe/Sofia\":{\"long\":[\"Eastern European Standard Time\",\"Eastern European Summer Time\"]},\"Asia/Nicosia\":{\"long\":[\"Eastern European Standard Time\",\"Eastern European Summer Time\"]},\"Africa/Cairo\":{\"long\":[\"Eastern European Standard Time\",\"Eastern European Summer Time\"]},\"Europe/Helsinki\":{\"long\":[\"Eastern European Standard Time\",\"Eastern European Summer Time\"]},\"Europe/Athens\":{\"long\":[\"Eastern European Standard Time\",\"Eastern European Summer Time\"]},\"Asia/Amman\":{\"long\":[\"Eastern European Standard Time\",\"Eastern European Summer Time\"]},\"Asia/Beirut\":{\"long\":[\"Eastern European Standard Time\",\"Eastern European Summer Time\"]},\"Asia/Damascus\":{\"long\":[\"Eastern European Standard Time\",\"Eastern European Summer Time\"]},\"Europe/Minsk\":{\"long\":[\"Further-eastern European Time\",\"Further-eastern European Time\"]},\"Europe/Kaliningrad\":{\"long\":[\"Further-eastern European Time\",\"Further-eastern European Time\"]},\"Atlantic/Canary\":{\"long\":[\"Western European Standard Time\",\"Western European Summer Time\"]},\"Atlantic/Faeroe\":{\"long\":[\"Western European Standard Time\",\"Western European Summer Time\"]},\"Atlantic/Stanley\":{\"long\":[\"Falkland Islands Standard Time\",\"Falkland Islands Summer Time\"]},\"Pacific/Fiji\":{\"long\":[\"Fiji Standard Time\",\"Fiji Summer Time\"]},\"America/Cayenne\":{\"long\":[\"French Guiana Time\",\"French Guiana Time\"]},\"Indian/Kerguelen\":{\"long\":[\"French Southern & Antarctic Time\",\"French Southern & Antarctic Time\"]},\"Asia/Bishkek\":{\"long\":[\"Kyrgyzstan Time\",\"Kyrgyzstan Time\"]},\"Pacific/Galapagos\":{\"long\":[\"Galapagos Time\",\"Galapagos Time\"]},\"Pacific/Gambier\":{\"long\":[\"Gambier Time\",\"Gambier Time\"]},\"Pacific/Tarawa\":{\"long\":[\"Gilbert Islands Time\",\"Gilbert Islands Time\"]},\"Atlantic/Reykjavik\":{\"long\":[\"Greenwich Mean Time\",\"Greenwich Mean Time\"],\"short\":[\"GMT\",\"GMT\"]},\"Africa/Ouagadougou\":{\"long\":[\"Greenwich Mean Time\",\"Greenwich Mean Time\"],\"short\":[\"GMT\",\"GMT\"]},\"Africa/Abidjan\":{\"long\":[\"Greenwich Mean Time\",\"Greenwich Mean Time\"],\"short\":[\"GMT\",\"GMT\"]},\"Africa/Accra\":{\"long\":[\"Greenwich Mean Time\",\"Greenwich Mean Time\"],\"short\":[\"GMT\",\"GMT\"]},\"Africa/Banjul\":{\"long\":[\"Greenwich Mean Time\",\"Greenwich Mean Time\"],\"short\":[\"GMT\",\"GMT\"]},\"Africa/Conakry\":{\"long\":[\"Greenwich Mean Time\",\"Greenwich Mean Time\"],\"short\":[\"GMT\",\"GMT\"]},\"Africa/Bamako\":{\"long\":[\"Greenwich Mean Time\",\"Greenwich Mean Time\"],\"short\":[\"GMT\",\"GMT\"]},\"Africa/Nouakchott\":{\"long\":[\"Greenwich Mean Time\",\"Greenwich Mean Time\"],\"short\":[\"GMT\",\"GMT\"]},\"Atlantic/St_Helena\":{\"long\":[\"Greenwich Mean Time\",\"Greenwich Mean Time\"],\"short\":[\"GMT\",\"GMT\"]},\"Africa/Freetown\":{\"long\":[\"Greenwich Mean Time\",\"Greenwich Mean Time\"],\"short\":[\"GMT\",\"GMT\"]},\"Africa/Dakar\":{\"long\":[\"Greenwich Mean Time\",\"Greenwich Mean Time\"],\"short\":[\"GMT\",\"GMT\"]},\"Africa/Lome\":{\"long\":[\"Greenwich Mean Time\",\"Greenwich Mean Time\"],\"short\":[\"GMT\",\"GMT\"]},\"America/Scoresbysund\":{\"long\":[\"East Greenland Standard Time\",\"East Greenland Summer Time\"]},\"America/Godthab\":{\"long\":[\"West Greenland Standard Time\",\"West Greenland Summer Time\"]},\"Asia/Dubai\":{\"long\":[\"Gulf Standard Time\",\"Gulf Standard Time\"]},\"Asia/Muscat\":{\"long\":[\"Gulf Standard Time\",\"Gulf Standard Time\"]},\"America/Guyana\":{\"long\":[\"Guyana Time\",\"Guyana Time\"]},\"Pacific/Honolulu\":{\"long\":[\"Hawaii-Aleutian Standard Time\",\"Hawaii-Aleutian Daylight Time\"],\"short\":[\"HAST\",\"HADT\"]},\"Asia/Hong_Kong\":{\"long\":[\"Hong Kong Standard Time\",\"Hong Kong Summer Time\"]},\"Asia/Hovd\":{\"long\":[\"Hovd Standard Time\",\"Hovd Summer Time\"]},\"Asia/Calcutta\":{\"long\":[\"India Standard Time\",\"India Standard Time\"]},\"Asia/Colombo\":{\"long\":[\"Lanka Time\",\"Lanka Time\"]},\"Indian/Chagos\":{\"long\":[\"Indian Ocean Time\",\"Indian Ocean Time\"]},\"Asia/Bangkok\":{\"long\":[\"Indochina Time\",\"Indochina Time\"]},\"Asia/Phnom_Penh\":{\"long\":[\"Indochina Time\",\"Indochina Time\"]},\"Asia/Vientiane\":{\"long\":[\"Indochina Time\",\"Indochina Time\"]},\"Asia/Makassar\":{\"long\":[\"Central Indonesia Time\",\"Central Indonesia Time\"]},\"Asia/Jayapura\":{\"long\":[\"Eastern Indonesia Time\",\"Eastern Indonesia Time\"]},\"Asia/Jakarta\":{\"long\":[\"Western Indonesia Time\",\"Western Indonesia Time\"]},\"Asia/Tehran\":{\"long\":[\"Iran Standard Time\",\"Iran Daylight Time\"]},\"Asia/Irkutsk\":{\"long\":[\"Irkutsk Standard Time\",\"Irkutsk Summer Time\"]},\"Asia/Jerusalem\":{\"long\":[\"Israel Standard Time\",\"Israel Daylight Time\"]},\"Asia/Tokyo\":{\"long\":[\"Japan Standard Time\",\"Japan Daylight Time\"]},\"Asia/Kamchatka\":{\"long\":[\"Petropavlovsk-Kamchatski Standard Time\",\"Petropavlovsk-Kamchatski Summer Time\"]},\"Asia/Karachi\":{\"long\":[\"Pakistan Standard Time\",\"Pakistan Summer Time\"]},\"Asia/Qyzylorda\":{\"long\":[\"Qyzylorda Standard Time\",\"Qyzylorda Summer Time\"]},\"Asia/Seoul\":{\"long\":[\"Korean Standard Time\",\"Korean Daylight Time\"]},\"Pacific/Kosrae\":{\"long\":[\"Kosrae Time\",\"Kosrae Time\"]},\"Asia/Krasnoyarsk\":{\"long\":[\"Krasnoyarsk Standard Time\",\"Krasnoyarsk Summer Time\"]},\"Europe/Samara\":{\"long\":[\"Samara Standard Time\",\"Samara Summer Time\"]},\"Pacific/Kiritimati\":{\"long\":[\"Line Islands Time\",\"Line Islands Time\"]},\"Australia/Lord_Howe\":{\"long\":[\"Lord Howe Standard Time\",\"Lord Howe Daylight Time\"]},\"Asia/Macau\":{\"long\":[\"Macao Standard Time\",\"Macao Summer Time\"]},\"Antarctica/Macquarie\":{\"long\":[\"Macquarie Island Time\",\"Macquarie Island Time\"]},\"Asia/Magadan\":{\"long\":[\"Magadan Standard Time\",\"Magadan Summer Time\"]},\"Indian/Maldives\":{\"long\":[\"Maldives Time\",\"Maldives Time\"]},\"Pacific/Marquesas\":{\"long\":[\"Marquesas Time\",\"Marquesas Time\"]},\"Pacific/Majuro\":{\"long\":[\"Marshall Islands Time\",\"Marshall Islands Time\"]},\"Indian/Mauritius\":{\"long\":[\"Mauritius Standard Time\",\"Mauritius Summer Time\"]},\"Antarctica/Mawson\":{\"long\":[\"Mawson Time\",\"Mawson Time\"]},\"America/Santa_Isabel\":{\"long\":[\"Northwest Mexico Standard Time\",\"Northwest Mexico Daylight Time\"]},\"America/Mazatlan\":{\"long\":[\"Mexican Pacific Standard Time\",\"Mexican Pacific Daylight Time\"]},\"Asia/Ulaanbaatar\":{\"long\":[\"Ulaanbaatar Standard Time\",\"Ulaanbaatar Summer Time\"]},\"Europe/Moscow\":{\"long\":[\"Moscow Standard Time\",\"Moscow Summer Time\"]},\"Asia/Rangoon\":{\"long\":[\"Myanmar Time\",\"Myanmar Time\"]},\"Pacific/Nauru\":{\"long\":[\"Nauru Time\",\"Nauru Time\"]},\"Asia/Katmandu\":{\"long\":[\"Nepal Time\",\"Nepal Time\"]},\"Pacific/Noumea\":{\"long\":[\"New Caledonia Standard Time\",\"New Caledonia Summer Time\"]},\"Pacific/Auckland\":{\"long\":[\"New Zealand Standard Time\",\"New Zealand Daylight Time\"]},\"Antarctica/McMurdo\":{\"long\":[\"New Zealand Standard Time\",\"New Zealand Daylight Time\"]},\"America/St_Johns\":{\"long\":[\"Newfoundland Standard Time\",\"Newfoundland Daylight Time\"]},\"Pacific/Niue\":{\"long\":[\"Niue Time\",\"Niue Time\"]},\"Pacific/Norfolk\":{\"long\":[\"Norfolk Island Standard Time\",\"Norfolk Island Daylight Time\"]},\"America/Noronha\":{\"long\":[\"Fernando de Noronha Standard Time\",\"Fernando de Noronha Summer Time\"]},\"Asia/Novosibirsk\":{\"long\":[\"Novosibirsk Standard Time\",\"Novosibirsk Summer Time\"]},\"Asia/Omsk\":{\"long\":[\"Omsk Standard Time\",\"Omsk Summer Time\"]},\"Pacific/Palau\":{\"long\":[\"Palau Time\",\"Palau Time\"]},\"Pacific/Port_Moresby\":{\"long\":[\"Papua New Guinea Time\",\"Papua New Guinea Time\"]},\"America/Asuncion\":{\"long\":[\"Paraguay Standard Time\",\"Paraguay Summer Time\"]},\"America/Lima\":{\"long\":[\"Peru Standard Time\",\"Peru Summer Time\"]},\"Asia/Manila\":{\"long\":[\"Philippine Standard Time\",\"Philippine Summer Time\"]},\"Pacific/Enderbury\":{\"long\":[\"Phoenix Islands Time\",\"Phoenix Islands Time\"]},\"America/Miquelon\":{\"long\":[\"St. Pierre & Miquelon Standard Time\",\"St. Pierre & Miquelon Daylight Time\"]},\"Pacific/Pitcairn\":{\"long\":[\"Pitcairn Time\",\"Pitcairn Time\"]},\"Pacific/Ponape\":{\"long\":[\"Ponape Time\",\"Ponape Time\"]},\"Asia/Pyongyang\":{\"long\":[\"Pyongyang Time\",\"Pyongyang Time\"]},\"Indian/Reunion\":{\"long\":[\"Réunion Time\",\"Réunion Time\"]},\"Antarctica/Rothera\":{\"long\":[\"Rothera Time\",\"Rothera Time\"]},\"Asia/Sakhalin\":{\"long\":[\"Sakhalin Standard Time\",\"Sakhalin Summer Time\"]},\"Pacific/Pago_Pago\":{\"long\":[\"Samoa Standard Time\",\"Samoa Daylight Time\"]},\"Indian/Mahe\":{\"long\":[\"Seychelles Time\",\"Seychelles Time\"]},\"Asia/Singapore\":{\"long\":[\"Singapore Standard Time\",\"Singapore Standard Time\"]},\"Pacific/Guadalcanal\":{\"long\":[\"Solomon Islands Time\",\"Solomon Islands Time\"]},\"Atlantic/South_Georgia\":{\"long\":[\"South Georgia Time\",\"South Georgia Time\"]},\"Asia/Yekaterinburg\":{\"long\":[\"Yekaterinburg Standard Time\",\"Yekaterinburg Summer Time\"]},\"Antarctica/Syowa\":{\"long\":[\"Syowa Time\",\"Syowa Time\"]},\"Pacific/Tahiti\":{\"long\":[\"Tahiti Time\",\"Tahiti Time\"]},\"Asia/Taipei\":{\"long\":[\"Taipei Standard Time\",\"Taipei Daylight Time\"]},\"Asia/Tashkent\":{\"long\":[\"Uzbekistan Standard Time\",\"Uzbekistan Summer Time\"]},\"Pacific/Fakaofo\":{\"long\":[\"Tokelau Time\",\"Tokelau Time\"]},\"Pacific/Tongatapu\":{\"long\":[\"Tonga Standard Time\",\"Tonga Summer Time\"]},\"Pacific/Truk\":{\"long\":[\"Chuuk Time\",\"Chuuk Time\"]},\"Pacific/Funafuti\":{\"long\":[\"Tuvalu Time\",\"Tuvalu Time\"]},\"America/Montevideo\":{\"long\":[\"Uruguay Standard Time\",\"Uruguay Summer Time\"]},\"Pacific/Efate\":{\"long\":[\"Vanuatu Standard Time\",\"Vanuatu Summer Time\"]},\"America/Caracas\":{\"long\":[\"Venezuela Time\",\"Venezuela Time\"]},\"Asia/Vladivostok\":{\"long\":[\"Vladivostok Standard Time\",\"Vladivostok Summer Time\"]},\"Europe/Volgograd\":{\"long\":[\"Volgograd Standard Time\",\"Volgograd Summer Time\"]},\"Antarctica/Vostok\":{\"long\":[\"Vostok Time\",\"Vostok Time\"]},\"Pacific/Wake\":{\"long\":[\"Wake Island Time\",\"Wake Island Time\"]},\"Pacific/Wallis\":{\"long\":[\"Wallis & Futuna Time\",\"Wallis & Futuna Time\"]},\"Asia/Yakutsk\":{\"long\":[\"Yakutsk Standard Time\",\"Yakutsk Summer Time\"]},\"UTC\":{\"long\":[\"Coordinated Universal Time\",\"Coordinated Universal Time\"],\"short\":[\"UTC\",\"UTC\"]}},\"gmtFormat\":\"GMT{0}\",\"hourFormat\":\"+HH:mm;-HH:mm\",\"dateFormat\":{\"full\":\"EEEE, MMMM d, y\",\"long\":\"MMMM d, y\",\"medium\":\"MMM d, y\",\"short\":\"M/d/yy\"},\"timeFormat\":{\"full\":\"h:mm:ss a zzzz\",\"long\":\"h:mm:ss a z\",\"medium\":\"h:mm:ss a\",\"short\":\"h:mm a\"},\"dateTimeFormat\":{\"full\":\"{1} 'at' {0}\",\"long\":\"{1} 'at' {0}\",\"medium\":\"{1}, {0}\",\"short\":\"{1}, {0}\"},\"formats\":{\"gregory\":{\"Bh\":\"h B\",\"Bhm\":\"h:mm B\",\"Bhms\":\"h:mm:ss B\",\"d\":\"d\",\"E\":\"ccc\",\"EBhm\":\"E h:mm B\",\"EBhms\":\"E h:mm:ss B\",\"Ed\":\"d E\",\"Ehm\":\"E h:mm a\",\"EHm\":\"E HH:mm\",\"Ehms\":\"E h:mm:ss a\",\"EHms\":\"E HH:mm:ss\",\"Gy\":\"y G\",\"GyMMM\":\"MMM y G\",\"GyMMMd\":\"MMM d, y G\",\"GyMMMEd\":\"E, MMM d, y G\",\"h\":\"h a\",\"H\":\"HH\",\"hm\":\"h:mm a\",\"Hm\":\"HH:mm\",\"hms\":\"h:mm:ss a\",\"Hms\":\"HH:mm:ss\",\"hmsv\":\"h:mm:ss a v\",\"Hmsv\":\"HH:mm:ss v\",\"hmv\":\"h:mm a v\",\"Hmv\":\"HH:mm v\",\"M\":\"L\",\"Md\":\"M/d\",\"MEd\":\"E, M/d\",\"MMM\":\"LLL\",\"MMMd\":\"MMM d\",\"MMMEd\":\"E, MMM d\",\"MMMMd\":\"MMMM d\",\"ms\":\"mm:ss\",\"y\":\"y\",\"yM\":\"M/y\",\"yMd\":\"M/d/y\",\"yMEd\":\"E, M/d/y\",\"yMMM\":\"MMM y\",\"yMMMd\":\"MMM d, y\",\"yMMMEd\":\"E, MMM d, y\",\"yMMMM\":\"MMMM y\",\"EEEE, MMMM d, y\":\"EEEE, MMMM d, y\",\"MMMM d, y\":\"MMMM d, y\",\"MMM d, y\":\"MMM d, y\",\"M/d/yy\":\"M/d/yy\",\"h:mm:ss a zzzz\":\"h:mm:ss a zzzz\",\"h:mm:ss a z\":\"h:mm:ss a z\",\"h:mm:ss a\":\"h:mm:ss a\",\"h:mm a\":\"h:mm a\",\"EEEE, MMMM d, y 'at' h:mm:ss a zzzz\":\"EEEE, MMMM d, y 'at' h:mm:ss a zzzz\",\"MMMM d, y 'at' h:mm:ss a zzzz\":\"MMMM d, y 'at' h:mm:ss a zzzz\",\"MMM d, y, h:mm:ss a zzzz\":\"MMM d, y, h:mm:ss a zzzz\",\"M/d/yy, h:mm:ss a zzzz\":\"M/d/yy, h:mm:ss a zzzz\",\"d, h:mm:ss a zzzz\":\"d, h:mm:ss a zzzz\",\"E, h:mm:ss a zzzz\":\"ccc, h:mm:ss a zzzz\",\"Ed, h:mm:ss a zzzz\":\"d E, h:mm:ss a zzzz\",\"Gy, h:mm:ss a zzzz\":\"y G, h:mm:ss a zzzz\",\"GyMMM, h:mm:ss a zzzz\":\"MMM y G, h:mm:ss a zzzz\",\"GyMMMd, h:mm:ss a zzzz\":\"MMM d, y G, h:mm:ss a zzzz\",\"GyMMMEd, h:mm:ss a zzzz\":\"E, MMM d, y G, h:mm:ss a zzzz\",\"M, h:mm:ss a zzzz\":\"L, h:mm:ss a zzzz\",\"Md, h:mm:ss a zzzz\":\"M/d, h:mm:ss a zzzz\",\"MEd, h:mm:ss a zzzz\":\"E, M/d, h:mm:ss a zzzz\",\"MMM, h:mm:ss a zzzz\":\"LLL, h:mm:ss a zzzz\",\"MMMd, h:mm:ss a zzzz\":\"MMM d, h:mm:ss a zzzz\",\"MMMEd, h:mm:ss a zzzz\":\"E, MMM d, h:mm:ss a zzzz\",\"MMMMd 'at' h:mm:ss a zzzz\":\"MMMM d 'at' h:mm:ss a zzzz\",\"y, h:mm:ss a zzzz\":\"y, h:mm:ss a zzzz\",\"yM, h:mm:ss a zzzz\":\"M/y, h:mm:ss a zzzz\",\"yMd, h:mm:ss a zzzz\":\"M/d/y, h:mm:ss a zzzz\",\"yMEd, h:mm:ss a zzzz\":\"E, M/d/y, h:mm:ss a zzzz\",\"yMMM, h:mm:ss a zzzz\":\"MMM y, h:mm:ss a zzzz\",\"yMMMd, h:mm:ss a zzzz\":\"MMM d, y, h:mm:ss a zzzz\",\"yMMMEd, h:mm:ss a zzzz\":\"E, MMM d, y, h:mm:ss a zzzz\",\"yMMMM 'at' h:mm:ss a zzzz\":\"MMMM y 'at' h:mm:ss a zzzz\",\"EEEE, MMMM d, y 'at' h:mm:ss a z\":\"EEEE, MMMM d, y 'at' h:mm:ss a z\",\"MMMM d, y 'at' h:mm:ss a z\":\"MMMM d, y 'at' h:mm:ss a z\",\"MMM d, y, h:mm:ss a z\":\"MMM d, y, h:mm:ss a z\",\"M/d/yy, h:mm:ss a z\":\"M/d/yy, h:mm:ss a z\",\"d, h:mm:ss a z\":\"d, h:mm:ss a z\",\"E, h:mm:ss a z\":\"ccc, h:mm:ss a z\",\"Ed, h:mm:ss a z\":\"d E, h:mm:ss a z\",\"Gy, h:mm:ss a z\":\"y G, h:mm:ss a z\",\"GyMMM, h:mm:ss a z\":\"MMM y G, h:mm:ss a z\",\"GyMMMd, h:mm:ss a z\":\"MMM d, y G, h:mm:ss a z\",\"GyMMMEd, h:mm:ss a z\":\"E, MMM d, y G, h:mm:ss a z\",\"M, h:mm:ss a z\":\"L, h:mm:ss a z\",\"Md, h:mm:ss a z\":\"M/d, h:mm:ss a z\",\"MEd, h:mm:ss a z\":\"E, M/d, h:mm:ss a z\",\"MMM, h:mm:ss a z\":\"LLL, h:mm:ss a z\",\"MMMd, h:mm:ss a z\":\"MMM d, h:mm:ss a z\",\"MMMEd, h:mm:ss a z\":\"E, MMM d, h:mm:ss a z\",\"MMMMd 'at' h:mm:ss a z\":\"MMMM d 'at' h:mm:ss a z\",\"y, h:mm:ss a z\":\"y, h:mm:ss a z\",\"yM, h:mm:ss a z\":\"M/y, h:mm:ss a z\",\"yMd, h:mm:ss a z\":\"M/d/y, h:mm:ss a z\",\"yMEd, h:mm:ss a z\":\"E, M/d/y, h:mm:ss a z\",\"yMMM, h:mm:ss a z\":\"MMM y, h:mm:ss a z\",\"yMMMd, h:mm:ss a z\":\"MMM d, y, h:mm:ss a z\",\"yMMMEd, h:mm:ss a z\":\"E, MMM d, y, h:mm:ss a z\",\"yMMMM 'at' h:mm:ss a z\":\"MMMM y 'at' h:mm:ss a z\",\"EEEE, MMMM d, y 'at' h:mm:ss a\":\"EEEE, MMMM d, y 'at' h:mm:ss a\",\"MMMM d, y 'at' h:mm:ss a\":\"MMMM d, y 'at' h:mm:ss a\",\"MMM d, y, h:mm:ss a\":\"MMM d, y, h:mm:ss a\",\"M/d/yy, h:mm:ss a\":\"M/d/yy, h:mm:ss a\",\"d, h:mm:ss a\":\"d, h:mm:ss a\",\"E, h:mm:ss a\":\"ccc, h:mm:ss a\",\"Ed, h:mm:ss a\":\"d E, h:mm:ss a\",\"Gy, h:mm:ss a\":\"y G, h:mm:ss a\",\"GyMMM, h:mm:ss a\":\"MMM y G, h:mm:ss a\",\"GyMMMd, h:mm:ss a\":\"MMM d, y G, h:mm:ss a\",\"GyMMMEd, h:mm:ss a\":\"E, MMM d, y G, h:mm:ss a\",\"M, h:mm:ss a\":\"L, h:mm:ss a\",\"Md, h:mm:ss a\":\"M/d, h:mm:ss a\",\"MEd, h:mm:ss a\":\"E, M/d, h:mm:ss a\",\"MMM, h:mm:ss a\":\"LLL, h:mm:ss a\",\"MMMd, h:mm:ss a\":\"MMM d, h:mm:ss a\",\"MMMEd, h:mm:ss a\":\"E, MMM d, h:mm:ss a\",\"MMMMd 'at' h:mm:ss a\":\"MMMM d 'at' h:mm:ss a\",\"y, h:mm:ss a\":\"y, h:mm:ss a\",\"yM, h:mm:ss a\":\"M/y, h:mm:ss a\",\"yMd, h:mm:ss a\":\"M/d/y, h:mm:ss a\",\"yMEd, h:mm:ss a\":\"E, M/d/y, h:mm:ss a\",\"yMMM, h:mm:ss a\":\"MMM y, h:mm:ss a\",\"yMMMd, h:mm:ss a\":\"MMM d, y, h:mm:ss a\",\"yMMMEd, h:mm:ss a\":\"E, MMM d, y, h:mm:ss a\",\"yMMMM 'at' h:mm:ss a\":\"MMMM y 'at' h:mm:ss a\",\"EEEE, MMMM d, y 'at' h:mm a\":\"EEEE, MMMM d, y 'at' h:mm a\",\"MMMM d, y 'at' h:mm a\":\"MMMM d, y 'at' h:mm a\",\"MMM d, y, h:mm a\":\"MMM d, y, h:mm a\",\"M/d/yy, h:mm a\":\"M/d/yy, h:mm a\",\"d, h:mm a\":\"d, h:mm a\",\"E, h:mm a\":\"ccc, h:mm a\",\"Ed, h:mm a\":\"d E, h:mm a\",\"Gy, h:mm a\":\"y G, h:mm a\",\"GyMMM, h:mm a\":\"MMM y G, h:mm a\",\"GyMMMd, h:mm a\":\"MMM d, y G, h:mm a\",\"GyMMMEd, h:mm a\":\"E, MMM d, y G, h:mm a\",\"M, h:mm a\":\"L, h:mm a\",\"Md, h:mm a\":\"M/d, h:mm a\",\"MEd, h:mm a\":\"E, M/d, h:mm a\",\"MMM, h:mm a\":\"LLL, h:mm a\",\"MMMd, h:mm a\":\"MMM d, h:mm a\",\"MMMEd, h:mm a\":\"E, MMM d, h:mm a\",\"MMMMd 'at' h:mm a\":\"MMMM d 'at' h:mm a\",\"y, h:mm a\":\"y, h:mm a\",\"yM, h:mm a\":\"M/y, h:mm a\",\"yMd, h:mm a\":\"M/d/y, h:mm a\",\"yMEd, h:mm a\":\"E, M/d/y, h:mm a\",\"yMMM, h:mm a\":\"MMM y, h:mm a\",\"yMMMd, h:mm a\":\"MMM d, y, h:mm a\",\"yMMMEd, h:mm a\":\"E, MMM d, y, h:mm a\",\"yMMMM 'at' h:mm a\":\"MMMM y 'at' h:mm a\",\"EEEE, MMMM d, y 'at' Bh\":\"EEEE, MMMM d, y 'at' h B\",\"MMMM d, y 'at' Bh\":\"MMMM d, y 'at' h B\",\"MMM d, y, Bh\":\"MMM d, y, h B\",\"M/d/yy, Bh\":\"M/d/yy, h B\",\"d, Bh\":\"d, h B\",\"E, Bh\":\"ccc, h B\",\"Ed, Bh\":\"d E, h B\",\"Gy, Bh\":\"y G, h B\",\"GyMMM, Bh\":\"MMM y G, h B\",\"GyMMMd, Bh\":\"MMM d, y G, h B\",\"GyMMMEd, Bh\":\"E, MMM d, y G, h B\",\"M, Bh\":\"L, h B\",\"Md, Bh\":\"M/d, h B\",\"MEd, Bh\":\"E, M/d, h B\",\"MMM, Bh\":\"LLL, h B\",\"MMMd, Bh\":\"MMM d, h B\",\"MMMEd, Bh\":\"E, MMM d, h B\",\"MMMMd 'at' Bh\":\"MMMM d 'at' h B\",\"y, Bh\":\"y, h B\",\"yM, Bh\":\"M/y, h B\",\"yMd, Bh\":\"M/d/y, h B\",\"yMEd, Bh\":\"E, M/d/y, h B\",\"yMMM, Bh\":\"MMM y, h B\",\"yMMMd, Bh\":\"MMM d, y, h B\",\"yMMMEd, Bh\":\"E, MMM d, y, h B\",\"yMMMM 'at' Bh\":\"MMMM y 'at' h B\",\"EEEE, MMMM d, y 'at' Bhm\":\"EEEE, MMMM d, y 'at' h:mm B\",\"MMMM d, y 'at' Bhm\":\"MMMM d, y 'at' h:mm B\",\"MMM d, y, Bhm\":\"MMM d, y, h:mm B\",\"M/d/yy, Bhm\":\"M/d/yy, h:mm B\",\"d, Bhm\":\"d, h:mm B\",\"E, Bhm\":\"ccc, h:mm B\",\"Ed, Bhm\":\"d E, h:mm B\",\"Gy, Bhm\":\"y G, h:mm B\",\"GyMMM, Bhm\":\"MMM y G, h:mm B\",\"GyMMMd, Bhm\":\"MMM d, y G, h:mm B\",\"GyMMMEd, Bhm\":\"E, MMM d, y G, h:mm B\",\"M, Bhm\":\"L, h:mm B\",\"Md, Bhm\":\"M/d, h:mm B\",\"MEd, Bhm\":\"E, M/d, h:mm B\",\"MMM, Bhm\":\"LLL, h:mm B\",\"MMMd, Bhm\":\"MMM d, h:mm B\",\"MMMEd, Bhm\":\"E, MMM d, h:mm B\",\"MMMMd 'at' Bhm\":\"MMMM d 'at' h:mm B\",\"y, Bhm\":\"y, h:mm B\",\"yM, Bhm\":\"M/y, h:mm B\",\"yMd, Bhm\":\"M/d/y, h:mm B\",\"yMEd, Bhm\":\"E, M/d/y, h:mm B\",\"yMMM, Bhm\":\"MMM y, h:mm B\",\"yMMMd, Bhm\":\"MMM d, y, h:mm B\",\"yMMMEd, Bhm\":\"E, MMM d, y, h:mm B\",\"yMMMM 'at' Bhm\":\"MMMM y 'at' h:mm B\",\"EEEE, MMMM d, y 'at' Bhms\":\"EEEE, MMMM d, y 'at' h:mm:ss B\",\"MMMM d, y 'at' Bhms\":\"MMMM d, y 'at' h:mm:ss B\",\"MMM d, y, Bhms\":\"MMM d, y, h:mm:ss B\",\"M/d/yy, Bhms\":\"M/d/yy, h:mm:ss B\",\"d, Bhms\":\"d, h:mm:ss B\",\"E, Bhms\":\"ccc, h:mm:ss B\",\"Ed, Bhms\":\"d E, h:mm:ss B\",\"Gy, Bhms\":\"y G, h:mm:ss B\",\"GyMMM, Bhms\":\"MMM y G, h:mm:ss B\",\"GyMMMd, Bhms\":\"MMM d, y G, h:mm:ss B\",\"GyMMMEd, Bhms\":\"E, MMM d, y G, h:mm:ss B\",\"M, Bhms\":\"L, h:mm:ss B\",\"Md, Bhms\":\"M/d, h:mm:ss B\",\"MEd, Bhms\":\"E, M/d, h:mm:ss B\",\"MMM, Bhms\":\"LLL, h:mm:ss B\",\"MMMd, Bhms\":\"MMM d, h:mm:ss B\",\"MMMEd, Bhms\":\"E, MMM d, h:mm:ss B\",\"MMMMd 'at' Bhms\":\"MMMM d 'at' h:mm:ss B\",\"y, Bhms\":\"y, h:mm:ss B\",\"yM, Bhms\":\"M/y, h:mm:ss B\",\"yMd, Bhms\":\"M/d/y, h:mm:ss B\",\"yMEd, Bhms\":\"E, M/d/y, h:mm:ss B\",\"yMMM, Bhms\":\"MMM y, h:mm:ss B\",\"yMMMd, Bhms\":\"MMM d, y, h:mm:ss B\",\"yMMMEd, Bhms\":\"E, MMM d, y, h:mm:ss B\",\"yMMMM 'at' Bhms\":\"MMMM y 'at' h:mm:ss B\",\"EEEE, MMMM d, y 'at' h\":\"EEEE, MMMM d, y 'at' h a\",\"MMMM d, y 'at' h\":\"MMMM d, y 'at' h a\",\"MMM d, y, h\":\"MMM d, y, h a\",\"M/d/yy, h\":\"M/d/yy, h a\",\"d, h\":\"d, h a\",\"E, h\":\"ccc, h a\",\"Ed, h\":\"d E, h a\",\"Gy, h\":\"y G, h a\",\"GyMMM, h\":\"MMM y G, h a\",\"GyMMMd, h\":\"MMM d, y G, h a\",\"GyMMMEd, h\":\"E, MMM d, y G, h a\",\"M, h\":\"L, h a\",\"Md, h\":\"M/d, h a\",\"MEd, h\":\"E, M/d, h a\",\"MMM, h\":\"LLL, h a\",\"MMMd, h\":\"MMM d, h a\",\"MMMEd, h\":\"E, MMM d, h a\",\"MMMMd 'at' h\":\"MMMM d 'at' h a\",\"y, h\":\"y, h a\",\"yM, h\":\"M/y, h a\",\"yMd, h\":\"M/d/y, h a\",\"yMEd, h\":\"E, M/d/y, h a\",\"yMMM, h\":\"MMM y, h a\",\"yMMMd, h\":\"MMM d, y, h a\",\"yMMMEd, h\":\"E, MMM d, y, h a\",\"yMMMM 'at' h\":\"MMMM y 'at' h a\",\"EEEE, MMMM d, y 'at' H\":\"EEEE, MMMM d, y 'at' HH\",\"MMMM d, y 'at' H\":\"MMMM d, y 'at' HH\",\"MMM d, y, H\":\"MMM d, y, HH\",\"M/d/yy, H\":\"M/d/yy, HH\",\"d, H\":\"d, HH\",\"E, H\":\"ccc, HH\",\"Ed, H\":\"d E, HH\",\"Gy, H\":\"y G, HH\",\"GyMMM, H\":\"MMM y G, HH\",\"GyMMMd, H\":\"MMM d, y G, HH\",\"GyMMMEd, H\":\"E, MMM d, y G, HH\",\"M, H\":\"L, HH\",\"Md, H\":\"M/d, HH\",\"MEd, H\":\"E, M/d, HH\",\"MMM, H\":\"LLL, HH\",\"MMMd, H\":\"MMM d, HH\",\"MMMEd, H\":\"E, MMM d, HH\",\"MMMMd 'at' H\":\"MMMM d 'at' HH\",\"y, H\":\"y, HH\",\"yM, H\":\"M/y, HH\",\"yMd, H\":\"M/d/y, HH\",\"yMEd, H\":\"E, M/d/y, HH\",\"yMMM, H\":\"MMM y, HH\",\"yMMMd, H\":\"MMM d, y, HH\",\"yMMMEd, H\":\"E, MMM d, y, HH\",\"yMMMM 'at' H\":\"MMMM y 'at' HH\",\"EEEE, MMMM d, y 'at' hm\":\"EEEE, MMMM d, y 'at' h:mm a\",\"MMMM d, y 'at' hm\":\"MMMM d, y 'at' h:mm a\",\"MMM d, y, hm\":\"MMM d, y, h:mm a\",\"M/d/yy, hm\":\"M/d/yy, h:mm a\",\"d, hm\":\"d, h:mm a\",\"E, hm\":\"ccc, h:mm a\",\"Ed, hm\":\"d E, h:mm a\",\"Gy, hm\":\"y G, h:mm a\",\"GyMMM, hm\":\"MMM y G, h:mm a\",\"GyMMMd, hm\":\"MMM d, y G, h:mm a\",\"GyMMMEd, hm\":\"E, MMM d, y G, h:mm a\",\"M, hm\":\"L, h:mm a\",\"Md, hm\":\"M/d, h:mm a\",\"MEd, hm\":\"E, M/d, h:mm a\",\"MMM, hm\":\"LLL, h:mm a\",\"MMMd, hm\":\"MMM d, h:mm a\",\"MMMEd, hm\":\"E, MMM d, h:mm a\",\"MMMMd 'at' hm\":\"MMMM d 'at' h:mm a\",\"y, hm\":\"y, h:mm a\",\"yM, hm\":\"M/y, h:mm a\",\"yMd, hm\":\"M/d/y, h:mm a\",\"yMEd, hm\":\"E, M/d/y, h:mm a\",\"yMMM, hm\":\"MMM y, h:mm a\",\"yMMMd, hm\":\"MMM d, y, h:mm a\",\"yMMMEd, hm\":\"E, MMM d, y, h:mm a\",\"yMMMM 'at' hm\":\"MMMM y 'at' h:mm a\",\"EEEE, MMMM d, y 'at' Hm\":\"EEEE, MMMM d, y 'at' HH:mm\",\"MMMM d, y 'at' Hm\":\"MMMM d, y 'at' HH:mm\",\"MMM d, y, Hm\":\"MMM d, y, HH:mm\",\"M/d/yy, Hm\":\"M/d/yy, HH:mm\",\"d, Hm\":\"d, HH:mm\",\"E, Hm\":\"ccc, HH:mm\",\"Ed, Hm\":\"d E, HH:mm\",\"Gy, Hm\":\"y G, HH:mm\",\"GyMMM, Hm\":\"MMM y G, HH:mm\",\"GyMMMd, Hm\":\"MMM d, y G, HH:mm\",\"GyMMMEd, Hm\":\"E, MMM d, y G, HH:mm\",\"M, Hm\":\"L, HH:mm\",\"Md, Hm\":\"M/d, HH:mm\",\"MEd, Hm\":\"E, M/d, HH:mm\",\"MMM, Hm\":\"LLL, HH:mm\",\"MMMd, Hm\":\"MMM d, HH:mm\",\"MMMEd, Hm\":\"E, MMM d, HH:mm\",\"MMMMd 'at' Hm\":\"MMMM d 'at' HH:mm\",\"y, Hm\":\"y, HH:mm\",\"yM, Hm\":\"M/y, HH:mm\",\"yMd, Hm\":\"M/d/y, HH:mm\",\"yMEd, Hm\":\"E, M/d/y, HH:mm\",\"yMMM, Hm\":\"MMM y, HH:mm\",\"yMMMd, Hm\":\"MMM d, y, HH:mm\",\"yMMMEd, Hm\":\"E, MMM d, y, HH:mm\",\"yMMMM 'at' Hm\":\"MMMM y 'at' HH:mm\",\"EEEE, MMMM d, y 'at' hms\":\"EEEE, MMMM d, y 'at' h:mm:ss a\",\"MMMM d, y 'at' hms\":\"MMMM d, y 'at' h:mm:ss a\",\"MMM d, y, hms\":\"MMM d, y, h:mm:ss a\",\"M/d/yy, hms\":\"M/d/yy, h:mm:ss a\",\"d, hms\":\"d, h:mm:ss a\",\"E, hms\":\"ccc, h:mm:ss a\",\"Ed, hms\":\"d E, h:mm:ss a\",\"Gy, hms\":\"y G, h:mm:ss a\",\"GyMMM, hms\":\"MMM y G, h:mm:ss a\",\"GyMMMd, hms\":\"MMM d, y G, h:mm:ss a\",\"GyMMMEd, hms\":\"E, MMM d, y G, h:mm:ss a\",\"M, hms\":\"L, h:mm:ss a\",\"Md, hms\":\"M/d, h:mm:ss a\",\"MEd, hms\":\"E, M/d, h:mm:ss a\",\"MMM, hms\":\"LLL, h:mm:ss a\",\"MMMd, hms\":\"MMM d, h:mm:ss a\",\"MMMEd, hms\":\"E, MMM d, h:mm:ss a\",\"MMMMd 'at' hms\":\"MMMM d 'at' h:mm:ss a\",\"y, hms\":\"y, h:mm:ss a\",\"yM, hms\":\"M/y, h:mm:ss a\",\"yMd, hms\":\"M/d/y, h:mm:ss a\",\"yMEd, hms\":\"E, M/d/y, h:mm:ss a\",\"yMMM, hms\":\"MMM y, h:mm:ss a\",\"yMMMd, hms\":\"MMM d, y, h:mm:ss a\",\"yMMMEd, hms\":\"E, MMM d, y, h:mm:ss a\",\"yMMMM 'at' hms\":\"MMMM y 'at' h:mm:ss a\",\"EEEE, MMMM d, y 'at' Hms\":\"EEEE, MMMM d, y 'at' HH:mm:ss\",\"MMMM d, y 'at' Hms\":\"MMMM d, y 'at' HH:mm:ss\",\"MMM d, y, Hms\":\"MMM d, y, HH:mm:ss\",\"M/d/yy, Hms\":\"M/d/yy, HH:mm:ss\",\"d, Hms\":\"d, HH:mm:ss\",\"E, Hms\":\"ccc, HH:mm:ss\",\"Ed, Hms\":\"d E, HH:mm:ss\",\"Gy, Hms\":\"y G, HH:mm:ss\",\"GyMMM, Hms\":\"MMM y G, HH:mm:ss\",\"GyMMMd, Hms\":\"MMM d, y G, HH:mm:ss\",\"GyMMMEd, Hms\":\"E, MMM d, y G, HH:mm:ss\",\"M, Hms\":\"L, HH:mm:ss\",\"Md, Hms\":\"M/d, HH:mm:ss\",\"MEd, Hms\":\"E, M/d, HH:mm:ss\",\"MMM, Hms\":\"LLL, HH:mm:ss\",\"MMMd, Hms\":\"MMM d, HH:mm:ss\",\"MMMEd, Hms\":\"E, MMM d, HH:mm:ss\",\"MMMMd 'at' Hms\":\"MMMM d 'at' HH:mm:ss\",\"y, Hms\":\"y, HH:mm:ss\",\"yM, Hms\":\"M/y, HH:mm:ss\",\"yMd, Hms\":\"M/d/y, HH:mm:ss\",\"yMEd, Hms\":\"E, M/d/y, HH:mm:ss\",\"yMMM, Hms\":\"MMM y, HH:mm:ss\",\"yMMMd, Hms\":\"MMM d, y, HH:mm:ss\",\"yMMMEd, Hms\":\"E, MMM d, y, HH:mm:ss\",\"yMMMM 'at' Hms\":\"MMMM y 'at' HH:mm:ss\",\"EEEE, MMMM d, y 'at' hmsv\":\"EEEE, MMMM d, y 'at' h:mm:ss a v\",\"MMMM d, y 'at' hmsv\":\"MMMM d, y 'at' h:mm:ss a v\",\"MMM d, y, hmsv\":\"MMM d, y, h:mm:ss a v\",\"M/d/yy, hmsv\":\"M/d/yy, h:mm:ss a v\",\"d, hmsv\":\"d, h:mm:ss a v\",\"E, hmsv\":\"ccc, h:mm:ss a v\",\"Ed, hmsv\":\"d E, h:mm:ss a v\",\"Gy, hmsv\":\"y G, h:mm:ss a v\",\"GyMMM, hmsv\":\"MMM y G, h:mm:ss a v\",\"GyMMMd, hmsv\":\"MMM d, y G, h:mm:ss a v\",\"GyMMMEd, hmsv\":\"E, MMM d, y G, h:mm:ss a v\",\"M, hmsv\":\"L, h:mm:ss a v\",\"Md, hmsv\":\"M/d, h:mm:ss a v\",\"MEd, hmsv\":\"E, M/d, h:mm:ss a v\",\"MMM, hmsv\":\"LLL, h:mm:ss a v\",\"MMMd, hmsv\":\"MMM d, h:mm:ss a v\",\"MMMEd, hmsv\":\"E, MMM d, h:mm:ss a v\",\"MMMMd 'at' hmsv\":\"MMMM d 'at' h:mm:ss a v\",\"y, hmsv\":\"y, h:mm:ss a v\",\"yM, hmsv\":\"M/y, h:mm:ss a v\",\"yMd, hmsv\":\"M/d/y, h:mm:ss a v\",\"yMEd, hmsv\":\"E, M/d/y, h:mm:ss a v\",\"yMMM, hmsv\":\"MMM y, h:mm:ss a v\",\"yMMMd, hmsv\":\"MMM d, y, h:mm:ss a v\",\"yMMMEd, hmsv\":\"E, MMM d, y, h:mm:ss a v\",\"yMMMM 'at' hmsv\":\"MMMM y 'at' h:mm:ss a v\",\"EEEE, MMMM d, y 'at' Hmsv\":\"EEEE, MMMM d, y 'at' HH:mm:ss v\",\"MMMM d, y 'at' Hmsv\":\"MMMM d, y 'at' HH:mm:ss v\",\"MMM d, y, Hmsv\":\"MMM d, y, HH:mm:ss v\",\"M/d/yy, Hmsv\":\"M/d/yy, HH:mm:ss v\",\"d, Hmsv\":\"d, HH:mm:ss v\",\"E, Hmsv\":\"ccc, HH:mm:ss v\",\"Ed, Hmsv\":\"d E, HH:mm:ss v\",\"Gy, Hmsv\":\"y G, HH:mm:ss v\",\"GyMMM, Hmsv\":\"MMM y G, HH:mm:ss v\",\"GyMMMd, Hmsv\":\"MMM d, y G, HH:mm:ss v\",\"GyMMMEd, Hmsv\":\"E, MMM d, y G, HH:mm:ss v\",\"M, Hmsv\":\"L, HH:mm:ss v\",\"Md, Hmsv\":\"M/d, HH:mm:ss v\",\"MEd, Hmsv\":\"E, M/d, HH:mm:ss v\",\"MMM, Hmsv\":\"LLL, HH:mm:ss v\",\"MMMd, Hmsv\":\"MMM d, HH:mm:ss v\",\"MMMEd, Hmsv\":\"E, MMM d, HH:mm:ss v\",\"MMMMd 'at' Hmsv\":\"MMMM d 'at' HH:mm:ss v\",\"y, Hmsv\":\"y, HH:mm:ss v\",\"yM, Hmsv\":\"M/y, HH:mm:ss v\",\"yMd, Hmsv\":\"M/d/y, HH:mm:ss v\",\"yMEd, Hmsv\":\"E, M/d/y, HH:mm:ss v\",\"yMMM, Hmsv\":\"MMM y, HH:mm:ss v\",\"yMMMd, Hmsv\":\"MMM d, y, HH:mm:ss v\",\"yMMMEd, Hmsv\":\"E, MMM d, y, HH:mm:ss v\",\"yMMMM 'at' Hmsv\":\"MMMM y 'at' HH:mm:ss v\",\"EEEE, MMMM d, y 'at' hmv\":\"EEEE, MMMM d, y 'at' h:mm a v\",\"MMMM d, y 'at' hmv\":\"MMMM d, y 'at' h:mm a v\",\"MMM d, y, hmv\":\"MMM d, y, h:mm a v\",\"M/d/yy, hmv\":\"M/d/yy, h:mm a v\",\"d, hmv\":\"d, h:mm a v\",\"E, hmv\":\"ccc, h:mm a v\",\"Ed, hmv\":\"d E, h:mm a v\",\"Gy, hmv\":\"y G, h:mm a v\",\"GyMMM, hmv\":\"MMM y G, h:mm a v\",\"GyMMMd, hmv\":\"MMM d, y G, h:mm a v\",\"GyMMMEd, hmv\":\"E, MMM d, y G, h:mm a v\",\"M, hmv\":\"L, h:mm a v\",\"Md, hmv\":\"M/d, h:mm a v\",\"MEd, hmv\":\"E, M/d, h:mm a v\",\"MMM, hmv\":\"LLL, h:mm a v\",\"MMMd, hmv\":\"MMM d, h:mm a v\",\"MMMEd, hmv\":\"E, MMM d, h:mm a v\",\"MMMMd 'at' hmv\":\"MMMM d 'at' h:mm a v\",\"y, hmv\":\"y, h:mm a v\",\"yM, hmv\":\"M/y, h:mm a v\",\"yMd, hmv\":\"M/d/y, h:mm a v\",\"yMEd, hmv\":\"E, M/d/y, h:mm a v\",\"yMMM, hmv\":\"MMM y, h:mm a v\",\"yMMMd, hmv\":\"MMM d, y, h:mm a v\",\"yMMMEd, hmv\":\"E, MMM d, y, h:mm a v\",\"yMMMM 'at' hmv\":\"MMMM y 'at' h:mm a v\",\"EEEE, MMMM d, y 'at' Hmv\":\"EEEE, MMMM d, y 'at' HH:mm v\",\"MMMM d, y 'at' Hmv\":\"MMMM d, y 'at' HH:mm v\",\"MMM d, y, Hmv\":\"MMM d, y, HH:mm v\",\"M/d/yy, Hmv\":\"M/d/yy, HH:mm v\",\"d, Hmv\":\"d, HH:mm v\",\"E, Hmv\":\"ccc, HH:mm v\",\"Ed, Hmv\":\"d E, HH:mm v\",\"Gy, Hmv\":\"y G, HH:mm v\",\"GyMMM, Hmv\":\"MMM y G, HH:mm v\",\"GyMMMd, Hmv\":\"MMM d, y G, HH:mm v\",\"GyMMMEd, Hmv\":\"E, MMM d, y G, HH:mm v\",\"M, Hmv\":\"L, HH:mm v\",\"Md, Hmv\":\"M/d, HH:mm v\",\"MEd, Hmv\":\"E, M/d, HH:mm v\",\"MMM, Hmv\":\"LLL, HH:mm v\",\"MMMd, Hmv\":\"MMM d, HH:mm v\",\"MMMEd, Hmv\":\"E, MMM d, HH:mm v\",\"MMMMd 'at' Hmv\":\"MMMM d 'at' HH:mm v\",\"y, Hmv\":\"y, HH:mm v\",\"yM, Hmv\":\"M/y, HH:mm v\",\"yMd, Hmv\":\"M/d/y, HH:mm v\",\"yMEd, Hmv\":\"E, M/d/y, HH:mm v\",\"yMMM, Hmv\":\"MMM y, HH:mm v\",\"yMMMd, Hmv\":\"MMM d, y, HH:mm v\",\"yMMMEd, Hmv\":\"E, MMM d, y, HH:mm v\",\"yMMMM 'at' Hmv\":\"MMMM y 'at' HH:mm v\",\"EEEE, MMMM d, y 'at' ms\":\"EEEE, MMMM d, y 'at' mm:ss\",\"MMMM d, y 'at' ms\":\"MMMM d, y 'at' mm:ss\",\"MMM d, y, ms\":\"MMM d, y, mm:ss\",\"M/d/yy, ms\":\"M/d/yy, mm:ss\",\"d, ms\":\"d, mm:ss\",\"E, ms\":\"ccc, mm:ss\",\"Ed, ms\":\"d E, mm:ss\",\"Gy, ms\":\"y G, mm:ss\",\"GyMMM, ms\":\"MMM y G, mm:ss\",\"GyMMMd, ms\":\"MMM d, y G, mm:ss\",\"GyMMMEd, ms\":\"E, MMM d, y G, mm:ss\",\"M, ms\":\"L, mm:ss\",\"Md, ms\":\"M/d, mm:ss\",\"MEd, ms\":\"E, M/d, mm:ss\",\"MMM, ms\":\"LLL, mm:ss\",\"MMMd, ms\":\"MMM d, mm:ss\",\"MMMEd, ms\":\"E, MMM d, mm:ss\",\"MMMMd 'at' ms\":\"MMMM d 'at' mm:ss\",\"y, ms\":\"y, mm:ss\",\"yM, ms\":\"M/y, mm:ss\",\"yMd, ms\":\"M/d/y, mm:ss\",\"yMEd, ms\":\"E, M/d/y, mm:ss\",\"yMMM, ms\":\"MMM y, mm:ss\",\"yMMMd, ms\":\"MMM d, y, mm:ss\",\"yMMMEd, ms\":\"E, MMM d, y, mm:ss\",\"yMMMM 'at' ms\":\"MMMM y 'at' mm:ss\"}},\"intervalFormats\":{\"intervalFormatFallback\":\"{0} – {1}\",\"Bh\":{\"B\":\"h B – h B\",\"h\":\"h – h B\"},\"Bhm\":{\"B\":\"h:mm B – h:mm B\",\"h\":\"h:mm – h:mm B\",\"m\":\"h:mm – h:mm B\"},\"d\":{\"d\":\"d – d\"},\"Gy\":{\"G\":\"y G – y G\",\"y\":\"y – y G\"},\"GyM\":{\"G\":\"M/y GGGGG – M/y GGGGG\",\"M\":\"M/y – M/y GGGGG\",\"y\":\"M/y – M/y GGGGG\"},\"GyMd\":{\"d\":\"M/d/y – M/d/y GGGGG\",\"G\":\"M/d/y GGGGG – M/d/y GGGGG\",\"M\":\"M/d/y – M/d/y GGGGG\",\"y\":\"M/d/y – M/d/y GGGGG\"},\"GyMEd\":{\"d\":\"E, M/d/y – E, M/d/y GGGGG\",\"G\":\"E, M/d/y GGGGG – E, M/d/y GGGGG\",\"M\":\"E, M/d/y – E, M/d/y GGGGG\",\"y\":\"E, M/d/y – E, M/d/y GGGGG\"},\"GyMMM\":{\"G\":\"MMM y G – MMM y G\",\"M\":\"MMM – MMM y G\",\"y\":\"MMM y – MMM y G\"},\"GyMMMd\":{\"d\":\"MMM d – d, y G\",\"G\":\"MMM d, y G – MMM d, y G\",\"M\":\"MMM d – MMM d, y G\",\"y\":\"MMM d, y – MMM d, y G\"},\"GyMMMEd\":{\"d\":\"E, MMM d – E, MMM d, y G\",\"G\":\"E, MMM d, y G – E, MMM d, y G\",\"M\":\"E, MMM d – E, MMM d, y G\",\"y\":\"E, MMM d, y – E, MMM d, y G\"},\"h\":{\"a\":\"h a – h a\",\"h\":\"h – h a\"},\"H\":{\"H\":\"HH – HH\"},\"hm\":{\"a\":\"h:mm a – h:mm a\",\"h\":\"h:mm – h:mm a\",\"m\":\"h:mm – h:mm a\"},\"Hm\":{\"H\":\"HH:mm – HH:mm\",\"m\":\"HH:mm – HH:mm\"},\"hmv\":{\"a\":\"h:mm a – h:mm a v\",\"h\":\"h:mm – h:mm a v\",\"m\":\"h:mm – h:mm a v\"},\"Hmv\":{\"H\":\"HH:mm – HH:mm v\",\"m\":\"HH:mm – HH:mm v\"},\"hv\":{\"a\":\"h a – h a v\",\"h\":\"h – h a v\"},\"Hv\":{\"H\":\"HH – HH v\"},\"M\":{\"M\":\"M – M\"},\"Md\":{\"d\":\"M/d – M/d\",\"M\":\"M/d – M/d\"},\"MEd\":{\"d\":\"E, M/d – E, M/d\",\"M\":\"E, M/d – E, M/d\"},\"MMM\":{\"M\":\"MMM – MMM\"},\"MMMd\":{\"d\":\"MMM d – d\",\"M\":\"MMM d – MMM d\"},\"MMMEd\":{\"d\":\"E, MMM d – E, MMM d\",\"M\":\"E, MMM d – E, MMM d\"},\"y\":{\"y\":\"y – y\"},\"yM\":{\"M\":\"M/y – M/y\",\"y\":\"M/y – M/y\"},\"yMd\":{\"d\":\"M/d/y – M/d/y\",\"M\":\"M/d/y – M/d/y\",\"y\":\"M/d/y – M/d/y\"},\"yMEd\":{\"d\":\"E, M/d/y – E, M/d/y\",\"M\":\"E, M/d/y – E, M/d/y\",\"y\":\"E, M/d/y – E, M/d/y\"},\"yMMM\":{\"M\":\"MMM – MMM y\",\"y\":\"MMM y – MMM y\"},\"yMMMd\":{\"d\":\"MMM d – d, y\",\"M\":\"MMM d – MMM d, y\",\"y\":\"MMM d, y – MMM d, y\"},\"yMMMEd\":{\"d\":\"E, MMM d – E, MMM d, y\",\"M\":\"E, MMM d – E, MMM d, y\",\"y\":\"E, MMM d, y – E, MMM d, y\"},\"yMMMM\":{\"M\":\"MMMM – MMMM y\",\"y\":\"MMMM y – MMMM y\"}},\"hourCycle\":\"h12\",\"nu\":[\"latn\"],\"ca\":[\"gregory\"],\"hc\":[\"h12\",\"\",\"h23\",\"\"]},\"locale\":\"en\"}\n)\n }","// @generated\n// prettier-ignore\nif ('DateTimeFormat' in Intl && Intl.DateTimeFormat.__addTZData) {\n Intl.DateTimeFormat.__addTZData({\"zones\":[\"Africa/Accra|,0,0,0|-s9p1ak,1,1,0|-q5eqo1,1,1,0|-q5eqo0,2,2,1|-q3g8pd,2,2,1|-q3g8pc,1,1,0|-pqwd41,1,1,0|-pqwd40,2,2,1|-pkmgpd,2,2,1|-pkmgpc,1,1,0|-p84fs1,1,1,0|-p84fs0,2,2,1|-p1ujdd,2,2,1|-p1ujdc,1,1,0|-opcig1,1,1,0|-opcig0,2,2,1|-oj2m1d,2,2,1|-oj2m1c,1,1,0|-o6kl41,1,1,0|-o6kl40,2,2,1|-o0aopd,2,2,1|-o0aopc,1,1,0|-nnqt41,1,1,0|-nnqt40,2,2,1|-nhgwpd,2,2,1|-nhgwpc,1,1,0|-n4yvs1,1,1,0|-n4yvs0,2,2,1|-myozdd,2,2,1|-myozdc,1,1,0|-mm6yg1,1,1,0|-mm6yg0,2,2,1|-mfx21d,2,2,1|-mfx21c,1,1,0|-m3f141,1,1,0|-m3f140,2,2,1|-lx54pd,2,2,1|-lx54pc,1,1,0|-lkl941,1,1,0|-lkl940,2,2,1|-lebcpd,2,2,1|-lebcpc,1,1,0|-l1tbs1,1,1,0|-l1tbs0,2,2,1|-kvjfdd,2,2,1|-kvjfdc,1,1,0|-kj1eg1,1,1,0|-kj1eg0,2,2,1|-kcri1d,2,2,1|-kcri1c,1,1,0|-k09h41,1,1,0|-k09h40,2,2,1|-jtzkpd,2,2,1|-jtzkpc,1,1,0|-jhfp41,1,1,0|-jhfp40,2,2,1|-jb5spd,2,2,1|-jb5spc,1,1,0|-iynrs1,1,1,0|-iynrs0,2,2,1|-isdvdd,2,2,1|-isdvdc,1,1,0|-ifvug1,1,1,0|-ifvug0,2,2,1|-i9ly1d,2,2,1|-i9ly1c,1,1,0|-hx3x41,1,1,0|-hx3x40,2,2,1|-hqu0pd,2,2,1|-hqu0pc,1,1,0|-hea541,1,1,0|-hea540,2,2,1|-h808pd,2,2,1|-h808pc,1,1,0|-gvi7s1,1,1,0|-gvi7s0,2,2,1|-gp8bdd,2,2,1|-gp8bdc,1,1,0|-gcqag1,1,1,0|-gcqag0,2,2,1|-g6ge1d,2,2,1|-g6ge1c,1,1,0|-ftyd41,1,1,0|-ftyd40,2,2,1|-fnogpd,2,2,1|-fnogpc,1,1,0|-fhgd41,1,1,0|-fhgd40,2,2,1|-f4uopd,2,2,1|-f4uopc,1,1,0|-eyofs1,1,1,0|-eyofs0,2,2,1|-em2rdd,2,2,1|-em2rdc,1,1,0|-ek4io1,1,1,0|-ek4io0,3,3,0|-cio421,3,3,0|-cio420,1,1,0|-a39mg1,1,1,0|-a39mg0,3,3,1|-9wzqi1,3,3,1|-9wzqi0,1,1,0|-9khp41,1,1,0|-9khp40,3,3,1|-9e7t61,3,3,1|-9e7t60,1,1,0|-91nx41,1,1,0|-91nx40,3,3,1|-8ve161,3,3,1|-8ve160,1,1,0|-8ivzs1,1,1,0|-8ivzs0,3,3,1|-8cm3u1,3,3,1|-8cm3u0,1,1,0|-8042g1,1,1,0|-8042g0,3,3,1|-7tu6i1,3,3,1|-7tu6i0,1,1,0|-7hc541,1,1,0|-7hc540,3,3,1|-7b2961,3,3,1|-7b2960,1,1,0\",\"Africa/Addis_Ababa|,0,4,0|-w6p5hg,4,5,0|-lnsey1,4,5,0|-lnsey0,5,6,0|-kvcdo1,5,6,0|-kvcdo0,4,5,0|-h80ka1,4,5,0|-h80ka0,6,7,0|-eb6ib1,6,7,0|-eb6ib0,5,6,0\",\"Africa/Algiers|,0,8,0|-154gb8c,7,9,0|-uozn3m,7,9,0|-uozn3l,8,1,0|-ry2lg1,8,1,0|-ry2lg0,9,10,1|-rsgqs1,9,10,1|-rsgqs0,8,1,0|-rjiis1,8,1,0|-rjiis0,9,10,1|-r9dpg1,9,10,1|-r9dpg0,8,1,0|-r1idg1,8,1,0|-r1idg0,9,10,1|-qqnms1,9,10,1|-qqnms0,8,1,0|-qj59g1,8,1,0|-qj59g0,9,10,1|-q7xk41,9,10,1|-q7xk40,8,1,0|-q15441,8,1,0|-q15440,9,10,1|-po6g41,9,10,1|-po6g40,8,1,0|-pgvhg1,8,1,0|-pgvhg0,9,10,1|-pbs5g1,9,10,1|-pbs5g0,8,1,0|-fte841,8,1,0|-fte840,9,10,1|-fpw801,9,10,1|-fpw800,8,1,0|-fkul41,8,1,0|-fkul40,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d62o01,11,11,1|-d62o00,10,10,0|-cx0nw1,10,10,0|-cx0nw0,11,11,1|-cofk41,11,11,1|-cofk40,10,10,0|-c4kqs1,10,10,0|-c4kqs0,8,1,0|-79mio1,8,1,0|-79mio0,10,10,0|-3i8is1,10,10,0|-3i8is0,8,1,0|oot7z,8,1,0|oot80,9,10,1|wlzvz,9,10,1|wlzw0,8,1,0|3tynzz,8,1,0|3tyo00,9,10,1|42lp7z,9,10,1|42lp80,10,10,0|4aiynz,10,10,0|4aiyo0,11,11,1|4jw2rz,11,11,1|4jw2s0,10,10,0|54et7z,10,10,0|54et80,8,1,0|5drxbz,8,1,0|5drxc0,9,10,1|5ni03z,9,10,1|5ni040,8,1,0|5wuynz,8,1,0|5wuyo0,10,10,0\",\"Africa/Asmara|,0,4,0|-w6p5hg,4,5,0|-lnsey1,4,5,0|-lnsey0,5,6,0|-kvcdo1,5,6,0|-kvcdo0,4,5,0|-h80ka1,4,5,0|-h80ka0,6,7,0|-eb6ib1,6,7,0|-eb6ib0,5,6,0\",\"Africa/Bamako|,0,12,0|-u9rgl4,1,1,0\",\"Africa/Bangui|,0,13,0|-xnxnan,1,1,0|-w3k001,1,1,0|-w3k000,0,13,0|-t85smo,0,13,0|-t85smn,3,3,0|-q9qc21,3,3,0|-q9qc20,12,10,0\",\"Africa/Banjul|,0,12,0|-u9rgl4,1,1,0\",\"Africa/Bissau|,0,14,0|-u9rek0,13,15,0|2lxk3z,13,15,0|2lxk40,1,1,0\",\"Africa/Blantyre|,0,16,0|-yvtfd8,14,11,0\",\"Africa/Brazzaville|,0,13,0|-xnxnan,1,1,0|-w3k001,1,1,0|-w3k000,0,13,0|-t85smo,0,13,0|-t85smn,3,3,0|-q9qc21,3,3,0|-q9qc20,12,10,0\",\"Africa/Bujumbura|,0,16,0|-yvtfd8,14,11,0\",\"Africa/Cairo|,0,17,0|-1054wgl,15,11,0|-fdls81,15,11,0|-fdls80,16,6,1|-f9lf01,16,6,1|-f9lf00,15,11,0|-ezidk1,15,11,0|-ezidk0,16,6,1|-erl9o1,16,6,1|-erl9o0,15,11,0|-ehgdk1,15,11,0|-ehgdk0,16,6,1|-e6pf01,16,6,1|-e6pf00,15,11,0|-dyog81,15,11,0|-dyog80,16,6,1|-dno8c1,16,6,1|-dno8c0,15,11,0|-dfuo81,15,11,0|-dfuo80,16,6,1|-d4ugc1,16,6,1|-d4ugc0,15,11,0|-cwayw1,15,11,0|-cwayw0,16,6,1|-cm2j01,16,6,1|-cm2j00,15,11,0|-6lluw1,15,11,0|-6lluw0,16,6,1|-6e79o1,16,6,1|-6e79o0,15,11,0|-63alk1,15,11,0|-63alk0,16,6,1|-5vfcc1,16,6,1|-5vfcc0,15,11,0|-5kilg1,15,11,0|-5kilg0,16,6,1|-5cp1c1,16,6,1|-5cp1c0,15,11,0|-51otg1,15,11,0|-51otg0,16,6,1|-4tv9c1,16,6,1|-4tv9c0,15,11,0|-4iww41,15,11,0|-4iww40,16,6,1|-4b3c01,16,6,1|-4b3c00,15,11,0|-404ys1,15,11,0|-404ys0,16,6,1|-3sbeo1,16,6,1|-3sbeo0,15,11,0|-3hd1g1,15,11,0|-3hd1g0,16,6,1|-39jhc1,16,6,1|-39jhc0,15,11,0|-2yj9g1,15,11,0|-2yj9g0,16,6,1|-2qppc1,16,6,1|-2qppc0,15,11,0|-2frc41,15,11,0|-2frc40,16,6,1|-27xs01,16,6,1|-27xs00,15,11,0|-1wzes1,15,11,0|-1wzes0,16,6,1|-1p4001,16,6,1|-1p4000,15,11,0|-1e7hg1,15,11,0|-1e7hg0,16,6,1|-16c2o1,16,6,1|-16c2o0,15,11,0|-vdpg1,15,11,0|-vdpg0,16,6,1|-niao1,16,6,1|-niao0,15,11,0|-cls41,15,11,0|-cls40,16,6,1|-4qdc1,16,6,1|-4qdc0,15,11,0|6657z,15,11,0|66580,16,6,1|e1jzz,16,6,1|e1k00,15,11,0|oy2jz,15,11,0|oy2k0,16,6,1|wthbz,16,6,1|wthc0,15,11,0|17rujz,15,11,0|17ruk0,16,6,1|1fn9bz,16,6,1|1fn9c0,15,11,0|1qjrvz,15,11,0|1qjrw0,16,6,1|1yf6nz,16,6,1|1yf6o0,15,11,0|29bp7z,15,11,0|29bp80,16,6,1|2h73zz,16,6,1|2h7400,15,11,0|2s3mjz,15,11,0|2s3mk0,16,6,1|2zz1bz,16,6,1|2zz1c0,15,11,0|3axejz,15,11,0|3axek0,16,6,1|3istbz,16,6,1|3istc0,15,11,0|3tpbvz,15,11,0|3tpbw0,16,6,1|41kqnz,16,6,1|41kqo0,15,11,0|4ch97z,15,11,0|4ch980,16,6,1|4kcnzz,16,6,1|4kco00,15,11,0|4v96jz,15,11,0|4v96k0,16,6,1|534lbz,16,6,1|534lc0,15,11,0|5e2yjz,15,11,0|5e2yk0,16,6,1|5lydbz,16,6,1|5lydc0,15,11,0|5wuvvz,15,11,0|5wuvw0,16,6,1|64qanz,16,6,1|64qao0,15,11,0|6k07vz,15,11,0|6k07w0,16,6,1|6ni7zz,16,6,1|6ni800,15,11,0|7242jz,15,11,0|7242k0,16,6,1|76a5bz,16,6,1|76a5c0,15,11,0|7h8ijz,15,11,0|7h8ik0,16,6,1|7p3xbz,16,6,1|7p3xc0,15,11,0|800fvz,15,11,0|800fw0,16,6,1|87vunz,16,6,1|87vuo0,15,11,0|8isd7z,15,11,0|8isd80,16,6,1|8qnrzz,16,6,1|8qns00,15,11,0|91kajz,15,11,0|91kak0,16,6,1|99fpbz,16,6,1|99fpc0,15,11,0|9ke2jz,15,11,0|9ke2k0,16,6,1|9s9hbz,16,6,1|9s9hc0,15,11,0|a3f97z,15,11,0|a3f980,16,6,1|ab1enz,16,6,1|ab1eo0,15,11,0|alxx7z,15,11,0|alxx80,16,6,1|attbzz,16,6,1|attc00,15,11,0|b4pujz,15,11,0|b4puk0,16,6,1|bcl9bz,16,6,1|bcl9c0,15,11,0|bnjmjz,15,11,0|bnjmk0,16,6,1|bvf1bz,16,6,1|bvf1c0,15,11,0|c6bjvz,15,11,0|c6bjw0,16,6,1|ce6ynz,16,6,1|ce6yo0,15,11,0|cp3h7z,15,11,0|cp3h80,16,6,1|cwyvzz,16,6,1|cwyw00,15,11,0|d7prrz,15,11,0|d7prs0,16,6,1|dfmvnz,16,6,1|dfmvo0,15,11,0|dqfufz,15,11,0|dqfug0,16,6,1|dycybz,16,6,1|dycyc0,15,11,0|e95x3z,15,11,0|e95x40,16,6,1|eh30zz,16,6,1|eh3100,15,11,0|ervzrz,15,11,0|ervzs0,16,6,1|ezt3nz,16,6,1|ezt3o0,15,11,0|faz13z,15,11,0|faz140,16,6,1|fiw4zz,16,6,1|fiw500,15,11,0|ftp3rz,15,11,0|ftp3s0,16,6,1|g1m7nz,16,6,1|g1m7o0,15,11,0|gcf6fz,15,11,0|gcf6g0,16,6,1|gkcabz,16,6,1|gkcac0,15,11,0|gv593z,15,11,0|gv5940,16,6,1|h32czz,16,6,1|h32d00,15,11,0|hdvbrz,15,11,0|hdvbs0,16,6,1|hlsfnz,16,6,1|hlsfo0,15,11,0|hwyd3z,15,11,0|hwyd40,16,6,1|i4vgzz,16,6,1|i4vh00,15,11,0|ifofrz,15,11,0|ifofs0,16,6,1|inljnz,16,6,1|inljo0,15,11,0|iyeifz,15,11,0|iyeig0,16,6,1|j5ynnz,16,6,1|j5yno0,15,11,0|jh4l3z,15,11,0|jh4l40,16,6,1|jnyszz,16,6,1|jnyt00,15,11,0|jzunrz,15,11,0|jzuns0,16,6,1|k6bwzz,16,6,1|k6bx00,15,11,0|kikqfz,15,11,0|kikqg0,16,6,1|kop0zz,16,6,1|kop100,15,11,0|l1nrrz,15,11,0|l1nrs0,16,6,1|l6yfnz,16,6,1|l6yfo0,15,11,0|l8i2fz,15,11,0|l8i2g0,16,6,1|l9kvnz,16,6,1|l9kvo0,15,11,0|n5myfz,15,11,0|n5myg0,16,6,1|n7snnz,16,6,1|n7sno0,15,11,0|n9ljrz,15,11,0|n9ljs0,16,6,1|nch6bz,16,6,1|nch6c0,15,11,0\",\"Africa/Casablanca|,0,18,0|-tblt9g,17,1,0|-fte5c1,17,1,0|-fte5c0,18,10,1|-fpwas1,18,10,1|-fpwas0,17,1,0|-fkuqo1,17,1,0|-fkuqo0,18,10,1|-cl6w41,18,10,1|-cl6w40,17,1,0|-a7hmo1,17,1,0|-a7hmo0,18,10,1|-a0ag41,18,10,1|-a0ag40,17,1,0|-1chdc1,17,1,0|-1chdc0,18,10,1|-16c5g1,18,10,1|-16c5g0,17,1,0|2c3rzz,17,1,0|2c3s00,18,10,1|2fnh7z,18,10,1|2fnh80,17,1,0|3axhbz,17,1,0|3axhc0,18,10,1|3fnrvz,18,10,1|3fnrw0,17,1,0|3tpenz,17,1,0|3tpeo0,18,10,1|41f3vz,18,10,1|41f3w0,17,1,0|4e2qnz,17,1,0|4e2qo0,18,10,1|4hd6jz,18,10,1|4hd6k0,17,1,0|7evenz,17,1,0|7eveo0,18,10,0|8cm57z,18,10,0|8cm580,17,1,0|k1rbzz,17,1,0|k1rc00,18,10,1|k6hmjz,18,10,1|k6hmk0,17,1,0|kkj9bz,17,1,0|kkj9c0,18,10,1|kop6jz,18,10,1|kop6k0,17,1,0|l1rmnz,17,1,0|l1rmo0,18,10,1|l6t17z,18,10,1|l6t180,17,1,0|lj1unz,17,1,0|lj1uo0,18,10,1|lp657z,18,10,1|lp6580,17,1,0|m37xjz,17,1,0|m37xk0,18,10,1|m7fs7z,18,10,1|m7fs80,17,1,0|m916vz,17,1,0|m916w0,18,10,1|mb547z,18,10,1|mb5480,17,1,0|mly07z,17,1,0|mly080,18,10,1|mpjmvz,18,10,1|mpjmw0,17,1,0|mraljz,17,1,0|mralk0,18,10,1|mvb1jz,18,10,1|mvb1k0,17,1,0|n3887z,17,1,0|n38880,18,10,1|n7uw7z,18,10,1|n7uw80,17,1,0|n9npjz,17,1,0|n9npk0,18,10,1|ne147z,18,10,1|ne1480,17,1,0|nlyavz,17,1,0|nlyaw0,18,10,1|npww7z,18,10,1|npww80,17,1,0|nrppjz,17,1,0|nrppk0,18,10,1|nwr6vz,18,10,1|nwr6w0,17,1,0|o4odjz,17,1,0|o4odk0,18,10,1|o8a07z,18,10,1|o8a080,17,1,0|oa2tjz,17,1,0|oa2tk0,18,10,1|ofu87z,18,10,1|ofu880,17,1,0|oneg7z,17,1,0|oneg80,18,10,1|oqa5jz,18,10,1|oqa5k0,17,1,0|osfxjz,17,1,0|osfxk0,18,10,1|oykavz,18,10,1|oykaw0,17,1,0|p64ivz,17,1,0|p64iw0,18,10,1|p8n9jz,18,10,1|p8n9k0,17,1,0|pag2vz,17,1,0|pag2w0,18,10,1|phadjz,18,10,1|phadk0,18,10,0|pr0djz,18,10,0|pr0dk0,17,1,1|pst6vz,17,1,1|pst6w0,18,10,0|q90ivz,18,10,0|q90iw0,17,1,1|qb6avz,17,1,1|qb6aw0,18,10,0|qrdmvz,18,10,0|qrdmw0,17,1,1|qt6g7z,17,1,1|qt6g80,18,10,0|r9ds7z,18,10,0|r9ds80,17,1,1|rbjk7z,17,1,1|rbjk80,18,10,0|rrqw7z,18,10,0|rrqw80,17,1,1|rtwo7z,17,1,1|rtwo80,18,10,0|sa407z,18,10,0|sa4080,17,1,1|sbwtjz,17,1,1|sbwtk0,18,10,0|ss45jz,18,10,0|ss45k0,17,1,1|su9xjz,17,1,1|su9xk0,18,10,0|tah9jz,18,10,0|tah9k0,17,1,1|tca2vz,17,1,1|tca2w0,18,10,0|tsudjz,18,10,0|tsudk0,17,1,1|tun6vz,17,1,1|tun6w0,18,10,0|uauivz,18,10,0|uauiw0,17,1,1|ud0avz,17,1,1|ud0aw0,18,10,0|ut7mvz,18,10,0|ut7mw0,17,1,1|uv0g7z,17,1,1|uv0g80,18,10,0|vb7s7z,18,10,0|vb7s80,17,1,1|vddk7z,17,1,1|vddk80,18,10,0|vtkw7z,18,10,0|vtkw80,17,1,1|vvqo7z,17,1,1|vvqo80,18,10,0|wby07z,18,10,0|wby080,17,1,1|wdqtjz,17,1,1|wdqtk0,18,10,0|wty5jz,18,10,0|wty5k0,17,1,1|ww3xjz,17,1,1|ww3xk0,18,10,0|xcb9jz,18,10,0|xcb9k0,17,1,1|xe42vz,17,1,1|xe42w0,18,10,0|xubevz,18,10,0|xubew0,17,1,1|xwh6vz,17,1,1|xwh6w0,18,10,0|ycoivz,18,10,0|ycoiw0,17,1,1|yeuavz,17,1,1|yeuaw0,18,10,0|yv1mvz,18,10,0|yv1mw0,17,1,1|ywug7z,17,1,1|ywug80,18,10,0|zd1s7z,18,10,0|zd1s80,17,1,1|zf7k7z,17,1,1|zf7k80,18,10,0\",\"Africa/Ceuta|,0,19,0|-100edc0,8,1,0|-qyiys1,8,1,0|-qyiys0,9,10,1|-qqluw1,9,10,1|-qqluw0,8,1,0|-nusqs1,8,1,0|-nusqs0,9,10,1|-nm0001,9,10,1|-nm0000,8,1,0|-mt71g1,8,1,0|-mt71g0,9,10,1|-mkjuo1,9,10,1|-mkjuo0,8,1,0|-matxg1,8,1,0|-matxg0,9,10,1|-m1ts01,9,10,1|-m1ts00,8,1,0|-lrqtc1,8,1,0|-lrqtc0,9,10,1|-liqqo1,9,10,1|-liqqo0,8,1,0|-1chdc1,8,1,0|-1chdc0,9,10,1|-16c5g1,9,10,1|-16c5g0,8,1,0|2c3rzz,8,1,0|2c3s00,9,10,1|2fnh7z,9,10,1|2fnh80,8,1,0|3axhbz,8,1,0|3axhc0,9,10,1|3fnrvz,9,10,1|3fnrw0,8,1,0|3tpenz,8,1,0|3tpeo0,9,10,1|41f3vz,9,10,1|41f3w0,8,1,0|4e2qnz,8,1,0|4e2qo0,9,10,1|4hd6jz,9,10,1|4hd6k0,8,1,0|7evenz,8,1,0|7eveo0,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Africa/Conakry|,0,12,0|-u9rgl4,1,1,0\",\"Africa/Dakar|,0,12,0|-u9rgl4,1,1,0\",\"Africa/Dar_es_Salaam|,0,4,0|-w6p5hg,4,5,0|-lnsey1,4,5,0|-lnsey0,5,6,0|-kvcdo1,5,6,0|-kvcdo0,4,5,0|-h80ka1,4,5,0|-h80ka0,6,7,0|-eb6ib1,6,7,0|-eb6ib0,5,6,0\",\"Africa/Djibouti|,0,4,0|-w6p5hg,4,5,0|-lnsey1,4,5,0|-lnsey0,5,6,0|-kvcdo1,5,6,0|-kvcdo0,4,5,0|-h80ka1,4,5,0|-h80ka0,6,7,0|-eb6ib1,6,7,0|-eb6ib0,5,6,0\",\"Africa/Douala|,0,13,0|-xnxnan,1,1,0|-w3k001,1,1,0|-w3k000,0,13,0|-t85smo,0,13,0|-t85smn,3,3,0|-q9qc21,3,3,0|-q9qc20,12,10,0\",\"Africa/El_Aaiun|,0,20,0|-isdxk0,13,15,0|3a22rz,13,15,0|3a22s0,17,1,0|3axhbz,17,1,0|3axhc0,18,10,1|3fnrvz,18,10,1|3fnrw0,17,1,0|3tpenz,17,1,0|3tpeo0,18,10,1|41f3vz,18,10,1|41f3w0,17,1,0|4e2qnz,17,1,0|4e2qo0,18,10,1|4hd6jz,18,10,1|4hd6k0,17,1,0|k1rbzz,17,1,0|k1rc00,18,10,1|k6hmjz,18,10,1|k6hmk0,17,1,0|kkj9bz,17,1,0|kkj9c0,18,10,1|kop6jz,18,10,1|kop6k0,17,1,0|l1rmnz,17,1,0|l1rmo0,18,10,1|l6t17z,18,10,1|l6t180,17,1,0|lj1unz,17,1,0|lj1uo0,18,10,1|lp657z,18,10,1|lp6580,17,1,0|m37xjz,17,1,0|m37xk0,18,10,1|m7fs7z,18,10,1|m7fs80,17,1,0|m916vz,17,1,0|m916w0,18,10,1|mb547z,18,10,1|mb5480,17,1,0|mly07z,17,1,0|mly080,18,10,1|mpjmvz,18,10,1|mpjmw0,17,1,0|mraljz,17,1,0|mralk0,18,10,1|mvb1jz,18,10,1|mvb1k0,17,1,0|n3887z,17,1,0|n38880,18,10,1|n7uw7z,18,10,1|n7uw80,17,1,0|n9npjz,17,1,0|n9npk0,18,10,1|ne147z,18,10,1|ne1480,17,1,0|nlyavz,17,1,0|nlyaw0,18,10,1|npww7z,18,10,1|npww80,17,1,0|nrppjz,17,1,0|nrppk0,18,10,1|nwr6vz,18,10,1|nwr6w0,17,1,0|o4odjz,17,1,0|o4odk0,18,10,1|o8a07z,18,10,1|o8a080,17,1,0|oa2tjz,17,1,0|oa2tk0,18,10,1|ofu87z,18,10,1|ofu880,17,1,0|oneg7z,17,1,0|oneg80,18,10,1|oqa5jz,18,10,1|oqa5k0,17,1,0|osfxjz,17,1,0|osfxk0,18,10,1|oykavz,18,10,1|oykaw0,17,1,0|p64ivz,17,1,0|p64iw0,18,10,1|p8n9jz,18,10,1|p8n9k0,17,1,0|pag2vz,17,1,0|pag2w0,18,10,1|phadjz,18,10,1|phadk0,18,10,0|pr0djz,18,10,0|pr0dk0,17,1,1|pst6vz,17,1,1|pst6w0,18,10,0|q90ivz,18,10,0|q90iw0,17,1,1|qb6avz,17,1,1|qb6aw0,18,10,0|qrdmvz,18,10,0|qrdmw0,17,1,1|qt6g7z,17,1,1|qt6g80,18,10,0|r9ds7z,18,10,0|r9ds80,17,1,1|rbjk7z,17,1,1|rbjk80,18,10,0|rrqw7z,18,10,0|rrqw80,17,1,1|rtwo7z,17,1,1|rtwo80,18,10,0|sa407z,18,10,0|sa4080,17,1,1|sbwtjz,17,1,1|sbwtk0,18,10,0|ss45jz,18,10,0|ss45k0,17,1,1|su9xjz,17,1,1|su9xk0,18,10,0|tah9jz,18,10,0|tah9k0,17,1,1|tca2vz,17,1,1|tca2w0,18,10,0|tsudjz,18,10,0|tsudk0,17,1,1|tun6vz,17,1,1|tun6w0,18,10,0|uauivz,18,10,0|uauiw0,17,1,1|ud0avz,17,1,1|ud0aw0,18,10,0|ut7mvz,18,10,0|ut7mw0,17,1,1|uv0g7z,17,1,1|uv0g80,18,10,0|vb7s7z,18,10,0|vb7s80,17,1,1|vddk7z,17,1,1|vddk80,18,10,0|vtkw7z,18,10,0|vtkw80,17,1,1|vvqo7z,17,1,1|vvqo80,18,10,0|wby07z,18,10,0|wby080,17,1,1|wdqtjz,17,1,1|wdqtk0,18,10,0|wty5jz,18,10,0|wty5k0,17,1,1|ww3xjz,17,1,1|ww3xk0,18,10,0|xcb9jz,18,10,0|xcb9k0,17,1,1|xe42vz,17,1,1|xe42w0,18,10,0|xubevz,18,10,0|xubew0,17,1,1|xwh6vz,17,1,1|xwh6w0,18,10,0|ycoivz,18,10,0|ycoiw0,17,1,1|yeuavz,17,1,1|yeuaw0,18,10,0|yv1mvz,18,10,0|yv1mw0,17,1,1|ywug7z,17,1,1|ywug80,18,10,0|zd1s7z,18,10,0|zd1s80,17,1,1|zf7k7z,17,1,1|zf7k80,18,10,0\",\"Africa/Freetown|,0,12,0|-u9rgl4,1,1,0\",\"Africa/Gaborone|,0,16,0|-yvtfd8,14,11,0\",\"Africa/Harare|,0,16,0|-yvtfd8,14,11,0\",\"Africa/Johannesburg|,0,21,0|-14nj6io,19,22,0|-yvtdi1,19,22,0|-yvtdi0,19,11,0|-e8lpc1,19,11,0|-e8lpc0,19,6,1|-dz8qs1,19,6,1|-dz8qs0,19,11,0|-dpvmo1,19,11,0|-dpvmo0,19,6,1|-dgio41,19,6,1|-dgio40,19,11,0\",\"Africa/Juba|,0,23,0|-kcrsis,14,11,0|662fz,14,11,0|662g0,20,6,1|er8zz,20,6,1|er900,14,11,0|ow53z,14,11,0|ow540,20,6,1|xj6bz,20,6,1|xj6c0,14,11,0|17px3z,14,11,0|17px40,20,6,1|1gcybz,20,6,1|1gcyc0,14,11,0|1qfzrz,14,11,0|1qfzs0,20,6,1|1z4vnz,20,6,1|1z4vo0,14,11,0|2962fz,14,11,0|2962g0,20,6,1|2hwszz,20,6,1|2hwt00,14,11,0|2rw53z,14,11,0|2rw540,20,6,1|30oqbz,20,6,1|30oqc0,14,11,0|3am7rz,14,11,0|3am7s0,20,6,1|3jiibz,20,6,1|3jiic0,14,11,0|3tcafz,14,11,0|3tcag0,20,6,1|42afnz,20,6,1|42afo0,14,11,0|4cfbrz,14,11,0|4cfbs0,20,6,1|4l2czz,20,6,1|4l2d00,14,11,0|4v5efz,14,11,0|4v5eg0,20,6,1|53uabz,20,6,1|53uac0,14,11,0|5dvh3z,14,11,0|5dvh40,20,6,1|5mo2bz,20,6,1|5mo2c0,14,11,0|5wljrz,14,11,0|5wljs0,20,6,1|65fznz,20,6,1|65fzo0,14,11,0|6fbmfz,14,11,0|6fbmg0,20,6,1|6o7wzz,20,6,1|6o7x00,14,11,0|6y1p3z,14,11,0|6y1p40,20,6,1|76zubz,20,6,1|76zuc0,14,11,0|7h4qfz,14,11,0|7h4qg0,20,6,1|7ptmbz,20,6,1|7ptmc0,14,11,0|7zut3z,14,11,0|7zut40,20,6,1|88ljnz,20,6,1|88ljo0,14,11,0|fodfrz,14,11,0|fodfs0,5,6,0|qntgzz,5,6,0|qnth00,14,11,0\",\"Africa/Kampala|,0,4,0|-w6p5hg,4,5,0|-lnsey1,4,5,0|-lnsey0,5,6,0|-kvcdo1,5,6,0|-kvcdo0,4,5,0|-h80ka1,4,5,0|-h80ka0,6,7,0|-eb6ib1,6,7,0|-eb6ib0,5,6,0\",\"Africa/Khartoum|,0,24,0|-kcrsow,14,11,0|662fz,14,11,0|662g0,20,6,1|er8zz,20,6,1|er900,14,11,0|ow53z,14,11,0|ow540,20,6,1|xj6bz,20,6,1|xj6c0,14,11,0|17px3z,14,11,0|17px40,20,6,1|1gcybz,20,6,1|1gcyc0,14,11,0|1qfzrz,14,11,0|1qfzs0,20,6,1|1z4vnz,20,6,1|1z4vo0,14,11,0|2962fz,14,11,0|2962g0,20,6,1|2hwszz,20,6,1|2hwt00,14,11,0|2rw53z,14,11,0|2rw540,20,6,1|30oqbz,20,6,1|30oqc0,14,11,0|3am7rz,14,11,0|3am7s0,20,6,1|3jiibz,20,6,1|3jiic0,14,11,0|3tcafz,14,11,0|3tcag0,20,6,1|42afnz,20,6,1|42afo0,14,11,0|4cfbrz,14,11,0|4cfbs0,20,6,1|4l2czz,20,6,1|4l2d00,14,11,0|4v5efz,14,11,0|4v5eg0,20,6,1|53uabz,20,6,1|53uac0,14,11,0|5dvh3z,14,11,0|5dvh40,20,6,1|5mo2bz,20,6,1|5mo2c0,14,11,0|5wljrz,14,11,0|5wljs0,20,6,1|65fznz,20,6,1|65fzo0,14,11,0|6fbmfz,14,11,0|6fbmg0,20,6,1|6o7wzz,20,6,1|6o7x00,14,11,0|6y1p3z,14,11,0|6y1p40,20,6,1|76zubz,20,6,1|76zuc0,14,11,0|7h4qfz,14,11,0|7h4qg0,20,6,1|7ptmbz,20,6,1|7ptmc0,14,11,0|7zut3z,14,11,0|7zut40,20,6,1|88ljnz,20,6,1|88ljo0,14,11,0|fodfrz,14,11,0|fodfs0,5,6,0|oypgzz,5,6,0|oyph00,14,11,0\",\"Africa/Kigali|,0,16,0|-yvtfd8,14,11,0\",\"Africa/Kinshasa|,0,13,0|-xnxnan,1,1,0|-w3k001,1,1,0|-w3k000,0,13,0|-t85smo,0,13,0|-t85smn,3,3,0|-q9qc21,3,3,0|-q9qc20,12,10,0\",\"Africa/Lagos|,0,13,0|-xnxnan,1,1,0|-w3k001,1,1,0|-w3k000,0,13,0|-t85smo,0,13,0|-t85smn,3,3,0|-q9qc21,3,3,0|-q9qc20,12,10,0\",\"Africa/Libreville|,0,13,0|-xnxnan,1,1,0|-w3k001,1,1,0|-w3k000,0,13,0|-t85smo,0,13,0|-t85smn,3,3,0|-q9qc21,3,3,0|-q9qc20,12,10,0\",\"Africa/Lome|,0,12,0|-u9rgl4,1,1,0\",\"Africa/Luanda|,0,13,0|-xnxnan,1,1,0|-w3k001,1,1,0|-w3k000,0,13,0|-t85smo,0,13,0|-t85smn,3,3,0|-q9qc21,3,3,0|-q9qc20,12,10,0\",\"Africa/Lubumbashi|,0,16,0|-yvtfd8,14,11,0\",\"Africa/Lusaka|,0,16,0|-yvtfd8,14,11,0\",\"Africa/Malabo|,0,13,0|-xnxnan,1,1,0|-w3k001,1,1,0|-w3k000,0,13,0|-t85smo,0,13,0|-t85smn,3,3,0|-q9qc21,3,3,0|-q9qc20,12,10,0\",\"Africa/Maputo|,0,16,0|-yvtfd8,14,11,0\",\"Africa/Maseru|,0,21,0|-14nj6io,19,22,0|-yvtdi1,19,22,0|-yvtdi0,19,11,0|-e8lpc1,19,11,0|-e8lpc0,19,6,1|-dz8qs1,19,6,1|-dz8qs0,19,11,0|-dpvmo1,19,11,0|-dpvmo0,19,6,1|-dgio41,19,6,1|-dgio40,19,11,0\",\"Africa/Mbabane|,0,21,0|-14nj6io,19,22,0|-yvtdi1,19,22,0|-yvtdi0,19,11,0|-e8lpc1,19,11,0|-e8lpc0,19,6,1|-dz8qs1,19,6,1|-dz8qs0,19,11,0|-dpvmo1,19,11,0|-dpvmo0,19,6,1|-dgio41,19,6,1|-dgio40,19,11,0\",\"Africa/Mogadishu|,0,4,0|-w6p5hg,4,5,0|-lnsey1,4,5,0|-lnsey0,5,6,0|-kvcdo1,5,6,0|-kvcdo0,4,5,0|-h80ka1,4,5,0|-h80ka0,6,7,0|-eb6ib1,6,7,0|-eb6ib0,5,6,0\",\"Africa/Monrovia|,0,25,0|-19xcbc4,21,25,0|-qj6zc5,21,25,0|-qj6zc4,21,26,0|11v0q5,21,26,0|11v0q6,1,1,0\",\"Africa/Nairobi|,0,4,0|-w6p5hg,4,5,0|-lnsey1,4,5,0|-lnsey0,5,6,0|-kvcdo1,5,6,0|-kvcdo0,4,5,0|-h80ka1,4,5,0|-h80ka0,6,7,0|-eb6ib1,6,7,0|-eb6ib0,5,6,0\",\"Africa/Ndjamena|,0,27,0|-u9rk4c,12,10,0|53sl7z,12,10,0|53sl80,22,11,1|5bavrz,22,11,1|5bavs0,12,10,0\",\"Africa/Niamey|,0,13,0|-xnxnan,1,1,0|-w3k001,1,1,0|-w3k000,0,13,0|-t85smo,0,13,0|-t85smn,3,3,0|-q9qc21,3,3,0|-q9qc20,12,10,0\",\"Africa/Nouakchott|,0,12,0|-u9rgl4,1,1,0\",\"Africa/Ouagadougou|,0,12,0|-u9rgl4,1,1,0\",\"Africa/Porto-Novo|,0,13,0|-xnxnan,1,1,0|-w3k001,1,1,0|-w3k000,0,13,0|-t85smo,0,13,0|-t85smn,3,3,0|-q9qc21,3,3,0|-q9qc20,12,10,0\",\"Africa/Sao_Tome|,0,28,0|-18vsjww,0,29,0|-u9rhc1,0,29,0|-u9rhc0,1,1,0|p1uqrz,1,1,0|p1uqs0,12,10,0|pkmo3z,12,10,0|pkmo40,1,1,0\",\"Africa/Tripoli|,0,30,0|-q3gfrw,10,10,0|-9ia581,10,10,0|-9ia580,11,11,1|-9e82w1,11,11,1|-9e82w0,10,10,0|-8gxp81,10,10,0|-8gxp80,11,11,1|-8cmdk1,11,11,1|-8cmdk0,10,10,0|-7fuo41,10,10,0|-7fuo40,11,11,1|-7b2iw1,11,11,1|-7b2iw0,10,10,0|-5qotg1,10,10,0|-5qotg0,15,11,0|69gifz,15,11,0|69gig0,10,10,0|6e397z,10,10,0|6e3980,11,11,1|6ni2fz,11,11,1|6ni2g0,10,10,0|6wv6jz,10,10,0|6wv6k0,11,11,1|769zrz,11,11,1|769zs0,10,10,0|7foyjz,10,10,0|7foyk0,11,11,1|7p3rrz,11,11,1|7p3rs0,10,10,0|7yq57z,10,10,0|7yq580,11,11,1|87vp3z,11,11,1|87vp40,10,10,0|8hed7z,10,10,0|8hed80,11,11,1|8qrbrz,11,11,1|8qrbs0,10,10,0|900qjz,10,10,0|900qk0,11,11,1|99fjrz,11,11,1|99fjs0,10,10,0|9iuijz,10,10,0|9iuik0,11,11,1|9s9brz,11,11,1|9s9bs0,10,10,0|a1mfvz,10,10,0|a1mfw0,11,11,1|ab193z,11,11,1|ab1940,10,10,0|am3h7z,10,10,0|am3h80,15,11,0|dyil3z,15,11,0|dyil40,10,10,0|e833vz,10,10,0|e833w0,11,11,1|ehhx3z,11,11,1|ehhx40,15,11,0|md8vzz,15,11,0|md8w00,10,10,0|mkeanz,10,10,0|mkeao0,11,11,1|mv76nz,11,11,1|mv76o0,15,11,0\",\"Africa/Tunis|,0,31,0|-1a9dr7w,7,9,0|-uozn3m,7,9,0|-uozn3l,10,10,0|-g12881,10,10,0|-g12880,11,11,1|-fpwdk1,11,11,1|-fpwdk0,10,10,0|-fkt1k1,10,10,0|-fkt1k0,11,11,1|-eqk5k1,11,11,1|-eqk5k0,10,10,0|-eimw41,10,10,0|-eimw40,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dxuo01,11,11,1|-dxuo00,10,10,0|-dxfrw1,10,10,0|-dxfrw0,11,11,1|-dp3uo1,11,11,1|-dp3uo0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d62tk1,11,11,1|-d62tk0,10,10,0|-cx0nw1,10,10,0|-cx0nw0,11,11,1|-cofmw1,11,11,1|-cofmw0,10,10,0|3tnh7z,10,10,0|3tnh80,11,11,1|417p7z,11,11,1|417p80,10,10,0|4ch97z,10,10,0|4ch980,11,11,1|4kcl7z,11,11,1|4kcl80,10,10,0|9lzh7z,10,10,0|9lzh80,11,11,1|9ryajz,11,11,1|9ryak0,10,10,0|a1bbvz,10,10,0|a1bbw0,11,11,1|aaod7z,11,11,1|aaod80,10,10,0|alxx7z,10,10,0|alxx80,11,11,1|atrejz,11,11,1|atrek0,10,10,0|ifs7vz,10,10,0|ifs7w0,11,11,1|inlrzz,11,11,1|inls00,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0\",\"Africa/Windhoek|,0,32,0|-14nj4i0,23,22,0|-yvtdi1,23,22,0|-yvtdi0,19,11,0|-e8lpc1,19,11,0|-e8lpc0,19,6,1|-dz8qs1,19,6,1|-dz8qs0,19,11,0|ajtx3z,19,11,0|ajtx40,14,11,0|cmzh3z,14,11,0|cmzh40,12,10,1|cvkyrz,12,10,1|cvkys0,14,11,0|d6drzz,14,11,0|d6ds00,12,10,1|deb1fz,12,10,1|deb1g0,14,11,0|dpgtbz,14,11,0|dpgtc0,12,10,1|dx143z,12,10,1|dx1440,14,11,0|e86vzz,14,11,0|e86w00,12,10,1|eg45fz,12,10,1|eg45g0,14,11,0|eqwynz,14,11,0|eqwyo0,12,10,1|eyu83z,12,10,1|eyu840,14,11,0|f9n1bz,14,11,0|f9n1c0,12,10,1|fhkarz,12,10,1|fhkas0,14,11,0|fsd3zz,14,11,0|fsd400,12,10,1|g0adfz,12,10,1|g0adg0,14,11,0|gb36nz,14,11,0|gb36o0,12,10,1|gj0g3z,12,10,1|gj0g40,14,11,0|gu67zz,14,11,0|gu6800,12,10,1|h1qirz,12,10,1|h1qis0,14,11,0|hcwanz,14,11,0|hcwao0,12,10,1|hktk3z,12,10,1|hktk40,14,11,0|hvmdbz,14,11,0|hvmdc0,12,10,1|i3jmrz,12,10,1|i3jms0,14,11,0|iecfzz,14,11,0|iecg00,12,10,1|im9pfz,12,10,1|im9pg0,14,11,0|ix2inz,14,11,0|ix2io0,12,10,1|j4zs3z,12,10,1|j4zs40,14,11,0|jfslbz,14,11,0|jfslc0,12,10,1|jnpurz,12,10,1|jnpus0,14,11,0|jyvmnz,14,11,0|jyvmo0,12,10,1|k6sw3z,12,10,1|k6sw40,14,11,0|khlpbz,14,11,0|khlpc0,12,10,1|kpiyrz,12,10,1|kpiys0,14,11,0|l0brzz,14,11,0|l0bs00,12,10,1|l891fz,12,10,1|l891g0,14,11,0|lj1unz,14,11,0|lj1uo0,12,10,1|lqz43z,12,10,1|lqz440,14,11,0|m1rxbz,14,11,0|m1rxc0,12,10,1|m9p6rz,12,10,1|m9p6s0,14,11,0|mkuynz,14,11,0|mkuyo0,12,10,1|msf9fz,12,10,1|msf9g0,14,11,0|n3l1bz,14,11,0|n3l1c0,12,10,1|nbiarz,12,10,1|nbias0,14,11,0|nmb3zz,14,11,0|nmb400,12,10,1|nu8dfz,12,10,1|nu8dg0,14,11,0|o516nz,14,11,0|o516o0,12,10,1|ocyg3z,12,10,1|ocyg40,14,11,0|onr9bz,14,11,0|onr9c0,12,10,1|ovoirz,12,10,1|ovois0,14,11,0\",\"America/Adak|,0,33,0|-1hc7qjz,0,34,0|-1078omb,0,34,0|-1078oma,24,35,0|-ek1nw1,24,35,0|-ek1nw0,25,36,1|-cq2tg1,25,36,1|-cq2tg0,26,36,1|-cnomo1,26,36,1|-cnomo0,24,35,0|-1fq441,24,35,0|-1fq440,27,35,0|-cs3w1,27,35,0|-cs3w0,28,36,1|-3f5c1,28,36,1|-3f5c0,27,35,0|5xyrz,27,35,0|5xys0,28,36,1|faxbz,28,36,1|faxc0,27,35,0|oo1fz,27,35,0|oo1g0,28,36,1|ydynz,28,36,1|ydyo0,27,35,0|17r2rz,27,35,0|17r2s0,28,36,1|1h41bz,28,36,1|1h41c0,27,35,0|1qh5fz,27,35,0|1qh5g0,28,36,1|1zu3zz,28,36,1|1zu400,27,35,0|23ftfz,27,35,0|23ftg0,28,36,1|2ik6nz,28,36,1|2ik6o0,27,35,0|2oomrz,27,35,0|2ooms0,28,36,1|31a9bz,28,36,1|31a9c0,27,35,0|3andfz,27,35,0|3andg0,28,36,1|3kdanz,28,36,1|3kdao0,27,35,0|3tdg3z,27,35,0|3tdg40,28,36,1|433dbz,28,36,1|433dc0,27,35,0|4cghfz,27,35,0|4cghg0,28,36,1|4ltfzz,28,36,1|4ltg00,27,35,0|4v6k3z,27,35,0|4v6k40,28,36,1|54jinz,28,36,1|54jio0,27,35,0|5dwmrz,27,35,0|5dwms0,28,36,1|5n9lbz,28,36,1|5n9lc0,27,35,0|5wmpfz,27,35,0|5wmpg0,28,36,1|65znzz,28,36,1|65zo00,27,35,0|6fcs3z,27,35,0|6fcs40,28,36,1|6p2pbz,28,36,1|6p2pc0,27,35,0|6y2urz,27,35,0|6y2us0,28,36,1|77srzz,28,36,1|77ss00,29,36,0|79e13z,29,36,0|79e140,30,36,0|7h5tbz,30,36,0|7h5tc0,31,37,1|7qirvz,31,37,1|7qirw0,30,36,0|7zvvzz,30,36,0|7zvw00,31,37,1|898ujz,31,37,1|898uk0,30,36,0|8ilynz,30,36,0|8ilyo0,31,37,1|8ryx7z,31,37,1|8ryx80,30,36,0|9095bz,30,36,0|9095c0,31,37,1|9aozvz,31,37,1|9aozw0,30,36,0|9iz7zz,30,36,0|9iz800,31,37,1|9ts17z,31,37,1|9ts180,30,36,0|a1panz,30,36,0|a1pao0,31,37,1|aci3vz,31,37,1|aci3w0,30,36,0|akfdbz,30,36,0|akfdc0,31,37,1|av86jz,31,37,1|av86k0,30,36,0|b3ienz,30,36,0|b3ieo0,31,37,1|bdy97z,31,37,1|bdy980,30,36,0|bm8hbz,30,36,0|bm8hc0,31,37,1|bwobvz,31,37,1|bwobw0,30,36,0|c4yjzz,30,36,0|c4yk00,31,37,1|cfrd7z,31,37,1|cfrd80,30,36,0|cnomnz,30,36,0|cnomo0,31,37,1|cyhfvz,31,37,1|cyhfw0,30,36,0|d6epbz,30,36,0|d6epc0,31,37,1|dh7ijz,31,37,1|dh7ik0,30,36,0|dphqnz,30,36,0|dphqo0,31,37,1|dzxl7z,31,37,1|dzxl80,30,36,0|e87tbz,30,36,0|e87tc0,31,37,1|einnvz,31,37,1|einnw0,30,36,0|eqxvzz,30,36,0|eqxw00,31,37,1|f1dqjz,31,37,1|f1dqk0,30,36,0|f9nynz,30,36,0|f9nyo0,31,37,1|fkgrvz,31,37,1|fkgrw0,30,36,0|fse1bz,30,36,0|fse1c0,31,37,1|g36ujz,31,37,1|g36uk0,30,36,0|gb43zz,30,36,0|gb4400,31,37,1|glwx7z,31,37,1|glwx80,30,36,0|gu75bz,30,36,0|gu75c0,31,37,1|h4mzvz,31,37,1|h4mzw0,30,36,0|hcx7zz,30,36,0|hcx800,31,37,1|hnd2jz,31,37,1|hnd2k0,30,36,0|hvnanz,30,36,0|hvnao0,31,37,1|i6g3vz,31,37,1|i6g3w0,30,36,0|ieddbz,30,36,0|ieddc0,31,37,1|ip66jz,31,37,1|ip66k0,30,36,0|ix3fzz,30,36,0|ix3g00,31,37,1|j7w97z,31,37,1|j7w980,30,36,0|jeqmnz,30,36,0|jeqmo0,31,37,1|jqzajz,31,37,1|jqzak0,30,36,0|jxgpbz,30,36,0|jxgpc0,31,37,1|k9pd7z,31,37,1|k9pd80,30,36,0|kg6rzz,30,36,0|kg6s00,31,37,1|ksffvz,31,37,1|ksffw0,30,36,0|kz9tbz,30,36,0|kz9tc0,31,37,1|lbih7z,31,37,1|lbih80,30,36,0|lhzvzz,30,36,0|lhzw00,31,37,1|lu8jvz,31,37,1|lu8jw0,30,36,0|m0pynz,30,36,0|m0pyo0,31,37,1|mcymjz,31,37,1|mcymk0,30,36,0|mjg1bz,30,36,0|mjg1c0,31,37,1|mvop7z,31,37,1|mvop80,30,36,0|n263zz,30,36,0|n26400,31,37,1|neervz,31,37,1|neerw0,30,36,0|nkw6nz,30,36,0|nkw6o0,31,37,1|nx4ujz,31,37,1|nx4uk0,30,36,0|o3z7zz,30,36,0|o3z800,31,37,1|og7vvz,31,37,1|og7vw0,30,36,0|ompanz,30,36,0|ompao0,31,37,1|oyxyjz,31,37,1|oyxyk0,30,36,0|p5fdbz,30,36,0|p5fdc0,31,37,1|pho17z,31,37,1|pho180,30,36,0|po5fzz,30,36,0|po5g00,31,37,1|q0e3vz,31,37,1|q0e3w0,30,36,0|q6vinz,30,36,0|q6vio0,31,37,1|qj46jz,31,37,1|qj46k0,30,36,0|qpyjzz,30,36,0|qpyk00,31,37,1|r277vz,31,37,1|r277w0,30,36,0|r8omnz,30,36,0|r8omo0,31,37,1|rkxajz,31,37,1|rkxak0,30,36,0|rrepbz,30,36,0|rrepc0,31,37,1|s3nd7z,31,37,1|s3nd80,30,36,0|sa4rzz,30,36,0|sa4s00,31,37,1|smdfvz,31,37,1|smdfw0,30,36,0|ssuunz,30,36,0|ssuuo0,31,37,1|t53ijz,31,37,1|t53ik0,30,36,0|tbkxbz,30,36,0|tbkxc0,31,37,1|tntl7z,31,37,1|tntl80,30,36,0|tunynz,30,36,0|tunyo0,31,37,1|u6wmjz,31,37,1|u6wmk0,30,36,0|ude1bz,30,36,0|ude1c0,31,37,1|upmp7z,31,37,1|upmp80,30,36,0|uw43zz,30,36,0|uw4400,31,37,1|v8crvz,31,37,1|v8crw0,30,36,0|veu6nz,30,36,0|veu6o0,31,37,1|vr2ujz,31,37,1|vr2uk0,30,36,0|vxk9bz,30,36,0|vxk9c0,31,37,1|w9sx7z,31,37,1|w9sx80,30,36,0|wgnanz,30,36,0|wgnao0,31,37,1|wsvyjz,31,37,1|wsvyk0,30,36,0|wzddbz,30,36,0|wzddc0,31,37,1|xbm17z,31,37,1|xbm180,30,36,0|xi3fzz,30,36,0|xi3g00,31,37,1|xuc3vz,31,37,1|xuc3w0,30,36,0|y0tinz,30,36,0|y0tio0,31,37,1|yd26jz,31,37,1|yd26k0,30,36,0|yjjlbz,30,36,0|yjjlc0,31,37,1|yvs97z,31,37,1|yvs980,30,36,0|z29nzz,30,36,0|z29o00,31,37,1|zeibvz,31,37,1|zeibw0,30,36,0\",\"America/Anchorage|,0,38,0|-1hc7qjz,0,39,0|-1078tkp,0,39,0|-1078tko,32,36,0|-ek1qo1,32,36,0|-ek1qo0,33,37,1|-cq2tg1,33,37,1|-cq2tg0,34,37,1|-cnopg1,34,37,1|-cnopg0,32,36,0|-1fq6w1,32,36,0|-1fq6w0,29,36,0|-cs6o1,29,36,0|-cs6o0,35,37,1|-3f841,35,37,1|-3f840,29,36,0|5xvzz,29,36,0|5xw00,35,37,1|faujz,35,37,1|fauk0,29,36,0|onynz,29,36,0|onyo0,35,37,1|ydvvz,35,37,1|ydvw0,29,36,0|17qzzz,29,36,0|17r000,35,37,1|1h3yjz,35,37,1|1h3yk0,29,36,0|1qh2nz,29,36,0|1qh2o0,35,37,1|1zu17z,35,37,1|1zu180,29,36,0|23fqnz,29,36,0|23fqo0,35,37,1|2ik3vz,35,37,1|2ik3w0,29,36,0|2oojzz,29,36,0|2ook00,35,37,1|31a6jz,35,37,1|31a6k0,29,36,0|3ananz,29,36,0|3anao0,35,37,1|3kd7vz,35,37,1|3kd7w0,29,36,0|3tddbz,29,36,0|3tddc0,35,37,1|433ajz,35,37,1|433ak0,29,36,0|4cgenz,29,36,0|4cgeo0,35,37,1|4ltd7z,35,37,1|4ltd80,29,36,0|4v6hbz,29,36,0|4v6hc0,35,37,1|54jfvz,35,37,1|54jfw0,29,36,0|5dwjzz,29,36,0|5dwk00,35,37,1|5n9ijz,35,37,1|5n9ik0,29,36,0|5wmmnz,29,36,0|5wmmo0,35,37,1|65zl7z,35,37,1|65zl80,29,36,0|6fcpbz,29,36,0|6fcpc0,35,37,1|6p2mjz,35,37,1|6p2mk0,29,36,0|6y2rzz,29,36,0|6y2s00,35,37,1|77sp7z,35,37,1|77sp80,36,37,0|79dybz,36,37,0|79dyc0,37,37,0|7h5qjz,37,37,0|7h5qk0,38,40,1|7qip3z,38,40,1|7qip40,37,37,0|7zvt7z,37,37,0|7zvt80,38,40,1|898rrz,38,40,1|898rs0,37,37,0|8ilvvz,37,37,0|8ilvw0,38,40,1|8ryufz,38,40,1|8ryug0,37,37,0|9092jz,37,37,0|9092k0,38,40,1|9aox3z,38,40,1|9aox40,37,37,0|9iz57z,37,37,0|9iz580,38,40,1|9tryfz,38,40,1|9tryg0,37,37,0|a1p7vz,37,37,0|a1p7w0,38,40,1|aci13z,38,40,1|aci140,37,37,0|akfajz,37,37,0|akfak0,38,40,1|av83rz,38,40,1|av83s0,37,37,0|b3ibvz,37,37,0|b3ibw0,38,40,1|bdy6fz,38,40,1|bdy6g0,37,37,0|bm8ejz,37,37,0|bm8ek0,38,40,1|bwo93z,38,40,1|bwo940,37,37,0|c4yh7z,37,37,0|c4yh80,38,40,1|cfrafz,38,40,1|cfrag0,37,37,0|cnojvz,37,37,0|cnojw0,38,40,1|cyhd3z,38,40,1|cyhd40,37,37,0|d6emjz,37,37,0|d6emk0,38,40,1|dh7frz,38,40,1|dh7fs0,37,37,0|dphnvz,37,37,0|dphnw0,38,40,1|dzxifz,38,40,1|dzxig0,37,37,0|e87qjz,37,37,0|e87qk0,38,40,1|einl3z,38,40,1|einl40,37,37,0|eqxt7z,37,37,0|eqxt80,38,40,1|f1dnrz,38,40,1|f1dns0,37,37,0|f9nvvz,37,37,0|f9nvw0,38,40,1|fkgp3z,38,40,1|fkgp40,37,37,0|fsdyjz,37,37,0|fsdyk0,38,40,1|g36rrz,38,40,1|g36rs0,37,37,0|gb417z,37,37,0|gb4180,38,40,1|glwufz,38,40,1|glwug0,37,37,0|gu72jz,37,37,0|gu72k0,38,40,1|h4mx3z,38,40,1|h4mx40,37,37,0|hcx57z,37,37,0|hcx580,38,40,1|hnczrz,38,40,1|hnczs0,37,37,0|hvn7vz,37,37,0|hvn7w0,38,40,1|i6g13z,38,40,1|i6g140,37,37,0|iedajz,37,37,0|iedak0,38,40,1|ip63rz,38,40,1|ip63s0,37,37,0|ix3d7z,37,37,0|ix3d80,38,40,1|j7w6fz,38,40,1|j7w6g0,37,37,0|jeqjvz,37,37,0|jeqjw0,38,40,1|jqz7rz,38,40,1|jqz7s0,37,37,0|jxgmjz,37,37,0|jxgmk0,38,40,1|k9pafz,38,40,1|k9pag0,37,37,0|kg6p7z,37,37,0|kg6p80,38,40,1|ksfd3z,38,40,1|ksfd40,37,37,0|kz9qjz,37,37,0|kz9qk0,38,40,1|lbiefz,38,40,1|lbieg0,37,37,0|lhzt7z,37,37,0|lhzt80,38,40,1|lu8h3z,38,40,1|lu8h40,37,37,0|m0pvvz,37,37,0|m0pvw0,38,40,1|mcyjrz,38,40,1|mcyjs0,37,37,0|mjfyjz,37,37,0|mjfyk0,38,40,1|mvomfz,38,40,1|mvomg0,37,37,0|n2617z,37,37,0|n26180,38,40,1|neep3z,38,40,1|neep40,37,37,0|nkw3vz,37,37,0|nkw3w0,38,40,1|nx4rrz,38,40,1|nx4rs0,37,37,0|o3z57z,37,37,0|o3z580,38,40,1|og7t3z,38,40,1|og7t40,37,37,0|omp7vz,37,37,0|omp7w0,38,40,1|oyxvrz,38,40,1|oyxvs0,37,37,0|p5fajz,37,37,0|p5fak0,38,40,1|phnyfz,38,40,1|phnyg0,37,37,0|po5d7z,37,37,0|po5d80,38,40,1|q0e13z,38,40,1|q0e140,37,37,0|q6vfvz,37,37,0|q6vfw0,38,40,1|qj43rz,38,40,1|qj43s0,37,37,0|qpyh7z,37,37,0|qpyh80,38,40,1|r2753z,38,40,1|r27540,37,37,0|r8ojvz,37,37,0|r8ojw0,38,40,1|rkx7rz,38,40,1|rkx7s0,37,37,0|rremjz,37,37,0|rremk0,38,40,1|s3nafz,38,40,1|s3nag0,37,37,0|sa4p7z,37,37,0|sa4p80,38,40,1|smdd3z,38,40,1|smdd40,37,37,0|ssurvz,37,37,0|ssurw0,38,40,1|t53frz,38,40,1|t53fs0,37,37,0|tbkujz,37,37,0|tbkuk0,38,40,1|tntifz,38,40,1|tntig0,37,37,0|tunvvz,37,37,0|tunvw0,38,40,1|u6wjrz,38,40,1|u6wjs0,37,37,0|uddyjz,37,37,0|uddyk0,38,40,1|upmmfz,38,40,1|upmmg0,37,37,0|uw417z,37,37,0|uw4180,38,40,1|v8cp3z,38,40,1|v8cp40,37,37,0|veu3vz,37,37,0|veu3w0,38,40,1|vr2rrz,38,40,1|vr2rs0,37,37,0|vxk6jz,37,37,0|vxk6k0,38,40,1|w9sufz,38,40,1|w9sug0,37,37,0|wgn7vz,37,37,0|wgn7w0,38,40,1|wsvvrz,38,40,1|wsvvs0,37,37,0|wzdajz,37,37,0|wzdak0,38,40,1|xblyfz,38,40,1|xblyg0,37,37,0|xi3d7z,37,37,0|xi3d80,38,40,1|xuc13z,38,40,1|xuc140,37,37,0|y0tfvz,37,37,0|y0tfw0,38,40,1|yd23rz,38,40,1|yd23s0,37,37,0|yjjijz,37,37,0|yjjik0,38,40,1|yvs6fz,38,40,1|yvs6g0,37,37,0|z29l7z,37,37,0|z29l80,38,40,1|zei93z,38,40,1|zei940,37,37,0\",\"America/Anguilla|,0,41,0|-u6m79w,32,42,0\",\"America/Antigua|,0,41,0|-u6m79w,32,42,0\",\"America/Araguaina|,0,43,0|-t85j2o,39,44,0|-jylag1,39,44,0|-jylag0,40,45,1|-jpb141,40,45,1|-jpb140,39,44,0|-jfsd01,39,44,0|-jfsd00,40,45,1|-j6j3s1,40,45,1|-j6j3s0,39,44,0|-ahcyc1,39,44,0|-ahcyc0,40,45,1|-aad3o1,40,45,1|-aad3o0,39,44,0|-9yl101,39,44,0|-9yl100,40,45,1|-9sd141,40,45,1|-9sd140,39,44,0|-9ft3o1,39,44,0|-9ft3o0,40,45,1|-99j941,40,45,1|-99j940,39,44,0|-8wzbo1,39,44,0|-8wzbo0,40,45,1|-8scqg1,40,45,1|-8scqg0,39,44,0|-35xmc1,39,44,0|-35xmc0,40,45,1|-31nzs1,40,45,1|-31nzs0,39,44,0|-2kdp01,39,44,0|-2kdp00,40,45,1|-2hcig1,40,45,1|-2hcig0,39,44,0|-24qqc1,39,44,0|-24qqc0,40,45,1|-204541,40,45,1|-204540,39,44,0|-1nid01,39,44,0|-1nid00,40,45,1|-1hc7s1,40,45,1|-1hc7s0,39,44,0|-14qfo1,39,44,0|-14qfo0,40,45,1|-yifs1,40,45,1|-yifs0,39,44,0|89jcbz,39,44,0|89jcc0,40,45,1|8gdk7z,40,45,1|8gdk80,39,44,0|8rwgbz,39,44,0|8rwgc0,40,45,1|8xns7z,40,45,1|8xns80,39,44,0|9aodnz,39,44,0|9aodo0,40,45,1|9g2qvz,40,45,1|9g2qw0,39,44,0|9t1hnz,39,44,0|9t1ho0,40,45,1|9yfuvz,40,45,1|9yfuw0,39,44,0|abrkbz,39,44,0|abrkc0,40,45,1|ahvuvz,40,45,1|ahvuw0,39,44,0|dggyzz,39,44,0|dggz00,40,45,1|dml9jz,40,45,1|dml9k0,39,44,0|dyu2zz,39,44,0|dyu300,40,45,1|e5oavz,40,45,1|e5oaw0,39,44,0|ehm0bz,39,44,0|ehm0c0,40,45,1|ep4avz,40,45,1|ep4aw0,39,44,0|f0n6zz,39,44,0|f0n700,40,45,1|f7hevz,40,45,1|f7hew0,39,44,0|fj0azz,39,44,0|fj0b00,40,45,1|fqkg7z,40,45,1|fqkg80,39,44,0|g23cbz,39,44,0|g23cc0,40,45,1|g8xk7z,40,45,1|g8xk80,39,44,0|gl6dnz,39,44,0|gl6do0,40,45,1|grnmvz,40,45,1|grnmw0,39,44,0|h4zcbz,39,44,0|h4zcc0,40,45,1|hadpjz,40,45,1|hadpk0,39,44,0|mc82zz,39,44,0|mc8300,40,45,1|micdjz,40,45,1|micdk0,39,44,0\",\"America/Argentina/Buenos_Aires|,0,46,0|-138aaic,41,47,0|-px7ys1,41,47,0|-px7ys0,42,42,0|-kecq81,42,42,0|-kecq80,39,44,1|-k84qc1,39,44,1|-k84qc0,42,42,0|-jxzu81,42,42,0|-jxzu80,39,44,1|-jqwd01,39,44,1|-jqwd00,42,42,0|-jeakw1,42,42,0|-jeakw0,39,44,1|-j84fo1,39,44,1|-j84fo0,42,42,0|-ivink1,42,42,0|-ivink0,39,44,1|-ipcic1,39,44,1|-ipcic0,42,42,0|-icqq81,42,42,0|-icqq80,39,44,1|-i6kl01,39,44,1|-i6kl00,42,42,0|-htysw1,42,42,0|-htysw0,39,44,1|-hnqt01,39,44,1|-hnqt00,42,42,0|-hb50w1,42,42,0|-hb50w0,39,44,1|-h4yvo1,39,44,1|-h4yvo0,42,42,0|-gsd3k1,42,42,0|-gsd3k0,39,44,1|-gm6yc1,39,44,1|-gm6yc0,42,42,0|-g9l681,42,42,0|-g9l680,39,44,1|-g3f101,39,44,1|-g3f100,42,42,0|-fqt8w1,42,42,0|-fqt8w0,39,44,1|-fkl901,39,44,1|-fkl900,42,42,0|-feb8w1,42,42,0|-feb8w0,39,44,1|-ewd101,39,44,1|-ewd100,42,42,0|-eq30w1,42,42,0|-eq30w0,39,44,1|-dse501,39,44,1|-dse500,42,42,0|-doj681,42,42,0|-doj680,39,44,1|-cfvuc1,39,44,1|-cfvuc0,42,42,0|-c4vgw1,42,42,0|-c4vgw0,39,44,1|-39hec1,39,44,1|-39hec0,42,42,0|-35mfk1,42,42,0|-35mfk0,39,44,1|-31nx01,39,44,1|-31nx00,42,42,0|-2pxm81,42,42,0|-2pxm80,39,44,1|-2ivzo1,39,44,1|-2ivzo0,42,42,0|-275ow1,42,42,0|-275ow0,39,44,1|-2042c1,39,44,1|-2042c0,42,42,0|-1odrk1,42,42,0|-1odrk0,39,44,1|-1fovo1,39,44,1|-1fovo0,42,42,0|-16brk1,42,42,0|-16brk0,39,44,1|-wluc1,39,44,1|-wluc0,42,42,0|-n8q81,42,42,0|-n8q80,39,44,1|-dvro1,39,44,1|-dvro0,42,42,0|-4ink1,42,42,0|-4ink0,39,44,0|24aizz,39,44,0|24aj00,40,45,1|29bxjz,40,45,1|29bxk0,39,44,0|9veobz,39,44,0|9veoc0,40,45,1|a08o7z,40,45,1|a08o80,39,44,0|abrkbz,39,44,0|abrkc0,40,45,1|aiyqvz,40,45,1|aiyqw0,39,44,0|auulnz,39,44,0|auulo0,40,45,1|b1otjz,40,45,1|b1otk0,39,44,0|bdkobz,39,44,0|bdkoc0,40,45,1|bkew7z,40,45,1|bkew80,39,44,0|bwaqzz,39,44,0|bwar00,40,45,1|c3hxjz,40,45,1|c3hxk0,39,44,0|fj0azz,39,44,0|fj0b00,39,44,1|fqtsbz,39,44,1|fqtsc0,39,44,0|jtudnz,39,44,0|jtudo0,40,45,1|jxsw7z,40,45,1|jxsw80,39,44,0|k8ytnz,39,44,0|k8yto0,40,45,1|kgiyvz,40,45,1|kgiyw0,39,44,0\",\"America/Argentina/Catamarca|,0,48,0|-138a95g,41,47,0|-px7ys1,41,47,0|-px7ys0,42,42,0|-kecq81,42,42,0|-kecq80,39,44,1|-k84qc1,39,44,1|-k84qc0,42,42,0|-jxzu81,42,42,0|-jxzu80,39,44,1|-jqwd01,39,44,1|-jqwd00,42,42,0|-jeakw1,42,42,0|-jeakw0,39,44,1|-j84fo1,39,44,1|-j84fo0,42,42,0|-ivink1,42,42,0|-ivink0,39,44,1|-ipcic1,39,44,1|-ipcic0,42,42,0|-icqq81,42,42,0|-icqq80,39,44,1|-i6kl01,39,44,1|-i6kl00,42,42,0|-htysw1,42,42,0|-htysw0,39,44,1|-hnqt01,39,44,1|-hnqt00,42,42,0|-hb50w1,42,42,0|-hb50w0,39,44,1|-h4yvo1,39,44,1|-h4yvo0,42,42,0|-gsd3k1,42,42,0|-gsd3k0,39,44,1|-gm6yc1,39,44,1|-gm6yc0,42,42,0|-g9l681,42,42,0|-g9l680,39,44,1|-g3f101,39,44,1|-g3f100,42,42,0|-fqt8w1,42,42,0|-fqt8w0,39,44,1|-fkl901,39,44,1|-fkl900,42,42,0|-feb8w1,42,42,0|-feb8w0,39,44,1|-ewd101,39,44,1|-ewd100,42,42,0|-eq30w1,42,42,0|-eq30w0,39,44,1|-dse501,39,44,1|-dse500,42,42,0|-doj681,42,42,0|-doj680,39,44,1|-cfvuc1,39,44,1|-cfvuc0,42,42,0|-c4vgw1,42,42,0|-c4vgw0,39,44,1|-39hec1,39,44,1|-39hec0,42,42,0|-35mfk1,42,42,0|-35mfk0,39,44,1|-31nx01,39,44,1|-31nx00,42,42,0|-2pxm81,42,42,0|-2pxm80,39,44,1|-2ivzo1,39,44,1|-2ivzo0,42,42,0|-275ow1,42,42,0|-275ow0,39,44,1|-2042c1,39,44,1|-2042c0,42,42,0|-1odrk1,42,42,0|-1odrk0,39,44,1|-1fovo1,39,44,1|-1fovo0,42,42,0|-16brk1,42,42,0|-16brk0,39,44,1|-wluc1,39,44,1|-wluc0,42,42,0|-n8q81,42,42,0|-n8q80,39,44,1|-dvro1,39,44,1|-dvro0,42,42,0|-4ink1,42,42,0|-4ink0,39,44,0|24aizz,39,44,0|24aj00,40,45,1|29bxjz,40,45,1|29bxk0,39,44,0|9veobz,39,44,0|9veoc0,40,45,1|a08o7z,40,45,1|a08o80,39,44,0|abrkbz,39,44,0|abrkc0,40,45,1|aiyqvz,40,45,1|aiyqw0,39,44,0|auulnz,39,44,0|auulo0,40,45,1|b1otjz,40,45,1|b1otk0,42,42,0|bdkr3z,42,42,0|bdkr40,40,45,1|bkew7z,40,45,1|bkew80,39,44,0|bwaqzz,39,44,0|bwar00,40,45,1|c3hxjz,40,45,1|c3hxk0,39,44,0|fj0azz,39,44,0|fj0b00,39,44,1|fqtsbz,39,44,1|fqtsc0,39,44,0|hym0bz,39,44,0|hym0c0,42,42,0|hzl9rz,42,42,0|hzl9s0,39,44,0|jtudnz,39,44,0|jtudo0,40,45,1|jxsw7z,40,45,1|jxsw80,39,44,0\",\"America/Argentina/Cordoba|,0,47,0|-138a9g0,41,47,0|-px7ys1,41,47,0|-px7ys0,42,42,0|-kecq81,42,42,0|-kecq80,39,44,1|-k84qc1,39,44,1|-k84qc0,42,42,0|-jxzu81,42,42,0|-jxzu80,39,44,1|-jqwd01,39,44,1|-jqwd00,42,42,0|-jeakw1,42,42,0|-jeakw0,39,44,1|-j84fo1,39,44,1|-j84fo0,42,42,0|-ivink1,42,42,0|-ivink0,39,44,1|-ipcic1,39,44,1|-ipcic0,42,42,0|-icqq81,42,42,0|-icqq80,39,44,1|-i6kl01,39,44,1|-i6kl00,42,42,0|-htysw1,42,42,0|-htysw0,39,44,1|-hnqt01,39,44,1|-hnqt00,42,42,0|-hb50w1,42,42,0|-hb50w0,39,44,1|-h4yvo1,39,44,1|-h4yvo0,42,42,0|-gsd3k1,42,42,0|-gsd3k0,39,44,1|-gm6yc1,39,44,1|-gm6yc0,42,42,0|-g9l681,42,42,0|-g9l680,39,44,1|-g3f101,39,44,1|-g3f100,42,42,0|-fqt8w1,42,42,0|-fqt8w0,39,44,1|-fkl901,39,44,1|-fkl900,42,42,0|-feb8w1,42,42,0|-feb8w0,39,44,1|-ewd101,39,44,1|-ewd100,42,42,0|-eq30w1,42,42,0|-eq30w0,39,44,1|-dse501,39,44,1|-dse500,42,42,0|-doj681,42,42,0|-doj680,39,44,1|-cfvuc1,39,44,1|-cfvuc0,42,42,0|-c4vgw1,42,42,0|-c4vgw0,39,44,1|-39hec1,39,44,1|-39hec0,42,42,0|-35mfk1,42,42,0|-35mfk0,39,44,1|-31nx01,39,44,1|-31nx00,42,42,0|-2pxm81,42,42,0|-2pxm80,39,44,1|-2ivzo1,39,44,1|-2ivzo0,42,42,0|-275ow1,42,42,0|-275ow0,39,44,1|-2042c1,39,44,1|-2042c0,42,42,0|-1odrk1,42,42,0|-1odrk0,39,44,1|-1fovo1,39,44,1|-1fovo0,42,42,0|-16brk1,42,42,0|-16brk0,39,44,1|-wluc1,39,44,1|-wluc0,42,42,0|-n8q81,42,42,0|-n8q80,39,44,1|-dvro1,39,44,1|-dvro0,42,42,0|-4ink1,42,42,0|-4ink0,39,44,0|24aizz,39,44,0|24aj00,40,45,1|29bxjz,40,45,1|29bxk0,39,44,0|9veobz,39,44,0|9veoc0,40,45,1|a08o7z,40,45,1|a08o80,39,44,0|abrkbz,39,44,0|abrkc0,40,45,1|aiyqvz,40,45,1|aiyqw0,39,44,0|auulnz,39,44,0|auulo0,40,45,1|b1otjz,40,45,1|b1otk0,42,42,0|bdkr3z,42,42,0|bdkr40,40,45,1|bkew7z,40,45,1|bkew80,39,44,0|bwaqzz,39,44,0|bwar00,40,45,1|c3hxjz,40,45,1|c3hxk0,39,44,0|fj0azz,39,44,0|fj0b00,39,44,1|fqtsbz,39,44,1|fqtsc0,39,44,0|jtudnz,39,44,0|jtudo0,40,45,1|jxsw7z,40,45,1|jxsw80,39,44,0|k8ytnz,39,44,0|k8yto0,40,45,1|kgiyvz,40,45,1|kgiyw0,39,44,0\",\"America/Argentina/Jujuy|,0,49,0|-138a98o,41,47,0|-px7ys1,41,47,0|-px7ys0,42,42,0|-kecq81,42,42,0|-kecq80,39,44,1|-k84qc1,39,44,1|-k84qc0,42,42,0|-jxzu81,42,42,0|-jxzu80,39,44,1|-jqwd01,39,44,1|-jqwd00,42,42,0|-jeakw1,42,42,0|-jeakw0,39,44,1|-j84fo1,39,44,1|-j84fo0,42,42,0|-ivink1,42,42,0|-ivink0,39,44,1|-ipcic1,39,44,1|-ipcic0,42,42,0|-icqq81,42,42,0|-icqq80,39,44,1|-i6kl01,39,44,1|-i6kl00,42,42,0|-htysw1,42,42,0|-htysw0,39,44,1|-hnqt01,39,44,1|-hnqt00,42,42,0|-hb50w1,42,42,0|-hb50w0,39,44,1|-h4yvo1,39,44,1|-h4yvo0,42,42,0|-gsd3k1,42,42,0|-gsd3k0,39,44,1|-gm6yc1,39,44,1|-gm6yc0,42,42,0|-g9l681,42,42,0|-g9l680,39,44,1|-g3f101,39,44,1|-g3f100,42,42,0|-fqt8w1,42,42,0|-fqt8w0,39,44,1|-fkl901,39,44,1|-fkl900,42,42,0|-feb8w1,42,42,0|-feb8w0,39,44,1|-ewd101,39,44,1|-ewd100,42,42,0|-eq30w1,42,42,0|-eq30w0,39,44,1|-dse501,39,44,1|-dse500,42,42,0|-doj681,42,42,0|-doj680,39,44,1|-cfvuc1,39,44,1|-cfvuc0,42,42,0|-c4vgw1,42,42,0|-c4vgw0,39,44,1|-39hec1,39,44,1|-39hec0,42,42,0|-35mfk1,42,42,0|-35mfk0,39,44,1|-31nx01,39,44,1|-31nx00,42,42,0|-2pxm81,42,42,0|-2pxm80,39,44,1|-2ivzo1,39,44,1|-2ivzo0,42,42,0|-275ow1,42,42,0|-275ow0,39,44,1|-2042c1,39,44,1|-2042c0,42,42,0|-1odrk1,42,42,0|-1odrk0,39,44,1|-1fovo1,39,44,1|-1fovo0,42,42,0|-16brk1,42,42,0|-16brk0,39,44,1|-wluc1,39,44,1|-wluc0,42,42,0|-n8q81,42,42,0|-n8q80,39,44,1|-dvro1,39,44,1|-dvro0,42,42,0|-4ink1,42,42,0|-4ink0,39,44,0|24aizz,39,44,0|24aj00,40,45,1|29bxjz,40,45,1|29bxk0,39,44,0|9veobz,39,44,0|9veoc0,40,45,1|a08o7z,40,45,1|a08o80,39,44,0|abrkbz,39,44,0|abrkc0,40,45,1|aiyqvz,40,45,1|aiyqw0,42,42,0|av7n3z,42,42,0|av7n40,39,44,1|b2etnz,39,44,1|b2eto0,42,42,0|bcutrz,42,42,0|bcuts0,40,45,1|bkew7z,40,45,1|bkew80,39,44,0|bwaqzz,39,44,0|bwar00,40,45,1|c3hxjz,40,45,1|c3hxk0,39,44,0|fj0azz,39,44,0|fj0b00,39,44,1|fqtsbz,39,44,1|fqtsc0,39,44,0|jtudnz,39,44,0|jtudo0,40,45,1|jxsw7z,40,45,1|jxsw80,39,44,0\",\"America/Argentina/La_Rioja|,0,50,0|-138a8yc,41,47,0|-px7ys1,41,47,0|-px7ys0,42,42,0|-kecq81,42,42,0|-kecq80,39,44,1|-k84qc1,39,44,1|-k84qc0,42,42,0|-jxzu81,42,42,0|-jxzu80,39,44,1|-jqwd01,39,44,1|-jqwd00,42,42,0|-jeakw1,42,42,0|-jeakw0,39,44,1|-j84fo1,39,44,1|-j84fo0,42,42,0|-ivink1,42,42,0|-ivink0,39,44,1|-ipcic1,39,44,1|-ipcic0,42,42,0|-icqq81,42,42,0|-icqq80,39,44,1|-i6kl01,39,44,1|-i6kl00,42,42,0|-htysw1,42,42,0|-htysw0,39,44,1|-hnqt01,39,44,1|-hnqt00,42,42,0|-hb50w1,42,42,0|-hb50w0,39,44,1|-h4yvo1,39,44,1|-h4yvo0,42,42,0|-gsd3k1,42,42,0|-gsd3k0,39,44,1|-gm6yc1,39,44,1|-gm6yc0,42,42,0|-g9l681,42,42,0|-g9l680,39,44,1|-g3f101,39,44,1|-g3f100,42,42,0|-fqt8w1,42,42,0|-fqt8w0,39,44,1|-fkl901,39,44,1|-fkl900,42,42,0|-feb8w1,42,42,0|-feb8w0,39,44,1|-ewd101,39,44,1|-ewd100,42,42,0|-eq30w1,42,42,0|-eq30w0,39,44,1|-dse501,39,44,1|-dse500,42,42,0|-doj681,42,42,0|-doj680,39,44,1|-cfvuc1,39,44,1|-cfvuc0,42,42,0|-c4vgw1,42,42,0|-c4vgw0,39,44,1|-39hec1,39,44,1|-39hec0,42,42,0|-35mfk1,42,42,0|-35mfk0,39,44,1|-31nx01,39,44,1|-31nx00,42,42,0|-2pxm81,42,42,0|-2pxm80,39,44,1|-2ivzo1,39,44,1|-2ivzo0,42,42,0|-275ow1,42,42,0|-275ow0,39,44,1|-2042c1,39,44,1|-2042c0,42,42,0|-1odrk1,42,42,0|-1odrk0,39,44,1|-1fovo1,39,44,1|-1fovo0,42,42,0|-16brk1,42,42,0|-16brk0,39,44,1|-wluc1,39,44,1|-wluc0,42,42,0|-n8q81,42,42,0|-n8q80,39,44,1|-dvro1,39,44,1|-dvro0,42,42,0|-4ink1,42,42,0|-4ink0,39,44,0|24aizz,39,44,0|24aj00,40,45,1|29bxjz,40,45,1|29bxk0,39,44,0|9veobz,39,44,0|9veoc0,40,45,1|a08o7z,40,45,1|a08o80,39,44,0|abrkbz,39,44,0|abrkc0,40,45,1|aiyqvz,40,45,1|aiyqw0,39,44,0|auulnz,39,44,0|auulo0,40,45,1|b1l47z,40,45,1|b1l480,42,42,0|b51cfz,42,42,0|b51cg0,39,44,0|bdkobz,39,44,0|bdkoc0,40,45,1|bkew7z,40,45,1|bkew80,39,44,0|bwaqzz,39,44,0|bwar00,40,45,1|c3hxjz,40,45,1|c3hxk0,39,44,0|fj0azz,39,44,0|fj0b00,39,44,1|fqtsbz,39,44,1|fqtsc0,39,44,0|hym0bz,39,44,0|hym0c0,42,42,0|hzl9rz,42,42,0|hzl9s0,39,44,0|jtudnz,39,44,0|jtudo0,40,45,1|jxsw7z,40,45,1|jxsw80,39,44,0\",\"America/Argentina/Mendoza|,0,51,0|-138a8l8,41,47,0|-px7ys1,41,47,0|-px7ys0,42,42,0|-kecq81,42,42,0|-kecq80,39,44,1|-k84qc1,39,44,1|-k84qc0,42,42,0|-jxzu81,42,42,0|-jxzu80,39,44,1|-jqwd01,39,44,1|-jqwd00,42,42,0|-jeakw1,42,42,0|-jeakw0,39,44,1|-j84fo1,39,44,1|-j84fo0,42,42,0|-ivink1,42,42,0|-ivink0,39,44,1|-ipcic1,39,44,1|-ipcic0,42,42,0|-icqq81,42,42,0|-icqq80,39,44,1|-i6kl01,39,44,1|-i6kl00,42,42,0|-htysw1,42,42,0|-htysw0,39,44,1|-hnqt01,39,44,1|-hnqt00,42,42,0|-hb50w1,42,42,0|-hb50w0,39,44,1|-h4yvo1,39,44,1|-h4yvo0,42,42,0|-gsd3k1,42,42,0|-gsd3k0,39,44,1|-gm6yc1,39,44,1|-gm6yc0,42,42,0|-g9l681,42,42,0|-g9l680,39,44,1|-g3f101,39,44,1|-g3f100,42,42,0|-fqt8w1,42,42,0|-fqt8w0,39,44,1|-fkl901,39,44,1|-fkl900,42,42,0|-feb8w1,42,42,0|-feb8w0,39,44,1|-ewd101,39,44,1|-ewd100,42,42,0|-eq30w1,42,42,0|-eq30w0,39,44,1|-dse501,39,44,1|-dse500,42,42,0|-doj681,42,42,0|-doj680,39,44,1|-cfvuc1,39,44,1|-cfvuc0,42,42,0|-c4vgw1,42,42,0|-c4vgw0,39,44,1|-39hec1,39,44,1|-39hec0,42,42,0|-35mfk1,42,42,0|-35mfk0,39,44,1|-31nx01,39,44,1|-31nx00,42,42,0|-2pxm81,42,42,0|-2pxm80,39,44,1|-2ivzo1,39,44,1|-2ivzo0,42,42,0|-275ow1,42,42,0|-275ow0,39,44,1|-2042c1,39,44,1|-2042c0,42,42,0|-1odrk1,42,42,0|-1odrk0,39,44,1|-1fovo1,39,44,1|-1fovo0,42,42,0|-16brk1,42,42,0|-16brk0,39,44,1|-wluc1,39,44,1|-wluc0,42,42,0|-n8q81,42,42,0|-n8q80,39,44,1|-dvro1,39,44,1|-dvro0,42,42,0|-4ink1,42,42,0|-4ink0,39,44,0|24aizz,39,44,0|24aj00,40,45,1|29bxjz,40,45,1|29bxk0,39,44,0|9veobz,39,44,0|9veoc0,40,45,1|a08o7z,40,45,1|a08o80,39,44,0|abrkbz,39,44,0|abrkc0,40,45,1|aiyqvz,40,45,1|aiyqw0,42,42,0|aujkfz,42,42,0|aujkg0,39,44,1|b1l6zz,39,44,1|b1l700,42,42,0|bdbhrz,42,42,0|bdbhs0,39,44,1|bkeyzz,39,44,1|bkez00,42,42,0|bwatrz,42,42,0|bwats0,40,45,1|c3hxjz,40,45,1|c3hxk0,39,44,0|fj0azz,39,44,0|fj0b00,39,44,1|fqtsbz,39,44,1|fqtsc0,39,44,0|hy5cbz,39,44,0|hy5cc0,42,42,0|i4mr3z,42,42,0|i4mr40,39,44,0|jtudnz,39,44,0|jtudo0,40,45,1|jxsw7z,40,45,1|jxsw80,39,44,0\",\"America/Argentina/Rio_Gallegos|,0,52,0|-138a8ik,41,47,0|-px7ys1,41,47,0|-px7ys0,42,42,0|-kecq81,42,42,0|-kecq80,39,44,1|-k84qc1,39,44,1|-k84qc0,42,42,0|-jxzu81,42,42,0|-jxzu80,39,44,1|-jqwd01,39,44,1|-jqwd00,42,42,0|-jeakw1,42,42,0|-jeakw0,39,44,1|-j84fo1,39,44,1|-j84fo0,42,42,0|-ivink1,42,42,0|-ivink0,39,44,1|-ipcic1,39,44,1|-ipcic0,42,42,0|-icqq81,42,42,0|-icqq80,39,44,1|-i6kl01,39,44,1|-i6kl00,42,42,0|-htysw1,42,42,0|-htysw0,39,44,1|-hnqt01,39,44,1|-hnqt00,42,42,0|-hb50w1,42,42,0|-hb50w0,39,44,1|-h4yvo1,39,44,1|-h4yvo0,42,42,0|-gsd3k1,42,42,0|-gsd3k0,39,44,1|-gm6yc1,39,44,1|-gm6yc0,42,42,0|-g9l681,42,42,0|-g9l680,39,44,1|-g3f101,39,44,1|-g3f100,42,42,0|-fqt8w1,42,42,0|-fqt8w0,39,44,1|-fkl901,39,44,1|-fkl900,42,42,0|-feb8w1,42,42,0|-feb8w0,39,44,1|-ewd101,39,44,1|-ewd100,42,42,0|-eq30w1,42,42,0|-eq30w0,39,44,1|-dse501,39,44,1|-dse500,42,42,0|-doj681,42,42,0|-doj680,39,44,1|-cfvuc1,39,44,1|-cfvuc0,42,42,0|-c4vgw1,42,42,0|-c4vgw0,39,44,1|-39hec1,39,44,1|-39hec0,42,42,0|-35mfk1,42,42,0|-35mfk0,39,44,1|-31nx01,39,44,1|-31nx00,42,42,0|-2pxm81,42,42,0|-2pxm80,39,44,1|-2ivzo1,39,44,1|-2ivzo0,42,42,0|-275ow1,42,42,0|-275ow0,39,44,1|-2042c1,39,44,1|-2042c0,42,42,0|-1odrk1,42,42,0|-1odrk0,39,44,1|-1fovo1,39,44,1|-1fovo0,42,42,0|-16brk1,42,42,0|-16brk0,39,44,1|-wluc1,39,44,1|-wluc0,42,42,0|-n8q81,42,42,0|-n8q80,39,44,1|-dvro1,39,44,1|-dvro0,42,42,0|-4ink1,42,42,0|-4ink0,39,44,0|24aizz,39,44,0|24aj00,40,45,1|29bxjz,40,45,1|29bxk0,39,44,0|9veobz,39,44,0|9veoc0,40,45,1|a08o7z,40,45,1|a08o80,39,44,0|abrkbz,39,44,0|abrkc0,40,45,1|aiyqvz,40,45,1|aiyqw0,39,44,0|auulnz,39,44,0|auulo0,40,45,1|b1otjz,40,45,1|b1otk0,39,44,0|bdkobz,39,44,0|bdkoc0,40,45,1|bkew7z,40,45,1|bkew80,39,44,0|bwaqzz,39,44,0|bwar00,40,45,1|c3hxjz,40,45,1|c3hxk0,39,44,0|fj0azz,39,44,0|fj0b00,39,44,1|fqtsbz,39,44,1|fqtsc0,39,44,0|hym0bz,39,44,0|hym0c0,42,42,0|hzl9rz,42,42,0|hzl9s0,39,44,0|jtudnz,39,44,0|jtudo0,40,45,1|jxsw7z,40,45,1|jxsw80,39,44,0\",\"America/Argentina/Salta|,0,53,0|-138a97w,41,47,0|-px7ys1,41,47,0|-px7ys0,42,42,0|-kecq81,42,42,0|-kecq80,39,44,1|-k84qc1,39,44,1|-k84qc0,42,42,0|-jxzu81,42,42,0|-jxzu80,39,44,1|-jqwd01,39,44,1|-jqwd00,42,42,0|-jeakw1,42,42,0|-jeakw0,39,44,1|-j84fo1,39,44,1|-j84fo0,42,42,0|-ivink1,42,42,0|-ivink0,39,44,1|-ipcic1,39,44,1|-ipcic0,42,42,0|-icqq81,42,42,0|-icqq80,39,44,1|-i6kl01,39,44,1|-i6kl00,42,42,0|-htysw1,42,42,0|-htysw0,39,44,1|-hnqt01,39,44,1|-hnqt00,42,42,0|-hb50w1,42,42,0|-hb50w0,39,44,1|-h4yvo1,39,44,1|-h4yvo0,42,42,0|-gsd3k1,42,42,0|-gsd3k0,39,44,1|-gm6yc1,39,44,1|-gm6yc0,42,42,0|-g9l681,42,42,0|-g9l680,39,44,1|-g3f101,39,44,1|-g3f100,42,42,0|-fqt8w1,42,42,0|-fqt8w0,39,44,1|-fkl901,39,44,1|-fkl900,42,42,0|-feb8w1,42,42,0|-feb8w0,39,44,1|-ewd101,39,44,1|-ewd100,42,42,0|-eq30w1,42,42,0|-eq30w0,39,44,1|-dse501,39,44,1|-dse500,42,42,0|-doj681,42,42,0|-doj680,39,44,1|-cfvuc1,39,44,1|-cfvuc0,42,42,0|-c4vgw1,42,42,0|-c4vgw0,39,44,1|-39hec1,39,44,1|-39hec0,42,42,0|-35mfk1,42,42,0|-35mfk0,39,44,1|-31nx01,39,44,1|-31nx00,42,42,0|-2pxm81,42,42,0|-2pxm80,39,44,1|-2ivzo1,39,44,1|-2ivzo0,42,42,0|-275ow1,42,42,0|-275ow0,39,44,1|-2042c1,39,44,1|-2042c0,42,42,0|-1odrk1,42,42,0|-1odrk0,39,44,1|-1fovo1,39,44,1|-1fovo0,42,42,0|-16brk1,42,42,0|-16brk0,39,44,1|-wluc1,39,44,1|-wluc0,42,42,0|-n8q81,42,42,0|-n8q80,39,44,1|-dvro1,39,44,1|-dvro0,42,42,0|-4ink1,42,42,0|-4ink0,39,44,0|24aizz,39,44,0|24aj00,40,45,1|29bxjz,40,45,1|29bxk0,39,44,0|9veobz,39,44,0|9veoc0,40,45,1|a08o7z,40,45,1|a08o80,39,44,0|abrkbz,39,44,0|abrkc0,40,45,1|aiyqvz,40,45,1|aiyqw0,39,44,0|auulnz,39,44,0|auulo0,40,45,1|b1otjz,40,45,1|b1otk0,42,42,0|bdkr3z,42,42,0|bdkr40,40,45,1|bkew7z,40,45,1|bkew80,39,44,0|bwaqzz,39,44,0|bwar00,40,45,1|c3hxjz,40,45,1|c3hxk0,39,44,0|fj0azz,39,44,0|fj0b00,39,44,1|fqtsbz,39,44,1|fqtsc0,39,44,0|jtudnz,39,44,0|jtudo0,40,45,1|jxsw7z,40,45,1|jxsw80,39,44,0\",\"America/Argentina/San_Juan|,0,54,0|-138a8n8,41,47,0|-px7ys1,41,47,0|-px7ys0,42,42,0|-kecq81,42,42,0|-kecq80,39,44,1|-k84qc1,39,44,1|-k84qc0,42,42,0|-jxzu81,42,42,0|-jxzu80,39,44,1|-jqwd01,39,44,1|-jqwd00,42,42,0|-jeakw1,42,42,0|-jeakw0,39,44,1|-j84fo1,39,44,1|-j84fo0,42,42,0|-ivink1,42,42,0|-ivink0,39,44,1|-ipcic1,39,44,1|-ipcic0,42,42,0|-icqq81,42,42,0|-icqq80,39,44,1|-i6kl01,39,44,1|-i6kl00,42,42,0|-htysw1,42,42,0|-htysw0,39,44,1|-hnqt01,39,44,1|-hnqt00,42,42,0|-hb50w1,42,42,0|-hb50w0,39,44,1|-h4yvo1,39,44,1|-h4yvo0,42,42,0|-gsd3k1,42,42,0|-gsd3k0,39,44,1|-gm6yc1,39,44,1|-gm6yc0,42,42,0|-g9l681,42,42,0|-g9l680,39,44,1|-g3f101,39,44,1|-g3f100,42,42,0|-fqt8w1,42,42,0|-fqt8w0,39,44,1|-fkl901,39,44,1|-fkl900,42,42,0|-feb8w1,42,42,0|-feb8w0,39,44,1|-ewd101,39,44,1|-ewd100,42,42,0|-eq30w1,42,42,0|-eq30w0,39,44,1|-dse501,39,44,1|-dse500,42,42,0|-doj681,42,42,0|-doj680,39,44,1|-cfvuc1,39,44,1|-cfvuc0,42,42,0|-c4vgw1,42,42,0|-c4vgw0,39,44,1|-39hec1,39,44,1|-39hec0,42,42,0|-35mfk1,42,42,0|-35mfk0,39,44,1|-31nx01,39,44,1|-31nx00,42,42,0|-2pxm81,42,42,0|-2pxm80,39,44,1|-2ivzo1,39,44,1|-2ivzo0,42,42,0|-275ow1,42,42,0|-275ow0,39,44,1|-2042c1,39,44,1|-2042c0,42,42,0|-1odrk1,42,42,0|-1odrk0,39,44,1|-1fovo1,39,44,1|-1fovo0,42,42,0|-16brk1,42,42,0|-16brk0,39,44,1|-wluc1,39,44,1|-wluc0,42,42,0|-n8q81,42,42,0|-n8q80,39,44,1|-dvro1,39,44,1|-dvro0,42,42,0|-4ink1,42,42,0|-4ink0,39,44,0|24aizz,39,44,0|24aj00,40,45,1|29bxjz,40,45,1|29bxk0,39,44,0|9veobz,39,44,0|9veoc0,40,45,1|a08o7z,40,45,1|a08o80,39,44,0|abrkbz,39,44,0|abrkc0,40,45,1|aiyqvz,40,45,1|aiyqw0,39,44,0|auulnz,39,44,0|auulo0,40,45,1|b1l47z,40,45,1|b1l480,42,42,0|b51cfz,42,42,0|b51cg0,39,44,0|bdkobz,39,44,0|bdkoc0,40,45,1|bkew7z,40,45,1|bkew80,39,44,0|bwaqzz,39,44,0|bwar00,40,45,1|c3hxjz,40,45,1|c3hxk0,39,44,0|fj0azz,39,44,0|fj0b00,39,44,1|fqtsbz,39,44,1|fqtsc0,39,44,0|hyk5nz,39,44,0|hyk5o0,42,42,0|i1e33z,42,42,0|i1e340,39,44,0|jtudnz,39,44,0|jtudo0,40,45,1|jxsw7z,40,45,1|jxsw80,39,44,0\",\"America/Argentina/San_Luis|,0,55,0|-138a91o,41,47,0|-px7ys1,41,47,0|-px7ys0,42,42,0|-kecq81,42,42,0|-kecq80,39,44,1|-k84qc1,39,44,1|-k84qc0,42,42,0|-jxzu81,42,42,0|-jxzu80,39,44,1|-jqwd01,39,44,1|-jqwd00,42,42,0|-jeakw1,42,42,0|-jeakw0,39,44,1|-j84fo1,39,44,1|-j84fo0,42,42,0|-ivink1,42,42,0|-ivink0,39,44,1|-ipcic1,39,44,1|-ipcic0,42,42,0|-icqq81,42,42,0|-icqq80,39,44,1|-i6kl01,39,44,1|-i6kl00,42,42,0|-htysw1,42,42,0|-htysw0,39,44,1|-hnqt01,39,44,1|-hnqt00,42,42,0|-hb50w1,42,42,0|-hb50w0,39,44,1|-h4yvo1,39,44,1|-h4yvo0,42,42,0|-gsd3k1,42,42,0|-gsd3k0,39,44,1|-gm6yc1,39,44,1|-gm6yc0,42,42,0|-g9l681,42,42,0|-g9l680,39,44,1|-g3f101,39,44,1|-g3f100,42,42,0|-fqt8w1,42,42,0|-fqt8w0,39,44,1|-fkl901,39,44,1|-fkl900,42,42,0|-feb8w1,42,42,0|-feb8w0,39,44,1|-ewd101,39,44,1|-ewd100,42,42,0|-eq30w1,42,42,0|-eq30w0,39,44,1|-dse501,39,44,1|-dse500,42,42,0|-doj681,42,42,0|-doj680,39,44,1|-cfvuc1,39,44,1|-cfvuc0,42,42,0|-c4vgw1,42,42,0|-c4vgw0,39,44,1|-39hec1,39,44,1|-39hec0,42,42,0|-35mfk1,42,42,0|-35mfk0,39,44,1|-31nx01,39,44,1|-31nx00,42,42,0|-2pxm81,42,42,0|-2pxm80,39,44,1|-2ivzo1,39,44,1|-2ivzo0,42,42,0|-275ow1,42,42,0|-275ow0,39,44,1|-2042c1,39,44,1|-2042c0,42,42,0|-1odrk1,42,42,0|-1odrk0,39,44,1|-1fovo1,39,44,1|-1fovo0,42,42,0|-16brk1,42,42,0|-16brk0,39,44,1|-wluc1,39,44,1|-wluc0,42,42,0|-n8q81,42,42,0|-n8q80,39,44,1|-dvro1,39,44,1|-dvro0,42,42,0|-4ink1,42,42,0|-4ink0,39,44,0|24aizz,39,44,0|24aj00,40,45,1|29bxjz,40,45,1|29bxk0,39,44,0|9veobz,39,44,0|9veoc0,40,45,1|a08o7z,40,45,1|a08o80,39,44,0|abrkbz,39,44,0|abrkc0,40,45,1|ajh9jz,40,45,1|ajh9k0,42,42,0|aujkfz,42,42,0|aujkg0,39,44,1|b1l6zz,39,44,1|b1l700,42,42,0|b6bn3z,42,42,0|b6bn40,39,44,0|fj0azz,39,44,0|fj0b00,39,44,1|fqtsbz,39,44,1|fqtsc0,39,44,0|hyk5nz,39,44,0|hyk5o0,42,42,0|i1e33z,42,42,0|i1e340,39,44,0|jtudnz,39,44,0|jtudo0,40,45,1|juz1jz,40,45,1|juz1k0,39,44,1|jxg0bz,39,44,1|jxg0c0,42,42,0|k8lxrz,42,42,0|k8lxs0,39,44,1|kg62zz,39,44,1|kg6300,42,42,0|krc0fz,42,42,0|krc0g0,39,44,0\",\"America/Argentina/Tucuman|,0,56,0|-138a998,41,47,0|-px7ys1,41,47,0|-px7ys0,42,42,0|-kecq81,42,42,0|-kecq80,39,44,1|-k84qc1,39,44,1|-k84qc0,42,42,0|-jxzu81,42,42,0|-jxzu80,39,44,1|-jqwd01,39,44,1|-jqwd00,42,42,0|-jeakw1,42,42,0|-jeakw0,39,44,1|-j84fo1,39,44,1|-j84fo0,42,42,0|-ivink1,42,42,0|-ivink0,39,44,1|-ipcic1,39,44,1|-ipcic0,42,42,0|-icqq81,42,42,0|-icqq80,39,44,1|-i6kl01,39,44,1|-i6kl00,42,42,0|-htysw1,42,42,0|-htysw0,39,44,1|-hnqt01,39,44,1|-hnqt00,42,42,0|-hb50w1,42,42,0|-hb50w0,39,44,1|-h4yvo1,39,44,1|-h4yvo0,42,42,0|-gsd3k1,42,42,0|-gsd3k0,39,44,1|-gm6yc1,39,44,1|-gm6yc0,42,42,0|-g9l681,42,42,0|-g9l680,39,44,1|-g3f101,39,44,1|-g3f100,42,42,0|-fqt8w1,42,42,0|-fqt8w0,39,44,1|-fkl901,39,44,1|-fkl900,42,42,0|-feb8w1,42,42,0|-feb8w0,39,44,1|-ewd101,39,44,1|-ewd100,42,42,0|-eq30w1,42,42,0|-eq30w0,39,44,1|-dse501,39,44,1|-dse500,42,42,0|-doj681,42,42,0|-doj680,39,44,1|-cfvuc1,39,44,1|-cfvuc0,42,42,0|-c4vgw1,42,42,0|-c4vgw0,39,44,1|-39hec1,39,44,1|-39hec0,42,42,0|-35mfk1,42,42,0|-35mfk0,39,44,1|-31nx01,39,44,1|-31nx00,42,42,0|-2pxm81,42,42,0|-2pxm80,39,44,1|-2ivzo1,39,44,1|-2ivzo0,42,42,0|-275ow1,42,42,0|-275ow0,39,44,1|-2042c1,39,44,1|-2042c0,42,42,0|-1odrk1,42,42,0|-1odrk0,39,44,1|-1fovo1,39,44,1|-1fovo0,42,42,0|-16brk1,42,42,0|-16brk0,39,44,1|-wluc1,39,44,1|-wluc0,42,42,0|-n8q81,42,42,0|-n8q80,39,44,1|-dvro1,39,44,1|-dvro0,42,42,0|-4ink1,42,42,0|-4ink0,39,44,0|24aizz,39,44,0|24aj00,40,45,1|29bxjz,40,45,1|29bxk0,39,44,0|9veobz,39,44,0|9veoc0,40,45,1|a08o7z,40,45,1|a08o80,39,44,0|abrkbz,39,44,0|abrkc0,40,45,1|aiyqvz,40,45,1|aiyqw0,39,44,0|auulnz,39,44,0|auulo0,40,45,1|b1otjz,40,45,1|b1otk0,42,42,0|bdkr3z,42,42,0|bdkr40,40,45,1|bkew7z,40,45,1|bkew80,39,44,0|bwaqzz,39,44,0|bwar00,40,45,1|c3hxjz,40,45,1|c3hxk0,39,44,0|fj0azz,39,44,0|fj0b00,39,44,1|fqtsbz,39,44,1|fqtsc0,39,44,0|hym0bz,39,44,0|hym0c0,42,42,0|hz8b3z,42,42,0|hz8b40,39,44,0|jtudnz,39,44,0|jtudo0,40,45,1|jxsw7z,40,45,1|jxsw80,39,44,0|k8ytnz,39,44,0|k8yto0,40,45,1|kgiyvz,40,45,1|kgiyw0,39,44,0\",\"America/Argentina/Ushuaia|,0,57,0|-138a8oo,41,47,0|-px7ys1,41,47,0|-px7ys0,42,42,0|-kecq81,42,42,0|-kecq80,39,44,1|-k84qc1,39,44,1|-k84qc0,42,42,0|-jxzu81,42,42,0|-jxzu80,39,44,1|-jqwd01,39,44,1|-jqwd00,42,42,0|-jeakw1,42,42,0|-jeakw0,39,44,1|-j84fo1,39,44,1|-j84fo0,42,42,0|-ivink1,42,42,0|-ivink0,39,44,1|-ipcic1,39,44,1|-ipcic0,42,42,0|-icqq81,42,42,0|-icqq80,39,44,1|-i6kl01,39,44,1|-i6kl00,42,42,0|-htysw1,42,42,0|-htysw0,39,44,1|-hnqt01,39,44,1|-hnqt00,42,42,0|-hb50w1,42,42,0|-hb50w0,39,44,1|-h4yvo1,39,44,1|-h4yvo0,42,42,0|-gsd3k1,42,42,0|-gsd3k0,39,44,1|-gm6yc1,39,44,1|-gm6yc0,42,42,0|-g9l681,42,42,0|-g9l680,39,44,1|-g3f101,39,44,1|-g3f100,42,42,0|-fqt8w1,42,42,0|-fqt8w0,39,44,1|-fkl901,39,44,1|-fkl900,42,42,0|-feb8w1,42,42,0|-feb8w0,39,44,1|-ewd101,39,44,1|-ewd100,42,42,0|-eq30w1,42,42,0|-eq30w0,39,44,1|-dse501,39,44,1|-dse500,42,42,0|-doj681,42,42,0|-doj680,39,44,1|-cfvuc1,39,44,1|-cfvuc0,42,42,0|-c4vgw1,42,42,0|-c4vgw0,39,44,1|-39hec1,39,44,1|-39hec0,42,42,0|-35mfk1,42,42,0|-35mfk0,39,44,1|-31nx01,39,44,1|-31nx00,42,42,0|-2pxm81,42,42,0|-2pxm80,39,44,1|-2ivzo1,39,44,1|-2ivzo0,42,42,0|-275ow1,42,42,0|-275ow0,39,44,1|-2042c1,39,44,1|-2042c0,42,42,0|-1odrk1,42,42,0|-1odrk0,39,44,1|-1fovo1,39,44,1|-1fovo0,42,42,0|-16brk1,42,42,0|-16brk0,39,44,1|-wluc1,39,44,1|-wluc0,42,42,0|-n8q81,42,42,0|-n8q80,39,44,1|-dvro1,39,44,1|-dvro0,42,42,0|-4ink1,42,42,0|-4ink0,39,44,0|24aizz,39,44,0|24aj00,40,45,1|29bxjz,40,45,1|29bxk0,39,44,0|9veobz,39,44,0|9veoc0,40,45,1|a08o7z,40,45,1|a08o80,39,44,0|abrkbz,39,44,0|abrkc0,40,45,1|aiyqvz,40,45,1|aiyqw0,39,44,0|auulnz,39,44,0|auulo0,40,45,1|b1otjz,40,45,1|b1otk0,39,44,0|bdkobz,39,44,0|bdkoc0,40,45,1|bkew7z,40,45,1|bkew80,39,44,0|bwaqzz,39,44,0|bwar00,40,45,1|c3hxjz,40,45,1|c3hxk0,39,44,0|fj0azz,39,44,0|fj0b00,39,44,1|fqtsbz,39,44,1|fqtsc0,39,44,0|hyiazz,39,44,0|hyib00,42,42,0|hzl9rz,42,42,0|hzl9s0,39,44,0|jtudnz,39,44,0|jtudo0,40,45,1|jxsw7z,40,45,1|jxsw80,39,44,0\",\"America/Aruba|,0,58,0|-u7lckd,43,59,0|-2lx4u1,43,59,0|-2lx4u0,32,42,0\",\"America/Asuncion|,0,60,0|-15r0ynk,44,60,0|-jy93zl,44,60,0|-jy93zk,42,42,0|1fnkfz,42,42,0|1fnkg0,39,44,0|27sgbz,39,44,0|27sgc0,42,42,0|2zzcfz,42,42,0|2zzcg0,39,44,1|37sqzz,39,44,1|37sr00,42,42,0|3it4fz,42,42,0|3it4g0,39,44,1|3qkobz,39,44,1|3qkoc0,42,42,0|41l1rz,42,42,0|41l1s0,39,44,1|49clnz,39,44,1|49clo0,42,42,0|4kcz3z,42,42,0|4kcz40,39,44,1|4tpxnz,39,44,1|4tpxo0,42,42,0|534wfz,42,42,0|534wg0,39,44,1|5cjpnz,39,44,1|5cjpo0,42,42,0|5lyofz,42,42,0|5lyog0,39,44,1|5vbmzz,39,44,1|5vbn00,42,42,0|64qlrz,42,42,0|64qls0,39,44,1|6e3kbz,39,44,1|6e3kc0,42,42,0|6nij3z,42,42,0|6nij40,39,44,1|6wvhnz,39,44,1|6wvho0,42,42,0|76agfz,42,42,0|76agg0,39,44,1|7fp9nz,39,44,1|7fp9o0,42,42,0|7p48fz,42,42,0|7p48g0,39,44,1|7yh6zz,39,44,1|7yh700,42,42,0|87w5rz,42,42,0|87w5s0,39,44,1|8h94bz,39,44,1|8h94c0,42,42,0|8qo33z,42,42,0|8qo340,39,44,1|9011nz,39,44,1|9011o0,42,42,0|99g0fz,42,42,0|99g0g0,39,44,1|9iutnz,39,44,1|9iuto0,42,42,0|9s9sfz,42,42,0|9s9sg0,39,44,1|a1mqzz,39,44,1|a1mr00,42,42,0|ac4lrz,42,42,0|ac4ls0,39,44,1|akeobz,39,44,1|akeoc0,42,42,0|attn3z,42,42,0|attn40,39,44,1|b36lnz,39,44,1|b36lo0,42,42,0|bcutrz,42,42,0|bcuts0,39,44,1|bkeyzz,39,44,1|bkez00,42,42,0|bvmr3z,42,42,0|bvmr40,39,44,1|c4qgbz,39,44,1|c4qgc0,42,42,0|ce79rz,42,42,0|ce79s0,39,44,1|clv4bz,39,44,1|clv4c0,42,42,0|cwz73z,42,42,0|cwz740,39,44,1|d4l6zz,39,44,1|d4l700,42,42,0|dfr4fz,42,42,0|dfr4g0,39,44,1|dnkizz,39,44,1|dnkj00,42,42,0|dyu5rz,42,42,0|dyu5s0,39,44,1|e61cbz,39,44,1|e61cc0,42,42,0|ehk8fz,42,42,0|ehk8g0,39,44,1|ep4dnz,39,44,1|ep4do0,42,42,0|f0ab3z,42,42,0|f0ab40,39,44,1|f87ezz,39,44,1|f87f00,42,42,0|fj0drz,42,42,0|fj0ds0,39,44,1|fqxhnz,39,44,1|fqxho0,42,42,0|g1qgfz,42,42,0|g1qgg0,39,44,1|g9nkbz,39,44,1|g9nkc0,42,42,0|gkthrz,42,42,0|gkths0,39,44,1|gu6gbz,39,44,1|gu6gc0,42,42,0|h1qr3z,42,42,0|h1qr40,39,44,1|hcwizz,39,44,1|hcwj00,42,42,0|hktsfz,42,42,0|hktsg0,39,44,1|hvmlnz,39,44,1|hvmlo0,42,42,0|i5pn3z,42,42,0|i5pn40,39,44,1|id9sbz,39,44,1|id9sc0,42,42,0|iofprz,42,42,0|iofps0,39,44,1|ivzuzz,39,44,1|ivzv00,42,42,0|j75sfz,42,42,0|j75sg0,39,44,1|jepxnz,39,44,1|jepxo0,42,42,0|jq8trz,42,42,0|jq8ts0,39,44,1|jxg0bz,39,44,1|jxg0c0,42,42,0|k8ywfz,42,42,0|k8ywg0,39,44,1|kg62zz,39,44,1|kg6300,42,42,0|kroz3z,42,42,0|kroz40,39,44,1|l0oyzz,39,44,1|l0oz00,42,42,0|l9p4fz,42,42,0|l9p4g0,39,44,1|ljf1nz,39,44,1|ljf1o0,42,42,0|lsf73z,42,42,0|lsf740,39,44,1|m254bz,39,44,1|m254c0,42,42,0|mbi8fz,42,42,0|mbi8g0,39,44,1|mk59nz,39,44,1|mk59o0,42,42,0|mu8b3z,42,42,0|mu8b40,39,44,1|n2vcbz,39,44,1|n2vcc0,42,42,0|ncydrz,42,42,0|ncyds0,39,44,1|nllezz,39,44,1|nllf00,42,42,0|nvogfz,42,42,0|nvogg0,39,44,1|o4ogbz,39,44,1|o4ogc0,42,42,0|oeej3z,42,42,0|oeej40,39,44,1|oneizz,39,44,1|onej00,42,42,0|ox4lrz,42,42,0|ox4ls0,39,44,1|p64lnz,39,44,1|p64lo0,42,42,0|pg7n3z,42,42,0|pg7n40,39,44,1|pouobz,39,44,1|pouoc0,42,42,0|pyxprz,42,42,0|pyxps0,39,44,1|q7kqzz,39,44,1|q7kr00,42,42,0|qhnsfz,42,42,0|qhnsg0,39,44,1|qqnsbz,39,44,1|qqnsc0,42,42,0|r0dv3z,42,42,0|r0dv40,39,44,1|r9duzz,39,44,1|r9dv00,42,42,0|rj3xrz,42,42,0|rj3xs0,39,44,1|rs3xnz,39,44,1|rs3xo0,42,42,0|s1u0fz,42,42,0|s1u0g0,39,44,1|sau0bz,39,44,1|sau0c0,42,42,0|skx1rz,42,42,0|skx1s0,39,44,1|stk2zz,39,44,1|stk300,42,42,0|t3n4fz,42,42,0|t3n4g0,39,44,1|tca5nz,39,44,1|tca5o0,42,42,0|tmd73z,42,42,0|tmd740,39,44,1|tvd6zz,39,44,1|tvd700,42,42,0|u539rz,42,42,0|u539s0,39,44,1|ue39nz,39,44,1|ue39o0,42,42,0|untcfz,42,42,0|untcg0,39,44,1|uwtcbz,39,44,1|uwtcc0,42,42,0|v6wdrz,42,42,0|v6wds0,39,44,1|vfjezz,39,44,1|vfjf00,42,42,0|vpmgfz,42,42,0|vpmgg0,39,44,1|vy9hnz,39,44,1|vy9ho0,42,42,0|w8cj3z,42,42,0|w8cj40,39,44,1|whcizz,39,44,1|whcj00,42,42,0|wr2lrz,42,42,0|wr2ls0,39,44,1|x02lnz,39,44,1|x02lo0,42,42,0|x9sofz,42,42,0|x9sog0,39,44,1|xisobz,39,44,1|xisoc0,42,42,0|xsir3z,42,42,0|xsir40,39,44,1|y1iqzz,39,44,1|y1ir00,42,42,0|yblsfz,42,42,0|yblsg0,39,44,1|yk8tnz,39,44,1|yk8to0,42,42,0|yubv3z,42,42,0|yubv40,39,44,1|z2ywbz,39,44,1|z2ywc0,42,42,0|zd1xrz,42,42,0|zd1xs0,39,44,1\",\"America/Atikokan|,0,61,0|-1353b18,45,62,0|-qzov41,45,62,0|-qzov40,46,63,1|-qplz81,46,63,1|-qplz80,45,62,0|-f9ofc1,45,62,0|-f9ofc0,46,63,1|-ek21s1,46,63,1|-ek21s0,47,63,1|-cq2tg1,47,63,1|-cq2tg0,48,63,1|-cnp0k1,48,63,1|-cnp0k0,49,63,0\",\"America/Bahia|,0,64,0|-t85kv8,39,44,0|-jylag1,39,44,0|-jylag0,40,45,1|-jpb141,40,45,1|-jpb140,39,44,0|-jfsd01,39,44,0|-jfsd00,40,45,1|-j6j3s1,40,45,1|-j6j3s0,39,44,0|-ahcyc1,39,44,0|-ahcyc0,40,45,1|-aad3o1,40,45,1|-aad3o0,39,44,0|-9yl101,39,44,0|-9yl100,40,45,1|-9sd141,40,45,1|-9sd140,39,44,0|-9ft3o1,39,44,0|-9ft3o0,40,45,1|-99j941,40,45,1|-99j940,39,44,0|-8wzbo1,39,44,0|-8wzbo0,40,45,1|-8scqg1,40,45,1|-8scqg0,39,44,0|-35xmc1,39,44,0|-35xmc0,40,45,1|-31nzs1,40,45,1|-31nzs0,39,44,0|-2kdp01,39,44,0|-2kdp00,40,45,1|-2hcig1,40,45,1|-2hcig0,39,44,0|-24qqc1,39,44,0|-24qqc0,40,45,1|-204541,40,45,1|-204540,39,44,0|-1nid01,39,44,0|-1nid00,40,45,1|-1hc7s1,40,45,1|-1hc7s0,39,44,0|-14qfo1,39,44,0|-14qfo0,40,45,1|-yifs1,40,45,1|-yifs0,39,44,0|89jcbz,39,44,0|89jcc0,40,45,1|8gdk7z,40,45,1|8gdk80,39,44,0|8rwgbz,39,44,0|8rwgc0,40,45,1|8xns7z,40,45,1|8xns80,39,44,0|9aodnz,39,44,0|9aodo0,40,45,1|9g2qvz,40,45,1|9g2qw0,39,44,0|9t1hnz,39,44,0|9t1ho0,40,45,1|9yfuvz,40,45,1|9yfuw0,39,44,0|abrkbz,39,44,0|abrkc0,40,45,1|ahvuvz,40,45,1|ahvuw0,39,44,0|auulnz,39,44,0|auulo0,40,45,1|b0yw7z,40,45,1|b0yw80,39,44,0|bdkobz,39,44,0|bdkoc0,40,45,1|bjc07z,40,45,1|bjc080,39,44,0|bwnpnz,39,44,0|bwnpo0,40,45,1|c1p47z,40,45,1|c1p480,39,44,0|cf0tnz,39,44,0|cf0to0,40,45,1|cli2vz,40,45,1|cli2w0,39,44,0|cxqwbz,39,44,0|cxqwc0,40,45,1|d485jz,40,45,1|d485k0,39,44,0|dggyzz,39,44,0|dggz00,40,45,1|dml9jz,40,45,1|dml9k0,39,44,0|dyu2zz,39,44,0|dyu300,40,45,1|e5oavz,40,45,1|e5oaw0,39,44,0|ehm0bz,39,44,0|ehm0c0,40,45,1|ep4avz,40,45,1|ep4aw0,39,44,0|f0n6zz,39,44,0|f0n700,40,45,1|f7hevz,40,45,1|f7hew0,39,44,0|fj0azz,39,44,0|fj0b00,40,45,1|fqkg7z,40,45,1|fqkg80,39,44,0|g23cbz,39,44,0|g23cc0,40,45,1|g8xk7z,40,45,1|g8xk80,39,44,0|gl6dnz,39,44,0|gl6do0,40,45,1|grnmvz,40,45,1|grnmw0,39,44,0|h4zcbz,39,44,0|h4zcc0,40,45,1|hadpjz,40,45,1|hadpk0,39,44,0|lt51nz,39,44,0|lt51o0,40,45,1|lzz9jz,40,45,1|lzz9k0,39,44,0\",\"America/Bahia_Banderas|,0,65,0|-p1u4k0,50,66,0|-m7mko1,50,66,0|-m7mko0,45,62,0|-kf67c1,45,62,0|-kf67c0,50,66,0|-k6j3c1,50,66,0|-k6j3c0,45,62,0|-jypm01,45,62,0|-jypm00,50,66,0|-jpan81,50,66,0|-jpan80,45,62,0|-eg9601,45,62,0|-eg9600,50,66,0|-axv381,50,66,0|-axv380,51,40,0|m7z,51,40,0|m80,50,66,0|dphibz,50,66,0|dphic0,52,62,1|dzxcvz,52,62,1|dzxcw0,50,66,0|e87kzz,50,66,0|e87l00,52,62,1|einfjz,52,62,1|einfk0,50,66,0|eqxnnz,50,66,0|eqxno0,52,62,1|f1di7z,52,62,1|f1di80,50,66,0|f9nqbz,50,66,0|f9nqc0,52,62,1|fkgjjz,52,62,1|fkgjk0,50,66,0|fsdszz,50,66,0|fsdt00,52,62,1|g36m7z,52,62,1|g36m80,50,66,0|gcwozz,50,66,0|gcwp00,52,62,1|gkgu7z,52,62,1|gkgu80,50,66,0|gu6wzz,50,66,0|gu6x00,52,62,1|h4mrjz,52,62,1|h4mrk0,50,66,0|hcwznz,50,66,0|hcwzo0,52,62,1|hncu7z,52,62,1|hncu80,50,66,0|hvn2bz,50,66,0|hvn2c0,52,62,1|i6fvjz,52,62,1|i6fvk0,50,66,0|ied4zz,50,66,0|ied500,52,62,1|ip5y7z,52,62,1|ip5y80,50,66,0|ix37nz,50,66,0|ix37o0,52,62,1|j7w0vz,52,62,1|j7w0w0,50,66,0|jftabz,50,66,0|jftac0,52,62,1|jqm3jz,52,62,1|jqm3k0,50,66,0|jywbnz,50,66,0|jywbo0,52,62,1|k9c67z,52,62,1|k9c680,50,66,0|khmebz,50,66,0|khmec0,52,62,1|ks28vz,52,62,1|ks28w0,50,66,0|l0cgzz,50,66,0|l0ch00,46,63,1|lb57fz,46,63,1|lb57g0,45,62,0|lj2gvz,45,62,0|lj2gw0,46,63,1|ltva3z,46,63,1|ltva40,45,62,0|m1sjjz,45,62,0|m1sjk0,46,63,1|mclcrz,46,63,1|mclcs0,45,62,0|mkvkvz,45,62,0|mkvkw0,46,63,1|mvbffz,46,63,1|mvbfg0,45,62,0|n3lnjz,45,62,0|n3lnk0,46,63,1|ne1i3z,46,63,1|ne1i40,45,62,0|nmbq7z,45,62,0|nmbq80,46,63,1|nwrkrz,46,63,1|nwrks0,45,62,0|o51svz,45,62,0|o51sw0,46,63,1|ofum3z,46,63,1|ofum40,45,62,0|onrvjz,45,62,0|onrvk0,46,63,1|oykorz,46,63,1|oykos0,45,62,0|p6hy7z,45,62,0|p6hy80,46,63,1|pharfz,46,63,1|pharg0,45,62,0|ppkzjz,45,62,0|ppkzk0,46,63,1|q00u3z,46,63,1|q00u40,45,62,0|q8b27z,45,62,0|q8b280,46,63,1|qiqwrz,46,63,1|qiqws0,45,62,0|qr14vz,45,62,0|qr14w0,46,63,1|r1ty3z,46,63,1|r1ty40,45,62,0|r9r7jz,45,62,0|r9r7k0,46,63,1|rkk0rz,46,63,1|rkk0s0,45,62,0|rsha7z,45,62,0|rsha80,46,63,1|s3a3fz,46,63,1|s3a3g0,45,62,0|sbkbjz,45,62,0|sbkbk0,46,63,1|sm063z,46,63,1|sm0640,45,62,0|suae7z,45,62,0|suae80,46,63,1|t4q8rz,46,63,1|t4q8s0,45,62,0|td0gvz,45,62,0|td0gw0,46,63,1|tngbfz,46,63,1|tngbg0,45,62,0|tvqjjz,45,62,0|tvqjk0,46,63,1|u6jcrz,46,63,1|u6jcs0,45,62,0|uegm7z,45,62,0|uegm80,46,63,1|up9ffz,46,63,1|up9fg0,45,62,0|ux6ovz,45,62,0|ux6ow0,46,63,1|v7zi3z,46,63,1|v7zi40,45,62,0|vg9q7z,45,62,0|vg9q80,46,63,1|vqpkrz,46,63,1|vqpks0,45,62,0|vyzsvz,45,62,0|vyzsw0,46,63,1|w9fnfz,46,63,1|w9fng0,45,62,0|whpvjz,45,62,0|whpvk0,46,63,1|wsiorz,46,63,1|wsios0,45,62,0|x0fy7z,45,62,0|x0fy80,46,63,1|xb8rfz,46,63,1|xb8rg0,45,62,0|xj60vz,45,62,0|xj60w0,46,63,1|xtyu3z,46,63,1|xtyu40,45,62,0|y1w3jz,45,62,0|y1w3k0,46,63,1|ycowrz,46,63,1|ycows0,45,62,0|ykz4vz,45,62,0|ykz4w0,46,63,1|yvezfz,46,63,1|yvezg0,45,62,0|z3p7jz,45,62,0|z3p7k0,46,63,1|ze523z,46,63,1|ze5240,45,62,0\",\"America/Barbados|,0,67,0|-o0aiaj,53,67,0|-jtzeak,53,67,0|-jtzeaj,32,42,0|3vvnbz,32,42,0|3vvnc0,54,44,1|41mz7z,54,44,1|41mz80,32,42,0|4bq0nz,32,42,0|4bq0o0,54,44,1|4kd1vz,54,44,1|4kd1w0,32,42,0|4ug3bz,32,42,0|4ug3c0,54,44,1|5334jz,54,44,1|5334k0,32,42,0|5dj4nz,32,42,0|5dj4o0,54,44,1|5lnn7z,54,44,1|5lnn80,32,42,0\",\"America/Belem|,0,68,0|-t85j0s,39,44,0|-jylag1,39,44,0|-jylag0,40,45,1|-jpb141,40,45,1|-jpb140,39,44,0|-jfsd01,39,44,0|-jfsd00,40,45,1|-j6j3s1,40,45,1|-j6j3s0,39,44,0|-ahcyc1,39,44,0|-ahcyc0,40,45,1|-aad3o1,40,45,1|-aad3o0,39,44,0|-9yl101,39,44,0|-9yl100,40,45,1|-9sd141,40,45,1|-9sd140,39,44,0|-9ft3o1,39,44,0|-9ft3o0,40,45,1|-99j941,40,45,1|-99j940,39,44,0|-8wzbo1,39,44,0|-8wzbo0,40,45,1|-8scqg1,40,45,1|-8scqg0,39,44,0|-35xmc1,39,44,0|-35xmc0,40,45,1|-31nzs1,40,45,1|-31nzs0,39,44,0|-2kdp01,39,44,0|-2kdp00,40,45,1|-2hcig1,40,45,1|-2hcig0,39,44,0|-24qqc1,39,44,0|-24qqc0,40,45,1|-204541,40,45,1|-204540,39,44,0|-1nid01,39,44,0|-1nid00,40,45,1|-1hc7s1,40,45,1|-1hc7s0,39,44,0|-14qfo1,39,44,0|-14qfo0,40,45,1|-yifs1,40,45,1|-yifs0,39,44,0|89jcbz,39,44,0|89jcc0,40,45,1|8gdk7z,40,45,1|8gdk80,39,44,0|8rwgbz,39,44,0|8rwgc0,40,45,1|8xns7z,40,45,1|8xns80,39,44,0|9aodnz,39,44,0|9aodo0,40,45,1|9g2qvz,40,45,1|9g2qw0,39,44,0\",\"America/Belize|,0,69,0|-u52ic0,45,62,0|-qqoy01,45,62,0|-qqoy00,55,70,1|-qk7ne1,55,70,1|-qk7ne0,45,62,0|-q7yvc1,45,62,0|-q7yvc0,55,70,1|-q14m21,55,70,1|-q14m20,45,62,0|-pp8so1,45,62,0|-pp8so0,55,70,1|-pieje1,55,70,1|-pieje0,45,62,0|-p6iq01,45,62,0|-p6iq00,55,70,1|-ozogq1,55,70,1|-ozogq0,45,62,0|-onfoo1,45,62,0|-onfoo0,55,70,1|-ogye21,55,70,1|-ogye20,45,62,0|-o4pm01,45,62,0|-o4pm00,55,70,1|-ny8be1,55,70,1|-ny8be0,45,62,0|-nlzjc1,45,62,0|-nlzjc0,55,70,1|-nf5a21,55,70,1|-nf5a20,45,62,0|-n39go1,45,62,0|-n39go0,55,70,1|-mwf7e1,55,70,1|-mwf7e0,45,62,0|-mkje01,45,62,0|-mkje00,55,70,1|-mdp4q1,55,70,1|-mdp4q0,45,62,0|-m1tbc1,45,62,0|-m1tbc0,55,70,1|-luz221,55,70,1|-luz220,45,62,0|-liqa01,45,62,0|-liqa00,55,70,1|-lc8ze1,55,70,1|-lc8ze0,45,62,0|-l007c1,45,62,0|-l007c0,55,70,1|-ktiwq1,55,70,1|-ktiwq0,45,62,0|-kha4o1,45,62,0|-kha4o0,55,70,1|-kafve1,55,70,1|-kafve0,45,62,0|-jyk201,45,62,0|-jyk200,55,70,1|-jrpsq1,55,70,1|-jrpsq0,45,62,0|-jftzc1,45,62,0|-jftzc0,55,70,1|-j8zq21,55,70,1|-j8zq20,45,62,0|-iwqy01,45,62,0|-iwqy00,55,70,1|-iq9ne1,55,70,1|-iq9ne0,45,62,0|-ie0vc1,45,62,0|-ie0vc0,55,70,1|-i7jkq1,55,70,1|-i7jkq0,45,62,0|-hvaso1,45,62,0|-hvaso0,55,70,1|-hoti21,55,70,1|-hoti20,45,62,0|-hckq01,45,62,0|-hckq00,55,70,1|-h5qgq1,55,70,1|-h5qgq0,45,62,0|-gtunc1,45,62,0|-gtunc0,55,70,1|-gn0e21,55,70,1|-gn0e20,45,62,0|-gb4ko1,45,62,0|-gb4ko0,55,70,1|-g4abe1,55,70,1|-g4abe0,45,62,0|-fs1jc1,45,62,0|-fs1jc0,55,70,1|-flk8q1,55,70,1|-flk8q0,45,62,0|-f9bgo1,45,62,0|-f9bgo0,55,70,1|-f2u621,55,70,1|-f2u620,45,62,0|-eqle01,45,62,0|-eqle00,55,70,1|-ejr4q1,55,70,1|-ejr4q0,45,62,0|-ecwso1,45,62,0|-ecwso0,47,63,1|-cq2tg1,47,63,1|-cq2tg0,48,63,1|-cjqks1,48,63,1|-cjqks0,45,62,0|-blvzc1,45,62,0|-blvzc0,55,70,1|-bf1q21,55,70,1|-bf1q20,45,62,0|-b35wo1,45,62,0|-b35wo0,55,70,1|-awbne1,55,70,1|-awbne0,45,62,0|-akfu01,45,62,0|-akfu00,55,70,1|-adlkq1,55,70,1|-adlkq0,45,62,0|-a1cso1,45,62,0|-a1cso0,55,70,1|-9uvi21,55,70,1|-9uvi20,45,62,0|-9imq01,45,62,0|-9imq00,55,70,1|-9c5fe1,55,70,1|-9c5fe0,45,62,0|-8zwnc1,45,62,0|-8zwnc0,55,70,1|-8t2e21,55,70,1|-8t2e20,45,62,0|-8h6ko1,45,62,0|-8h6ko0,55,70,1|-8acbe1,55,70,1|-8acbe0,45,62,0|-7ygi01,45,62,0|-7ygi00,55,70,1|-7rm8q1,55,70,1|-7rm8q0,45,62,0|-7fqfc1,45,62,0|-7fqfc0,55,70,1|-78w621,55,70,1|-78w620,45,62,0|-6wne01,45,62,0|-6wne00,55,70,1|-6q63e1,55,70,1|-6q63e0,45,62,0|-6dxbc1,45,62,0|-6dxbc0,55,70,1|-67g0q1,55,70,1|-67g0q0,45,62,0|-5v78o1,45,62,0|-5v78o0,55,70,1|-5ocze1,55,70,1|-5ocze0,45,62,0|-5ch601,45,62,0|-5ch600,55,70,1|-55mwq1,55,70,1|-55mwq0,45,62,0|-4tr3c1,45,62,0|-4tr3c0,55,70,1|-4mwu21,55,70,1|-4mwu20,45,62,0|-4ao201,45,62,0|-4ao200,55,70,1|-446re1,55,70,1|-446re0,45,62,0|-3rxzc1,45,62,0|-3rxzc0,55,70,1|-3lgoq1,55,70,1|-3lgoq0,45,62,0|-397wo1,45,62,0|-397wo0,55,70,1|-32qm21,55,70,1|-32qm20,45,62,0|-2qhu01,45,62,0|-2qhu00,55,70,1|-2jnkq1,55,70,1|-2jnkq0,45,62,0|-27rrc1,45,62,0|-27rrc0,55,70,1|-20xi21,55,70,1|-20xi20,45,62,0|-1p1oo1,45,62,0|-1p1oo0,55,70,1|-1i7fe1,55,70,1|-1i7fe0,45,62,0|-15ync1,45,62,0|-15ync0,55,70,1|-zhcq1,55,70,1|-zhcq0,45,62,0|21s0nz,45,62,0|21s0o0,46,63,1|2565vz,46,63,1|2565w0,45,62,0|6rj4nz,45,62,0|6rj4o0,46,63,1|6uer7z,46,63,1|6uer80,45,62,0\",\"America/Blanc-Sablon|,0,71,0|-18vs838,32,42,0|-qzp0o1,32,42,0|-qzp0o0,54,44,1|-qpm4s1,54,44,1|-qpm4s0,32,42,0|-ek27c1,32,42,0|-ek27c0,33,44,1|-cq2tg1,33,44,1|-cq2tg0,34,44,1|-cnp641,34,44,1|-cnp640,32,42,0\",\"America/Boa_Vista|,0,72,0|-t85grk,42,42,0|-jyl7o1,42,42,0|-jyl7o0,39,44,1|-jpayc1,39,44,1|-jpayc0,42,42,0|-jfsa81,42,42,0|-jfsa80,39,44,1|-j6j101,39,44,1|-j6j100,42,42,0|-ahcvk1,42,42,0|-ahcvk0,39,44,1|-aad0w1,39,44,1|-aad0w0,42,42,0|-9yky81,42,42,0|-9yky80,39,44,1|-9scyc1,39,44,1|-9scyc0,42,42,0|-9ft0w1,42,42,0|-9ft0w0,39,44,1|-99j6c1,39,44,1|-99j6c0,42,42,0|-8wz8w1,42,42,0|-8wz8w0,39,44,1|-8scno1,39,44,1|-8scno0,42,42,0|-35xjk1,42,42,0|-35xjk0,39,44,1|-31nx01,39,44,1|-31nx00,42,42,0|-2kdm81,42,42,0|-2kdm80,39,44,1|-2hcfo1,39,44,1|-2hcfo0,42,42,0|-24qnk1,42,42,0|-24qnk0,39,44,1|-2042c1,39,44,1|-2042c0,42,42,0|-1nia81,42,42,0|-1nia80,39,44,1|-1hc501,39,44,1|-1hc500,42,42,0|-14qcw1,42,42,0|-14qcw0,39,44,1|-yid01,39,44,1|-yid00,42,42,0|89jf3z,42,42,0|89jf40,39,44,1|8gdmzz,39,44,1|8gdn00,42,42,0|8rwj3z,42,42,0|8rwj40,39,44,1|8xnuzz,39,44,1|8xnv00,42,42,0|9aogfz,42,42,0|9aogg0,39,44,1|9g2tnz,39,44,1|9g2to0,42,42,0|fj0drz,42,42,0|fj0ds0,39,44,1|fqkizz,39,44,1|fqkj00,42,42,0|g23f3z,42,42,0|g23f40,39,44,1|g2gazz,39,44,1|g2gb00,42,42,0\",\"America/Bogota|,0,73,0|-18s2sy8,53,73,0|-srdoy9,53,73,0|-srdoy8,56,63,0|bnnsjz,56,63,0|bnnsk0,42,42,1|c4xxrz,42,42,1|c4xxs0,56,63,0\",\"America/Boise|,0,74,0|-18y0gg0,51,40,0|-r0emw1,51,40,0|-r0emw0,57,66,1|-qplto1,57,66,1|-qplto0,51,40,0|-qhok81,51,40,0|-qhok80,57,66,1|-q6vr01,57,66,1|-q6vr00,51,40,0|-oc9iw1,51,40,0|-oc9iw0,50,66,0|-ek1z01,50,66,0|-ek1z00,58,62,1|-cq2tg1,58,62,1|-cq2tg0,59,62,1|-cnoxs1,59,62,1|-cnoxs0,50,66,0|-1e8kc1,50,66,0|-1e8kc0,52,62,1|-14vls1,52,62,1|-14vls0,50,66,0|-viho1,50,66,0|-viho0,52,62,1|-m5j41,52,62,1|-m5j40,50,66,0|-csf01,50,66,0|-csf00,52,62,1|-3fgg1,52,62,1|-3fgg0,50,66,0|5xnnz,50,66,0|5xno0,52,62,1|fam7z,52,62,1|fam80,50,66,0|onqbz,50,66,0|onqc0,52,62,1|ydnjz,52,62,1|ydnk0,50,66,0|17qrnz,50,66,0|17qro0,52,62,1|1h3q7z,52,62,1|1h3q80,50,66,0|1qgubz,50,66,0|1qguc0,52,62,1|1ztsvz,52,62,1|1ztsw0,50,66,0|24vczz,50,66,0|24vd00,52,62,1|2ijvjz,52,62,1|2ijvk0,50,66,0|2oobnz,50,66,0|2oobo0,52,62,1|319y7z,52,62,1|319y80,50,66,0|3an2bz,50,66,0|3an2c0,52,62,1|3kczjz,52,62,1|3kczk0,50,66,0|3td4zz,50,66,0|3td500,52,62,1|43327z,52,62,1|433280,50,66,0|4cg6bz,50,66,0|4cg6c0,52,62,1|4lt4vz,52,62,1|4lt4w0,50,66,0|4v68zz,50,66,0|4v6900,52,62,1|54j7jz,52,62,1|54j7k0,50,66,0|5dwbnz,50,66,0|5dwbo0,52,62,1|5n9a7z,52,62,1|5n9a80,50,66,0|5wmebz,50,66,0|5wmec0,52,62,1|65zcvz,52,62,1|65zcw0,50,66,0|6fcgzz,50,66,0|6fch00,52,62,1|6p2e7z,52,62,1|6p2e80,50,66,0|6y2jnz,50,66,0|6y2jo0,52,62,1|77sgvz,52,62,1|77sgw0,50,66,0|7h5kzz,50,66,0|7h5l00,52,62,1|7qijjz,52,62,1|7qijk0,50,66,0|7zvnnz,50,66,0|7zvno0,52,62,1|898m7z,52,62,1|898m80,50,66,0|8ilqbz,50,66,0|8ilqc0,52,62,1|8ryovz,52,62,1|8ryow0,50,66,0|908wzz,50,66,0|908x00,52,62,1|9aorjz,52,62,1|9aork0,50,66,0|9iyznz,50,66,0|9iyzo0,52,62,1|9trsvz,52,62,1|9trsw0,50,66,0|a1p2bz,50,66,0|a1p2c0,52,62,1|achvjz,52,62,1|achvk0,50,66,0|akf4zz,50,66,0|akf500,52,62,1|av7y7z,52,62,1|av7y80,50,66,0|b3i6bz,50,66,0|b3i6c0,52,62,1|bdy0vz,52,62,1|bdy0w0,50,66,0|bm88zz,50,66,0|bm8900,52,62,1|bwo3jz,52,62,1|bwo3k0,50,66,0|c4ybnz,50,66,0|c4ybo0,52,62,1|cfr4vz,52,62,1|cfr4w0,50,66,0|cnoebz,50,66,0|cnoec0,52,62,1|cyh7jz,52,62,1|cyh7k0,50,66,0|d6egzz,50,66,0|d6eh00,52,62,1|dh7a7z,52,62,1|dh7a80,50,66,0|dphibz,50,66,0|dphic0,52,62,1|dzxcvz,52,62,1|dzxcw0,50,66,0|e87kzz,50,66,0|e87l00,52,62,1|einfjz,52,62,1|einfk0,50,66,0|eqxnnz,50,66,0|eqxno0,52,62,1|f1di7z,52,62,1|f1di80,50,66,0|f9nqbz,50,66,0|f9nqc0,52,62,1|fkgjjz,52,62,1|fkgjk0,50,66,0|fsdszz,50,66,0|fsdt00,52,62,1|g36m7z,52,62,1|g36m80,50,66,0|gb3vnz,50,66,0|gb3vo0,52,62,1|glwovz,52,62,1|glwow0,50,66,0|gu6wzz,50,66,0|gu6x00,52,62,1|h4mrjz,52,62,1|h4mrk0,50,66,0|hcwznz,50,66,0|hcwzo0,52,62,1|hncu7z,52,62,1|hncu80,50,66,0|hvn2bz,50,66,0|hvn2c0,52,62,1|i6fvjz,52,62,1|i6fvk0,50,66,0|ied4zz,50,66,0|ied500,52,62,1|ip5y7z,52,62,1|ip5y80,50,66,0|ix37nz,50,66,0|ix37o0,52,62,1|j7w0vz,52,62,1|j7w0w0,50,66,0|jeqebz,50,66,0|jeqec0,52,62,1|jqz27z,52,62,1|jqz280,50,66,0|jxggzz,50,66,0|jxgh00,52,62,1|k9p4vz,52,62,1|k9p4w0,50,66,0|kg6jnz,50,66,0|kg6jo0,52,62,1|ksf7jz,52,62,1|ksf7k0,50,66,0|kz9kzz,50,66,0|kz9l00,52,62,1|lbi8vz,52,62,1|lbi8w0,50,66,0|lhznnz,50,66,0|lhzno0,52,62,1|lu8bjz,52,62,1|lu8bk0,50,66,0|m0pqbz,50,66,0|m0pqc0,52,62,1|mcye7z,52,62,1|mcye80,50,66,0|mjfszz,50,66,0|mjft00,52,62,1|mvogvz,52,62,1|mvogw0,50,66,0|n25vnz,50,66,0|n25vo0,52,62,1|neejjz,52,62,1|neejk0,50,66,0|nkvybz,50,66,0|nkvyc0,52,62,1|nx4m7z,52,62,1|nx4m80,50,66,0|o3yznz,50,66,0|o3yzo0,52,62,1|og7njz,52,62,1|og7nk0,50,66,0|omp2bz,50,66,0|omp2c0,52,62,1|oyxq7z,52,62,1|oyxq80,50,66,0|p5f4zz,50,66,0|p5f500,52,62,1|phnsvz,52,62,1|phnsw0,50,66,0|po57nz,50,66,0|po57o0,52,62,1|q0dvjz,52,62,1|q0dvk0,50,66,0|q6vabz,50,66,0|q6vac0,52,62,1|qj3y7z,52,62,1|qj3y80,50,66,0|qpybnz,50,66,0|qpybo0,52,62,1|r26zjz,52,62,1|r26zk0,50,66,0|r8oebz,50,66,0|r8oec0,52,62,1|rkx27z,52,62,1|rkx280,50,66,0|rregzz,50,66,0|rreh00,52,62,1|s3n4vz,52,62,1|s3n4w0,50,66,0|sa4jnz,50,66,0|sa4jo0,52,62,1|smd7jz,52,62,1|smd7k0,50,66,0|ssumbz,50,66,0|ssumc0,52,62,1|t53a7z,52,62,1|t53a80,50,66,0|tbkozz,50,66,0|tbkp00,52,62,1|tntcvz,52,62,1|tntcw0,50,66,0|tunqbz,50,66,0|tunqc0,52,62,1|u6we7z,52,62,1|u6we80,50,66,0|uddszz,50,66,0|uddt00,52,62,1|upmgvz,52,62,1|upmgw0,50,66,0|uw3vnz,50,66,0|uw3vo0,52,62,1|v8cjjz,52,62,1|v8cjk0,50,66,0|vetybz,50,66,0|vetyc0,52,62,1|vr2m7z,52,62,1|vr2m80,50,66,0|vxk0zz,50,66,0|vxk100,52,62,1|w9sovz,52,62,1|w9sow0,50,66,0|wgn2bz,50,66,0|wgn2c0,52,62,1|wsvq7z,52,62,1|wsvq80,50,66,0|wzd4zz,50,66,0|wzd500,52,62,1|xblsvz,52,62,1|xblsw0,50,66,0|xi37nz,50,66,0|xi37o0,52,62,1|xubvjz,52,62,1|xubvk0,50,66,0|y0tabz,50,66,0|y0tac0,52,62,1|yd1y7z,52,62,1|yd1y80,50,66,0|yjjczz,50,66,0|yjjd00,52,62,1|yvs0vz,52,62,1|yvs0w0,50,66,0|z29fnz,50,66,0|z29fo0,52,62,1|zei3jz,52,62,1|zei3k0,50,66,0\",\"America/Cambridge_Bay|,60,1,0|-q3gdc0,50,66,0|-ek1z01,50,66,0|-ek1z00,58,62,1|-cq2tg1,58,62,1|-cq2tg0,59,62,1|-cnoxs1,59,62,1|-cnoxs0,50,66,0|-2g1tw1,50,66,0|-2g1tw0,61,63,1|-26btw1,61,63,1|-26btw0,50,66,0|5dwbnz,50,66,0|5dwbo0,52,62,1|5n9a7z,52,62,1|5n9a80,50,66,0|5wmebz,50,66,0|5wmec0,52,62,1|65zcvz,52,62,1|65zcw0,50,66,0|6fcgzz,50,66,0|6fch00,52,62,1|6p2e7z,52,62,1|6p2e80,50,66,0|6y2jnz,50,66,0|6y2jo0,52,62,1|77sgvz,52,62,1|77sgw0,50,66,0|7h5kzz,50,66,0|7h5l00,52,62,1|7qijjz,52,62,1|7qijk0,50,66,0|7zvnnz,50,66,0|7zvno0,52,62,1|898m7z,52,62,1|898m80,50,66,0|8ilqbz,50,66,0|8ilqc0,52,62,1|8ryovz,52,62,1|8ryow0,50,66,0|908wzz,50,66,0|908x00,52,62,1|9aorjz,52,62,1|9aork0,50,66,0|9iyznz,50,66,0|9iyzo0,52,62,1|9trsvz,52,62,1|9trsw0,50,66,0|a1p2bz,50,66,0|a1p2c0,52,62,1|achvjz,52,62,1|achvk0,50,66,0|akf4zz,50,66,0|akf500,52,62,1|av7y7z,52,62,1|av7y80,50,66,0|b3i6bz,50,66,0|b3i6c0,52,62,1|bdy0vz,52,62,1|bdy0w0,50,66,0|bm88zz,50,66,0|bm8900,52,62,1|bwo3jz,52,62,1|bwo3k0,50,66,0|c4ybnz,50,66,0|c4ybo0,52,62,1|cfr4vz,52,62,1|cfr4w0,50,66,0|cnoebz,50,66,0|cnoec0,52,62,1|cyh7jz,52,62,1|cyh7k0,50,66,0|d6egzz,50,66,0|d6eh00,52,62,1|dh7a7z,52,62,1|dh7a80,50,66,0|dphibz,50,66,0|dphic0,52,62,1|dzxcvz,52,62,1|dzxcw0,50,66,0|e87kzz,50,66,0|e87l00,52,62,1|einfjz,52,62,1|einfk0,50,66,0|eqxnnz,50,66,0|eqxno0,52,62,1|f1di7z,52,62,1|f1di80,50,66,0|f9nqbz,50,66,0|f9nqc0,52,62,1|fkgjjz,52,62,1|fkgjk0,45,62,0|fsdq7z,45,62,0|fsdq80,46,63,1|g36jfz,46,63,1|g36jg0,49,63,0|g3jcjz,49,63,0|g3jck0,45,62,0|gb3vnz,45,62,0|gb3vo0,52,62,1|glwovz,52,62,1|glwow0,50,66,0|gu6wzz,50,66,0|gu6x00,52,62,1|h4mrjz,52,62,1|h4mrk0,50,66,0|hcwznz,50,66,0|hcwzo0,52,62,1|hncu7z,52,62,1|hncu80,50,66,0|hvn2bz,50,66,0|hvn2c0,52,62,1|i6fvjz,52,62,1|i6fvk0,50,66,0|ied4zz,50,66,0|ied500,52,62,1|ip5y7z,52,62,1|ip5y80,50,66,0|ix37nz,50,66,0|ix37o0,52,62,1|j7w0vz,52,62,1|j7w0w0,50,66,0|jeqebz,50,66,0|jeqec0,52,62,1|jqz27z,52,62,1|jqz280,50,66,0|jxggzz,50,66,0|jxgh00,52,62,1|k9p4vz,52,62,1|k9p4w0,50,66,0|kg6jnz,50,66,0|kg6jo0,52,62,1|ksf7jz,52,62,1|ksf7k0,50,66,0|kz9kzz,50,66,0|kz9l00,52,62,1|lbi8vz,52,62,1|lbi8w0,50,66,0|lhznnz,50,66,0|lhzno0,52,62,1|lu8bjz,52,62,1|lu8bk0,50,66,0|m0pqbz,50,66,0|m0pqc0,52,62,1|mcye7z,52,62,1|mcye80,50,66,0|mjfszz,50,66,0|mjft00,52,62,1|mvogvz,52,62,1|mvogw0,50,66,0|n25vnz,50,66,0|n25vo0,52,62,1|neejjz,52,62,1|neejk0,50,66,0|nkvybz,50,66,0|nkvyc0,52,62,1|nx4m7z,52,62,1|nx4m80,50,66,0|o3yznz,50,66,0|o3yzo0,52,62,1|og7njz,52,62,1|og7nk0,50,66,0|omp2bz,50,66,0|omp2c0,52,62,1|oyxq7z,52,62,1|oyxq80,50,66,0|p5f4zz,50,66,0|p5f500,52,62,1|phnsvz,52,62,1|phnsw0,50,66,0|po57nz,50,66,0|po57o0,52,62,1|q0dvjz,52,62,1|q0dvk0,50,66,0|q6vabz,50,66,0|q6vac0,52,62,1|qj3y7z,52,62,1|qj3y80,50,66,0|qpybnz,50,66,0|qpybo0,52,62,1|r26zjz,52,62,1|r26zk0,50,66,0|r8oebz,50,66,0|r8oec0,52,62,1|rkx27z,52,62,1|rkx280,50,66,0|rregzz,50,66,0|rreh00,52,62,1|s3n4vz,52,62,1|s3n4w0,50,66,0|sa4jnz,50,66,0|sa4jo0,52,62,1|smd7jz,52,62,1|smd7k0,50,66,0|ssumbz,50,66,0|ssumc0,52,62,1|t53a7z,52,62,1|t53a80,50,66,0|tbkozz,50,66,0|tbkp00,52,62,1|tntcvz,52,62,1|tntcw0,50,66,0|tunqbz,50,66,0|tunqc0,52,62,1|u6we7z,52,62,1|u6we80,50,66,0|uddszz,50,66,0|uddt00,52,62,1|upmgvz,52,62,1|upmgw0,50,66,0|uw3vnz,50,66,0|uw3vo0,52,62,1|v8cjjz,52,62,1|v8cjk0,50,66,0|vetybz,50,66,0|vetyc0,52,62,1|vr2m7z,52,62,1|vr2m80,50,66,0|vxk0zz,50,66,0|vxk100,52,62,1|w9sovz,52,62,1|w9sow0,50,66,0|wgn2bz,50,66,0|wgn2c0,52,62,1|wsvq7z,52,62,1|wsvq80,50,66,0|wzd4zz,50,66,0|wzd500,52,62,1|xblsvz,52,62,1|xblsw0,50,66,0|xi37nz,50,66,0|xi37o0,52,62,1|xubvjz,52,62,1|xubvk0,50,66,0|y0tabz,50,66,0|y0tac0,52,62,1|yd1y7z,52,62,1|yd1y80,50,66,0|yjjczz,50,66,0|yjjd00,52,62,1|yvs0vz,52,62,1|yvs0w0,50,66,0|z29fnz,50,66,0|z29fo0,52,62,1|zei3jz,52,62,1|zei3k0,50,66,0\",\"America/Campo_Grande|,0,75,0|-t85hvw,42,42,0|-jyl7o1,42,42,0|-jyl7o0,39,44,1|-jpayc1,39,44,1|-jpayc0,42,42,0|-jfsa81,42,42,0|-jfsa80,39,44,1|-j6j101,39,44,1|-j6j100,42,42,0|-ahcvk1,42,42,0|-ahcvk0,39,44,1|-aad0w1,39,44,1|-aad0w0,42,42,0|-9yky81,42,42,0|-9yky80,39,44,1|-9scyc1,39,44,1|-9scyc0,42,42,0|-9ft0w1,42,42,0|-9ft0w0,39,44,1|-99j6c1,39,44,1|-99j6c0,42,42,0|-8wz8w1,42,42,0|-8wz8w0,39,44,1|-8scno1,39,44,1|-8scno0,42,42,0|-35xjk1,42,42,0|-35xjk0,39,44,1|-31nx01,39,44,1|-31nx00,42,42,0|-2kdm81,42,42,0|-2kdm80,39,44,1|-2hcfo1,39,44,1|-2hcfo0,42,42,0|-24qnk1,42,42,0|-24qnk0,39,44,1|-2042c1,39,44,1|-2042c0,42,42,0|-1nia81,42,42,0|-1nia80,39,44,1|-1hc501,39,44,1|-1hc500,42,42,0|-14qcw1,42,42,0|-14qcw0,39,44,1|-yid01,39,44,1|-yid00,42,42,0|89jf3z,42,42,0|89jf40,39,44,1|8gdmzz,39,44,1|8gdn00,42,42,0|8rwj3z,42,42,0|8rwj40,39,44,1|8xnuzz,39,44,1|8xnv00,42,42,0|9aogfz,42,42,0|9aogg0,39,44,1|9g2tnz,39,44,1|9g2to0,42,42,0|9t1kfz,42,42,0|9t1kg0,39,44,1|9yfxnz,39,44,1|9yfxo0,42,42,0|abrn3z,42,42,0|abrn40,39,44,1|ahvxnz,39,44,1|ahvxo0,42,42,0|auuofz,42,42,0|auuog0,39,44,1|b0yyzz,39,44,1|b0yz00,42,42,0|bdkr3z,42,42,0|bdkr40,39,44,1|bjc2zz,39,44,1|bjc300,42,42,0|bwnsfz,42,42,0|bwnsg0,39,44,1|c1p6zz,39,44,1|c1p700,42,42,0|cf0wfz,42,42,0|cf0wg0,39,44,1|cli5nz,39,44,1|cli5o0,42,42,0|cxqz3z,42,42,0|cxqz40,39,44,1|d488bz,39,44,1|d488c0,42,42,0|dgh1rz,42,42,0|dgh1s0,39,44,1|dmlcbz,39,44,1|dmlcc0,42,42,0|dyu5rz,42,42,0|dyu5s0,39,44,1|e5odnz,39,44,1|e5odo0,42,42,0|ehm33z,42,42,0|ehm340,39,44,1|ep4dnz,39,44,1|ep4do0,42,42,0|f0n9rz,42,42,0|f0n9s0,39,44,1|f7hhnz,39,44,1|f7hho0,42,42,0|fj0drz,42,42,0|fj0ds0,39,44,1|fqkizz,39,44,1|fqkj00,42,42,0|g23f3z,42,42,0|g23f40,39,44,1|g8xmzz,39,44,1|g8xn00,42,42,0|gl6gfz,42,42,0|gl6gg0,39,44,1|grnpnz,39,44,1|grnpo0,42,42,0|h4zf3z,42,42,0|h4zf40,39,44,1|hadsbz,39,44,1|hadsc0,42,42,0|hmzkfz,42,42,0|hmzkg0,39,44,1|ht3uzz,39,44,1|ht3v00,42,42,0|i6j9rz,42,42,0|i6j9s0,39,44,1|ic6wbz,39,44,1|ic6wc0,42,42,0|iofprz,42,42,0|iofps0,39,44,1|iuwyzz,39,44,1|iuwz00,42,42,0|j88ofz,42,42,0|j88og0,39,44,1|je00bz,39,44,1|je00c0,42,42,0|jpvv3z,42,42,0|jpvv40,39,44,1|jwd4bz,39,44,1|jwd4c0,42,42,0|k8ywfz,42,42,0|k8ywg0,39,44,1|kf36zz,39,44,1|kf3700,42,42,0|kroz3z,42,42,0|kroz40,39,44,1|ky68bz,39,44,1|ky68c0,42,42,0|laf1rz,42,42,0|laf1s0,39,44,1|lgwazz,39,44,1|lgwb00,42,42,0|lt54fz,42,42,0|lt54g0,39,44,1|lzzcbz,39,44,1|lzzcc0,42,42,0|mc85rz,42,42,0|mc85s0,39,44,1|micgbz,39,44,1|micgc0,42,42,0|muy8fz,42,42,0|muy8g0,39,44,1|n12izz,39,44,1|n12j00,42,42,0|ndob3z,42,42,0|ndob40,39,44,1|nk5kbz,39,44,1|nk5kc0,42,42,0|nwedrz,42,42,0|nweds0,39,44,1|o2vmzz,39,44,1|o2vn00,42,42,0|of4gfz,42,42,0|of4gg0,39,44,1|ollpnz,39,44,1|ollpo0,42,42,0|oxuj3z,42,42,0|oxuj40,39,44,1|p4bsbz,39,44,1|p4bsc0,42,42,0|phnhrz,42,42,0|phnhs0,39,44,1|pn1uzz,39,44,1|pn1v00,42,42,0\",\"America/Cancun|,0,76,0|-p1u7c0,45,62,0|690gnz,45,62,0|690go0,49,63,0|dphcrz,49,63,0|dphcs0,62,42,1|dzx7bz,62,42,1|dzx7c0,49,63,0|e87ffz,49,63,0|e87fg0,62,42,1|ein9zz,62,42,1|eina00,49,63,0|eqxi3z,49,63,0|eqxi40,62,42,1|ex1snz,62,42,1|ex1so0,46,63,1|f1dffz,46,63,1|f1dfg0,45,62,0|f9nnjz,45,62,0|f9nnk0,46,63,1|fkggrz,46,63,1|fkggs0,45,62,0|fsdq7z,45,62,0|fsdq80,46,63,1|g36jfz,46,63,1|g36jg0,45,62,0|gcwm7z,45,62,0|gcwm80,46,63,1|gkgrfz,46,63,1|gkgrg0,45,62,0|gu6u7z,45,62,0|gu6u80,46,63,1|h4morz,46,63,1|h4mos0,45,62,0|hcwwvz,45,62,0|hcwww0,46,63,1|hncrfz,46,63,1|hncrg0,45,62,0|hvmzjz,45,62,0|hvmzk0,46,63,1|i6fsrz,46,63,1|i6fss0,45,62,0|ied27z,45,62,0|ied280,46,63,1|ip5vfz,46,63,1|ip5vg0,45,62,0|ix34vz,45,62,0|ix34w0,46,63,1|j7vy3z,46,63,1|j7vy40,45,62,0|jft7jz,45,62,0|jft7k0,46,63,1|jqm0rz,46,63,1|jqm0s0,45,62,0|jyw8vz,45,62,0|jyw8w0,46,63,1|k9c3fz,46,63,1|k9c3g0,45,62,0|khmbjz,45,62,0|khmbk0,46,63,1|ks263z,46,63,1|ks2640,45,62,0|l0ce7z,45,62,0|l0ce80,46,63,1|lb57fz,46,63,1|lb57g0,45,62,0|lj2gvz,45,62,0|lj2gw0,46,63,1|ltva3z,46,63,1|ltva40,45,62,0|m1sjjz,45,62,0|m1sjk0,46,63,1|mclcrz,46,63,1|mclcs0,45,62,0|mkvkvz,45,62,0|mkvkw0,46,63,1|mvbffz,46,63,1|mvbfg0,45,62,0|n3lnjz,45,62,0|n3lnk0,46,63,1|ne1i3z,46,63,1|ne1i40,45,62,0|nj327z,45,62,0|nj3280,49,63,0\",\"America/Caracas|,0,77,0|-15r0wxs,41,78,0|-u7lcxx,41,78,0|-u7lcxw,43,59,0|-2lx4u1,43,59,0|-2lx4u0,42,42,0|jsrsrz,42,42,0|jsrss0,43,59,0|o6hkrz,43,59,0|o6hks0,42,42,0\",\"America/Cayenne|,0,79,0|-uj7yb4,42,42,0|-16brk1,42,42,0|-16brk0,39,44,0\",\"America/Cayman|,0,80,0|-15r0uls,41,81,0|-w757vd,41,81,0|-w757vc,49,63,0\",\"America/Chicago|,0,82,0|-18y0m00,45,62,0|-r0esg1,45,62,0|-r0esg0,46,63,1|-qplz81,46,63,1|-qplz80,45,62,0|-qhops1,45,62,0|-qhops0,46,63,1|-q6vwk1,46,63,1|-q6vwk0,45,62,0|-pv01s1,45,62,0|-pv01s0,46,63,1|-pnsv81,46,63,1|-pnsv80,45,62,0|-pg8kg1,45,62,0|-pg8kg0,46,63,1|-p52sk1,46,63,1|-p52sk0,45,62,0|-ovpog1,45,62,0|-ovpog0,46,63,1|-oo5j81,46,63,1|-oo5j80,45,62,0|-oczls1,45,62,0|-oczls0,46,63,1|-o52hw1,46,63,1|-o52hw0,45,62,0|-nu9j41,45,62,0|-nu9j40,46,63,1|-nmcf81,46,63,1|-nmcf80,45,62,0|-nbjgg1,45,62,0|-nbjgg0,46,63,1|-n3mck1,46,63,1|-n3mck0,45,62,0|-mstds1,45,62,0|-mstds0,46,63,1|-mkw9w1,46,63,1|-mkw9w0,45,62,0|-ma3b41,45,62,0|-ma3b40,46,63,1|-m26781,46,63,1|-m26780,45,62,0|-lr09s1,45,62,0|-lr09s0,46,63,1|-lj35w1,46,63,1|-lj35w0,45,62,0|-l8a741,45,62,0|-l8a740,46,63,1|-l0d381,46,63,1|-l0d380,45,62,0|-kpk4g1,45,62,0|-kpk4g0,46,63,1|-khn0k1,46,63,1|-khn0k0,45,62,0|-k6u1s1,45,62,0|-k6u1s0,46,63,1|-jywxw1,46,63,1|-jywxw0,45,62,0|-jo3z41,45,62,0|-jo3z40,46,63,1|-jg6v81,46,63,1|-jg6v80,45,62,0|-j50xs1,45,62,0|-j50xs0,46,63,1|-ixgsk1,46,63,1|-ixgsk0,45,62,0|-imav41,45,62,0|-imav40,46,63,1|-iedr81,46,63,1|-iedr80,45,62,0|-i3ksg1,45,62,0|-i3ksg0,46,63,1|-hvnok1,46,63,1|-hvnok0,45,62,0|-hnqf41,45,62,0|-hnqf40,49,63,0|-haev81,49,63,0|-haev80,45,62,0|-h24n41,45,62,0|-h24n40,46,63,1|-gu7j81,46,63,1|-gu7j80,45,62,0|-gjekg1,45,62,0|-gjekg0,46,63,1|-gbhgk1,46,63,1|-gbhgk0,45,62,0|-g0bj41,45,62,0|-g0bj40,46,63,1|-fsrdw1,46,63,1|-fsrdw0,45,62,0|-fhlgg1,45,62,0|-fhlgg0,46,63,1|-f9ock1,46,63,1|-f9ock0,45,62,0|-eyvds1,45,62,0|-eyvds0,46,63,1|-eqy9w1,46,63,1|-eqy9w0,45,62,0|-ek21s1,45,62,0|-ek21s0,47,63,1|-cq2tg1,47,63,1|-cq2tg0,48,63,1|-cnp0k1,48,63,1|-cnp0k0,45,62,0|-ccw1s1,45,62,0|-ccw1s0,46,63,1|-c4yxw1,46,63,1|-c4yxw0,45,62,0|-bu5z41,45,62,0|-bu5z40,46,63,1|-bm8v81,46,63,1|-bm8v80,45,62,0|-bbfwg1,45,62,0|-bbfwg0,46,63,1|-b3isk1,46,63,1|-b3isk0,45,62,0|-aspts1,45,62,0|-aspts0,46,63,1|-akspw1,46,63,1|-akspw0,45,62,0|-a9msg1,45,62,0|-a9msg0,46,63,1|-a22n81,46,63,1|-a22n80,45,62,0|-9qwps1,45,62,0|-9qwps0,46,63,1|-9izlw1,46,63,1|-9izlw0,45,62,0|-986n41,45,62,0|-986n40,46,63,1|-909j81,46,63,1|-909j80,45,62,0|-8pgkg1,45,62,0|-8pgkg0,46,63,1|-8hjgk1,46,63,1|-8hjgk0,45,62,0|-86qhs1,45,62,0|-86qhs0,46,63,1|-7ytdw1,46,63,1|-7ytdw0,45,62,0|-7o0f41,45,62,0|-7o0f40,46,63,1|-7eahw1,46,63,1|-7eahw0,45,62,0|-74xds1,45,62,0|-74xds0,46,63,1|-6vkf81,46,63,1|-6vkf80,45,62,0|-6m7b41,45,62,0|-6m7b40,46,63,1|-6cuck1,46,63,1|-6cuck0,45,62,0|-63h8g1,45,62,0|-63h8g0,46,63,1|-5u49w1,46,63,1|-5u49w0,45,62,0|-5kr5s1,45,62,0|-5kr5s0,46,63,1|-5be781,46,63,1|-5be780,45,62,0|-521341,45,62,0|-521340,46,63,1|-4sb5w1,46,63,1|-4sb5w0,45,62,0|-4iy1s1,45,62,0|-4iy1s0,46,63,1|-49l381,46,63,1|-49l380,45,62,0|-407z41,45,62,0|-407z40,46,63,1|-3qv0k1,46,63,1|-3qv0k0,45,62,0|-3hhwg1,45,62,0|-3hhwg0,46,63,1|-384xw1,46,63,1|-384xw0,45,62,0|-2yrts1,45,62,0|-2yrts0,46,63,1|-2pev81,46,63,1|-2pev80,45,62,0|-2g1r41,45,62,0|-2g1r40,46,63,1|-26btw1,46,63,1|-26btw0,45,62,0|-1xbog1,45,62,0|-1xbog0,46,63,1|-1nlr81,46,63,1|-1nlr80,45,62,0|-1e8n41,45,62,0|-1e8n40,46,63,1|-14vok1,46,63,1|-14vok0,45,62,0|-vikg1,45,62,0|-vikg0,46,63,1|-m5lw1,46,63,1|-m5lw0,45,62,0|-cshs1,45,62,0|-cshs0,46,63,1|-3fj81,46,63,1|-3fj80,45,62,0|5xkvz,45,62,0|5xkw0,46,63,1|fajfz,46,63,1|fajg0,45,62,0|onnjz,45,62,0|onnk0,46,63,1|ydkrz,46,63,1|ydks0,45,62,0|17qovz,45,62,0|17qow0,46,63,1|1h3nfz,46,63,1|1h3ng0,45,62,0|1qgrjz,45,62,0|1qgrk0,46,63,1|1ztq3z,46,63,1|1ztq40,45,62,0|23ffjz,45,62,0|23ffk0,46,63,1|2ijsrz,46,63,1|2ijss0,45,62,0|2oo8vz,45,62,0|2oo8w0,46,63,1|319vfz,46,63,1|319vg0,45,62,0|3amzjz,45,62,0|3amzk0,46,63,1|3kcwrz,46,63,1|3kcws0,45,62,0|3td27z,45,62,0|3td280,46,63,1|432zfz,46,63,1|432zg0,45,62,0|4cg3jz,45,62,0|4cg3k0,46,63,1|4lt23z,46,63,1|4lt240,45,62,0|4v667z,45,62,0|4v6680,46,63,1|54j4rz,46,63,1|54j4s0,45,62,0|5dw8vz,45,62,0|5dw8w0,46,63,1|5n97fz,46,63,1|5n97g0,45,62,0|5wmbjz,45,62,0|5wmbk0,46,63,1|65za3z,46,63,1|65za40,45,62,0|6fce7z,45,62,0|6fce80,46,63,1|6p2bfz,46,63,1|6p2bg0,45,62,0|6y2gvz,45,62,0|6y2gw0,46,63,1|77se3z,46,63,1|77se40,45,62,0|7h5i7z,45,62,0|7h5i80,46,63,1|7qigrz,46,63,1|7qigs0,45,62,0|7zvkvz,45,62,0|7zvkw0,46,63,1|898jfz,46,63,1|898jg0,45,62,0|8ilnjz,45,62,0|8ilnk0,46,63,1|8rym3z,46,63,1|8rym40,45,62,0|908u7z,45,62,0|908u80,46,63,1|9aoorz,46,63,1|9aoos0,45,62,0|9iywvz,45,62,0|9iyww0,46,63,1|9trq3z,46,63,1|9trq40,45,62,0|a1ozjz,45,62,0|a1ozk0,46,63,1|achsrz,46,63,1|achss0,45,62,0|akf27z,45,62,0|akf280,46,63,1|av7vfz,46,63,1|av7vg0,45,62,0|b3i3jz,45,62,0|b3i3k0,46,63,1|bdxy3z,46,63,1|bdxy40,45,62,0|bm867z,45,62,0|bm8680,46,63,1|bwo0rz,46,63,1|bwo0s0,45,62,0|c4y8vz,45,62,0|c4y8w0,46,63,1|cfr23z,46,63,1|cfr240,45,62,0|cnobjz,45,62,0|cnobk0,46,63,1|cyh4rz,46,63,1|cyh4s0,45,62,0|d6ee7z,45,62,0|d6ee80,46,63,1|dh77fz,46,63,1|dh77g0,45,62,0|dphfjz,45,62,0|dphfk0,46,63,1|dzxa3z,46,63,1|dzxa40,45,62,0|e87i7z,45,62,0|e87i80,46,63,1|eincrz,46,63,1|eincs0,45,62,0|eqxkvz,45,62,0|eqxkw0,46,63,1|f1dffz,46,63,1|f1dfg0,45,62,0|f9nnjz,45,62,0|f9nnk0,46,63,1|fkggrz,46,63,1|fkggs0,45,62,0|fsdq7z,45,62,0|fsdq80,46,63,1|g36jfz,46,63,1|g36jg0,45,62,0|gb3svz,45,62,0|gb3sw0,46,63,1|glwm3z,46,63,1|glwm40,45,62,0|gu6u7z,45,62,0|gu6u80,46,63,1|h4morz,46,63,1|h4mos0,45,62,0|hcwwvz,45,62,0|hcwww0,46,63,1|hncrfz,46,63,1|hncrg0,45,62,0|hvmzjz,45,62,0|hvmzk0,46,63,1|i6fsrz,46,63,1|i6fss0,45,62,0|ied27z,45,62,0|ied280,46,63,1|ip5vfz,46,63,1|ip5vg0,45,62,0|ix34vz,45,62,0|ix34w0,46,63,1|j7vy3z,46,63,1|j7vy40,45,62,0|jeqbjz,45,62,0|jeqbk0,46,63,1|jqyzfz,46,63,1|jqyzg0,45,62,0|jxge7z,45,62,0|jxge80,46,63,1|k9p23z,46,63,1|k9p240,45,62,0|kg6gvz,45,62,0|kg6gw0,46,63,1|ksf4rz,46,63,1|ksf4s0,45,62,0|kz9i7z,45,62,0|kz9i80,46,63,1|lbi63z,46,63,1|lbi640,45,62,0|lhzkvz,45,62,0|lhzkw0,46,63,1|lu88rz,46,63,1|lu88s0,45,62,0|m0pnjz,45,62,0|m0pnk0,46,63,1|mcybfz,46,63,1|mcybg0,45,62,0|mjfq7z,45,62,0|mjfq80,46,63,1|mvoe3z,46,63,1|mvoe40,45,62,0|n25svz,45,62,0|n25sw0,46,63,1|neegrz,46,63,1|neegs0,45,62,0|nkvvjz,45,62,0|nkvvk0,46,63,1|nx4jfz,46,63,1|nx4jg0,45,62,0|o3ywvz,45,62,0|o3yww0,46,63,1|og7krz,46,63,1|og7ks0,45,62,0|omozjz,45,62,0|omozk0,46,63,1|oyxnfz,46,63,1|oyxng0,45,62,0|p5f27z,45,62,0|p5f280,46,63,1|phnq3z,46,63,1|phnq40,45,62,0|po54vz,45,62,0|po54w0,46,63,1|q0dsrz,46,63,1|q0dss0,45,62,0|q6v7jz,45,62,0|q6v7k0,46,63,1|qj3vfz,46,63,1|qj3vg0,45,62,0|qpy8vz,45,62,0|qpy8w0,46,63,1|r26wrz,46,63,1|r26ws0,45,62,0|r8objz,45,62,0|r8obk0,46,63,1|rkwzfz,46,63,1|rkwzg0,45,62,0|rree7z,45,62,0|rree80,46,63,1|s3n23z,46,63,1|s3n240,45,62,0|sa4gvz,45,62,0|sa4gw0,46,63,1|smd4rz,46,63,1|smd4s0,45,62,0|ssujjz,45,62,0|ssujk0,46,63,1|t537fz,46,63,1|t537g0,45,62,0|tbkm7z,45,62,0|tbkm80,46,63,1|tnta3z,46,63,1|tnta40,45,62,0|tunnjz,45,62,0|tunnk0,46,63,1|u6wbfz,46,63,1|u6wbg0,45,62,0|uddq7z,45,62,0|uddq80,46,63,1|upme3z,46,63,1|upme40,45,62,0|uw3svz,45,62,0|uw3sw0,46,63,1|v8cgrz,46,63,1|v8cgs0,45,62,0|vetvjz,45,62,0|vetvk0,46,63,1|vr2jfz,46,63,1|vr2jg0,45,62,0|vxjy7z,45,62,0|vxjy80,46,63,1|w9sm3z,46,63,1|w9sm40,45,62,0|wgmzjz,45,62,0|wgmzk0,46,63,1|wsvnfz,46,63,1|wsvng0,45,62,0|wzd27z,45,62,0|wzd280,46,63,1|xblq3z,46,63,1|xblq40,45,62,0|xi34vz,45,62,0|xi34w0,46,63,1|xubsrz,46,63,1|xubss0,45,62,0|y0t7jz,45,62,0|y0t7k0,46,63,1|yd1vfz,46,63,1|yd1vg0,45,62,0|yjja7z,45,62,0|yjja80,46,63,1|yvry3z,46,63,1|yvry40,45,62,0|z29cvz,45,62,0|z29cw0,46,63,1|zei0rz,46,63,1|zei0s0,45,62,0\",\"America/Chihuahua|,0,83,0|-p1u4k0,50,66,0|-m7mko1,50,66,0|-m7mko0,45,62,0|-kf67c1,45,62,0|-kf67c0,50,66,0|-k6j3c1,50,66,0|-k6j3c0,45,62,0|-jypm01,45,62,0|-jypm00,50,66,0|-jpan81,50,66,0|-jpan80,45,62,0|dphfjz,45,62,0|dphfk0,46,63,1|dzxa3z,46,63,1|dzxa40,45,62,0|e87i7z,45,62,0|e87i80,46,63,1|eincrz,46,63,1|eincs0,45,62,0|eqxnnz,45,62,0|eqxno0,52,62,1|f1di7z,52,62,1|f1di80,50,66,0|f9nqbz,50,66,0|f9nqc0,52,62,1|fkgjjz,52,62,1|fkgjk0,50,66,0|fsdszz,50,66,0|fsdt00,52,62,1|g36m7z,52,62,1|g36m80,50,66,0|gcwozz,50,66,0|gcwp00,52,62,1|gkgu7z,52,62,1|gkgu80,50,66,0|gu6wzz,50,66,0|gu6x00,52,62,1|h4mrjz,52,62,1|h4mrk0,50,66,0|hcwznz,50,66,0|hcwzo0,52,62,1|hncu7z,52,62,1|hncu80,50,66,0|hvn2bz,50,66,0|hvn2c0,52,62,1|i6fvjz,52,62,1|i6fvk0,50,66,0|ied4zz,50,66,0|ied500,52,62,1|ip5y7z,52,62,1|ip5y80,50,66,0|ix37nz,50,66,0|ix37o0,52,62,1|j7w0vz,52,62,1|j7w0w0,50,66,0|jftabz,50,66,0|jftac0,52,62,1|jqm3jz,52,62,1|jqm3k0,50,66,0|jywbnz,50,66,0|jywbo0,52,62,1|k9c67z,52,62,1|k9c680,50,66,0|khmebz,50,66,0|khmec0,52,62,1|ks28vz,52,62,1|ks28w0,50,66,0|l0cgzz,50,66,0|l0ch00,52,62,1|lb5a7z,52,62,1|lb5a80,50,66,0|lj2jnz,50,66,0|lj2jo0,52,62,1|ltvcvz,52,62,1|ltvcw0,50,66,0|m1smbz,50,66,0|m1smc0,52,62,1|mclfjz,52,62,1|mclfk0,50,66,0|mkvnnz,50,66,0|mkvno0,52,62,1|mvbi7z,52,62,1|mvbi80,50,66,0|n3lqbz,50,66,0|n3lqc0,52,62,1|ne1kvz,52,62,1|ne1kw0,50,66,0|nmbszz,50,66,0|nmbt00,52,62,1|nwrnjz,52,62,1|nwrnk0,50,66,0|o51vnz,50,66,0|o51vo0,52,62,1|ofuovz,52,62,1|ofuow0,50,66,0|onrybz,50,66,0|onryc0,52,62,1|oykrjz,52,62,1|oykrk0,50,66,0|p6i0zz,50,66,0|p6i100,52,62,1|phau7z,52,62,1|phau80,50,66,0|ppl2bz,50,66,0|ppl2c0,52,62,1|q00wvz,52,62,1|q00ww0,50,66,0|q8b4zz,50,66,0|q8b500,52,62,1|qiqzjz,52,62,1|qiqzk0,50,66,0|qr17nz,50,66,0|qr17o0,52,62,1|r1u0vz,52,62,1|r1u0w0,50,66,0|r9rabz,50,66,0|r9rac0,52,62,1|rkk3jz,52,62,1|rkk3k0,50,66,0|rshczz,50,66,0|rshd00,52,62,1|s3a67z,52,62,1|s3a680,50,66,0|sbkebz,50,66,0|sbkec0,52,62,1|sm08vz,52,62,1|sm08w0,50,66,0|suagzz,50,66,0|suah00,52,62,1|t4qbjz,52,62,1|t4qbk0,50,66,0|td0jnz,50,66,0|td0jo0,52,62,1|tnge7z,52,62,1|tnge80,50,66,0|tvqmbz,50,66,0|tvqmc0,52,62,1|u6jfjz,52,62,1|u6jfk0,50,66,0|uegozz,50,66,0|uegp00,52,62,1|up9i7z,52,62,1|up9i80,50,66,0|ux6rnz,50,66,0|ux6ro0,52,62,1|v7zkvz,52,62,1|v7zkw0,50,66,0|vg9szz,50,66,0|vg9t00,52,62,1|vqpnjz,52,62,1|vqpnk0,50,66,0|vyzvnz,50,66,0|vyzvo0,52,62,1|w9fq7z,52,62,1|w9fq80,50,66,0|whpybz,50,66,0|whpyc0,52,62,1|wsirjz,52,62,1|wsirk0,50,66,0|x0g0zz,50,66,0|x0g100,52,62,1|xb8u7z,52,62,1|xb8u80,50,66,0|xj63nz,50,66,0|xj63o0,52,62,1|xtywvz,52,62,1|xtyww0,50,66,0|y1w6bz,50,66,0|y1w6c0,52,62,1|ycozjz,52,62,1|ycozk0,50,66,0|ykz7nz,50,66,0|ykz7o0,52,62,1|yvf27z,52,62,1|yvf280,50,66,0|z3pabz,50,66,0|z3pac0,52,62,1|ze54vz,52,62,1|ze54w0,50,66,0\",\"America/Costa_Rica|,0,84,0|-15r0trn,63,84,0|-pjw8fo,63,84,0|-pjw8fn,45,62,0|4rxcnz,45,62,0|4rxco0,46,63,1|4wyr7z,46,63,1|4wyr80,45,62,0|5anfbz,45,62,0|5anfc0,46,63,1|5fotvz,46,63,1|5fotw0,45,62,0|azhhzz,45,62,0|azhi00,46,63,1|b7v9vz,46,63,1|b7v9w0,45,62,0|bi7knz,45,62,0|bi7ko0,46,63,1|bl51vz,46,63,1|bl51w0,45,62,0\",\"America/Creston|,0,85,0|-18vrx38,50,66,0|-rshz81,50,66,0|-rshz80,51,40,0|-qx64g1,51,40,0|-qx64g0,50,66,0\",\"America/Cuiaba|,0,86,0|-t85hm4,42,42,0|-jyl7o1,42,42,0|-jyl7o0,39,44,1|-jpayc1,39,44,1|-jpayc0,42,42,0|-jfsa81,42,42,0|-jfsa80,39,44,1|-j6j101,39,44,1|-j6j100,42,42,0|-ahcvk1,42,42,0|-ahcvk0,39,44,1|-aad0w1,39,44,1|-aad0w0,42,42,0|-9yky81,42,42,0|-9yky80,39,44,1|-9scyc1,39,44,1|-9scyc0,42,42,0|-9ft0w1,42,42,0|-9ft0w0,39,44,1|-99j6c1,39,44,1|-99j6c0,42,42,0|-8wz8w1,42,42,0|-8wz8w0,39,44,1|-8scno1,39,44,1|-8scno0,42,42,0|-35xjk1,42,42,0|-35xjk0,39,44,1|-31nx01,39,44,1|-31nx00,42,42,0|-2kdm81,42,42,0|-2kdm80,39,44,1|-2hcfo1,39,44,1|-2hcfo0,42,42,0|-24qnk1,42,42,0|-24qnk0,39,44,1|-2042c1,39,44,1|-2042c0,42,42,0|-1nia81,42,42,0|-1nia80,39,44,1|-1hc501,39,44,1|-1hc500,42,42,0|-14qcw1,42,42,0|-14qcw0,39,44,1|-yid01,39,44,1|-yid00,42,42,0|89jf3z,42,42,0|89jf40,39,44,1|8gdmzz,39,44,1|8gdn00,42,42,0|8rwj3z,42,42,0|8rwj40,39,44,1|8xnuzz,39,44,1|8xnv00,42,42,0|9aogfz,42,42,0|9aogg0,39,44,1|9g2tnz,39,44,1|9g2to0,42,42,0|9t1kfz,42,42,0|9t1kg0,39,44,1|9yfxnz,39,44,1|9yfxo0,42,42,0|abrn3z,42,42,0|abrn40,39,44,1|ahvxnz,39,44,1|ahvxo0,42,42,0|auuofz,42,42,0|auuog0,39,44,1|b0yyzz,39,44,1|b0yz00,42,42,0|bdkr3z,42,42,0|bdkr40,39,44,1|bjc2zz,39,44,1|bjc300,42,42,0|bwnsfz,42,42,0|bwnsg0,39,44,1|c1p6zz,39,44,1|c1p700,42,42,0|cf0wfz,42,42,0|cf0wg0,39,44,1|cli5nz,39,44,1|cli5o0,42,42,0|cxqz3z,42,42,0|cxqz40,39,44,1|d488bz,39,44,1|d488c0,42,42,0|dgh1rz,42,42,0|dgh1s0,39,44,1|dmlcbz,39,44,1|dmlcc0,42,42,0|dyu5rz,42,42,0|dyu5s0,39,44,1|e5odnz,39,44,1|e5odo0,42,42,0|ehm33z,42,42,0|ehm340,39,44,1|ep4dnz,39,44,1|ep4do0,42,42,0|f0n9rz,42,42,0|f0n9s0,39,44,1|f7hhnz,39,44,1|f7hho0,42,42,0|fj0drz,42,42,0|fj0ds0,39,44,1|fqkizz,39,44,1|fqkj00,42,42,0|g23f3z,42,42,0|g23f40,39,44,1|g8xmzz,39,44,1|g8xn00,42,42,0|gl6gfz,42,42,0|gl6gg0,39,44,1|grnpnz,39,44,1|grnpo0,42,42,0|h4zf3z,42,42,0|h4zf40,39,44,1|hadsbz,39,44,1|hadsc0,42,42,0|i6j9rz,42,42,0|i6j9s0,39,44,1|ic6wbz,39,44,1|ic6wc0,42,42,0|iofprz,42,42,0|iofps0,39,44,1|iuwyzz,39,44,1|iuwz00,42,42,0|j88ofz,42,42,0|j88og0,39,44,1|je00bz,39,44,1|je00c0,42,42,0|jpvv3z,42,42,0|jpvv40,39,44,1|jwd4bz,39,44,1|jwd4c0,42,42,0|k8ywfz,42,42,0|k8ywg0,39,44,1|kf36zz,39,44,1|kf3700,42,42,0|kroz3z,42,42,0|kroz40,39,44,1|ky68bz,39,44,1|ky68c0,42,42,0|laf1rz,42,42,0|laf1s0,39,44,1|lgwazz,39,44,1|lgwb00,42,42,0|lt54fz,42,42,0|lt54g0,39,44,1|lzzcbz,39,44,1|lzzcc0,42,42,0|mc85rz,42,42,0|mc85s0,39,44,1|micgbz,39,44,1|micgc0,42,42,0|muy8fz,42,42,0|muy8g0,39,44,1|n12izz,39,44,1|n12j00,42,42,0|ndob3z,42,42,0|ndob40,39,44,1|nk5kbz,39,44,1|nk5kc0,42,42,0|nwedrz,42,42,0|nweds0,39,44,1|o2vmzz,39,44,1|o2vn00,42,42,0|of4gfz,42,42,0|of4gg0,39,44,1|ollpnz,39,44,1|ollpo0,42,42,0|oxuj3z,42,42,0|oxuj40,39,44,1|p4bsbz,39,44,1|p4bsc0,42,42,0|phnhrz,42,42,0|phnhs0,39,44,1|pn1uzz,39,44,1|pn1v00,42,42,0\",\"America/Curacao|,0,58,0|-u7lckd,43,59,0|-2lx4u1,43,59,0|-2lx4u0,32,42,0\",\"America/Danmarkshavn|,0,87,0|-rvusjk,39,44,0|5ct4jz,39,44,0|5ct4k0,40,45,1|5lsw3z,40,45,1|5lsw40,39,44,0|5v5xfz,39,44,0|5v5xg0,40,45,1|64iyrz,40,45,1|64iys0,39,44,0|6dw03z,39,44,0|6dw040,40,45,1|6n91fz,40,45,1|6n91g0,39,44,0|6wm2rz,39,44,0|6wm2s0,40,45,1|75z43z,40,45,1|75z440,39,44,0|7fc5fz,39,44,0|7fc5g0,40,45,1|7p25fz,40,45,1|7p25g0,39,44,0|7yf6rz,39,44,0|7yf6s0,40,45,1|87s83z,40,45,1|87s840,39,44,0|8h59fz,39,44,0|8h59g0,40,45,1|8qiarz,40,45,1|8qias0,39,44,0|8zvc3z,39,44,0|8zvc40,40,45,1|998dfz,40,45,1|998dg0,39,44,0|9ilerz,39,44,0|9iles0,40,45,1|9ryg3z,40,45,1|9ryg40,39,44,0|a1bhfz,39,44,0|a1bhg0,40,45,1|aaoirz,40,45,1|aaois0,39,44,0|ak1k3z,39,44,0|ak1k40,40,45,1|atrk3z,40,45,1|atrk40,39,44,0|b34lfz,39,44,0|b34lg0,40,45,1|bchmrz,40,45,1|bchms0,39,44,0|bluo3z,39,44,0|bluo40,40,45,1|bv7pfz,40,45,1|bv7pg0,39,44,0|c4kqrz,39,44,0|c4kqs0,40,45,1|cdxs3z,40,45,1|cdxs40,39,44,0|cnatfz,39,44,0|cnatg0,40,45,1|cwnurz,40,45,1|cwnus0,39,44,0|d60w3z,39,44,0|d60w40,40,45,1|dfdxfz,40,45,1|dfdxg0,39,44,0|dkhezz,39,44,0|dkhf00,1,1,0\",\"America/Dawson|,0,88,0|-1079suk,36,37,0|-qzoms1,36,37,0|-qzoms0,64,40,1|-qplqw1,64,40,1|-qplqw0,36,37,0|-qess41,36,37,0|-qess40,64,40,1|-q6kps1,64,40,1|-q6kps0,36,37,0|-ek1tg1,36,37,0|-ek1tg0,65,40,1|-cq2tg1,65,40,1|-cq2tg0,66,40,1|-cnos81,66,40,1|-cnos80,36,37,0|-2g1oc1,36,37,0|-2g1oc0,67,66,1|-26boc1,67,66,1|-26boc0,36,37,0|1ztvnz,36,37,0|1ztvo0,51,40,0|5dwefz,51,40,0|5dweg0,57,66,1|5n9czz,57,66,1|5n9d00,51,40,0|5wmh3z,51,40,0|5wmh40,57,66,1|65zfnz,57,66,1|65zfo0,51,40,0|6fcjrz,51,40,0|6fcjs0,57,66,1|6p2gzz,57,66,1|6p2h00,51,40,0|6y2mfz,51,40,0|6y2mg0,57,66,1|77sjnz,57,66,1|77sjo0,51,40,0|7h5nrz,51,40,0|7h5ns0,57,66,1|7qimbz,57,66,1|7qimc0,51,40,0|7zvqfz,51,40,0|7zvqg0,57,66,1|898ozz,57,66,1|898p00,51,40,0|8ilt3z,51,40,0|8ilt40,57,66,1|8ryrnz,57,66,1|8ryro0,51,40,0|908zrz,51,40,0|908zs0,57,66,1|9aoubz,57,66,1|9aouc0,51,40,0|9iz2fz,51,40,0|9iz2g0,57,66,1|9trvnz,57,66,1|9trvo0,51,40,0|a1p53z,51,40,0|a1p540,57,66,1|achybz,57,66,1|achyc0,51,40,0|akf7rz,51,40,0|akf7s0,57,66,1|av80zz,57,66,1|av8100,51,40,0|b3i93z,51,40,0|b3i940,57,66,1|bdy3nz,57,66,1|bdy3o0,51,40,0|bm8brz,51,40,0|bm8bs0,57,66,1|bwo6bz,57,66,1|bwo6c0,51,40,0|c4yefz,51,40,0|c4yeg0,57,66,1|cfr7nz,57,66,1|cfr7o0,51,40,0|cnoh3z,51,40,0|cnoh40,57,66,1|cyhabz,57,66,1|cyhac0,51,40,0|d6ejrz,51,40,0|d6ejs0,57,66,1|dh7czz,57,66,1|dh7d00,51,40,0|dphl3z,51,40,0|dphl40,57,66,1|dzxfnz,57,66,1|dzxfo0,51,40,0|e87nrz,51,40,0|e87ns0,57,66,1|einibz,57,66,1|einic0,51,40,0|eqxqfz,51,40,0|eqxqg0,57,66,1|f1dkzz,57,66,1|f1dl00,51,40,0|f9nt3z,51,40,0|f9nt40,57,66,1|fkgmbz,57,66,1|fkgmc0,51,40,0|fsdvrz,51,40,0|fsdvs0,57,66,1|g36ozz,57,66,1|g36p00,51,40,0|gb3yfz,51,40,0|gb3yg0,57,66,1|glwrnz,57,66,1|glwro0,51,40,0|gu6zrz,51,40,0|gu6zs0,57,66,1|h4mubz,57,66,1|h4muc0,51,40,0|hcx2fz,51,40,0|hcx2g0,57,66,1|hncwzz,57,66,1|hncx00,51,40,0|hvn53z,51,40,0|hvn540,57,66,1|i6fybz,57,66,1|i6fyc0,51,40,0|ied7rz,51,40,0|ied7s0,57,66,1|ip60zz,57,66,1|ip6100,51,40,0|ix3afz,51,40,0|ix3ag0,57,66,1|j7w3nz,57,66,1|j7w3o0,51,40,0|jeqh3z,51,40,0|jeqh40,57,66,1|jqz4zz,57,66,1|jqz500,51,40,0|jxgjrz,51,40,0|jxgjs0,57,66,1|k9p7nz,57,66,1|k9p7o0,51,40,0|kg6mfz,51,40,0|kg6mg0,57,66,1|ksfabz,57,66,1|ksfac0,51,40,0|kz9nrz,51,40,0|kz9ns0,57,66,1|lbibnz,57,66,1|lbibo0,51,40,0|lhzqfz,51,40,0|lhzqg0,57,66,1|lu8ebz,57,66,1|lu8ec0,51,40,0|m0pt3z,51,40,0|m0pt40,57,66,1|mcygzz,57,66,1|mcyh00,51,40,0|mjfvrz,51,40,0|mjfvs0,57,66,1|mvojnz,57,66,1|mvojo0,51,40,0|n25yfz,51,40,0|n25yg0,57,66,1|neembz,57,66,1|neemc0,51,40,0|nkw13z,51,40,0|nkw140,57,66,1|nx4ozz,57,66,1|nx4p00,51,40,0|o3z2fz,51,40,0|o3z2g0,57,66,1|og7qbz,57,66,1|og7qc0,51,40,0|omp53z,51,40,0|omp540,57,66,1|oyxszz,57,66,1|oyxt00,51,40,0|p5f7rz,51,40,0|p5f7s0,57,66,1|phnvnz,57,66,1|phnvo0,51,40,0|po5afz,51,40,0|po5ag0,57,66,1|q0dybz,57,66,1|q0dyc0,51,40,0|q6vd3z,51,40,0|q6vd40,57,66,1|qj3vfz,57,66,1|qj3vg0,50,66,0\",\"America/Dawson_Creek|,0,89,0|-18vrweg,51,40,0|-qzopk1,51,40,0|-qzopk0,57,66,1|-qplto1,57,66,1|-qplto0,51,40,0|-ek1w81,51,40,0|-ek1w80,68,66,1|-cq2tg1,68,66,1|-cq2tg0,69,66,1|-cnov01,69,66,1|-cnov00,51,40,0|-bu5tk1,51,40,0|-bu5tk0,57,66,1|-bm8po1,57,66,1|-bm8po0,51,40,0|-bbfqw1,51,40,0|-bbfqw0,57,66,1|-b3in01,57,66,1|-b3in00,51,40,0|-aspo81,51,40,0|-aspo80,57,66,1|-akskc1,57,66,1|-akskc0,51,40,0|-a9mmw1,51,40,0|-a9mmw0,57,66,1|-a22ho1,57,66,1|-a22ho0,51,40,0|-9qwk81,51,40,0|-9qwk80,57,66,1|-9izgc1,57,66,1|-9izgc0,51,40,0|-986hk1,51,40,0|-986hk0,57,66,1|-909do1,57,66,1|-909do0,51,40,0|-8pgew1,51,40,0|-8pgew0,57,66,1|-8hjb01,57,66,1|-8hjb00,51,40,0|-86qc81,51,40,0|-86qc80,57,66,1|-7yt8c1,57,66,1|-7yt8c0,51,40,0|-7o09k1,51,40,0|-7o09k0,57,66,1|-7g35o1,57,66,1|-7g35o0,51,40,0|-74x881,51,40,0|-74x880,57,66,1|-6x04c1,57,66,1|-6x04c0,51,40,0|-6m75k1,51,40,0|-6m75k0,57,66,1|-6ea1o1,57,66,1|-6ea1o0,51,40,0|-63h2w1,51,40,0|-63h2w0,57,66,1|-5vjz01,57,66,1|-5vjz00,51,40,0|-5kr081,51,40,0|-5kr080,57,66,1|-5ctwc1,57,66,1|-5ctwc0,51,40,0|-520xk1,51,40,0|-520xk0,57,66,1|-4u3to1,57,66,1|-4u3to0,51,40,0|-4ixw81,51,40,0|-4ixw80,57,66,1|-4bdr01,57,66,1|-4bdr00,51,40,0|-407tk1,51,40,0|-407tk0,57,66,1|-3quv01,57,66,1|-3quv00,51,40,0|-3hhqw1,51,40,0|-3hhqw0,57,66,1|-384sc1,57,66,1|-384sc0,51,40,0|-2yro81,51,40,0|-2yro80,57,66,1|-2pepo1,57,66,1|-2pepo0,51,40,0|-2g1lk1,51,40,0|-2g1lk0,57,66,1|-26boc1,57,66,1|-26boc0,51,40,0|-1xbiw1,51,40,0|-1xbiw0,57,66,1|-1nllo1,57,66,1|-1nllo0,51,40,0|-1e8hk1,51,40,0|-1e8hk0,57,66,1|-14vj01,57,66,1|-14vj00,51,40,0|-view1,51,40,0|-view0,57,66,1|-m5gc1,57,66,1|-m5gc0,51,40,0|-csc81,51,40,0|-csc80,57,66,1|-3fdo1,57,66,1|-3fdo0,51,40,0|5xqfz,51,40,0|5xqg0,57,66,1|faozz,57,66,1|fap00,51,40,0|ont3z,51,40,0|ont40,57,66,1|ydqbz,57,66,1|ydqc0,51,40,0|17qufz,51,40,0|17qug0,57,66,1|1e0ozz,57,66,1|1e0p00,50,66,0\",\"America/Denver|,0,90,0|-18y0j80,50,66,0|-r0epo1,50,66,0|-r0epo0,52,62,1|-qplwg1,52,62,1|-qplwg0,50,66,0|-qhon01,50,66,0|-qhon00,52,62,1|-q6vts1,52,62,1|-q6vts0,50,66,0|-pyykc1,50,66,0|-pyykc0,52,62,1|-pnssg1,52,62,1|-pnssg0,50,66,0|-pg8ho1,50,66,0|-pg8ho0,52,62,1|-pdcv41,52,62,1|-pdcv40,50,66,0|-ek1z01,50,66,0|-ek1z00,58,62,1|-cq2tg1,58,62,1|-cq2tg0,59,62,1|-cnoxs1,59,62,1|-cnoxs0,50,66,0|-2g1oc1,50,66,0|-2g1oc0,52,62,1|-26br41,52,62,1|-26br40,50,66,0|-1xblo1,50,66,0|-1xblo0,52,62,1|-1nlog1,52,62,1|-1nlog0,50,66,0|-1e8kc1,50,66,0|-1e8kc0,52,62,1|-14vls1,52,62,1|-14vls0,50,66,0|-viho1,50,66,0|-viho0,52,62,1|-m5j41,52,62,1|-m5j40,50,66,0|-csf01,50,66,0|-csf00,52,62,1|-3fgg1,52,62,1|-3fgg0,50,66,0|5xnnz,50,66,0|5xno0,52,62,1|fam7z,52,62,1|fam80,50,66,0|onqbz,50,66,0|onqc0,52,62,1|ydnjz,52,62,1|ydnk0,50,66,0|17qrnz,50,66,0|17qro0,52,62,1|1h3q7z,52,62,1|1h3q80,50,66,0|1qgubz,50,66,0|1qguc0,52,62,1|1ztsvz,52,62,1|1ztsw0,50,66,0|23fibz,50,66,0|23fic0,52,62,1|2ijvjz,52,62,1|2ijvk0,50,66,0|2oobnz,50,66,0|2oobo0,52,62,1|319y7z,52,62,1|319y80,50,66,0|3an2bz,50,66,0|3an2c0,52,62,1|3kczjz,52,62,1|3kczk0,50,66,0|3td4zz,50,66,0|3td500,52,62,1|43327z,52,62,1|433280,50,66,0|4cg6bz,50,66,0|4cg6c0,52,62,1|4lt4vz,52,62,1|4lt4w0,50,66,0|4v68zz,50,66,0|4v6900,52,62,1|54j7jz,52,62,1|54j7k0,50,66,0|5dwbnz,50,66,0|5dwbo0,52,62,1|5n9a7z,52,62,1|5n9a80,50,66,0|5wmebz,50,66,0|5wmec0,52,62,1|65zcvz,52,62,1|65zcw0,50,66,0|6fcgzz,50,66,0|6fch00,52,62,1|6p2e7z,52,62,1|6p2e80,50,66,0|6y2jnz,50,66,0|6y2jo0,52,62,1|77sgvz,52,62,1|77sgw0,50,66,0|7h5kzz,50,66,0|7h5l00,52,62,1|7qijjz,52,62,1|7qijk0,50,66,0|7zvnnz,50,66,0|7zvno0,52,62,1|898m7z,52,62,1|898m80,50,66,0|8ilqbz,50,66,0|8ilqc0,52,62,1|8ryovz,52,62,1|8ryow0,50,66,0|908wzz,50,66,0|908x00,52,62,1|9aorjz,52,62,1|9aork0,50,66,0|9iyznz,50,66,0|9iyzo0,52,62,1|9trsvz,52,62,1|9trsw0,50,66,0|a1p2bz,50,66,0|a1p2c0,52,62,1|achvjz,52,62,1|achvk0,50,66,0|akf4zz,50,66,0|akf500,52,62,1|av7y7z,52,62,1|av7y80,50,66,0|b3i6bz,50,66,0|b3i6c0,52,62,1|bdy0vz,52,62,1|bdy0w0,50,66,0|bm88zz,50,66,0|bm8900,52,62,1|bwo3jz,52,62,1|bwo3k0,50,66,0|c4ybnz,50,66,0|c4ybo0,52,62,1|cfr4vz,52,62,1|cfr4w0,50,66,0|cnoebz,50,66,0|cnoec0,52,62,1|cyh7jz,52,62,1|cyh7k0,50,66,0|d6egzz,50,66,0|d6eh00,52,62,1|dh7a7z,52,62,1|dh7a80,50,66,0|dphibz,50,66,0|dphic0,52,62,1|dzxcvz,52,62,1|dzxcw0,50,66,0|e87kzz,50,66,0|e87l00,52,62,1|einfjz,52,62,1|einfk0,50,66,0|eqxnnz,50,66,0|eqxno0,52,62,1|f1di7z,52,62,1|f1di80,50,66,0|f9nqbz,50,66,0|f9nqc0,52,62,1|fkgjjz,52,62,1|fkgjk0,50,66,0|fsdszz,50,66,0|fsdt00,52,62,1|g36m7z,52,62,1|g36m80,50,66,0|gb3vnz,50,66,0|gb3vo0,52,62,1|glwovz,52,62,1|glwow0,50,66,0|gu6wzz,50,66,0|gu6x00,52,62,1|h4mrjz,52,62,1|h4mrk0,50,66,0|hcwznz,50,66,0|hcwzo0,52,62,1|hncu7z,52,62,1|hncu80,50,66,0|hvn2bz,50,66,0|hvn2c0,52,62,1|i6fvjz,52,62,1|i6fvk0,50,66,0|ied4zz,50,66,0|ied500,52,62,1|ip5y7z,52,62,1|ip5y80,50,66,0|ix37nz,50,66,0|ix37o0,52,62,1|j7w0vz,52,62,1|j7w0w0,50,66,0|jeqebz,50,66,0|jeqec0,52,62,1|jqz27z,52,62,1|jqz280,50,66,0|jxggzz,50,66,0|jxgh00,52,62,1|k9p4vz,52,62,1|k9p4w0,50,66,0|kg6jnz,50,66,0|kg6jo0,52,62,1|ksf7jz,52,62,1|ksf7k0,50,66,0|kz9kzz,50,66,0|kz9l00,52,62,1|lbi8vz,52,62,1|lbi8w0,50,66,0|lhznnz,50,66,0|lhzno0,52,62,1|lu8bjz,52,62,1|lu8bk0,50,66,0|m0pqbz,50,66,0|m0pqc0,52,62,1|mcye7z,52,62,1|mcye80,50,66,0|mjfszz,50,66,0|mjft00,52,62,1|mvogvz,52,62,1|mvogw0,50,66,0|n25vnz,50,66,0|n25vo0,52,62,1|neejjz,52,62,1|neejk0,50,66,0|nkvybz,50,66,0|nkvyc0,52,62,1|nx4m7z,52,62,1|nx4m80,50,66,0|o3yznz,50,66,0|o3yzo0,52,62,1|og7njz,52,62,1|og7nk0,50,66,0|omp2bz,50,66,0|omp2c0,52,62,1|oyxq7z,52,62,1|oyxq80,50,66,0|p5f4zz,50,66,0|p5f500,52,62,1|phnsvz,52,62,1|phnsw0,50,66,0|po57nz,50,66,0|po57o0,52,62,1|q0dvjz,52,62,1|q0dvk0,50,66,0|q6vabz,50,66,0|q6vac0,52,62,1|qj3y7z,52,62,1|qj3y80,50,66,0|qpybnz,50,66,0|qpybo0,52,62,1|r26zjz,52,62,1|r26zk0,50,66,0|r8oebz,50,66,0|r8oec0,52,62,1|rkx27z,52,62,1|rkx280,50,66,0|rregzz,50,66,0|rreh00,52,62,1|s3n4vz,52,62,1|s3n4w0,50,66,0|sa4jnz,50,66,0|sa4jo0,52,62,1|smd7jz,52,62,1|smd7k0,50,66,0|ssumbz,50,66,0|ssumc0,52,62,1|t53a7z,52,62,1|t53a80,50,66,0|tbkozz,50,66,0|tbkp00,52,62,1|tntcvz,52,62,1|tntcw0,50,66,0|tunqbz,50,66,0|tunqc0,52,62,1|u6we7z,52,62,1|u6we80,50,66,0|uddszz,50,66,0|uddt00,52,62,1|upmgvz,52,62,1|upmgw0,50,66,0|uw3vnz,50,66,0|uw3vo0,52,62,1|v8cjjz,52,62,1|v8cjk0,50,66,0|vetybz,50,66,0|vetyc0,52,62,1|vr2m7z,52,62,1|vr2m80,50,66,0|vxk0zz,50,66,0|vxk100,52,62,1|w9sovz,52,62,1|w9sow0,50,66,0|wgn2bz,50,66,0|wgn2c0,52,62,1|wsvq7z,52,62,1|wsvq80,50,66,0|wzd4zz,50,66,0|wzd500,52,62,1|xblsvz,52,62,1|xblsw0,50,66,0|xi37nz,50,66,0|xi37o0,52,62,1|xubvjz,52,62,1|xubvk0,50,66,0|y0tabz,50,66,0|y0tac0,52,62,1|yd1y7z,52,62,1|yd1y80,50,66,0|yjjczz,50,66,0|yjjd00,52,62,1|yvs0vz,52,62,1|yvs0w0,50,66,0|z29fnz,50,66,0|z29fo0,52,62,1|zei3jz,52,62,1|zei3k0,50,66,0\",\"America/Detroit|,0,91,0|-xx8dyd,45,62,0|-sih341,45,62,0|-sih340,49,63,0|-ek24k1,49,63,0|-ek24k0,70,42,1|-cq2tg1,70,42,1|-cq2tg0,71,42,1|-cnp3c1,71,42,1|-cnp3c0,49,63,0|-bbfz81,49,63,0|-bbfz80,62,42,1|-b3ivc1,62,42,1|-b3ivc0,49,63,0|-1bxjed,49,63,0|-1bxjec,62,42,1|-14vrc1,62,42,1|-14vrc0,49,63,0|-vin81,49,63,0|-vin80,62,42,1|-m5oo1,62,42,1|-m5oo0,49,63,0|1qgorz,49,63,0|1qgos0,62,42,1|1ztnbz,62,42,1|1ztnc0,49,63,0|23fcrz,49,63,0|23fcs0,62,42,1|2ijpzz,62,42,1|2ijq00,49,63,0|2rwu3z,49,63,0|2rwu40,62,42,1|319snz,62,42,1|319so0,49,63,0|3amwrz,49,63,0|3amws0,62,42,1|3kctzz,62,42,1|3kcu00,49,63,0|3tczfz,49,63,0|3tczg0,62,42,1|432wnz,62,42,1|432wo0,49,63,0|4cg0rz,49,63,0|4cg0s0,62,42,1|4lszbz,62,42,1|4lszc0,49,63,0|4v63fz,49,63,0|4v63g0,62,42,1|54j1zz,62,42,1|54j200,49,63,0|5dw63z,49,63,0|5dw640,62,42,1|5n94nz,62,42,1|5n94o0,49,63,0|5wm8rz,49,63,0|5wm8s0,62,42,1|65z7bz,62,42,1|65z7c0,49,63,0|6fcbfz,49,63,0|6fcbg0,62,42,1|6p28nz,62,42,1|6p28o0,49,63,0|6y2e3z,49,63,0|6y2e40,62,42,1|77sbbz,62,42,1|77sbc0,49,63,0|7h5ffz,49,63,0|7h5fg0,62,42,1|7qidzz,62,42,1|7qie00,49,63,0|7zvi3z,49,63,0|7zvi40,62,42,1|898gnz,62,42,1|898go0,49,63,0|8ilkrz,49,63,0|8ilks0,62,42,1|8ryjbz,62,42,1|8ryjc0,49,63,0|908rfz,49,63,0|908rg0,62,42,1|9aolzz,62,42,1|9aom00,49,63,0|9iyu3z,49,63,0|9iyu40,62,42,1|9trnbz,62,42,1|9trnc0,49,63,0|a1owrz,49,63,0|a1ows0,62,42,1|achpzz,62,42,1|achq00,49,63,0|akezfz,49,63,0|akezg0,62,42,1|av7snz,62,42,1|av7so0,49,63,0|b3i0rz,49,63,0|b3i0s0,62,42,1|bdxvbz,62,42,1|bdxvc0,49,63,0|bm83fz,49,63,0|bm83g0,62,42,1|bwnxzz,62,42,1|bwny00,49,63,0|c4y63z,49,63,0|c4y640,62,42,1|cfqzbz,62,42,1|cfqzc0,49,63,0|cno8rz,49,63,0|cno8s0,62,42,1|cyh1zz,62,42,1|cyh200,49,63,0|d6ebfz,49,63,0|d6ebg0,62,42,1|dh74nz,62,42,1|dh74o0,49,63,0|dphcrz,49,63,0|dphcs0,62,42,1|dzx7bz,62,42,1|dzx7c0,49,63,0|e87ffz,49,63,0|e87fg0,62,42,1|ein9zz,62,42,1|eina00,49,63,0|eqxi3z,49,63,0|eqxi40,62,42,1|f1dcnz,62,42,1|f1dco0,49,63,0|f9nkrz,49,63,0|f9nks0,62,42,1|fkgdzz,62,42,1|fkge00,49,63,0|fsdnfz,49,63,0|fsdng0,62,42,1|g36gnz,62,42,1|g36go0,49,63,0|gb3q3z,49,63,0|gb3q40,62,42,1|glwjbz,62,42,1|glwjc0,49,63,0|gu6rfz,49,63,0|gu6rg0,62,42,1|h4mlzz,62,42,1|h4mm00,49,63,0|hcwu3z,49,63,0|hcwu40,62,42,1|hnconz,62,42,1|hncoo0,49,63,0|hvmwrz,49,63,0|hvmws0,62,42,1|i6fpzz,62,42,1|i6fq00,49,63,0|ieczfz,49,63,0|ieczg0,62,42,1|ip5snz,62,42,1|ip5so0,49,63,0|ix323z,49,63,0|ix3240,62,42,1|j7vvbz,62,42,1|j7vvc0,49,63,0|jeq8rz,49,63,0|jeq8s0,62,42,1|jqywnz,62,42,1|jqywo0,49,63,0|jxgbfz,49,63,0|jxgbg0,62,42,1|k9ozbz,62,42,1|k9ozc0,49,63,0|kg6e3z,49,63,0|kg6e40,62,42,1|ksf1zz,62,42,1|ksf200,49,63,0|kz9ffz,49,63,0|kz9fg0,62,42,1|lbi3bz,62,42,1|lbi3c0,49,63,0|lhzi3z,49,63,0|lhzi40,62,42,1|lu85zz,62,42,1|lu8600,49,63,0|m0pkrz,49,63,0|m0pks0,62,42,1|mcy8nz,62,42,1|mcy8o0,49,63,0|mjfnfz,49,63,0|mjfng0,62,42,1|mvobbz,62,42,1|mvobc0,49,63,0|n25q3z,49,63,0|n25q40,62,42,1|needzz,62,42,1|neee00,49,63,0|nkvsrz,49,63,0|nkvss0,62,42,1|nx4gnz,62,42,1|nx4go0,49,63,0|o3yu3z,49,63,0|o3yu40,62,42,1|og7hzz,62,42,1|og7i00,49,63,0|omowrz,49,63,0|omows0,62,42,1|oyxknz,62,42,1|oyxko0,49,63,0|p5ezfz,49,63,0|p5ezg0,62,42,1|phnnbz,62,42,1|phnnc0,49,63,0|po523z,49,63,0|po5240,62,42,1|q0dpzz,62,42,1|q0dq00,49,63,0|q6v4rz,49,63,0|q6v4s0,62,42,1|qj3snz,62,42,1|qj3so0,49,63,0|qpy63z,49,63,0|qpy640,62,42,1|r26tzz,62,42,1|r26u00,49,63,0|r8o8rz,49,63,0|r8o8s0,62,42,1|rkwwnz,62,42,1|rkwwo0,49,63,0|rrebfz,49,63,0|rrebg0,62,42,1|s3mzbz,62,42,1|s3mzc0,49,63,0|sa4e3z,49,63,0|sa4e40,62,42,1|smd1zz,62,42,1|smd200,49,63,0|ssugrz,49,63,0|ssugs0,62,42,1|t534nz,62,42,1|t534o0,49,63,0|tbkjfz,49,63,0|tbkjg0,62,42,1|tnt7bz,62,42,1|tnt7c0,49,63,0|tunkrz,49,63,0|tunks0,62,42,1|u6w8nz,62,42,1|u6w8o0,49,63,0|uddnfz,49,63,0|uddng0,62,42,1|upmbbz,62,42,1|upmbc0,49,63,0|uw3q3z,49,63,0|uw3q40,62,42,1|v8cdzz,62,42,1|v8ce00,49,63,0|vetsrz,49,63,0|vetss0,62,42,1|vr2gnz,62,42,1|vr2go0,49,63,0|vxjvfz,49,63,0|vxjvg0,62,42,1|w9sjbz,62,42,1|w9sjc0,49,63,0|wgmwrz,49,63,0|wgmws0,62,42,1|wsvknz,62,42,1|wsvko0,49,63,0|wzczfz,49,63,0|wzczg0,62,42,1|xblnbz,62,42,1|xblnc0,49,63,0|xi323z,49,63,0|xi3240,62,42,1|xubpzz,62,42,1|xubq00,49,63,0|y0t4rz,49,63,0|y0t4s0,62,42,1|yd1snz,62,42,1|yd1so0,49,63,0|yjj7fz,49,63,0|yjj7g0,62,42,1|yvrvbz,62,42,1|yvrvc0,49,63,0|z29a3z,49,63,0|z29a40,62,42,1|zehxzz,62,42,1|zehy00,49,63,0\",\"America/Dominica|,0,41,0|-u6m79w,32,42,0\",\"America/Edmonton|,0,92,0|-x1yazk,50,66,0|-qzosc1,50,66,0|-qzosc0,52,62,1|-qplwg1,52,62,1|-qplwg0,50,66,0|-qgypo1,50,66,0|-qgypo0,52,62,1|-qepb41,52,62,1|-qepb40,50,66,0|-pxipo1,50,66,0|-pxipo0,52,62,1|-pnssg1,52,62,1|-pnssg0,50,66,0|-pesn01,50,66,0|-pesn00,52,62,1|-p6vj41,52,62,1|-p6vj40,50,66,0|-ovplo1,50,66,0|-ovplo0,52,62,1|-oo5gg1,52,62,1|-oo5gg0,50,66,0|-oczj01,50,66,0|-oczj00,52,62,1|-o52f41,52,62,1|-o52f40,50,66,0|-ek1z01,50,66,0|-ek1z00,58,62,1|-cq2tg1,58,62,1|-cq2tg0,59,62,1|-cnoxs1,59,62,1|-cnoxs0,50,66,0|-bu5wc1,50,66,0|-bu5wc0,52,62,1|-bm8sg1,52,62,1|-bm8sg0,50,66,0|17qrnz,50,66,0|17qro0,52,62,1|1h3q7z,52,62,1|1h3q80,50,66,0|1qgubz,50,66,0|1qguc0,52,62,1|1ztsvz,52,62,1|1ztsw0,50,66,0|296wzz,50,66,0|296x00,52,62,1|2ijvjz,52,62,1|2ijvk0,50,66,0|2rwznz,50,66,0|2rwzo0,52,62,1|319y7z,52,62,1|319y80,50,66,0|3an2bz,50,66,0|3an2c0,52,62,1|3kczjz,52,62,1|3kczk0,50,66,0|3td4zz,50,66,0|3td500,52,62,1|43327z,52,62,1|433280,50,66,0|4cg6bz,50,66,0|4cg6c0,52,62,1|4lt4vz,52,62,1|4lt4w0,50,66,0|4v68zz,50,66,0|4v6900,52,62,1|54j7jz,52,62,1|54j7k0,50,66,0|5dwbnz,50,66,0|5dwbo0,52,62,1|5n9a7z,52,62,1|5n9a80,50,66,0|5wmebz,50,66,0|5wmec0,52,62,1|65zcvz,52,62,1|65zcw0,50,66,0|6fcgzz,50,66,0|6fch00,52,62,1|6p2e7z,52,62,1|6p2e80,50,66,0|6y2jnz,50,66,0|6y2jo0,52,62,1|77sgvz,52,62,1|77sgw0,50,66,0|7h5kzz,50,66,0|7h5l00,52,62,1|7qijjz,52,62,1|7qijk0,50,66,0|7zvnnz,50,66,0|7zvno0,52,62,1|898m7z,52,62,1|898m80,50,66,0|8ilqbz,50,66,0|8ilqc0,52,62,1|8ryovz,52,62,1|8ryow0,50,66,0|908wzz,50,66,0|908x00,52,62,1|9aorjz,52,62,1|9aork0,50,66,0|9iyznz,50,66,0|9iyzo0,52,62,1|9trsvz,52,62,1|9trsw0,50,66,0|a1p2bz,50,66,0|a1p2c0,52,62,1|achvjz,52,62,1|achvk0,50,66,0|akf4zz,50,66,0|akf500,52,62,1|av7y7z,52,62,1|av7y80,50,66,0|b3i6bz,50,66,0|b3i6c0,52,62,1|bdy0vz,52,62,1|bdy0w0,50,66,0|bm88zz,50,66,0|bm8900,52,62,1|bwo3jz,52,62,1|bwo3k0,50,66,0|c4ybnz,50,66,0|c4ybo0,52,62,1|cfr4vz,52,62,1|cfr4w0,50,66,0|cnoebz,50,66,0|cnoec0,52,62,1|cyh7jz,52,62,1|cyh7k0,50,66,0|d6egzz,50,66,0|d6eh00,52,62,1|dh7a7z,52,62,1|dh7a80,50,66,0|dphibz,50,66,0|dphic0,52,62,1|dzxcvz,52,62,1|dzxcw0,50,66,0|e87kzz,50,66,0|e87l00,52,62,1|einfjz,52,62,1|einfk0,50,66,0|eqxnnz,50,66,0|eqxno0,52,62,1|f1di7z,52,62,1|f1di80,50,66,0|f9nqbz,50,66,0|f9nqc0,52,62,1|fkgjjz,52,62,1|fkgjk0,50,66,0|fsdszz,50,66,0|fsdt00,52,62,1|g36m7z,52,62,1|g36m80,50,66,0|gb3vnz,50,66,0|gb3vo0,52,62,1|glwovz,52,62,1|glwow0,50,66,0|gu6wzz,50,66,0|gu6x00,52,62,1|h4mrjz,52,62,1|h4mrk0,50,66,0|hcwznz,50,66,0|hcwzo0,52,62,1|hncu7z,52,62,1|hncu80,50,66,0|hvn2bz,50,66,0|hvn2c0,52,62,1|i6fvjz,52,62,1|i6fvk0,50,66,0|ied4zz,50,66,0|ied500,52,62,1|ip5y7z,52,62,1|ip5y80,50,66,0|ix37nz,50,66,0|ix37o0,52,62,1|j7w0vz,52,62,1|j7w0w0,50,66,0|jeqebz,50,66,0|jeqec0,52,62,1|jqz27z,52,62,1|jqz280,50,66,0|jxggzz,50,66,0|jxgh00,52,62,1|k9p4vz,52,62,1|k9p4w0,50,66,0|kg6jnz,50,66,0|kg6jo0,52,62,1|ksf7jz,52,62,1|ksf7k0,50,66,0|kz9kzz,50,66,0|kz9l00,52,62,1|lbi8vz,52,62,1|lbi8w0,50,66,0|lhznnz,50,66,0|lhzno0,52,62,1|lu8bjz,52,62,1|lu8bk0,50,66,0|m0pqbz,50,66,0|m0pqc0,52,62,1|mcye7z,52,62,1|mcye80,50,66,0|mjfszz,50,66,0|mjft00,52,62,1|mvogvz,52,62,1|mvogw0,50,66,0|n25vnz,50,66,0|n25vo0,52,62,1|neejjz,52,62,1|neejk0,50,66,0|nkvybz,50,66,0|nkvyc0,52,62,1|nx4m7z,52,62,1|nx4m80,50,66,0|o3yznz,50,66,0|o3yzo0,52,62,1|og7njz,52,62,1|og7nk0,50,66,0|omp2bz,50,66,0|omp2c0,52,62,1|oyxq7z,52,62,1|oyxq80,50,66,0|p5f4zz,50,66,0|p5f500,52,62,1|phnsvz,52,62,1|phnsw0,50,66,0|po57nz,50,66,0|po57o0,52,62,1|q0dvjz,52,62,1|q0dvk0,50,66,0|q6vabz,50,66,0|q6vac0,52,62,1|qj3y7z,52,62,1|qj3y80,50,66,0|qpybnz,50,66,0|qpybo0,52,62,1|r26zjz,52,62,1|r26zk0,50,66,0|r8oebz,50,66,0|r8oec0,52,62,1|rkx27z,52,62,1|rkx280,50,66,0|rregzz,50,66,0|rreh00,52,62,1|s3n4vz,52,62,1|s3n4w0,50,66,0|sa4jnz,50,66,0|sa4jo0,52,62,1|smd7jz,52,62,1|smd7k0,50,66,0|ssumbz,50,66,0|ssumc0,52,62,1|t53a7z,52,62,1|t53a80,50,66,0|tbkozz,50,66,0|tbkp00,52,62,1|tntcvz,52,62,1|tntcw0,50,66,0|tunqbz,50,66,0|tunqc0,52,62,1|u6we7z,52,62,1|u6we80,50,66,0|uddszz,50,66,0|uddt00,52,62,1|upmgvz,52,62,1|upmgw0,50,66,0|uw3vnz,50,66,0|uw3vo0,52,62,1|v8cjjz,52,62,1|v8cjk0,50,66,0|vetybz,50,66,0|vetyc0,52,62,1|vr2m7z,52,62,1|vr2m80,50,66,0|vxk0zz,50,66,0|vxk100,52,62,1|w9sovz,52,62,1|w9sow0,50,66,0|wgn2bz,50,66,0|wgn2c0,52,62,1|wsvq7z,52,62,1|wsvq80,50,66,0|wzd4zz,50,66,0|wzd500,52,62,1|xblsvz,52,62,1|xblsw0,50,66,0|xi37nz,50,66,0|xi37o0,52,62,1|xubvjz,52,62,1|xubvk0,50,66,0|y0tabz,50,66,0|y0tac0,52,62,1|yd1y7z,52,62,1|yd1y80,50,66,0|yjjczz,50,66,0|yjjd00,52,62,1|yvs0vz,52,62,1|yvs0w0,50,66,0|z29fnz,50,66,0|z29fo0,52,62,1|zei3jz,52,62,1|zei3k0,50,66,0\",\"America/Eirunepe|,0,93,0|-t85f28,56,63,0|-jyl4w1,56,63,0|-jyl4w0,42,42,1|-jpavk1,42,42,1|-jpavk0,56,63,0|-jfs7g1,56,63,0|-jfs7g0,42,42,1|-j6iy81,42,42,1|-j6iy80,56,63,0|-ahcss1,56,63,0|-ahcss0,42,42,1|-aacy41,42,42,1|-aacy40,56,63,0|-9ykvg1,56,63,0|-9ykvg0,42,42,1|-9scvk1,42,42,1|-9scvk0,56,63,0|-9fsy41,56,63,0|-9fsy40,42,42,1|-99j3k1,42,42,1|-99j3k0,56,63,0|-8wz641,56,63,0|-8wz640,42,42,1|-8sckw1,42,42,1|-8sckw0,56,63,0|-35xgs1,56,63,0|-35xgs0,42,42,1|-31nu81,42,42,1|-31nu80,56,63,0|-2kdjg1,56,63,0|-2kdjg0,42,42,1|-2hccw1,42,42,1|-2hccw0,56,63,0|-24qks1,56,63,0|-24qks0,42,42,1|-203zk1,42,42,1|-203zk0,56,63,0|-1ni7g1,56,63,0|-1ni7g0,42,42,1|-1hc281,42,42,1|-1hc280,56,63,0|-14qa41,56,63,0|-14qa40,42,42,1|-yia81,42,42,1|-yia80,56,63,0|89jhvz,56,63,0|89jhw0,42,42,1|8gdprz,42,42,1|8gdps0,56,63,0|8rwlvz,56,63,0|8rwlw0,42,42,1|8xnxrz,42,42,1|8xnxs0,56,63,0|9aoj7z,56,63,0|9aoj80,42,42,1|9g2wfz,42,42,1|9g2wg0,56,63,0|cf0z7z,56,63,0|cf0z80,42,42,1|cli8fz,42,42,1|cli8g0,56,63,0|k2yb7z,56,63,0|k2yb80,42,42,0|mw14fz,42,42,0|mw14g0,56,63,0\",\"America/El_Salvador|,0,94,0|-pkm4tc,45,62,0|91ojbz,45,62,0|91ojc0,46,63,1|998ojz,46,63,1|998ok0,45,62,0|9kelzz,45,62,0|9kem00,46,63,1|9ryr7z,46,63,1|9ryr80,45,62,0\",\"America/Fort_Nelson|,0,95,0|-18vrvy1,51,40,0|-qzopk1,51,40,0|-qzopk0,57,66,1|-qplto1,57,66,1|-qplto0,51,40,0|-ek1w81,51,40,0|-ek1w80,68,66,1|-cq2tg1,68,66,1|-cq2tg0,69,66,1|-cnov01,69,66,1|-cnov00,51,40,0|-bu5tk1,51,40,0|-bu5tk0,57,66,1|-bm8po1,57,66,1|-bm8po0,51,40,0|-bbfqw1,51,40,0|-bbfqw0,57,66,1|-b3in01,57,66,1|-b3in00,51,40,0|-aspo81,51,40,0|-aspo80,57,66,1|-akskc1,57,66,1|-akskc0,51,40,0|-a9mmw1,51,40,0|-a9mmw0,57,66,1|-a22ho1,57,66,1|-a22ho0,51,40,0|-9qwk81,51,40,0|-9qwk80,57,66,1|-9izgc1,57,66,1|-9izgc0,51,40,0|-986hk1,51,40,0|-986hk0,57,66,1|-909do1,57,66,1|-909do0,51,40,0|-8pgew1,51,40,0|-8pgew0,57,66,1|-8hjb01,57,66,1|-8hjb00,51,40,0|-86qc81,51,40,0|-86qc80,57,66,1|-7yt8c1,57,66,1|-7yt8c0,51,40,0|-7o09k1,51,40,0|-7o09k0,57,66,1|-7g35o1,57,66,1|-7g35o0,51,40,0|-74x881,51,40,0|-74x880,57,66,1|-6x04c1,57,66,1|-6x04c0,51,40,0|-6m75k1,51,40,0|-6m75k0,57,66,1|-6ea1o1,57,66,1|-6ea1o0,51,40,0|-63h2w1,51,40,0|-63h2w0,57,66,1|-5vjz01,57,66,1|-5vjz00,51,40,0|-5kr081,51,40,0|-5kr080,57,66,1|-5ctwc1,57,66,1|-5ctwc0,51,40,0|-520xk1,51,40,0|-520xk0,57,66,1|-4u3to1,57,66,1|-4u3to0,51,40,0|-4ixw81,51,40,0|-4ixw80,57,66,1|-4bdr01,57,66,1|-4bdr00,51,40,0|-407tk1,51,40,0|-407tk0,57,66,1|-3quv01,57,66,1|-3quv00,51,40,0|-3hhqw1,51,40,0|-3hhqw0,57,66,1|-384sc1,57,66,1|-384sc0,51,40,0|-2yro81,51,40,0|-2yro80,57,66,1|-2pepo1,57,66,1|-2pepo0,51,40,0|-2g1lk1,51,40,0|-2g1lk0,57,66,1|-26boc1,57,66,1|-26boc0,51,40,0|-1xbiw1,51,40,0|-1xbiw0,57,66,1|-1nllo1,57,66,1|-1nllo0,51,40,0|-1e8hk1,51,40,0|-1e8hk0,57,66,1|-14vj01,57,66,1|-14vj00,51,40,0|-view1,51,40,0|-view0,57,66,1|-m5gc1,57,66,1|-m5gc0,51,40,0|-csc81,51,40,0|-csc80,57,66,1|-3fdo1,57,66,1|-3fdo0,51,40,0|5xqfz,51,40,0|5xqg0,57,66,1|faozz,57,66,1|fap00,51,40,0|ont3z,51,40,0|ont40,57,66,1|ydqbz,57,66,1|ydqc0,51,40,0|17qufz,51,40,0|17qug0,57,66,1|1h3szz,57,66,1|1h3t00,51,40,0|1qgx3z,51,40,0|1qgx40,57,66,1|1ztvnz,57,66,1|1ztvo0,51,40,0|296zrz,51,40,0|296zs0,57,66,1|2ijybz,57,66,1|2ijyc0,51,40,0|2rx2fz,51,40,0|2rx2g0,57,66,1|31a0zz,57,66,1|31a100,51,40,0|3an53z,51,40,0|3an540,57,66,1|3kd2bz,57,66,1|3kd2c0,51,40,0|3td7rz,51,40,0|3td7s0,57,66,1|4334zz,57,66,1|433500,51,40,0|4cg93z,51,40,0|4cg940,57,66,1|4lt7nz,57,66,1|4lt7o0,51,40,0|4v6brz,51,40,0|4v6bs0,57,66,1|54jabz,57,66,1|54jac0,51,40,0|5dwefz,51,40,0|5dweg0,57,66,1|5n9czz,57,66,1|5n9d00,51,40,0|5wmh3z,51,40,0|5wmh40,57,66,1|65zfnz,57,66,1|65zfo0,51,40,0|6fcjrz,51,40,0|6fcjs0,57,66,1|6p2gzz,57,66,1|6p2h00,51,40,0|6y2mfz,51,40,0|6y2mg0,57,66,1|77sjnz,57,66,1|77sjo0,51,40,0|7h5nrz,51,40,0|7h5ns0,57,66,1|7qimbz,57,66,1|7qimc0,51,40,0|7zvqfz,51,40,0|7zvqg0,57,66,1|898ozz,57,66,1|898p00,51,40,0|8ilt3z,51,40,0|8ilt40,57,66,1|8ryrnz,57,66,1|8ryro0,51,40,0|908zrz,51,40,0|908zs0,57,66,1|9aoubz,57,66,1|9aouc0,51,40,0|9iz2fz,51,40,0|9iz2g0,57,66,1|9trvnz,57,66,1|9trvo0,51,40,0|a1p53z,51,40,0|a1p540,57,66,1|achybz,57,66,1|achyc0,51,40,0|akf7rz,51,40,0|akf7s0,57,66,1|av80zz,57,66,1|av8100,51,40,0|b3i93z,51,40,0|b3i940,57,66,1|bdy3nz,57,66,1|bdy3o0,51,40,0|bm8brz,51,40,0|bm8bs0,57,66,1|bwo6bz,57,66,1|bwo6c0,51,40,0|c4yefz,51,40,0|c4yeg0,57,66,1|cfr7nz,57,66,1|cfr7o0,51,40,0|cnoh3z,51,40,0|cnoh40,57,66,1|cyhabz,57,66,1|cyhac0,51,40,0|d6ejrz,51,40,0|d6ejs0,57,66,1|dh7czz,57,66,1|dh7d00,51,40,0|dphl3z,51,40,0|dphl40,57,66,1|dzxfnz,57,66,1|dzxfo0,51,40,0|e87nrz,51,40,0|e87ns0,57,66,1|einibz,57,66,1|einic0,51,40,0|eqxqfz,51,40,0|eqxqg0,57,66,1|f1dkzz,57,66,1|f1dl00,51,40,0|f9nt3z,51,40,0|f9nt40,57,66,1|fkgmbz,57,66,1|fkgmc0,51,40,0|fsdvrz,51,40,0|fsdvs0,57,66,1|g36ozz,57,66,1|g36p00,51,40,0|gb3yfz,51,40,0|gb3yg0,57,66,1|glwrnz,57,66,1|glwro0,51,40,0|gu6zrz,51,40,0|gu6zs0,57,66,1|h4mubz,57,66,1|h4muc0,51,40,0|hcx2fz,51,40,0|hcx2g0,57,66,1|hncwzz,57,66,1|hncx00,51,40,0|hvn53z,51,40,0|hvn540,57,66,1|i6fybz,57,66,1|i6fyc0,51,40,0|ied7rz,51,40,0|ied7s0,57,66,1|ip60zz,57,66,1|ip6100,51,40,0|ix3afz,51,40,0|ix3ag0,57,66,1|j7w3nz,57,66,1|j7w3o0,51,40,0|jeqh3z,51,40,0|jeqh40,57,66,1|jqz4zz,57,66,1|jqz500,51,40,0|jxgjrz,51,40,0|jxgjs0,57,66,1|k9p7nz,57,66,1|k9p7o0,51,40,0|kg6mfz,51,40,0|kg6mg0,57,66,1|ksfabz,57,66,1|ksfac0,51,40,0|kz9nrz,51,40,0|kz9ns0,57,66,1|lbibnz,57,66,1|lbibo0,51,40,0|lhzqfz,51,40,0|lhzqg0,57,66,1|lu8ebz,57,66,1|lu8ec0,51,40,0|m0pt3z,51,40,0|m0pt40,57,66,1|mcygzz,57,66,1|mcyh00,51,40,0|mjfvrz,51,40,0|mjfvs0,57,66,1|mvojnz,57,66,1|mvojo0,51,40,0|n25yfz,51,40,0|n25yg0,57,66,1|neembz,57,66,1|neemc0,51,40,0|nkw13z,51,40,0|nkw140,50,66,0\",\"America/Fortaleza|,0,96,0|-t85kvc,39,44,0|-jylag1,39,44,0|-jylag0,40,45,1|-jpb141,40,45,1|-jpb140,39,44,0|-jfsd01,39,44,0|-jfsd00,40,45,1|-j6j3s1,40,45,1|-j6j3s0,39,44,0|-ahcyc1,39,44,0|-ahcyc0,40,45,1|-aad3o1,40,45,1|-aad3o0,39,44,0|-9yl101,39,44,0|-9yl100,40,45,1|-9sd141,40,45,1|-9sd140,39,44,0|-9ft3o1,39,44,0|-9ft3o0,40,45,1|-99j941,40,45,1|-99j940,39,44,0|-8wzbo1,39,44,0|-8wzbo0,40,45,1|-8scqg1,40,45,1|-8scqg0,39,44,0|-35xmc1,39,44,0|-35xmc0,40,45,1|-31nzs1,40,45,1|-31nzs0,39,44,0|-2kdp01,39,44,0|-2kdp00,40,45,1|-2hcig1,40,45,1|-2hcig0,39,44,0|-24qqc1,39,44,0|-24qqc0,40,45,1|-204541,40,45,1|-204540,39,44,0|-1nid01,39,44,0|-1nid00,40,45,1|-1hc7s1,40,45,1|-1hc7s0,39,44,0|-14qfo1,39,44,0|-14qfo0,40,45,1|-yifs1,40,45,1|-yifs0,39,44,0|89jcbz,39,44,0|89jcc0,40,45,1|8gdk7z,40,45,1|8gdk80,39,44,0|8rwgbz,39,44,0|8rwgc0,40,45,1|8xns7z,40,45,1|8xns80,39,44,0|9aodnz,39,44,0|9aodo0,40,45,1|9g2qvz,40,45,1|9g2qw0,39,44,0|9t1hnz,39,44,0|9t1ho0,40,45,1|9yfuvz,40,45,1|9yfuw0,39,44,0|abrkbz,39,44,0|abrkc0,40,45,1|ahvuvz,40,45,1|ahvuw0,39,44,0|fj0azz,39,44,0|fj0b00,40,45,1|fqkg7z,40,45,1|fqkg80,39,44,0|g23cbz,39,44,0|g23cc0,40,45,1|g2t6vz,40,45,1|g2t6w0,39,44,0|gl6dnz,39,44,0|gl6do0,40,45,1|grnmvz,40,45,1|grnmw0,39,44,0\",\"America/Glace_Bay|,0,97,0|-z94kwc,32,42,0|-qzp0o1,32,42,0|-qzp0o0,54,44,1|-qpm4s1,54,44,1|-qpm4s0,32,42,0|-ek27c1,32,42,0|-ek27c0,33,44,1|-cq2tg1,33,44,1|-cq2tg0,34,44,1|-cnp641,34,44,1|-cnp640,32,42,0|-8pgq01,32,42,0|-8pgq00,54,44,1|-8hjm41,54,44,1|-8hjm40,32,42,0|17qjbz,32,42,0|17qjc0,54,44,1|1h3hvz,54,44,1|1h3hw0,32,42,0|1qglzz,32,42,0|1qgm00,54,44,1|1ztkjz,54,44,1|1ztkk0,32,42,0|296onz,32,42,0|296oo0,54,44,1|2ijn7z,54,44,1|2ijn80,32,42,0|2rwrbz,32,42,0|2rwrc0,54,44,1|319pvz,54,44,1|319pw0,32,42,0|3amtzz,32,42,0|3amu00,54,44,1|3kcr7z,54,44,1|3kcr80,32,42,0|3tcwnz,32,42,0|3tcwo0,54,44,1|432tvz,54,44,1|432tw0,32,42,0|4cfxzz,32,42,0|4cfy00,54,44,1|4lswjz,54,44,1|4lswk0,32,42,0|4v60nz,32,42,0|4v60o0,54,44,1|54iz7z,54,44,1|54iz80,32,42,0|5dw3bz,32,42,0|5dw3c0,54,44,1|5n91vz,54,44,1|5n91w0,32,42,0|5wm5zz,32,42,0|5wm600,54,44,1|65z4jz,54,44,1|65z4k0,32,42,0|6fc8nz,32,42,0|6fc8o0,54,44,1|6p25vz,54,44,1|6p25w0,32,42,0|6y2bbz,32,42,0|6y2bc0,54,44,1|77s8jz,54,44,1|77s8k0,32,42,0|7h5cnz,32,42,0|7h5co0,54,44,1|7qib7z,54,44,1|7qib80,32,42,0|7zvfbz,32,42,0|7zvfc0,54,44,1|898dvz,54,44,1|898dw0,32,42,0|8ilhzz,32,42,0|8ili00,54,44,1|8rygjz,54,44,1|8rygk0,32,42,0|908onz,32,42,0|908oo0,54,44,1|9aoj7z,54,44,1|9aoj80,32,42,0|9iyrbz,32,42,0|9iyrc0,54,44,1|9trkjz,54,44,1|9trkk0,32,42,0|a1otzz,32,42,0|a1ou00,54,44,1|achn7z,54,44,1|achn80,32,42,0|akewnz,32,42,0|akewo0,54,44,1|av7pvz,54,44,1|av7pw0,32,42,0|b3hxzz,32,42,0|b3hy00,54,44,1|bdxsjz,54,44,1|bdxsk0,32,42,0|bm80nz,32,42,0|bm80o0,54,44,1|bwnv7z,54,44,1|bwnv80,32,42,0|c4y3bz,32,42,0|c4y3c0,54,44,1|cfqwjz,54,44,1|cfqwk0,32,42,0|cno5zz,32,42,0|cno600,54,44,1|cygz7z,54,44,1|cygz80,32,42,0|d6e8nz,32,42,0|d6e8o0,54,44,1|dh71vz,54,44,1|dh71w0,32,42,0|dph9zz,32,42,0|dpha00,54,44,1|dzx4jz,54,44,1|dzx4k0,32,42,0|e87cnz,32,42,0|e87co0,54,44,1|ein77z,54,44,1|ein780,32,42,0|eqxfbz,32,42,0|eqxfc0,54,44,1|f1d9vz,54,44,1|f1d9w0,32,42,0|f9nhzz,32,42,0|f9ni00,54,44,1|fkgb7z,54,44,1|fkgb80,32,42,0|fsdknz,32,42,0|fsdko0,54,44,1|g36dvz,54,44,1|g36dw0,32,42,0|gb3nbz,32,42,0|gb3nc0,54,44,1|glwgjz,54,44,1|glwgk0,32,42,0|gu6onz,32,42,0|gu6oo0,54,44,1|h4mj7z,54,44,1|h4mj80,32,42,0|hcwrbz,32,42,0|hcwrc0,54,44,1|hnclvz,54,44,1|hnclw0,32,42,0|hvmtzz,32,42,0|hvmu00,54,44,1|i6fn7z,54,44,1|i6fn80,32,42,0|iecwnz,32,42,0|iecwo0,54,44,1|ip5pvz,54,44,1|ip5pw0,32,42,0|ix2zbz,32,42,0|ix2zc0,54,44,1|j7vsjz,54,44,1|j7vsk0,32,42,0|jeq5zz,32,42,0|jeq600,54,44,1|jqytvz,54,44,1|jqytw0,32,42,0|jxg8nz,32,42,0|jxg8o0,54,44,1|k9owjz,54,44,1|k9owk0,32,42,0|kg6bbz,32,42,0|kg6bc0,54,44,1|ksez7z,54,44,1|ksez80,32,42,0|kz9cnz,32,42,0|kz9co0,54,44,1|lbi0jz,54,44,1|lbi0k0,32,42,0|lhzfbz,32,42,0|lhzfc0,54,44,1|lu837z,54,44,1|lu8380,32,42,0|m0phzz,32,42,0|m0pi00,54,44,1|mcy5vz,54,44,1|mcy5w0,32,42,0|mjfknz,32,42,0|mjfko0,54,44,1|mvo8jz,54,44,1|mvo8k0,32,42,0|n25nbz,32,42,0|n25nc0,54,44,1|neeb7z,54,44,1|neeb80,32,42,0|nkvpzz,32,42,0|nkvq00,54,44,1|nx4dvz,54,44,1|nx4dw0,32,42,0|o3yrbz,32,42,0|o3yrc0,54,44,1|og7f7z,54,44,1|og7f80,32,42,0|omotzz,32,42,0|omou00,54,44,1|oyxhvz,54,44,1|oyxhw0,32,42,0|p5ewnz,32,42,0|p5ewo0,54,44,1|phnkjz,54,44,1|phnkk0,32,42,0|po4zbz,32,42,0|po4zc0,54,44,1|q0dn7z,54,44,1|q0dn80,32,42,0|q6v1zz,32,42,0|q6v200,54,44,1|qj3pvz,54,44,1|qj3pw0,32,42,0|qpy3bz,32,42,0|qpy3c0,54,44,1|r26r7z,54,44,1|r26r80,32,42,0|r8o5zz,32,42,0|r8o600,54,44,1|rkwtvz,54,44,1|rkwtw0,32,42,0|rre8nz,32,42,0|rre8o0,54,44,1|s3mwjz,54,44,1|s3mwk0,32,42,0|sa4bbz,32,42,0|sa4bc0,54,44,1|smcz7z,54,44,1|smcz80,32,42,0|ssudzz,32,42,0|ssue00,54,44,1|t531vz,54,44,1|t531w0,32,42,0|tbkgnz,32,42,0|tbkgo0,54,44,1|tnt4jz,54,44,1|tnt4k0,32,42,0|tunhzz,32,42,0|tuni00,54,44,1|u6w5vz,54,44,1|u6w5w0,32,42,0|uddknz,32,42,0|uddko0,54,44,1|upm8jz,54,44,1|upm8k0,32,42,0|uw3nbz,32,42,0|uw3nc0,54,44,1|v8cb7z,54,44,1|v8cb80,32,42,0|vetpzz,32,42,0|vetq00,54,44,1|vr2dvz,54,44,1|vr2dw0,32,42,0|vxjsnz,32,42,0|vxjso0,54,44,1|w9sgjz,54,44,1|w9sgk0,32,42,0|wgmtzz,32,42,0|wgmu00,54,44,1|wsvhvz,54,44,1|wsvhw0,32,42,0|wzcwnz,32,42,0|wzcwo0,54,44,1|xblkjz,54,44,1|xblkk0,32,42,0|xi2zbz,32,42,0|xi2zc0,54,44,1|xubn7z,54,44,1|xubn80,32,42,0|y0t1zz,32,42,0|y0t200,54,44,1|yd1pvz,54,44,1|yd1pw0,32,42,0|yjj4nz,32,42,0|yjj4o0,54,44,1|yvrsjz,54,44,1|yvrsk0,32,42,0|z297bz,32,42,0|z297c0,54,44,1|zehv7z,54,44,1|zehv80,32,42,0\",\"America/Goose_Bay|,0,98,0|-18vs7h8,24,99,0|-qzp20l,24,99,0|-qzp20k,72,100,1|-qpm64l,72,100,1|-qpm64k,24,99,0|-i52u8l,24,99,0|-i52u8k,24,101,0|-hk3aa1,24,101,0|-hk3aa0,72,102,1|-hcj521,72,102,1|-hcj520,24,101,0|-h1d7m1,24,101,0|-h1d7m0,72,102,1|-gtt2e1,72,102,1|-gtt2e0,24,101,0|-gin4y1,24,101,0|-gin4y0,72,102,1|-gb2zq1,72,102,1|-gb2zq0,24,101,0|-fzk3m1,24,101,0|-fzk3m0,72,102,1|-fscx21,72,102,1|-fscx20,24,101,0|-fgu0y1,24,101,0|-fgu0y0,72,102,1|-f99vq1,72,102,1|-f99vq0,24,101,0|-ey3ya1,24,101,0|-ey3ya0,72,102,1|-eqjt21,72,102,1|-eqjt20,24,101,0|-efdvm1,24,101,0|-efdvm0,25,102,1|-cq2tg1,25,102,1|-cq2tg0,26,102,1|-cnp7i1,26,102,1|-cnp7i0,24,101,0|-cc6be1,24,101,0|-cc6be0,72,102,1|-c4m661,72,102,1|-c4m660,24,101,0|-btg8q1,24,101,0|-btg8q0,72,102,1|-blw3i1,72,102,1|-blw3i0,24,101,0|-baq621,24,101,0|-baq620,72,102,1|-b360u1,72,102,1|-b360u0,24,101,0|-as03e1,24,101,0|-as03e0,72,102,1|-akfy61,72,102,1|-akfy60,24,101,0|-a8x221,24,101,0|-a8x220,72,102,1|-a1cwu1,72,102,1|-a1cwu0,24,101,0|-9qwwq1,24,101,0|-9qwwq0,72,102,1|-9izsu1,72,102,1|-9izsu0,24,101,0|-986u21,24,101,0|-986u20,72,102,1|-909q61,72,102,1|-909q60,24,101,0|-8pgre1,24,101,0|-8pgre0,72,102,1|-8hjni1,72,102,1|-8hjni0,24,101,0|-86qoq1,24,101,0|-86qoq0,72,102,1|-7ytku1,72,102,1|-7ytku0,24,101,0|-7o0m21,24,101,0|-7o0m20,72,102,1|-7g3i61,72,102,1|-7g3i60,24,101,0|-74xkq1,24,101,0|-74xkq0,72,102,1|-6x0gu1,72,102,1|-6x0gu0,24,101,0|-6m7i21,24,101,0|-6m7i20,72,102,1|-6eae61,72,102,1|-6eae60,24,101,0|-63hfe1,24,101,0|-63hfe0,72,102,1|-5vkbi1,72,102,1|-5vkbi0,24,101,0|-5krcq1,24,101,0|-5krcq0,72,102,1|-5cu8u1,72,102,1|-5cu8u0,24,101,0|-521a21,24,101,0|-521a20,72,102,1|-4sbcu1,72,102,1|-4sbcu0,24,101,0|-4iy8q1,24,101,0|-4iy8q0,72,102,1|-49la61,72,102,1|-49la60,24,101,0|-408621,24,101,0|-408620,72,102,1|-3qv7i1,72,102,1|-3qv7i0,24,101,0|-3hi3e1,24,101,0|-3hi3e0,72,102,1|-3854u1,72,102,1|-3854u0,24,101,0|-2ys0q1,24,101,0|-2ys0q0,72,102,1|-2pf261,72,102,1|-2pf260,24,101,0|-2g1y21,24,101,0|-2g1y20,72,102,1|-26c0u1,72,102,1|-26c0u0,24,101,0|-1zdy21,24,101,0|-1zdy20,32,42,0|-1xbu01,32,42,0|-1xbu00,54,44,1|-1nlws1,54,44,1|-1nlws0,32,42,0|-1e8so1,32,42,0|-1e8so0,54,44,1|-14vu41,54,44,1|-14vu40,32,42,0|-viq01,32,42,0|-viq00,54,44,1|-m5rg1,54,44,1|-m5rg0,32,42,0|-csnc1,32,42,0|-csnc0,54,44,1|-3fos1,54,44,1|-3fos0,32,42,0|5xfbz,32,42,0|5xfc0,54,44,1|fadvz,54,44,1|fadw0,32,42,0|onhzz,32,42,0|oni00,54,44,1|ydf7z,54,44,1|ydf80,32,42,0|17qjbz,32,42,0|17qjc0,54,44,1|1h3hvz,54,44,1|1h3hw0,32,42,0|1qglzz,32,42,0|1qgm00,54,44,1|1ztkjz,54,44,1|1ztkk0,32,42,0|296onz,32,42,0|296oo0,54,44,1|2ijn7z,54,44,1|2ijn80,32,42,0|2rwrbz,32,42,0|2rwrc0,54,44,1|319pvz,54,44,1|319pw0,32,42,0|3amtzz,32,42,0|3amu00,54,44,1|3kcr7z,54,44,1|3kcr80,32,42,0|3tcwnz,32,42,0|3tcwo0,54,44,1|432tvz,54,44,1|432tw0,32,42,0|4cfxzz,32,42,0|4cfy00,54,44,1|4lswjz,54,44,1|4lswk0,32,42,0|4v60nz,32,42,0|4v60o0,54,44,1|54iz7z,54,44,1|54iz80,32,42,0|5dw3bz,32,42,0|5dw3c0,54,44,1|5n91vz,54,44,1|5n91w0,32,42,0|5wm5zz,32,42,0|5wm600,54,44,1|65z4jz,54,44,1|65z4k0,32,42,0|6fc8nz,32,42,0|6fc8o0,54,44,1|6p25vz,54,44,1|6p25w0,32,42,0|6y2bbz,32,42,0|6y2bc0,54,44,1|77s8jz,54,44,1|77s8k0,32,42,0|7h5cnz,32,42,0|7h5co0,54,44,1|7qib7z,54,44,1|7qib80,32,42,0|7zvfbz,32,42,0|7zvfc0,54,44,1|898dvz,54,44,1|898dw0,32,42,0|8ilhzz,32,42,0|8ili00,54,44,1|8rygjz,54,44,1|8rygk0,32,42,0|908j5n,32,42,0|908j5o,54,44,1|9aodpn,54,44,1|9aodpo,32,42,0|9iyltn,32,42,0|9iylto,73,45,1|9trc9n,73,45,1|9trc9o,32,42,0|a1oohn,32,42,0|a1ooho,54,44,1|achhpn,54,44,1|achhpo,32,42,0|aker5n,32,42,0|aker5o,54,44,1|av7kdn,54,44,1|av7kdo,32,42,0|b3hshn,32,42,0|b3hsho,54,44,1|bdxn1n,54,44,1|bdxn1o,32,42,0|bm7v5n,32,42,0|bm7v5o,54,44,1|bwnppn,54,44,1|bwnppo,32,42,0|c4xxtn,32,42,0|c4xxto,54,44,1|cfqr1n,54,44,1|cfqr1o,32,42,0|cno0hn,32,42,0|cno0ho,54,44,1|cygtpn,54,44,1|cygtpo,32,42,0|d6e35n,32,42,0|d6e35o,54,44,1|dh6wdn,54,44,1|dh6wdo,32,42,0|dph4hn,32,42,0|dph4ho,54,44,1|dzwz1n,54,44,1|dzwz1o,32,42,0|e8775n,32,42,0|e8775o,54,44,1|ein1pn,54,44,1|ein1po,32,42,0|eqx9tn,32,42,0|eqx9to,54,44,1|f1d4dn,54,44,1|f1d4do,32,42,0|f9nchn,32,42,0|f9ncho,54,44,1|fkg5pn,54,44,1|fkg5po,32,42,0|fsdf5n,32,42,0|fsdf5o,54,44,1|g368dn,54,44,1|g368do,32,42,0|gb3htn,32,42,0|gb3hto,54,44,1|glwb1n,54,44,1|glwb1o,32,42,0|gu6j5n,32,42,0|gu6j5o,54,44,1|h4mdpn,54,44,1|h4mdpo,32,42,0|hcwltn,32,42,0|hcwlto,54,44,1|hncgdn,54,44,1|hncgdo,32,42,0|hvmohn,32,42,0|hvmoho,54,44,1|i6fhpn,54,44,1|i6fhpo,32,42,0|iecr5n,32,42,0|iecr5o,54,44,1|ip5kdn,54,44,1|ip5kdo,32,42,0|ix2ttn,32,42,0|ix2tto,54,44,1|j7vn1n,54,44,1|j7vn1o,32,42,0|jeq0hn,32,42,0|jeq0ho,54,44,1|jqyodn,54,44,1|jqyodo,32,42,0|jxg35n,32,42,0|jxg35o,54,44,1|k9or1n,54,44,1|k9or1o,32,42,0|kg65tn,32,42,0|kg65to,54,44,1|ksetpn,54,44,1|ksetpo,32,42,0|kz975n,32,42,0|kz975o,54,44,1|lbhv1n,54,44,1|lbhv1o,32,42,0|lhz9tn,32,42,0|lhz9to,54,44,1|lu837z,54,44,1|lu8380,32,42,0|m0phzz,32,42,0|m0pi00,54,44,1|mcy5vz,54,44,1|mcy5w0,32,42,0|mjfknz,32,42,0|mjfko0,54,44,1|mvo8jz,54,44,1|mvo8k0,32,42,0|n25nbz,32,42,0|n25nc0,54,44,1|neeb7z,54,44,1|neeb80,32,42,0|nkvpzz,32,42,0|nkvq00,54,44,1|nx4dvz,54,44,1|nx4dw0,32,42,0|o3yrbz,32,42,0|o3yrc0,54,44,1|og7f7z,54,44,1|og7f80,32,42,0|omotzz,32,42,0|omou00,54,44,1|oyxhvz,54,44,1|oyxhw0,32,42,0|p5ewnz,32,42,0|p5ewo0,54,44,1|phnkjz,54,44,1|phnkk0,32,42,0|po4zbz,32,42,0|po4zc0,54,44,1|q0dn7z,54,44,1|q0dn80,32,42,0|q6v1zz,32,42,0|q6v200,54,44,1|qj3pvz,54,44,1|qj3pw0,32,42,0|qpy3bz,32,42,0|qpy3c0,54,44,1|r26r7z,54,44,1|r26r80,32,42,0|r8o5zz,32,42,0|r8o600,54,44,1|rkwtvz,54,44,1|rkwtw0,32,42,0|rre8nz,32,42,0|rre8o0,54,44,1|s3mwjz,54,44,1|s3mwk0,32,42,0|sa4bbz,32,42,0|sa4bc0,54,44,1|smcz7z,54,44,1|smcz80,32,42,0|ssudzz,32,42,0|ssue00,54,44,1|t531vz,54,44,1|t531w0,32,42,0|tbkgnz,32,42,0|tbkgo0,54,44,1|tnt4jz,54,44,1|tnt4k0,32,42,0|tunhzz,32,42,0|tuni00,54,44,1|u6w5vz,54,44,1|u6w5w0,32,42,0|uddknz,32,42,0|uddko0,54,44,1|upm8jz,54,44,1|upm8k0,32,42,0|uw3nbz,32,42,0|uw3nc0,54,44,1|v8cb7z,54,44,1|v8cb80,32,42,0|vetpzz,32,42,0|vetq00,54,44,1|vr2dvz,54,44,1|vr2dw0,32,42,0|vxjsnz,32,42,0|vxjso0,54,44,1|w9sgjz,54,44,1|w9sgk0,32,42,0|wgmtzz,32,42,0|wgmu00,54,44,1|wsvhvz,54,44,1|wsvhw0,32,42,0|wzcwnz,32,42,0|wzcwo0,54,44,1|xblkjz,54,44,1|xblkk0,32,42,0|xi2zbz,32,42,0|xi2zc0,54,44,1|xubn7z,54,44,1|xubn80,32,42,0|y0t1zz,32,42,0|y0t200,54,44,1|yd1pvz,54,44,1|yd1pw0,32,42,0|yjj4nz,32,42,0|yjj4o0,54,44,1|yvrsjz,54,44,1|yvrsk0,32,42,0|z297bz,32,42,0|z297c0,54,44,1|zehv7z,54,44,1|zehv80,32,42,0\",\"America/Grand_Turk|,0,103,0|-15r0w5s,74,104,0|-u85og3,74,104,0|-u85og2,49,63,0|4v63fz,49,63,0|4v63g0,62,42,1|54j1zz,62,42,1|54j200,49,63,0|5dw63z,49,63,0|5dw640,62,42,1|5n94nz,62,42,1|5n94o0,49,63,0|5wm8rz,49,63,0|5wm8s0,62,42,1|65z7bz,62,42,1|65z7c0,49,63,0|6fcbfz,49,63,0|6fcbg0,62,42,1|6p28nz,62,42,1|6p28o0,49,63,0|6y2e3z,49,63,0|6y2e40,62,42,1|77sbbz,62,42,1|77sbc0,49,63,0|7h5ffz,49,63,0|7h5fg0,62,42,1|7qidzz,62,42,1|7qie00,49,63,0|7zvi3z,49,63,0|7zvi40,62,42,1|898gnz,62,42,1|898go0,49,63,0|8ilkrz,49,63,0|8ilks0,62,42,1|8ryjbz,62,42,1|8ryjc0,49,63,0|908rfz,49,63,0|908rg0,62,42,1|9aolzz,62,42,1|9aom00,49,63,0|9iyu3z,49,63,0|9iyu40,62,42,1|9trnbz,62,42,1|9trnc0,49,63,0|a1owrz,49,63,0|a1ows0,62,42,1|achpzz,62,42,1|achq00,49,63,0|akezfz,49,63,0|akezg0,62,42,1|av7snz,62,42,1|av7so0,49,63,0|b3i0rz,49,63,0|b3i0s0,62,42,1|bdxvbz,62,42,1|bdxvc0,49,63,0|bm83fz,49,63,0|bm83g0,62,42,1|bwnxzz,62,42,1|bwny00,49,63,0|c4y63z,49,63,0|c4y640,62,42,1|cfqzbz,62,42,1|cfqzc0,49,63,0|cno8rz,49,63,0|cno8s0,62,42,1|cyh1zz,62,42,1|cyh200,49,63,0|d6ebfz,49,63,0|d6ebg0,62,42,1|dh74nz,62,42,1|dh74o0,49,63,0|dphcrz,49,63,0|dphcs0,62,42,1|dzx7bz,62,42,1|dzx7c0,49,63,0|e87ffz,49,63,0|e87fg0,62,42,1|ein9zz,62,42,1|eina00,49,63,0|eqxi3z,49,63,0|eqxi40,62,42,1|f1dcnz,62,42,1|f1dco0,49,63,0|f9nkrz,49,63,0|f9nks0,62,42,1|fkgdzz,62,42,1|fkge00,49,63,0|fsdnfz,49,63,0|fsdng0,62,42,1|g36gnz,62,42,1|g36go0,49,63,0|gb3q3z,49,63,0|gb3q40,62,42,1|glwjbz,62,42,1|glwjc0,49,63,0|gu6rfz,49,63,0|gu6rg0,62,42,1|h4mlzz,62,42,1|h4mm00,49,63,0|hcwu3z,49,63,0|hcwu40,62,42,1|hnconz,62,42,1|hncoo0,49,63,0|hvmwrz,49,63,0|hvmws0,62,42,1|i6fpzz,62,42,1|i6fq00,49,63,0|ieczfz,49,63,0|ieczg0,62,42,1|ip5snz,62,42,1|ip5so0,49,63,0|ix323z,49,63,0|ix3240,62,42,1|j7vvbz,62,42,1|j7vvc0,49,63,0|jeq8rz,49,63,0|jeq8s0,62,42,1|jqywnz,62,42,1|jqywo0,49,63,0|jxgbfz,49,63,0|jxgbg0,62,42,1|k9ozbz,62,42,1|k9ozc0,49,63,0|kg6e3z,49,63,0|kg6e40,62,42,1|ksf1zz,62,42,1|ksf200,49,63,0|kz9ffz,49,63,0|kz9fg0,62,42,1|lbi3bz,62,42,1|lbi3c0,49,63,0|lhzi3z,49,63,0|lhzi40,62,42,1|lu85zz,62,42,1|lu8600,49,63,0|m0pkrz,49,63,0|m0pks0,62,42,1|mcy8nz,62,42,1|mcy8o0,49,63,0|mjfnfz,49,63,0|mjfng0,62,42,1|mvobbz,62,42,1|mvobc0,49,63,0|n25q3z,49,63,0|n25q40,62,42,1|needzz,62,42,1|neee00,49,63,0|nkvsrz,49,63,0|nkvss0,32,42,0|p5ezfz,32,42,0|p5ezg0,62,42,1|phnnbz,62,42,1|phnnc0,49,63,0|po523z,49,63,0|po5240,62,42,1|q0dpzz,62,42,1|q0dq00,49,63,0|q6v4rz,49,63,0|q6v4s0,62,42,1|qj3snz,62,42,1|qj3so0,49,63,0|qpy63z,49,63,0|qpy640,62,42,1|r26tzz,62,42,1|r26u00,49,63,0|r8o8rz,49,63,0|r8o8s0,62,42,1|rkwwnz,62,42,1|rkwwo0,49,63,0|rrebfz,49,63,0|rrebg0,62,42,1|s3mzbz,62,42,1|s3mzc0,49,63,0|sa4e3z,49,63,0|sa4e40,62,42,1|smd1zz,62,42,1|smd200,49,63,0|ssugrz,49,63,0|ssugs0,62,42,1|t534nz,62,42,1|t534o0,49,63,0|tbkjfz,49,63,0|tbkjg0,62,42,1|tnt7bz,62,42,1|tnt7c0,49,63,0|tunkrz,49,63,0|tunks0,62,42,1|u6w8nz,62,42,1|u6w8o0,49,63,0|uddnfz,49,63,0|uddng0,62,42,1|upmbbz,62,42,1|upmbc0,49,63,0|uw3q3z,49,63,0|uw3q40,62,42,1|v8cdzz,62,42,1|v8ce00,49,63,0|vetsrz,49,63,0|vetss0,62,42,1|vr2gnz,62,42,1|vr2go0,49,63,0|vxjvfz,49,63,0|vxjvg0,62,42,1|w9sjbz,62,42,1|w9sjc0,49,63,0|wgmwrz,49,63,0|wgmws0,62,42,1|wsvknz,62,42,1|wsvko0,49,63,0|wzczfz,49,63,0|wzczg0,62,42,1|xblnbz,62,42,1|xblnc0,49,63,0|xi323z,49,63,0|xi3240,62,42,1|xubpzz,62,42,1|xubq00,49,63,0|y0t4rz,49,63,0|y0t4s0,62,42,1|yd1snz,62,42,1|yd1so0,49,63,0|yjj7fz,49,63,0|yjj7g0,62,42,1|yvrvbz,62,42,1|yvrvc0,49,63,0|z29a3z,49,63,0|z29a40,62,42,1|zehxzz,62,42,1|zehy00,49,63,0\",\"America/Grenada|,0,41,0|-u6m79w,32,42,0\",\"America/Guadeloupe|,0,41,0|-u6m79w,32,42,0\",\"America/Guatemala|,0,105,0|-qqqskk,45,62,0|219hzz,45,62,0|219i00,46,63,1|25xxvz,46,63,1|25xxw0,45,62,0|6zgbbz,45,62,0|6zgbc0,46,63,1|75tv7z,46,63,1|75tv80,45,62,0|b2q5zz,45,62,0|b2q600,46,63,1|bbd77z,46,63,1|bbd780,45,62,0|iyitzz,45,62,0|iyiu00,46,63,1|j6fxvz,46,63,1|j6fxw0,45,62,0\",\"America/Guayaquil|,0,106,0|-15r0ujs,75,107,0|-kcr84p,75,107,0|-kcr84o,56,63,0|byetvz,56,63,0|byetw0,42,42,1|c1yj3z,42,42,1|c1yj40,56,63,0\",\"America/Guyana|,0,108,0|-smcak8,76,109,0|2wsiez,76,109,0|2wsif0,39,44,0|ayjxnz,39,44,0|ayjxo0,42,42,0\",\"America/Halifax|,0,110,0|-z94k80,32,42,0|-s1x3k1,32,42,0|-s1x3k0,54,44,1|-rsiac1,54,44,1|-rsiac0,32,42,0|-qzp0o1,32,42,0|-qzp0o0,54,44,1|-qpm4s1,54,44,1|-qpm4s0,32,42,0|-pwt681,32,42,0|-pwt680,54,44,1|-pr1uc1,54,44,1|-pr1uc0,32,42,0|-pe6sw1,32,42,0|-pe6sw0,54,44,1|-p7wyc1,54,44,1|-p7wyc0,32,42,0|-ovpzk1,32,42,0|-ovpzk0,54,44,1|-op5101,54,44,1|-op5100,32,42,0|-ocmy81,32,42,0|-ocmy80,54,44,1|-o6eyc1,54,44,1|-o6eyc0,32,42,0|-ntwvk1,32,42,0|-ntwvk0,54,44,1|-nn0t01,54,44,1|-nn0t00,32,42,0|-nb6sw1,32,42,0|-nb6sw0,54,44,1|-n3kt01,54,44,1|-n3kt00,32,42,0|-mrqsw1,32,42,0|-mrqsw0,54,44,1|-mlkno1,54,44,1|-mlkno0,32,42,0|-m9qnk1,32,42,0|-m9qnk0,54,44,1|-m24no1,54,44,1|-m24no0,32,42,0|-lqank1,32,42,0|-lqank0,54,44,1|-lk6d01,54,44,1|-lk6d00,32,42,0|-l7kkw1,32,42,0|-l7kkw0,54,44,1|-l1pjo1,54,44,1|-l1pjo0,32,42,0|-koui81,32,42,0|-koui80,54,44,1|-kibec1,54,44,1|-kibec0,32,42,0|-k64fk1,32,42,0|-k64fk0,54,44,1|-jyvec1,54,44,1|-jyvec0,32,42,0|-jnrbk1,32,42,0|-jnrbk0,54,44,1|-jg5bo1,54,44,1|-jg5bo0,32,42,0|-j518w1,32,42,0|-j518w0,54,44,1|-ix2ac1,54,44,1|-ix2ac0,32,42,0|-il8a81,32,42,0|-il8a80,54,44,1|-if3zo1,54,44,1|-if3zo0,32,42,0|-i1sa81,32,42,0|-i1sa80,54,44,1|-hvm501,54,44,1|-hvm500,32,42,0|-hj0cw1,32,42,0|-hj0cw0,54,44,1|-hdlzo1,54,44,1|-hdlzo0,32,42,0|-h1rzk1,32,42,0|-h1rzk0,54,44,1|-gu5zo1,54,44,1|-gu5zo0,32,42,0|-gj1ww1,32,42,0|-gj1ww0,54,44,1|-gbfx01,54,44,1|-gbfx00,32,42,0|-fyvzk1,32,42,0|-fyvzk0,54,44,1|-fspuc1,54,44,1|-fspuc0,32,42,0|-fh8sw1,32,42,0|-fh8sw0,54,44,1|-f9mt01,54,44,1|-f9mt00,32,42,0|-eyiq81,32,42,0|-eyiq80,54,44,1|-eqwqc1,54,44,1|-eqwqc0,32,42,0|-ek27c1,32,42,0|-ek27c0,33,44,1|-cq2tg1,33,44,1|-cq2tg0,34,44,1|-cnp641,34,44,1|-cnp640,32,42,0|-ccw7c1,32,42,0|-ccw7c0,54,44,1|-c4z3g1,54,44,1|-c4z3g0,32,42,0|-bu64o1,32,42,0|-bu64o0,54,44,1|-bm90s1,54,44,1|-bm90s0,32,42,0|-bbg201,32,42,0|-bbg200,54,44,1|-b3iy41,54,44,1|-b3iy40,32,42,0|-aspzc1,32,42,0|-aspzc0,54,44,1|-aksvg1,54,44,1|-aksvg0,32,42,0|-9qwvc1,32,42,0|-9qwvc0,54,44,1|-9izrg1,54,44,1|-9izrg0,32,42,0|-986so1,32,42,0|-986so0,54,44,1|-909os1,54,44,1|-909os0,32,42,0|-8pgq01,32,42,0|-8pgq00,54,44,1|-8hjm41,54,44,1|-8hjm40,32,42,0|-86qnc1,32,42,0|-86qnc0,54,44,1|-7ytjg1,54,44,1|-7ytjg0,32,42,0|-74xjc1,32,42,0|-74xjc0,54,44,1|-6x0fg1,54,44,1|-6x0fg0,32,42,0|-6m7go1,32,42,0|-6m7go0,54,44,1|-6eacs1,54,44,1|-6eacs0,32,42,0|-63he01,32,42,0|-63he00,54,44,1|-5vka41,54,44,1|-5vka40,32,42,0|-5krbc1,32,42,0|-5krbc0,54,44,1|-5cu7g1,54,44,1|-5cu7g0,32,42,0|-4084o1,32,42,0|-4084o0,54,44,1|-3qv641,54,44,1|-3qv640,32,42,0|-3hi201,32,42,0|-3hi200,54,44,1|-3853g1,54,44,1|-3853g0,32,42,0|-2yrzc1,32,42,0|-2yrzc0,54,44,1|-2pf0s1,54,44,1|-2pf0s0,32,42,0|-2g1wo1,32,42,0|-2g1wo0,54,44,1|-26bzg1,54,44,1|-26bzg0,32,42,0|-1xbu01,32,42,0|-1xbu00,54,44,1|-1nlws1,54,44,1|-1nlws0,32,42,0|-1e8so1,32,42,0|-1e8so0,54,44,1|-14vu41,54,44,1|-14vu40,32,42,0|-viq01,32,42,0|-viq00,54,44,1|-m5rg1,54,44,1|-m5rg0,32,42,0|-csnc1,32,42,0|-csnc0,54,44,1|-3fos1,54,44,1|-3fos0,32,42,0|5xfbz,32,42,0|5xfc0,54,44,1|fadvz,54,44,1|fadw0,32,42,0|onhzz,32,42,0|oni00,54,44,1|ydf7z,54,44,1|ydf80,32,42,0|17qjbz,32,42,0|17qjc0,54,44,1|1h3hvz,54,44,1|1h3hw0,32,42,0|1qglzz,32,42,0|1qgm00,54,44,1|1ztkjz,54,44,1|1ztkk0,32,42,0|296onz,32,42,0|296oo0,54,44,1|2ijn7z,54,44,1|2ijn80,32,42,0|2rwrbz,32,42,0|2rwrc0,54,44,1|319pvz,54,44,1|319pw0,32,42,0|3amtzz,32,42,0|3amu00,54,44,1|3kcr7z,54,44,1|3kcr80,32,42,0|3tcwnz,32,42,0|3tcwo0,54,44,1|432tvz,54,44,1|432tw0,32,42,0|4cfxzz,32,42,0|4cfy00,54,44,1|4lswjz,54,44,1|4lswk0,32,42,0|4v60nz,32,42,0|4v60o0,54,44,1|54iz7z,54,44,1|54iz80,32,42,0|5dw3bz,32,42,0|5dw3c0,54,44,1|5n91vz,54,44,1|5n91w0,32,42,0|5wm5zz,32,42,0|5wm600,54,44,1|65z4jz,54,44,1|65z4k0,32,42,0|6fc8nz,32,42,0|6fc8o0,54,44,1|6p25vz,54,44,1|6p25w0,32,42,0|6y2bbz,32,42,0|6y2bc0,54,44,1|77s8jz,54,44,1|77s8k0,32,42,0|7h5cnz,32,42,0|7h5co0,54,44,1|7qib7z,54,44,1|7qib80,32,42,0|7zvfbz,32,42,0|7zvfc0,54,44,1|898dvz,54,44,1|898dw0,32,42,0|8ilhzz,32,42,0|8ili00,54,44,1|8rygjz,54,44,1|8rygk0,32,42,0|908onz,32,42,0|908oo0,54,44,1|9aoj7z,54,44,1|9aoj80,32,42,0|9iyrbz,32,42,0|9iyrc0,54,44,1|9trkjz,54,44,1|9trkk0,32,42,0|a1otzz,32,42,0|a1ou00,54,44,1|achn7z,54,44,1|achn80,32,42,0|akewnz,32,42,0|akewo0,54,44,1|av7pvz,54,44,1|av7pw0,32,42,0|b3hxzz,32,42,0|b3hy00,54,44,1|bdxsjz,54,44,1|bdxsk0,32,42,0|bm80nz,32,42,0|bm80o0,54,44,1|bwnv7z,54,44,1|bwnv80,32,42,0|c4y3bz,32,42,0|c4y3c0,54,44,1|cfqwjz,54,44,1|cfqwk0,32,42,0|cno5zz,32,42,0|cno600,54,44,1|cygz7z,54,44,1|cygz80,32,42,0|d6e8nz,32,42,0|d6e8o0,54,44,1|dh71vz,54,44,1|dh71w0,32,42,0|dph9zz,32,42,0|dpha00,54,44,1|dzx4jz,54,44,1|dzx4k0,32,42,0|e87cnz,32,42,0|e87co0,54,44,1|ein77z,54,44,1|ein780,32,42,0|eqxfbz,32,42,0|eqxfc0,54,44,1|f1d9vz,54,44,1|f1d9w0,32,42,0|f9nhzz,32,42,0|f9ni00,54,44,1|fkgb7z,54,44,1|fkgb80,32,42,0|fsdknz,32,42,0|fsdko0,54,44,1|g36dvz,54,44,1|g36dw0,32,42,0|gb3nbz,32,42,0|gb3nc0,54,44,1|glwgjz,54,44,1|glwgk0,32,42,0|gu6onz,32,42,0|gu6oo0,54,44,1|h4mj7z,54,44,1|h4mj80,32,42,0|hcwrbz,32,42,0|hcwrc0,54,44,1|hnclvz,54,44,1|hnclw0,32,42,0|hvmtzz,32,42,0|hvmu00,54,44,1|i6fn7z,54,44,1|i6fn80,32,42,0|iecwnz,32,42,0|iecwo0,54,44,1|ip5pvz,54,44,1|ip5pw0,32,42,0|ix2zbz,32,42,0|ix2zc0,54,44,1|j7vsjz,54,44,1|j7vsk0,32,42,0|jeq5zz,32,42,0|jeq600,54,44,1|jqytvz,54,44,1|jqytw0,32,42,0|jxg8nz,32,42,0|jxg8o0,54,44,1|k9owjz,54,44,1|k9owk0,32,42,0|kg6bbz,32,42,0|kg6bc0,54,44,1|ksez7z,54,44,1|ksez80,32,42,0|kz9cnz,32,42,0|kz9co0,54,44,1|lbi0jz,54,44,1|lbi0k0,32,42,0|lhzfbz,32,42,0|lhzfc0,54,44,1|lu837z,54,44,1|lu8380,32,42,0|m0phzz,32,42,0|m0pi00,54,44,1|mcy5vz,54,44,1|mcy5w0,32,42,0|mjfknz,32,42,0|mjfko0,54,44,1|mvo8jz,54,44,1|mvo8k0,32,42,0|n25nbz,32,42,0|n25nc0,54,44,1|neeb7z,54,44,1|neeb80,32,42,0|nkvpzz,32,42,0|nkvq00,54,44,1|nx4dvz,54,44,1|nx4dw0,32,42,0|o3yrbz,32,42,0|o3yrc0,54,44,1|og7f7z,54,44,1|og7f80,32,42,0|omotzz,32,42,0|omou00,54,44,1|oyxhvz,54,44,1|oyxhw0,32,42,0|p5ewnz,32,42,0|p5ewo0,54,44,1|phnkjz,54,44,1|phnkk0,32,42,0|po4zbz,32,42,0|po4zc0,54,44,1|q0dn7z,54,44,1|q0dn80,32,42,0|q6v1zz,32,42,0|q6v200,54,44,1|qj3pvz,54,44,1|qj3pw0,32,42,0|qpy3bz,32,42,0|qpy3c0,54,44,1|r26r7z,54,44,1|r26r80,32,42,0|r8o5zz,32,42,0|r8o600,54,44,1|rkwtvz,54,44,1|rkwtw0,32,42,0|rre8nz,32,42,0|rre8o0,54,44,1|s3mwjz,54,44,1|s3mwk0,32,42,0|sa4bbz,32,42,0|sa4bc0,54,44,1|smcz7z,54,44,1|smcz80,32,42,0|ssudzz,32,42,0|ssue00,54,44,1|t531vz,54,44,1|t531w0,32,42,0|tbkgnz,32,42,0|tbkgo0,54,44,1|tnt4jz,54,44,1|tnt4k0,32,42,0|tunhzz,32,42,0|tuni00,54,44,1|u6w5vz,54,44,1|u6w5w0,32,42,0|uddknz,32,42,0|uddko0,54,44,1|upm8jz,54,44,1|upm8k0,32,42,0|uw3nbz,32,42,0|uw3nc0,54,44,1|v8cb7z,54,44,1|v8cb80,32,42,0|vetpzz,32,42,0|vetq00,54,44,1|vr2dvz,54,44,1|vr2dw0,32,42,0|vxjsnz,32,42,0|vxjso0,54,44,1|w9sgjz,54,44,1|w9sgk0,32,42,0|wgmtzz,32,42,0|wgmu00,54,44,1|wsvhvz,54,44,1|wsvhw0,32,42,0|wzcwnz,32,42,0|wzcwo0,54,44,1|xblkjz,54,44,1|xblkk0,32,42,0|xi2zbz,32,42,0|xi2zc0,54,44,1|xubn7z,54,44,1|xubn80,32,42,0|y0t1zz,32,42,0|y0t200,54,44,1|yd1pvz,54,44,1|yd1pw0,32,42,0|yjj4nz,32,42,0|yjj4o0,54,44,1|yvrsjz,54,44,1|yvrsk0,32,42,0|z297bz,32,42,0|z297c0,54,44,1|zehv7z,54,44,1|zehv80,32,42,0\",\"America/Havana|,0,111,0|-15r0u2w,77,112,0|-n7762p,77,112,0|-n7762o,45,63,0|-louq41,45,63,0|-louq40,46,42,1|-likvk1,46,42,1|-likvk0,45,63,0|-ffsvg1,45,63,0|-ffsvg0,46,42,1|-fb4fk1,46,42,1|-fb4fk0,45,63,0|-ex2ss1,45,63,0|-ex2ss0,46,42,1|-es1e81,46,42,1|-es1e80,45,63,0|-edzrg1,45,63,0|-edzrg0,46,42,1|-e9bbk1,46,42,1|-e9bbk0,45,63,0|-cttjg1,45,63,0|-cttjg0,46,42,1|-cp53k1,46,42,1|-cp53k0,45,63,0|-cb3gs1,45,63,0|-cb3gs0,46,42,1|-c6f0w1,46,42,1|-c6f0w0,45,63,0|-2e5gs1,45,63,0|-2e5gs0,46,42,1|-27xgw1,46,42,1|-27xgw0,45,63,0|-1vj3g1,45,63,0|-1vj3g0,46,42,1|-1p1u81,46,42,1|-1p1u80,45,63,0|-1fdm41,45,63,0|-1fdm40,46,42,1|-17enk1,46,42,1|-17enk0,45,63,0|-w8q41,45,63,0|-w8q40,46,42,1|-ookw1,46,42,1|-ookw0,45,63,0|-csq41,45,63,0|-csq40,46,42,1|-3frk1,46,42,1|-3frk0,45,63,0|5xcjz,45,63,0|5xck0,46,42,1|fab3z,46,42,1|fab40,45,63,0|onf7z,45,63,0|onf80,46,42,1|ydcfz,46,42,1|ydcg0,45,63,0|17qgjz,45,63,0|17qgk0,46,42,1|1g0j3z,46,42,1|1g0j40,45,63,0|1qgj7z,45,63,0|1qgj80,46,42,1|1ysgfz,46,42,1|1ysgg0,45,63,0|296lvz,45,63,0|296lw0,46,42,1|2hkdrz,46,42,1|2hkds0,45,63,0|2rwojz,45,63,0|2rwok0,46,42,1|319n3z,46,42,1|319n40,45,63,0|3amr7z,45,63,0|3amr80,46,42,1|3kcofz,46,42,1|3kcog0,45,63,0|3tctvz,45,63,0|3tctw0,46,42,1|432r3z,46,42,1|432r40,45,63,0|4cstvz,45,63,0|4cstw0,46,42,1|4kpxrz,46,42,1|4kpxs0,45,63,0|4t05vz,45,63,0|4t05w0,46,42,1|53sz3z,46,42,1|53sz40,45,63,0|5bq8jz,45,63,0|5bq8k0,46,42,1|5mj1rz,46,42,1|5mj1s0,45,63,0|5xc0jz,45,63,0|5xc0k0,46,42,1|6594fz,46,42,1|6594g0,45,63,0|6g237z,45,63,0|6g2380,46,42,1|6nz73z,46,42,1|6nz740,45,63,0|6ys5vz,45,63,0|6ys5w0,46,42,1|76p9rz,46,42,1|76p9s0,45,63,0|7hi8jz,45,63,0|7hi8k0,46,42,1|7psb3z,46,42,1|7psb40,45,63,0|808b7z,45,63,0|808b80,46,42,1|88idrz,46,42,1|88ids0,45,63,0|8gfn7z,45,63,0|8gfn80,46,42,1|8r8gfz,46,42,1|8r8gg0,45,63,0|8z5pvz,45,63,0|8z5pw0,46,42,1|99yj3z,46,42,1|99yj40,45,63,0|9i8r7z,45,63,0|9i8r80,46,42,1|9solrz,46,42,1|9sols0,45,63,0|a0ytvz,45,63,0|a0ytw0,46,42,1|abeofz,46,42,1|abeog0,45,63,0|aketvz,45,63,0|aketw0,46,42,1|auhprz,46,42,1|auhps0,45,63,0|b3hv7z,45,63,0|b3hv80,46,42,1|bd7v7z,46,42,1|bd7v80,45,63,0|bm7xvz,45,63,0|bm7xw0,46,42,1|bvxxvz,46,42,1|bvxxw0,45,63,0|c4y0jz,45,63,0|c4y0k0,46,42,1|ceo0jz,46,42,1|ceo0k0,45,63,0|cno37z,45,63,0|cno380,46,42,1|cxe37z,46,42,1|cxe380,45,63,0|d6e5vz,45,63,0|d6e5w0,46,42,1|dg45vz,46,42,1|dg45w0,45,63,0|dph77z,45,63,0|dph780,46,42,1|dyu8jz,46,42,1|dyu8k0,45,63,0|e879vz,45,63,0|e879w0,46,42,1|ehx9vz,46,42,1|ehx9w0,45,63,0|eqkdvz,45,63,0|eqkdw0,46,42,1|f1d9vz,46,42,1|f1d9w0,45,63,0|f9agjz,45,63,0|f9agk0,46,42,1|fkgb7z,46,42,1|fkgb80,45,63,0|fsdhvz,45,63,0|fsdhw0,46,42,1|g36dvz,46,42,1|g36dw0,45,63,0|gb3kjz,45,63,0|gb3kk0,46,42,1|glwgjz,46,42,1|glwgk0,45,63,0|gu6lvz,45,63,0|gu6lw0,46,42,1|h4mj7z,46,42,1|h4mj80,45,63,0|hcwojz,45,63,0|hcwok0,46,42,1|hnclvz,46,42,1|hnclw0,45,63,0|hv9sjz,45,63,0|hv9sk0,46,42,1|j7vsjz,46,42,1|j7vsk0,45,63,0|jeq37z,45,63,0|jeq380,46,42,1|jqlv7z,46,42,1|jqlv80,45,63,0|jxt4jz,45,63,0|jxt4k0,46,42,1|k9bxvz,46,42,1|k9bxw0,45,63,0|kg68jz,45,63,0|kg68k0,46,42,1|ks20jz,46,42,1|ks20k0,45,63,0|kz99vz,45,63,0|kz99w0,46,42,1|lb51vz,46,42,1|lb51w0,45,63,0|licb7z,45,63,0|licb80,46,42,1|lul1vz,46,42,1|lul1w0,45,63,0|m1sb7z,45,63,0|m1sb80,46,42,1|mcy5vz,46,42,1|mcy5w0,45,63,0|mjfhvz,45,63,0|mjfhw0,46,42,1|mvo8jz,46,42,1|mvo8k0,45,63,0|n25kjz,45,63,0|n25kk0,46,42,1|neeb7z,46,42,1|neeb80,45,63,0|nkvn7z,45,63,0|nkvn80,46,42,1|nx4dvz,46,42,1|nx4dw0,45,63,0|o3yojz,45,63,0|o3yok0,46,42,1|og7f7z,46,42,1|og7f80,45,63,0|omor7z,45,63,0|omor80,46,42,1|oyxhvz,46,42,1|oyxhw0,45,63,0|p5etvz,45,63,0|p5etw0,46,42,1|phnkjz,46,42,1|phnkk0,45,63,0|po4wjz,45,63,0|po4wk0,46,42,1|q0dn7z,46,42,1|q0dn80,45,63,0|q6uz7z,45,63,0|q6uz80,46,42,1|qj3pvz,46,42,1|qj3pw0,45,63,0|qpy0jz,45,63,0|qpy0k0,46,42,1|r26r7z,46,42,1|r26r80,45,63,0|r8o37z,45,63,0|r8o380,46,42,1|rkwtvz,46,42,1|rkwtw0,45,63,0|rre5vz,45,63,0|rre5w0,46,42,1|s3mwjz,46,42,1|s3mwk0,45,63,0|sa48jz,45,63,0|sa48k0,46,42,1|smcz7z,46,42,1|smcz80,45,63,0|ssub7z,45,63,0|ssub80,46,42,1|t531vz,46,42,1|t531w0,45,63,0|tbkdvz,45,63,0|tbkdw0,46,42,1|tnt4jz,46,42,1|tnt4k0,45,63,0|tunf7z,45,63,0|tunf80,46,42,1|u6w5vz,46,42,1|u6w5w0,45,63,0|uddhvz,45,63,0|uddhw0,46,42,1|upm8jz,46,42,1|upm8k0,45,63,0|uw3kjz,45,63,0|uw3kk0,46,42,1|v8cb7z,46,42,1|v8cb80,45,63,0|vetn7z,45,63,0|vetn80,46,42,1|vr2dvz,46,42,1|vr2dw0,45,63,0|vxjpvz,45,63,0|vxjpw0,46,42,1|w9sgjz,46,42,1|w9sgk0,45,63,0|wgmr7z,45,63,0|wgmr80,46,42,1|wsvhvz,46,42,1|wsvhw0,45,63,0|wzctvz,45,63,0|wzctw0,46,42,1|xblkjz,46,42,1|xblkk0,45,63,0|xi2wjz,45,63,0|xi2wk0,46,42,1|xubn7z,46,42,1|xubn80,45,63,0|y0sz7z,45,63,0|y0sz80,46,42,1|yd1pvz,46,42,1|yd1pw0,45,63,0|yjj1vz,45,63,0|yjj1w0,46,42,1|yvrsjz,46,42,1|yvrsk0,45,63,0|z294jz,45,63,0|z294k0,46,42,1|zehv7z,46,42,1|zehv80,45,63,0\",\"America/Hermosillo|,0,113,0|-p1u4k0,50,66,0|-m7mko1,50,66,0|-m7mko0,45,62,0|-kf67c1,45,62,0|-kf67c0,50,66,0|-k6j3c1,50,66,0|-k6j3c0,45,62,0|-jypm01,45,62,0|-jypm00,50,66,0|-jpan81,50,66,0|-jpan80,45,62,0|-eg9601,45,62,0|-eg9600,50,66,0|-axv381,50,66,0|-axv380,51,40,0|m7z,51,40,0|m80,50,66,0|dphibz,50,66,0|dphic0,52,62,1|dzxcvz,52,62,1|dzxcw0,50,66,0|e87kzz,50,66,0|e87l00,52,62,1|einfjz,52,62,1|einfk0,50,66,0|eqxnnz,50,66,0|eqxno0,52,62,1|f1di7z,52,62,1|f1di80,50,66,0\",\"America/Indiana/Indianapolis|,0,114,0|-18y0m00,45,62,0|-r0esg1,45,62,0|-r0esg0,46,63,1|-qplz81,46,63,1|-qplz80,45,62,0|-qhops1,45,62,0|-qhops0,46,63,1|-q6vwk1,46,63,1|-q6vwk0,45,62,0|-evzog1,45,62,0|-evzog0,46,63,1|-eqy9w1,46,63,1|-eqy9w0,45,62,0|-ek21s1,45,62,0|-ek21s0,47,63,1|-cq2tg1,47,63,1|-cq2tg0,48,63,1|-cnp0k1,48,63,1|-cnp0k0,45,62,0|-ccw1s1,45,62,0|-ccw1s0,46,63,1|-c4yxw1,46,63,1|-c4yxw0,45,62,0|-bu5z41,45,62,0|-bu5z40,46,63,1|-bm8v81,46,63,1|-bm8v80,45,62,0|-bbfwg1,45,62,0|-bbfwg0,46,63,1|-b3isk1,46,63,1|-b3isk0,45,62,0|-aspts1,45,62,0|-aspts0,46,63,1|-akspw1,46,63,1|-akspw0,45,62,0|-a9msg1,45,62,0|-a9msg0,46,63,1|-a22n81,46,63,1|-a22n80,45,62,0|-9qwps1,45,62,0|-9qwps0,46,63,1|-9izlw1,46,63,1|-9izlw0,45,62,0|-986n41,45,62,0|-986n40,46,63,1|-909j81,46,63,1|-909j80,45,62,0|-8pgkg1,45,62,0|-8pgkg0,46,63,1|-8hjgk1,46,63,1|-8hjgk0,45,62,0|-86qhs1,45,62,0|-86qhs0,46,63,1|-7ytdw1,46,63,1|-7ytdw0,45,62,0|-7o0f41,45,62,0|-7o0f40,49,63,0|-6ea781,49,63,0|-6ea780,45,62,0|-63h8g1,45,62,0|-63h8g0,49,63,0|-cskk1,49,63,0|-cskk0,62,42,1|-3fm01,62,42,1|-3fm00,49,63,0|5xi3z,49,63,0|5xi40,62,42,1|fagnz,62,42,1|fago0,49,63,0|ix323z,49,63,0|ix3240,62,42,1|j7vvbz,62,42,1|j7vvc0,49,63,0|jeq8rz,49,63,0|jeq8s0,62,42,1|jqywnz,62,42,1|jqywo0,49,63,0|jxgbfz,49,63,0|jxgbg0,62,42,1|k9ozbz,62,42,1|k9ozc0,49,63,0|kg6e3z,49,63,0|kg6e40,62,42,1|ksf1zz,62,42,1|ksf200,49,63,0|kz9ffz,49,63,0|kz9fg0,62,42,1|lbi3bz,62,42,1|lbi3c0,49,63,0|lhzi3z,49,63,0|lhzi40,62,42,1|lu85zz,62,42,1|lu8600,49,63,0|m0pkrz,49,63,0|m0pks0,62,42,1|mcy8nz,62,42,1|mcy8o0,49,63,0|mjfnfz,49,63,0|mjfng0,62,42,1|mvobbz,62,42,1|mvobc0,49,63,0|n25q3z,49,63,0|n25q40,62,42,1|needzz,62,42,1|neee00,49,63,0|nkvsrz,49,63,0|nkvss0,62,42,1|nx4gnz,62,42,1|nx4go0,49,63,0|o3yu3z,49,63,0|o3yu40,62,42,1|og7hzz,62,42,1|og7i00,49,63,0|omowrz,49,63,0|omows0,62,42,1|oyxknz,62,42,1|oyxko0,49,63,0|p5ezfz,49,63,0|p5ezg0,62,42,1|phnnbz,62,42,1|phnnc0,49,63,0|po523z,49,63,0|po5240,62,42,1|q0dpzz,62,42,1|q0dq00,49,63,0|q6v4rz,49,63,0|q6v4s0,62,42,1|qj3snz,62,42,1|qj3so0,49,63,0|qpy63z,49,63,0|qpy640,62,42,1|r26tzz,62,42,1|r26u00,49,63,0|r8o8rz,49,63,0|r8o8s0,62,42,1|rkwwnz,62,42,1|rkwwo0,49,63,0|rrebfz,49,63,0|rrebg0,62,42,1|s3mzbz,62,42,1|s3mzc0,49,63,0|sa4e3z,49,63,0|sa4e40,62,42,1|smd1zz,62,42,1|smd200,49,63,0|ssugrz,49,63,0|ssugs0,62,42,1|t534nz,62,42,1|t534o0,49,63,0|tbkjfz,49,63,0|tbkjg0,62,42,1|tnt7bz,62,42,1|tnt7c0,49,63,0|tunkrz,49,63,0|tunks0,62,42,1|u6w8nz,62,42,1|u6w8o0,49,63,0|uddnfz,49,63,0|uddng0,62,42,1|upmbbz,62,42,1|upmbc0,49,63,0|uw3q3z,49,63,0|uw3q40,62,42,1|v8cdzz,62,42,1|v8ce00,49,63,0|vetsrz,49,63,0|vetss0,62,42,1|vr2gnz,62,42,1|vr2go0,49,63,0|vxjvfz,49,63,0|vxjvg0,62,42,1|w9sjbz,62,42,1|w9sjc0,49,63,0|wgmwrz,49,63,0|wgmws0,62,42,1|wsvknz,62,42,1|wsvko0,49,63,0|wzczfz,49,63,0|wzczg0,62,42,1|xblnbz,62,42,1|xblnc0,49,63,0|xi323z,49,63,0|xi3240,62,42,1|xubpzz,62,42,1|xubq00,49,63,0|y0t4rz,49,63,0|y0t4s0,62,42,1|yd1snz,62,42,1|yd1so0,49,63,0|yjj7fz,49,63,0|yjj7g0,62,42,1|yvrvbz,62,42,1|yvrvc0,49,63,0|z29a3z,49,63,0|z29a40,62,42,1|zehxzz,62,42,1|zehy00,49,63,0\",\"America/Indiana/Knox|,0,115,0|-18y0m00,45,62,0|-r0esg1,45,62,0|-r0esg0,46,63,1|-qplz81,46,63,1|-qplz80,45,62,0|-qhops1,45,62,0|-qhops0,46,63,1|-q6vwk1,46,63,1|-q6vwk0,45,62,0|-ek21s1,45,62,0|-ek21s0,47,63,1|-cq2tg1,47,63,1|-cq2tg0,48,63,1|-cnp0k1,48,63,1|-cnp0k0,45,62,0|-bu5z41,45,62,0|-bu5z40,46,63,1|-bm8v81,46,63,1|-bm8v80,45,62,0|-bbfwg1,45,62,0|-bbfwg0,46,63,1|-b3isk1,46,63,1|-b3isk0,45,62,0|-aspts1,45,62,0|-aspts0,46,63,1|-akspw1,46,63,1|-akspw0,45,62,0|-a9msg1,45,62,0|-a9msg0,46,63,1|-a22n81,46,63,1|-a22n80,45,62,0|-9qwps1,45,62,0|-9qwps0,46,63,1|-9izlw1,46,63,1|-9izlw0,45,62,0|-986n41,45,62,0|-986n40,46,63,1|-909j81,46,63,1|-909j80,45,62,0|-8pgkg1,45,62,0|-8pgkg0,46,63,1|-8hjgk1,46,63,1|-8hjgk0,45,62,0|-86qhs1,45,62,0|-86qhs0,46,63,1|-7ytdw1,46,63,1|-7ytdw0,45,62,0|-7o0f41,45,62,0|-7o0f40,46,63,1|-7eahw1,46,63,1|-7eahw0,45,62,0|-74xds1,45,62,0|-74xds0,46,63,1|-6vkf81,46,63,1|-6vkf80,45,62,0|-6m7b41,45,62,0|-6m7b40,46,63,1|-6ea781,46,63,1|-6ea780,45,62,0|-63h8g1,45,62,0|-63h8g0,46,63,1|-5vk4k1,46,63,1|-5vk4k0,45,62,0|-5kr5s1,45,62,0|-5kr5s0,46,63,1|-5be781,46,63,1|-5be780,45,62,0|-521341,45,62,0|-521340,46,63,1|-4sb5w1,46,63,1|-4sb5w0,45,62,0|-4iy1s1,45,62,0|-4iy1s0,46,63,1|-49l381,46,63,1|-49l380,45,62,0|-407z41,45,62,0|-407z40,49,63,0|-384xw1,49,63,0|-384xw0,45,62,0|-1e8n41,45,62,0|-1e8n40,46,63,1|-14vok1,46,63,1|-14vok0,45,62,0|-vikg1,45,62,0|-vikg0,46,63,1|-m5lw1,46,63,1|-m5lw0,45,62,0|-cshs1,45,62,0|-cshs0,46,63,1|-3fj81,46,63,1|-3fj80,45,62,0|5xkvz,45,62,0|5xkw0,46,63,1|fajfz,46,63,1|fajg0,45,62,0|onnjz,45,62,0|onnk0,46,63,1|ydkrz,46,63,1|ydks0,45,62,0|17qovz,45,62,0|17qow0,46,63,1|1h3nfz,46,63,1|1h3ng0,45,62,0|1qgrjz,45,62,0|1qgrk0,46,63,1|1ztq3z,46,63,1|1ztq40,45,62,0|23ffjz,45,62,0|23ffk0,46,63,1|2ijsrz,46,63,1|2ijss0,45,62,0|2oo8vz,45,62,0|2oo8w0,46,63,1|319vfz,46,63,1|319vg0,45,62,0|3amzjz,45,62,0|3amzk0,46,63,1|3kcwrz,46,63,1|3kcws0,45,62,0|3td27z,45,62,0|3td280,46,63,1|432zfz,46,63,1|432zg0,45,62,0|4cg3jz,45,62,0|4cg3k0,46,63,1|4lt23z,46,63,1|4lt240,45,62,0|4v667z,45,62,0|4v6680,46,63,1|54j4rz,46,63,1|54j4s0,45,62,0|5dw8vz,45,62,0|5dw8w0,46,63,1|5n97fz,46,63,1|5n97g0,45,62,0|5wmbjz,45,62,0|5wmbk0,46,63,1|65za3z,46,63,1|65za40,45,62,0|6fce7z,45,62,0|6fce80,46,63,1|6p2bfz,46,63,1|6p2bg0,45,62,0|6y2gvz,45,62,0|6y2gw0,46,63,1|77se3z,46,63,1|77se40,45,62,0|7h5i7z,45,62,0|7h5i80,46,63,1|7qigrz,46,63,1|7qigs0,45,62,0|7zvkvz,45,62,0|7zvkw0,46,63,1|898jfz,46,63,1|898jg0,45,62,0|8ilnjz,45,62,0|8ilnk0,46,63,1|8rym3z,46,63,1|8rym40,45,62,0|908u7z,45,62,0|908u80,46,63,1|9aoorz,46,63,1|9aoos0,45,62,0|9iywvz,45,62,0|9iyww0,46,63,1|9trq3z,46,63,1|9trq40,45,62,0|a1ozjz,45,62,0|a1ozk0,46,63,1|achsrz,46,63,1|achss0,45,62,0|akf27z,45,62,0|akf280,46,63,1|av7vfz,46,63,1|av7vg0,45,62,0|b3i3jz,45,62,0|b3i3k0,46,63,1|bdxy3z,46,63,1|bdxy40,49,63,0|ix323z,49,63,0|ix3240,46,63,1|j7vy3z,46,63,1|j7vy40,45,62,0|jeqbjz,45,62,0|jeqbk0,46,63,1|jqyzfz,46,63,1|jqyzg0,45,62,0|jxge7z,45,62,0|jxge80,46,63,1|k9p23z,46,63,1|k9p240,45,62,0|kg6gvz,45,62,0|kg6gw0,46,63,1|ksf4rz,46,63,1|ksf4s0,45,62,0|kz9i7z,45,62,0|kz9i80,46,63,1|lbi63z,46,63,1|lbi640,45,62,0|lhzkvz,45,62,0|lhzkw0,46,63,1|lu88rz,46,63,1|lu88s0,45,62,0|m0pnjz,45,62,0|m0pnk0,46,63,1|mcybfz,46,63,1|mcybg0,45,62,0|mjfq7z,45,62,0|mjfq80,46,63,1|mvoe3z,46,63,1|mvoe40,45,62,0|n25svz,45,62,0|n25sw0,46,63,1|neegrz,46,63,1|neegs0,45,62,0|nkvvjz,45,62,0|nkvvk0,46,63,1|nx4jfz,46,63,1|nx4jg0,45,62,0|o3ywvz,45,62,0|o3yww0,46,63,1|og7krz,46,63,1|og7ks0,45,62,0|omozjz,45,62,0|omozk0,46,63,1|oyxnfz,46,63,1|oyxng0,45,62,0|p5f27z,45,62,0|p5f280,46,63,1|phnq3z,46,63,1|phnq40,45,62,0|po54vz,45,62,0|po54w0,46,63,1|q0dsrz,46,63,1|q0dss0,45,62,0|q6v7jz,45,62,0|q6v7k0,46,63,1|qj3vfz,46,63,1|qj3vg0,45,62,0|qpy8vz,45,62,0|qpy8w0,46,63,1|r26wrz,46,63,1|r26ws0,45,62,0|r8objz,45,62,0|r8obk0,46,63,1|rkwzfz,46,63,1|rkwzg0,45,62,0|rree7z,45,62,0|rree80,46,63,1|s3n23z,46,63,1|s3n240,45,62,0|sa4gvz,45,62,0|sa4gw0,46,63,1|smd4rz,46,63,1|smd4s0,45,62,0|ssujjz,45,62,0|ssujk0,46,63,1|t537fz,46,63,1|t537g0,45,62,0|tbkm7z,45,62,0|tbkm80,46,63,1|tnta3z,46,63,1|tnta40,45,62,0|tunnjz,45,62,0|tunnk0,46,63,1|u6wbfz,46,63,1|u6wbg0,45,62,0|uddq7z,45,62,0|uddq80,46,63,1|upme3z,46,63,1|upme40,45,62,0|uw3svz,45,62,0|uw3sw0,46,63,1|v8cgrz,46,63,1|v8cgs0,45,62,0|vetvjz,45,62,0|vetvk0,46,63,1|vr2jfz,46,63,1|vr2jg0,45,62,0|vxjy7z,45,62,0|vxjy80,46,63,1|w9sm3z,46,63,1|w9sm40,45,62,0|wgmzjz,45,62,0|wgmzk0,46,63,1|wsvnfz,46,63,1|wsvng0,45,62,0|wzd27z,45,62,0|wzd280,46,63,1|xblq3z,46,63,1|xblq40,45,62,0|xi34vz,45,62,0|xi34w0,46,63,1|xubsrz,46,63,1|xubss0,45,62,0|y0t7jz,45,62,0|y0t7k0,46,63,1|yd1vfz,46,63,1|yd1vg0,45,62,0|yjja7z,45,62,0|yjja80,46,63,1|yvry3z,46,63,1|yvry40,45,62,0|z29cvz,45,62,0|z29cw0,46,63,1|zei0rz,46,63,1|zei0s0,45,62,0\",\"America/Indiana/Marengo|,0,116,0|-18y0m00,45,62,0|-r0esg1,45,62,0|-r0esg0,46,63,1|-qplz81,46,63,1|-qplz80,45,62,0|-qhops1,45,62,0|-qhops0,46,63,1|-q6vwk1,46,63,1|-q6vwk0,45,62,0|-ek21s1,45,62,0|-ek21s0,47,63,1|-cq2tg1,47,63,1|-cq2tg0,48,63,1|-cnp0k1,48,63,1|-cnp0k0,45,62,0|-9qwps1,45,62,0|-9qwps0,46,63,1|-9izlw1,46,63,1|-9izlw0,45,62,0|-86qhs1,45,62,0|-86qhs0,46,63,1|-7ytdw1,46,63,1|-7ytdw0,45,62,0|-7o0f41,45,62,0|-7o0f40,46,63,1|-7g3b81,46,63,1|-7g3b80,45,62,0|-74xds1,45,62,0|-74xds0,46,63,1|-6x09w1,46,63,1|-6x09w0,45,62,0|-6m7b41,45,62,0|-6m7b40,46,63,1|-6ea781,46,63,1|-6ea780,45,62,0|-63h8g1,45,62,0|-63h8g0,46,63,1|-5vk4k1,46,63,1|-5vk4k0,45,62,0|-5kr5s1,45,62,0|-5kr5s0,46,63,1|-5cu1w1,46,63,1|-5cu1w0,45,62,0|-521341,45,62,0|-521340,46,63,1|-4u3z81,46,63,1|-4u3z80,45,62,0|-4iy1s1,45,62,0|-4iy1s0,49,63,0|-cskk1,49,63,0|-cskk0,62,42,1|-3fm01,62,42,1|-3fm00,49,63,0|5xi3z,49,63,0|5xi40,62,42,1|fagnz,62,42,1|fago0,49,63,0|onkrz,49,63,0|onks0,62,42,1|ydhzz,62,42,1|ydi00,49,63,0|17qm3z,49,63,0|17qm40,62,42,1|1h3knz,62,42,1|1h3ko0,49,63,0|1qgorz,49,63,0|1qgos0,62,42,1|1ztnbz,62,42,1|1ztnc0,49,63,0|23fcrz,49,63,0|23fcs0,46,63,1|2ijsrz,46,63,1|2ijss0,49,63,0|2oo63z,49,63,0|2oo640,62,42,1|319snz,62,42,1|319so0,49,63,0|ix323z,49,63,0|ix3240,62,42,1|j7vvbz,62,42,1|j7vvc0,49,63,0|jeq8rz,49,63,0|jeq8s0,62,42,1|jqywnz,62,42,1|jqywo0,49,63,0|jxgbfz,49,63,0|jxgbg0,62,42,1|k9ozbz,62,42,1|k9ozc0,49,63,0|kg6e3z,49,63,0|kg6e40,62,42,1|ksf1zz,62,42,1|ksf200,49,63,0|kz9ffz,49,63,0|kz9fg0,62,42,1|lbi3bz,62,42,1|lbi3c0,49,63,0|lhzi3z,49,63,0|lhzi40,62,42,1|lu85zz,62,42,1|lu8600,49,63,0|m0pkrz,49,63,0|m0pks0,62,42,1|mcy8nz,62,42,1|mcy8o0,49,63,0|mjfnfz,49,63,0|mjfng0,62,42,1|mvobbz,62,42,1|mvobc0,49,63,0|n25q3z,49,63,0|n25q40,62,42,1|needzz,62,42,1|neee00,49,63,0|nkvsrz,49,63,0|nkvss0,62,42,1|nx4gnz,62,42,1|nx4go0,49,63,0|o3yu3z,49,63,0|o3yu40,62,42,1|og7hzz,62,42,1|og7i00,49,63,0|omowrz,49,63,0|omows0,62,42,1|oyxknz,62,42,1|oyxko0,49,63,0|p5ezfz,49,63,0|p5ezg0,62,42,1|phnnbz,62,42,1|phnnc0,49,63,0|po523z,49,63,0|po5240,62,42,1|q0dpzz,62,42,1|q0dq00,49,63,0|q6v4rz,49,63,0|q6v4s0,62,42,1|qj3snz,62,42,1|qj3so0,49,63,0|qpy63z,49,63,0|qpy640,62,42,1|r26tzz,62,42,1|r26u00,49,63,0|r8o8rz,49,63,0|r8o8s0,62,42,1|rkwwnz,62,42,1|rkwwo0,49,63,0|rrebfz,49,63,0|rrebg0,62,42,1|s3mzbz,62,42,1|s3mzc0,49,63,0|sa4e3z,49,63,0|sa4e40,62,42,1|smd1zz,62,42,1|smd200,49,63,0|ssugrz,49,63,0|ssugs0,62,42,1|t534nz,62,42,1|t534o0,49,63,0|tbkjfz,49,63,0|tbkjg0,62,42,1|tnt7bz,62,42,1|tnt7c0,49,63,0|tunkrz,49,63,0|tunks0,62,42,1|u6w8nz,62,42,1|u6w8o0,49,63,0|uddnfz,49,63,0|uddng0,62,42,1|upmbbz,62,42,1|upmbc0,49,63,0|uw3q3z,49,63,0|uw3q40,62,42,1|v8cdzz,62,42,1|v8ce00,49,63,0|vetsrz,49,63,0|vetss0,62,42,1|vr2gnz,62,42,1|vr2go0,49,63,0|vxjvfz,49,63,0|vxjvg0,62,42,1|w9sjbz,62,42,1|w9sjc0,49,63,0|wgmwrz,49,63,0|wgmws0,62,42,1|wsvknz,62,42,1|wsvko0,49,63,0|wzczfz,49,63,0|wzczg0,62,42,1|xblnbz,62,42,1|xblnc0,49,63,0|xi323z,49,63,0|xi3240,62,42,1|xubpzz,62,42,1|xubq00,49,63,0|y0t4rz,49,63,0|y0t4s0,62,42,1|yd1snz,62,42,1|yd1so0,49,63,0|yjj7fz,49,63,0|yjj7g0,62,42,1|yvrvbz,62,42,1|yvrvc0,49,63,0|z29a3z,49,63,0|z29a40,62,42,1|zehxzz,62,42,1|zehy00,49,63,0\",\"America/Indiana/Petersburg|,0,117,0|-18y0m00,45,62,0|-r0esg1,45,62,0|-r0esg0,46,63,1|-qplz81,46,63,1|-qplz80,45,62,0|-qhops1,45,62,0|-qhops0,46,63,1|-q6vwk1,46,63,1|-q6vwk0,45,62,0|-ek21s1,45,62,0|-ek21s0,47,63,1|-cq2tg1,47,63,1|-cq2tg0,48,63,1|-cnp0k1,48,63,1|-cnp0k0,45,62,0|-7nnm01,45,62,0|-7nnm00,46,63,1|-7g3b81,46,63,1|-7g3b80,45,62,0|-74xds1,45,62,0|-74xds0,46,63,1|-6x09w1,46,63,1|-6x09w0,45,62,0|-6m7b41,45,62,0|-6m7b40,46,63,1|-6ea781,46,63,1|-6ea780,45,62,0|-63h8g1,45,62,0|-63h8g0,46,63,1|-5vk4k1,46,63,1|-5vk4k0,45,62,0|-5kr5s1,45,62,0|-5kr5s0,46,63,1|-5cu1w1,46,63,1|-5cu1w0,45,62,0|-521341,45,62,0|-521340,46,63,1|-4u3z81,46,63,1|-4u3z80,45,62,0|-4iy1s1,45,62,0|-4iy1s0,46,63,1|-49l381,46,63,1|-49l380,45,62,0|-407z41,45,62,0|-407z40,46,63,1|-3qv0k1,46,63,1|-3qv0k0,45,62,0|-3hhwg1,45,62,0|-3hhwg0,46,63,1|-384xw1,46,63,1|-384xw0,45,62,0|-2yrts1,45,62,0|-2yrts0,46,63,1|-2pev81,46,63,1|-2pev80,45,62,0|-2g1r41,45,62,0|-2g1r40,49,63,0|-1nlr81,49,63,0|-1nlr80,45,62,0|-1e8n41,45,62,0|-1e8n40,46,63,1|-14vok1,46,63,1|-14vok0,45,62,0|-vikg1,45,62,0|-vikg0,46,63,1|-m5lw1,46,63,1|-m5lw0,45,62,0|-cshs1,45,62,0|-cshs0,46,63,1|-3fj81,46,63,1|-3fj80,45,62,0|5xkvz,45,62,0|5xkw0,46,63,1|fajfz,46,63,1|fajg0,45,62,0|onnjz,45,62,0|onnk0,46,63,1|ydkrz,46,63,1|ydks0,45,62,0|17qovz,45,62,0|17qow0,46,63,1|1h3nfz,46,63,1|1h3ng0,45,62,0|1qgrjz,45,62,0|1qgrk0,46,63,1|1ztq3z,46,63,1|1ztq40,45,62,0|23ffjz,45,62,0|23ffk0,46,63,1|2ijsrz,46,63,1|2ijss0,45,62,0|2oo8vz,45,62,0|2oo8w0,46,63,1|319vfz,46,63,1|319vg0,45,62,0|3amzjz,45,62,0|3amzk0,46,63,1|3kcwrz,46,63,1|3kcws0,45,62,0|3td27z,45,62,0|3td280,46,63,1|432zfz,46,63,1|432zg0,49,63,0|ix323z,49,63,0|ix3240,46,63,1|j7vy3z,46,63,1|j7vy40,45,62,0|jeqbjz,45,62,0|jeqbk0,46,63,1|jqyzfz,46,63,1|jqyzg0,49,63,0|jxgbfz,49,63,0|jxgbg0,62,42,1|k9ozbz,62,42,1|k9ozc0,49,63,0|kg6e3z,49,63,0|kg6e40,62,42,1|ksf1zz,62,42,1|ksf200,49,63,0|kz9ffz,49,63,0|kz9fg0,62,42,1|lbi3bz,62,42,1|lbi3c0,49,63,0|lhzi3z,49,63,0|lhzi40,62,42,1|lu85zz,62,42,1|lu8600,49,63,0|m0pkrz,49,63,0|m0pks0,62,42,1|mcy8nz,62,42,1|mcy8o0,49,63,0|mjfnfz,49,63,0|mjfng0,62,42,1|mvobbz,62,42,1|mvobc0,49,63,0|n25q3z,49,63,0|n25q40,62,42,1|needzz,62,42,1|neee00,49,63,0|nkvsrz,49,63,0|nkvss0,62,42,1|nx4gnz,62,42,1|nx4go0,49,63,0|o3yu3z,49,63,0|o3yu40,62,42,1|og7hzz,62,42,1|og7i00,49,63,0|omowrz,49,63,0|omows0,62,42,1|oyxknz,62,42,1|oyxko0,49,63,0|p5ezfz,49,63,0|p5ezg0,62,42,1|phnnbz,62,42,1|phnnc0,49,63,0|po523z,49,63,0|po5240,62,42,1|q0dpzz,62,42,1|q0dq00,49,63,0|q6v4rz,49,63,0|q6v4s0,62,42,1|qj3snz,62,42,1|qj3so0,49,63,0|qpy63z,49,63,0|qpy640,62,42,1|r26tzz,62,42,1|r26u00,49,63,0|r8o8rz,49,63,0|r8o8s0,62,42,1|rkwwnz,62,42,1|rkwwo0,49,63,0|rrebfz,49,63,0|rrebg0,62,42,1|s3mzbz,62,42,1|s3mzc0,49,63,0|sa4e3z,49,63,0|sa4e40,62,42,1|smd1zz,62,42,1|smd200,49,63,0|ssugrz,49,63,0|ssugs0,62,42,1|t534nz,62,42,1|t534o0,49,63,0|tbkjfz,49,63,0|tbkjg0,62,42,1|tnt7bz,62,42,1|tnt7c0,49,63,0|tunkrz,49,63,0|tunks0,62,42,1|u6w8nz,62,42,1|u6w8o0,49,63,0|uddnfz,49,63,0|uddng0,62,42,1|upmbbz,62,42,1|upmbc0,49,63,0|uw3q3z,49,63,0|uw3q40,62,42,1|v8cdzz,62,42,1|v8ce00,49,63,0|vetsrz,49,63,0|vetss0,62,42,1|vr2gnz,62,42,1|vr2go0,49,63,0|vxjvfz,49,63,0|vxjvg0,62,42,1|w9sjbz,62,42,1|w9sjc0,49,63,0|wgmwrz,49,63,0|wgmws0,62,42,1|wsvknz,62,42,1|wsvko0,49,63,0|wzczfz,49,63,0|wzczg0,62,42,1|xblnbz,62,42,1|xblnc0,49,63,0|xi323z,49,63,0|xi3240,62,42,1|xubpzz,62,42,1|xubq00,49,63,0|y0t4rz,49,63,0|y0t4s0,62,42,1|yd1snz,62,42,1|yd1so0,49,63,0|yjj7fz,49,63,0|yjj7g0,62,42,1|yvrvbz,62,42,1|yvrvc0,49,63,0|z29a3z,49,63,0|z29a40,62,42,1|zehxzz,62,42,1|zehy00,49,63,0\",\"America/Indiana/Tell_City|,0,118,0|-18y0m00,45,62,0|-r0esg1,45,62,0|-r0esg0,46,63,1|-qplz81,46,63,1|-qplz80,45,62,0|-qhops1,45,62,0|-qhops0,46,63,1|-q6vwk1,46,63,1|-q6vwk0,45,62,0|-ek21s1,45,62,0|-ek21s0,47,63,1|-cq2tg1,47,63,1|-cq2tg0,48,63,1|-cnp0k1,48,63,1|-cnp0k0,45,62,0|-7nnm01,45,62,0|-7nnm00,46,63,1|-7g3b81,46,63,1|-7g3b80,45,62,0|-74xds1,45,62,0|-74xds0,46,63,1|-6x09w1,46,63,1|-6x09w0,45,62,0|-6m7b41,45,62,0|-6m7b40,46,63,1|-6ea781,46,63,1|-6ea780,45,62,0|-63h8g1,45,62,0|-63h8g0,46,63,1|-5vk4k1,46,63,1|-5vk4k0,45,62,0|-5kr5s1,45,62,0|-5kr5s0,46,63,1|-5cu1w1,46,63,1|-5cu1w0,45,62,0|-521341,45,62,0|-521340,46,63,1|-4u3z81,46,63,1|-4u3z80,45,62,0|-4iy1s1,45,62,0|-4iy1s0,46,63,1|-49l381,46,63,1|-49l380,45,62,0|-407z41,45,62,0|-407z40,46,63,1|-3qv0k1,46,63,1|-3qv0k0,45,62,0|-3hhwg1,45,62,0|-3hhwg0,46,63,1|-384xw1,46,63,1|-384xw0,45,62,0|-2yrts1,45,62,0|-2yrts0,49,63,0|-14vok1,49,63,0|-14vok0,45,62,0|-vikg1,45,62,0|-vikg0,46,63,1|-m5lw1,46,63,1|-m5lw0,45,62,0|-cshs1,45,62,0|-cshs0,62,42,1|-3fm01,62,42,1|-3fm00,49,63,0|5xi3z,49,63,0|5xi40,62,42,1|fagnz,62,42,1|fago0,49,63,0|ix323z,49,63,0|ix3240,46,63,1|j7vy3z,46,63,1|j7vy40,45,62,0|jeqbjz,45,62,0|jeqbk0,46,63,1|jqyzfz,46,63,1|jqyzg0,45,62,0|jxge7z,45,62,0|jxge80,46,63,1|k9p23z,46,63,1|k9p240,45,62,0|kg6gvz,45,62,0|kg6gw0,46,63,1|ksf4rz,46,63,1|ksf4s0,45,62,0|kz9i7z,45,62,0|kz9i80,46,63,1|lbi63z,46,63,1|lbi640,45,62,0|lhzkvz,45,62,0|lhzkw0,46,63,1|lu88rz,46,63,1|lu88s0,45,62,0|m0pnjz,45,62,0|m0pnk0,46,63,1|mcybfz,46,63,1|mcybg0,45,62,0|mjfq7z,45,62,0|mjfq80,46,63,1|mvoe3z,46,63,1|mvoe40,45,62,0|n25svz,45,62,0|n25sw0,46,63,1|neegrz,46,63,1|neegs0,45,62,0|nkvvjz,45,62,0|nkvvk0,46,63,1|nx4jfz,46,63,1|nx4jg0,45,62,0|o3ywvz,45,62,0|o3yww0,46,63,1|og7krz,46,63,1|og7ks0,45,62,0|omozjz,45,62,0|omozk0,46,63,1|oyxnfz,46,63,1|oyxng0,45,62,0|p5f27z,45,62,0|p5f280,46,63,1|phnq3z,46,63,1|phnq40,45,62,0|po54vz,45,62,0|po54w0,46,63,1|q0dsrz,46,63,1|q0dss0,45,62,0|q6v7jz,45,62,0|q6v7k0,46,63,1|qj3vfz,46,63,1|qj3vg0,45,62,0|qpy8vz,45,62,0|qpy8w0,46,63,1|r26wrz,46,63,1|r26ws0,45,62,0|r8objz,45,62,0|r8obk0,46,63,1|rkwzfz,46,63,1|rkwzg0,45,62,0|rree7z,45,62,0|rree80,46,63,1|s3n23z,46,63,1|s3n240,45,62,0|sa4gvz,45,62,0|sa4gw0,46,63,1|smd4rz,46,63,1|smd4s0,45,62,0|ssujjz,45,62,0|ssujk0,46,63,1|t537fz,46,63,1|t537g0,45,62,0|tbkm7z,45,62,0|tbkm80,46,63,1|tnta3z,46,63,1|tnta40,45,62,0|tunnjz,45,62,0|tunnk0,46,63,1|u6wbfz,46,63,1|u6wbg0,45,62,0|uddq7z,45,62,0|uddq80,46,63,1|upme3z,46,63,1|upme40,45,62,0|uw3svz,45,62,0|uw3sw0,46,63,1|v8cgrz,46,63,1|v8cgs0,45,62,0|vetvjz,45,62,0|vetvk0,46,63,1|vr2jfz,46,63,1|vr2jg0,45,62,0|vxjy7z,45,62,0|vxjy80,46,63,1|w9sm3z,46,63,1|w9sm40,45,62,0|wgmzjz,45,62,0|wgmzk0,46,63,1|wsvnfz,46,63,1|wsvng0,45,62,0|wzd27z,45,62,0|wzd280,46,63,1|xblq3z,46,63,1|xblq40,45,62,0|xi34vz,45,62,0|xi34w0,46,63,1|xubsrz,46,63,1|xubss0,45,62,0|y0t7jz,45,62,0|y0t7k0,46,63,1|yd1vfz,46,63,1|yd1vg0,45,62,0|yjja7z,45,62,0|yjja80,46,63,1|yvry3z,46,63,1|yvry40,45,62,0|z29cvz,45,62,0|z29cw0,46,63,1|zei0rz,46,63,1|zei0s0,45,62,0\",\"America/Indiana/Vevay|,0,119,0|-18y0m00,45,62,0|-r0esg1,45,62,0|-r0esg0,46,63,1|-qplz81,46,63,1|-qplz80,45,62,0|-qhops1,45,62,0|-qhops0,46,63,1|-q6vwk1,46,63,1|-q6vwk0,45,62,0|-ek21s1,45,62,0|-ek21s0,47,63,1|-cq2tg1,47,63,1|-cq2tg0,48,63,1|-cnp0k1,48,63,1|-cnp0k0,45,62,0|-86qhs1,45,62,0|-86qhs0,49,63,0|-cskk1,49,63,0|-cskk0,62,42,1|-3fm01,62,42,1|-3fm00,49,63,0|5xi3z,49,63,0|5xi40,62,42,1|fagnz,62,42,1|fago0,49,63,0|onkrz,49,63,0|onks0,62,42,1|ydhzz,62,42,1|ydi00,49,63,0|17qm3z,49,63,0|17qm40,62,42,1|1h3knz,62,42,1|1h3ko0,49,63,0|ix323z,49,63,0|ix3240,62,42,1|j7vvbz,62,42,1|j7vvc0,49,63,0|jeq8rz,49,63,0|jeq8s0,62,42,1|jqywnz,62,42,1|jqywo0,49,63,0|jxgbfz,49,63,0|jxgbg0,62,42,1|k9ozbz,62,42,1|k9ozc0,49,63,0|kg6e3z,49,63,0|kg6e40,62,42,1|ksf1zz,62,42,1|ksf200,49,63,0|kz9ffz,49,63,0|kz9fg0,62,42,1|lbi3bz,62,42,1|lbi3c0,49,63,0|lhzi3z,49,63,0|lhzi40,62,42,1|lu85zz,62,42,1|lu8600,49,63,0|m0pkrz,49,63,0|m0pks0,62,42,1|mcy8nz,62,42,1|mcy8o0,49,63,0|mjfnfz,49,63,0|mjfng0,62,42,1|mvobbz,62,42,1|mvobc0,49,63,0|n25q3z,49,63,0|n25q40,62,42,1|needzz,62,42,1|neee00,49,63,0|nkvsrz,49,63,0|nkvss0,62,42,1|nx4gnz,62,42,1|nx4go0,49,63,0|o3yu3z,49,63,0|o3yu40,62,42,1|og7hzz,62,42,1|og7i00,49,63,0|omowrz,49,63,0|omows0,62,42,1|oyxknz,62,42,1|oyxko0,49,63,0|p5ezfz,49,63,0|p5ezg0,62,42,1|phnnbz,62,42,1|phnnc0,49,63,0|po523z,49,63,0|po5240,62,42,1|q0dpzz,62,42,1|q0dq00,49,63,0|q6v4rz,49,63,0|q6v4s0,62,42,1|qj3snz,62,42,1|qj3so0,49,63,0|qpy63z,49,63,0|qpy640,62,42,1|r26tzz,62,42,1|r26u00,49,63,0|r8o8rz,49,63,0|r8o8s0,62,42,1|rkwwnz,62,42,1|rkwwo0,49,63,0|rrebfz,49,63,0|rrebg0,62,42,1|s3mzbz,62,42,1|s3mzc0,49,63,0|sa4e3z,49,63,0|sa4e40,62,42,1|smd1zz,62,42,1|smd200,49,63,0|ssugrz,49,63,0|ssugs0,62,42,1|t534nz,62,42,1|t534o0,49,63,0|tbkjfz,49,63,0|tbkjg0,62,42,1|tnt7bz,62,42,1|tnt7c0,49,63,0|tunkrz,49,63,0|tunks0,62,42,1|u6w8nz,62,42,1|u6w8o0,49,63,0|uddnfz,49,63,0|uddng0,62,42,1|upmbbz,62,42,1|upmbc0,49,63,0|uw3q3z,49,63,0|uw3q40,62,42,1|v8cdzz,62,42,1|v8ce00,49,63,0|vetsrz,49,63,0|vetss0,62,42,1|vr2gnz,62,42,1|vr2go0,49,63,0|vxjvfz,49,63,0|vxjvg0,62,42,1|w9sjbz,62,42,1|w9sjc0,49,63,0|wgmwrz,49,63,0|wgmws0,62,42,1|wsvknz,62,42,1|wsvko0,49,63,0|wzczfz,49,63,0|wzczg0,62,42,1|xblnbz,62,42,1|xblnc0,49,63,0|xi323z,49,63,0|xi3240,62,42,1|xubpzz,62,42,1|xubq00,49,63,0|y0t4rz,49,63,0|y0t4s0,62,42,1|yd1snz,62,42,1|yd1so0,49,63,0|yjj7fz,49,63,0|yjj7g0,62,42,1|yvrvbz,62,42,1|yvrvc0,49,63,0|z29a3z,49,63,0|z29a40,62,42,1|zehxzz,62,42,1|zehy00,49,63,0\",\"America/Indiana/Vincennes|,0,120,0|-18y0m00,45,62,0|-r0esg1,45,62,0|-r0esg0,46,63,1|-qplz81,46,63,1|-qplz80,45,62,0|-qhops1,45,62,0|-qhops0,46,63,1|-q6vwk1,46,63,1|-q6vwk0,45,62,0|-ek21s1,45,62,0|-ek21s0,47,63,1|-cq2tg1,47,63,1|-cq2tg0,48,63,1|-cnp0k1,48,63,1|-cnp0k0,45,62,0|-ccw1s1,45,62,0|-ccw1s0,46,63,1|-c4yxw1,46,63,1|-c4yxw0,45,62,0|-8pgkg1,45,62,0|-8pgkg0,46,63,1|-8hjgk1,46,63,1|-8hjgk0,45,62,0|-86qhs1,45,62,0|-86qhs0,46,63,1|-7ytdw1,46,63,1|-7ytdw0,45,62,0|-7nnm01,45,62,0|-7nnm00,46,63,1|-7g3b81,46,63,1|-7g3b80,45,62,0|-74xds1,45,62,0|-74xds0,46,63,1|-6x09w1,46,63,1|-6x09w0,45,62,0|-6m7b41,45,62,0|-6m7b40,46,63,1|-6ea781,46,63,1|-6ea780,45,62,0|-63h8g1,45,62,0|-63h8g0,46,63,1|-5vk4k1,46,63,1|-5vk4k0,45,62,0|-5kr5s1,45,62,0|-5kr5s0,46,63,1|-5cu1w1,46,63,1|-5cu1w0,45,62,0|-521341,45,62,0|-521340,46,63,1|-4sb5w1,46,63,1|-4sb5w0,45,62,0|-4iy1s1,45,62,0|-4iy1s0,46,63,1|-4bdwk1,46,63,1|-4bdwk0,45,62,0|-407z41,45,62,0|-407z40,46,63,1|-3qv0k1,46,63,1|-3qv0k0,45,62,0|-3hhwg1,45,62,0|-3hhwg0,46,63,1|-384xw1,46,63,1|-384xw0,45,62,0|-2yrts1,45,62,0|-2yrts0,49,63,0|-cskk1,49,63,0|-cskk0,62,42,1|-3fm01,62,42,1|-3fm00,49,63,0|5xi3z,49,63,0|5xi40,62,42,1|fagnz,62,42,1|fago0,49,63,0|ix323z,49,63,0|ix3240,46,63,1|j7vy3z,46,63,1|j7vy40,45,62,0|jeqbjz,45,62,0|jeqbk0,46,63,1|jqyzfz,46,63,1|jqyzg0,49,63,0|jxgbfz,49,63,0|jxgbg0,62,42,1|k9ozbz,62,42,1|k9ozc0,49,63,0|kg6e3z,49,63,0|kg6e40,62,42,1|ksf1zz,62,42,1|ksf200,49,63,0|kz9ffz,49,63,0|kz9fg0,62,42,1|lbi3bz,62,42,1|lbi3c0,49,63,0|lhzi3z,49,63,0|lhzi40,62,42,1|lu85zz,62,42,1|lu8600,49,63,0|m0pkrz,49,63,0|m0pks0,62,42,1|mcy8nz,62,42,1|mcy8o0,49,63,0|mjfnfz,49,63,0|mjfng0,62,42,1|mvobbz,62,42,1|mvobc0,49,63,0|n25q3z,49,63,0|n25q40,62,42,1|needzz,62,42,1|neee00,49,63,0|nkvsrz,49,63,0|nkvss0,62,42,1|nx4gnz,62,42,1|nx4go0,49,63,0|o3yu3z,49,63,0|o3yu40,62,42,1|og7hzz,62,42,1|og7i00,49,63,0|omowrz,49,63,0|omows0,62,42,1|oyxknz,62,42,1|oyxko0,49,63,0|p5ezfz,49,63,0|p5ezg0,62,42,1|phnnbz,62,42,1|phnnc0,49,63,0|po523z,49,63,0|po5240,62,42,1|q0dpzz,62,42,1|q0dq00,49,63,0|q6v4rz,49,63,0|q6v4s0,62,42,1|qj3snz,62,42,1|qj3so0,49,63,0|qpy63z,49,63,0|qpy640,62,42,1|r26tzz,62,42,1|r26u00,49,63,0|r8o8rz,49,63,0|r8o8s0,62,42,1|rkwwnz,62,42,1|rkwwo0,49,63,0|rrebfz,49,63,0|rrebg0,62,42,1|s3mzbz,62,42,1|s3mzc0,49,63,0|sa4e3z,49,63,0|sa4e40,62,42,1|smd1zz,62,42,1|smd200,49,63,0|ssugrz,49,63,0|ssugs0,62,42,1|t534nz,62,42,1|t534o0,49,63,0|tbkjfz,49,63,0|tbkjg0,62,42,1|tnt7bz,62,42,1|tnt7c0,49,63,0|tunkrz,49,63,0|tunks0,62,42,1|u6w8nz,62,42,1|u6w8o0,49,63,0|uddnfz,49,63,0|uddng0,62,42,1|upmbbz,62,42,1|upmbc0,49,63,0|uw3q3z,49,63,0|uw3q40,62,42,1|v8cdzz,62,42,1|v8ce00,49,63,0|vetsrz,49,63,0|vetss0,62,42,1|vr2gnz,62,42,1|vr2go0,49,63,0|vxjvfz,49,63,0|vxjvg0,62,42,1|w9sjbz,62,42,1|w9sjc0,49,63,0|wgmwrz,49,63,0|wgmws0,62,42,1|wsvknz,62,42,1|wsvko0,49,63,0|wzczfz,49,63,0|wzczg0,62,42,1|xblnbz,62,42,1|xblnc0,49,63,0|xi323z,49,63,0|xi3240,62,42,1|xubpzz,62,42,1|xubq00,49,63,0|y0t4rz,49,63,0|y0t4s0,62,42,1|yd1snz,62,42,1|yd1so0,49,63,0|yjj7fz,49,63,0|yjj7g0,62,42,1|yvrvbz,62,42,1|yvrvc0,49,63,0|z29a3z,49,63,0|z29a40,62,42,1|zehxzz,62,42,1|zehy00,49,63,0\",\"America/Indiana/Winamac|,0,121,0|-18y0m00,45,62,0|-r0esg1,45,62,0|-r0esg0,46,63,1|-qplz81,46,63,1|-qplz80,45,62,0|-qhops1,45,62,0|-qhops0,46,63,1|-q6vwk1,46,63,1|-q6vwk0,45,62,0|-ek21s1,45,62,0|-ek21s0,47,63,1|-cq2tg1,47,63,1|-cq2tg0,48,63,1|-cnp0k1,48,63,1|-cnp0k0,45,62,0|-ccw1s1,45,62,0|-ccw1s0,46,63,1|-c4yxw1,46,63,1|-c4yxw0,45,62,0|-bu5z41,45,62,0|-bu5z40,46,63,1|-bm8v81,46,63,1|-bm8v80,45,62,0|-bbfwg1,45,62,0|-bbfwg0,46,63,1|-b3isk1,46,63,1|-b3isk0,45,62,0|-aspts1,45,62,0|-aspts0,46,63,1|-akspw1,46,63,1|-akspw0,45,62,0|-a9msg1,45,62,0|-a9msg0,46,63,1|-a22n81,46,63,1|-a22n80,45,62,0|-9qwps1,45,62,0|-9qwps0,46,63,1|-9izlw1,46,63,1|-9izlw0,45,62,0|-986n41,45,62,0|-986n40,46,63,1|-909j81,46,63,1|-909j80,45,62,0|-8pgkg1,45,62,0|-8pgkg0,46,63,1|-8hjgk1,46,63,1|-8hjgk0,45,62,0|-86qhs1,45,62,0|-86qhs0,46,63,1|-7ytdw1,46,63,1|-7ytdw0,45,62,0|-7o0f41,45,62,0|-7o0f40,46,63,1|-7eahw1,46,63,1|-7eahw0,45,62,0|-74xds1,45,62,0|-74xds0,46,63,1|-6vkf81,46,63,1|-6vkf80,45,62,0|-6m7b41,45,62,0|-6m7b40,46,63,1|-6ea781,46,63,1|-6ea780,45,62,0|-63h8g1,45,62,0|-63h8g0,46,63,1|-5vk4k1,46,63,1|-5vk4k0,45,62,0|-5kr5s1,45,62,0|-5kr5s0,46,63,1|-5cu1w1,46,63,1|-5cu1w0,45,62,0|-521341,45,62,0|-521340,46,63,1|-4u3z81,46,63,1|-4u3z80,45,62,0|-4iy1s1,45,62,0|-4iy1s0,49,63,0|-cskk1,49,63,0|-cskk0,62,42,1|-3fm01,62,42,1|-3fm00,49,63,0|5xi3z,49,63,0|5xi40,62,42,1|fagnz,62,42,1|fago0,49,63,0|ix323z,49,63,0|ix3240,46,63,1|j7vy3z,46,63,1|j7vy40,45,62,0|jeqbjz,45,62,0|jeqbk0,62,42,1|jqywnz,62,42,1|jqywo0,49,63,0|jxgbfz,49,63,0|jxgbg0,62,42,1|k9ozbz,62,42,1|k9ozc0,49,63,0|kg6e3z,49,63,0|kg6e40,62,42,1|ksf1zz,62,42,1|ksf200,49,63,0|kz9ffz,49,63,0|kz9fg0,62,42,1|lbi3bz,62,42,1|lbi3c0,49,63,0|lhzi3z,49,63,0|lhzi40,62,42,1|lu85zz,62,42,1|lu8600,49,63,0|m0pkrz,49,63,0|m0pks0,62,42,1|mcy8nz,62,42,1|mcy8o0,49,63,0|mjfnfz,49,63,0|mjfng0,62,42,1|mvobbz,62,42,1|mvobc0,49,63,0|n25q3z,49,63,0|n25q40,62,42,1|needzz,62,42,1|neee00,49,63,0|nkvsrz,49,63,0|nkvss0,62,42,1|nx4gnz,62,42,1|nx4go0,49,63,0|o3yu3z,49,63,0|o3yu40,62,42,1|og7hzz,62,42,1|og7i00,49,63,0|omowrz,49,63,0|omows0,62,42,1|oyxknz,62,42,1|oyxko0,49,63,0|p5ezfz,49,63,0|p5ezg0,62,42,1|phnnbz,62,42,1|phnnc0,49,63,0|po523z,49,63,0|po5240,62,42,1|q0dpzz,62,42,1|q0dq00,49,63,0|q6v4rz,49,63,0|q6v4s0,62,42,1|qj3snz,62,42,1|qj3so0,49,63,0|qpy63z,49,63,0|qpy640,62,42,1|r26tzz,62,42,1|r26u00,49,63,0|r8o8rz,49,63,0|r8o8s0,62,42,1|rkwwnz,62,42,1|rkwwo0,49,63,0|rrebfz,49,63,0|rrebg0,62,42,1|s3mzbz,62,42,1|s3mzc0,49,63,0|sa4e3z,49,63,0|sa4e40,62,42,1|smd1zz,62,42,1|smd200,49,63,0|ssugrz,49,63,0|ssugs0,62,42,1|t534nz,62,42,1|t534o0,49,63,0|tbkjfz,49,63,0|tbkjg0,62,42,1|tnt7bz,62,42,1|tnt7c0,49,63,0|tunkrz,49,63,0|tunks0,62,42,1|u6w8nz,62,42,1|u6w8o0,49,63,0|uddnfz,49,63,0|uddng0,62,42,1|upmbbz,62,42,1|upmbc0,49,63,0|uw3q3z,49,63,0|uw3q40,62,42,1|v8cdzz,62,42,1|v8ce00,49,63,0|vetsrz,49,63,0|vetss0,62,42,1|vr2gnz,62,42,1|vr2go0,49,63,0|vxjvfz,49,63,0|vxjvg0,62,42,1|w9sjbz,62,42,1|w9sjc0,49,63,0|wgmwrz,49,63,0|wgmws0,62,42,1|wsvknz,62,42,1|wsvko0,49,63,0|wzczfz,49,63,0|wzczg0,62,42,1|xblnbz,62,42,1|xblnc0,49,63,0|xi323z,49,63,0|xi3240,62,42,1|xubpzz,62,42,1|xubq00,49,63,0|y0t4rz,49,63,0|y0t4s0,62,42,1|yd1snz,62,42,1|yd1so0,49,63,0|yjj7fz,49,63,0|yjj7g0,62,42,1|yvrvbz,62,42,1|yvrvc0,49,63,0|z29a3z,49,63,0|z29a40,62,42,1|zehxzz,62,42,1|zehy00,49,63,0\",\"America/Inuvik|,60,1,0|-8ve5c0,51,40,0|-2g1r41,51,40,0|-2g1r40,78,62,1|-26br41,78,62,1|-26br40,51,40,0|4v6brz,51,40,0|4v6bs0,50,66,0|5dwbnz,50,66,0|5dwbo0,52,62,1|5n9a7z,52,62,1|5n9a80,50,66,0|5wmebz,50,66,0|5wmec0,52,62,1|65zcvz,52,62,1|65zcw0,50,66,0|6fcgzz,50,66,0|6fch00,52,62,1|6p2e7z,52,62,1|6p2e80,50,66,0|6y2jnz,50,66,0|6y2jo0,52,62,1|77sgvz,52,62,1|77sgw0,50,66,0|7h5kzz,50,66,0|7h5l00,52,62,1|7qijjz,52,62,1|7qijk0,50,66,0|7zvnnz,50,66,0|7zvno0,52,62,1|898m7z,52,62,1|898m80,50,66,0|8ilqbz,50,66,0|8ilqc0,52,62,1|8ryovz,52,62,1|8ryow0,50,66,0|908wzz,50,66,0|908x00,52,62,1|9aorjz,52,62,1|9aork0,50,66,0|9iyznz,50,66,0|9iyzo0,52,62,1|9trsvz,52,62,1|9trsw0,50,66,0|a1p2bz,50,66,0|a1p2c0,52,62,1|achvjz,52,62,1|achvk0,50,66,0|akf4zz,50,66,0|akf500,52,62,1|av7y7z,52,62,1|av7y80,50,66,0|b3i6bz,50,66,0|b3i6c0,52,62,1|bdy0vz,52,62,1|bdy0w0,50,66,0|bm88zz,50,66,0|bm8900,52,62,1|bwo3jz,52,62,1|bwo3k0,50,66,0|c4ybnz,50,66,0|c4ybo0,52,62,1|cfr4vz,52,62,1|cfr4w0,50,66,0|cnoebz,50,66,0|cnoec0,52,62,1|cyh7jz,52,62,1|cyh7k0,50,66,0|d6egzz,50,66,0|d6eh00,52,62,1|dh7a7z,52,62,1|dh7a80,50,66,0|dphibz,50,66,0|dphic0,52,62,1|dzxcvz,52,62,1|dzxcw0,50,66,0|e87kzz,50,66,0|e87l00,52,62,1|einfjz,52,62,1|einfk0,50,66,0|eqxnnz,50,66,0|eqxno0,52,62,1|f1di7z,52,62,1|f1di80,50,66,0|f9nqbz,50,66,0|f9nqc0,52,62,1|fkgjjz,52,62,1|fkgjk0,50,66,0|fsdszz,50,66,0|fsdt00,52,62,1|g36m7z,52,62,1|g36m80,50,66,0|gb3vnz,50,66,0|gb3vo0,52,62,1|glwovz,52,62,1|glwow0,50,66,0|gu6wzz,50,66,0|gu6x00,52,62,1|h4mrjz,52,62,1|h4mrk0,50,66,0|hcwznz,50,66,0|hcwzo0,52,62,1|hncu7z,52,62,1|hncu80,50,66,0|hvn2bz,50,66,0|hvn2c0,52,62,1|i6fvjz,52,62,1|i6fvk0,50,66,0|ied4zz,50,66,0|ied500,52,62,1|ip5y7z,52,62,1|ip5y80,50,66,0|ix37nz,50,66,0|ix37o0,52,62,1|j7w0vz,52,62,1|j7w0w0,50,66,0|jeqebz,50,66,0|jeqec0,52,62,1|jqz27z,52,62,1|jqz280,50,66,0|jxggzz,50,66,0|jxgh00,52,62,1|k9p4vz,52,62,1|k9p4w0,50,66,0|kg6jnz,50,66,0|kg6jo0,52,62,1|ksf7jz,52,62,1|ksf7k0,50,66,0|kz9kzz,50,66,0|kz9l00,52,62,1|lbi8vz,52,62,1|lbi8w0,50,66,0|lhznnz,50,66,0|lhzno0,52,62,1|lu8bjz,52,62,1|lu8bk0,50,66,0|m0pqbz,50,66,0|m0pqc0,52,62,1|mcye7z,52,62,1|mcye80,50,66,0|mjfszz,50,66,0|mjft00,52,62,1|mvogvz,52,62,1|mvogw0,50,66,0|n25vnz,50,66,0|n25vo0,52,62,1|neejjz,52,62,1|neejk0,50,66,0|nkvybz,50,66,0|nkvyc0,52,62,1|nx4m7z,52,62,1|nx4m80,50,66,0|o3yznz,50,66,0|o3yzo0,52,62,1|og7njz,52,62,1|og7nk0,50,66,0|omp2bz,50,66,0|omp2c0,52,62,1|oyxq7z,52,62,1|oyxq80,50,66,0|p5f4zz,50,66,0|p5f500,52,62,1|phnsvz,52,62,1|phnsw0,50,66,0|po57nz,50,66,0|po57o0,52,62,1|q0dvjz,52,62,1|q0dvk0,50,66,0|q6vabz,50,66,0|q6vac0,52,62,1|qj3y7z,52,62,1|qj3y80,50,66,0|qpybnz,50,66,0|qpybo0,52,62,1|r26zjz,52,62,1|r26zk0,50,66,0|r8oebz,50,66,0|r8oec0,52,62,1|rkx27z,52,62,1|rkx280,50,66,0|rregzz,50,66,0|rreh00,52,62,1|s3n4vz,52,62,1|s3n4w0,50,66,0|sa4jnz,50,66,0|sa4jo0,52,62,1|smd7jz,52,62,1|smd7k0,50,66,0|ssumbz,50,66,0|ssumc0,52,62,1|t53a7z,52,62,1|t53a80,50,66,0|tbkozz,50,66,0|tbkp00,52,62,1|tntcvz,52,62,1|tntcw0,50,66,0|tunqbz,50,66,0|tunqc0,52,62,1|u6we7z,52,62,1|u6we80,50,66,0|uddszz,50,66,0|uddt00,52,62,1|upmgvz,52,62,1|upmgw0,50,66,0|uw3vnz,50,66,0|uw3vo0,52,62,1|v8cjjz,52,62,1|v8cjk0,50,66,0|vetybz,50,66,0|vetyc0,52,62,1|vr2m7z,52,62,1|vr2m80,50,66,0|vxk0zz,50,66,0|vxk100,52,62,1|w9sovz,52,62,1|w9sow0,50,66,0|wgn2bz,50,66,0|wgn2c0,52,62,1|wsvq7z,52,62,1|wsvq80,50,66,0|wzd4zz,50,66,0|wzd500,52,62,1|xblsvz,52,62,1|xblsw0,50,66,0|xi37nz,50,66,0|xi37o0,52,62,1|xubvjz,52,62,1|xubvk0,50,66,0|y0tabz,50,66,0|y0tac0,52,62,1|yd1y7z,52,62,1|yd1y80,50,66,0|yjjczz,50,66,0|yjjd00,52,62,1|yvs0vz,52,62,1|yvs0w0,50,66,0|z29fnz,50,66,0|z29fo0,52,62,1|zei3jz,52,62,1|zei3k0,50,66,0\",\"America/Iqaluit|,60,1,0|-eb6ao0,70,42,1|-cq2tg1,70,42,1|-cq2tg0,71,42,1|-cnp3c1,71,42,1|-cnp3c0,49,63,0|-2g1zg1,49,63,0|-2g1zg0,79,44,1|-26bzg1,79,44,1|-26bzg0,49,63,0|5dw63z,49,63,0|5dw640,62,42,1|5n94nz,62,42,1|5n94o0,49,63,0|5wm8rz,49,63,0|5wm8s0,62,42,1|65z7bz,62,42,1|65z7c0,49,63,0|6fcbfz,49,63,0|6fcbg0,62,42,1|6p28nz,62,42,1|6p28o0,49,63,0|6y2e3z,49,63,0|6y2e40,62,42,1|77sbbz,62,42,1|77sbc0,49,63,0|7h5ffz,49,63,0|7h5fg0,62,42,1|7qidzz,62,42,1|7qie00,49,63,0|7zvi3z,49,63,0|7zvi40,62,42,1|898gnz,62,42,1|898go0,49,63,0|8ilkrz,49,63,0|8ilks0,62,42,1|8ryjbz,62,42,1|8ryjc0,49,63,0|908rfz,49,63,0|908rg0,62,42,1|9aolzz,62,42,1|9aom00,49,63,0|9iyu3z,49,63,0|9iyu40,62,42,1|9trnbz,62,42,1|9trnc0,49,63,0|a1owrz,49,63,0|a1ows0,62,42,1|achpzz,62,42,1|achq00,49,63,0|akezfz,49,63,0|akezg0,62,42,1|av7snz,62,42,1|av7so0,49,63,0|b3i0rz,49,63,0|b3i0s0,62,42,1|bdxvbz,62,42,1|bdxvc0,49,63,0|bm83fz,49,63,0|bm83g0,62,42,1|bwnxzz,62,42,1|bwny00,49,63,0|c4y63z,49,63,0|c4y640,62,42,1|cfqzbz,62,42,1|cfqzc0,49,63,0|cno8rz,49,63,0|cno8s0,62,42,1|cyh1zz,62,42,1|cyh200,49,63,0|d6ebfz,49,63,0|d6ebg0,62,42,1|dh74nz,62,42,1|dh74o0,49,63,0|dphcrz,49,63,0|dphcs0,62,42,1|dzx7bz,62,42,1|dzx7c0,49,63,0|e87ffz,49,63,0|e87fg0,62,42,1|ein9zz,62,42,1|eina00,49,63,0|eqxi3z,49,63,0|eqxi40,62,42,1|f1dcnz,62,42,1|f1dco0,49,63,0|f9nkrz,49,63,0|f9nks0,62,42,1|fkgdzz,62,42,1|fkge00,45,62,0|fsdq7z,45,62,0|fsdq80,46,63,1|g36jfz,46,63,1|g36jg0,49,63,0|gb3q3z,49,63,0|gb3q40,62,42,1|glwjbz,62,42,1|glwjc0,49,63,0|gu6rfz,49,63,0|gu6rg0,62,42,1|h4mlzz,62,42,1|h4mm00,49,63,0|hcwu3z,49,63,0|hcwu40,62,42,1|hnconz,62,42,1|hncoo0,49,63,0|hvmwrz,49,63,0|hvmws0,62,42,1|i6fpzz,62,42,1|i6fq00,49,63,0|ieczfz,49,63,0|ieczg0,62,42,1|ip5snz,62,42,1|ip5so0,49,63,0|ix323z,49,63,0|ix3240,62,42,1|j7vvbz,62,42,1|j7vvc0,49,63,0|jeq8rz,49,63,0|jeq8s0,62,42,1|jqywnz,62,42,1|jqywo0,49,63,0|jxgbfz,49,63,0|jxgbg0,62,42,1|k9ozbz,62,42,1|k9ozc0,49,63,0|kg6e3z,49,63,0|kg6e40,62,42,1|ksf1zz,62,42,1|ksf200,49,63,0|kz9ffz,49,63,0|kz9fg0,62,42,1|lbi3bz,62,42,1|lbi3c0,49,63,0|lhzi3z,49,63,0|lhzi40,62,42,1|lu85zz,62,42,1|lu8600,49,63,0|m0pkrz,49,63,0|m0pks0,62,42,1|mcy8nz,62,42,1|mcy8o0,49,63,0|mjfnfz,49,63,0|mjfng0,62,42,1|mvobbz,62,42,1|mvobc0,49,63,0|n25q3z,49,63,0|n25q40,62,42,1|needzz,62,42,1|neee00,49,63,0|nkvsrz,49,63,0|nkvss0,62,42,1|nx4gnz,62,42,1|nx4go0,49,63,0|o3yu3z,49,63,0|o3yu40,62,42,1|og7hzz,62,42,1|og7i00,49,63,0|omowrz,49,63,0|omows0,62,42,1|oyxknz,62,42,1|oyxko0,49,63,0|p5ezfz,49,63,0|p5ezg0,62,42,1|phnnbz,62,42,1|phnnc0,49,63,0|po523z,49,63,0|po5240,62,42,1|q0dpzz,62,42,1|q0dq00,49,63,0|q6v4rz,49,63,0|q6v4s0,62,42,1|qj3snz,62,42,1|qj3so0,49,63,0|qpy63z,49,63,0|qpy640,62,42,1|r26tzz,62,42,1|r26u00,49,63,0|r8o8rz,49,63,0|r8o8s0,62,42,1|rkwwnz,62,42,1|rkwwo0,49,63,0|rrebfz,49,63,0|rrebg0,62,42,1|s3mzbz,62,42,1|s3mzc0,49,63,0|sa4e3z,49,63,0|sa4e40,62,42,1|smd1zz,62,42,1|smd200,49,63,0|ssugrz,49,63,0|ssugs0,62,42,1|t534nz,62,42,1|t534o0,49,63,0|tbkjfz,49,63,0|tbkjg0,62,42,1|tnt7bz,62,42,1|tnt7c0,49,63,0|tunkrz,49,63,0|tunks0,62,42,1|u6w8nz,62,42,1|u6w8o0,49,63,0|uddnfz,49,63,0|uddng0,62,42,1|upmbbz,62,42,1|upmbc0,49,63,0|uw3q3z,49,63,0|uw3q40,62,42,1|v8cdzz,62,42,1|v8ce00,49,63,0|vetsrz,49,63,0|vetss0,62,42,1|vr2gnz,62,42,1|vr2go0,49,63,0|vxjvfz,49,63,0|vxjvg0,62,42,1|w9sjbz,62,42,1|w9sjc0,49,63,0|wgmwrz,49,63,0|wgmws0,62,42,1|wsvknz,62,42,1|wsvko0,49,63,0|wzczfz,49,63,0|wzczg0,62,42,1|xblnbz,62,42,1|xblnc0,49,63,0|xi323z,49,63,0|xi3240,62,42,1|xubpzz,62,42,1|xubq00,49,63,0|y0t4rz,49,63,0|y0t4s0,62,42,1|yd1snz,62,42,1|yd1so0,49,63,0|yjj7fz,49,63,0|yjj7g0,62,42,1|yvrvbz,62,42,1|yvrvc0,49,63,0|z29a3z,49,63,0|z29a40,62,42,1|zehxzz,62,42,1|zehy00,49,63,0\",\"America/Jamaica|,0,104,0|-15r0v42,74,104,0|-u85og3,74,104,0|-u85og2,49,63,0|23fcrz,49,63,0|23fcs0,62,42,1|2ijpzz,62,42,1|2ijq00,49,63,0|2oo63z,49,63,0|2oo640,62,42,1|319snz,62,42,1|319so0,49,63,0|3amwrz,49,63,0|3amws0,62,42,1|3kctzz,62,42,1|3kcu00,49,63,0|3tczfz,49,63,0|3tczg0,62,42,1|432wnz,62,42,1|432wo0,49,63,0|4cg0rz,49,63,0|4cg0s0,62,42,1|4lszbz,62,42,1|4lszc0,49,63,0|4v63fz,49,63,0|4v63g0,62,42,1|54j1zz,62,42,1|54j200,49,63,0|5dw63z,49,63,0|5dw640,62,42,1|5n94nz,62,42,1|5n94o0,49,63,0|5wm8rz,49,63,0|5wm8s0,62,42,1|65z7bz,62,42,1|65z7c0,49,63,0|6fcbfz,49,63,0|6fcbg0,62,42,1|6p28nz,62,42,1|6p28o0,49,63,0|6y2e3z,49,63,0|6y2e40,62,42,1|77sbbz,62,42,1|77sbc0,49,63,0\",\"America/Juneau|,0,122,0|-1hc7qjz,0,123,0|-1078wfw,0,123,0|-1078wfv,51,40,0|-ek1w81,51,40,0|-ek1w80,68,66,1|-cq2tg1,68,66,1|-cq2tg0,69,66,1|-cnov01,69,66,1|-cnov00,51,40,0|-csc81,51,40,0|-csc80,57,66,1|-3fdo1,57,66,1|-3fdo0,51,40,0|5xqfz,51,40,0|5xqg0,57,66,1|faozz,57,66,1|fap00,51,40,0|ont3z,51,40,0|ont40,57,66,1|ydqbz,57,66,1|ydqc0,51,40,0|17qufz,51,40,0|17qug0,57,66,1|1h3szz,57,66,1|1h3t00,51,40,0|1qgx3z,51,40,0|1qgx40,57,66,1|1ztvnz,57,66,1|1ztvo0,51,40,0|23fl3z,51,40,0|23fl40,57,66,1|2ijybz,57,66,1|2ijyc0,51,40,0|2ooefz,51,40,0|2ooeg0,57,66,1|31a0zz,57,66,1|31a100,51,40,0|3an53z,51,40,0|3an540,57,66,1|3kd2bz,57,66,1|3kd2c0,51,40,0|3td7rz,51,40,0|3td7s0,57,66,1|4334zz,57,66,1|433500,51,40,0|4cg93z,51,40,0|4cg940,57,66,1|4lt7nz,57,66,1|4lt7o0,51,40,0|4v6brz,51,40,0|4v6bs0,57,66,1|54jabz,57,66,1|54jac0,51,40,0|5dwefz,51,40,0|5dweg0,64,40,1|5n9frz,64,40,1|5n9fs0,51,40,0|5wmh3z,51,40,0|5wmh40,57,66,1|65zfnz,57,66,1|65zfo0,51,40,0|6fcjrz,51,40,0|6fcjs0,57,66,1|6p2gzz,57,66,1|6p2h00,51,40,0|6y2mfz,51,40,0|6y2mg0,57,66,1|77sjnz,57,66,1|77sjo0,36,37,0|79dybz,36,37,0|79dyc0,37,37,0|7h5qjz,37,37,0|7h5qk0,38,40,1|7qip3z,38,40,1|7qip40,37,37,0|7zvt7z,37,37,0|7zvt80,38,40,1|898rrz,38,40,1|898rs0,37,37,0|8ilvvz,37,37,0|8ilvw0,38,40,1|8ryufz,38,40,1|8ryug0,37,37,0|9092jz,37,37,0|9092k0,38,40,1|9aox3z,38,40,1|9aox40,37,37,0|9iz57z,37,37,0|9iz580,38,40,1|9tryfz,38,40,1|9tryg0,37,37,0|a1p7vz,37,37,0|a1p7w0,38,40,1|aci13z,38,40,1|aci140,37,37,0|akfajz,37,37,0|akfak0,38,40,1|av83rz,38,40,1|av83s0,37,37,0|b3ibvz,37,37,0|b3ibw0,38,40,1|bdy6fz,38,40,1|bdy6g0,37,37,0|bm8ejz,37,37,0|bm8ek0,38,40,1|bwo93z,38,40,1|bwo940,37,37,0|c4yh7z,37,37,0|c4yh80,38,40,1|cfrafz,38,40,1|cfrag0,37,37,0|cnojvz,37,37,0|cnojw0,38,40,1|cyhd3z,38,40,1|cyhd40,37,37,0|d6emjz,37,37,0|d6emk0,38,40,1|dh7frz,38,40,1|dh7fs0,37,37,0|dphnvz,37,37,0|dphnw0,38,40,1|dzxifz,38,40,1|dzxig0,37,37,0|e87qjz,37,37,0|e87qk0,38,40,1|einl3z,38,40,1|einl40,37,37,0|eqxt7z,37,37,0|eqxt80,38,40,1|f1dnrz,38,40,1|f1dns0,37,37,0|f9nvvz,37,37,0|f9nvw0,38,40,1|fkgp3z,38,40,1|fkgp40,37,37,0|fsdyjz,37,37,0|fsdyk0,38,40,1|g36rrz,38,40,1|g36rs0,37,37,0|gb417z,37,37,0|gb4180,38,40,1|glwufz,38,40,1|glwug0,37,37,0|gu72jz,37,37,0|gu72k0,38,40,1|h4mx3z,38,40,1|h4mx40,37,37,0|hcx57z,37,37,0|hcx580,38,40,1|hnczrz,38,40,1|hnczs0,37,37,0|hvn7vz,37,37,0|hvn7w0,38,40,1|i6g13z,38,40,1|i6g140,37,37,0|iedajz,37,37,0|iedak0,38,40,1|ip63rz,38,40,1|ip63s0,37,37,0|ix3d7z,37,37,0|ix3d80,38,40,1|j7w6fz,38,40,1|j7w6g0,37,37,0|jeqjvz,37,37,0|jeqjw0,38,40,1|jqz7rz,38,40,1|jqz7s0,37,37,0|jxgmjz,37,37,0|jxgmk0,38,40,1|k9pafz,38,40,1|k9pag0,37,37,0|kg6p7z,37,37,0|kg6p80,38,40,1|ksfd3z,38,40,1|ksfd40,37,37,0|kz9qjz,37,37,0|kz9qk0,38,40,1|lbiefz,38,40,1|lbieg0,37,37,0|lhzt7z,37,37,0|lhzt80,38,40,1|lu8h3z,38,40,1|lu8h40,37,37,0|m0pvvz,37,37,0|m0pvw0,38,40,1|mcyjrz,38,40,1|mcyjs0,37,37,0|mjfyjz,37,37,0|mjfyk0,38,40,1|mvomfz,38,40,1|mvomg0,37,37,0|n2617z,37,37,0|n26180,38,40,1|neep3z,38,40,1|neep40,37,37,0|nkw3vz,37,37,0|nkw3w0,38,40,1|nx4rrz,38,40,1|nx4rs0,37,37,0|o3z57z,37,37,0|o3z580,38,40,1|og7t3z,38,40,1|og7t40,37,37,0|omp7vz,37,37,0|omp7w0,38,40,1|oyxvrz,38,40,1|oyxvs0,37,37,0|p5fajz,37,37,0|p5fak0,38,40,1|phnyfz,38,40,1|phnyg0,37,37,0|po5d7z,37,37,0|po5d80,38,40,1|q0e13z,38,40,1|q0e140,37,37,0|q6vfvz,37,37,0|q6vfw0,38,40,1|qj43rz,38,40,1|qj43s0,37,37,0|qpyh7z,37,37,0|qpyh80,38,40,1|r2753z,38,40,1|r27540,37,37,0|r8ojvz,37,37,0|r8ojw0,38,40,1|rkx7rz,38,40,1|rkx7s0,37,37,0|rremjz,37,37,0|rremk0,38,40,1|s3nafz,38,40,1|s3nag0,37,37,0|sa4p7z,37,37,0|sa4p80,38,40,1|smdd3z,38,40,1|smdd40,37,37,0|ssurvz,37,37,0|ssurw0,38,40,1|t53frz,38,40,1|t53fs0,37,37,0|tbkujz,37,37,0|tbkuk0,38,40,1|tntifz,38,40,1|tntig0,37,37,0|tunvvz,37,37,0|tunvw0,38,40,1|u6wjrz,38,40,1|u6wjs0,37,37,0|uddyjz,37,37,0|uddyk0,38,40,1|upmmfz,38,40,1|upmmg0,37,37,0|uw417z,37,37,0|uw4180,38,40,1|v8cp3z,38,40,1|v8cp40,37,37,0|veu3vz,37,37,0|veu3w0,38,40,1|vr2rrz,38,40,1|vr2rs0,37,37,0|vxk6jz,37,37,0|vxk6k0,38,40,1|w9sufz,38,40,1|w9sug0,37,37,0|wgn7vz,37,37,0|wgn7w0,38,40,1|wsvvrz,38,40,1|wsvvs0,37,37,0|wzdajz,37,37,0|wzdak0,38,40,1|xblyfz,38,40,1|xblyg0,37,37,0|xi3d7z,37,37,0|xi3d80,38,40,1|xuc13z,38,40,1|xuc140,37,37,0|y0tfvz,37,37,0|y0tfw0,38,40,1|yd23rz,38,40,1|yd23s0,37,37,0|yjjijz,37,37,0|yjjik0,38,40,1|yvs6fz,38,40,1|yvs6g0,37,37,0|z29l7z,37,37,0|z29l80,38,40,1|zei93z,38,40,1|zei940,37,37,0\",\"America/Kentucky/Louisville|,0,124,0|-18y0m00,45,62,0|-r0esg1,45,62,0|-r0esg0,46,63,1|-qplz81,46,63,1|-qplz80,45,62,0|-qhops1,45,62,0|-qhops0,46,63,1|-q6vwk1,46,63,1|-q6vwk0,45,62,0|-pefr41,45,62,0|-pefr40,46,63,1|-p841w1,46,63,1|-p841w0,45,62,0|-eyvds1,45,62,0|-eyvds0,46,63,1|-eqy9w1,46,63,1|-eqy9w0,45,62,0|-ek21s1,45,62,0|-ek21s0,47,63,1|-cq2tg1,47,63,1|-cq2tg0,48,63,1|-cnp0k1,48,63,1|-cnp0k0,45,62,0|-ccw7ad,45,62,0|-ccw7ac,46,63,1|-cb3b81,46,63,1|-cb3b80,45,62,0|-a9msg1,45,62,0|-a9msg0,46,63,1|-a22n81,46,63,1|-a22n80,45,62,0|-9qwps1,45,62,0|-9qwps0,46,63,1|-9izlw1,46,63,1|-9izlw0,45,62,0|-986n41,45,62,0|-986n40,46,63,1|-909j81,46,63,1|-909j80,45,62,0|-8pgkg1,45,62,0|-8pgkg0,46,63,1|-8hjgk1,46,63,1|-8hjgk0,45,62,0|-86qhs1,45,62,0|-86qhs0,46,63,1|-7ytdw1,46,63,1|-7ytdw0,45,62,0|-7o0f41,45,62,0|-7o0f40,46,63,1|-7g3b81,46,63,1|-7g3b80,45,62,0|-74xds1,45,62,0|-74xds0,46,63,1|-6vkf81,46,63,1|-6vkf80,45,62,0|-6m7b41,45,62,0|-6m7b40,46,63,1|-6cuck1,46,63,1|-6cuck0,45,62,0|-63h8g1,45,62,0|-63h8g0,46,63,1|-5u49w1,46,63,1|-5u49w0,45,62,0|-5kr5s1,45,62,0|-5kr5s0,46,63,1|-5be781,46,63,1|-5be780,45,62,0|-521341,45,62,0|-521340,46,63,1|-4sb5w1,46,63,1|-4sb5w0,45,62,0|-4iy1s1,45,62,0|-4iy1s0,46,63,1|-4emkk1,46,63,1|-4emkk0,49,63,0|-vin81,49,63,0|-vin80,62,42,1|-m5oo1,62,42,1|-m5oo0,49,63,0|-cskk1,49,63,0|-cskk0,62,42,1|-3fm01,62,42,1|-3fm00,49,63,0|5xi3z,49,63,0|5xi40,62,42,1|fagnz,62,42,1|fago0,49,63,0|onkrz,49,63,0|onks0,62,42,1|ydhzz,62,42,1|ydi00,49,63,0|17qm3z,49,63,0|17qm40,62,42,1|1h3knz,62,42,1|1h3ko0,49,63,0|1qgorz,49,63,0|1qgos0,62,42,1|1ztnbz,62,42,1|1ztnc0,49,63,0|23fcrz,49,63,0|23fcs0,46,63,1|2ijsrz,46,63,1|2ijss0,49,63,0|2oo63z,49,63,0|2oo640,62,42,1|319snz,62,42,1|319so0,49,63,0|3amwrz,49,63,0|3amws0,62,42,1|3kctzz,62,42,1|3kcu00,49,63,0|3tczfz,49,63,0|3tczg0,62,42,1|432wnz,62,42,1|432wo0,49,63,0|4cg0rz,49,63,0|4cg0s0,62,42,1|4lszbz,62,42,1|4lszc0,49,63,0|4v63fz,49,63,0|4v63g0,62,42,1|54j1zz,62,42,1|54j200,49,63,0|5dw63z,49,63,0|5dw640,62,42,1|5n94nz,62,42,1|5n94o0,49,63,0|5wm8rz,49,63,0|5wm8s0,62,42,1|65z7bz,62,42,1|65z7c0,49,63,0|6fcbfz,49,63,0|6fcbg0,62,42,1|6p28nz,62,42,1|6p28o0,49,63,0|6y2e3z,49,63,0|6y2e40,62,42,1|77sbbz,62,42,1|77sbc0,49,63,0|7h5ffz,49,63,0|7h5fg0,62,42,1|7qidzz,62,42,1|7qie00,49,63,0|7zvi3z,49,63,0|7zvi40,62,42,1|898gnz,62,42,1|898go0,49,63,0|8ilkrz,49,63,0|8ilks0,62,42,1|8ryjbz,62,42,1|8ryjc0,49,63,0|908rfz,49,63,0|908rg0,62,42,1|9aolzz,62,42,1|9aom00,49,63,0|9iyu3z,49,63,0|9iyu40,62,42,1|9trnbz,62,42,1|9trnc0,49,63,0|a1owrz,49,63,0|a1ows0,62,42,1|achpzz,62,42,1|achq00,49,63,0|akezfz,49,63,0|akezg0,62,42,1|av7snz,62,42,1|av7so0,49,63,0|b3i0rz,49,63,0|b3i0s0,62,42,1|bdxvbz,62,42,1|bdxvc0,49,63,0|bm83fz,49,63,0|bm83g0,62,42,1|bwnxzz,62,42,1|bwny00,49,63,0|c4y63z,49,63,0|c4y640,62,42,1|cfqzbz,62,42,1|cfqzc0,49,63,0|cno8rz,49,63,0|cno8s0,62,42,1|cyh1zz,62,42,1|cyh200,49,63,0|d6ebfz,49,63,0|d6ebg0,62,42,1|dh74nz,62,42,1|dh74o0,49,63,0|dphcrz,49,63,0|dphcs0,62,42,1|dzx7bz,62,42,1|dzx7c0,49,63,0|e87ffz,49,63,0|e87fg0,62,42,1|ein9zz,62,42,1|eina00,49,63,0|eqxi3z,49,63,0|eqxi40,62,42,1|f1dcnz,62,42,1|f1dco0,49,63,0|f9nkrz,49,63,0|f9nks0,62,42,1|fkgdzz,62,42,1|fkge00,49,63,0|fsdnfz,49,63,0|fsdng0,62,42,1|g36gnz,62,42,1|g36go0,49,63,0|gb3q3z,49,63,0|gb3q40,62,42,1|glwjbz,62,42,1|glwjc0,49,63,0|gu6rfz,49,63,0|gu6rg0,62,42,1|h4mlzz,62,42,1|h4mm00,49,63,0|hcwu3z,49,63,0|hcwu40,62,42,1|hnconz,62,42,1|hncoo0,49,63,0|hvmwrz,49,63,0|hvmws0,62,42,1|i6fpzz,62,42,1|i6fq00,49,63,0|ieczfz,49,63,0|ieczg0,62,42,1|ip5snz,62,42,1|ip5so0,49,63,0|ix323z,49,63,0|ix3240,62,42,1|j7vvbz,62,42,1|j7vvc0,49,63,0|jeq8rz,49,63,0|jeq8s0,62,42,1|jqywnz,62,42,1|jqywo0,49,63,0|jxgbfz,49,63,0|jxgbg0,62,42,1|k9ozbz,62,42,1|k9ozc0,49,63,0|kg6e3z,49,63,0|kg6e40,62,42,1|ksf1zz,62,42,1|ksf200,49,63,0|kz9ffz,49,63,0|kz9fg0,62,42,1|lbi3bz,62,42,1|lbi3c0,49,63,0|lhzi3z,49,63,0|lhzi40,62,42,1|lu85zz,62,42,1|lu8600,49,63,0|m0pkrz,49,63,0|m0pks0,62,42,1|mcy8nz,62,42,1|mcy8o0,49,63,0|mjfnfz,49,63,0|mjfng0,62,42,1|mvobbz,62,42,1|mvobc0,49,63,0|n25q3z,49,63,0|n25q40,62,42,1|needzz,62,42,1|neee00,49,63,0|nkvsrz,49,63,0|nkvss0,62,42,1|nx4gnz,62,42,1|nx4go0,49,63,0|o3yu3z,49,63,0|o3yu40,62,42,1|og7hzz,62,42,1|og7i00,49,63,0|omowrz,49,63,0|omows0,62,42,1|oyxknz,62,42,1|oyxko0,49,63,0|p5ezfz,49,63,0|p5ezg0,62,42,1|phnnbz,62,42,1|phnnc0,49,63,0|po523z,49,63,0|po5240,62,42,1|q0dpzz,62,42,1|q0dq00,49,63,0|q6v4rz,49,63,0|q6v4s0,62,42,1|qj3snz,62,42,1|qj3so0,49,63,0|qpy63z,49,63,0|qpy640,62,42,1|r26tzz,62,42,1|r26u00,49,63,0|r8o8rz,49,63,0|r8o8s0,62,42,1|rkwwnz,62,42,1|rkwwo0,49,63,0|rrebfz,49,63,0|rrebg0,62,42,1|s3mzbz,62,42,1|s3mzc0,49,63,0|sa4e3z,49,63,0|sa4e40,62,42,1|smd1zz,62,42,1|smd200,49,63,0|ssugrz,49,63,0|ssugs0,62,42,1|t534nz,62,42,1|t534o0,49,63,0|tbkjfz,49,63,0|tbkjg0,62,42,1|tnt7bz,62,42,1|tnt7c0,49,63,0|tunkrz,49,63,0|tunks0,62,42,1|u6w8nz,62,42,1|u6w8o0,49,63,0|uddnfz,49,63,0|uddng0,62,42,1|upmbbz,62,42,1|upmbc0,49,63,0|uw3q3z,49,63,0|uw3q40,62,42,1|v8cdzz,62,42,1|v8ce00,49,63,0|vetsrz,49,63,0|vetss0,62,42,1|vr2gnz,62,42,1|vr2go0,49,63,0|vxjvfz,49,63,0|vxjvg0,62,42,1|w9sjbz,62,42,1|w9sjc0,49,63,0|wgmwrz,49,63,0|wgmws0,62,42,1|wsvknz,62,42,1|wsvko0,49,63,0|wzczfz,49,63,0|wzczg0,62,42,1|xblnbz,62,42,1|xblnc0,49,63,0|xi323z,49,63,0|xi3240,62,42,1|xubpzz,62,42,1|xubq00,49,63,0|y0t4rz,49,63,0|y0t4s0,62,42,1|yd1snz,62,42,1|yd1so0,49,63,0|yjj7fz,49,63,0|yjj7g0,62,42,1|yvrvbz,62,42,1|yvrvc0,49,63,0|z29a3z,49,63,0|z29a40,62,42,1|zehxzz,62,42,1|zehy00,49,63,0\",\"America/Kentucky/Monticello|,0,125,0|-18y0m00,45,62,0|-r0esg1,45,62,0|-r0esg0,46,63,1|-qplz81,46,63,1|-qplz80,45,62,0|-qhops1,45,62,0|-qhops0,46,63,1|-q6vwk1,46,63,1|-q6vwk0,45,62,0|-ek21s1,45,62,0|-ek21s0,47,63,1|-cq2tg1,47,63,1|-cq2tg0,48,63,1|-cnp0k1,48,63,1|-cnp0k0,45,62,0|-vikg1,45,62,0|-vikg0,46,63,1|-m5lw1,46,63,1|-m5lw0,45,62,0|-cshs1,45,62,0|-cshs0,46,63,1|-3fj81,46,63,1|-3fj80,45,62,0|5xkvz,45,62,0|5xkw0,46,63,1|fajfz,46,63,1|fajg0,45,62,0|onnjz,45,62,0|onnk0,46,63,1|ydkrz,46,63,1|ydks0,45,62,0|17qovz,45,62,0|17qow0,46,63,1|1h3nfz,46,63,1|1h3ng0,45,62,0|1qgrjz,45,62,0|1qgrk0,46,63,1|1ztq3z,46,63,1|1ztq40,45,62,0|23ffjz,45,62,0|23ffk0,46,63,1|2ijsrz,46,63,1|2ijss0,45,62,0|2oo8vz,45,62,0|2oo8w0,46,63,1|319vfz,46,63,1|319vg0,45,62,0|3amzjz,45,62,0|3amzk0,46,63,1|3kcwrz,46,63,1|3kcws0,45,62,0|3td27z,45,62,0|3td280,46,63,1|432zfz,46,63,1|432zg0,45,62,0|4cg3jz,45,62,0|4cg3k0,46,63,1|4lt23z,46,63,1|4lt240,45,62,0|4v667z,45,62,0|4v6680,46,63,1|54j4rz,46,63,1|54j4s0,45,62,0|5dw8vz,45,62,0|5dw8w0,46,63,1|5n97fz,46,63,1|5n97g0,45,62,0|5wmbjz,45,62,0|5wmbk0,46,63,1|65za3z,46,63,1|65za40,45,62,0|6fce7z,45,62,0|6fce80,46,63,1|6p2bfz,46,63,1|6p2bg0,45,62,0|6y2gvz,45,62,0|6y2gw0,46,63,1|77se3z,46,63,1|77se40,45,62,0|7h5i7z,45,62,0|7h5i80,46,63,1|7qigrz,46,63,1|7qigs0,45,62,0|7zvkvz,45,62,0|7zvkw0,46,63,1|898jfz,46,63,1|898jg0,45,62,0|8ilnjz,45,62,0|8ilnk0,46,63,1|8rym3z,46,63,1|8rym40,45,62,0|908u7z,45,62,0|908u80,46,63,1|9aoorz,46,63,1|9aoos0,45,62,0|9iywvz,45,62,0|9iyww0,46,63,1|9trq3z,46,63,1|9trq40,45,62,0|a1ozjz,45,62,0|a1ozk0,46,63,1|achsrz,46,63,1|achss0,45,62,0|akf27z,45,62,0|akf280,46,63,1|av7vfz,46,63,1|av7vg0,45,62,0|b3i3jz,45,62,0|b3i3k0,46,63,1|bdxy3z,46,63,1|bdxy40,45,62,0|bm867z,45,62,0|bm8680,46,63,1|bwo0rz,46,63,1|bwo0s0,45,62,0|c4y8vz,45,62,0|c4y8w0,46,63,1|cfr23z,46,63,1|cfr240,45,62,0|cnobjz,45,62,0|cnobk0,46,63,1|cyh4rz,46,63,1|cyh4s0,45,62,0|d6ee7z,45,62,0|d6ee80,46,63,1|dh77fz,46,63,1|dh77g0,45,62,0|dphfjz,45,62,0|dphfk0,46,63,1|dzxa3z,46,63,1|dzxa40,45,62,0|e87i7z,45,62,0|e87i80,46,63,1|eincrz,46,63,1|eincs0,45,62,0|eqxkvz,45,62,0|eqxkw0,46,63,1|f1dffz,46,63,1|f1dfg0,45,62,0|f9nnjz,45,62,0|f9nnk0,46,63,1|fkggrz,46,63,1|fkggs0,45,62,0|fsdq7z,45,62,0|fsdq80,46,63,1|g36jfz,46,63,1|g36jg0,49,63,0|gb3q3z,49,63,0|gb3q40,62,42,1|glwjbz,62,42,1|glwjc0,49,63,0|gu6rfz,49,63,0|gu6rg0,62,42,1|h4mlzz,62,42,1|h4mm00,49,63,0|hcwu3z,49,63,0|hcwu40,62,42,1|hnconz,62,42,1|hncoo0,49,63,0|hvmwrz,49,63,0|hvmws0,62,42,1|i6fpzz,62,42,1|i6fq00,49,63,0|ieczfz,49,63,0|ieczg0,62,42,1|ip5snz,62,42,1|ip5so0,49,63,0|ix323z,49,63,0|ix3240,62,42,1|j7vvbz,62,42,1|j7vvc0,49,63,0|jeq8rz,49,63,0|jeq8s0,62,42,1|jqywnz,62,42,1|jqywo0,49,63,0|jxgbfz,49,63,0|jxgbg0,62,42,1|k9ozbz,62,42,1|k9ozc0,49,63,0|kg6e3z,49,63,0|kg6e40,62,42,1|ksf1zz,62,42,1|ksf200,49,63,0|kz9ffz,49,63,0|kz9fg0,62,42,1|lbi3bz,62,42,1|lbi3c0,49,63,0|lhzi3z,49,63,0|lhzi40,62,42,1|lu85zz,62,42,1|lu8600,49,63,0|m0pkrz,49,63,0|m0pks0,62,42,1|mcy8nz,62,42,1|mcy8o0,49,63,0|mjfnfz,49,63,0|mjfng0,62,42,1|mvobbz,62,42,1|mvobc0,49,63,0|n25q3z,49,63,0|n25q40,62,42,1|needzz,62,42,1|neee00,49,63,0|nkvsrz,49,63,0|nkvss0,62,42,1|nx4gnz,62,42,1|nx4go0,49,63,0|o3yu3z,49,63,0|o3yu40,62,42,1|og7hzz,62,42,1|og7i00,49,63,0|omowrz,49,63,0|omows0,62,42,1|oyxknz,62,42,1|oyxko0,49,63,0|p5ezfz,49,63,0|p5ezg0,62,42,1|phnnbz,62,42,1|phnnc0,49,63,0|po523z,49,63,0|po5240,62,42,1|q0dpzz,62,42,1|q0dq00,49,63,0|q6v4rz,49,63,0|q6v4s0,62,42,1|qj3snz,62,42,1|qj3so0,49,63,0|qpy63z,49,63,0|qpy640,62,42,1|r26tzz,62,42,1|r26u00,49,63,0|r8o8rz,49,63,0|r8o8s0,62,42,1|rkwwnz,62,42,1|rkwwo0,49,63,0|rrebfz,49,63,0|rrebg0,62,42,1|s3mzbz,62,42,1|s3mzc0,49,63,0|sa4e3z,49,63,0|sa4e40,62,42,1|smd1zz,62,42,1|smd200,49,63,0|ssugrz,49,63,0|ssugs0,62,42,1|t534nz,62,42,1|t534o0,49,63,0|tbkjfz,49,63,0|tbkjg0,62,42,1|tnt7bz,62,42,1|tnt7c0,49,63,0|tunkrz,49,63,0|tunks0,62,42,1|u6w8nz,62,42,1|u6w8o0,49,63,0|uddnfz,49,63,0|uddng0,62,42,1|upmbbz,62,42,1|upmbc0,49,63,0|uw3q3z,49,63,0|uw3q40,62,42,1|v8cdzz,62,42,1|v8ce00,49,63,0|vetsrz,49,63,0|vetss0,62,42,1|vr2gnz,62,42,1|vr2go0,49,63,0|vxjvfz,49,63,0|vxjvg0,62,42,1|w9sjbz,62,42,1|w9sjc0,49,63,0|wgmwrz,49,63,0|wgmws0,62,42,1|wsvknz,62,42,1|wsvko0,49,63,0|wzczfz,49,63,0|wzczg0,62,42,1|xblnbz,62,42,1|xblnc0,49,63,0|xi323z,49,63,0|xi3240,62,42,1|xubpzz,62,42,1|xubq00,49,63,0|y0t4rz,49,63,0|y0t4s0,62,42,1|yd1snz,62,42,1|yd1so0,49,63,0|yjj7fz,49,63,0|yjj7g0,62,42,1|yvrvbz,62,42,1|yvrvc0,49,63,0|z29a3z,49,63,0|z29a40,62,42,1|zehxzz,62,42,1|zehy00,49,63,0\",\"America/Kralendijk|,0,58,0|-u7lckd,43,59,0|-2lx4u1,43,59,0|-2lx4u0,32,42,0\",\"America/La_Paz|,0,126,0|-15r0wpo,41,126,0|-jxzspp,41,126,0|-jxzspo,27,127,1|-jpva5p,27,127,1|-jpva5o,42,42,0\",\"America/Lima|,0,128,0|-15r0v2c,0,129,0|-w25lpp,0,129,0|-w25lpo,56,63,0|-gp8241,56,63,0|-gp8240,42,42,1|-gklgw1,42,42,1|-gklgw0,56,63,0|-gbhm41,56,63,0|-gbhm40,42,42,1|-g24nk1,42,42,1|-g24nk0,56,63,0|-fsrjg1,56,63,0|-fsrjg0,42,42,1|-fjekw1,42,42,1|-fjekw0,56,63,0|8cmlvz,56,63,0|8cmlw0,42,42,1|8h973z,42,42,1|8h9740,56,63,0|8vej7z,56,63,0|8vej80,42,42,1|9014fz,42,42,1|9014g0,56,63,0|afs5vz,56,63,0|afs5w0,42,42,1|aker3z,42,42,1|aker40,56,63,0|cixpvz,56,63,0|cixpw0,42,42,1|cnkb3z,42,42,1|cnkb40,56,63,0\",\"America/Los_Angeles|,0,130,0|-18y0gg0,51,40,0|-r0emw1,51,40,0|-r0emw0,57,66,1|-qplto1,57,66,1|-qplto0,51,40,0|-qhok81,51,40,0|-qhok80,57,66,1|-q6vr01,57,66,1|-q6vr00,51,40,0|-ek1w81,51,40,0|-ek1w80,68,66,1|-cq2tg1,68,66,1|-cq2tg0,69,66,1|-cnov01,69,66,1|-cnov00,51,40,0|-bdliud,51,40,0|-bdliuc,57,66,1|-ayj0c1,57,66,1|-ayj0c0,51,40,0|-a9mpo1,51,40,0|-a9mpo0,57,66,1|-a22ho1,57,66,1|-a22ho0,51,40,0|-9qwn01,51,40,0|-9qwn00,57,66,1|-9izgc1,57,66,1|-9izgc0,51,40,0|-986kc1,51,40,0|-986kc0,57,66,1|-909do1,57,66,1|-909do0,51,40,0|-8pgho1,51,40,0|-8pgho0,57,66,1|-8hjb01,57,66,1|-8hjb00,51,40,0|-86qf01,51,40,0|-86qf00,57,66,1|-7yt8c1,57,66,1|-7yt8c0,51,40,0|-7o0cc1,51,40,0|-7o0cc0,57,66,1|-7g35o1,57,66,1|-7g35o0,51,40,0|-74xb01,51,40,0|-74xb00,57,66,1|-6x04c1,57,66,1|-6x04c0,51,40,0|-6m78c1,51,40,0|-6m78c0,57,66,1|-6ea1o1,57,66,1|-6ea1o0,51,40,0|-63h5o1,51,40,0|-63h5o0,57,66,1|-5vjz01,57,66,1|-5vjz00,51,40,0|-5kr301,51,40,0|-5kr300,57,66,1|-5ctwc1,57,66,1|-5ctwc0,51,40,0|-5210c1,51,40,0|-5210c0,57,66,1|-4u3to1,57,66,1|-4u3to0,51,40,0|-4ixz01,51,40,0|-4ixz00,57,66,1|-4bdr01,57,66,1|-4bdr00,51,40,0|-407wc1,51,40,0|-407wc0,57,66,1|-3quv01,57,66,1|-3quv00,51,40,0|-3hhto1,51,40,0|-3hhto0,57,66,1|-384sc1,57,66,1|-384sc0,51,40,0|-2yrr01,51,40,0|-2yrr00,57,66,1|-2pepo1,57,66,1|-2pepo0,51,40,0|-2g1oc1,51,40,0|-2g1oc0,57,66,1|-26boc1,57,66,1|-26boc0,51,40,0|-1xblo1,51,40,0|-1xblo0,57,66,1|-1nllo1,57,66,1|-1nllo0,51,40,0|-1e8hk1,51,40,0|-1e8hk0,57,66,1|-14vj01,57,66,1|-14vj00,51,40,0|-view1,51,40,0|-view0,57,66,1|-m5gc1,57,66,1|-m5gc0,51,40,0|-csc81,51,40,0|-csc80,57,66,1|-3fdo1,57,66,1|-3fdo0,51,40,0|5xqfz,51,40,0|5xqg0,57,66,1|faozz,57,66,1|fap00,51,40,0|ont3z,51,40,0|ont40,57,66,1|ydqbz,57,66,1|ydqc0,51,40,0|17qufz,51,40,0|17qug0,57,66,1|1h3szz,57,66,1|1h3t00,51,40,0|1qgx3z,51,40,0|1qgx40,57,66,1|1ztvnz,57,66,1|1ztvo0,51,40,0|23fl3z,51,40,0|23fl40,57,66,1|2ijybz,57,66,1|2ijyc0,51,40,0|2ooefz,51,40,0|2ooeg0,57,66,1|31a0zz,57,66,1|31a100,51,40,0|3an53z,51,40,0|3an540,57,66,1|3kd2bz,57,66,1|3kd2c0,51,40,0|3td7rz,51,40,0|3td7s0,57,66,1|4334zz,57,66,1|433500,51,40,0|4cg93z,51,40,0|4cg940,57,66,1|4lt7nz,57,66,1|4lt7o0,51,40,0|4v6brz,51,40,0|4v6bs0,57,66,1|54jabz,57,66,1|54jac0,51,40,0|5dwefz,51,40,0|5dweg0,57,66,1|5n9czz,57,66,1|5n9d00,51,40,0|5wmh3z,51,40,0|5wmh40,57,66,1|65zfnz,57,66,1|65zfo0,51,40,0|6fcjrz,51,40,0|6fcjs0,57,66,1|6p2gzz,57,66,1|6p2h00,51,40,0|6y2mfz,51,40,0|6y2mg0,57,66,1|77sjnz,57,66,1|77sjo0,51,40,0|7h5nrz,51,40,0|7h5ns0,57,66,1|7qimbz,57,66,1|7qimc0,51,40,0|7zvqfz,51,40,0|7zvqg0,57,66,1|898ozz,57,66,1|898p00,51,40,0|8ilt3z,51,40,0|8ilt40,57,66,1|8ryrnz,57,66,1|8ryro0,51,40,0|908zrz,51,40,0|908zs0,57,66,1|9aoubz,57,66,1|9aouc0,51,40,0|9iz2fz,51,40,0|9iz2g0,57,66,1|9trvnz,57,66,1|9trvo0,51,40,0|a1p53z,51,40,0|a1p540,57,66,1|achybz,57,66,1|achyc0,51,40,0|akf7rz,51,40,0|akf7s0,57,66,1|av80zz,57,66,1|av8100,51,40,0|b3i93z,51,40,0|b3i940,57,66,1|bdy3nz,57,66,1|bdy3o0,51,40,0|bm8brz,51,40,0|bm8bs0,57,66,1|bwo6bz,57,66,1|bwo6c0,51,40,0|c4yefz,51,40,0|c4yeg0,57,66,1|cfr7nz,57,66,1|cfr7o0,51,40,0|cnoh3z,51,40,0|cnoh40,57,66,1|cyhabz,57,66,1|cyhac0,51,40,0|d6ejrz,51,40,0|d6ejs0,57,66,1|dh7czz,57,66,1|dh7d00,51,40,0|dphl3z,51,40,0|dphl40,57,66,1|dzxfnz,57,66,1|dzxfo0,51,40,0|e87nrz,51,40,0|e87ns0,57,66,1|einibz,57,66,1|einic0,51,40,0|eqxqfz,51,40,0|eqxqg0,57,66,1|f1dkzz,57,66,1|f1dl00,51,40,0|f9nt3z,51,40,0|f9nt40,57,66,1|fkgmbz,57,66,1|fkgmc0,51,40,0|fsdvrz,51,40,0|fsdvs0,57,66,1|g36ozz,57,66,1|g36p00,51,40,0|gb3yfz,51,40,0|gb3yg0,57,66,1|glwrnz,57,66,1|glwro0,51,40,0|gu6zrz,51,40,0|gu6zs0,57,66,1|h4mubz,57,66,1|h4muc0,51,40,0|hcx2fz,51,40,0|hcx2g0,57,66,1|hncwzz,57,66,1|hncx00,51,40,0|hvn53z,51,40,0|hvn540,57,66,1|i6fybz,57,66,1|i6fyc0,51,40,0|ied7rz,51,40,0|ied7s0,57,66,1|ip60zz,57,66,1|ip6100,51,40,0|ix3afz,51,40,0|ix3ag0,57,66,1|j7w3nz,57,66,1|j7w3o0,51,40,0|jeqh3z,51,40,0|jeqh40,57,66,1|jqz4zz,57,66,1|jqz500,51,40,0|jxgjrz,51,40,0|jxgjs0,57,66,1|k9p7nz,57,66,1|k9p7o0,51,40,0|kg6mfz,51,40,0|kg6mg0,57,66,1|ksfabz,57,66,1|ksfac0,51,40,0|kz9nrz,51,40,0|kz9ns0,57,66,1|lbibnz,57,66,1|lbibo0,51,40,0|lhzqfz,51,40,0|lhzqg0,57,66,1|lu8ebz,57,66,1|lu8ec0,51,40,0|m0pt3z,51,40,0|m0pt40,57,66,1|mcygzz,57,66,1|mcyh00,51,40,0|mjfvrz,51,40,0|mjfvs0,57,66,1|mvojnz,57,66,1|mvojo0,51,40,0|n25yfz,51,40,0|n25yg0,57,66,1|neembz,57,66,1|neemc0,51,40,0|nkw13z,51,40,0|nkw140,57,66,1|nx4ozz,57,66,1|nx4p00,51,40,0|o3z2fz,51,40,0|o3z2g0,57,66,1|og7qbz,57,66,1|og7qc0,51,40,0|omp53z,51,40,0|omp540,57,66,1|oyxszz,57,66,1|oyxt00,51,40,0|p5f7rz,51,40,0|p5f7s0,57,66,1|phnvnz,57,66,1|phnvo0,51,40,0|po5afz,51,40,0|po5ag0,57,66,1|q0dybz,57,66,1|q0dyc0,51,40,0|q6vd3z,51,40,0|q6vd40,57,66,1|qj40zz,57,66,1|qj4100,51,40,0|qpyefz,51,40,0|qpyeg0,57,66,1|r272bz,57,66,1|r272c0,51,40,0|r8oh3z,51,40,0|r8oh40,57,66,1|rkx4zz,57,66,1|rkx500,51,40,0|rrejrz,51,40,0|rrejs0,57,66,1|s3n7nz,57,66,1|s3n7o0,51,40,0|sa4mfz,51,40,0|sa4mg0,57,66,1|smdabz,57,66,1|smdac0,51,40,0|ssup3z,51,40,0|ssup40,57,66,1|t53czz,57,66,1|t53d00,51,40,0|tbkrrz,51,40,0|tbkrs0,57,66,1|tntfnz,57,66,1|tntfo0,51,40,0|tunt3z,51,40,0|tunt40,57,66,1|u6wgzz,57,66,1|u6wh00,51,40,0|uddvrz,51,40,0|uddvs0,57,66,1|upmjnz,57,66,1|upmjo0,51,40,0|uw3yfz,51,40,0|uw3yg0,57,66,1|v8cmbz,57,66,1|v8cmc0,51,40,0|veu13z,51,40,0|veu140,57,66,1|vr2ozz,57,66,1|vr2p00,51,40,0|vxk3rz,51,40,0|vxk3s0,57,66,1|w9srnz,57,66,1|w9sro0,51,40,0|wgn53z,51,40,0|wgn540,57,66,1|wsvszz,57,66,1|wsvt00,51,40,0|wzd7rz,51,40,0|wzd7s0,57,66,1|xblvnz,57,66,1|xblvo0,51,40,0|xi3afz,51,40,0|xi3ag0,57,66,1|xubybz,57,66,1|xubyc0,51,40,0|y0td3z,51,40,0|y0td40,57,66,1|yd20zz,57,66,1|yd2100,51,40,0|yjjfrz,51,40,0|yjjfs0,57,66,1|yvs3nz,57,66,1|yvs3o0,51,40,0|z29ifz,51,40,0|z29ig0,57,66,1|zei6bz,57,66,1|zei6c0,51,40,0\",\"America/Lower_Princes|,0,58,0|-u7lckd,43,59,0|-2lx4u1,43,59,0|-2lx4u0,32,42,0\",\"America/Maceio|,0,131,0|-t85ldw,39,44,0|-jylag1,39,44,0|-jylag0,40,45,1|-jpb141,40,45,1|-jpb140,39,44,0|-jfsd01,39,44,0|-jfsd00,40,45,1|-j6j3s1,40,45,1|-j6j3s0,39,44,0|-ahcyc1,39,44,0|-ahcyc0,40,45,1|-aad3o1,40,45,1|-aad3o0,39,44,0|-9yl101,39,44,0|-9yl100,40,45,1|-9sd141,40,45,1|-9sd140,39,44,0|-9ft3o1,39,44,0|-9ft3o0,40,45,1|-99j941,40,45,1|-99j940,39,44,0|-8wzbo1,39,44,0|-8wzbo0,40,45,1|-8scqg1,40,45,1|-8scqg0,39,44,0|-35xmc1,39,44,0|-35xmc0,40,45,1|-31nzs1,40,45,1|-31nzs0,39,44,0|-2kdp01,39,44,0|-2kdp00,40,45,1|-2hcig1,40,45,1|-2hcig0,39,44,0|-24qqc1,39,44,0|-24qqc0,40,45,1|-204541,40,45,1|-204540,39,44,0|-1nid01,39,44,0|-1nid00,40,45,1|-1hc7s1,40,45,1|-1hc7s0,39,44,0|-14qfo1,39,44,0|-14qfo0,40,45,1|-yifs1,40,45,1|-yifs0,39,44,0|89jcbz,39,44,0|89jcc0,40,45,1|8gdk7z,40,45,1|8gdk80,39,44,0|8rwgbz,39,44,0|8rwgc0,40,45,1|8xns7z,40,45,1|8xns80,39,44,0|9aodnz,39,44,0|9aodo0,40,45,1|9g2qvz,40,45,1|9g2qw0,39,44,0|9t1hnz,39,44,0|9t1ho0,40,45,1|9yfuvz,40,45,1|9yfuw0,39,44,0|abrkbz,39,44,0|abrkc0,40,45,1|ahvuvz,40,45,1|ahvuw0,39,44,0|dggyzz,39,44,0|dggz00,40,45,1|dml9jz,40,45,1|dml9k0,39,44,0|fj0azz,39,44,0|fj0b00,40,45,1|fqkg7z,40,45,1|fqkg80,39,44,0|g23cbz,39,44,0|g23cc0,40,45,1|g2t6vz,40,45,1|g2t6w0,39,44,0|gl6dnz,39,44,0|gl6do0,40,45,1|grnmvz,40,45,1|grnmw0,39,44,0\",\"America/Managua|,0,132,0|-15r0tcs,21,133,0|-ijh6op,21,133,0|-ijh6oo,45,62,0|1qkbbz,45,62,0|1qkbc0,49,63,0|2ob1vz,49,63,0|2ob1w0,45,62,0|4t08nz,45,62,0|4t08o0,46,63,1|4y3hvz,46,63,1|4y3hw0,45,62,0|5bqbbz,45,62,0|5bqbc0,46,63,1|5gtkjz,46,63,1|5gtkk0,45,62,0|bhcefz,45,62,0|bhceg0,49,63,0|bv2gjz,49,63,0|bv2gk0,45,62,0|c05vbz,45,62,0|c05vc0,49,63,0|e3bcjz,49,63,0|e3bck0,45,62,0|iepvbz,45,62,0|iepvc0,46,63,1|inpv7z,46,63,1|inpv80,45,62,0|iyizjz,45,62,0|iyizk0,46,63,1|j6g0nz,46,63,1|j6g0o0,45,62,0\",\"America/Manaus|,0,134,0|-t85gvw,42,42,0|-jyl7o1,42,42,0|-jyl7o0,39,44,1|-jpayc1,39,44,1|-jpayc0,42,42,0|-jfsa81,42,42,0|-jfsa80,39,44,1|-j6j101,39,44,1|-j6j100,42,42,0|-ahcvk1,42,42,0|-ahcvk0,39,44,1|-aad0w1,39,44,1|-aad0w0,42,42,0|-9yky81,42,42,0|-9yky80,39,44,1|-9scyc1,39,44,1|-9scyc0,42,42,0|-9ft0w1,42,42,0|-9ft0w0,39,44,1|-99j6c1,39,44,1|-99j6c0,42,42,0|-8wz8w1,42,42,0|-8wz8w0,39,44,1|-8scno1,39,44,1|-8scno0,42,42,0|-35xjk1,42,42,0|-35xjk0,39,44,1|-31nx01,39,44,1|-31nx00,42,42,0|-2kdm81,42,42,0|-2kdm80,39,44,1|-2hcfo1,39,44,1|-2hcfo0,42,42,0|-24qnk1,42,42,0|-24qnk0,39,44,1|-2042c1,39,44,1|-2042c0,42,42,0|-1nia81,42,42,0|-1nia80,39,44,1|-1hc501,39,44,1|-1hc500,42,42,0|-14qcw1,42,42,0|-14qcw0,39,44,1|-yid01,39,44,1|-yid00,42,42,0|89jf3z,42,42,0|89jf40,39,44,1|8gdmzz,39,44,1|8gdn00,42,42,0|8rwj3z,42,42,0|8rwj40,39,44,1|8xnuzz,39,44,1|8xnv00,42,42,0|9aogfz,42,42,0|9aogg0,39,44,1|9g2tnz,39,44,1|9g2to0,42,42,0|cf0wfz,42,42,0|cf0wg0,39,44,1|cli5nz,39,44,1|cli5o0,42,42,0\",\"America/Marigot|,0,41,0|-u6m79w,32,42,0\",\"America/Martinique|,0,135,0|-15r0y0s,80,135,0|-umcvct,80,135,0|-umcvcs,32,42,0|5ct1rz,32,42,0|5ct1s0,54,44,1|5lt1nz,54,44,1|5lt1o0,32,42,0\",\"America/Matamoros|,0,136,0|-p1u7c0,45,62,0|9iywvz,45,62,0|9iyww0,46,63,1|9trq3z,46,63,1|9trq40,45,62,0|dphfjz,45,62,0|dphfk0,46,63,1|dzxa3z,46,63,1|dzxa40,45,62,0|e87i7z,45,62,0|e87i80,46,63,1|eincrz,46,63,1|eincs0,45,62,0|eqxkvz,45,62,0|eqxkw0,46,63,1|f1dffz,46,63,1|f1dfg0,45,62,0|f9nnjz,45,62,0|f9nnk0,46,63,1|fkggrz,46,63,1|fkggs0,45,62,0|fsdq7z,45,62,0|fsdq80,46,63,1|g36jfz,46,63,1|g36jg0,45,62,0|gcwm7z,45,62,0|gcwm80,46,63,1|gkgrfz,46,63,1|gkgrg0,45,62,0|gu6u7z,45,62,0|gu6u80,46,63,1|h4morz,46,63,1|h4mos0,45,62,0|hcwwvz,45,62,0|hcwww0,46,63,1|hncrfz,46,63,1|hncrg0,45,62,0|hvmzjz,45,62,0|hvmzk0,46,63,1|i6fsrz,46,63,1|i6fss0,45,62,0|ied27z,45,62,0|ied280,46,63,1|ip5vfz,46,63,1|ip5vg0,45,62,0|ix34vz,45,62,0|ix34w0,46,63,1|j7vy3z,46,63,1|j7vy40,45,62,0|jft7jz,45,62,0|jft7k0,46,63,1|jqm0rz,46,63,1|jqm0s0,45,62,0|jyw8vz,45,62,0|jyw8w0,46,63,1|k9c3fz,46,63,1|k9c3g0,45,62,0|khmbjz,45,62,0|khmbk0,46,63,1|ks263z,46,63,1|ks2640,45,62,0|kz9i7z,45,62,0|kz9i80,46,63,1|lbi63z,46,63,1|lbi640,45,62,0|lhzkvz,45,62,0|lhzkw0,46,63,1|lu88rz,46,63,1|lu88s0,45,62,0|m0pnjz,45,62,0|m0pnk0,46,63,1|mcybfz,46,63,1|mcybg0,45,62,0|mjfq7z,45,62,0|mjfq80,46,63,1|mvoe3z,46,63,1|mvoe40,45,62,0|n25svz,45,62,0|n25sw0,46,63,1|neegrz,46,63,1|neegs0,45,62,0|nkvvjz,45,62,0|nkvvk0,46,63,1|nx4jfz,46,63,1|nx4jg0,45,62,0|o3ywvz,45,62,0|o3yww0,46,63,1|og7krz,46,63,1|og7ks0,45,62,0|omozjz,45,62,0|omozk0,46,63,1|oyxnfz,46,63,1|oyxng0,45,62,0|p5f27z,45,62,0|p5f280,46,63,1|phnq3z,46,63,1|phnq40,45,62,0|po54vz,45,62,0|po54w0,46,63,1|q0dsrz,46,63,1|q0dss0,45,62,0|q6v7jz,45,62,0|q6v7k0,46,63,1|qj3vfz,46,63,1|qj3vg0,45,62,0|qpy8vz,45,62,0|qpy8w0,46,63,1|r26wrz,46,63,1|r26ws0,45,62,0|r8objz,45,62,0|r8obk0,46,63,1|rkwzfz,46,63,1|rkwzg0,45,62,0|rree7z,45,62,0|rree80,46,63,1|s3n23z,46,63,1|s3n240,45,62,0|sa4gvz,45,62,0|sa4gw0,46,63,1|smd4rz,46,63,1|smd4s0,45,62,0|ssujjz,45,62,0|ssujk0,46,63,1|t537fz,46,63,1|t537g0,45,62,0|tbkm7z,45,62,0|tbkm80,46,63,1|tnta3z,46,63,1|tnta40,45,62,0|tunnjz,45,62,0|tunnk0,46,63,1|u6wbfz,46,63,1|u6wbg0,45,62,0|uddq7z,45,62,0|uddq80,46,63,1|upme3z,46,63,1|upme40,45,62,0|uw3svz,45,62,0|uw3sw0,46,63,1|v8cgrz,46,63,1|v8cgs0,45,62,0|vetvjz,45,62,0|vetvk0,46,63,1|vr2jfz,46,63,1|vr2jg0,45,62,0|vxjy7z,45,62,0|vxjy80,46,63,1|w9sm3z,46,63,1|w9sm40,45,62,0|wgmzjz,45,62,0|wgmzk0,46,63,1|wsvnfz,46,63,1|wsvng0,45,62,0|wzd27z,45,62,0|wzd280,46,63,1|xblq3z,46,63,1|xblq40,45,62,0|xi34vz,45,62,0|xi34w0,46,63,1|xubsrz,46,63,1|xubss0,45,62,0|y0t7jz,45,62,0|y0t7k0,46,63,1|yd1vfz,46,63,1|yd1vg0,45,62,0|yjja7z,45,62,0|yjja80,46,63,1|yvry3z,46,63,1|yvry40,45,62,0|z29cvz,45,62,0|z29cw0,46,63,1|zei0rz,46,63,1|zei0s0,45,62,0\",\"America/Mazatlan|,0,137,0|-p1u4k0,50,66,0|-m7mko1,50,66,0|-m7mko0,45,62,0|-kf67c1,45,62,0|-kf67c0,50,66,0|-k6j3c1,50,66,0|-k6j3c0,45,62,0|-jypm01,45,62,0|-jypm00,50,66,0|-jpan81,50,66,0|-jpan80,45,62,0|-eg9601,45,62,0|-eg9600,50,66,0|-axv381,50,66,0|-axv380,51,40,0|m7z,51,40,0|m80,50,66,0|dphibz,50,66,0|dphic0,52,62,1|dzxcvz,52,62,1|dzxcw0,50,66,0|e87kzz,50,66,0|e87l00,52,62,1|einfjz,52,62,1|einfk0,50,66,0|eqxnnz,50,66,0|eqxno0,52,62,1|f1di7z,52,62,1|f1di80,50,66,0|f9nqbz,50,66,0|f9nqc0,52,62,1|fkgjjz,52,62,1|fkgjk0,50,66,0|fsdszz,50,66,0|fsdt00,52,62,1|g36m7z,52,62,1|g36m80,50,66,0|gcwozz,50,66,0|gcwp00,52,62,1|gkgu7z,52,62,1|gkgu80,50,66,0|gu6wzz,50,66,0|gu6x00,52,62,1|h4mrjz,52,62,1|h4mrk0,50,66,0|hcwznz,50,66,0|hcwzo0,52,62,1|hncu7z,52,62,1|hncu80,50,66,0|hvn2bz,50,66,0|hvn2c0,52,62,1|i6fvjz,52,62,1|i6fvk0,50,66,0|ied4zz,50,66,0|ied500,52,62,1|ip5y7z,52,62,1|ip5y80,50,66,0|ix37nz,50,66,0|ix37o0,52,62,1|j7w0vz,52,62,1|j7w0w0,50,66,0|jftabz,50,66,0|jftac0,52,62,1|jqm3jz,52,62,1|jqm3k0,50,66,0|jywbnz,50,66,0|jywbo0,52,62,1|k9c67z,52,62,1|k9c680,50,66,0|khmebz,50,66,0|khmec0,52,62,1|ks28vz,52,62,1|ks28w0,50,66,0|l0cgzz,50,66,0|l0ch00,52,62,1|lb5a7z,52,62,1|lb5a80,50,66,0|lj2jnz,50,66,0|lj2jo0,52,62,1|ltvcvz,52,62,1|ltvcw0,50,66,0|m1smbz,50,66,0|m1smc0,52,62,1|mclfjz,52,62,1|mclfk0,50,66,0|mkvnnz,50,66,0|mkvno0,52,62,1|mvbi7z,52,62,1|mvbi80,50,66,0|n3lqbz,50,66,0|n3lqc0,52,62,1|ne1kvz,52,62,1|ne1kw0,50,66,0|nmbszz,50,66,0|nmbt00,52,62,1|nwrnjz,52,62,1|nwrnk0,50,66,0|o51vnz,50,66,0|o51vo0,52,62,1|ofuovz,52,62,1|ofuow0,50,66,0|onrybz,50,66,0|onryc0,52,62,1|oykrjz,52,62,1|oykrk0,50,66,0|p6i0zz,50,66,0|p6i100,52,62,1|phau7z,52,62,1|phau80,50,66,0|ppl2bz,50,66,0|ppl2c0,52,62,1|q00wvz,52,62,1|q00ww0,50,66,0|q8b4zz,50,66,0|q8b500,52,62,1|qiqzjz,52,62,1|qiqzk0,50,66,0|qr17nz,50,66,0|qr17o0,52,62,1|r1u0vz,52,62,1|r1u0w0,50,66,0|r9rabz,50,66,0|r9rac0,52,62,1|rkk3jz,52,62,1|rkk3k0,50,66,0|rshczz,50,66,0|rshd00,52,62,1|s3a67z,52,62,1|s3a680,50,66,0|sbkebz,50,66,0|sbkec0,52,62,1|sm08vz,52,62,1|sm08w0,50,66,0|suagzz,50,66,0|suah00,52,62,1|t4qbjz,52,62,1|t4qbk0,50,66,0|td0jnz,50,66,0|td0jo0,52,62,1|tnge7z,52,62,1|tnge80,50,66,0|tvqmbz,50,66,0|tvqmc0,52,62,1|u6jfjz,52,62,1|u6jfk0,50,66,0|uegozz,50,66,0|uegp00,52,62,1|up9i7z,52,62,1|up9i80,50,66,0|ux6rnz,50,66,0|ux6ro0,52,62,1|v7zkvz,52,62,1|v7zkw0,50,66,0|vg9szz,50,66,0|vg9t00,52,62,1|vqpnjz,52,62,1|vqpnk0,50,66,0|vyzvnz,50,66,0|vyzvo0,52,62,1|w9fq7z,52,62,1|w9fq80,50,66,0|whpybz,50,66,0|whpyc0,52,62,1|wsirjz,52,62,1|wsirk0,50,66,0|x0g0zz,50,66,0|x0g100,52,62,1|xb8u7z,52,62,1|xb8u80,50,66,0|xj63nz,50,66,0|xj63o0,52,62,1|xtywvz,52,62,1|xtyww0,50,66,0|y1w6bz,50,66,0|y1w6c0,52,62,1|ycozjz,52,62,1|ycozk0,50,66,0|ykz7nz,50,66,0|ykz7o0,52,62,1|yvf27z,52,62,1|yvf280,50,66,0|z3pabz,50,66,0|z3pac0,52,62,1|ze54vz,52,62,1|ze54w0,50,66,0\",\"America/Menominee|,0,138,0|-17zjvrx,45,62,0|-r0esg1,45,62,0|-r0esg0,46,63,1|-qplz81,46,63,1|-qplz80,45,62,0|-qhops1,45,62,0|-qhops0,46,63,1|-q6vwk1,46,63,1|-q6vwk0,45,62,0|-ek21s1,45,62,0|-ek21s0,47,63,1|-cq2tg1,47,63,1|-cq2tg0,48,63,1|-cnp0k1,48,63,1|-cnp0k0,45,62,0|-ccw1s1,45,62,0|-ccw1s0,46,63,1|-c4yxw1,46,63,1|-c4yxw0,45,62,0|-1xbog1,45,62,0|-1xbog0,46,63,1|-1nlr81,46,63,1|-1nlr80,45,62,0|-cshs1,45,62,0|-cshs0,49,63,0|1qgorz,49,63,0|1qgos0,46,63,1|1ztq3z,46,63,1|1ztq40,45,62,0|23ffjz,45,62,0|23ffk0,46,63,1|2ijsrz,46,63,1|2ijss0,45,62,0|2oo8vz,45,62,0|2oo8w0,46,63,1|319vfz,46,63,1|319vg0,45,62,0|3amzjz,45,62,0|3amzk0,46,63,1|3kcwrz,46,63,1|3kcws0,45,62,0|3td27z,45,62,0|3td280,46,63,1|432zfz,46,63,1|432zg0,45,62,0|4cg3jz,45,62,0|4cg3k0,46,63,1|4lt23z,46,63,1|4lt240,45,62,0|4v667z,45,62,0|4v6680,46,63,1|54j4rz,46,63,1|54j4s0,45,62,0|5dw8vz,45,62,0|5dw8w0,46,63,1|5n97fz,46,63,1|5n97g0,45,62,0|5wmbjz,45,62,0|5wmbk0,46,63,1|65za3z,46,63,1|65za40,45,62,0|6fce7z,45,62,0|6fce80,46,63,1|6p2bfz,46,63,1|6p2bg0,45,62,0|6y2gvz,45,62,0|6y2gw0,46,63,1|77se3z,46,63,1|77se40,45,62,0|7h5i7z,45,62,0|7h5i80,46,63,1|7qigrz,46,63,1|7qigs0,45,62,0|7zvkvz,45,62,0|7zvkw0,46,63,1|898jfz,46,63,1|898jg0,45,62,0|8ilnjz,45,62,0|8ilnk0,46,63,1|8rym3z,46,63,1|8rym40,45,62,0|908u7z,45,62,0|908u80,46,63,1|9aoorz,46,63,1|9aoos0,45,62,0|9iywvz,45,62,0|9iyww0,46,63,1|9trq3z,46,63,1|9trq40,45,62,0|a1ozjz,45,62,0|a1ozk0,46,63,1|achsrz,46,63,1|achss0,45,62,0|akf27z,45,62,0|akf280,46,63,1|av7vfz,46,63,1|av7vg0,45,62,0|b3i3jz,45,62,0|b3i3k0,46,63,1|bdxy3z,46,63,1|bdxy40,45,62,0|bm867z,45,62,0|bm8680,46,63,1|bwo0rz,46,63,1|bwo0s0,45,62,0|c4y8vz,45,62,0|c4y8w0,46,63,1|cfr23z,46,63,1|cfr240,45,62,0|cnobjz,45,62,0|cnobk0,46,63,1|cyh4rz,46,63,1|cyh4s0,45,62,0|d6ee7z,45,62,0|d6ee80,46,63,1|dh77fz,46,63,1|dh77g0,45,62,0|dphfjz,45,62,0|dphfk0,46,63,1|dzxa3z,46,63,1|dzxa40,45,62,0|e87i7z,45,62,0|e87i80,46,63,1|eincrz,46,63,1|eincs0,45,62,0|eqxkvz,45,62,0|eqxkw0,46,63,1|f1dffz,46,63,1|f1dfg0,45,62,0|f9nnjz,45,62,0|f9nnk0,46,63,1|fkggrz,46,63,1|fkggs0,45,62,0|fsdq7z,45,62,0|fsdq80,46,63,1|g36jfz,46,63,1|g36jg0,45,62,0|gb3svz,45,62,0|gb3sw0,46,63,1|glwm3z,46,63,1|glwm40,45,62,0|gu6u7z,45,62,0|gu6u80,46,63,1|h4morz,46,63,1|h4mos0,45,62,0|hcwwvz,45,62,0|hcwww0,46,63,1|hncrfz,46,63,1|hncrg0,45,62,0|hvmzjz,45,62,0|hvmzk0,46,63,1|i6fsrz,46,63,1|i6fss0,45,62,0|ied27z,45,62,0|ied280,46,63,1|ip5vfz,46,63,1|ip5vg0,45,62,0|ix34vz,45,62,0|ix34w0,46,63,1|j7vy3z,46,63,1|j7vy40,45,62,0|jeqbjz,45,62,0|jeqbk0,46,63,1|jqyzfz,46,63,1|jqyzg0,45,62,0|jxge7z,45,62,0|jxge80,46,63,1|k9p23z,46,63,1|k9p240,45,62,0|kg6gvz,45,62,0|kg6gw0,46,63,1|ksf4rz,46,63,1|ksf4s0,45,62,0|kz9i7z,45,62,0|kz9i80,46,63,1|lbi63z,46,63,1|lbi640,45,62,0|lhzkvz,45,62,0|lhzkw0,46,63,1|lu88rz,46,63,1|lu88s0,45,62,0|m0pnjz,45,62,0|m0pnk0,46,63,1|mcybfz,46,63,1|mcybg0,45,62,0|mjfq7z,45,62,0|mjfq80,46,63,1|mvoe3z,46,63,1|mvoe40,45,62,0|n25svz,45,62,0|n25sw0,46,63,1|neegrz,46,63,1|neegs0,45,62,0|nkvvjz,45,62,0|nkvvk0,46,63,1|nx4jfz,46,63,1|nx4jg0,45,62,0|o3ywvz,45,62,0|o3yww0,46,63,1|og7krz,46,63,1|og7ks0,45,62,0|omozjz,45,62,0|omozk0,46,63,1|oyxnfz,46,63,1|oyxng0,45,62,0|p5f27z,45,62,0|p5f280,46,63,1|phnq3z,46,63,1|phnq40,45,62,0|po54vz,45,62,0|po54w0,46,63,1|q0dsrz,46,63,1|q0dss0,45,62,0|q6v7jz,45,62,0|q6v7k0,46,63,1|qj3vfz,46,63,1|qj3vg0,45,62,0|qpy8vz,45,62,0|qpy8w0,46,63,1|r26wrz,46,63,1|r26ws0,45,62,0|r8objz,45,62,0|r8obk0,46,63,1|rkwzfz,46,63,1|rkwzg0,45,62,0|rree7z,45,62,0|rree80,46,63,1|s3n23z,46,63,1|s3n240,45,62,0|sa4gvz,45,62,0|sa4gw0,46,63,1|smd4rz,46,63,1|smd4s0,45,62,0|ssujjz,45,62,0|ssujk0,46,63,1|t537fz,46,63,1|t537g0,45,62,0|tbkm7z,45,62,0|tbkm80,46,63,1|tnta3z,46,63,1|tnta40,45,62,0|tunnjz,45,62,0|tunnk0,46,63,1|u6wbfz,46,63,1|u6wbg0,45,62,0|uddq7z,45,62,0|uddq80,46,63,1|upme3z,46,63,1|upme40,45,62,0|uw3svz,45,62,0|uw3sw0,46,63,1|v8cgrz,46,63,1|v8cgs0,45,62,0|vetvjz,45,62,0|vetvk0,46,63,1|vr2jfz,46,63,1|vr2jg0,45,62,0|vxjy7z,45,62,0|vxjy80,46,63,1|w9sm3z,46,63,1|w9sm40,45,62,0|wgmzjz,45,62,0|wgmzk0,46,63,1|wsvnfz,46,63,1|wsvng0,45,62,0|wzd27z,45,62,0|wzd280,46,63,1|xblq3z,46,63,1|xblq40,45,62,0|xi34vz,45,62,0|xi34w0,46,63,1|xubsrz,46,63,1|xubss0,45,62,0|y0t7jz,45,62,0|y0t7k0,46,63,1|yd1vfz,46,63,1|yd1vg0,45,62,0|yjja7z,45,62,0|yjja80,46,63,1|yvry3z,46,63,1|yvry40,45,62,0|z29cvz,45,62,0|z29cw0,46,63,1|zei0rz,46,63,1|zei0s0,45,62,0\",\"America/Merida|,0,139,0|-p1u7c0,45,62,0|690gnz,45,62,0|690go0,49,63,0|6qpf7z,49,63,0|6qpf80,45,62,0|dphfjz,45,62,0|dphfk0,46,63,1|dzxa3z,46,63,1|dzxa40,45,62,0|e87i7z,45,62,0|e87i80,46,63,1|eincrz,46,63,1|eincs0,45,62,0|eqxkvz,45,62,0|eqxkw0,46,63,1|f1dffz,46,63,1|f1dfg0,45,62,0|f9nnjz,45,62,0|f9nnk0,46,63,1|fkggrz,46,63,1|fkggs0,45,62,0|fsdq7z,45,62,0|fsdq80,46,63,1|g36jfz,46,63,1|g36jg0,45,62,0|gcwm7z,45,62,0|gcwm80,46,63,1|gkgrfz,46,63,1|gkgrg0,45,62,0|gu6u7z,45,62,0|gu6u80,46,63,1|h4morz,46,63,1|h4mos0,45,62,0|hcwwvz,45,62,0|hcwww0,46,63,1|hncrfz,46,63,1|hncrg0,45,62,0|hvmzjz,45,62,0|hvmzk0,46,63,1|i6fsrz,46,63,1|i6fss0,45,62,0|ied27z,45,62,0|ied280,46,63,1|ip5vfz,46,63,1|ip5vg0,45,62,0|ix34vz,45,62,0|ix34w0,46,63,1|j7vy3z,46,63,1|j7vy40,45,62,0|jft7jz,45,62,0|jft7k0,46,63,1|jqm0rz,46,63,1|jqm0s0,45,62,0|jyw8vz,45,62,0|jyw8w0,46,63,1|k9c3fz,46,63,1|k9c3g0,45,62,0|khmbjz,45,62,0|khmbk0,46,63,1|ks263z,46,63,1|ks2640,45,62,0|l0ce7z,45,62,0|l0ce80,46,63,1|lb57fz,46,63,1|lb57g0,45,62,0|lj2gvz,45,62,0|lj2gw0,46,63,1|ltva3z,46,63,1|ltva40,45,62,0|m1sjjz,45,62,0|m1sjk0,46,63,1|mclcrz,46,63,1|mclcs0,45,62,0|mkvkvz,45,62,0|mkvkw0,46,63,1|mvbffz,46,63,1|mvbfg0,45,62,0|n3lnjz,45,62,0|n3lnk0,46,63,1|ne1i3z,46,63,1|ne1i40,45,62,0|nmbq7z,45,62,0|nmbq80,46,63,1|nwrkrz,46,63,1|nwrks0,45,62,0|o51svz,45,62,0|o51sw0,46,63,1|ofum3z,46,63,1|ofum40,45,62,0|onrvjz,45,62,0|onrvk0,46,63,1|oykorz,46,63,1|oykos0,45,62,0|p6hy7z,45,62,0|p6hy80,46,63,1|pharfz,46,63,1|pharg0,45,62,0|ppkzjz,45,62,0|ppkzk0,46,63,1|q00u3z,46,63,1|q00u40,45,62,0|q8b27z,45,62,0|q8b280,46,63,1|qiqwrz,46,63,1|qiqws0,45,62,0|qr14vz,45,62,0|qr14w0,46,63,1|r1ty3z,46,63,1|r1ty40,45,62,0|r9r7jz,45,62,0|r9r7k0,46,63,1|rkk0rz,46,63,1|rkk0s0,45,62,0|rsha7z,45,62,0|rsha80,46,63,1|s3a3fz,46,63,1|s3a3g0,45,62,0|sbkbjz,45,62,0|sbkbk0,46,63,1|sm063z,46,63,1|sm0640,45,62,0|suae7z,45,62,0|suae80,46,63,1|t4q8rz,46,63,1|t4q8s0,45,62,0|td0gvz,45,62,0|td0gw0,46,63,1|tngbfz,46,63,1|tngbg0,45,62,0|tvqjjz,45,62,0|tvqjk0,46,63,1|u6jcrz,46,63,1|u6jcs0,45,62,0|uegm7z,45,62,0|uegm80,46,63,1|up9ffz,46,63,1|up9fg0,45,62,0|ux6ovz,45,62,0|ux6ow0,46,63,1|v7zi3z,46,63,1|v7zi40,45,62,0|vg9q7z,45,62,0|vg9q80,46,63,1|vqpkrz,46,63,1|vqpks0,45,62,0|vyzsvz,45,62,0|vyzsw0,46,63,1|w9fnfz,46,63,1|w9fng0,45,62,0|whpvjz,45,62,0|whpvk0,46,63,1|wsiorz,46,63,1|wsios0,45,62,0|x0fy7z,45,62,0|x0fy80,46,63,1|xb8rfz,46,63,1|xb8rg0,45,62,0|xj60vz,45,62,0|xj60w0,46,63,1|xtyu3z,46,63,1|xtyu40,45,62,0|y1w3jz,45,62,0|y1w3k0,46,63,1|ycowrz,46,63,1|ycows0,45,62,0|ykz4vz,45,62,0|ykz4w0,46,63,1|yvezfz,46,63,1|yvezg0,45,62,0|z3p7jz,45,62,0|z3p7k0,46,63,1|ze523z,46,63,1|ze5240,45,62,0\",\"America/Metlakatla|,0,140,0|-1hc7qjz,0,141,0|-1078wyv,0,141,0|-1078wyu,51,40,0|-ek1w81,51,40,0|-ek1w80,68,66,1|-cq2tg1,68,66,1|-cq2tg0,69,66,1|-cnov01,69,66,1|-cnov00,51,40,0|-csc81,51,40,0|-csc80,57,66,1|-3fdo1,57,66,1|-3fdo0,51,40,0|5xqfz,51,40,0|5xqg0,57,66,1|faozz,57,66,1|fap00,51,40,0|ont3z,51,40,0|ont40,57,66,1|ydqbz,57,66,1|ydqc0,51,40,0|17qufz,51,40,0|17qug0,57,66,1|1h3szz,57,66,1|1h3t00,51,40,0|1qgx3z,51,40,0|1qgx40,57,66,1|1ztvnz,57,66,1|1ztvo0,51,40,0|23fl3z,51,40,0|23fl40,57,66,1|2ijybz,57,66,1|2ijyc0,51,40,0|2ooefz,51,40,0|2ooeg0,57,66,1|31a0zz,57,66,1|31a100,51,40,0|3an53z,51,40,0|3an540,57,66,1|3kd2bz,57,66,1|3kd2c0,51,40,0|3td7rz,51,40,0|3td7s0,57,66,1|4334zz,57,66,1|433500,51,40,0|4cg93z,51,40,0|4cg940,57,66,1|4lt7nz,57,66,1|4lt7o0,51,40,0|4v6brz,51,40,0|4v6bs0,57,66,1|54jabz,57,66,1|54jac0,51,40,0|5dwefz,51,40,0|5dweg0,57,66,1|5n9czz,57,66,1|5n9d00,51,40,0|5wmh3z,51,40,0|5wmh40,57,66,1|65zfnz,57,66,1|65zfo0,51,40,0|6fcjrz,51,40,0|6fcjs0,57,66,1|6p2gzz,57,66,1|6p2h00,51,40,0|6y2mfz,51,40,0|6y2mg0,57,66,1|77sjnz,57,66,1|77sjo0,51,40,0|nx4rrz,51,40,0|nx4rs0,37,37,0|o3z57z,37,37,0|o3z580,38,40,1|og7t3z,38,40,1|og7t40,37,37,0|omp7vz,37,37,0|omp7w0,38,40,1|oyxvrz,38,40,1|oyxvs0,37,37,0|p5fajz,37,37,0|p5fak0,38,40,1|phnyfz,38,40,1|phnyg0,51,40,0|plmjrz,51,40,0|plmjs0,37,37,0|po5d7z,37,37,0|po5d80,38,40,1|q0e13z,38,40,1|q0e140,37,37,0|q6vfvz,37,37,0|q6vfw0,38,40,1|qj43rz,38,40,1|qj43s0,37,37,0|qpyh7z,37,37,0|qpyh80,38,40,1|r2753z,38,40,1|r27540,37,37,0|r8ojvz,37,37,0|r8ojw0,38,40,1|rkx7rz,38,40,1|rkx7s0,37,37,0|rremjz,37,37,0|rremk0,38,40,1|s3nafz,38,40,1|s3nag0,37,37,0|sa4p7z,37,37,0|sa4p80,38,40,1|smdd3z,38,40,1|smdd40,37,37,0|ssurvz,37,37,0|ssurw0,38,40,1|t53frz,38,40,1|t53fs0,37,37,0|tbkujz,37,37,0|tbkuk0,38,40,1|tntifz,38,40,1|tntig0,37,37,0|tunvvz,37,37,0|tunvw0,38,40,1|u6wjrz,38,40,1|u6wjs0,37,37,0|uddyjz,37,37,0|uddyk0,38,40,1|upmmfz,38,40,1|upmmg0,37,37,0|uw417z,37,37,0|uw4180,38,40,1|v8cp3z,38,40,1|v8cp40,37,37,0|veu3vz,37,37,0|veu3w0,38,40,1|vr2rrz,38,40,1|vr2rs0,37,37,0|vxk6jz,37,37,0|vxk6k0,38,40,1|w9sufz,38,40,1|w9sug0,37,37,0|wgn7vz,37,37,0|wgn7w0,38,40,1|wsvvrz,38,40,1|wsvvs0,37,37,0|wzdajz,37,37,0|wzdak0,38,40,1|xblyfz,38,40,1|xblyg0,37,37,0|xi3d7z,37,37,0|xi3d80,38,40,1|xuc13z,38,40,1|xuc140,37,37,0|y0tfvz,37,37,0|y0tfw0,38,40,1|yd23rz,38,40,1|yd23s0,37,37,0|yjjijz,37,37,0|yjjik0,38,40,1|yvs6fz,38,40,1|yvs6g0,37,37,0|z29l7z,37,37,0|z29l80,38,40,1|zei93z,38,40,1|zei940,37,37,0\",\"America/Mexico_City|,0,142,0|-p1u4k0,50,66,0|-m7mko1,50,66,0|-m7mko0,45,62,0|-kf67c1,45,62,0|-kf67c0,50,66,0|-k6j3c1,50,66,0|-k6j3c0,45,62,0|-jypm01,45,62,0|-jypm00,50,66,0|-jpan81,50,66,0|-jpan80,45,62,0|-g4n8o1,45,62,0|-g4n8o0,46,63,1|-fxg241,46,63,1|-fxg240,45,62,0|-f60y01,45,62,0|-f60y00,46,63,1|-f07rg1,46,63,1|-f07rg0,45,62,0|-dlc7c1,45,62,0|-dlc7c0,47,63,1|-deaks1,47,63,1|-deaks0,45,62,0|-adljc1,45,62,0|-adljc0,46,63,1|-a4yi41,46,63,1|-a4yi40,45,62,0|dphfjz,45,62,0|dphfk0,46,63,1|dzxa3z,46,63,1|dzxa40,45,62,0|e87i7z,45,62,0|e87i80,46,63,1|eincrz,46,63,1|eincs0,45,62,0|eqxkvz,45,62,0|eqxkw0,46,63,1|f1dffz,46,63,1|f1dfg0,45,62,0|f9nnjz,45,62,0|f9nnk0,46,63,1|fkggrz,46,63,1|fkggs0,45,62,0|fsdq7z,45,62,0|fsdq80,46,63,1|g36jfz,46,63,1|g36jg0,45,62,0|gcwm7z,45,62,0|gcwm80,46,63,1|gkgrfz,46,63,1|gkgrg0,45,62,0|gu6u7z,45,62,0|gu6u80,46,63,1|h4morz,46,63,1|h4mos0,45,62,0|hcwwvz,45,62,0|hcwww0,46,63,1|hncrfz,46,63,1|hncrg0,45,62,0|hvmzjz,45,62,0|hvmzk0,46,63,1|i6fsrz,46,63,1|i6fss0,45,62,0|ied27z,45,62,0|ied280,46,63,1|ip5vfz,46,63,1|ip5vg0,45,62,0|ix34vz,45,62,0|ix34w0,46,63,1|j7vy3z,46,63,1|j7vy40,45,62,0|jft7jz,45,62,0|jft7k0,46,63,1|jqm0rz,46,63,1|jqm0s0,45,62,0|jyw8vz,45,62,0|jyw8w0,46,63,1|k9c3fz,46,63,1|k9c3g0,45,62,0|khmbjz,45,62,0|khmbk0,46,63,1|ks263z,46,63,1|ks2640,45,62,0|l0ce7z,45,62,0|l0ce80,46,63,1|lb57fz,46,63,1|lb57g0,45,62,0|lj2gvz,45,62,0|lj2gw0,46,63,1|ltva3z,46,63,1|ltva40,45,62,0|m1sjjz,45,62,0|m1sjk0,46,63,1|mclcrz,46,63,1|mclcs0,45,62,0|mkvkvz,45,62,0|mkvkw0,46,63,1|mvbffz,46,63,1|mvbfg0,45,62,0|n3lnjz,45,62,0|n3lnk0,46,63,1|ne1i3z,46,63,1|ne1i40,45,62,0|nmbq7z,45,62,0|nmbq80,46,63,1|nwrkrz,46,63,1|nwrks0,45,62,0|o51svz,45,62,0|o51sw0,46,63,1|ofum3z,46,63,1|ofum40,45,62,0|onrvjz,45,62,0|onrvk0,46,63,1|oykorz,46,63,1|oykos0,45,62,0|p6hy7z,45,62,0|p6hy80,46,63,1|pharfz,46,63,1|pharg0,45,62,0|ppkzjz,45,62,0|ppkzk0,46,63,1|q00u3z,46,63,1|q00u40,45,62,0|q8b27z,45,62,0|q8b280,46,63,1|qiqwrz,46,63,1|qiqws0,45,62,0|qr14vz,45,62,0|qr14w0,46,63,1|r1ty3z,46,63,1|r1ty40,45,62,0|r9r7jz,45,62,0|r9r7k0,46,63,1|rkk0rz,46,63,1|rkk0s0,45,62,0|rsha7z,45,62,0|rsha80,46,63,1|s3a3fz,46,63,1|s3a3g0,45,62,0|sbkbjz,45,62,0|sbkbk0,46,63,1|sm063z,46,63,1|sm0640,45,62,0|suae7z,45,62,0|suae80,46,63,1|t4q8rz,46,63,1|t4q8s0,45,62,0|td0gvz,45,62,0|td0gw0,46,63,1|tngbfz,46,63,1|tngbg0,45,62,0|tvqjjz,45,62,0|tvqjk0,46,63,1|u6jcrz,46,63,1|u6jcs0,45,62,0|uegm7z,45,62,0|uegm80,46,63,1|up9ffz,46,63,1|up9fg0,45,62,0|ux6ovz,45,62,0|ux6ow0,46,63,1|v7zi3z,46,63,1|v7zi40,45,62,0|vg9q7z,45,62,0|vg9q80,46,63,1|vqpkrz,46,63,1|vqpks0,45,62,0|vyzsvz,45,62,0|vyzsw0,46,63,1|w9fnfz,46,63,1|w9fng0,45,62,0|whpvjz,45,62,0|whpvk0,46,63,1|wsiorz,46,63,1|wsios0,45,62,0|x0fy7z,45,62,0|x0fy80,46,63,1|xb8rfz,46,63,1|xb8rg0,45,62,0|xj60vz,45,62,0|xj60w0,46,63,1|xtyu3z,46,63,1|xtyu40,45,62,0|y1w3jz,45,62,0|y1w3k0,46,63,1|ycowrz,46,63,1|ycows0,45,62,0|ykz4vz,45,62,0|ykz4w0,46,63,1|yvezfz,46,63,1|yvezg0,45,62,0|z3p7jz,45,62,0|z3p7k0,46,63,1|ze523z,46,63,1|ze5240,45,62,0\",\"America/Miquelon|,0,143,0|-ulmyxk,32,42,0|5e3cfz,32,42,0|5e3cg0,39,44,0|908lvz,39,44,0|908lw0,40,45,1|9aogfz,40,45,1|9aogg0,39,44,0|9iyojz,39,44,0|9iyok0,40,45,1|9trhrz,40,45,1|9trhs0,39,44,0|a1or7z,39,44,0|a1or80,40,45,1|achkfz,40,45,1|achkg0,39,44,0|aketvz,39,44,0|aketw0,40,45,1|av7n3z,40,45,1|av7n40,39,44,0|b3hv7z,39,44,0|b3hv80,40,45,1|bdxprz,40,45,1|bdxps0,39,44,0|bm7xvz,39,44,0|bm7xw0,40,45,1|bwnsfz,40,45,1|bwnsg0,39,44,0|c4y0jz,39,44,0|c4y0k0,40,45,1|cfqtrz,40,45,1|cfqts0,39,44,0|cno37z,39,44,0|cno380,40,45,1|cygwfz,40,45,1|cygwg0,39,44,0|d6e5vz,39,44,0|d6e5w0,40,45,1|dh6z3z,40,45,1|dh6z40,39,44,0|dph77z,39,44,0|dph780,40,45,1|dzx1rz,40,45,1|dzx1s0,39,44,0|e879vz,39,44,0|e879w0,40,45,1|ein4fz,40,45,1|ein4g0,39,44,0|eqxcjz,39,44,0|eqxck0,40,45,1|f1d73z,40,45,1|f1d740,39,44,0|f9nf7z,39,44,0|f9nf80,40,45,1|fkg8fz,40,45,1|fkg8g0,39,44,0|fsdhvz,39,44,0|fsdhw0,40,45,1|g36b3z,40,45,1|g36b40,39,44,0|gb3kjz,39,44,0|gb3kk0,40,45,1|glwdrz,40,45,1|glwds0,39,44,0|gu6lvz,39,44,0|gu6lw0,40,45,1|h4mgfz,40,45,1|h4mgg0,39,44,0|hcwojz,39,44,0|hcwok0,40,45,1|hncj3z,40,45,1|hncj40,39,44,0|hvmr7z,39,44,0|hvmr80,40,45,1|i6fkfz,40,45,1|i6fkg0,39,44,0|iectvz,39,44,0|iectw0,40,45,1|ip5n3z,40,45,1|ip5n40,39,44,0|ix2wjz,39,44,0|ix2wk0,40,45,1|j7vprz,40,45,1|j7vps0,39,44,0|jeq37z,39,44,0|jeq380,40,45,1|jqyr3z,40,45,1|jqyr40,39,44,0|jxg5vz,39,44,0|jxg5w0,40,45,1|k9otrz,40,45,1|k9ots0,39,44,0|kg68jz,39,44,0|kg68k0,40,45,1|ksewfz,40,45,1|ksewg0,39,44,0|kz99vz,39,44,0|kz99w0,40,45,1|lbhxrz,40,45,1|lbhxs0,39,44,0|lhzcjz,39,44,0|lhzck0,40,45,1|lu80fz,40,45,1|lu80g0,39,44,0|m0pf7z,39,44,0|m0pf80,40,45,1|mcy33z,40,45,1|mcy340,39,44,0|mjfhvz,39,44,0|mjfhw0,40,45,1|mvo5rz,40,45,1|mvo5s0,39,44,0|n25kjz,39,44,0|n25kk0,40,45,1|nee8fz,40,45,1|nee8g0,39,44,0|nkvn7z,39,44,0|nkvn80,40,45,1|nx4b3z,40,45,1|nx4b40,39,44,0|o3yojz,39,44,0|o3yok0,40,45,1|og7cfz,40,45,1|og7cg0,39,44,0|omor7z,39,44,0|omor80,40,45,1|oyxf3z,40,45,1|oyxf40,39,44,0|p5etvz,39,44,0|p5etw0,40,45,1|phnhrz,40,45,1|phnhs0,39,44,0|po4wjz,39,44,0|po4wk0,40,45,1|q0dkfz,40,45,1|q0dkg0,39,44,0|q6uz7z,39,44,0|q6uz80,40,45,1|qj3n3z,40,45,1|qj3n40,39,44,0|qpy0jz,39,44,0|qpy0k0,40,45,1|r26ofz,40,45,1|r26og0,39,44,0|r8o37z,39,44,0|r8o380,40,45,1|rkwr3z,40,45,1|rkwr40,39,44,0|rre5vz,39,44,0|rre5w0,40,45,1|s3mtrz,40,45,1|s3mts0,39,44,0|sa48jz,39,44,0|sa48k0,40,45,1|smcwfz,40,45,1|smcwg0,39,44,0|ssub7z,39,44,0|ssub80,40,45,1|t52z3z,40,45,1|t52z40,39,44,0|tbkdvz,39,44,0|tbkdw0,40,45,1|tnt1rz,40,45,1|tnt1s0,39,44,0|tunf7z,39,44,0|tunf80,40,45,1|u6w33z,40,45,1|u6w340,39,44,0|uddhvz,39,44,0|uddhw0,40,45,1|upm5rz,40,45,1|upm5s0,39,44,0|uw3kjz,39,44,0|uw3kk0,40,45,1|v8c8fz,40,45,1|v8c8g0,39,44,0|vetn7z,39,44,0|vetn80,40,45,1|vr2b3z,40,45,1|vr2b40,39,44,0|vxjpvz,39,44,0|vxjpw0,40,45,1|w9sdrz,40,45,1|w9sds0,39,44,0|wgmr7z,39,44,0|wgmr80,40,45,1|wsvf3z,40,45,1|wsvf40,39,44,0|wzctvz,39,44,0|wzctw0,40,45,1|xblhrz,40,45,1|xblhs0,39,44,0|xi2wjz,39,44,0|xi2wk0,40,45,1|xubkfz,40,45,1|xubkg0,39,44,0|y0sz7z,39,44,0|y0sz80,40,45,1|yd1n3z,40,45,1|yd1n40,39,44,0|yjj1vz,39,44,0|yjj1w0,40,45,1|yvrprz,40,45,1|yvrps0,39,44,0|z294jz,39,44,0|z294k0,40,45,1|zehsfz,40,45,1|zehsg0,39,44,0\",\"America/Moncton|,0,144,0|-18wys04,49,63,0|-z94i41,49,63,0|-z94i40,32,42,0|-qzp0o1,32,42,0|-qzp0o0,54,44,1|-qpm4s1,54,44,1|-qpm4s0,32,42,0|-j2ve41,32,42,0|-j2ve40,54,44,1|-iy6y81,54,44,1|-iy6y80,32,42,0|-ik5bg1,32,42,0|-ik5bg0,54,44,1|-ifgvk1,54,44,1|-ifgvk0,32,42,0|-i1f8s1,32,42,0|-i1f8s0,54,44,1|-hwqsw1,54,44,1|-hwqsw0,32,42,0|-hip641,32,42,0|-hip640,54,44,1|-he0q81,54,44,1|-he0q80,32,42,0|-gzz3g1,32,42,0|-gzz3g0,54,44,1|-gvank1,54,44,1|-gvank0,32,42,0|-gh90s1,32,42,0|-gh90s0,54,44,1|-gckkw1,54,44,1|-gckkw0,32,42,0|-fyxrg1,32,42,0|-fyxrg0,54,44,1|-fstgw1,54,44,1|-fstgw0,32,42,0|-fgiss1,32,42,0|-fgiss0,54,44,1|-fa3e81,54,44,1|-fa3e80,32,42,0|-eying1,32,42,0|-eying0,54,44,1|-er0cw1,54,44,1|-er0cw0,32,42,0|-ek27c1,32,42,0|-ek27c0,33,44,1|-cq2tg1,33,44,1|-cq2tg0,34,44,1|-cnp641,34,44,1|-cnp640,32,42,0|-ccw7c1,32,42,0|-ccw7c0,54,44,1|-c4z3g1,54,44,1|-c4z3g0,32,42,0|-bu64o1,32,42,0|-bu64o0,54,44,1|-bm90s1,54,44,1|-bm90s0,32,42,0|-bbg201,32,42,0|-bbg200,54,44,1|-b3iy41,54,44,1|-b3iy40,32,42,0|-aspzc1,32,42,0|-aspzc0,54,44,1|-aksvg1,54,44,1|-aksvg0,32,42,0|-a9my01,32,42,0|-a9my00,54,44,1|-a22ss1,54,44,1|-a22ss0,32,42,0|-9qwvc1,32,42,0|-9qwvc0,54,44,1|-9izrg1,54,44,1|-9izrg0,32,42,0|-986so1,32,42,0|-986so0,54,44,1|-909os1,54,44,1|-909os0,32,42,0|-8pgq01,32,42,0|-8pgq00,54,44,1|-8hjm41,54,44,1|-8hjm40,32,42,0|-86qnc1,32,42,0|-86qnc0,54,44,1|-7ytjg1,54,44,1|-7ytjg0,32,42,0|-7o0ko1,32,42,0|-7o0ko0,54,44,1|-7g3gs1,54,44,1|-7g3gs0,32,42,0|-74xjc1,32,42,0|-74xjc0,54,44,1|-6x0fg1,54,44,1|-6x0fg0,32,42,0|-6m7go1,32,42,0|-6m7go0,54,44,1|-6cui41,54,44,1|-6cui40,32,42,0|-63he01,32,42,0|-63he00,54,44,1|-5u4fg1,54,44,1|-5u4fg0,32,42,0|-5krbc1,32,42,0|-5krbc0,54,44,1|-5becs1,54,44,1|-5becs0,32,42,0|-5218o1,32,42,0|-5218o0,54,44,1|-4sbbg1,54,44,1|-4sbbg0,32,42,0|-4iy7c1,32,42,0|-4iy7c0,54,44,1|-49l8s1,54,44,1|-49l8s0,32,42,0|-4084o1,32,42,0|-4084o0,54,44,1|-3qv641,54,44,1|-3qv640,32,42,0|-3hi201,32,42,0|-3hi200,54,44,1|-3853g1,54,44,1|-3853g0,32,42,0|-2yrzc1,32,42,0|-2yrzc0,54,44,1|-2pf0s1,54,44,1|-2pf0s0,32,42,0|-2g1wo1,32,42,0|-2g1wo0,54,44,1|-26bzg1,54,44,1|-26bzg0,32,42,0|-1xbu01,32,42,0|-1xbu00,54,44,1|-1nlws1,54,44,1|-1nlws0,32,42,0|-1e8so1,32,42,0|-1e8so0,54,44,1|-14vu41,54,44,1|-14vu40,32,42,0|-viq01,32,42,0|-viq00,54,44,1|-m5rg1,54,44,1|-m5rg0,32,42,0|-csnc1,32,42,0|-csnc0,54,44,1|-3fos1,54,44,1|-3fos0,32,42,0|5xfbz,32,42,0|5xfc0,54,44,1|fadvz,54,44,1|fadw0,32,42,0|onhzz,32,42,0|oni00,54,44,1|ydf7z,54,44,1|ydf80,32,42,0|17qjbz,32,42,0|17qjc0,54,44,1|1h3hvz,54,44,1|1h3hw0,32,42,0|296onz,32,42,0|296oo0,54,44,1|2ijn7z,54,44,1|2ijn80,32,42,0|2rwrbz,32,42,0|2rwrc0,54,44,1|319pvz,54,44,1|319pw0,32,42,0|3amtzz,32,42,0|3amu00,54,44,1|3kcr7z,54,44,1|3kcr80,32,42,0|3tcwnz,32,42,0|3tcwo0,54,44,1|432tvz,54,44,1|432tw0,32,42,0|4cfxzz,32,42,0|4cfy00,54,44,1|4lswjz,54,44,1|4lswk0,32,42,0|4v60nz,32,42,0|4v60o0,54,44,1|54iz7z,54,44,1|54iz80,32,42,0|5dw3bz,32,42,0|5dw3c0,54,44,1|5n91vz,54,44,1|5n91w0,32,42,0|5wm5zz,32,42,0|5wm600,54,44,1|65z4jz,54,44,1|65z4k0,32,42,0|6fc8nz,32,42,0|6fc8o0,54,44,1|6p25vz,54,44,1|6p25w0,32,42,0|6y2bbz,32,42,0|6y2bc0,54,44,1|77s8jz,54,44,1|77s8k0,32,42,0|7h5cnz,32,42,0|7h5co0,54,44,1|7qib7z,54,44,1|7qib80,32,42,0|7zvfbz,32,42,0|7zvfc0,54,44,1|898dvz,54,44,1|898dw0,32,42,0|8ilhzz,32,42,0|8ili00,54,44,1|8rygjz,54,44,1|8rygk0,32,42,0|908onz,32,42,0|908oo0,54,44,1|9aoj7z,54,44,1|9aoj80,32,42,0|9iyrbz,32,42,0|9iyrc0,54,44,1|9trkjz,54,44,1|9trkk0,32,42,0|a1otzz,32,42,0|a1ou00,54,44,1|achn7z,54,44,1|achn80,32,42,0|akewnz,32,42,0|akewo0,54,44,1|av7pvz,54,44,1|av7pw0,32,42,0|b3hxzz,32,42,0|b3hy00,54,44,1|bdxsjz,54,44,1|bdxsk0,32,42,0|bm80nz,32,42,0|bm80o0,54,44,1|bwnv7z,54,44,1|bwnv80,32,42,0|c4xxtn,32,42,0|c4xxto,54,44,1|cfqr1n,54,44,1|cfqr1o,32,42,0|cno0hn,32,42,0|cno0ho,54,44,1|cygtpn,54,44,1|cygtpo,32,42,0|d6e35n,32,42,0|d6e35o,54,44,1|dh6wdn,54,44,1|dh6wdo,32,42,0|dph4hn,32,42,0|dph4ho,54,44,1|dzwz1n,54,44,1|dzwz1o,32,42,0|e8775n,32,42,0|e8775o,54,44,1|ein1pn,54,44,1|ein1po,32,42,0|eqx9tn,32,42,0|eqx9to,54,44,1|f1d4dn,54,44,1|f1d4do,32,42,0|f9nchn,32,42,0|f9ncho,54,44,1|fkg5pn,54,44,1|fkg5po,32,42,0|fsdf5n,32,42,0|fsdf5o,54,44,1|g368dn,54,44,1|g368do,32,42,0|gb3htn,32,42,0|gb3hto,54,44,1|glwb1n,54,44,1|glwb1o,32,42,0|gu6j5n,32,42,0|gu6j5o,54,44,1|h4mdpn,54,44,1|h4mdpo,32,42,0|hcwltn,32,42,0|hcwlto,54,44,1|hncgdn,54,44,1|hncgdo,32,42,0|hvmohn,32,42,0|hvmoho,54,44,1|i6fhpn,54,44,1|i6fhpo,32,42,0|iecr5n,32,42,0|iecr5o,54,44,1|ip5kdn,54,44,1|ip5kdo,32,42,0|ix2ttn,32,42,0|ix2tto,54,44,1|j7vn1n,54,44,1|j7vn1o,32,42,0|jeq5zz,32,42,0|jeq600,54,44,1|jqytvz,54,44,1|jqytw0,32,42,0|jxg8nz,32,42,0|jxg8o0,54,44,1|k9owjz,54,44,1|k9owk0,32,42,0|kg6bbz,32,42,0|kg6bc0,54,44,1|ksez7z,54,44,1|ksez80,32,42,0|kz9cnz,32,42,0|kz9co0,54,44,1|lbi0jz,54,44,1|lbi0k0,32,42,0|lhzfbz,32,42,0|lhzfc0,54,44,1|lu837z,54,44,1|lu8380,32,42,0|m0phzz,32,42,0|m0pi00,54,44,1|mcy5vz,54,44,1|mcy5w0,32,42,0|mjfknz,32,42,0|mjfko0,54,44,1|mvo8jz,54,44,1|mvo8k0,32,42,0|n25nbz,32,42,0|n25nc0,54,44,1|neeb7z,54,44,1|neeb80,32,42,0|nkvpzz,32,42,0|nkvq00,54,44,1|nx4dvz,54,44,1|nx4dw0,32,42,0|o3yrbz,32,42,0|o3yrc0,54,44,1|og7f7z,54,44,1|og7f80,32,42,0|omotzz,32,42,0|omou00,54,44,1|oyxhvz,54,44,1|oyxhw0,32,42,0|p5ewnz,32,42,0|p5ewo0,54,44,1|phnkjz,54,44,1|phnkk0,32,42,0|po4zbz,32,42,0|po4zc0,54,44,1|q0dn7z,54,44,1|q0dn80,32,42,0|q6v1zz,32,42,0|q6v200,54,44,1|qj3pvz,54,44,1|qj3pw0,32,42,0|qpy3bz,32,42,0|qpy3c0,54,44,1|r26r7z,54,44,1|r26r80,32,42,0|r8o5zz,32,42,0|r8o600,54,44,1|rkwtvz,54,44,1|rkwtw0,32,42,0|rre8nz,32,42,0|rre8o0,54,44,1|s3mwjz,54,44,1|s3mwk0,32,42,0|sa4bbz,32,42,0|sa4bc0,54,44,1|smcz7z,54,44,1|smcz80,32,42,0|ssudzz,32,42,0|ssue00,54,44,1|t531vz,54,44,1|t531w0,32,42,0|tbkgnz,32,42,0|tbkgo0,54,44,1|tnt4jz,54,44,1|tnt4k0,32,42,0|tunhzz,32,42,0|tuni00,54,44,1|u6w5vz,54,44,1|u6w5w0,32,42,0|uddknz,32,42,0|uddko0,54,44,1|upm8jz,54,44,1|upm8k0,32,42,0|uw3nbz,32,42,0|uw3nc0,54,44,1|v8cb7z,54,44,1|v8cb80,32,42,0|vetpzz,32,42,0|vetq00,54,44,1|vr2dvz,54,44,1|vr2dw0,32,42,0|vxjsnz,32,42,0|vxjso0,54,44,1|w9sgjz,54,44,1|w9sgk0,32,42,0|wgmtzz,32,42,0|wgmu00,54,44,1|wsvhvz,54,44,1|wsvhw0,32,42,0|wzcwnz,32,42,0|wzcwo0,54,44,1|xblkjz,54,44,1|xblkk0,32,42,0|xi2zbz,32,42,0|xi2zc0,54,44,1|xubn7z,54,44,1|xubn80,32,42,0|y0t1zz,32,42,0|y0t200,54,44,1|yd1pvz,54,44,1|yd1pw0,32,42,0|yjj4nz,32,42,0|yjj4o0,54,44,1|yvrsjz,54,44,1|yvrsk0,32,42,0|z297bz,32,42,0|z297c0,54,44,1|zehv7z,54,44,1|zehv80,32,42,0\",\"America/Monterrey|,0,145,0|-p1u7c0,45,62,0|9iywvz,45,62,0|9iyww0,46,63,1|9trq3z,46,63,1|9trq40,45,62,0|dphfjz,45,62,0|dphfk0,46,63,1|dzxa3z,46,63,1|dzxa40,45,62,0|e87i7z,45,62,0|e87i80,46,63,1|eincrz,46,63,1|eincs0,45,62,0|eqxkvz,45,62,0|eqxkw0,46,63,1|f1dffz,46,63,1|f1dfg0,45,62,0|f9nnjz,45,62,0|f9nnk0,46,63,1|fkggrz,46,63,1|fkggs0,45,62,0|fsdq7z,45,62,0|fsdq80,46,63,1|g36jfz,46,63,1|g36jg0,45,62,0|gcwm7z,45,62,0|gcwm80,46,63,1|gkgrfz,46,63,1|gkgrg0,45,62,0|gu6u7z,45,62,0|gu6u80,46,63,1|h4morz,46,63,1|h4mos0,45,62,0|hcwwvz,45,62,0|hcwww0,46,63,1|hncrfz,46,63,1|hncrg0,45,62,0|hvmzjz,45,62,0|hvmzk0,46,63,1|i6fsrz,46,63,1|i6fss0,45,62,0|ied27z,45,62,0|ied280,46,63,1|ip5vfz,46,63,1|ip5vg0,45,62,0|ix34vz,45,62,0|ix34w0,46,63,1|j7vy3z,46,63,1|j7vy40,45,62,0|jft7jz,45,62,0|jft7k0,46,63,1|jqm0rz,46,63,1|jqm0s0,45,62,0|jyw8vz,45,62,0|jyw8w0,46,63,1|k9c3fz,46,63,1|k9c3g0,45,62,0|khmbjz,45,62,0|khmbk0,46,63,1|ks263z,46,63,1|ks2640,45,62,0|l0ce7z,45,62,0|l0ce80,46,63,1|lb57fz,46,63,1|lb57g0,45,62,0|lj2gvz,45,62,0|lj2gw0,46,63,1|ltva3z,46,63,1|ltva40,45,62,0|m1sjjz,45,62,0|m1sjk0,46,63,1|mclcrz,46,63,1|mclcs0,45,62,0|mkvkvz,45,62,0|mkvkw0,46,63,1|mvbffz,46,63,1|mvbfg0,45,62,0|n3lnjz,45,62,0|n3lnk0,46,63,1|ne1i3z,46,63,1|ne1i40,45,62,0|nmbq7z,45,62,0|nmbq80,46,63,1|nwrkrz,46,63,1|nwrks0,45,62,0|o51svz,45,62,0|o51sw0,46,63,1|ofum3z,46,63,1|ofum40,45,62,0|onrvjz,45,62,0|onrvk0,46,63,1|oykorz,46,63,1|oykos0,45,62,0|p6hy7z,45,62,0|p6hy80,46,63,1|pharfz,46,63,1|pharg0,45,62,0|ppkzjz,45,62,0|ppkzk0,46,63,1|q00u3z,46,63,1|q00u40,45,62,0|q8b27z,45,62,0|q8b280,46,63,1|qiqwrz,46,63,1|qiqws0,45,62,0|qr14vz,45,62,0|qr14w0,46,63,1|r1ty3z,46,63,1|r1ty40,45,62,0|r9r7jz,45,62,0|r9r7k0,46,63,1|rkk0rz,46,63,1|rkk0s0,45,62,0|rsha7z,45,62,0|rsha80,46,63,1|s3a3fz,46,63,1|s3a3g0,45,62,0|sbkbjz,45,62,0|sbkbk0,46,63,1|sm063z,46,63,1|sm0640,45,62,0|suae7z,45,62,0|suae80,46,63,1|t4q8rz,46,63,1|t4q8s0,45,62,0|td0gvz,45,62,0|td0gw0,46,63,1|tngbfz,46,63,1|tngbg0,45,62,0|tvqjjz,45,62,0|tvqjk0,46,63,1|u6jcrz,46,63,1|u6jcs0,45,62,0|uegm7z,45,62,0|uegm80,46,63,1|up9ffz,46,63,1|up9fg0,45,62,0|ux6ovz,45,62,0|ux6ow0,46,63,1|v7zi3z,46,63,1|v7zi40,45,62,0|vg9q7z,45,62,0|vg9q80,46,63,1|vqpkrz,46,63,1|vqpks0,45,62,0|vyzsvz,45,62,0|vyzsw0,46,63,1|w9fnfz,46,63,1|w9fng0,45,62,0|whpvjz,45,62,0|whpvk0,46,63,1|wsiorz,46,63,1|wsios0,45,62,0|x0fy7z,45,62,0|x0fy80,46,63,1|xb8rfz,46,63,1|xb8rg0,45,62,0|xj60vz,45,62,0|xj60w0,46,63,1|xtyu3z,46,63,1|xtyu40,45,62,0|y1w3jz,45,62,0|y1w3k0,46,63,1|ycowrz,46,63,1|ycows0,45,62,0|ykz4vz,45,62,0|ykz4w0,46,63,1|yvezfz,46,63,1|yvezg0,45,62,0|z3p7jz,45,62,0|z3p7k0,46,63,1|ze523z,46,63,1|ze5240,45,62,0\",\"America/Montevideo|,0,146,0|-w4mll9,21,146,0|-px809a,21,146,0|-px8099,42,42,0|-o50vk1,42,42,0|-o50vk0,39,44,1|-nvm2c1,39,44,1|-nvm2c0,81,101,0|-nm74y1,81,101,0|-nm74y0,39,44,1|-ncu501,39,44,1|-ncu500,81,101,0|-n3f7m1,81,101,0|-n3f7m0,39,44,1|-mu27o1,39,44,1|-mu27o0,81,101,0|-ivo8y1,81,101,0|-ivo8y0,39,44,1|-inr3o1,39,44,1|-inr3o0,81,101,0|-icy6a1,81,101,0|-icy6a0,39,44,1|-i51101,39,44,1|-i51100,81,101,0|-hu83m1,81,101,0|-hu83m0,39,44,1|-hmayc1,39,44,1|-hmayc0,81,101,0|-hbi0y1,81,101,0|-hbi0y0,39,44,1|-h3kvo1,39,44,1|-h3kvo0,81,101,0|-gsezm1,81,101,0|-gsezm0,39,44,1|-gkut01,39,44,1|-gkut00,81,101,0|-g9owy1,81,101,0|-g9owy0,39,44,1|-g24qc1,39,44,1|-g24qc0,81,101,0|-fseoy1,81,101,0|-fseoy0,39,44,1|-fj1p01,39,44,1|-fj1p00,81,101,0|-f88rm1,81,101,0|-f88rm0,39,44,1|-f0bmc1,39,44,1|-f0bmc0,81,101,0|-etxya1,81,101,0|-etxya0,39,44,1|-e482c1,39,44,1|-e482c0,82,102,1|-dzlfq1,82,102,1|-dzlfq0,39,44,0|-5jbp01,39,44,0|-5jbp00,82,102,1|-5abnq1,82,102,1|-5abnq0,39,44,0|-572yc1,39,44,0|-572yc0,40,45,1|-54kag1,40,45,1|-54kag0,39,44,0|-2h5101,39,44,0|-2h5100,40,45,1|-285141,40,45,1|-285140,39,44,0|-u1901,39,44,0|-u1900,82,102,1|-kd521,82,102,1|-kd520,39,44,0|5vcbz,39,44,0|5vcc0,40,45,1|8fuvz,40,45,1|8fuw0,39,44,0|17dcbz,39,44,0|17dcc0,40,45,1|1botjz,40,45,1|1botk0,39,44,0|23s0bz,39,44,0|23s0c0,83,147,1|26nlhz,83,147,1|26nli0,82,102,1|2fnqxz,82,102,1|2fnqy0,39,44,0|2lf6zz,39,44,0|2lf700,40,45,1|2qgljz,40,45,1|2qglk0,39,44,0|3mvcbz,39,44,0|3mvcc0,40,45,1|3qtuvz,40,45,1|3qtuw0,39,44,0|44vhnz,39,44,0|44vho0,40,45,1|49jxjz,40,45,1|49jxk0,39,44,0|4obhnz,39,44,0|4obho0,40,45,1|4sa07z,40,45,1|4sa080,39,44,0|4v5sbz,39,44,0|4v5sc0,40,45,1|5bq07z,40,45,1|5bq080,39,44,0|9d8yzz,39,44,0|9d8z00,40,45,1|9h5mvz,40,45,1|9h5mw0,39,44,0|9vx6zz,39,44,0|9vx700,40,45,1|a08o7z,40,45,1|a08o80,39,44,0|achhnz,39,44,0|achho0,40,45,1|ails7z,40,45,1|ails80,39,44,0|auulnz,39,44,0|auulo0,40,45,1|b1otjz,40,45,1|b1otk0,39,44,0|bdxmzz,39,44,0|bdxn00,40,45,1|bkew7z,40,45,1|bkew80,39,44,0|bwaqzz,39,44,0|bwar00,40,45,1|c34yvz,40,45,1|c34yw0,39,44,0|i49pnz,39,44,0|i49po0,40,45,1|idzsfz,40,45,1|idzsg0,39,44,0|io2tvz,39,44,0|io2tw0,40,45,1|ivzxrz,40,45,1|ivzxs0,39,44,0|j6fxvz,39,44,0|j6fxw0,40,45,1|jeq0fz,40,45,1|jeq0g0,39,44,0|jpiz7z,39,44,0|jpiz80,40,45,1|jxg33z,40,45,1|jxg340,39,44,0|k891vz,39,44,0|k891w0,40,45,1|kg65rz,40,45,1|kg65s0,39,44,0|kqz4jz,39,44,0|kqz4k0,40,45,1|kz973z,40,45,1|kz9740,39,44,0|l9p77z,39,44,0|l9p780,40,45,1|lhz9rz,40,45,1|lhz9s0,39,44,0|lsf9vz,39,44,0|lsf9w0,40,45,1|m0pcfz,40,45,1|m0pcg0,39,44,0|mbib7z,39,44,0|mbib80,40,45,1|mjff3z,40,45,1|mjff40,39,44,0|mu8dvz,39,44,0|mu8dw0,40,45,1|n25hrz,40,45,1|n25hs0,39,44,0|ncygjz,39,44,0|ncygk0,40,45,1|nkvkfz,40,45,1|nkvkg0,39,44,0\",\"America/Montserrat|,0,41,0|-u6m79w,32,42,0\",\"America/Nassau|,0,148,0|-u6m4c6,49,63,0|-efufg1,49,63,0|-efufg0,70,42,1|-d1oy81,70,42,1|-d1oy80,49,63,0|-d03gs1,49,63,0|-d03gs0,70,42,1|-cq2tg1,70,42,1|-cq2tg0,71,42,1|-cmrww1,71,42,1|-cmrww0,49,63,0|-2yrwk1,49,63,0|-2yrwk0,62,42,1|-2pey01,62,42,1|-2pey00,49,63,0|-2g1tw1,49,63,0|-2g1tw0,62,42,1|-26bwo1,62,42,1|-26bwo0,49,63,0|-1xbr81,49,63,0|-1xbr80,62,42,1|-1nlu01,62,42,1|-1nlu00,49,63,0|-1e8pw1,49,63,0|-1e8pw0,62,42,1|-14vrc1,62,42,1|-14vrc0,49,63,0|-vin81,49,63,0|-vin80,62,42,1|-m5oo1,62,42,1|-m5oo0,49,63,0|-cskk1,49,63,0|-cskk0,62,42,1|-3fm01,62,42,1|-3fm00,49,63,0|5xi3z,49,63,0|5xi40,62,42,1|fagnz,62,42,1|fago0,49,63,0|onkrz,49,63,0|onks0,62,42,1|ydhzz,62,42,1|ydi00,49,63,0|17qm3z,49,63,0|17qm40,62,42,1|1h3knz,62,42,1|1h3ko0,49,63,0|1qgorz,49,63,0|1qgos0,62,42,1|1ztnbz,62,42,1|1ztnc0,49,63,0|296rfz,49,63,0|296rg0,62,42,1|2ijpzz,62,42,1|2ijq00,49,63,0|2rwu3z,49,63,0|2rwu40,62,42,1|319snz,62,42,1|319so0,49,63,0|3amwrz,49,63,0|3amws0,62,42,1|3kctzz,62,42,1|3kcu00,49,63,0|3tczfz,49,63,0|3tczg0,62,42,1|432wnz,62,42,1|432wo0,49,63,0|4cg0rz,49,63,0|4cg0s0,62,42,1|4lszbz,62,42,1|4lszc0,49,63,0|4v63fz,49,63,0|4v63g0,62,42,1|54j1zz,62,42,1|54j200,49,63,0|5dw63z,49,63,0|5dw640,62,42,1|5n94nz,62,42,1|5n94o0,49,63,0|5wm8rz,49,63,0|5wm8s0,62,42,1|65z7bz,62,42,1|65z7c0,49,63,0|6fcbfz,49,63,0|6fcbg0,62,42,1|6p28nz,62,42,1|6p28o0,49,63,0|6y2e3z,49,63,0|6y2e40,62,42,1|77sbbz,62,42,1|77sbc0,49,63,0|7h5ffz,49,63,0|7h5fg0,62,42,1|7qidzz,62,42,1|7qie00,49,63,0|7zvi3z,49,63,0|7zvi40,62,42,1|898gnz,62,42,1|898go0,49,63,0|8ilkrz,49,63,0|8ilks0,62,42,1|8ryjbz,62,42,1|8ryjc0,49,63,0|908rfz,49,63,0|908rg0,62,42,1|9aolzz,62,42,1|9aom00,49,63,0|9iyu3z,49,63,0|9iyu40,62,42,1|9trnbz,62,42,1|9trnc0,49,63,0|a1owrz,49,63,0|a1ows0,62,42,1|achpzz,62,42,1|achq00,49,63,0|akezfz,49,63,0|akezg0,62,42,1|av7snz,62,42,1|av7so0,49,63,0|b3i0rz,49,63,0|b3i0s0,62,42,1|bdxvbz,62,42,1|bdxvc0,49,63,0|bm83fz,49,63,0|bm83g0,62,42,1|bwnxzz,62,42,1|bwny00,49,63,0|c4y63z,49,63,0|c4y640,62,42,1|cfqzbz,62,42,1|cfqzc0,49,63,0|cno8rz,49,63,0|cno8s0,62,42,1|cyh1zz,62,42,1|cyh200,49,63,0|d6ebfz,49,63,0|d6ebg0,62,42,1|dh74nz,62,42,1|dh74o0,49,63,0|dphcrz,49,63,0|dphcs0,62,42,1|dzx7bz,62,42,1|dzx7c0,49,63,0|e87ffz,49,63,0|e87fg0,62,42,1|ein9zz,62,42,1|eina00,49,63,0|eqxi3z,49,63,0|eqxi40,62,42,1|f1dcnz,62,42,1|f1dco0,49,63,0|f9nkrz,49,63,0|f9nks0,62,42,1|fkgdzz,62,42,1|fkge00,49,63,0|fsdnfz,49,63,0|fsdng0,62,42,1|g36gnz,62,42,1|g36go0,49,63,0|gb3q3z,49,63,0|gb3q40,62,42,1|glwjbz,62,42,1|glwjc0,49,63,0|gu6rfz,49,63,0|gu6rg0,62,42,1|h4mlzz,62,42,1|h4mm00,49,63,0|hcwu3z,49,63,0|hcwu40,62,42,1|hnconz,62,42,1|hncoo0,49,63,0|hvmwrz,49,63,0|hvmws0,62,42,1|i6fpzz,62,42,1|i6fq00,49,63,0|ieczfz,49,63,0|ieczg0,62,42,1|ip5snz,62,42,1|ip5so0,49,63,0|ix323z,49,63,0|ix3240,62,42,1|j7vvbz,62,42,1|j7vvc0,49,63,0|jeq8rz,49,63,0|jeq8s0,62,42,1|jqywnz,62,42,1|jqywo0,49,63,0|jxgbfz,49,63,0|jxgbg0,62,42,1|k9ozbz,62,42,1|k9ozc0,49,63,0|kg6e3z,49,63,0|kg6e40,62,42,1|ksf1zz,62,42,1|ksf200,49,63,0|kz9ffz,49,63,0|kz9fg0,62,42,1|lbi3bz,62,42,1|lbi3c0,49,63,0|lhzi3z,49,63,0|lhzi40,62,42,1|lu85zz,62,42,1|lu8600,49,63,0|m0pkrz,49,63,0|m0pks0,62,42,1|mcy8nz,62,42,1|mcy8o0,49,63,0|mjfnfz,49,63,0|mjfng0,62,42,1|mvobbz,62,42,1|mvobc0,49,63,0|n25q3z,49,63,0|n25q40,62,42,1|needzz,62,42,1|neee00,49,63,0|nkvsrz,49,63,0|nkvss0,62,42,1|nx4gnz,62,42,1|nx4go0,49,63,0|o3yu3z,49,63,0|o3yu40,62,42,1|og7hzz,62,42,1|og7i00,49,63,0|omowrz,49,63,0|omows0,62,42,1|oyxknz,62,42,1|oyxko0,49,63,0|p5ezfz,49,63,0|p5ezg0,62,42,1|phnnbz,62,42,1|phnnc0,49,63,0|po523z,49,63,0|po5240,62,42,1|q0dpzz,62,42,1|q0dq00,49,63,0|q6v4rz,49,63,0|q6v4s0,62,42,1|qj3snz,62,42,1|qj3so0,49,63,0|qpy63z,49,63,0|qpy640,62,42,1|r26tzz,62,42,1|r26u00,49,63,0|r8o8rz,49,63,0|r8o8s0,62,42,1|rkwwnz,62,42,1|rkwwo0,49,63,0|rrebfz,49,63,0|rrebg0,62,42,1|s3mzbz,62,42,1|s3mzc0,49,63,0|sa4e3z,49,63,0|sa4e40,62,42,1|smd1zz,62,42,1|smd200,49,63,0|ssugrz,49,63,0|ssugs0,62,42,1|t534nz,62,42,1|t534o0,49,63,0|tbkjfz,49,63,0|tbkjg0,62,42,1|tnt7bz,62,42,1|tnt7c0,49,63,0|tunkrz,49,63,0|tunks0,62,42,1|u6w8nz,62,42,1|u6w8o0,49,63,0|uddnfz,49,63,0|uddng0,62,42,1|upmbbz,62,42,1|upmbc0,49,63,0|uw3q3z,49,63,0|uw3q40,62,42,1|v8cdzz,62,42,1|v8ce00,49,63,0|vetsrz,49,63,0|vetss0,62,42,1|vr2gnz,62,42,1|vr2go0,49,63,0|vxjvfz,49,63,0|vxjvg0,62,42,1|w9sjbz,62,42,1|w9sjc0,49,63,0|wgmwrz,49,63,0|wgmws0,62,42,1|wsvknz,62,42,1|wsvko0,49,63,0|wzczfz,49,63,0|wzczg0,62,42,1|xblnbz,62,42,1|xblnc0,49,63,0|xi323z,49,63,0|xi3240,62,42,1|xubpzz,62,42,1|xubq00,49,63,0|y0t4rz,49,63,0|y0t4s0,62,42,1|yd1snz,62,42,1|yd1so0,49,63,0|yjj7fz,49,63,0|yjj7g0,62,42,1|yvrvbz,62,42,1|yvrvc0,49,63,0|z29a3z,49,63,0|z29a40,62,42,1|zehxzz,62,42,1|zehy00,49,63,0\",\"America/New_York|,0,149,0|-18y0os0,49,63,0|-r0ev81,49,63,0|-r0ev80,62,42,1|-qpm201,62,42,1|-qpm200,49,63,0|-qhosk1,49,63,0|-qhosk0,62,42,1|-q6vzc1,62,42,1|-q6vzc0,49,63,0|-pyypw1,49,63,0|-pyypw0,62,42,1|-pnsy01,62,42,1|-pnsy00,49,63,0|-pessk1,49,63,0|-pessk0,62,42,1|-p6voo1,62,42,1|-p6voo0,49,63,0|-ovpr81,49,63,0|-ovpr80,62,42,1|-oo5m01,62,42,1|-oo5m00,49,63,0|-oczok1,49,63,0|-oczok0,62,42,1|-o52ko1,62,42,1|-o52ko0,49,63,0|-nu9lw1,49,63,0|-nu9lw0,62,42,1|-nmci01,62,42,1|-nmci00,49,63,0|-nbjj81,49,63,0|-nbjj80,62,42,1|-n3mfc1,62,42,1|-n3mfc0,49,63,0|-mstgk1,49,63,0|-mstgk0,62,42,1|-mkwco1,62,42,1|-mkwco0,49,63,0|-ma3dw1,49,63,0|-ma3dw0,62,42,1|-m26a01,62,42,1|-m26a00,49,63,0|-lr0ck1,49,63,0|-lr0ck0,62,42,1|-lj38o1,62,42,1|-lj38o0,49,63,0|-l8a9w1,49,63,0|-l8a9w0,62,42,1|-l0d601,62,42,1|-l0d600,49,63,0|-kpk781,49,63,0|-kpk780,62,42,1|-khn3c1,62,42,1|-khn3c0,49,63,0|-k6u4k1,49,63,0|-k6u4k0,62,42,1|-jyx0o1,62,42,1|-jyx0o0,49,63,0|-jo41w1,49,63,0|-jo41w0,62,42,1|-jg6y01,62,42,1|-jg6y00,49,63,0|-j510k1,49,63,0|-j510k0,62,42,1|-ixgvc1,62,42,1|-ixgvc0,49,63,0|-imaxw1,49,63,0|-imaxw0,62,42,1|-iedu01,62,42,1|-iedu00,49,63,0|-i3kv81,49,63,0|-i3kv80,62,42,1|-hvnrc1,62,42,1|-hvnrc0,49,63,0|-hkusk1,49,63,0|-hkusk0,62,42,1|-hcxoo1,62,42,1|-hcxoo0,49,63,0|-h24pw1,49,63,0|-h24pw0,62,42,1|-gu7m01,62,42,1|-gu7m00,49,63,0|-gjen81,49,63,0|-gjen80,62,42,1|-gbhjc1,62,42,1|-gbhjc0,49,63,0|-g0blw1,49,63,0|-g0blw0,62,42,1|-fsrgo1,62,42,1|-fsrgo0,49,63,0|-fhlj81,49,63,0|-fhlj80,62,42,1|-f9ofc1,62,42,1|-f9ofc0,49,63,0|-eyvgk1,49,63,0|-eyvgk0,62,42,1|-eqyco1,62,42,1|-eqyco0,49,63,0|-ek24k1,49,63,0|-ek24k0,70,42,1|-cq2tg1,70,42,1|-cq2tg0,71,42,1|-cnp3c1,71,42,1|-cnp3c0,49,63,0|-ccw4k1,49,63,0|-ccw4k0,62,42,1|-c4z0o1,62,42,1|-c4z0o0,49,63,0|-bu61w1,49,63,0|-bu61w0,62,42,1|-bm8y01,62,42,1|-bm8y00,49,63,0|-bbfz81,49,63,0|-bbfz80,62,42,1|-b3ivc1,62,42,1|-b3ivc0,49,63,0|-aspwk1,49,63,0|-aspwk0,62,42,1|-aksso1,62,42,1|-aksso0,49,63,0|-a9mv81,49,63,0|-a9mv80,62,42,1|-a22q01,62,42,1|-a22q00,49,63,0|-9qwsk1,49,63,0|-9qwsk0,62,42,1|-9izoo1,62,42,1|-9izoo0,49,63,0|-986pw1,49,63,0|-986pw0,62,42,1|-909m01,62,42,1|-909m00,49,63,0|-8pgn81,49,63,0|-8pgn80,62,42,1|-8hjjc1,62,42,1|-8hjjc0,49,63,0|-86qkk1,49,63,0|-86qkk0,62,42,1|-7ytgo1,62,42,1|-7ytgo0,49,63,0|-7o0hw1,49,63,0|-7o0hw0,62,42,1|-7eako1,62,42,1|-7eako0,49,63,0|-74xgk1,49,63,0|-74xgk0,62,42,1|-6vki01,62,42,1|-6vki00,49,63,0|-6m7dw1,49,63,0|-6m7dw0,62,42,1|-6cufc1,62,42,1|-6cufc0,49,63,0|-63hb81,49,63,0|-63hb80,62,42,1|-5u4co1,62,42,1|-5u4co0,49,63,0|-5kr8k1,49,63,0|-5kr8k0,62,42,1|-5bea01,62,42,1|-5bea00,49,63,0|-5215w1,49,63,0|-5215w0,62,42,1|-4sb8o1,62,42,1|-4sb8o0,49,63,0|-4iy4k1,49,63,0|-4iy4k0,62,42,1|-49l601,62,42,1|-49l600,49,63,0|-4081w1,49,63,0|-4081w0,62,42,1|-3qv3c1,62,42,1|-3qv3c0,49,63,0|-3hhz81,49,63,0|-3hhz80,62,42,1|-3850o1,62,42,1|-3850o0,49,63,0|-2yrwk1,49,63,0|-2yrwk0,62,42,1|-2pey01,62,42,1|-2pey00,49,63,0|-2g1tw1,49,63,0|-2g1tw0,62,42,1|-26bwo1,62,42,1|-26bwo0,49,63,0|-1xbr81,49,63,0|-1xbr80,62,42,1|-1nlu01,62,42,1|-1nlu00,49,63,0|-1e8pw1,49,63,0|-1e8pw0,62,42,1|-14vrc1,62,42,1|-14vrc0,49,63,0|-vin81,49,63,0|-vin80,62,42,1|-m5oo1,62,42,1|-m5oo0,49,63,0|-cskk1,49,63,0|-cskk0,62,42,1|-3fm01,62,42,1|-3fm00,49,63,0|5xi3z,49,63,0|5xi40,62,42,1|fagnz,62,42,1|fago0,49,63,0|onkrz,49,63,0|onks0,62,42,1|ydhzz,62,42,1|ydi00,49,63,0|17qm3z,49,63,0|17qm40,62,42,1|1h3knz,62,42,1|1h3ko0,49,63,0|1qgorz,49,63,0|1qgos0,62,42,1|1ztnbz,62,42,1|1ztnc0,49,63,0|23fcrz,49,63,0|23fcs0,62,42,1|2ijpzz,62,42,1|2ijq00,49,63,0|2oo63z,49,63,0|2oo640,62,42,1|319snz,62,42,1|319so0,49,63,0|3amwrz,49,63,0|3amws0,62,42,1|3kctzz,62,42,1|3kcu00,49,63,0|3tczfz,49,63,0|3tczg0,62,42,1|432wnz,62,42,1|432wo0,49,63,0|4cg0rz,49,63,0|4cg0s0,62,42,1|4lszbz,62,42,1|4lszc0,49,63,0|4v63fz,49,63,0|4v63g0,62,42,1|54j1zz,62,42,1|54j200,49,63,0|5dw63z,49,63,0|5dw640,62,42,1|5n94nz,62,42,1|5n94o0,49,63,0|5wm8rz,49,63,0|5wm8s0,62,42,1|65z7bz,62,42,1|65z7c0,49,63,0|6fcbfz,49,63,0|6fcbg0,62,42,1|6p28nz,62,42,1|6p28o0,49,63,0|6y2e3z,49,63,0|6y2e40,62,42,1|77sbbz,62,42,1|77sbc0,49,63,0|7h5ffz,49,63,0|7h5fg0,62,42,1|7qidzz,62,42,1|7qie00,49,63,0|7zvi3z,49,63,0|7zvi40,62,42,1|898gnz,62,42,1|898go0,49,63,0|8ilkrz,49,63,0|8ilks0,62,42,1|8ryjbz,62,42,1|8ryjc0,49,63,0|908rfz,49,63,0|908rg0,62,42,1|9aolzz,62,42,1|9aom00,49,63,0|9iyu3z,49,63,0|9iyu40,62,42,1|9trnbz,62,42,1|9trnc0,49,63,0|a1owrz,49,63,0|a1ows0,62,42,1|achpzz,62,42,1|achq00,49,63,0|akezfz,49,63,0|akezg0,62,42,1|av7snz,62,42,1|av7so0,49,63,0|b3i0rz,49,63,0|b3i0s0,62,42,1|bdxvbz,62,42,1|bdxvc0,49,63,0|bm83fz,49,63,0|bm83g0,62,42,1|bwnxzz,62,42,1|bwny00,49,63,0|c4y63z,49,63,0|c4y640,62,42,1|cfqzbz,62,42,1|cfqzc0,49,63,0|cno8rz,49,63,0|cno8s0,62,42,1|cyh1zz,62,42,1|cyh200,49,63,0|d6ebfz,49,63,0|d6ebg0,62,42,1|dh74nz,62,42,1|dh74o0,49,63,0|dphcrz,49,63,0|dphcs0,62,42,1|dzx7bz,62,42,1|dzx7c0,49,63,0|e87ffz,49,63,0|e87fg0,62,42,1|ein9zz,62,42,1|eina00,49,63,0|eqxi3z,49,63,0|eqxi40,62,42,1|f1dcnz,62,42,1|f1dco0,49,63,0|f9nkrz,49,63,0|f9nks0,62,42,1|fkgdzz,62,42,1|fkge00,49,63,0|fsdnfz,49,63,0|fsdng0,62,42,1|g36gnz,62,42,1|g36go0,49,63,0|gb3q3z,49,63,0|gb3q40,62,42,1|glwjbz,62,42,1|glwjc0,49,63,0|gu6rfz,49,63,0|gu6rg0,62,42,1|h4mlzz,62,42,1|h4mm00,49,63,0|hcwu3z,49,63,0|hcwu40,62,42,1|hnconz,62,42,1|hncoo0,49,63,0|hvmwrz,49,63,0|hvmws0,62,42,1|i6fpzz,62,42,1|i6fq00,49,63,0|ieczfz,49,63,0|ieczg0,62,42,1|ip5snz,62,42,1|ip5so0,49,63,0|ix323z,49,63,0|ix3240,62,42,1|j7vvbz,62,42,1|j7vvc0,49,63,0|jeq8rz,49,63,0|jeq8s0,62,42,1|jqywnz,62,42,1|jqywo0,49,63,0|jxgbfz,49,63,0|jxgbg0,62,42,1|k9ozbz,62,42,1|k9ozc0,49,63,0|kg6e3z,49,63,0|kg6e40,62,42,1|ksf1zz,62,42,1|ksf200,49,63,0|kz9ffz,49,63,0|kz9fg0,62,42,1|lbi3bz,62,42,1|lbi3c0,49,63,0|lhzi3z,49,63,0|lhzi40,62,42,1|lu85zz,62,42,1|lu8600,49,63,0|m0pkrz,49,63,0|m0pks0,62,42,1|mcy8nz,62,42,1|mcy8o0,49,63,0|mjfnfz,49,63,0|mjfng0,62,42,1|mvobbz,62,42,1|mvobc0,49,63,0|n25q3z,49,63,0|n25q40,62,42,1|needzz,62,42,1|neee00,49,63,0|nkvsrz,49,63,0|nkvss0,62,42,1|nx4gnz,62,42,1|nx4go0,49,63,0|o3yu3z,49,63,0|o3yu40,62,42,1|og7hzz,62,42,1|og7i00,49,63,0|omowrz,49,63,0|omows0,62,42,1|oyxknz,62,42,1|oyxko0,49,63,0|p5ezfz,49,63,0|p5ezg0,62,42,1|phnnbz,62,42,1|phnnc0,49,63,0|po523z,49,63,0|po5240,62,42,1|q0dpzz,62,42,1|q0dq00,49,63,0|q6v4rz,49,63,0|q6v4s0,62,42,1|qj3snz,62,42,1|qj3so0,49,63,0|qpy63z,49,63,0|qpy640,62,42,1|r26tzz,62,42,1|r26u00,49,63,0|r8o8rz,49,63,0|r8o8s0,62,42,1|rkwwnz,62,42,1|rkwwo0,49,63,0|rrebfz,49,63,0|rrebg0,62,42,1|s3mzbz,62,42,1|s3mzc0,49,63,0|sa4e3z,49,63,0|sa4e40,62,42,1|smd1zz,62,42,1|smd200,49,63,0|ssugrz,49,63,0|ssugs0,62,42,1|t534nz,62,42,1|t534o0,49,63,0|tbkjfz,49,63,0|tbkjg0,62,42,1|tnt7bz,62,42,1|tnt7c0,49,63,0|tunkrz,49,63,0|tunks0,62,42,1|u6w8nz,62,42,1|u6w8o0,49,63,0|uddnfz,49,63,0|uddng0,62,42,1|upmbbz,62,42,1|upmbc0,49,63,0|uw3q3z,49,63,0|uw3q40,62,42,1|v8cdzz,62,42,1|v8ce00,49,63,0|vetsrz,49,63,0|vetss0,62,42,1|vr2gnz,62,42,1|vr2go0,49,63,0|vxjvfz,49,63,0|vxjvg0,62,42,1|w9sjbz,62,42,1|w9sjc0,49,63,0|wgmwrz,49,63,0|wgmws0,62,42,1|wsvknz,62,42,1|wsvko0,49,63,0|wzczfz,49,63,0|wzczg0,62,42,1|xblnbz,62,42,1|xblnc0,49,63,0|xi323z,49,63,0|xi3240,62,42,1|xubpzz,62,42,1|xubq00,49,63,0|y0t4rz,49,63,0|y0t4s0,62,42,1|yd1snz,62,42,1|yd1so0,49,63,0|yjj7fz,49,63,0|yjj7g0,62,42,1|yvrvbz,62,42,1|yvrvc0,49,63,0|z29a3z,49,63,0|z29a40,62,42,1|zehxzz,62,42,1|zehy00,49,63,0\",\"America/Nipigon|,0,150,0|-1353bnk,49,63,0|-qzoxw1,49,63,0|-qzoxw0,62,42,1|-qpm201,62,42,1|-qpm200,49,63,0|-f9oi41,49,63,0|-f9oi40,62,42,1|-ek24k1,62,42,1|-ek24k0,70,42,1|-cq2tg1,70,42,1|-cq2tg0,71,42,1|-cnp3c1,71,42,1|-cnp3c0,49,63,0|296rfz,49,63,0|296rg0,62,42,1|2ijpzz,62,42,1|2ijq00,49,63,0|2rwu3z,49,63,0|2rwu40,62,42,1|319snz,62,42,1|319so0,49,63,0|3amwrz,49,63,0|3amws0,62,42,1|3kctzz,62,42,1|3kcu00,49,63,0|3tczfz,49,63,0|3tczg0,62,42,1|432wnz,62,42,1|432wo0,49,63,0|4cg0rz,49,63,0|4cg0s0,62,42,1|4lszbz,62,42,1|4lszc0,49,63,0|4v63fz,49,63,0|4v63g0,62,42,1|54j1zz,62,42,1|54j200,49,63,0|5dw63z,49,63,0|5dw640,62,42,1|5n94nz,62,42,1|5n94o0,49,63,0|5wm8rz,49,63,0|5wm8s0,62,42,1|65z7bz,62,42,1|65z7c0,49,63,0|6fcbfz,49,63,0|6fcbg0,62,42,1|6p28nz,62,42,1|6p28o0,49,63,0|6y2e3z,49,63,0|6y2e40,62,42,1|77sbbz,62,42,1|77sbc0,49,63,0|7h5ffz,49,63,0|7h5fg0,62,42,1|7qidzz,62,42,1|7qie00,49,63,0|7zvi3z,49,63,0|7zvi40,62,42,1|898gnz,62,42,1|898go0,49,63,0|8ilkrz,49,63,0|8ilks0,62,42,1|8ryjbz,62,42,1|8ryjc0,49,63,0|908rfz,49,63,0|908rg0,62,42,1|9aolzz,62,42,1|9aom00,49,63,0|9iyu3z,49,63,0|9iyu40,62,42,1|9trnbz,62,42,1|9trnc0,49,63,0|a1owrz,49,63,0|a1ows0,62,42,1|achpzz,62,42,1|achq00,49,63,0|akezfz,49,63,0|akezg0,62,42,1|av7snz,62,42,1|av7so0,49,63,0|b3i0rz,49,63,0|b3i0s0,62,42,1|bdxvbz,62,42,1|bdxvc0,49,63,0|bm83fz,49,63,0|bm83g0,62,42,1|bwnxzz,62,42,1|bwny00,49,63,0|c4y63z,49,63,0|c4y640,62,42,1|cfqzbz,62,42,1|cfqzc0,49,63,0|cno8rz,49,63,0|cno8s0,62,42,1|cyh1zz,62,42,1|cyh200,49,63,0|d6ebfz,49,63,0|d6ebg0,62,42,1|dh74nz,62,42,1|dh74o0,49,63,0|dphcrz,49,63,0|dphcs0,62,42,1|dzx7bz,62,42,1|dzx7c0,49,63,0|e87ffz,49,63,0|e87fg0,62,42,1|ein9zz,62,42,1|eina00,49,63,0|eqxi3z,49,63,0|eqxi40,62,42,1|f1dcnz,62,42,1|f1dco0,49,63,0|f9nkrz,49,63,0|f9nks0,62,42,1|fkgdzz,62,42,1|fkge00,49,63,0|fsdnfz,49,63,0|fsdng0,62,42,1|g36gnz,62,42,1|g36go0,49,63,0|gb3q3z,49,63,0|gb3q40,62,42,1|glwjbz,62,42,1|glwjc0,49,63,0|gu6rfz,49,63,0|gu6rg0,62,42,1|h4mlzz,62,42,1|h4mm00,49,63,0|hcwu3z,49,63,0|hcwu40,62,42,1|hnconz,62,42,1|hncoo0,49,63,0|hvmwrz,49,63,0|hvmws0,62,42,1|i6fpzz,62,42,1|i6fq00,49,63,0|ieczfz,49,63,0|ieczg0,62,42,1|ip5snz,62,42,1|ip5so0,49,63,0|ix323z,49,63,0|ix3240,62,42,1|j7vvbz,62,42,1|j7vvc0,49,63,0|jeq8rz,49,63,0|jeq8s0,62,42,1|jqywnz,62,42,1|jqywo0,49,63,0|jxgbfz,49,63,0|jxgbg0,62,42,1|k9ozbz,62,42,1|k9ozc0,49,63,0|kg6e3z,49,63,0|kg6e40,62,42,1|ksf1zz,62,42,1|ksf200,49,63,0|kz9ffz,49,63,0|kz9fg0,62,42,1|lbi3bz,62,42,1|lbi3c0,49,63,0|lhzi3z,49,63,0|lhzi40,62,42,1|lu85zz,62,42,1|lu8600,49,63,0|m0pkrz,49,63,0|m0pks0,62,42,1|mcy8nz,62,42,1|mcy8o0,49,63,0|mjfnfz,49,63,0|mjfng0,62,42,1|mvobbz,62,42,1|mvobc0,49,63,0|n25q3z,49,63,0|n25q40,62,42,1|needzz,62,42,1|neee00,49,63,0|nkvsrz,49,63,0|nkvss0,62,42,1|nx4gnz,62,42,1|nx4go0,49,63,0|o3yu3z,49,63,0|o3yu40,62,42,1|og7hzz,62,42,1|og7i00,49,63,0|omowrz,49,63,0|omows0,62,42,1|oyxknz,62,42,1|oyxko0,49,63,0|p5ezfz,49,63,0|p5ezg0,62,42,1|phnnbz,62,42,1|phnnc0,49,63,0|po523z,49,63,0|po5240,62,42,1|q0dpzz,62,42,1|q0dq00,49,63,0|q6v4rz,49,63,0|q6v4s0,62,42,1|qj3snz,62,42,1|qj3so0,49,63,0|qpy63z,49,63,0|qpy640,62,42,1|r26tzz,62,42,1|r26u00,49,63,0|r8o8rz,49,63,0|r8o8s0,62,42,1|rkwwnz,62,42,1|rkwwo0,49,63,0|rrebfz,49,63,0|rrebg0,62,42,1|s3mzbz,62,42,1|s3mzc0,49,63,0|sa4e3z,49,63,0|sa4e40,62,42,1|smd1zz,62,42,1|smd200,49,63,0|ssugrz,49,63,0|ssugs0,62,42,1|t534nz,62,42,1|t534o0,49,63,0|tbkjfz,49,63,0|tbkjg0,62,42,1|tnt7bz,62,42,1|tnt7c0,49,63,0|tunkrz,49,63,0|tunks0,62,42,1|u6w8nz,62,42,1|u6w8o0,49,63,0|uddnfz,49,63,0|uddng0,62,42,1|upmbbz,62,42,1|upmbc0,49,63,0|uw3q3z,49,63,0|uw3q40,62,42,1|v8cdzz,62,42,1|v8ce00,49,63,0|vetsrz,49,63,0|vetss0,62,42,1|vr2gnz,62,42,1|vr2go0,49,63,0|vxjvfz,49,63,0|vxjvg0,62,42,1|w9sjbz,62,42,1|w9sjc0,49,63,0|wgmwrz,49,63,0|wgmws0,62,42,1|wsvknz,62,42,1|wsvko0,49,63,0|wzczfz,49,63,0|wzczg0,62,42,1|xblnbz,62,42,1|xblnc0,49,63,0|xi323z,49,63,0|xi3240,62,42,1|xubpzz,62,42,1|xubq00,49,63,0|y0t4rz,49,63,0|y0t4s0,62,42,1|yd1snz,62,42,1|yd1so0,49,63,0|yjj7fz,49,63,0|yjj7g0,62,42,1|yvrvbz,62,42,1|yvrvc0,49,63,0|z29a3z,49,63,0|z29a40,62,42,1|zehxzz,62,42,1|zehy00,49,63,0\",\"America/Nome|,0,151,0|-1hc7qjz,0,152,0|-1078qpb,0,152,0|-1078qpa,24,35,0|-ek1nw1,24,35,0|-ek1nw0,25,36,1|-cq2tg1,25,36,1|-cq2tg0,26,36,1|-cnomo1,26,36,1|-cnomo0,24,35,0|-1fq441,24,35,0|-1fq440,27,35,0|-cs3w1,27,35,0|-cs3w0,28,36,1|-3f5c1,28,36,1|-3f5c0,27,35,0|5xyrz,27,35,0|5xys0,28,36,1|faxbz,28,36,1|faxc0,27,35,0|oo1fz,27,35,0|oo1g0,28,36,1|ydynz,28,36,1|ydyo0,27,35,0|17r2rz,27,35,0|17r2s0,28,36,1|1h41bz,28,36,1|1h41c0,27,35,0|1qh5fz,27,35,0|1qh5g0,28,36,1|1zu3zz,28,36,1|1zu400,27,35,0|23ftfz,27,35,0|23ftg0,28,36,1|2ik6nz,28,36,1|2ik6o0,27,35,0|2oomrz,27,35,0|2ooms0,28,36,1|31a9bz,28,36,1|31a9c0,27,35,0|3andfz,27,35,0|3andg0,28,36,1|3kdanz,28,36,1|3kdao0,27,35,0|3tdg3z,27,35,0|3tdg40,28,36,1|433dbz,28,36,1|433dc0,27,35,0|4cghfz,27,35,0|4cghg0,28,36,1|4ltfzz,28,36,1|4ltg00,27,35,0|4v6k3z,27,35,0|4v6k40,28,36,1|54jinz,28,36,1|54jio0,27,35,0|5dwmrz,27,35,0|5dwms0,28,36,1|5n9lbz,28,36,1|5n9lc0,27,35,0|5wmpfz,27,35,0|5wmpg0,28,36,1|65znzz,28,36,1|65zo00,27,35,0|6fcs3z,27,35,0|6fcs40,28,36,1|6p2pbz,28,36,1|6p2pc0,27,35,0|6y2urz,27,35,0|6y2us0,28,36,1|77srzz,28,36,1|77ss00,36,37,0|79dybz,36,37,0|79dyc0,37,37,0|7h5qjz,37,37,0|7h5qk0,38,40,1|7qip3z,38,40,1|7qip40,37,37,0|7zvt7z,37,37,0|7zvt80,38,40,1|898rrz,38,40,1|898rs0,37,37,0|8ilvvz,37,37,0|8ilvw0,38,40,1|8ryufz,38,40,1|8ryug0,37,37,0|9092jz,37,37,0|9092k0,38,40,1|9aox3z,38,40,1|9aox40,37,37,0|9iz57z,37,37,0|9iz580,38,40,1|9tryfz,38,40,1|9tryg0,37,37,0|a1p7vz,37,37,0|a1p7w0,38,40,1|aci13z,38,40,1|aci140,37,37,0|akfajz,37,37,0|akfak0,38,40,1|av83rz,38,40,1|av83s0,37,37,0|b3ibvz,37,37,0|b3ibw0,38,40,1|bdy6fz,38,40,1|bdy6g0,37,37,0|bm8ejz,37,37,0|bm8ek0,38,40,1|bwo93z,38,40,1|bwo940,37,37,0|c4yh7z,37,37,0|c4yh80,38,40,1|cfrafz,38,40,1|cfrag0,37,37,0|cnojvz,37,37,0|cnojw0,38,40,1|cyhd3z,38,40,1|cyhd40,37,37,0|d6emjz,37,37,0|d6emk0,38,40,1|dh7frz,38,40,1|dh7fs0,37,37,0|dphnvz,37,37,0|dphnw0,38,40,1|dzxifz,38,40,1|dzxig0,37,37,0|e87qjz,37,37,0|e87qk0,38,40,1|einl3z,38,40,1|einl40,37,37,0|eqxt7z,37,37,0|eqxt80,38,40,1|f1dnrz,38,40,1|f1dns0,37,37,0|f9nvvz,37,37,0|f9nvw0,38,40,1|fkgp3z,38,40,1|fkgp40,37,37,0|fsdyjz,37,37,0|fsdyk0,38,40,1|g36rrz,38,40,1|g36rs0,37,37,0|gb417z,37,37,0|gb4180,38,40,1|glwufz,38,40,1|glwug0,37,37,0|gu72jz,37,37,0|gu72k0,38,40,1|h4mx3z,38,40,1|h4mx40,37,37,0|hcx57z,37,37,0|hcx580,38,40,1|hnczrz,38,40,1|hnczs0,37,37,0|hvn7vz,37,37,0|hvn7w0,38,40,1|i6g13z,38,40,1|i6g140,37,37,0|iedajz,37,37,0|iedak0,38,40,1|ip63rz,38,40,1|ip63s0,37,37,0|ix3d7z,37,37,0|ix3d80,38,40,1|j7w6fz,38,40,1|j7w6g0,37,37,0|jeqjvz,37,37,0|jeqjw0,38,40,1|jqz7rz,38,40,1|jqz7s0,37,37,0|jxgmjz,37,37,0|jxgmk0,38,40,1|k9pafz,38,40,1|k9pag0,37,37,0|kg6p7z,37,37,0|kg6p80,38,40,1|ksfd3z,38,40,1|ksfd40,37,37,0|kz9qjz,37,37,0|kz9qk0,38,40,1|lbiefz,38,40,1|lbieg0,37,37,0|lhzt7z,37,37,0|lhzt80,38,40,1|lu8h3z,38,40,1|lu8h40,37,37,0|m0pvvz,37,37,0|m0pvw0,38,40,1|mcyjrz,38,40,1|mcyjs0,37,37,0|mjfyjz,37,37,0|mjfyk0,38,40,1|mvomfz,38,40,1|mvomg0,37,37,0|n2617z,37,37,0|n26180,38,40,1|neep3z,38,40,1|neep40,37,37,0|nkw3vz,37,37,0|nkw3w0,38,40,1|nx4rrz,38,40,1|nx4rs0,37,37,0|o3z57z,37,37,0|o3z580,38,40,1|og7t3z,38,40,1|og7t40,37,37,0|omp7vz,37,37,0|omp7w0,38,40,1|oyxvrz,38,40,1|oyxvs0,37,37,0|p5fajz,37,37,0|p5fak0,38,40,1|phnyfz,38,40,1|phnyg0,37,37,0|po5d7z,37,37,0|po5d80,38,40,1|q0e13z,38,40,1|q0e140,37,37,0|q6vfvz,37,37,0|q6vfw0,38,40,1|qj43rz,38,40,1|qj43s0,37,37,0|qpyh7z,37,37,0|qpyh80,38,40,1|r2753z,38,40,1|r27540,37,37,0|r8ojvz,37,37,0|r8ojw0,38,40,1|rkx7rz,38,40,1|rkx7s0,37,37,0|rremjz,37,37,0|rremk0,38,40,1|s3nafz,38,40,1|s3nag0,37,37,0|sa4p7z,37,37,0|sa4p80,38,40,1|smdd3z,38,40,1|smdd40,37,37,0|ssurvz,37,37,0|ssurw0,38,40,1|t53frz,38,40,1|t53fs0,37,37,0|tbkujz,37,37,0|tbkuk0,38,40,1|tntifz,38,40,1|tntig0,37,37,0|tunvvz,37,37,0|tunvw0,38,40,1|u6wjrz,38,40,1|u6wjs0,37,37,0|uddyjz,37,37,0|uddyk0,38,40,1|upmmfz,38,40,1|upmmg0,37,37,0|uw417z,37,37,0|uw4180,38,40,1|v8cp3z,38,40,1|v8cp40,37,37,0|veu3vz,37,37,0|veu3w0,38,40,1|vr2rrz,38,40,1|vr2rs0,37,37,0|vxk6jz,37,37,0|vxk6k0,38,40,1|w9sufz,38,40,1|w9sug0,37,37,0|wgn7vz,37,37,0|wgn7w0,38,40,1|wsvvrz,38,40,1|wsvvs0,37,37,0|wzdajz,37,37,0|wzdak0,38,40,1|xblyfz,38,40,1|xblyg0,37,37,0|xi3d7z,37,37,0|xi3d80,38,40,1|xuc13z,38,40,1|xuc140,37,37,0|y0tfvz,37,37,0|y0tfw0,38,40,1|yd23rz,38,40,1|yd23s0,37,37,0|yjjijz,37,37,0|yjjik0,38,40,1|yvs6fz,38,40,1|yvs6g0,37,37,0|z29l7z,37,37,0|z29l80,38,40,1|zei93z,38,40,1|zei940,37,37,0\",\"America/Noronha|,0,153,0|-t85lzw,40,45,0|-jyld81,40,45,0|-jyld80,13,15,1|-jpb3w1,13,15,1|-jpb3w0,40,45,0|-jfsfs1,40,45,0|-jfsfs0,13,15,1|-j6j6k1,13,15,1|-j6j6k0,40,45,0|-ahd141,40,45,0|-ahd140,13,15,1|-aad6g1,13,15,1|-aad6g0,40,45,0|-9yl3s1,40,45,0|-9yl3s0,13,15,1|-9sd3w1,13,15,1|-9sd3w0,40,45,0|-9ft6g1,40,45,0|-9ft6g0,13,15,1|-99jbw1,13,15,1|-99jbw0,40,45,0|-8wzeg1,40,45,0|-8wzeg0,13,15,1|-8sct81,13,15,1|-8sct80,40,45,0|-35xp41,40,45,0|-35xp40,13,15,1|-31o2k1,13,15,1|-31o2k0,40,45,0|-2kdrs1,40,45,0|-2kdrs0,13,15,1|-2hcl81,13,15,1|-2hcl80,40,45,0|-24qt41,40,45,0|-24qt40,13,15,1|-2047w1,13,15,1|-2047w0,40,45,0|-1nifs1,40,45,0|-1nifs0,13,15,1|-1hcak1,13,15,1|-1hcak0,40,45,0|-14qig1,40,45,0|-14qig0,13,15,1|-yiik1,13,15,1|-yiik0,40,45,0|89j9jz,40,45,0|89j9k0,13,15,1|8gdhfz,13,15,1|8gdhg0,40,45,0|8rwdjz,40,45,0|8rwdk0,13,15,1|8xnpfz,13,15,1|8xnpg0,40,45,0|9aoavz,40,45,0|9aoaw0,13,15,1|9g2o3z,13,15,1|9g2o40,40,45,0|9t1evz,40,45,0|9t1ew0,13,15,1|9yfs3z,13,15,1|9yfs40,40,45,0|abrhjz,40,45,0|abrhk0,13,15,1|ahvs3z,13,15,1|ahvs40,40,45,0|fj087z,40,45,0|fj0880,13,15,1|fqkdfz,13,15,1|fqkdg0,40,45,0|g239jz,40,45,0|g239k0,13,15,1|g2g5fz,13,15,1|g2g5g0,40,45,0|gl6avz,40,45,0|gl6aw0,13,15,1|grnk3z,13,15,1|grnk40,40,45,0\",\"America/North_Dakota/Beulah|,0,154,0|-18y0j80,50,66,0|-r0epo1,50,66,0|-r0epo0,52,62,1|-qplwg1,52,62,1|-qplwg0,50,66,0|-qhon01,50,66,0|-qhon00,52,62,1|-q6vts1,52,62,1|-q6vts0,50,66,0|-ek1z01,50,66,0|-ek1z00,58,62,1|-cq2tg1,58,62,1|-cq2tg0,59,62,1|-cnoxs1,59,62,1|-cnoxs0,50,66,0|-1e8kc1,50,66,0|-1e8kc0,52,62,1|-14vls1,52,62,1|-14vls0,50,66,0|-viho1,50,66,0|-viho0,52,62,1|-m5j41,52,62,1|-m5j40,50,66,0|-csf01,50,66,0|-csf00,52,62,1|-3fgg1,52,62,1|-3fgg0,50,66,0|5xnnz,50,66,0|5xno0,52,62,1|fam7z,52,62,1|fam80,50,66,0|onqbz,50,66,0|onqc0,52,62,1|ydnjz,52,62,1|ydnk0,50,66,0|17qrnz,50,66,0|17qro0,52,62,1|1h3q7z,52,62,1|1h3q80,50,66,0|1qgubz,50,66,0|1qguc0,52,62,1|1ztsvz,52,62,1|1ztsw0,50,66,0|23fibz,50,66,0|23fic0,52,62,1|2ijvjz,52,62,1|2ijvk0,50,66,0|2oobnz,50,66,0|2oobo0,52,62,1|319y7z,52,62,1|319y80,50,66,0|3an2bz,50,66,0|3an2c0,52,62,1|3kczjz,52,62,1|3kczk0,50,66,0|3td4zz,50,66,0|3td500,52,62,1|43327z,52,62,1|433280,50,66,0|4cg6bz,50,66,0|4cg6c0,52,62,1|4lt4vz,52,62,1|4lt4w0,50,66,0|4v68zz,50,66,0|4v6900,52,62,1|54j7jz,52,62,1|54j7k0,50,66,0|5dwbnz,50,66,0|5dwbo0,52,62,1|5n9a7z,52,62,1|5n9a80,50,66,0|5wmebz,50,66,0|5wmec0,52,62,1|65zcvz,52,62,1|65zcw0,50,66,0|6fcgzz,50,66,0|6fch00,52,62,1|6p2e7z,52,62,1|6p2e80,50,66,0|6y2jnz,50,66,0|6y2jo0,52,62,1|77sgvz,52,62,1|77sgw0,50,66,0|7h5kzz,50,66,0|7h5l00,52,62,1|7qijjz,52,62,1|7qijk0,50,66,0|7zvnnz,50,66,0|7zvno0,52,62,1|898m7z,52,62,1|898m80,50,66,0|8ilqbz,50,66,0|8ilqc0,52,62,1|8ryovz,52,62,1|8ryow0,50,66,0|908wzz,50,66,0|908x00,52,62,1|9aorjz,52,62,1|9aork0,50,66,0|9iyznz,50,66,0|9iyzo0,52,62,1|9trsvz,52,62,1|9trsw0,50,66,0|a1p2bz,50,66,0|a1p2c0,52,62,1|achvjz,52,62,1|achvk0,50,66,0|akf4zz,50,66,0|akf500,52,62,1|av7y7z,52,62,1|av7y80,50,66,0|b3i6bz,50,66,0|b3i6c0,52,62,1|bdy0vz,52,62,1|bdy0w0,50,66,0|bm88zz,50,66,0|bm8900,52,62,1|bwo3jz,52,62,1|bwo3k0,50,66,0|c4ybnz,50,66,0|c4ybo0,52,62,1|cfr4vz,52,62,1|cfr4w0,50,66,0|cnoebz,50,66,0|cnoec0,52,62,1|cyh7jz,52,62,1|cyh7k0,50,66,0|d6egzz,50,66,0|d6eh00,52,62,1|dh7a7z,52,62,1|dh7a80,50,66,0|dphibz,50,66,0|dphic0,52,62,1|dzxcvz,52,62,1|dzxcw0,50,66,0|e87kzz,50,66,0|e87l00,52,62,1|einfjz,52,62,1|einfk0,50,66,0|eqxnnz,50,66,0|eqxno0,52,62,1|f1di7z,52,62,1|f1di80,50,66,0|f9nqbz,50,66,0|f9nqc0,52,62,1|fkgjjz,52,62,1|fkgjk0,50,66,0|fsdszz,50,66,0|fsdt00,52,62,1|g36m7z,52,62,1|g36m80,50,66,0|gb3vnz,50,66,0|gb3vo0,52,62,1|glwovz,52,62,1|glwow0,50,66,0|gu6wzz,50,66,0|gu6x00,52,62,1|h4mrjz,52,62,1|h4mrk0,50,66,0|hcwznz,50,66,0|hcwzo0,52,62,1|hncu7z,52,62,1|hncu80,50,66,0|hvn2bz,50,66,0|hvn2c0,52,62,1|i6fvjz,52,62,1|i6fvk0,50,66,0|ied4zz,50,66,0|ied500,52,62,1|ip5y7z,52,62,1|ip5y80,50,66,0|ix37nz,50,66,0|ix37o0,52,62,1|j7w0vz,52,62,1|j7w0w0,50,66,0|jeqebz,50,66,0|jeqec0,52,62,1|jqz27z,52,62,1|jqz280,50,66,0|jxggzz,50,66,0|jxgh00,52,62,1|k9p4vz,52,62,1|k9p4w0,50,66,0|kg6jnz,50,66,0|kg6jo0,52,62,1|ksf7jz,52,62,1|ksf7k0,50,66,0|kz9kzz,50,66,0|kz9l00,52,62,1|lbi8vz,52,62,1|lbi8w0,45,62,0|lhzkvz,45,62,0|lhzkw0,46,63,1|lu88rz,46,63,1|lu88s0,45,62,0|m0pnjz,45,62,0|m0pnk0,46,63,1|mcybfz,46,63,1|mcybg0,45,62,0|mjfq7z,45,62,0|mjfq80,46,63,1|mvoe3z,46,63,1|mvoe40,45,62,0|n25svz,45,62,0|n25sw0,46,63,1|neegrz,46,63,1|neegs0,45,62,0|nkvvjz,45,62,0|nkvvk0,46,63,1|nx4jfz,46,63,1|nx4jg0,45,62,0|o3ywvz,45,62,0|o3yww0,46,63,1|og7krz,46,63,1|og7ks0,45,62,0|omozjz,45,62,0|omozk0,46,63,1|oyxnfz,46,63,1|oyxng0,45,62,0|p5f27z,45,62,0|p5f280,46,63,1|phnq3z,46,63,1|phnq40,45,62,0|po54vz,45,62,0|po54w0,46,63,1|q0dsrz,46,63,1|q0dss0,45,62,0|q6v7jz,45,62,0|q6v7k0,46,63,1|qj3vfz,46,63,1|qj3vg0,45,62,0|qpy8vz,45,62,0|qpy8w0,46,63,1|r26wrz,46,63,1|r26ws0,45,62,0|r8objz,45,62,0|r8obk0,46,63,1|rkwzfz,46,63,1|rkwzg0,45,62,0|rree7z,45,62,0|rree80,46,63,1|s3n23z,46,63,1|s3n240,45,62,0|sa4gvz,45,62,0|sa4gw0,46,63,1|smd4rz,46,63,1|smd4s0,45,62,0|ssujjz,45,62,0|ssujk0,46,63,1|t537fz,46,63,1|t537g0,45,62,0|tbkm7z,45,62,0|tbkm80,46,63,1|tnta3z,46,63,1|tnta40,45,62,0|tunnjz,45,62,0|tunnk0,46,63,1|u6wbfz,46,63,1|u6wbg0,45,62,0|uddq7z,45,62,0|uddq80,46,63,1|upme3z,46,63,1|upme40,45,62,0|uw3svz,45,62,0|uw3sw0,46,63,1|v8cgrz,46,63,1|v8cgs0,45,62,0|vetvjz,45,62,0|vetvk0,46,63,1|vr2jfz,46,63,1|vr2jg0,45,62,0|vxjy7z,45,62,0|vxjy80,46,63,1|w9sm3z,46,63,1|w9sm40,45,62,0|wgmzjz,45,62,0|wgmzk0,46,63,1|wsvnfz,46,63,1|wsvng0,45,62,0|wzd27z,45,62,0|wzd280,46,63,1|xblq3z,46,63,1|xblq40,45,62,0|xi34vz,45,62,0|xi34w0,46,63,1|xubsrz,46,63,1|xubss0,45,62,0|y0t7jz,45,62,0|y0t7k0,46,63,1|yd1vfz,46,63,1|yd1vg0,45,62,0|yjja7z,45,62,0|yjja80,46,63,1|yvry3z,46,63,1|yvry40,45,62,0|z29cvz,45,62,0|z29cw0,46,63,1|zei0rz,46,63,1|zei0s0,45,62,0\",\"America/North_Dakota/Center|,0,155,0|-18y0j80,50,66,0|-r0epo1,50,66,0|-r0epo0,52,62,1|-qplwg1,52,62,1|-qplwg0,50,66,0|-qhon01,50,66,0|-qhon00,52,62,1|-q6vts1,52,62,1|-q6vts0,50,66,0|-ek1z01,50,66,0|-ek1z00,58,62,1|-cq2tg1,58,62,1|-cq2tg0,59,62,1|-cnoxs1,59,62,1|-cnoxs0,50,66,0|-1e8kc1,50,66,0|-1e8kc0,52,62,1|-14vls1,52,62,1|-14vls0,50,66,0|-viho1,50,66,0|-viho0,52,62,1|-m5j41,52,62,1|-m5j40,50,66,0|-csf01,50,66,0|-csf00,52,62,1|-3fgg1,52,62,1|-3fgg0,50,66,0|5xnnz,50,66,0|5xno0,52,62,1|fam7z,52,62,1|fam80,50,66,0|onqbz,50,66,0|onqc0,52,62,1|ydnjz,52,62,1|ydnk0,50,66,0|17qrnz,50,66,0|17qro0,52,62,1|1h3q7z,52,62,1|1h3q80,50,66,0|1qgubz,50,66,0|1qguc0,52,62,1|1ztsvz,52,62,1|1ztsw0,50,66,0|23fibz,50,66,0|23fic0,52,62,1|2ijvjz,52,62,1|2ijvk0,50,66,0|2oobnz,50,66,0|2oobo0,52,62,1|319y7z,52,62,1|319y80,50,66,0|3an2bz,50,66,0|3an2c0,52,62,1|3kczjz,52,62,1|3kczk0,50,66,0|3td4zz,50,66,0|3td500,52,62,1|43327z,52,62,1|433280,50,66,0|4cg6bz,50,66,0|4cg6c0,52,62,1|4lt4vz,52,62,1|4lt4w0,50,66,0|4v68zz,50,66,0|4v6900,52,62,1|54j7jz,52,62,1|54j7k0,50,66,0|5dwbnz,50,66,0|5dwbo0,52,62,1|5n9a7z,52,62,1|5n9a80,50,66,0|5wmebz,50,66,0|5wmec0,52,62,1|65zcvz,52,62,1|65zcw0,50,66,0|6fcgzz,50,66,0|6fch00,52,62,1|6p2e7z,52,62,1|6p2e80,50,66,0|6y2jnz,50,66,0|6y2jo0,52,62,1|77sgvz,52,62,1|77sgw0,50,66,0|7h5kzz,50,66,0|7h5l00,52,62,1|7qijjz,52,62,1|7qijk0,50,66,0|7zvnnz,50,66,0|7zvno0,52,62,1|898m7z,52,62,1|898m80,50,66,0|8ilqbz,50,66,0|8ilqc0,52,62,1|8ryovz,52,62,1|8ryow0,50,66,0|908wzz,50,66,0|908x00,52,62,1|9aorjz,52,62,1|9aork0,50,66,0|9iyznz,50,66,0|9iyzo0,52,62,1|9trsvz,52,62,1|9trsw0,50,66,0|a1p2bz,50,66,0|a1p2c0,52,62,1|achvjz,52,62,1|achvk0,50,66,0|akf4zz,50,66,0|akf500,52,62,1|av7y7z,52,62,1|av7y80,50,66,0|b3i6bz,50,66,0|b3i6c0,52,62,1|bdy0vz,52,62,1|bdy0w0,50,66,0|bm88zz,50,66,0|bm8900,52,62,1|bwo3jz,52,62,1|bwo3k0,45,62,0|c4y8vz,45,62,0|c4y8w0,46,63,1|cfr23z,46,63,1|cfr240,45,62,0|cnobjz,45,62,0|cnobk0,46,63,1|cyh4rz,46,63,1|cyh4s0,45,62,0|d6ee7z,45,62,0|d6ee80,46,63,1|dh77fz,46,63,1|dh77g0,45,62,0|dphfjz,45,62,0|dphfk0,46,63,1|dzxa3z,46,63,1|dzxa40,45,62,0|e87i7z,45,62,0|e87i80,46,63,1|eincrz,46,63,1|eincs0,45,62,0|eqxkvz,45,62,0|eqxkw0,46,63,1|f1dffz,46,63,1|f1dfg0,45,62,0|f9nnjz,45,62,0|f9nnk0,46,63,1|fkggrz,46,63,1|fkggs0,45,62,0|fsdq7z,45,62,0|fsdq80,46,63,1|g36jfz,46,63,1|g36jg0,45,62,0|gb3svz,45,62,0|gb3sw0,46,63,1|glwm3z,46,63,1|glwm40,45,62,0|gu6u7z,45,62,0|gu6u80,46,63,1|h4morz,46,63,1|h4mos0,45,62,0|hcwwvz,45,62,0|hcwww0,46,63,1|hncrfz,46,63,1|hncrg0,45,62,0|hvmzjz,45,62,0|hvmzk0,46,63,1|i6fsrz,46,63,1|i6fss0,45,62,0|ied27z,45,62,0|ied280,46,63,1|ip5vfz,46,63,1|ip5vg0,45,62,0|ix34vz,45,62,0|ix34w0,46,63,1|j7vy3z,46,63,1|j7vy40,45,62,0|jeqbjz,45,62,0|jeqbk0,46,63,1|jqyzfz,46,63,1|jqyzg0,45,62,0|jxge7z,45,62,0|jxge80,46,63,1|k9p23z,46,63,1|k9p240,45,62,0|kg6gvz,45,62,0|kg6gw0,46,63,1|ksf4rz,46,63,1|ksf4s0,45,62,0|kz9i7z,45,62,0|kz9i80,46,63,1|lbi63z,46,63,1|lbi640,45,62,0|lhzkvz,45,62,0|lhzkw0,46,63,1|lu88rz,46,63,1|lu88s0,45,62,0|m0pnjz,45,62,0|m0pnk0,46,63,1|mcybfz,46,63,1|mcybg0,45,62,0|mjfq7z,45,62,0|mjfq80,46,63,1|mvoe3z,46,63,1|mvoe40,45,62,0|n25svz,45,62,0|n25sw0,46,63,1|neegrz,46,63,1|neegs0,45,62,0|nkvvjz,45,62,0|nkvvk0,46,63,1|nx4jfz,46,63,1|nx4jg0,45,62,0|o3ywvz,45,62,0|o3yww0,46,63,1|og7krz,46,63,1|og7ks0,45,62,0|omozjz,45,62,0|omozk0,46,63,1|oyxnfz,46,63,1|oyxng0,45,62,0|p5f27z,45,62,0|p5f280,46,63,1|phnq3z,46,63,1|phnq40,45,62,0|po54vz,45,62,0|po54w0,46,63,1|q0dsrz,46,63,1|q0dss0,45,62,0|q6v7jz,45,62,0|q6v7k0,46,63,1|qj3vfz,46,63,1|qj3vg0,45,62,0|qpy8vz,45,62,0|qpy8w0,46,63,1|r26wrz,46,63,1|r26ws0,45,62,0|r8objz,45,62,0|r8obk0,46,63,1|rkwzfz,46,63,1|rkwzg0,45,62,0|rree7z,45,62,0|rree80,46,63,1|s3n23z,46,63,1|s3n240,45,62,0|sa4gvz,45,62,0|sa4gw0,46,63,1|smd4rz,46,63,1|smd4s0,45,62,0|ssujjz,45,62,0|ssujk0,46,63,1|t537fz,46,63,1|t537g0,45,62,0|tbkm7z,45,62,0|tbkm80,46,63,1|tnta3z,46,63,1|tnta40,45,62,0|tunnjz,45,62,0|tunnk0,46,63,1|u6wbfz,46,63,1|u6wbg0,45,62,0|uddq7z,45,62,0|uddq80,46,63,1|upme3z,46,63,1|upme40,45,62,0|uw3svz,45,62,0|uw3sw0,46,63,1|v8cgrz,46,63,1|v8cgs0,45,62,0|vetvjz,45,62,0|vetvk0,46,63,1|vr2jfz,46,63,1|vr2jg0,45,62,0|vxjy7z,45,62,0|vxjy80,46,63,1|w9sm3z,46,63,1|w9sm40,45,62,0|wgmzjz,45,62,0|wgmzk0,46,63,1|wsvnfz,46,63,1|wsvng0,45,62,0|wzd27z,45,62,0|wzd280,46,63,1|xblq3z,46,63,1|xblq40,45,62,0|xi34vz,45,62,0|xi34w0,46,63,1|xubsrz,46,63,1|xubss0,45,62,0|y0t7jz,45,62,0|y0t7k0,46,63,1|yd1vfz,46,63,1|yd1vg0,45,62,0|yjja7z,45,62,0|yjja80,46,63,1|yvry3z,46,63,1|yvry40,45,62,0|z29cvz,45,62,0|z29cw0,46,63,1|zei0rz,46,63,1|zei0s0,45,62,0\",\"America/North_Dakota/New_Salem|,0,156,0|-18y0j80,50,66,0|-r0epo1,50,66,0|-r0epo0,52,62,1|-qplwg1,52,62,1|-qplwg0,50,66,0|-qhon01,50,66,0|-qhon00,52,62,1|-q6vts1,52,62,1|-q6vts0,50,66,0|-ek1z01,50,66,0|-ek1z00,58,62,1|-cq2tg1,58,62,1|-cq2tg0,59,62,1|-cnoxs1,59,62,1|-cnoxs0,50,66,0|-1e8kc1,50,66,0|-1e8kc0,52,62,1|-14vls1,52,62,1|-14vls0,50,66,0|-viho1,50,66,0|-viho0,52,62,1|-m5j41,52,62,1|-m5j40,50,66,0|-csf01,50,66,0|-csf00,52,62,1|-3fgg1,52,62,1|-3fgg0,50,66,0|5xnnz,50,66,0|5xno0,52,62,1|fam7z,52,62,1|fam80,50,66,0|onqbz,50,66,0|onqc0,52,62,1|ydnjz,52,62,1|ydnk0,50,66,0|17qrnz,50,66,0|17qro0,52,62,1|1h3q7z,52,62,1|1h3q80,50,66,0|1qgubz,50,66,0|1qguc0,52,62,1|1ztsvz,52,62,1|1ztsw0,50,66,0|23fibz,50,66,0|23fic0,52,62,1|2ijvjz,52,62,1|2ijvk0,50,66,0|2oobnz,50,66,0|2oobo0,52,62,1|319y7z,52,62,1|319y80,50,66,0|3an2bz,50,66,0|3an2c0,52,62,1|3kczjz,52,62,1|3kczk0,50,66,0|3td4zz,50,66,0|3td500,52,62,1|43327z,52,62,1|433280,50,66,0|4cg6bz,50,66,0|4cg6c0,52,62,1|4lt4vz,52,62,1|4lt4w0,50,66,0|4v68zz,50,66,0|4v6900,52,62,1|54j7jz,52,62,1|54j7k0,50,66,0|5dwbnz,50,66,0|5dwbo0,52,62,1|5n9a7z,52,62,1|5n9a80,50,66,0|5wmebz,50,66,0|5wmec0,52,62,1|65zcvz,52,62,1|65zcw0,50,66,0|6fcgzz,50,66,0|6fch00,52,62,1|6p2e7z,52,62,1|6p2e80,50,66,0|6y2jnz,50,66,0|6y2jo0,52,62,1|77sgvz,52,62,1|77sgw0,50,66,0|7h5kzz,50,66,0|7h5l00,52,62,1|7qijjz,52,62,1|7qijk0,50,66,0|7zvnnz,50,66,0|7zvno0,52,62,1|898m7z,52,62,1|898m80,50,66,0|8ilqbz,50,66,0|8ilqc0,52,62,1|8ryovz,52,62,1|8ryow0,50,66,0|908wzz,50,66,0|908x00,52,62,1|9aorjz,52,62,1|9aork0,50,66,0|9iyznz,50,66,0|9iyzo0,52,62,1|9trsvz,52,62,1|9trsw0,50,66,0|a1p2bz,50,66,0|a1p2c0,52,62,1|achvjz,52,62,1|achvk0,50,66,0|akf4zz,50,66,0|akf500,52,62,1|av7y7z,52,62,1|av7y80,50,66,0|b3i6bz,50,66,0|b3i6c0,52,62,1|bdy0vz,52,62,1|bdy0w0,50,66,0|bm88zz,50,66,0|bm8900,52,62,1|bwo3jz,52,62,1|bwo3k0,50,66,0|c4ybnz,50,66,0|c4ybo0,52,62,1|cfr4vz,52,62,1|cfr4w0,50,66,0|cnoebz,50,66,0|cnoec0,52,62,1|cyh7jz,52,62,1|cyh7k0,50,66,0|d6egzz,50,66,0|d6eh00,52,62,1|dh7a7z,52,62,1|dh7a80,50,66,0|dphibz,50,66,0|dphic0,52,62,1|dzxcvz,52,62,1|dzxcw0,50,66,0|e87kzz,50,66,0|e87l00,52,62,1|einfjz,52,62,1|einfk0,50,66,0|eqxnnz,50,66,0|eqxno0,52,62,1|f1di7z,52,62,1|f1di80,50,66,0|f9nqbz,50,66,0|f9nqc0,52,62,1|fkgjjz,52,62,1|fkgjk0,50,66,0|fsdszz,50,66,0|fsdt00,52,62,1|g36m7z,52,62,1|g36m80,50,66,0|gb3vnz,50,66,0|gb3vo0,52,62,1|glwovz,52,62,1|glwow0,50,66,0|gu6wzz,50,66,0|gu6x00,52,62,1|h4mrjz,52,62,1|h4mrk0,50,66,0|hcwznz,50,66,0|hcwzo0,52,62,1|hncu7z,52,62,1|hncu80,45,62,0|hvmzjz,45,62,0|hvmzk0,46,63,1|i6fsrz,46,63,1|i6fss0,45,62,0|ied27z,45,62,0|ied280,46,63,1|ip5vfz,46,63,1|ip5vg0,45,62,0|ix34vz,45,62,0|ix34w0,46,63,1|j7vy3z,46,63,1|j7vy40,45,62,0|jeqbjz,45,62,0|jeqbk0,46,63,1|jqyzfz,46,63,1|jqyzg0,45,62,0|jxge7z,45,62,0|jxge80,46,63,1|k9p23z,46,63,1|k9p240,45,62,0|kg6gvz,45,62,0|kg6gw0,46,63,1|ksf4rz,46,63,1|ksf4s0,45,62,0|kz9i7z,45,62,0|kz9i80,46,63,1|lbi63z,46,63,1|lbi640,45,62,0|lhzkvz,45,62,0|lhzkw0,46,63,1|lu88rz,46,63,1|lu88s0,45,62,0|m0pnjz,45,62,0|m0pnk0,46,63,1|mcybfz,46,63,1|mcybg0,45,62,0|mjfq7z,45,62,0|mjfq80,46,63,1|mvoe3z,46,63,1|mvoe40,45,62,0|n25svz,45,62,0|n25sw0,46,63,1|neegrz,46,63,1|neegs0,45,62,0|nkvvjz,45,62,0|nkvvk0,46,63,1|nx4jfz,46,63,1|nx4jg0,45,62,0|o3ywvz,45,62,0|o3yww0,46,63,1|og7krz,46,63,1|og7ks0,45,62,0|omozjz,45,62,0|omozk0,46,63,1|oyxnfz,46,63,1|oyxng0,45,62,0|p5f27z,45,62,0|p5f280,46,63,1|phnq3z,46,63,1|phnq40,45,62,0|po54vz,45,62,0|po54w0,46,63,1|q0dsrz,46,63,1|q0dss0,45,62,0|q6v7jz,45,62,0|q6v7k0,46,63,1|qj3vfz,46,63,1|qj3vg0,45,62,0|qpy8vz,45,62,0|qpy8w0,46,63,1|r26wrz,46,63,1|r26ws0,45,62,0|r8objz,45,62,0|r8obk0,46,63,1|rkwzfz,46,63,1|rkwzg0,45,62,0|rree7z,45,62,0|rree80,46,63,1|s3n23z,46,63,1|s3n240,45,62,0|sa4gvz,45,62,0|sa4gw0,46,63,1|smd4rz,46,63,1|smd4s0,45,62,0|ssujjz,45,62,0|ssujk0,46,63,1|t537fz,46,63,1|t537g0,45,62,0|tbkm7z,45,62,0|tbkm80,46,63,1|tnta3z,46,63,1|tnta40,45,62,0|tunnjz,45,62,0|tunnk0,46,63,1|u6wbfz,46,63,1|u6wbg0,45,62,0|uddq7z,45,62,0|uddq80,46,63,1|upme3z,46,63,1|upme40,45,62,0|uw3svz,45,62,0|uw3sw0,46,63,1|v8cgrz,46,63,1|v8cgs0,45,62,0|vetvjz,45,62,0|vetvk0,46,63,1|vr2jfz,46,63,1|vr2jg0,45,62,0|vxjy7z,45,62,0|vxjy80,46,63,1|w9sm3z,46,63,1|w9sm40,45,62,0|wgmzjz,45,62,0|wgmzk0,46,63,1|wsvnfz,46,63,1|wsvng0,45,62,0|wzd27z,45,62,0|wzd280,46,63,1|xblq3z,46,63,1|xblq40,45,62,0|xi34vz,45,62,0|xi34w0,46,63,1|xubsrz,46,63,1|xubss0,45,62,0|y0t7jz,45,62,0|y0t7k0,46,63,1|yd1vfz,46,63,1|yd1vg0,45,62,0|yjja7z,45,62,0|yjja80,46,63,1|yvry3z,46,63,1|yvry40,45,62,0|z29cvz,45,62,0|z29cw0,46,63,1|zei0rz,46,63,1|zei0s0,45,62,0\",\"America/Nuuk|,0,157,0|-rvumf4,39,44,0|5ct4jz,39,44,0|5ct4k0,40,45,1|5lsw3z,40,45,1|5lsw40,39,44,0|5v5xfz,39,44,0|5v5xg0,40,45,1|64iyrz,40,45,1|64iys0,39,44,0|6dw03z,39,44,0|6dw040,40,45,1|6n91fz,40,45,1|6n91g0,39,44,0|6wm2rz,39,44,0|6wm2s0,40,45,1|75z43z,40,45,1|75z440,39,44,0|7fc5fz,39,44,0|7fc5g0,40,45,1|7p25fz,40,45,1|7p25g0,39,44,0|7yf6rz,39,44,0|7yf6s0,40,45,1|87s83z,40,45,1|87s840,39,44,0|8h59fz,39,44,0|8h59g0,40,45,1|8qiarz,40,45,1|8qias0,39,44,0|8zvc3z,39,44,0|8zvc40,40,45,1|998dfz,40,45,1|998dg0,39,44,0|9ilerz,39,44,0|9iles0,40,45,1|9ryg3z,40,45,1|9ryg40,39,44,0|a1bhfz,39,44,0|a1bhg0,40,45,1|aaoirz,40,45,1|aaois0,39,44,0|ak1k3z,39,44,0|ak1k40,40,45,1|atrk3z,40,45,1|atrk40,39,44,0|b34lfz,39,44,0|b34lg0,40,45,1|bchmrz,40,45,1|bchms0,39,44,0|bluo3z,39,44,0|bluo40,40,45,1|bv7pfz,40,45,1|bv7pg0,39,44,0|c4kqrz,39,44,0|c4kqs0,40,45,1|cdxs3z,40,45,1|cdxs40,39,44,0|cnatfz,39,44,0|cnatg0,40,45,1|cwnurz,40,45,1|cwnus0,39,44,0|d60w3z,39,44,0|d60w40,40,45,1|dfdxfz,40,45,1|dfdxg0,39,44,0|dp3xfz,39,44,0|dp3xg0,40,45,1|dzwtfz,40,45,1|dzwtg0,39,44,0|e7u03z,39,44,0|e7u040,40,45,1|eimw3z,40,45,1|eimw40,39,44,0|eqk2rz,39,44,0|eqk2s0,40,45,1|f1cyrz,40,45,1|f1cys0,39,44,0|f9a5fz,39,44,0|f9a5g0,40,45,1|fkg03z,40,45,1|fkg040,39,44,0|fs083z,39,44,0|fs0840,40,45,1|g362rz,40,45,1|g362s0,39,44,0|gaqarz,39,44,0|gaqas0,40,45,1|glw5fz,40,45,1|glw5g0,39,44,0|gttc3z,39,44,0|gttc40,40,45,1|h4m83z,40,45,1|h4m840,39,44,0|hcjerz,39,44,0|hcjes0,40,45,1|hncarz,40,45,1|hncas0,39,44,0|hv9hfz,39,44,0|hv9hg0,40,45,1|i6fc3z,40,45,1|i6fc40,39,44,0|idzk3z,39,44,0|idzk40,40,45,1|ip5erz,40,45,1|ip5es0,39,44,0|iwpmrz,39,44,0|iwpms0,40,45,1|j7vhfz,40,45,1|j7vhg0,39,44,0|jffpfz,39,44,0|jffpg0,40,45,1|jqlk3z,40,45,1|jqlk40,39,44,0|jyiqrz,39,44,0|jyiqs0,40,45,1|k9bmrz,40,45,1|k9bms0,39,44,0|kh8tfz,39,44,0|kh8tg0,40,45,1|ks1pfz,40,45,1|ks1pg0,39,44,0|kzyw3z,39,44,0|kzyw40,40,45,1|lb4qrz,40,45,1|lb4qs0,39,44,0|lioyrz,39,44,0|lioys0,40,45,1|ltutfz,40,45,1|ltutg0,39,44,0|m1f1fz,39,44,0|m1f1g0,40,45,1|mckw3z,40,45,1|mckw40,39,44,0|mki2rz,39,44,0|mki2s0,40,45,1|mvayrz,40,45,1|mvays0,39,44,0|n385fz,39,44,0|n385g0,40,45,1|ne11fz,40,45,1|ne11g0,39,44,0|nly83z,39,44,0|nly840,40,45,1|nwr43z,40,45,1|nwr440,39,44,0|o4oarz,39,44,0|o4oas0,40,45,1|ofu5fz,40,45,1|ofu5g0,39,44,0|onedfz,39,44,0|onedg0,40,45,1|oyk83z,40,45,1|oyk840,39,44,0|p64g3z,39,44,0|p64g40,40,45,1|phaarz,40,45,1|phaas0,39,44,0|pp7hfz,39,44,0|pp7hg0,40,45,1|q00dfz,40,45,1|q00dg0,39,44,0|q7xk3z,39,44,0|q7xk40,40,45,1|qiqg3z,40,45,1|qiqg40,39,44,0|qqnmrz,39,44,0|qqnms0,40,45,1|r1thfz,40,45,1|r1thg0,39,44,0|r9dpfz,39,44,0|r9dpg0,40,45,1|rkjk3z,40,45,1|rkjk40,39,44,0|rs3s3z,39,44,0|rs3s40,40,45,1|s39mrz,40,45,1|s39ms0,39,44,0|sb6tfz,39,44,0|sb6tg0,40,45,1|slzpfz,40,45,1|slzpg0,39,44,0|stww3z,39,44,0|stww40,40,45,1|t4ps3z,40,45,1|t4ps40,39,44,0|tcmyrz,39,44,0|tcmys0,40,45,1|tnfurz,40,45,1|tnfus0,39,44,0|tvd1fz,39,44,0|tvd1g0,40,45,1|u6iw3z,40,45,1|u6iw40,39,44,0|ue343z,39,44,0|ue3440,40,45,1|up8yrz,40,45,1|up8ys0,39,44,0|uwt6rz,39,44,0|uwt6s0,40,45,1|v7z1fz,40,45,1|v7z1g0,39,44,0|vfw83z,39,44,0|vfw840,40,45,1|vqp43z,40,45,1|vqp440,39,44,0|vymarz,39,44,0|vymas0,40,45,1|w9f6rz,40,45,1|w9f6s0,39,44,0|whcdfz,39,44,0|whcdg0,40,45,1|wsi83z,40,45,1|wsi840,39,44,0|x02g3z,39,44,0|x02g40,40,45,1|xb8arz,40,45,1|xb8as0,39,44,0|xisirz,39,44,0|xisis0,40,45,1|xtydfz,40,45,1|xtydg0,39,44,0|y1ilfz,39,44,0|y1ilg0,40,45,1|ycog3z,40,45,1|ycog40,39,44,0|yklmrz,39,44,0|yklms0,40,45,1|yveirz,40,45,1|yveis0,39,44,0|z3bpfz,39,44,0|z3bpg0,40,45,1|ze4lfz,40,45,1|ze4lg0,39,44,0\",\"America/Ojinaga|,0,158,0|-p1u4k0,50,66,0|-m7mko1,50,66,0|-m7mko0,45,62,0|-kf67c1,45,62,0|-kf67c0,50,66,0|-k6j3c1,50,66,0|-k6j3c0,45,62,0|-jypm01,45,62,0|-jypm00,50,66,0|-jpan81,50,66,0|-jpan80,45,62,0|dphfjz,45,62,0|dphfk0,46,63,1|dzxa3z,46,63,1|dzxa40,45,62,0|e87i7z,45,62,0|e87i80,46,63,1|eincrz,46,63,1|eincs0,45,62,0|eqxnnz,45,62,0|eqxno0,52,62,1|f1di7z,52,62,1|f1di80,50,66,0|f9nqbz,50,66,0|f9nqc0,52,62,1|fkgjjz,52,62,1|fkgjk0,50,66,0|fsdszz,50,66,0|fsdt00,52,62,1|g36m7z,52,62,1|g36m80,50,66,0|gcwozz,50,66,0|gcwp00,52,62,1|gkgu7z,52,62,1|gkgu80,50,66,0|gu6wzz,50,66,0|gu6x00,52,62,1|h4mrjz,52,62,1|h4mrk0,50,66,0|hcwznz,50,66,0|hcwzo0,52,62,1|hncu7z,52,62,1|hncu80,50,66,0|hvn2bz,50,66,0|hvn2c0,52,62,1|i6fvjz,52,62,1|i6fvk0,50,66,0|ied4zz,50,66,0|ied500,52,62,1|ip5y7z,52,62,1|ip5y80,50,66,0|ix37nz,50,66,0|ix37o0,52,62,1|j7w0vz,52,62,1|j7w0w0,50,66,0|jftabz,50,66,0|jftac0,52,62,1|jqm3jz,52,62,1|jqm3k0,50,66,0|jywbnz,50,66,0|jywbo0,52,62,1|k9c67z,52,62,1|k9c680,50,66,0|khmebz,50,66,0|khmec0,52,62,1|ks28vz,52,62,1|ks28w0,50,66,0|kz9kzz,50,66,0|kz9l00,52,62,1|lbi8vz,52,62,1|lbi8w0,50,66,0|lhznnz,50,66,0|lhzno0,52,62,1|lu8bjz,52,62,1|lu8bk0,50,66,0|m0pqbz,50,66,0|m0pqc0,52,62,1|mcye7z,52,62,1|mcye80,50,66,0|mjfszz,50,66,0|mjft00,52,62,1|mvogvz,52,62,1|mvogw0,50,66,0|n25vnz,50,66,0|n25vo0,52,62,1|neejjz,52,62,1|neejk0,50,66,0|nkvybz,50,66,0|nkvyc0,52,62,1|nx4m7z,52,62,1|nx4m80,50,66,0|o3yznz,50,66,0|o3yzo0,52,62,1|og7njz,52,62,1|og7nk0,50,66,0|omp2bz,50,66,0|omp2c0,52,62,1|oyxq7z,52,62,1|oyxq80,50,66,0|p5f4zz,50,66,0|p5f500,52,62,1|phnsvz,52,62,1|phnsw0,50,66,0|po57nz,50,66,0|po57o0,52,62,1|q0dvjz,52,62,1|q0dvk0,50,66,0|q6vabz,50,66,0|q6vac0,52,62,1|qj3y7z,52,62,1|qj3y80,50,66,0|qpybnz,50,66,0|qpybo0,52,62,1|r26zjz,52,62,1|r26zk0,50,66,0|r8oebz,50,66,0|r8oec0,52,62,1|rkx27z,52,62,1|rkx280,50,66,0|rregzz,50,66,0|rreh00,52,62,1|s3n4vz,52,62,1|s3n4w0,50,66,0|sa4jnz,50,66,0|sa4jo0,52,62,1|smd7jz,52,62,1|smd7k0,50,66,0|ssumbz,50,66,0|ssumc0,52,62,1|t53a7z,52,62,1|t53a80,50,66,0|tbkozz,50,66,0|tbkp00,52,62,1|tntcvz,52,62,1|tntcw0,50,66,0|tunqbz,50,66,0|tunqc0,52,62,1|u6we7z,52,62,1|u6we80,50,66,0|uddszz,50,66,0|uddt00,52,62,1|upmgvz,52,62,1|upmgw0,50,66,0|uw3vnz,50,66,0|uw3vo0,52,62,1|v8cjjz,52,62,1|v8cjk0,50,66,0|vetybz,50,66,0|vetyc0,52,62,1|vr2m7z,52,62,1|vr2m80,50,66,0|vxk0zz,50,66,0|vxk100,52,62,1|w9sovz,52,62,1|w9sow0,50,66,0|wgn2bz,50,66,0|wgn2c0,52,62,1|wsvq7z,52,62,1|wsvq80,50,66,0|wzd4zz,50,66,0|wzd500,52,62,1|xblsvz,52,62,1|xblsw0,50,66,0|xi37nz,50,66,0|xi37o0,52,62,1|xubvjz,52,62,1|xubvk0,50,66,0|y0tabz,50,66,0|y0tac0,52,62,1|yd1y7z,52,62,1|yd1y80,50,66,0|yjjczz,50,66,0|yjjd00,52,62,1|yvs0vz,52,62,1|yvs0w0,50,66,0|z29fnz,50,66,0|z29fo0,52,62,1|zei3jz,52,62,1|zei3k0,50,66,0\",\"America/Panama|,0,80,0|-15r0uls,41,81,0|-w757vd,41,81,0|-w757vc,49,63,0\",\"America/Pangnirtung|,60,1,0|-pkmlc0,32,42,0|-ek27c1,32,42,0|-ek27c0,33,44,1|-cq2tg1,33,44,1|-cq2tg0,34,44,1|-cnp641,34,44,1|-cnp640,32,42,0|-2g2281,32,42,0|-2g2280,73,45,1|-26c281,73,45,1|-26c280,32,42,0|5dw3bz,32,42,0|5dw3c0,54,44,1|5n91vz,54,44,1|5n91w0,32,42,0|5wm5zz,32,42,0|5wm600,54,44,1|65z4jz,54,44,1|65z4k0,32,42,0|6fc8nz,32,42,0|6fc8o0,54,44,1|6p25vz,54,44,1|6p25w0,32,42,0|6y2bbz,32,42,0|6y2bc0,54,44,1|77s8jz,54,44,1|77s8k0,32,42,0|7h5cnz,32,42,0|7h5co0,54,44,1|7qib7z,54,44,1|7qib80,32,42,0|7zvfbz,32,42,0|7zvfc0,54,44,1|898dvz,54,44,1|898dw0,32,42,0|8ilhzz,32,42,0|8ili00,54,44,1|8rygjz,54,44,1|8rygk0,32,42,0|908onz,32,42,0|908oo0,54,44,1|9aoj7z,54,44,1|9aoj80,32,42,0|9iyrbz,32,42,0|9iyrc0,54,44,1|9trkjz,54,44,1|9trkk0,32,42,0|a1otzz,32,42,0|a1ou00,54,44,1|achn7z,54,44,1|achn80,32,42,0|akewnz,32,42,0|akewo0,54,44,1|av7pvz,54,44,1|av7pw0,32,42,0|b3hxzz,32,42,0|b3hy00,54,44,1|bdxsjz,54,44,1|bdxsk0,32,42,0|bm80nz,32,42,0|bm80o0,54,44,1|bwnv7z,54,44,1|bwnv80,32,42,0|c4y3bz,32,42,0|c4y3c0,54,44,1|cfqwjz,54,44,1|cfqwk0,32,42,0|cno5zz,32,42,0|cno600,54,44,1|cygz7z,54,44,1|cygz80,32,42,0|d6e8nz,32,42,0|d6e8o0,62,42,1|dh74nz,62,42,1|dh74o0,49,63,0|dphcrz,49,63,0|dphcs0,62,42,1|dzx7bz,62,42,1|dzx7c0,49,63,0|e87ffz,49,63,0|e87fg0,62,42,1|ein9zz,62,42,1|eina00,49,63,0|eqxi3z,49,63,0|eqxi40,62,42,1|f1dcnz,62,42,1|f1dco0,49,63,0|f9nkrz,49,63,0|f9nks0,62,42,1|fkgdzz,62,42,1|fkge00,45,62,0|fsdq7z,45,62,0|fsdq80,46,63,1|g36jfz,46,63,1|g36jg0,49,63,0|gb3q3z,49,63,0|gb3q40,62,42,1|glwjbz,62,42,1|glwjc0,49,63,0|gu6rfz,49,63,0|gu6rg0,62,42,1|h4mlzz,62,42,1|h4mm00,49,63,0|hcwu3z,49,63,0|hcwu40,62,42,1|hnconz,62,42,1|hncoo0,49,63,0|hvmwrz,49,63,0|hvmws0,62,42,1|i6fpzz,62,42,1|i6fq00,49,63,0|ieczfz,49,63,0|ieczg0,62,42,1|ip5snz,62,42,1|ip5so0,49,63,0|ix323z,49,63,0|ix3240,62,42,1|j7vvbz,62,42,1|j7vvc0,49,63,0|jeq8rz,49,63,0|jeq8s0,62,42,1|jqywnz,62,42,1|jqywo0,49,63,0|jxgbfz,49,63,0|jxgbg0,62,42,1|k9ozbz,62,42,1|k9ozc0,49,63,0|kg6e3z,49,63,0|kg6e40,62,42,1|ksf1zz,62,42,1|ksf200,49,63,0|kz9ffz,49,63,0|kz9fg0,62,42,1|lbi3bz,62,42,1|lbi3c0,49,63,0|lhzi3z,49,63,0|lhzi40,62,42,1|lu85zz,62,42,1|lu8600,49,63,0|m0pkrz,49,63,0|m0pks0,62,42,1|mcy8nz,62,42,1|mcy8o0,49,63,0|mjfnfz,49,63,0|mjfng0,62,42,1|mvobbz,62,42,1|mvobc0,49,63,0|n25q3z,49,63,0|n25q40,62,42,1|needzz,62,42,1|neee00,49,63,0|nkvsrz,49,63,0|nkvss0,62,42,1|nx4gnz,62,42,1|nx4go0,49,63,0|o3yu3z,49,63,0|o3yu40,62,42,1|og7hzz,62,42,1|og7i00,49,63,0|omowrz,49,63,0|omows0,62,42,1|oyxknz,62,42,1|oyxko0,49,63,0|p5ezfz,49,63,0|p5ezg0,62,42,1|phnnbz,62,42,1|phnnc0,49,63,0|po523z,49,63,0|po5240,62,42,1|q0dpzz,62,42,1|q0dq00,49,63,0|q6v4rz,49,63,0|q6v4s0,62,42,1|qj3snz,62,42,1|qj3so0,49,63,0|qpy63z,49,63,0|qpy640,62,42,1|r26tzz,62,42,1|r26u00,49,63,0|r8o8rz,49,63,0|r8o8s0,62,42,1|rkwwnz,62,42,1|rkwwo0,49,63,0|rrebfz,49,63,0|rrebg0,62,42,1|s3mzbz,62,42,1|s3mzc0,49,63,0|sa4e3z,49,63,0|sa4e40,62,42,1|smd1zz,62,42,1|smd200,49,63,0|ssugrz,49,63,0|ssugs0,62,42,1|t534nz,62,42,1|t534o0,49,63,0|tbkjfz,49,63,0|tbkjg0,62,42,1|tnt7bz,62,42,1|tnt7c0,49,63,0|tunkrz,49,63,0|tunks0,62,42,1|u6w8nz,62,42,1|u6w8o0,49,63,0|uddnfz,49,63,0|uddng0,62,42,1|upmbbz,62,42,1|upmbc0,49,63,0|uw3q3z,49,63,0|uw3q40,62,42,1|v8cdzz,62,42,1|v8ce00,49,63,0|vetsrz,49,63,0|vetss0,62,42,1|vr2gnz,62,42,1|vr2go0,49,63,0|vxjvfz,49,63,0|vxjvg0,62,42,1|w9sjbz,62,42,1|w9sjc0,49,63,0|wgmwrz,49,63,0|wgmws0,62,42,1|wsvknz,62,42,1|wsvko0,49,63,0|wzczfz,49,63,0|wzczg0,62,42,1|xblnbz,62,42,1|xblnc0,49,63,0|xi323z,49,63,0|xi3240,62,42,1|xubpzz,62,42,1|xubq00,49,63,0|y0t4rz,49,63,0|y0t4s0,62,42,1|yd1snz,62,42,1|yd1so0,49,63,0|yjj7fz,49,63,0|yjj7g0,62,42,1|yvrvbz,62,42,1|yvrvc0,49,63,0|z29a3z,49,63,0|z29a40,62,42,1|zehxzz,62,42,1|zehy00,49,63,0\",\"America/Paramaribo|,0,159,0|-usj4g8,7,160,0|-i9lsfx,7,160,0|-i9lsfw,7,161,0|-cnnf4d,7,161,0|-cnnf4c,81,101,0|7p471z,81,101,0|7p4720,39,44,0\",\"America/Phoenix|,0,162,0|-18y0j80,50,66,0|-r0epo1,50,66,0|-r0epo0,52,62,1|-qplwg1,52,62,1|-qplwg0,50,66,0|-qhon01,50,66,0|-qhon00,52,62,1|-q6vts1,52,62,1|-q6vts0,50,66,0|-ek1z01,50,66,0|-ek1z00,58,62,1|-dkikmd,58,62,1|-dkikmc,50,66,0|-dftz6d,50,66,0|-dftz6c,58,62,1|-d6f5yd,58,62,1|-d6f5yc,50,66,0|-1e8kc1,50,66,0|-1e8kc0,52,62,1|-14vls1,52,62,1|-14vls0,50,66,0\",\"America/Port-au-Prince|,0,163,0|-15r0vxs,84,164,0|-rmk9ad,84,164,0|-rmk9ac,49,63,0|6ys5vz,49,63,0|6ys5w0,62,42,1|77s5rz,62,42,1|77s5s0,49,63,0|7h59vz,49,63,0|7h59w0,62,42,1|7qi8fz,62,42,1|7qi8g0,49,63,0|7zvcjz,49,63,0|7zvck0,62,42,1|898b3z,62,42,1|898b40,49,63,0|8ilf7z,49,63,0|8ilf80,62,42,1|8rydrz,62,42,1|8ryds0,49,63,0|91bhvz,49,63,0|91bhw0,62,42,1|9aogfz,62,42,1|9aogg0,49,63,0|9iyrbz,49,63,0|9iyrc0,62,42,1|9trnbz,62,42,1|9trnc0,49,63,0|a1otzz,49,63,0|a1ou00,62,42,1|achpzz,62,42,1|achq00,49,63,0|akewnz,49,63,0|akewo0,62,42,1|av7snz,62,42,1|av7so0,49,63,0|b3hxzz,49,63,0|b3hy00,62,42,1|bdxvbz,62,42,1|bdxvc0,49,63,0|bm80nz,49,63,0|bm80o0,62,42,1|bwnxzz,62,42,1|bwny00,49,63,0|c4y3bz,49,63,0|c4y3c0,62,42,1|cfqzbz,62,42,1|cfqzc0,49,63,0|cno5zz,49,63,0|cno600,62,42,1|cyh1zz,62,42,1|cyh200,49,63,0|d6e8nz,49,63,0|d6e8o0,62,42,1|dh74nz,62,42,1|dh74o0,49,63,0|dph9zz,49,63,0|dpha00,62,42,1|dzx7bz,62,42,1|dzx7c0,49,63,0|e87cnz,49,63,0|e87co0,62,42,1|ein9zz,62,42,1|eina00,49,63,0|iectvz,49,63,0|iectw0,62,42,1|ip5n3z,62,42,1|ip5n40,49,63,0|ix2wjz,49,63,0|ix2wk0,62,42,1|j7vprz,62,42,1|j7vps0,49,63,0|m0pkrz,49,63,0|m0pks0,62,42,1|mcy8nz,62,42,1|mcy8o0,49,63,0|mjfnfz,49,63,0|mjfng0,62,42,1|mvobbz,62,42,1|mvobc0,49,63,0|n25q3z,49,63,0|n25q40,62,42,1|needzz,62,42,1|neee00,49,63,0|nkvsrz,49,63,0|nkvss0,62,42,1|nx4gnz,62,42,1|nx4go0,49,63,0|omowrz,49,63,0|omows0,62,42,1|oyxknz,62,42,1|oyxko0,49,63,0|p5ezfz,49,63,0|p5ezg0,62,42,1|phnnbz,62,42,1|phnnc0,49,63,0|po523z,49,63,0|po5240,62,42,1|q0dpzz,62,42,1|q0dq00,49,63,0|q6v4rz,49,63,0|q6v4s0,62,42,1|qj3snz,62,42,1|qj3so0,49,63,0|qpy63z,49,63,0|qpy640,62,42,1|r26tzz,62,42,1|r26u00,49,63,0|r8o8rz,49,63,0|r8o8s0,62,42,1|rkwwnz,62,42,1|rkwwo0,49,63,0|rrebfz,49,63,0|rrebg0,62,42,1|s3mzbz,62,42,1|s3mzc0,49,63,0|sa4e3z,49,63,0|sa4e40,62,42,1|smd1zz,62,42,1|smd200,49,63,0|ssugrz,49,63,0|ssugs0,62,42,1|t534nz,62,42,1|t534o0,49,63,0|tbkjfz,49,63,0|tbkjg0,62,42,1|tnt7bz,62,42,1|tnt7c0,49,63,0|tunkrz,49,63,0|tunks0,62,42,1|u6w8nz,62,42,1|u6w8o0,49,63,0|uddnfz,49,63,0|uddng0,62,42,1|upmbbz,62,42,1|upmbc0,49,63,0|uw3q3z,49,63,0|uw3q40,62,42,1|v8cdzz,62,42,1|v8ce00,49,63,0|vetsrz,49,63,0|vetss0,62,42,1|vr2gnz,62,42,1|vr2go0,49,63,0|vxjvfz,49,63,0|vxjvg0,62,42,1|w9sjbz,62,42,1|w9sjc0,49,63,0|wgmwrz,49,63,0|wgmws0,62,42,1|wsvknz,62,42,1|wsvko0,49,63,0|wzczfz,49,63,0|wzczg0,62,42,1|xblnbz,62,42,1|xblnc0,49,63,0|xi323z,49,63,0|xi3240,62,42,1|xubpzz,62,42,1|xubq00,49,63,0|y0t4rz,49,63,0|y0t4s0,62,42,1|yd1snz,62,42,1|yd1so0,49,63,0|yjj7fz,49,63,0|yjj7g0,62,42,1|yvrvbz,62,42,1|yvrvc0,49,63,0|z29a3z,49,63,0|z29a40,62,42,1|zehxzz,62,42,1|zehy00,49,63,0\",\"America/Port_of_Spain|,0,41,0|-u6m79w,32,42,0\",\"America/Porto_Velho|,0,165,0|-t85g60,42,42,0|-jyl7o1,42,42,0|-jyl7o0,39,44,1|-jpayc1,39,44,1|-jpayc0,42,42,0|-jfsa81,42,42,0|-jfsa80,39,44,1|-j6j101,39,44,1|-j6j100,42,42,0|-ahcvk1,42,42,0|-ahcvk0,39,44,1|-aad0w1,39,44,1|-aad0w0,42,42,0|-9yky81,42,42,0|-9yky80,39,44,1|-9scyc1,39,44,1|-9scyc0,42,42,0|-9ft0w1,42,42,0|-9ft0w0,39,44,1|-99j6c1,39,44,1|-99j6c0,42,42,0|-8wz8w1,42,42,0|-8wz8w0,39,44,1|-8scno1,39,44,1|-8scno0,42,42,0|-35xjk1,42,42,0|-35xjk0,39,44,1|-31nx01,39,44,1|-31nx00,42,42,0|-2kdm81,42,42,0|-2kdm80,39,44,1|-2hcfo1,39,44,1|-2hcfo0,42,42,0|-24qnk1,42,42,0|-24qnk0,39,44,1|-2042c1,39,44,1|-2042c0,42,42,0|-1nia81,42,42,0|-1nia80,39,44,1|-1hc501,39,44,1|-1hc500,42,42,0|-14qcw1,42,42,0|-14qcw0,39,44,1|-yid01,39,44,1|-yid00,42,42,0|89jf3z,42,42,0|89jf40,39,44,1|8gdmzz,39,44,1|8gdn00,42,42,0|8rwj3z,42,42,0|8rwj40,39,44,1|8xnuzz,39,44,1|8xnv00,42,42,0|9aogfz,42,42,0|9aogg0,39,44,1|9g2tnz,39,44,1|9g2to0,42,42,0\",\"America/Puerto_Rico|,0,166,0|-10xhp3b,32,42,0|-efsnk1,32,42,0|-efsnk0,33,44,1|-cq2tg1,33,44,1|-cq2tg0,34,44,1|-cnp641,34,44,1|-cnp640,32,42,0\",\"America/Punta_Arenas|,0,167,0|-15r0w78,85,168,0|-vauawr,85,168,0|-vauawq,56,63,0|-rx8i41,56,63,0|-rx8i40,85,168,0|-qs16wr,85,168,0|-qs16wq,42,42,0|-qcwsw1,42,42,0|-qcwsw0,85,168,0|-m3etkr,85,168,0|-m3etkq,42,42,1|-lsgfk1,42,42,1|-lsgfk0,56,63,0|-lkl0s1,56,63,0|-lkl0s0,42,42,1|-l9oi81,42,42,1|-l9oi80,56,63,0|-l1t3g1,56,63,0|-l1t3g0,42,42,1|-kqwkw1,42,42,1|-kqwkw0,56,63,0|-kj1641,56,63,0|-kj1640,42,42,1|-k84nk1,42,42,1|-k84nk0,56,63,0|-k098s1,56,63,0|-k098s0,42,42,1|-jpavk1,42,42,1|-jpavk0,56,63,0|-jhfgs1,56,63,0|-jhfgs0,42,42,0|-eeay81,42,42,0|-eeay80,56,63,0|-eb5ws1,56,63,0|-eb5ws0,42,42,0|-bvifk1,42,42,0|-bvifk0,56,63,0|-bsvzk1,56,63,0|-bsvzk0,42,42,0|-lsvk1,42,42,0|-lsvk0,39,44,1|-e8qc1,39,44,1|-e8qc0,42,42,0|-1zww1,42,42,0|-1zww0,39,44,1|4hcbz,39,44,1|4hcc0,42,42,0|ekdrz,42,42,0|ekds0,39,44,1|mhhnz,39,44,1|mhho0,42,42,0|xagfz,42,42,0|xagg0,39,44,1|157kbz,39,44,1|157kc0,42,42,0|1gdhrz,42,42,0|1gdhs0,39,44,1|1nxmzz,39,44,1|1nxn00,42,42,0|1ydn3z,42,42,0|1ydn40,39,44,1|26npnz,39,44,1|26npo0,42,42,0|2htn3z,42,42,0|2htn40,39,44,1|2pdsbz,39,44,1|2pdsc0,42,42,0|30jprz,42,42,0|30jps0,39,44,1|38gtnz,39,44,1|38gto0,42,42,0|3j9sfz,42,42,0|3j9sg0,39,44,1|3r6wbz,39,44,1|3r6wc0,42,42,0|41zv3z,42,42,0|41zv40,39,44,1|49wyzz,39,44,1|49wz00,42,42,0|4l2wfz,42,42,0|4l2wg0,39,44,1|4sn1nz,39,44,1|4sn1o0,42,42,0|53sz3z,42,42,0|53sz40,39,44,1|5bd4bz,39,44,1|5bd4c0,42,42,0|5mj1rz,42,42,0|5mj1s0,39,44,1|5ug5nz,39,44,1|5ug5o0,42,42,0|6594fz,42,42,0|6594g0,39,44,1|6d68bz,39,44,1|6d68c0,42,42,0|6nz73z,42,42,0|6nz740,39,44,1|6vwazz,39,44,1|6vwb00,42,42,0|76p9rz,42,42,0|76p9s0,39,44,1|7emdnz,39,44,1|7emdo0,42,42,0|7psb3z,42,42,0|7psb40,39,44,1|7xcgbz,39,44,1|7xcgc0,42,42,0|88idrz,42,42,0|88ids0,39,44,1|8g2izz,39,44,1|8g2j00,42,42,0|8r8gfz,42,42,0|8r8gg0,39,44,1|90lezz,39,44,1|90lf00,42,42,0|99yj3z,42,42,0|99yj40,39,44,1|9hvmzz,39,44,1|9hvn00,42,42,0|9solrz,42,42,0|9sols0,39,44,1|a0lpnz,39,44,1|a0lpo0,42,42,0|abrn3z,42,42,0|abrn40,39,44,1|ajbsbz,39,44,1|ajbsc0,42,42,0|at1v3z,42,42,0|at1v40,39,44,1|b21uzz,39,44,1|b21v00,42,42,0|bd7sfz,42,42,0|bd7sg0,39,44,1|bl4wbz,39,44,1|bl4wc0,42,42,0|bvxv3z,42,42,0|bvxv40,39,44,1|c3uyzz,39,44,1|c3uz00,42,42,0|cenxrz,42,42,0|cenxs0,39,44,1|cml1nz,39,44,1|cml1o0,42,42,0|cxe0fz,42,42,0|cxe0g0,39,44,1|d5b4bz,39,44,1|d5b4c0,42,42,0|dgh1rz,42,42,0|dgh1s0,39,44,1|do16zz,39,44,1|do1700,42,42,0|dz74fz,42,42,0|dz74g0,39,44,1|e7u5nz,39,44,1|e7u5o0,42,42,0|ehx73z,42,42,0|ehx740,39,44,1|epuazz,39,44,1|epub00,42,42,0|ezxcfz,42,42,0|ezxcg0,39,44,1|f9n9nz,39,44,1|f9n9o0,42,42,0|fjdcfz,42,42,0|fjdcg0,39,44,1|fragbz,39,44,1|fragc0,42,42,0|g2gdrz,42,42,0|g2gds0,39,44,1|ga0izz,39,44,1|ga0j00,42,42,0|gl6gfz,42,42,0|gl6gg0,39,44,1|gsqlnz,39,44,1|gsqlo0,42,42,0|h3wj3z,42,42,0|h3wj40,39,44,1|hbgobz,39,44,1|hbgoc0,42,42,0|hmmlrz,42,42,0|hmmls0,39,44,1|hujpnz,39,44,1|hujpo0,42,42,0|i5cofz,42,42,0|i5cog0,39,44,1|id9sbz,39,44,1|id9sc0,42,42,0|io2r3z,42,42,0|io2r40,39,44,1|ivzuzz,39,44,1|ivzv00,42,42,0|j75sfz,42,42,0|j75sg0,39,44,1|jepxnz,39,44,1|jepxo0,42,42,0|jpvv3z,42,42,0|jpvv40,39,44,1|jyiwbz,39,44,1|jyiwc0,42,42,0|k8lxrz,42,42,0|k8lxs0,39,44,1|kgj1nz,39,44,1|kgj1o0,42,42,0|krc0fz,42,42,0|krc0g0,39,44,1|l0c0bz,39,44,1|l0c0c0,42,42,0|la233z,42,42,0|la2340,39,44,1|lkuwbz,39,44,1|lkuwc0,42,42,0|lq9f3z,42,42,0|lq9f40,39,44,1|m380bz,39,44,1|m380c0,42,42,0|m9pf3z,42,42,0|m9pf40,39,44,1|mly2zz,39,44,1|mly300,42,42,0|mssgfz,42,42,0|mssgg0,39,44,1|n4o5nz,39,44,1|n4o5o0,42,42,0|nbij3z,42,42,0|nbij40,39,44,1|o776zz,39,44,1|o77700,42,42,0|obvsfz,42,42,0|obvsg0,39,44,1|ohn4bz,39,44,1|ohn4c0,39,44,0\",\"America/Rainy_River|,0,169,0|-1353ahk,45,62,0|-qzov41,45,62,0|-qzov40,46,63,1|-qplz81,46,63,1|-qplz80,45,62,0|-f9ofc1,45,62,0|-f9ofc0,46,63,1|-ek21s1,46,63,1|-ek21s0,47,63,1|-cq2tg1,47,63,1|-cq2tg0,48,63,1|-cnp0k1,48,63,1|-cnp0k0,45,62,0|296u7z,45,62,0|296u80,46,63,1|2ijsrz,46,63,1|2ijss0,45,62,0|2rwwvz,45,62,0|2rwww0,46,63,1|319vfz,46,63,1|319vg0,45,62,0|3amzjz,45,62,0|3amzk0,46,63,1|3kcwrz,46,63,1|3kcws0,45,62,0|3td27z,45,62,0|3td280,46,63,1|432zfz,46,63,1|432zg0,45,62,0|4cg3jz,45,62,0|4cg3k0,46,63,1|4lt23z,46,63,1|4lt240,45,62,0|4v667z,45,62,0|4v6680,46,63,1|54j4rz,46,63,1|54j4s0,45,62,0|5dw8vz,45,62,0|5dw8w0,46,63,1|5n97fz,46,63,1|5n97g0,45,62,0|5wmbjz,45,62,0|5wmbk0,46,63,1|65za3z,46,63,1|65za40,45,62,0|6fce7z,45,62,0|6fce80,46,63,1|6p2bfz,46,63,1|6p2bg0,45,62,0|6y2gvz,45,62,0|6y2gw0,46,63,1|77se3z,46,63,1|77se40,45,62,0|7h5i7z,45,62,0|7h5i80,46,63,1|7qigrz,46,63,1|7qigs0,45,62,0|7zvkvz,45,62,0|7zvkw0,46,63,1|898jfz,46,63,1|898jg0,45,62,0|8ilnjz,45,62,0|8ilnk0,46,63,1|8rym3z,46,63,1|8rym40,45,62,0|908u7z,45,62,0|908u80,46,63,1|9aoorz,46,63,1|9aoos0,45,62,0|9iywvz,45,62,0|9iyww0,46,63,1|9trq3z,46,63,1|9trq40,45,62,0|a1ozjz,45,62,0|a1ozk0,46,63,1|achsrz,46,63,1|achss0,45,62,0|akf27z,45,62,0|akf280,46,63,1|av7vfz,46,63,1|av7vg0,45,62,0|b3i3jz,45,62,0|b3i3k0,46,63,1|bdxy3z,46,63,1|bdxy40,45,62,0|bm867z,45,62,0|bm8680,46,63,1|bwo0rz,46,63,1|bwo0s0,45,62,0|c4y8vz,45,62,0|c4y8w0,46,63,1|cfr23z,46,63,1|cfr240,45,62,0|cnobjz,45,62,0|cnobk0,46,63,1|cyh4rz,46,63,1|cyh4s0,45,62,0|d6ee7z,45,62,0|d6ee80,46,63,1|dh77fz,46,63,1|dh77g0,45,62,0|dphfjz,45,62,0|dphfk0,46,63,1|dzxa3z,46,63,1|dzxa40,45,62,0|e87i7z,45,62,0|e87i80,46,63,1|eincrz,46,63,1|eincs0,45,62,0|eqxkvz,45,62,0|eqxkw0,46,63,1|f1dffz,46,63,1|f1dfg0,45,62,0|f9nnjz,45,62,0|f9nnk0,46,63,1|fkggrz,46,63,1|fkggs0,45,62,0|fsdq7z,45,62,0|fsdq80,46,63,1|g36jfz,46,63,1|g36jg0,45,62,0|gb3svz,45,62,0|gb3sw0,46,63,1|glwm3z,46,63,1|glwm40,45,62,0|gu6u7z,45,62,0|gu6u80,46,63,1|h4morz,46,63,1|h4mos0,45,62,0|hcwwvz,45,62,0|hcwww0,46,63,1|hncrfz,46,63,1|hncrg0,45,62,0|hvmzjz,45,62,0|hvmzk0,46,63,1|i6fsrz,46,63,1|i6fss0,45,62,0|ied27z,45,62,0|ied280,46,63,1|ip5vfz,46,63,1|ip5vg0,45,62,0|ix34vz,45,62,0|ix34w0,46,63,1|j7vy3z,46,63,1|j7vy40,45,62,0|jeqbjz,45,62,0|jeqbk0,46,63,1|jqyzfz,46,63,1|jqyzg0,45,62,0|jxge7z,45,62,0|jxge80,46,63,1|k9p23z,46,63,1|k9p240,45,62,0|kg6gvz,45,62,0|kg6gw0,46,63,1|ksf4rz,46,63,1|ksf4s0,45,62,0|kz9i7z,45,62,0|kz9i80,46,63,1|lbi63z,46,63,1|lbi640,45,62,0|lhzkvz,45,62,0|lhzkw0,46,63,1|lu88rz,46,63,1|lu88s0,45,62,0|m0pnjz,45,62,0|m0pnk0,46,63,1|mcybfz,46,63,1|mcybg0,45,62,0|mjfq7z,45,62,0|mjfq80,46,63,1|mvoe3z,46,63,1|mvoe40,45,62,0|n25svz,45,62,0|n25sw0,46,63,1|neegrz,46,63,1|neegs0,45,62,0|nkvvjz,45,62,0|nkvvk0,46,63,1|nx4jfz,46,63,1|nx4jg0,45,62,0|o3ywvz,45,62,0|o3yww0,46,63,1|og7krz,46,63,1|og7ks0,45,62,0|omozjz,45,62,0|omozk0,46,63,1|oyxnfz,46,63,1|oyxng0,45,62,0|p5f27z,45,62,0|p5f280,46,63,1|phnq3z,46,63,1|phnq40,45,62,0|po54vz,45,62,0|po54w0,46,63,1|q0dsrz,46,63,1|q0dss0,45,62,0|q6v7jz,45,62,0|q6v7k0,46,63,1|qj3vfz,46,63,1|qj3vg0,45,62,0|qpy8vz,45,62,0|qpy8w0,46,63,1|r26wrz,46,63,1|r26ws0,45,62,0|r8objz,45,62,0|r8obk0,46,63,1|rkwzfz,46,63,1|rkwzg0,45,62,0|rree7z,45,62,0|rree80,46,63,1|s3n23z,46,63,1|s3n240,45,62,0|sa4gvz,45,62,0|sa4gw0,46,63,1|smd4rz,46,63,1|smd4s0,45,62,0|ssujjz,45,62,0|ssujk0,46,63,1|t537fz,46,63,1|t537g0,45,62,0|tbkm7z,45,62,0|tbkm80,46,63,1|tnta3z,46,63,1|tnta40,45,62,0|tunnjz,45,62,0|tunnk0,46,63,1|u6wbfz,46,63,1|u6wbg0,45,62,0|uddq7z,45,62,0|uddq80,46,63,1|upme3z,46,63,1|upme40,45,62,0|uw3svz,45,62,0|uw3sw0,46,63,1|v8cgrz,46,63,1|v8cgs0,45,62,0|vetvjz,45,62,0|vetvk0,46,63,1|vr2jfz,46,63,1|vr2jg0,45,62,0|vxjy7z,45,62,0|vxjy80,46,63,1|w9sm3z,46,63,1|w9sm40,45,62,0|wgmzjz,45,62,0|wgmzk0,46,63,1|wsvnfz,46,63,1|wsvng0,45,62,0|wzd27z,45,62,0|wzd280,46,63,1|xblq3z,46,63,1|xblq40,45,62,0|xi34vz,45,62,0|xi34w0,46,63,1|xubsrz,46,63,1|xubss0,45,62,0|y0t7jz,45,62,0|y0t7k0,46,63,1|yd1vfz,46,63,1|yd1vg0,45,62,0|yjja7z,45,62,0|yjja80,46,63,1|yvry3z,46,63,1|yvry40,45,62,0|z29cvz,45,62,0|z29cw0,46,63,1|zei0rz,46,63,1|zei0s0,45,62,0\",\"America/Rankin_Inlet|,60,1,0|-6s8lc0,45,62,0|-2g1wo1,45,62,0|-2g1wo0,86,42,1|-26bwo1,86,42,1|-26bwo0,45,62,0|5dw8vz,45,62,0|5dw8w0,46,63,1|5n97fz,46,63,1|5n97g0,45,62,0|5wmbjz,45,62,0|5wmbk0,46,63,1|65za3z,46,63,1|65za40,45,62,0|6fce7z,45,62,0|6fce80,46,63,1|6p2bfz,46,63,1|6p2bg0,45,62,0|6y2gvz,45,62,0|6y2gw0,46,63,1|77se3z,46,63,1|77se40,45,62,0|7h5i7z,45,62,0|7h5i80,46,63,1|7qigrz,46,63,1|7qigs0,45,62,0|7zvkvz,45,62,0|7zvkw0,46,63,1|898jfz,46,63,1|898jg0,45,62,0|8ilnjz,45,62,0|8ilnk0,46,63,1|8rym3z,46,63,1|8rym40,45,62,0|908u7z,45,62,0|908u80,46,63,1|9aoorz,46,63,1|9aoos0,45,62,0|9iywvz,45,62,0|9iyww0,46,63,1|9trq3z,46,63,1|9trq40,45,62,0|a1ozjz,45,62,0|a1ozk0,46,63,1|achsrz,46,63,1|achss0,45,62,0|akf27z,45,62,0|akf280,46,63,1|av7vfz,46,63,1|av7vg0,45,62,0|b3i3jz,45,62,0|b3i3k0,46,63,1|bdxy3z,46,63,1|bdxy40,45,62,0|bm867z,45,62,0|bm8680,46,63,1|bwo0rz,46,63,1|bwo0s0,45,62,0|c4y8vz,45,62,0|c4y8w0,46,63,1|cfr23z,46,63,1|cfr240,45,62,0|cnobjz,45,62,0|cnobk0,46,63,1|cyh4rz,46,63,1|cyh4s0,45,62,0|d6ee7z,45,62,0|d6ee80,46,63,1|dh77fz,46,63,1|dh77g0,45,62,0|dphfjz,45,62,0|dphfk0,46,63,1|dzxa3z,46,63,1|dzxa40,45,62,0|e87i7z,45,62,0|e87i80,46,63,1|eincrz,46,63,1|eincs0,45,62,0|eqxkvz,45,62,0|eqxkw0,46,63,1|f1dffz,46,63,1|f1dfg0,45,62,0|f9nnjz,45,62,0|f9nnk0,46,63,1|fkggrz,46,63,1|fkggs0,45,62,0|fsdq7z,45,62,0|fsdq80,46,63,1|g36jfz,46,63,1|g36jg0,49,63,0|gb3svz,49,63,0|gb3sw0,46,63,1|glwm3z,46,63,1|glwm40,45,62,0|gu6u7z,45,62,0|gu6u80,46,63,1|h4morz,46,63,1|h4mos0,45,62,0|hcwwvz,45,62,0|hcwww0,46,63,1|hncrfz,46,63,1|hncrg0,45,62,0|hvmzjz,45,62,0|hvmzk0,46,63,1|i6fsrz,46,63,1|i6fss0,45,62,0|ied27z,45,62,0|ied280,46,63,1|ip5vfz,46,63,1|ip5vg0,45,62,0|ix34vz,45,62,0|ix34w0,46,63,1|j7vy3z,46,63,1|j7vy40,45,62,0|jeqbjz,45,62,0|jeqbk0,46,63,1|jqyzfz,46,63,1|jqyzg0,45,62,0|jxge7z,45,62,0|jxge80,46,63,1|k9p23z,46,63,1|k9p240,45,62,0|kg6gvz,45,62,0|kg6gw0,46,63,1|ksf4rz,46,63,1|ksf4s0,45,62,0|kz9i7z,45,62,0|kz9i80,46,63,1|lbi63z,46,63,1|lbi640,45,62,0|lhzkvz,45,62,0|lhzkw0,46,63,1|lu88rz,46,63,1|lu88s0,45,62,0|m0pnjz,45,62,0|m0pnk0,46,63,1|mcybfz,46,63,1|mcybg0,45,62,0|mjfq7z,45,62,0|mjfq80,46,63,1|mvoe3z,46,63,1|mvoe40,45,62,0|n25svz,45,62,0|n25sw0,46,63,1|neegrz,46,63,1|neegs0,45,62,0|nkvvjz,45,62,0|nkvvk0,46,63,1|nx4jfz,46,63,1|nx4jg0,45,62,0|o3ywvz,45,62,0|o3yww0,46,63,1|og7krz,46,63,1|og7ks0,45,62,0|omozjz,45,62,0|omozk0,46,63,1|oyxnfz,46,63,1|oyxng0,45,62,0|p5f27z,45,62,0|p5f280,46,63,1|phnq3z,46,63,1|phnq40,45,62,0|po54vz,45,62,0|po54w0,46,63,1|q0dsrz,46,63,1|q0dss0,45,62,0|q6v7jz,45,62,0|q6v7k0,46,63,1|qj3vfz,46,63,1|qj3vg0,45,62,0|qpy8vz,45,62,0|qpy8w0,46,63,1|r26wrz,46,63,1|r26ws0,45,62,0|r8objz,45,62,0|r8obk0,46,63,1|rkwzfz,46,63,1|rkwzg0,45,62,0|rree7z,45,62,0|rree80,46,63,1|s3n23z,46,63,1|s3n240,45,62,0|sa4gvz,45,62,0|sa4gw0,46,63,1|smd4rz,46,63,1|smd4s0,45,62,0|ssujjz,45,62,0|ssujk0,46,63,1|t537fz,46,63,1|t537g0,45,62,0|tbkm7z,45,62,0|tbkm80,46,63,1|tnta3z,46,63,1|tnta40,45,62,0|tunnjz,45,62,0|tunnk0,46,63,1|u6wbfz,46,63,1|u6wbg0,45,62,0|uddq7z,45,62,0|uddq80,46,63,1|upme3z,46,63,1|upme40,45,62,0|uw3svz,45,62,0|uw3sw0,46,63,1|v8cgrz,46,63,1|v8cgs0,45,62,0|vetvjz,45,62,0|vetvk0,46,63,1|vr2jfz,46,63,1|vr2jg0,45,62,0|vxjy7z,45,62,0|vxjy80,46,63,1|w9sm3z,46,63,1|w9sm40,45,62,0|wgmzjz,45,62,0|wgmzk0,46,63,1|wsvnfz,46,63,1|wsvng0,45,62,0|wzd27z,45,62,0|wzd280,46,63,1|xblq3z,46,63,1|xblq40,45,62,0|xi34vz,45,62,0|xi34w0,46,63,1|xubsrz,46,63,1|xubss0,45,62,0|y0t7jz,45,62,0|y0t7k0,46,63,1|yd1vfz,46,63,1|yd1vg0,45,62,0|yjja7z,45,62,0|yjja80,46,63,1|yvry3z,46,63,1|yvry40,45,62,0|z29cvz,45,62,0|z29cw0,46,63,1|zei0rz,46,63,1|zei0s0,45,62,0\",\"America/Recife|,0,170,0|-t85ljc,39,44,0|-jylag1,39,44,0|-jylag0,40,45,1|-jpb141,40,45,1|-jpb140,39,44,0|-jfsd01,39,44,0|-jfsd00,40,45,1|-j6j3s1,40,45,1|-j6j3s0,39,44,0|-ahcyc1,39,44,0|-ahcyc0,40,45,1|-aad3o1,40,45,1|-aad3o0,39,44,0|-9yl101,39,44,0|-9yl100,40,45,1|-9sd141,40,45,1|-9sd140,39,44,0|-9ft3o1,39,44,0|-9ft3o0,40,45,1|-99j941,40,45,1|-99j940,39,44,0|-8wzbo1,39,44,0|-8wzbo0,40,45,1|-8scqg1,40,45,1|-8scqg0,39,44,0|-35xmc1,39,44,0|-35xmc0,40,45,1|-31nzs1,40,45,1|-31nzs0,39,44,0|-2kdp01,39,44,0|-2kdp00,40,45,1|-2hcig1,40,45,1|-2hcig0,39,44,0|-24qqc1,39,44,0|-24qqc0,40,45,1|-204541,40,45,1|-204540,39,44,0|-1nid01,39,44,0|-1nid00,40,45,1|-1hc7s1,40,45,1|-1hc7s0,39,44,0|-14qfo1,39,44,0|-14qfo0,40,45,1|-yifs1,40,45,1|-yifs0,39,44,0|89jcbz,39,44,0|89jcc0,40,45,1|8gdk7z,40,45,1|8gdk80,39,44,0|8rwgbz,39,44,0|8rwgc0,40,45,1|8xns7z,40,45,1|8xns80,39,44,0|9aodnz,39,44,0|9aodo0,40,45,1|9g2qvz,40,45,1|9g2qw0,39,44,0|9t1hnz,39,44,0|9t1ho0,40,45,1|9yfuvz,40,45,1|9yfuw0,39,44,0|abrkbz,39,44,0|abrkc0,40,45,1|ahvuvz,40,45,1|ahvuw0,39,44,0|fj0azz,39,44,0|fj0b00,40,45,1|fqkg7z,40,45,1|fqkg80,39,44,0|g23cbz,39,44,0|g23cc0,40,45,1|g2g87z,40,45,1|g2g880,39,44,0|gl6dnz,39,44,0|gl6do0,40,45,1|grnmvz,40,45,1|grnmw0,39,44,0\",\"America/Regina|,0,171,0|-xkq9yc,50,66,0|-qzosc1,50,66,0|-qzosc0,52,62,1|-qplwg1,52,62,1|-qplwg0,50,66,0|-kp78k1,50,66,0|-kp78k0,52,62,1|-kha4o1,52,62,1|-kha4o0,50,66,0|-k6h5w1,50,66,0|-k6h5w0,52,62,1|-jyk201,52,62,1|-jyk200,50,66,0|-jnr381,50,66,0|-jnr380,52,62,1|-jftzc1,52,62,1|-jftzc0,50,66,0|-j4o1w1,50,66,0|-j4o1w0,52,62,1|-ix3wo1,52,62,1|-ix3wo0,50,66,0|-ilxz81,50,66,0|-ilxz80,52,62,1|-ie0vc1,52,62,1|-ie0vc0,50,66,0|-h2un81,50,66,0|-h2un80,52,62,1|-gthoo1,52,62,1|-gthoo0,50,66,0|-gk4kk1,50,66,0|-gk4kk0,52,62,1|-gb4ko1,52,62,1|-gb4ko0,50,66,0|-g1ehw1,50,66,0|-g1ehw0,52,62,1|-fs1jc1,52,62,1|-fs1jc0,50,66,0|-fibgk1,50,66,0|-fibgk0,52,62,1|-f8yi01,52,62,1|-f8yi00,50,66,0|-ezldw1,50,66,0|-ezldw0,52,62,1|-eq8fc1,52,62,1|-eq8fc0,50,66,0|-ek1z01,50,66,0|-ek1z00,58,62,1|-cq2tg1,58,62,1|-cq2tg0,59,62,1|-cnoxs1,59,62,1|-cnoxs0,50,66,0|-cdlwc1,50,66,0|-cdlwc0,52,62,1|-c48xs1,52,62,1|-c48xs0,50,66,0|-bu5wc1,50,66,0|-bu5wc0,52,62,1|-bm8sg1,52,62,1|-bm8sg0,50,66,0|-bbfto1,50,66,0|-bbfto0,52,62,1|-b3ips1,52,62,1|-b3ips0,50,66,0|-aspr01,50,66,0|-aspr00,52,62,1|-aksn41,52,62,1|-aksn40,50,66,0|-a9mpo1,50,66,0|-a9mpo0,52,62,1|-a22kg1,52,62,1|-a22kg0,50,66,0|-9qwn01,50,66,0|-9qwn00,52,62,1|-9izj41,52,62,1|-9izj40,50,66,0|-986kc1,50,66,0|-986kc0,52,62,1|-909gg1,52,62,1|-909gg0,50,66,0|-8pgho1,50,66,0|-8pgho0,52,62,1|-8hjds1,52,62,1|-8hjds0,50,66,0|-86qf01,50,66,0|-86qf00,52,62,1|-7ytb41,52,62,1|-7ytb40,50,66,0|-7o0cc1,50,66,0|-7o0cc0,52,62,1|-7g38g1,52,62,1|-7g38g0,50,66,0|-74xb01,50,66,0|-74xb00,52,62,1|-6x0741,52,62,1|-6x0740,50,66,0|-6m78c1,50,66,0|-6m78c0,52,62,1|-6ea4g1,52,62,1|-6ea4g0,50,66,0|-5kr301,50,66,0|-5kr300,52,62,1|-5be4g1,52,62,1|-5be4g0,50,66,0|-5210c1,50,66,0|-5210c0,45,62,0\",\"America/Resolute|,60,1,0|-bnp9c0,45,62,0|-2g1wo1,45,62,0|-2g1wo0,86,42,1|-26bwo1,86,42,1|-26bwo0,45,62,0|5dw8vz,45,62,0|5dw8w0,46,63,1|5n97fz,46,63,1|5n97g0,45,62,0|5wmbjz,45,62,0|5wmbk0,46,63,1|65za3z,46,63,1|65za40,45,62,0|6fce7z,45,62,0|6fce80,46,63,1|6p2bfz,46,63,1|6p2bg0,45,62,0|6y2gvz,45,62,0|6y2gw0,46,63,1|77se3z,46,63,1|77se40,45,62,0|7h5i7z,45,62,0|7h5i80,46,63,1|7qigrz,46,63,1|7qigs0,45,62,0|7zvkvz,45,62,0|7zvkw0,46,63,1|898jfz,46,63,1|898jg0,45,62,0|8ilnjz,45,62,0|8ilnk0,46,63,1|8rym3z,46,63,1|8rym40,45,62,0|908u7z,45,62,0|908u80,46,63,1|9aoorz,46,63,1|9aoos0,45,62,0|9iywvz,45,62,0|9iyww0,46,63,1|9trq3z,46,63,1|9trq40,45,62,0|a1ozjz,45,62,0|a1ozk0,46,63,1|achsrz,46,63,1|achss0,45,62,0|akf27z,45,62,0|akf280,46,63,1|av7vfz,46,63,1|av7vg0,45,62,0|b3i3jz,45,62,0|b3i3k0,46,63,1|bdxy3z,46,63,1|bdxy40,45,62,0|bm867z,45,62,0|bm8680,46,63,1|bwo0rz,46,63,1|bwo0s0,45,62,0|c4y8vz,45,62,0|c4y8w0,46,63,1|cfr23z,46,63,1|cfr240,45,62,0|cnobjz,45,62,0|cnobk0,46,63,1|cyh4rz,46,63,1|cyh4s0,45,62,0|d6ee7z,45,62,0|d6ee80,46,63,1|dh77fz,46,63,1|dh77g0,45,62,0|dphfjz,45,62,0|dphfk0,46,63,1|dzxa3z,46,63,1|dzxa40,45,62,0|e87i7z,45,62,0|e87i80,46,63,1|eincrz,46,63,1|eincs0,45,62,0|eqxkvz,45,62,0|eqxkw0,46,63,1|f1dffz,46,63,1|f1dfg0,45,62,0|f9nnjz,45,62,0|f9nnk0,46,63,1|fkggrz,46,63,1|fkggs0,45,62,0|fsdq7z,45,62,0|fsdq80,46,63,1|g36jfz,46,63,1|g36jg0,49,63,0|gb3svz,49,63,0|gb3sw0,46,63,1|glwm3z,46,63,1|glwm40,45,62,0|gu6u7z,45,62,0|gu6u80,46,63,1|h4morz,46,63,1|h4mos0,45,62,0|hcwwvz,45,62,0|hcwww0,46,63,1|hncrfz,46,63,1|hncrg0,45,62,0|hvmzjz,45,62,0|hvmzk0,46,63,1|i6fsrz,46,63,1|i6fss0,45,62,0|ied27z,45,62,0|ied280,46,63,1|ip5vfz,46,63,1|ip5vg0,45,62,0|ix34vz,45,62,0|ix34w0,46,63,1|j7vy3z,46,63,1|j7vy40,49,63,0|jeqbjz,49,63,0|jeqbk0,46,63,1|jqyzfz,46,63,1|jqyzg0,45,62,0|jxge7z,45,62,0|jxge80,46,63,1|k9p23z,46,63,1|k9p240,45,62,0|kg6gvz,45,62,0|kg6gw0,46,63,1|ksf4rz,46,63,1|ksf4s0,45,62,0|kz9i7z,45,62,0|kz9i80,46,63,1|lbi63z,46,63,1|lbi640,45,62,0|lhzkvz,45,62,0|lhzkw0,46,63,1|lu88rz,46,63,1|lu88s0,45,62,0|m0pnjz,45,62,0|m0pnk0,46,63,1|mcybfz,46,63,1|mcybg0,45,62,0|mjfq7z,45,62,0|mjfq80,46,63,1|mvoe3z,46,63,1|mvoe40,45,62,0|n25svz,45,62,0|n25sw0,46,63,1|neegrz,46,63,1|neegs0,45,62,0|nkvvjz,45,62,0|nkvvk0,46,63,1|nx4jfz,46,63,1|nx4jg0,45,62,0|o3ywvz,45,62,0|o3yww0,46,63,1|og7krz,46,63,1|og7ks0,45,62,0|omozjz,45,62,0|omozk0,46,63,1|oyxnfz,46,63,1|oyxng0,45,62,0|p5f27z,45,62,0|p5f280,46,63,1|phnq3z,46,63,1|phnq40,45,62,0|po54vz,45,62,0|po54w0,46,63,1|q0dsrz,46,63,1|q0dss0,45,62,0|q6v7jz,45,62,0|q6v7k0,46,63,1|qj3vfz,46,63,1|qj3vg0,45,62,0|qpy8vz,45,62,0|qpy8w0,46,63,1|r26wrz,46,63,1|r26ws0,45,62,0|r8objz,45,62,0|r8obk0,46,63,1|rkwzfz,46,63,1|rkwzg0,45,62,0|rree7z,45,62,0|rree80,46,63,1|s3n23z,46,63,1|s3n240,45,62,0|sa4gvz,45,62,0|sa4gw0,46,63,1|smd4rz,46,63,1|smd4s0,45,62,0|ssujjz,45,62,0|ssujk0,46,63,1|t537fz,46,63,1|t537g0,45,62,0|tbkm7z,45,62,0|tbkm80,46,63,1|tnta3z,46,63,1|tnta40,45,62,0|tunnjz,45,62,0|tunnk0,46,63,1|u6wbfz,46,63,1|u6wbg0,45,62,0|uddq7z,45,62,0|uddq80,46,63,1|upme3z,46,63,1|upme40,45,62,0|uw3svz,45,62,0|uw3sw0,46,63,1|v8cgrz,46,63,1|v8cgs0,45,62,0|vetvjz,45,62,0|vetvk0,46,63,1|vr2jfz,46,63,1|vr2jg0,45,62,0|vxjy7z,45,62,0|vxjy80,46,63,1|w9sm3z,46,63,1|w9sm40,45,62,0|wgmzjz,45,62,0|wgmzk0,46,63,1|wsvnfz,46,63,1|wsvng0,45,62,0|wzd27z,45,62,0|wzd280,46,63,1|xblq3z,46,63,1|xblq40,45,62,0|xi34vz,45,62,0|xi34w0,46,63,1|xubsrz,46,63,1|xubss0,45,62,0|y0t7jz,45,62,0|y0t7k0,46,63,1|yd1vfz,46,63,1|yd1vg0,45,62,0|yjja7z,45,62,0|yjja80,46,63,1|yvry3z,46,63,1|yvry40,45,62,0|z29cvz,45,62,0|z29cw0,46,63,1|zei0rz,46,63,1|zei0s0,45,62,0\",\"America/Rio_Branco|,0,172,0|-t85fg0,56,63,0|-jyl4w1,56,63,0|-jyl4w0,42,42,1|-jpavk1,42,42,1|-jpavk0,56,63,0|-jfs7g1,56,63,0|-jfs7g0,42,42,1|-j6iy81,42,42,1|-j6iy80,56,63,0|-ahcss1,56,63,0|-ahcss0,42,42,1|-aacy41,42,42,1|-aacy40,56,63,0|-9ykvg1,56,63,0|-9ykvg0,42,42,1|-9scvk1,42,42,1|-9scvk0,56,63,0|-9fsy41,56,63,0|-9fsy40,42,42,1|-99j3k1,42,42,1|-99j3k0,56,63,0|-8wz641,56,63,0|-8wz640,42,42,1|-8sckw1,42,42,1|-8sckw0,56,63,0|-35xgs1,56,63,0|-35xgs0,42,42,1|-31nu81,42,42,1|-31nu80,56,63,0|-2kdjg1,56,63,0|-2kdjg0,42,42,1|-2hccw1,42,42,1|-2hccw0,56,63,0|-24qks1,56,63,0|-24qks0,42,42,1|-203zk1,42,42,1|-203zk0,56,63,0|-1ni7g1,56,63,0|-1ni7g0,42,42,1|-1hc281,42,42,1|-1hc280,56,63,0|-14qa41,56,63,0|-14qa40,42,42,1|-yia81,42,42,1|-yia80,56,63,0|89jhvz,56,63,0|89jhw0,42,42,1|8gdprz,42,42,1|8gdps0,56,63,0|8rwlvz,56,63,0|8rwlw0,42,42,1|8xnxrz,42,42,1|8xnxs0,56,63,0|9aoj7z,56,63,0|9aoj80,42,42,1|9g2wfz,42,42,1|9g2wg0,56,63,0|k2yb7z,56,63,0|k2yb80,42,42,0|mw14fz,42,42,0|mw14g0,56,63,0\",\"America/Santarem|,0,173,0|-t85hvc,42,42,0|-jyl7o1,42,42,0|-jyl7o0,39,44,1|-jpayc1,39,44,1|-jpayc0,42,42,0|-jfsa81,42,42,0|-jfsa80,39,44,1|-j6j101,39,44,1|-j6j100,42,42,0|-ahcvk1,42,42,0|-ahcvk0,39,44,1|-aad0w1,39,44,1|-aad0w0,42,42,0|-9yky81,42,42,0|-9yky80,39,44,1|-9scyc1,39,44,1|-9scyc0,42,42,0|-9ft0w1,42,42,0|-9ft0w0,39,44,1|-99j6c1,39,44,1|-99j6c0,42,42,0|-8wz8w1,42,42,0|-8wz8w0,39,44,1|-8scno1,39,44,1|-8scno0,42,42,0|-35xjk1,42,42,0|-35xjk0,39,44,1|-31nx01,39,44,1|-31nx00,42,42,0|-2kdm81,42,42,0|-2kdm80,39,44,1|-2hcfo1,39,44,1|-2hcfo0,42,42,0|-24qnk1,42,42,0|-24qnk0,39,44,1|-2042c1,39,44,1|-2042c0,42,42,0|-1nia81,42,42,0|-1nia80,39,44,1|-1hc501,39,44,1|-1hc500,42,42,0|-14qcw1,42,42,0|-14qcw0,39,44,1|-yid01,39,44,1|-yid00,42,42,0|89jf3z,42,42,0|89jf40,39,44,1|8gdmzz,39,44,1|8gdn00,42,42,0|8rwj3z,42,42,0|8rwj40,39,44,1|8xnuzz,39,44,1|8xnv00,42,42,0|9aogfz,42,42,0|9aogg0,39,44,1|9g2tnz,39,44,1|9g2to0,42,42,0|k2y8fz,42,42,0|k2y8g0,39,44,0\",\"America/Santiago|,0,168,0|-15r0w8q,85,168,0|-vauawr,85,168,0|-vauawq,56,63,0|-rx8i41,56,63,0|-rx8i40,85,168,0|-qs16wr,85,168,0|-qs16wq,42,42,0|-qcwsw1,42,42,0|-qcwsw0,85,168,0|-m3etkr,85,168,0|-m3etkq,42,42,1|-lsgfk1,42,42,1|-lsgfk0,56,63,0|-lkl0s1,56,63,0|-lkl0s0,42,42,1|-l9oi81,42,42,1|-l9oi80,56,63,0|-l1t3g1,56,63,0|-l1t3g0,42,42,1|-kqwkw1,42,42,1|-kqwkw0,56,63,0|-kj1641,56,63,0|-kj1640,42,42,1|-k84nk1,42,42,1|-k84nk0,56,63,0|-k098s1,56,63,0|-k098s0,42,42,1|-jpavk1,42,42,1|-jpavk0,56,63,0|-jhfgs1,56,63,0|-jhfgs0,42,42,0|-eeay81,42,42,0|-eeay80,56,63,0|-eb5ws1,56,63,0|-eb5ws0,42,42,0|-c8vww1,42,42,0|-c8vww0,39,44,1|-c6f3o1,39,44,1|-c6f3o0,42,42,0|-bvifk1,42,42,0|-bvifk0,56,63,0|-bsvzk1,56,63,0|-bsvzk0,42,42,0|-lsvk1,42,42,0|-lsvk0,39,44,1|-e8qc1,39,44,1|-e8qc0,42,42,0|-1zww1,42,42,0|-1zww0,39,44,1|4hcbz,39,44,1|4hcc0,42,42,0|ekdrz,42,42,0|ekds0,39,44,1|mhhnz,39,44,1|mhho0,42,42,0|xagfz,42,42,0|xagg0,39,44,1|157kbz,39,44,1|157kc0,42,42,0|1gdhrz,42,42,0|1gdhs0,39,44,1|1nxmzz,39,44,1|1nxn00,42,42,0|1ydn3z,42,42,0|1ydn40,39,44,1|26npnz,39,44,1|26npo0,42,42,0|2htn3z,42,42,0|2htn40,39,44,1|2pdsbz,39,44,1|2pdsc0,42,42,0|30jprz,42,42,0|30jps0,39,44,1|38gtnz,39,44,1|38gto0,42,42,0|3j9sfz,42,42,0|3j9sg0,39,44,1|3r6wbz,39,44,1|3r6wc0,42,42,0|41zv3z,42,42,0|41zv40,39,44,1|49wyzz,39,44,1|49wz00,42,42,0|4l2wfz,42,42,0|4l2wg0,39,44,1|4sn1nz,39,44,1|4sn1o0,42,42,0|53sz3z,42,42,0|53sz40,39,44,1|5bd4bz,39,44,1|5bd4c0,42,42,0|5mj1rz,42,42,0|5mj1s0,39,44,1|5ug5nz,39,44,1|5ug5o0,42,42,0|6594fz,42,42,0|6594g0,39,44,1|6d68bz,39,44,1|6d68c0,42,42,0|6nz73z,42,42,0|6nz740,39,44,1|6vwazz,39,44,1|6vwb00,42,42,0|76p9rz,42,42,0|76p9s0,39,44,1|7emdnz,39,44,1|7emdo0,42,42,0|7psb3z,42,42,0|7psb40,39,44,1|7xcgbz,39,44,1|7xcgc0,42,42,0|88idrz,42,42,0|88ids0,39,44,1|8g2izz,39,44,1|8g2j00,42,42,0|8r8gfz,42,42,0|8r8gg0,39,44,1|90lezz,39,44,1|90lf00,42,42,0|99yj3z,42,42,0|99yj40,39,44,1|9hvmzz,39,44,1|9hvn00,42,42,0|9solrz,42,42,0|9sols0,39,44,1|a0lpnz,39,44,1|a0lpo0,42,42,0|abrn3z,42,42,0|abrn40,39,44,1|ajbsbz,39,44,1|ajbsc0,42,42,0|at1v3z,42,42,0|at1v40,39,44,1|b21uzz,39,44,1|b21v00,42,42,0|bd7sfz,42,42,0|bd7sg0,39,44,1|bl4wbz,39,44,1|bl4wc0,42,42,0|bvxv3z,42,42,0|bvxv40,39,44,1|c3uyzz,39,44,1|c3uz00,42,42,0|cenxrz,42,42,0|cenxs0,39,44,1|cml1nz,39,44,1|cml1o0,42,42,0|cxe0fz,42,42,0|cxe0g0,39,44,1|d5b4bz,39,44,1|d5b4c0,42,42,0|dgh1rz,42,42,0|dgh1s0,39,44,1|do16zz,39,44,1|do1700,42,42,0|dz74fz,42,42,0|dz74g0,39,44,1|e7u5nz,39,44,1|e7u5o0,42,42,0|ehx73z,42,42,0|ehx740,39,44,1|epuazz,39,44,1|epub00,42,42,0|ezxcfz,42,42,0|ezxcg0,39,44,1|f9n9nz,39,44,1|f9n9o0,42,42,0|fjdcfz,42,42,0|fjdcg0,39,44,1|fragbz,39,44,1|fragc0,42,42,0|g2gdrz,42,42,0|g2gds0,39,44,1|ga0izz,39,44,1|ga0j00,42,42,0|gl6gfz,42,42,0|gl6gg0,39,44,1|gsqlnz,39,44,1|gsqlo0,42,42,0|h3wj3z,42,42,0|h3wj40,39,44,1|hbgobz,39,44,1|hbgoc0,42,42,0|hmmlrz,42,42,0|hmmls0,39,44,1|hujpnz,39,44,1|hujpo0,42,42,0|i5cofz,42,42,0|i5cog0,39,44,1|id9sbz,39,44,1|id9sc0,42,42,0|io2r3z,42,42,0|io2r40,39,44,1|ivzuzz,39,44,1|ivzv00,42,42,0|j75sfz,42,42,0|j75sg0,39,44,1|jepxnz,39,44,1|jepxo0,42,42,0|jpvv3z,42,42,0|jpvv40,39,44,1|jyiwbz,39,44,1|jyiwc0,42,42,0|k8lxrz,42,42,0|k8lxs0,39,44,1|kgj1nz,39,44,1|kgj1o0,42,42,0|krc0fz,42,42,0|krc0g0,39,44,1|l0c0bz,39,44,1|l0c0c0,42,42,0|la233z,42,42,0|la2340,39,44,1|lkuwbz,39,44,1|lkuwc0,42,42,0|lq9f3z,42,42,0|lq9f40,39,44,1|m380bz,39,44,1|m380c0,42,42,0|m9pf3z,42,42,0|m9pf40,39,44,1|mly2zz,39,44,1|mly300,42,42,0|mssgfz,42,42,0|mssgg0,39,44,1|n4o5nz,39,44,1|n4o5o0,42,42,0|nbij3z,42,42,0|nbij40,39,44,1|o776zz,39,44,1|o77700,42,42,0|obvsfz,42,42,0|obvsg0,39,44,1|opx9nz,39,44,1|opx9o0,42,42,0|oulv3z,42,42,0|oulv40,39,44,1|p8ncbz,39,44,1|p8ncc0,42,42,0|pdbxrz,42,42,0|pdbxs0,39,44,1|ppklnz,39,44,1|ppklo0,42,42,0|pxhv3z,42,42,0|pxhv40,39,44,1|q8aobz,39,44,1|q8aoc0,42,42,0|qg7xrz,42,42,0|qg7xs0,39,44,1|qr0qzz,39,44,1|qr0r00,42,42,0|qyy0fz,42,42,0|qyy0g0,39,44,1|r9qtnz,39,44,1|r9qto0,42,42,0|rho33z,42,42,0|rho340,39,44,1|rsgwbz,39,44,1|rsgwc0,42,42,0|s0e5rz,42,42,0|s0e5s0,39,44,1|sbjxnz,39,44,1|sbjxo0,42,42,0|sjh73z,42,42,0|sjh740,39,44,1|sua0bz,39,44,1|sua0c0,42,42,0|t279rz,42,42,0|t279s0,39,44,1|td02zz,39,44,1|td0300,42,42,0|tkxcfz,42,42,0|tkxcg0,39,44,1|tvq5nz,39,44,1|tvq5o0,42,42,0|u3nf3z,42,42,0|u3nf40,39,44,1|ueg8bz,39,44,1|ueg8c0,42,42,0|umdhrz,42,42,0|umdhs0,39,44,1|uxj9nz,39,44,1|uxj9o0,42,42,0|v53kfz,42,42,0|v53kg0,39,44,1|vg9cbz,39,44,1|vg9cc0,42,42,0|vo6lrz,42,42,0|vo6ls0,39,44,1|vyzezz,39,44,1|vyzf00,42,42,0|w6wofz,42,42,0|w6wog0,39,44,1|whphnz,39,44,1|whpho0,42,42,0|wpmr3z,42,42,0|wpmr40,39,44,1|x0fkbz,39,44,1|x0fkc0,42,42,0|x8ctrz,42,42,0|x8cts0,39,44,1|xj5mzz,39,44,1|xj5n00,42,42,0|xr2wfz,42,42,0|xr2wg0,39,44,1|y28obz,39,44,1|y28oc0,42,42,0|y9sz3z,42,42,0|y9sz40,39,44,1|ykyqzz,39,44,1|ykyr00,42,42,0|ysw0fz,42,42,0|ysw0g0,39,44,1|z3otnz,39,44,1|z3oto0,42,42,0|zbm33z,42,42,0|zbm340,39,44,1\",\"America/Santo_Domingo|,0,174,0|-15r0we0,87,175,0|-j6hz1d,87,175,0|-j6hz1c,49,63,0|-1nlws1,49,63,0|-1nlws0,62,42,1|-1hdww1,62,42,1|-1hdww0,49,63,0|-3fos1,49,63,0|-3fos0,43,59,1|2mshz,43,59,1|2msi0,49,63,0|fadvz,49,63,0|fadw0,43,59,1|jrghz,43,59,1|jrgi0,49,63,0|ydf7z,49,63,0|ydf80,43,59,1|12l8hz,43,59,1|12l8i0,49,63,0|1h3hvz,49,63,0|1h3hw0,43,59,1|1lf0hz,43,59,1|1lf0i0,49,63,0|1ztkjz,49,63,0|1ztkk0,43,59,1|246xtz,43,59,1|246xu0,49,63,0|2ijn7z,49,63,0|2ijn80,32,42,0|g36gnz,32,42,0|g36go0,49,63,0|g4z9zz,49,63,0|g4za00,32,42,0\",\"America/Sao_Paulo|,0,176,0|-t85jd8,39,44,0|-jylag1,39,44,0|-jylag0,40,45,1|-jpb141,40,45,1|-jpb140,39,44,0|-jfsd01,39,44,0|-jfsd00,40,45,1|-j6j3s1,40,45,1|-j6j3s0,39,44,0|-ahcyc1,39,44,0|-ahcyc0,40,45,1|-aad3o1,40,45,1|-aad3o0,39,44,0|-9yl101,39,44,0|-9yl100,40,45,1|-9sd141,40,45,1|-9sd140,39,44,0|-9ft3o1,39,44,0|-9ft3o0,40,45,1|-99j941,40,45,1|-99j940,39,44,0|-8wzbo1,39,44,0|-8wzbo0,40,45,1|-8scqg1,40,45,1|-8scqg0,39,44,0|-38cno1,39,44,0|-38cno0,40,45,1|-31nzs1,40,45,1|-31nzs0,39,44,0|-2kdp01,39,44,0|-2kdp00,40,45,1|-2hcig1,40,45,1|-2hcig0,39,44,0|-24qqc1,39,44,0|-24qqc0,40,45,1|-204541,40,45,1|-204540,39,44,0|-1nid01,39,44,0|-1nid00,40,45,1|-1hc7s1,40,45,1|-1hc7s0,39,44,0|-14qfo1,39,44,0|-14qfo0,40,45,1|-yifs1,40,45,1|-yifs0,39,44,0|89jcbz,39,44,0|89jcc0,40,45,1|8gdk7z,40,45,1|8gdk80,39,44,0|8rwgbz,39,44,0|8rwgc0,40,45,1|8xns7z,40,45,1|8xns80,39,44,0|9aodnz,39,44,0|9aodo0,40,45,1|9g2qvz,40,45,1|9g2qw0,39,44,0|9t1hnz,39,44,0|9t1ho0,40,45,1|9yfuvz,40,45,1|9yfuw0,39,44,0|abrkbz,39,44,0|abrkc0,40,45,1|ahvuvz,40,45,1|ahvuw0,39,44,0|auulnz,39,44,0|auulo0,40,45,1|b0yw7z,40,45,1|b0yw80,39,44,0|bdkobz,39,44,0|bdkoc0,40,45,1|bjc07z,40,45,1|bjc080,39,44,0|bwnpnz,39,44,0|bwnpo0,40,45,1|c1p47z,40,45,1|c1p480,39,44,0|cf0tnz,39,44,0|cf0to0,40,45,1|cli2vz,40,45,1|cli2w0,39,44,0|cxqwbz,39,44,0|cxqwc0,40,45,1|d485jz,40,45,1|d485k0,39,44,0|dggyzz,39,44,0|dggz00,40,45,1|dml9jz,40,45,1|dml9k0,39,44,0|dyu2zz,39,44,0|dyu300,40,45,1|e5oavz,40,45,1|e5oaw0,39,44,0|ehm0bz,39,44,0|ehm0c0,40,45,1|ep4avz,40,45,1|ep4aw0,39,44,0|f0n6zz,39,44,0|f0n700,40,45,1|f7hevz,40,45,1|f7hew0,39,44,0|fj0azz,39,44,0|fj0b00,40,45,1|fqkg7z,40,45,1|fqkg80,39,44,0|g23cbz,39,44,0|g23cc0,40,45,1|g8xk7z,40,45,1|g8xk80,39,44,0|gl6dnz,39,44,0|gl6do0,40,45,1|grnmvz,40,45,1|grnmw0,39,44,0|h4zcbz,39,44,0|h4zcc0,40,45,1|hadpjz,40,45,1|hadpk0,39,44,0|hmzhnz,39,44,0|hmzho0,40,45,1|ht3s7z,40,45,1|ht3s80,39,44,0|i6j6zz,39,44,0|i6j700,40,45,1|ic6tjz,40,45,1|ic6tk0,39,44,0|iofmzz,39,44,0|iofn00,40,45,1|iuww7z,40,45,1|iuww80,39,44,0|j88lnz,39,44,0|j88lo0,40,45,1|jdzxjz,40,45,1|jdzxk0,39,44,0|jpvsbz,39,44,0|jpvsc0,40,45,1|jwd1jz,40,45,1|jwd1k0,39,44,0|k8ytnz,39,44,0|k8yto0,40,45,1|kf347z,40,45,1|kf3480,39,44,0|krowbz,39,44,0|krowc0,40,45,1|ky65jz,40,45,1|ky65k0,39,44,0|laeyzz,39,44,0|laez00,40,45,1|lgw87z,40,45,1|lgw880,39,44,0|lt51nz,39,44,0|lt51o0,40,45,1|lzz9jz,40,45,1|lzz9k0,39,44,0|mc82zz,39,44,0|mc8300,40,45,1|micdjz,40,45,1|micdk0,39,44,0|muy5nz,39,44,0|muy5o0,40,45,1|n12g7z,40,45,1|n12g80,39,44,0|ndo8bz,39,44,0|ndo8c0,40,45,1|nk5hjz,40,45,1|nk5hk0,39,44,0|nweazz,39,44,0|nweb00,40,45,1|o2vk7z,40,45,1|o2vk80,39,44,0|of4dnz,39,44,0|of4do0,40,45,1|ollmvz,40,45,1|ollmw0,39,44,0|oxugbz,39,44,0|oxugc0,40,45,1|p4bpjz,40,45,1|p4bpk0,39,44,0|phnezz,39,44,0|phnf00,40,45,1|pn1s7z,40,45,1|pn1s80,39,44,0\",\"America/Scoresbysund|,0,177,0|-rvurxk,40,45,0|5ct1rz,40,45,0|5ct1s0,13,15,1|5lt4fz,13,15,1|5lt4g0,40,45,0|5v607z,40,45,0|5v6080,17,1,1|64iyrz,17,1,1|64iys0,13,15,0|6dw03z,13,15,0|6dw040,17,1,1|6n91fz,17,1,1|6n91g0,13,15,0|6wm2rz,13,15,0|6wm2s0,17,1,1|75z43z,17,1,1|75z440,13,15,0|7fc5fz,13,15,0|7fc5g0,17,1,1|7p25fz,17,1,1|7p25g0,13,15,0|7yf6rz,13,15,0|7yf6s0,17,1,1|87s83z,17,1,1|87s840,13,15,0|8h59fz,13,15,0|8h59g0,17,1,1|8qiarz,17,1,1|8qias0,13,15,0|8zvc3z,13,15,0|8zvc40,17,1,1|998dfz,17,1,1|998dg0,13,15,0|9ilerz,13,15,0|9iles0,17,1,1|9ryg3z,17,1,1|9ryg40,13,15,0|a1bhfz,13,15,0|a1bhg0,17,1,1|aaoirz,17,1,1|aaois0,13,15,0|ak1k3z,13,15,0|ak1k40,17,1,1|atrk3z,17,1,1|atrk40,13,15,0|b34lfz,13,15,0|b34lg0,17,1,1|bchmrz,17,1,1|bchms0,13,15,0|bluo3z,13,15,0|bluo40,17,1,1|bv7pfz,17,1,1|bv7pg0,13,15,0|c4kqrz,13,15,0|c4kqs0,17,1,1|cdxs3z,17,1,1|cdxs40,13,15,0|cnatfz,13,15,0|cnatg0,17,1,1|cwnurz,17,1,1|cwnus0,13,15,0|d60w3z,13,15,0|d60w40,17,1,1|dfdxfz,17,1,1|dfdxg0,13,15,0|dp3xfz,13,15,0|dp3xg0,17,1,1|dzwtfz,17,1,1|dzwtg0,13,15,0|e7u03z,13,15,0|e7u040,17,1,1|eimw3z,17,1,1|eimw40,13,15,0|eqk2rz,13,15,0|eqk2s0,17,1,1|f1cyrz,17,1,1|f1cys0,13,15,0|f9a5fz,13,15,0|f9a5g0,17,1,1|fkg03z,17,1,1|fkg040,13,15,0|fs083z,13,15,0|fs0840,17,1,1|g362rz,17,1,1|g362s0,13,15,0|gaqarz,13,15,0|gaqas0,17,1,1|glw5fz,17,1,1|glw5g0,13,15,0|gttc3z,13,15,0|gttc40,17,1,1|h4m83z,17,1,1|h4m840,13,15,0|hcjerz,13,15,0|hcjes0,17,1,1|hncarz,17,1,1|hncas0,13,15,0|hv9hfz,13,15,0|hv9hg0,17,1,1|i6fc3z,17,1,1|i6fc40,13,15,0|idzk3z,13,15,0|idzk40,17,1,1|ip5erz,17,1,1|ip5es0,13,15,0|iwpmrz,13,15,0|iwpms0,17,1,1|j7vhfz,17,1,1|j7vhg0,13,15,0|jffpfz,13,15,0|jffpg0,17,1,1|jqlk3z,17,1,1|jqlk40,13,15,0|jyiqrz,13,15,0|jyiqs0,17,1,1|k9bmrz,17,1,1|k9bms0,13,15,0|kh8tfz,13,15,0|kh8tg0,17,1,1|ks1pfz,17,1,1|ks1pg0,13,15,0|kzyw3z,13,15,0|kzyw40,17,1,1|lb4qrz,17,1,1|lb4qs0,13,15,0|lioyrz,13,15,0|lioys0,17,1,1|ltutfz,17,1,1|ltutg0,13,15,0|m1f1fz,13,15,0|m1f1g0,17,1,1|mckw3z,17,1,1|mckw40,13,15,0|mki2rz,13,15,0|mki2s0,17,1,1|mvayrz,17,1,1|mvays0,13,15,0|n385fz,13,15,0|n385g0,17,1,1|ne11fz,17,1,1|ne11g0,13,15,0|nly83z,13,15,0|nly840,17,1,1|nwr43z,17,1,1|nwr440,13,15,0|o4oarz,13,15,0|o4oas0,17,1,1|ofu5fz,17,1,1|ofu5g0,13,15,0|onedfz,13,15,0|onedg0,17,1,1|oyk83z,17,1,1|oyk840,13,15,0|p64g3z,13,15,0|p64g40,17,1,1|phaarz,17,1,1|phaas0,13,15,0|pp7hfz,13,15,0|pp7hg0,17,1,1|q00dfz,17,1,1|q00dg0,13,15,0|q7xk3z,13,15,0|q7xk40,17,1,1|qiqg3z,17,1,1|qiqg40,13,15,0|qqnmrz,13,15,0|qqnms0,17,1,1|r1thfz,17,1,1|r1thg0,13,15,0|r9dpfz,13,15,0|r9dpg0,17,1,1|rkjk3z,17,1,1|rkjk40,13,15,0|rs3s3z,13,15,0|rs3s40,17,1,1|s39mrz,17,1,1|s39ms0,13,15,0|sb6tfz,13,15,0|sb6tg0,17,1,1|slzpfz,17,1,1|slzpg0,13,15,0|stww3z,13,15,0|stww40,17,1,1|t4ps3z,17,1,1|t4ps40,13,15,0|tcmyrz,13,15,0|tcmys0,17,1,1|tnfurz,17,1,1|tnfus0,13,15,0|tvd1fz,13,15,0|tvd1g0,17,1,1|u6iw3z,17,1,1|u6iw40,13,15,0|ue343z,13,15,0|ue3440,17,1,1|up8yrz,17,1,1|up8ys0,13,15,0|uwt6rz,13,15,0|uwt6s0,17,1,1|v7z1fz,17,1,1|v7z1g0,13,15,0|vfw83z,13,15,0|vfw840,17,1,1|vqp43z,17,1,1|vqp440,13,15,0|vymarz,13,15,0|vymas0,17,1,1|w9f6rz,17,1,1|w9f6s0,13,15,0|whcdfz,13,15,0|whcdg0,17,1,1|wsi83z,17,1,1|wsi840,13,15,0|x02g3z,13,15,0|x02g40,17,1,1|xb8arz,17,1,1|xb8as0,13,15,0|xisirz,13,15,0|xisis0,17,1,1|xtydfz,17,1,1|xtydg0,13,15,0|y1ilfz,13,15,0|y1ilg0,17,1,1|ycog3z,17,1,1|ycog40,13,15,0|yklmrz,13,15,0|yklms0,17,1,1|yveirz,17,1,1|yveis0,13,15,0|z3bpfz,13,15,0|z3bpg0,17,1,1|ze4lfz,17,1,1|ze4lg0,13,15,0\",\"America/Sitka|,0,178,0|-1hc7qjz,0,179,0|-1078wa0,0,179,0|-1078w9z,51,40,0|-ek1w81,51,40,0|-ek1w80,68,66,1|-cq2tg1,68,66,1|-cq2tg0,69,66,1|-cnov01,69,66,1|-cnov00,51,40,0|-csc81,51,40,0|-csc80,57,66,1|-3fdo1,57,66,1|-3fdo0,51,40,0|5xqfz,51,40,0|5xqg0,57,66,1|faozz,57,66,1|fap00,51,40,0|ont3z,51,40,0|ont40,57,66,1|ydqbz,57,66,1|ydqc0,51,40,0|17qufz,51,40,0|17qug0,57,66,1|1h3szz,57,66,1|1h3t00,51,40,0|1qgx3z,51,40,0|1qgx40,57,66,1|1ztvnz,57,66,1|1ztvo0,51,40,0|23fl3z,51,40,0|23fl40,57,66,1|2ijybz,57,66,1|2ijyc0,51,40,0|2ooefz,51,40,0|2ooeg0,57,66,1|31a0zz,57,66,1|31a100,51,40,0|3an53z,51,40,0|3an540,57,66,1|3kd2bz,57,66,1|3kd2c0,51,40,0|3td7rz,51,40,0|3td7s0,57,66,1|4334zz,57,66,1|433500,51,40,0|4cg93z,51,40,0|4cg940,57,66,1|4lt7nz,57,66,1|4lt7o0,51,40,0|4v6brz,51,40,0|4v6bs0,57,66,1|54jabz,57,66,1|54jac0,51,40,0|5dwefz,51,40,0|5dweg0,57,66,1|5n9czz,57,66,1|5n9d00,51,40,0|5wmh3z,51,40,0|5wmh40,57,66,1|65zfnz,57,66,1|65zfo0,51,40,0|6fcjrz,51,40,0|6fcjs0,57,66,1|6p2gzz,57,66,1|6p2h00,51,40,0|6y2mfz,51,40,0|6y2mg0,57,66,1|77sjnz,57,66,1|77sjo0,36,37,0|79dybz,36,37,0|79dyc0,37,37,0|7h5qjz,37,37,0|7h5qk0,38,40,1|7qip3z,38,40,1|7qip40,37,37,0|7zvt7z,37,37,0|7zvt80,38,40,1|898rrz,38,40,1|898rs0,37,37,0|8ilvvz,37,37,0|8ilvw0,38,40,1|8ryufz,38,40,1|8ryug0,37,37,0|9092jz,37,37,0|9092k0,38,40,1|9aox3z,38,40,1|9aox40,37,37,0|9iz57z,37,37,0|9iz580,38,40,1|9tryfz,38,40,1|9tryg0,37,37,0|a1p7vz,37,37,0|a1p7w0,38,40,1|aci13z,38,40,1|aci140,37,37,0|akfajz,37,37,0|akfak0,38,40,1|av83rz,38,40,1|av83s0,37,37,0|b3ibvz,37,37,0|b3ibw0,38,40,1|bdy6fz,38,40,1|bdy6g0,37,37,0|bm8ejz,37,37,0|bm8ek0,38,40,1|bwo93z,38,40,1|bwo940,37,37,0|c4yh7z,37,37,0|c4yh80,38,40,1|cfrafz,38,40,1|cfrag0,37,37,0|cnojvz,37,37,0|cnojw0,38,40,1|cyhd3z,38,40,1|cyhd40,37,37,0|d6emjz,37,37,0|d6emk0,38,40,1|dh7frz,38,40,1|dh7fs0,37,37,0|dphnvz,37,37,0|dphnw0,38,40,1|dzxifz,38,40,1|dzxig0,37,37,0|e87qjz,37,37,0|e87qk0,38,40,1|einl3z,38,40,1|einl40,37,37,0|eqxt7z,37,37,0|eqxt80,38,40,1|f1dnrz,38,40,1|f1dns0,37,37,0|f9nvvz,37,37,0|f9nvw0,38,40,1|fkgp3z,38,40,1|fkgp40,37,37,0|fsdyjz,37,37,0|fsdyk0,38,40,1|g36rrz,38,40,1|g36rs0,37,37,0|gb417z,37,37,0|gb4180,38,40,1|glwufz,38,40,1|glwug0,37,37,0|gu72jz,37,37,0|gu72k0,38,40,1|h4mx3z,38,40,1|h4mx40,37,37,0|hcx57z,37,37,0|hcx580,38,40,1|hnczrz,38,40,1|hnczs0,37,37,0|hvn7vz,37,37,0|hvn7w0,38,40,1|i6g13z,38,40,1|i6g140,37,37,0|iedajz,37,37,0|iedak0,38,40,1|ip63rz,38,40,1|ip63s0,37,37,0|ix3d7z,37,37,0|ix3d80,38,40,1|j7w6fz,38,40,1|j7w6g0,37,37,0|jeqjvz,37,37,0|jeqjw0,38,40,1|jqz7rz,38,40,1|jqz7s0,37,37,0|jxgmjz,37,37,0|jxgmk0,38,40,1|k9pafz,38,40,1|k9pag0,37,37,0|kg6p7z,37,37,0|kg6p80,38,40,1|ksfd3z,38,40,1|ksfd40,37,37,0|kz9qjz,37,37,0|kz9qk0,38,40,1|lbiefz,38,40,1|lbieg0,37,37,0|lhzt7z,37,37,0|lhzt80,38,40,1|lu8h3z,38,40,1|lu8h40,37,37,0|m0pvvz,37,37,0|m0pvw0,38,40,1|mcyjrz,38,40,1|mcyjs0,37,37,0|mjfyjz,37,37,0|mjfyk0,38,40,1|mvomfz,38,40,1|mvomg0,37,37,0|n2617z,37,37,0|n26180,38,40,1|neep3z,38,40,1|neep40,37,37,0|nkw3vz,37,37,0|nkw3w0,38,40,1|nx4rrz,38,40,1|nx4rs0,37,37,0|o3z57z,37,37,0|o3z580,38,40,1|og7t3z,38,40,1|og7t40,37,37,0|omp7vz,37,37,0|omp7w0,38,40,1|oyxvrz,38,40,1|oyxvs0,37,37,0|p5fajz,37,37,0|p5fak0,38,40,1|phnyfz,38,40,1|phnyg0,37,37,0|po5d7z,37,37,0|po5d80,38,40,1|q0e13z,38,40,1|q0e140,37,37,0|q6vfvz,37,37,0|q6vfw0,38,40,1|qj43rz,38,40,1|qj43s0,37,37,0|qpyh7z,37,37,0|qpyh80,38,40,1|r2753z,38,40,1|r27540,37,37,0|r8ojvz,37,37,0|r8ojw0,38,40,1|rkx7rz,38,40,1|rkx7s0,37,37,0|rremjz,37,37,0|rremk0,38,40,1|s3nafz,38,40,1|s3nag0,37,37,0|sa4p7z,37,37,0|sa4p80,38,40,1|smdd3z,38,40,1|smdd40,37,37,0|ssurvz,37,37,0|ssurw0,38,40,1|t53frz,38,40,1|t53fs0,37,37,0|tbkujz,37,37,0|tbkuk0,38,40,1|tntifz,38,40,1|tntig0,37,37,0|tunvvz,37,37,0|tunvw0,38,40,1|u6wjrz,38,40,1|u6wjs0,37,37,0|uddyjz,37,37,0|uddyk0,38,40,1|upmmfz,38,40,1|upmmg0,37,37,0|uw417z,37,37,0|uw4180,38,40,1|v8cp3z,38,40,1|v8cp40,37,37,0|veu3vz,37,37,0|veu3w0,38,40,1|vr2rrz,38,40,1|vr2rs0,37,37,0|vxk6jz,37,37,0|vxk6k0,38,40,1|w9sufz,38,40,1|w9sug0,37,37,0|wgn7vz,37,37,0|wgn7w0,38,40,1|wsvvrz,38,40,1|wsvvs0,37,37,0|wzdajz,37,37,0|wzdak0,38,40,1|xblyfz,38,40,1|xblyg0,37,37,0|xi3d7z,37,37,0|xi3d80,38,40,1|xuc13z,38,40,1|xuc140,37,37,0|y0tfvz,37,37,0|y0tfw0,38,40,1|yd23rz,38,40,1|yd23s0,37,37,0|yjjijz,37,37,0|yjjik0,38,40,1|yvs6fz,38,40,1|yvs6g0,37,37,0|z29l7z,37,37,0|z29l80,38,40,1|zei93z,38,40,1|zei940,37,37,0\",\"America/St_Barthelemy|,0,41,0|-u6m79w,32,42,0\",\"America/St_Johns|,0,99,0|-18vs8wk,24,99,0|-ris3cl,24,99,0|-ris3ck,72,100,1|-rag64l,72,100,1|-rag64k,24,99,0|-qzp20l,24,99,0|-qzp20k,72,100,1|-qpm64l,72,100,1|-qpm64k,24,99,0|-qfsmcl,24,99,0|-qfsmck,72,100,1|-qapd4l,72,100,1|-qapd4k,24,99,0|-px4ecl,24,99,0|-px4eck,72,100,1|-pnrfsl,72,100,1|-pnrfsk,24,99,0|-peebol,24,99,0|-peebok,72,100,1|-p51d4l,72,100,1|-p51d4k,24,99,0|-ovbacl,24,99,0|-ovback,72,100,1|-ombagl,72,100,1|-ombagk,24,99,0|-ocl7ol,24,99,0|-ocl7ok,72,100,1|-o3l7sl,72,100,1|-o3l7sk,24,99,0|-ntv50l,24,99,0|-ntv50k,72,100,1|-nkv54l,72,100,1|-nkv54k,24,99,0|-nb52cl,24,99,0|-nb52ck,72,100,1|-n252gl,72,100,1|-n252gk,24,99,0|-msezol,24,99,0|-msezok,72,100,1|-mj214l,72,100,1|-mj214k,24,99,0|-m9ox0l,24,99,0|-m9ox0k,72,100,1|-m0bygl,72,100,1|-m0bygk,24,99,0|-lqlvol,24,99,0|-lqlvok,72,100,1|-lhlvsl,72,100,1|-lhlvsk,24,99,0|-l7vt0l,24,99,0|-l7vt0k,72,100,1|-kyvt4l,72,100,1|-kyvt4k,24,99,0|-kp5qcl,24,99,0|-kp5qck,72,100,1|-kg5qgl,72,100,1|-kg5qgk,24,99,0|-k6fnol,24,99,0|-k6fnok,72,100,1|-jxfnsl,72,100,1|-jxfnsk,24,99,0|-jnpl0l,24,99,0|-jnpl0k,72,100,1|-jecmgl,72,100,1|-jecmgk,24,99,0|-j4mjol,24,99,0|-j4mjok,72,100,1|-ivmjsl,72,100,1|-ivmjsk,24,99,0|-ilwh0l,24,99,0|-ilwh0k,72,100,1|-icwh4l,72,100,1|-icwh4k,24,99,0|-i52u8l,24,99,0|-i52u8k,24,101,0|-i36ee1,24,101,0|-i36ee0,72,102,1|-hu6ei1,72,102,1|-hu6ei0,24,101,0|-hk3aa1,24,101,0|-hk3aa0,72,102,1|-hcj521,72,102,1|-hcj520,24,101,0|-h1d7m1,24,101,0|-h1d7m0,72,102,1|-gtt2e1,72,102,1|-gtt2e0,24,101,0|-gin4y1,24,101,0|-gin4y0,72,102,1|-gb2zq1,72,102,1|-gb2zq0,24,101,0|-fzk3m1,24,101,0|-fzk3m0,72,102,1|-fscx21,72,102,1|-fscx20,24,101,0|-fgu0y1,24,101,0|-fgu0y0,72,102,1|-f99vq1,72,102,1|-f99vq0,24,101,0|-ey3ya1,24,101,0|-ey3ya0,72,102,1|-eqjt21,72,102,1|-eqjt20,24,101,0|-efdvm1,24,101,0|-efdvm0,25,102,1|-cq2tg1,25,102,1|-cq2tg0,26,102,1|-cnp7i1,26,102,1|-cnp7i0,24,101,0|-cc6be1,24,101,0|-cc6be0,72,102,1|-c4m661,72,102,1|-c4m660,24,101,0|-btg8q1,24,101,0|-btg8q0,72,102,1|-blw3i1,72,102,1|-blw3i0,24,101,0|-baq621,24,101,0|-baq620,72,102,1|-b360u1,72,102,1|-b360u0,24,101,0|-as03e1,24,101,0|-as03e0,72,102,1|-akfy61,72,102,1|-akfy60,24,101,0|-a8x221,24,101,0|-a8x220,72,102,1|-a1cwu1,72,102,1|-a1cwu0,24,101,0|-9qwwq1,24,101,0|-9qwwq0,72,102,1|-9izsu1,72,102,1|-9izsu0,24,101,0|-986u21,24,101,0|-986u20,72,102,1|-909q61,72,102,1|-909q60,24,101,0|-8pgre1,24,101,0|-8pgre0,72,102,1|-8hjni1,72,102,1|-8hjni0,24,101,0|-86qoq1,24,101,0|-86qoq0,72,102,1|-7ytku1,72,102,1|-7ytku0,24,101,0|-7o0m21,24,101,0|-7o0m20,72,102,1|-7g3i61,72,102,1|-7g3i60,24,101,0|-74xkq1,24,101,0|-74xkq0,72,102,1|-6x0gu1,72,102,1|-6x0gu0,24,101,0|-6m7i21,24,101,0|-6m7i20,72,102,1|-6eae61,72,102,1|-6eae60,24,101,0|-63hfe1,24,101,0|-63hfe0,72,102,1|-5vkbi1,72,102,1|-5vkbi0,24,101,0|-5krcq1,24,101,0|-5krcq0,72,102,1|-5cu8u1,72,102,1|-5cu8u0,24,101,0|-521a21,24,101,0|-521a20,72,102,1|-4sbcu1,72,102,1|-4sbcu0,24,101,0|-4iy8q1,24,101,0|-4iy8q0,72,102,1|-49la61,72,102,1|-49la60,24,101,0|-408621,24,101,0|-408620,72,102,1|-3qv7i1,72,102,1|-3qv7i0,24,101,0|-3hi3e1,24,101,0|-3hi3e0,72,102,1|-3854u1,72,102,1|-3854u0,24,101,0|-2ys0q1,24,101,0|-2ys0q0,72,102,1|-2pf261,72,102,1|-2pf260,24,101,0|-2g1y21,24,101,0|-2g1y20,72,102,1|-26c0u1,72,102,1|-26c0u0,24,101,0|-1xbve1,24,101,0|-1xbve0,72,102,1|-1nly61,72,102,1|-1nly60,24,101,0|-1e8u21,24,101,0|-1e8u20,72,102,1|-14vvi1,72,102,1|-14vvi0,24,101,0|-vire1,24,101,0|-vire0,72,102,1|-m5su1,72,102,1|-m5su0,24,101,0|-csoq1,24,101,0|-csoq0,72,102,1|-3fq61,72,102,1|-3fq60,24,101,0|5xdxz,24,101,0|5xdy0,72,102,1|fachz,72,102,1|faci0,24,101,0|onglz,24,101,0|ongm0,72,102,1|yddtz,72,102,1|yddu0,24,101,0|17qhxz,24,101,0|17qhy0,72,102,1|1h3ghz,72,102,1|1h3gi0,24,101,0|1qgklz,24,101,0|1qgkm0,72,102,1|1ztj5z,72,102,1|1ztj60,24,101,0|296n9z,24,101,0|296na0,72,102,1|2ijltz,72,102,1|2ijlu0,24,101,0|2rwpxz,24,101,0|2rwpy0,72,102,1|319ohz,72,102,1|319oi0,24,101,0|3amslz,24,101,0|3amsm0,72,102,1|3kcptz,72,102,1|3kcpu0,24,101,0|3tcv9z,24,101,0|3tcva0,72,102,1|432shz,72,102,1|432si0,24,101,0|4cfwlz,24,101,0|4cfwm0,72,102,1|4lsv5z,72,102,1|4lsv60,24,101,0|4v5z9z,24,101,0|4v5za0,72,102,1|54ixtz,72,102,1|54ixu0,24,101,0|5dw1xz,24,101,0|5dw1y0,72,102,1|5n90hz,72,102,1|5n90i0,24,101,0|5wm4lz,24,101,0|5wm4m0,72,102,1|65z35z,72,102,1|65z360,24,101,0|6fc79z,24,101,0|6fc7a0,72,102,1|6p24hz,72,102,1|6p24i0,24,101,0|6y29xz,24,101,0|6y29y0,72,102,1|77s75z,72,102,1|77s760,24,101,0|7h5b9z,24,101,0|7h5ba0,72,102,1|7qi9tz,72,102,1|7qi9u0,24,101,0|7zvdxz,24,101,0|7zvdy0,72,102,1|898chz,72,102,1|898ci0,24,101,0|8ilglz,24,101,0|8ilgm0,72,102,1|8ryf5z,72,102,1|8ryf60,24,101,0|908hrn,24,101,0|908hro,72,102,1|9aocbn,72,102,1|9aocbo,24,101,0|9iykfn,24,101,0|9iykfo,88,147,1|9travn,88,147,1|9travo,24,101,0|a1on3n,24,101,0|a1on3o,72,102,1|achgbn,72,102,1|achgbo,24,101,0|akeprn,24,101,0|akepro,72,102,1|av7izn,72,102,1|av7izo,24,101,0|b3hr3n,24,101,0|b3hr3o,72,102,1|bdxlnn,72,102,1|bdxlno,24,101,0|bm7trn,24,101,0|bm7tro,72,102,1|bwnobn,72,102,1|bwnobo,24,101,0|c4xwfn,24,101,0|c4xwfo,72,102,1|cfqpnn,72,102,1|cfqpno,24,101,0|cnnz3n,24,101,0|cnnz3o,72,102,1|cygsbn,72,102,1|cygsbo,24,101,0|d6e1rn,24,101,0|d6e1ro,72,102,1|dh6uzn,72,102,1|dh6uzo,24,101,0|dph33n,24,101,0|dph33o,72,102,1|dzwxnn,72,102,1|dzwxno,24,101,0|e875rn,24,101,0|e875ro,72,102,1|ein0bn,72,102,1|ein0bo,24,101,0|eqx8fn,24,101,0|eqx8fo,72,102,1|f1d2zn,72,102,1|f1d2zo,24,101,0|f9nb3n,24,101,0|f9nb3o,72,102,1|fkg4bn,72,102,1|fkg4bo,24,101,0|fsddrn,24,101,0|fsddro,72,102,1|g366zn,72,102,1|g366zo,24,101,0|gb3gfn,24,101,0|gb3gfo,72,102,1|glw9nn,72,102,1|glw9no,24,101,0|gu6hrn,24,101,0|gu6hro,72,102,1|h4mcbn,72,102,1|h4mcbo,24,101,0|hcwkfn,24,101,0|hcwkfo,72,102,1|hncezn,72,102,1|hncezo,24,101,0|hvmn3n,24,101,0|hvmn3o,72,102,1|i6fgbn,72,102,1|i6fgbo,24,101,0|iecprn,24,101,0|iecpro,72,102,1|ip5izn,72,102,1|ip5izo,24,101,0|ix2sfn,24,101,0|ix2sfo,72,102,1|j7vlnn,72,102,1|j7vlno,24,101,0|jepz3n,24,101,0|jepz3o,72,102,1|jqymzn,72,102,1|jqymzo,24,101,0|jxg1rn,24,101,0|jxg1ro,72,102,1|k9opnn,72,102,1|k9opno,24,101,0|kg64fn,24,101,0|kg64fo,72,102,1|ksesbn,72,102,1|ksesbo,24,101,0|kz95rn,24,101,0|kz95ro,72,102,1|lbhtnn,72,102,1|lbhtno,24,101,0|lhz8fn,24,101,0|lhz8fo,72,102,1|lu81tz,72,102,1|lu81u0,24,101,0|m0pglz,24,101,0|m0pgm0,72,102,1|mcy4hz,72,102,1|mcy4i0,24,101,0|mjfj9z,24,101,0|mjfja0,72,102,1|mvo75z,72,102,1|mvo760,24,101,0|n25lxz,24,101,0|n25ly0,72,102,1|nee9tz,72,102,1|nee9u0,24,101,0|nkvolz,24,101,0|nkvom0,72,102,1|nx4chz,72,102,1|nx4ci0,24,101,0|o3ypxz,24,101,0|o3ypy0,72,102,1|og7dtz,72,102,1|og7du0,24,101,0|omoslz,24,101,0|omosm0,72,102,1|oyxghz,72,102,1|oyxgi0,24,101,0|p5ev9z,24,101,0|p5eva0,72,102,1|phnj5z,72,102,1|phnj60,24,101,0|po4xxz,24,101,0|po4xy0,72,102,1|q0dltz,72,102,1|q0dlu0,24,101,0|q6v0lz,24,101,0|q6v0m0,72,102,1|qj3ohz,72,102,1|qj3oi0,24,101,0|qpy1xz,24,101,0|qpy1y0,72,102,1|r26ptz,72,102,1|r26pu0,24,101,0|r8o4lz,24,101,0|r8o4m0,72,102,1|rkwshz,72,102,1|rkwsi0,24,101,0|rre79z,24,101,0|rre7a0,72,102,1|s3mv5z,72,102,1|s3mv60,24,101,0|sa49xz,24,101,0|sa49y0,72,102,1|smcxtz,72,102,1|smcxu0,24,101,0|ssuclz,24,101,0|ssucm0,72,102,1|t530hz,72,102,1|t530i0,24,101,0|tbkf9z,24,101,0|tbkfa0,72,102,1|tnt35z,72,102,1|tnt360,24,101,0|tunglz,24,101,0|tungm0,72,102,1|u6w4hz,72,102,1|u6w4i0,24,101,0|uddj9z,24,101,0|uddja0,72,102,1|upm75z,72,102,1|upm760,24,101,0|uw3lxz,24,101,0|uw3ly0,72,102,1|v8c9tz,72,102,1|v8c9u0,24,101,0|vetolz,24,101,0|vetom0,72,102,1|vr2chz,72,102,1|vr2ci0,24,101,0|vxjr9z,24,101,0|vxjra0,72,102,1|w9sf5z,72,102,1|w9sf60,24,101,0|wgmslz,24,101,0|wgmsm0,72,102,1|wsvghz,72,102,1|wsvgi0,24,101,0|wzcv9z,24,101,0|wzcva0,72,102,1|xblj5z,72,102,1|xblj60,24,101,0|xi2xxz,24,101,0|xi2xy0,72,102,1|xubltz,72,102,1|xublu0,24,101,0|y0t0lz,24,101,0|y0t0m0,72,102,1|yd1ohz,72,102,1|yd1oi0,24,101,0|yjj39z,24,101,0|yjj3a0,72,102,1|yvrr5z,72,102,1|yvrr60,24,101,0|z295xz,24,101,0|z295y0,72,102,1|zehttz,72,102,1|zehtu0,24,101,0\",\"America/St_Kitts|,0,41,0|-u6m79w,32,42,0\",\"America/St_Lucia|,0,41,0|-u6m79w,32,42,0\",\"America/St_Thomas|,0,41,0|-u6m79w,32,42,0\",\"America/St_Vincent|,0,41,0|-u6m79w,32,42,0\",\"America/Swift_Current|,0,180,0|-xkq9d4,50,66,0|-qzosc1,50,66,0|-qzosc0,52,62,1|-qplwg1,52,62,1|-qplwg0,50,66,0|-ek1z01,50,66,0|-ek1z00,58,62,1|-cq2tg1,58,62,1|-cq2tg0,59,62,1|-cnoxs1,59,62,1|-cnoxs0,50,66,0|-ccvz01,50,66,0|-ccvz00,52,62,1|-c48xs1,52,62,1|-c48xs0,50,66,0|-bu5wc1,50,66,0|-bu5wc0,52,62,1|-bm8sg1,52,62,1|-bm8sg0,50,66,0|-bbfto1,50,66,0|-bbfto0,52,62,1|-b3ips1,52,62,1|-b3ips0,50,66,0|-aspr01,50,66,0|-aspr00,52,62,1|-aksn41,52,62,1|-aksn40,50,66,0|-6m78c1,50,66,0|-6m78c0,52,62,1|-6cu9s1,52,62,1|-6cu9s0,50,66,0|-5kr301,50,66,0|-5kr300,52,62,1|-5be4g1,52,62,1|-5be4g0,50,66,0|-5210c1,50,66,0|-5210c0,52,62,1|-4u3wg1,52,62,1|-4u3wg0,50,66,0|-4ixz01,50,66,0|-4ixz00,52,62,1|-4bdts1,52,62,1|-4bdts0,50,66,0|17qrnz,50,66,0|17qro0,45,62,0\",\"America/Tegucigalpa|,0,181,0|-pfzh6k,45,62,0|91ojbz,45,62,0|91ojc0,46,63,1|998ojz,46,63,1|998ok0,45,62,0|9kelzz,45,62,0|9kem00,46,63,1|9ryr7z,46,63,1|9ryr80,45,62,0|iyvsnz,45,62,0|iyvso0,46,63,1|j3m37z,46,63,1|j3m380,45,62,0\",\"America/Thule|,0,182,0|-rvuj9g,32,42,0|b34zbz,32,42,0|b34zc0,54,44,1|bchxvz,54,44,1|bchxw0,32,42,0|blv1zz,32,42,0|blv200,54,44,1|bv80jz,54,44,1|bv80k0,32,42,0|c4y3bz,32,42,0|c4y3c0,54,44,1|cfqwjz,54,44,1|cfqwk0,32,42,0|cno5zz,32,42,0|cno600,54,44,1|cygz7z,54,44,1|cygz80,32,42,0|d6e8nz,32,42,0|d6e8o0,54,44,1|dh71vz,54,44,1|dh71w0,32,42,0|dph9zz,32,42,0|dpha00,54,44,1|dzx4jz,54,44,1|dzx4k0,32,42,0|e87cnz,32,42,0|e87co0,54,44,1|ein77z,54,44,1|ein780,32,42,0|eqxfbz,32,42,0|eqxfc0,54,44,1|f1d9vz,54,44,1|f1d9w0,32,42,0|f9nhzz,32,42,0|f9ni00,54,44,1|fkgb7z,54,44,1|fkgb80,32,42,0|fsdknz,32,42,0|fsdko0,54,44,1|g36dvz,54,44,1|g36dw0,32,42,0|gb3nbz,32,42,0|gb3nc0,54,44,1|glwgjz,54,44,1|glwgk0,32,42,0|gu6onz,32,42,0|gu6oo0,54,44,1|h4mj7z,54,44,1|h4mj80,32,42,0|hcwrbz,32,42,0|hcwrc0,54,44,1|hnclvz,54,44,1|hnclw0,32,42,0|hvmtzz,32,42,0|hvmu00,54,44,1|i6fn7z,54,44,1|i6fn80,32,42,0|iecwnz,32,42,0|iecwo0,54,44,1|ip5pvz,54,44,1|ip5pw0,32,42,0|ix2zbz,32,42,0|ix2zc0,54,44,1|j7vsjz,54,44,1|j7vsk0,32,42,0|jeq5zz,32,42,0|jeq600,54,44,1|jqytvz,54,44,1|jqytw0,32,42,0|jxg8nz,32,42,0|jxg8o0,54,44,1|k9owjz,54,44,1|k9owk0,32,42,0|kg6bbz,32,42,0|kg6bc0,54,44,1|ksez7z,54,44,1|ksez80,32,42,0|kz9cnz,32,42,0|kz9co0,54,44,1|lbi0jz,54,44,1|lbi0k0,32,42,0|lhzfbz,32,42,0|lhzfc0,54,44,1|lu837z,54,44,1|lu8380,32,42,0|m0phzz,32,42,0|m0pi00,54,44,1|mcy5vz,54,44,1|mcy5w0,32,42,0|mjfknz,32,42,0|mjfko0,54,44,1|mvo8jz,54,44,1|mvo8k0,32,42,0|n25nbz,32,42,0|n25nc0,54,44,1|neeb7z,54,44,1|neeb80,32,42,0|nkvpzz,32,42,0|nkvq00,54,44,1|nx4dvz,54,44,1|nx4dw0,32,42,0|o3yrbz,32,42,0|o3yrc0,54,44,1|og7f7z,54,44,1|og7f80,32,42,0|omotzz,32,42,0|omou00,54,44,1|oyxhvz,54,44,1|oyxhw0,32,42,0|p5ewnz,32,42,0|p5ewo0,54,44,1|phnkjz,54,44,1|phnkk0,32,42,0|po4zbz,32,42,0|po4zc0,54,44,1|q0dn7z,54,44,1|q0dn80,32,42,0|q6v1zz,32,42,0|q6v200,54,44,1|qj3pvz,54,44,1|qj3pw0,32,42,0|qpy3bz,32,42,0|qpy3c0,54,44,1|r26r7z,54,44,1|r26r80,32,42,0|r8o5zz,32,42,0|r8o600,54,44,1|rkwtvz,54,44,1|rkwtw0,32,42,0|rre8nz,32,42,0|rre8o0,54,44,1|s3mwjz,54,44,1|s3mwk0,32,42,0|sa4bbz,32,42,0|sa4bc0,54,44,1|smcz7z,54,44,1|smcz80,32,42,0|ssudzz,32,42,0|ssue00,54,44,1|t531vz,54,44,1|t531w0,32,42,0|tbkgnz,32,42,0|tbkgo0,54,44,1|tnt4jz,54,44,1|tnt4k0,32,42,0|tunhzz,32,42,0|tuni00,54,44,1|u6w5vz,54,44,1|u6w5w0,32,42,0|uddknz,32,42,0|uddko0,54,44,1|upm8jz,54,44,1|upm8k0,32,42,0|uw3nbz,32,42,0|uw3nc0,54,44,1|v8cb7z,54,44,1|v8cb80,32,42,0|vetpzz,32,42,0|vetq00,54,44,1|vr2dvz,54,44,1|vr2dw0,32,42,0|vxjsnz,32,42,0|vxjso0,54,44,1|w9sgjz,54,44,1|w9sgk0,32,42,0|wgmtzz,32,42,0|wgmu00,54,44,1|wsvhvz,54,44,1|wsvhw0,32,42,0|wzcwnz,32,42,0|wzcwo0,54,44,1|xblkjz,54,44,1|xblkk0,32,42,0|xi2zbz,32,42,0|xi2zc0,54,44,1|xubn7z,54,44,1|xubn80,32,42,0|y0t1zz,32,42,0|y0t200,54,44,1|yd1pvz,54,44,1|yd1pw0,32,42,0|yjj4nz,32,42,0|yjj4o0,54,44,1|yvrsjz,54,44,1|yvrsk0,32,42,0|z297bz,32,42,0|z297c0,54,44,1|zehv7z,54,44,1|zehv80,32,42,0\",\"America/Thunder_Bay|,0,183,0|-1353bh0,45,62,0|-vbavc1,45,62,0|-vbavc0,49,63,0|-ek24k1,49,63,0|-ek24k0,70,42,1|-cq2tg1,70,42,1|-cq2tg0,71,42,1|-cnp3c1,71,42,1|-cnp3c0,49,63,0|5xi3z,49,63,0|5xi40,62,42,1|fagnz,62,42,1|fago0,49,63,0|onkrz,49,63,0|onks0,62,42,1|ydhzz,62,42,1|ydi00,49,63,0|17qm3z,49,63,0|17qm40,62,42,1|1h3knz,62,42,1|1h3ko0,49,63,0|296rfz,49,63,0|296rg0,62,42,1|2ijpzz,62,42,1|2ijq00,49,63,0|2rwu3z,49,63,0|2rwu40,62,42,1|319snz,62,42,1|319so0,49,63,0|3amwrz,49,63,0|3amws0,62,42,1|3kctzz,62,42,1|3kcu00,49,63,0|3tczfz,49,63,0|3tczg0,62,42,1|432wnz,62,42,1|432wo0,49,63,0|4cg0rz,49,63,0|4cg0s0,62,42,1|4lszbz,62,42,1|4lszc0,49,63,0|4v63fz,49,63,0|4v63g0,62,42,1|54j1zz,62,42,1|54j200,49,63,0|5dw63z,49,63,0|5dw640,62,42,1|5n94nz,62,42,1|5n94o0,49,63,0|5wm8rz,49,63,0|5wm8s0,62,42,1|65z7bz,62,42,1|65z7c0,49,63,0|6fcbfz,49,63,0|6fcbg0,62,42,1|6p28nz,62,42,1|6p28o0,49,63,0|6y2e3z,49,63,0|6y2e40,62,42,1|77sbbz,62,42,1|77sbc0,49,63,0|7h5ffz,49,63,0|7h5fg0,62,42,1|7qidzz,62,42,1|7qie00,49,63,0|7zvi3z,49,63,0|7zvi40,62,42,1|898gnz,62,42,1|898go0,49,63,0|8ilkrz,49,63,0|8ilks0,62,42,1|8ryjbz,62,42,1|8ryjc0,49,63,0|908rfz,49,63,0|908rg0,62,42,1|9aolzz,62,42,1|9aom00,49,63,0|9iyu3z,49,63,0|9iyu40,62,42,1|9trnbz,62,42,1|9trnc0,49,63,0|a1owrz,49,63,0|a1ows0,62,42,1|achpzz,62,42,1|achq00,49,63,0|akezfz,49,63,0|akezg0,62,42,1|av7snz,62,42,1|av7so0,49,63,0|b3i0rz,49,63,0|b3i0s0,62,42,1|bdxvbz,62,42,1|bdxvc0,49,63,0|bm83fz,49,63,0|bm83g0,62,42,1|bwnxzz,62,42,1|bwny00,49,63,0|c4y63z,49,63,0|c4y640,62,42,1|cfqzbz,62,42,1|cfqzc0,49,63,0|cno8rz,49,63,0|cno8s0,62,42,1|cyh1zz,62,42,1|cyh200,49,63,0|d6ebfz,49,63,0|d6ebg0,62,42,1|dh74nz,62,42,1|dh74o0,49,63,0|dphcrz,49,63,0|dphcs0,62,42,1|dzx7bz,62,42,1|dzx7c0,49,63,0|e87ffz,49,63,0|e87fg0,62,42,1|ein9zz,62,42,1|eina00,49,63,0|eqxi3z,49,63,0|eqxi40,62,42,1|f1dcnz,62,42,1|f1dco0,49,63,0|f9nkrz,49,63,0|f9nks0,62,42,1|fkgdzz,62,42,1|fkge00,49,63,0|fsdnfz,49,63,0|fsdng0,62,42,1|g36gnz,62,42,1|g36go0,49,63,0|gb3q3z,49,63,0|gb3q40,62,42,1|glwjbz,62,42,1|glwjc0,49,63,0|gu6rfz,49,63,0|gu6rg0,62,42,1|h4mlzz,62,42,1|h4mm00,49,63,0|hcwu3z,49,63,0|hcwu40,62,42,1|hnconz,62,42,1|hncoo0,49,63,0|hvmwrz,49,63,0|hvmws0,62,42,1|i6fpzz,62,42,1|i6fq00,49,63,0|ieczfz,49,63,0|ieczg0,62,42,1|ip5snz,62,42,1|ip5so0,49,63,0|ix323z,49,63,0|ix3240,62,42,1|j7vvbz,62,42,1|j7vvc0,49,63,0|jeq8rz,49,63,0|jeq8s0,62,42,1|jqywnz,62,42,1|jqywo0,49,63,0|jxgbfz,49,63,0|jxgbg0,62,42,1|k9ozbz,62,42,1|k9ozc0,49,63,0|kg6e3z,49,63,0|kg6e40,62,42,1|ksf1zz,62,42,1|ksf200,49,63,0|kz9ffz,49,63,0|kz9fg0,62,42,1|lbi3bz,62,42,1|lbi3c0,49,63,0|lhzi3z,49,63,0|lhzi40,62,42,1|lu85zz,62,42,1|lu8600,49,63,0|m0pkrz,49,63,0|m0pks0,62,42,1|mcy8nz,62,42,1|mcy8o0,49,63,0|mjfnfz,49,63,0|mjfng0,62,42,1|mvobbz,62,42,1|mvobc0,49,63,0|n25q3z,49,63,0|n25q40,62,42,1|needzz,62,42,1|neee00,49,63,0|nkvsrz,49,63,0|nkvss0,62,42,1|nx4gnz,62,42,1|nx4go0,49,63,0|o3yu3z,49,63,0|o3yu40,62,42,1|og7hzz,62,42,1|og7i00,49,63,0|omowrz,49,63,0|omows0,62,42,1|oyxknz,62,42,1|oyxko0,49,63,0|p5ezfz,49,63,0|p5ezg0,62,42,1|phnnbz,62,42,1|phnnc0,49,63,0|po523z,49,63,0|po5240,62,42,1|q0dpzz,62,42,1|q0dq00,49,63,0|q6v4rz,49,63,0|q6v4s0,62,42,1|qj3snz,62,42,1|qj3so0,49,63,0|qpy63z,49,63,0|qpy640,62,42,1|r26tzz,62,42,1|r26u00,49,63,0|r8o8rz,49,63,0|r8o8s0,62,42,1|rkwwnz,62,42,1|rkwwo0,49,63,0|rrebfz,49,63,0|rrebg0,62,42,1|s3mzbz,62,42,1|s3mzc0,49,63,0|sa4e3z,49,63,0|sa4e40,62,42,1|smd1zz,62,42,1|smd200,49,63,0|ssugrz,49,63,0|ssugs0,62,42,1|t534nz,62,42,1|t534o0,49,63,0|tbkjfz,49,63,0|tbkjg0,62,42,1|tnt7bz,62,42,1|tnt7c0,49,63,0|tunkrz,49,63,0|tunks0,62,42,1|u6w8nz,62,42,1|u6w8o0,49,63,0|uddnfz,49,63,0|uddng0,62,42,1|upmbbz,62,42,1|upmbc0,49,63,0|uw3q3z,49,63,0|uw3q40,62,42,1|v8cdzz,62,42,1|v8ce00,49,63,0|vetsrz,49,63,0|vetss0,62,42,1|vr2gnz,62,42,1|vr2go0,49,63,0|vxjvfz,49,63,0|vxjvg0,62,42,1|w9sjbz,62,42,1|w9sjc0,49,63,0|wgmwrz,49,63,0|wgmws0,62,42,1|wsvknz,62,42,1|wsvko0,49,63,0|wzczfz,49,63,0|wzczg0,62,42,1|xblnbz,62,42,1|xblnc0,49,63,0|xi323z,49,63,0|xi3240,62,42,1|xubpzz,62,42,1|xubq00,49,63,0|y0t4rz,49,63,0|y0t4s0,62,42,1|yd1snz,62,42,1|yd1so0,49,63,0|yjj7fz,49,63,0|yjj7g0,62,42,1|yvrvbz,62,42,1|yvrvc0,49,63,0|z29a3z,49,63,0|z29a40,62,42,1|zehxzz,62,42,1|zehy00,49,63,0\",\"America/Tijuana|,0,184,0|-p1u1s0,50,66,0|-o0a9w1,50,66,0|-o0a9w0,51,40,0|-m7mhw1,51,40,0|-m7mhw0,50,66,0|-kf64k1,50,66,0|-kf64k0,51,40,0|-k84cg1,51,40,0|-k84cg0,57,66,1|-jyrdw1,57,66,1|-jyrdw0,51,40,0|-eg90g1,51,40,0|-eg90g0,68,66,1|-cq2tg1,68,66,1|-cq2tg0,69,66,1|-clhdw1,69,66,1|-clhdw0,51,40,0|-bcgxs1,51,40,0|-bcgxs0,57,66,1|-axv381,57,66,1|-axv380,51,40,0|-86qf01,51,40,0|-86qf00,57,66,1|-7yt8c1,57,66,1|-7yt8c0,51,40,0|-7o0cc1,51,40,0|-7o0cc0,57,66,1|-7g35o1,57,66,1|-7g35o0,51,40,0|-74xb01,51,40,0|-74xb00,57,66,1|-6x04c1,57,66,1|-6x04c0,51,40,0|-6m78c1,51,40,0|-6m78c0,57,66,1|-6ea1o1,57,66,1|-6ea1o0,51,40,0|-63h5o1,51,40,0|-63h5o0,57,66,1|-5vjz01,57,66,1|-5vjz00,51,40,0|-5kr301,51,40,0|-5kr300,57,66,1|-5ctwc1,57,66,1|-5ctwc0,51,40,0|-5210c1,51,40,0|-5210c0,57,66,1|-4u3to1,57,66,1|-4u3to0,51,40,0|3an53z,51,40,0|3an540,57,66,1|3kd2bz,57,66,1|3kd2c0,51,40,0|3td7rz,51,40,0|3td7s0,57,66,1|4334zz,57,66,1|433500,51,40,0|4cg93z,51,40,0|4cg940,57,66,1|4lt7nz,57,66,1|4lt7o0,51,40,0|4v6brz,51,40,0|4v6bs0,57,66,1|54jabz,57,66,1|54jac0,51,40,0|5dwefz,51,40,0|5dweg0,57,66,1|5n9czz,57,66,1|5n9d00,51,40,0|5wmh3z,51,40,0|5wmh40,57,66,1|65zfnz,57,66,1|65zfo0,51,40,0|6fcjrz,51,40,0|6fcjs0,57,66,1|6p2gzz,57,66,1|6p2h00,51,40,0|6y2mfz,51,40,0|6y2mg0,57,66,1|77sjnz,57,66,1|77sjo0,51,40,0|7h5nrz,51,40,0|7h5ns0,57,66,1|7qimbz,57,66,1|7qimc0,51,40,0|7zvqfz,51,40,0|7zvqg0,57,66,1|898ozz,57,66,1|898p00,51,40,0|8ilt3z,51,40,0|8ilt40,57,66,1|8ryrnz,57,66,1|8ryro0,51,40,0|908zrz,51,40,0|908zs0,57,66,1|9aoubz,57,66,1|9aouc0,51,40,0|9iz2fz,51,40,0|9iz2g0,57,66,1|9trvnz,57,66,1|9trvo0,51,40,0|a1p53z,51,40,0|a1p540,57,66,1|achybz,57,66,1|achyc0,51,40,0|akf7rz,51,40,0|akf7s0,57,66,1|av80zz,57,66,1|av8100,51,40,0|b3i93z,51,40,0|b3i940,57,66,1|bdy3nz,57,66,1|bdy3o0,51,40,0|bm8brz,51,40,0|bm8bs0,57,66,1|bwo6bz,57,66,1|bwo6c0,51,40,0|c4yefz,51,40,0|c4yeg0,57,66,1|cfr7nz,57,66,1|cfr7o0,51,40,0|cnoh3z,51,40,0|cnoh40,57,66,1|cyhabz,57,66,1|cyhac0,51,40,0|d6ejrz,51,40,0|d6ejs0,57,66,1|dh7czz,57,66,1|dh7d00,51,40,0|dphl3z,51,40,0|dphl40,57,66,1|dzxfnz,57,66,1|dzxfo0,51,40,0|e87nrz,51,40,0|e87ns0,57,66,1|einibz,57,66,1|einic0,51,40,0|eqxqfz,51,40,0|eqxqg0,57,66,1|f1dkzz,57,66,1|f1dl00,51,40,0|f9nt3z,51,40,0|f9nt40,57,66,1|fkgmbz,57,66,1|fkgmc0,51,40,0|fsdvrz,51,40,0|fsdvs0,57,66,1|g36ozz,57,66,1|g36p00,51,40,0|gb3yfz,51,40,0|gb3yg0,57,66,1|glwrnz,57,66,1|glwro0,51,40,0|gu6zrz,51,40,0|gu6zs0,57,66,1|h4mubz,57,66,1|h4muc0,51,40,0|hcx2fz,51,40,0|hcx2g0,57,66,1|hncwzz,57,66,1|hncx00,51,40,0|hvn53z,51,40,0|hvn540,57,66,1|i6fybz,57,66,1|i6fyc0,51,40,0|ied7rz,51,40,0|ied7s0,57,66,1|ip60zz,57,66,1|ip6100,51,40,0|ix3afz,51,40,0|ix3ag0,57,66,1|j7w3nz,57,66,1|j7w3o0,51,40,0|jftd3z,51,40,0|jftd40,57,66,1|jqm6bz,57,66,1|jqm6c0,51,40,0|jywefz,51,40,0|jyweg0,57,66,1|k9c8zz,57,66,1|k9c900,51,40,0|khmh3z,51,40,0|khmh40,57,66,1|ks2bnz,57,66,1|ks2bo0,51,40,0|kz9nrz,51,40,0|kz9ns0,57,66,1|lbibnz,57,66,1|lbibo0,51,40,0|lhzqfz,51,40,0|lhzqg0,57,66,1|lu8ebz,57,66,1|lu8ec0,51,40,0|m0pt3z,51,40,0|m0pt40,57,66,1|mcygzz,57,66,1|mcyh00,51,40,0|mjfvrz,51,40,0|mjfvs0,57,66,1|mvojnz,57,66,1|mvojo0,51,40,0|n25yfz,51,40,0|n25yg0,57,66,1|neembz,57,66,1|neemc0,51,40,0|nkw13z,51,40,0|nkw140,57,66,1|nx4ozz,57,66,1|nx4p00,51,40,0|o3z2fz,51,40,0|o3z2g0,57,66,1|og7qbz,57,66,1|og7qc0,51,40,0|omp53z,51,40,0|omp540,57,66,1|oyxszz,57,66,1|oyxt00,51,40,0|p5f7rz,51,40,0|p5f7s0,57,66,1|phnvnz,57,66,1|phnvo0,51,40,0|po5afz,51,40,0|po5ag0,57,66,1|q0dybz,57,66,1|q0dyc0,51,40,0|q6vd3z,51,40,0|q6vd40,57,66,1|qj40zz,57,66,1|qj4100,51,40,0|qpyefz,51,40,0|qpyeg0,57,66,1|r272bz,57,66,1|r272c0,51,40,0|r8oh3z,51,40,0|r8oh40,57,66,1|rkx4zz,57,66,1|rkx500,51,40,0|rrejrz,51,40,0|rrejs0,57,66,1|s3n7nz,57,66,1|s3n7o0,51,40,0|sa4mfz,51,40,0|sa4mg0,57,66,1|smdabz,57,66,1|smdac0,51,40,0|ssup3z,51,40,0|ssup40,57,66,1|t53czz,57,66,1|t53d00,51,40,0|tbkrrz,51,40,0|tbkrs0,57,66,1|tntfnz,57,66,1|tntfo0,51,40,0|tunt3z,51,40,0|tunt40,57,66,1|u6wgzz,57,66,1|u6wh00,51,40,0|uddvrz,51,40,0|uddvs0,57,66,1|upmjnz,57,66,1|upmjo0,51,40,0|uw3yfz,51,40,0|uw3yg0,57,66,1|v8cmbz,57,66,1|v8cmc0,51,40,0|veu13z,51,40,0|veu140,57,66,1|vr2ozz,57,66,1|vr2p00,51,40,0|vxk3rz,51,40,0|vxk3s0,57,66,1|w9srnz,57,66,1|w9sro0,51,40,0|wgn53z,51,40,0|wgn540,57,66,1|wsvszz,57,66,1|wsvt00,51,40,0|wzd7rz,51,40,0|wzd7s0,57,66,1|xblvnz,57,66,1|xblvo0,51,40,0|xi3afz,51,40,0|xi3ag0,57,66,1|xubybz,57,66,1|xubyc0,51,40,0|y0td3z,51,40,0|y0td40,57,66,1|yd20zz,57,66,1|yd2100,51,40,0|yjjfrz,51,40,0|yjjfs0,57,66,1|yvs3nz,57,66,1|yvs3o0,51,40,0|z29ifz,51,40,0|z29ig0,57,66,1|zei6bz,57,66,1|zei6c0,51,40,0\",\"America/Toronto|,0,185,0|-1353das,49,63,0|-qzoxw1,49,63,0|-qzoxw0,62,42,1|-qpm201,62,42,1|-qpm200,49,63,0|-qhn4u1,49,63,0|-qhn4u0,62,42,1|-q6w4w1,62,42,1|-q6w4w0,49,63,0|-px5wk1,49,63,0|-px5wk0,62,42,1|-pplww1,62,42,1|-pplww0,49,63,0|-pdpwk1,49,63,0|-pdpwk0,62,42,1|-p7e7c1,62,42,1|-p7e7c0,49,63,0|-ouztw1,49,63,0|-ouztw0,62,42,1|-ooiko1,62,42,1|-ooiko0,49,63,0|-oc9r81,49,63,0|-oc9r80,62,42,1|-o5si01,62,42,1|-o5si00,49,63,0|-ntwn81,49,63,0|-ntwn80,62,42,1|-nmpgo1,62,42,1|-nmpgo0,49,63,0|-nb6kk1,49,63,0|-nb6kk0,62,42,1|-n3ze01,62,42,1|-n3ze00,49,63,0|-msghw1,49,63,0|-msghw0,62,42,1|-ml9bc1,62,42,1|-ml9bc0,49,63,0|-m9qf81,49,63,0|-m9qf80,62,42,1|-m26a01,62,42,1|-m26a00,49,63,0|-lr0ck1,49,63,0|-lr0ck0,62,42,1|-lj38o1,62,42,1|-lj38o0,49,63,0|-l8a9w1,49,63,0|-l8a9w0,62,42,1|-l0d601,62,42,1|-l0d600,49,63,0|-kpk781,49,63,0|-kpk780,62,42,1|-khn3c1,62,42,1|-khn3c0,49,63,0|-k6u4k1,49,63,0|-k6u4k0,62,42,1|-jyx0o1,62,42,1|-jyx0o0,49,63,0|-jnr381,49,63,0|-jnr380,62,42,1|-jg6y01,62,42,1|-jg6y00,49,63,0|-j510k1,49,63,0|-j510k0,62,42,1|-ix3wo1,62,42,1|-ix3wo0,49,63,0|-imaxw1,49,63,0|-imaxw0,62,42,1|-iedu01,62,42,1|-iedu00,49,63,0|-i3kv81,49,63,0|-i3kv80,62,42,1|-hvnrc1,62,42,1|-hvnrc0,49,63,0|-hkusk1,49,63,0|-hkusk0,62,42,1|-hcxoo1,62,42,1|-hcxoo0,49,63,0|-h24pw1,49,63,0|-h24pw0,62,42,1|-gu7m01,62,42,1|-gu7m00,49,63,0|-gjen81,49,63,0|-gjen80,62,42,1|-gbhjc1,62,42,1|-gbhjc0,49,63,0|-g0blw1,49,63,0|-g0blw0,62,42,1|-fsrgo1,62,42,1|-fsrgo0,49,63,0|-fhlj81,49,63,0|-fhlj80,62,42,1|-ek24k1,62,42,1|-ek24k0,70,42,1|-cq2tg1,70,42,1|-cq2tg0,71,42,1|-cnp3c1,71,42,1|-cnp3c0,49,63,0|-ccw4k1,49,63,0|-ccw4k0,62,42,1|-c4z0o1,62,42,1|-c4z0o0,49,63,0|-bu67g1,49,63,0|-bu67g0,62,42,1|-bm93k1,62,42,1|-bm93k0,49,63,0|-bbg4s1,49,63,0|-bbg4s0,62,42,1|-b3j0w1,62,42,1|-b3j0w0,49,63,0|-asq241,49,63,0|-asq240,62,42,1|-ahka81,62,42,1|-ahka80,49,63,0|-a9mv81,49,63,0|-a9mv80,62,42,1|-9yu201,62,42,1|-9yu200,49,63,0|-9qwsk1,49,63,0|-9qwsk0,62,42,1|-9izoo1,62,42,1|-9izoo0,49,63,0|-986pw1,49,63,0|-986pw0,62,42,1|-909m01,62,42,1|-909m00,49,63,0|-8pgn81,49,63,0|-8pgn80,62,42,1|-8hjjc1,62,42,1|-8hjjc0,49,63,0|-86qkk1,49,63,0|-86qkk0,62,42,1|-7ytgo1,62,42,1|-7ytgo0,49,63,0|-7o0hw1,49,63,0|-7o0hw0,62,42,1|-7g3e01,62,42,1|-7g3e00,49,63,0|-74xgk1,49,63,0|-74xgk0,62,42,1|-6x0co1,62,42,1|-6x0co0,49,63,0|-6m7dw1,49,63,0|-6m7dw0,62,42,1|-6cufc1,62,42,1|-6cufc0,49,63,0|-63hb81,49,63,0|-63hb80,62,42,1|-5u4co1,62,42,1|-5u4co0,49,63,0|-5kr8k1,49,63,0|-5kr8k0,62,42,1|-5bea01,62,42,1|-5bea00,49,63,0|-5215w1,49,63,0|-5215w0,62,42,1|-4sb8o1,62,42,1|-4sb8o0,49,63,0|-4iy4k1,49,63,0|-4iy4k0,62,42,1|-49l601,62,42,1|-49l600,49,63,0|-4081w1,49,63,0|-4081w0,62,42,1|-3qv3c1,62,42,1|-3qv3c0,49,63,0|-3hhz81,49,63,0|-3hhz80,62,42,1|-3850o1,62,42,1|-3850o0,49,63,0|-2yrwk1,49,63,0|-2yrwk0,62,42,1|-2pey01,62,42,1|-2pey00,49,63,0|-2g1tw1,49,63,0|-2g1tw0,62,42,1|-26bwo1,62,42,1|-26bwo0,49,63,0|-1xbr81,49,63,0|-1xbr80,62,42,1|-1nlu01,62,42,1|-1nlu00,49,63,0|-1e8pw1,49,63,0|-1e8pw0,62,42,1|-14vrc1,62,42,1|-14vrc0,49,63,0|-vin81,49,63,0|-vin80,62,42,1|-m5oo1,62,42,1|-m5oo0,49,63,0|-cskk1,49,63,0|-cskk0,62,42,1|-3fm01,62,42,1|-3fm00,49,63,0|5xi3z,49,63,0|5xi40,62,42,1|fagnz,62,42,1|fago0,49,63,0|onkrz,49,63,0|onks0,62,42,1|ydhzz,62,42,1|ydi00,49,63,0|17qm3z,49,63,0|17qm40,62,42,1|1h3knz,62,42,1|1h3ko0,49,63,0|1qgorz,49,63,0|1qgos0,62,42,1|1ztnbz,62,42,1|1ztnc0,49,63,0|296rfz,49,63,0|296rg0,62,42,1|2ijpzz,62,42,1|2ijq00,49,63,0|2rwu3z,49,63,0|2rwu40,62,42,1|319snz,62,42,1|319so0,49,63,0|3amwrz,49,63,0|3amws0,62,42,1|3kctzz,62,42,1|3kcu00,49,63,0|3tczfz,49,63,0|3tczg0,62,42,1|432wnz,62,42,1|432wo0,49,63,0|4cg0rz,49,63,0|4cg0s0,62,42,1|4lszbz,62,42,1|4lszc0,49,63,0|4v63fz,49,63,0|4v63g0,62,42,1|54j1zz,62,42,1|54j200,49,63,0|5dw63z,49,63,0|5dw640,62,42,1|5n94nz,62,42,1|5n94o0,49,63,0|5wm8rz,49,63,0|5wm8s0,62,42,1|65z7bz,62,42,1|65z7c0,49,63,0|6fcbfz,49,63,0|6fcbg0,62,42,1|6p28nz,62,42,1|6p28o0,49,63,0|6y2e3z,49,63,0|6y2e40,62,42,1|77sbbz,62,42,1|77sbc0,49,63,0|7h5ffz,49,63,0|7h5fg0,62,42,1|7qidzz,62,42,1|7qie00,49,63,0|7zvi3z,49,63,0|7zvi40,62,42,1|898gnz,62,42,1|898go0,49,63,0|8ilkrz,49,63,0|8ilks0,62,42,1|8ryjbz,62,42,1|8ryjc0,49,63,0|908rfz,49,63,0|908rg0,62,42,1|9aolzz,62,42,1|9aom00,49,63,0|9iyu3z,49,63,0|9iyu40,62,42,1|9trnbz,62,42,1|9trnc0,49,63,0|a1owrz,49,63,0|a1ows0,62,42,1|achpzz,62,42,1|achq00,49,63,0|akezfz,49,63,0|akezg0,62,42,1|av7snz,62,42,1|av7so0,49,63,0|b3i0rz,49,63,0|b3i0s0,62,42,1|bdxvbz,62,42,1|bdxvc0,49,63,0|bm83fz,49,63,0|bm83g0,62,42,1|bwnxzz,62,42,1|bwny00,49,63,0|c4y63z,49,63,0|c4y640,62,42,1|cfqzbz,62,42,1|cfqzc0,49,63,0|cno8rz,49,63,0|cno8s0,62,42,1|cyh1zz,62,42,1|cyh200,49,63,0|d6ebfz,49,63,0|d6ebg0,62,42,1|dh74nz,62,42,1|dh74o0,49,63,0|dphcrz,49,63,0|dphcs0,62,42,1|dzx7bz,62,42,1|dzx7c0,49,63,0|e87ffz,49,63,0|e87fg0,62,42,1|ein9zz,62,42,1|eina00,49,63,0|eqxi3z,49,63,0|eqxi40,62,42,1|f1dcnz,62,42,1|f1dco0,49,63,0|f9nkrz,49,63,0|f9nks0,62,42,1|fkgdzz,62,42,1|fkge00,49,63,0|fsdnfz,49,63,0|fsdng0,62,42,1|g36gnz,62,42,1|g36go0,49,63,0|gb3q3z,49,63,0|gb3q40,62,42,1|glwjbz,62,42,1|glwjc0,49,63,0|gu6rfz,49,63,0|gu6rg0,62,42,1|h4mlzz,62,42,1|h4mm00,49,63,0|hcwu3z,49,63,0|hcwu40,62,42,1|hnconz,62,42,1|hncoo0,49,63,0|hvmwrz,49,63,0|hvmws0,62,42,1|i6fpzz,62,42,1|i6fq00,49,63,0|ieczfz,49,63,0|ieczg0,62,42,1|ip5snz,62,42,1|ip5so0,49,63,0|ix323z,49,63,0|ix3240,62,42,1|j7vvbz,62,42,1|j7vvc0,49,63,0|jeq8rz,49,63,0|jeq8s0,62,42,1|jqywnz,62,42,1|jqywo0,49,63,0|jxgbfz,49,63,0|jxgbg0,62,42,1|k9ozbz,62,42,1|k9ozc0,49,63,0|kg6e3z,49,63,0|kg6e40,62,42,1|ksf1zz,62,42,1|ksf200,49,63,0|kz9ffz,49,63,0|kz9fg0,62,42,1|lbi3bz,62,42,1|lbi3c0,49,63,0|lhzi3z,49,63,0|lhzi40,62,42,1|lu85zz,62,42,1|lu8600,49,63,0|m0pkrz,49,63,0|m0pks0,62,42,1|mcy8nz,62,42,1|mcy8o0,49,63,0|mjfnfz,49,63,0|mjfng0,62,42,1|mvobbz,62,42,1|mvobc0,49,63,0|n25q3z,49,63,0|n25q40,62,42,1|needzz,62,42,1|neee00,49,63,0|nkvsrz,49,63,0|nkvss0,62,42,1|nx4gnz,62,42,1|nx4go0,49,63,0|o3yu3z,49,63,0|o3yu40,62,42,1|og7hzz,62,42,1|og7i00,49,63,0|omowrz,49,63,0|omows0,62,42,1|oyxknz,62,42,1|oyxko0,49,63,0|p5ezfz,49,63,0|p5ezg0,62,42,1|phnnbz,62,42,1|phnnc0,49,63,0|po523z,49,63,0|po5240,62,42,1|q0dpzz,62,42,1|q0dq00,49,63,0|q6v4rz,49,63,0|q6v4s0,62,42,1|qj3snz,62,42,1|qj3so0,49,63,0|qpy63z,49,63,0|qpy640,62,42,1|r26tzz,62,42,1|r26u00,49,63,0|r8o8rz,49,63,0|r8o8s0,62,42,1|rkwwnz,62,42,1|rkwwo0,49,63,0|rrebfz,49,63,0|rrebg0,62,42,1|s3mzbz,62,42,1|s3mzc0,49,63,0|sa4e3z,49,63,0|sa4e40,62,42,1|smd1zz,62,42,1|smd200,49,63,0|ssugrz,49,63,0|ssugs0,62,42,1|t534nz,62,42,1|t534o0,49,63,0|tbkjfz,49,63,0|tbkjg0,62,42,1|tnt7bz,62,42,1|tnt7c0,49,63,0|tunkrz,49,63,0|tunks0,62,42,1|u6w8nz,62,42,1|u6w8o0,49,63,0|uddnfz,49,63,0|uddng0,62,42,1|upmbbz,62,42,1|upmbc0,49,63,0|uw3q3z,49,63,0|uw3q40,62,42,1|v8cdzz,62,42,1|v8ce00,49,63,0|vetsrz,49,63,0|vetss0,62,42,1|vr2gnz,62,42,1|vr2go0,49,63,0|vxjvfz,49,63,0|vxjvg0,62,42,1|w9sjbz,62,42,1|w9sjc0,49,63,0|wgmwrz,49,63,0|wgmws0,62,42,1|wsvknz,62,42,1|wsvko0,49,63,0|wzczfz,49,63,0|wzczg0,62,42,1|xblnbz,62,42,1|xblnc0,49,63,0|xi323z,49,63,0|xi3240,62,42,1|xubpzz,62,42,1|xubq00,49,63,0|y0t4rz,49,63,0|y0t4s0,62,42,1|yd1snz,62,42,1|yd1so0,49,63,0|yjj7fz,49,63,0|yjj7g0,62,42,1|yvrvbz,62,42,1|yvrvc0,49,63,0|z29a3z,49,63,0|z29a40,62,42,1|zehxzz,62,42,1|zehy00,49,63,0\",\"America/Tortola|,0,41,0|-u6m79w,32,42,0\",\"America/Vancouver|,0,186,0|-18vrvv8,51,40,0|-qzopk1,51,40,0|-qzopk0,57,66,1|-qplto1,57,66,1|-qplto0,51,40,0|-ek1w81,51,40,0|-ek1w80,68,66,1|-cq2tg1,68,66,1|-cq2tg0,69,66,1|-cnov01,69,66,1|-cnov00,51,40,0|-ccvw81,51,40,0|-ccvw80,57,66,1|-c4ysc1,57,66,1|-c4ysc0,51,40,0|-bu5tk1,51,40,0|-bu5tk0,57,66,1|-bm8po1,57,66,1|-bm8po0,51,40,0|-bbfqw1,51,40,0|-bbfqw0,57,66,1|-b3in01,57,66,1|-b3in00,51,40,0|-aspo81,51,40,0|-aspo80,57,66,1|-akskc1,57,66,1|-akskc0,51,40,0|-a9mmw1,51,40,0|-a9mmw0,57,66,1|-a22ho1,57,66,1|-a22ho0,51,40,0|-9qwk81,51,40,0|-9qwk80,57,66,1|-9izgc1,57,66,1|-9izgc0,51,40,0|-986hk1,51,40,0|-986hk0,57,66,1|-909do1,57,66,1|-909do0,51,40,0|-8pgew1,51,40,0|-8pgew0,57,66,1|-8hjb01,57,66,1|-8hjb00,51,40,0|-86qc81,51,40,0|-86qc80,57,66,1|-7yt8c1,57,66,1|-7yt8c0,51,40,0|-7o09k1,51,40,0|-7o09k0,57,66,1|-7g35o1,57,66,1|-7g35o0,51,40,0|-74x881,51,40,0|-74x880,57,66,1|-6x04c1,57,66,1|-6x04c0,51,40,0|-6m75k1,51,40,0|-6m75k0,57,66,1|-6ea1o1,57,66,1|-6ea1o0,51,40,0|-63h2w1,51,40,0|-63h2w0,57,66,1|-5vjz01,57,66,1|-5vjz00,51,40,0|-5kr081,51,40,0|-5kr080,57,66,1|-5ctwc1,57,66,1|-5ctwc0,51,40,0|-520xk1,51,40,0|-520xk0,57,66,1|-4u3to1,57,66,1|-4u3to0,51,40,0|-4ixw81,51,40,0|-4ixw80,57,66,1|-4bdr01,57,66,1|-4bdr00,51,40,0|-407tk1,51,40,0|-407tk0,57,66,1|-3quv01,57,66,1|-3quv00,51,40,0|-3hhqw1,51,40,0|-3hhqw0,57,66,1|-384sc1,57,66,1|-384sc0,51,40,0|-2yro81,51,40,0|-2yro80,57,66,1|-2pepo1,57,66,1|-2pepo0,51,40,0|-2g1lk1,51,40,0|-2g1lk0,57,66,1|-26boc1,57,66,1|-26boc0,51,40,0|-1xbiw1,51,40,0|-1xbiw0,57,66,1|-1nllo1,57,66,1|-1nllo0,51,40,0|-1e8hk1,51,40,0|-1e8hk0,57,66,1|-14vj01,57,66,1|-14vj00,51,40,0|-view1,51,40,0|-view0,57,66,1|-m5gc1,57,66,1|-m5gc0,51,40,0|-csc81,51,40,0|-csc80,57,66,1|-3fdo1,57,66,1|-3fdo0,51,40,0|5xqfz,51,40,0|5xqg0,57,66,1|faozz,57,66,1|fap00,51,40,0|ont3z,51,40,0|ont40,57,66,1|ydqbz,57,66,1|ydqc0,51,40,0|17qufz,51,40,0|17qug0,57,66,1|1h3szz,57,66,1|1h3t00,51,40,0|1qgx3z,51,40,0|1qgx40,57,66,1|1ztvnz,57,66,1|1ztvo0,51,40,0|296zrz,51,40,0|296zs0,57,66,1|2ijybz,57,66,1|2ijyc0,51,40,0|2rx2fz,51,40,0|2rx2g0,57,66,1|31a0zz,57,66,1|31a100,51,40,0|3an53z,51,40,0|3an540,57,66,1|3kd2bz,57,66,1|3kd2c0,51,40,0|3td7rz,51,40,0|3td7s0,57,66,1|4334zz,57,66,1|433500,51,40,0|4cg93z,51,40,0|4cg940,57,66,1|4lt7nz,57,66,1|4lt7o0,51,40,0|4v6brz,51,40,0|4v6bs0,57,66,1|54jabz,57,66,1|54jac0,51,40,0|5dwefz,51,40,0|5dweg0,57,66,1|5n9czz,57,66,1|5n9d00,51,40,0|5wmh3z,51,40,0|5wmh40,57,66,1|65zfnz,57,66,1|65zfo0,51,40,0|6fcjrz,51,40,0|6fcjs0,57,66,1|6p2gzz,57,66,1|6p2h00,51,40,0|6y2mfz,51,40,0|6y2mg0,57,66,1|77sjnz,57,66,1|77sjo0,51,40,0|7h5nrz,51,40,0|7h5ns0,57,66,1|7qimbz,57,66,1|7qimc0,51,40,0|7zvqfz,51,40,0|7zvqg0,57,66,1|898ozz,57,66,1|898p00,51,40,0|8ilt3z,51,40,0|8ilt40,57,66,1|8ryrnz,57,66,1|8ryro0,51,40,0|908zrz,51,40,0|908zs0,57,66,1|9aoubz,57,66,1|9aouc0,51,40,0|9iz2fz,51,40,0|9iz2g0,57,66,1|9trvnz,57,66,1|9trvo0,51,40,0|a1p53z,51,40,0|a1p540,57,66,1|achybz,57,66,1|achyc0,51,40,0|akf7rz,51,40,0|akf7s0,57,66,1|av80zz,57,66,1|av8100,51,40,0|b3i93z,51,40,0|b3i940,57,66,1|bdy3nz,57,66,1|bdy3o0,51,40,0|bm8brz,51,40,0|bm8bs0,57,66,1|bwo6bz,57,66,1|bwo6c0,51,40,0|c4yefz,51,40,0|c4yeg0,57,66,1|cfr7nz,57,66,1|cfr7o0,51,40,0|cnoh3z,51,40,0|cnoh40,57,66,1|cyhabz,57,66,1|cyhac0,51,40,0|d6ejrz,51,40,0|d6ejs0,57,66,1|dh7czz,57,66,1|dh7d00,51,40,0|dphl3z,51,40,0|dphl40,57,66,1|dzxfnz,57,66,1|dzxfo0,51,40,0|e87nrz,51,40,0|e87ns0,57,66,1|einibz,57,66,1|einic0,51,40,0|eqxqfz,51,40,0|eqxqg0,57,66,1|f1dkzz,57,66,1|f1dl00,51,40,0|f9nt3z,51,40,0|f9nt40,57,66,1|fkgmbz,57,66,1|fkgmc0,51,40,0|fsdvrz,51,40,0|fsdvs0,57,66,1|g36ozz,57,66,1|g36p00,51,40,0|gb3yfz,51,40,0|gb3yg0,57,66,1|glwrnz,57,66,1|glwro0,51,40,0|gu6zrz,51,40,0|gu6zs0,57,66,1|h4mubz,57,66,1|h4muc0,51,40,0|hcx2fz,51,40,0|hcx2g0,57,66,1|hncwzz,57,66,1|hncx00,51,40,0|hvn53z,51,40,0|hvn540,57,66,1|i6fybz,57,66,1|i6fyc0,51,40,0|ied7rz,51,40,0|ied7s0,57,66,1|ip60zz,57,66,1|ip6100,51,40,0|ix3afz,51,40,0|ix3ag0,57,66,1|j7w3nz,57,66,1|j7w3o0,51,40,0|jeqh3z,51,40,0|jeqh40,57,66,1|jqz4zz,57,66,1|jqz500,51,40,0|jxgjrz,51,40,0|jxgjs0,57,66,1|k9p7nz,57,66,1|k9p7o0,51,40,0|kg6mfz,51,40,0|kg6mg0,57,66,1|ksfabz,57,66,1|ksfac0,51,40,0|kz9nrz,51,40,0|kz9ns0,57,66,1|lbibnz,57,66,1|lbibo0,51,40,0|lhzqfz,51,40,0|lhzqg0,57,66,1|lu8ebz,57,66,1|lu8ec0,51,40,0|m0pt3z,51,40,0|m0pt40,57,66,1|mcygzz,57,66,1|mcyh00,51,40,0|mjfvrz,51,40,0|mjfvs0,57,66,1|mvojnz,57,66,1|mvojo0,51,40,0|n25yfz,51,40,0|n25yg0,57,66,1|neembz,57,66,1|neemc0,51,40,0|nkw13z,51,40,0|nkw140,57,66,1|nx4ozz,57,66,1|nx4p00,51,40,0|o3z2fz,51,40,0|o3z2g0,57,66,1|og7qbz,57,66,1|og7qc0,51,40,0|omp53z,51,40,0|omp540,57,66,1|oyxszz,57,66,1|oyxt00,51,40,0|p5f7rz,51,40,0|p5f7s0,57,66,1|phnvnz,57,66,1|phnvo0,51,40,0|po5afz,51,40,0|po5ag0,57,66,1|q0dybz,57,66,1|q0dyc0,51,40,0|q6vd3z,51,40,0|q6vd40,57,66,1|qj40zz,57,66,1|qj4100,51,40,0|qpyefz,51,40,0|qpyeg0,57,66,1|r272bz,57,66,1|r272c0,51,40,0|r8oh3z,51,40,0|r8oh40,57,66,1|rkx4zz,57,66,1|rkx500,51,40,0|rrejrz,51,40,0|rrejs0,57,66,1|s3n7nz,57,66,1|s3n7o0,51,40,0|sa4mfz,51,40,0|sa4mg0,57,66,1|smdabz,57,66,1|smdac0,51,40,0|ssup3z,51,40,0|ssup40,57,66,1|t53czz,57,66,1|t53d00,51,40,0|tbkrrz,51,40,0|tbkrs0,57,66,1|tntfnz,57,66,1|tntfo0,51,40,0|tunt3z,51,40,0|tunt40,57,66,1|u6wgzz,57,66,1|u6wh00,51,40,0|uddvrz,51,40,0|uddvs0,57,66,1|upmjnz,57,66,1|upmjo0,51,40,0|uw3yfz,51,40,0|uw3yg0,57,66,1|v8cmbz,57,66,1|v8cmc0,51,40,0|veu13z,51,40,0|veu140,57,66,1|vr2ozz,57,66,1|vr2p00,51,40,0|vxk3rz,51,40,0|vxk3s0,57,66,1|w9srnz,57,66,1|w9sro0,51,40,0|wgn53z,51,40,0|wgn540,57,66,1|wsvszz,57,66,1|wsvt00,51,40,0|wzd7rz,51,40,0|wzd7s0,57,66,1|xblvnz,57,66,1|xblvo0,51,40,0|xi3afz,51,40,0|xi3ag0,57,66,1|xubybz,57,66,1|xubyc0,51,40,0|y0td3z,51,40,0|y0td40,57,66,1|yd20zz,57,66,1|yd2100,51,40,0|yjjfrz,51,40,0|yjjfs0,57,66,1|yvs3nz,57,66,1|yvs3o0,51,40,0|z29ifz,51,40,0|z29ig0,57,66,1|zei6bz,57,66,1|zei6c0,51,40,0\",\"America/Whitehorse|,0,187,0|-1079tno,36,37,0|-qzoms1,36,37,0|-qzoms0,64,40,1|-qplqw1,64,40,1|-qplqw0,36,37,0|-qess41,36,37,0|-qess40,64,40,1|-q6kps1,64,40,1|-q6kps0,36,37,0|-ek1tg1,36,37,0|-ek1tg0,65,40,1|-cq2tg1,65,40,1|-cq2tg0,66,40,1|-cnos81,66,40,1|-cnos80,36,37,0|-2g1oc1,36,37,0|-2g1oc0,67,66,1|-26boc1,67,66,1|-26boc0,36,37,0|-1cspo1,36,37,0|-1cspo0,51,40,0|5dwefz,51,40,0|5dweg0,57,66,1|5n9czz,57,66,1|5n9d00,51,40,0|5wmh3z,51,40,0|5wmh40,57,66,1|65zfnz,57,66,1|65zfo0,51,40,0|6fcjrz,51,40,0|6fcjs0,57,66,1|6p2gzz,57,66,1|6p2h00,51,40,0|6y2mfz,51,40,0|6y2mg0,57,66,1|77sjnz,57,66,1|77sjo0,51,40,0|7h5nrz,51,40,0|7h5ns0,57,66,1|7qimbz,57,66,1|7qimc0,51,40,0|7zvqfz,51,40,0|7zvqg0,57,66,1|898ozz,57,66,1|898p00,51,40,0|8ilt3z,51,40,0|8ilt40,57,66,1|8ryrnz,57,66,1|8ryro0,51,40,0|908zrz,51,40,0|908zs0,57,66,1|9aoubz,57,66,1|9aouc0,51,40,0|9iz2fz,51,40,0|9iz2g0,57,66,1|9trvnz,57,66,1|9trvo0,51,40,0|a1p53z,51,40,0|a1p540,57,66,1|achybz,57,66,1|achyc0,51,40,0|akf7rz,51,40,0|akf7s0,57,66,1|av80zz,57,66,1|av8100,51,40,0|b3i93z,51,40,0|b3i940,57,66,1|bdy3nz,57,66,1|bdy3o0,51,40,0|bm8brz,51,40,0|bm8bs0,57,66,1|bwo6bz,57,66,1|bwo6c0,51,40,0|c4yefz,51,40,0|c4yeg0,57,66,1|cfr7nz,57,66,1|cfr7o0,51,40,0|cnoh3z,51,40,0|cnoh40,57,66,1|cyhabz,57,66,1|cyhac0,51,40,0|d6ejrz,51,40,0|d6ejs0,57,66,1|dh7czz,57,66,1|dh7d00,51,40,0|dphl3z,51,40,0|dphl40,57,66,1|dzxfnz,57,66,1|dzxfo0,51,40,0|e87nrz,51,40,0|e87ns0,57,66,1|einibz,57,66,1|einic0,51,40,0|eqxqfz,51,40,0|eqxqg0,57,66,1|f1dkzz,57,66,1|f1dl00,51,40,0|f9nt3z,51,40,0|f9nt40,57,66,1|fkgmbz,57,66,1|fkgmc0,51,40,0|fsdvrz,51,40,0|fsdvs0,57,66,1|g36ozz,57,66,1|g36p00,51,40,0|gb3yfz,51,40,0|gb3yg0,57,66,1|glwrnz,57,66,1|glwro0,51,40,0|gu6zrz,51,40,0|gu6zs0,57,66,1|h4mubz,57,66,1|h4muc0,51,40,0|hcx2fz,51,40,0|hcx2g0,57,66,1|hncwzz,57,66,1|hncx00,51,40,0|hvn53z,51,40,0|hvn540,57,66,1|i6fybz,57,66,1|i6fyc0,51,40,0|ied7rz,51,40,0|ied7s0,57,66,1|ip60zz,57,66,1|ip6100,51,40,0|ix3afz,51,40,0|ix3ag0,57,66,1|j7w3nz,57,66,1|j7w3o0,51,40,0|jeqh3z,51,40,0|jeqh40,57,66,1|jqz4zz,57,66,1|jqz500,51,40,0|jxgjrz,51,40,0|jxgjs0,57,66,1|k9p7nz,57,66,1|k9p7o0,51,40,0|kg6mfz,51,40,0|kg6mg0,57,66,1|ksfabz,57,66,1|ksfac0,51,40,0|kz9nrz,51,40,0|kz9ns0,57,66,1|lbibnz,57,66,1|lbibo0,51,40,0|lhzqfz,51,40,0|lhzqg0,57,66,1|lu8ebz,57,66,1|lu8ec0,51,40,0|m0pt3z,51,40,0|m0pt40,57,66,1|mcygzz,57,66,1|mcyh00,51,40,0|mjfvrz,51,40,0|mjfvs0,57,66,1|mvojnz,57,66,1|mvojo0,51,40,0|n25yfz,51,40,0|n25yg0,57,66,1|neembz,57,66,1|neemc0,51,40,0|nkw13z,51,40,0|nkw140,57,66,1|nx4ozz,57,66,1|nx4p00,51,40,0|o3z2fz,51,40,0|o3z2g0,57,66,1|og7qbz,57,66,1|og7qc0,51,40,0|omp53z,51,40,0|omp540,57,66,1|oyxszz,57,66,1|oyxt00,51,40,0|p5f7rz,51,40,0|p5f7s0,57,66,1|phnvnz,57,66,1|phnvo0,51,40,0|po5afz,51,40,0|po5ag0,57,66,1|q0dybz,57,66,1|q0dyc0,51,40,0|q6vd3z,51,40,0|q6vd40,57,66,1|qj3vfz,57,66,1|qj3vg0,50,66,0\",\"America/Winnipeg|,0,188,0|-171bfcc,45,62,0|-s0s7c1,45,62,0|-s0s7c0,46,63,1|-rt8241,46,63,1|-rt8240,45,62,0|-qzov41,45,62,0|-qzov40,46,63,1|-qplz81,46,63,1|-qplz80,45,62,0|-h11r41,45,62,0|-h11r40,46,63,1|-gu7j81,46,63,1|-gu7j80,45,62,0|-ek21s1,45,62,0|-ek21s0,47,63,1|-cq2tg1,47,63,1|-cq2tg0,48,63,1|-cnp0k1,48,63,1|-cnp0k0,45,62,0|-cc64g1,45,62,0|-cc64g0,46,63,1|-c490k1,46,63,1|-c490k0,45,62,0|-bu5z41,45,62,0|-bu5z40,46,63,1|-bm8v81,46,63,1|-bm8v80,45,62,0|-bbfwg1,45,62,0|-bbfwg0,46,63,1|-b3isk1,46,63,1|-b3isk0,45,62,0|-aspts1,45,62,0|-aspts0,46,63,1|-akspw1,46,63,1|-akspw0,45,62,0|-a9kxs1,45,62,0|-a9kxs0,46,63,1|-a1rj81,46,63,1|-a1rj80,45,62,0|-9qwps1,45,62,0|-9qwps0,46,63,1|-9izlw1,46,63,1|-9izlw0,45,62,0|-986n41,45,62,0|-986n40,46,63,1|-909j81,46,63,1|-909j80,45,62,0|-8pgkg1,45,62,0|-8pgkg0,46,63,1|-8hjgk1,46,63,1|-8hjgk0,45,62,0|-86qhs1,45,62,0|-86qhs0,46,63,1|-7ytdw1,46,63,1|-7ytdw0,45,62,0|-7o0f41,45,62,0|-7o0f40,46,63,1|-7g3b81,46,63,1|-7g3b80,45,62,0|-74xds1,45,62,0|-74xds0,46,63,1|-6x09w1,46,63,1|-6x09w0,45,62,0|-6m7b41,45,62,0|-6m7b40,46,63,1|-6ea781,46,63,1|-6ea780,45,62,0|-63h8g1,45,62,0|-63h8g0,46,63,1|-5vk4k1,46,63,1|-5vk4k0,45,62,0|-5kr5s1,45,62,0|-5kr5s0,46,63,1|-5be781,46,63,1|-5be780,45,62,0|-521341,45,62,0|-521340,46,63,1|-4u3z81,46,63,1|-4u3z80,45,62,0|-3hhwg1,45,62,0|-3hhwg0,46,63,1|-39xr81,46,63,1|-39xr80,45,62,0|-1xbog1,45,62,0|-1xbog0,46,63,1|-1nlog1,46,63,1|-1nlog0,45,62,0|-1e8n41,45,62,0|-1e8n40,46,63,1|-14vls1,46,63,1|-14vls0,45,62,0|-vikg1,45,62,0|-vikg0,46,63,1|-m5j41,46,63,1|-m5j40,45,62,0|-cshs1,45,62,0|-cshs0,46,63,1|-3fgg1,46,63,1|-3fgg0,45,62,0|5xkvz,45,62,0|5xkw0,46,63,1|fam7z,46,63,1|fam80,45,62,0|onnjz,45,62,0|onnk0,46,63,1|ydnjz,46,63,1|ydnk0,45,62,0|17qovz,45,62,0|17qow0,46,63,1|1h3q7z,46,63,1|1h3q80,45,62,0|1qgrjz,45,62,0|1qgrk0,46,63,1|1ztsvz,46,63,1|1ztsw0,45,62,0|296u7z,45,62,0|296u80,46,63,1|2ijvjz,46,63,1|2ijvk0,45,62,0|2rwwvz,45,62,0|2rwww0,46,63,1|319y7z,46,63,1|319y80,45,62,0|3amzjz,45,62,0|3amzk0,46,63,1|3kczjz,46,63,1|3kczk0,45,62,0|3td27z,45,62,0|3td280,46,63,1|43327z,46,63,1|433280,45,62,0|4cg3jz,45,62,0|4cg3k0,46,63,1|4lt4vz,46,63,1|4lt4w0,45,62,0|4v667z,45,62,0|4v6680,46,63,1|54j7jz,46,63,1|54j7k0,45,62,0|5dw8vz,45,62,0|5dw8w0,46,63,1|5n9a7z,46,63,1|5n9a80,45,62,0|5wmbjz,45,62,0|5wmbk0,46,63,1|65zcvz,46,63,1|65zcw0,45,62,0|6fce7z,45,62,0|6fce80,46,63,1|6p2e7z,46,63,1|6p2e80,45,62,0|6y2gvz,45,62,0|6y2gw0,46,63,1|77sgvz,46,63,1|77sgw0,45,62,0|7h5i7z,45,62,0|7h5i80,46,63,1|7qijjz,46,63,1|7qijk0,45,62,0|7zvkvz,45,62,0|7zvkw0,46,63,1|898m7z,46,63,1|898m80,45,62,0|8ilnjz,45,62,0|8ilnk0,46,63,1|8ryovz,46,63,1|8ryow0,45,62,0|908u7z,45,62,0|908u80,46,63,1|9aorjz,46,63,1|9aork0,45,62,0|9iywvz,45,62,0|9iyww0,46,63,1|9trsvz,46,63,1|9trsw0,45,62,0|a1ozjz,45,62,0|a1ozk0,46,63,1|achvjz,46,63,1|achvk0,45,62,0|akf27z,45,62,0|akf280,46,63,1|av7y7z,46,63,1|av7y80,45,62,0|b3i3jz,45,62,0|b3i3k0,46,63,1|bdy0vz,46,63,1|bdy0w0,45,62,0|bm867z,45,62,0|bm8680,46,63,1|bwo3jz,46,63,1|bwo3k0,45,62,0|c4y8vz,45,62,0|c4y8w0,46,63,1|cfr4vz,46,63,1|cfr4w0,45,62,0|cnobjz,45,62,0|cnobk0,46,63,1|cyh7jz,46,63,1|cyh7k0,45,62,0|d6ee7z,45,62,0|d6ee80,46,63,1|dh7a7z,46,63,1|dh7a80,45,62,0|dphfjz,45,62,0|dphfk0,46,63,1|dzxcvz,46,63,1|dzxcw0,45,62,0|e87i7z,45,62,0|e87i80,46,63,1|einfjz,46,63,1|einfk0,45,62,0|eqxkvz,45,62,0|eqxkw0,46,63,1|f1di7z,46,63,1|f1di80,45,62,0|f9nnjz,45,62,0|f9nnk0,46,63,1|fkgjjz,46,63,1|fkgjk0,45,62,0|fsdq7z,45,62,0|fsdq80,46,63,1|g36m7z,46,63,1|g36m80,45,62,0|gb3svz,45,62,0|gb3sw0,46,63,1|glwovz,46,63,1|glwow0,45,62,0|gu6u7z,45,62,0|gu6u80,46,63,1|h4mrjz,46,63,1|h4mrk0,45,62,0|hcwwvz,45,62,0|hcwww0,46,63,1|hncu7z,46,63,1|hncu80,45,62,0|hvmzjz,45,62,0|hvmzk0,46,63,1|i6fvjz,46,63,1|i6fvk0,45,62,0|ied27z,45,62,0|ied280,46,63,1|ip5y7z,46,63,1|ip5y80,45,62,0|ix34vz,45,62,0|ix34w0,46,63,1|j7vy3z,46,63,1|j7vy40,45,62,0|jeqbjz,45,62,0|jeqbk0,46,63,1|jqyzfz,46,63,1|jqyzg0,45,62,0|jxge7z,45,62,0|jxge80,46,63,1|k9p23z,46,63,1|k9p240,45,62,0|kg6gvz,45,62,0|kg6gw0,46,63,1|ksf4rz,46,63,1|ksf4s0,45,62,0|kz9i7z,45,62,0|kz9i80,46,63,1|lbi63z,46,63,1|lbi640,45,62,0|lhzkvz,45,62,0|lhzkw0,46,63,1|lu88rz,46,63,1|lu88s0,45,62,0|m0pnjz,45,62,0|m0pnk0,46,63,1|mcybfz,46,63,1|mcybg0,45,62,0|mjfq7z,45,62,0|mjfq80,46,63,1|mvoe3z,46,63,1|mvoe40,45,62,0|n25svz,45,62,0|n25sw0,46,63,1|neegrz,46,63,1|neegs0,45,62,0|nkvvjz,45,62,0|nkvvk0,46,63,1|nx4jfz,46,63,1|nx4jg0,45,62,0|o3ywvz,45,62,0|o3yww0,46,63,1|og7krz,46,63,1|og7ks0,45,62,0|omozjz,45,62,0|omozk0,46,63,1|oyxnfz,46,63,1|oyxng0,45,62,0|p5f27z,45,62,0|p5f280,46,63,1|phnq3z,46,63,1|phnq40,45,62,0|po54vz,45,62,0|po54w0,46,63,1|q0dsrz,46,63,1|q0dss0,45,62,0|q6v7jz,45,62,0|q6v7k0,46,63,1|qj3vfz,46,63,1|qj3vg0,45,62,0|qpy8vz,45,62,0|qpy8w0,46,63,1|r26wrz,46,63,1|r26ws0,45,62,0|r8objz,45,62,0|r8obk0,46,63,1|rkwzfz,46,63,1|rkwzg0,45,62,0|rree7z,45,62,0|rree80,46,63,1|s3n23z,46,63,1|s3n240,45,62,0|sa4gvz,45,62,0|sa4gw0,46,63,1|smd4rz,46,63,1|smd4s0,45,62,0|ssujjz,45,62,0|ssujk0,46,63,1|t537fz,46,63,1|t537g0,45,62,0|tbkm7z,45,62,0|tbkm80,46,63,1|tnta3z,46,63,1|tnta40,45,62,0|tunnjz,45,62,0|tunnk0,46,63,1|u6wbfz,46,63,1|u6wbg0,45,62,0|uddq7z,45,62,0|uddq80,46,63,1|upme3z,46,63,1|upme40,45,62,0|uw3svz,45,62,0|uw3sw0,46,63,1|v8cgrz,46,63,1|v8cgs0,45,62,0|vetvjz,45,62,0|vetvk0,46,63,1|vr2jfz,46,63,1|vr2jg0,45,62,0|vxjy7z,45,62,0|vxjy80,46,63,1|w9sm3z,46,63,1|w9sm40,45,62,0|wgmzjz,45,62,0|wgmzk0,46,63,1|wsvnfz,46,63,1|wsvng0,45,62,0|wzd27z,45,62,0|wzd280,46,63,1|xblq3z,46,63,1|xblq40,45,62,0|xi34vz,45,62,0|xi34w0,46,63,1|xubsrz,46,63,1|xubss0,45,62,0|y0t7jz,45,62,0|y0t7k0,46,63,1|yd1vfz,46,63,1|yd1vg0,45,62,0|yjja7z,45,62,0|yjja80,46,63,1|yvry3z,46,63,1|yvry40,45,62,0|z29cvz,45,62,0|z29cw0,46,63,1|zei0rz,46,63,1|zei0s0,45,62,0\",\"America/Yakutat|,0,189,0|-1hc7qjz,0,190,0|-1078vgi,0,190,0|-1078vgh,36,37,0|-ek1tg1,36,37,0|-ek1tg0,65,40,1|-cq2tg1,65,40,1|-cq2tg0,66,40,1|-cnos81,66,40,1|-cnos80,36,37,0|-cs9g1,36,37,0|-cs9g0,64,40,1|-3faw1,64,40,1|-3faw0,36,37,0|5xt7z,36,37,0|5xt80,64,40,1|farrz,64,40,1|fars0,36,37,0|onvvz,36,37,0|onvw0,64,40,1|ydt3z,64,40,1|ydt40,36,37,0|17qx7z,36,37,0|17qx80,64,40,1|1h3vrz,64,40,1|1h3vs0,36,37,0|1qgzvz,36,37,0|1qgzw0,64,40,1|1ztyfz,64,40,1|1ztyg0,36,37,0|23fnvz,36,37,0|23fnw0,64,40,1|2ik13z,64,40,1|2ik140,36,37,0|2ooh7z,36,37,0|2ooh80,64,40,1|31a3rz,64,40,1|31a3s0,36,37,0|3an7vz,36,37,0|3an7w0,64,40,1|3kd53z,64,40,1|3kd540,36,37,0|3tdajz,36,37,0|3tdak0,64,40,1|4337rz,64,40,1|4337s0,36,37,0|4cgbvz,36,37,0|4cgbw0,64,40,1|4ltafz,64,40,1|4ltag0,36,37,0|4v6ejz,36,37,0|4v6ek0,64,40,1|54jd3z,64,40,1|54jd40,36,37,0|5dwh7z,36,37,0|5dwh80,64,40,1|5n9frz,64,40,1|5n9fs0,36,37,0|5wmjvz,36,37,0|5wmjw0,64,40,1|65zifz,64,40,1|65zig0,36,37,0|6fcmjz,36,37,0|6fcmk0,64,40,1|6p2jrz,64,40,1|6p2js0,36,37,0|6y2p7z,36,37,0|6y2p80,64,40,1|77smfz,64,40,1|77smg0,36,37,0|79dybz,36,37,0|79dyc0,37,37,0|7h5qjz,37,37,0|7h5qk0,38,40,1|7qip3z,38,40,1|7qip40,37,37,0|7zvt7z,37,37,0|7zvt80,38,40,1|898rrz,38,40,1|898rs0,37,37,0|8ilvvz,37,37,0|8ilvw0,38,40,1|8ryufz,38,40,1|8ryug0,37,37,0|9092jz,37,37,0|9092k0,38,40,1|9aox3z,38,40,1|9aox40,37,37,0|9iz57z,37,37,0|9iz580,38,40,1|9tryfz,38,40,1|9tryg0,37,37,0|a1p7vz,37,37,0|a1p7w0,38,40,1|aci13z,38,40,1|aci140,37,37,0|akfajz,37,37,0|akfak0,38,40,1|av83rz,38,40,1|av83s0,37,37,0|b3ibvz,37,37,0|b3ibw0,38,40,1|bdy6fz,38,40,1|bdy6g0,37,37,0|bm8ejz,37,37,0|bm8ek0,38,40,1|bwo93z,38,40,1|bwo940,37,37,0|c4yh7z,37,37,0|c4yh80,38,40,1|cfrafz,38,40,1|cfrag0,37,37,0|cnojvz,37,37,0|cnojw0,38,40,1|cyhd3z,38,40,1|cyhd40,37,37,0|d6emjz,37,37,0|d6emk0,38,40,1|dh7frz,38,40,1|dh7fs0,37,37,0|dphnvz,37,37,0|dphnw0,38,40,1|dzxifz,38,40,1|dzxig0,37,37,0|e87qjz,37,37,0|e87qk0,38,40,1|einl3z,38,40,1|einl40,37,37,0|eqxt7z,37,37,0|eqxt80,38,40,1|f1dnrz,38,40,1|f1dns0,37,37,0|f9nvvz,37,37,0|f9nvw0,38,40,1|fkgp3z,38,40,1|fkgp40,37,37,0|fsdyjz,37,37,0|fsdyk0,38,40,1|g36rrz,38,40,1|g36rs0,37,37,0|gb417z,37,37,0|gb4180,38,40,1|glwufz,38,40,1|glwug0,37,37,0|gu72jz,37,37,0|gu72k0,38,40,1|h4mx3z,38,40,1|h4mx40,37,37,0|hcx57z,37,37,0|hcx580,38,40,1|hnczrz,38,40,1|hnczs0,37,37,0|hvn7vz,37,37,0|hvn7w0,38,40,1|i6g13z,38,40,1|i6g140,37,37,0|iedajz,37,37,0|iedak0,38,40,1|ip63rz,38,40,1|ip63s0,37,37,0|ix3d7z,37,37,0|ix3d80,38,40,1|j7w6fz,38,40,1|j7w6g0,37,37,0|jeqjvz,37,37,0|jeqjw0,38,40,1|jqz7rz,38,40,1|jqz7s0,37,37,0|jxgmjz,37,37,0|jxgmk0,38,40,1|k9pafz,38,40,1|k9pag0,37,37,0|kg6p7z,37,37,0|kg6p80,38,40,1|ksfd3z,38,40,1|ksfd40,37,37,0|kz9qjz,37,37,0|kz9qk0,38,40,1|lbiefz,38,40,1|lbieg0,37,37,0|lhzt7z,37,37,0|lhzt80,38,40,1|lu8h3z,38,40,1|lu8h40,37,37,0|m0pvvz,37,37,0|m0pvw0,38,40,1|mcyjrz,38,40,1|mcyjs0,37,37,0|mjfyjz,37,37,0|mjfyk0,38,40,1|mvomfz,38,40,1|mvomg0,37,37,0|n2617z,37,37,0|n26180,38,40,1|neep3z,38,40,1|neep40,37,37,0|nkw3vz,37,37,0|nkw3w0,38,40,1|nx4rrz,38,40,1|nx4rs0,37,37,0|o3z57z,37,37,0|o3z580,38,40,1|og7t3z,38,40,1|og7t40,37,37,0|omp7vz,37,37,0|omp7w0,38,40,1|oyxvrz,38,40,1|oyxvs0,37,37,0|p5fajz,37,37,0|p5fak0,38,40,1|phnyfz,38,40,1|phnyg0,37,37,0|po5d7z,37,37,0|po5d80,38,40,1|q0e13z,38,40,1|q0e140,37,37,0|q6vfvz,37,37,0|q6vfw0,38,40,1|qj43rz,38,40,1|qj43s0,37,37,0|qpyh7z,37,37,0|qpyh80,38,40,1|r2753z,38,40,1|r27540,37,37,0|r8ojvz,37,37,0|r8ojw0,38,40,1|rkx7rz,38,40,1|rkx7s0,37,37,0|rremjz,37,37,0|rremk0,38,40,1|s3nafz,38,40,1|s3nag0,37,37,0|sa4p7z,37,37,0|sa4p80,38,40,1|smdd3z,38,40,1|smdd40,37,37,0|ssurvz,37,37,0|ssurw0,38,40,1|t53frz,38,40,1|t53fs0,37,37,0|tbkujz,37,37,0|tbkuk0,38,40,1|tntifz,38,40,1|tntig0,37,37,0|tunvvz,37,37,0|tunvw0,38,40,1|u6wjrz,38,40,1|u6wjs0,37,37,0|uddyjz,37,37,0|uddyk0,38,40,1|upmmfz,38,40,1|upmmg0,37,37,0|uw417z,37,37,0|uw4180,38,40,1|v8cp3z,38,40,1|v8cp40,37,37,0|veu3vz,37,37,0|veu3w0,38,40,1|vr2rrz,38,40,1|vr2rs0,37,37,0|vxk6jz,37,37,0|vxk6k0,38,40,1|w9sufz,38,40,1|w9sug0,37,37,0|wgn7vz,37,37,0|wgn7w0,38,40,1|wsvvrz,38,40,1|wsvvs0,37,37,0|wzdajz,37,37,0|wzdak0,38,40,1|xblyfz,38,40,1|xblyg0,37,37,0|xi3d7z,37,37,0|xi3d80,38,40,1|xuc13z,38,40,1|xuc140,37,37,0|y0tfvz,37,37,0|y0tfw0,38,40,1|yd23rz,38,40,1|yd23s0,37,37,0|yjjijz,37,37,0|yjjik0,38,40,1|yvs6fz,38,40,1|yvs6g0,37,37,0|z29l7z,37,37,0|z29l80,38,40,1|zei93z,38,40,1|zei940,37,37,0\",\"America/Yellowknife|,60,1,0|-i9m2o0,50,66,0|-ek1z01,50,66,0|-ek1z00,58,62,1|-cq2tg1,58,62,1|-cq2tg0,59,62,1|-cnoxs1,59,62,1|-cnoxs0,50,66,0|-2g1tw1,50,66,0|-2g1tw0,61,63,1|-26btw1,61,63,1|-26btw0,50,66,0|5dwbnz,50,66,0|5dwbo0,52,62,1|5n9a7z,52,62,1|5n9a80,50,66,0|5wmebz,50,66,0|5wmec0,52,62,1|65zcvz,52,62,1|65zcw0,50,66,0|6fcgzz,50,66,0|6fch00,52,62,1|6p2e7z,52,62,1|6p2e80,50,66,0|6y2jnz,50,66,0|6y2jo0,52,62,1|77sgvz,52,62,1|77sgw0,50,66,0|7h5kzz,50,66,0|7h5l00,52,62,1|7qijjz,52,62,1|7qijk0,50,66,0|7zvnnz,50,66,0|7zvno0,52,62,1|898m7z,52,62,1|898m80,50,66,0|8ilqbz,50,66,0|8ilqc0,52,62,1|8ryovz,52,62,1|8ryow0,50,66,0|908wzz,50,66,0|908x00,52,62,1|9aorjz,52,62,1|9aork0,50,66,0|9iyznz,50,66,0|9iyzo0,52,62,1|9trsvz,52,62,1|9trsw0,50,66,0|a1p2bz,50,66,0|a1p2c0,52,62,1|achvjz,52,62,1|achvk0,50,66,0|akf4zz,50,66,0|akf500,52,62,1|av7y7z,52,62,1|av7y80,50,66,0|b3i6bz,50,66,0|b3i6c0,52,62,1|bdy0vz,52,62,1|bdy0w0,50,66,0|bm88zz,50,66,0|bm8900,52,62,1|bwo3jz,52,62,1|bwo3k0,50,66,0|c4ybnz,50,66,0|c4ybo0,52,62,1|cfr4vz,52,62,1|cfr4w0,50,66,0|cnoebz,50,66,0|cnoec0,52,62,1|cyh7jz,52,62,1|cyh7k0,50,66,0|d6egzz,50,66,0|d6eh00,52,62,1|dh7a7z,52,62,1|dh7a80,50,66,0|dphibz,50,66,0|dphic0,52,62,1|dzxcvz,52,62,1|dzxcw0,50,66,0|e87kzz,50,66,0|e87l00,52,62,1|einfjz,52,62,1|einfk0,50,66,0|eqxnnz,50,66,0|eqxno0,52,62,1|f1di7z,52,62,1|f1di80,50,66,0|f9nqbz,50,66,0|f9nqc0,52,62,1|fkgjjz,52,62,1|fkgjk0,50,66,0|fsdszz,50,66,0|fsdt00,52,62,1|g36m7z,52,62,1|g36m80,50,66,0|gb3vnz,50,66,0|gb3vo0,52,62,1|glwovz,52,62,1|glwow0,50,66,0|gu6wzz,50,66,0|gu6x00,52,62,1|h4mrjz,52,62,1|h4mrk0,50,66,0|hcwznz,50,66,0|hcwzo0,52,62,1|hncu7z,52,62,1|hncu80,50,66,0|hvn2bz,50,66,0|hvn2c0,52,62,1|i6fvjz,52,62,1|i6fvk0,50,66,0|ied4zz,50,66,0|ied500,52,62,1|ip5y7z,52,62,1|ip5y80,50,66,0|ix37nz,50,66,0|ix37o0,52,62,1|j7w0vz,52,62,1|j7w0w0,50,66,0|jeqebz,50,66,0|jeqec0,52,62,1|jqz27z,52,62,1|jqz280,50,66,0|jxggzz,50,66,0|jxgh00,52,62,1|k9p4vz,52,62,1|k9p4w0,50,66,0|kg6jnz,50,66,0|kg6jo0,52,62,1|ksf7jz,52,62,1|ksf7k0,50,66,0|kz9kzz,50,66,0|kz9l00,52,62,1|lbi8vz,52,62,1|lbi8w0,50,66,0|lhznnz,50,66,0|lhzno0,52,62,1|lu8bjz,52,62,1|lu8bk0,50,66,0|m0pqbz,50,66,0|m0pqc0,52,62,1|mcye7z,52,62,1|mcye80,50,66,0|mjfszz,50,66,0|mjft00,52,62,1|mvogvz,52,62,1|mvogw0,50,66,0|n25vnz,50,66,0|n25vo0,52,62,1|neejjz,52,62,1|neejk0,50,66,0|nkvybz,50,66,0|nkvyc0,52,62,1|nx4m7z,52,62,1|nx4m80,50,66,0|o3yznz,50,66,0|o3yzo0,52,62,1|og7njz,52,62,1|og7nk0,50,66,0|omp2bz,50,66,0|omp2c0,52,62,1|oyxq7z,52,62,1|oyxq80,50,66,0|p5f4zz,50,66,0|p5f500,52,62,1|phnsvz,52,62,1|phnsw0,50,66,0|po57nz,50,66,0|po57o0,52,62,1|q0dvjz,52,62,1|q0dvk0,50,66,0|q6vabz,50,66,0|q6vac0,52,62,1|qj3y7z,52,62,1|qj3y80,50,66,0|qpybnz,50,66,0|qpybo0,52,62,1|r26zjz,52,62,1|r26zk0,50,66,0|r8oebz,50,66,0|r8oec0,52,62,1|rkx27z,52,62,1|rkx280,50,66,0|rregzz,50,66,0|rreh00,52,62,1|s3n4vz,52,62,1|s3n4w0,50,66,0|sa4jnz,50,66,0|sa4jo0,52,62,1|smd7jz,52,62,1|smd7k0,50,66,0|ssumbz,50,66,0|ssumc0,52,62,1|t53a7z,52,62,1|t53a80,50,66,0|tbkozz,50,66,0|tbkp00,52,62,1|tntcvz,52,62,1|tntcw0,50,66,0|tunqbz,50,66,0|tunqc0,52,62,1|u6we7z,52,62,1|u6we80,50,66,0|uddszz,50,66,0|uddt00,52,62,1|upmgvz,52,62,1|upmgw0,50,66,0|uw3vnz,50,66,0|uw3vo0,52,62,1|v8cjjz,52,62,1|v8cjk0,50,66,0|vetybz,50,66,0|vetyc0,52,62,1|vr2m7z,52,62,1|vr2m80,50,66,0|vxk0zz,50,66,0|vxk100,52,62,1|w9sovz,52,62,1|w9sow0,50,66,0|wgn2bz,50,66,0|wgn2c0,52,62,1|wsvq7z,52,62,1|wsvq80,50,66,0|wzd4zz,50,66,0|wzd500,52,62,1|xblsvz,52,62,1|xblsw0,50,66,0|xi37nz,50,66,0|xi37o0,52,62,1|xubvjz,52,62,1|xubvk0,50,66,0|y0tabz,50,66,0|y0tac0,52,62,1|yd1y7z,52,62,1|yd1y80,50,66,0|yjjczz,50,66,0|yjjd00,52,62,1|yvs0vz,52,62,1|yvs0w0,50,66,0|z29fnz,50,66,0|z29fo0,52,62,1|zei3jz,52,62,1|zei3k0,50,66,0\",\"Antarctica/Casey|,60,1,0|-irxc0,89,191,0|kro7bz,89,191,0|kro7c0,90,192,0|kyrizz,90,192,0|kyrj00,89,191,0|ltqknz,89,191,0|ltqko0,90,192,0|lzr5vz,90,192,0|lzr5w0,89,191,0|ofen3z,89,191,0|ofen40,90,192,0|p5dwjz,90,192,0|p5dwk0,89,191,0|pg70vz,89,191,0|pg70w0,90,192,0|pogv3z,90,192,0|pogv40,89,191,0|pytbfz,89,191,0|pytbg0,90,192,0|q6tz3z,90,192,0|q6tz40,89,191,0|qhmv5n,89,191,0|qhmv5o,90,192,0\",\"Antarctica/Davis|,60,1,0|-6rmdc0,91,193,0|-2p2zg1,91,193,0|-2p2zg0,60,1,0|-h6io1,60,1,0|-h6io0,91,193,0|kroa3z,91,193,0|kroa40,92,194,0|kz30vz,92,194,0|kz30w0,91,193,0|ltqnfz,91,193,0|ltqng0,92,194,0|lzre7z,92,194,0|lzre80,91,193,0\",\"Antarctica/DumontDUrville|,60,1,0|-c05eo0,93,195,0|-9dkmg1,93,195,0|-9dkmg0,60,1,0|-6vdk01,60,1,0|-6vdk00,93,195,0\",\"Antarctica/Macquarie|,60,1,0|-10mb9c0,94,195,0|-rsj4w1,94,195,0|-rsj4w0,95,192,1|-rjj281,95,192,1|-rjj280,94,195,0|-qhmeg1,94,195,0|-qhmeg0,60,1,0|-bd1xc1,60,1,0|-bd1xc0,94,195,0|-16cow1,94,195,0|-16cow0,95,192,1|-wznk1,95,192,1|-wznk0,94,195,0|-m6rk1,94,195,0|-m6rk0,95,192,1|-fcgw1,95,192,1|-fcgw0,94,195,0|-3gow1,94,195,0|-3gow0,95,192,1|3dlrz,95,192,1|3dls0,94,195,0|f9drz,94,195,0|f9ds0,95,192,1|mgn3z,95,192,1|mgn40,94,195,0|ycf3z,94,195,0|ycf40,95,192,1|14gsfz,95,192,1|14gsg0,94,195,0|1h2hrz,94,195,0|1h2hs0,95,192,1|1njtrz,95,192,1|1njts0,94,195,0|1zskfz,94,195,0|1zskg0,95,192,1|269wfz,95,192,1|269wg0,94,195,0|2iin3z,94,195,0|2iin40,95,192,1|2ozz3z,95,192,1|2ozz40,94,195,0|318prz,94,195,0|318ps0,95,192,1|3830fz,95,192,1|3830g0,94,195,0|3kbr3z,94,195,0|3kbr40,95,192,1|3qt33z,95,192,1|3qt340,94,195,0|431trz,94,195,0|431ts0,95,192,1|49j5rz,95,192,1|49j5s0,94,195,0|4lrwfz,94,195,0|4lrwg0,95,192,1|4s98fz,95,192,1|4s98g0,94,195,0|54hz3z,94,195,0|54hz40,95,192,1|5azb3z,95,192,1|5azb40,94,195,0|5n81rz,94,195,0|5n81s0,95,192,1|5tpdrz,95,192,1|5tpds0,94,195,0|65y4fz,94,195,0|65y4g0,95,192,1|6dvb3z,95,192,1|6dvb40,94,195,0|6p15rz,94,195,0|6p15s0,95,192,1|6wldrz,95,192,1|6wlds0,94,195,0|77r8fz,94,195,0|77r8g0,95,192,1|7e8kfz,95,192,1|7e8kg0,94,195,0|7qhb3z,94,195,0|7qhb40,95,192,1|7wyn3z,95,192,1|7wyn40,94,195,0|897drz,94,195,0|897ds0,95,192,1|8foprz,95,192,1|8fops0,94,195,0|8rkhrz,94,195,0|8rkhs0,95,192,1|8z4prz,95,192,1|8z4ps0,94,195,0|9anj3z,94,195,0|9anj40,95,192,1|9i7r3z,95,192,1|9i7r40,94,195,0|9tqkfz,94,195,0|9tqkg0,95,192,1|a0xtrz,95,192,1|a0xts0,94,195,0|acgn3z,94,195,0|acgn40,95,192,1|ajnwfz,95,192,1|ajnwg0,94,195,0|av6prz,94,195,0|av6ps0,95,192,1|b33wfz,95,192,1|b33wg0,94,195,0|bctwfz,94,195,0|bctwg0,95,192,1|bltz3z,95,192,1|bltz40,94,195,0|bvjz3z,94,195,0|bvjz40,95,192,1|c4k1rz,95,192,1|c4k1s0,94,195,0|cea1rz,94,195,0|cea1s0,95,192,1|cna4fz,95,192,1|cna4g0,94,195,0|cx04fz,94,195,0|cx04g0,95,192,1|d6073z,95,192,1|d60740,94,195,0|dfq73z,94,195,0|dfq740,95,192,1|dp38fz,95,192,1|dp38g0,94,195,0|dyt8fz,94,195,0|dyt8g0,95,192,1|e7tb3z,95,192,1|e7tb40,94,195,0|ehjb3z,94,195,0|ehjb40,95,192,1|eqjdrz,95,192,1|eqjds0,94,195,0|f09drz,94,195,0|f09ds0,95,192,1|f99gfz,95,192,1|f99gg0,94,195,0|fizgfz,94,195,0|fizgg0,95,192,1|frzj3z,95,192,1|frzj40,94,195,0|fzwprz,94,195,0|fzwps0,95,192,1|gaplrz,95,192,1|gapls0,94,195,0|gkskfz,94,195,0|gkskg0,95,192,1|gtsn3z,95,192,1|gtsn40,94,195,0|h3in3z,94,195,0|h3in40,95,192,1|hciprz,95,192,1|hcips0,94,195,0|hm8prz,94,195,0|hm8ps0,95,192,1|hv8sfz,95,192,1|hv8sg0,94,195,0|i4ysfz,94,195,0|i4ysg0,95,192,1|idyv3z,95,192,1|idyv40,94,195,0|inov3z,94,195,0|inov40,95,192,1|ix1wfz,95,192,1|ix1wg0,94,195,0|j6exrz,94,195,0|j6exs0,95,192,1|jff0fz,95,192,1|jff0g0,94,195,0|jphz3z,94,195,0|jphz40,95,192,1|jyv0fz,95,192,1|jyv0g0,94,195,0|k881rz,94,195,0|k881s0,95,192,1|khl33z,95,192,1|khl340,94,195,0|kqy4fz,94,195,0|kqy4g0,95,192,1|lj18fz,95,192,1|lj18g0,94,195,0|lse9rz,94,195,0|lse9s0,95,192,1|m1rb3z,95,192,1|m1rb40,94,195,0|mbhb3z,94,195,0|mbhb40,95,192,1|mkucfz,95,192,1|mkucg0,94,195,0|mu7drz,94,195,0|mu7ds0,95,192,1|n3kf3z,95,192,1|n3kf40,94,195,0|ncxgfz,94,195,0|ncxgg0,95,192,1|nmahrz,95,192,1|nmahs0,94,195,0|nvnj3z,94,195,0|nvnj40,95,192,1|o50kfz,95,192,1|o50kg0,94,195,0|oedlrz,94,195,0|oedls0,95,192,1|onqn3z,95,192,1|onqn40,94,195,0|ox3ofz,94,195,0|ox3og0,95,192,1|p6gprz,95,192,1|p6gps0,94,195,0|pg6prz,94,195,0|pg6ps0,95,192,1|ppjr3z,95,192,1|ppjr40,94,195,0|pywsfz,94,195,0|pywsg0,95,192,1|q89trz,95,192,1|q89ts0,94,195,0|qhmv3z,94,195,0|qhmv40,95,192,1|qqzwfz,95,192,1|qqzwg0,94,195,0|r0cxrz,94,195,0|r0cxs0,95,192,1|r9pz3z,95,192,1|r9pz40,94,195,0|rj30fz,94,195,0|rj30g0,95,192,1|rsg1rz,95,192,1|rsg1s0,94,195,0|s1t33z,94,195,0|s1t340,95,192,1|sbj33z,95,192,1|sbj340,94,195,0|skw4fz,94,195,0|skw4g0,95,192,1|su95rz,95,192,1|su95s0,94,195,0|t3m73z,94,195,0|t3m740,95,192,1|tcz8fz,95,192,1|tcz8g0,94,195,0|tmc9rz,94,195,0|tmc9s0,95,192,1|tvpb3z,95,192,1|tvpb40,94,195,0|u52cfz,94,195,0|u52cg0,95,192,1|uefdrz,95,192,1|uefds0,94,195,0|unsf3z,94,195,0|unsf40,95,192,1|ux5gfz,95,192,1|ux5gg0,94,195,0|v6vgfz,94,195,0|v6vgg0,95,192,1|vg8hrz,95,192,1|vg8hs0,94,195,0|vplj3z,94,195,0|vplj40,95,192,1|vyykfz,95,192,1|vyykg0,94,195,0|w8blrz,94,195,0|w8bls0,95,192,1|whon3z,95,192,1|whon40,94,195,0|wr1ofz,94,195,0|wr1og0,95,192,1|x0eprz,95,192,1|x0eps0,94,195,0|x9rr3z,94,195,0|x9rr40,95,192,1|xj4sfz,95,192,1|xj4sg0,94,195,0|xshtrz,94,195,0|xshts0,95,192,1|y1uv3z,95,192,1|y1uv40,94,195,0|ybkv3z,94,195,0|ybkv40,95,192,1|ykxwfz,95,192,1|ykxwg0,94,195,0|yuaxrz,94,195,0|yuaxs0,95,192,1|z3nz3z,95,192,1|z3nz40,94,195,0|zd10fz,94,195,0|zd10g0,95,192,1\",\"Antarctica/Mawson|,60,1,0|-8aelc0,96,196,0|krocvz,96,196,0|krocw0,92,194,0\",\"Antarctica/McMurdo|,0,197,0|-1gsoz14,97,198,0|-m01p21,97,198,0|-m01p20,98,199,1|-ltxei1,98,199,1|-ltxei0,97,198,0|-lieie1,97,198,0|-lieie0,98,200,1|-lahd41,98,200,1|-lahd40,97,198,0|-kzofq1,97,198,0|-kzofq0,98,200,1|-krrag1,98,200,1|-krrag0,97,198,0|-kgyd21,97,198,0|-kgyd20,98,200,1|-k917s1,98,200,1|-k917s0,97,198,0|-jy8ae1,97,198,0|-jy8ae0,98,200,1|-jpy6g1,98,200,1|-jpy6g0,97,198,0|-jfi7q1,97,198,0|-jfi7q0,98,200,1|-j783s1,98,200,1|-j783s0,97,198,0|-iws521,97,198,0|-iws520,98,200,1|-imc941,98,200,1|-imc940,97,198,0|-ief121,97,198,0|-ief120,98,200,1|-i3m6g1,98,200,1|-i3m6g0,97,198,0|-hvoye1,97,198,0|-hvoye0,98,200,1|-hkw3s1,98,200,1|-hkw3s0,97,198,0|-hcyvq1,97,198,0|-hcyvq0,98,200,1|-h26141,98,200,1|-h26140,97,198,0|-gu8t21,97,198,0|-gu8t20,98,200,1|-gjfyg1,98,200,1|-gjfyg0,97,198,0|-gbiqe1,97,198,0|-gbiqe0,98,200,1|-g0cx41,98,200,1|-g0cx40,97,198,0|-fssnq1,97,198,0|-fssnq0,98,200,1|-fhmug1,98,200,1|-fhmug0,97,198,0|-f9pme1,97,198,0|-f9pme0,98,200,1|-ciy9c1,98,200,1|-ciy9c0,98,200,0|2ivg7z,98,200,0|2ivg80,99,201,1|2omuvz,99,201,1|2omuw0,98,200,0|318k7z,98,200,0|318k80,99,201,1|382uvz,99,201,1|382uw0,98,200,0|3kbljz,98,200,0|3kblk0,99,201,1|3qsxjz,99,201,1|3qsxk0,98,200,0|431o7z,98,200,0|431o80,99,201,1|49j07z,99,201,1|49j080,98,200,0|4lrqvz,98,200,0|4lrqw0,99,201,1|4s92vz,99,201,1|4s92w0,98,200,0|54htjz,98,200,0|54htk0,99,201,1|5az5jz,99,201,1|5az5k0,98,200,0|5n7w7z,98,200,0|5n7w80,99,201,1|5tp87z,99,201,1|5tp880,98,200,0|65xyvz,98,200,0|65xyw0,99,201,1|6cs9jz,99,201,1|6cs9k0,98,200,0|6p107z,98,200,0|6p1080,99,201,1|6vic7z,99,201,1|6vic80,98,200,0|77r2vz,98,200,0|77r2w0,99,201,1|7e8evz,99,201,1|7e8ew0,98,200,0|7qh5jz,98,200,0|7qh5k0,99,201,1|7wyhjz,99,201,1|7wyhk0,98,200,0|89787z,98,200,0|897880,99,201,1|8fok7z,99,201,1|8fok80,98,200,0|8rxavz,98,200,0|8rxaw0,99,201,1|8yemvz,99,201,1|8yemw0,98,200,0|9andjz,98,200,0|9andk0,99,201,1|9hho7z,99,201,1|9hho80,98,200,0|9tqevz,98,200,0|9tqew0,99,201,1|a07qvz,99,201,1|a07qw0,98,200,0|abdljz,98,200,0|abdlk0,99,201,1|ajnqvz,99,201,1|ajnqw0,98,200,0|au3o7z,98,200,0|au3o80,99,201,1|b2dtjz,99,201,1|b2dtk0,98,200,0|bctqvz,98,200,0|bctqw0,99,201,1|bl3w7z,99,201,1|bl3w80,98,200,0|bvjtjz,98,200,0|bvjtk0,99,201,1|c46xjz,99,201,1|c46xk0,98,200,0|ce9w7z,98,200,0|ce9w80,99,201,1|cmx07z,99,201,1|cmx080,98,200,0|cwzyvz,98,200,0|cwzyw0,99,201,1|d5n2vz,99,201,1|d5n2w0,98,200,0|dfq1jz,98,200,0|dfq1k0,99,201,1|dod5jz,99,201,1|dod5k0,98,200,0|dyt2vz,98,200,0|dyt2w0,99,201,1|e7387z,99,201,1|e73880,98,200,0|ehj5jz,98,200,0|ehj5k0,99,201,1|eptavz,99,201,1|eptaw0,98,200,0|f0987z,98,200,0|f09880,99,201,1|f8wc7z,99,201,1|f8wc80,98,200,0|fizavz,98,200,0|fizaw0,99,201,1|frmevz,99,201,1|frmew0,98,200,0|g1pdjz,98,200,0|g1pdk0,99,201,1|gachjz,99,201,1|gachk0,98,200,0|gksevz,98,200,0|gksew0,99,201,1|gt2k7z,99,201,1|gt2k80,98,200,0|h3ihjz,98,200,0|h3ihk0,99,201,1|hbsmvz,99,201,1|hbsmw0,98,200,0|hm8k7z,98,200,0|hm8k80,99,201,1|huvo7z,99,201,1|huvo80,98,200,0|i4ymvz,98,200,0|i4ymw0,99,201,1|idlqvz,99,201,1|idlqw0,98,200,0|inopjz,98,200,0|inopk0,99,201,1|iwbtjz,99,201,1|iwbtk0,98,200,0|j6es7z,98,200,0|j6es80,99,201,1|jf1w7z,99,201,1|jf1w80,98,200,0|jp4uvz,98,200,0|jp4uw0,99,201,1|jyuuvz,99,201,1|jyuuw0,98,200,0|k7uxjz,98,200,0|k7uxk0,99,201,1|khkxjz,99,201,1|khkxk0,98,200,0|kql07z,98,200,0|kql080,99,201,1|l0b07z,99,201,1|l0b080,98,200,0|l9b2vz,98,200,0|l9b2w0,99,201,1|lj12vz,99,201,1|lj12w0,98,200,0|ls15jz,98,200,0|ls15k0,99,201,1|m1r5jz,99,201,1|m1r5k0,98,200,0|mb46vz,98,200,0|mb46w0,99,201,1|mku6vz,99,201,1|mku6w0,98,200,0|mtu9jz,98,200,0|mtu9k0,99,201,1|n3k9jz,99,201,1|n3k9k0,98,200,0|nckc7z,98,200,0|nckc80,99,201,1|nmac7z,99,201,1|nmac80,98,200,0|nvaevz,98,200,0|nvaew0,99,201,1|o50evz,99,201,1|o50ew0,98,200,0|oe0hjz,98,200,0|oe0hk0,99,201,1|onqhjz,99,201,1|onqhk0,98,200,0|owqk7z,98,200,0|owqk80,99,201,1|p6gk7z,99,201,1|p6gk80,98,200,0|pftljz,98,200,0|pftlk0,99,201,1|ppjljz,99,201,1|ppjlk0,98,200,0|pyjo7z,98,200,0|pyjo80,99,201,1|q89o7z,99,201,1|q89o80,98,200,0|qh9qvz,98,200,0|qh9qw0,99,201,1|qqzqvz,99,201,1|qqzqw0,98,200,0|qzztjz,98,200,0|qzztk0,99,201,1|r9ptjz,99,201,1|r9ptk0,98,200,0|ripw7z,98,200,0|ripw80,99,201,1|rsfw7z,99,201,1|rsfw80,98,200,0|s1fyvz,98,200,0|s1fyw0,99,201,1|sbixjz,99,201,1|sbixk0,98,200,0|skj07z,98,200,0|skj080,99,201,1|su907z,99,201,1|su9080,98,200,0|t392vz,98,200,0|t392w0,99,201,1|tcz2vz,99,201,1|tcz2w0,98,200,0|tlz5jz,98,200,0|tlz5k0,99,201,1|tvp5jz,99,201,1|tvp5k0,98,200,0|u4p87z,98,200,0|u4p880,99,201,1|uef87z,99,201,1|uef880,98,200,0|unfavz,98,200,0|unfaw0,99,201,1|ux5avz,99,201,1|ux5aw0,98,200,0|v6ic7z,98,200,0|v6ic80,99,201,1|vg8c7z,99,201,1|vg8c80,98,200,0|vp8evz,98,200,0|vp8ew0,99,201,1|vyyevz,99,201,1|vyyew0,98,200,0|w7yhjz,98,200,0|w7yhk0,99,201,1|whohjz,99,201,1|whohk0,98,200,0|wqok7z,98,200,0|wqok80,99,201,1|x0ek7z,99,201,1|x0ek80,98,200,0|x9emvz,98,200,0|x9emw0,99,201,1|xj4mvz,99,201,1|xj4mw0,98,200,0|xs4pjz,98,200,0|xs4pk0,99,201,1|y1upjz,99,201,1|y1upk0,98,200,0|yb7qvz,98,200,0|yb7qw0,99,201,1|ykxqvz,99,201,1|ykxqw0,98,200,0|ytxtjz,98,200,0|ytxtk0,99,201,1|z3ntjz,99,201,1|z3ntk0,98,200,0|zcnw7z,98,200,0|zcnw80,99,201,1\",\"Antarctica/Palmer|,60,1,0|-2lxhc0,39,44,1|-2ivzo1,39,44,1|-2ivzo0,42,42,0|-275ow1,42,42,0|-275ow0,39,44,1|-2042c1,39,44,1|-2042c0,42,42,0|-1odrk1,42,42,0|-1odrk0,39,44,1|-1fovo1,39,44,1|-1fovo0,42,42,0|-16brk1,42,42,0|-16brk0,39,44,1|-wluc1,39,44,1|-wluc0,42,42,0|-n8q81,42,42,0|-n8q80,39,44,1|-dvro1,39,44,1|-dvro0,42,42,0|-4ink1,42,42,0|-4ink0,39,44,0|24aizz,39,44,0|24aj00,40,45,1|29bxjz,40,45,1|29bxk0,39,44,0|6fn4bz,39,44,0|6fn4c0,42,42,0|6nz73z,42,42,0|6nz740,39,44,1|6vwazz,39,44,1|6vwb00,42,42,0|76p9rz,42,42,0|76p9s0,39,44,1|7emdnz,39,44,1|7emdo0,42,42,0|7psb3z,42,42,0|7psb40,39,44,1|7xcgbz,39,44,1|7xcgc0,42,42,0|88idrz,42,42,0|88ids0,39,44,1|8g2izz,39,44,1|8g2j00,42,42,0|8r8gfz,42,42,0|8r8gg0,39,44,1|90lezz,39,44,1|90lf00,42,42,0|99yj3z,42,42,0|99yj40,39,44,1|9hvmzz,39,44,1|9hvn00,42,42,0|9solrz,42,42,0|9sols0,39,44,1|a0lpnz,39,44,1|a0lpo0,42,42,0|abrn3z,42,42,0|abrn40,39,44,1|ajbsbz,39,44,1|ajbsc0,42,42,0|at1v3z,42,42,0|at1v40,39,44,1|b21uzz,39,44,1|b21v00,42,42,0|bd7sfz,42,42,0|bd7sg0,39,44,1|bl4wbz,39,44,1|bl4wc0,42,42,0|bvxv3z,42,42,0|bvxv40,39,44,1|c3uyzz,39,44,1|c3uz00,42,42,0|cenxrz,42,42,0|cenxs0,39,44,1|cml1nz,39,44,1|cml1o0,42,42,0|cxe0fz,42,42,0|cxe0g0,39,44,1|d5b4bz,39,44,1|d5b4c0,42,42,0|dgh1rz,42,42,0|dgh1s0,39,44,1|do16zz,39,44,1|do1700,42,42,0|dz74fz,42,42,0|dz74g0,39,44,1|e7u5nz,39,44,1|e7u5o0,42,42,0|ehx73z,42,42,0|ehx740,39,44,1|epuazz,39,44,1|epub00,42,42,0|ezxcfz,42,42,0|ezxcg0,39,44,1|f9n9nz,39,44,1|f9n9o0,42,42,0|fjdcfz,42,42,0|fjdcg0,39,44,1|fragbz,39,44,1|fragc0,42,42,0|g2gdrz,42,42,0|g2gds0,39,44,1|ga0izz,39,44,1|ga0j00,42,42,0|gl6gfz,42,42,0|gl6gg0,39,44,1|gsqlnz,39,44,1|gsqlo0,42,42,0|h3wj3z,42,42,0|h3wj40,39,44,1|hbgobz,39,44,1|hbgoc0,42,42,0|hmmlrz,42,42,0|hmmls0,39,44,1|hujpnz,39,44,1|hujpo0,42,42,0|i5cofz,42,42,0|i5cog0,39,44,1|id9sbz,39,44,1|id9sc0,42,42,0|io2r3z,42,42,0|io2r40,39,44,1|ivzuzz,39,44,1|ivzv00,42,42,0|j75sfz,42,42,0|j75sg0,39,44,1|jepxnz,39,44,1|jepxo0,42,42,0|jpvv3z,42,42,0|jpvv40,39,44,1|jyiwbz,39,44,1|jyiwc0,42,42,0|k8lxrz,42,42,0|k8lxs0,39,44,1|kgj1nz,39,44,1|kgj1o0,42,42,0|krc0fz,42,42,0|krc0g0,39,44,1|l0c0bz,39,44,1|l0c0c0,42,42,0|la233z,42,42,0|la2340,39,44,1|lkuwbz,39,44,1|lkuwc0,42,42,0|lq9f3z,42,42,0|lq9f40,39,44,1|m380bz,39,44,1|m380c0,42,42,0|m9pf3z,42,42,0|m9pf40,39,44,1|mly2zz,39,44,1|mly300,42,42,0|mssgfz,42,42,0|mssgg0,39,44,1|n4o5nz,39,44,1|n4o5o0,42,42,0|nbij3z,42,42,0|nbij40,39,44,1|o776zz,39,44,1|o77700,42,42,0|obvsfz,42,42,0|obvsg0,39,44,1|ohn4bz,39,44,1|ohn4c0,39,44,0\",\"Antarctica/Rothera|,60,1,0|3lxs00,39,44,0\",\"Antarctica/Syowa|,60,1,0|-6qsqo0,100,6,0\",\"Antarctica/Troll|,60,1,0|ibruo0,17,1,0|idzk3z,17,1,0|idzk40,101,11,1|ip5erz,101,11,1|ip5es0,17,1,0|iwpmrz,17,1,0|iwpms0,101,11,1|j7vhfz,101,11,1|j7vhg0,17,1,0|jffpfz,17,1,0|jffpg0,101,11,1|jqlk3z,101,11,1|jqlk40,17,1,0|jyiqrz,17,1,0|jyiqs0,101,11,1|k9bmrz,101,11,1|k9bms0,17,1,0|kh8tfz,17,1,0|kh8tg0,101,11,1|ks1pfz,101,11,1|ks1pg0,17,1,0|kzyw3z,17,1,0|kzyw40,101,11,1|lb4qrz,101,11,1|lb4qs0,17,1,0|lioyrz,17,1,0|lioys0,101,11,1|ltutfz,101,11,1|ltutg0,17,1,0|m1f1fz,17,1,0|m1f1g0,101,11,1|mckw3z,101,11,1|mckw40,17,1,0|mki2rz,17,1,0|mki2s0,101,11,1|mvayrz,101,11,1|mvays0,17,1,0|n385fz,17,1,0|n385g0,101,11,1|ne11fz,101,11,1|ne11g0,17,1,0|nly83z,17,1,0|nly840,101,11,1|nwr43z,101,11,1|nwr440,17,1,0|o4oarz,17,1,0|o4oas0,101,11,1|ofu5fz,101,11,1|ofu5g0,17,1,0|onedfz,17,1,0|onedg0,101,11,1|oyk83z,101,11,1|oyk840,17,1,0|p64g3z,17,1,0|p64g40,101,11,1|phaarz,101,11,1|phaas0,17,1,0|pp7hfz,17,1,0|pp7hg0,101,11,1|q00dfz,101,11,1|q00dg0,17,1,0|q7xk3z,17,1,0|q7xk40,101,11,1|qiqg3z,101,11,1|qiqg40,17,1,0|qqnmrz,17,1,0|qqnms0,101,11,1|r1thfz,101,11,1|r1thg0,17,1,0|r9dpfz,17,1,0|r9dpg0,101,11,1|rkjk3z,101,11,1|rkjk40,17,1,0|rs3s3z,17,1,0|rs3s40,101,11,1|s39mrz,101,11,1|s39ms0,17,1,0|sb6tfz,17,1,0|sb6tg0,101,11,1|slzpfz,101,11,1|slzpg0,17,1,0|stww3z,17,1,0|stww40,101,11,1|t4ps3z,101,11,1|t4ps40,17,1,0|tcmyrz,17,1,0|tcmys0,101,11,1|tnfurz,101,11,1|tnfus0,17,1,0|tvd1fz,17,1,0|tvd1g0,101,11,1|u6iw3z,101,11,1|u6iw40,17,1,0|ue343z,17,1,0|ue3440,101,11,1|up8yrz,101,11,1|up8ys0,17,1,0|uwt6rz,17,1,0|uwt6s0,101,11,1|v7z1fz,101,11,1|v7z1g0,17,1,0|vfw83z,17,1,0|vfw840,101,11,1|vqp43z,101,11,1|vqp440,17,1,0|vymarz,17,1,0|vymas0,101,11,1|w9f6rz,101,11,1|w9f6s0,17,1,0|whcdfz,17,1,0|whcdg0,101,11,1|wsi83z,101,11,1|wsi840,17,1,0|x02g3z,17,1,0|x02g40,101,11,1|xb8arz,101,11,1|xb8as0,17,1,0|xisirz,17,1,0|xisis0,101,11,1|xtydfz,101,11,1|xtydg0,17,1,0|y1ilfz,17,1,0|y1ilg0,101,11,1|ycog3z,101,11,1|ycog40,17,1,0|yklmrz,17,1,0|yklms0,101,11,1|yveirz,101,11,1|yveis0,17,1,0|z3bpfz,17,1,0|z3bpg0,101,11,1|ze4lfz,101,11,1|ze4lg0,17,1,0\",\"Antarctica/Vostok|,60,1,0|-6aaao0,96,196,0\",\"Arctic/Longyearbyen|,0,202,0|-1353tzo,10,10,0|-rzayo1,10,10,0|-rzayo0,11,11,1|-rskiw1,11,11,1|-rskiw0,10,10,0|-fc7s81,10,10,0|-fc7s80,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d6dp81,11,11,1|-d6dp80,10,10,0|-cx0nw1,10,10,0|-cx0nw0,11,11,1|-cnnmk1,11,11,1|-cnnmk0,10,10,0|-5mxh81,10,10,0|-5mxh80,11,11,1|-5d7h81,11,11,1|-5d7h80,10,10,0|-53ufw1,10,10,0|-53ufw0,11,11,1|-4uhek1,11,11,1|-4uhek0,10,10,0|-4l4d81,10,10,0|-4l4d80,11,11,1|-4brbw1,11,11,1|-4brbw0,10,10,0|-42eak1,10,10,0|-42eak0,11,11,1|-3t1981,11,11,1|-3t1980,10,10,0|-3jo7w1,10,10,0|-3jo7w0,11,11,1|-3ab6k1,11,11,1|-3ab6k0,10,10,0|-30y581,10,10,0|-30y580,11,11,1|-2r8581,11,11,1|-2r8580,10,10,0|-2g2ak1,10,10,0|-2g2ak0,11,11,1|-28i2k1,11,11,1|-28i2k0,10,10,0|5cstfz,10,10,0|5cstg0,11,11,1|5lsw3z,11,11,1|5lsw40,10,10,0|5v5xfz,10,10,0|5v5xg0,11,11,1|64iyrz,11,11,1|64iys0,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Asia/Aden|,0,203,0|-bwgbbg,100,6,0\",\"Asia/Almaty|,0,204,0|-nu1a90,92,194,0|-kmr9w1,92,194,0|-kmr9w0,96,196,0|5vaxzz,96,196,0|5vay00,91,193,1|64pr7z,91,193,1|64pr80,96,196,0|6e2vbz,96,196,0|6e2vc0,91,193,1|6nhojz,91,193,1|6nhok0,96,196,0|6wusnz,96,196,0|6wuso0,91,193,1|769lvz,91,193,1|769lw0,96,196,0|7foknz,96,196,0|7foko0,91,193,1|7p1rjz,91,193,1|7p1rk0,96,196,0|7yesvz,96,196,0|7yesw0,91,193,1|87ru7z,91,193,1|87ru80,96,196,0|8h4vjz,96,196,0|8h4vk0,91,193,1|8qhwvz,91,193,1|8qhww0,96,196,0|8zuy7z,96,196,0|8zuy80,91,193,1|997zjz,91,193,1|997zk0,96,196,0|9il0vz,96,196,0|9il0w0,91,193,1|9ry27z,91,193,1|9ry280,96,196,0|a1b3jz,96,196,0|a1b3k0,91,193,1|aao4vz,91,193,1|aao4w0,96,196,0|ak167z,96,196,0|ak1680,91,193,1|atr67z,91,193,1|atr680,96,196,0|b347jz,96,196,0|b347k0,96,196,1|bchbnz,96,196,1|bchbo0,92,194,0|bi8qbz,92,194,0|bi8qc0,96,196,0|blua7z,96,196,0|blua80,91,193,1|bv7bjz,91,193,1|bv7bk0,96,196,0|c4kcvz,96,196,0|c4kcw0,91,193,1|cdxe7z,91,193,1|cdxe80,96,196,0|cnafjz,96,196,0|cnafk0,91,193,1|cwngvz,91,193,1|cwngw0,96,196,0|d60i7z,96,196,0|d60i80,91,193,1|dfdjjz,91,193,1|dfdjk0,96,196,0|dp3jjz,96,196,0|dp3jk0,91,193,1|dzwfjz,91,193,1|dzwfk0,96,196,0|e7tm7z,96,196,0|e7tm80,91,193,1|eimi7z,91,193,1|eimi80,96,196,0|eqjovz,96,196,0|eqjow0,91,193,1|f1ckvz,91,193,1|f1ckw0,96,196,0|f99rjz,96,196,0|f99rk0,91,193,1|fkfm7z,91,193,1|fkfm80,96,196,0|frzu7z,96,196,0|frzu80,91,193,1|g35ovz,91,193,1|g35ow0,96,196,0|gapwvz,96,196,0|gapww0,91,193,1|glvrjz,91,193,1|glvrk0,96,196,0|gtsy7z,96,196,0|gtsy80,91,193,1|h4lu7z,91,193,1|h4lu80,96,196,0|hcj0vz,96,196,0|hcj0w0,91,193,1|hnbwvz,91,193,1|hnbww0,96,196,0|hv93jz,96,196,0|hv93k0,91,193,1|i6ey7z,91,193,1|i6ey80,96,196,0\",\"Asia/Amman|,0,205,0|-kcrtbk,15,11,0|1sed3z,15,11,0|1sed40,16,6,1|1yeybz,16,6,1|1yeyc0,15,11,0|29bmfz,15,11,0|29bmg0,16,6,1|2h6vnz,16,6,1|2h6vo0,15,11,0|2s3jrz,15,11,0|2s3js0,16,6,1|2zyszz,16,6,1|2zyt00,15,11,0|3axbrz,15,11,0|3axbs0,16,6,1|3kdznz,16,6,1|3kdzo0,15,11,0|3tp93z,15,11,0|3tp940,16,6,1|41kibz,16,6,1|41kic0,15,11,0|4cfbrz,15,11,0|4cfbs0,16,6,1|4kakzz,16,6,1|4kal00,15,11,0|7ygt3z,15,11,0|7ygt40,16,6,1|87vmbz,16,6,1|87vmc0,15,11,0|8heafz,15,11,0|8heag0,16,6,1|8qr8zz,16,6,1|8qr900,15,11,0|904d3z,15,11,0|904d40,16,6,1|99hbnz,16,6,1|99hbo0,15,11,0|9iufrz,15,11,0|9iufs0,16,6,1|9skczz,16,6,1|9skd00,15,11,0|a3ivrz,15,11,0|a3ivs0,16,6,1|abafnz,16,6,1|abafo0,15,11,0|alqfrz,15,11,0|alqfs0,16,6,1|au0ibz,16,6,1|au0ic0,15,11,0|b3zufz,15,11,0|b3zug0,16,6,1|bcdmbz,16,6,1|bcdmc0,15,11,0|bmgnrz,15,11,0|bmgns0,16,6,1|bvgnnz,16,6,1|bvgno0,15,11,0|c4trrz,15,11,0|c4trs0,16,6,1|ce6qbz,16,6,1|ce6qc0,15,11,0|cnjufz,15,11,0|cnjug0,16,6,1|cw6vnz,16,6,1|cw6vo0,15,11,0|d6mvrz,15,11,0|d6mvs0,16,6,1|dex13z,16,6,1|dex140,15,11,0|dpcyfz,15,11,0|dpcyg0,16,6,1|dy02fz,16,6,1|dy02g0,15,11,0|e8313z,15,11,0|e83140,16,6,1|egq53z,16,6,1|egq540,15,11,0|eqt3rz,15,11,0|eqt3s0,16,6,1|ezg7rz,16,6,1|ezg7s0,15,11,0|fe5ufz,15,11,0|fe5ug0,16,6,1|fij93z,16,6,1|fij940,15,11,0|fs7efz,15,11,0|fs7eg0,16,6,1|g1mafz,16,6,1|g1mag0,15,11,0|gaxh3z,15,11,0|gaxh40,16,6,1|gkcd3z,16,6,1|gkcd40,15,11,0|gtpefz,15,11,0|gtpeg0,16,6,1|h32frz,16,6,1|h32fs0,15,11,0|hcfh3z,15,11,0|hcfh40,16,6,1|hn8d3z,16,6,1|hn8d40,15,11,0|hv5jrz,15,11,0|hv5js0,16,6,1|i5lh3z,16,6,1|i5lh40,15,11,0|ie8l3z,15,11,0|ie8l40,16,6,1|inlmfz,16,6,1|inlmg0,15,11,0|iwynrz,15,11,0|iwyns0,16,6,1|j7rjrz,16,6,1|j7rjs0,15,11,0|jfoqfz,15,11,0|jfoqg0,16,6,1|jqhmfz,16,6,1|jqhmg0,15,11,0|jyet3z,15,11,0|jyet40,16,6,1|k9knrz,16,6,1|k9kns0,15,11,0|kh4vrz,15,11,0|kh4vs0,16,6,1|ksaqfz,16,6,1|ksaqg0,15,11,0|kzuyfz,15,11,0|kzuyg0,16,6,1|lb0t3z,16,6,1|lb0t40,15,11,0|lixzrz,15,11,0|lixzs0,16,6,1|ltqvrz,16,6,1|ltqvs0,15,11,0|m1o2fz,15,11,0|m1o2g0,16,6,1|my2nnz,16,6,1|my2no0,15,11,0|n347rz,15,11,0|n347s0,16,6,1|nea2fz,16,6,1|nea2g0,15,11,0|nluafz,15,11,0|nluag0,16,6,1|nx053z,16,6,1|nx0540,15,11,0|o4xbrz,15,11,0|o4xbs0,16,6,1|ofq7rz,16,6,1|ofq7s0,15,11,0|onnefz,15,11,0|onneg0,16,6,1|oygafz,16,6,1|oygag0,15,11,0|p6dh3z,15,11,0|p6dh40,16,6,1|ph6d3z,16,6,1|ph6d40,15,11,0|pp3jrz,15,11,0|pp3js0,16,6,1|pzwfrz,16,6,1|pzwfs0,15,11,0|q7tmfz,15,11,0|q7tmg0,16,6,1|qizh3z,16,6,1|qizh40,15,11,0|qqjp3z,15,11,0|qqjp40,16,6,1|r1pjrz,16,6,1|r1pjs0,15,11,0|r9mqfz,15,11,0|r9mqg0,16,6,1|rkfmfz,16,6,1|rkfmg0,15,11,0|rsct3z,15,11,0|rsct40,16,6,1|s35p3z,16,6,1|s35p40,15,11,0|sb2vrz,15,11,0|sb2vs0,16,6,1|slvrrz,16,6,1|slvrs0,15,11,0|stsyfz,15,11,0|stsyg0,16,6,1|t4yt3z,16,6,1|t4yt40,15,11,0|tcj13z,15,11,0|tcj140,16,6,1|tnovrz,16,6,1|tnovs0,15,11,0|tv93rz,15,11,0|tv93s0,16,6,1|u6eyfz,16,6,1|u6eyg0,15,11,0|uec53z,15,11,0|uec540,16,6,1|up513z,16,6,1|up5140,15,11,0|ux27rz,15,11,0|ux27s0,16,6,1|v7v3rz,16,6,1|v7v3s0,15,11,0|vfsafz,15,11,0|vfsag0,16,6,1|vql6fz,16,6,1|vql6g0,15,11,0|vyid3z,15,11,0|vyid40,16,6,1|w9o7rz,16,6,1|w9o7s0,15,11,0|wh8frz,15,11,0|wh8fs0,16,6,1|wseafz,16,6,1|wseag0,15,11,0|x0bh3z,15,11,0|x0bh40,16,6,1|xb4d3z,16,6,1|xb4d40,15,11,0|xj1jrz,15,11,0|xj1js0,16,6,1|xtufrz,16,6,1|xtufs0,15,11,0|y1rmfz,15,11,0|y1rmg0,16,6,1|yckifz,16,6,1|yckig0,15,11,0|ykhp3z,15,11,0|ykhp40,16,6,1|yvnjrz,16,6,1|yvnjs0,15,11,0|z37rrz,15,11,0|z37rs0,16,6,1|zedmfz,16,6,1|zedmg0,15,11,0\",\"Asia/Anadyr|,0,206,0|-nu1sv8,102,200,0|-kmrtc1,102,200,0|-kmrtc0,103,201,0|5vaejz,103,201,0|5vaek0,104,207,1|64p7rz,104,207,1|64p7s0,103,201,0|6e2bvz,103,201,0|6e2bw0,103,201,1|6nh7vz,103,201,1|6nh7w0,102,200,0|6wubzz,102,200,0|6wuc00,103,201,1|76957z,103,201,1|769580,102,200,0|7fo3zz,102,200,0|7fo400,103,201,1|7p1avz,103,201,1|7p1aw0,102,200,0|7yec7z,102,200,0|7yec80,103,201,1|87rdjz,103,201,1|87rdk0,102,200,0|8h4evz,102,200,0|8h4ew0,103,201,1|8qhg7z,103,201,1|8qhg80,102,200,0|8zuhjz,102,200,0|8zuhk0,103,201,1|997ivz,103,201,1|997iw0,102,200,0|9ikk7z,102,200,0|9ikk80,103,201,1|9rxljz,103,201,1|9rxlk0,102,200,0|a1amvz,102,200,0|a1amw0,103,201,1|aano7z,103,201,1|aano80,102,200,0|ak0pjz,102,200,0|ak0pk0,103,201,1|atqpjz,103,201,1|atqpk0,102,200,0|b33qvz,102,200,0|b33qw0,102,200,1|bcguzz,102,200,1|bcgv00,90,192,0|bi89nz,90,192,0|bi89o0,102,200,0|blttjz,102,200,0|blttk0,103,201,1|bv6uvz,103,201,1|bv6uw0,102,200,0|c4jw7z,102,200,0|c4jw80,103,201,1|cdwxjz,103,201,1|cdwxk0,102,200,0|cn9yvz,102,200,0|cn9yw0,103,201,1|cwn07z,103,201,1|cwn080,102,200,0|d601jz,102,200,0|d601k0,103,201,1|dfd2vz,103,201,1|dfd2w0,102,200,0|dp32vz,102,200,0|dp32w0,103,201,1|dzvyvz,103,201,1|dzvyw0,102,200,0|e7t5jz,102,200,0|e7t5k0,103,201,1|eim1jz,103,201,1|eim1k0,102,200,0|eqj87z,102,200,0|eqj880,103,201,1|f1c47z,103,201,1|f1c480,102,200,0|f99avz,102,200,0|f99aw0,103,201,1|fkf5jz,103,201,1|fkf5k0,102,200,0|frzdjz,102,200,0|frzdk0,103,201,1|g3587z,103,201,1|g35880,102,200,0|gapg7z,102,200,0|gapg80,103,201,1|glvavz,103,201,1|glvaw0,102,200,0|gtshjz,102,200,0|gtshk0,103,201,1|h4ldjz,103,201,1|h4ldk0,102,200,0|hcik7z,102,200,0|hcik80,103,201,1|hnbg7z,103,201,1|hnbg80,102,200,0|hv8mvz,102,200,0|hv8mw0,103,201,1|i6ehjz,103,201,1|i6ehk0,102,200,0|idypjz,102,200,0|idypk0,103,201,1|ip4k7z,103,201,1|ip4k80,102,200,0|iwos7z,102,200,0|iwos80,103,201,1|j7umvz,103,201,1|j7umw0,102,200,0|jfeuvz,102,200,0|jfeuw0,103,201,1|jqkpjz,103,201,1|jqkpk0,102,200,0|jyhw7z,102,200,0|jyhw80,103,201,1|k9as7z,103,201,1|k9as80,102,200,0|kh7yvz,102,200,0|kh7yw0,103,201,1|ks0uvz,103,201,1|ks0uw0,102,200,0|kzy1jz,102,200,0|kzy1k0,102,200,1|lb3yzz,102,200,1|lb3z00,90,192,0|lio6zz,90,192,0|lio700,102,200,0\",\"Asia/Aqtau|,0,208,0|-nu15b4,105,209,0|-kmr741,105,209,0|-kmr740,92,194,0|64pwrz,92,194,0|64pws0,96,196,0|6e2vbz,96,196,0|6e2vc0,96,196,1|6nhrbz,96,196,1|6nhrc0,92,194,0|6wuvfz,92,194,0|6wuvg0,96,196,1|769onz,96,196,1|769oo0,92,194,0|7fonfz,92,194,0|7fong0,96,196,1|7p1ubz,96,196,1|7p1uc0,92,194,0|7yevnz,92,194,0|7yevo0,96,196,1|87rwzz,96,196,1|87rx00,92,194,0|8h4ybz,92,194,0|8h4yc0,96,196,1|8qhznz,96,196,1|8qhzo0,92,194,0|8zv0zz,92,194,0|8zv100,96,196,1|9982bz,96,196,1|9982c0,92,194,0|9il3nz,92,194,0|9il3o0,96,196,1|9ry4zz,96,196,1|9ry500,92,194,0|a1b6bz,92,194,0|a1b6c0,96,196,1|aao7nz,96,196,1|aao7o0,92,194,0|ak18zz,92,194,0|ak1900,96,196,1|atr8zz,96,196,1|atr900,92,194,0|b34abz,92,194,0|b34ac0,92,194,1|bchefz,92,194,1|bcheg0,105,209,0|bi8t3z,105,209,0|bi8t40,92,194,0|bluczz,92,194,0|blud00,96,196,1|bv7ebz,96,196,1|bv7ec0,92,194,0|c4kfnz,92,194,0|c4kfo0,96,196,1|cdxgzz,96,196,1|cdxh00,92,194,0|cnaibz,92,194,0|cnaic0,96,196,1|cwnjnz,96,196,1|cwnjo0,105,209,0|d60nrz,105,209,0|d60ns0,92,194,1|dfdp3z,92,194,1|dfdp40,105,209,0|dp3p3z,105,209,0|dp3p40,92,194,1|dzwl3z,92,194,1|dzwl40,105,209,0|e7trrz,105,209,0|e7trs0,92,194,1|eimnrz,92,194,1|eimns0,105,209,0|eqjufz,105,209,0|eqjug0,92,194,1|f1cqfz,92,194,1|f1cqg0,105,209,0|f99x3z,105,209,0|f99x40,92,194,1|fkfrrz,92,194,1|fkfrs0,105,209,0|frzzrz,105,209,0|frzzs0,92,194,1|g35ufz,92,194,1|g35ug0,105,209,0|gaq2fz,105,209,0|gaq2g0,92,194,1|glvx3z,92,194,1|glvx40,105,209,0|gtt3rz,105,209,0|gtt3s0,92,194,1|h4lzrz,92,194,1|h4lzs0,105,209,0|hcj6fz,105,209,0|hcj6g0,92,194,1|hnc2fz,92,194,1|hnc2g0,105,209,0|hv993z,105,209,0|hv9940,92,194,1|i6f3rz,92,194,1|i6f3s0,92,194,0\",\"Asia/Aqtobe|,0,210,0|-nu16l4,105,209,0|-kmr741,105,209,0|-kmr740,92,194,0|5vb0rz,92,194,0|5vb0s0,96,196,1|64ptzz,96,196,1|64pu00,96,196,0|6e2vbz,96,196,0|6e2vc0,96,196,1|6nhrbz,96,196,1|6nhrc0,92,194,0|6wuvfz,92,194,0|6wuvg0,96,196,1|769onz,96,196,1|769oo0,92,194,0|7fonfz,92,194,0|7fong0,96,196,1|7p1ubz,96,196,1|7p1uc0,92,194,0|7yevnz,92,194,0|7yevo0,96,196,1|87rwzz,96,196,1|87rx00,92,194,0|8h4ybz,92,194,0|8h4yc0,96,196,1|8qhznz,96,196,1|8qhzo0,92,194,0|8zv0zz,92,194,0|8zv100,96,196,1|9982bz,96,196,1|9982c0,92,194,0|9il3nz,92,194,0|9il3o0,96,196,1|9ry4zz,96,196,1|9ry500,92,194,0|a1b6bz,92,194,0|a1b6c0,96,196,1|aao7nz,96,196,1|aao7o0,92,194,0|ak18zz,92,194,0|ak1900,96,196,1|atr8zz,96,196,1|atr900,92,194,0|b34abz,92,194,0|b34ac0,92,194,1|bchefz,92,194,1|bcheg0,105,209,0|bi8t3z,105,209,0|bi8t40,92,194,0|bluczz,92,194,0|blud00,96,196,1|bv7ebz,96,196,1|bv7ec0,92,194,0|c4kfnz,92,194,0|c4kfo0,96,196,1|cdxgzz,96,196,1|cdxh00,92,194,0|cnaibz,92,194,0|cnaic0,96,196,1|cwnjnz,96,196,1|cwnjo0,92,194,0|d60kzz,92,194,0|d60l00,96,196,1|dfdmbz,96,196,1|dfdmc0,92,194,0|dp3mbz,92,194,0|dp3mc0,96,196,1|dzwibz,96,196,1|dzwic0,92,194,0|e7tozz,92,194,0|e7tp00,96,196,1|eimkzz,96,196,1|eiml00,92,194,0|eqjrnz,92,194,0|eqjro0,96,196,1|f1cnnz,96,196,1|f1cno0,92,194,0|f99ubz,92,194,0|f99uc0,96,196,1|fkfozz,96,196,1|fkfp00,92,194,0|frzwzz,92,194,0|frzx00,96,196,1|g35rnz,96,196,1|g35ro0,92,194,0|gapznz,92,194,0|gapzo0,96,196,1|glvubz,96,196,1|glvuc0,92,194,0|gtt0zz,92,194,0|gtt100,96,196,1|h4lwzz,96,196,1|h4lx00,92,194,0|hcj3nz,92,194,0|hcj3o0,96,196,1|hnbznz,96,196,1|hnbzo0,92,194,0|hv96bz,92,194,0|hv96c0,96,196,1|i6f0zz,96,196,1|i6f100,92,194,0\",\"Asia/Ashgabat|,0,211,0|-nu16t8,105,209,0|-kmr741,105,209,0|-kmr740,92,194,0|5vb0rz,92,194,0|5vb0s0,96,196,1|64ptzz,96,196,1|64pu00,92,194,0|6e2y3z,92,194,0|6e2y40,96,196,1|6nhrbz,96,196,1|6nhrc0,92,194,0|6wuvfz,92,194,0|6wuvg0,96,196,1|769onz,96,196,1|769oo0,92,194,0|7fonfz,92,194,0|7fong0,96,196,1|7p1ubz,96,196,1|7p1uc0,92,194,0|7yevnz,92,194,0|7yevo0,96,196,1|87rwzz,96,196,1|87rx00,92,194,0|8h4ybz,92,194,0|8h4yc0,96,196,1|8qhznz,96,196,1|8qhzo0,92,194,0|8zv0zz,92,194,0|8zv100,96,196,1|9982bz,96,196,1|9982c0,92,194,0|9il3nz,92,194,0|9il3o0,96,196,1|9ry4zz,96,196,1|9ry500,92,194,0|a1b6bz,92,194,0|a1b6c0,96,196,1|aao7nz,96,196,1|aao7o0,92,194,0|ak18zz,92,194,0|ak1900,96,196,1|atr8zz,96,196,1|atr900,92,194,0|b34abz,92,194,0|b34ac0,92,194,1|bchefz,92,194,1|bcheg0,105,209,0|bi8t3z,105,209,0|bi8t40,92,194,0\",\"Asia/Atyrau|,0,212,0|-nu15m8,100,6,0|-kmr4c1,100,6,0|-kmr4c0,92,194,0|64pwrz,92,194,0|64pws0,96,196,0|6e2vbz,96,196,0|6e2vc0,96,196,1|6nhrbz,96,196,1|6nhrc0,92,194,0|6wuvfz,92,194,0|6wuvg0,96,196,1|769onz,96,196,1|769oo0,92,194,0|7fonfz,92,194,0|7fong0,96,196,1|7p1ubz,96,196,1|7p1uc0,92,194,0|7yevnz,92,194,0|7yevo0,96,196,1|87rwzz,96,196,1|87rx00,92,194,0|8h4ybz,92,194,0|8h4yc0,96,196,1|8qhznz,96,196,1|8qhzo0,92,194,0|8zv0zz,92,194,0|8zv100,96,196,1|9982bz,96,196,1|9982c0,92,194,0|9il3nz,92,194,0|9il3o0,96,196,1|9ry4zz,96,196,1|9ry500,92,194,0|a1b6bz,92,194,0|a1b6c0,96,196,1|aao7nz,96,196,1|aao7o0,92,194,0|ak18zz,92,194,0|ak1900,96,196,1|atr8zz,96,196,1|atr900,92,194,0|b34abz,92,194,0|b34ac0,92,194,1|bchefz,92,194,1|bcheg0,105,209,0|bi8t3z,105,209,0|bi8t40,92,194,0|bluczz,92,194,0|blud00,96,196,1|bv7ebz,96,196,1|bv7ec0,92,194,0|c4kfnz,92,194,0|c4kfo0,96,196,1|cdxgzz,96,196,1|cdxh00,92,194,0|cnaibz,92,194,0|cnaic0,96,196,1|cwnjnz,96,196,1|cwnjo0,92,194,0|d60kzz,92,194,0|d60l00,96,196,1|dfdmbz,96,196,1|dfdmc0,92,194,0|dp3mbz,92,194,0|dp3mc0,96,196,1|dzwibz,96,196,1|dzwic0,92,194,0|e7tozz,92,194,0|e7tp00,96,196,1|eimkzz,96,196,1|eiml00,92,194,0|eqjrnz,92,194,0|eqjro0,96,196,1|f1cnnz,96,196,1|f1cno0,92,194,0|f99ubz,92,194,0|f99uc0,92,194,1|fkfrrz,92,194,1|fkfrs0,105,209,0|frzzrz,105,209,0|frzzs0,92,194,1|g35ufz,92,194,1|g35ug0,105,209,0|gaq2fz,105,209,0|gaq2g0,92,194,1|glvx3z,92,194,1|glvx40,105,209,0|gtt3rz,105,209,0|gtt3s0,92,194,1|h4lzrz,92,194,1|h4lzs0,105,209,0|hcj6fz,105,209,0|hcj6g0,92,194,1|hnc2fz,92,194,1|hnc2g0,105,209,0|hv993z,105,209,0|hv9940,92,194,1|i6f3rz,92,194,1|i6f3s0,92,194,0\",\"Asia/Baghdad|,0,213,0|-15r1hk4,53,214,0|-r50g81,53,214,0|-r50g80,100,6,0|6fmnnz,100,6,0|6fmno0,105,209,1|6nhwvz,105,209,1|6nhww0,100,6,0|6wt6bz,100,6,0|6wt6c0,105,209,1|769u7z,105,209,1|769u80,100,6,0|7foszz,100,6,0|7fot00,105,209,1|7p3m7z,105,209,1|7p3m80,100,6,0|7ygqbz,100,6,0|7ygqc0,105,209,1|87rzrz,105,209,1|87rzs0,100,6,0|8h513z,100,6,0|8h5140,105,209,1|8qi2fz,105,209,1|8qi2g0,100,6,0|8zv3rz,100,6,0|8zv3s0,105,209,1|99853z,105,209,1|998540,100,6,0|9il6fz,100,6,0|9il6g0,105,209,1|9ry7rz,105,209,1|9ry7s0,100,6,0|a1b93z,100,6,0|a1b940,105,209,1|aaoafz,105,209,1|aaoag0,100,6,0|ak1brz,100,6,0|ak1bs0,105,209,1|atrbrz,105,209,1|atrbs0,100,6,0|b36dbz,100,6,0|b36dc0,105,209,1|bcl9bz,105,209,1|bcl9c0,100,6,0|bm05bz,100,6,0|bm05c0,105,209,1|bvf1bz,105,209,1|bvf1c0,100,6,0|c4s2nz,100,6,0|c4s2o0,105,209,1|ce6ynz,105,209,1|ce6yo0,100,6,0|cnjzzz,100,6,0|cnk000,105,209,1|cwyvzz,105,209,1|cwyw00,100,6,0|d6bxbz,100,6,0|d6bxc0,105,209,1|dfqtbz,105,209,1|dfqtc0,100,6,0|dp5pbz,100,6,0|dp5pc0,105,209,1|dyklbz,105,209,1|dyklc0,100,6,0|e7xmnz,100,6,0|e7xmo0,105,209,1|ehcinz,105,209,1|ehcio0,100,6,0|eqpjzz,100,6,0|eqpk00,105,209,1|f04fzz,105,209,1|f04g00,100,6,0|f9hhbz,100,6,0|f9hhc0,105,209,1|fiwdbz,105,209,1|fiwdc0,100,6,0|fsb9bz,100,6,0|fsb9c0,105,209,1|g1q5bz,105,209,1|g1q5c0,100,6,0|gb36nz,100,6,0|gb36o0,105,209,1|gki2nz,105,209,1|gki2o0,100,6,0|gtv3zz,100,6,0|gtv400,105,209,1|h39zzz,105,209,1|h3a000,100,6,0|hcn1bz,100,6,0|hcn1c0,105,209,1|hm1xbz,105,209,1|hm1xc0,100,6,0|hvgtbz,100,6,0|hvgtc0,105,209,1|i4vpbz,105,209,1|i4vpc0,100,6,0|ie8qnz,100,6,0|ie8qo0,105,209,1|innmnz,105,209,1|innmo0,100,6,0|ix0nzz,100,6,0|ix0o00,105,209,1|j6fjzz,105,209,1|j6fk00,100,6,0|jfslbz,100,6,0|jfslc0,105,209,1|jp7hbz,105,209,1|jp7hc0,100,6,0\",\"Asia/Bahrain|,0,215,0|-q3gmvk,105,209,0|19d0vz,105,209,0|19d0w0,100,6,0\",\"Asia/Baku|,0,216,0|-nu158c,100,6,0|-6p7kc1,100,6,0|-6p7kc0,105,209,0|5vb3jz,105,209,0|5vb3k0,92,194,1|64pwrz,92,194,1|64pws0,105,209,0|6e30vz,105,209,0|6e30w0,92,194,1|6nhu3z,92,194,1|6nhu40,105,209,0|6wuy7z,105,209,0|6wuy80,92,194,1|769rfz,92,194,1|769rg0,105,209,0|7foq7z,105,209,0|7foq80,92,194,1|7p1x3z,92,194,1|7p1x40,105,209,0|7yeyfz,105,209,0|7yeyg0,92,194,1|87rzrz,92,194,1|87rzs0,105,209,0|8h513z,105,209,0|8h5140,92,194,1|8qi2fz,92,194,1|8qi2g0,105,209,0|8zv3rz,105,209,0|8zv3s0,92,194,1|99853z,92,194,1|998540,105,209,0|9il6fz,105,209,0|9il6g0,92,194,1|9ry7rz,92,194,1|9ry7s0,105,209,0|a1b93z,105,209,0|a1b940,92,194,1|aaoafz,92,194,1|aaoag0,105,209,0|ak1brz,105,209,0|ak1bs0,92,194,1|atrbrz,92,194,1|atrbs0,105,209,0|b34d3z,105,209,0|b34d40,105,209,1|bchh7z,105,209,1|bchh80,100,6,0|bluijz,100,6,0|bluik0,105,209,1|bv7jvz,105,209,1|bv7jw0,105,209,0|dp3xfz,105,209,0|dp3xg0,92,194,1|dzwtfz,92,194,1|dzwtg0,105,209,0|e7txbz,105,209,0|e7txc0,92,194,1|eimtbz,92,194,1|eimtc0,105,209,0|eqjzzz,105,209,0|eqk000,92,194,1|f1cvzz,92,194,1|f1cw00,105,209,0|f9a2nz,105,209,0|f9a2o0,92,194,1|fkfxbz,92,194,1|fkfxc0,105,209,0|fs05bz,105,209,0|fs05c0,92,194,1|g35zzz,92,194,1|g36000,105,209,0|gaq7zz,105,209,0|gaq800,92,194,1|glw2nz,92,194,1|glw2o0,105,209,0|gtt9bz,105,209,0|gtt9c0,92,194,1|h4m5bz,92,194,1|h4m5c0,105,209,0|hcjbzz,105,209,0|hcjc00,92,194,1|hnc7zz,92,194,1|hnc800,105,209,0|hv9enz,105,209,0|hv9eo0,92,194,1|i6f9bz,92,194,1|i6f9c0,105,209,0|idzhbz,105,209,0|idzhc0,92,194,1|ip5bzz,92,194,1|ip5c00,105,209,0|iwpjzz,105,209,0|iwpk00,92,194,1|j7venz,92,194,1|j7veo0,105,209,0|jffmnz,105,209,0|jffmo0,92,194,1|jqlhbz,92,194,1|jqlhc0,105,209,0|jyinzz,105,209,0|jyio00,92,194,1|k9bjzz,92,194,1|k9bk00,105,209,0|kh8qnz,105,209,0|kh8qo0,92,194,1|ks1mnz,92,194,1|ks1mo0,105,209,0|kzytbz,105,209,0|kzytc0,92,194,1|lb4nzz,92,194,1|lb4o00,105,209,0|liovzz,105,209,0|liow00,92,194,1|ltuqnz,92,194,1|ltuqo0,105,209,0|m1eynz,105,209,0|m1eyo0,92,194,1|mcktbz,92,194,1|mcktc0,105,209,0|mkhzzz,105,209,0|mki000,92,194,1|mvavzz,92,194,1|mvaw00,105,209,0|n382nz,105,209,0|n382o0,92,194,1|ne0ynz,92,194,1|ne0yo0,105,209,0|nly5bz,105,209,0|nly5c0,92,194,1|nwr1bz,92,194,1|nwr1c0,105,209,0\",\"Asia/Bangkok|,0,217,0|-1ayyla4,53,217,0|-pysda5,53,217,0|-pysda4,91,193,0\",\"Asia/Barnaul|,0,218,0|-q4ljic,96,196,0|-kmrco1,96,196,0|-kmrco0,91,193,0|5vav7z,91,193,0|5vav80,89,191,1|64pofz,89,191,1|64pog0,91,193,0|6e2sjz,91,193,0|6e2sk0,89,191,1|6nhlrz,89,191,1|6nhls0,91,193,0|6wupvz,91,193,0|6wupw0,89,191,1|769j3z,89,191,1|769j40,91,193,0|7fohvz,91,193,0|7fohw0,89,191,1|7p1orz,89,191,1|7p1os0,91,193,0|7yeq3z,91,193,0|7yeq40,89,191,1|87rrfz,89,191,1|87rrg0,91,193,0|8h4srz,91,193,0|8h4ss0,89,191,1|8qhu3z,89,191,1|8qhu40,91,193,0|8zuvfz,91,193,0|8zuvg0,89,191,1|997wrz,89,191,1|997ws0,91,193,0|9iky3z,91,193,0|9iky40,89,191,1|9rxzfz,89,191,1|9rxzg0,91,193,0|a1b0rz,91,193,0|a1b0s0,89,191,1|aao23z,89,191,1|aao240,91,193,0|ak13fz,91,193,0|ak13g0,89,191,1|atr3fz,89,191,1|atr3g0,91,193,0|b344rz,91,193,0|b344s0,91,193,1|bch8vz,91,193,1|bch8w0,96,196,0|bi8njz,96,196,0|bi8nk0,91,193,0|blu7fz,91,193,0|blu7g0,89,191,1|bv78rz,89,191,1|bv78s0,91,193,0|c4ka3z,91,193,0|c4ka40,89,191,1|cdxbfz,89,191,1|cdxbg0,91,193,0|cnacrz,91,193,0|cnacs0,89,191,1|cwne3z,89,191,1|cwne40,91,193,0|d60ffz,91,193,0|d60fg0,89,191,1|d98v3z,89,191,1|d98v40,91,193,1|dfdjjz,91,193,1|dfdjk0,96,196,0|dp3jjz,96,196,0|dp3jk0,91,193,1|dzwfjz,91,193,1|dzwfk0,96,196,0|e7tm7z,96,196,0|e7tm80,91,193,1|eimi7z,91,193,1|eimi80,96,196,0|eqjovz,96,196,0|eqjow0,91,193,1|f1ckvz,91,193,1|f1ckw0,96,196,0|f99rjz,96,196,0|f99rk0,91,193,1|fkfm7z,91,193,1|fkfm80,96,196,0|frzu7z,96,196,0|frzu80,91,193,1|g35ovz,91,193,1|g35ow0,96,196,0|gapwvz,96,196,0|gapww0,91,193,1|glvrjz,91,193,1|glvrk0,96,196,0|gtsy7z,96,196,0|gtsy80,91,193,1|h4lu7z,91,193,1|h4lu80,96,196,0|hcj0vz,96,196,0|hcj0w0,91,193,1|hnbwvz,91,193,1|hnbww0,96,196,0|hv93jz,96,196,0|hv93k0,91,193,1|i6ey7z,91,193,1|i6ey80,96,196,0|idz67z,96,196,0|idz680,91,193,1|ip50vz,91,193,1|ip50w0,96,196,0|iwp8vz,96,196,0|iwp8w0,91,193,1|j7v3jz,91,193,1|j7v3k0,96,196,0|jffbjz,96,196,0|jffbk0,91,193,1|jql67z,91,193,1|jql680,96,196,0|jyicvz,96,196,0|jyicw0,91,193,1|k9b8vz,91,193,1|k9b8w0,96,196,0|kh8fjz,96,196,0|kh8fk0,91,193,1|ks1bjz,91,193,1|ks1bk0,96,196,0|kzyi7z,96,196,0|kzyi80,91,193,1|lb4cvz,91,193,1|lb4cw0,96,196,0|liokvz,96,196,0|liokw0,91,193,0|ne0krz,91,193,0|ne0ks0,96,196,0|o4nwvz,96,196,0|o4nww0,91,193,0\",\"Asia/Beirut|,0,219,0|-1ayy98o,15,11,0|-pyzew1,15,11,0|-pyzew0,16,6,1|-po4r01,16,6,1|-po4r00,15,11,0|-pfwdk1,15,11,0|-pfwdk0,16,6,1|-p6hkc1,16,6,1|-p6hkc0,15,11,0|-oxj9k1,15,11,0|-oxj9k0,16,6,1|-ongdo1,16,6,1|-ongdo0,15,11,0|-oddc81,15,11,0|-oddc80,16,6,1|-o5t701,16,6,1|-o5t700,15,11,0|-6m2iw1,15,11,0|-6m2iw0,16,6,1|-6e79o1,16,6,1|-6e79o0,15,11,0|-63alk1,15,11,0|-63alk0,16,6,1|-5vfcc1,16,6,1|-5vfcc0,15,11,0|-5kio81,15,11,0|-5kio80,16,6,1|-5cnf01,16,6,1|-5cnf00,15,11,0|-51ow81,15,11,0|-51ow80,16,6,1|-4ttn01,16,6,1|-4ttn00,15,11,0|-4iwyw1,15,11,0|-4iwyw0,16,6,1|-4b1po1,16,6,1|-4b1po0,15,11,0|1ag2fz,15,11,0|1ag2g0,16,6,1|1fn0zz,16,6,1|1fn100,15,11,0|1qjp3z,15,11,0|1qjp40,16,6,1|1yeybz,16,6,1|1yeyc0,15,11,0|29bmfz,15,11,0|29bmg0,16,6,1|2h6vnz,16,6,1|2h6vo0,15,11,0|2s3jrz,15,11,0|2s3js0,16,6,1|2zyszz,16,6,1|2zyt00,15,11,0|3axbrz,15,11,0|3axbs0,16,6,1|3iskzz,16,6,1|3isl00,15,11,0|3tp93z,15,11,0|3tp940,16,6,1|41kibz,16,6,1|41kic0,15,11,0|4cfbrz,15,11,0|4cfbs0,16,6,1|4kakzz,16,6,1|4kal00,15,11,0|7h8frz,15,11,0|7h8fs0,16,6,1|7pvgzz,16,6,1|7pvh00,15,11,0|800d3z,15,11,0|800d40,16,6,1|88nebz,16,6,1|88nec0,15,11,0|8isafz,15,11,0|8isag0,16,6,1|8rfbnz,16,6,1|8rfbo0,15,11,0|91k7rz,15,11,0|91k7s0,16,6,1|9a78zz,16,6,1|9a7900,15,11,0|9lzefz,15,11,0|9lzeg0,16,6,1|9t10zz,16,6,1|9t1100,15,11,0|a3ml3z,15,11,0|a3ml40,16,6,1|absybz,16,6,1|absyc0,15,11,0|alxufz,15,11,0|alxug0,16,6,1|aukvnz,16,6,1|aukvo0,15,11,0|b4prrz,15,11,0|b4prs0,16,6,1|bdcszz,16,6,1|bdct00,15,11,0|bnjjrz,15,11,0|bnjjs0,16,6,1|bvkczz,16,6,1|bvkd00,15,11,0|c4kifz,15,11,0|c4kig0,16,6,1|cdxgzz,16,6,1|cdxh00,15,11,0|cnal3z,15,11,0|cnal40,16,6,1|cwnjnz,16,6,1|cwnjo0,15,11,0|d60nrz,15,11,0|d60ns0,16,6,1|dfdmbz,16,6,1|dfdmc0,15,11,0|dp3p3z,15,11,0|dp3p40,16,6,1|dygnnz,16,6,1|dygno0,15,11,0|e7trrz,15,11,0|e7trs0,16,6,1|eh6qbz,16,6,1|eh6qc0,15,11,0|eqjufz,15,11,0|eqjug0,16,6,1|ezwszz,16,6,1|ezwt00,15,11,0|f99x3z,15,11,0|f99x40,16,6,1|fkfozz,16,6,1|fkfp00,15,11,0|frzzrz,15,11,0|frzzs0,16,6,1|g35rnz,16,6,1|g35ro0,15,11,0|gaq2fz,15,11,0|gaq2g0,16,6,1|glvubz,16,6,1|glvuc0,15,11,0|gtt3rz,15,11,0|gtt3s0,16,6,1|h4lwzz,16,6,1|h4lx00,15,11,0|hcj6fz,15,11,0|hcj6g0,16,6,1|hnbznz,16,6,1|hnbzo0,15,11,0|hv993z,15,11,0|hv9940,16,6,1|i6f0zz,16,6,1|i6f100,15,11,0|idzbrz,15,11,0|idzbs0,16,6,1|ip53nz,16,6,1|ip53o0,15,11,0|iwpefz,15,11,0|iwpeg0,16,6,1|j7v6bz,16,6,1|j7v6c0,15,11,0|jffh3z,15,11,0|jffh40,16,6,1|jql8zz,16,6,1|jql900,15,11,0|jyiifz,15,11,0|jyiig0,16,6,1|k9bbnz,16,6,1|k9bbo0,15,11,0|kh8l3z,15,11,0|kh8l40,16,6,1|ks1ebz,16,6,1|ks1ec0,15,11,0|kzynrz,15,11,0|kzyns0,16,6,1|lb4fnz,16,6,1|lb4fo0,15,11,0|lioqfz,15,11,0|lioqg0,16,6,1|ltuibz,16,6,1|ltuic0,15,11,0|m1et3z,15,11,0|m1et40,16,6,1|mckkzz,16,6,1|mckl00,15,11,0|mkhufz,15,11,0|mkhug0,16,6,1|mvannz,16,6,1|mvano0,15,11,0|n37x3z,15,11,0|n37x40,16,6,1|ne0qbz,16,6,1|ne0qc0,15,11,0|nlxzrz,15,11,0|nlxzs0,16,6,1|nwqszz,16,6,1|nwqt00,15,11,0|o4o2fz,15,11,0|o4o2g0,16,6,1|oftubz,16,6,1|oftuc0,15,11,0|one53z,15,11,0|one540,16,6,1|oyjwzz,16,6,1|oyjx00,15,11,0|p647rz,15,11,0|p647s0,16,6,1|ph9znz,16,6,1|ph9zo0,15,11,0|pp793z,15,11,0|pp7940,16,6,1|q002bz,16,6,1|q002c0,15,11,0|q7xbrz,15,11,0|q7xbs0,16,6,1|qiq4zz,16,6,1|qiq500,15,11,0|qqnefz,15,11,0|qqneg0,16,6,1|r1t6bz,16,6,1|r1t6c0,15,11,0|r9dh3z,15,11,0|r9dh40,16,6,1|rkj8zz,16,6,1|rkj900,15,11,0|rs3jrz,15,11,0|rs3js0,16,6,1|s39bnz,16,6,1|s39bo0,15,11,0|sb6l3z,15,11,0|sb6l40,16,6,1|slzebz,16,6,1|slzec0,15,11,0|stwnrz,15,11,0|stwns0,16,6,1|t4pgzz,16,6,1|t4ph00,15,11,0|tcmqfz,15,11,0|tcmqg0,16,6,1|tnfjnz,16,6,1|tnfjo0,15,11,0|tvct3z,15,11,0|tvct40,16,6,1|u6ikzz,16,6,1|u6il00,15,11,0|ue2vrz,15,11,0|ue2vs0,16,6,1|up8nnz,16,6,1|up8no0,15,11,0|uwsyfz,15,11,0|uwsyg0,16,6,1|v7yqbz,16,6,1|v7yqc0,15,11,0|vfvzrz,15,11,0|vfvzs0,16,6,1|vqoszz,16,6,1|vqot00,15,11,0|vym2fz,15,11,0|vym2g0,16,6,1|w9evnz,16,6,1|w9evo0,15,11,0|whc53z,15,11,0|whc540,16,6,1|wshwzz,16,6,1|wshx00,15,11,0|x027rz,15,11,0|x027s0,16,6,1|xb7znz,16,6,1|xb7zo0,15,11,0|xisafz,15,11,0|xisag0,16,6,1|xty2bz,16,6,1|xty2c0,15,11,0|y1id3z,15,11,0|y1id40,16,6,1|yco4zz,16,6,1|yco500,15,11,0|yklefz,15,11,0|ykleg0,16,6,1|yve7nz,16,6,1|yve7o0,15,11,0|z3bh3z,15,11,0|z3bh40,16,6,1|ze4abz,16,6,1|ze4ac0,15,11,0\",\"Asia/Bishkek|,0,220,0|-nu19tc,92,194,0|-kmr9w1,92,194,0|-kmr9w0,96,196,0|5vaxzz,96,196,0|5vay00,91,193,1|64pr7z,91,193,1|64pr80,96,196,0|6e2vbz,96,196,0|6e2vc0,91,193,1|6nhojz,91,193,1|6nhok0,96,196,0|6wusnz,96,196,0|6wuso0,91,193,1|769lvz,91,193,1|769lw0,96,196,0|7foknz,96,196,0|7foko0,91,193,1|7p1rjz,91,193,1|7p1rk0,96,196,0|7yesvz,96,196,0|7yesw0,91,193,1|87ru7z,91,193,1|87ru80,96,196,0|8h4vjz,96,196,0|8h4vk0,91,193,1|8qhwvz,91,193,1|8qhww0,96,196,0|8zuy7z,96,196,0|8zuy80,91,193,1|997zjz,91,193,1|997zk0,96,196,0|9il0vz,96,196,0|9il0w0,91,193,1|9ry27z,91,193,1|9ry280,96,196,0|a1b3jz,96,196,0|a1b3k0,91,193,1|aao4vz,91,193,1|aao4w0,96,196,0|ak167z,96,196,0|ak1680,91,193,1|atr67z,91,193,1|atr680,96,196,0|b347jz,96,196,0|b347k0,96,196,1|bazjjz,96,196,1|bazjk0,92,194,0|bmk4rz,92,194,0|bmk4s0,96,196,1|bv75zz,96,196,1|bv7600,92,194,0|c5a7fz,92,194,0|c5a7g0,96,196,1|cdx8nz,96,196,1|cdx8o0,92,194,0|co0a3z,92,194,0|co0a40,96,196,1|cwnbbz,96,196,1|cwnbc0,92,194,0|d6qcrz,92,194,0|d6qcs0,96,196,1|dfddzz,96,196,1|dfde00,92,194,0|dpgffz,92,194,0|dpgfg0,96,196,1|dygfbz,96,196,1|dygfc0,92,194,0|e7tqdz,92,194,0|e7tqe0,96,196,1|eimjlz,96,196,1|eimjm0,92,194,0|eqjt1z,92,194,0|eqjt20,96,196,1|f1cm9z,96,196,1|f1cma0,92,194,0|f99vpz,92,194,0|f99vq0,96,196,1|fkfnlz,96,196,1|fkfnm0,92,194,0|frzydz,92,194,0|frzye0,96,196,1|g35q9z,96,196,1|g35qa0,92,194,0|gaq11z,92,194,0|gaq120,96,196,1|glvsxz,96,196,1|glvsy0,92,194,0|gtt2dz,92,194,0|gtt2e0,96,196,1|h4lvlz,96,196,1|h4lvm0,92,194,0|hcj51z,92,194,0|hcj520,96,196,1|hnby9z,96,196,1|hnbya0,92,194,0|hv97pz,92,194,0|hv97q0,96,196,1|i6ezlz,96,196,1|i6ezm0,92,194,0|idzadz,92,194,0|idzae0,96,196,1|il2knz,96,196,1|il2ko0,96,196,0\",\"Asia/Brunei|,0,221,0|-mvofy4,106,222,0|-jb6i61,106,222,0|-jb6i60,89,191,0\",\"Asia/Chita|,0,223,0|-q4cfog,89,191,0|-kmri81,89,191,0|-kmri80,107,224,0|5vapnz,107,224,0|5vapo0,93,195,1|64pivz,93,195,1|64piw0,107,224,0|6e2mzz,107,224,0|6e2n00,93,195,1|6nhg7z,93,195,1|6nhg80,107,224,0|6wukbz,107,224,0|6wukc0,93,195,1|769djz,93,195,1|769dk0,107,224,0|7focbz,107,224,0|7focc0,93,195,1|7p1j7z,93,195,1|7p1j80,107,224,0|7yekjz,107,224,0|7yekk0,93,195,1|87rlvz,93,195,1|87rlw0,107,224,0|8h4n7z,107,224,0|8h4n80,93,195,1|8qhojz,93,195,1|8qhok0,107,224,0|8zupvz,107,224,0|8zupw0,93,195,1|997r7z,93,195,1|997r80,107,224,0|9iksjz,107,224,0|9iksk0,93,195,1|9rxtvz,93,195,1|9rxtw0,107,224,0|a1av7z,107,224,0|a1av80,93,195,1|aanwjz,93,195,1|aanwk0,107,224,0|ak0xvz,107,224,0|ak0xw0,93,195,1|atqxvz,93,195,1|atqxw0,107,224,0|b33z7z,107,224,0|b33z80,107,224,1|bch3bz,107,224,1|bch3c0,89,191,0|bi8hzz,89,191,0|bi8i00,107,224,0|blu1vz,107,224,0|blu1w0,93,195,1|bv737z,93,195,1|bv7380,107,224,0|c4k4jz,107,224,0|c4k4k0,93,195,1|cdx5vz,93,195,1|cdx5w0,107,224,0|cna77z,107,224,0|cna780,93,195,1|cwn8jz,93,195,1|cwn8k0,107,224,0|d609vz,107,224,0|d609w0,93,195,1|dfdb7z,93,195,1|dfdb80,107,224,0|dp3b7z,107,224,0|dp3b80,93,195,1|dzw77z,93,195,1|dzw780,107,224,0|e7tdvz,107,224,0|e7tdw0,93,195,1|eim9vz,93,195,1|eim9w0,107,224,0|eqjgjz,107,224,0|eqjgk0,93,195,1|f1ccjz,93,195,1|f1cck0,107,224,0|f99j7z,107,224,0|f99j80,93,195,1|fkfdvz,93,195,1|fkfdw0,107,224,0|frzlvz,107,224,0|frzlw0,93,195,1|g35gjz,93,195,1|g35gk0,107,224,0|gapojz,107,224,0|gapok0,93,195,1|glvj7z,93,195,1|glvj80,107,224,0|gtspvz,107,224,0|gtspw0,93,195,1|h4llvz,93,195,1|h4llw0,107,224,0|hcisjz,107,224,0|hcisk0,93,195,1|hnbojz,93,195,1|hnbok0,107,224,0|hv8v7z,107,224,0|hv8v80,93,195,1|i6epvz,93,195,1|i6epw0,107,224,0|idyxvz,107,224,0|idyxw0,93,195,1|ip4sjz,93,195,1|ip4sk0,107,224,0|iwp0jz,107,224,0|iwp0k0,93,195,1|j7uv7z,93,195,1|j7uv80,107,224,0|jff37z,107,224,0|jff380,93,195,1|jqkxvz,93,195,1|jqkxw0,107,224,0|jyi4jz,107,224,0|jyi4k0,93,195,1|k9b0jz,93,195,1|k9b0k0,107,224,0|kh877z,107,224,0|kh8780,93,195,1|ks137z,93,195,1|ks1380,107,224,0|kzy9vz,107,224,0|kzy9w0,93,195,1|lb44jz,93,195,1|lb44k0,107,224,0|liocjz,107,224,0|liock0,93,195,0|ne0cfz,93,195,0|ne0cg0,89,191,0|o4nrbz,89,191,0|o4nrc0,107,224,0\",\"Asia/Choibalsan|,0,225,0|-xmct7c,91,193,0|46akjz,91,193,0|46akk0,89,191,0|6wun3z,89,191,0|6wun40,93,195,1|769djz,93,195,1|769dk0,107,224,0|7focbz,107,224,0|7focc0,93,195,1|7p1avz,93,195,1|7p1aw0,107,224,0|7yeezz,107,224,0|7yef00,93,195,1|87rdjz,93,195,1|87rdk0,107,224,0|8h4hnz,107,224,0|8h4ho0,93,195,1|8qhg7z,93,195,1|8qhg80,107,224,0|8zukbz,107,224,0|8zukc0,93,195,1|997ivz,93,195,1|997iw0,107,224,0|9ikmzz,107,224,0|9ikn00,93,195,1|9rxljz,93,195,1|9rxlk0,107,224,0|a1apnz,107,224,0|a1apo0,93,195,1|aano7z,93,195,1|aano80,107,224,0|ak0sbz,107,224,0|ak0sc0,93,195,1|atqpjz,93,195,1|atqpk0,107,224,0|b33tnz,107,224,0|b33to0,93,195,1|bcgs7z,93,195,1|bcgs80,107,224,0|bltwbz,107,224,0|bltwc0,93,195,1|bv6uvz,93,195,1|bv6uw0,107,224,0|c4jyzz,107,224,0|c4jz00,93,195,1|cdwxjz,93,195,1|cdwxk0,107,224,0|cna1nz,107,224,0|cna1o0,93,195,1|cwn07z,93,195,1|cwn080,107,224,0|d604bz,107,224,0|d604c0,93,195,1|dfd2vz,93,195,1|dfd2w0,107,224,0|dp35nz,107,224,0|dp35o0,93,195,1|dyg47z,93,195,1|dyg480,107,224,0|e7t8bz,107,224,0|e7t8c0,93,195,1|eh66vz,93,195,1|eh66w0,107,224,0|eqjazz,107,224,0|eqjb00,93,195,1|ezw9jz,93,195,1|ezw9k0,107,224,0|gcgn7z,107,224,0|gcgn80,93,195,1|gkdr3z,93,195,1|gkdr40,107,224,0|gtqv7z,107,224,0|gtqv80,93,195,1|h33trz,93,195,1|h33ts0,107,224,0|hcgxvz,107,224,0|hcgxw0,93,195,1|hltwfz,93,195,1|hltwg0,107,224,0|hv70jz,107,224,0|hv70k0,93,195,1|i4jz3z,93,195,1|i4jz40,107,224,0|idx37z,107,224,0|idx380,93,195,1|ina1rz,93,195,1|ina1s0,107,224,0|iwn5vz,107,224,0|iwn5w0,93,195,1|j6d33z,93,195,1|j6d340,107,224,0|jyjtnz,107,224,0|jyjto0,89,191,0|nlvtzz,89,191,0|nlvu00,107,224,1|nv8mzz,107,224,1|nv8n00,89,191,0|o4lwnz,89,191,0|o4lwo0,107,224,1|odypnz,107,224,1|odypo0,89,191,0\",\"Asia/Colombo|,0,226,0|-1ayyhgc,21,227,0|-xehasl,21,227,0|-xehask,108,228,0|-elvwm1,108,228,0|-elvwm0,96,196,1|-e9lco1,96,196,1|-e9lco0,109,229,1|-cmw9u1,109,229,1|-cmw9u0,108,228,0|drxa1z,108,228,0|drxa20,109,229,0|dzufbz,109,229,0|dzufc0,96,196,0|ixq61z,96,196,0|ixq620,108,228,0\",\"Asia/Damascus|,0,230,0|-q3gk20,15,11,0|-pxwdc1,15,11,0|-pxwdc0,16,6,1|-pp9c41,16,6,1|-pp9c40,15,11,0|-pf6ao1,15,11,0|-pf6ao0,16,6,1|-p6j9g1,16,6,1|-p6j9g0,15,11,0|-owg801,15,11,0|-owg800,16,6,1|-ont6s1,16,6,1|-ont6s0,15,11,0|-odq5c1,15,11,0|-odq5c0,16,6,1|-o4q5g1,16,6,1|-o4q5g0,15,11,0|-408lc1,15,11,0|-408lc0,16,6,1|-3s9ms1,16,6,1|-3s9ms0,15,11,0|-3hcyo1,15,11,0|-3hcyo0,16,6,1|-39jk41,16,6,1|-39jk40,15,11,0|-2yj6o1,15,11,0|-2yj6o0,16,6,1|-2qnxg1,16,6,1|-2qnxg0,15,11,0|-2fr9c1,15,11,0|-2fr9c0,16,6,1|-27xus1,16,6,1|-27xus0,15,11,0|-1xcao1,15,11,0|-1xcao0,16,6,1|-1p42s1,16,6,1|-1p42s0,15,11,0|-1e7eo1,15,11,0|-1e7eo0,16,6,1|-16c5g1,16,6,1|-16c5g0,15,11,0|-vdmo1,15,11,0|-vdmo0,16,6,1|-nidg1,16,6,1|-nidg0,15,11,0|-clpc1,15,11,0|-clpc0,16,6,1|-4qg41,16,6,1|-4qg40,15,11,0|667zz,15,11,0|66800,16,6,1|e1h7z,16,6,1|e1h80,15,11,0|oy5bz,15,11,0|oy5c0,16,6,1|wtejz,16,6,1|wtek0,15,11,0|17rxbz,15,11,0|17rxc0,16,6,1|1fn6jz,16,6,1|1fn6k0,15,11,0|1qjunz,15,11,0|1qjuo0,16,6,1|1yf3vz,16,6,1|1yf3w0,15,11,0|29brzz,15,11,0|29bs00,16,6,1|2h717z,16,6,1|2h7180,15,11,0|2s3pbz,15,11,0|2s3pc0,16,6,1|2zyyjz,16,6,1|2zyyk0,15,11,0|3axhbz,15,11,0|3axhc0,16,6,1|3isqjz,16,6,1|3isqk0,15,11,0|3tpenz,15,11,0|3tpeo0,16,6,1|4013vz,16,6,1|4013w0,15,11,0|4chbzz,15,11,0|4chc00,16,6,1|4it17z,16,6,1|4it180,15,11,0|6xa2nz,15,11,0|6xa2o0,16,6,1|76a2jz,16,6,1|76a2k0,15,11,0|7g3unz,15,11,0|7g3uo0,16,6,1|7p3ujz,16,6,1|7p3uk0,15,11,0|8ezenz,15,11,0|8ezeo0,16,6,1|8r2ijz,16,6,1|8r2ik0,15,11,0|8yfenz,15,11,0|8yfeo0,16,6,1|9az6jz,16,6,1|9az6k0,15,11,0|9hz3zz,15,11,0|9hz400,16,6,1|9tsyjz,16,6,1|9tsyk0,15,11,0|a1knzz,15,11,0|a1ko00,16,6,1|ab1bvz,16,6,1|ab1bw0,15,11,0|akefzz,15,11,0|akeg00,16,6,1|atrejz,16,6,1|atrek0,15,11,0|b367rz,15,11,0|b367s0,16,6,1|bcl0zz,16,6,1|bcl100,15,11,0|bmcyfz,15,11,0|bmcyg0,16,6,1|bveszz,16,6,1|bvet00,15,11,0|c4gt3z,15,11,0|c4gt40,16,6,1|cdvmbz,16,6,1|cdvmc0,15,11,0|cnjufz,15,11,0|cnjug0,16,6,1|cwynnz,16,6,1|cwyno0,15,11,0|d6brrz,15,11,0|d6brs0,16,6,1|dfqkzz,16,6,1|dfql00,15,11,0|dp5jrz,15,11,0|dp5js0,16,6,1|dykczz,16,6,1|dykd00,15,11,0|e7vmfz,15,11,0|e7vmg0,16,6,1|ehcabz,16,6,1|ehcac0,15,11,0|eqlp3z,15,11,0|eqlp40,16,6,1|f047nz,16,6,1|f047o0,15,11,0|f9hbrz,15,11,0|f9hbs0,16,6,1|fiw4zz,16,6,1|fiw500,15,11,0|fsb3rz,15,11,0|fsb3s0,16,6,1|g1pwzz,16,6,1|g1px00,15,11,0|gb313z,15,11,0|gb3140,16,6,1|gkhubz,16,6,1|gkhuc0,15,11,0|gtuyfz,15,11,0|gtuyg0,16,6,1|h39rnz,16,6,1|h39ro0,15,11,0|hcmvrz,15,11,0|hcmvs0,16,6,1|hm1ozz,16,6,1|hm1p00,15,11,0|hvgnrz,15,11,0|hvgns0,16,6,1|i4vgzz,16,6,1|i4vh00,15,11,0|ie8l3z,15,11,0|ie8l40,16,6,1|innebz,16,6,1|innec0,15,11,0|ix0ifz,15,11,0|ix0ig0,16,6,1|j5ynnz,16,6,1|j5yno0,15,11,0|jfoqfz,15,11,0|jfoqg0,16,6,1|jquibz,16,6,1|jquic0,15,11,0|jyrrrz,15,11,0|jyrrs0,16,6,1|k9mfnz,16,6,1|k9mfo0,15,11,0|kh4vrz,15,11,0|kh4vs0,16,6,1|ksannz,16,6,1|ksano0,15,11,0|l07x3z,15,11,0|l07x40,16,6,1|lb0qbz,16,6,1|lb0qc0,15,11,0|lixzrz,15,11,0|lixzs0,16,6,1|ltqszz,16,6,1|ltqt00,15,11,0|m1o2fz,15,11,0|m1o2g0,16,6,1|mcgvnz,16,6,1|mcgvo0,15,11,0|mke53z,15,11,0|mke540,16,6,1|mv6ybz,16,6,1|mv6yc0,15,11,0|n347rz,15,11,0|n347s0,16,6,1|ne9znz,16,6,1|ne9zo0,15,11,0|nluafz,15,11,0|nluag0,16,6,1|nx02bz,16,6,1|nx02c0,15,11,0|o4kd3z,15,11,0|o4kd40,16,6,1|ofq4zz,16,6,1|ofq500,15,11,0|onnefz,15,11,0|onneg0,16,6,1|oyg7nz,16,6,1|oyg7o0,15,11,0|p6dh3z,15,11,0|p6dh40,16,6,1|ph6abz,16,6,1|ph6ac0,15,11,0|pp3jrz,15,11,0|pp3js0,16,6,1|pzwczz,16,6,1|pzwd00,15,11,0|q7tmfz,15,11,0|q7tmg0,16,6,1|qizebz,16,6,1|qizec0,15,11,0|qqjp3z,15,11,0|qqjp40,16,6,1|r1pgzz,16,6,1|r1ph00,15,11,0|r99rrz,15,11,0|r99rs0,16,6,1|rkfjnz,16,6,1|rkfjo0,15,11,0|rsct3z,15,11,0|rsct40,16,6,1|s35mbz,16,6,1|s35mc0,15,11,0|sb2vrz,15,11,0|sb2vs0,16,6,1|slvozz,16,6,1|slvp00,15,11,0|stsyfz,15,11,0|stsyg0,16,6,1|t4yqbz,16,6,1|t4yqc0,15,11,0|tcj13z,15,11,0|tcj140,16,6,1|tnoszz,16,6,1|tnot00,15,11,0|tv93rz,15,11,0|tv93s0,16,6,1|u6evnz,16,6,1|u6evo0,15,11,0|uec53z,15,11,0|uec540,16,6,1|up4ybz,16,6,1|up4yc0,15,11,0|ux27rz,15,11,0|ux27s0,16,6,1|v7v0zz,16,6,1|v7v100,15,11,0|vfsafz,15,11,0|vfsag0,16,6,1|vql3nz,16,6,1|vql3o0,15,11,0|vyid3z,15,11,0|vyid40,16,6,1|w9o4zz,16,6,1|w9o500,15,11,0|wh8frz,15,11,0|wh8fs0,16,6,1|wse7nz,16,6,1|wse7o0,15,11,0|wzyifz,15,11,0|wzyig0,16,6,1|xb4abz,16,6,1|xb4ac0,15,11,0|xj1jrz,15,11,0|xj1js0,16,6,1|xtuczz,16,6,1|xtud00,15,11,0|y1rmfz,15,11,0|y1rmg0,16,6,1|yckfnz,16,6,1|yckfo0,15,11,0|ykhp3z,15,11,0|ykhp40,16,6,1|yvngzz,16,6,1|yvnh00,15,11,0|z37rrz,15,11,0|z37rs0,16,6,1|zedjnz,16,6,1|zedjo0,15,11,0\",\"Asia/Dhaka|,0,231,0|-15r1q2s,77,232,0|-eqtpox,77,232,0|-eqtpow,109,229,0|-ef78q1,109,229,0|-ef78q0,108,228,0|-e9lba1,108,228,0|-e9lba0,109,229,0|-9j0ne1,109,229,0|-9j0ne0,96,196,0|klhwjz,96,196,0|klhwk0,91,193,1|kvj0jz,91,193,1|kvj0k0,96,196,0\",\"Asia/Dili|,0,233,0|-u9s4l8,89,191,0|-ejfac1,89,191,0|-ejfac0,107,224,0|3b0hnz,107,224,0|3b0ho0,89,191,0|g0zlrz,89,191,0|g0zls0,107,224,0\",\"Asia/Dubai|,0,234,0|-q3gnko,105,209,0\",\"Asia/Dushanbe|,0,235,0|-nu18qo,92,194,0|-kmr9w1,92,194,0|-kmr9w0,96,196,0|5vaxzz,96,196,0|5vay00,91,193,1|64pr7z,91,193,1|64pr80,96,196,0|6e2vbz,96,196,0|6e2vc0,91,193,1|6nhojz,91,193,1|6nhok0,96,196,0|6wusnz,96,196,0|6wuso0,91,193,1|769lvz,91,193,1|769lw0,96,196,0|7foknz,96,196,0|7foko0,91,193,1|7p1rjz,91,193,1|7p1rk0,96,196,0|7yesvz,96,196,0|7yesw0,91,193,1|87ru7z,91,193,1|87ru80,96,196,0|8h4vjz,96,196,0|8h4vk0,91,193,1|8qhwvz,91,193,1|8qhww0,96,196,0|8zuy7z,96,196,0|8zuy80,91,193,1|997zjz,91,193,1|997zk0,96,196,0|9il0vz,96,196,0|9il0w0,91,193,1|9ry27z,91,193,1|9ry280,96,196,0|a1b3jz,96,196,0|a1b3k0,91,193,1|aao4vz,91,193,1|aao4w0,96,196,0|ak167z,96,196,0|ak1680,91,193,1|atr67z,91,193,1|atr680,96,196,0|b347jz,96,196,0|b347k0,96,196,1|bbgabz,96,196,1|bbgac0,92,194,0\",\"Asia/Famagusta|,0,236,0|-p4bqac,15,11,0|2r67rz,15,11,0|2r67s0,16,6,1|30j6bz,16,6,1|30j6c0,15,11,0|3bn93z,15,11,0|3bn940,16,6,1|3jb3nz,16,6,1|3jb3o0,15,11,0|3s9efz,15,11,0|3s9eg0,16,6,1|419ebz,16,6,1|419ec0,15,11,0|4azh3z,15,11,0|4azh40,16,6,1|4keabz,16,6,1|4keac0,15,11,0|4tpjrz,15,11,0|4tpjs0,16,6,1|532ibz,16,6,1|532ic0,15,11,0|5csl3z,15,11,0|5csl40,16,6,1|5lskzz,16,6,1|5lsl00,15,11,0|5v5p3z,15,11,0|5v5p40,16,6,1|64innz,16,6,1|64ino0,15,11,0|6dvrrz,15,11,0|6dvrs0,16,6,1|6n8qbz,16,6,1|6n8qc0,15,11,0|6wlufz,15,11,0|6wlug0,16,6,1|75yszz,16,6,1|75yt00,15,11,0|7fbx3z,15,11,0|7fbx40,16,6,1|7p1ubz,16,6,1|7p1uc0,15,11,0|7yeyfz,15,11,0|7yeyg0,16,6,1|87rwzz,16,6,1|87rx00,15,11,0|8h513z,15,11,0|8h5140,16,6,1|8qhznz,16,6,1|8qhzo0,15,11,0|8zv3rz,15,11,0|8zv3s0,16,6,1|9982bz,16,6,1|9982c0,15,11,0|9il6fz,15,11,0|9il6g0,16,6,1|9ry4zz,16,6,1|9ry500,15,11,0|a1b93z,15,11,0|a1b940,16,6,1|aao7nz,16,6,1|aao7o0,15,11,0|ak1brz,15,11,0|ak1bs0,16,6,1|atr8zz,16,6,1|atr900,15,11,0|b34d3z,15,11,0|b34d40,16,6,1|bchbnz,16,6,1|bchbo0,15,11,0|blufrz,15,11,0|blufs0,16,6,1|bv7ebz,16,6,1|bv7ec0,15,11,0|c4kifz,15,11,0|c4kig0,16,6,1|cdxgzz,16,6,1|cdxh00,15,11,0|cnal3z,15,11,0|cnal40,16,6,1|cwnjnz,16,6,1|cwnjo0,15,11,0|d60nrz,15,11,0|d60ns0,16,6,1|dfdmbz,16,6,1|dfdmc0,15,11,0|dp3p3z,15,11,0|dp3p40,16,6,1|dygnnz,16,6,1|dygno0,15,11,0|e7trrz,15,11,0|e7trs0,16,6,1|eh6qbz,16,6,1|eh6qc0,15,11,0|eqjufz,15,11,0|eqjug0,16,6,1|f1cyrz,16,6,1|f1cys0,15,11,0|f9a5fz,15,11,0|f9a5g0,16,6,1|fkg03z,16,6,1|fkg040,15,11,0|fs083z,15,11,0|fs0840,16,6,1|g362rz,16,6,1|g362s0,15,11,0|gaqarz,15,11,0|gaqas0,16,6,1|glw5fz,16,6,1|glw5g0,15,11,0|gttc3z,15,11,0|gttc40,16,6,1|h4m83z,16,6,1|h4m840,15,11,0|hcjerz,15,11,0|hcjes0,16,6,1|hncarz,16,6,1|hncas0,15,11,0|hv9hfz,15,11,0|hv9hg0,16,6,1|i6fc3z,16,6,1|i6fc40,15,11,0|idzk3z,15,11,0|idzk40,16,6,1|ip5erz,16,6,1|ip5es0,15,11,0|iwpmrz,15,11,0|iwpms0,16,6,1|j7vhfz,16,6,1|j7vhg0,15,11,0|jffpfz,15,11,0|jffpg0,16,6,1|jqlk3z,16,6,1|jqlk40,15,11,0|jyiqrz,15,11,0|jyiqs0,16,6,1|k9bmrz,16,6,1|k9bms0,15,11,0|kh8tfz,15,11,0|kh8tg0,16,6,1|ks1pfz,16,6,1|ks1pg0,15,11,0|kzyw3z,15,11,0|kzyw40,16,6,1|lb4qrz,16,6,1|lb4qs0,15,11,0|lioyrz,15,11,0|lioys0,16,6,1|ltutfz,16,6,1|ltutg0,15,11,0|m1f1fz,15,11,0|m1f1g0,16,6,1|mckw3z,16,6,1|mckw40,15,11,0|mki2rz,15,11,0|mki2s0,16,6,1|mvayrz,16,6,1|mvays0,15,11,0|n385fz,15,11,0|n385g0,16,6,1|ne11fz,16,6,1|ne11g0,15,11,0|nly83z,15,11,0|nly840,16,6,1|nwr43z,16,6,1|nwr440,15,11,0|o4oarz,15,11,0|o4oas0,16,6,1|od5jnz,16,6,1|od5jo0,100,6,0|oyk83z,100,6,0|oyk840,15,11,0|p64g3z,15,11,0|p64g40,16,6,1|phaarz,16,6,1|phaas0,15,11,0|pp7hfz,15,11,0|pp7hg0,16,6,1|q00dfz,16,6,1|q00dg0,15,11,0|q7xk3z,15,11,0|q7xk40,16,6,1|qiqg3z,16,6,1|qiqg40,15,11,0|qqnmrz,15,11,0|qqnms0,16,6,1|r1thfz,16,6,1|r1thg0,15,11,0|r9dpfz,15,11,0|r9dpg0,16,6,1|rkjk3z,16,6,1|rkjk40,15,11,0|rs3s3z,15,11,0|rs3s40,16,6,1|s39mrz,16,6,1|s39ms0,15,11,0|sb6tfz,15,11,0|sb6tg0,16,6,1|slzpfz,16,6,1|slzpg0,15,11,0|stww3z,15,11,0|stww40,16,6,1|t4ps3z,16,6,1|t4ps40,15,11,0|tcmyrz,15,11,0|tcmys0,16,6,1|tnfurz,16,6,1|tnfus0,15,11,0|tvd1fz,15,11,0|tvd1g0,16,6,1|u6iw3z,16,6,1|u6iw40,15,11,0|ue343z,15,11,0|ue3440,16,6,1|up8yrz,16,6,1|up8ys0,15,11,0|uwt6rz,15,11,0|uwt6s0,16,6,1|v7z1fz,16,6,1|v7z1g0,15,11,0|vfw83z,15,11,0|vfw840,16,6,1|vqp43z,16,6,1|vqp440,15,11,0|vymarz,15,11,0|vymas0,16,6,1|w9f6rz,16,6,1|w9f6s0,15,11,0|whcdfz,15,11,0|whcdg0,16,6,1|wsi83z,16,6,1|wsi840,15,11,0|x02g3z,15,11,0|x02g40,16,6,1|xb8arz,16,6,1|xb8as0,15,11,0|xisirz,15,11,0|xisis0,16,6,1|xtydfz,16,6,1|xtydg0,15,11,0|y1ilfz,15,11,0|y1ilg0,16,6,1|ycog3z,16,6,1|ycog40,15,11,0|yklmrz,15,11,0|yklms0,16,6,1|yveirz,16,6,1|yveis0,15,11,0|z3bpfz,15,11,0|z3bpg0,16,6,1|ze4lfz,16,6,1|ze4lg0,15,11,0\",\"Asia/Gaza|,0,237,0|-1054x1s,15,11,0|-ffv401,15,11,0|-ffv400,16,6,1|-f9l6o1,16,6,1|-f9l6o0,15,11,0|-f765c1,15,11,0|-f765c0,16,6,1|-e6fxc1,16,6,1|-e6fxc0,15,11,0|-dyoao1,15,11,0|-dyoao0,16,6,1|-dno001,16,6,1|-dno000,15,11,0|-dfuio1,15,11,0|-dfuio0,16,6,1|-d4u801,16,6,1|-d4u800,15,11,0|-cwatc1,15,11,0|-cwatc0,16,6,1|-cm2ao1,16,6,1|-cm2ao0,15,11,0|-cdiw01,15,11,0|-cdiw00,16,6,1|-c3adc1,16,6,1|-c3adc0,15,11,0|-6lluw1,15,11,0|-6lluw0,16,6,1|-6e79o1,16,6,1|-6e79o0,15,11,0|-63alk1,15,11,0|-63alk0,16,6,1|-5vfcc1,16,6,1|-5vfcc0,15,11,0|-5kilg1,15,11,0|-5kilg0,16,6,1|-5cp1c1,16,6,1|-5cp1c0,15,11,0|-51otg1,15,11,0|-51otg0,16,6,1|-4tv9c1,16,6,1|-4tv9c0,15,11,0|-4iww41,15,11,0|-4iww40,16,6,1|-4b3c01,16,6,1|-4b3c00,15,11,0|-404ys1,15,11,0|-404ys0,16,6,1|-3sbeo1,16,6,1|-3sbeo0,15,11,0|-3hd1g1,15,11,0|-3hd1g0,16,6,1|-39jhc1,16,6,1|-39jhc0,15,11,0|-2yj9g1,15,11,0|-2yj9g0,16,6,1|-2qppc1,16,6,1|-2qppc0,15,11,0|-2frc41,15,11,0|-2frc40,16,6,1|-27xs01,16,6,1|-27xs00,15,11,0|-1wzes1,15,11,0|-1wzes0,16,6,1|-1p4001,16,6,1|-1p4000,15,11,0|-1e7hg1,15,11,0|-1e7hg0,16,6,1|-1ceto1,16,6,1|-1ceto0,110,11,0|2crp3z,110,11,0|2crp40,111,6,1|2ht3nz,111,6,1|2ht3o0,110,11,0|2rj6fz,110,11,0|2rj6g0,111,6,1|2ydebz,111,6,1|2ydec0,110,11,0|5iwyfz,110,11,0|5iwyg0,111,6,1|5l2qfz,111,6,1|5l2qg0,110,11,0|7hhp3z,110,11,0|7hhp40,111,6,1|7n93rz,111,6,1|7n93s0,110,11,0|7z4vrz,110,11,0|7z4vs0,111,6,1|86c2bz,111,6,1|86c2c0,110,11,0|8jnrrz,110,11,0|8jnrs0,111,6,1|8pf3nz,111,6,1|8pf3o0,110,11,0|90ql3z,110,11,0|90ql40,111,6,1|98i4zz,111,6,1|98i500,110,11,0|9jb3rz,110,11,0|9jb3s0,111,6,1|9qv8zz,111,6,1|9qv900,110,11,0|a342fz,110,11,0|a342g0,111,6,1|a9lbnz,111,6,1|a9lbo0,110,11,0|ak1brz,110,11,0|ak1bs0,111,6,1|aryfnz,111,6,1|aryfo0,110,11,0|b2refz,110,11,0|b2reg0,111,6,1|bb1gzz,111,6,1|bb1h00,110,11,0|blufrz,110,11,0|blufs0,111,6,1|bu4ibz,111,6,1|bu4ic0,110,11,0|c4trrz,110,11,0|c4trs0,111,6,1|ccukzz,111,6,1|ccul00,110,11,0|cnjufz,110,11,0|cnjug0,111,6,1|cv7ozz,111,6,1|cv7p00,110,11,0|d69x3z,110,11,0|d69x40,111,6,1|deaqbz,111,6,1|deaqc0,110,11,0|dkh13z,110,11,0|dkh140,15,11,0|dpcyfz,15,11,0|dpcyg0,16,6,1|dy02fz,16,6,1|dy02g0,15,11,0|e8313z,15,11,0|e83140,16,6,1|egq53z,16,6,1|egq540,15,11,0|eqt3rz,15,11,0|eqt3s0,16,6,1|ezg7rz,16,6,1|ezg7s0,15,11,0|fa93rz,15,11,0|fa93s0,16,6,1|fjm2bz,16,6,1|fjm2c0,15,11,0|ftc53z,15,11,0|ftc540,16,6,1|g2p3nz,16,6,1|g2p3o0,15,11,0|gc27rz,15,11,0|gc27s0,16,6,1|glf6bz,16,6,1|glf6c0,15,11,0|gusafz,15,11,0|gusag0,16,6,1|h458zz,16,6,1|h45900,15,11,0|hdid3z,15,11,0|hdid40,16,6,1|hmvbnz,16,6,1|hmvbo0,15,11,0|hw8frz,15,11,0|hw8fs0,16,6,1|i4vjrz,16,6,1|i4vjs0,15,11,0|ieyifz,15,11,0|ieyig0,16,6,1|int3vz,16,6,1|int3w0,15,11,0|ix0ifz,15,11,0|ix0ig0,16,6,1|j5ynnz,16,6,1|j5yno0,15,11,0|jfsfrz,15,11,0|jfsfs0,16,6,1|joa2jz,16,6,1|joa2k0,15,11,0|jyet3z,15,11,0|jyet40,16,6,1|k6bwzz,16,6,1|k6bx00,15,11,0|kh4vrz,15,11,0|kh4vs0,16,6,1|kpf13z,16,6,1|kpf140,15,11,0|kzwt5n,15,11,0|kzwt5o,16,6,1|l6yfnz,16,6,1|l6yfo0,15,11,0|lixztn,15,11,0|lixzto,16,6,1|lp7ubz,16,6,1|lp7uc0,15,11,0|m1o2fz,15,11,0|m1o2g0,16,6,1|mao53z,16,6,1|mao540,15,11,0|mke53z,15,11,0|mke540,16,6,1|mtr3nz,16,6,1|mtr3o0,15,11,0|n347rz,15,11,0|n347s0,16,6,1|ndx0zz,16,6,1|ndx100,15,11,0|nlw53z,15,11,0|nlw540,16,6,1|nwn6fz,16,6,1|nwn6g0,15,11,0|o4majz,15,11,0|o4mak0,16,6,1|ofs2fz,16,6,1|ofs2g0,15,11,0|oncd7z,15,11,0|oncd80,16,6,1|oyi53z,16,6,1|oyi540,15,11,0|p62fvz,15,11,0|p62fw0,16,6,1|ph87rz,16,6,1|ph87s0,15,11,0|pp3jrz,15,11,0|pp3js0,16,6,1|pzy7nz,16,6,1|pzy7o0,15,11,0|q7vh3z,15,11,0|q7vh40,16,6,1|qiod3z,16,6,1|qiod40,15,11,0|qqljrz,15,11,0|qqljs0,16,6,1|r1refz,16,6,1|r1reg0,15,11,0|r9bmfz,15,11,0|r9bmg0,16,6,1|rkhh3z,16,6,1|rkhh40,15,11,0|rs1p3z,15,11,0|rs1p40,16,6,1|s37jrz,16,6,1|s37js0,15,11,0|sb4qfz,15,11,0|sb4qg0,16,6,1|slxmfz,16,6,1|slxmg0,15,11,0|stut3z,15,11,0|stut40,16,6,1|t4np3z,16,6,1|t4np40,15,11,0|tckvrz,15,11,0|tckvs0,16,6,1|tndrrz,16,6,1|tndrs0,15,11,0|tvayfz,15,11,0|tvayg0,16,6,1|u6gt3z,16,6,1|u6gt40,15,11,0|ue113z,15,11,0|ue1140,16,6,1|up6vrz,16,6,1|up6vs0,15,11,0|uwr3rz,15,11,0|uwr3s0,16,6,1|v7wyfz,16,6,1|v7wyg0,15,11,0|vfu53z,15,11,0|vfu540,16,6,1|vqn13z,16,6,1|vqn140,15,11,0|vyk7rz,15,11,0|vyk7s0,16,6,1|w9d3rz,16,6,1|w9d3s0,15,11,0|whaafz,15,11,0|whaag0,16,6,1|wsg53z,16,6,1|wsg540,15,11,0|x00d3z,15,11,0|x00d40,16,6,1|xb67rz,16,6,1|xb67s0,15,11,0|xiqfrz,15,11,0|xiqfs0,16,6,1|xtwafz,16,6,1|xtwag0,15,11,0|y1gifz,15,11,0|y1gig0,16,6,1|ycmd3z,16,6,1|ycmd40,15,11,0|ykjjrz,15,11,0|ykjjs0,16,6,1|yvcfrz,16,6,1|yvcfs0,15,11,0|z39mfz,15,11,0|z39mg0,16,6,1|ze2ifz,16,6,1|ze2ig0,15,11,0\",\"Asia/Hebron|,0,238,0|-1054x5z,15,11,0|-ffv401,15,11,0|-ffv400,16,6,1|-f9l6o1,16,6,1|-f9l6o0,15,11,0|-f765c1,15,11,0|-f765c0,16,6,1|-e6fxc1,16,6,1|-e6fxc0,15,11,0|-dyoao1,15,11,0|-dyoao0,16,6,1|-dno001,16,6,1|-dno000,15,11,0|-dfuio1,15,11,0|-dfuio0,16,6,1|-d4u801,16,6,1|-d4u800,15,11,0|-cwatc1,15,11,0|-cwatc0,16,6,1|-cm2ao1,16,6,1|-cm2ao0,15,11,0|-cdiw01,15,11,0|-cdiw00,16,6,1|-c3adc1,16,6,1|-c3adc0,15,11,0|-6lluw1,15,11,0|-6lluw0,16,6,1|-6e79o1,16,6,1|-6e79o0,15,11,0|-63alk1,15,11,0|-63alk0,16,6,1|-5vfcc1,16,6,1|-5vfcc0,15,11,0|-5kilg1,15,11,0|-5kilg0,16,6,1|-5cp1c1,16,6,1|-5cp1c0,15,11,0|-51otg1,15,11,0|-51otg0,16,6,1|-4tv9c1,16,6,1|-4tv9c0,15,11,0|-4iww41,15,11,0|-4iww40,16,6,1|-4b3c01,16,6,1|-4b3c00,15,11,0|-404ys1,15,11,0|-404ys0,16,6,1|-3sbeo1,16,6,1|-3sbeo0,15,11,0|-3hd1g1,15,11,0|-3hd1g0,16,6,1|-39jhc1,16,6,1|-39jhc0,15,11,0|-2yj9g1,15,11,0|-2yj9g0,16,6,1|-2qppc1,16,6,1|-2qppc0,15,11,0|-2frc41,15,11,0|-2frc40,16,6,1|-27xs01,16,6,1|-27xs00,15,11,0|-1wzes1,15,11,0|-1wzes0,16,6,1|-1p4001,16,6,1|-1p4000,15,11,0|-1e7hg1,15,11,0|-1e7hg0,16,6,1|-1ceto1,16,6,1|-1ceto0,110,11,0|2crp3z,110,11,0|2crp40,111,6,1|2ht3nz,111,6,1|2ht3o0,110,11,0|2rj6fz,110,11,0|2rj6g0,111,6,1|2ydebz,111,6,1|2ydec0,110,11,0|5iwyfz,110,11,0|5iwyg0,111,6,1|5l2qfz,111,6,1|5l2qg0,110,11,0|7hhp3z,110,11,0|7hhp40,111,6,1|7n93rz,111,6,1|7n93s0,110,11,0|7z4vrz,110,11,0|7z4vs0,111,6,1|86c2bz,111,6,1|86c2c0,110,11,0|8jnrrz,110,11,0|8jnrs0,111,6,1|8pf3nz,111,6,1|8pf3o0,110,11,0|90ql3z,110,11,0|90ql40,111,6,1|98i4zz,111,6,1|98i500,110,11,0|9jb3rz,110,11,0|9jb3s0,111,6,1|9qv8zz,111,6,1|9qv900,110,11,0|a342fz,110,11,0|a342g0,111,6,1|a9lbnz,111,6,1|a9lbo0,110,11,0|ak1brz,110,11,0|ak1bs0,111,6,1|aryfnz,111,6,1|aryfo0,110,11,0|b2refz,110,11,0|b2reg0,111,6,1|bb1gzz,111,6,1|bb1h00,110,11,0|blufrz,110,11,0|blufs0,111,6,1|bu4ibz,111,6,1|bu4ic0,110,11,0|c4trrz,110,11,0|c4trs0,111,6,1|ccukzz,111,6,1|ccul00,110,11,0|cnjufz,110,11,0|cnjug0,111,6,1|cv7ozz,111,6,1|cv7p00,110,11,0|d69x3z,110,11,0|d69x40,111,6,1|deaqbz,111,6,1|deaqc0,110,11,0|dkh13z,110,11,0|dkh140,15,11,0|dpcyfz,15,11,0|dpcyg0,16,6,1|dy02fz,16,6,1|dy02g0,15,11,0|e8313z,15,11,0|e83140,16,6,1|egq53z,16,6,1|egq540,15,11,0|eqt3rz,15,11,0|eqt3s0,16,6,1|ezg7rz,16,6,1|ezg7s0,15,11,0|fa93rz,15,11,0|fa93s0,16,6,1|fjm2bz,16,6,1|fjm2c0,15,11,0|ftc53z,15,11,0|ftc540,16,6,1|g2p3nz,16,6,1|g2p3o0,15,11,0|gc27rz,15,11,0|gc27s0,16,6,1|glf6bz,16,6,1|glf6c0,15,11,0|gusafz,15,11,0|gusag0,16,6,1|h458zz,16,6,1|h45900,15,11,0|hdid3z,15,11,0|hdid40,16,6,1|hmvbnz,16,6,1|hmvbo0,15,11,0|hw8frz,15,11,0|hw8fs0,16,6,1|i4vjrz,16,6,1|i4vjs0,15,11,0|ieyifz,15,11,0|ieyig0,16,6,1|int3vz,16,6,1|int3w0,15,11,0|ix0ifz,15,11,0|ix0ig0,16,6,1|j5ynnz,16,6,1|j5yno0,15,11,0|jfsfrz,15,11,0|jfsfs0,16,6,1|joa2jz,16,6,1|joa2k0,15,11,0|jyet3z,15,11,0|jyet40,16,6,1|k6hgzz,16,6,1|k6hh00,15,11,0|kh4vrz,15,11,0|kh4vs0,16,6,1|kpf13z,16,6,1|kpf140,15,11,0|kzuyfz,15,11,0|kzuyg0,16,6,1|l6yfnz,16,6,1|l6yfo0,15,11,0|lixztn,15,11,0|lixzto,16,6,1|lp7ubz,16,6,1|lp7uc0,15,11,0|lqpmfz,15,11,0|lqpmg0,16,6,1|lsaybz,16,6,1|lsayc0,15,11,0|m1o2fz,15,11,0|m1o2g0,16,6,1|mao53z,16,6,1|mao540,15,11,0|mke53z,15,11,0|mke540,16,6,1|mtr3nz,16,6,1|mtr3o0,15,11,0|n347rz,15,11,0|n347s0,16,6,1|ndx0zz,16,6,1|ndx100,15,11,0|nlw53z,15,11,0|nlw540,16,6,1|nwn6fz,16,6,1|nwn6g0,15,11,0|o4majz,15,11,0|o4mak0,16,6,1|ofs2fz,16,6,1|ofs2g0,15,11,0|oncd7z,15,11,0|oncd80,16,6,1|oyi53z,16,6,1|oyi540,15,11,0|p62fvz,15,11,0|p62fw0,16,6,1|ph87rz,16,6,1|ph87s0,15,11,0|pp3jrz,15,11,0|pp3js0,16,6,1|pzy7nz,16,6,1|pzy7o0,15,11,0|q7vh3z,15,11,0|q7vh40,16,6,1|qiod3z,16,6,1|qiod40,15,11,0|qqljrz,15,11,0|qqljs0,16,6,1|r1refz,16,6,1|r1reg0,15,11,0|r9bmfz,15,11,0|r9bmg0,16,6,1|rkhh3z,16,6,1|rkhh40,15,11,0|rs1p3z,15,11,0|rs1p40,16,6,1|s37jrz,16,6,1|s37js0,15,11,0|sb4qfz,15,11,0|sb4qg0,16,6,1|slxmfz,16,6,1|slxmg0,15,11,0|stut3z,15,11,0|stut40,16,6,1|t4np3z,16,6,1|t4np40,15,11,0|tckvrz,15,11,0|tckvs0,16,6,1|tndrrz,16,6,1|tndrs0,15,11,0|tvayfz,15,11,0|tvayg0,16,6,1|u6gt3z,16,6,1|u6gt40,15,11,0|ue113z,15,11,0|ue1140,16,6,1|up6vrz,16,6,1|up6vs0,15,11,0|uwr3rz,15,11,0|uwr3s0,16,6,1|v7wyfz,16,6,1|v7wyg0,15,11,0|vfu53z,15,11,0|vfu540,16,6,1|vqn13z,16,6,1|vqn140,15,11,0|vyk7rz,15,11,0|vyk7s0,16,6,1|w9d3rz,16,6,1|w9d3s0,15,11,0|whaafz,15,11,0|whaag0,16,6,1|wsg53z,16,6,1|wsg540,15,11,0|x00d3z,15,11,0|x00d40,16,6,1|xb67rz,16,6,1|xb67s0,15,11,0|xiqfrz,15,11,0|xiqfs0,16,6,1|xtwafz,16,6,1|xtwag0,15,11,0|y1gifz,15,11,0|y1gig0,16,6,1|ycmd3z,16,6,1|ycmd40,15,11,0|ykjjrz,15,11,0|ykjjs0,16,6,1|yvcfrz,16,6,1|yvcfs0,15,11,0|z39mfz,15,11,0|z39mg0,16,6,1|ze2ifz,16,6,1|ze2ig0,15,11,0\",\"Asia/Ho_Chi_Minh|,0,239,0|-x56934,112,240,0|-umdqev,112,240,0|-umdqeu,91,193,0|-e3bkw1,91,193,0|-e3bkw0,89,191,0|-cxyro1,89,191,0|-cxyro0,107,224,0|-cp63o1,107,224,0|-cp63o0,91,193,0|-bvja41,91,193,0|-bvja40,89,191,0|-7kjq81,89,191,0|-7kjq80,91,193,0|-57xfk1,91,193,0|-57xfk0,89,191,0|2uaprz,89,191,0|2uaps0,91,193,0\",\"Asia/Hong_Kong|,0,241,0|-y0i0s0,113,191,0|-ewdn81,113,191,0|-ewdn80,114,224,1|-eqtn81,114,224,1|-eqtn80,115,242,1|-emgia1,115,242,1|-emgia0,116,224,0|-cl7cs1,116,224,0|-cl7cs0,113,191,0|-cda8w1,113,191,0|-cda8w0,114,224,1|-c1r5u1,114,224,1|-c1r5u0,113,191,0|-buwv61,113,191,0|-buwv60,114,224,1|-bj1361,114,224,1|-bj1360,113,191,0|-bb3wi1,113,191,0|-bb3wi0,114,224,1|-b1qv61,114,224,1|-b1qv60,113,191,0|-attoi1,113,191,0|-attoi0,114,224,1|-aj0si1,114,224,1|-aj0si0,113,191,0|-ab3lu1,113,191,0|-ab3lu0,114,224,1|-a0apu1,114,224,1|-a0apu0,113,191,0|-9sdj61,113,191,0|-9sdj60,114,224,1|-9hkn61,114,224,1|-9hkn60,113,191,0|-99ahu1,113,191,0|-99ahu0,114,224,1|-8yhlu1,114,224,1|-8yhlu0,113,191,0|-8qkf61,113,191,0|-8qkf60,114,224,1|-8frly1,114,224,1|-8frly0,113,191,0|-88k9u1,113,191,0|-88k9u0,114,224,1|-7x1ja1,114,224,1|-7x1ja0,113,191,0|-7pu761,113,191,0|-7pu760,114,224,1|-7dyhy1,114,224,1|-7dyhy0,113,191,0|-7744i1,113,191,0|-7744i0,114,224,1|-6v8fa1,114,224,1|-6v8fa0,113,191,0|-6o1361,113,191,0|-6o1360,114,224,1|-6cicm1,114,224,1|-6cicm0,113,191,0|-65b0i1,113,191,0|-65b0i0,114,224,1|-5ts9y1,114,224,1|-5ts9y0,113,191,0|-5mkxu1,113,191,0|-5mkxu0,114,224,1|-5b27a1,114,224,1|-5b27a0,113,191,0|-53uv61,113,191,0|-53uv60,114,224,1|-4rz5y1,114,224,1|-4rz5y0,113,191,0|-4l4si1,113,191,0|-4l4si0,114,224,1|-4993a1,114,224,1|-4993a0,113,191,0|-42epu1,113,191,0|-42epu0,114,224,1|-3qj0m1,114,224,1|-3qj0m0,113,191,0|-3jboi1,113,191,0|-3jboi0,114,224,1|-37sxy1,114,224,1|-37sxy0,113,191,0|-30llu1,113,191,0|-30llu0,114,224,1|-2p2va1,114,224,1|-2p2va0,113,191,0|-2gfoi1,113,191,0|-2gfoi0,114,224,1|-272py1,114,224,1|-272py0,113,191,0|-1xplu1,113,191,0|-1xplu0,114,224,1|-1ocna1,114,224,1|-1ocna0,113,191,0|-1ezj61,113,191,0|-1ezj60,114,224,1|-159ly1,114,224,1|-159ly0,113,191,0|-vwhu1,113,191,0|-vwhu0,114,224,1|-mjja1,114,224,1|-mjja0,113,191,0|-d6f61,113,191,0|-d6f60,114,224,1|-3tgm1,114,224,1|-3tgm0,113,191,0|5jnhz,113,191,0|5jni0,114,224,1|ewm1z,114,224,1|ewm20,113,191,0|o9q5z,113,191,0|o9q60,114,224,1|xmopz,114,224,1|xmoq0,113,191,0|16zstz,113,191,0|16zsu0,114,224,1|1gpq1z,114,224,1|1gpq20,113,191,0|1q2u5z,113,191,0|1q2u60,114,224,1|1zfspz,114,224,1|1zfsq0,113,191,0|231i5z,113,191,0|231i60,114,224,1|2i5vdz,114,224,1|2i5ve0,113,191,0|2rizhz,113,191,0|2rizi0,114,224,1|30vy1z,114,224,1|30vy20,113,191,0|3a925z,113,191,0|3a9260,114,224,1|3jm0pz,114,224,1|3jm0q0,113,191,0|4vv4tz,113,191,0|4vv4u0,114,224,1|5457dz,114,224,1|5457e0,113,191,0\",\"Asia/Hovd|,0,243,0|-xmcoz0,96,196,0|46anbz,96,196,0|46anc0,91,193,0|6wupvz,91,193,0|6wupw0,89,191,1|769j3z,89,191,1|769j40,91,193,0|7fohvz,91,193,0|7fohw0,89,191,1|7p1gfz,89,191,1|7p1gg0,91,193,0|7yekjz,91,193,0|7yekk0,89,191,1|87rj3z,89,191,1|87rj40,91,193,0|8h4n7z,91,193,0|8h4n80,89,191,1|8qhlrz,89,191,1|8qhls0,91,193,0|8zupvz,91,193,0|8zupw0,89,191,1|997ofz,89,191,1|997og0,91,193,0|9iksjz,91,193,0|9iksk0,89,191,1|9rxr3z,89,191,1|9rxr40,91,193,0|a1av7z,91,193,0|a1av80,89,191,1|aantrz,89,191,1|aants0,91,193,0|ak0xvz,91,193,0|ak0xw0,89,191,1|atqv3z,89,191,1|atqv40,91,193,0|b33z7z,91,193,0|b33z80,89,191,1|bcgxrz,89,191,1|bcgxs0,91,193,0|blu1vz,91,193,0|blu1w0,89,191,1|bv70fz,89,191,1|bv70g0,91,193,0|c4k4jz,91,193,0|c4k4k0,89,191,1|cdx33z,89,191,1|cdx340,91,193,0|cna77z,91,193,0|cna780,89,191,1|cwn5rz,89,191,1|cwn5s0,91,193,0|d609vz,91,193,0|d609w0,89,191,1|dfd8fz,89,191,1|dfd8g0,91,193,0|dp3b7z,91,193,0|dp3b80,89,191,1|dyg9rz,89,191,1|dyg9s0,91,193,0|e7tdvz,91,193,0|e7tdw0,89,191,1|eh6cfz,89,191,1|eh6cg0,91,193,0|eqjgjz,91,193,0|eqjgk0,89,191,1|ezwf3z,89,191,1|ezwf40,91,193,0|gcgsrz,91,193,0|gcgss0,89,191,1|gkdwnz,89,191,1|gkdwo0,91,193,0|gtr0rz,91,193,0|gtr0s0,89,191,1|h33zbz,89,191,1|h33zc0,91,193,0|hch3fz,91,193,0|hch3g0,89,191,1|hlu1zz,89,191,1|hlu200,91,193,0|hv763z,91,193,0|hv7640,89,191,1|i4k4nz,89,191,1|i4k4o0,91,193,0|idx8rz,91,193,0|idx8s0,89,191,1|ina7bz,89,191,1|ina7c0,91,193,0|iwnbfz,91,193,0|iwnbg0,89,191,1|j6d8nz,89,191,1|j6d8o0,91,193,0|nlvwrz,91,193,0|nlvws0,89,191,1|nv8prz,89,191,1|nv8ps0,91,193,0|o4lzfz,91,193,0|o4lzg0,89,191,1|odysfz,89,191,1|odysg0,91,193,0\",\"Asia/Irkutsk|,0,244,0|-1ayylz5,117,244,0|-q28gn6,117,244,0|-q28gn5,91,193,0|-kmrfg1,91,193,0|-kmrfg0,89,191,0|5vasfz,89,191,0|5vasg0,107,224,1|64plnz,107,224,1|64plo0,89,191,0|6e2prz,89,191,0|6e2ps0,107,224,1|6nhizz,107,224,1|6nhj00,89,191,0|6wun3z,89,191,0|6wun40,107,224,1|769gbz,107,224,1|769gc0,89,191,0|7fof3z,89,191,0|7fof40,107,224,1|7p1lzz,107,224,1|7p1m00,89,191,0|7yenbz,89,191,0|7yenc0,107,224,1|87ronz,107,224,1|87roo0,89,191,0|8h4pzz,89,191,0|8h4q00,107,224,1|8qhrbz,107,224,1|8qhrc0,89,191,0|8zusnz,89,191,0|8zuso0,107,224,1|997tzz,107,224,1|997u00,89,191,0|9ikvbz,89,191,0|9ikvc0,107,224,1|9rxwnz,107,224,1|9rxwo0,89,191,0|a1axzz,89,191,0|a1ay00,107,224,1|aanzbz,107,224,1|aanzc0,89,191,0|ak10nz,89,191,0|ak10o0,107,224,1|atr0nz,107,224,1|atr0o0,89,191,0|b341zz,89,191,0|b34200,89,191,1|bch63z,89,191,1|bch640,91,193,0|bi8krz,91,193,0|bi8ks0,89,191,0|blu4nz,89,191,0|blu4o0,107,224,1|bv75zz,107,224,1|bv7600,89,191,0|c4k7bz,89,191,0|c4k7c0,107,224,1|cdx8nz,107,224,1|cdx8o0,89,191,0|cna9zz,89,191,0|cnaa00,107,224,1|cwnbbz,107,224,1|cwnbc0,89,191,0|d60cnz,89,191,0|d60co0,107,224,1|dfddzz,107,224,1|dfde00,89,191,0|dp3dzz,89,191,0|dp3e00,107,224,1|dzw9zz,107,224,1|dzwa00,89,191,0|e7tgnz,89,191,0|e7tgo0,107,224,1|eimcnz,107,224,1|eimco0,89,191,0|eqjjbz,89,191,0|eqjjc0,107,224,1|f1cfbz,107,224,1|f1cfc0,89,191,0|f99lzz,89,191,0|f99m00,107,224,1|fkfgnz,107,224,1|fkfgo0,89,191,0|frzonz,89,191,0|frzoo0,107,224,1|g35jbz,107,224,1|g35jc0,89,191,0|gaprbz,89,191,0|gaprc0,107,224,1|glvlzz,107,224,1|glvm00,89,191,0|gtssnz,89,191,0|gtsso0,107,224,1|h4lonz,107,224,1|h4loo0,89,191,0|hcivbz,89,191,0|hcivc0,107,224,1|hnbrbz,107,224,1|hnbrc0,89,191,0|hv8xzz,89,191,0|hv8y00,107,224,1|i6esnz,107,224,1|i6eso0,89,191,0|idz0nz,89,191,0|idz0o0,107,224,1|ip4vbz,107,224,1|ip4vc0,89,191,0|iwp3bz,89,191,0|iwp3c0,107,224,1|j7uxzz,107,224,1|j7uy00,89,191,0|jff5zz,89,191,0|jff600,107,224,1|jql0nz,107,224,1|jql0o0,89,191,0|jyi7bz,89,191,0|jyi7c0,107,224,1|k9b3bz,107,224,1|k9b3c0,89,191,0|kh89zz,89,191,0|kh8a00,107,224,1|ks15zz,107,224,1|ks1600,89,191,0|kzycnz,89,191,0|kzyco0,107,224,1|lb47bz,107,224,1|lb47c0,89,191,0|liofbz,89,191,0|liofc0,107,224,0|ne0f7z,107,224,0|ne0f80,89,191,0\",\"Asia/Jakarta|,0,245,0|-1hftyg0,53,245,0|-o0bdpd,53,245,0|-o0bdpc,118,246,0|-jebgdd,118,246,0|-jebgdc,106,222,0|-ehxgu1,106,222,0|-ehxgu0,107,224,0|-co37o1,107,224,0|-co37o0,106,222,0|-bb5zi1,106,222,0|-bb5zi0,89,191,0|-a9m681,89,191,0|-a9m680,106,222,0|-34ru61,106,222,0|-34ru60,119,193,0\",\"Asia/Jayapura|,0,247,0|-jebm20,107,224,0|-d7zvo1,107,224,0|-d7zvo0,120,248,0|-34rzq1,120,248,0|-34rzq0,121,224,0\",\"Asia/Jerusalem|,0,249,0|-1ayy96u,122,250,0|-r50eih,122,250,0|-r50eig,110,11,0|-ffv401,110,11,0|-ffv400,111,6,1|-f9l6o1,111,6,1|-f9l6o0,110,11,0|-f765c1,110,11,0|-f765c0,111,6,1|-e6fxc1,111,6,1|-e6fxc0,110,11,0|-dyoao1,110,11,0|-dyoao0,111,6,1|-dno001,111,6,1|-dno000,110,11,0|-dfuio1,110,11,0|-dfuio0,111,6,1|-d4u801,111,6,1|-d4u800,110,11,0|-cwatc1,110,11,0|-cwatc0,111,6,1|-cm2ao1,111,6,1|-cm2ao0,110,11,0|-cdiw01,110,11,0|-cdiw00,111,6,1|-c3adc1,111,6,1|-c3adc0,110,11,0|-ba0o01,110,11,0|-ba0o00,123,209,1|-b4tmo1,123,209,1|-b4tmo0,111,6,1|-b1oo01,111,6,1|-b1oo00,110,11,0|-asdhc1,110,11,0|-asdhc0,111,6,1|-aiwqo1,111,6,1|-aiwqo0,110,11,0|-aadc01,110,11,0|-aadc00,111,6,1|-a2juo1,111,6,1|-a2juo0,110,11,0|-9sd6o1,110,11,0|-9sd6o0,111,6,1|-9gudc1,111,6,1|-9gudc0,110,11,0|-98k801,110,11,0|-98k800,111,6,1|-8z76o1,111,6,1|-8z76o0,110,11,0|-8q7401,110,11,0|-8q7400,111,6,1|-8i9xc1,111,6,1|-8i9xc0,110,11,0|-848dc1,110,11,0|-848dc0,111,6,1|-7zjuo1,111,6,1|-7zjuo0,110,11,0|-7liao1,110,11,0|-7liao0,111,6,1|-7gts01,111,6,1|-7gts00,110,11,0|-7356o1,110,11,0|-7356o0,111,6,1|-6x0tc1,111,6,1|-6x0tc0,110,11,0|-6m7xc1,110,11,0|-6m7xc0,111,6,1|-6enpc1,111,6,1|-6enpc0,110,11,0|2crp3z,110,11,0|2crp40,111,6,1|2ht3nz,111,6,1|2ht3o0,110,11,0|2rj6fz,110,11,0|2rj6g0,111,6,1|2ydebz,111,6,1|2ydec0,110,11,0|5iwyfz,110,11,0|5iwyg0,111,6,1|5l2qfz,111,6,1|5l2qg0,110,11,0|7hhp3z,110,11,0|7hhp40,111,6,1|7n93rz,111,6,1|7n93s0,110,11,0|7z4vrz,110,11,0|7z4vs0,111,6,1|86c2bz,111,6,1|86c2c0,110,11,0|8jnrrz,110,11,0|8jnrs0,111,6,1|8pf3nz,111,6,1|8pf3o0,110,11,0|90ql3z,110,11,0|90ql40,111,6,1|98i4zz,111,6,1|98i500,110,11,0|9jb3rz,110,11,0|9jb3s0,111,6,1|9qv8zz,111,6,1|9qv900,110,11,0|a342fz,110,11,0|a342g0,111,6,1|a9lbnz,111,6,1|a9lbo0,110,11,0|ak1brz,110,11,0|ak1bs0,111,6,1|aryfnz,111,6,1|aryfo0,110,11,0|b2refz,110,11,0|b2reg0,111,6,1|bb1gzz,111,6,1|bb1h00,110,11,0|blufrz,110,11,0|blufs0,111,6,1|bu4ibz,111,6,1|bu4ic0,110,11,0|c4trrz,110,11,0|c4trs0,111,6,1|ccukzz,111,6,1|ccul00,110,11,0|cnjufz,110,11,0|cnjug0,111,6,1|cv7ozz,111,6,1|cv7p00,110,11,0|d69x3z,110,11,0|d69x40,111,6,1|deaqbz,111,6,1|deaqc0,110,11,0|doa2fz,110,11,0|doa2g0,111,6,1|dxskzz,111,6,1|dxsl00,110,11,0|e7d3rz,110,11,0|e7d3s0,111,6,1|eggszz,111,6,1|eggt00,110,11,0|eq36fz,110,11,0|eq36g0,111,6,1|eytwzz,111,6,1|eytx00,110,11,0|f9jbzz,110,11,0|f9jc00,111,6,1|fhgfvz,111,6,1|fhgfw0,110,11,0|fszbzz,110,11,0|fszc00,111,6,1|g1z93z,111,6,1|g1z940,110,11,0|gbhx7z,110,11,0|gbhx80,111,6,1|gk4yfz,111,6,1|gk4yg0,110,11,0|gtph7z,110,11,0|gtph80,111,6,1|h3kyfz,111,6,1|h3kyg0,110,11,0|hcfjvz,110,11,0|hcfjw0,111,6,1|hm5h3z,111,6,1|hm5h40,110,11,0|hvrujz,110,11,0|hvruk0,111,6,1|i4evrz,111,6,1|i4evs0,110,11,0|ie8qnz,110,11,0|ie8qo0,111,6,1|io2d7z,111,6,1|io2d80,110,11,0|iwytbz,110,11,0|iwytc0,111,6,1|j6fh7z,111,6,1|j6fh80,110,11,0|jfovzz,110,11,0|jfow00,111,6,1|jofmjz,111,6,1|jofmk0,110,11,0|jyeynz,110,11,0|jyeyo0,111,6,1|k88l7z,111,6,1|k88l80,110,11,0|kh51bz,110,11,0|kh51c0,111,6,1|kqlp7z,111,6,1|kqlp80,110,11,0|kzv3zz,110,11,0|kzv400,111,6,1|l8lujz,111,6,1|l8luk0,110,11,0|liy5bz,110,11,0|liy5c0,111,6,1|lset7z,111,6,1|lset80,110,11,0|m1o7zz,110,11,0|m1o800,111,6,1|marx7z,111,6,1|marx80,110,11,0|mkeanz,110,11,0|mkeao0,111,6,1|mvat7z,111,6,1|mvat80,110,11,0|n34dbz,110,11,0|n34dc0,111,6,1|ne0vvz,111,6,1|ne0vw0,110,11,0|nlufzz,110,11,0|nlug00,111,6,1|nwqyjz,111,6,1|nwqyk0,110,11,0|o4kinz,110,11,0|o4kio0,111,6,1|oftzvz,111,6,1|oftzw0,110,11,0|onalbz,110,11,0|onalc0,111,6,1|oyk2jz,111,6,1|oyk2k0,110,11,0|p60nzz,110,11,0|p60o00,111,6,1|pha57z,111,6,1|pha580,110,11,0|pp3pbz,110,11,0|pp3pc0,111,6,1|q007vz,111,6,1|q007w0,110,11,0|q7trzz,110,11,0|q7ts00,111,6,1|qiqajz,111,6,1|qiqak0,110,11,0|qqjunz,110,11,0|qqjuo0,111,6,1|r1tbvz,111,6,1|r1tbw0,110,11,0|r99xbz,110,11,0|r99xc0,111,6,1|rkjejz,111,6,1|rkjek0,110,11,0|rrzzzz,110,11,0|rs0000,111,6,1|s39h7z,111,6,1|s39h80,110,11,0|sb31bz,110,11,0|sb31c0,111,6,1|slzjvz,111,6,1|slzjw0,110,11,0|stt3zz,110,11,0|stt400,111,6,1|t4pmjz,111,6,1|t4pmk0,110,11,0|tcj6nz,110,11,0|tcj6o0,111,6,1|tnfp7z,111,6,1|tnfp80,110,11,0|tv99bz,110,11,0|tv99c0,111,6,1|u6iqjz,111,6,1|u6iqk0,110,11,0|udzbzz,110,11,0|udzc00,111,6,1|up8t7z,111,6,1|up8t80,110,11,0|uwpenz,110,11,0|uwpeo0,111,6,1|v7yvvz,111,6,1|v7yvw0,110,11,0|vfsfzz,110,11,0|vfsg00,111,6,1|vqoyjz,111,6,1|vqoyk0,110,11,0|vyiinz,110,11,0|vyiio0,111,6,1|w9f17z,111,6,1|w9f180,110,11,0|wh8lbz,110,11,0|wh8lc0,111,6,1|wsi2jz,111,6,1|wsi2k0,110,11,0|wzynzz,110,11,0|wzyo00,111,6,1|xb857z,111,6,1|xb8580,110,11,0|xioqnz,110,11,0|xioqo0,111,6,1|xty7vz,111,6,1|xty7w0,110,11,0|y1etbz,110,11,0|y1etc0,111,6,1|ycoajz,111,6,1|ycoak0,110,11,0|ykhunz,110,11,0|ykhuo0,111,6,1|yved7z,111,6,1|yved80,110,11,0|z37xbz,110,11,0|z37xc0,111,6,1|ze4fvz,111,6,1|ze4fw0,110,11,0\",\"Asia/Kabul|,0,251,0|-15r1m5c,105,209,0|-d1pkg1,105,209,0|-d1pkg0,124,252,0\",\"Asia/Kamchatka|,0,253,0|-olrupo,90,192,0|-kmrqk1,90,192,0|-kmrqk0,102,200,0|5vahbz,102,200,0|5vahc0,103,201,1|64pajz,103,201,1|64pak0,102,200,0|6e2enz,102,200,0|6e2eo0,103,201,1|6nh7vz,103,201,1|6nh7w0,102,200,0|6wubzz,102,200,0|6wuc00,103,201,1|76957z,103,201,1|769580,102,200,0|7fo3zz,102,200,0|7fo400,103,201,1|7p1avz,103,201,1|7p1aw0,102,200,0|7yec7z,102,200,0|7yec80,103,201,1|87rdjz,103,201,1|87rdk0,102,200,0|8h4evz,102,200,0|8h4ew0,103,201,1|8qhg7z,103,201,1|8qhg80,102,200,0|8zuhjz,102,200,0|8zuhk0,103,201,1|997ivz,103,201,1|997iw0,102,200,0|9ikk7z,102,200,0|9ikk80,103,201,1|9rxljz,103,201,1|9rxlk0,102,200,0|a1amvz,102,200,0|a1amw0,103,201,1|aano7z,103,201,1|aano80,102,200,0|ak0pjz,102,200,0|ak0pk0,103,201,1|atqpjz,103,201,1|atqpk0,102,200,0|b33qvz,102,200,0|b33qw0,102,200,1|bcguzz,102,200,1|bcgv00,90,192,0|bi89nz,90,192,0|bi89o0,102,200,0|blttjz,102,200,0|blttk0,103,201,1|bv6uvz,103,201,1|bv6uw0,102,200,0|c4jw7z,102,200,0|c4jw80,103,201,1|cdwxjz,103,201,1|cdwxk0,102,200,0|cn9yvz,102,200,0|cn9yw0,103,201,1|cwn07z,103,201,1|cwn080,102,200,0|d601jz,102,200,0|d601k0,103,201,1|dfd2vz,103,201,1|dfd2w0,102,200,0|dp32vz,102,200,0|dp32w0,103,201,1|dzvyvz,103,201,1|dzvyw0,102,200,0|e7t5jz,102,200,0|e7t5k0,103,201,1|eim1jz,103,201,1|eim1k0,102,200,0|eqj87z,102,200,0|eqj880,103,201,1|f1c47z,103,201,1|f1c480,102,200,0|f99avz,102,200,0|f99aw0,103,201,1|fkf5jz,103,201,1|fkf5k0,102,200,0|frzdjz,102,200,0|frzdk0,103,201,1|g3587z,103,201,1|g35880,102,200,0|gapg7z,102,200,0|gapg80,103,201,1|glvavz,103,201,1|glvaw0,102,200,0|gtshjz,102,200,0|gtshk0,103,201,1|h4ldjz,103,201,1|h4ldk0,102,200,0|hcik7z,102,200,0|hcik80,103,201,1|hnbg7z,103,201,1|hnbg80,102,200,0|hv8mvz,102,200,0|hv8mw0,103,201,1|i6ehjz,103,201,1|i6ehk0,102,200,0|idypjz,102,200,0|idypk0,103,201,1|ip4k7z,103,201,1|ip4k80,102,200,0|iwos7z,102,200,0|iwos80,103,201,1|j7umvz,103,201,1|j7umw0,102,200,0|jfeuvz,102,200,0|jfeuw0,103,201,1|jqkpjz,103,201,1|jqkpk0,102,200,0|jyhw7z,102,200,0|jyhw80,103,201,1|k9as7z,103,201,1|k9as80,102,200,0|kh7yvz,102,200,0|kh7yw0,103,201,1|ks0uvz,103,201,1|ks0uw0,102,200,0|kzy1jz,102,200,0|kzy1k0,102,200,1|lb3yzz,102,200,1|lb3z00,90,192,0|lio6zz,90,192,0|lio700,102,200,0\",\"Asia/Karachi|,0,254,0|-wvpb30,108,228,0|-e9lba1,108,228,0|-e9lba0,109,229,1|-cmya21,109,229,1|-cmya20,108,228,0|-9j0km1,108,228,0|-9j0km0,92,194,0|n33fz,92,194,0|n33g0,125,194,0|gu5u3z,125,194,0|gu5u40,126,196,1|h3isnz,126,196,1|h3iso0,125,194,0|k1qy3z,125,194,0|k1qy40,126,196,1|k9m7bz,126,196,1|k9m7c0,125,194,0|ki3u3z,125,194,0|ki3u40,126,196,1|kse4nz,126,196,1|kse4o0,125,194,0\",\"Asia/Kathmandu|,0,255,0|-q3gt4s,108,228,0|8clspz,108,228,0|8clsq0,127,256,0\",\"Asia/Khandyga|,0,257,0|-q4cjrp,89,191,0|-kmri81,89,191,0|-kmri80,107,224,0|5vapnz,107,224,0|5vapo0,93,195,1|64pivz,93,195,1|64piw0,107,224,0|6e2mzz,107,224,0|6e2n00,93,195,1|6nhg7z,93,195,1|6nhg80,107,224,0|6wukbz,107,224,0|6wukc0,93,195,1|769djz,93,195,1|769dk0,107,224,0|7focbz,107,224,0|7focc0,93,195,1|7p1j7z,93,195,1|7p1j80,107,224,0|7yekjz,107,224,0|7yekk0,93,195,1|87rlvz,93,195,1|87rlw0,107,224,0|8h4n7z,107,224,0|8h4n80,93,195,1|8qhojz,93,195,1|8qhok0,107,224,0|8zupvz,107,224,0|8zupw0,93,195,1|997r7z,93,195,1|997r80,107,224,0|9iksjz,107,224,0|9iksk0,93,195,1|9rxtvz,93,195,1|9rxtw0,107,224,0|a1av7z,107,224,0|a1av80,93,195,1|aanwjz,93,195,1|aanwk0,107,224,0|ak0xvz,107,224,0|ak0xw0,93,195,1|atqxvz,93,195,1|atqxw0,107,224,0|b33z7z,107,224,0|b33z80,107,224,1|bch3bz,107,224,1|bch3c0,89,191,0|bi8hzz,89,191,0|bi8i00,107,224,0|blu1vz,107,224,0|blu1w0,93,195,1|bv737z,93,195,1|bv7380,107,224,0|c4k4jz,107,224,0|c4k4k0,93,195,1|cdx5vz,93,195,1|cdx5w0,107,224,0|cna77z,107,224,0|cna780,93,195,1|cwn8jz,93,195,1|cwn8k0,107,224,0|d609vz,107,224,0|d609w0,93,195,1|dfdb7z,93,195,1|dfdb80,107,224,0|dp3b7z,107,224,0|dp3b80,93,195,1|dzw77z,93,195,1|dzw780,107,224,0|e7tdvz,107,224,0|e7tdw0,93,195,1|eim9vz,93,195,1|eim9w0,107,224,0|eqjgjz,107,224,0|eqjgk0,93,195,1|f1ccjz,93,195,1|f1cck0,107,224,0|f99j7z,107,224,0|f99j80,93,195,1|fkfdvz,93,195,1|fkfdw0,107,224,0|frzlvz,107,224,0|frzlw0,93,195,1|g35gjz,93,195,1|g35gk0,107,224,0|gapojz,107,224,0|gapok0,93,195,1|glvj7z,93,195,1|glvj80,107,224,0|gtspvz,107,224,0|gtspw0,93,195,1|h4llvz,93,195,1|h4llw0,107,224,0|hcisjz,107,224,0|hcisk0,93,195,1|hnbojz,93,195,1|hnbok0,107,224,0|hqrlnz,107,224,0|hqrlo0,93,195,0|hv8sfz,93,195,0|hv8sg0,90,192,1|i6en3z,90,192,1|i6en40,93,195,0|idyv3z,93,195,0|idyv40,90,192,1|ip4prz,90,192,1|ip4ps0,93,195,0|iwoxrz,93,195,0|iwoxs0,90,192,1|j7usfz,90,192,1|j7usg0,93,195,0|jff0fz,93,195,0|jff0g0,90,192,1|jqkv3z,90,192,1|jqkv40,93,195,0|jyi1rz,93,195,0|jyi1s0,90,192,1|k9axrz,90,192,1|k9axs0,93,195,0|kh84fz,93,195,0|kh84g0,90,192,1|ks10fz,90,192,1|ks10g0,93,195,0|kzy73z,93,195,0|kzy740,90,192,1|lb41rz,90,192,1|lb41s0,93,195,0|lio9rz,93,195,0|lio9s0,90,192,0|lreurz,90,192,0|lreus0,93,195,0|ne0cfz,93,195,0|ne0cg0,107,224,0\",\"Asia/Kolkata|,0,258,0|-1oaa314,77,232,0|-1g6thox,77,232,0|-1g6thow,21,259,0|-xehavb,21,259,0|-xehava,110,228,0|-eqtom1,110,228,0|-eqtom0,109,229,1|-ef78q1,109,229,1|-ef78q0,110,228,0|-e9lba1,110,228,0|-e9lba0,109,229,1|-cmya21,109,229,1|-cmya20,110,228,0\",\"Asia/Krasnoyarsk|,0,260,0|-q37l72,96,196,0|-kmrco1,96,196,0|-kmrco0,91,193,0|5vav7z,91,193,0|5vav80,89,191,1|64pofz,89,191,1|64pog0,91,193,0|6e2sjz,91,193,0|6e2sk0,89,191,1|6nhlrz,89,191,1|6nhls0,91,193,0|6wupvz,91,193,0|6wupw0,89,191,1|769j3z,89,191,1|769j40,91,193,0|7fohvz,91,193,0|7fohw0,89,191,1|7p1orz,89,191,1|7p1os0,91,193,0|7yeq3z,91,193,0|7yeq40,89,191,1|87rrfz,89,191,1|87rrg0,91,193,0|8h4srz,91,193,0|8h4ss0,89,191,1|8qhu3z,89,191,1|8qhu40,91,193,0|8zuvfz,91,193,0|8zuvg0,89,191,1|997wrz,89,191,1|997ws0,91,193,0|9iky3z,91,193,0|9iky40,89,191,1|9rxzfz,89,191,1|9rxzg0,91,193,0|a1b0rz,91,193,0|a1b0s0,89,191,1|aao23z,89,191,1|aao240,91,193,0|ak13fz,91,193,0|ak13g0,89,191,1|atr3fz,89,191,1|atr3g0,91,193,0|b344rz,91,193,0|b344s0,91,193,1|bch8vz,91,193,1|bch8w0,96,196,0|bi8njz,96,196,0|bi8nk0,91,193,0|blu7fz,91,193,0|blu7g0,89,191,1|bv78rz,89,191,1|bv78s0,91,193,0|c4ka3z,91,193,0|c4ka40,89,191,1|cdxbfz,89,191,1|cdxbg0,91,193,0|cnacrz,91,193,0|cnacs0,89,191,1|cwne3z,89,191,1|cwne40,91,193,0|d60ffz,91,193,0|d60fg0,89,191,1|dfdgrz,89,191,1|dfdgs0,91,193,0|dp3grz,91,193,0|dp3gs0,89,191,1|dzwcrz,89,191,1|dzwcs0,91,193,0|e7tjfz,91,193,0|e7tjg0,89,191,1|eimffz,89,191,1|eimfg0,91,193,0|eqjm3z,91,193,0|eqjm40,89,191,1|f1ci3z,89,191,1|f1ci40,91,193,0|f99orz,91,193,0|f99os0,89,191,1|fkfjfz,89,191,1|fkfjg0,91,193,0|frzrfz,91,193,0|frzrg0,89,191,1|g35m3z,89,191,1|g35m40,91,193,0|gapu3z,91,193,0|gapu40,89,191,1|glvorz,89,191,1|glvos0,91,193,0|gtsvfz,91,193,0|gtsvg0,89,191,1|h4lrfz,89,191,1|h4lrg0,91,193,0|hciy3z,91,193,0|hciy40,89,191,1|hnbu3z,89,191,1|hnbu40,91,193,0|hv90rz,91,193,0|hv90s0,89,191,1|i6evfz,89,191,1|i6evg0,91,193,0|idz3fz,91,193,0|idz3g0,89,191,1|ip4y3z,89,191,1|ip4y40,91,193,0|iwp63z,91,193,0|iwp640,89,191,1|j7v0rz,89,191,1|j7v0s0,91,193,0|jff8rz,91,193,0|jff8s0,89,191,1|jql3fz,89,191,1|jql3g0,91,193,0|jyia3z,91,193,0|jyia40,89,191,1|k9b63z,89,191,1|k9b640,91,193,0|kh8crz,91,193,0|kh8cs0,89,191,1|ks18rz,89,191,1|ks18s0,91,193,0|kzyffz,91,193,0|kzyfg0,89,191,1|lb4a3z,89,191,1|lb4a40,91,193,0|lioi3z,91,193,0|lioi40,89,191,0|ne0hzz,89,191,0|ne0i00,91,193,0\",\"Asia/Kuala_Lumpur|,0,261,0|-100ew5y,85,262,0|-xphpwe,85,262,0|-xphpwd,91,193,0|-jb6gs1,91,193,0|-jb6gs0,118,246,1|-hquppd,118,246,1|-hquppc,118,246,0|-esddpd,118,246,0|-esddpc,106,222,0|-ejqa61,106,222,0|-ejqa60,107,224,0|-conl01,107,224,0|-conl00,106,222,0|69g35z,106,222,0|69g360,89,191,0\",\"Asia/Kuching|,0,263,0|-mvof3k,106,222,0|-jb6i61,106,222,0|-jb6i60,89,191,0|-hwgm81,89,191,0|-hwgm80,128,264,1|-hrs4hd,128,264,1|-hrs4hc,89,191,0|-hdmu81,89,191,0|-hdmu80,128,264,1|-h8ychd,128,264,1|-h8ychc,89,191,0|-guuww1,89,191,0|-guuww0,128,264,1|-gq6f5d,128,264,1|-gq6f5c,89,191,0|-gc2zk1,89,191,0|-gc2zk0,128,264,1|-g7ehtd,128,264,1|-g7ehtc,89,191,0|-ftb281,89,191,0|-ftb280,128,264,1|-fomkhd,128,264,1|-fomkhc,89,191,0|-faha81,89,191,0|-faha80,128,264,1|-f5sshd,128,264,1|-f5sshc,89,191,0|-erpcw1,89,191,0|-erpcw0,128,264,1|-en0v5d,128,264,1|-en0v5c,89,191,0|-ejqbk1,89,191,0|-ejqbk0,107,224,0|-conl01,107,224,0|-conl00,89,191,0\",\"Asia/Kuwait|,0,203,0|-bwgbbg,100,6,0\",\"Asia/Macau|,0,265,0|-y0i2cy,45,191,0|-emm3o1,45,191,0|-emm3o0,107,224,0|-efxfs1,107,224,0|-efxfs0,93,195,1|-e5lak1,93,195,1|-e5lak0,107,224,0|-dx5ig1,107,224,0|-dx5ig0,93,195,1|-dpa981,93,195,1|-dpa980,107,224,0|-cnoec1,107,224,0|-cnoec0,45,191,0|-ccrt01,45,191,0|-ccrt00,46,224,1|-c4wh01,46,224,1|-c4wh00,45,191,0|-buk901,45,191,0|-buk900,46,224,1|-bizl01,46,224,1|-bizl00,45,191,0|-bb2ec1,45,191,0|-bb2ec0,46,224,1|-b1pd01,46,224,1|-b1pd00,45,191,0|-atu101,45,191,0|-atu100,46,224,1|-aj1501,46,224,1|-aj1500,45,191,0|-ab3yc1,45,191,0|-ab3yc0,46,224,1|-a0b2c1,46,224,1|-a0b2c0,45,191,0|-9sdvo1,45,191,0|-9sdvo0,46,224,1|-9hj501,46,224,1|-9hj500,45,191,0|-99auc1,45,191,0|-99auc0,46,224,1|-8yhyc1,46,224,1|-8yhyc0,45,191,0|-8qkro1,45,191,0|-8qkro0,46,224,1|-8frvo1,46,224,1|-8frvo0,45,191,0|-88kmc1,45,191,0|-88kmc0,46,224,1|-7x1t01,46,224,1|-7x1t00,45,191,0|-7pujo1,45,191,0|-7pujo0,46,224,1|-7dyro1,46,224,1|-7dyro0,45,191,0|-774h01,45,191,0|-774h00,46,224,1|-6v8fa1,46,224,1|-6v8fa0,45,191,0|-6o1361,45,191,0|-6o1360,46,224,1|-6cicm1,46,224,1|-6cicm0,45,191,0|-65b0i1,45,191,0|-65b0i0,46,224,1|-5ts9y1,46,224,1|-5ts9y0,45,191,0|-5mkxu1,45,191,0|-5mkxu0,46,224,1|-5b27a1,46,224,1|-5b27a0,45,191,0|-53uv61,45,191,0|-53uv60,46,224,1|-4rz5y1,46,224,1|-4rz5y0,45,191,0|-4l4si1,45,191,0|-4l4si0,46,224,1|-4993a1,46,224,1|-4993a0,45,191,0|-42epu1,45,191,0|-42epu0,46,224,1|-3qj0m1,46,224,1|-3qj0m0,45,191,0|-3jboi1,45,191,0|-3jboi0,46,224,1|-37sxy1,46,224,1|-37sxy0,45,191,0|-30llu1,45,191,0|-30llu0,46,224,1|-2p2va1,46,224,1|-2p2va0,45,191,0|-2gfoi1,45,191,0|-2gfoi0,46,224,1|-272sq1,46,224,1|-272sq0,45,191,0|-1xplu1,45,191,0|-1xplu0,46,224,1|-1ocq21,46,224,1|-1ocq20,45,191,0|-1ezj61,45,191,0|-1ezj60,46,224,1|-159ly1,46,224,1|-159ly0,45,191,0|-vwhu1,45,191,0|-vwhu0,46,224,1|-mjja1,46,224,1|-mjja0,45,191,0|-d6f61,45,191,0|-d6f60,46,224,1|-3tgm1,46,224,1|-3tgm0,45,191,0|5jnhz,45,191,0|5jni0,46,224,1|ewm1z,46,224,1|ewm20,45,191,0|o9q5z,45,191,0|o9q60,46,224,1|xmopz,46,224,1|xmoq0,45,191,0|16zstz,45,191,0|16zsu0,46,224,1|1gpq1z,46,224,1|1gpq20,45,191,0|1q2u5z,45,191,0|1q2u60,46,224,1|1zfspz,46,224,1|1zfsq0,45,191,0|231i5z,45,191,0|231i60,46,224,1|2i5vdz,46,224,1|2i5ve0,45,191,0|2rizhz,45,191,0|2rizi0,46,224,1|30vy1z,46,224,1|30vy20,45,191,0|3a925z,45,191,0|3a9260,46,224,1|3jm0pz,46,224,1|3jm0q0,45,191,0|4vv4tz,45,191,0|4vv4u0,46,224,1|5457dz,46,224,1|5457e0,45,191,0\",\"Asia/Magadan|,0,266,0|-nu1nxc,93,195,0|-kmrns1,93,195,0|-kmrns0,90,192,0|5vak3z,90,192,0|5vak40,102,200,1|64pdbz,102,200,1|64pdc0,90,192,0|6e2hfz,90,192,0|6e2hg0,102,200,1|6nhanz,102,200,1|6nhao0,90,192,0|6wuerz,90,192,0|6wues0,102,200,1|7697zz,102,200,1|769800,90,192,0|7fo6rz,90,192,0|7fo6s0,102,200,1|7p1dnz,102,200,1|7p1do0,90,192,0|7yeezz,90,192,0|7yef00,102,200,1|87rgbz,102,200,1|87rgc0,90,192,0|8h4hnz,90,192,0|8h4ho0,102,200,1|8qhizz,102,200,1|8qhj00,90,192,0|8zukbz,90,192,0|8zukc0,102,200,1|997lnz,102,200,1|997lo0,90,192,0|9ikmzz,90,192,0|9ikn00,102,200,1|9rxobz,102,200,1|9rxoc0,90,192,0|a1apnz,90,192,0|a1apo0,102,200,1|aanqzz,102,200,1|aanr00,90,192,0|ak0sbz,90,192,0|ak0sc0,102,200,1|atqsbz,102,200,1|atqsc0,90,192,0|b33tnz,90,192,0|b33to0,90,192,1|bcgxrz,90,192,1|bcgxs0,93,195,0|bi8cfz,93,195,0|bi8cg0,90,192,0|bltwbz,90,192,0|bltwc0,102,200,1|bv6xnz,102,200,1|bv6xo0,90,192,0|c4jyzz,90,192,0|c4jz00,102,200,1|cdx0bz,102,200,1|cdx0c0,90,192,0|cna1nz,90,192,0|cna1o0,102,200,1|cwn2zz,102,200,1|cwn300,90,192,0|d604bz,90,192,0|d604c0,102,200,1|dfd5nz,102,200,1|dfd5o0,90,192,0|dp35nz,90,192,0|dp35o0,102,200,1|dzw1nz,102,200,1|dzw1o0,90,192,0|e7t8bz,90,192,0|e7t8c0,102,200,1|eim4bz,102,200,1|eim4c0,90,192,0|eqjazz,90,192,0|eqjb00,102,200,1|f1c6zz,102,200,1|f1c700,90,192,0|f99dnz,90,192,0|f99do0,102,200,1|fkf8bz,102,200,1|fkf8c0,90,192,0|frzgbz,90,192,0|frzgc0,102,200,1|g35azz,102,200,1|g35b00,90,192,0|gapizz,90,192,0|gapj00,102,200,1|glvdnz,102,200,1|glvdo0,90,192,0|gtskbz,90,192,0|gtskc0,102,200,1|h4lgbz,102,200,1|h4lgc0,90,192,0|hcimzz,90,192,0|hcin00,102,200,1|hnbizz,102,200,1|hnbj00,90,192,0|hv8pnz,90,192,0|hv8po0,102,200,1|i6ekbz,102,200,1|i6ekc0,90,192,0|idysbz,90,192,0|idysc0,102,200,1|ip4mzz,102,200,1|ip4n00,90,192,0|iwouzz,90,192,0|iwov00,102,200,1|j7upnz,102,200,1|j7upo0,90,192,0|jfexnz,90,192,0|jfexo0,102,200,1|jqksbz,102,200,1|jqksc0,90,192,0|jyhyzz,90,192,0|jyhz00,102,200,1|k9auzz,102,200,1|k9av00,90,192,0|kh81nz,90,192,0|kh81o0,102,200,1|ks0xnz,102,200,1|ks0xo0,90,192,0|kzy4bz,90,192,0|kzy4c0,102,200,1|lb3yzz,102,200,1|lb3z00,90,192,0|lio6zz,90,192,0|lio700,102,200,0|ne06vz,102,200,0|ne06w0,93,195,0|o63gfz,93,195,0|o63gg0,90,192,0\",\"Asia/Makassar|,0,267,0|-q3gzg0,21,267,0|-jebi41,21,267,0|-jebi40,89,191,0|-ek3a81,89,191,0|-ek3a80,107,224,0|-co37o1,107,224,0|-co37o0,129,191,0\",\"Asia/Manila|,0,268,0|-1t8ix2o,0,269,0|-10va3qp,0,269,0|-10va3qo,51,191,0|-hb5y81,51,191,0|-hb5y80,57,224,1|-h6fno1,57,224,1|-h6fno0,51,191,0|-efxa81,51,191,0|-efxa80,116,224,0|-d4ux01,116,224,0|-d4ux00,51,191,0|-87fsw1,51,191,0|-87fsw0,57,224,1|-83bqc1,57,224,1|-83bqc0,51,191,0|4aen3z,51,191,0|4aen40,57,224,1|4jtgbz,57,224,1|4jtgc0,51,191,0\",\"Asia/Muscat|,0,234,0|-q3gnko,105,209,0\",\"Asia/Nicosia|,0,270,0|-p4bq6g,15,11,0|2r67rz,15,11,0|2r67s0,16,6,1|30j6bz,16,6,1|30j6c0,15,11,0|3bn93z,15,11,0|3bn940,16,6,1|3jb3nz,16,6,1|3jb3o0,15,11,0|3s9efz,15,11,0|3s9eg0,16,6,1|419ebz,16,6,1|419ec0,15,11,0|4azh3z,15,11,0|4azh40,16,6,1|4keabz,16,6,1|4keac0,15,11,0|4tpjrz,15,11,0|4tpjs0,16,6,1|532ibz,16,6,1|532ic0,15,11,0|5csl3z,15,11,0|5csl40,16,6,1|5lskzz,16,6,1|5lsl00,15,11,0|5v5p3z,15,11,0|5v5p40,16,6,1|64innz,16,6,1|64ino0,15,11,0|6dvrrz,15,11,0|6dvrs0,16,6,1|6n8qbz,16,6,1|6n8qc0,15,11,0|6wlufz,15,11,0|6wlug0,16,6,1|75yszz,16,6,1|75yt00,15,11,0|7fbx3z,15,11,0|7fbx40,16,6,1|7p1ubz,16,6,1|7p1uc0,15,11,0|7yeyfz,15,11,0|7yeyg0,16,6,1|87rwzz,16,6,1|87rx00,15,11,0|8h513z,15,11,0|8h5140,16,6,1|8qhznz,16,6,1|8qhzo0,15,11,0|8zv3rz,15,11,0|8zv3s0,16,6,1|9982bz,16,6,1|9982c0,15,11,0|9il6fz,15,11,0|9il6g0,16,6,1|9ry4zz,16,6,1|9ry500,15,11,0|a1b93z,15,11,0|a1b940,16,6,1|aao7nz,16,6,1|aao7o0,15,11,0|ak1brz,15,11,0|ak1bs0,16,6,1|atr8zz,16,6,1|atr900,15,11,0|b34d3z,15,11,0|b34d40,16,6,1|bchbnz,16,6,1|bchbo0,15,11,0|blufrz,15,11,0|blufs0,16,6,1|bv7ebz,16,6,1|bv7ec0,15,11,0|c4kifz,15,11,0|c4kig0,16,6,1|cdxgzz,16,6,1|cdxh00,15,11,0|cnal3z,15,11,0|cnal40,16,6,1|cwnjnz,16,6,1|cwnjo0,15,11,0|d60nrz,15,11,0|d60ns0,16,6,1|dfdmbz,16,6,1|dfdmc0,15,11,0|dp3p3z,15,11,0|dp3p40,16,6,1|dygnnz,16,6,1|dygno0,15,11,0|e7trrz,15,11,0|e7trs0,16,6,1|eh6qbz,16,6,1|eh6qc0,15,11,0|eqjufz,15,11,0|eqjug0,16,6,1|f1cyrz,16,6,1|f1cys0,15,11,0|f9a5fz,15,11,0|f9a5g0,16,6,1|fkg03z,16,6,1|fkg040,15,11,0|fs083z,15,11,0|fs0840,16,6,1|g362rz,16,6,1|g362s0,15,11,0|gaqarz,15,11,0|gaqas0,16,6,1|glw5fz,16,6,1|glw5g0,15,11,0|gttc3z,15,11,0|gttc40,16,6,1|h4m83z,16,6,1|h4m840,15,11,0|hcjerz,15,11,0|hcjes0,16,6,1|hncarz,16,6,1|hncas0,15,11,0|hv9hfz,15,11,0|hv9hg0,16,6,1|i6fc3z,16,6,1|i6fc40,15,11,0|idzk3z,15,11,0|idzk40,16,6,1|ip5erz,16,6,1|ip5es0,15,11,0|iwpmrz,15,11,0|iwpms0,16,6,1|j7vhfz,16,6,1|j7vhg0,15,11,0|jffpfz,15,11,0|jffpg0,16,6,1|jqlk3z,16,6,1|jqlk40,15,11,0|jyiqrz,15,11,0|jyiqs0,16,6,1|k9bmrz,16,6,1|k9bms0,15,11,0|kh8tfz,15,11,0|kh8tg0,16,6,1|ks1pfz,16,6,1|ks1pg0,15,11,0|kzyw3z,15,11,0|kzyw40,16,6,1|lb4qrz,16,6,1|lb4qs0,15,11,0|lioyrz,15,11,0|lioys0,16,6,1|ltutfz,16,6,1|ltutg0,15,11,0|m1f1fz,15,11,0|m1f1g0,16,6,1|mckw3z,16,6,1|mckw40,15,11,0|mki2rz,15,11,0|mki2s0,16,6,1|mvayrz,16,6,1|mvays0,15,11,0|n385fz,15,11,0|n385g0,16,6,1|ne11fz,16,6,1|ne11g0,15,11,0|nly83z,15,11,0|nly840,16,6,1|nwr43z,16,6,1|nwr440,15,11,0|o4oarz,15,11,0|o4oas0,16,6,1|ofu5fz,16,6,1|ofu5g0,15,11,0|onedfz,15,11,0|onedg0,16,6,1|oyk83z,16,6,1|oyk840,15,11,0|p64g3z,15,11,0|p64g40,16,6,1|phaarz,16,6,1|phaas0,15,11,0|pp7hfz,15,11,0|pp7hg0,16,6,1|q00dfz,16,6,1|q00dg0,15,11,0|q7xk3z,15,11,0|q7xk40,16,6,1|qiqg3z,16,6,1|qiqg40,15,11,0|qqnmrz,15,11,0|qqnms0,16,6,1|r1thfz,16,6,1|r1thg0,15,11,0|r9dpfz,15,11,0|r9dpg0,16,6,1|rkjk3z,16,6,1|rkjk40,15,11,0|rs3s3z,15,11,0|rs3s40,16,6,1|s39mrz,16,6,1|s39ms0,15,11,0|sb6tfz,15,11,0|sb6tg0,16,6,1|slzpfz,16,6,1|slzpg0,15,11,0|stww3z,15,11,0|stww40,16,6,1|t4ps3z,16,6,1|t4ps40,15,11,0|tcmyrz,15,11,0|tcmys0,16,6,1|tnfurz,16,6,1|tnfus0,15,11,0|tvd1fz,15,11,0|tvd1g0,16,6,1|u6iw3z,16,6,1|u6iw40,15,11,0|ue343z,15,11,0|ue3440,16,6,1|up8yrz,16,6,1|up8ys0,15,11,0|uwt6rz,15,11,0|uwt6s0,16,6,1|v7z1fz,16,6,1|v7z1g0,15,11,0|vfw83z,15,11,0|vfw840,16,6,1|vqp43z,16,6,1|vqp440,15,11,0|vymarz,15,11,0|vymas0,16,6,1|w9f6rz,16,6,1|w9f6s0,15,11,0|whcdfz,15,11,0|whcdg0,16,6,1|wsi83z,16,6,1|wsi840,15,11,0|x02g3z,15,11,0|x02g40,16,6,1|xb8arz,16,6,1|xb8as0,15,11,0|xisirz,15,11,0|xisis0,16,6,1|xtydfz,16,6,1|xtydg0,15,11,0|y1ilfz,15,11,0|y1ilg0,16,6,1|ycog3z,16,6,1|ycog40,15,11,0|yklmrz,15,11,0|yklms0,16,6,1|yveirz,16,6,1|yveis0,15,11,0|z3bpfz,15,11,0|z3bpg0,16,6,1|ze4lfz,16,6,1|ze4lg0,15,11,0\",\"Asia/Novokuznetsk|,0,271,0|-nu36tc,96,196,0|-kmrco1,96,196,0|-kmrco0,91,193,0|5vav7z,91,193,0|5vav80,89,191,1|64pofz,89,191,1|64pog0,91,193,0|6e2sjz,91,193,0|6e2sk0,89,191,1|6nhlrz,89,191,1|6nhls0,91,193,0|6wupvz,91,193,0|6wupw0,89,191,1|769j3z,89,191,1|769j40,91,193,0|7fohvz,91,193,0|7fohw0,89,191,1|7p1orz,89,191,1|7p1os0,91,193,0|7yeq3z,91,193,0|7yeq40,89,191,1|87rrfz,89,191,1|87rrg0,91,193,0|8h4srz,91,193,0|8h4ss0,89,191,1|8qhu3z,89,191,1|8qhu40,91,193,0|8zuvfz,91,193,0|8zuvg0,89,191,1|997wrz,89,191,1|997ws0,91,193,0|9iky3z,91,193,0|9iky40,89,191,1|9rxzfz,89,191,1|9rxzg0,91,193,0|a1b0rz,91,193,0|a1b0s0,89,191,1|aao23z,89,191,1|aao240,91,193,0|ak13fz,91,193,0|ak13g0,89,191,1|atr3fz,89,191,1|atr3g0,91,193,0|b344rz,91,193,0|b344s0,91,193,1|bch8vz,91,193,1|bch8w0,96,196,0|bi8njz,96,196,0|bi8nk0,91,193,0|blu7fz,91,193,0|blu7g0,89,191,1|bv78rz,89,191,1|bv78s0,91,193,0|c4ka3z,91,193,0|c4ka40,89,191,1|cdxbfz,89,191,1|cdxbg0,91,193,0|cnacrz,91,193,0|cnacs0,89,191,1|cwne3z,89,191,1|cwne40,91,193,0|d60ffz,91,193,0|d60fg0,89,191,1|dfdgrz,89,191,1|dfdgs0,91,193,0|dp3grz,91,193,0|dp3gs0,89,191,1|dzwcrz,89,191,1|dzwcs0,91,193,0|e7tjfz,91,193,0|e7tjg0,89,191,1|eimffz,89,191,1|eimfg0,91,193,0|eqjm3z,91,193,0|eqjm40,89,191,1|f1ci3z,89,191,1|f1ci40,91,193,0|f99orz,91,193,0|f99os0,89,191,1|fkfjfz,89,191,1|fkfjg0,91,193,0|frzrfz,91,193,0|frzrg0,89,191,1|g35m3z,89,191,1|g35m40,91,193,0|gapu3z,91,193,0|gapu40,89,191,1|glvorz,89,191,1|glvos0,91,193,0|gtsvfz,91,193,0|gtsvg0,89,191,1|h4lrfz,89,191,1|h4lrg0,91,193,0|hciy3z,91,193,0|hciy40,89,191,1|hnbu3z,89,191,1|hnbu40,91,193,0|hv90rz,91,193,0|hv90s0,89,191,1|i6evfz,89,191,1|i6evg0,91,193,0|idz3fz,91,193,0|idz3g0,89,191,1|ip4y3z,89,191,1|ip4y40,91,193,0|iwp63z,91,193,0|iwp640,89,191,1|j7v0rz,89,191,1|j7v0s0,91,193,0|jff8rz,91,193,0|jff8s0,89,191,1|jql3fz,89,191,1|jql3g0,91,193,0|jyia3z,91,193,0|jyia40,89,191,1|k9b63z,89,191,1|k9b640,91,193,0|kh8crz,91,193,0|kh8cs0,89,191,1|ks18rz,89,191,1|ks18s0,91,193,0|kzyffz,91,193,0|kzyfg0,91,193,1|lb4cvz,91,193,1|lb4cw0,96,196,0|liokvz,96,196,0|liokw0,91,193,0\",\"Asia/Novosibirsk|,0,272,0|-q4do0s,96,196,0|-kmrco1,96,196,0|-kmrco0,91,193,0|5vav7z,91,193,0|5vav80,89,191,1|64pofz,89,191,1|64pog0,91,193,0|6e2sjz,91,193,0|6e2sk0,89,191,1|6nhlrz,89,191,1|6nhls0,91,193,0|6wupvz,91,193,0|6wupw0,89,191,1|769j3z,89,191,1|769j40,91,193,0|7fohvz,91,193,0|7fohw0,89,191,1|7p1orz,89,191,1|7p1os0,91,193,0|7yeq3z,91,193,0|7yeq40,89,191,1|87rrfz,89,191,1|87rrg0,91,193,0|8h4srz,91,193,0|8h4ss0,89,191,1|8qhu3z,89,191,1|8qhu40,91,193,0|8zuvfz,91,193,0|8zuvg0,89,191,1|997wrz,89,191,1|997ws0,91,193,0|9iky3z,91,193,0|9iky40,89,191,1|9rxzfz,89,191,1|9rxzg0,91,193,0|a1b0rz,91,193,0|a1b0s0,89,191,1|aao23z,89,191,1|aao240,91,193,0|ak13fz,91,193,0|ak13g0,89,191,1|atr3fz,89,191,1|atr3g0,91,193,0|b344rz,91,193,0|b344s0,91,193,1|bch8vz,91,193,1|bch8w0,96,196,0|bi8njz,96,196,0|bi8nk0,91,193,0|blu7fz,91,193,0|blu7g0,89,191,1|bv78rz,89,191,1|bv78s0,91,193,0|c4ka3z,91,193,0|c4ka40,89,191,1|c7fr3z,89,191,1|c7fr40,91,193,1|cdxe7z,91,193,1|cdxe80,96,196,0|cnafjz,96,196,0|cnafk0,91,193,1|cwngvz,91,193,1|cwngw0,96,196,0|d60i7z,96,196,0|d60i80,91,193,1|dfdjjz,91,193,1|dfdjk0,96,196,0|dp3jjz,96,196,0|dp3jk0,91,193,1|dzwfjz,91,193,1|dzwfk0,96,196,0|e7tm7z,96,196,0|e7tm80,91,193,1|eimi7z,91,193,1|eimi80,96,196,0|eqjovz,96,196,0|eqjow0,91,193,1|f1ckvz,91,193,1|f1ckw0,96,196,0|f99rjz,96,196,0|f99rk0,91,193,1|fkfm7z,91,193,1|fkfm80,96,196,0|frzu7z,96,196,0|frzu80,91,193,1|g35ovz,91,193,1|g35ow0,96,196,0|gapwvz,96,196,0|gapww0,91,193,1|glvrjz,91,193,1|glvrk0,96,196,0|gtsy7z,96,196,0|gtsy80,91,193,1|h4lu7z,91,193,1|h4lu80,96,196,0|hcj0vz,96,196,0|hcj0w0,91,193,1|hnbwvz,91,193,1|hnbww0,96,196,0|hv93jz,96,196,0|hv93k0,91,193,1|i6ey7z,91,193,1|i6ey80,96,196,0|idz67z,96,196,0|idz680,91,193,1|ip50vz,91,193,1|ip50w0,96,196,0|iwp8vz,96,196,0|iwp8w0,91,193,1|j7v3jz,91,193,1|j7v3k0,96,196,0|jffbjz,96,196,0|jffbk0,91,193,1|jql67z,91,193,1|jql680,96,196,0|jyicvz,96,196,0|jyicw0,91,193,1|k9b8vz,91,193,1|k9b8w0,96,196,0|kh8fjz,96,196,0|kh8fk0,91,193,1|ks1bjz,91,193,1|ks1bk0,96,196,0|kzyi7z,96,196,0|kzyi80,91,193,1|lb4cvz,91,193,1|lb4cw0,96,196,0|liokvz,96,196,0|liokw0,91,193,0|ne0krz,91,193,0|ne0ks0,96,196,0|oasa7z,96,196,0|oasa80,91,193,0\",\"Asia/Omsk|,0,273,0|-q5xmx6,92,194,0|-kmr9w1,92,194,0|-kmr9w0,96,196,0|5vaxzz,96,196,0|5vay00,91,193,1|64pr7z,91,193,1|64pr80,96,196,0|6e2vbz,96,196,0|6e2vc0,91,193,1|6nhojz,91,193,1|6nhok0,96,196,0|6wusnz,96,196,0|6wuso0,91,193,1|769lvz,91,193,1|769lw0,96,196,0|7foknz,96,196,0|7foko0,91,193,1|7p1rjz,91,193,1|7p1rk0,96,196,0|7yesvz,96,196,0|7yesw0,91,193,1|87ru7z,91,193,1|87ru80,96,196,0|8h4vjz,96,196,0|8h4vk0,91,193,1|8qhwvz,91,193,1|8qhww0,96,196,0|8zuy7z,96,196,0|8zuy80,91,193,1|997zjz,91,193,1|997zk0,96,196,0|9il0vz,96,196,0|9il0w0,91,193,1|9ry27z,91,193,1|9ry280,96,196,0|a1b3jz,96,196,0|a1b3k0,91,193,1|aao4vz,91,193,1|aao4w0,96,196,0|ak167z,96,196,0|ak1680,91,193,1|atr67z,91,193,1|atr680,96,196,0|b347jz,96,196,0|b347k0,96,196,1|bchbnz,96,196,1|bchbo0,92,194,0|bi8qbz,92,194,0|bi8qc0,96,196,0|blua7z,96,196,0|blua80,91,193,1|bv7bjz,91,193,1|bv7bk0,96,196,0|c4kcvz,96,196,0|c4kcw0,91,193,1|cdxe7z,91,193,1|cdxe80,96,196,0|cnafjz,96,196,0|cnafk0,91,193,1|cwngvz,91,193,1|cwngw0,96,196,0|d60i7z,96,196,0|d60i80,91,193,1|dfdjjz,91,193,1|dfdjk0,96,196,0|dp3jjz,96,196,0|dp3jk0,91,193,1|dzwfjz,91,193,1|dzwfk0,96,196,0|e7tm7z,96,196,0|e7tm80,91,193,1|eimi7z,91,193,1|eimi80,96,196,0|eqjovz,96,196,0|eqjow0,91,193,1|f1ckvz,91,193,1|f1ckw0,96,196,0|f99rjz,96,196,0|f99rk0,91,193,1|fkfm7z,91,193,1|fkfm80,96,196,0|frzu7z,96,196,0|frzu80,91,193,1|g35ovz,91,193,1|g35ow0,96,196,0|gapwvz,96,196,0|gapww0,91,193,1|glvrjz,91,193,1|glvrk0,96,196,0|gtsy7z,96,196,0|gtsy80,91,193,1|h4lu7z,91,193,1|h4lu80,96,196,0|hcj0vz,96,196,0|hcj0w0,91,193,1|hnbwvz,91,193,1|hnbww0,96,196,0|hv93jz,96,196,0|hv93k0,91,193,1|i6ey7z,91,193,1|i6ey80,96,196,0|idz67z,96,196,0|idz680,91,193,1|ip50vz,91,193,1|ip50w0,96,196,0|iwp8vz,96,196,0|iwp8w0,91,193,1|j7v3jz,91,193,1|j7v3k0,96,196,0|jffbjz,96,196,0|jffbk0,91,193,1|jql67z,91,193,1|jql680,96,196,0|jyicvz,96,196,0|jyicw0,91,193,1|k9b8vz,91,193,1|k9b8w0,96,196,0|kh8fjz,96,196,0|kh8fk0,91,193,1|ks1bjz,91,193,1|ks1bk0,96,196,0|kzyi7z,96,196,0|kzyi80,91,193,1|lb4cvz,91,193,1|lb4cw0,96,196,0|liokvz,96,196,0|liokw0,91,193,0|ne0krz,91,193,0|ne0ks0,96,196,0\",\"Asia/Oral|,0,274,0|-nu15ic,100,6,0|-kmr4c1,100,6,0|-kmr4c0,92,194,0|5vb0rz,92,194,0|5vb0s0,96,196,1|64ptzz,96,196,1|64pu00,96,196,0|6e2vbz,96,196,0|6e2vc0,96,196,1|6nhrbz,96,196,1|6nhrc0,92,194,0|6wuvfz,92,194,0|6wuvg0,96,196,1|769onz,96,196,1|769oo0,92,194,0|7fonfz,92,194,0|7fong0,96,196,1|7p1ubz,96,196,1|7p1uc0,92,194,0|7yevnz,92,194,0|7yevo0,96,196,1|87rwzz,96,196,1|87rx00,92,194,0|8h4ybz,92,194,0|8h4yc0,96,196,1|8qhznz,96,196,1|8qhzo0,92,194,0|8zv0zz,92,194,0|8zv100,96,196,1|9982bz,96,196,1|9982c0,92,194,0|9il3nz,92,194,0|9il3o0,96,196,1|9ry4zz,96,196,1|9ry500,92,194,0|a1b6bz,92,194,0|a1b6c0,92,194,1|aaoafz,92,194,1|aaoag0,105,209,0|ak1brz,105,209,0|ak1bs0,92,194,1|atrbrz,92,194,1|atrbs0,105,209,0|b34d3z,105,209,0|b34d40,92,194,1|bchefz,92,194,1|bcheg0,105,209,0|bi8t3z,105,209,0|bi8t40,92,194,0|bluczz,92,194,0|blud00,92,194,1|bv7h3z,92,194,1|bv7h40,105,209,0|c4kifz,105,209,0|c4kig0,92,194,1|cdxjrz,92,194,1|cdxjs0,105,209,0|cnal3z,105,209,0|cnal40,92,194,1|cwnmfz,92,194,1|cwnmg0,105,209,0|d60nrz,105,209,0|d60ns0,92,194,1|dfdp3z,92,194,1|dfdp40,105,209,0|dp3p3z,105,209,0|dp3p40,92,194,1|dzwl3z,92,194,1|dzwl40,105,209,0|e7trrz,105,209,0|e7trs0,92,194,1|eimnrz,92,194,1|eimns0,105,209,0|eqjufz,105,209,0|eqjug0,92,194,1|f1cqfz,92,194,1|f1cqg0,105,209,0|f99x3z,105,209,0|f99x40,92,194,1|fkfrrz,92,194,1|fkfrs0,105,209,0|frzzrz,105,209,0|frzzs0,92,194,1|g35ufz,92,194,1|g35ug0,105,209,0|gaq2fz,105,209,0|gaq2g0,92,194,1|glvx3z,92,194,1|glvx40,105,209,0|gtt3rz,105,209,0|gtt3s0,92,194,1|h4lzrz,92,194,1|h4lzs0,105,209,0|hcj6fz,105,209,0|hcj6g0,92,194,1|hnc2fz,92,194,1|hnc2g0,105,209,0|hv993z,105,209,0|hv9940,92,194,1|i6f3rz,92,194,1|i6f3s0,92,194,0\",\"Asia/Phnom_Penh|,0,217,0|-1ayyla4,53,217,0|-pysda5,53,217,0|-pysda4,91,193,0\",\"Asia/Pontianak|,0,275,0|-w6piww,7,275,0|-jebg8x,7,275,0|-jebg8w,106,222,0|-eknm61,106,222,0|-eknm60,107,224,0|-co37o1,107,224,0|-co37o0,106,222,0|-bb5zi1,106,222,0|-bb5zi0,89,191,0|-a9m681,89,191,0|-a9m680,106,222,0|-34ru61,106,222,0|-34ru60,129,191,0|9e5gfz,129,191,0|9e5gg0,119,193,0\",\"Asia/Pyongyang|,0,276,0|-w895yc,130,242,0|-u9s4y1,130,242,0|-u9s4y0,116,224,0|-cpmro1,116,224,0|-cpmro0,130,224,0|nt2uzz,130,224,0|nt2v00,130,242,0|p87lnz,130,242,0|p87lo0,130,224,0\",\"Asia/Qatar|,0,215,0|-q3gmvk,105,209,0|19d0vz,105,209,0|19d0w0,100,6,0\",\"Asia/Qostanay|,0,277,0|-nu17s4,105,209,0|-kmr741,105,209,0|-kmr740,92,194,0|5vb0rz,92,194,0|5vb0s0,96,196,1|64ptzz,96,196,1|64pu00,96,196,0|6e2vbz,96,196,0|6e2vc0,96,196,1|6nhrbz,96,196,1|6nhrc0,92,194,0|6wuvfz,92,194,0|6wuvg0,96,196,1|769onz,96,196,1|769oo0,92,194,0|7fonfz,92,194,0|7fong0,96,196,1|7p1ubz,96,196,1|7p1uc0,92,194,0|7yevnz,92,194,0|7yevo0,96,196,1|87rwzz,96,196,1|87rx00,92,194,0|8h4ybz,92,194,0|8h4yc0,96,196,1|8qhznz,96,196,1|8qhzo0,92,194,0|8zv0zz,92,194,0|8zv100,96,196,1|9982bz,96,196,1|9982c0,92,194,0|9il3nz,92,194,0|9il3o0,96,196,1|9ry4zz,96,196,1|9ry500,92,194,0|a1b6bz,92,194,0|a1b6c0,96,196,1|aao7nz,96,196,1|aao7o0,92,194,0|ak18zz,92,194,0|ak1900,96,196,1|atr8zz,96,196,1|atr900,92,194,0|b34abz,92,194,0|b34ac0,92,194,1|bchefz,92,194,1|bcheg0,105,209,0|bi8t3z,105,209,0|bi8t40,92,194,0|bluczz,92,194,0|blud00,96,196,1|bv7ebz,96,196,1|bv7ec0,92,194,0|c4kfnz,92,194,0|c4kfo0,96,196,1|cdxgzz,96,196,1|cdxh00,92,194,0|cnaibz,92,194,0|cnaic0,96,196,1|cwnjnz,96,196,1|cwnjo0,92,194,0|d60kzz,92,194,0|d60l00,96,196,1|dfdmbz,96,196,1|dfdmc0,92,194,0|dp3mbz,92,194,0|dp3mc0,96,196,1|dzwibz,96,196,1|dzwic0,92,194,0|e7tozz,92,194,0|e7tp00,96,196,1|eimkzz,96,196,1|eiml00,92,194,0|eqjrnz,92,194,0|eqjro0,96,196,1|f1cnnz,96,196,1|f1cno0,92,194,0|f99ubz,92,194,0|f99uc0,96,196,1|fkfozz,96,196,1|fkfp00,92,194,0|frzwzz,92,194,0|frzx00,96,196,1|g35rnz,96,196,1|g35ro0,92,194,0|gapznz,92,194,0|gapzo0,96,196,1|glvubz,96,196,1|glvuc0,92,194,0|gtt0zz,92,194,0|gtt100,96,196,1|h4lwzz,96,196,1|h4lx00,92,194,0|hcj3nz,92,194,0|hcj3o0,96,196,1|hnbznz,96,196,1|hnbzo0,92,194,0|hv96bz,92,194,0|hv96c0,96,196,1|i6f0zz,96,196,1|i6f100,96,196,0\",\"Asia/Qyzylorda|,0,278,0|-nu184g,105,209,0|-kmr741,105,209,0|-kmr740,92,194,0|5vb0rz,92,194,0|5vb0s0,96,196,1|64ptzz,96,196,1|64pu00,96,196,0|6e2vbz,96,196,0|6e2vc0,96,196,1|6nhrbz,96,196,1|6nhrc0,92,194,0|6wuvfz,92,194,0|6wuvg0,96,196,1|769onz,96,196,1|769oo0,92,194,0|7fonfz,92,194,0|7fong0,96,196,1|7p1ubz,96,196,1|7p1uc0,92,194,0|7yevnz,92,194,0|7yevo0,96,196,1|87rwzz,96,196,1|87rx00,92,194,0|8h4ybz,92,194,0|8h4yc0,96,196,1|8qhznz,96,196,1|8qhzo0,92,194,0|8zv0zz,92,194,0|8zv100,96,196,1|9982bz,96,196,1|9982c0,92,194,0|9il3nz,92,194,0|9il3o0,96,196,1|9ry4zz,96,196,1|9ry500,92,194,0|a1b6bz,92,194,0|a1b6c0,96,196,1|aao7nz,96,196,1|aao7o0,92,194,0|ak18zz,92,194,0|ak1900,96,196,1|atr8zz,96,196,1|atr900,92,194,0|b34abz,92,194,0|b34ac0,92,194,1|bchefz,92,194,1|bcheg0,92,194,0|bi8qbz,92,194,0|bi8qc0,96,196,0|blua7z,96,196,0|blua80,96,196,1|bv7ebz,96,196,1|bv7ec0,92,194,0|c4kfnz,92,194,0|c4kfo0,96,196,1|cdxgzz,96,196,1|cdxh00,92,194,0|cnaibz,92,194,0|cnaic0,96,196,1|cwnjnz,96,196,1|cwnjo0,92,194,0|d60kzz,92,194,0|d60l00,96,196,1|dfdmbz,96,196,1|dfdmc0,92,194,0|dp3mbz,92,194,0|dp3mc0,96,196,1|dzwibz,96,196,1|dzwic0,92,194,0|e7tozz,92,194,0|e7tp00,96,196,1|eimkzz,96,196,1|eiml00,92,194,0|eqjrnz,92,194,0|eqjro0,96,196,1|f1cnnz,96,196,1|f1cno0,92,194,0|f99ubz,92,194,0|f99uc0,96,196,1|fkfozz,96,196,1|fkfp00,92,194,0|frzwzz,92,194,0|frzx00,96,196,1|g35rnz,96,196,1|g35ro0,92,194,0|gapznz,92,194,0|gapzo0,96,196,1|glvubz,96,196,1|glvuc0,92,194,0|gtt0zz,92,194,0|gtt100,96,196,1|h4lwzz,96,196,1|h4lx00,92,194,0|hcj3nz,92,194,0|hcj3o0,96,196,1|hnbznz,96,196,1|hnbzo0,92,194,0|hv96bz,92,194,0|hv96c0,96,196,1|i6f0zz,96,196,1|i6f100,96,196,0|pk1rbz,96,196,0|pk1rc0,92,194,0\",\"Asia/Riyadh|,0,203,0|-bwgbbg,100,6,0\",\"Asia/Sakhalin|,0,279,0|-xl87rc,107,224,0|-cpkx01,107,224,0|-cpkx00,90,192,0|5vak3z,90,192,0|5vak40,102,200,1|64pdbz,102,200,1|64pdc0,90,192,0|6e2hfz,90,192,0|6e2hg0,102,200,1|6nhanz,102,200,1|6nhao0,90,192,0|6wuerz,90,192,0|6wues0,102,200,1|7697zz,102,200,1|769800,90,192,0|7fo6rz,90,192,0|7fo6s0,102,200,1|7p1dnz,102,200,1|7p1do0,90,192,0|7yeezz,90,192,0|7yef00,102,200,1|87rgbz,102,200,1|87rgc0,90,192,0|8h4hnz,90,192,0|8h4ho0,102,200,1|8qhizz,102,200,1|8qhj00,90,192,0|8zukbz,90,192,0|8zukc0,102,200,1|997lnz,102,200,1|997lo0,90,192,0|9ikmzz,90,192,0|9ikn00,102,200,1|9rxobz,102,200,1|9rxoc0,90,192,0|a1apnz,90,192,0|a1apo0,102,200,1|aanqzz,102,200,1|aanr00,90,192,0|ak0sbz,90,192,0|ak0sc0,102,200,1|atqsbz,102,200,1|atqsc0,90,192,0|b33tnz,90,192,0|b33to0,90,192,1|bcgxrz,90,192,1|bcgxs0,93,195,0|bi8cfz,93,195,0|bi8cg0,90,192,0|bltwbz,90,192,0|bltwc0,102,200,1|bv6xnz,102,200,1|bv6xo0,90,192,0|c4jyzz,90,192,0|c4jz00,102,200,1|cdx0bz,102,200,1|cdx0c0,90,192,0|cna1nz,90,192,0|cna1o0,102,200,1|cwn2zz,102,200,1|cwn300,90,192,0|d604bz,90,192,0|d604c0,102,200,1|dfd5nz,102,200,1|dfd5o0,90,192,0|dp35nz,90,192,0|dp35o0,102,200,1|dzw1nz,102,200,1|dzw1o0,90,192,0|e7t8bz,90,192,0|e7t8c0,90,192,1|eim73z,90,192,1|eim740,93,195,0|eqjdrz,93,195,0|eqjds0,90,192,1|f1c9rz,90,192,1|f1c9s0,93,195,0|f99gfz,93,195,0|f99gg0,90,192,1|fkfb3z,90,192,1|fkfb40,93,195,0|frzj3z,93,195,0|frzj40,90,192,1|g35drz,90,192,1|g35ds0,93,195,0|gaplrz,93,195,0|gapls0,90,192,1|glvgfz,90,192,1|glvgg0,93,195,0|gtsn3z,93,195,0|gtsn40,90,192,1|h4lj3z,90,192,1|h4lj40,93,195,0|hciprz,93,195,0|hcips0,90,192,1|hnblrz,90,192,1|hnbls0,93,195,0|hv8sfz,93,195,0|hv8sg0,90,192,1|i6en3z,90,192,1|i6en40,93,195,0|idyv3z,93,195,0|idyv40,90,192,1|ip4prz,90,192,1|ip4ps0,93,195,0|iwoxrz,93,195,0|iwoxs0,90,192,1|j7usfz,90,192,1|j7usg0,93,195,0|jff0fz,93,195,0|jff0g0,90,192,1|jqkv3z,90,192,1|jqkv40,93,195,0|jyi1rz,93,195,0|jyi1s0,90,192,1|k9axrz,90,192,1|k9axs0,93,195,0|kh84fz,93,195,0|kh84g0,90,192,1|ks10fz,90,192,1|ks10g0,93,195,0|kzy73z,93,195,0|kzy740,90,192,1|lb41rz,90,192,1|lb41s0,93,195,0|lio9rz,93,195,0|lio9s0,90,192,0|ne09nz,90,192,0|ne09o0,93,195,0|o4nlrz,93,195,0|o4nls0,90,192,0\",\"Asia/Samarkand|,0,280,0|-nu18eh,105,209,0|-kmr741,105,209,0|-kmr740,92,194,0|5vb0rz,92,194,0|5vb0s0,96,196,1|64ptzz,96,196,1|64pu00,96,196,0|6e2vbz,96,196,0|6e2vc0,96,196,1|6nhrbz,96,196,1|6nhrc0,92,194,0|6wuvfz,92,194,0|6wuvg0,96,196,1|769onz,96,196,1|769oo0,92,194,0|7fonfz,92,194,0|7fong0,96,196,1|7p1ubz,96,196,1|7p1uc0,92,194,0|7yevnz,92,194,0|7yevo0,96,196,1|87rwzz,96,196,1|87rx00,92,194,0|8h4ybz,92,194,0|8h4yc0,96,196,1|8qhznz,96,196,1|8qhzo0,92,194,0|8zv0zz,92,194,0|8zv100,96,196,1|9982bz,96,196,1|9982c0,92,194,0|9il3nz,92,194,0|9il3o0,96,196,1|9ry4zz,96,196,1|9ry500,92,194,0|a1b6bz,92,194,0|a1b6c0,96,196,1|aao7nz,96,196,1|aao7o0,92,194,0|ak18zz,92,194,0|ak1900,96,196,1|atr8zz,96,196,1|atr900,92,194,0|b34abz,92,194,0|b34ac0,96,196,1|bchbnz,96,196,1|bchbo0,92,194,0\",\"Asia/Seoul|,0,281,0|-w8966g,130,242,0|-u9s4y1,130,242,0|-u9s4y0,116,224,0|-couzo1,116,224,0|-couzo0,130,224,0|-b9kp01,130,224,0|-b9kp00,131,195,1|-b486g1,131,195,1|-b486g0,130,224,0|-atu101,130,224,0|-atu100,131,195,1|-aljyg1,131,195,1|-aljyg0,130,224,0|-ab5t01,130,224,0|-ab5t00,131,195,1|-a2tvs1,131,195,1|-a2tvs0,130,224,0|-9ql2c1,130,224,0|-9ql2c0,131,195,1|-9k3t41,131,195,1|-9k3t40,130,224,0|-88kmc1,130,224,0|-88kmc0,130,242,0|-7nhbm1,130,242,0|-7nhbm0,131,248,1|-7gy7q1,131,248,1|-7gy7q0,130,242,0|-73vrm1,130,242,0|-73vrm0,131,248,1|-6x1jq1,131,248,1|-6x1jq0,130,242,0|-6lvma1,130,242,0|-6lvma0,131,248,1|-6eofq1,131,248,1|-6eofq0,130,242,0|-635jm1,130,242,0|-635jm0,131,248,1|-5vyd21,131,248,1|-5vyd20,130,242,0|-5kfgy1,130,242,0|-5kfgy0,131,248,1|-5d8ae1,131,248,1|-5d8ae0,130,242,0|-51pea1,130,242,0|-51pea0,131,248,1|-4ui7q1,131,248,1|-4ui7q0,130,242,0|-4dqfm1,130,242,0|-4dqfm0,130,224,0|920hvz,130,224,0|920hw0,131,195,1|99xojz,131,195,1|99xok0,130,224,0|9kqkjz,130,224,0|9kqkk0,131,195,1|9snr7z,131,195,1|9snr80,130,224,0\",\"Asia/Shanghai|,0,282,0|-100eztj,45,191,0|-qh00w1,45,191,0|-qh00w0,46,224,1|-q87fo1,46,224,1|-q87fo0,45,191,0|-ffvq81,45,191,0|-ffvq80,46,224,1|-f8zno1,46,224,1|-f8zno0,45,191,0|-f148w1,45,191,0|-f148w0,46,224,1|-ep6p01,46,224,1|-ep6p00,45,191,0|-ekjy81,45,191,0|-ekjy80,46,224,1|-cp63o1,46,224,1|-cp63o0,45,191,0|-cc1sw1,45,191,0|-cc1sw0,46,224,1|-c4wh01,46,224,1|-c4wh00,45,191,0|-butfk1,45,191,0|-butfk0,46,224,1|-bkj501,46,224,1|-bkj500,45,191,0|-bb60w1,45,191,0|-bb60w0,46,224,1|-b3aro1,46,224,1|-b3aro0,45,191,0|-ase3k1,45,191,0|-ase3k0,46,224,1|-ar06c1,46,224,1|-ar06c0,45,191,0|8ixjbz,45,191,0|8ixjc0,46,224,1|8prr7z,46,224,1|8prr80,45,191,0|90kpzz,45,191,0|90kq00,46,224,1|98htvz,46,224,1|98htw0,45,191,0|9jnrbz,45,191,0|9jnrc0,46,224,1|9r7wjz,46,224,1|9r7wk0,45,191,0|a2dtzz,45,191,0|a2du00,46,224,1|aaaxvz,46,224,1|aaaxw0,45,191,0|al3wnz,45,191,0|al3wo0,46,224,1|at10jz,46,224,1|at10k0,45,191,0|b3tzbz,45,191,0|b3tzc0,46,224,1|bbr37z,46,224,1|bbr380,45,191,0\",\"Asia/Singapore|,0,262,0|-100ewkd,85,262,0|-xphpwe,85,262,0|-xphpwd,91,193,0|-jb6gs1,91,193,0|-jb6gs0,118,246,1|-hquppd,118,246,1|-hquppc,118,246,0|-esddpd,118,246,0|-esddpc,106,222,0|-ejqa61,106,222,0|-ejqa60,107,224,0|-conl01,107,224,0|-conl00,106,222,0|69g35z,106,222,0|69g360,89,191,0\",\"Asia/Srednekolymsk|,0,283,0|-nu1ogs,93,195,0|-kmrns1,93,195,0|-kmrns0,90,192,0|5vak3z,90,192,0|5vak40,102,200,1|64pdbz,102,200,1|64pdc0,90,192,0|6e2hfz,90,192,0|6e2hg0,102,200,1|6nhanz,102,200,1|6nhao0,90,192,0|6wuerz,90,192,0|6wues0,102,200,1|7697zz,102,200,1|769800,90,192,0|7fo6rz,90,192,0|7fo6s0,102,200,1|7p1dnz,102,200,1|7p1do0,90,192,0|7yeezz,90,192,0|7yef00,102,200,1|87rgbz,102,200,1|87rgc0,90,192,0|8h4hnz,90,192,0|8h4ho0,102,200,1|8qhizz,102,200,1|8qhj00,90,192,0|8zukbz,90,192,0|8zukc0,102,200,1|997lnz,102,200,1|997lo0,90,192,0|9ikmzz,90,192,0|9ikn00,102,200,1|9rxobz,102,200,1|9rxoc0,90,192,0|a1apnz,90,192,0|a1apo0,102,200,1|aanqzz,102,200,1|aanr00,90,192,0|ak0sbz,90,192,0|ak0sc0,102,200,1|atqsbz,102,200,1|atqsc0,90,192,0|b33tnz,90,192,0|b33to0,90,192,1|bcgxrz,90,192,1|bcgxs0,93,195,0|bi8cfz,93,195,0|bi8cg0,90,192,0|bltwbz,90,192,0|bltwc0,102,200,1|bv6xnz,102,200,1|bv6xo0,90,192,0|c4jyzz,90,192,0|c4jz00,102,200,1|cdx0bz,102,200,1|cdx0c0,90,192,0|cna1nz,90,192,0|cna1o0,102,200,1|cwn2zz,102,200,1|cwn300,90,192,0|d604bz,90,192,0|d604c0,102,200,1|dfd5nz,102,200,1|dfd5o0,90,192,0|dp35nz,90,192,0|dp35o0,102,200,1|dzw1nz,102,200,1|dzw1o0,90,192,0|e7t8bz,90,192,0|e7t8c0,102,200,1|eim4bz,102,200,1|eim4c0,90,192,0|eqjazz,90,192,0|eqjb00,102,200,1|f1c6zz,102,200,1|f1c700,90,192,0|f99dnz,90,192,0|f99do0,102,200,1|fkf8bz,102,200,1|fkf8c0,90,192,0|frzgbz,90,192,0|frzgc0,102,200,1|g35azz,102,200,1|g35b00,90,192,0|gapizz,90,192,0|gapj00,102,200,1|glvdnz,102,200,1|glvdo0,90,192,0|gtskbz,90,192,0|gtskc0,102,200,1|h4lgbz,102,200,1|h4lgc0,90,192,0|hcimzz,90,192,0|hcin00,102,200,1|hnbizz,102,200,1|hnbj00,90,192,0|hv8pnz,90,192,0|hv8po0,102,200,1|i6ekbz,102,200,1|i6ekc0,90,192,0|idysbz,90,192,0|idysc0,102,200,1|ip4mzz,102,200,1|ip4n00,90,192,0|iwouzz,90,192,0|iwov00,102,200,1|j7upnz,102,200,1|j7upo0,90,192,0|jfexnz,90,192,0|jfexo0,102,200,1|jqksbz,102,200,1|jqksc0,90,192,0|jyhyzz,90,192,0|jyhz00,102,200,1|k9auzz,102,200,1|k9av00,90,192,0|kh81nz,90,192,0|kh81o0,102,200,1|ks0xnz,102,200,1|ks0xo0,90,192,0|kzy4bz,90,192,0|kzy4c0,102,200,1|lb3yzz,102,200,1|lb3z00,90,192,0|lio6zz,90,192,0|lio700,102,200,0|ne06vz,102,200,0|ne06w0,90,192,0\",\"Asia/Taipei|,0,284,0|-12mch60,45,191,0|-gtzfk1,45,191,0|-gtzfk0,116,224,0|-co6u81,116,224,0|-co6u80,45,191,0|-cc1sw1,45,191,0|-cc1sw0,46,224,1|-c4wh01,46,224,1|-c4wh00,45,191,0|-butfk1,45,191,0|-butfk0,46,224,1|-bkj501,46,224,1|-bkj500,45,191,0|-bb60w1,45,191,0|-bb60w0,46,224,1|-b3aro1,46,224,1|-b3aro0,45,191,0|-ase3k1,45,191,0|-ase3k0,46,224,1|-akiuc1,46,224,1|-akiuc0,45,191,0|-a9m681,45,191,0|-a9m680,46,224,1|-a1qx01,46,224,1|-a1qx00,45,191,0|-9qu8w1,45,191,0|-9qu8w0,46,224,1|-9iyzo1,46,224,1|-9iyzo0,45,191,0|-9b5fk1,45,191,0|-9b5fk0,46,224,1|-8yjt01,46,224,1|-8yjt00,45,191,0|-8qs3k1,45,191,0|-8qs3k0,46,224,1|-8frvo1,46,224,1|-8frvo0,45,191,0|-880681,45,191,0|-880680,46,224,1|-7wzyc1,46,224,1|-7wzyc0,45,191,0|-7p88w1,45,191,0|-7p88w0,46,224,1|-7ftfo1,46,224,1|-7ftfo0,45,191,0|-76egw1,45,191,0|-76egw0,46,224,1|-6wzno1,46,224,1|-6wzno0,45,191,0|-6nmjk1,45,191,0|-6nmjk0,46,224,1|-6e7qc1,46,224,1|-6e7qc0,45,191,0|-64um81,45,191,0|-64um80,46,224,1|-5vft01,46,224,1|-5vft00,45,191,0|-5m2ow1,45,191,0|-5m2ow0,46,224,1|-5cnvo1,46,224,1|-5cnvo0,45,191,0|-503y81,45,191,0|-503y80,46,224,1|-4tu3o1,46,224,1|-4tu3o0,45,191,0|-4hc0w1,45,191,0|-4hc0w0,46,224,1|-4b26c1,46,224,1|-4b26c0,45,191,0|27rlrz,45,191,0|27rls0,46,224,1|2h6ezz,46,224,1|2h6f00,45,191,0|2qjj3z,45,191,0|2qjj40,46,224,1|2zycbz,46,224,1|2zycc0,45,191,0|4ydlrz,45,191,0|4ydls0,46,224,1|533wbz,46,224,1|533wc0,45,191,0\",\"Asia/Tashkent|,0,285,0|-nu18tz,92,194,0|-kmr9w1,92,194,0|-kmr9w0,96,196,0|5vaxzz,96,196,0|5vay00,91,193,1|64pr7z,91,193,1|64pr80,96,196,0|6e2vbz,96,196,0|6e2vc0,91,193,1|6nhojz,91,193,1|6nhok0,96,196,0|6wusnz,96,196,0|6wuso0,91,193,1|769lvz,91,193,1|769lw0,96,196,0|7foknz,96,196,0|7foko0,91,193,1|7p1rjz,91,193,1|7p1rk0,96,196,0|7yesvz,96,196,0|7yesw0,91,193,1|87ru7z,91,193,1|87ru80,96,196,0|8h4vjz,96,196,0|8h4vk0,91,193,1|8qhwvz,91,193,1|8qhww0,96,196,0|8zuy7z,96,196,0|8zuy80,91,193,1|997zjz,91,193,1|997zk0,96,196,0|9il0vz,96,196,0|9il0w0,91,193,1|9ry27z,91,193,1|9ry280,96,196,0|a1b3jz,96,196,0|a1b3k0,91,193,1|aao4vz,91,193,1|aao4w0,96,196,0|ak167z,96,196,0|ak1680,91,193,1|atr67z,91,193,1|atr680,96,196,0|b347jz,96,196,0|b347k0,96,196,1|bchbnz,96,196,1|bchbo0,92,194,0\",\"Asia/Tbilisi|,0,286,0|-1ayyayn,132,286,0|-nu14ao,132,286,0|-nu14an,100,6,0|-6p7kc1,100,6,0|-6p7kc0,105,209,0|5vb3jz,105,209,0|5vb3k0,92,194,1|64pwrz,92,194,1|64pws0,105,209,0|6e30vz,105,209,0|6e30w0,92,194,1|6nhu3z,92,194,1|6nhu40,105,209,0|6wuy7z,105,209,0|6wuy80,92,194,1|769rfz,92,194,1|769rg0,105,209,0|7foq7z,105,209,0|7foq80,92,194,1|7p1x3z,92,194,1|7p1x40,105,209,0|7yeyfz,105,209,0|7yeyg0,92,194,1|87rzrz,92,194,1|87rzs0,105,209,0|8h513z,105,209,0|8h5140,92,194,1|8qi2fz,92,194,1|8qi2g0,105,209,0|8zv3rz,105,209,0|8zv3s0,92,194,1|99853z,92,194,1|998540,105,209,0|9il6fz,105,209,0|9il6g0,92,194,1|9ry7rz,92,194,1|9ry7s0,105,209,0|a1b93z,105,209,0|a1b940,92,194,1|aaoafz,92,194,1|aaoag0,105,209,0|ak1brz,105,209,0|ak1bs0,92,194,1|atrbrz,92,194,1|atrbs0,105,209,0|b34d3z,105,209,0|b34d40,105,209,1|bchh7z,105,209,1|bchh80,100,6,0|bluczz,100,6,0|blud00,105,209,1|bv7bjz,105,209,1|bv7bk0,100,6,0|c4kfnz,100,6,0|c4kfo0,105,209,1|cdxe7z,105,209,1|cdxe80,100,6,0|cnaibz,100,6,0|cnaic0,105,209,1|cwngvz,105,209,1|cwngw0,105,209,0|d60i7z,105,209,0|d60i80,92,194,1|dfdgrz,92,194,1|dfdgs0,105,209,0|dp3jjz,105,209,0|dp3jk0,92,194,1|eimffz,92,194,1|eimfg0,105,209,0|eqjovz,105,209,0|eqjow0,92,194,1|f1ci3z,92,194,1|f1ci40,105,209,0|f99rjz,105,209,0|f99rk0,92,194,1|fkfjfz,92,194,1|fkfjg0,105,209,0|frzu7z,105,209,0|frzu80,92,194,1|g35m3z,92,194,1|g35m40,105,209,0|gapwvz,105,209,0|gapww0,92,194,1|glvorz,92,194,1|glvos0,105,209,0|gtsy7z,105,209,0|gtsy80,92,194,1|h4lrfz,92,194,1|h4lrg0,105,209,0|hcj0vz,105,209,0|hcj0w0,92,194,1|hnbu3z,92,194,1|hnbu40,105,209,0|hv93jz,105,209,0|hv93k0,92,194,1|hzxjfz,92,194,1|hzxjg0,105,209,1|i6f6jz,105,209,1|i6f6k0,100,6,0|idzejz,100,6,0|idzek0,105,209,0\",\"Asia/Tehran|,0,287,0|-s6m6uw,133,287,0|-cixlix,133,287,0|-cixliw,134,288,0|435vlz,134,288,0|435vm0,105,209,0|4ad3jz,105,209,0|4ad3k0,92,194,1|4ldbfz,92,194,1|4ldbg0,105,209,0|4p2q7z,105,209,0|4p2q80,134,288,0|4t529z,134,288,0|4t52a0,124,252,1|52i0tz,124,252,1|52i0u0,134,288,0|5byu9z,134,288,0|5byua0,124,252,1|5lj7hz,124,252,1|5lj7i0,134,288,0|b4tcxz,134,288,0|b4tcy0,124,252,1|bc48tz,124,252,1|bc48u0,134,288,0|blhcxz,134,288,0|blhcy0,124,252,1|buy0tz,124,252,1|buy0u0,134,288,0|c49a9z,134,288,0|c49aa0,124,252,1|cdpy5z,124,252,1|cdpy60,134,288,0|cn17lz,134,288,0|cn17m0,124,252,1|cwhvhz,124,252,1|cwhvi0,134,288,0|d5t4xz,134,288,0|d5t4y0,124,252,1|df9stz,124,252,1|df9su0,134,288,0|dol29z,134,288,0|dol2a0,124,252,1|dy1q5z,124,252,1|dy1q60,134,288,0|e7eu9z,134,288,0|e7eua0,124,252,1|egvi5z,124,252,1|egvi60,134,288,0|eq6rlz,134,288,0|eq6rm0,124,252,1|eznfhz,124,252,1|eznfi0,134,288,0|f8yoxz,134,288,0|f8yoy0,124,252,1|fifctz,124,252,1|fifcu0,134,288,0|frqm9z,134,288,0|frqma0,124,252,1|g17a5z,124,252,1|g17a60,134,288,0|gake9z,134,288,0|gakea0,124,252,1|gk125z,124,252,1|gk1260,134,288,0|gtcblz,134,288,0|gtcbm0,124,252,1|h2szhz,124,252,1|h2szi0,134,288,0|hc48xz,134,288,0|hc48y0,124,252,1|hlkwtz,124,252,1|hlkwu0,134,288,0|huw69z,134,288,0|huw6a0,124,252,1|i4cu5z,124,252,1|i4cu60,134,288,0|idpy9z,134,288,0|idpya0,124,252,1|in6m5z,124,252,1|in6m60,134,288,0|jy1q9z,134,288,0|jy1qa0,124,252,1|k7ie5z,124,252,1|k7ie60,134,288,0|kgvi9z,134,288,0|kgvia0,124,252,1|kqc65z,124,252,1|kqc660,134,288,0|kznflz,134,288,0|kznfm0,124,252,1|l943hz,124,252,1|l943i0,134,288,0|lifcxz,134,288,0|lifcy0,124,252,1|lrw0tz,124,252,1|lrw0u0,134,288,0|m17a9z,134,288,0|m17aa0,124,252,1|many5z,124,252,1|many60,134,288,0|mk129z,134,288,0|mk12a0,124,252,1|mthq5z,124,252,1|mthq60,134,288,0|n2szlz,134,288,0|n2szm0,124,252,1|nc9nhz,124,252,1|nc9ni0,134,288,0|nlkwxz,134,288,0|nlkwy0,124,252,1|nv1ktz,124,252,1|nv1ku0,134,288,0|o4cu9z,134,288,0|o4cua0,124,252,1|odti5z,124,252,1|odti60,134,288,0|on6m9z,134,288,0|on6ma0,124,252,1|owna5z,124,252,1|owna60,134,288,0|p5yjlz,134,288,0|p5yjm0,124,252,1|pff7hz,124,252,1|pff7i0,134,288,0|poqgxz,134,288,0|poqgy0,124,252,1|py74tz,124,252,1|py74u0,134,288,0|q7ie9z,134,288,0|q7iea0,124,252,1|qgz25z,124,252,1|qgz260,134,288,0|qqc69z,134,288,0|qqc6a0,124,252,1|qzsu5z,124,252,1|qzsu60,134,288,0|r943lz,134,288,0|r943m0,124,252,1|rikrhz,124,252,1|rikri0,134,288,0|rrw0xz,134,288,0|rrw0y0,124,252,1|s1cotz,124,252,1|s1cou0,134,288,0|sany9z,134,288,0|sanya0,124,252,1|sk4m5z,124,252,1|sk4m60,134,288,0|sthq9z,134,288,0|sthqa0,124,252,1|t2ye5z,124,252,1|t2ye60,134,288,0|tc9nlz,134,288,0|tc9nm0,124,252,1|tlqbhz,124,252,1|tlqbi0,134,288,0|tv1kxz,134,288,0|tv1ky0,124,252,1|u4i8tz,124,252,1|u4i8u0,134,288,0|udti9z,134,288,0|udtia0,124,252,1|una65z,124,252,1|una660,134,288,0|uwlflz,134,288,0|uwlfm0,124,252,1|v623hz,124,252,1|v623i0,134,288,0|vff7lz,134,288,0|vff7m0,124,252,1|vovvhz,124,252,1|vovvi0,134,288,0|vy74xz,134,288,0|vy74y0,124,252,1|w7nstz,124,252,1|w7nsu0,134,288,0|wgz29z,134,288,0|wgz2a0,124,252,1|wqfq5z,124,252,1|wqfq60,134,288,0|wzqzlz,134,288,0|wzqzm0,124,252,1|x97nhz,124,252,1|x97ni0,134,288,0|xikrlz,134,288,0|xikrm0,124,252,1|xs1fhz,124,252,1|xs1fi0,134,288,0|y1coxz,134,288,0|y1coy0,124,252,1|yatctz,124,252,1|yatcu0,134,288,0|yk4m9z,134,288,0|yk4ma0,124,252,1|ytla5z,124,252,1|ytla60,134,288,0|z2wjlz,134,288,0|z2wjm0,124,252,1|zcd7hz,124,252,1|zcd7i0,134,288,0\",\"Asia/Thimphu|,0,289,0|-bojclo,108,228,0|99fa1z,108,228,0|99fa20,96,196,0\",\"Asia/Tokyo|,0,290,0|-16snno0,116,224,0|-bb4901,116,224,0|-bb4900,135,195,1|-b49yc1,135,195,1|-b49yc0,116,224,0|-atu101,116,224,0|-atu100,135,195,1|-aljvo1,135,195,1|-aljvo0,116,224,0|-a9b501,116,224,0|-a9b500,135,195,1|-a2tt01,135,195,1|-a2tt00,116,224,0|-9ql2c1,116,224,0|-9ql2c0,135,195,1|-9k3qc1,135,195,1|-9k3qc0,116,224,0\",\"Asia/Tomsk|,0,291,0|-q3zbqf,96,196,0|-kmrco1,96,196,0|-kmrco0,91,193,0|5vav7z,91,193,0|5vav80,89,191,1|64pofz,89,191,1|64pog0,91,193,0|6e2sjz,91,193,0|6e2sk0,89,191,1|6nhlrz,89,191,1|6nhls0,91,193,0|6wupvz,91,193,0|6wupw0,89,191,1|769j3z,89,191,1|769j40,91,193,0|7fohvz,91,193,0|7fohw0,89,191,1|7p1orz,89,191,1|7p1os0,91,193,0|7yeq3z,91,193,0|7yeq40,89,191,1|87rrfz,89,191,1|87rrg0,91,193,0|8h4srz,91,193,0|8h4ss0,89,191,1|8qhu3z,89,191,1|8qhu40,91,193,0|8zuvfz,91,193,0|8zuvg0,89,191,1|997wrz,89,191,1|997ws0,91,193,0|9iky3z,91,193,0|9iky40,89,191,1|9rxzfz,89,191,1|9rxzg0,91,193,0|a1b0rz,91,193,0|a1b0s0,89,191,1|aao23z,89,191,1|aao240,91,193,0|ak13fz,91,193,0|ak13g0,89,191,1|atr3fz,89,191,1|atr3g0,91,193,0|b344rz,91,193,0|b344s0,91,193,1|bch8vz,91,193,1|bch8w0,96,196,0|bi8njz,96,196,0|bi8nk0,91,193,0|blu7fz,91,193,0|blu7g0,89,191,1|bv78rz,89,191,1|bv78s0,91,193,0|c4ka3z,91,193,0|c4ka40,89,191,1|cdxbfz,89,191,1|cdxbg0,91,193,0|cnacrz,91,193,0|cnacs0,89,191,1|cwne3z,89,191,1|cwne40,91,193,0|d60ffz,91,193,0|d60fg0,89,191,1|dfdgrz,89,191,1|dfdgs0,91,193,0|dp3grz,91,193,0|dp3gs0,89,191,1|dzwcrz,89,191,1|dzwcs0,91,193,0|e7tjfz,91,193,0|e7tjg0,89,191,1|eimffz,89,191,1|eimfg0,91,193,0|eqjm3z,91,193,0|eqjm40,89,191,1|f1ci3z,89,191,1|f1ci40,91,193,0|f99orz,91,193,0|f99os0,89,191,1|fkfjfz,89,191,1|fkfjg0,91,193,0|frzrfz,91,193,0|frzrg0,89,191,1|g35m3z,89,191,1|g35m40,91,193,0|gapu3z,91,193,0|gapu40,89,191,1|glvorz,89,191,1|glvos0,91,193,0|gtsvfz,91,193,0|gtsvg0,89,191,1|gvea3z,89,191,1|gvea40,91,193,1|h4lu7z,91,193,1|h4lu80,96,196,0|hcj0vz,96,196,0|hcj0w0,91,193,1|hnbwvz,91,193,1|hnbww0,96,196,0|hv93jz,96,196,0|hv93k0,91,193,1|i6ey7z,91,193,1|i6ey80,96,196,0|idz67z,96,196,0|idz680,91,193,1|ip50vz,91,193,1|ip50w0,96,196,0|iwp8vz,96,196,0|iwp8w0,91,193,1|j7v3jz,91,193,1|j7v3k0,96,196,0|jffbjz,96,196,0|jffbk0,91,193,1|jql67z,91,193,1|jql680,96,196,0|jyicvz,96,196,0|jyicw0,91,193,1|k9b8vz,91,193,1|k9b8w0,96,196,0|kh8fjz,96,196,0|kh8fk0,91,193,1|ks1bjz,91,193,1|ks1bk0,96,196,0|kzyi7z,96,196,0|kzyi80,91,193,1|lb4cvz,91,193,1|lb4cw0,96,196,0|liokvz,96,196,0|liokw0,91,193,0|ne0krz,91,193,0|ne0ks0,96,196,0|o7wkvz,96,196,0|o7wkw0,91,193,0\",\"Asia/Ulaanbaatar|,0,292,0|-xmcrsk,91,193,0|46akjz,91,193,0|46akk0,89,191,0|6wun3z,89,191,0|6wun40,107,224,1|769gbz,107,224,1|769gc0,89,191,0|7fof3z,89,191,0|7fof40,107,224,1|7p1dnz,107,224,1|7p1do0,89,191,0|7yehrz,89,191,0|7yehs0,107,224,1|87rgbz,107,224,1|87rgc0,89,191,0|8h4kfz,89,191,0|8h4kg0,107,224,1|8qhizz,107,224,1|8qhj00,89,191,0|8zun3z,89,191,0|8zun40,107,224,1|997lnz,107,224,1|997lo0,89,191,0|9ikprz,89,191,0|9ikps0,107,224,1|9rxobz,107,224,1|9rxoc0,89,191,0|a1asfz,89,191,0|a1asg0,107,224,1|aanqzz,107,224,1|aanr00,89,191,0|ak0v3z,89,191,0|ak0v40,107,224,1|atqsbz,107,224,1|atqsc0,89,191,0|b33wfz,89,191,0|b33wg0,107,224,1|bcguzz,107,224,1|bcgv00,89,191,0|bltz3z,89,191,0|bltz40,107,224,1|bv6xnz,107,224,1|bv6xo0,89,191,0|c4k1rz,89,191,0|c4k1s0,107,224,1|cdx0bz,107,224,1|cdx0c0,89,191,0|cna4fz,89,191,0|cna4g0,107,224,1|cwn2zz,107,224,1|cwn300,89,191,0|d6073z,89,191,0|d60740,107,224,1|dfd5nz,107,224,1|dfd5o0,89,191,0|dp38fz,89,191,0|dp38g0,107,224,1|dyg6zz,107,224,1|dyg700,89,191,0|e7tb3z,89,191,0|e7tb40,107,224,1|eh69nz,107,224,1|eh69o0,89,191,0|eqjdrz,89,191,0|eqjds0,107,224,1|ezwcbz,107,224,1|ezwcc0,89,191,0|gcgpzz,89,191,0|gcgq00,107,224,1|gkdtvz,107,224,1|gkdtw0,89,191,0|gtqxzz,89,191,0|gtqy00,107,224,1|h33wjz,107,224,1|h33wk0,89,191,0|hch0nz,89,191,0|hch0o0,107,224,1|hltz7z,107,224,1|hltz80,89,191,0|hv73bz,89,191,0|hv73c0,107,224,1|i4k1vz,107,224,1|i4k1w0,89,191,0|idx5zz,89,191,0|idx600,107,224,1|ina4jz,107,224,1|ina4k0,89,191,0|iwn8nz,89,191,0|iwn8o0,107,224,1|j6d5vz,107,224,1|j6d5w0,89,191,0|nlvtzz,89,191,0|nlvu00,107,224,1|nv8mzz,107,224,1|nv8n00,89,191,0|o4lwnz,89,191,0|o4lwo0,107,224,1|odypnz,107,224,1|odypo0,89,191,0\",\"Asia/Urumqi|,0,293,0|-lx5pjw,96,196,0\",\"Asia/Ust-Nera|,0,294,0|-q4cl6u,89,191,0|-kmri81,89,191,0|-kmri80,107,224,0|5vapnz,107,224,0|5vapo0,102,200,1|64pdbz,102,200,1|64pdc0,90,192,0|6e2hfz,90,192,0|6e2hg0,102,200,1|6nhanz,102,200,1|6nhao0,90,192,0|6wuerz,90,192,0|6wues0,102,200,1|7697zz,102,200,1|769800,90,192,0|7fo6rz,90,192,0|7fo6s0,102,200,1|7p1dnz,102,200,1|7p1do0,90,192,0|7yeezz,90,192,0|7yef00,102,200,1|87rgbz,102,200,1|87rgc0,90,192,0|8h4hnz,90,192,0|8h4ho0,102,200,1|8qhizz,102,200,1|8qhj00,90,192,0|8zukbz,90,192,0|8zukc0,102,200,1|997lnz,102,200,1|997lo0,90,192,0|9ikmzz,90,192,0|9ikn00,102,200,1|9rxobz,102,200,1|9rxoc0,90,192,0|a1apnz,90,192,0|a1apo0,102,200,1|aanqzz,102,200,1|aanr00,90,192,0|ak0sbz,90,192,0|ak0sc0,102,200,1|atqsbz,102,200,1|atqsc0,90,192,0|b33tnz,90,192,0|b33to0,90,192,1|bcgxrz,90,192,1|bcgxs0,93,195,0|bi8cfz,93,195,0|bi8cg0,90,192,0|bltwbz,90,192,0|bltwc0,102,200,1|bv6xnz,102,200,1|bv6xo0,90,192,0|c4jyzz,90,192,0|c4jz00,102,200,1|cdx0bz,102,200,1|cdx0c0,90,192,0|cna1nz,90,192,0|cna1o0,102,200,1|cwn2zz,102,200,1|cwn300,90,192,0|d604bz,90,192,0|d604c0,102,200,1|dfd5nz,102,200,1|dfd5o0,90,192,0|dp35nz,90,192,0|dp35o0,102,200,1|dzw1nz,102,200,1|dzw1o0,90,192,0|e7t8bz,90,192,0|e7t8c0,102,200,1|eim4bz,102,200,1|eim4c0,90,192,0|eqjazz,90,192,0|eqjb00,102,200,1|f1c6zz,102,200,1|f1c700,90,192,0|f99dnz,90,192,0|f99do0,102,200,1|fkf8bz,102,200,1|fkf8c0,90,192,0|frzgbz,90,192,0|frzgc0,102,200,1|g35azz,102,200,1|g35b00,90,192,0|gapizz,90,192,0|gapj00,102,200,1|glvdnz,102,200,1|glvdo0,90,192,0|gtskbz,90,192,0|gtskc0,102,200,1|h4lgbz,102,200,1|h4lgc0,90,192,0|hcimzz,90,192,0|hcin00,102,200,1|hnbizz,102,200,1|hnbj00,90,192,0|hv8pnz,90,192,0|hv8po0,102,200,1|i6ekbz,102,200,1|i6ekc0,90,192,0|idysbz,90,192,0|idysc0,102,200,1|ip4mzz,102,200,1|ip4n00,90,192,0|iwouzz,90,192,0|iwov00,102,200,1|j7upnz,102,200,1|j7upo0,90,192,0|jfexnz,90,192,0|jfexo0,102,200,1|jqksbz,102,200,1|jqksc0,90,192,0|jyhyzz,90,192,0|jyhz00,102,200,1|k9auzz,102,200,1|k9av00,90,192,0|kh81nz,90,192,0|kh81o0,102,200,1|ks0xnz,102,200,1|ks0xo0,90,192,0|kzy4bz,90,192,0|kzy4c0,102,200,1|lb3yzz,102,200,1|lb3z00,90,192,0|lio6zz,90,192,0|lio700,102,200,0|lrerzz,102,200,0|lres00,90,192,0|ne09nz,90,192,0|ne09o0,93,195,0\",\"Asia/Vientiane|,0,217,0|-1ayyla4,53,217,0|-pysda5,53,217,0|-pysda4,91,193,0\",\"Asia/Vladivostok|,0,295,0|-oligf7,107,224,0|-kmrl01,107,224,0|-kmrl00,93,195,0|5vamvz,93,195,0|5vamw0,90,192,1|64pg3z,90,192,1|64pg40,93,195,0|6e2k7z,93,195,0|6e2k80,90,192,1|6nhdfz,90,192,1|6nhdg0,93,195,0|6wuhjz,93,195,0|6wuhk0,90,192,1|769arz,90,192,1|769as0,93,195,0|7fo9jz,93,195,0|7fo9k0,90,192,1|7p1gfz,90,192,1|7p1gg0,93,195,0|7yehrz,93,195,0|7yehs0,90,192,1|87rj3z,90,192,1|87rj40,93,195,0|8h4kfz,93,195,0|8h4kg0,90,192,1|8qhlrz,90,192,1|8qhls0,93,195,0|8zun3z,93,195,0|8zun40,90,192,1|997ofz,90,192,1|997og0,93,195,0|9ikprz,93,195,0|9ikps0,90,192,1|9rxr3z,90,192,1|9rxr40,93,195,0|a1asfz,93,195,0|a1asg0,90,192,1|aantrz,90,192,1|aants0,93,195,0|ak0v3z,93,195,0|ak0v40,90,192,1|atqv3z,90,192,1|atqv40,93,195,0|b33wfz,93,195,0|b33wg0,93,195,1|bch0jz,93,195,1|bch0k0,107,224,0|bi8f7z,107,224,0|bi8f80,93,195,0|bltz3z,93,195,0|bltz40,90,192,1|bv70fz,90,192,1|bv70g0,93,195,0|c4k1rz,93,195,0|c4k1s0,90,192,1|cdx33z,90,192,1|cdx340,93,195,0|cna4fz,93,195,0|cna4g0,90,192,1|cwn5rz,90,192,1|cwn5s0,93,195,0|d6073z,93,195,0|d60740,90,192,1|dfd8fz,90,192,1|dfd8g0,93,195,0|dp38fz,93,195,0|dp38g0,90,192,1|dzw4fz,90,192,1|dzw4g0,93,195,0|e7tb3z,93,195,0|e7tb40,90,192,1|eim73z,90,192,1|eim740,93,195,0|eqjdrz,93,195,0|eqjds0,90,192,1|f1c9rz,90,192,1|f1c9s0,93,195,0|f99gfz,93,195,0|f99gg0,90,192,1|fkfb3z,90,192,1|fkfb40,93,195,0|frzj3z,93,195,0|frzj40,90,192,1|g35drz,90,192,1|g35ds0,93,195,0|gaplrz,93,195,0|gapls0,90,192,1|glvgfz,90,192,1|glvgg0,93,195,0|gtsn3z,93,195,0|gtsn40,90,192,1|h4lj3z,90,192,1|h4lj40,93,195,0|hciprz,93,195,0|hcips0,90,192,1|hnblrz,90,192,1|hnbls0,93,195,0|hv8sfz,93,195,0|hv8sg0,90,192,1|i6en3z,90,192,1|i6en40,93,195,0|idyv3z,93,195,0|idyv40,90,192,1|ip4prz,90,192,1|ip4ps0,93,195,0|iwoxrz,93,195,0|iwoxs0,90,192,1|j7usfz,90,192,1|j7usg0,93,195,0|jff0fz,93,195,0|jff0g0,90,192,1|jqkv3z,90,192,1|jqkv40,93,195,0|jyi1rz,93,195,0|jyi1s0,90,192,1|k9axrz,90,192,1|k9axs0,93,195,0|kh84fz,93,195,0|kh84g0,90,192,1|ks10fz,90,192,1|ks10g0,93,195,0|kzy73z,93,195,0|kzy740,90,192,1|lb41rz,90,192,1|lb41s0,93,195,0|lio9rz,93,195,0|lio9s0,90,192,0|ne09nz,90,192,0|ne09o0,93,195,0\",\"Asia/Yakutsk|,0,296,0|-q4cioy,89,191,0|-kmri81,89,191,0|-kmri80,107,224,0|5vapnz,107,224,0|5vapo0,93,195,1|64pivz,93,195,1|64piw0,107,224,0|6e2mzz,107,224,0|6e2n00,93,195,1|6nhg7z,93,195,1|6nhg80,107,224,0|6wukbz,107,224,0|6wukc0,93,195,1|769djz,93,195,1|769dk0,107,224,0|7focbz,107,224,0|7focc0,93,195,1|7p1j7z,93,195,1|7p1j80,107,224,0|7yekjz,107,224,0|7yekk0,93,195,1|87rlvz,93,195,1|87rlw0,107,224,0|8h4n7z,107,224,0|8h4n80,93,195,1|8qhojz,93,195,1|8qhok0,107,224,0|8zupvz,107,224,0|8zupw0,93,195,1|997r7z,93,195,1|997r80,107,224,0|9iksjz,107,224,0|9iksk0,93,195,1|9rxtvz,93,195,1|9rxtw0,107,224,0|a1av7z,107,224,0|a1av80,93,195,1|aanwjz,93,195,1|aanwk0,107,224,0|ak0xvz,107,224,0|ak0xw0,93,195,1|atqxvz,93,195,1|atqxw0,107,224,0|b33z7z,107,224,0|b33z80,107,224,1|bch3bz,107,224,1|bch3c0,89,191,0|bi8hzz,89,191,0|bi8i00,107,224,0|blu1vz,107,224,0|blu1w0,93,195,1|bv737z,93,195,1|bv7380,107,224,0|c4k4jz,107,224,0|c4k4k0,93,195,1|cdx5vz,93,195,1|cdx5w0,107,224,0|cna77z,107,224,0|cna780,93,195,1|cwn8jz,93,195,1|cwn8k0,107,224,0|d609vz,107,224,0|d609w0,93,195,1|dfdb7z,93,195,1|dfdb80,107,224,0|dp3b7z,107,224,0|dp3b80,93,195,1|dzw77z,93,195,1|dzw780,107,224,0|e7tdvz,107,224,0|e7tdw0,93,195,1|eim9vz,93,195,1|eim9w0,107,224,0|eqjgjz,107,224,0|eqjgk0,93,195,1|f1ccjz,93,195,1|f1cck0,107,224,0|f99j7z,107,224,0|f99j80,93,195,1|fkfdvz,93,195,1|fkfdw0,107,224,0|frzlvz,107,224,0|frzlw0,93,195,1|g35gjz,93,195,1|g35gk0,107,224,0|gapojz,107,224,0|gapok0,93,195,1|glvj7z,93,195,1|glvj80,107,224,0|gtspvz,107,224,0|gtspw0,93,195,1|h4llvz,93,195,1|h4llw0,107,224,0|hcisjz,107,224,0|hcisk0,93,195,1|hnbojz,93,195,1|hnbok0,107,224,0|hv8v7z,107,224,0|hv8v80,93,195,1|i6epvz,93,195,1|i6epw0,107,224,0|idyxvz,107,224,0|idyxw0,93,195,1|ip4sjz,93,195,1|ip4sk0,107,224,0|iwp0jz,107,224,0|iwp0k0,93,195,1|j7uv7z,93,195,1|j7uv80,107,224,0|jff37z,107,224,0|jff380,93,195,1|jqkxvz,93,195,1|jqkxw0,107,224,0|jyi4jz,107,224,0|jyi4k0,93,195,1|k9b0jz,93,195,1|k9b0k0,107,224,0|kh877z,107,224,0|kh8780,93,195,1|ks137z,93,195,1|ks1380,107,224,0|kzy9vz,107,224,0|kzy9w0,93,195,1|lb44jz,93,195,1|lb44k0,107,224,0|liocjz,107,224,0|liock0,93,195,0|ne0cfz,93,195,0|ne0cg0,107,224,0\",\"Asia/Yangon|,0,297,0|-1ayykhb,136,297,0|-q3gv5c,136,297,0|-q3gv5b,109,229,0|-efx621,109,229,0|-efx620,107,224,0|-cvg101,107,224,0|-cvg100,109,229,0\",\"Asia/Yekaterinburg|,0,298,0|-rx5hw9,7,299,0|-qc75z6,7,299,0|-qc75z5,105,209,0|-kmr741,105,209,0|-kmr740,92,194,0|5vb0rz,92,194,0|5vb0s0,96,196,1|64ptzz,96,196,1|64pu00,92,194,0|6e2y3z,92,194,0|6e2y40,96,196,1|6nhrbz,96,196,1|6nhrc0,92,194,0|6wuvfz,92,194,0|6wuvg0,96,196,1|769onz,96,196,1|769oo0,92,194,0|7fonfz,92,194,0|7fong0,96,196,1|7p1ubz,96,196,1|7p1uc0,92,194,0|7yevnz,92,194,0|7yevo0,96,196,1|87rwzz,96,196,1|87rx00,92,194,0|8h4ybz,92,194,0|8h4yc0,96,196,1|8qhznz,96,196,1|8qhzo0,92,194,0|8zv0zz,92,194,0|8zv100,96,196,1|9982bz,96,196,1|9982c0,92,194,0|9il3nz,92,194,0|9il3o0,96,196,1|9ry4zz,96,196,1|9ry500,92,194,0|a1b6bz,92,194,0|a1b6c0,96,196,1|aao7nz,96,196,1|aao7o0,92,194,0|ak18zz,92,194,0|ak1900,96,196,1|atr8zz,96,196,1|atr900,92,194,0|b34abz,92,194,0|b34ac0,92,194,1|bchefz,92,194,1|bcheg0,105,209,0|bi8t3z,105,209,0|bi8t40,92,194,0|bluczz,92,194,0|blud00,96,196,1|bv7ebz,96,196,1|bv7ec0,92,194,0|c4kfnz,92,194,0|c4kfo0,96,196,1|cdxgzz,96,196,1|cdxh00,92,194,0|cnaibz,92,194,0|cnaic0,96,196,1|cwnjnz,96,196,1|cwnjo0,92,194,0|d60kzz,92,194,0|d60l00,96,196,1|dfdmbz,96,196,1|dfdmc0,92,194,0|dp3mbz,92,194,0|dp3mc0,96,196,1|dzwibz,96,196,1|dzwic0,92,194,0|e7tozz,92,194,0|e7tp00,96,196,1|eimkzz,96,196,1|eiml00,92,194,0|eqjrnz,92,194,0|eqjro0,96,196,1|f1cnnz,96,196,1|f1cno0,92,194,0|f99ubz,92,194,0|f99uc0,96,196,1|fkfozz,96,196,1|fkfp00,92,194,0|frzwzz,92,194,0|frzx00,96,196,1|g35rnz,96,196,1|g35ro0,92,194,0|gapznz,92,194,0|gapzo0,96,196,1|glvubz,96,196,1|glvuc0,92,194,0|gtt0zz,92,194,0|gtt100,96,196,1|h4lwzz,96,196,1|h4lx00,92,194,0|hcj3nz,92,194,0|hcj3o0,96,196,1|hnbznz,96,196,1|hnbzo0,92,194,0|hv96bz,92,194,0|hv96c0,96,196,1|i6f0zz,96,196,1|i6f100,92,194,0|idz8zz,92,194,0|idz900,96,196,1|ip53nz,96,196,1|ip53o0,92,194,0|iwpbnz,92,194,0|iwpbo0,96,196,1|j7v6bz,96,196,1|j7v6c0,92,194,0|jffebz,92,194,0|jffec0,96,196,1|jql8zz,96,196,1|jql900,92,194,0|jyifnz,92,194,0|jyifo0,96,196,1|k9bbnz,96,196,1|k9bbo0,92,194,0|kh8ibz,92,194,0|kh8ic0,96,196,1|ks1ebz,96,196,1|ks1ec0,92,194,0|kzykzz,92,194,0|kzyl00,96,196,1|lb4fnz,96,196,1|lb4fo0,92,194,0|lionnz,92,194,0|liono0,96,196,0|ne0njz,96,196,0|ne0nk0,92,194,0\",\"Asia/Yerevan|,0,300,0|-nu148o,100,6,0|-6p7kc1,100,6,0|-6p7kc0,105,209,0|5vb3jz,105,209,0|5vb3k0,92,194,1|64pwrz,92,194,1|64pws0,105,209,0|6e30vz,105,209,0|6e30w0,92,194,1|6nhu3z,92,194,1|6nhu40,105,209,0|6wuy7z,105,209,0|6wuy80,92,194,1|769rfz,92,194,1|769rg0,105,209,0|7foq7z,105,209,0|7foq80,92,194,1|7p1x3z,92,194,1|7p1x40,105,209,0|7yeyfz,105,209,0|7yeyg0,92,194,1|87rzrz,92,194,1|87rzs0,105,209,0|8h513z,105,209,0|8h5140,92,194,1|8qi2fz,92,194,1|8qi2g0,105,209,0|8zv3rz,105,209,0|8zv3s0,92,194,1|99853z,92,194,1|998540,105,209,0|9il6fz,105,209,0|9il6g0,92,194,1|9ry7rz,92,194,1|9ry7s0,105,209,0|a1b93z,105,209,0|a1b940,92,194,1|aaoafz,92,194,1|aaoag0,105,209,0|ak1brz,105,209,0|ak1bs0,92,194,1|atrbrz,92,194,1|atrbs0,105,209,0|b34d3z,105,209,0|b34d40,105,209,1|bchh7z,105,209,1|bchh80,100,6,0|bluijz,100,6,0|bluik0,105,209,1|bv7jvz,105,209,1|bv7jw0,100,6,0|c4kl7z,100,6,0|c4kl80,105,209,1|cdxmjz,105,209,1|cdxmk0,100,6,0|cnanvz,100,6,0|cnanw0,105,209,1|cwnp7z,105,209,1|cwnp80,100,6,0|d60qjz,100,6,0|d60qk0,105,209,1|dfdrvz,105,209,1|dfdrw0,105,209,0|e7trrz,105,209,0|e7trs0,92,194,1|eimnrz,92,194,1|eimns0,105,209,0|eqjufz,105,209,0|eqjug0,92,194,1|f1cqfz,92,194,1|f1cqg0,105,209,0|f99x3z,105,209,0|f99x40,92,194,1|fkfrrz,92,194,1|fkfrs0,105,209,0|frzzrz,105,209,0|frzzs0,92,194,1|g35ufz,92,194,1|g35ug0,105,209,0|gaq2fz,105,209,0|gaq2g0,92,194,1|glvx3z,92,194,1|glvx40,105,209,0|gtt3rz,105,209,0|gtt3s0,92,194,1|h4lzrz,92,194,1|h4lzs0,105,209,0|hcj6fz,105,209,0|hcj6g0,92,194,1|hnc2fz,92,194,1|hnc2g0,105,209,0|hv993z,105,209,0|hv9940,92,194,1|i6f3rz,92,194,1|i6f3s0,105,209,0|idzbrz,105,209,0|idzbs0,92,194,1|ip56fz,92,194,1|ip56g0,105,209,0|iwpefz,105,209,0|iwpeg0,92,194,1|j7v93z,92,194,1|j7v940,105,209,0|jffh3z,105,209,0|jffh40,92,194,1|jqlbrz,92,194,1|jqlbs0,105,209,0|jyiifz,105,209,0|jyiig0,92,194,1|k9befz,92,194,1|k9beg0,105,209,0|kh8l3z,105,209,0|kh8l40,92,194,1|ks1h3z,92,194,1|ks1h40,105,209,0|kzynrz,105,209,0|kzyns0,92,194,1|lb4ifz,92,194,1|lb4ig0,105,209,0|lioqfz,105,209,0|lioqg0,92,194,1|ltul3z,92,194,1|ltul40,105,209,0\",\"Atlantic/Azores|,0,301,0|-18vsdww,77,302,0|-u9rbs1,77,302,0|-u9rbs0,40,45,0|-rxwvw1,40,45,0|-rxwvw0,13,15,1|-rqwyg1,13,15,1|-rqwyg0,40,45,0|-rkqt81,40,45,0|-rkqt80,13,15,1|-r90l81,13,15,1|-r90l80,40,45,0|-r1x181,40,45,0|-r1x180,13,15,1|-qq8nw1,13,15,1|-qq8nw0,40,45,0|-qj6yk1,40,45,0|-qj6yk0,13,15,1|-q7gqk1,13,15,1|-q7gqk0,40,45,0|-q0d6k1,40,45,0|-q0d6k0,13,15,1|-pomyk1,13,15,1|-pomyk0,40,45,0|-phl981,40,45,0|-phl980,13,15,1|-p5v181,13,15,1|-p5v180,40,45,0|-nusl81,40,45,0|-nusl80,13,15,1|-nlhek1,13,15,1|-nlhek0,40,45,0|-mt6vw1,40,45,0|-mt6vw0,13,15,1|-mkjrw1,13,15,1|-mkjrw0,40,45,0|-matrw1,40,45,0|-matrw0,13,15,1|-m1tp81,13,15,1|-m1tp80,40,45,0|-lrqqk1,40,45,0|-lrqqk0,13,15,1|-liqnw1,13,15,1|-liqnw0,40,45,0|-l8np81,40,45,0|-l8np80,13,15,1|-l00l81,13,15,1|-l00l80,40,45,0|-k77jw1,40,45,0|-k77jw0,13,15,1|-jykfw1,13,15,1|-jykfw0,40,45,0|-jp7ek1,40,45,0|-jp7ek0,13,15,1|-jfud81,13,15,1|-jfud80,40,45,0|-ineak1,40,45,0|-ineak0,13,15,1|-ie1981,13,15,1|-ie1980,40,45,0|-i516k1,40,45,0|-i516k0,13,15,1|-hvb6k1,13,15,1|-hvb6k0,40,45,0|-hl87w1,40,45,0|-hl87w0,13,15,1|-hcl3w1,13,15,1|-hcl3w0,40,45,0|-h382k1,40,45,0|-h382k0,13,15,1|-gtv181,13,15,1|-gtv180,40,45,0|-gkuyk1,40,45,0|-gkuyk0,13,15,1|-gb4yk1,13,15,1|-gb4yk0,40,45,0|-g11zw1,40,45,0|-g11zw0,13,15,1|-fpw581,13,15,1|-fpw580,40,45,0|-fkunw1,40,45,0|-fkunw0,13,15,1|-f9buk1,13,15,1|-f9buk0,40,45,0|-ezyt81,40,45,0|-ezyt80,13,15,1|-eqjx81,13,15,1|-eqjx80,40,45,0|-eibmk1,40,45,0|-eibmk0,13,15,1|-eg5xc1,13,15,1|-eg5xc0,17,1,1|-eaeio1,17,1,1|-eaeio0,13,15,1|-e6st81,13,15,1|-e6st80,40,45,0|-dzljw1,40,45,0|-dzljw0,13,15,1|-dxstc1,13,15,1|-dxstc0,17,1,1|-dqyio1,17,1,1|-dqyio0,13,15,1|-dnprw1,13,15,1|-dnprw0,40,45,0|-dgvh81,40,45,0|-dgvh80,13,15,1|-deps01,13,15,1|-deps00,17,1,1|-d88g01,17,1,1|-d88g00,13,15,1|-d4zp81,13,15,1|-d4zp80,40,45,0|-cy5ek1,40,45,0|-cy5ek0,13,15,1|-cvzpc1,13,15,1|-cvzpc0,17,1,1|-cpidc1,17,1,1|-cpidc0,13,15,1|-cm9mk1,13,15,1|-cm9mk0,40,45,0|-cdzh81,40,45,0|-cdzh80,13,15,1|-c4mfw1,13,15,1|-c4mfw0,40,45,0|-bv9681,40,45,0|-bv9680,13,15,1|-blw4w1,13,15,1|-blw4w0,40,45,0|-bcj3k1,40,45,0|-bcj3k0,13,15,1|-b36281,13,15,1|-b36280,40,45,0|-att0w1,40,45,0|-att0w0,13,15,1|-akfzk1,13,15,1|-akfzk0,40,45,0|-9scvk1,40,45,0|-9scvk0,13,15,1|-9imvk1,13,15,1|-9imvk0,40,45,0|-999u81,40,45,0|-999u80,13,15,1|-8zwsw1,13,15,1|-8zwsw0,40,45,0|-8qjrk1,40,45,0|-8qjrk0,13,15,1|-8h6q81,13,15,1|-8h6q80,40,45,0|-87tow1,40,45,0|-87tow0,13,15,1|-7ygnk1,13,15,1|-7ygnk0,40,45,0|-7p3m81,40,45,0|-7p3m80,13,15,1|-7fqkw1,13,15,1|-7fqkw0,40,45,0|-76djk1,40,45,0|-76djk0,13,15,1|-6wnjk1,13,15,1|-6wnjk0,40,45,0|-6nai81,40,45,0|-6nai80,13,15,1|-6dxgw1,13,15,1|-6dxgw0,40,45,0|-64kfk1,40,45,0|-64kfk0,13,15,1|-5v7e81,13,15,1|-5v7e80,40,45,0|-5lucw1,40,45,0|-5lucw0,13,15,1|-5chbk1,13,15,1|-5chbk0,40,45,0|-534a81,40,45,0|-534a80,13,15,1|-4tr8w1,13,15,1|-4tr8w0,40,45,0|-4ke7k1,40,45,0|-4ke7k0,13,15,1|-4b1681,13,15,1|-4b1680,40,45,0|-41o4w1,40,45,0|-41o4w0,13,15,1|-3ry4w1,13,15,1|-3ry4w0,40,45,0|-3il3k1,40,45,0|-3il3k0,13,15,1|-398281,13,15,1|-398280,40,45,0|-2zv0w1,40,45,0|-2zv0w0,13,15,1|-2qhzk1,13,15,1|-2qhzk0,40,45,0|-2h4y81,40,45,0|-2h4y80,13,15,1|-27rww1,13,15,1|-27rww0,40,45,0|-1yevk1,40,45,0|-1yevk0,13,15,0|3rwo3z,13,15,0|3rwo40,17,1,1|419pfz,17,1,1|419pg0,13,15,0|4azpfz,13,15,0|4azpg0,17,1,1|4kcqrz,17,1,1|4kcqs0,13,15,0|4tps3z,13,15,0|4tps40,17,1,1|532w7z,17,1,1|532w80,13,15,0|5cfurz,13,15,0|5cfus0,17,1,1|5lsyvz,17,1,1|5lsyw0,13,15,0|5v607z,13,15,0|5v6080,17,1,1|64j1jz,17,1,1|64j1k0,13,15,0|6dw2vz,13,15,0|6dw2w0,17,1,1|6n947z,17,1,1|6n9480,13,15,0|6wm8bz,13,15,0|6wm8c0,17,1,1|75z6vz,17,1,1|75z6w0,13,15,0|7fc87z,13,15,0|7fc880,17,1,1|7p287z,17,1,1|7p2880,13,15,0|7yf9jz,13,15,0|7yf9k0,17,1,1|87savz,17,1,1|87saw0,13,15,0|8h5c7z,13,15,0|8h5c80,17,1,1|8qidjz,17,1,1|8qidk0,13,15,0|8zvevz,13,15,0|8zvew0,17,1,1|998g7z,17,1,1|998g80,13,15,0|9ilhjz,13,15,0|9ilhk0,17,1,1|9ryivz,17,1,1|9ryiw0,13,15,0|a1bk7z,13,15,0|a1bk80,17,1,1|aaoljz,17,1,1|aaolk0,13,15,0|ak1mvz,13,15,0|ak1mw0,17,1,1|atrmvz,17,1,1|atrmw0,13,15,0|b34o7z,13,15,0|b34o80,17,1,1|bchpjz,17,1,1|bchpk0,13,15,0|bluqvz,13,15,0|bluqw0,17,1,1|bv7s7z,17,1,1|bv7s80,8,1,0|c4kqrz,8,1,0|c4kqs0,17,1,1|cdxs3z,17,1,1|cdxs40,13,15,0|cnatfz,13,15,0|cnatg0,17,1,1|cwnurz,17,1,1|cwnus0,13,15,0|d60w3z,13,15,0|d60w40,17,1,1|dfdxfz,17,1,1|dfdxg0,13,15,0|dp3xfz,13,15,0|dp3xg0,17,1,1|dzwtfz,17,1,1|dzwtg0,13,15,0|e7u03z,13,15,0|e7u040,17,1,1|eimw3z,17,1,1|eimw40,13,15,0|eqk2rz,13,15,0|eqk2s0,17,1,1|f1cyrz,17,1,1|f1cys0,13,15,0|f9a5fz,13,15,0|f9a5g0,17,1,1|fkg03z,17,1,1|fkg040,13,15,0|fs083z,13,15,0|fs0840,17,1,1|g362rz,17,1,1|g362s0,13,15,0|gaqarz,13,15,0|gaqas0,17,1,1|glw5fz,17,1,1|glw5g0,13,15,0|gttc3z,13,15,0|gttc40,17,1,1|h4m83z,17,1,1|h4m840,13,15,0|hcjerz,13,15,0|hcjes0,17,1,1|hncarz,17,1,1|hncas0,13,15,0|hv9hfz,13,15,0|hv9hg0,17,1,1|i6fc3z,17,1,1|i6fc40,13,15,0|idzk3z,13,15,0|idzk40,17,1,1|ip5erz,17,1,1|ip5es0,13,15,0|iwpmrz,13,15,0|iwpms0,17,1,1|j7vhfz,17,1,1|j7vhg0,13,15,0|jffpfz,13,15,0|jffpg0,17,1,1|jqlk3z,17,1,1|jqlk40,13,15,0|jyiqrz,13,15,0|jyiqs0,17,1,1|k9bmrz,17,1,1|k9bms0,13,15,0|kh8tfz,13,15,0|kh8tg0,17,1,1|ks1pfz,17,1,1|ks1pg0,13,15,0|kzyw3z,13,15,0|kzyw40,17,1,1|lb4qrz,17,1,1|lb4qs0,13,15,0|lioyrz,13,15,0|lioys0,17,1,1|ltutfz,17,1,1|ltutg0,13,15,0|m1f1fz,13,15,0|m1f1g0,17,1,1|mckw3z,17,1,1|mckw40,13,15,0|mki2rz,13,15,0|mki2s0,17,1,1|mvayrz,17,1,1|mvays0,13,15,0|n385fz,13,15,0|n385g0,17,1,1|ne11fz,17,1,1|ne11g0,13,15,0|nly83z,13,15,0|nly840,17,1,1|nwr43z,17,1,1|nwr440,13,15,0|o4oarz,13,15,0|o4oas0,17,1,1|ofu5fz,17,1,1|ofu5g0,13,15,0|onedfz,13,15,0|onedg0,17,1,1|oyk83z,17,1,1|oyk840,13,15,0|p64g3z,13,15,0|p64g40,17,1,1|phaarz,17,1,1|phaas0,13,15,0|pp7hfz,13,15,0|pp7hg0,17,1,1|q00dfz,17,1,1|q00dg0,13,15,0|q7xk3z,13,15,0|q7xk40,17,1,1|qiqg3z,17,1,1|qiqg40,13,15,0|qqnmrz,13,15,0|qqnms0,17,1,1|r1thfz,17,1,1|r1thg0,13,15,0|r9dpfz,13,15,0|r9dpg0,17,1,1|rkjk3z,17,1,1|rkjk40,13,15,0|rs3s3z,13,15,0|rs3s40,17,1,1|s39mrz,17,1,1|s39ms0,13,15,0|sb6tfz,13,15,0|sb6tg0,17,1,1|slzpfz,17,1,1|slzpg0,13,15,0|stww3z,13,15,0|stww40,17,1,1|t4ps3z,17,1,1|t4ps40,13,15,0|tcmyrz,13,15,0|tcmys0,17,1,1|tnfurz,17,1,1|tnfus0,13,15,0|tvd1fz,13,15,0|tvd1g0,17,1,1|u6iw3z,17,1,1|u6iw40,13,15,0|ue343z,13,15,0|ue3440,17,1,1|up8yrz,17,1,1|up8ys0,13,15,0|uwt6rz,13,15,0|uwt6s0,17,1,1|v7z1fz,17,1,1|v7z1g0,13,15,0|vfw83z,13,15,0|vfw840,17,1,1|vqp43z,17,1,1|vqp440,13,15,0|vymarz,13,15,0|vymas0,17,1,1|w9f6rz,17,1,1|w9f6s0,13,15,0|whcdfz,13,15,0|whcdg0,17,1,1|wsi83z,17,1,1|wsi840,13,15,0|x02g3z,13,15,0|x02g40,17,1,1|xb8arz,17,1,1|xb8as0,13,15,0|xisirz,13,15,0|xisis0,17,1,1|xtydfz,17,1,1|xtydg0,13,15,0|y1ilfz,13,15,0|y1ilg0,17,1,1|ycog3z,17,1,1|ycog40,13,15,0|yklmrz,13,15,0|yklms0,17,1,1|yveirz,17,1,1|yveis0,13,15,0|z3bpfz,13,15,0|z3bpg0,17,1,1|ze4lfz,17,1,1|ze4lg0,13,15,0\",\"Atlantic/Bermuda|,0,303,0|-15r0xbu,53,303,0|-rivvzv,53,303,0|-rivvzu,27,304,1|-r9qc3v,27,304,1|-r9qc3u,53,303,0|-qzp5bv,53,303,0|-qzp5bu,27,304,1|-qrq6rv,27,304,1|-qrq6ru,53,303,0|-kvj2fv,53,303,0|-kvj2fu,32,42,0|-eljwo1,32,42,0|-eljwo0,54,44,1|-e75gs1,54,44,1|-e75gs0,32,42,0|-dz87c1,32,42,0|-dz87c0,54,44,1|-dnpgs1,54,44,1|-dnpgs0,32,42,0|-dgv3c1,32,42,0|-dgv3c0,54,44,1|-d4mfg1,54,44,1|-d4mfg0,32,42,0|-cy50o1,32,42,0|-cy50o0,54,44,1|-clwcs1,54,44,1|-clwcs0,32,42,0|-bt38o1,32,42,0|-bt38o0,54,44,1|-bmyy41,54,44,1|-bmyy40,32,42,0|-ba07c1,32,42,0|-ba07c0,54,44,1|-b4lu41,54,44,1|-b4lu40,32,42,0|-ara4o1,32,42,0|-ara4o0,54,44,1|-alvrg1,54,44,1|-alvrg0,32,42,0|-a873c1,32,42,0|-a873c0,54,44,1|-a35os1,54,44,1|-a35os0,32,42,0|-9ph0o1,32,42,0|-9ph0o0,54,44,1|-9kfm41,54,44,1|-9kfm40,32,42,0|-96qy01,32,42,0|-96qy00,54,44,1|-91cks1,54,44,1|-91cks0,32,42,0|-73hoo1,32,42,0|-73hoo0,54,44,1|-6vkks1,54,44,1|-6vkks0,32,42,0|296onz,32,42,0|296oo0,54,44,1|2ijn7z,54,44,1|2ijn80,32,42,0|2rwrbz,32,42,0|2rwrc0,54,44,1|319pvz,54,44,1|319pw0,32,42,0|3amtzz,32,42,0|3amu00,54,44,1|3kcr7z,54,44,1|3kcr80,32,42,0|3tcwnz,32,42,0|3tcwo0,54,44,1|432tvz,54,44,1|432tw0,32,42,0|4cfxzz,32,42,0|4cfy00,54,44,1|4lswjz,54,44,1|4lswk0,32,42,0|4v60nz,32,42,0|4v60o0,54,44,1|54iz7z,54,44,1|54iz80,32,42,0|5dw3bz,32,42,0|5dw3c0,54,44,1|5n91vz,54,44,1|5n91w0,32,42,0|5wm5zz,32,42,0|5wm600,54,44,1|65z4jz,54,44,1|65z4k0,32,42,0|6fc8nz,32,42,0|6fc8o0,54,44,1|6p25vz,54,44,1|6p25w0,32,42,0|6y2bbz,32,42,0|6y2bc0,54,44,1|77s8jz,54,44,1|77s8k0,32,42,0|7h5cnz,32,42,0|7h5co0,54,44,1|7qib7z,54,44,1|7qib80,32,42,0|7zvfbz,32,42,0|7zvfc0,54,44,1|898dvz,54,44,1|898dw0,32,42,0|8ilhzz,32,42,0|8ili00,54,44,1|8rygjz,54,44,1|8rygk0,32,42,0|908onz,32,42,0|908oo0,54,44,1|9aoj7z,54,44,1|9aoj80,32,42,0|9iyrbz,32,42,0|9iyrc0,54,44,1|9trkjz,54,44,1|9trkk0,32,42,0|a1otzz,32,42,0|a1ou00,54,44,1|achn7z,54,44,1|achn80,32,42,0|akewnz,32,42,0|akewo0,54,44,1|av7pvz,54,44,1|av7pw0,32,42,0|b3hxzz,32,42,0|b3hy00,54,44,1|bdxsjz,54,44,1|bdxsk0,32,42,0|bm80nz,32,42,0|bm80o0,54,44,1|bwnv7z,54,44,1|bwnv80,32,42,0|c4y3bz,32,42,0|c4y3c0,54,44,1|cfqwjz,54,44,1|cfqwk0,32,42,0|cno5zz,32,42,0|cno600,54,44,1|cygz7z,54,44,1|cygz80,32,42,0|d6e8nz,32,42,0|d6e8o0,54,44,1|dh71vz,54,44,1|dh71w0,32,42,0|dph9zz,32,42,0|dpha00,54,44,1|dzx4jz,54,44,1|dzx4k0,32,42,0|e87cnz,32,42,0|e87co0,54,44,1|ein77z,54,44,1|ein780,32,42,0|eqxfbz,32,42,0|eqxfc0,54,44,1|f1d9vz,54,44,1|f1d9w0,32,42,0|f9nhzz,32,42,0|f9ni00,54,44,1|fkgb7z,54,44,1|fkgb80,32,42,0|fsdknz,32,42,0|fsdko0,54,44,1|g36dvz,54,44,1|g36dw0,32,42,0|gb3nbz,32,42,0|gb3nc0,54,44,1|glwgjz,54,44,1|glwgk0,32,42,0|gu6onz,32,42,0|gu6oo0,54,44,1|h4mj7z,54,44,1|h4mj80,32,42,0|hcwrbz,32,42,0|hcwrc0,54,44,1|hnclvz,54,44,1|hnclw0,32,42,0|hvmtzz,32,42,0|hvmu00,54,44,1|i6fn7z,54,44,1|i6fn80,32,42,0|iecwnz,32,42,0|iecwo0,54,44,1|ip5pvz,54,44,1|ip5pw0,32,42,0|ix2zbz,32,42,0|ix2zc0,54,44,1|j7vsjz,54,44,1|j7vsk0,32,42,0|jeq5zz,32,42,0|jeq600,54,44,1|jqytvz,54,44,1|jqytw0,32,42,0|jxg8nz,32,42,0|jxg8o0,54,44,1|k9owjz,54,44,1|k9owk0,32,42,0|kg6bbz,32,42,0|kg6bc0,54,44,1|ksez7z,54,44,1|ksez80,32,42,0|kz9cnz,32,42,0|kz9co0,54,44,1|lbi0jz,54,44,1|lbi0k0,32,42,0|lhzfbz,32,42,0|lhzfc0,54,44,1|lu837z,54,44,1|lu8380,32,42,0|m0phzz,32,42,0|m0pi00,54,44,1|mcy5vz,54,44,1|mcy5w0,32,42,0|mjfknz,32,42,0|mjfko0,54,44,1|mvo8jz,54,44,1|mvo8k0,32,42,0|n25nbz,32,42,0|n25nc0,54,44,1|neeb7z,54,44,1|neeb80,32,42,0|nkvpzz,32,42,0|nkvq00,54,44,1|nx4dvz,54,44,1|nx4dw0,32,42,0|o3yrbz,32,42,0|o3yrc0,54,44,1|og7f7z,54,44,1|og7f80,32,42,0|omotzz,32,42,0|omou00,54,44,1|oyxhvz,54,44,1|oyxhw0,32,42,0|p5ewnz,32,42,0|p5ewo0,54,44,1|phnkjz,54,44,1|phnkk0,32,42,0|po4zbz,32,42,0|po4zc0,54,44,1|q0dn7z,54,44,1|q0dn80,32,42,0|q6v1zz,32,42,0|q6v200,54,44,1|qj3pvz,54,44,1|qj3pw0,32,42,0|qpy3bz,32,42,0|qpy3c0,54,44,1|r26r7z,54,44,1|r26r80,32,42,0|r8o5zz,32,42,0|r8o600,54,44,1|rkwtvz,54,44,1|rkwtw0,32,42,0|rre8nz,32,42,0|rre8o0,54,44,1|s3mwjz,54,44,1|s3mwk0,32,42,0|sa4bbz,32,42,0|sa4bc0,54,44,1|smcz7z,54,44,1|smcz80,32,42,0|ssudzz,32,42,0|ssue00,54,44,1|t531vz,54,44,1|t531w0,32,42,0|tbkgnz,32,42,0|tbkgo0,54,44,1|tnt4jz,54,44,1|tnt4k0,32,42,0|tunhzz,32,42,0|tuni00,54,44,1|u6w5vz,54,44,1|u6w5w0,32,42,0|uddknz,32,42,0|uddko0,54,44,1|upm8jz,54,44,1|upm8k0,32,42,0|uw3nbz,32,42,0|uw3nc0,54,44,1|v8cb7z,54,44,1|v8cb80,32,42,0|vetpzz,32,42,0|vetq00,54,44,1|vr2dvz,54,44,1|vr2dw0,32,42,0|vxjsnz,32,42,0|vxjso0,54,44,1|w9sgjz,54,44,1|w9sgk0,32,42,0|wgmtzz,32,42,0|wgmu00,54,44,1|wsvhvz,54,44,1|wsvhw0,32,42,0|wzcwnz,32,42,0|wzcwo0,54,44,1|xblkjz,54,44,1|xblkk0,32,42,0|xi2zbz,32,42,0|xi2zc0,54,44,1|xubn7z,54,44,1|xubn80,32,42,0|y0t1zz,32,42,0|y0t200,54,44,1|yd1pvz,54,44,1|yd1pw0,32,42,0|yjj4nz,32,42,0|yjj4o0,54,44,1|yvrsjz,54,44,1|yvrsk0,32,42,0|z297bz,32,42,0|z297c0,54,44,1|zehv7z,54,44,1|zehv80,32,42,0\",\"Atlantic/Canary|,0,305,0|-oytbtc,13,15,0|-c4xh41,13,15,0|-c4xh40,8,1,0|5csqnz,8,1,0|5csqo0,9,10,1|5lsw3z,9,10,1|5lsw40,8,1,0|5v5xfz,8,1,0|5v5xg0,9,10,1|64iyrz,9,10,1|64iys0,8,1,0|6dw03z,8,1,0|6dw040,9,10,1|6n91fz,9,10,1|6n91g0,8,1,0|6wm2rz,8,1,0|6wm2s0,9,10,1|75z43z,9,10,1|75z440,8,1,0|7fc5fz,8,1,0|7fc5g0,9,10,1|7p25fz,9,10,1|7p25g0,8,1,0|7yf6rz,8,1,0|7yf6s0,9,10,1|87s83z,9,10,1|87s840,8,1,0|8h59fz,8,1,0|8h59g0,9,10,1|8qiarz,9,10,1|8qias0,8,1,0|8zvc3z,8,1,0|8zvc40,9,10,1|998dfz,9,10,1|998dg0,8,1,0|9ilerz,8,1,0|9iles0,9,10,1|9ryg3z,9,10,1|9ryg40,8,1,0|a1bhfz,8,1,0|a1bhg0,9,10,1|aaoirz,9,10,1|aaois0,8,1,0|ak1k3z,8,1,0|ak1k40,9,10,1|atrk3z,9,10,1|atrk40,8,1,0|b34lfz,8,1,0|b34lg0,9,10,1|bchmrz,9,10,1|bchms0,8,1,0|bluo3z,8,1,0|bluo40,9,10,1|bv7pfz,9,10,1|bv7pg0,8,1,0|c4kqrz,8,1,0|c4kqs0,9,10,1|cdxs3z,9,10,1|cdxs40,8,1,0|cnatfz,8,1,0|cnatg0,9,10,1|cwnurz,9,10,1|cwnus0,8,1,0|d60w3z,8,1,0|d60w40,9,10,1|dfdxfz,9,10,1|dfdxg0,8,1,0|dp3xfz,8,1,0|dp3xg0,9,10,1|dzwtfz,9,10,1|dzwtg0,8,1,0|e7u03z,8,1,0|e7u040,9,10,1|eimw3z,9,10,1|eimw40,8,1,0|eqk2rz,8,1,0|eqk2s0,9,10,1|f1cyrz,9,10,1|f1cys0,8,1,0|f9a5fz,8,1,0|f9a5g0,9,10,1|fkg03z,9,10,1|fkg040,8,1,0|fs083z,8,1,0|fs0840,9,10,1|g362rz,9,10,1|g362s0,8,1,0|gaqarz,8,1,0|gaqas0,9,10,1|glw5fz,9,10,1|glw5g0,8,1,0|gttc3z,8,1,0|gttc40,9,10,1|h4m83z,9,10,1|h4m840,8,1,0|hcjerz,8,1,0|hcjes0,9,10,1|hncarz,9,10,1|hncas0,8,1,0|hv9hfz,8,1,0|hv9hg0,9,10,1|i6fc3z,9,10,1|i6fc40,8,1,0|idzk3z,8,1,0|idzk40,9,10,1|ip5erz,9,10,1|ip5es0,8,1,0|iwpmrz,8,1,0|iwpms0,9,10,1|j7vhfz,9,10,1|j7vhg0,8,1,0|jffpfz,8,1,0|jffpg0,9,10,1|jqlk3z,9,10,1|jqlk40,8,1,0|jyiqrz,8,1,0|jyiqs0,9,10,1|k9bmrz,9,10,1|k9bms0,8,1,0|kh8tfz,8,1,0|kh8tg0,9,10,1|ks1pfz,9,10,1|ks1pg0,8,1,0|kzyw3z,8,1,0|kzyw40,9,10,1|lb4qrz,9,10,1|lb4qs0,8,1,0|lioyrz,8,1,0|lioys0,9,10,1|ltutfz,9,10,1|ltutg0,8,1,0|m1f1fz,8,1,0|m1f1g0,9,10,1|mckw3z,9,10,1|mckw40,8,1,0|mki2rz,8,1,0|mki2s0,9,10,1|mvayrz,9,10,1|mvays0,8,1,0|n385fz,8,1,0|n385g0,9,10,1|ne11fz,9,10,1|ne11g0,8,1,0|nly83z,8,1,0|nly840,9,10,1|nwr43z,9,10,1|nwr440,8,1,0|o4oarz,8,1,0|o4oas0,9,10,1|ofu5fz,9,10,1|ofu5g0,8,1,0|onedfz,8,1,0|onedg0,9,10,1|oyk83z,9,10,1|oyk840,8,1,0|p64g3z,8,1,0|p64g40,9,10,1|phaarz,9,10,1|phaas0,8,1,0|pp7hfz,8,1,0|pp7hg0,9,10,1|q00dfz,9,10,1|q00dg0,8,1,0|q7xk3z,8,1,0|q7xk40,9,10,1|qiqg3z,9,10,1|qiqg40,8,1,0|qqnmrz,8,1,0|qqnms0,9,10,1|r1thfz,9,10,1|r1thg0,8,1,0|r9dpfz,8,1,0|r9dpg0,9,10,1|rkjk3z,9,10,1|rkjk40,8,1,0|rs3s3z,8,1,0|rs3s40,9,10,1|s39mrz,9,10,1|s39ms0,8,1,0|sb6tfz,8,1,0|sb6tg0,9,10,1|slzpfz,9,10,1|slzpg0,8,1,0|stww3z,8,1,0|stww40,9,10,1|t4ps3z,9,10,1|t4ps40,8,1,0|tcmyrz,8,1,0|tcmys0,9,10,1|tnfurz,9,10,1|tnfus0,8,1,0|tvd1fz,8,1,0|tvd1g0,9,10,1|u6iw3z,9,10,1|u6iw40,8,1,0|ue343z,8,1,0|ue3440,9,10,1|up8yrz,9,10,1|up8ys0,8,1,0|uwt6rz,8,1,0|uwt6s0,9,10,1|v7z1fz,9,10,1|v7z1g0,8,1,0|vfw83z,8,1,0|vfw840,9,10,1|vqp43z,9,10,1|vqp440,8,1,0|vymarz,8,1,0|vymas0,9,10,1|w9f6rz,9,10,1|w9f6s0,8,1,0|whcdfz,8,1,0|whcdg0,9,10,1|wsi83z,9,10,1|wsi840,8,1,0|x02g3z,8,1,0|x02g40,9,10,1|xb8arz,9,10,1|xb8as0,8,1,0|xisirz,8,1,0|xisis0,9,10,1|xtydfz,9,10,1|xtydg0,8,1,0|y1ilfz,8,1,0|y1ilg0,9,10,1|ycog3z,9,10,1|ycog40,8,1,0|yklmrz,8,1,0|yklms0,9,10,1|yveirz,9,10,1|yveis0,8,1,0|z3bpfz,8,1,0|z3bpg0,9,10,1|ze4lfz,9,10,1|ze4lg0,8,1,0\",\"Atlantic/Cape_Verde|,0,306,0|-u9rbs0,40,45,0|-e9kqg1,40,45,0|-e9kqg0,13,15,1|-cmxp81,13,15,1|-cmxp80,40,45,0|32t73z,40,45,0|32t740,13,15,0\",\"Atlantic/Faroe|,0,307,0|-wcehew,8,1,0|5v5xfz,8,1,0|5v5xg0,9,10,1|64iyrz,9,10,1|64iys0,8,1,0|6dw03z,8,1,0|6dw040,9,10,1|6n91fz,9,10,1|6n91g0,8,1,0|6wm2rz,8,1,0|6wm2s0,9,10,1|75z43z,9,10,1|75z440,8,1,0|7fc5fz,8,1,0|7fc5g0,9,10,1|7p25fz,9,10,1|7p25g0,8,1,0|7yf6rz,8,1,0|7yf6s0,9,10,1|87s83z,9,10,1|87s840,8,1,0|8h59fz,8,1,0|8h59g0,9,10,1|8qiarz,9,10,1|8qias0,8,1,0|8zvc3z,8,1,0|8zvc40,9,10,1|998dfz,9,10,1|998dg0,8,1,0|9ilerz,8,1,0|9iles0,9,10,1|9ryg3z,9,10,1|9ryg40,8,1,0|a1bhfz,8,1,0|a1bhg0,9,10,1|aaoirz,9,10,1|aaois0,8,1,0|ak1k3z,8,1,0|ak1k40,9,10,1|atrk3z,9,10,1|atrk40,8,1,0|b34lfz,8,1,0|b34lg0,9,10,1|bchmrz,9,10,1|bchms0,8,1,0|bluo3z,8,1,0|bluo40,9,10,1|bv7pfz,9,10,1|bv7pg0,8,1,0|c4kqrz,8,1,0|c4kqs0,9,10,1|cdxs3z,9,10,1|cdxs40,8,1,0|cnatfz,8,1,0|cnatg0,9,10,1|cwnurz,9,10,1|cwnus0,8,1,0|d60w3z,8,1,0|d60w40,9,10,1|dfdxfz,9,10,1|dfdxg0,8,1,0|dp3xfz,8,1,0|dp3xg0,9,10,1|dzwtfz,9,10,1|dzwtg0,8,1,0|e7u03z,8,1,0|e7u040,9,10,1|eimw3z,9,10,1|eimw40,8,1,0|eqk2rz,8,1,0|eqk2s0,9,10,1|f1cyrz,9,10,1|f1cys0,8,1,0|f9a5fz,8,1,0|f9a5g0,9,10,1|fkg03z,9,10,1|fkg040,8,1,0|fs083z,8,1,0|fs0840,9,10,1|g362rz,9,10,1|g362s0,8,1,0|gaqarz,8,1,0|gaqas0,9,10,1|glw5fz,9,10,1|glw5g0,8,1,0|gttc3z,8,1,0|gttc40,9,10,1|h4m83z,9,10,1|h4m840,8,1,0|hcjerz,8,1,0|hcjes0,9,10,1|hncarz,9,10,1|hncas0,8,1,0|hv9hfz,8,1,0|hv9hg0,9,10,1|i6fc3z,9,10,1|i6fc40,8,1,0|idzk3z,8,1,0|idzk40,9,10,1|ip5erz,9,10,1|ip5es0,8,1,0|iwpmrz,8,1,0|iwpms0,9,10,1|j7vhfz,9,10,1|j7vhg0,8,1,0|jffpfz,8,1,0|jffpg0,9,10,1|jqlk3z,9,10,1|jqlk40,8,1,0|jyiqrz,8,1,0|jyiqs0,9,10,1|k9bmrz,9,10,1|k9bms0,8,1,0|kh8tfz,8,1,0|kh8tg0,9,10,1|ks1pfz,9,10,1|ks1pg0,8,1,0|kzyw3z,8,1,0|kzyw40,9,10,1|lb4qrz,9,10,1|lb4qs0,8,1,0|lioyrz,8,1,0|lioys0,9,10,1|ltutfz,9,10,1|ltutg0,8,1,0|m1f1fz,8,1,0|m1f1g0,9,10,1|mckw3z,9,10,1|mckw40,8,1,0|mki2rz,8,1,0|mki2s0,9,10,1|mvayrz,9,10,1|mvays0,8,1,0|n385fz,8,1,0|n385g0,9,10,1|ne11fz,9,10,1|ne11g0,8,1,0|nly83z,8,1,0|nly840,9,10,1|nwr43z,9,10,1|nwr440,8,1,0|o4oarz,8,1,0|o4oas0,9,10,1|ofu5fz,9,10,1|ofu5g0,8,1,0|onedfz,8,1,0|onedg0,9,10,1|oyk83z,9,10,1|oyk840,8,1,0|p64g3z,8,1,0|p64g40,9,10,1|phaarz,9,10,1|phaas0,8,1,0|pp7hfz,8,1,0|pp7hg0,9,10,1|q00dfz,9,10,1|q00dg0,8,1,0|q7xk3z,8,1,0|q7xk40,9,10,1|qiqg3z,9,10,1|qiqg40,8,1,0|qqnmrz,8,1,0|qqnms0,9,10,1|r1thfz,9,10,1|r1thg0,8,1,0|r9dpfz,8,1,0|r9dpg0,9,10,1|rkjk3z,9,10,1|rkjk40,8,1,0|rs3s3z,8,1,0|rs3s40,9,10,1|s39mrz,9,10,1|s39ms0,8,1,0|sb6tfz,8,1,0|sb6tg0,9,10,1|slzpfz,9,10,1|slzpg0,8,1,0|stww3z,8,1,0|stww40,9,10,1|t4ps3z,9,10,1|t4ps40,8,1,0|tcmyrz,8,1,0|tcmys0,9,10,1|tnfurz,9,10,1|tnfus0,8,1,0|tvd1fz,8,1,0|tvd1g0,9,10,1|u6iw3z,9,10,1|u6iw40,8,1,0|ue343z,8,1,0|ue3440,9,10,1|up8yrz,9,10,1|up8ys0,8,1,0|uwt6rz,8,1,0|uwt6s0,9,10,1|v7z1fz,9,10,1|v7z1g0,8,1,0|vfw83z,8,1,0|vfw840,9,10,1|vqp43z,9,10,1|vqp440,8,1,0|vymarz,8,1,0|vymas0,9,10,1|w9f6rz,9,10,1|w9f6s0,8,1,0|whcdfz,8,1,0|whcdg0,9,10,1|wsi83z,9,10,1|wsi840,8,1,0|x02g3z,8,1,0|x02g40,9,10,1|xb8arz,9,10,1|xb8as0,8,1,0|xisirz,8,1,0|xisis0,9,10,1|xtydfz,9,10,1|xtydg0,8,1,0|y1ilfz,8,1,0|y1ilg0,9,10,1|ycog3z,9,10,1|ycog40,8,1,0|yklmrz,8,1,0|yklms0,9,10,1|yveirz,9,10,1|yveis0,8,1,0|z3bpfz,8,1,0|z3bpg0,9,10,1|ze4lfz,9,10,1|ze4lg0,8,1,0\",\"Atlantic/Madeira|,0,308,0|-18vsfjc,137,308,0|-u9rek1,137,308,0|-u9rek0,13,15,0|-rxwyo1,13,15,0|-rxwyo0,17,1,1|-rqx181,17,1,1|-rqx180,13,15,0|-rkqw01,13,15,0|-rkqw00,17,1,1|-r90o01,17,1,1|-r90o00,13,15,0|-r1x401,13,15,0|-r1x400,17,1,1|-qq8qo1,17,1,1|-qq8qo0,13,15,0|-qj71c1,13,15,0|-qj71c0,17,1,1|-q7gtc1,17,1,1|-q7gtc0,13,15,0|-q0d9c1,13,15,0|-q0d9c0,17,1,1|-pon1c1,17,1,1|-pon1c0,13,15,0|-phlc01,13,15,0|-phlc00,17,1,1|-p5v401,17,1,1|-p5v400,13,15,0|-nuso01,13,15,0|-nuso00,17,1,1|-nlhhc1,17,1,1|-nlhhc0,13,15,0|-mt6yo1,13,15,0|-mt6yo0,17,1,1|-mkjuo1,17,1,1|-mkjuo0,13,15,0|-matuo1,13,15,0|-matuo0,17,1,1|-m1ts01,17,1,1|-m1ts00,13,15,0|-lrqtc1,13,15,0|-lrqtc0,17,1,1|-liqqo1,17,1,1|-liqqo0,13,15,0|-l8ns01,13,15,0|-l8ns00,17,1,1|-l00o01,17,1,1|-l00o00,13,15,0|-k77mo1,13,15,0|-k77mo0,17,1,1|-jykio1,17,1,1|-jykio0,13,15,0|-jp7hc1,13,15,0|-jp7hc0,17,1,1|-jfug01,17,1,1|-jfug00,13,15,0|-inedc1,13,15,0|-inedc0,17,1,1|-ie1c01,17,1,1|-ie1c00,13,15,0|-i519c1,13,15,0|-i519c0,17,1,1|-hvb9c1,17,1,1|-hvb9c0,13,15,0|-hl8ao1,13,15,0|-hl8ao0,17,1,1|-hcl6o1,17,1,1|-hcl6o0,13,15,0|-h385c1,13,15,0|-h385c0,17,1,1|-gtv401,17,1,1|-gtv400,13,15,0|-gkv1c1,13,15,0|-gkv1c0,17,1,1|-gb51c1,17,1,1|-gb51c0,13,15,0|-g122o1,13,15,0|-g122o0,17,1,1|-fpw801,17,1,1|-fpw800,13,15,0|-fkuqo1,13,15,0|-fkuqo0,17,1,1|-f9bxc1,17,1,1|-f9bxc0,13,15,0|-ezyw01,13,15,0|-ezyw00,17,1,1|-eqk001,17,1,1|-eqk000,13,15,0|-eibpc1,13,15,0|-eibpc0,17,1,1|-eg6041,17,1,1|-eg6040,18,10,1|-eaelg1,18,10,1|-eaelg0,17,1,1|-e6sw01,17,1,1|-e6sw00,13,15,0|-dzlmo1,13,15,0|-dzlmo0,17,1,1|-dxsw41,17,1,1|-dxsw40,18,10,1|-dqylg1,18,10,1|-dqylg0,17,1,1|-dnpuo1,17,1,1|-dnpuo0,13,15,0|-dgvk01,13,15,0|-dgvk00,17,1,1|-depus1,17,1,1|-depus0,18,10,1|-d88is1,18,10,1|-d88is0,17,1,1|-d4zs01,17,1,1|-d4zs00,13,15,0|-cy5hc1,13,15,0|-cy5hc0,17,1,1|-cvzs41,17,1,1|-cvzs40,18,10,1|-cpig41,18,10,1|-cpig40,17,1,1|-cm9pc1,17,1,1|-cm9pc0,13,15,0|-cdzk01,13,15,0|-cdzk00,17,1,1|-c4mio1,17,1,1|-c4mio0,13,15,0|-bv9901,13,15,0|-bv9900,17,1,1|-blw7o1,17,1,1|-blw7o0,13,15,0|-bcj6c1,13,15,0|-bcj6c0,17,1,1|-b36501,17,1,1|-b36500,13,15,0|-att3o1,13,15,0|-att3o0,17,1,1|-akg2c1,17,1,1|-akg2c0,13,15,0|-9scyc1,13,15,0|-9scyc0,17,1,1|-9imyc1,17,1,1|-9imyc0,13,15,0|-999x01,13,15,0|-999x00,17,1,1|-8zwvo1,17,1,1|-8zwvo0,13,15,0|-8qjuc1,13,15,0|-8qjuc0,17,1,1|-8h6t01,17,1,1|-8h6t00,13,15,0|-87tro1,13,15,0|-87tro0,17,1,1|-7ygqc1,17,1,1|-7ygqc0,13,15,0|-7p3p01,13,15,0|-7p3p00,17,1,1|-7fqno1,17,1,1|-7fqno0,13,15,0|-76dmc1,13,15,0|-76dmc0,17,1,1|-6wnmc1,17,1,1|-6wnmc0,13,15,0|-6nal01,13,15,0|-6nal00,17,1,1|-6dxjo1,17,1,1|-6dxjo0,13,15,0|-64kic1,13,15,0|-64kic0,17,1,1|-5v7h01,17,1,1|-5v7h00,13,15,0|-5lufo1,13,15,0|-5lufo0,17,1,1|-5chec1,17,1,1|-5chec0,13,15,0|-534d01,13,15,0|-534d00,17,1,1|-4trbo1,17,1,1|-4trbo0,13,15,0|-4keac1,13,15,0|-4keac0,17,1,1|-4b1901,17,1,1|-4b1900,13,15,0|-41o7o1,13,15,0|-41o7o0,17,1,1|-3ry7o1,17,1,1|-3ry7o0,13,15,0|-3il6c1,13,15,0|-3il6c0,17,1,1|-398501,17,1,1|-398500,13,15,0|-2zv3o1,13,15,0|-2zv3o0,17,1,1|-2qi2c1,17,1,1|-2qi2c0,13,15,0|-2h5101,13,15,0|-2h5100,17,1,1|-27rzo1,17,1,1|-27rzo0,13,15,0|-1yeyc1,13,15,0|-1yeyc0,8,1,0|3rwlbz,8,1,0|3rwlc0,9,10,1|419mnz,9,10,1|419mo0,8,1,0|4azmnz,8,1,0|4azmo0,9,10,1|4kcnzz,9,10,1|4kco00,8,1,0|4tppbz,8,1,0|4tppc0,9,10,1|532tfz,9,10,1|532tg0,8,1,0|5cfrzz,8,1,0|5cfs00,9,10,1|5lsw3z,9,10,1|5lsw40,8,1,0|5v5xfz,8,1,0|5v5xg0,9,10,1|64iyrz,9,10,1|64iys0,8,1,0|6dw03z,8,1,0|6dw040,9,10,1|6n91fz,9,10,1|6n91g0,8,1,0|6wm5jz,8,1,0|6wm5k0,9,10,1|75z43z,9,10,1|75z440,8,1,0|7fc5fz,8,1,0|7fc5g0,9,10,1|7p25fz,9,10,1|7p25g0,8,1,0|7yf6rz,8,1,0|7yf6s0,9,10,1|87s83z,9,10,1|87s840,8,1,0|8h59fz,8,1,0|8h59g0,9,10,1|8qiarz,9,10,1|8qias0,8,1,0|8zvc3z,8,1,0|8zvc40,9,10,1|998dfz,9,10,1|998dg0,8,1,0|9ilerz,8,1,0|9iles0,9,10,1|9ryg3z,9,10,1|9ryg40,8,1,0|a1bhfz,8,1,0|a1bhg0,9,10,1|aaoirz,9,10,1|aaois0,8,1,0|ak1k3z,8,1,0|ak1k40,9,10,1|atrk3z,9,10,1|atrk40,8,1,0|b34lfz,8,1,0|b34lg0,9,10,1|bchmrz,9,10,1|bchms0,8,1,0|bluo3z,8,1,0|bluo40,9,10,1|bv7pfz,9,10,1|bv7pg0,8,1,0|c4kqrz,8,1,0|c4kqs0,9,10,1|cdxs3z,9,10,1|cdxs40,8,1,0|cnatfz,8,1,0|cnatg0,9,10,1|cwnurz,9,10,1|cwnus0,8,1,0|d60w3z,8,1,0|d60w40,9,10,1|dfdxfz,9,10,1|dfdxg0,8,1,0|dp3xfz,8,1,0|dp3xg0,9,10,1|dzwtfz,9,10,1|dzwtg0,8,1,0|e7u03z,8,1,0|e7u040,9,10,1|eimw3z,9,10,1|eimw40,8,1,0|eqk2rz,8,1,0|eqk2s0,9,10,1|f1cyrz,9,10,1|f1cys0,8,1,0|f9a5fz,8,1,0|f9a5g0,9,10,1|fkg03z,9,10,1|fkg040,8,1,0|fs083z,8,1,0|fs0840,9,10,1|g362rz,9,10,1|g362s0,8,1,0|gaqarz,8,1,0|gaqas0,9,10,1|glw5fz,9,10,1|glw5g0,8,1,0|gttc3z,8,1,0|gttc40,9,10,1|h4m83z,9,10,1|h4m840,8,1,0|hcjerz,8,1,0|hcjes0,9,10,1|hncarz,9,10,1|hncas0,8,1,0|hv9hfz,8,1,0|hv9hg0,9,10,1|i6fc3z,9,10,1|i6fc40,8,1,0|idzk3z,8,1,0|idzk40,9,10,1|ip5erz,9,10,1|ip5es0,8,1,0|iwpmrz,8,1,0|iwpms0,9,10,1|j7vhfz,9,10,1|j7vhg0,8,1,0|jffpfz,8,1,0|jffpg0,9,10,1|jqlk3z,9,10,1|jqlk40,8,1,0|jyiqrz,8,1,0|jyiqs0,9,10,1|k9bmrz,9,10,1|k9bms0,8,1,0|kh8tfz,8,1,0|kh8tg0,9,10,1|ks1pfz,9,10,1|ks1pg0,8,1,0|kzyw3z,8,1,0|kzyw40,9,10,1|lb4qrz,9,10,1|lb4qs0,8,1,0|lioyrz,8,1,0|lioys0,9,10,1|ltutfz,9,10,1|ltutg0,8,1,0|m1f1fz,8,1,0|m1f1g0,9,10,1|mckw3z,9,10,1|mckw40,8,1,0|mki2rz,8,1,0|mki2s0,9,10,1|mvayrz,9,10,1|mvays0,8,1,0|n385fz,8,1,0|n385g0,9,10,1|ne11fz,9,10,1|ne11g0,8,1,0|nly83z,8,1,0|nly840,9,10,1|nwr43z,9,10,1|nwr440,8,1,0|o4oarz,8,1,0|o4oas0,9,10,1|ofu5fz,9,10,1|ofu5g0,8,1,0|onedfz,8,1,0|onedg0,9,10,1|oyk83z,9,10,1|oyk840,8,1,0|p64g3z,8,1,0|p64g40,9,10,1|phaarz,9,10,1|phaas0,8,1,0|pp7hfz,8,1,0|pp7hg0,9,10,1|q00dfz,9,10,1|q00dg0,8,1,0|q7xk3z,8,1,0|q7xk40,9,10,1|qiqg3z,9,10,1|qiqg40,8,1,0|qqnmrz,8,1,0|qqnms0,9,10,1|r1thfz,9,10,1|r1thg0,8,1,0|r9dpfz,8,1,0|r9dpg0,9,10,1|rkjk3z,9,10,1|rkjk40,8,1,0|rs3s3z,8,1,0|rs3s40,9,10,1|s39mrz,9,10,1|s39ms0,8,1,0|sb6tfz,8,1,0|sb6tg0,9,10,1|slzpfz,9,10,1|slzpg0,8,1,0|stww3z,8,1,0|stww40,9,10,1|t4ps3z,9,10,1|t4ps40,8,1,0|tcmyrz,8,1,0|tcmys0,9,10,1|tnfurz,9,10,1|tnfus0,8,1,0|tvd1fz,8,1,0|tvd1g0,9,10,1|u6iw3z,9,10,1|u6iw40,8,1,0|ue343z,8,1,0|ue3440,9,10,1|up8yrz,9,10,1|up8ys0,8,1,0|uwt6rz,8,1,0|uwt6s0,9,10,1|v7z1fz,9,10,1|v7z1g0,8,1,0|vfw83z,8,1,0|vfw840,9,10,1|vqp43z,9,10,1|vqp440,8,1,0|vymarz,8,1,0|vymas0,9,10,1|w9f6rz,9,10,1|w9f6s0,8,1,0|whcdfz,8,1,0|whcdg0,9,10,1|wsi83z,9,10,1|wsi840,8,1,0|x02g3z,8,1,0|x02g40,9,10,1|xb8arz,9,10,1|xb8as0,8,1,0|xisirz,8,1,0|xisis0,9,10,1|xtydfz,9,10,1|xtydg0,8,1,0|y1ilfz,8,1,0|y1ilg0,9,10,1|ycog3z,9,10,1|ycog40,8,1,0|yklmrz,8,1,0|yklms0,9,10,1|yveirz,9,10,1|yveis0,8,1,0|z3bpfz,8,1,0|z3bpg0,9,10,1|ze4lfz,9,10,1|ze4lg0,8,1,0\",\"Atlantic/Reykjavik|,0,309,0|-wcwx9c,13,15,0|-rl7k01,13,15,0|-rl7k00,17,1,1|-r8ph81,17,1,1|-r8ph80,13,15,0|-r2fmo1,13,15,0|-r2fmo0,17,1,1|-qolek1,17,1,1|-qolek0,13,15,0|-qjnpc1,13,15,0|-qjnpc0,17,1,1|-q5th81,17,1,1|-q5th80,13,15,0|-pgm5c1,13,15,0|-pgm5c0,17,1,1|-pbq581,17,1,1|-pbq580,13,15,0|-g0c5c1,13,15,0|-g0c5c0,17,1,1|-fqyyg1,17,1,1|-fqyyg0,13,15,0|-fkuic1,13,15,0|-fkuic0,17,1,1|-f7vx41,17,1,1|-f7vx40,13,15,0|-f1rjs1,13,15,0|-f1rjs0,17,1,1|-ep5ug1,17,1,1|-ep5ug0,13,15,0|-eioig1,13,15,0|-eioig0,17,1,1|-e6sqg1,17,1,1|-e6sqg0,13,15,0|-dzyfs1,13,15,0|-dzyfs0,17,1,1|-do2ns1,17,1,1|-do2ns0,13,15,0|-dh8d41,13,15,0|-dh8d40,17,1,1|-d5cl41,17,1,1|-d5cl40,13,15,0|-cyiag1,13,15,0|-cyiag0,17,1,1|-cm9js1,17,1,1|-cm9js0,13,15,0|-cfs7s1,13,15,0|-cfs7s0,17,1,1|-c3jh41,17,1,1|-c3jh40,13,15,0|-bv9bs1,13,15,0|-bv9bs0,17,1,1|-bkteg1,17,1,1|-bkteg0,13,15,0|-bcj941,13,15,0|-bcj940,17,1,1|-b23bs1,17,1,1|-b23bs0,13,15,0|-att6g1,13,15,0|-att6g0,17,1,1|-aj0ag1,17,1,1|-aj0ag0,13,15,0|-ab33s1,13,15,0|-ab33s0,17,1,1|-a0n6g1,17,1,1|-a0n6g0,13,15,0|-9sd141,13,15,0|-9sd140,17,1,1|-9hk541,17,1,1|-9hk540,13,15,0|-999zs1,13,15,0|-999zs0,17,1,1|-8yu2g1,17,1,1|-8yu2g0,13,15,0|-8qjx41,13,15,0|-8qjx40,17,1,1|-8g3zs1,17,1,1|-8g3zs0,13,15,0|-87tug1,13,15,0|-87tug0,17,1,1|-7xdx41,17,1,1|-7xdx40,13,15,0|-7p3rs1,13,15,0|-7p3rs0,17,1,1|-7enug1,17,1,1|-7enug0,13,15,0|-76dp41,13,15,0|-76dp40,17,1,1|-6vkt41,17,1,1|-6vkt40,13,15,0|-6nans1,13,15,0|-6nans0,17,1,1|-6cuqg1,17,1,1|-6cuqg0,13,15,0|-64kl41,13,15,0|-64kl40,17,1,1|-5u4ns1,17,1,1|-5u4ns0,13,15,0|-5luig1,13,15,0|-5luig0,17,1,1|-5bel41,17,1,1|-5bel40,13,15,0|-534fs1,13,15,0|-534fs0,17,1,1|-4soig1,17,1,1|-4soig0,13,15,0|-4ked41,13,15,0|-4ked40,17,1,1|-49yfs1,17,1,1|-49yfs0,13,15,0|-41oag1,13,15,0|-41oag0,17,1,1|-3qveg1,17,1,1|-3qveg0,13,15,0|-3il941,13,15,0|-3il940,17,1,1|-385bs1,17,1,1|-385bs0,13,15,0|-2zv6g1,13,15,0|-2zv6g0,17,1,1|-2pf941,17,1,1|-2pf940,13,15,0|-2h53s1,13,15,0|-2h53s0,17,1,1|-26p6g1,17,1,1|-26p6g0,13,15,0|-1yf141,13,15,0|-1yf140,17,1,1|-1nz3s1,17,1,1|-1nz3s0,13,15,0|-1foyg1,13,15,0|-1foyg0,17,1,1|-14w2g1,17,1,1|-14w2g0,13,15,0|-wlx41,13,15,0|-wlx40,1,1,0\",\"Atlantic/South_Georgia|,0,310,0|-15r12kg,40,45,0\",\"Atlantic/St_Helena|,0,12,0|-u9rgl4,1,1,0\",\"Atlantic/Stanley|,0,311,0|-15r0ymc,85,311,0|-u63pad,85,311,0|-u63pac,42,42,0|-gu7rk1,42,42,0|-gu7rk0,39,44,1|-gl7ro1,39,44,1|-gl7ro0,42,42,0|-gbhow1,42,42,0|-gbhow0,39,44,1|-g2hp01,39,44,1|-g2hp00,42,42,0|-fsenk1,42,42,0|-fsenk0,39,44,1|-fjeno1,39,44,1|-fjeno0,42,42,0|-f9okw1,42,42,0|-f9okw0,39,44,1|-f0ol01,39,44,1|-f0ol00,42,42,0|-eqyi81,42,42,0|-eqyi80,39,44,1|-ehyic1,39,44,1|-ehyic0,42,42,0|-e88fk1,42,42,0|-e88fk0,39,44,1|-e3aqc1,39,44,1|-e3aqc0,42,42,0|6yf4fz,42,42,0|6yf4g0,39,44,0|75z9nz,39,44,0|75z9o0,40,45,1|7h51jz,40,45,1|7h51k0,39,44,0|7ocdnz,39,44,0|7ocdo0,40,45,1|7zv47z,40,45,1|7zv480,39,44,0|872gbz,39,44,0|872gc0,39,44,1|8i8azz,39,44,1|8i8b00,42,42,0|8pslrz,42,42,0|8psls0,39,44,1|90ydnz,39,44,1|90ydo0,42,42,0|98iofz,42,42,0|98iog0,39,44,1|9jogbz,39,44,1|9jogc0,42,42,0|9r8r3z,42,42,0|9r8r40,39,44,1|a2eizz,39,44,1|a2ej00,42,42,0|a9ytrz,42,42,0|a9yts0,39,44,1|alhkbz,39,44,1|alhkc0,42,42,0|asowfz,42,42,0|asowg0,39,44,1|b47mzz,39,44,1|b47n00,42,42,0|bbrxrz,42,42,0|bbrxs0,39,44,1|bmxpnz,39,44,1|bmxpo0,42,42,0|bui0fz,42,42,0|bui0g0,39,44,1|c5nsbz,39,44,1|c5nsc0,42,42,0|cd833z,42,42,0|cd8340,39,44,1|coduzz,39,44,1|codv00,42,42,0|cvy5rz,42,42,0|cvy5s0,39,44,1|d73xnz,39,44,1|d73xo0,42,42,0|deo8fz,42,42,0|deo8g0,39,44,1|dq6yzz,39,44,1|dq6z00,42,42,0|dxr9rz,42,42,0|dxr9s0,39,44,1|e8x1nz,39,44,1|e8x1o0,42,42,0|eghcfz,42,42,0|eghcg0,39,44,1|ern4bz,39,44,1|ern4c0,42,42,0|ez7f3z,42,42,0|ez7f40,39,44,1|fad6zz,39,44,1|fad700,42,42,0|fhxhrz,42,42,0|fhxhs0,39,44,1|ft39nz,39,44,1|ft39o0,42,42,0|g0nkfz,42,42,0|g0nkg0,39,44,1|gbthvz,39,44,1|gbthw0,42,42,0|gj0tzz,42,42,0|gj0u00,39,44,1|guwj7z,39,44,1|guwj80,42,42,0|h1qwnz,42,42,0|h1qwo0,39,44,1|hdmlvz,39,44,1|hdmlw0,42,42,0|hktxzz,42,42,0|hkty00,39,44,1|hwcojz,39,44,1|hwcok0,42,42,0|i3k0nz,42,42,0|i3k0o0,39,44,1|if2r7z,39,44,1|if2r80,42,42,0|ima3bz,42,42,0|ima3c0,39,44,1|ixstvz,39,44,1|ixstw0,42,42,0|j505zz,42,42,0|j50600,39,44,1|jgiwjz,39,44,1|jgiwk0,42,42,0|jnq8nz,42,42,0|jnq8o0,39,44,1|jzlxvz,39,44,1|jzlxw0,42,42,0|k6t9zz,42,42,0|k6ta00,39,44,1|kic0jz,39,44,1|kic0k0,42,42,0|kpjcnz,42,42,0|kpjco0,39,44,1|l1237z,39,44,1|l12380,42,42,0|l89fbz,42,42,0|l89fc0,39,44,0\",\"Australia/Adelaide|,0,312,0|-133j2zw,138,224,0|-10vsp01,138,224,0|-10vsp00,138,248,0|-rnsq61,138,248,0|-rnsq60,139,313,1|-rjj0u1,139,313,1|-rjj0u0,138,248,0|-em3gu1,138,248,0|-em3gu0,139,313,1|-ehmcu1,139,313,1|-ehmcu0,138,248,0|-e89bi1,138,248,0|-e89bi0,139,313,1|-dywa61,139,313,1|-dywa60,138,248,0|-dp6a61,138,248,0|-dp6a60,139,313,1|-dg67i1,139,313,1|-dg67i0,138,248,0|ycghz,138,248,0|ycgi0,139,313,1|14gttz,139,313,1|14gtu0,138,248,0|1h2j5z,138,248,0|1h2j60,139,313,1|1njv5z,139,313,1|1njv60,138,248,0|1zsltz,138,248,0|1zslu0,139,313,1|269xtz,139,313,1|269xu0,138,248,0|2iiohz,138,248,0|2iioi0,139,313,1|2p00hz,139,313,1|2p00i0,138,248,0|318r5z,138,248,0|318r60,139,313,1|3831tz,139,313,1|3831u0,138,248,0|3kbshz,138,248,0|3kbsi0,139,313,1|3qt4hz,139,313,1|3qt4i0,138,248,0|431v5z,138,248,0|431v60,139,313,1|49j75z,139,313,1|49j760,138,248,0|4lrxtz,138,248,0|4lrxu0,139,313,1|4s99tz,139,313,1|4s99u0,138,248,0|54i0hz,138,248,0|54i0i0,139,313,1|5azchz,139,313,1|5azci0,138,248,0|5n835z,138,248,0|5n8360,139,313,1|5tpf5z,139,313,1|5tpf60,138,248,0|65y5tz,138,248,0|65y5u0,139,313,1|6csghz,139,313,1|6csgi0,138,248,0|6p175z,138,248,0|6p1760,139,313,1|6vij5z,139,313,1|6vij60,138,248,0|77r9tz,138,248,0|77r9u0,139,313,1|7e8ltz,139,313,1|7e8lu0,138,248,0|7qhchz,138,248,0|7qhci0,139,313,1|7wyohz,139,313,1|7wyoi0,138,248,0|897f5z,138,248,0|897f60,139,313,1|8geohz,139,313,1|8geoi0,138,248,0|8rkj5z,138,248,0|8rkj60,139,313,1|8z4r5z,139,313,1|8z4r60,138,248,0|9ankhz,138,248,0|9anki0,139,313,1|9i7shz,139,313,1|9i7si0,138,248,0|9tqltz,138,248,0|9tqlu0,139,313,1|a0xv5z,139,313,1|a0xv60,138,248,0|acgohz,138,248,0|acgoi0,139,313,1|ajnxtz,139,313,1|ajnxu0,138,248,0|av6r5z,138,248,0|av6r60,139,313,1|b1o35z,139,313,1|b1o360,138,248,0|bdwttz,138,248,0|bdwtu0,139,313,1|blh1tz,139,313,1|blh1u0,138,248,0|bwmwhz,138,248,0|bwmwi0,139,313,1|c3h75z,139,313,1|c3h760,138,248,0|cfpxtz,138,248,0|cfpxu0,139,313,1|cmx75z,139,313,1|cmx760,138,248,0|cyg0hz,138,248,0|cyg0i0,139,313,1|d608hz,139,313,1|d608i0,138,248,0|dh635z,138,248,0|dh6360,139,313,1|dp39tz,139,313,1|dp39u0,138,248,0|dzw5tz,138,248,0|dzw5u0,139,313,1|e7tchz,139,313,1|e7tci0,138,248,0|eim8hz,138,248,0|eim8i0,139,313,1|eqjf5z,139,313,1|eqjf60,138,248,0|f1cb5z,138,248,0|f1cb60,139,313,1|f99htz,139,313,1|f99hu0,138,248,0|fkfchz,138,248,0|fkfci0,139,313,1|frzkhz,139,313,1|frzki0,138,248,0|g35f5z,138,248,0|g35f60,139,313,1|gapn5z,139,313,1|gapn60,138,248,0|glvhtz,138,248,0|glvhu0,139,313,1|gtsohz,139,313,1|gtsoi0,138,248,0|h4lkhz,138,248,0|h4lki0,139,313,1|hcir5z,139,313,1|hcir60,138,248,0|hnbn5z,138,248,0|hnbn60,139,313,1|hv8ttz,139,313,1|hv8tu0,138,248,0|i6eohz,138,248,0|i6eoi0,139,313,1|idywhz,139,313,1|idywi0,138,248,0|ip4r5z,138,248,0|ip4r60,139,313,1|ix1xtz,139,313,1|ix1xu0,138,248,0|j7uttz,138,248,0|j7utu0,139,313,1|jff1tz,139,313,1|jff1u0,138,248,0|jqkwhz,138,248,0|jqkwi0,139,313,1|jyv1tz,139,313,1|jyv1u0,138,248,0|k8835z,138,248,0|k88360,139,313,1|khl4hz,139,313,1|khl4i0,138,248,0|kqy5tz,138,248,0|kqy5u0,139,313,1|l0b75z,139,313,1|l0b760,138,248,0|l9o8hz,138,248,0|l9o8i0,139,313,1|lj19tz,139,313,1|lj19u0,138,248,0|lseb5z,138,248,0|lseb60,139,313,1|m1rchz,139,313,1|m1rci0,138,248,0|mbhchz,138,248,0|mbhci0,139,313,1|mkudtz,139,313,1|mkudu0,138,248,0|mu7f5z,138,248,0|mu7f60,139,313,1|n3kghz,139,313,1|n3kgi0,138,248,0|ncxhtz,138,248,0|ncxhu0,139,313,1|nmaj5z,139,313,1|nmaj60,138,248,0|nvnkhz,138,248,0|nvnki0,139,313,1|o50ltz,139,313,1|o50lu0,138,248,0|oedn5z,138,248,0|oedn60,139,313,1|onqohz,139,313,1|onqoi0,138,248,0|ox3ptz,138,248,0|ox3pu0,139,313,1|p6gr5z,139,313,1|p6gr60,138,248,0|pg6r5z,138,248,0|pg6r60,139,313,1|ppjshz,139,313,1|ppjsi0,138,248,0|pywttz,138,248,0|pywtu0,139,313,1|q89v5z,139,313,1|q89v60,138,248,0|qhmwhz,138,248,0|qhmwi0,139,313,1|qqzxtz,139,313,1|qqzxu0,138,248,0|r0cz5z,138,248,0|r0cz60,139,313,1|r9q0hz,139,313,1|r9q0i0,138,248,0|rj31tz,138,248,0|rj31u0,139,313,1|rsg35z,139,313,1|rsg360,138,248,0|s1t4hz,138,248,0|s1t4i0,139,313,1|sbj4hz,139,313,1|sbj4i0,138,248,0|skw5tz,138,248,0|skw5u0,139,313,1|su975z,139,313,1|su9760,138,248,0|t3m8hz,138,248,0|t3m8i0,139,313,1|tcz9tz,139,313,1|tcz9u0,138,248,0|tmcb5z,138,248,0|tmcb60,139,313,1|tvpchz,139,313,1|tvpci0,138,248,0|u52dtz,138,248,0|u52du0,139,313,1|ueff5z,139,313,1|ueff60,138,248,0|unsghz,138,248,0|unsgi0,139,313,1|ux5htz,139,313,1|ux5hu0,138,248,0|v6vhtz,138,248,0|v6vhu0,139,313,1|vg8j5z,139,313,1|vg8j60,138,248,0|vplkhz,138,248,0|vplki0,139,313,1|vyyltz,139,313,1|vyylu0,138,248,0|w8bn5z,138,248,0|w8bn60,139,313,1|whoohz,139,313,1|whooi0,138,248,0|wr1ptz,138,248,0|wr1pu0,139,313,1|x0er5z,139,313,1|x0er60,138,248,0|x9rshz,138,248,0|x9rsi0,139,313,1|xj4ttz,139,313,1|xj4tu0,138,248,0|xshv5z,138,248,0|xshv60,139,313,1|y1uwhz,139,313,1|y1uwi0,138,248,0|ybkwhz,138,248,0|ybkwi0,139,313,1|ykxxtz,139,313,1|ykxxu0,138,248,0|yuaz5z,138,248,0|yuaz60,139,313,1|z3o0hz,139,313,1|z3o0i0,138,248,0|zd11tz,138,248,0|zd11u0,139,313,1\",\"Australia/Brisbane|,0,314,0|-1354kc8,94,195,0|-rnsrk1,94,195,0|-rnsrk0,95,192,1|-rjj281,95,192,1|-rjj280,94,195,0|-em3i81,94,195,0|-em3i80,95,192,1|-ehme81,95,192,1|-ehme80,94,195,0|-e89cw1,94,195,0|-e89cw0,95,192,1|-dywbk1,95,192,1|-dywbk0,94,195,0|-dp6bk1,94,195,0|-dp6bk0,95,192,1|-dg68w1,95,192,1|-dg68w0,94,195,0|ycf3z,94,195,0|ycf40,95,192,1|14gsfz,95,192,1|14gsg0,94,195,0|acgn3z,94,195,0|acgn40,95,192,1|aixz3z,95,192,1|aixz40,94,195,0|av6prz,94,195,0|av6ps0,95,192,1|b1o1rz,95,192,1|b1o1s0,94,195,0|bdwsfz,94,195,0|bdwsg0,95,192,1|bke4fz,95,192,1|bke4g0,94,195,0\",\"Australia/Broken_Hill|,0,315,0|-133j3j0,94,195,0|-12a9fs1,94,195,0|-12a9fs0,138,224,0|-10vsp01,138,224,0|-10vsp00,138,248,0|-rnsq61,138,248,0|-rnsq60,139,313,1|-rjj0u1,139,313,1|-rjj0u0,138,248,0|-em3gu1,138,248,0|-em3gu0,139,313,1|-ehmcu1,139,313,1|-ehmcu0,138,248,0|-e89bi1,138,248,0|-e89bi0,139,313,1|-dywa61,139,313,1|-dywa60,138,248,0|-dp6a61,138,248,0|-dp6a60,139,313,1|-dg67i1,139,313,1|-dg67i0,138,248,0|ycghz,138,248,0|ycgi0,139,313,1|14gttz,139,313,1|14gtu0,138,248,0|1h2j5z,138,248,0|1h2j60,139,313,1|1njv5z,139,313,1|1njv60,138,248,0|1zsltz,138,248,0|1zslu0,139,313,1|269xtz,139,313,1|269xu0,138,248,0|2iiohz,138,248,0|2iioi0,139,313,1|2p00hz,139,313,1|2p00i0,138,248,0|318r5z,138,248,0|318r60,139,313,1|3831tz,139,313,1|3831u0,138,248,0|3kbshz,138,248,0|3kbsi0,139,313,1|3qt4hz,139,313,1|3qt4i0,138,248,0|431v5z,138,248,0|431v60,139,313,1|49j75z,139,313,1|49j760,138,248,0|4lrxtz,138,248,0|4lrxu0,139,313,1|4s99tz,139,313,1|4s99u0,138,248,0|54i0hz,138,248,0|54i0i0,139,313,1|5azchz,139,313,1|5azci0,138,248,0|5n835z,138,248,0|5n8360,139,313,1|5tpf5z,139,313,1|5tpf60,138,248,0|65y5tz,138,248,0|65y5u0,139,313,1|6e8b5z,139,313,1|6e8b60,138,248,0|6p175z,138,248,0|6p1760,139,313,1|6vij5z,139,313,1|6vij60,138,248,0|77r9tz,138,248,0|77r9u0,139,313,1|7e8ltz,139,313,1|7e8lu0,138,248,0|7qhchz,138,248,0|7qhci0,139,313,1|7wyohz,139,313,1|7wyoi0,138,248,0|897f5z,138,248,0|897f60,139,313,1|8geohz,139,313,1|8geoi0,138,248,0|8rkj5z,138,248,0|8rkj60,139,313,1|8z4r5z,139,313,1|8z4r60,138,248,0|9ankhz,138,248,0|9anki0,139,313,1|9i7shz,139,313,1|9i7si0,138,248,0|9tqltz,138,248,0|9tqlu0,139,313,1|a0xv5z,139,313,1|a0xv60,138,248,0|acgohz,138,248,0|acgoi0,139,313,1|aiy0hz,139,313,1|aiy0i0,138,248,0|av6r5z,138,248,0|av6r60,139,313,1|b1o35z,139,313,1|b1o360,138,248,0|bdwttz,138,248,0|bdwtu0,139,313,1|bke5tz,139,313,1|bke5u0,138,248,0|bwmwhz,138,248,0|bwmwi0,139,313,1|c3h75z,139,313,1|c3h760,138,248,0|cfpxtz,138,248,0|cfpxu0,139,313,1|cm79tz,139,313,1|cm79u0,138,248,0|cyg0hz,138,248,0|cyg0i0,139,313,1|d4xchz,139,313,1|d4xci0,138,248,0|dh635z,138,248,0|dh6360,139,313,1|dp39tz,139,313,1|dp39u0,138,248,0|dzw5tz,138,248,0|dzw5u0,139,313,1|e7tchz,139,313,1|e7tci0,138,248,0|eim8hz,138,248,0|eim8i0,139,313,1|eqjf5z,139,313,1|eqjf60,138,248,0|f1cb5z,138,248,0|f1cb60,139,313,1|f99htz,139,313,1|f99hu0,138,248,0|fkfchz,138,248,0|fkfci0,139,313,1|frzkhz,139,313,1|frzki0,138,248,0|g35f5z,138,248,0|g35f60,139,313,1|gapn5z,139,313,1|gapn60,138,248,0|glvhtz,138,248,0|glvhu0,139,313,1|gtsohz,139,313,1|gtsoi0,138,248,0|h4lkhz,138,248,0|h4lki0,139,313,1|hcir5z,139,313,1|hcir60,138,248,0|hnbn5z,138,248,0|hnbn60,139,313,1|hv8ttz,139,313,1|hv8tu0,138,248,0|i6eohz,138,248,0|i6eoi0,139,313,1|idywhz,139,313,1|idywi0,138,248,0|ip4r5z,138,248,0|ip4r60,139,313,1|ix1xtz,139,313,1|ix1xu0,138,248,0|j7uttz,138,248,0|j7utu0,139,313,1|jff1tz,139,313,1|jff1u0,138,248,0|jqkwhz,138,248,0|jqkwi0,139,313,1|jyv1tz,139,313,1|jyv1u0,138,248,0|k8835z,138,248,0|k88360,139,313,1|khl4hz,139,313,1|khl4i0,138,248,0|kqy5tz,138,248,0|kqy5u0,139,313,1|l0b75z,139,313,1|l0b760,138,248,0|l9o8hz,138,248,0|l9o8i0,139,313,1|lj19tz,139,313,1|lj19u0,138,248,0|lseb5z,138,248,0|lseb60,139,313,1|m1rchz,139,313,1|m1rci0,138,248,0|mbhchz,138,248,0|mbhci0,139,313,1|mkudtz,139,313,1|mkudu0,138,248,0|mu7f5z,138,248,0|mu7f60,139,313,1|n3kghz,139,313,1|n3kgi0,138,248,0|ncxhtz,138,248,0|ncxhu0,139,313,1|nmaj5z,139,313,1|nmaj60,138,248,0|nvnkhz,138,248,0|nvnki0,139,313,1|o50ltz,139,313,1|o50lu0,138,248,0|oedn5z,138,248,0|oedn60,139,313,1|onqohz,139,313,1|onqoi0,138,248,0|ox3ptz,138,248,0|ox3pu0,139,313,1|p6gr5z,139,313,1|p6gr60,138,248,0|pg6r5z,138,248,0|pg6r60,139,313,1|ppjshz,139,313,1|ppjsi0,138,248,0|pywttz,138,248,0|pywtu0,139,313,1|q89v5z,139,313,1|q89v60,138,248,0|qhmwhz,138,248,0|qhmwi0,139,313,1|qqzxtz,139,313,1|qqzxu0,138,248,0|r0cz5z,138,248,0|r0cz60,139,313,1|r9q0hz,139,313,1|r9q0i0,138,248,0|rj31tz,138,248,0|rj31u0,139,313,1|rsg35z,139,313,1|rsg360,138,248,0|s1t4hz,138,248,0|s1t4i0,139,313,1|sbj4hz,139,313,1|sbj4i0,138,248,0|skw5tz,138,248,0|skw5u0,139,313,1|su975z,139,313,1|su9760,138,248,0|t3m8hz,138,248,0|t3m8i0,139,313,1|tcz9tz,139,313,1|tcz9u0,138,248,0|tmcb5z,138,248,0|tmcb60,139,313,1|tvpchz,139,313,1|tvpci0,138,248,0|u52dtz,138,248,0|u52du0,139,313,1|ueff5z,139,313,1|ueff60,138,248,0|unsghz,138,248,0|unsgi0,139,313,1|ux5htz,139,313,1|ux5hu0,138,248,0|v6vhtz,138,248,0|v6vhu0,139,313,1|vg8j5z,139,313,1|vg8j60,138,248,0|vplkhz,138,248,0|vplki0,139,313,1|vyyltz,139,313,1|vyylu0,138,248,0|w8bn5z,138,248,0|w8bn60,139,313,1|whoohz,139,313,1|whooi0,138,248,0|wr1ptz,138,248,0|wr1pu0,139,313,1|x0er5z,139,313,1|x0er60,138,248,0|x9rshz,138,248,0|x9rsi0,139,313,1|xj4ttz,139,313,1|xj4tu0,138,248,0|xshv5z,138,248,0|xshv60,139,313,1|y1uwhz,139,313,1|y1uwi0,138,248,0|ybkwhz,138,248,0|ybkwi0,139,313,1|ykxxtz,139,313,1|ykxxu0,138,248,0|yuaz5z,138,248,0|yuaz60,139,313,1|z3o0hz,139,313,1|z3o0i0,138,248,0|zd11tz,138,248,0|zd11u0,139,313,1\",\"Australia/Currie|,0,316,0|-12smja4,94,195,0|-rsj4w1,94,195,0|-rsj4w0,95,192,1|-rjj281,95,192,1|-rjj280,94,195,0|-r8d7k1,94,195,0|-r8d7k0,95,192,1|-r1vvk1,95,192,1|-r1vvk0,94,195,0|-qpn4w1,94,195,0|-qpn4w0,95,192,1|-qj5sw1,95,192,1|-qj5sw0,94,195,0|-em3i81,94,195,0|-em3i80,95,192,1|-ehme81,95,192,1|-ehme80,94,195,0|-e89cw1,94,195,0|-e89cw0,95,192,1|-dywbk1,95,192,1|-dywbk0,94,195,0|-dp6bk1,94,195,0|-dp6bk0,95,192,1|-dg68w1,95,192,1|-dg68w0,94,195,0|-16cow1,94,195,0|-16cow0,95,192,1|-wznk1,95,192,1|-wznk0,94,195,0|-m6rk1,94,195,0|-m6rk0,95,192,1|-fcgw1,95,192,1|-fcgw0,94,195,0|-3gow1,94,195,0|-3gow0,95,192,1|3dlrz,95,192,1|3dls0,94,195,0|f9drz,94,195,0|f9ds0,95,192,1|mgn3z,95,192,1|mgn40,94,195,0|ycf3z,94,195,0|ycf40,95,192,1|14gsfz,95,192,1|14gsg0,94,195,0|1h2hrz,94,195,0|1h2hs0,95,192,1|1njtrz,95,192,1|1njts0,94,195,0|1zskfz,94,195,0|1zskg0,95,192,1|269wfz,95,192,1|269wg0,94,195,0|2iin3z,94,195,0|2iin40,95,192,1|2ozz3z,95,192,1|2ozz40,94,195,0|318prz,94,195,0|318ps0,95,192,1|3830fz,95,192,1|3830g0,94,195,0|3kbr3z,94,195,0|3kbr40,95,192,1|3qt33z,95,192,1|3qt340,94,195,0|431trz,94,195,0|431ts0,95,192,1|49j5rz,95,192,1|49j5s0,94,195,0|4lrwfz,94,195,0|4lrwg0,95,192,1|4s98fz,95,192,1|4s98g0,94,195,0|54hz3z,94,195,0|54hz40,95,192,1|5azb3z,95,192,1|5azb40,94,195,0|5n81rz,94,195,0|5n81s0,95,192,1|5tpdrz,95,192,1|5tpds0,94,195,0|65y4fz,94,195,0|65y4g0,95,192,1|6dvb3z,95,192,1|6dvb40,94,195,0|6p15rz,94,195,0|6p15s0,95,192,1|6wldrz,95,192,1|6wlds0,94,195,0|77r8fz,94,195,0|77r8g0,95,192,1|7e8kfz,95,192,1|7e8kg0,94,195,0|7qhb3z,94,195,0|7qhb40,95,192,1|7wyn3z,95,192,1|7wyn40,94,195,0|897drz,94,195,0|897ds0,95,192,1|8foprz,95,192,1|8fops0,94,195,0|8rkhrz,94,195,0|8rkhs0,95,192,1|8z4prz,95,192,1|8z4ps0,94,195,0|9anj3z,94,195,0|9anj40,95,192,1|9i7r3z,95,192,1|9i7r40,94,195,0|9tqkfz,94,195,0|9tqkg0,95,192,1|a0xtrz,95,192,1|a0xts0,94,195,0|acgn3z,94,195,0|acgn40,95,192,1|ajnwfz,95,192,1|ajnwg0,94,195,0|av6prz,94,195,0|av6ps0,95,192,1|b33wfz,95,192,1|b33wg0,94,195,0|bctwfz,94,195,0|bctwg0,95,192,1|bltz3z,95,192,1|bltz40,94,195,0|bvjz3z,94,195,0|bvjz40,95,192,1|c4k1rz,95,192,1|c4k1s0,94,195,0|cea1rz,94,195,0|cea1s0,95,192,1|cna4fz,95,192,1|cna4g0,94,195,0|cx04fz,94,195,0|cx04g0,95,192,1|d6073z,95,192,1|d60740,94,195,0|dfq73z,94,195,0|dfq740,95,192,1|dp38fz,95,192,1|dp38g0,94,195,0|dyt8fz,94,195,0|dyt8g0,95,192,1|e7tb3z,95,192,1|e7tb40,94,195,0|ehjb3z,94,195,0|ehjb40,95,192,1|eqjdrz,95,192,1|eqjds0,94,195,0|f09drz,94,195,0|f09ds0,95,192,1|f99gfz,95,192,1|f99gg0,94,195,0|fizgfz,94,195,0|fizgg0,95,192,1|frzj3z,95,192,1|frzj40,94,195,0|fzwprz,94,195,0|fzwps0,95,192,1|gaplrz,95,192,1|gapls0,94,195,0|gkskfz,94,195,0|gkskg0,95,192,1|gtsn3z,95,192,1|gtsn40,94,195,0|h3in3z,94,195,0|h3in40,95,192,1|hciprz,95,192,1|hcips0,94,195,0|hm8prz,94,195,0|hm8ps0,95,192,1|hv8sfz,95,192,1|hv8sg0,94,195,0|i4ysfz,94,195,0|i4ysg0,95,192,1|idyv3z,95,192,1|idyv40,94,195,0|inov3z,94,195,0|inov40,95,192,1|ix1wfz,95,192,1|ix1wg0,94,195,0|j6exrz,94,195,0|j6exs0,95,192,1|jff0fz,95,192,1|jff0g0,94,195,0|jphz3z,94,195,0|jphz40,95,192,1|jyv0fz,95,192,1|jyv0g0,94,195,0|k881rz,94,195,0|k881s0,95,192,1|khl33z,95,192,1|khl340,94,195,0|kqy4fz,94,195,0|kqy4g0,95,192,1|l0b5rz,95,192,1|l0b5s0,94,195,0|l9o73z,94,195,0|l9o740,95,192,1|lj18fz,95,192,1|lj18g0,94,195,0|lse9rz,94,195,0|lse9s0,95,192,1|m1rb3z,95,192,1|m1rb40,94,195,0|mbhb3z,94,195,0|mbhb40,95,192,1|mkucfz,95,192,1|mkucg0,94,195,0|mu7drz,94,195,0|mu7ds0,95,192,1|n3kf3z,95,192,1|n3kf40,94,195,0|ncxgfz,94,195,0|ncxgg0,95,192,1|nmahrz,95,192,1|nmahs0,94,195,0|nvnj3z,94,195,0|nvnj40,95,192,1|o50kfz,95,192,1|o50kg0,94,195,0|oedlrz,94,195,0|oedls0,95,192,1|onqn3z,95,192,1|onqn40,94,195,0|ox3ofz,94,195,0|ox3og0,95,192,1|p6gprz,95,192,1|p6gps0,94,195,0|pg6prz,94,195,0|pg6ps0,95,192,1|ppjr3z,95,192,1|ppjr40,94,195,0|pywsfz,94,195,0|pywsg0,95,192,1|q89trz,95,192,1|q89ts0,94,195,0|qhmv3z,94,195,0|qhmv40,95,192,1|qqzwfz,95,192,1|qqzwg0,94,195,0|r0cxrz,94,195,0|r0cxs0,95,192,1|r9pz3z,95,192,1|r9pz40,94,195,0|rj30fz,94,195,0|rj30g0,95,192,1|rsg1rz,95,192,1|rsg1s0,94,195,0|s1t33z,94,195,0|s1t340,95,192,1|sbj33z,95,192,1|sbj340,94,195,0|skw4fz,94,195,0|skw4g0,95,192,1|su95rz,95,192,1|su95s0,94,195,0|t3m73z,94,195,0|t3m740,95,192,1|tcz8fz,95,192,1|tcz8g0,94,195,0|tmc9rz,94,195,0|tmc9s0,95,192,1|tvpb3z,95,192,1|tvpb40,94,195,0|u52cfz,94,195,0|u52cg0,95,192,1|uefdrz,95,192,1|uefds0,94,195,0|unsf3z,94,195,0|unsf40,95,192,1|ux5gfz,95,192,1|ux5gg0,94,195,0|v6vgfz,94,195,0|v6vgg0,95,192,1|vg8hrz,95,192,1|vg8hs0,94,195,0|vplj3z,94,195,0|vplj40,95,192,1|vyykfz,95,192,1|vyykg0,94,195,0|w8blrz,94,195,0|w8bls0,95,192,1|whon3z,95,192,1|whon40,94,195,0|wr1ofz,94,195,0|wr1og0,95,192,1|x0eprz,95,192,1|x0eps0,94,195,0|x9rr3z,94,195,0|x9rr40,95,192,1|xj4sfz,95,192,1|xj4sg0,94,195,0|xshtrz,94,195,0|xshts0,95,192,1|y1uv3z,95,192,1|y1uv40,94,195,0|ybkv3z,94,195,0|ybkv40,95,192,1|ykxwfz,95,192,1|ykxwg0,94,195,0|yuaxrz,94,195,0|yuaxs0,95,192,1|z3nz3z,95,192,1|z3nz40,94,195,0|zd10fz,94,195,0|zd10g0,95,192,1\",\"Australia/Darwin|,0,317,0|-133j1k8,138,224,0|-10vsp01,138,224,0|-10vsp00,138,248,0|-rnsq61,138,248,0|-rnsq60,139,313,1|-rjj0u1,139,313,1|-rjj0u0,138,248,0|-em3gu1,138,248,0|-em3gu0,139,313,1|-ehmcu1,139,313,1|-ehmcu0,138,248,0|-e89bi1,138,248,0|-e89bi0,139,313,1|-dywa61,139,313,1|-dywa60,138,248,0|-dp6a61,138,248,0|-dp6a60,139,313,1|-dg67i1,139,313,1|-dg67i0,138,248,0\",\"Australia/Eucla|,0,318,0|-12nxx74,140,319,0|-rnso31,140,319,0|-rnso30,141,320,1|-rjiyr1,141,320,1|-rjiyr0,140,319,0|-em3er1,140,319,0|-em3er0,141,320,1|-ehmar1,141,320,1|-ehmar0,140,319,0|-e899f1,140,319,0|-e899f0,141,320,1|-dyw831,141,320,1|-dyw830,140,319,0|2iiqkz,140,319,0|2iiql0,141,320,1|2p02kz,141,320,1|2p02l0,140,319,0|77rbwz,140,319,0|77rbx0,141,320,1|7e8nwz,141,320,1|7e8nx0,140,319,0|bezrwz,140,319,0|bezrx0,141,320,1|bke7wz,141,320,1|bke7x0,140,319,0|j9np8z,140,319,0|j9np90,141,320,1|jff3wz,141,320,1|jff3x0,140,319,0|jqkykz,140,319,0|jqkyl0,141,320,1|jyi58z,141,320,1|jyi590,140,319,0|k9b18z,140,319,0|k9b190,141,320,1|kh87wz,141,320,1|kh87x0,140,319,0\",\"Australia/Hobart|,0,316,0|-12smja4,94,195,0|-rsj4w1,94,195,0|-rsj4w0,95,192,1|-rjj281,95,192,1|-rjj280,94,195,0|-r8d7k1,94,195,0|-r8d7k0,95,192,1|-r1vvk1,95,192,1|-r1vvk0,94,195,0|-qpn4w1,94,195,0|-qpn4w0,95,192,1|-qj5sw1,95,192,1|-qj5sw0,94,195,0|-em3i81,94,195,0|-em3i80,95,192,1|-ehme81,95,192,1|-ehme80,94,195,0|-e89cw1,94,195,0|-e89cw0,95,192,1|-dywbk1,95,192,1|-dywbk0,94,195,0|-dp6bk1,94,195,0|-dp6bk0,95,192,1|-dg68w1,95,192,1|-dg68w0,94,195,0|-16cow1,94,195,0|-16cow0,95,192,1|-wznk1,95,192,1|-wznk0,94,195,0|-m6rk1,94,195,0|-m6rk0,95,192,1|-fcgw1,95,192,1|-fcgw0,94,195,0|-3gow1,94,195,0|-3gow0,95,192,1|3dlrz,95,192,1|3dls0,94,195,0|f9drz,94,195,0|f9ds0,95,192,1|mgn3z,95,192,1|mgn40,94,195,0|ycf3z,94,195,0|ycf40,95,192,1|14gsfz,95,192,1|14gsg0,94,195,0|1h2hrz,94,195,0|1h2hs0,95,192,1|1njtrz,95,192,1|1njts0,94,195,0|1zskfz,94,195,0|1zskg0,95,192,1|269wfz,95,192,1|269wg0,94,195,0|2iin3z,94,195,0|2iin40,95,192,1|2ozz3z,95,192,1|2ozz40,94,195,0|318prz,94,195,0|318ps0,95,192,1|3830fz,95,192,1|3830g0,94,195,0|3kbr3z,94,195,0|3kbr40,95,192,1|3qt33z,95,192,1|3qt340,94,195,0|431trz,94,195,0|431ts0,95,192,1|49j5rz,95,192,1|49j5s0,94,195,0|4lrwfz,94,195,0|4lrwg0,95,192,1|4s98fz,95,192,1|4s98g0,94,195,0|54hz3z,94,195,0|54hz40,95,192,1|5azb3z,95,192,1|5azb40,94,195,0|5n81rz,94,195,0|5n81s0,95,192,1|5tpdrz,95,192,1|5tpds0,94,195,0|65y4fz,94,195,0|65y4g0,95,192,1|6dvb3z,95,192,1|6dvb40,94,195,0|6p15rz,94,195,0|6p15s0,95,192,1|6wldrz,95,192,1|6wlds0,94,195,0|77r8fz,94,195,0|77r8g0,95,192,1|7e8kfz,95,192,1|7e8kg0,94,195,0|7qhb3z,94,195,0|7qhb40,95,192,1|7wyn3z,95,192,1|7wyn40,94,195,0|897drz,94,195,0|897ds0,95,192,1|8foprz,95,192,1|8fops0,94,195,0|8rkhrz,94,195,0|8rkhs0,95,192,1|8z4prz,95,192,1|8z4ps0,94,195,0|9anj3z,94,195,0|9anj40,95,192,1|9i7r3z,95,192,1|9i7r40,94,195,0|9tqkfz,94,195,0|9tqkg0,95,192,1|a0xtrz,95,192,1|a0xts0,94,195,0|acgn3z,94,195,0|acgn40,95,192,1|ajnwfz,95,192,1|ajnwg0,94,195,0|av6prz,94,195,0|av6ps0,95,192,1|b33wfz,95,192,1|b33wg0,94,195,0|bctwfz,94,195,0|bctwg0,95,192,1|bltz3z,95,192,1|bltz40,94,195,0|bvjz3z,94,195,0|bvjz40,95,192,1|c4k1rz,95,192,1|c4k1s0,94,195,0|cea1rz,94,195,0|cea1s0,95,192,1|cna4fz,95,192,1|cna4g0,94,195,0|cx04fz,94,195,0|cx04g0,95,192,1|d6073z,95,192,1|d60740,94,195,0|dfq73z,94,195,0|dfq740,95,192,1|dp38fz,95,192,1|dp38g0,94,195,0|dyt8fz,94,195,0|dyt8g0,95,192,1|e7tb3z,95,192,1|e7tb40,94,195,0|ehjb3z,94,195,0|ehjb40,95,192,1|eqjdrz,95,192,1|eqjds0,94,195,0|f09drz,94,195,0|f09ds0,95,192,1|f99gfz,95,192,1|f99gg0,94,195,0|fizgfz,94,195,0|fizgg0,95,192,1|frzj3z,95,192,1|frzj40,94,195,0|fzwprz,94,195,0|fzwps0,95,192,1|gaplrz,95,192,1|gapls0,94,195,0|gkskfz,94,195,0|gkskg0,95,192,1|gtsn3z,95,192,1|gtsn40,94,195,0|h3in3z,94,195,0|h3in40,95,192,1|hciprz,95,192,1|hcips0,94,195,0|hm8prz,94,195,0|hm8ps0,95,192,1|hv8sfz,95,192,1|hv8sg0,94,195,0|i4ysfz,94,195,0|i4ysg0,95,192,1|idyv3z,95,192,1|idyv40,94,195,0|inov3z,94,195,0|inov40,95,192,1|ix1wfz,95,192,1|ix1wg0,94,195,0|j6exrz,94,195,0|j6exs0,95,192,1|jff0fz,95,192,1|jff0g0,94,195,0|jphz3z,94,195,0|jphz40,95,192,1|jyv0fz,95,192,1|jyv0g0,94,195,0|k881rz,94,195,0|k881s0,95,192,1|khl33z,95,192,1|khl340,94,195,0|kqy4fz,94,195,0|kqy4g0,95,192,1|l0b5rz,95,192,1|l0b5s0,94,195,0|l9o73z,94,195,0|l9o740,95,192,1|lj18fz,95,192,1|lj18g0,94,195,0|lse9rz,94,195,0|lse9s0,95,192,1|m1rb3z,95,192,1|m1rb40,94,195,0|mbhb3z,94,195,0|mbhb40,95,192,1|mkucfz,95,192,1|mkucg0,94,195,0|mu7drz,94,195,0|mu7ds0,95,192,1|n3kf3z,95,192,1|n3kf40,94,195,0|ncxgfz,94,195,0|ncxgg0,95,192,1|nmahrz,95,192,1|nmahs0,94,195,0|nvnj3z,94,195,0|nvnj40,95,192,1|o50kfz,95,192,1|o50kg0,94,195,0|oedlrz,94,195,0|oedls0,95,192,1|onqn3z,95,192,1|onqn40,94,195,0|ox3ofz,94,195,0|ox3og0,95,192,1|p6gprz,95,192,1|p6gps0,94,195,0|pg6prz,94,195,0|pg6ps0,95,192,1|ppjr3z,95,192,1|ppjr40,94,195,0|pywsfz,94,195,0|pywsg0,95,192,1|q89trz,95,192,1|q89ts0,94,195,0|qhmv3z,94,195,0|qhmv40,95,192,1|qqzwfz,95,192,1|qqzwg0,94,195,0|r0cxrz,94,195,0|r0cxs0,95,192,1|r9pz3z,95,192,1|r9pz40,94,195,0|rj30fz,94,195,0|rj30g0,95,192,1|rsg1rz,95,192,1|rsg1s0,94,195,0|s1t33z,94,195,0|s1t340,95,192,1|sbj33z,95,192,1|sbj340,94,195,0|skw4fz,94,195,0|skw4g0,95,192,1|su95rz,95,192,1|su95s0,94,195,0|t3m73z,94,195,0|t3m740,95,192,1|tcz8fz,95,192,1|tcz8g0,94,195,0|tmc9rz,94,195,0|tmc9s0,95,192,1|tvpb3z,95,192,1|tvpb40,94,195,0|u52cfz,94,195,0|u52cg0,95,192,1|uefdrz,95,192,1|uefds0,94,195,0|unsf3z,94,195,0|unsf40,95,192,1|ux5gfz,95,192,1|ux5gg0,94,195,0|v6vgfz,94,195,0|v6vgg0,95,192,1|vg8hrz,95,192,1|vg8hs0,94,195,0|vplj3z,94,195,0|vplj40,95,192,1|vyykfz,95,192,1|vyykg0,94,195,0|w8blrz,94,195,0|w8bls0,95,192,1|whon3z,95,192,1|whon40,94,195,0|wr1ofz,94,195,0|wr1og0,95,192,1|x0eprz,95,192,1|x0eps0,94,195,0|x9rr3z,94,195,0|x9rr40,95,192,1|xj4sfz,95,192,1|xj4sg0,94,195,0|xshtrz,94,195,0|xshts0,95,192,1|y1uv3z,95,192,1|y1uv40,94,195,0|ybkv3z,94,195,0|ybkv40,95,192,1|ykxwfz,95,192,1|ykxwg0,94,195,0|yuaxrz,94,195,0|yuaxs0,95,192,1|z3nz3z,95,192,1|z3nz40,94,195,0|zd10fz,94,195,0|zd10g0,95,192,1\",\"Australia/Lindeman|,0,321,0|-1354jl8,94,195,0|-rnsrk1,94,195,0|-rnsrk0,95,192,1|-rjj281,95,192,1|-rjj280,94,195,0|-em3i81,94,195,0|-em3i80,95,192,1|-ehme81,95,192,1|-ehme80,94,195,0|-e89cw1,94,195,0|-e89cw0,95,192,1|-dywbk1,95,192,1|-dywbk0,94,195,0|-dp6bk1,94,195,0|-dp6bk0,95,192,1|-dg68w1,95,192,1|-dg68w0,94,195,0|ycf3z,94,195,0|ycf40,95,192,1|14gsfz,95,192,1|14gsg0,94,195,0|acgn3z,94,195,0|acgn40,95,192,1|aixz3z,95,192,1|aixz40,94,195,0|av6prz,94,195,0|av6ps0,95,192,1|b1o1rz,95,192,1|b1o1s0,94,195,0|bdwsfz,94,195,0|bdwsg0,95,192,1|bke4fz,95,192,1|bke4g0,94,195,0|bwmv3z,94,195,0|bwmv40,95,192,1|c3h5rz,95,192,1|c3h5s0,94,195,0|cfpwfz,94,195,0|cfpwg0,95,192,1|cm78fz,95,192,1|cm78g0,94,195,0\",\"Australia/Lord_Howe|,0,322,0|-133j6sk,94,195,0|5tp87z,94,195,0|5tp880,142,313,0|65y31z,142,313,0|65y320,143,198,1|6csaxz,143,198,1|6csay0,142,313,0|6p14dz,142,313,0|6p14e0,143,198,1|6vidlz,143,198,1|6vidm0,142,313,0|77r71z,142,313,0|77r720,143,198,1|7e8g9z,143,198,1|7e8ga0,142,313,0|7qh9pz,142,313,0|7qh9q0,143,198,1|7wyixz,143,198,1|7wyiy0,142,313,0|897cdz,142,313,0|897ce0,90,192,1|8gekbz,90,192,1|8gekc0,142,313,0|8rkgdz,142,313,0|8rkge0,90,192,1|8z4mzz,90,192,1|8z4n00,142,313,0|9anhpz,142,313,0|9anhq0,90,192,1|9i7obz,90,192,1|9i7oc0,142,313,0|9tqj1z,142,313,0|9tqj20,90,192,1|a0xqzz,90,192,1|a0xr00,142,313,0|acglpz,142,313,0|acglq0,90,192,1|aixwbz,90,192,1|aixwc0,142,313,0|av6odz,142,313,0|av6oe0,90,192,1|b1nyzz,90,192,1|b1nz00,142,313,0|bdwr1z,142,313,0|bdwr20,90,192,1|bke1nz,90,192,1|bke1o0,142,313,0|bwmtpz,142,313,0|bwmtq0,90,192,1|c3h2zz,90,192,1|c3h300,142,313,0|cfpv1z,142,313,0|cfpv20,90,192,1|cm75nz,90,192,1|cm75o0,142,313,0|cyfxpz,142,313,0|cyfxq0,90,192,1|d4x8bz,90,192,1|d4x8c0,142,313,0|dh60dz,142,313,0|dh60e0,90,192,1|dp35nz,90,192,1|dp35o0,142,313,0|dzw31z,142,313,0|dzw320,90,192,1|e7t8bz,90,192,1|e7t8c0,142,313,0|eim5pz,142,313,0|eim5q0,90,192,1|eqjazz,90,192,1|eqjb00,142,313,0|f1c8dz,142,313,0|f1c8e0,90,192,1|f99dnz,90,192,1|f99do0,142,313,0|fkf9pz,142,313,0|fkf9q0,90,192,1|frzgbz,90,192,1|frzgc0,142,313,0|fzwodz,142,313,0|fzwoe0,90,192,1|gapizz,90,192,1|gapj00,142,313,0|glvf1z,142,313,0|glvf20,90,192,1|gtskbz,90,192,1|gtskc0,142,313,0|h4lhpz,142,313,0|h4lhq0,90,192,1|hcimzz,90,192,1|hcin00,142,313,0|hnbkdz,142,313,0|hnbke0,90,192,1|hv8pnz,90,192,1|hv8po0,142,313,0|i6elpz,142,313,0|i6elq0,90,192,1|idysbz,90,192,1|idysc0,142,313,0|ip4odz,142,313,0|ip4oe0,90,192,1|ix1tnz,90,192,1|ix1to0,142,313,0|j7ur1z,142,313,0|j7ur20,90,192,1|jfexnz,90,192,1|jfexo0,142,313,0|jqktpz,142,313,0|jqktq0,90,192,1|jyuxnz,90,192,1|jyuxo0,142,313,0|k880dz,142,313,0|k880e0,90,192,1|khl0bz,90,192,1|khl0c0,142,313,0|kqy31z,142,313,0|kqy320,90,192,1|l0b2zz,90,192,1|l0b300,142,313,0|l9o5pz,142,313,0|l9o5q0,90,192,1|lj15nz,90,192,1|lj15o0,142,313,0|lse8dz,142,313,0|lse8e0,90,192,1|m1r8bz,90,192,1|m1r8c0,142,313,0|mbh9pz,142,313,0|mbh9q0,90,192,1|mku9nz,90,192,1|mku9o0,142,313,0|mu7cdz,142,313,0|mu7ce0,90,192,1|n3kcbz,90,192,1|n3kcc0,142,313,0|ncxf1z,142,313,0|ncxf20,90,192,1|nmaezz,90,192,1|nmaf00,142,313,0|nvnhpz,142,313,0|nvnhq0,90,192,1|o50hnz,90,192,1|o50ho0,142,313,0|oedkdz,142,313,0|oedke0,90,192,1|onqkbz,90,192,1|onqkc0,142,313,0|ox3n1z,142,313,0|ox3n20,90,192,1|p6gmzz,90,192,1|p6gn00,142,313,0|pg6odz,142,313,0|pg6oe0,90,192,1|ppjobz,90,192,1|ppjoc0,142,313,0|pywr1z,142,313,0|pywr20,90,192,1|q89qzz,90,192,1|q89r00,142,313,0|qhmtpz,142,313,0|qhmtq0,90,192,1|qqztnz,90,192,1|qqzto0,142,313,0|r0cwdz,142,313,0|r0cwe0,90,192,1|r9pwbz,90,192,1|r9pwc0,142,313,0|rj2z1z,142,313,0|rj2z20,90,192,1|rsfyzz,90,192,1|rsfz00,142,313,0|s1t1pz,142,313,0|s1t1q0,90,192,1|sbj0bz,90,192,1|sbj0c0,142,313,0|skw31z,142,313,0|skw320,90,192,1|su92zz,90,192,1|su9300,142,313,0|t3m5pz,142,313,0|t3m5q0,90,192,1|tcz5nz,90,192,1|tcz5o0,142,313,0|tmc8dz,142,313,0|tmc8e0,90,192,1|tvp8bz,90,192,1|tvp8c0,142,313,0|u52b1z,142,313,0|u52b20,90,192,1|uefazz,90,192,1|uefb00,142,313,0|unsdpz,142,313,0|unsdq0,90,192,1|ux5dnz,90,192,1|ux5do0,142,313,0|v6vf1z,142,313,0|v6vf20,90,192,1|vg8ezz,90,192,1|vg8f00,142,313,0|vplhpz,142,313,0|vplhq0,90,192,1|vyyhnz,90,192,1|vyyho0,142,313,0|w8bkdz,142,313,0|w8bke0,90,192,1|whokbz,90,192,1|whokc0,142,313,0|wr1n1z,142,313,0|wr1n20,90,192,1|x0emzz,90,192,1|x0en00,142,313,0|x9rppz,142,313,0|x9rpq0,90,192,1|xj4pnz,90,192,1|xj4po0,142,313,0|xshsdz,142,313,0|xshse0,90,192,1|y1usbz,90,192,1|y1usc0,142,313,0|ybktpz,142,313,0|ybktq0,90,192,1|ykxtnz,90,192,1|ykxto0,142,313,0|yuawdz,142,313,0|yuawe0,90,192,1|z3nwbz,90,192,1|z3nwc0,142,313,0|zd0z1z,142,313,0|zd0z20,90,192,1\",\"Australia/Melbourne|,0,323,0|-133j46g,94,195,0|-rnsrk1,94,195,0|-rnsrk0,95,192,1|-rjj281,95,192,1|-rjj280,94,195,0|-em3i81,94,195,0|-em3i80,95,192,1|-ehme81,95,192,1|-ehme80,94,195,0|-e89cw1,94,195,0|-e89cw0,95,192,1|-dywbk1,95,192,1|-dywbk0,94,195,0|-dp6bk1,94,195,0|-dp6bk0,95,192,1|-dg68w1,95,192,1|-dg68w0,94,195,0|ycf3z,94,195,0|ycf40,95,192,1|14gsfz,95,192,1|14gsg0,94,195,0|1h2hrz,94,195,0|1h2hs0,95,192,1|1njtrz,95,192,1|1njts0,94,195,0|1zskfz,94,195,0|1zskg0,95,192,1|269wfz,95,192,1|269wg0,94,195,0|2iin3z,94,195,0|2iin40,95,192,1|2ozz3z,95,192,1|2ozz40,94,195,0|318prz,94,195,0|318ps0,95,192,1|3830fz,95,192,1|3830g0,94,195,0|3kbr3z,94,195,0|3kbr40,95,192,1|3qt33z,95,192,1|3qt340,94,195,0|431trz,94,195,0|431ts0,95,192,1|49j5rz,95,192,1|49j5s0,94,195,0|4lrwfz,94,195,0|4lrwg0,95,192,1|4s98fz,95,192,1|4s98g0,94,195,0|54hz3z,94,195,0|54hz40,95,192,1|5azb3z,95,192,1|5azb40,94,195,0|5n81rz,94,195,0|5n81s0,95,192,1|5tpdrz,95,192,1|5tpds0,94,195,0|65y4fz,94,195,0|65y4g0,95,192,1|6csf3z,95,192,1|6csf40,94,195,0|6p15rz,94,195,0|6p15s0,95,192,1|6vihrz,95,192,1|6vihs0,94,195,0|77r8fz,94,195,0|77r8g0,95,192,1|7e8kfz,95,192,1|7e8kg0,94,195,0|7qhb3z,94,195,0|7qhb40,95,192,1|7wyn3z,95,192,1|7wyn40,94,195,0|897drz,94,195,0|897ds0,95,192,1|8gen3z,95,192,1|8gen40,94,195,0|8rkhrz,94,195,0|8rkhs0,95,192,1|8z4prz,95,192,1|8z4ps0,94,195,0|9aakfz,94,195,0|9aakg0,95,192,1|9i7r3z,95,192,1|9i7r40,94,195,0|9tqkfz,94,195,0|9tqkg0,95,192,1|a0xtrz,95,192,1|a0xts0,94,195,0|acgn3z,94,195,0|acgn40,95,192,1|ajnwfz,95,192,1|ajnwg0,94,195,0|av6prz,94,195,0|av6ps0,95,192,1|b1o1rz,95,192,1|b1o1s0,94,195,0|bdwsfz,94,195,0|bdwsg0,95,192,1|bke4fz,95,192,1|bke4g0,94,195,0|bwmv3z,94,195,0|bwmv40,95,192,1|c3h5rz,95,192,1|c3h5s0,94,195,0|cfpwfz,94,195,0|cfpwg0,95,192,1|cm78fz,95,192,1|cm78g0,94,195,0|cyfz3z,94,195,0|cyfz40,95,192,1|d6073z,95,192,1|d60740,94,195,0|dh61rz,94,195,0|dh61s0,95,192,1|dp38fz,95,192,1|dp38g0,94,195,0|dzw4fz,94,195,0|dzw4g0,95,192,1|e7tb3z,95,192,1|e7tb40,94,195,0|eim73z,94,195,0|eim740,95,192,1|eqjdrz,95,192,1|eqjds0,94,195,0|f1c9rz,94,195,0|f1c9s0,95,192,1|f99gfz,95,192,1|f99gg0,94,195,0|fkfb3z,94,195,0|fkfb40,95,192,1|frzj3z,95,192,1|frzj40,94,195,0|fzwprz,94,195,0|fzwps0,95,192,1|gaplrz,95,192,1|gapls0,94,195,0|glvgfz,94,195,0|glvgg0,95,192,1|gtsn3z,95,192,1|gtsn40,94,195,0|h4lj3z,94,195,0|h4lj40,95,192,1|hciprz,95,192,1|hcips0,94,195,0|hnblrz,94,195,0|hnbls0,95,192,1|hv8sfz,95,192,1|hv8sg0,94,195,0|i6en3z,94,195,0|i6en40,95,192,1|idyv3z,95,192,1|idyv40,94,195,0|ip4prz,94,195,0|ip4ps0,95,192,1|ix1wfz,95,192,1|ix1wg0,94,195,0|j7usfz,94,195,0|j7usg0,95,192,1|jff0fz,95,192,1|jff0g0,94,195,0|jqkv3z,94,195,0|jqkv40,95,192,1|jyv0fz,95,192,1|jyv0g0,94,195,0|k881rz,94,195,0|k881s0,95,192,1|khl33z,95,192,1|khl340,94,195,0|kqy4fz,94,195,0|kqy4g0,95,192,1|l0b5rz,95,192,1|l0b5s0,94,195,0|l9o73z,94,195,0|l9o740,95,192,1|lj18fz,95,192,1|lj18g0,94,195,0|lse9rz,94,195,0|lse9s0,95,192,1|m1rb3z,95,192,1|m1rb40,94,195,0|mbhb3z,94,195,0|mbhb40,95,192,1|mkucfz,95,192,1|mkucg0,94,195,0|mu7drz,94,195,0|mu7ds0,95,192,1|n3kf3z,95,192,1|n3kf40,94,195,0|ncxgfz,94,195,0|ncxgg0,95,192,1|nmahrz,95,192,1|nmahs0,94,195,0|nvnj3z,94,195,0|nvnj40,95,192,1|o50kfz,95,192,1|o50kg0,94,195,0|oedlrz,94,195,0|oedls0,95,192,1|onqn3z,95,192,1|onqn40,94,195,0|ox3ofz,94,195,0|ox3og0,95,192,1|p6gprz,95,192,1|p6gps0,94,195,0|pg6prz,94,195,0|pg6ps0,95,192,1|ppjr3z,95,192,1|ppjr40,94,195,0|pywsfz,94,195,0|pywsg0,95,192,1|q89trz,95,192,1|q89ts0,94,195,0|qhmv3z,94,195,0|qhmv40,95,192,1|qqzwfz,95,192,1|qqzwg0,94,195,0|r0cxrz,94,195,0|r0cxs0,95,192,1|r9pz3z,95,192,1|r9pz40,94,195,0|rj30fz,94,195,0|rj30g0,95,192,1|rsg1rz,95,192,1|rsg1s0,94,195,0|s1t33z,94,195,0|s1t340,95,192,1|sbj33z,95,192,1|sbj340,94,195,0|skw4fz,94,195,0|skw4g0,95,192,1|su95rz,95,192,1|su95s0,94,195,0|t3m73z,94,195,0|t3m740,95,192,1|tcz8fz,95,192,1|tcz8g0,94,195,0|tmc9rz,94,195,0|tmc9s0,95,192,1|tvpb3z,95,192,1|tvpb40,94,195,0|u52cfz,94,195,0|u52cg0,95,192,1|uefdrz,95,192,1|uefds0,94,195,0|unsf3z,94,195,0|unsf40,95,192,1|ux5gfz,95,192,1|ux5gg0,94,195,0|v6vgfz,94,195,0|v6vgg0,95,192,1|vg8hrz,95,192,1|vg8hs0,94,195,0|vplj3z,94,195,0|vplj40,95,192,1|vyykfz,95,192,1|vyykg0,94,195,0|w8blrz,94,195,0|w8bls0,95,192,1|whon3z,95,192,1|whon40,94,195,0|wr1ofz,94,195,0|wr1og0,95,192,1|x0eprz,95,192,1|x0eps0,94,195,0|x9rr3z,94,195,0|x9rr40,95,192,1|xj4sfz,95,192,1|xj4sg0,94,195,0|xshtrz,94,195,0|xshts0,95,192,1|y1uv3z,95,192,1|y1uv40,94,195,0|ybkv3z,94,195,0|ybkv40,95,192,1|ykxwfz,95,192,1|ykxwg0,94,195,0|yuaxrz,94,195,0|yuaxs0,95,192,1|z3nz3z,95,192,1|z3nz40,94,195,0|zd10fz,94,195,0|zd10g0,95,192,1\",\"Australia/Perth|,0,324,0|-12nxusc,144,191,0|-rnsm01,144,191,0|-rnsm00,145,224,1|-rjiwo1,145,224,1|-rjiwo0,144,191,0|-em3co1,144,191,0|-em3co0,145,224,1|-ehm8o1,145,224,1|-ehm8o0,144,191,0|-e897c1,144,191,0|-e897c0,145,224,1|-dyw601,145,224,1|-dyw600,144,191,0|2iisnz,144,191,0|2iiso0,145,224,1|2p04nz,145,224,1|2p04o0,144,191,0|77rdzz,144,191,0|77re00,145,224,1|7e8pzz,145,224,1|7e8q00,144,191,0|beztzz,144,191,0|bezu00,145,224,1|bke9zz,145,224,1|bkea00,144,191,0|j9nrbz,144,191,0|j9nrc0,145,224,1|jff5zz,145,224,1|jff600,144,191,0|jql0nz,144,191,0|jql0o0,145,224,1|jyi7bz,145,224,1|jyi7c0,144,191,0|k9b3bz,144,191,0|k9b3c0,145,224,1|kh89zz,145,224,1|kh8a00,144,191,0\",\"Australia/Sydney|,0,325,0|-133j5c4,94,195,0|-rnsrk1,94,195,0|-rnsrk0,95,192,1|-rjj281,95,192,1|-rjj280,94,195,0|-em3i81,94,195,0|-em3i80,95,192,1|-ehme81,95,192,1|-ehme80,94,195,0|-e89cw1,94,195,0|-e89cw0,95,192,1|-dywbk1,95,192,1|-dywbk0,94,195,0|-dp6bk1,94,195,0|-dp6bk0,95,192,1|-dg68w1,95,192,1|-dg68w0,94,195,0|ycf3z,94,195,0|ycf40,95,192,1|14gsfz,95,192,1|14gsg0,94,195,0|1h2hrz,94,195,0|1h2hs0,95,192,1|1njtrz,95,192,1|1njts0,94,195,0|1zskfz,94,195,0|1zskg0,95,192,1|269wfz,95,192,1|269wg0,94,195,0|2iin3z,94,195,0|2iin40,95,192,1|2ozz3z,95,192,1|2ozz40,94,195,0|318prz,94,195,0|318ps0,95,192,1|3830fz,95,192,1|3830g0,94,195,0|3kbr3z,94,195,0|3kbr40,95,192,1|3qt33z,95,192,1|3qt340,94,195,0|431trz,94,195,0|431ts0,95,192,1|49j5rz,95,192,1|49j5s0,94,195,0|4lrwfz,94,195,0|4lrwg0,95,192,1|4s98fz,95,192,1|4s98g0,94,195,0|54hz3z,94,195,0|54hz40,95,192,1|5azb3z,95,192,1|5azb40,94,195,0|5n81rz,94,195,0|5n81s0,95,192,1|5tpdrz,95,192,1|5tpds0,94,195,0|65y4fz,94,195,0|65y4g0,95,192,1|6e89rz,95,192,1|6e89s0,94,195,0|6p15rz,94,195,0|6p15s0,95,192,1|6vihrz,95,192,1|6vihs0,94,195,0|77r8fz,94,195,0|77r8g0,95,192,1|7e8kfz,95,192,1|7e8kg0,94,195,0|7qhb3z,94,195,0|7qhb40,95,192,1|7wyn3z,95,192,1|7wyn40,94,195,0|897drz,94,195,0|897ds0,95,192,1|8gen3z,95,192,1|8gen40,94,195,0|8rkhrz,94,195,0|8rkhs0,95,192,1|8z4prz,95,192,1|8z4ps0,94,195,0|9anj3z,94,195,0|9anj40,95,192,1|9i7r3z,95,192,1|9i7r40,94,195,0|9tqkfz,94,195,0|9tqkg0,95,192,1|a0xtrz,95,192,1|a0xts0,94,195,0|acgn3z,94,195,0|acgn40,95,192,1|aixz3z,95,192,1|aixz40,94,195,0|av6prz,94,195,0|av6ps0,95,192,1|b1o1rz,95,192,1|b1o1s0,94,195,0|bdwsfz,94,195,0|bdwsg0,95,192,1|bke4fz,95,192,1|bke4g0,94,195,0|bwmv3z,94,195,0|bwmv40,95,192,1|c3h5rz,95,192,1|c3h5s0,94,195,0|cfpwfz,94,195,0|cfpwg0,95,192,1|cm78fz,95,192,1|cm78g0,94,195,0|cyfz3z,94,195,0|cyfz40,95,192,1|d4xb3z,95,192,1|d4xb40,94,195,0|dh61rz,94,195,0|dh61s0,95,192,1|dp38fz,95,192,1|dp38g0,94,195,0|dzw4fz,94,195,0|dzw4g0,95,192,1|e7tb3z,95,192,1|e7tb40,94,195,0|eim73z,94,195,0|eim740,95,192,1|eqjdrz,95,192,1|eqjds0,94,195,0|f1c9rz,94,195,0|f1c9s0,95,192,1|f99gfz,95,192,1|f99gg0,94,195,0|fkfb3z,94,195,0|fkfb40,95,192,1|frzj3z,95,192,1|frzj40,94,195,0|fzwprz,94,195,0|fzwps0,95,192,1|gaplrz,95,192,1|gapls0,94,195,0|glvgfz,94,195,0|glvgg0,95,192,1|gtsn3z,95,192,1|gtsn40,94,195,0|h4lj3z,94,195,0|h4lj40,95,192,1|hciprz,95,192,1|hcips0,94,195,0|hnblrz,94,195,0|hnbls0,95,192,1|hv8sfz,95,192,1|hv8sg0,94,195,0|i6en3z,94,195,0|i6en40,95,192,1|idyv3z,95,192,1|idyv40,94,195,0|ip4prz,94,195,0|ip4ps0,95,192,1|ix1wfz,95,192,1|ix1wg0,94,195,0|j7usfz,94,195,0|j7usg0,95,192,1|jff0fz,95,192,1|jff0g0,94,195,0|jqkv3z,94,195,0|jqkv40,95,192,1|jyv0fz,95,192,1|jyv0g0,94,195,0|k881rz,94,195,0|k881s0,95,192,1|khl33z,95,192,1|khl340,94,195,0|kqy4fz,94,195,0|kqy4g0,95,192,1|l0b5rz,95,192,1|l0b5s0,94,195,0|l9o73z,94,195,0|l9o740,95,192,1|lj18fz,95,192,1|lj18g0,94,195,0|lse9rz,94,195,0|lse9s0,95,192,1|m1rb3z,95,192,1|m1rb40,94,195,0|mbhb3z,94,195,0|mbhb40,95,192,1|mkucfz,95,192,1|mkucg0,94,195,0|mu7drz,94,195,0|mu7ds0,95,192,1|n3kf3z,95,192,1|n3kf40,94,195,0|ncxgfz,94,195,0|ncxgg0,95,192,1|nmahrz,95,192,1|nmahs0,94,195,0|nvnj3z,94,195,0|nvnj40,95,192,1|o50kfz,95,192,1|o50kg0,94,195,0|oedlrz,94,195,0|oedls0,95,192,1|onqn3z,95,192,1|onqn40,94,195,0|ox3ofz,94,195,0|ox3og0,95,192,1|p6gprz,95,192,1|p6gps0,94,195,0|pg6prz,94,195,0|pg6ps0,95,192,1|ppjr3z,95,192,1|ppjr40,94,195,0|pywsfz,94,195,0|pywsg0,95,192,1|q89trz,95,192,1|q89ts0,94,195,0|qhmv3z,94,195,0|qhmv40,95,192,1|qqzwfz,95,192,1|qqzwg0,94,195,0|r0cxrz,94,195,0|r0cxs0,95,192,1|r9pz3z,95,192,1|r9pz40,94,195,0|rj30fz,94,195,0|rj30g0,95,192,1|rsg1rz,95,192,1|rsg1s0,94,195,0|s1t33z,94,195,0|s1t340,95,192,1|sbj33z,95,192,1|sbj340,94,195,0|skw4fz,94,195,0|skw4g0,95,192,1|su95rz,95,192,1|su95s0,94,195,0|t3m73z,94,195,0|t3m740,95,192,1|tcz8fz,95,192,1|tcz8g0,94,195,0|tmc9rz,94,195,0|tmc9s0,95,192,1|tvpb3z,95,192,1|tvpb40,94,195,0|u52cfz,94,195,0|u52cg0,95,192,1|uefdrz,95,192,1|uefds0,94,195,0|unsf3z,94,195,0|unsf40,95,192,1|ux5gfz,95,192,1|ux5gg0,94,195,0|v6vgfz,94,195,0|v6vgg0,95,192,1|vg8hrz,95,192,1|vg8hs0,94,195,0|vplj3z,94,195,0|vplj40,95,192,1|vyykfz,95,192,1|vyykg0,94,195,0|w8blrz,94,195,0|w8bls0,95,192,1|whon3z,95,192,1|whon40,94,195,0|wr1ofz,94,195,0|wr1og0,95,192,1|x0eprz,95,192,1|x0eps0,94,195,0|x9rr3z,94,195,0|x9rr40,95,192,1|xj4sfz,95,192,1|xj4sg0,94,195,0|xshtrz,94,195,0|xshts0,95,192,1|y1uv3z,95,192,1|y1uv40,94,195,0|ybkv3z,94,195,0|ybkv40,95,192,1|ykxwfz,95,192,1|ykxwg0,94,195,0|yuaxrz,94,195,0|yuaxs0,95,192,1|z3nz3z,95,192,1|z3nz40,94,195,0|zd10fz,94,195,0|zd10g0,95,192,1\",\"Etc/GMT+1|,199,15,0\",\"Etc/GMT+10|,208,36,0\",\"Etc/GMT+11|,209,35,0\",\"Etc/GMT+12|,210,403,0\",\"Etc/GMT+2|,200,45,0\",\"Etc/GMT+3|,201,44,0\",\"Etc/GMT+4|,202,42,0\",\"Etc/GMT+5|,203,63,0\",\"Etc/GMT+6|,204,62,0\",\"Etc/GMT+7|,205,66,0\",\"Etc/GMT+8|,206,40,0\",\"Etc/GMT+9|,207,37,0\",\"Etc/GMT-1|,198,10,0\",\"Etc/GMT-10|,189,195,0\",\"Etc/GMT-11|,188,192,0\",\"Etc/GMT-12|,187,200,0\",\"Etc/GMT-13|,186,201,0\",\"Etc/GMT-14|,185,207,0\",\"Etc/GMT-2|,197,11,0\",\"Etc/GMT-3|,196,6,0\",\"Etc/GMT-4|,195,209,0\",\"Etc/GMT-5|,194,194,0\",\"Etc/GMT-6|,193,196,0\",\"Etc/GMT-7|,192,193,0\",\"Etc/GMT-8|,191,191,0\",\"Etc/GMT-9|,190,224,0\",\"Europe/Amsterdam|,0,326,0|-1ygf4wk,44,326,0|-s0dvkl,44,326,0|-s0dvkk,24,327,1|-rsimcl,24,327,1|-rsimck,44,326,0|-ridkol,44,326,0|-ridkok,24,327,1|-rage0l,24,327,1|-rage0k,44,326,0|-r0dfcl,44,326,0|-r0dfck,24,327,1|-qr0e0l,24,327,1|-qr0e0k,44,326,0|-qhae0l,44,326,0|-qhae0k,24,327,1|-q8abcl,24,327,1|-q8abck,44,326,0|-pykbcl,44,326,0|-pykbck,24,327,1|-ppk8ol,24,327,1|-ppk8ok,44,326,0|-pfu8ol,44,326,0|-pfu8ok,24,327,1|-p6u60l,24,327,1|-p6u60k,44,326,0|-oxizcl,44,326,0|-oxizck,24,327,1|-ong0ol,24,327,1|-ong0ok,44,326,0|-obazcl,44,326,0|-obazck,24,327,1|-o4py0l,24,327,1|-o4py0k,44,326,0|-nvpvcl,44,326,0|-nvpvck,24,327,1|-nlzvcl,24,327,1|-nlzvck,44,326,0|-n9hvcl,44,326,0|-n9hvck,24,327,1|-n39sol,24,327,1|-n39sok,44,326,0|-mrsu0l,44,326,0|-mrsu0k,24,327,1|-mkjq0l,24,327,1|-mkjq0k,44,326,0|-m90wol,44,326,0|-m90wok,24,327,1|-m1tncl,24,327,1|-m1tnck,44,326,0|-lq74ol,44,326,0|-lq74ok,24,327,1|-liqm0l,24,327,1|-liqm0k,44,326,0|-l7f7cl,44,326,0|-l7f7ck,24,327,1|-l00jcl,24,327,1|-l00jck,44,326,0|-kona0l,44,326,0|-kona0k,24,327,1|-khagol,24,327,1|-khagok,44,326,0|-k5vcol,44,326,0|-k5vcok,24,327,1|-jyke0l,24,327,1|-jyke0k,44,326,0|-jmom0l,44,326,0|-jmom0k,24,327,1|-jfubcl,24,327,1|-jfubck,44,326,0|-j49ncl,44,326,0|-j49nck,24,327,1|-iwra0l,24,327,1|-iwra0k,44,326,0|-ilhq0l,44,326,0|-ilhq0k,24,327,1|-ie17cl,24,327,1|-ie17ck,44,326,0|-i2psol,44,326,0|-i2psok,24,327,1|-hvb4ol,24,327,1|-hvb4ok,44,326,0|-hjw0ol,44,326,0|-hjw0ok,24,327,1|-hcl20l,24,327,1|-hcl20k,44,326,0|-h0r4ol,44,326,0|-h0r4ok,24,327,1|-gypacl,24,327,1|-gypack,146,328,1|-gtuzdd,146,328,1|-gtuzdc,2,2,0|-gic61d,2,2,0|-gic61c,146,328,1|-gb4wpd,146,328,1|-gb4wpc,2,2,0|-fzk8pd,2,2,0|-fzk8pc,146,328,1|-fs1vdd,146,328,1|-fs1vdc,2,2,0|-fgorld,2,2,0|-fgorlc,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d6dp81,11,11,1|-d6dp80,10,10,0|-cx0nw1,10,10,0|-cx0nw0,11,11,1|-cofek1,11,11,1|-cofek0,10,10,0|3s9mrz,10,10,0|3s9ms0,11,11,1|419pfz,11,11,1|419pg0,10,10,0|4azpfz,10,10,0|4azpg0,11,11,1|4kcqrz,11,11,1|4kcqs0,10,10,0|4tps3z,10,10,0|4tps40,11,11,1|532tfz,11,11,1|532tg0,10,10,0|5cstfz,10,10,0|5cstg0,11,11,1|5lsw3z,11,11,1|5lsw40,10,10,0|5v5xfz,10,10,0|5v5xg0,11,11,1|64iyrz,11,11,1|64iys0,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Andorra|,0,329,0|-100edm4,8,1,0|-c4xmo1,8,1,0|-c4xmo0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Astrakhan|,0,330,0|-nu2zkc,100,6,0|-kmr4c1,100,6,0|-kmr4c0,105,209,0|5vb3jz,105,209,0|5vb3k0,92,194,1|64pwrz,92,194,1|64pws0,105,209,0|6e30vz,105,209,0|6e30w0,92,194,1|6nhu3z,92,194,1|6nhu40,105,209,0|6wuy7z,105,209,0|6wuy80,92,194,1|769rfz,92,194,1|769rg0,105,209,0|7foq7z,105,209,0|7foq80,92,194,1|7p1x3z,92,194,1|7p1x40,105,209,0|7yeyfz,105,209,0|7yeyg0,92,194,1|87rzrz,92,194,1|87rzs0,105,209,0|8h513z,105,209,0|8h5140,92,194,1|8qi2fz,92,194,1|8qi2g0,105,209,0|8zv3rz,105,209,0|8zv3s0,92,194,1|99853z,92,194,1|998540,105,209,0|9il6fz,105,209,0|9il6g0,92,194,1|9ry7rz,92,194,1|9ry7s0,105,209,0|a1b93z,105,209,0|a1b940,105,209,1|aaod7z,105,209,1|aaod80,100,6,0|ak1ejz,100,6,0|ak1ek0,105,209,1|atrejz,105,209,1|atrek0,100,6,0|b34fvz,100,6,0|b34fw0,105,209,0|blufrz,105,209,0|blufs0,105,209,1|bv7jvz,105,209,1|bv7jw0,100,6,0|c4kl7z,100,6,0|c4kl80,105,209,1|cdxmjz,105,209,1|cdxmk0,100,6,0|cnanvz,100,6,0|cnanw0,105,209,1|cwnp7z,105,209,1|cwnp80,100,6,0|d60qjz,100,6,0|d60qk0,105,209,1|dfdrvz,105,209,1|dfdrw0,100,6,0|dp3rvz,100,6,0|dp3rw0,105,209,1|dzwnvz,105,209,1|dzwnw0,100,6,0|e7tujz,100,6,0|e7tuk0,105,209,1|eimqjz,105,209,1|eimqk0,100,6,0|eqjx7z,100,6,0|eqjx80,105,209,1|f1ct7z,105,209,1|f1ct80,100,6,0|f99zvz,100,6,0|f99zw0,105,209,1|fkfujz,105,209,1|fkfuk0,100,6,0|fs02jz,100,6,0|fs02k0,105,209,1|g35x7z,105,209,1|g35x80,100,6,0|gaq57z,100,6,0|gaq580,105,209,1|glvzvz,105,209,1|glvzw0,100,6,0|gtt6jz,100,6,0|gtt6k0,105,209,1|h4m2jz,105,209,1|h4m2k0,100,6,0|hcj97z,100,6,0|hcj980,105,209,1|hnc57z,105,209,1|hnc580,100,6,0|hv9bvz,100,6,0|hv9bw0,105,209,1|i6f6jz,105,209,1|i6f6k0,100,6,0|idzejz,100,6,0|idzek0,105,209,1|ip597z,105,209,1|ip5980,100,6,0|iwph7z,100,6,0|iwph80,105,209,1|j7vbvz,105,209,1|j7vbw0,100,6,0|jffjvz,100,6,0|jffjw0,105,209,1|jqlejz,105,209,1|jqlek0,100,6,0|jyil7z,100,6,0|jyil80,105,209,1|k9bh7z,105,209,1|k9bh80,100,6,0|kh8nvz,100,6,0|kh8nw0,105,209,1|ks1jvz,105,209,1|ks1jw0,100,6,0|kzyqjz,100,6,0|kzyqk0,105,209,1|lb4l7z,105,209,1|lb4l80,100,6,0|liot7z,100,6,0|liot80,105,209,0|ne0t3z,105,209,0|ne0t40,100,6,0|o4o57z,100,6,0|o4o580,105,209,0\",\"Europe/Athens|,0,331,0|-12rxtq4,44,331,0|-rvv0ch,44,331,0|-rvv0cg,15,11,0|-jkbpk1,15,11,0|-jkbpk0,16,6,1|-jhg301,16,6,1|-jhg300,15,11,0|-ezx6w1,15,11,0|-ezx6w0,16,6,1|-eyqoc1,16,6,1|-eyqoc0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dys2s1,10,10,0|-dys2s0,11,11,1|-dp4081,11,11,1|-dp4080,10,10,0|-dfp1g1,10,10,0|-dfp1g0,15,11,0|-94v1k1,15,11,0|-94v1k0,16,6,1|-8yhho1,16,6,1|-8yhho0,15,11,0|2r4d3z,15,11,0|2r4d40,16,6,1|32ul3z,16,6,1|32ul40,15,11,0|39wfzz,15,11,0|39wg00,16,6,1|3j9hbz,16,6,1|3j9hc0,15,11,0|3s9jzz,15,11,0|3s9k00,16,6,1|41bhbz,16,6,1|41bhc0,15,11,0|4azmnz,15,11,0|4azmo0,16,6,1|4jzs3z,16,6,1|4jzs40,15,11,0|4tq8rz,15,11,0|4tq8s0,16,6,1|530t7z,16,6,1|530t80,15,11,0|5cjbrz,15,11,0|5cjbs0,16,6,1|5lskzz,16,6,1|5lsl00,15,11,0|5v5xfz,15,11,0|5v5xg0,16,6,1|64iyrz,16,6,1|64iys0,15,11,0|6dw03z,15,11,0|6dw040,16,6,1|6n91fz,16,6,1|6n91g0,15,11,0|6wm2rz,15,11,0|6wm2s0,16,6,1|75z43z,16,6,1|75z440,15,11,0|7fc5fz,15,11,0|7fc5g0,16,6,1|7p25fz,16,6,1|7p25g0,15,11,0|7yf6rz,15,11,0|7yf6s0,16,6,1|87s83z,16,6,1|87s840,15,11,0|8h59fz,15,11,0|8h59g0,16,6,1|8qiarz,16,6,1|8qias0,15,11,0|8zvc3z,15,11,0|8zvc40,16,6,1|998dfz,16,6,1|998dg0,15,11,0|9ilerz,15,11,0|9iles0,16,6,1|9ryg3z,16,6,1|9ryg40,15,11,0|a1bhfz,15,11,0|a1bhg0,16,6,1|aaoirz,16,6,1|aaois0,15,11,0|ak1k3z,15,11,0|ak1k40,16,6,1|atrk3z,16,6,1|atrk40,15,11,0|b34lfz,15,11,0|b34lg0,16,6,1|bchmrz,16,6,1|bchms0,15,11,0|bluo3z,15,11,0|bluo40,16,6,1|bv7pfz,16,6,1|bv7pg0,15,11,0|c4kqrz,15,11,0|c4kqs0,16,6,1|cdxs3z,16,6,1|cdxs40,15,11,0|cnatfz,15,11,0|cnatg0,16,6,1|cwnurz,16,6,1|cwnus0,15,11,0|d60w3z,15,11,0|d60w40,16,6,1|dfdxfz,16,6,1|dfdxg0,15,11,0|dp3xfz,15,11,0|dp3xg0,16,6,1|dzwtfz,16,6,1|dzwtg0,15,11,0|e7u03z,15,11,0|e7u040,16,6,1|eimw3z,16,6,1|eimw40,15,11,0|eqk2rz,15,11,0|eqk2s0,16,6,1|f1cyrz,16,6,1|f1cys0,15,11,0|f9a5fz,15,11,0|f9a5g0,16,6,1|fkg03z,16,6,1|fkg040,15,11,0|fs083z,15,11,0|fs0840,16,6,1|g362rz,16,6,1|g362s0,15,11,0|gaqarz,15,11,0|gaqas0,16,6,1|glw5fz,16,6,1|glw5g0,15,11,0|gttc3z,15,11,0|gttc40,16,6,1|h4m83z,16,6,1|h4m840,15,11,0|hcjerz,15,11,0|hcjes0,16,6,1|hncarz,16,6,1|hncas0,15,11,0|hv9hfz,15,11,0|hv9hg0,16,6,1|i6fc3z,16,6,1|i6fc40,15,11,0|idzk3z,15,11,0|idzk40,16,6,1|ip5erz,16,6,1|ip5es0,15,11,0|iwpmrz,15,11,0|iwpms0,16,6,1|j7vhfz,16,6,1|j7vhg0,15,11,0|jffpfz,15,11,0|jffpg0,16,6,1|jqlk3z,16,6,1|jqlk40,15,11,0|jyiqrz,15,11,0|jyiqs0,16,6,1|k9bmrz,16,6,1|k9bms0,15,11,0|kh8tfz,15,11,0|kh8tg0,16,6,1|ks1pfz,16,6,1|ks1pg0,15,11,0|kzyw3z,15,11,0|kzyw40,16,6,1|lb4qrz,16,6,1|lb4qs0,15,11,0|lioyrz,15,11,0|lioys0,16,6,1|ltutfz,16,6,1|ltutg0,15,11,0|m1f1fz,15,11,0|m1f1g0,16,6,1|mckw3z,16,6,1|mckw40,15,11,0|mki2rz,15,11,0|mki2s0,16,6,1|mvayrz,16,6,1|mvays0,15,11,0|n385fz,15,11,0|n385g0,16,6,1|ne11fz,16,6,1|ne11g0,15,11,0|nly83z,15,11,0|nly840,16,6,1|nwr43z,16,6,1|nwr440,15,11,0|o4oarz,15,11,0|o4oas0,16,6,1|ofu5fz,16,6,1|ofu5g0,15,11,0|onedfz,15,11,0|onedg0,16,6,1|oyk83z,16,6,1|oyk840,15,11,0|p64g3z,15,11,0|p64g40,16,6,1|phaarz,16,6,1|phaas0,15,11,0|pp7hfz,15,11,0|pp7hg0,16,6,1|q00dfz,16,6,1|q00dg0,15,11,0|q7xk3z,15,11,0|q7xk40,16,6,1|qiqg3z,16,6,1|qiqg40,15,11,0|qqnmrz,15,11,0|qqnms0,16,6,1|r1thfz,16,6,1|r1thg0,15,11,0|r9dpfz,15,11,0|r9dpg0,16,6,1|rkjk3z,16,6,1|rkjk40,15,11,0|rs3s3z,15,11,0|rs3s40,16,6,1|s39mrz,16,6,1|s39ms0,15,11,0|sb6tfz,15,11,0|sb6tg0,16,6,1|slzpfz,16,6,1|slzpg0,15,11,0|stww3z,15,11,0|stww40,16,6,1|t4ps3z,16,6,1|t4ps40,15,11,0|tcmyrz,15,11,0|tcmys0,16,6,1|tnfurz,16,6,1|tnfus0,15,11,0|tvd1fz,15,11,0|tvd1g0,16,6,1|u6iw3z,16,6,1|u6iw40,15,11,0|ue343z,15,11,0|ue3440,16,6,1|up8yrz,16,6,1|up8ys0,15,11,0|uwt6rz,15,11,0|uwt6s0,16,6,1|v7z1fz,16,6,1|v7z1g0,15,11,0|vfw83z,15,11,0|vfw840,16,6,1|vqp43z,16,6,1|vqp440,15,11,0|vymarz,15,11,0|vymas0,16,6,1|w9f6rz,16,6,1|w9f6s0,15,11,0|whcdfz,15,11,0|whcdg0,16,6,1|wsi83z,16,6,1|wsi840,15,11,0|x02g3z,15,11,0|x02g40,16,6,1|xb8arz,16,6,1|xb8as0,15,11,0|xisirz,15,11,0|xisis0,16,6,1|xtydfz,16,6,1|xtydg0,15,11,0|y1ilfz,15,11,0|y1ilg0,16,6,1|ycog3z,16,6,1|ycog40,15,11,0|yklmrz,15,11,0|yklms0,16,6,1|yveirz,16,6,1|yveis0,15,11,0|z3bpfz,15,11,0|z3bpg0,16,6,1|ze4lfz,16,6,1|ze4lg0,15,11,0\",\"Europe/Belgrade|,0,332,0|-18vsmgo,10,10,0|-ezayw1,10,10,0|-ezayw0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d6dp81,11,11,1|-d6dp80,10,10,0|-cv5zw1,10,10,0|-cv5zw0,11,11,1|-cofek1,11,11,1|-cofek0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Berlin|,0,333,0|-1421154,10,10,0|-s0e081,10,10,0|-s0e080,11,11,1|-rsilg1,11,11,1|-rsilg0,10,10,0|-ridmk1,10,10,0|-ridmk0,11,11,1|-ragfw1,11,11,1|-ragfw0,10,10,0|-qznjw1,10,10,0|-qznjw0,11,11,1|-qrqd81,11,11,1|-qrqd80,10,10,0|-fizzw1,10,10,0|-fizzw0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d6dp81,11,11,1|-d6dp80,10,10,0|-cx0nw1,10,10,0|-cx0nw0,11,11,1|-cucg01,11,11,1|-cucg00,147,6,1|-co0o01,147,6,1|-co0o00,11,11,1|-cl6qk1,11,11,1|-cl6qk0,10,10,0|-cdmik1,10,10,0|-cdmik0,11,11,1|-c4kl81,11,11,1|-c4kl80,10,10,0|-bv9bs1,10,10,0|-bv9bs0,11,11,1|-btgl81,11,11,1|-btgl80,147,6,1|-bqxxc1,147,6,1|-bqxxc0,11,11,1|-blwd81,11,11,1|-blwd80,10,10,0|-bbtek1,10,10,0|-bbtek0,11,11,1|-b36ak1,11,11,1|-b36ak0,10,10,0|-atgak1,10,10,0|-atgak0,11,11,1|-akg7w1,11,11,1|-akg7w0,10,10,0|5cstfz,10,10,0|5cstg0,11,11,1|5lsw3z,11,11,1|5lsw40,10,10,0|5v5xfz,10,10,0|5v5xg0,11,11,1|64iyrz,11,11,1|64iys0,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Bratislava|,0,334,0|-1qmkw08,7,334,0|-14u7uo9,7,334,0|-14u7uo8,10,10,0|-s0e081,10,10,0|-s0e080,11,11,1|-rsilg1,11,11,1|-rsilg0,10,10,0|-ridmk1,10,10,0|-ridmk0,11,11,1|-ragfw1,11,11,1|-ragfw0,10,10,0|-qznjw1,10,10,0|-qznjw0,11,11,1|-qrqd81,11,11,1|-qrqd80,10,10,0|-fizzw1,10,10,0|-fizzw0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d6dp81,11,11,1|-d6dp80,10,10,0|-cx0nw1,10,10,0|-cx0nw0,11,11,1|-cnnmk1,11,11,1|-cnnmk0,10,10,0|-cchrw1,10,10,0|-cchrw0,11,11,1|-c4mfw1,11,11,1|-c4mfw0,10,10,0|-c1qns1,10,10,0|-c1qns0,1,1,1|-bxf3s1,1,1,1|-bxf3s0,10,10,0|-bujh81,10,10,0|-bujh80,11,11,1|-blwd81,11,11,1|-blwd80,10,10,0|-bbtek1,10,10,0|-bbtek0,11,11,1|-b36ak1,11,11,1|-b36ak0,10,10,0|-ati581,10,10,0|-ati580,11,11,1|-akg7w1,11,11,1|-akg7w0,10,10,0|4tps3z,10,10,0|4tps40,11,11,1|532tfz,11,11,1|532tg0,10,10,0|5cstfz,10,10,0|5cstg0,11,11,1|5lsw3z,11,11,1|5lsw40,10,10,0|5v5xfz,10,10,0|5v5xg0,11,11,1|64iyrz,11,11,1|64iys0,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Brussels|,0,335,0|-1ayy3h6,53,335,0|-14j9c01,53,335,0|-14j9c00,8,1,0|-ss5uo1,8,1,0|-ss5uo0,10,10,0|-s0dxg1,10,10,0|-s0dxg0,11,11,1|-rsilg1,11,11,1|-rsilg0,10,10,0|-ridmk1,10,10,0|-ridmk0,11,11,1|-ragfw1,11,11,1|-ragfw0,10,10,0|-qznjw1,10,10,0|-qznjw0,11,11,1|-qrqd81,11,11,1|-qrqd80,10,10,0|-qotw41,10,10,0|-qotw40,8,1,0|-qj59g1,8,1,0|-qj59g0,9,10,1|-q7zes1,9,10,1|-q7zes0,8,1,0|-q15441,8,1,0|-q15440,9,10,1|-po6g41,9,10,1|-po6g40,8,1,0|-pgvhg1,8,1,0|-pgvhg0,9,10,1|-p5atg1,9,10,1|-p5atg0,8,1,0|-oxj6s1,8,1,0|-oxj6s0,9,10,1|-ong841,9,10,1|-ong840,8,1,0|-odd9g1,8,1,0|-odd9g0,9,10,1|-o4q5g1,9,10,1|-o4q5g0,8,1,0|-nvq2s1,8,1,0|-nvq2s0,9,10,1|-nm02s1,9,10,1|-nm02s0,8,1,0|-ncn1g1,8,1,0|-ncn1g0,9,10,1|-n3a041,9,10,1|-n3a040,8,1,0|-mt71g1,8,1,0|-mt71g0,9,10,1|-mkjxg1,9,10,1|-mkjxg0,8,1,0|-matxg1,8,1,0|-matxg0,9,10,1|-m1tus1,9,10,1|-m1tus0,8,1,0|-lrqw41,8,1,0|-lrqw40,9,10,1|-liql41,9,10,1|-liql40,8,1,0|-l8nmg1,8,1,0|-l8nmg0,9,10,1|-l00ig1,9,10,1|-l00ig0,8,1,0|-kqaig1,8,1,0|-kqaig0,9,10,1|-khafs1,9,10,1|-khafs0,8,1,0|-k77h41,8,1,0|-k77h40,9,10,1|-jykd41,9,10,1|-jykd40,8,1,0|-jp7bs1,8,1,0|-jp7bs0,9,10,1|-jfuag1,9,10,1|-jfuag0,8,1,0|-j6u7s1,8,1,0|-j6u7s0,9,10,1|-iwr941,9,10,1|-iwr940,8,1,0|-ine7s1,8,1,0|-ine7s0,9,10,1|-ie16g1,9,10,1|-ie16g0,8,1,0|-i513s1,8,1,0|-i513s0,9,10,1|-hvb3s1,9,10,1|-hvb3s0,8,1,0|-hl8541,8,1,0|-hl8540,9,10,1|-hcl141,9,10,1|-hcl140,8,1,0|-h37zs1,8,1,0|-h37zs0,9,10,1|-gtuyg1,9,10,1|-gtuyg0,8,1,0|-gkuvs1,8,1,0|-gkuvs0,9,10,1|-gb4vs1,9,10,1|-gb4vs0,8,1,0|-g11x41,8,1,0|-g11x40,9,10,1|-fpw2g1,9,10,1|-fpw2g0,8,1,0|-fkul41,8,1,0|-fkul40,9,10,1|-fgh6g1,9,10,1|-fgh6g0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d75h81,11,11,1|-d75h80,10,10,0|-cx0nw1,10,10,0|-cx0nw0,11,11,1|-cofek1,11,11,1|-cofek0,10,10,0|-cbtp81,10,10,0|-cbtp80,11,11,1|-c4kl81,11,11,1|-c4kl80,10,10,0|3s9mrz,10,10,0|3s9ms0,11,11,1|419pfz,11,11,1|419pg0,10,10,0|4azpfz,10,10,0|4azpg0,11,11,1|4kcqrz,11,11,1|4kcqs0,10,10,0|4tps3z,10,10,0|4tps40,11,11,1|532tfz,11,11,1|532tg0,10,10,0|5cstfz,10,10,0|5cstg0,11,11,1|5lsw3z,11,11,1|5lsw40,10,10,0|5v5xfz,10,10,0|5v5xg0,11,11,1|64iyrz,11,11,1|64iys0,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Bucharest|,0,336,0|-14u7wu0,53,336,0|-k29zi1,53,336,0|-k29zi0,15,11,0|-jmqqw1,15,11,0|-jmqqw0,16,6,1|-jfulk1,16,6,1|-jfulk0,15,11,0|-j6hk81,15,11,0|-j6hk80,16,6,1|-ix4iw1,16,6,1|-ix4iw0,15,11,0|-ineiw1,15,11,0|-ineiw0,16,6,1|-ie1hk1,16,6,1|-ie1hk0,15,11,0|-i4og81,15,11,0|-i4og80,16,6,1|-hvbew1,16,6,1|-hvbew0,15,11,0|-hlydk1,15,11,0|-hlydk0,16,6,1|-hclc81,16,6,1|-hclc80,15,11,0|-h38aw1,15,11,0|-h38aw0,16,6,1|-gtv9k1,16,6,1|-gtv9k0,15,11,0|-gki881,15,11,0|-gki880,16,6,1|-gb56w1,16,6,1|-gb56w0,15,11,0|-g1s5k1,15,11,0|-g1s5k0,16,6,1|-fsf481,16,6,1|-fsf480,15,11,0|4wl93z,15,11,0|4wl940,16,6,1|532ibz,16,6,1|532ic0,15,11,0|5csibz,15,11,0|5csic0,16,6,1|5lsnrz,16,6,1|5lsns0,15,11,0|5v5unz,15,11,0|5v5uo0,16,6,1|64ivzz,16,6,1|64iw00,15,11,0|6dvxbz,15,11,0|6dvxc0,16,6,1|6n8ynz,16,6,1|6n8yo0,15,11,0|6wlzzz,15,11,0|6wm000,16,6,1|75z1bz,16,6,1|75z1c0,15,11,0|7fc2nz,15,11,0|7fc2o0,16,6,1|7p22nz,16,6,1|7p22o0,15,11,0|7yf3zz,15,11,0|7yf400,16,6,1|87s5bz,16,6,1|87s5c0,15,11,0|8h56nz,15,11,0|8h56o0,16,6,1|8qi7zz,16,6,1|8qi800,15,11,0|8zv9bz,15,11,0|8zv9c0,16,6,1|998anz,16,6,1|998ao0,15,11,0|9ilbzz,15,11,0|9ilc00,16,6,1|9rydbz,16,6,1|9rydc0,15,11,0|a1benz,15,11,0|a1beo0,16,6,1|aaofzz,16,6,1|aaog00,15,11,0|ak1hbz,15,11,0|ak1hc0,16,6,1|atrhbz,16,6,1|atrhc0,15,11,0|b34d3z,15,11,0|b34d40,16,6,1|bchefz,16,6,1|bcheg0,15,11,0|blufrz,15,11,0|blufs0,16,6,1|bv7h3z,16,6,1|bv7h40,15,11,0|c4kifz,15,11,0|c4kig0,16,6,1|cdxjrz,16,6,1|cdxjs0,15,11,0|cnal3z,15,11,0|cnal40,16,6,1|cwnjnz,16,6,1|cwnjo0,15,11,0|d60nrz,15,11,0|d60ns0,16,6,1|dfdmbz,16,6,1|dfdmc0,15,11,0|dp3p3z,15,11,0|dp3p40,16,6,1|dzwibz,16,6,1|dzwic0,15,11,0|e7u03z,15,11,0|e7u040,16,6,1|eimw3z,16,6,1|eimw40,15,11,0|eqk2rz,15,11,0|eqk2s0,16,6,1|f1cyrz,16,6,1|f1cys0,15,11,0|f9a5fz,15,11,0|f9a5g0,16,6,1|fkg03z,16,6,1|fkg040,15,11,0|fs083z,15,11,0|fs0840,16,6,1|g362rz,16,6,1|g362s0,15,11,0|gaqarz,15,11,0|gaqas0,16,6,1|glw5fz,16,6,1|glw5g0,15,11,0|gttc3z,15,11,0|gttc40,16,6,1|h4m83z,16,6,1|h4m840,15,11,0|hcjerz,15,11,0|hcjes0,16,6,1|hncarz,16,6,1|hncas0,15,11,0|hv9hfz,15,11,0|hv9hg0,16,6,1|i6fc3z,16,6,1|i6fc40,15,11,0|idzk3z,15,11,0|idzk40,16,6,1|ip5erz,16,6,1|ip5es0,15,11,0|iwpmrz,15,11,0|iwpms0,16,6,1|j7vhfz,16,6,1|j7vhg0,15,11,0|jffpfz,15,11,0|jffpg0,16,6,1|jqlk3z,16,6,1|jqlk40,15,11,0|jyiqrz,15,11,0|jyiqs0,16,6,1|k9bmrz,16,6,1|k9bms0,15,11,0|kh8tfz,15,11,0|kh8tg0,16,6,1|ks1pfz,16,6,1|ks1pg0,15,11,0|kzyw3z,15,11,0|kzyw40,16,6,1|lb4qrz,16,6,1|lb4qs0,15,11,0|lioyrz,15,11,0|lioys0,16,6,1|ltutfz,16,6,1|ltutg0,15,11,0|m1f1fz,15,11,0|m1f1g0,16,6,1|mckw3z,16,6,1|mckw40,15,11,0|mki2rz,15,11,0|mki2s0,16,6,1|mvayrz,16,6,1|mvays0,15,11,0|n385fz,15,11,0|n385g0,16,6,1|ne11fz,16,6,1|ne11g0,15,11,0|nly83z,15,11,0|nly840,16,6,1|nwr43z,16,6,1|nwr440,15,11,0|o4oarz,15,11,0|o4oas0,16,6,1|ofu5fz,16,6,1|ofu5g0,15,11,0|onedfz,15,11,0|onedg0,16,6,1|oyk83z,16,6,1|oyk840,15,11,0|p64g3z,15,11,0|p64g40,16,6,1|phaarz,16,6,1|phaas0,15,11,0|pp7hfz,15,11,0|pp7hg0,16,6,1|q00dfz,16,6,1|q00dg0,15,11,0|q7xk3z,15,11,0|q7xk40,16,6,1|qiqg3z,16,6,1|qiqg40,15,11,0|qqnmrz,15,11,0|qqnms0,16,6,1|r1thfz,16,6,1|r1thg0,15,11,0|r9dpfz,15,11,0|r9dpg0,16,6,1|rkjk3z,16,6,1|rkjk40,15,11,0|rs3s3z,15,11,0|rs3s40,16,6,1|s39mrz,16,6,1|s39ms0,15,11,0|sb6tfz,15,11,0|sb6tg0,16,6,1|slzpfz,16,6,1|slzpg0,15,11,0|stww3z,15,11,0|stww40,16,6,1|t4ps3z,16,6,1|t4ps40,15,11,0|tcmyrz,15,11,0|tcmys0,16,6,1|tnfurz,16,6,1|tnfus0,15,11,0|tvd1fz,15,11,0|tvd1g0,16,6,1|u6iw3z,16,6,1|u6iw40,15,11,0|ue343z,15,11,0|ue3440,16,6,1|up8yrz,16,6,1|up8ys0,15,11,0|uwt6rz,15,11,0|uwt6s0,16,6,1|v7z1fz,16,6,1|v7z1g0,15,11,0|vfw83z,15,11,0|vfw840,16,6,1|vqp43z,16,6,1|vqp440,15,11,0|vymarz,15,11,0|vymas0,16,6,1|w9f6rz,16,6,1|w9f6s0,15,11,0|whcdfz,15,11,0|whcdg0,16,6,1|wsi83z,16,6,1|wsi840,15,11,0|x02g3z,15,11,0|x02g40,16,6,1|xb8arz,16,6,1|xb8as0,15,11,0|xisirz,15,11,0|xisis0,16,6,1|xtydfz,16,6,1|xtydg0,15,11,0|y1ilfz,15,11,0|y1ilg0,16,6,1|ycog3z,16,6,1|ycog40,15,11,0|yklmrz,15,11,0|yklms0,16,6,1|yveirz,16,6,1|yveis0,15,11,0|z3bpfz,15,11,0|z3bpg0,16,6,1|ze4lfz,16,6,1|ze4lg0,15,11,0\",\"Europe/Budapest|,0,337,0|-15bee78,10,10,0|-s0e081,10,10,0|-s0e080,11,11,1|-rsilg1,11,11,1|-rsilg0,10,10,0|-ridmk1,10,10,0|-ridmk0,11,11,1|-ragfw1,11,11,1|-ragfw0,10,10,0|-qznjw1,10,10,0|-qznjw0,11,11,1|-qrqd81,11,11,1|-qrqd80,10,10,0|-qgvmk1,10,10,0|-qgvmk0,11,11,1|-q90ak1,11,11,1|-q90ak0,10,10,0|-pykd81,10,10,0|-pykd80,11,11,1|-ppx981,11,11,1|-ppx980,10,10,0|-ezvc81,10,10,0|-ezvc80,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d6dp81,11,11,1|-d6dp80,10,10,0|-cvhc81,10,10,0|-cvhc80,11,11,1|-cm2dg1,11,11,1|-cm2dg0,10,10,0|-cecfw1,10,10,0|-cecfw0,11,11,1|-c4ko01,11,11,1|-c4ko00,10,10,0|-bv9ek1,10,10,0|-bv9ek0,11,11,1|-blwd81,11,11,1|-blwd80,10,10,0|-bcjbw1,10,10,0|-bcjbw0,11,11,1|-b36ak1,11,11,1|-b36ak0,10,10,0|-atgak1,10,10,0|-atgak0,11,11,1|-akg7w1,11,11,1|-akg7w0,10,10,0|-85bc41,10,10,0|-85bc40,11,11,1|-7yh481,11,11,1|-7yh480,10,10,0|-7ml3w1,10,10,0|-7ml3w0,11,11,1|-7fqt81,11,11,1|-7fqt80,10,10,0|-7353w1,10,10,0|-7353w0,11,11,1|-6x0qk1,11,11,1|-6x0qk0,10,10,0|-6kf181,10,10,0|-6kf180,11,11,1|-6eanw1,11,11,1|-6eanw0,10,10,0|5csnvz,10,10,0|5csnw0,11,11,1|5lsqjz,11,11,1|5lsqk0,10,10,0|5v5rvz,10,10,0|5v5rw0,11,11,1|64it7z,11,11,1|64it80,10,10,0|6dvujz,10,10,0|6dvuk0,11,11,1|6n8vvz,11,11,1|6n8vw0,10,10,0|6wlx7z,10,10,0|6wlx80,11,11,1|75yyjz,11,11,1|75yyk0,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Busingen|,0,338,0|-1os49kw,53,339,0|-13g441n,53,339,0|-13g441m,10,10,0|-eyh6o1,10,10,0|-eyh6o0,11,11,1|-eqk001,11,11,1|-eqk000,10,10,0|-efr401,10,10,0|-efr400,11,11,1|-e7txc1,11,11,1|-e7txc0,10,10,0|5v5xfz,10,10,0|5v5xg0,11,11,1|64iyrz,11,11,1|64iys0,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Chisinau|,0,340,0|-1ayy808,41,341,0|-r2p1bp,41,341,0|-r2p1bo,53,336,0|-k29zi1,53,336,0|-k29zi0,15,11,0|-jmqqw1,15,11,0|-jmqqw0,16,6,1|-jfulk1,16,6,1|-jfulk0,15,11,0|-j6hk81,15,11,0|-j6hk80,16,6,1|-ix4iw1,16,6,1|-ix4iw0,15,11,0|-ineiw1,15,11,0|-ineiw0,16,6,1|-ie1hk1,16,6,1|-ie1hk0,15,11,0|-i4og81,15,11,0|-i4og80,16,6,1|-hvbew1,16,6,1|-hvbew0,15,11,0|-hlydk1,15,11,0|-hlydk0,16,6,1|-hclc81,16,6,1|-hclc80,15,11,0|-h38aw1,15,11,0|-h38aw0,16,6,1|-gtv9k1,16,6,1|-gtv9k0,15,11,0|-gki881,15,11,0|-gki880,16,6,1|-gb56w1,16,6,1|-gb56w0,15,11,0|-g1s5k1,15,11,0|-g1s5k0,16,6,1|-fsf481,16,6,1|-fsf480,15,11,0|-fc0dk1,15,11,0|-fc0dk0,16,6,1|-euq8c1,16,6,1|-euq8c0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d8e5k1,11,11,1|-d8e5k0,148,6,0|5vb6bz,148,6,0|5vb6c0,149,209,1|64pzjz,149,209,1|64pzk0,148,6,0|6e33nz,148,6,0|6e33o0,149,209,1|6nhwvz,149,209,1|6nhww0,148,6,0|6wv0zz,148,6,0|6wv100,149,209,1|769u7z,149,209,1|769u80,148,6,0|7foszz,148,6,0|7fot00,149,209,1|7p1zvz,149,209,1|7p1zw0,148,6,0|7yf17z,148,6,0|7yf180,149,209,1|87s2jz,149,209,1|87s2k0,148,6,0|8h53vz,148,6,0|8h53w0,149,209,1|8qi57z,149,209,1|8qi580,148,6,0|8zv6jz,148,6,0|8zv6k0,149,209,1|9987vz,149,209,1|9987w0,148,6,0|9il97z,148,6,0|9il980,149,209,1|9ryajz,149,209,1|9ryak0,148,6,0|a1bbvz,148,6,0|a1bbw0,149,209,1|aaod7z,149,209,1|aaod80,148,6,0|ak1ejz,148,6,0|ak1ek0,149,209,1|am73rz,149,209,1|am73s0,16,6,1|atrhbz,16,6,1|atrhc0,15,11,0|b34inz,15,11,0|b34io0,16,6,1|bchjzz,16,6,1|bchk00,15,11,0|blufrz,15,11,0|blufs0,16,6,1|bv7ebz,16,6,1|bv7ec0,15,11,0|c4kifz,15,11,0|c4kig0,16,6,1|cdxgzz,16,6,1|cdxh00,15,11,0|cnal3z,15,11,0|cnal40,16,6,1|cwnjnz,16,6,1|cwnjo0,15,11,0|d60nrz,15,11,0|d60ns0,16,6,1|dfdmbz,16,6,1|dfdmc0,15,11,0|dp3p3z,15,11,0|dp3p40,16,6,1|dzwibz,16,6,1|dzwic0,15,11,0|e7txbz,15,11,0|e7txc0,16,6,1|eimtbz,16,6,1|eimtc0,15,11,0|eqjzzz,15,11,0|eqk000,16,6,1|f1cvzz,16,6,1|f1cw00,15,11,0|f9a2nz,15,11,0|f9a2o0,16,6,1|fkfxbz,16,6,1|fkfxc0,15,11,0|fs05bz,15,11,0|fs05c0,16,6,1|g35zzz,16,6,1|g36000,15,11,0|gaq7zz,15,11,0|gaq800,16,6,1|glw2nz,16,6,1|glw2o0,15,11,0|gtt9bz,15,11,0|gtt9c0,16,6,1|h4m5bz,16,6,1|h4m5c0,15,11,0|hcjbzz,15,11,0|hcjc00,16,6,1|hnc7zz,16,6,1|hnc800,15,11,0|hv9enz,15,11,0|hv9eo0,16,6,1|i6f9bz,16,6,1|i6f9c0,15,11,0|idzhbz,15,11,0|idzhc0,16,6,1|ip5bzz,16,6,1|ip5c00,15,11,0|iwpjzz,15,11,0|iwpk00,16,6,1|j7venz,16,6,1|j7veo0,15,11,0|jffmnz,15,11,0|jffmo0,16,6,1|jqlhbz,16,6,1|jqlhc0,15,11,0|jyinzz,15,11,0|jyio00,16,6,1|k9bjzz,16,6,1|k9bk00,15,11,0|kh8qnz,15,11,0|kh8qo0,16,6,1|ks1mnz,16,6,1|ks1mo0,15,11,0|kzytbz,15,11,0|kzytc0,16,6,1|lb4nzz,16,6,1|lb4o00,15,11,0|liovzz,15,11,0|liow00,16,6,1|ltuqnz,16,6,1|ltuqo0,15,11,0|m1eynz,15,11,0|m1eyo0,16,6,1|mcktbz,16,6,1|mcktc0,15,11,0|mkhzzz,15,11,0|mki000,16,6,1|mvavzz,16,6,1|mvaw00,15,11,0|n382nz,15,11,0|n382o0,16,6,1|ne0ynz,16,6,1|ne0yo0,15,11,0|nly5bz,15,11,0|nly5c0,16,6,1|nwr1bz,16,6,1|nwr1c0,15,11,0|o4o7zz,15,11,0|o4o800,16,6,1|ofu2nz,16,6,1|ofu2o0,15,11,0|oneanz,15,11,0|oneao0,16,6,1|oyk5bz,16,6,1|oyk5c0,15,11,0|p64dbz,15,11,0|p64dc0,16,6,1|pha7zz,16,6,1|pha800,15,11,0|pp7enz,15,11,0|pp7eo0,16,6,1|q00anz,16,6,1|q00ao0,15,11,0|q7xhbz,15,11,0|q7xhc0,16,6,1|qiqdbz,16,6,1|qiqdc0,15,11,0|qqnjzz,15,11,0|qqnk00,16,6,1|r1tenz,16,6,1|r1teo0,15,11,0|r9dmnz,15,11,0|r9dmo0,16,6,1|rkjhbz,16,6,1|rkjhc0,15,11,0|rs3pbz,15,11,0|rs3pc0,16,6,1|s39jzz,16,6,1|s39k00,15,11,0|sb6qnz,15,11,0|sb6qo0,16,6,1|slzmnz,16,6,1|slzmo0,15,11,0|stwtbz,15,11,0|stwtc0,16,6,1|t4ppbz,16,6,1|t4ppc0,15,11,0|tcmvzz,15,11,0|tcmw00,16,6,1|tnfrzz,16,6,1|tnfs00,15,11,0|tvcynz,15,11,0|tvcyo0,16,6,1|u6itbz,16,6,1|u6itc0,15,11,0|ue31bz,15,11,0|ue31c0,16,6,1|up8vzz,16,6,1|up8w00,15,11,0|uwt3zz,15,11,0|uwt400,16,6,1|v7yynz,16,6,1|v7yyo0,15,11,0|vfw5bz,15,11,0|vfw5c0,16,6,1|vqp1bz,16,6,1|vqp1c0,15,11,0|vym7zz,15,11,0|vym800,16,6,1|w9f3zz,16,6,1|w9f400,15,11,0|whcanz,15,11,0|whcao0,16,6,1|wsi5bz,16,6,1|wsi5c0,15,11,0|x02dbz,15,11,0|x02dc0,16,6,1|xb87zz,16,6,1|xb8800,15,11,0|xisfzz,15,11,0|xisg00,16,6,1|xtyanz,16,6,1|xtyao0,15,11,0|y1iinz,15,11,0|y1iio0,16,6,1|ycodbz,16,6,1|ycodc0,15,11,0|ykljzz,15,11,0|yklk00,16,6,1|yvefzz,16,6,1|yveg00,15,11,0|z3bmnz,15,11,0|z3bmo0,16,6,1|ze4inz,16,6,1|ze4io0,15,11,0\",\"Europe/Copenhagen|,0,342,0|-15r1bnw,41,342,0|-13nvrnx,41,342,0|-13nvrnw,10,10,0|-rzo2w1,10,10,0|-rzo2w0,11,11,1|-rsir01,11,11,1|-rsir00,10,10,0|-fgqo41,10,10,0|-fgqo40,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d6dp81,11,11,1|-d6dp80,10,10,0|-cx0nw1,10,10,0|-cx0nw0,11,11,1|-cq2nw1,11,11,1|-cq2nw0,10,10,0|-ccr181,10,10,0|-ccr180,11,11,1|-c6f981,11,11,1|-c6f980,10,10,0|-bttjw1,10,10,0|-bttjw0,11,11,1|-bos2k1,11,11,1|-bos2k0,10,10,0|-baqik1,10,10,0|-baqik0,11,11,1|-b61zw1,11,11,1|-b61zw0,10,10,0|5cstfz,10,10,0|5cstg0,11,11,1|5lsw3z,11,11,1|5lsw40,10,10,0|5v5xfz,10,10,0|5v5xg0,11,11,1|64iyrz,11,11,1|64iys0,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Dublin|,0,343,0|-1anxquc,150,344,0|-rzcmls,150,344,0|-rzcmlr,110,345,1|-rsibxs,110,345,1|-rsibxr,1,1,0|-risd41,1,1,0|-risd40,27,10,1|-ragd41,27,10,1|-ragd40,1,1,0|-r0s7s1,1,1,0|-r0s7s0,27,10,1|-qr0d41,27,10,1|-qr0d40,1,1,0|-qhp6g1,1,1,0|-qhp6g0,27,10,1|-q8aag1,27,10,1|-q8aag0,1,1,0|-pyz3s1,1,1,0|-pyz3s0,27,10,1|-po4d41,27,10,1|-po4d40,1,1,0|-pfw2g1,1,1,0|-pfw2g0,27,10,1|-p6h6g1,27,10,1|-p6h6g0,1,1,0|-oxiyg1,1,1,0|-oxiyg0,110,10,1|-onfzs1,110,10,1|-onfzs0,1,1,0|-odd141,1,1,0|-odd140,110,10,1|-o5st41,110,10,1|-o5st40,1,1,0|-nuzx41,1,1,0|-nuzx40,110,10,1|-nmprs1,110,10,1|-nmprs0,1,1,0|-nbwvs1,1,1,0|-nbwvs0,110,10,1|-n39rs1,110,10,1|-n39rs0,1,1,0|-mt6t41,1,1,0|-mt6t40,110,10,1|-mkjp41,110,10,1|-mkjp40,1,1,0|-matp41,1,1,0|-matp40,110,10,1|-m1tmg1,110,10,1|-m1tmg0,1,1,0|-lrdp41,1,1,0|-lrdp40,110,10,1|-liql41,110,10,1|-liql40,1,1,0|-l8nmg1,1,1,0|-l8nmg0,110,10,1|-l00ig1,110,10,1|-l00ig0,1,1,0|-kqaig1,1,1,0|-kqaig0,110,10,1|-khafs1,110,10,1|-khafs0,1,1,0|-k77h41,1,1,0|-k77h40,110,10,1|-jykd41,110,10,1|-jykd40,1,1,0|-joheg1,1,1,0|-joheg0,110,10,1|-jfuag1,110,10,1|-jfuag0,1,1,0|-j64ag1,1,1,0|-j64ag0,110,10,1|-iwr941,110,10,1|-iwr940,1,1,0|-imoag1,1,1,0|-imoag0,110,10,1|-ie16g1,110,10,1|-ie16g0,1,1,0|-i4b6g1,1,1,0|-i4b6g0,110,10,1|-hvb3s1,110,10,1|-hvb3s0,1,1,0|-hl8541,1,1,0|-hl8540,110,10,1|-hcl141,110,10,1|-hcl140,1,1,0|-h2i2g1,1,1,0|-h2i2g0,110,10,1|-gtuyg1,110,10,1|-gtuyg0,1,1,0|-gk4yg1,1,1,0|-gk4yg0,110,10,1|-gb4vs1,110,10,1|-gb4vs0,1,1,0|-g11x41,1,1,0|-g11x40,110,10,1|-fpw2g1,110,10,1|-fpw2g0,1,1,0|-fkul41,1,1,0|-fkul40,110,10,1|-c4md41,110,10,1|-c4md40,1,1,0|-bwc7s1,1,1,0|-bwc7s0,110,10,1|-bkgfs1,110,10,1|-bkgfs0,1,1,0|-bbtbs1,1,1,0|-bbtbs0,110,10,1|-b1qd41,110,10,1|-b1qd40,1,1,0|-att6g1,1,1,0|-att6g0,110,10,1|-aj0ag1,110,10,1|-aj0ag0,1,1,0|-aad6g1,1,1,0|-aad6g0,110,10,1|-a0n6g1,110,10,1|-a0n6g0,1,1,0|-9rn3s1,1,1,0|-9rn3s0,110,10,1|-9hx3s1,110,10,1|-9hx3s0,1,1,0|-98k2g1,1,1,0|-98k2g0,110,10,1|-8yu2g1,110,10,1|-8yu2g0,1,1,0|-8ptzs1,1,1,0|-8ptzs0,110,10,1|-8h6vs1,110,10,1|-8h6vs0,1,1,0|-87gvs1,1,1,0|-87gvs0,110,10,1|-7ygt41,110,10,1|-7ygt40,1,1,0|-7odug1,1,1,0|-7odug0,110,10,1|-7fqqg1,110,10,1|-7fqqg0,1,1,0|-75at41,1,1,0|-75at40,110,10,1|-6wnp41,110,10,1|-6wnp40,1,1,0|-6mxp41,1,1,0|-6mxp40,110,10,1|-6dxmg1,110,10,1|-6dxmg0,1,1,0|-63uns1,1,1,0|-63uns0,110,10,1|-5v7js1,110,10,1|-5v7js0,1,1,0|-5l4l41,1,1,0|-5l4l40,110,10,1|-5chh41,110,10,1|-5chh40,1,1,0|-52rh41,1,1,0|-52rh40,110,10,1|-4treg1,110,10,1|-4treg0,1,1,0|-4krbs1,1,1,0|-4krbs0,110,10,1|-49lh41,110,10,1|-49lh40,1,1,0|-421941,1,1,0|-421940,110,10,1|-3qveg1,110,10,1|-3qveg0,1,1,0|-3iy7s1,1,1,0|-3iy7s0,110,10,1|-385bs1,110,10,1|-385bs0,1,1,0|-30l3s1,1,1,0|-30l3s0,110,10,1|-2pf941,110,10,1|-2pf940,1,1,0|-2hv141,1,1,0|-2hv140,110,10,1|-26p6g1,110,10,1|-26p6g0,1,1,0|-1z4yg1,1,1,0|-1z4yg0,110,10,1|-1nz3s1,110,10,1|-1nz3s0,1,1,0|-1gevs1,1,1,0|-1gevs0,110,10,1|-14w2g1,110,10,1|-14w2g0,1,1,0|-z4ns1,1,1,0|-z4ns0,110,10,1|-m6841,110,10,1|-m6840,110,10,0|yd6vz,110,10,0|yd6w0,1,1,1|15kg7z,1,1,1|15kg80,110,10,0|1h39jz,110,10,0|1h39k0,1,1,1|1oaivz,1,1,1|1oaiw0,110,10,0|1ztc7z,110,10,0|1ztc80,1,1,1|270ljz,1,1,1|270lk0,110,10,0|2ijevz,110,10,0|2ijew0,1,1,1|2pqo7z,1,1,1|2pqo80,110,10,0|319hjz,110,10,0|319hk0,1,1,1|38tpjz,1,1,1|38tpk0,110,10,0|3jzk7z,110,10,0|3jzk80,1,1,1|3rjs7z,1,1,1|3rjs80,110,10,0|42pmvz,110,10,0|42pmw0,1,1,1|4a9uvz,1,1,1|4a9uw0,110,10,0|4lso7z,110,10,0|4lso80,1,1,1|4szxjz,1,1,1|4szxk0,110,10,0|54iqvz,110,10,0|54iqw0,1,1,1|5bq07z,1,1,1|5bq080,110,10,0|5n8tjz,110,10,0|5n8tk0,1,1,1|5v5xfz,1,1,1|5v5xg0,110,10,0|65ytfz,110,10,0|65ytg0,1,1,1|6dw03z,1,1,1|6dw040,110,10,0|6oow3z,110,10,0|6oow40,1,1,1|6wm2rz,1,1,1|6wm2s0,110,10,0|77eyrz,110,10,0|77eys0,1,1,1|7fc5fz,1,1,1|7fc5g0,110,10,0|7qi03z,110,10,0|7qi040,1,1,1|7yf6rz,1,1,1|7yf6s0,110,10,0|8982rz,110,10,0|8982s0,1,1,1|8h59fz,1,1,1|8h59g0,110,10,0|8ry5fz,110,10,0|8ry5g0,1,1,1|8zvc3z,1,1,1|8zvc40,110,10,0|9ao83z,110,10,0|9ao840,1,1,1|9ilerz,1,1,1|9iles0,110,10,0|9tearz,110,10,0|9teas0,1,1,1|a1bhfz,1,1,1|a1bhg0,110,10,0|achc3z,110,10,0|achc40,1,1,1|ak1k3z,1,1,1|ak1k40,110,10,0|av7erz,110,10,0|av7es0,1,1,1|b34lfz,1,1,1|b34lg0,110,10,0|bdxhfz,110,10,0|bdxhg0,1,1,1|bluo3z,1,1,1|bluo40,110,10,0|bwnk3z,110,10,0|bwnk40,1,1,1|c4kqrz,1,1,1|c4kqs0,110,10,0|cfdmrz,110,10,0|cfdms0,1,1,1|cnatfz,1,1,1|cnatg0,110,10,0|cy3pfz,110,10,0|cy3pg0,1,1,1|d60w3z,1,1,1|d60w40,110,10,0|dgts3z,110,10,0|dgts40,1,1,1|dp3xfz,1,1,1|dp3xg0,110,10,0|dzwtfz,110,10,0|dzwtg0,1,1,1|e7u03z,1,1,1|e7u040,110,10,0|eimw3z,110,10,0|eimw40,1,1,1|eqk2rz,1,1,1|eqk2s0,110,10,0|f1cyrz,110,10,0|f1cys0,1,1,1|f9a5fz,1,1,1|f9a5g0,110,10,0|fkg03z,110,10,0|fkg040,1,1,1|fs083z,1,1,1|fs0840,110,10,0|g362rz,110,10,0|g362s0,1,1,1|gaqarz,1,1,1|gaqas0,110,10,0|glw5fz,110,10,0|glw5g0,1,1,1|gttc3z,1,1,1|gttc40,110,10,0|h4m83z,110,10,0|h4m840,1,1,1|hcjerz,1,1,1|hcjes0,110,10,0|hncarz,110,10,0|hncas0,1,1,1|hv9hfz,1,1,1|hv9hg0,110,10,0|i6fc3z,110,10,0|i6fc40,1,1,1|idzk3z,1,1,1|idzk40,110,10,0|ip5erz,110,10,0|ip5es0,1,1,1|iwpmrz,1,1,1|iwpms0,110,10,0|j7vhfz,110,10,0|j7vhg0,1,1,1|jffpfz,1,1,1|jffpg0,110,10,0|jqlk3z,110,10,0|jqlk40,1,1,1|jyiqrz,1,1,1|jyiqs0,110,10,0|k9bmrz,110,10,0|k9bms0,1,1,1|kh8tfz,1,1,1|kh8tg0,110,10,0|ks1pfz,110,10,0|ks1pg0,1,1,1|kzyw3z,1,1,1|kzyw40,110,10,0|lb4qrz,110,10,0|lb4qs0,1,1,1|lioyrz,1,1,1|lioys0,110,10,0|ltutfz,110,10,0|ltutg0,1,1,1|m1f1fz,1,1,1|m1f1g0,110,10,0|mckw3z,110,10,0|mckw40,1,1,1|mki2rz,1,1,1|mki2s0,110,10,0|mvayrz,110,10,0|mvays0,1,1,1|n385fz,1,1,1|n385g0,110,10,0|ne11fz,110,10,0|ne11g0,1,1,1|nly83z,1,1,1|nly840,110,10,0|nwr43z,110,10,0|nwr440,1,1,1|o4oarz,1,1,1|o4oas0,110,10,0|ofu5fz,110,10,0|ofu5g0,1,1,1|onedfz,1,1,1|onedg0,110,10,0|oyk83z,110,10,0|oyk840,1,1,1|p64g3z,1,1,1|p64g40,110,10,0|phaarz,110,10,0|phaas0,1,1,1|pp7hfz,1,1,1|pp7hg0,110,10,0|q00dfz,110,10,0|q00dg0,1,1,1|q7xk3z,1,1,1|q7xk40,110,10,0|qiqg3z,110,10,0|qiqg40,1,1,1|qqnmrz,1,1,1|qqnms0,110,10,0|r1thfz,110,10,0|r1thg0,1,1,1|r9dpfz,1,1,1|r9dpg0,110,10,0|rkjk3z,110,10,0|rkjk40,1,1,1|rs3s3z,1,1,1|rs3s40,110,10,0|s39mrz,110,10,0|s39ms0,1,1,1|sb6tfz,1,1,1|sb6tg0,110,10,0|slzpfz,110,10,0|slzpg0,1,1,1|stww3z,1,1,1|stww40,110,10,0|t4ps3z,110,10,0|t4ps40,1,1,1|tcmyrz,1,1,1|tcmys0,110,10,0|tnfurz,110,10,0|tnfus0,1,1,1|tvd1fz,1,1,1|tvd1g0,110,10,0|u6iw3z,110,10,0|u6iw40,1,1,1|ue343z,1,1,1|ue3440,110,10,0|up8yrz,110,10,0|up8ys0,1,1,1|uwt6rz,1,1,1|uwt6s0,110,10,0|v7z1fz,110,10,0|v7z1g0,1,1,1|vfw83z,1,1,1|vfw840,110,10,0|vqp43z,110,10,0|vqp440,1,1,1|vymarz,1,1,1|vymas0,110,10,0|w9f6rz,110,10,0|w9f6s0,1,1,1|whcdfz,1,1,1|whcdg0,110,10,0|wsi83z,110,10,0|wsi840,1,1,1|x02g3z,1,1,1|x02g40,110,10,0|xb8arz,110,10,0|xb8as0,1,1,1|xisirz,1,1,1|xisis0,110,10,0|xtydfz,110,10,0|xtydg0,1,1,1|y1ilfz,1,1,1|y1ilg0,110,10,0|ycog3z,110,10,0|ycog40,1,1,1|yklmrz,1,1,1|yklms0,110,10,0|yveirz,110,10,0|yveis0,1,1,1|z3bpfz,1,1,1|z3bpg0,110,10,0|ze4lfz,110,10,0|ze4lg0,1,1,1\",\"Europe/Gibraltar|,0,346,0|-1anxr0c,1,1,0|-rzcns1,1,1,0|-rzcns0,27,10,1|-rsid41,27,10,1|-rsid40,1,1,0|-risd41,1,1,0|-risd40,27,10,1|-ragd41,27,10,1|-ragd40,1,1,0|-r0s7s1,1,1,0|-r0s7s0,27,10,1|-qr0d41,27,10,1|-qr0d40,1,1,0|-qhp6g1,1,1,0|-qhp6g0,27,10,1|-q8aag1,27,10,1|-q8aag0,1,1,0|-pyz3s1,1,1,0|-pyz3s0,27,10,1|-po4d41,27,10,1|-po4d40,1,1,0|-pfw2g1,1,1,0|-pfw2g0,27,10,1|-p6h6g1,27,10,1|-p6h6g0,1,1,0|-oxiyg1,1,1,0|-oxiyg0,27,10,1|-onfzs1,27,10,1|-onfzs0,1,1,0|-odd141,1,1,0|-odd140,27,10,1|-o5st41,27,10,1|-o5st40,1,1,0|-nuzx41,1,1,0|-nuzx40,27,10,1|-nmprs1,27,10,1|-nmprs0,1,1,0|-nbwvs1,1,1,0|-nbwvs0,27,10,1|-n39rs1,27,10,1|-n39rs0,1,1,0|-mt6t41,1,1,0|-mt6t40,27,10,1|-mkjp41,27,10,1|-mkjp40,1,1,0|-matp41,1,1,0|-matp40,27,10,1|-m1tmg1,27,10,1|-m1tmg0,1,1,0|-lrdp41,1,1,0|-lrdp40,27,10,1|-liql41,27,10,1|-liql40,1,1,0|-l8nmg1,1,1,0|-l8nmg0,27,10,1|-l00ig1,27,10,1|-l00ig0,1,1,0|-kqaig1,1,1,0|-kqaig0,27,10,1|-khafs1,27,10,1|-khafs0,1,1,0|-k77h41,1,1,0|-k77h40,27,10,1|-jykd41,27,10,1|-jykd40,1,1,0|-joheg1,1,1,0|-joheg0,27,10,1|-jfuag1,27,10,1|-jfuag0,1,1,0|-j64ag1,1,1,0|-j64ag0,27,10,1|-iwr941,27,10,1|-iwr940,1,1,0|-imoag1,1,1,0|-imoag0,27,10,1|-ie16g1,27,10,1|-ie16g0,1,1,0|-i4b6g1,1,1,0|-i4b6g0,27,10,1|-hvb3s1,27,10,1|-hvb3s0,1,1,0|-hl8541,1,1,0|-hl8540,27,10,1|-hcl141,27,10,1|-hcl140,1,1,0|-h2i2g1,1,1,0|-h2i2g0,27,10,1|-gtuyg1,27,10,1|-gtuyg0,1,1,0|-gk4yg1,1,1,0|-gk4yg0,27,10,1|-gb4vs1,27,10,1|-gb4vs0,1,1,0|-g11x41,1,1,0|-g11x40,27,10,1|-fpw2g1,27,10,1|-fpw2g0,1,1,0|-fkul41,1,1,0|-fkul40,27,10,1|-eyiyk1,27,10,1|-eyiyk0,151,11,1|-ethh81,151,11,1|-ethh80,27,10,1|-eh8qk1,27,10,1|-eh8qk0,151,11,1|-earek1,151,11,1|-earek0,27,10,1|-dyinw1,27,10,1|-dyinw0,151,11,1|-drod81,151,11,1|-drod80,27,10,1|-dfsl81,27,10,1|-dfsl80,151,11,1|-d75h81,151,11,1|-d75h80,27,10,1|-cx0nw1,27,10,1|-cx0nw0,151,11,1|-cro2k1,151,11,1|-cro2k0,27,10,1|-cncfs1,27,10,1|-cncfs0,1,1,0|-cdmfs1,1,1,0|-cdmfs0,27,10,1|-c4md41,27,10,1|-c4md40,1,1,0|-bwc7s1,1,1,0|-bwc7s0,27,10,1|-buwfw1,27,10,1|-buwfw0,151,11,1|-bos2k1,151,11,1|-bos2k0,27,10,1|-bkgfs1,27,10,1|-bkgfs0,1,1,0|-bdm541,1,1,0|-bdm540,27,10,1|-b1qd41,27,10,1|-b1qd40,1,1,0|-att6g1,1,1,0|-att6g0,27,10,1|-aj0ag1,27,10,1|-aj0ag0,1,1,0|-aad6g1,1,1,0|-aad6g0,27,10,1|-a0n6g1,27,10,1|-a0n6g0,1,1,0|-9rn3s1,1,1,0|-9rn3s0,27,10,1|-9hx3s1,27,10,1|-9hx3s0,1,1,0|-98k2g1,1,1,0|-98k2g0,27,10,1|-8yu2g1,27,10,1|-8yu2g0,1,1,0|-8ptzs1,1,1,0|-8ptzs0,27,10,1|-8h6vs1,27,10,1|-8h6vs0,1,1,0|-87gvs1,1,1,0|-87gvs0,27,10,1|-7ygt41,27,10,1|-7ygt40,1,1,0|-7odug1,1,1,0|-7odug0,27,10,1|-7fqqg1,27,10,1|-7fqqg0,1,1,0|-75at41,1,1,0|-75at40,27,10,1|-6wnp41,27,10,1|-6wnp40,1,1,0|-6mxp41,1,1,0|-6mxp40,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Guernsey|,0,347,0|-1rprx9x,1,1,0|-rzcns1,1,1,0|-rzcns0,27,10,1|-rsid41,27,10,1|-rsid40,1,1,0|-risd41,1,1,0|-risd40,27,10,1|-ragd41,27,10,1|-ragd40,1,1,0|-r0s7s1,1,1,0|-r0s7s0,27,10,1|-qr0d41,27,10,1|-qr0d40,1,1,0|-qhp6g1,1,1,0|-qhp6g0,27,10,1|-q8aag1,27,10,1|-q8aag0,1,1,0|-pyz3s1,1,1,0|-pyz3s0,27,10,1|-po4d41,27,10,1|-po4d40,1,1,0|-pfw2g1,1,1,0|-pfw2g0,27,10,1|-p6h6g1,27,10,1|-p6h6g0,1,1,0|-oxiyg1,1,1,0|-oxiyg0,27,10,1|-onfzs1,27,10,1|-onfzs0,1,1,0|-odd141,1,1,0|-odd140,27,10,1|-o5st41,27,10,1|-o5st40,1,1,0|-nuzx41,1,1,0|-nuzx40,27,10,1|-nmprs1,27,10,1|-nmprs0,1,1,0|-nbwvs1,1,1,0|-nbwvs0,27,10,1|-n39rs1,27,10,1|-n39rs0,1,1,0|-mt6t41,1,1,0|-mt6t40,27,10,1|-mkjp41,27,10,1|-mkjp40,1,1,0|-matp41,1,1,0|-matp40,27,10,1|-m1tmg1,27,10,1|-m1tmg0,1,1,0|-lrdp41,1,1,0|-lrdp40,27,10,1|-liql41,27,10,1|-liql40,1,1,0|-l8nmg1,1,1,0|-l8nmg0,27,10,1|-l00ig1,27,10,1|-l00ig0,1,1,0|-kqaig1,1,1,0|-kqaig0,27,10,1|-khafs1,27,10,1|-khafs0,1,1,0|-k77h41,1,1,0|-k77h40,27,10,1|-jykd41,27,10,1|-jykd40,1,1,0|-joheg1,1,1,0|-joheg0,27,10,1|-jfuag1,27,10,1|-jfuag0,1,1,0|-j64ag1,1,1,0|-j64ag0,27,10,1|-iwr941,27,10,1|-iwr940,1,1,0|-imoag1,1,1,0|-imoag0,27,10,1|-ie16g1,27,10,1|-ie16g0,1,1,0|-i4b6g1,1,1,0|-i4b6g0,27,10,1|-hvb3s1,27,10,1|-hvb3s0,1,1,0|-hl8541,1,1,0|-hl8540,27,10,1|-hcl141,27,10,1|-hcl140,1,1,0|-h2i2g1,1,1,0|-h2i2g0,27,10,1|-gtuyg1,27,10,1|-gtuyg0,1,1,0|-gk4yg1,1,1,0|-gk4yg0,27,10,1|-gb4vs1,27,10,1|-gb4vs0,1,1,0|-g11x41,1,1,0|-g11x40,27,10,1|-fpw2g1,27,10,1|-fpw2g0,1,1,0|-fkul41,1,1,0|-fkul40,27,10,1|-eyiyk1,27,10,1|-eyiyk0,151,11,1|-ethh81,151,11,1|-ethh80,27,10,1|-eh8qk1,27,10,1|-eh8qk0,151,11,1|-earek1,151,11,1|-earek0,27,10,1|-dyinw1,27,10,1|-dyinw0,151,11,1|-drod81,151,11,1|-drod80,27,10,1|-dfsl81,27,10,1|-dfsl80,151,11,1|-d75h81,151,11,1|-d75h80,27,10,1|-cx0nw1,27,10,1|-cx0nw0,151,11,1|-cro2k1,151,11,1|-cro2k0,27,10,1|-cncfs1,27,10,1|-cncfs0,1,1,0|-cdmfs1,1,1,0|-cdmfs0,27,10,1|-c4md41,27,10,1|-c4md40,1,1,0|-bwc7s1,1,1,0|-bwc7s0,27,10,1|-buwfw1,27,10,1|-buwfw0,151,11,1|-bos2k1,151,11,1|-bos2k0,27,10,1|-bkgfs1,27,10,1|-bkgfs0,1,1,0|-bdm541,1,1,0|-bdm540,27,10,1|-b1qd41,27,10,1|-b1qd40,1,1,0|-att6g1,1,1,0|-att6g0,27,10,1|-aj0ag1,27,10,1|-aj0ag0,1,1,0|-aad6g1,1,1,0|-aad6g0,27,10,1|-a0n6g1,27,10,1|-a0n6g0,1,1,0|-9rn3s1,1,1,0|-9rn3s0,27,10,1|-9hx3s1,27,10,1|-9hx3s0,1,1,0|-98k2g1,1,1,0|-98k2g0,27,10,1|-8yu2g1,27,10,1|-8yu2g0,1,1,0|-8ptzs1,1,1,0|-8ptzs0,27,10,1|-8h6vs1,27,10,1|-8h6vs0,1,1,0|-87gvs1,1,1,0|-87gvs0,27,10,1|-7ygt41,27,10,1|-7ygt40,1,1,0|-7odug1,1,1,0|-7odug0,27,10,1|-7fqqg1,27,10,1|-7fqqg0,1,1,0|-75at41,1,1,0|-75at40,27,10,1|-6wnp41,27,10,1|-6wnp40,1,1,0|-6mxp41,1,1,0|-6mxp40,27,10,1|-6dxmg1,27,10,1|-6dxmg0,1,1,0|-63uns1,1,1,0|-63uns0,27,10,1|-5v7js1,27,10,1|-5v7js0,1,1,0|-5l4l41,1,1,0|-5l4l40,27,10,1|-5chh41,27,10,1|-5chh40,1,1,0|-52rh41,1,1,0|-52rh40,27,10,1|-4treg1,27,10,1|-4treg0,1,1,0|-4krbs1,1,1,0|-4krbs0,27,10,1|-49lh41,27,10,1|-49lh40,1,1,0|-421941,1,1,0|-421940,27,10,1|-3qveg1,27,10,1|-3qveg0,1,1,0|-3iy7s1,1,1,0|-3iy7s0,27,10,1|-385bs1,27,10,1|-385bs0,1,1,0|-30l3s1,1,1,0|-30l3s0,27,10,1|-2pf941,27,10,1|-2pf940,1,1,0|-2hv141,1,1,0|-2hv140,27,10,1|-26p6g1,27,10,1|-26p6g0,1,1,0|-1z4yg1,1,1,0|-1z4yg0,27,10,1|-1nz3s1,27,10,1|-1nz3s0,1,1,0|-1gevs1,1,1,0|-1gevs0,27,10,1|-14w2g1,27,10,1|-14w2g0,1,1,0|-z4ns1,1,1,0|-z4ns0,27,10,1|-m6841,27,10,1|-m6840,27,10,0|yd6vz,27,10,0|yd6w0,1,1,0|15kg7z,1,1,0|15kg80,27,10,1|1h39jz,27,10,1|1h39k0,1,1,0|1oaivz,1,1,0|1oaiw0,27,10,1|1ztc7z,27,10,1|1ztc80,1,1,0|270ljz,1,1,0|270lk0,27,10,1|2ijevz,27,10,1|2ijew0,1,1,0|2pqo7z,1,1,0|2pqo80,27,10,1|319hjz,27,10,1|319hk0,1,1,0|38tpjz,1,1,0|38tpk0,27,10,1|3jzk7z,27,10,1|3jzk80,1,1,0|3rjs7z,1,1,0|3rjs80,27,10,1|42pmvz,27,10,1|42pmw0,1,1,0|4a9uvz,1,1,0|4a9uw0,27,10,1|4lso7z,27,10,1|4lso80,1,1,0|4szxjz,1,1,0|4szxk0,27,10,1|54iqvz,27,10,1|54iqw0,1,1,0|5bq07z,1,1,0|5bq080,27,10,1|5n8tjz,27,10,1|5n8tk0,1,1,0|5v5xfz,1,1,0|5v5xg0,27,10,1|65ytfz,27,10,1|65ytg0,1,1,0|6dw03z,1,1,0|6dw040,27,10,1|6oow3z,27,10,1|6oow40,1,1,0|6wm2rz,1,1,0|6wm2s0,27,10,1|77eyrz,27,10,1|77eys0,1,1,0|7fc5fz,1,1,0|7fc5g0,27,10,1|7qi03z,27,10,1|7qi040,1,1,0|7yf6rz,1,1,0|7yf6s0,27,10,1|8982rz,27,10,1|8982s0,1,1,0|8h59fz,1,1,0|8h59g0,27,10,1|8ry5fz,27,10,1|8ry5g0,1,1,0|8zvc3z,1,1,0|8zvc40,27,10,1|9ao83z,27,10,1|9ao840,1,1,0|9ilerz,1,1,0|9iles0,27,10,1|9tearz,27,10,1|9teas0,1,1,0|a1bhfz,1,1,0|a1bhg0,27,10,1|achc3z,27,10,1|achc40,1,1,0|ak1k3z,1,1,0|ak1k40,27,10,1|av7erz,27,10,1|av7es0,1,1,0|b34lfz,1,1,0|b34lg0,27,10,1|bdxhfz,27,10,1|bdxhg0,1,1,0|bluo3z,1,1,0|bluo40,27,10,1|bwnk3z,27,10,1|bwnk40,1,1,0|c4kqrz,1,1,0|c4kqs0,27,10,1|cfdmrz,27,10,1|cfdms0,1,1,0|cnatfz,1,1,0|cnatg0,27,10,1|cy3pfz,27,10,1|cy3pg0,1,1,0|d60w3z,1,1,0|d60w40,27,10,1|dgts3z,27,10,1|dgts40,1,1,0|dp3xfz,1,1,0|dp3xg0,27,10,1|dzwtfz,27,10,1|dzwtg0,1,1,0|e7u03z,1,1,0|e7u040,27,10,1|eimw3z,27,10,1|eimw40,1,1,0|eqk2rz,1,1,0|eqk2s0,27,10,1|f1cyrz,27,10,1|f1cys0,1,1,0|f9a5fz,1,1,0|f9a5g0,27,10,1|fkg03z,27,10,1|fkg040,1,1,0|fs083z,1,1,0|fs0840,27,10,1|g362rz,27,10,1|g362s0,1,1,0|gaqarz,1,1,0|gaqas0,27,10,1|glw5fz,27,10,1|glw5g0,1,1,0|gttc3z,1,1,0|gttc40,27,10,1|h4m83z,27,10,1|h4m840,1,1,0|hcjerz,1,1,0|hcjes0,27,10,1|hncarz,27,10,1|hncas0,1,1,0|hv9hfz,1,1,0|hv9hg0,27,10,1|i6fc3z,27,10,1|i6fc40,1,1,0|idzk3z,1,1,0|idzk40,27,10,1|ip5erz,27,10,1|ip5es0,1,1,0|iwpmrz,1,1,0|iwpms0,27,10,1|j7vhfz,27,10,1|j7vhg0,1,1,0|jffpfz,1,1,0|jffpg0,27,10,1|jqlk3z,27,10,1|jqlk40,1,1,0|jyiqrz,1,1,0|jyiqs0,27,10,1|k9bmrz,27,10,1|k9bms0,1,1,0|kh8tfz,1,1,0|kh8tg0,27,10,1|ks1pfz,27,10,1|ks1pg0,1,1,0|kzyw3z,1,1,0|kzyw40,27,10,1|lb4qrz,27,10,1|lb4qs0,1,1,0|lioyrz,1,1,0|lioys0,27,10,1|ltutfz,27,10,1|ltutg0,1,1,0|m1f1fz,1,1,0|m1f1g0,27,10,1|mckw3z,27,10,1|mckw40,1,1,0|mki2rz,1,1,0|mki2s0,27,10,1|mvayrz,27,10,1|mvays0,1,1,0|n385fz,1,1,0|n385g0,27,10,1|ne11fz,27,10,1|ne11g0,1,1,0|nly83z,1,1,0|nly840,27,10,1|nwr43z,27,10,1|nwr440,1,1,0|o4oarz,1,1,0|o4oas0,27,10,1|ofu5fz,27,10,1|ofu5g0,1,1,0|onedfz,1,1,0|onedg0,27,10,1|oyk83z,27,10,1|oyk840,1,1,0|p64g3z,1,1,0|p64g40,27,10,1|phaarz,27,10,1|phaas0,1,1,0|pp7hfz,1,1,0|pp7hg0,27,10,1|q00dfz,27,10,1|q00dg0,1,1,0|q7xk3z,1,1,0|q7xk40,27,10,1|qiqg3z,27,10,1|qiqg40,1,1,0|qqnmrz,1,1,0|qqnms0,27,10,1|r1thfz,27,10,1|r1thg0,1,1,0|r9dpfz,1,1,0|r9dpg0,27,10,1|rkjk3z,27,10,1|rkjk40,1,1,0|rs3s3z,1,1,0|rs3s40,27,10,1|s39mrz,27,10,1|s39ms0,1,1,0|sb6tfz,1,1,0|sb6tg0,27,10,1|slzpfz,27,10,1|slzpg0,1,1,0|stww3z,1,1,0|stww40,27,10,1|t4ps3z,27,10,1|t4ps40,1,1,0|tcmyrz,1,1,0|tcmys0,27,10,1|tnfurz,27,10,1|tnfus0,1,1,0|tvd1fz,1,1,0|tvd1g0,27,10,1|u6iw3z,27,10,1|u6iw40,1,1,0|ue343z,1,1,0|ue3440,27,10,1|up8yrz,27,10,1|up8ys0,1,1,0|uwt6rz,1,1,0|uwt6s0,27,10,1|v7z1fz,27,10,1|v7z1g0,1,1,0|vfw83z,1,1,0|vfw840,27,10,1|vqp43z,27,10,1|vqp440,1,1,0|vymarz,1,1,0|vymas0,27,10,1|w9f6rz,27,10,1|w9f6s0,1,1,0|whcdfz,1,1,0|whcdg0,27,10,1|wsi83z,27,10,1|wsi840,1,1,0|x02g3z,1,1,0|x02g40,27,10,1|xb8arz,27,10,1|xb8as0,1,1,0|xisirz,1,1,0|xisis0,27,10,1|xtydfz,27,10,1|xtydg0,1,1,0|y1ilfz,1,1,0|y1ilg0,27,10,1|ycog3z,27,10,1|ycog40,1,1,0|yklmrz,1,1,0|yklms0,27,10,1|yveirz,27,10,1|yveis0,1,1,0|z3bpfz,1,1,0|z3bpg0,27,10,1|ze4lfz,27,10,1|ze4lg0,1,1,0\",\"Europe/Helsinki|,0,348,0|-1bss9yd,77,348,0|-peghye,77,348,0|-peghyd,15,11,0|-ehco81,15,11,0|-ehco80,16,6,1|-e7vxk1,16,6,1|-e7vxk0,15,11,0|5v5unz,15,11,0|5v5uo0,16,6,1|64ivzz,16,6,1|64iw00,15,11,0|6dvxbz,15,11,0|6dvxc0,16,6,1|6n8ynz,16,6,1|6n8yo0,15,11,0|6wm2rz,15,11,0|6wm2s0,16,6,1|75z43z,16,6,1|75z440,15,11,0|7fc5fz,15,11,0|7fc5g0,16,6,1|7p25fz,16,6,1|7p25g0,15,11,0|7yf6rz,15,11,0|7yf6s0,16,6,1|87s83z,16,6,1|87s840,15,11,0|8h59fz,15,11,0|8h59g0,16,6,1|8qiarz,16,6,1|8qias0,15,11,0|8zvc3z,15,11,0|8zvc40,16,6,1|998dfz,16,6,1|998dg0,15,11,0|9ilerz,15,11,0|9iles0,16,6,1|9ryg3z,16,6,1|9ryg40,15,11,0|a1bhfz,15,11,0|a1bhg0,16,6,1|aaoirz,16,6,1|aaois0,15,11,0|ak1k3z,15,11,0|ak1k40,16,6,1|atrk3z,16,6,1|atrk40,15,11,0|b34lfz,15,11,0|b34lg0,16,6,1|bchmrz,16,6,1|bchms0,15,11,0|bluo3z,15,11,0|bluo40,16,6,1|bv7pfz,16,6,1|bv7pg0,15,11,0|c4kqrz,15,11,0|c4kqs0,16,6,1|cdxs3z,16,6,1|cdxs40,15,11,0|cnatfz,15,11,0|cnatg0,16,6,1|cwnurz,16,6,1|cwnus0,15,11,0|d60w3z,15,11,0|d60w40,16,6,1|dfdxfz,16,6,1|dfdxg0,15,11,0|dp3xfz,15,11,0|dp3xg0,16,6,1|dzwtfz,16,6,1|dzwtg0,15,11,0|e7u03z,15,11,0|e7u040,16,6,1|eimw3z,16,6,1|eimw40,15,11,0|eqk2rz,15,11,0|eqk2s0,16,6,1|f1cyrz,16,6,1|f1cys0,15,11,0|f9a5fz,15,11,0|f9a5g0,16,6,1|fkg03z,16,6,1|fkg040,15,11,0|fs083z,15,11,0|fs0840,16,6,1|g362rz,16,6,1|g362s0,15,11,0|gaqarz,15,11,0|gaqas0,16,6,1|glw5fz,16,6,1|glw5g0,15,11,0|gttc3z,15,11,0|gttc40,16,6,1|h4m83z,16,6,1|h4m840,15,11,0|hcjerz,15,11,0|hcjes0,16,6,1|hncarz,16,6,1|hncas0,15,11,0|hv9hfz,15,11,0|hv9hg0,16,6,1|i6fc3z,16,6,1|i6fc40,15,11,0|idzk3z,15,11,0|idzk40,16,6,1|ip5erz,16,6,1|ip5es0,15,11,0|iwpmrz,15,11,0|iwpms0,16,6,1|j7vhfz,16,6,1|j7vhg0,15,11,0|jffpfz,15,11,0|jffpg0,16,6,1|jqlk3z,16,6,1|jqlk40,15,11,0|jyiqrz,15,11,0|jyiqs0,16,6,1|k9bmrz,16,6,1|k9bms0,15,11,0|kh8tfz,15,11,0|kh8tg0,16,6,1|ks1pfz,16,6,1|ks1pg0,15,11,0|kzyw3z,15,11,0|kzyw40,16,6,1|lb4qrz,16,6,1|lb4qs0,15,11,0|lioyrz,15,11,0|lioys0,16,6,1|ltutfz,16,6,1|ltutg0,15,11,0|m1f1fz,15,11,0|m1f1g0,16,6,1|mckw3z,16,6,1|mckw40,15,11,0|mki2rz,15,11,0|mki2s0,16,6,1|mvayrz,16,6,1|mvays0,15,11,0|n385fz,15,11,0|n385g0,16,6,1|ne11fz,16,6,1|ne11g0,15,11,0|nly83z,15,11,0|nly840,16,6,1|nwr43z,16,6,1|nwr440,15,11,0|o4oarz,15,11,0|o4oas0,16,6,1|ofu5fz,16,6,1|ofu5g0,15,11,0|onedfz,15,11,0|onedg0,16,6,1|oyk83z,16,6,1|oyk840,15,11,0|p64g3z,15,11,0|p64g40,16,6,1|phaarz,16,6,1|phaas0,15,11,0|pp7hfz,15,11,0|pp7hg0,16,6,1|q00dfz,16,6,1|q00dg0,15,11,0|q7xk3z,15,11,0|q7xk40,16,6,1|qiqg3z,16,6,1|qiqg40,15,11,0|qqnmrz,15,11,0|qqnms0,16,6,1|r1thfz,16,6,1|r1thg0,15,11,0|r9dpfz,15,11,0|r9dpg0,16,6,1|rkjk3z,16,6,1|rkjk40,15,11,0|rs3s3z,15,11,0|rs3s40,16,6,1|s39mrz,16,6,1|s39ms0,15,11,0|sb6tfz,15,11,0|sb6tg0,16,6,1|slzpfz,16,6,1|slzpg0,15,11,0|stww3z,15,11,0|stww40,16,6,1|t4ps3z,16,6,1|t4ps40,15,11,0|tcmyrz,15,11,0|tcmys0,16,6,1|tnfurz,16,6,1|tnfus0,15,11,0|tvd1fz,15,11,0|tvd1g0,16,6,1|u6iw3z,16,6,1|u6iw40,15,11,0|ue343z,15,11,0|ue3440,16,6,1|up8yrz,16,6,1|up8ys0,15,11,0|uwt6rz,15,11,0|uwt6s0,16,6,1|v7z1fz,16,6,1|v7z1g0,15,11,0|vfw83z,15,11,0|vfw840,16,6,1|vqp43z,16,6,1|vqp440,15,11,0|vymarz,15,11,0|vymas0,16,6,1|w9f6rz,16,6,1|w9f6s0,15,11,0|whcdfz,15,11,0|whcdg0,16,6,1|wsi83z,16,6,1|wsi840,15,11,0|x02g3z,15,11,0|x02g40,16,6,1|xb8arz,16,6,1|xb8as0,15,11,0|xisirz,15,11,0|xisis0,16,6,1|xtydfz,16,6,1|xtydg0,15,11,0|y1ilfz,15,11,0|y1ilg0,16,6,1|ycog3z,16,6,1|ycog40,15,11,0|yklmrz,15,11,0|yklms0,16,6,1|yveirz,16,6,1|yveis0,15,11,0|z3bpfz,15,11,0|z3bpg0,16,6,1|ze4lfz,16,6,1|ze4lg0,15,11,0\",\"Europe/Isle_of_Man|,0,347,0|-1rprx9x,1,1,0|-rzcns1,1,1,0|-rzcns0,27,10,1|-rsid41,27,10,1|-rsid40,1,1,0|-risd41,1,1,0|-risd40,27,10,1|-ragd41,27,10,1|-ragd40,1,1,0|-r0s7s1,1,1,0|-r0s7s0,27,10,1|-qr0d41,27,10,1|-qr0d40,1,1,0|-qhp6g1,1,1,0|-qhp6g0,27,10,1|-q8aag1,27,10,1|-q8aag0,1,1,0|-pyz3s1,1,1,0|-pyz3s0,27,10,1|-po4d41,27,10,1|-po4d40,1,1,0|-pfw2g1,1,1,0|-pfw2g0,27,10,1|-p6h6g1,27,10,1|-p6h6g0,1,1,0|-oxiyg1,1,1,0|-oxiyg0,27,10,1|-onfzs1,27,10,1|-onfzs0,1,1,0|-odd141,1,1,0|-odd140,27,10,1|-o5st41,27,10,1|-o5st40,1,1,0|-nuzx41,1,1,0|-nuzx40,27,10,1|-nmprs1,27,10,1|-nmprs0,1,1,0|-nbwvs1,1,1,0|-nbwvs0,27,10,1|-n39rs1,27,10,1|-n39rs0,1,1,0|-mt6t41,1,1,0|-mt6t40,27,10,1|-mkjp41,27,10,1|-mkjp40,1,1,0|-matp41,1,1,0|-matp40,27,10,1|-m1tmg1,27,10,1|-m1tmg0,1,1,0|-lrdp41,1,1,0|-lrdp40,27,10,1|-liql41,27,10,1|-liql40,1,1,0|-l8nmg1,1,1,0|-l8nmg0,27,10,1|-l00ig1,27,10,1|-l00ig0,1,1,0|-kqaig1,1,1,0|-kqaig0,27,10,1|-khafs1,27,10,1|-khafs0,1,1,0|-k77h41,1,1,0|-k77h40,27,10,1|-jykd41,27,10,1|-jykd40,1,1,0|-joheg1,1,1,0|-joheg0,27,10,1|-jfuag1,27,10,1|-jfuag0,1,1,0|-j64ag1,1,1,0|-j64ag0,27,10,1|-iwr941,27,10,1|-iwr940,1,1,0|-imoag1,1,1,0|-imoag0,27,10,1|-ie16g1,27,10,1|-ie16g0,1,1,0|-i4b6g1,1,1,0|-i4b6g0,27,10,1|-hvb3s1,27,10,1|-hvb3s0,1,1,0|-hl8541,1,1,0|-hl8540,27,10,1|-hcl141,27,10,1|-hcl140,1,1,0|-h2i2g1,1,1,0|-h2i2g0,27,10,1|-gtuyg1,27,10,1|-gtuyg0,1,1,0|-gk4yg1,1,1,0|-gk4yg0,27,10,1|-gb4vs1,27,10,1|-gb4vs0,1,1,0|-g11x41,1,1,0|-g11x40,27,10,1|-fpw2g1,27,10,1|-fpw2g0,1,1,0|-fkul41,1,1,0|-fkul40,27,10,1|-eyiyk1,27,10,1|-eyiyk0,151,11,1|-ethh81,151,11,1|-ethh80,27,10,1|-eh8qk1,27,10,1|-eh8qk0,151,11,1|-earek1,151,11,1|-earek0,27,10,1|-dyinw1,27,10,1|-dyinw0,151,11,1|-drod81,151,11,1|-drod80,27,10,1|-dfsl81,27,10,1|-dfsl80,151,11,1|-d75h81,151,11,1|-d75h80,27,10,1|-cx0nw1,27,10,1|-cx0nw0,151,11,1|-cro2k1,151,11,1|-cro2k0,27,10,1|-cncfs1,27,10,1|-cncfs0,1,1,0|-cdmfs1,1,1,0|-cdmfs0,27,10,1|-c4md41,27,10,1|-c4md40,1,1,0|-bwc7s1,1,1,0|-bwc7s0,27,10,1|-buwfw1,27,10,1|-buwfw0,151,11,1|-bos2k1,151,11,1|-bos2k0,27,10,1|-bkgfs1,27,10,1|-bkgfs0,1,1,0|-bdm541,1,1,0|-bdm540,27,10,1|-b1qd41,27,10,1|-b1qd40,1,1,0|-att6g1,1,1,0|-att6g0,27,10,1|-aj0ag1,27,10,1|-aj0ag0,1,1,0|-aad6g1,1,1,0|-aad6g0,27,10,1|-a0n6g1,27,10,1|-a0n6g0,1,1,0|-9rn3s1,1,1,0|-9rn3s0,27,10,1|-9hx3s1,27,10,1|-9hx3s0,1,1,0|-98k2g1,1,1,0|-98k2g0,27,10,1|-8yu2g1,27,10,1|-8yu2g0,1,1,0|-8ptzs1,1,1,0|-8ptzs0,27,10,1|-8h6vs1,27,10,1|-8h6vs0,1,1,0|-87gvs1,1,1,0|-87gvs0,27,10,1|-7ygt41,27,10,1|-7ygt40,1,1,0|-7odug1,1,1,0|-7odug0,27,10,1|-7fqqg1,27,10,1|-7fqqg0,1,1,0|-75at41,1,1,0|-75at40,27,10,1|-6wnp41,27,10,1|-6wnp40,1,1,0|-6mxp41,1,1,0|-6mxp40,27,10,1|-6dxmg1,27,10,1|-6dxmg0,1,1,0|-63uns1,1,1,0|-63uns0,27,10,1|-5v7js1,27,10,1|-5v7js0,1,1,0|-5l4l41,1,1,0|-5l4l40,27,10,1|-5chh41,27,10,1|-5chh40,1,1,0|-52rh41,1,1,0|-52rh40,27,10,1|-4treg1,27,10,1|-4treg0,1,1,0|-4krbs1,1,1,0|-4krbs0,27,10,1|-49lh41,27,10,1|-49lh40,1,1,0|-421941,1,1,0|-421940,27,10,1|-3qveg1,27,10,1|-3qveg0,1,1,0|-3iy7s1,1,1,0|-3iy7s0,27,10,1|-385bs1,27,10,1|-385bs0,1,1,0|-30l3s1,1,1,0|-30l3s0,27,10,1|-2pf941,27,10,1|-2pf940,1,1,0|-2hv141,1,1,0|-2hv140,27,10,1|-26p6g1,27,10,1|-26p6g0,1,1,0|-1z4yg1,1,1,0|-1z4yg0,27,10,1|-1nz3s1,27,10,1|-1nz3s0,1,1,0|-1gevs1,1,1,0|-1gevs0,27,10,1|-14w2g1,27,10,1|-14w2g0,1,1,0|-z4ns1,1,1,0|-z4ns0,27,10,1|-m6841,27,10,1|-m6840,27,10,0|yd6vz,27,10,0|yd6w0,1,1,0|15kg7z,1,1,0|15kg80,27,10,1|1h39jz,27,10,1|1h39k0,1,1,0|1oaivz,1,1,0|1oaiw0,27,10,1|1ztc7z,27,10,1|1ztc80,1,1,0|270ljz,1,1,0|270lk0,27,10,1|2ijevz,27,10,1|2ijew0,1,1,0|2pqo7z,1,1,0|2pqo80,27,10,1|319hjz,27,10,1|319hk0,1,1,0|38tpjz,1,1,0|38tpk0,27,10,1|3jzk7z,27,10,1|3jzk80,1,1,0|3rjs7z,1,1,0|3rjs80,27,10,1|42pmvz,27,10,1|42pmw0,1,1,0|4a9uvz,1,1,0|4a9uw0,27,10,1|4lso7z,27,10,1|4lso80,1,1,0|4szxjz,1,1,0|4szxk0,27,10,1|54iqvz,27,10,1|54iqw0,1,1,0|5bq07z,1,1,0|5bq080,27,10,1|5n8tjz,27,10,1|5n8tk0,1,1,0|5v5xfz,1,1,0|5v5xg0,27,10,1|65ytfz,27,10,1|65ytg0,1,1,0|6dw03z,1,1,0|6dw040,27,10,1|6oow3z,27,10,1|6oow40,1,1,0|6wm2rz,1,1,0|6wm2s0,27,10,1|77eyrz,27,10,1|77eys0,1,1,0|7fc5fz,1,1,0|7fc5g0,27,10,1|7qi03z,27,10,1|7qi040,1,1,0|7yf6rz,1,1,0|7yf6s0,27,10,1|8982rz,27,10,1|8982s0,1,1,0|8h59fz,1,1,0|8h59g0,27,10,1|8ry5fz,27,10,1|8ry5g0,1,1,0|8zvc3z,1,1,0|8zvc40,27,10,1|9ao83z,27,10,1|9ao840,1,1,0|9ilerz,1,1,0|9iles0,27,10,1|9tearz,27,10,1|9teas0,1,1,0|a1bhfz,1,1,0|a1bhg0,27,10,1|achc3z,27,10,1|achc40,1,1,0|ak1k3z,1,1,0|ak1k40,27,10,1|av7erz,27,10,1|av7es0,1,1,0|b34lfz,1,1,0|b34lg0,27,10,1|bdxhfz,27,10,1|bdxhg0,1,1,0|bluo3z,1,1,0|bluo40,27,10,1|bwnk3z,27,10,1|bwnk40,1,1,0|c4kqrz,1,1,0|c4kqs0,27,10,1|cfdmrz,27,10,1|cfdms0,1,1,0|cnatfz,1,1,0|cnatg0,27,10,1|cy3pfz,27,10,1|cy3pg0,1,1,0|d60w3z,1,1,0|d60w40,27,10,1|dgts3z,27,10,1|dgts40,1,1,0|dp3xfz,1,1,0|dp3xg0,27,10,1|dzwtfz,27,10,1|dzwtg0,1,1,0|e7u03z,1,1,0|e7u040,27,10,1|eimw3z,27,10,1|eimw40,1,1,0|eqk2rz,1,1,0|eqk2s0,27,10,1|f1cyrz,27,10,1|f1cys0,1,1,0|f9a5fz,1,1,0|f9a5g0,27,10,1|fkg03z,27,10,1|fkg040,1,1,0|fs083z,1,1,0|fs0840,27,10,1|g362rz,27,10,1|g362s0,1,1,0|gaqarz,1,1,0|gaqas0,27,10,1|glw5fz,27,10,1|glw5g0,1,1,0|gttc3z,1,1,0|gttc40,27,10,1|h4m83z,27,10,1|h4m840,1,1,0|hcjerz,1,1,0|hcjes0,27,10,1|hncarz,27,10,1|hncas0,1,1,0|hv9hfz,1,1,0|hv9hg0,27,10,1|i6fc3z,27,10,1|i6fc40,1,1,0|idzk3z,1,1,0|idzk40,27,10,1|ip5erz,27,10,1|ip5es0,1,1,0|iwpmrz,1,1,0|iwpms0,27,10,1|j7vhfz,27,10,1|j7vhg0,1,1,0|jffpfz,1,1,0|jffpg0,27,10,1|jqlk3z,27,10,1|jqlk40,1,1,0|jyiqrz,1,1,0|jyiqs0,27,10,1|k9bmrz,27,10,1|k9bms0,1,1,0|kh8tfz,1,1,0|kh8tg0,27,10,1|ks1pfz,27,10,1|ks1pg0,1,1,0|kzyw3z,1,1,0|kzyw40,27,10,1|lb4qrz,27,10,1|lb4qs0,1,1,0|lioyrz,1,1,0|lioys0,27,10,1|ltutfz,27,10,1|ltutg0,1,1,0|m1f1fz,1,1,0|m1f1g0,27,10,1|mckw3z,27,10,1|mckw40,1,1,0|mki2rz,1,1,0|mki2s0,27,10,1|mvayrz,27,10,1|mvays0,1,1,0|n385fz,1,1,0|n385g0,27,10,1|ne11fz,27,10,1|ne11g0,1,1,0|nly83z,1,1,0|nly840,27,10,1|nwr43z,27,10,1|nwr440,1,1,0|o4oarz,1,1,0|o4oas0,27,10,1|ofu5fz,27,10,1|ofu5g0,1,1,0|onedfz,1,1,0|onedg0,27,10,1|oyk83z,27,10,1|oyk840,1,1,0|p64g3z,1,1,0|p64g40,27,10,1|phaarz,27,10,1|phaas0,1,1,0|pp7hfz,1,1,0|pp7hg0,27,10,1|q00dfz,27,10,1|q00dg0,1,1,0|q7xk3z,1,1,0|q7xk40,27,10,1|qiqg3z,27,10,1|qiqg40,1,1,0|qqnmrz,1,1,0|qqnms0,27,10,1|r1thfz,27,10,1|r1thg0,1,1,0|r9dpfz,1,1,0|r9dpg0,27,10,1|rkjk3z,27,10,1|rkjk40,1,1,0|rs3s3z,1,1,0|rs3s40,27,10,1|s39mrz,27,10,1|s39ms0,1,1,0|sb6tfz,1,1,0|sb6tg0,27,10,1|slzpfz,27,10,1|slzpg0,1,1,0|stww3z,1,1,0|stww40,27,10,1|t4ps3z,27,10,1|t4ps40,1,1,0|tcmyrz,1,1,0|tcmys0,27,10,1|tnfurz,27,10,1|tnfus0,1,1,0|tvd1fz,1,1,0|tvd1g0,27,10,1|u6iw3z,27,10,1|u6iw40,1,1,0|ue343z,1,1,0|ue3440,27,10,1|up8yrz,27,10,1|up8ys0,1,1,0|uwt6rz,1,1,0|uwt6s0,27,10,1|v7z1fz,27,10,1|v7z1g0,1,1,0|vfw83z,1,1,0|vfw840,27,10,1|vqp43z,27,10,1|vqp440,1,1,0|vymarz,1,1,0|vymas0,27,10,1|w9f6rz,27,10,1|w9f6s0,1,1,0|whcdfz,1,1,0|whcdg0,27,10,1|wsi83z,27,10,1|wsi840,1,1,0|x02g3z,1,1,0|x02g40,27,10,1|xb8arz,27,10,1|xb8as0,1,1,0|xisirz,1,1,0|xisis0,27,10,1|xtydfz,27,10,1|xtydg0,1,1,0|y1ilfz,1,1,0|y1ilg0,27,10,1|ycog3z,27,10,1|ycog40,1,1,0|yklmrz,1,1,0|yklms0,27,10,1|yveirz,27,10,1|yveis0,1,1,0|z3bpfz,1,1,0|z3bpg0,27,10,1|ze4lfz,27,10,1|ze4lg0,1,1,0\",\"Europe/Istanbul|,0,349,0|-1ayy814,117,350,0|-ux9xex,117,350,0|-ux9xew,15,11,0|-s0e081,15,11,0|-s0e080,16,6,1|-rsir01,16,6,1|-rsir00,15,11,0|-pyzew1,15,11,0|-pyzew0,16,6,1|-po4r01,16,6,1|-po4r00,15,11,0|-pfwdk1,15,11,0|-pfwdk0,16,6,1|-p6hkc1,16,6,1|-p6hkc0,15,11,0|-oxj9k1,15,11,0|-oxj9k0,16,6,1|-ongdo1,16,6,1|-ongdo0,15,11,0|-ntgo81,15,11,0|-ntgo80,16,6,1|-nm7n01,16,6,1|-nm7n00,15,11,0|-nbayw1,15,11,0|-nbayw0,16,6,1|-n3fpo1,16,6,1|-n3fpo0,15,11,0|-febpk1,15,11,0|-febpk0,16,6,1|-f9c5o1,16,6,1|-f9c5o0,15,11,0|-f6gdk1,15,11,0|-f6gdk0,16,6,1|-erc0c1,16,6,1|-erc0c0,15,11,0|-ehgdk1,15,11,0|-ehgdk0,16,6,1|-cnaz01,16,6,1|-cnaz00,15,11,0|-cb5uw1,15,11,0|-cb5uw0,16,6,1|-c4w0c1,16,6,1|-c4w0c0,15,11,0|-bujpk1,15,11,0|-bujpk0,16,6,1|-blwoc1,16,6,1|-blwoc0,15,11,0|-bbtmw1,15,11,0|-bbtmw0,16,6,1|-b36lo1,16,6,1|-b36lo0,15,11,0|-atgiw1,15,11,0|-atgiw0,16,6,1|-akgj01,16,6,1|-akgj00,15,11,0|-aadhk1,15,11,0|-aadhk0,16,6,1|-a1dho1,16,6,1|-a1dho0,15,11,0|-9rag81,15,11,0|-9rag80,16,6,1|-9inf01,16,6,1|-9inf00,15,11,0|-3wa5k1,15,11,0|-3wa5k0,16,6,1|-3805o1,16,6,1|-3805o0,15,11,0|-2xtew1,15,11,0|-2xtew0,16,6,1|-2qo301,16,6,1|-2qo300,15,11,0|1s8vvz,15,11,0|1s8vw0,16,6,1|2062jz,16,6,1|2062k0,15,11,0|27qdbz,15,11,0|27qdc0,16,6,1|2iw57z,16,6,1|2iw580,15,11,0|2q1mnz,15,11,0|2q1mo0,16,6,1|31m7vz,16,6,1|31m7w0,15,11,0|38tjzz,15,11,0|38tk00,16,6,1|3kcajz,16,6,1|3kcak0,15,11,0|3s9jzz,15,11,0|3s9k00,16,6,1|42cfvz,16,6,1|42cfw0,15,11,0|4azmnz,15,11,0|4azmo0,16,6,1|4ficzz,16,6,1|4fid00,100,6,0|73397z,100,6,0|733980,105,209,1|76bufz,105,209,1|76bug0,100,6,0|7qp97z,100,6,0|7qp980,15,11,0|7zg2jz,15,11,0|7zg2k0,16,6,1|87q7vz,16,6,1|87q7w0,15,11,0|8h53vz,15,11,0|8h53w0,16,6,1|8qi57z,16,6,1|8qi580,15,11,0|8zv6jz,15,11,0|8zv6k0,16,6,1|9987vz,16,6,1|9987w0,15,11,0|9il97z,15,11,0|9il980,16,6,1|9ryajz,16,6,1|9ryak0,15,11,0|a1bbvz,15,11,0|a1bbw0,16,6,1|aaod7z,16,6,1|aaod80,15,11,0|ak1ejz,15,11,0|ak1ek0,16,6,1|atrejz,16,6,1|atrek0,15,11,0|b34fvz,15,11,0|b34fw0,16,6,1|bchh7z,16,6,1|bchh80,15,11,0|bluijz,15,11,0|bluik0,16,6,1|bv7jvz,16,6,1|bv7jw0,15,11,0|c4kl7z,15,11,0|c4kl80,16,6,1|cdxmjz,16,6,1|cdxmk0,15,11,0|cmxp7z,15,11,0|cmxp80,16,6,1|cwnp7z,16,6,1|cwnp80,15,11,0|d60qjz,15,11,0|d60qk0,16,6,1|dfdrvz,16,6,1|dfdrw0,15,11,0|dp3rvz,15,11,0|dp3rw0,16,6,1|dzwnvz,16,6,1|dzwnw0,15,11,0|e7tujz,15,11,0|e7tuk0,16,6,1|eimqjz,16,6,1|eimqk0,15,11,0|eqjx7z,15,11,0|eqjx80,16,6,1|f1ct7z,16,6,1|f1ct80,15,11,0|f99zvz,15,11,0|f99zw0,16,6,1|fkfujz,16,6,1|fkfuk0,15,11,0|fs02jz,15,11,0|fs02k0,16,6,1|g35x7z,16,6,1|g35x80,15,11,0|gaq57z,15,11,0|gaq580,16,6,1|glvzvz,16,6,1|glvzw0,15,11,0|gtt6jz,15,11,0|gtt6k0,16,6,1|h4m2jz,16,6,1|h4m2k0,15,11,0|hcj97z,15,11,0|hcj980,16,6,1|hnc57z,16,6,1|hnc580,15,11,0|hv9bvz,15,11,0|hv9bw0,16,6,1|i6f6jz,16,6,1|i6f6k0,15,11,0|idzejz,15,11,0|idzek0,16,6,1|ip597z,16,6,1|ip5980,15,11,0|iwph7z,15,11,0|iwph80,16,6,1|j7vbvz,16,6,1|j7vbw0,15,11,0|jffpfz,15,11,0|jffpg0,16,6,1|jqlk3z,16,6,1|jqlk40,15,11,0|jyiqrz,15,11,0|jyiqs0,16,6,1|k9bmrz,16,6,1|k9bms0,15,11,0|kh8tfz,15,11,0|kh8tg0,16,6,1|ks1pfz,16,6,1|ks1pg0,15,11,0|kzyw3z,15,11,0|kzyw40,16,6,1|lb4qrz,16,6,1|lb4qs0,15,11,0|liqtfz,15,11,0|liqtg0,16,6,1|ltutfz,16,6,1|ltutg0,15,11,0|m1f1fz,15,11,0|m1f1g0,16,6,1|mckw3z,16,6,1|mckw40,15,11,0|mki2rz,15,11,0|mki2s0,16,6,1|mvayrz,16,6,1|mvays0,15,11,0|n3a03z,15,11,0|n3a040,16,6,1|ne11fz,16,6,1|ne11g0,15,11,0|nly83z,15,11,0|nly840,16,6,1|nxh1fz,16,6,1|nxh1g0,15,11,0|o4oarz,15,11,0|o4oas0,16,6,1|od3ozz,16,6,1|od3p00,100,6,0\",\"Europe/Jersey|,0,347,0|-1rprx9x,1,1,0|-rzcns1,1,1,0|-rzcns0,27,10,1|-rsid41,27,10,1|-rsid40,1,1,0|-risd41,1,1,0|-risd40,27,10,1|-ragd41,27,10,1|-ragd40,1,1,0|-r0s7s1,1,1,0|-r0s7s0,27,10,1|-qr0d41,27,10,1|-qr0d40,1,1,0|-qhp6g1,1,1,0|-qhp6g0,27,10,1|-q8aag1,27,10,1|-q8aag0,1,1,0|-pyz3s1,1,1,0|-pyz3s0,27,10,1|-po4d41,27,10,1|-po4d40,1,1,0|-pfw2g1,1,1,0|-pfw2g0,27,10,1|-p6h6g1,27,10,1|-p6h6g0,1,1,0|-oxiyg1,1,1,0|-oxiyg0,27,10,1|-onfzs1,27,10,1|-onfzs0,1,1,0|-odd141,1,1,0|-odd140,27,10,1|-o5st41,27,10,1|-o5st40,1,1,0|-nuzx41,1,1,0|-nuzx40,27,10,1|-nmprs1,27,10,1|-nmprs0,1,1,0|-nbwvs1,1,1,0|-nbwvs0,27,10,1|-n39rs1,27,10,1|-n39rs0,1,1,0|-mt6t41,1,1,0|-mt6t40,27,10,1|-mkjp41,27,10,1|-mkjp40,1,1,0|-matp41,1,1,0|-matp40,27,10,1|-m1tmg1,27,10,1|-m1tmg0,1,1,0|-lrdp41,1,1,0|-lrdp40,27,10,1|-liql41,27,10,1|-liql40,1,1,0|-l8nmg1,1,1,0|-l8nmg0,27,10,1|-l00ig1,27,10,1|-l00ig0,1,1,0|-kqaig1,1,1,0|-kqaig0,27,10,1|-khafs1,27,10,1|-khafs0,1,1,0|-k77h41,1,1,0|-k77h40,27,10,1|-jykd41,27,10,1|-jykd40,1,1,0|-joheg1,1,1,0|-joheg0,27,10,1|-jfuag1,27,10,1|-jfuag0,1,1,0|-j64ag1,1,1,0|-j64ag0,27,10,1|-iwr941,27,10,1|-iwr940,1,1,0|-imoag1,1,1,0|-imoag0,27,10,1|-ie16g1,27,10,1|-ie16g0,1,1,0|-i4b6g1,1,1,0|-i4b6g0,27,10,1|-hvb3s1,27,10,1|-hvb3s0,1,1,0|-hl8541,1,1,0|-hl8540,27,10,1|-hcl141,27,10,1|-hcl140,1,1,0|-h2i2g1,1,1,0|-h2i2g0,27,10,1|-gtuyg1,27,10,1|-gtuyg0,1,1,0|-gk4yg1,1,1,0|-gk4yg0,27,10,1|-gb4vs1,27,10,1|-gb4vs0,1,1,0|-g11x41,1,1,0|-g11x40,27,10,1|-fpw2g1,27,10,1|-fpw2g0,1,1,0|-fkul41,1,1,0|-fkul40,27,10,1|-eyiyk1,27,10,1|-eyiyk0,151,11,1|-ethh81,151,11,1|-ethh80,27,10,1|-eh8qk1,27,10,1|-eh8qk0,151,11,1|-earek1,151,11,1|-earek0,27,10,1|-dyinw1,27,10,1|-dyinw0,151,11,1|-drod81,151,11,1|-drod80,27,10,1|-dfsl81,27,10,1|-dfsl80,151,11,1|-d75h81,151,11,1|-d75h80,27,10,1|-cx0nw1,27,10,1|-cx0nw0,151,11,1|-cro2k1,151,11,1|-cro2k0,27,10,1|-cncfs1,27,10,1|-cncfs0,1,1,0|-cdmfs1,1,1,0|-cdmfs0,27,10,1|-c4md41,27,10,1|-c4md40,1,1,0|-bwc7s1,1,1,0|-bwc7s0,27,10,1|-buwfw1,27,10,1|-buwfw0,151,11,1|-bos2k1,151,11,1|-bos2k0,27,10,1|-bkgfs1,27,10,1|-bkgfs0,1,1,0|-bdm541,1,1,0|-bdm540,27,10,1|-b1qd41,27,10,1|-b1qd40,1,1,0|-att6g1,1,1,0|-att6g0,27,10,1|-aj0ag1,27,10,1|-aj0ag0,1,1,0|-aad6g1,1,1,0|-aad6g0,27,10,1|-a0n6g1,27,10,1|-a0n6g0,1,1,0|-9rn3s1,1,1,0|-9rn3s0,27,10,1|-9hx3s1,27,10,1|-9hx3s0,1,1,0|-98k2g1,1,1,0|-98k2g0,27,10,1|-8yu2g1,27,10,1|-8yu2g0,1,1,0|-8ptzs1,1,1,0|-8ptzs0,27,10,1|-8h6vs1,27,10,1|-8h6vs0,1,1,0|-87gvs1,1,1,0|-87gvs0,27,10,1|-7ygt41,27,10,1|-7ygt40,1,1,0|-7odug1,1,1,0|-7odug0,27,10,1|-7fqqg1,27,10,1|-7fqqg0,1,1,0|-75at41,1,1,0|-75at40,27,10,1|-6wnp41,27,10,1|-6wnp40,1,1,0|-6mxp41,1,1,0|-6mxp40,27,10,1|-6dxmg1,27,10,1|-6dxmg0,1,1,0|-63uns1,1,1,0|-63uns0,27,10,1|-5v7js1,27,10,1|-5v7js0,1,1,0|-5l4l41,1,1,0|-5l4l40,27,10,1|-5chh41,27,10,1|-5chh40,1,1,0|-52rh41,1,1,0|-52rh40,27,10,1|-4treg1,27,10,1|-4treg0,1,1,0|-4krbs1,1,1,0|-4krbs0,27,10,1|-49lh41,27,10,1|-49lh40,1,1,0|-421941,1,1,0|-421940,27,10,1|-3qveg1,27,10,1|-3qveg0,1,1,0|-3iy7s1,1,1,0|-3iy7s0,27,10,1|-385bs1,27,10,1|-385bs0,1,1,0|-30l3s1,1,1,0|-30l3s0,27,10,1|-2pf941,27,10,1|-2pf940,1,1,0|-2hv141,1,1,0|-2hv140,27,10,1|-26p6g1,27,10,1|-26p6g0,1,1,0|-1z4yg1,1,1,0|-1z4yg0,27,10,1|-1nz3s1,27,10,1|-1nz3s0,1,1,0|-1gevs1,1,1,0|-1gevs0,27,10,1|-14w2g1,27,10,1|-14w2g0,1,1,0|-z4ns1,1,1,0|-z4ns0,27,10,1|-m6841,27,10,1|-m6840,27,10,0|yd6vz,27,10,0|yd6w0,1,1,0|15kg7z,1,1,0|15kg80,27,10,1|1h39jz,27,10,1|1h39k0,1,1,0|1oaivz,1,1,0|1oaiw0,27,10,1|1ztc7z,27,10,1|1ztc80,1,1,0|270ljz,1,1,0|270lk0,27,10,1|2ijevz,27,10,1|2ijew0,1,1,0|2pqo7z,1,1,0|2pqo80,27,10,1|319hjz,27,10,1|319hk0,1,1,0|38tpjz,1,1,0|38tpk0,27,10,1|3jzk7z,27,10,1|3jzk80,1,1,0|3rjs7z,1,1,0|3rjs80,27,10,1|42pmvz,27,10,1|42pmw0,1,1,0|4a9uvz,1,1,0|4a9uw0,27,10,1|4lso7z,27,10,1|4lso80,1,1,0|4szxjz,1,1,0|4szxk0,27,10,1|54iqvz,27,10,1|54iqw0,1,1,0|5bq07z,1,1,0|5bq080,27,10,1|5n8tjz,27,10,1|5n8tk0,1,1,0|5v5xfz,1,1,0|5v5xg0,27,10,1|65ytfz,27,10,1|65ytg0,1,1,0|6dw03z,1,1,0|6dw040,27,10,1|6oow3z,27,10,1|6oow40,1,1,0|6wm2rz,1,1,0|6wm2s0,27,10,1|77eyrz,27,10,1|77eys0,1,1,0|7fc5fz,1,1,0|7fc5g0,27,10,1|7qi03z,27,10,1|7qi040,1,1,0|7yf6rz,1,1,0|7yf6s0,27,10,1|8982rz,27,10,1|8982s0,1,1,0|8h59fz,1,1,0|8h59g0,27,10,1|8ry5fz,27,10,1|8ry5g0,1,1,0|8zvc3z,1,1,0|8zvc40,27,10,1|9ao83z,27,10,1|9ao840,1,1,0|9ilerz,1,1,0|9iles0,27,10,1|9tearz,27,10,1|9teas0,1,1,0|a1bhfz,1,1,0|a1bhg0,27,10,1|achc3z,27,10,1|achc40,1,1,0|ak1k3z,1,1,0|ak1k40,27,10,1|av7erz,27,10,1|av7es0,1,1,0|b34lfz,1,1,0|b34lg0,27,10,1|bdxhfz,27,10,1|bdxhg0,1,1,0|bluo3z,1,1,0|bluo40,27,10,1|bwnk3z,27,10,1|bwnk40,1,1,0|c4kqrz,1,1,0|c4kqs0,27,10,1|cfdmrz,27,10,1|cfdms0,1,1,0|cnatfz,1,1,0|cnatg0,27,10,1|cy3pfz,27,10,1|cy3pg0,1,1,0|d60w3z,1,1,0|d60w40,27,10,1|dgts3z,27,10,1|dgts40,1,1,0|dp3xfz,1,1,0|dp3xg0,27,10,1|dzwtfz,27,10,1|dzwtg0,1,1,0|e7u03z,1,1,0|e7u040,27,10,1|eimw3z,27,10,1|eimw40,1,1,0|eqk2rz,1,1,0|eqk2s0,27,10,1|f1cyrz,27,10,1|f1cys0,1,1,0|f9a5fz,1,1,0|f9a5g0,27,10,1|fkg03z,27,10,1|fkg040,1,1,0|fs083z,1,1,0|fs0840,27,10,1|g362rz,27,10,1|g362s0,1,1,0|gaqarz,1,1,0|gaqas0,27,10,1|glw5fz,27,10,1|glw5g0,1,1,0|gttc3z,1,1,0|gttc40,27,10,1|h4m83z,27,10,1|h4m840,1,1,0|hcjerz,1,1,0|hcjes0,27,10,1|hncarz,27,10,1|hncas0,1,1,0|hv9hfz,1,1,0|hv9hg0,27,10,1|i6fc3z,27,10,1|i6fc40,1,1,0|idzk3z,1,1,0|idzk40,27,10,1|ip5erz,27,10,1|ip5es0,1,1,0|iwpmrz,1,1,0|iwpms0,27,10,1|j7vhfz,27,10,1|j7vhg0,1,1,0|jffpfz,1,1,0|jffpg0,27,10,1|jqlk3z,27,10,1|jqlk40,1,1,0|jyiqrz,1,1,0|jyiqs0,27,10,1|k9bmrz,27,10,1|k9bms0,1,1,0|kh8tfz,1,1,0|kh8tg0,27,10,1|ks1pfz,27,10,1|ks1pg0,1,1,0|kzyw3z,1,1,0|kzyw40,27,10,1|lb4qrz,27,10,1|lb4qs0,1,1,0|lioyrz,1,1,0|lioys0,27,10,1|ltutfz,27,10,1|ltutg0,1,1,0|m1f1fz,1,1,0|m1f1g0,27,10,1|mckw3z,27,10,1|mckw40,1,1,0|mki2rz,1,1,0|mki2s0,27,10,1|mvayrz,27,10,1|mvays0,1,1,0|n385fz,1,1,0|n385g0,27,10,1|ne11fz,27,10,1|ne11g0,1,1,0|nly83z,1,1,0|nly840,27,10,1|nwr43z,27,10,1|nwr440,1,1,0|o4oarz,1,1,0|o4oas0,27,10,1|ofu5fz,27,10,1|ofu5g0,1,1,0|onedfz,1,1,0|onedg0,27,10,1|oyk83z,27,10,1|oyk840,1,1,0|p64g3z,1,1,0|p64g40,27,10,1|phaarz,27,10,1|phaas0,1,1,0|pp7hfz,1,1,0|pp7hg0,27,10,1|q00dfz,27,10,1|q00dg0,1,1,0|q7xk3z,1,1,0|q7xk40,27,10,1|qiqg3z,27,10,1|qiqg40,1,1,0|qqnmrz,1,1,0|qqnms0,27,10,1|r1thfz,27,10,1|r1thg0,1,1,0|r9dpfz,1,1,0|r9dpg0,27,10,1|rkjk3z,27,10,1|rkjk40,1,1,0|rs3s3z,1,1,0|rs3s40,27,10,1|s39mrz,27,10,1|s39ms0,1,1,0|sb6tfz,1,1,0|sb6tg0,27,10,1|slzpfz,27,10,1|slzpg0,1,1,0|stww3z,1,1,0|stww40,27,10,1|t4ps3z,27,10,1|t4ps40,1,1,0|tcmyrz,1,1,0|tcmys0,27,10,1|tnfurz,27,10,1|tnfus0,1,1,0|tvd1fz,1,1,0|tvd1g0,27,10,1|u6iw3z,27,10,1|u6iw40,1,1,0|ue343z,1,1,0|ue3440,27,10,1|up8yrz,27,10,1|up8ys0,1,1,0|uwt6rz,1,1,0|uwt6s0,27,10,1|v7z1fz,27,10,1|v7z1g0,1,1,0|vfw83z,1,1,0|vfw840,27,10,1|vqp43z,27,10,1|vqp440,1,1,0|vymarz,1,1,0|vymas0,27,10,1|w9f6rz,27,10,1|w9f6s0,1,1,0|whcdfz,1,1,0|whcdg0,27,10,1|wsi83z,27,10,1|wsi840,1,1,0|x02g3z,1,1,0|x02g40,27,10,1|xb8arz,27,10,1|xb8as0,1,1,0|xisirz,1,1,0|xisis0,27,10,1|xtydfz,27,10,1|xtydg0,1,1,0|y1ilfz,1,1,0|y1ilg0,27,10,1|ycog3z,27,10,1|ycog40,1,1,0|yklmrz,1,1,0|yklms0,27,10,1|yveirz,27,10,1|yveis0,1,1,0|z3bpfz,1,1,0|z3bpg0,27,10,1|ze4lfz,27,10,1|ze4lg0,1,1,0\",\"Europe/Kaliningrad|,0,332,0|-14212go,10,10,0|-s0e081,10,10,0|-s0e080,11,11,1|-rsilg1,11,11,1|-rsilg0,10,10,0|-ridmk1,10,10,0|-ridmk0,11,11,1|-ragfw1,11,11,1|-ragfw0,10,10,0|-qznjw1,10,10,0|-qznjw0,11,11,1|-qrqd81,11,11,1|-qrqd80,10,10,0|-fizzw1,10,10,0|-fizzw0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d6dp81,11,11,1|-d6dp80,10,10,0|-cx0nw1,10,10,0|-cx0nw0,11,11,1|-cwm2w1,11,11,1|-cwm2w0,15,11,0|-cvmw81,15,11,0|-cvmw80,16,6,1|-cm2j01,16,6,1|-cm2j00,15,11,0|-cdzpk1,15,11,0|-cdzpk0,148,6,0|5vb6bz,148,6,0|5vb6c0,149,209,1|64pzjz,149,209,1|64pzk0,148,6,0|6e33nz,148,6,0|6e33o0,149,209,1|6nhwvz,149,209,1|6nhww0,148,6,0|6wv0zz,148,6,0|6wv100,149,209,1|769u7z,149,209,1|769u80,148,6,0|7foszz,148,6,0|7fot00,149,209,1|7p1zvz,149,209,1|7p1zw0,148,6,0|7yf17z,148,6,0|7yf180,149,209,1|87s2jz,149,209,1|87s2k0,148,6,0|8h53vz,148,6,0|8h53w0,149,209,1|8qi57z,149,209,1|8qi580,148,6,0|8zv6jz,148,6,0|8zv6k0,149,209,1|9987vz,149,209,1|9987w0,148,6,0|9il97z,148,6,0|9il980,149,209,1|9ryajz,149,209,1|9ryak0,148,6,0|a1bbvz,148,6,0|a1bbw0,16,6,1|aaofzz,16,6,1|aaog00,15,11,0|ak1hbz,15,11,0|ak1hc0,16,6,1|atrhbz,16,6,1|atrhc0,15,11,0|b34inz,15,11,0|b34io0,16,6,1|bchjzz,16,6,1|bchk00,15,11,0|blulbz,15,11,0|blulc0,16,6,1|bv7mnz,16,6,1|bv7mo0,15,11,0|c4knzz,15,11,0|c4ko00,16,6,1|cdxpbz,16,6,1|cdxpc0,15,11,0|cnaqnz,15,11,0|cnaqo0,16,6,1|cwnrzz,16,6,1|cwns00,15,11,0|d60tbz,15,11,0|d60tc0,16,6,1|dfdunz,16,6,1|dfduo0,15,11,0|dp3unz,15,11,0|dp3uo0,16,6,1|dzwqnz,16,6,1|dzwqo0,15,11,0|e7txbz,15,11,0|e7txc0,16,6,1|eimtbz,16,6,1|eimtc0,15,11,0|eqjzzz,15,11,0|eqk000,16,6,1|f1cvzz,16,6,1|f1cw00,15,11,0|f9a2nz,15,11,0|f9a2o0,16,6,1|fkfxbz,16,6,1|fkfxc0,15,11,0|fs05bz,15,11,0|fs05c0,16,6,1|g35zzz,16,6,1|g36000,15,11,0|gaq7zz,15,11,0|gaq800,16,6,1|glw2nz,16,6,1|glw2o0,15,11,0|gtt9bz,15,11,0|gtt9c0,16,6,1|h4m5bz,16,6,1|h4m5c0,15,11,0|hcjbzz,15,11,0|hcjc00,16,6,1|hnc7zz,16,6,1|hnc800,15,11,0|hv9enz,15,11,0|hv9eo0,16,6,1|i6f9bz,16,6,1|i6f9c0,15,11,0|idzhbz,15,11,0|idzhc0,16,6,1|ip5bzz,16,6,1|ip5c00,15,11,0|iwpjzz,15,11,0|iwpk00,16,6,1|j7venz,16,6,1|j7veo0,15,11,0|jffmnz,15,11,0|jffmo0,16,6,1|jqlhbz,16,6,1|jqlhc0,15,11,0|jyinzz,15,11,0|jyio00,16,6,1|k9bjzz,16,6,1|k9bk00,15,11,0|kh8qnz,15,11,0|kh8qo0,16,6,1|ks1mnz,16,6,1|ks1mo0,15,11,0|kzytbz,15,11,0|kzytc0,16,6,1|lb4nzz,16,6,1|lb4o00,15,11,0|liovzz,15,11,0|liow00,100,6,0|ne0vvz,100,6,0|ne0vw0,15,11,0\",\"Europe/Kiev|,0,351,0|-1ayy8bg,74,351,0|-nu11nh,74,351,0|-nu11ng,15,11,0|-kmr1k1,15,11,0|-kmr1k0,148,6,0|-erdv01,148,6,0|-erdv00,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dnetg1,10,10,0|-dnetg0,148,6,0|5vb6bz,148,6,0|5vb6c0,149,209,1|64pzjz,149,209,1|64pzk0,148,6,0|6e33nz,148,6,0|6e33o0,149,209,1|6nhwvz,149,209,1|6nhww0,148,6,0|6wv0zz,148,6,0|6wv100,149,209,1|769u7z,149,209,1|769u80,148,6,0|7foszz,148,6,0|7fot00,149,209,1|7p1zvz,149,209,1|7p1zw0,148,6,0|7yf17z,148,6,0|7yf180,149,209,1|87s2jz,149,209,1|87s2k0,148,6,0|8h53vz,148,6,0|8h53w0,149,209,1|8qi57z,149,209,1|8qi580,148,6,0|8zv6jz,148,6,0|8zv6k0,149,209,1|9987vz,149,209,1|9987w0,148,6,0|9il97z,148,6,0|9il980,149,209,1|9ryajz,149,209,1|9ryak0,148,6,0|a1bbvz,148,6,0|a1bbw0,149,209,1|aaod7z,149,209,1|aaod80,148,6,0|ak1ejz,148,6,0|ak1ek0,149,209,1|ap2t3z,149,209,1|ap2t40,16,6,1|bchjzz,16,6,1|bchk00,15,11,0|blufrz,15,11,0|blufs0,16,6,1|bv7ebz,16,6,1|bv7ec0,15,11,0|c4kifz,15,11,0|c4kig0,16,6,1|cdxgzz,16,6,1|cdxh00,15,11,0|cnal3z,15,11,0|cnal40,16,6,1|cwnjnz,16,6,1|cwnjo0,15,11,0|d60w3z,15,11,0|d60w40,16,6,1|dfdxfz,16,6,1|dfdxg0,15,11,0|dp3xfz,15,11,0|dp3xg0,16,6,1|dzwtfz,16,6,1|dzwtg0,15,11,0|e7u03z,15,11,0|e7u040,16,6,1|eimw3z,16,6,1|eimw40,15,11,0|eqk2rz,15,11,0|eqk2s0,16,6,1|f1cyrz,16,6,1|f1cys0,15,11,0|f9a5fz,15,11,0|f9a5g0,16,6,1|fkg03z,16,6,1|fkg040,15,11,0|fs083z,15,11,0|fs0840,16,6,1|g362rz,16,6,1|g362s0,15,11,0|gaqarz,15,11,0|gaqas0,16,6,1|glw5fz,16,6,1|glw5g0,15,11,0|gttc3z,15,11,0|gttc40,16,6,1|h4m83z,16,6,1|h4m840,15,11,0|hcjerz,15,11,0|hcjes0,16,6,1|hncarz,16,6,1|hncas0,15,11,0|hv9hfz,15,11,0|hv9hg0,16,6,1|i6fc3z,16,6,1|i6fc40,15,11,0|idzk3z,15,11,0|idzk40,16,6,1|ip5erz,16,6,1|ip5es0,15,11,0|iwpmrz,15,11,0|iwpms0,16,6,1|j7vhfz,16,6,1|j7vhg0,15,11,0|jffpfz,15,11,0|jffpg0,16,6,1|jqlk3z,16,6,1|jqlk40,15,11,0|jyiqrz,15,11,0|jyiqs0,16,6,1|k9bmrz,16,6,1|k9bms0,15,11,0|kh8tfz,15,11,0|kh8tg0,16,6,1|ks1pfz,16,6,1|ks1pg0,15,11,0|kzyw3z,15,11,0|kzyw40,16,6,1|lb4qrz,16,6,1|lb4qs0,15,11,0|lioyrz,15,11,0|lioys0,16,6,1|ltutfz,16,6,1|ltutg0,15,11,0|m1f1fz,15,11,0|m1f1g0,16,6,1|mckw3z,16,6,1|mckw40,15,11,0|mki2rz,15,11,0|mki2s0,16,6,1|mvayrz,16,6,1|mvays0,15,11,0|n385fz,15,11,0|n385g0,16,6,1|ne11fz,16,6,1|ne11g0,15,11,0|nly83z,15,11,0|nly840,16,6,1|nwr43z,16,6,1|nwr440,15,11,0|o4oarz,15,11,0|o4oas0,16,6,1|ofu5fz,16,6,1|ofu5g0,15,11,0|onedfz,15,11,0|onedg0,16,6,1|oyk83z,16,6,1|oyk840,15,11,0|p64g3z,15,11,0|p64g40,16,6,1|phaarz,16,6,1|phaas0,15,11,0|pp7hfz,15,11,0|pp7hg0,16,6,1|q00dfz,16,6,1|q00dg0,15,11,0|q7xk3z,15,11,0|q7xk40,16,6,1|qiqg3z,16,6,1|qiqg40,15,11,0|qqnmrz,15,11,0|qqnms0,16,6,1|r1thfz,16,6,1|r1thg0,15,11,0|r9dpfz,15,11,0|r9dpg0,16,6,1|rkjk3z,16,6,1|rkjk40,15,11,0|rs3s3z,15,11,0|rs3s40,16,6,1|s39mrz,16,6,1|s39ms0,15,11,0|sb6tfz,15,11,0|sb6tg0,16,6,1|slzpfz,16,6,1|slzpg0,15,11,0|stww3z,15,11,0|stww40,16,6,1|t4ps3z,16,6,1|t4ps40,15,11,0|tcmyrz,15,11,0|tcmys0,16,6,1|tnfurz,16,6,1|tnfus0,15,11,0|tvd1fz,15,11,0|tvd1g0,16,6,1|u6iw3z,16,6,1|u6iw40,15,11,0|ue343z,15,11,0|ue3440,16,6,1|up8yrz,16,6,1|up8ys0,15,11,0|uwt6rz,15,11,0|uwt6s0,16,6,1|v7z1fz,16,6,1|v7z1g0,15,11,0|vfw83z,15,11,0|vfw840,16,6,1|vqp43z,16,6,1|vqp440,15,11,0|vymarz,15,11,0|vymas0,16,6,1|w9f6rz,16,6,1|w9f6s0,15,11,0|whcdfz,15,11,0|whcdg0,16,6,1|wsi83z,16,6,1|wsi840,15,11,0|x02g3z,15,11,0|x02g40,16,6,1|xb8arz,16,6,1|xb8as0,15,11,0|xisirz,15,11,0|xisis0,16,6,1|xtydfz,16,6,1|xtydg0,15,11,0|y1ilfz,15,11,0|y1ilg0,16,6,1|ycog3z,16,6,1|ycog40,15,11,0|yklmrz,15,11,0|yklms0,16,6,1|yveirz,16,6,1|yveis0,15,11,0|z3bpfz,15,11,0|z3bpg0,16,6,1|ze4lfz,16,6,1|ze4lg0,15,11,0\",\"Europe/Kirov|,0,352,0|-qcx400,100,6,0|-kmr4c1,100,6,0|-kmr4c0,105,209,0|5vb3jz,105,209,0|5vb3k0,92,194,1|64pwrz,92,194,1|64pws0,105,209,0|6e30vz,105,209,0|6e30w0,92,194,1|6nhu3z,92,194,1|6nhu40,105,209,0|6wuy7z,105,209,0|6wuy80,92,194,1|769rfz,92,194,1|769rg0,105,209,0|7foq7z,105,209,0|7foq80,92,194,1|7p1x3z,92,194,1|7p1x40,105,209,0|7yeyfz,105,209,0|7yeyg0,92,194,1|87rzrz,92,194,1|87rzs0,105,209,0|8h513z,105,209,0|8h5140,92,194,1|8qi2fz,92,194,1|8qi2g0,105,209,0|8zv3rz,105,209,0|8zv3s0,92,194,1|99853z,92,194,1|998540,105,209,0|9il6fz,105,209,0|9il6g0,92,194,1|9ry7rz,92,194,1|9ry7s0,105,209,0|a1b93z,105,209,0|a1b940,105,209,1|aaod7z,105,209,1|aaod80,100,6,0|ak1ejz,100,6,0|ak1ek0,105,209,1|atrejz,105,209,1|atrek0,100,6,0|b34fvz,100,6,0|b34fw0,105,209,0|blufrz,105,209,0|blufs0,105,209,1|bv7jvz,105,209,1|bv7jw0,100,6,0|c4kl7z,100,6,0|c4kl80,105,209,1|cdxmjz,105,209,1|cdxmk0,100,6,0|cnanvz,100,6,0|cnanw0,105,209,1|cwnp7z,105,209,1|cwnp80,100,6,0|d60qjz,100,6,0|d60qk0,105,209,1|dfdrvz,105,209,1|dfdrw0,100,6,0|dp3rvz,100,6,0|dp3rw0,105,209,1|dzwnvz,105,209,1|dzwnw0,100,6,0|e7tujz,100,6,0|e7tuk0,105,209,1|eimqjz,105,209,1|eimqk0,100,6,0|eqjx7z,100,6,0|eqjx80,105,209,1|f1ct7z,105,209,1|f1ct80,100,6,0|f99zvz,100,6,0|f99zw0,105,209,1|fkfujz,105,209,1|fkfuk0,100,6,0|fs02jz,100,6,0|fs02k0,105,209,1|g35x7z,105,209,1|g35x80,100,6,0|gaq57z,100,6,0|gaq580,105,209,1|glvzvz,105,209,1|glvzw0,100,6,0|gtt6jz,100,6,0|gtt6k0,105,209,1|h4m2jz,105,209,1|h4m2k0,100,6,0|hcj97z,100,6,0|hcj980,105,209,1|hnc57z,105,209,1|hnc580,100,6,0|hv9bvz,100,6,0|hv9bw0,105,209,1|i6f6jz,105,209,1|i6f6k0,100,6,0|idzejz,100,6,0|idzek0,105,209,1|ip597z,105,209,1|ip5980,100,6,0|iwph7z,100,6,0|iwph80,105,209,1|j7vbvz,105,209,1|j7vbw0,100,6,0|jffjvz,100,6,0|jffjw0,105,209,1|jqlejz,105,209,1|jqlek0,100,6,0|jyil7z,100,6,0|jyil80,105,209,1|k9bh7z,105,209,1|k9bh80,100,6,0|kh8nvz,100,6,0|kh8nw0,105,209,1|ks1jvz,105,209,1|ks1jw0,100,6,0|kzyqjz,100,6,0|kzyqk0,105,209,1|lb4l7z,105,209,1|lb4l80,100,6,0|liot7z,100,6,0|liot80,105,209,0|ne0t3z,105,209,0|ne0t40,100,6,0\",\"Europe/Lisbon|,0,29,0|-u9rhc0,8,1,0|-rxx1g1,8,1,0|-rxx1g0,9,10,1|-rqx401,9,10,1|-rqx400,8,1,0|-rkqys1,8,1,0|-rkqys0,9,10,1|-r90qs1,9,10,1|-r90qs0,8,1,0|-r1x6s1,8,1,0|-r1x6s0,9,10,1|-qq8tg1,9,10,1|-qq8tg0,8,1,0|-qj7441,8,1,0|-qj7440,9,10,1|-q7gw41,9,10,1|-q7gw40,8,1,0|-q0dc41,8,1,0|-q0dc40,9,10,1|-pon441,9,10,1|-pon440,8,1,0|-phles1,8,1,0|-phles0,9,10,1|-p5v6s1,9,10,1|-p5v6s0,8,1,0|-nusqs1,8,1,0|-nusqs0,9,10,1|-nlhk41,9,10,1|-nlhk40,8,1,0|-mt71g1,8,1,0|-mt71g0,9,10,1|-mkjxg1,9,10,1|-mkjxg0,8,1,0|-matxg1,8,1,0|-matxg0,9,10,1|-m1tus1,9,10,1|-m1tus0,8,1,0|-lrqw41,8,1,0|-lrqw40,9,10,1|-liqtg1,9,10,1|-liqtg0,8,1,0|-l8nus1,8,1,0|-l8nus0,9,10,1|-l00qs1,9,10,1|-l00qs0,8,1,0|-k77pg1,8,1,0|-k77pg0,9,10,1|-jyklg1,9,10,1|-jyklg0,8,1,0|-jp7k41,8,1,0|-jp7k40,9,10,1|-jfuis1,9,10,1|-jfuis0,8,1,0|-ineg41,8,1,0|-ineg40,9,10,1|-ie1es1,9,10,1|-ie1es0,8,1,0|-i51c41,8,1,0|-i51c40,9,10,1|-hvbc41,9,10,1|-hvbc40,8,1,0|-hl8dg1,8,1,0|-hl8dg0,9,10,1|-hcl9g1,9,10,1|-hcl9g0,8,1,0|-h38841,8,1,0|-h38840,9,10,1|-gtv6s1,9,10,1|-gtv6s0,8,1,0|-gkv441,8,1,0|-gkv440,9,10,1|-gb5441,9,10,1|-gb5440,8,1,0|-g125g1,8,1,0|-g125g0,9,10,1|-fpwas1,9,10,1|-fpwas0,8,1,0|-fkutg1,8,1,0|-fkutg0,9,10,1|-f9c041,9,10,1|-f9c040,8,1,0|-ezyys1,8,1,0|-ezyys0,9,10,1|-eqk2s1,9,10,1|-eqk2s0,8,1,0|-eibs41,8,1,0|-eibs40,9,10,1|-eg62w1,9,10,1|-eg62w0,152,11,1|-eaeo81,152,11,1|-eaeo80,9,10,1|-e6sys1,9,10,1|-e6sys0,8,1,0|-dzlpg1,8,1,0|-dzlpg0,9,10,1|-dxsyw1,9,10,1|-dxsyw0,152,11,1|-dqyo81,152,11,1|-dqyo80,9,10,1|-dnpxg1,9,10,1|-dnpxg0,8,1,0|-dgvms1,8,1,0|-dgvms0,9,10,1|-depxk1,9,10,1|-depxk0,152,11,1|-d88lk1,152,11,1|-d88lk0,9,10,1|-d4zus1,9,10,1|-d4zus0,8,1,0|-cy5k41,8,1,0|-cy5k40,9,10,1|-cvzuw1,9,10,1|-cvzuw0,152,11,1|-cpiiw1,152,11,1|-cpiiw0,9,10,1|-cm9s41,9,10,1|-cm9s40,8,1,0|-cdzms1,8,1,0|-cdzms0,9,10,1|-c4mlg1,9,10,1|-c4mlg0,8,1,0|-bv9bs1,8,1,0|-bv9bs0,9,10,1|-blwag1,9,10,1|-blwag0,8,1,0|-bcj941,8,1,0|-bcj940,9,10,1|-b367s1,9,10,1|-b367s0,8,1,0|-att6g1,8,1,0|-att6g0,9,10,1|-akg541,9,10,1|-akg540,8,1,0|-9sd141,8,1,0|-9sd140,9,10,1|-9in141,9,10,1|-9in140,8,1,0|-999zs1,8,1,0|-999zs0,9,10,1|-8zwyg1,9,10,1|-8zwyg0,8,1,0|-8qjx41,8,1,0|-8qjx40,9,10,1|-8h6vs1,9,10,1|-8h6vs0,8,1,0|-87tug1,8,1,0|-87tug0,9,10,1|-7ygt41,9,10,1|-7ygt40,8,1,0|-7p3rs1,8,1,0|-7p3rs0,9,10,1|-7fqqg1,9,10,1|-7fqqg0,8,1,0|-76dp41,8,1,0|-76dp40,9,10,1|-6wnp41,9,10,1|-6wnp40,8,1,0|-6nans1,8,1,0|-6nans0,9,10,1|-6dxmg1,9,10,1|-6dxmg0,8,1,0|-64kl41,8,1,0|-64kl40,9,10,1|-5v7js1,9,10,1|-5v7js0,8,1,0|-5luig1,8,1,0|-5luig0,9,10,1|-5chh41,9,10,1|-5chh40,8,1,0|-534fs1,8,1,0|-534fs0,9,10,1|-4treg1,9,10,1|-4treg0,8,1,0|-4ked41,8,1,0|-4ked40,9,10,1|-4b1bs1,9,10,1|-4b1bs0,8,1,0|-41oag1,8,1,0|-41oag0,9,10,1|-3ryag1,9,10,1|-3ryag0,8,1,0|-3il941,8,1,0|-3il940,9,10,1|-3987s1,9,10,1|-3987s0,8,1,0|-2zv6g1,8,1,0|-2zv6g0,9,10,1|-2qi541,9,10,1|-2qi540,8,1,0|-2h53s1,8,1,0|-2h53s0,9,10,1|-27s2g1,9,10,1|-27s2g0,8,1,0|-1yf141,8,1,0|-1yf140,10,10,0|3ijjzz,10,10,0|3ijk00,8,1,0|3rwlbz,8,1,0|3rwlc0,9,10,1|419mnz,9,10,1|419mo0,8,1,0|4azmnz,8,1,0|4azmo0,9,10,1|4kcnzz,9,10,1|4kco00,8,1,0|4tppbz,8,1,0|4tppc0,9,10,1|532tfz,9,10,1|532tg0,8,1,0|5cfrzz,8,1,0|5cfs00,9,10,1|5lsw3z,9,10,1|5lsw40,8,1,0|5v5xfz,8,1,0|5v5xg0,9,10,1|64iyrz,9,10,1|64iys0,8,1,0|6dw03z,8,1,0|6dw040,9,10,1|6n91fz,9,10,1|6n91g0,8,1,0|6wm5jz,8,1,0|6wm5k0,9,10,1|75z43z,9,10,1|75z440,8,1,0|7fc5fz,8,1,0|7fc5g0,9,10,1|7p25fz,9,10,1|7p25g0,8,1,0|7yf6rz,8,1,0|7yf6s0,9,10,1|87s83z,9,10,1|87s840,8,1,0|8h59fz,8,1,0|8h59g0,9,10,1|8qiarz,9,10,1|8qias0,8,1,0|8zvc3z,8,1,0|8zvc40,9,10,1|998dfz,9,10,1|998dg0,8,1,0|9ilerz,8,1,0|9iles0,9,10,1|9ryg3z,9,10,1|9ryg40,8,1,0|a1bhfz,8,1,0|a1bhg0,9,10,1|aaoirz,9,10,1|aaois0,8,1,0|ak1k3z,8,1,0|ak1k40,9,10,1|atrk3z,9,10,1|atrk40,8,1,0|b34lfz,8,1,0|b34lg0,9,10,1|bchmrz,9,10,1|bchms0,8,1,0|bluo3z,8,1,0|bluo40,9,10,1|bv7pfz,9,10,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,9,10,1|dzwtfz,9,10,1|dzwtg0,8,1,0|e7u03z,8,1,0|e7u040,9,10,1|eimw3z,9,10,1|eimw40,8,1,0|eqk2rz,8,1,0|eqk2s0,9,10,1|f1cyrz,9,10,1|f1cys0,8,1,0|f9a5fz,8,1,0|f9a5g0,9,10,1|fkg03z,9,10,1|fkg040,8,1,0|fs083z,8,1,0|fs0840,9,10,1|g362rz,9,10,1|g362s0,8,1,0|gaqarz,8,1,0|gaqas0,9,10,1|glw5fz,9,10,1|glw5g0,8,1,0|gttc3z,8,1,0|gttc40,9,10,1|h4m83z,9,10,1|h4m840,8,1,0|hcjerz,8,1,0|hcjes0,9,10,1|hncarz,9,10,1|hncas0,8,1,0|hv9hfz,8,1,0|hv9hg0,9,10,1|i6fc3z,9,10,1|i6fc40,8,1,0|idzk3z,8,1,0|idzk40,9,10,1|ip5erz,9,10,1|ip5es0,8,1,0|iwpmrz,8,1,0|iwpms0,9,10,1|j7vhfz,9,10,1|j7vhg0,8,1,0|jffpfz,8,1,0|jffpg0,9,10,1|jqlk3z,9,10,1|jqlk40,8,1,0|jyiqrz,8,1,0|jyiqs0,9,10,1|k9bmrz,9,10,1|k9bms0,8,1,0|kh8tfz,8,1,0|kh8tg0,9,10,1|ks1pfz,9,10,1|ks1pg0,8,1,0|kzyw3z,8,1,0|kzyw40,9,10,1|lb4qrz,9,10,1|lb4qs0,8,1,0|lioyrz,8,1,0|lioys0,9,10,1|ltutfz,9,10,1|ltutg0,8,1,0|m1f1fz,8,1,0|m1f1g0,9,10,1|mckw3z,9,10,1|mckw40,8,1,0|mki2rz,8,1,0|mki2s0,9,10,1|mvayrz,9,10,1|mvays0,8,1,0|n385fz,8,1,0|n385g0,9,10,1|ne11fz,9,10,1|ne11g0,8,1,0|nly83z,8,1,0|nly840,9,10,1|nwr43z,9,10,1|nwr440,8,1,0|o4oarz,8,1,0|o4oas0,9,10,1|ofu5fz,9,10,1|ofu5g0,8,1,0|onedfz,8,1,0|onedg0,9,10,1|oyk83z,9,10,1|oyk840,8,1,0|p64g3z,8,1,0|p64g40,9,10,1|phaarz,9,10,1|phaas0,8,1,0|pp7hfz,8,1,0|pp7hg0,9,10,1|q00dfz,9,10,1|q00dg0,8,1,0|q7xk3z,8,1,0|q7xk40,9,10,1|qiqg3z,9,10,1|qiqg40,8,1,0|qqnmrz,8,1,0|qqnms0,9,10,1|r1thfz,9,10,1|r1thg0,8,1,0|r9dpfz,8,1,0|r9dpg0,9,10,1|rkjk3z,9,10,1|rkjk40,8,1,0|rs3s3z,8,1,0|rs3s40,9,10,1|s39mrz,9,10,1|s39ms0,8,1,0|sb6tfz,8,1,0|sb6tg0,9,10,1|slzpfz,9,10,1|slzpg0,8,1,0|stww3z,8,1,0|stww40,9,10,1|t4ps3z,9,10,1|t4ps40,8,1,0|tcmyrz,8,1,0|tcmys0,9,10,1|tnfurz,9,10,1|tnfus0,8,1,0|tvd1fz,8,1,0|tvd1g0,9,10,1|u6iw3z,9,10,1|u6iw40,8,1,0|ue343z,8,1,0|ue3440,9,10,1|up8yrz,9,10,1|up8ys0,8,1,0|uwt6rz,8,1,0|uwt6s0,9,10,1|v7z1fz,9,10,1|v7z1g0,8,1,0|vfw83z,8,1,0|vfw840,9,10,1|vqp43z,9,10,1|vqp440,8,1,0|vymarz,8,1,0|vymas0,9,10,1|w9f6rz,9,10,1|w9f6s0,8,1,0|whcdfz,8,1,0|whcdg0,9,10,1|wsi83z,9,10,1|wsi840,8,1,0|x02g3z,8,1,0|x02g40,9,10,1|xb8arz,9,10,1|xb8as0,8,1,0|xisirz,8,1,0|xisis0,9,10,1|xtydfz,9,10,1|xtydg0,8,1,0|y1ilfz,8,1,0|y1ilg0,9,10,1|ycog3z,9,10,1|ycog40,8,1,0|yklmrz,8,1,0|yklms0,9,10,1|yveirz,9,10,1|yveis0,8,1,0|z3bpfz,8,1,0|z3bpg0,9,10,1|ze4lfz,9,10,1|ze4lg0,8,1,0\",\"Europe/Ljubljana|,0,332,0|-18vsmgo,10,10,0|-ezayw1,10,10,0|-ezayw0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d6dp81,11,11,1|-d6dp80,10,10,0|-cv5zw1,10,10,0|-cv5zw0,11,11,1|-cofek1,11,11,1|-cofek0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/London|,0,347,0|-1rprx9x,1,1,0|-rzcns1,1,1,0|-rzcns0,27,10,1|-rsid41,27,10,1|-rsid40,1,1,0|-risd41,1,1,0|-risd40,27,10,1|-ragd41,27,10,1|-ragd40,1,1,0|-r0s7s1,1,1,0|-r0s7s0,27,10,1|-qr0d41,27,10,1|-qr0d40,1,1,0|-qhp6g1,1,1,0|-qhp6g0,27,10,1|-q8aag1,27,10,1|-q8aag0,1,1,0|-pyz3s1,1,1,0|-pyz3s0,27,10,1|-po4d41,27,10,1|-po4d40,1,1,0|-pfw2g1,1,1,0|-pfw2g0,27,10,1|-p6h6g1,27,10,1|-p6h6g0,1,1,0|-oxiyg1,1,1,0|-oxiyg0,27,10,1|-onfzs1,27,10,1|-onfzs0,1,1,0|-odd141,1,1,0|-odd140,27,10,1|-o5st41,27,10,1|-o5st40,1,1,0|-nuzx41,1,1,0|-nuzx40,27,10,1|-nmprs1,27,10,1|-nmprs0,1,1,0|-nbwvs1,1,1,0|-nbwvs0,27,10,1|-n39rs1,27,10,1|-n39rs0,1,1,0|-mt6t41,1,1,0|-mt6t40,27,10,1|-mkjp41,27,10,1|-mkjp40,1,1,0|-matp41,1,1,0|-matp40,27,10,1|-m1tmg1,27,10,1|-m1tmg0,1,1,0|-lrdp41,1,1,0|-lrdp40,27,10,1|-liql41,27,10,1|-liql40,1,1,0|-l8nmg1,1,1,0|-l8nmg0,27,10,1|-l00ig1,27,10,1|-l00ig0,1,1,0|-kqaig1,1,1,0|-kqaig0,27,10,1|-khafs1,27,10,1|-khafs0,1,1,0|-k77h41,1,1,0|-k77h40,27,10,1|-jykd41,27,10,1|-jykd40,1,1,0|-joheg1,1,1,0|-joheg0,27,10,1|-jfuag1,27,10,1|-jfuag0,1,1,0|-j64ag1,1,1,0|-j64ag0,27,10,1|-iwr941,27,10,1|-iwr940,1,1,0|-imoag1,1,1,0|-imoag0,27,10,1|-ie16g1,27,10,1|-ie16g0,1,1,0|-i4b6g1,1,1,0|-i4b6g0,27,10,1|-hvb3s1,27,10,1|-hvb3s0,1,1,0|-hl8541,1,1,0|-hl8540,27,10,1|-hcl141,27,10,1|-hcl140,1,1,0|-h2i2g1,1,1,0|-h2i2g0,27,10,1|-gtuyg1,27,10,1|-gtuyg0,1,1,0|-gk4yg1,1,1,0|-gk4yg0,27,10,1|-gb4vs1,27,10,1|-gb4vs0,1,1,0|-g11x41,1,1,0|-g11x40,27,10,1|-fpw2g1,27,10,1|-fpw2g0,1,1,0|-fkul41,1,1,0|-fkul40,27,10,1|-eyiyk1,27,10,1|-eyiyk0,151,11,1|-ethh81,151,11,1|-ethh80,27,10,1|-eh8qk1,27,10,1|-eh8qk0,151,11,1|-earek1,151,11,1|-earek0,27,10,1|-dyinw1,27,10,1|-dyinw0,151,11,1|-drod81,151,11,1|-drod80,27,10,1|-dfsl81,27,10,1|-dfsl80,151,11,1|-d75h81,151,11,1|-d75h80,27,10,1|-cx0nw1,27,10,1|-cx0nw0,151,11,1|-cro2k1,151,11,1|-cro2k0,27,10,1|-cncfs1,27,10,1|-cncfs0,1,1,0|-cdmfs1,1,1,0|-cdmfs0,27,10,1|-c4md41,27,10,1|-c4md40,1,1,0|-bwc7s1,1,1,0|-bwc7s0,27,10,1|-buwfw1,27,10,1|-buwfw0,151,11,1|-bos2k1,151,11,1|-bos2k0,27,10,1|-bkgfs1,27,10,1|-bkgfs0,1,1,0|-bdm541,1,1,0|-bdm540,27,10,1|-b1qd41,27,10,1|-b1qd40,1,1,0|-att6g1,1,1,0|-att6g0,27,10,1|-aj0ag1,27,10,1|-aj0ag0,1,1,0|-aad6g1,1,1,0|-aad6g0,27,10,1|-a0n6g1,27,10,1|-a0n6g0,1,1,0|-9rn3s1,1,1,0|-9rn3s0,27,10,1|-9hx3s1,27,10,1|-9hx3s0,1,1,0|-98k2g1,1,1,0|-98k2g0,27,10,1|-8yu2g1,27,10,1|-8yu2g0,1,1,0|-8ptzs1,1,1,0|-8ptzs0,27,10,1|-8h6vs1,27,10,1|-8h6vs0,1,1,0|-87gvs1,1,1,0|-87gvs0,27,10,1|-7ygt41,27,10,1|-7ygt40,1,1,0|-7odug1,1,1,0|-7odug0,27,10,1|-7fqqg1,27,10,1|-7fqqg0,1,1,0|-75at41,1,1,0|-75at40,27,10,1|-6wnp41,27,10,1|-6wnp40,1,1,0|-6mxp41,1,1,0|-6mxp40,27,10,1|-6dxmg1,27,10,1|-6dxmg0,1,1,0|-63uns1,1,1,0|-63uns0,27,10,1|-5v7js1,27,10,1|-5v7js0,1,1,0|-5l4l41,1,1,0|-5l4l40,27,10,1|-5chh41,27,10,1|-5chh40,1,1,0|-52rh41,1,1,0|-52rh40,27,10,1|-4treg1,27,10,1|-4treg0,1,1,0|-4krbs1,1,1,0|-4krbs0,27,10,1|-49lh41,27,10,1|-49lh40,1,1,0|-421941,1,1,0|-421940,27,10,1|-3qveg1,27,10,1|-3qveg0,1,1,0|-3iy7s1,1,1,0|-3iy7s0,27,10,1|-385bs1,27,10,1|-385bs0,1,1,0|-30l3s1,1,1,0|-30l3s0,27,10,1|-2pf941,27,10,1|-2pf940,1,1,0|-2hv141,1,1,0|-2hv140,27,10,1|-26p6g1,27,10,1|-26p6g0,1,1,0|-1z4yg1,1,1,0|-1z4yg0,27,10,1|-1nz3s1,27,10,1|-1nz3s0,1,1,0|-1gevs1,1,1,0|-1gevs0,27,10,1|-14w2g1,27,10,1|-14w2g0,1,1,0|-z4ns1,1,1,0|-z4ns0,27,10,1|-m6841,27,10,1|-m6840,27,10,0|yd6vz,27,10,0|yd6w0,1,1,0|15kg7z,1,1,0|15kg80,27,10,1|1h39jz,27,10,1|1h39k0,1,1,0|1oaivz,1,1,0|1oaiw0,27,10,1|1ztc7z,27,10,1|1ztc80,1,1,0|270ljz,1,1,0|270lk0,27,10,1|2ijevz,27,10,1|2ijew0,1,1,0|2pqo7z,1,1,0|2pqo80,27,10,1|319hjz,27,10,1|319hk0,1,1,0|38tpjz,1,1,0|38tpk0,27,10,1|3jzk7z,27,10,1|3jzk80,1,1,0|3rjs7z,1,1,0|3rjs80,27,10,1|42pmvz,27,10,1|42pmw0,1,1,0|4a9uvz,1,1,0|4a9uw0,27,10,1|4lso7z,27,10,1|4lso80,1,1,0|4szxjz,1,1,0|4szxk0,27,10,1|54iqvz,27,10,1|54iqw0,1,1,0|5bq07z,1,1,0|5bq080,27,10,1|5n8tjz,27,10,1|5n8tk0,1,1,0|5v5xfz,1,1,0|5v5xg0,27,10,1|65ytfz,27,10,1|65ytg0,1,1,0|6dw03z,1,1,0|6dw040,27,10,1|6oow3z,27,10,1|6oow40,1,1,0|6wm2rz,1,1,0|6wm2s0,27,10,1|77eyrz,27,10,1|77eys0,1,1,0|7fc5fz,1,1,0|7fc5g0,27,10,1|7qi03z,27,10,1|7qi040,1,1,0|7yf6rz,1,1,0|7yf6s0,27,10,1|8982rz,27,10,1|8982s0,1,1,0|8h59fz,1,1,0|8h59g0,27,10,1|8ry5fz,27,10,1|8ry5g0,1,1,0|8zvc3z,1,1,0|8zvc40,27,10,1|9ao83z,27,10,1|9ao840,1,1,0|9ilerz,1,1,0|9iles0,27,10,1|9tearz,27,10,1|9teas0,1,1,0|a1bhfz,1,1,0|a1bhg0,27,10,1|achc3z,27,10,1|achc40,1,1,0|ak1k3z,1,1,0|ak1k40,27,10,1|av7erz,27,10,1|av7es0,1,1,0|b34lfz,1,1,0|b34lg0,27,10,1|bdxhfz,27,10,1|bdxhg0,1,1,0|bluo3z,1,1,0|bluo40,27,10,1|bwnk3z,27,10,1|bwnk40,1,1,0|c4kqrz,1,1,0|c4kqs0,27,10,1|cfdmrz,27,10,1|cfdms0,1,1,0|cnatfz,1,1,0|cnatg0,27,10,1|cy3pfz,27,10,1|cy3pg0,1,1,0|d60w3z,1,1,0|d60w40,27,10,1|dgts3z,27,10,1|dgts40,1,1,0|dp3xfz,1,1,0|dp3xg0,27,10,1|dzwtfz,27,10,1|dzwtg0,1,1,0|e7u03z,1,1,0|e7u040,27,10,1|eimw3z,27,10,1|eimw40,1,1,0|eqk2rz,1,1,0|eqk2s0,27,10,1|f1cyrz,27,10,1|f1cys0,1,1,0|f9a5fz,1,1,0|f9a5g0,27,10,1|fkg03z,27,10,1|fkg040,1,1,0|fs083z,1,1,0|fs0840,27,10,1|g362rz,27,10,1|g362s0,1,1,0|gaqarz,1,1,0|gaqas0,27,10,1|glw5fz,27,10,1|glw5g0,1,1,0|gttc3z,1,1,0|gttc40,27,10,1|h4m83z,27,10,1|h4m840,1,1,0|hcjerz,1,1,0|hcjes0,27,10,1|hncarz,27,10,1|hncas0,1,1,0|hv9hfz,1,1,0|hv9hg0,27,10,1|i6fc3z,27,10,1|i6fc40,1,1,0|idzk3z,1,1,0|idzk40,27,10,1|ip5erz,27,10,1|ip5es0,1,1,0|iwpmrz,1,1,0|iwpms0,27,10,1|j7vhfz,27,10,1|j7vhg0,1,1,0|jffpfz,1,1,0|jffpg0,27,10,1|jqlk3z,27,10,1|jqlk40,1,1,0|jyiqrz,1,1,0|jyiqs0,27,10,1|k9bmrz,27,10,1|k9bms0,1,1,0|kh8tfz,1,1,0|kh8tg0,27,10,1|ks1pfz,27,10,1|ks1pg0,1,1,0|kzyw3z,1,1,0|kzyw40,27,10,1|lb4qrz,27,10,1|lb4qs0,1,1,0|lioyrz,1,1,0|lioys0,27,10,1|ltutfz,27,10,1|ltutg0,1,1,0|m1f1fz,1,1,0|m1f1g0,27,10,1|mckw3z,27,10,1|mckw40,1,1,0|mki2rz,1,1,0|mki2s0,27,10,1|mvayrz,27,10,1|mvays0,1,1,0|n385fz,1,1,0|n385g0,27,10,1|ne11fz,27,10,1|ne11g0,1,1,0|nly83z,1,1,0|nly840,27,10,1|nwr43z,27,10,1|nwr440,1,1,0|o4oarz,1,1,0|o4oas0,27,10,1|ofu5fz,27,10,1|ofu5g0,1,1,0|onedfz,1,1,0|onedg0,27,10,1|oyk83z,27,10,1|oyk840,1,1,0|p64g3z,1,1,0|p64g40,27,10,1|phaarz,27,10,1|phaas0,1,1,0|pp7hfz,1,1,0|pp7hg0,27,10,1|q00dfz,27,10,1|q00dg0,1,1,0|q7xk3z,1,1,0|q7xk40,27,10,1|qiqg3z,27,10,1|qiqg40,1,1,0|qqnmrz,1,1,0|qqnms0,27,10,1|r1thfz,27,10,1|r1thg0,1,1,0|r9dpfz,1,1,0|r9dpg0,27,10,1|rkjk3z,27,10,1|rkjk40,1,1,0|rs3s3z,1,1,0|rs3s40,27,10,1|s39mrz,27,10,1|s39ms0,1,1,0|sb6tfz,1,1,0|sb6tg0,27,10,1|slzpfz,27,10,1|slzpg0,1,1,0|stww3z,1,1,0|stww40,27,10,1|t4ps3z,27,10,1|t4ps40,1,1,0|tcmyrz,1,1,0|tcmys0,27,10,1|tnfurz,27,10,1|tnfus0,1,1,0|tvd1fz,1,1,0|tvd1g0,27,10,1|u6iw3z,27,10,1|u6iw40,1,1,0|ue343z,1,1,0|ue3440,27,10,1|up8yrz,27,10,1|up8ys0,1,1,0|uwt6rz,1,1,0|uwt6s0,27,10,1|v7z1fz,27,10,1|v7z1g0,1,1,0|vfw83z,1,1,0|vfw840,27,10,1|vqp43z,27,10,1|vqp440,1,1,0|vymarz,1,1,0|vymas0,27,10,1|w9f6rz,27,10,1|w9f6s0,1,1,0|whcdfz,1,1,0|whcdg0,27,10,1|wsi83z,27,10,1|wsi840,1,1,0|x02g3z,1,1,0|x02g40,27,10,1|xb8arz,27,10,1|xb8as0,1,1,0|xisirz,1,1,0|xisis0,27,10,1|xtydfz,27,10,1|xtydg0,1,1,0|y1ilfz,1,1,0|y1ilg0,27,10,1|ycog3z,27,10,1|ycog40,1,1,0|yklmrz,1,1,0|yklms0,27,10,1|yveirz,27,10,1|yveis0,1,1,0|z3bpfz,1,1,0|z3bpg0,27,10,1|ze4lfz,27,10,1|ze4lg0,1,1,0\",\"Europe/Luxembourg|,0,353,0|-y89550,10,10,0|-rzo2w1,10,10,0|-rzo2w0,11,11,1|-rsilg1,11,11,1|-rsilg0,10,10,0|-rhps81,10,10,0|-rhps80,11,11,1|-raglg1,11,11,1|-raglg0,10,10,0|-qznjw1,10,10,0|-qznjw0,11,11,1|-qrqd81,11,11,1|-qrqd80,10,10,0|-qo4w41,10,10,0|-qo4w40,8,1,0|-qj59g1,8,1,0|-qj59g0,9,10,1|-q7z6g1,9,10,1|-q7z6g0,8,1,0|-q15441,8,1,0|-q15440,9,10,1|-po6ak1,9,10,1|-po6ak0,8,1,0|-pgvhg1,8,1,0|-pgvhg0,9,10,1|-p5anw1,9,10,1|-p5anw0,8,1,0|-oxj6s1,8,1,0|-oxj6s0,9,10,1|-ong5c1,9,10,1|-ong5c0,8,1,0|-odd9g1,8,1,0|-odd9g0,9,10,1|-o4pzw1,9,10,1|-o4pzw0,8,1,0|-nvq2s1,8,1,0|-nvq2s0,9,10,1|-nm0001,9,10,1|-nm0000,8,1,0|-ncl6s1,8,1,0|-ncl6s0,9,10,1|-n39xc1,9,10,1|-n39xc0,8,1,0|-mt71g1,8,1,0|-mt71g0,9,10,1|-mkjuo1,9,10,1|-mkjuo0,8,1,0|-matxg1,8,1,0|-matxg0,9,10,1|-m1ts01,9,10,1|-m1ts00,8,1,0|-lrqw41,8,1,0|-lrqw40,9,10,1|-liqqo1,9,10,1|-liqqo0,8,1,0|-l8nus1,8,1,0|-l8nus0,9,10,1|-l00ig1,9,10,1|-l00ig0,8,1,0|-kqaig1,8,1,0|-kqaig0,9,10,1|-khafs1,9,10,1|-khafs0,8,1,0|-k77h41,8,1,0|-k77h40,9,10,1|-jykd41,9,10,1|-jykd40,8,1,0|-jp7bs1,8,1,0|-jp7bs0,9,10,1|-jfuag1,9,10,1|-jfuag0,8,1,0|-j6u7s1,8,1,0|-j6u7s0,9,10,1|-iwr941,9,10,1|-iwr940,8,1,0|-ine7s1,8,1,0|-ine7s0,9,10,1|-ie16g1,9,10,1|-ie16g0,8,1,0|-i513s1,8,1,0|-i513s0,9,10,1|-hvb3s1,9,10,1|-hvb3s0,8,1,0|-hl8541,8,1,0|-hl8540,9,10,1|-hcl141,9,10,1|-hcl140,8,1,0|-h37zs1,8,1,0|-h37zs0,9,10,1|-gtuyg1,9,10,1|-gtuyg0,8,1,0|-gkuvs1,8,1,0|-gkuvs0,9,10,1|-gb4vs1,9,10,1|-gb4vs0,8,1,0|-g11x41,8,1,0|-g11x40,9,10,1|-fpw2g1,9,10,1|-fpw2g0,8,1,0|-fkul41,8,1,0|-fkul40,9,10,1|-fgsag1,9,10,1|-fgsag0,9,11,1|-e6dzw1,9,11,1|-e6dzw0,8,10,0|-dytrw1,8,10,0|-dytrw0,9,11,1|-dp3rw1,9,11,1|-dp3rw0,8,10,0|-dfqqk1,8,10,0|-dfqqk0,9,11,1|-d73mk1,9,11,1|-d73mk0,10,10,0|-cx0nw1,10,10,0|-cx0nw0,11,11,1|-cofek1,11,11,1|-cofek0,10,10,0|-cbtp81,10,10,0|-cbtp80,11,11,1|-c4kl81,11,11,1|-c4kl80,10,10,0|3s9mrz,10,10,0|3s9ms0,11,11,1|419pfz,11,11,1|419pg0,10,10,0|4azpfz,10,10,0|4azpg0,11,11,1|4kcqrz,11,11,1|4kcqs0,10,10,0|4tps3z,10,10,0|4tps40,11,11,1|532tfz,11,11,1|532tg0,10,10,0|5cstfz,10,10,0|5cstg0,11,11,1|5lsw3z,11,11,1|5lsw40,10,10,0|5v5xfz,10,10,0|5v5xg0,11,11,1|64iyrz,11,11,1|64iys0,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Madrid|,0,354,0|-100edc0,8,1,0|-qzlus1,8,1,0|-qzlus0,9,10,1|-qqnk01,9,10,1|-qqnk00,8,1,0|-qhalg1,8,1,0|-qhalg0,9,10,1|-q7vmo1,9,10,1|-q7vmo0,8,1,0|-nusqs1,8,1,0|-nusqs0,9,10,1|-nm0001,9,10,1|-nm0000,8,1,0|-mt71g1,8,1,0|-mt71g0,9,10,1|-mkjuo1,9,10,1|-mkjuo0,8,1,0|-matxg1,8,1,0|-matxg0,9,10,1|-m1ts01,9,10,1|-m1ts00,8,1,0|-lrqtc1,8,1,0|-lrqtc0,9,10,1|-liqqo1,9,10,1|-liqqo0,8,1,0|-l8nus1,8,1,0|-l8nus0,9,10,1|-l00o01,9,10,1|-l00o00,8,1,0|-gzf6s1,8,1,0|-gzf6s0,9,10,1|-gtv401,9,10,1|-gtv400,8,1,0|-gki5g1,8,1,0|-gki5g0,9,10,1|-gj2dk1,9,10,1|-gj2dk0,152,11,1|-gb3c81,152,11,1|-gb3c80,9,10,1|-fs2001,9,10,1|-fs2000,8,1,0|-fjrxg1,8,1,0|-fjrxg0,10,10,0|-eft481,10,10,0|-eft480,11,11,1|-e9kys1,11,11,1|-e9kys0,10,10,0|-dxsyw1,10,10,0|-dxsyw0,11,11,1|-dp5s41,11,11,1|-dp5s40,10,10,0|-df2w81,10,10,0|-df2w80,11,11,1|-d6fpg1,11,11,1|-d6fpg0,10,10,0|-cwctk1,10,10,0|-cwctk0,11,11,1|-cnpms1,11,11,1|-cnpms0,10,10,0|-cdmqw1,10,10,0|-cdmqw0,11,11,1|-c4zk41,11,11,1|-c4zk40,10,10,0|-asdmw1,10,10,0|-asdmw0,11,11,1|-akgdg1,11,11,1|-akgdg0,10,10,0|28g53z,10,10,0|28g540,11,11,1|2hgajz,11,11,1|2hgak0,10,10,0|2r67rz,10,10,0|2r67s0,11,11,1|306d7z,11,11,1|306d80,10,10,0|396d3z,10,10,0|396d40,11,11,1|3ijh7z,11,11,1|3ijh80,10,10,0|3s9efz,10,10,0|3s9eg0,11,11,1|419jvz,11,11,1|419jw0,10,10,0|4azpfz,10,10,0|4azpg0,11,11,1|4kcqrz,11,11,1|4kcqs0,10,10,0|4tps3z,10,10,0|4tps40,11,11,1|532tfz,11,11,1|532tg0,10,10,0|5cstfz,10,10,0|5cstg0,11,11,1|5lsw3z,11,11,1|5lsw40,10,10,0|5v5xfz,10,10,0|5v5xg0,11,11,1|64iyrz,11,11,1|64iys0,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Malta|,0,355,0|-13qyw0s,10,10,0|-rymys1,10,10,0|-rymys0,11,11,1|-rsio81,11,11,1|-rsio80,10,10,0|-rj5k41,10,10,0|-rj5k40,11,11,1|-r9qqw1,11,11,1|-r9qqw0,10,10,0|-r1idg1,10,10,0|-r1idg0,11,11,1|-qqnpk1,11,11,1|-qqnpk0,10,10,0|-qj59g1,10,10,0|-qj59g0,11,11,1|-q7zhk1,11,11,1|-q7zhk0,10,10,0|-pzcas1,10,10,0|-pzcas0,11,11,1|-ppzc81,11,11,1|-ppzc80,10,10,0|-ff59g1,10,10,0|-ff59g0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfsl81,10,10,0|-dfsl80,11,11,1|-d75h81,11,11,1|-d75h80,10,10,0|-cx0nw1,10,10,0|-cx0nw0,11,11,1|-cohes1,11,11,1|-cohes0,10,10,0|-cf2d81,10,10,0|-cf2d80,11,11,1|-c4mfw1,11,11,1|-c4mfw0,10,10,0|-bwcg41,10,10,0|-bwcg40,11,11,1|-blwis1,11,11,1|-blwis0,10,10,0|-bec581,10,10,0|-bec580,11,11,1|-b36ak1,11,11,1|-b36ak0,10,10,0|-1vwis1,10,10,0|-1vwis0,11,11,1|-1pf9k1,11,11,1|-1pf9k0,10,10,0|-1cthg1,10,10,0|-1cthg0,11,11,1|-16p441,11,11,1|-16p440,10,10,0|-u3es1,10,10,0|-u3es0,11,11,1|-nz1g1,11,11,1|-nz1g0,10,10,0|-b0dg1,10,10,0|-b0dg0,11,11,1|-4w041,11,11,1|-4w040,10,10,0|7pp7z,10,10,0|7pp80,11,11,1|du2jz,11,11,1|du2k0,10,10,0|q2t7z,10,10,0|q2t80,11,11,1|wk57z,11,11,1|wk580,10,10,0|195ujz,10,10,0|195uk0,11,11,1|1fn6jz,11,11,1|1fn6k0,10,10,0|1oyd7z,10,10,0|1oyd80,11,11,1|1ybejz,11,11,1|1ybek0,10,10,0|28t6jz,10,10,0|28t6k0,11,11,1|2gf97z,11,11,1|2gf980,10,10,0|2rjerz,10,10,0|2rjes0,11,11,1|2zginz,11,11,1|2zgio0,10,10,0|3a9hfz,10,10,0|3a9hg0,11,11,1|3i6lbz,11,11,1|3i6lc0,10,10,0|3szk3z,10,10,0|3szk40,11,11,1|40wnzz,11,11,1|40wo00,10,10,0|4bpmrz,10,10,0|4bpms0,11,11,1|4jmqnz,11,11,1|4jmqo0,10,10,0|4ufpfz,10,10,0|4ufpg0,11,11,1|52ctbz,11,11,1|52ctc0,10,10,0|5chpfz,10,10,0|5chpg0,11,11,1|5lfunz,11,11,1|5lfuo0,10,10,0|5v5xfz,10,10,0|5v5xg0,11,11,1|64iyrz,11,11,1|64iys0,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Mariehamn|,0,348,0|-1bss9yd,77,348,0|-peghye,77,348,0|-peghyd,15,11,0|-ehco81,15,11,0|-ehco80,16,6,1|-e7vxk1,16,6,1|-e7vxk0,15,11,0|5v5unz,15,11,0|5v5uo0,16,6,1|64ivzz,16,6,1|64iw00,15,11,0|6dvxbz,15,11,0|6dvxc0,16,6,1|6n8ynz,16,6,1|6n8yo0,15,11,0|6wm2rz,15,11,0|6wm2s0,16,6,1|75z43z,16,6,1|75z440,15,11,0|7fc5fz,15,11,0|7fc5g0,16,6,1|7p25fz,16,6,1|7p25g0,15,11,0|7yf6rz,15,11,0|7yf6s0,16,6,1|87s83z,16,6,1|87s840,15,11,0|8h59fz,15,11,0|8h59g0,16,6,1|8qiarz,16,6,1|8qias0,15,11,0|8zvc3z,15,11,0|8zvc40,16,6,1|998dfz,16,6,1|998dg0,15,11,0|9ilerz,15,11,0|9iles0,16,6,1|9ryg3z,16,6,1|9ryg40,15,11,0|a1bhfz,15,11,0|a1bhg0,16,6,1|aaoirz,16,6,1|aaois0,15,11,0|ak1k3z,15,11,0|ak1k40,16,6,1|atrk3z,16,6,1|atrk40,15,11,0|b34lfz,15,11,0|b34lg0,16,6,1|bchmrz,16,6,1|bchms0,15,11,0|bluo3z,15,11,0|bluo40,16,6,1|bv7pfz,16,6,1|bv7pg0,15,11,0|c4kqrz,15,11,0|c4kqs0,16,6,1|cdxs3z,16,6,1|cdxs40,15,11,0|cnatfz,15,11,0|cnatg0,16,6,1|cwnurz,16,6,1|cwnus0,15,11,0|d60w3z,15,11,0|d60w40,16,6,1|dfdxfz,16,6,1|dfdxg0,15,11,0|dp3xfz,15,11,0|dp3xg0,16,6,1|dzwtfz,16,6,1|dzwtg0,15,11,0|e7u03z,15,11,0|e7u040,16,6,1|eimw3z,16,6,1|eimw40,15,11,0|eqk2rz,15,11,0|eqk2s0,16,6,1|f1cyrz,16,6,1|f1cys0,15,11,0|f9a5fz,15,11,0|f9a5g0,16,6,1|fkg03z,16,6,1|fkg040,15,11,0|fs083z,15,11,0|fs0840,16,6,1|g362rz,16,6,1|g362s0,15,11,0|gaqarz,15,11,0|gaqas0,16,6,1|glw5fz,16,6,1|glw5g0,15,11,0|gttc3z,15,11,0|gttc40,16,6,1|h4m83z,16,6,1|h4m840,15,11,0|hcjerz,15,11,0|hcjes0,16,6,1|hncarz,16,6,1|hncas0,15,11,0|hv9hfz,15,11,0|hv9hg0,16,6,1|i6fc3z,16,6,1|i6fc40,15,11,0|idzk3z,15,11,0|idzk40,16,6,1|ip5erz,16,6,1|ip5es0,15,11,0|iwpmrz,15,11,0|iwpms0,16,6,1|j7vhfz,16,6,1|j7vhg0,15,11,0|jffpfz,15,11,0|jffpg0,16,6,1|jqlk3z,16,6,1|jqlk40,15,11,0|jyiqrz,15,11,0|jyiqs0,16,6,1|k9bmrz,16,6,1|k9bms0,15,11,0|kh8tfz,15,11,0|kh8tg0,16,6,1|ks1pfz,16,6,1|ks1pg0,15,11,0|kzyw3z,15,11,0|kzyw40,16,6,1|lb4qrz,16,6,1|lb4qs0,15,11,0|lioyrz,15,11,0|lioys0,16,6,1|ltutfz,16,6,1|ltutg0,15,11,0|m1f1fz,15,11,0|m1f1g0,16,6,1|mckw3z,16,6,1|mckw40,15,11,0|mki2rz,15,11,0|mki2s0,16,6,1|mvayrz,16,6,1|mvays0,15,11,0|n385fz,15,11,0|n385g0,16,6,1|ne11fz,16,6,1|ne11g0,15,11,0|nly83z,15,11,0|nly840,16,6,1|nwr43z,16,6,1|nwr440,15,11,0|o4oarz,15,11,0|o4oas0,16,6,1|ofu5fz,16,6,1|ofu5g0,15,11,0|onedfz,15,11,0|onedg0,16,6,1|oyk83z,16,6,1|oyk840,15,11,0|p64g3z,15,11,0|p64g40,16,6,1|phaarz,16,6,1|phaas0,15,11,0|pp7hfz,15,11,0|pp7hg0,16,6,1|q00dfz,16,6,1|q00dg0,15,11,0|q7xk3z,15,11,0|q7xk40,16,6,1|qiqg3z,16,6,1|qiqg40,15,11,0|qqnmrz,15,11,0|qqnms0,16,6,1|r1thfz,16,6,1|r1thg0,15,11,0|r9dpfz,15,11,0|r9dpg0,16,6,1|rkjk3z,16,6,1|rkjk40,15,11,0|rs3s3z,15,11,0|rs3s40,16,6,1|s39mrz,16,6,1|s39ms0,15,11,0|sb6tfz,15,11,0|sb6tg0,16,6,1|slzpfz,16,6,1|slzpg0,15,11,0|stww3z,15,11,0|stww40,16,6,1|t4ps3z,16,6,1|t4ps40,15,11,0|tcmyrz,15,11,0|tcmys0,16,6,1|tnfurz,16,6,1|tnfus0,15,11,0|tvd1fz,15,11,0|tvd1g0,16,6,1|u6iw3z,16,6,1|u6iw40,15,11,0|ue343z,15,11,0|ue3440,16,6,1|up8yrz,16,6,1|up8ys0,15,11,0|uwt6rz,15,11,0|uwt6s0,16,6,1|v7z1fz,16,6,1|v7z1g0,15,11,0|vfw83z,15,11,0|vfw840,16,6,1|vqp43z,16,6,1|vqp440,15,11,0|vymarz,15,11,0|vymas0,16,6,1|w9f6rz,16,6,1|w9f6s0,15,11,0|whcdfz,15,11,0|whcdg0,16,6,1|wsi83z,16,6,1|wsi840,15,11,0|x02g3z,15,11,0|x02g40,16,6,1|xb8arz,16,6,1|xb8as0,15,11,0|xisirz,15,11,0|xisis0,16,6,1|xtydfz,16,6,1|xtydg0,15,11,0|y1ilfz,15,11,0|y1ilg0,16,6,1|ycog3z,16,6,1|ycog40,15,11,0|yklmrz,15,11,0|yklms0,16,6,1|yveirz,16,6,1|yveis0,15,11,0|z3bpfz,15,11,0|z3bpg0,16,6,1|ze4lfz,16,6,1|ze4lg0,15,11,0\",\"Europe/Minsk|,0,356,0|-1ayy7rs,21,357,0|-nu113d,21,357,0|-nu113c,15,11,0|-kmr1k1,15,11,0|-kmr1k0,148,6,0|-evpf01,148,6,0|-evpf00,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-db2g81,11,11,1|-db2g80,148,6,0|5vb6bz,148,6,0|5vb6c0,149,209,1|64pzjz,149,209,1|64pzk0,148,6,0|6e33nz,148,6,0|6e33o0,149,209,1|6nhwvz,149,209,1|6nhww0,148,6,0|6wv0zz,148,6,0|6wv100,149,209,1|769u7z,149,209,1|769u80,148,6,0|7foszz,148,6,0|7fot00,149,209,1|7p1zvz,149,209,1|7p1zw0,148,6,0|7yf17z,148,6,0|7yf180,149,209,1|87s2jz,149,209,1|87s2k0,148,6,0|8h53vz,148,6,0|8h53w0,149,209,1|8qi57z,149,209,1|8qi580,148,6,0|8zv6jz,148,6,0|8zv6k0,149,209,1|9987vz,149,209,1|9987w0,148,6,0|9il97z,148,6,0|9il980,149,209,1|9ryajz,149,209,1|9ryak0,148,6,0|a1bbvz,148,6,0|a1bbw0,149,209,1|aaod7z,149,209,1|aaod80,148,6,0|b34fvz,148,6,0|b34fw0,16,6,1|bchjzz,16,6,1|bchk00,15,11,0|blulbz,15,11,0|blulc0,16,6,1|bv7mnz,16,6,1|bv7mo0,15,11,0|c4knzz,15,11,0|c4ko00,16,6,1|cdxpbz,16,6,1|cdxpc0,15,11,0|cnaqnz,15,11,0|cnaqo0,16,6,1|cwnrzz,16,6,1|cwns00,15,11,0|d60tbz,15,11,0|d60tc0,16,6,1|dfdunz,16,6,1|dfduo0,15,11,0|dp3unz,15,11,0|dp3uo0,16,6,1|dzwqnz,16,6,1|dzwqo0,15,11,0|e7txbz,15,11,0|e7txc0,16,6,1|eimtbz,16,6,1|eimtc0,15,11,0|eqjzzz,15,11,0|eqk000,16,6,1|f1cvzz,16,6,1|f1cw00,15,11,0|f9a2nz,15,11,0|f9a2o0,16,6,1|fkfxbz,16,6,1|fkfxc0,15,11,0|fs05bz,15,11,0|fs05c0,16,6,1|g35zzz,16,6,1|g36000,15,11,0|gaq7zz,15,11,0|gaq800,16,6,1|glw2nz,16,6,1|glw2o0,15,11,0|gtt9bz,15,11,0|gtt9c0,16,6,1|h4m5bz,16,6,1|h4m5c0,15,11,0|hcjbzz,15,11,0|hcjc00,16,6,1|hnc7zz,16,6,1|hnc800,15,11,0|hv9enz,15,11,0|hv9eo0,16,6,1|i6f9bz,16,6,1|i6f9c0,15,11,0|idzhbz,15,11,0|idzhc0,16,6,1|ip5bzz,16,6,1|ip5c00,15,11,0|iwpjzz,15,11,0|iwpk00,16,6,1|j7venz,16,6,1|j7veo0,15,11,0|jffmnz,15,11,0|jffmo0,16,6,1|jqlhbz,16,6,1|jqlhc0,15,11,0|jyinzz,15,11,0|jyio00,16,6,1|k9bjzz,16,6,1|k9bk00,15,11,0|kh8qnz,15,11,0|kh8qo0,16,6,1|ks1mnz,16,6,1|ks1mo0,15,11,0|kzytbz,15,11,0|kzytc0,16,6,1|lb4nzz,16,6,1|lb4o00,15,11,0|liovzz,15,11,0|liow00,100,6,0\",\"Europe/Monaco|,0,358,0|-14hnyp8,7,9,0|-uo2b3m,7,9,0|-uo2b3l,8,1,0|-ry2lg1,8,1,0|-ry2lg0,9,10,1|-rsgqs1,9,10,1|-rsgqs0,8,1,0|-rjiis1,8,1,0|-rjiis0,9,10,1|-r9dpg1,9,10,1|-r9dpg0,8,1,0|-r1idg1,8,1,0|-r1idg0,9,10,1|-qqnms1,9,10,1|-qqnms0,8,1,0|-qj59g1,8,1,0|-qj59g0,9,10,1|-q7xk41,9,10,1|-q7xk40,8,1,0|-q15441,8,1,0|-q15440,9,10,1|-po6g41,9,10,1|-po6g40,8,1,0|-pgvhg1,8,1,0|-pgvhg0,9,10,1|-p5atg1,9,10,1|-p5atg0,8,1,0|-oxj6s1,8,1,0|-oxj6s0,9,10,1|-ong841,9,10,1|-ong840,8,1,0|-obkg41,8,1,0|-obkg40,9,10,1|-o4q5g1,9,10,1|-o4q5g0,8,1,0|-nvq2s1,8,1,0|-nvq2s0,9,10,1|-nm02s1,9,10,1|-nm02s0,8,1,0|-ncn1g1,8,1,0|-ncn1g0,9,10,1|-n3a041,9,10,1|-n3a040,8,1,0|-mt71g1,8,1,0|-mt71g0,9,10,1|-mkjxg1,9,10,1|-mkjxg0,8,1,0|-matxg1,8,1,0|-matxg0,9,10,1|-m1tus1,9,10,1|-m1tus0,8,1,0|-lrqw41,8,1,0|-lrqw40,9,10,1|-liqtg1,9,10,1|-liqtg0,8,1,0|-l8nus1,8,1,0|-l8nus0,9,10,1|-l00qs1,9,10,1|-l00qs0,8,1,0|-kqaqs1,8,1,0|-kqaqs0,9,10,1|-khao41,9,10,1|-khao40,8,1,0|-k77pg1,8,1,0|-k77pg0,9,10,1|-jyklg1,9,10,1|-jyklg0,8,1,0|-jp7k41,8,1,0|-jp7k40,9,10,1|-jfuis1,9,10,1|-jfuis0,8,1,0|-j6ug41,8,1,0|-j6ug40,9,10,1|-iwrhg1,9,10,1|-iwrhg0,8,1,0|-ineg41,8,1,0|-ineg40,9,10,1|-ie1es1,9,10,1|-ie1es0,8,1,0|-i51c41,8,1,0|-i51c40,9,10,1|-hvbc41,9,10,1|-hvbc40,8,1,0|-hl8dg1,8,1,0|-hl8dg0,9,10,1|-hcl9g1,9,10,1|-hcl9g0,8,1,0|-h38841,8,1,0|-h38840,9,10,1|-gtv6s1,9,10,1|-gtv6s0,8,1,0|-gkv441,8,1,0|-gkv440,9,10,1|-gb5441,9,10,1|-gb5440,8,1,0|-g125g1,8,1,0|-g125g0,9,10,1|-fpwas1,9,10,1|-fpwas0,8,1,0|-fkul41,8,1,0|-fkul40,9,10,1|-eyh9g1,9,10,1|-eyh9g0,152,11,1|-eqk5k1,152,11,1|-eqk5k0,9,10,1|-eimw41,9,10,1|-eimw40,152,11,1|-e6dzw1,152,11,1|-e6dzw0,9,10,1|-dytrw1,9,10,1|-dytrw0,152,11,1|-dp3rw1,152,11,1|-dp3rw0,9,10,1|-dfqqk1,9,10,1|-dfqqk0,152,11,1|-d62qs1,152,11,1|-d62qs0,9,10,1|-cx0nw1,9,10,1|-cx0nw0,152,11,1|-cofek1,152,11,1|-cofek0,10,10,0|396inz,10,10,0|396io0,11,11,1|3ijh7z,11,11,1|3ijh80,10,10,0|3s9mrz,10,10,0|3s9ms0,11,11,1|419pfz,11,11,1|419pg0,10,10,0|4azpfz,10,10,0|4azpg0,11,11,1|4kcqrz,11,11,1|4kcqs0,10,10,0|4tps3z,10,10,0|4tps40,11,11,1|532tfz,11,11,1|532tg0,10,10,0|5cstfz,10,10,0|5cstg0,11,11,1|5lsw3z,11,11,1|5lsw40,10,10,0|5v5xfz,10,10,0|5v5xg0,11,11,1|64iyrz,11,11,1|64iys0,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Moscow|,0,359,0|-1ayy9mh,21,359,0|-rx5dmi,21,359,0|-rx5dmh,21,360,0|-refds8,21,360,0|-refds7,50,361,1|-r57wg8,50,361,1|-r57wg7,21,360,0|-qx8xw8,21,360,0|-qx8xw7,153,362,1|-qrqps8,153,362,1|-qrqps7,50,361,1|-qeh0k8,50,361,1|-qeh0k7,153,362,1|-qcx401,153,362,1|-qcx400,149,209,1|-qak8g1,149,209,1|-qak8g0,148,6,0|-pibkg1,148,6,0|-pibkg0,149,209,1|-pgkok1,149,209,1|-pgkok0,92,194,1|-p84z81,92,194,1|-p84z80,149,209,1|-p6lcg1,149,209,1|-p6lcg0,148,6,0|-ontcc1,148,6,0|-ontcc0,15,11,0|-kmr1k1,15,11,0|-kmr1k0,148,6,0|5vb6bz,148,6,0|5vb6c0,149,209,1|64pzjz,149,209,1|64pzk0,148,6,0|6e33nz,148,6,0|6e33o0,149,209,1|6nhwvz,149,209,1|6nhww0,148,6,0|6wv0zz,148,6,0|6wv100,149,209,1|769u7z,149,209,1|769u80,148,6,0|7foszz,148,6,0|7fot00,149,209,1|7p1zvz,149,209,1|7p1zw0,148,6,0|7yf17z,148,6,0|7yf180,149,209,1|87s2jz,149,209,1|87s2k0,148,6,0|8h53vz,148,6,0|8h53w0,149,209,1|8qi57z,149,209,1|8qi580,148,6,0|8zv6jz,148,6,0|8zv6k0,149,209,1|9987vz,149,209,1|9987w0,148,6,0|9il97z,148,6,0|9il980,149,209,1|9ryajz,149,209,1|9ryak0,148,6,0|a1bbvz,148,6,0|a1bbw0,149,209,1|aaod7z,149,209,1|aaod80,148,6,0|ak1ejz,148,6,0|ak1ek0,149,209,1|atrejz,149,209,1|atrek0,148,6,0|b34fvz,148,6,0|b34fw0,16,6,1|bchjzz,16,6,1|bchk00,15,11,0|bi8ynz,15,11,0|bi8yo0,148,6,0|bluijz,148,6,0|bluik0,149,209,1|bv7jvz,149,209,1|bv7jw0,148,6,0|c4kl7z,148,6,0|c4kl80,149,209,1|cdxmjz,149,209,1|cdxmk0,148,6,0|cnanvz,148,6,0|cnanw0,149,209,1|cwnp7z,149,209,1|cwnp80,148,6,0|d60qjz,148,6,0|d60qk0,149,209,1|dfdrvz,149,209,1|dfdrw0,148,6,0|dp3rvz,148,6,0|dp3rw0,149,209,1|dzwnvz,149,209,1|dzwnw0,148,6,0|e7tujz,148,6,0|e7tuk0,149,209,1|eimqjz,149,209,1|eimqk0,148,6,0|eqjx7z,148,6,0|eqjx80,149,209,1|f1ct7z,149,209,1|f1ct80,148,6,0|f99zvz,148,6,0|f99zw0,149,209,1|fkfujz,149,209,1|fkfuk0,148,6,0|fs02jz,148,6,0|fs02k0,149,209,1|g35x7z,149,209,1|g35x80,148,6,0|gaq57z,148,6,0|gaq580,149,209,1|glvzvz,149,209,1|glvzw0,148,6,0|gtt6jz,148,6,0|gtt6k0,149,209,1|h4m2jz,149,209,1|h4m2k0,148,6,0|hcj97z,148,6,0|hcj980,149,209,1|hnc57z,149,209,1|hnc580,148,6,0|hv9bvz,148,6,0|hv9bw0,149,209,1|i6f6jz,149,209,1|i6f6k0,148,6,0|idzejz,148,6,0|idzek0,149,209,1|ip597z,149,209,1|ip5980,148,6,0|iwph7z,148,6,0|iwph80,149,209,1|j7vbvz,149,209,1|j7vbw0,148,6,0|jffjvz,148,6,0|jffjw0,149,209,1|jqlejz,149,209,1|jqlek0,148,6,0|jyil7z,148,6,0|jyil80,149,209,1|k9bh7z,149,209,1|k9bh80,148,6,0|kh8nvz,148,6,0|kh8nw0,149,209,1|ks1jvz,149,209,1|ks1jw0,148,6,0|kzyqjz,148,6,0|kzyqk0,149,209,1|lb4l7z,149,209,1|lb4l80,148,6,0|liot7z,148,6,0|liot80,148,209,0|ne0t3z,148,209,0|ne0t40,148,6,0\",\"Europe/Oslo|,0,202,0|-1353tzo,10,10,0|-rzayo1,10,10,0|-rzayo0,11,11,1|-rskiw1,11,11,1|-rskiw0,10,10,0|-fc7s81,10,10,0|-fc7s80,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d6dp81,11,11,1|-d6dp80,10,10,0|-cx0nw1,10,10,0|-cx0nw0,11,11,1|-cnnmk1,11,11,1|-cnnmk0,10,10,0|-5mxh81,10,10,0|-5mxh80,11,11,1|-5d7h81,11,11,1|-5d7h80,10,10,0|-53ufw1,10,10,0|-53ufw0,11,11,1|-4uhek1,11,11,1|-4uhek0,10,10,0|-4l4d81,10,10,0|-4l4d80,11,11,1|-4brbw1,11,11,1|-4brbw0,10,10,0|-42eak1,10,10,0|-42eak0,11,11,1|-3t1981,11,11,1|-3t1980,10,10,0|-3jo7w1,10,10,0|-3jo7w0,11,11,1|-3ab6k1,11,11,1|-3ab6k0,10,10,0|-30y581,10,10,0|-30y580,11,11,1|-2r8581,11,11,1|-2r8580,10,10,0|-2g2ak1,10,10,0|-2g2ak0,11,11,1|-28i2k1,11,11,1|-28i2k0,10,10,0|5cstfz,10,10,0|5cstg0,11,11,1|5lsw3z,11,11,1|5lsw40,10,10,0|5v5xfz,10,10,0|5v5xg0,11,11,1|64iyrz,11,11,1|64iys0,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Paris|,0,9,0|-154gb3l,7,9,0|-uozn3m,7,9,0|-uozn3l,8,1,0|-ry2lg1,8,1,0|-ry2lg0,9,10,1|-rsgqs1,9,10,1|-rsgqs0,8,1,0|-rjiis1,8,1,0|-rjiis0,9,10,1|-r9dpg1,9,10,1|-r9dpg0,8,1,0|-r1idg1,8,1,0|-r1idg0,9,10,1|-qqnms1,9,10,1|-qqnms0,8,1,0|-qj59g1,8,1,0|-qj59g0,9,10,1|-q7xk41,9,10,1|-q7xk40,8,1,0|-q15441,8,1,0|-q15440,9,10,1|-po6g41,9,10,1|-po6g40,8,1,0|-pgvhg1,8,1,0|-pgvhg0,9,10,1|-p5atg1,9,10,1|-p5atg0,8,1,0|-oxj6s1,8,1,0|-oxj6s0,9,10,1|-ong841,9,10,1|-ong840,8,1,0|-obkg41,8,1,0|-obkg40,9,10,1|-o4q5g1,9,10,1|-o4q5g0,8,1,0|-nvq2s1,8,1,0|-nvq2s0,9,10,1|-nm02s1,9,10,1|-nm02s0,8,1,0|-ncn1g1,8,1,0|-ncn1g0,9,10,1|-n3a041,9,10,1|-n3a040,8,1,0|-mt71g1,8,1,0|-mt71g0,9,10,1|-mkjxg1,9,10,1|-mkjxg0,8,1,0|-matxg1,8,1,0|-matxg0,9,10,1|-m1tus1,9,10,1|-m1tus0,8,1,0|-lrqw41,8,1,0|-lrqw40,9,10,1|-liqtg1,9,10,1|-liqtg0,8,1,0|-l8nus1,8,1,0|-l8nus0,9,10,1|-l00qs1,9,10,1|-l00qs0,8,1,0|-kqaqs1,8,1,0|-kqaqs0,9,10,1|-khao41,9,10,1|-khao40,8,1,0|-k77pg1,8,1,0|-k77pg0,9,10,1|-jyklg1,9,10,1|-jyklg0,8,1,0|-jp7k41,8,1,0|-jp7k40,9,10,1|-jfuis1,9,10,1|-jfuis0,8,1,0|-j6ug41,8,1,0|-j6ug40,9,10,1|-iwrhg1,9,10,1|-iwrhg0,8,1,0|-ineg41,8,1,0|-ineg40,9,10,1|-ie1es1,9,10,1|-ie1es0,8,1,0|-i51c41,8,1,0|-i51c40,9,10,1|-hvbc41,9,10,1|-hvbc40,8,1,0|-hl8dg1,8,1,0|-hl8dg0,9,10,1|-hcl9g1,9,10,1|-hcl9g0,8,1,0|-h38841,8,1,0|-h38840,9,10,1|-gtv6s1,9,10,1|-gtv6s0,8,1,0|-gkv441,8,1,0|-gkv440,9,10,1|-gb5441,9,10,1|-gb5440,8,1,0|-g125g1,8,1,0|-g125g0,9,10,1|-fpwas1,9,10,1|-fpwas0,8,1,0|-fkul41,8,1,0|-fkul40,9,10,1|-ff5c81,9,10,1|-ff5c80,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d8caw1,11,11,1|-d8caw0,152,11,1|-d62qs1,152,11,1|-d62qs0,9,10,1|-cx0nw1,9,10,1|-cx0nw0,152,11,1|-cofek1,152,11,1|-cofek0,10,10,0|396inz,10,10,0|396io0,11,11,1|3ijh7z,11,11,1|3ijh80,10,10,0|3s9mrz,10,10,0|3s9ms0,11,11,1|419pfz,11,11,1|419pg0,10,10,0|4azpfz,10,10,0|4azpg0,11,11,1|4kcqrz,11,11,1|4kcqs0,10,10,0|4tps3z,10,10,0|4tps40,11,11,1|532tfz,11,11,1|532tg0,10,10,0|5cstfz,10,10,0|5cstg0,11,11,1|5lsw3z,11,11,1|5lsw40,10,10,0|5v5xfz,10,10,0|5v5xg0,11,11,1|64iyrz,11,11,1|64iys0,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Podgorica|,0,332,0|-18vsmgo,10,10,0|-ezayw1,10,10,0|-ezayw0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d6dp81,11,11,1|-d6dp80,10,10,0|-cv5zw1,10,10,0|-cv5zw0,11,11,1|-cofek1,11,11,1|-cofek0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Prague|,0,334,0|-1qmkw08,7,334,0|-14u7uo9,7,334,0|-14u7uo8,10,10,0|-s0e081,10,10,0|-s0e080,11,11,1|-rsilg1,11,11,1|-rsilg0,10,10,0|-ridmk1,10,10,0|-ridmk0,11,11,1|-ragfw1,11,11,1|-ragfw0,10,10,0|-qznjw1,10,10,0|-qznjw0,11,11,1|-qrqd81,11,11,1|-qrqd80,10,10,0|-fizzw1,10,10,0|-fizzw0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d6dp81,11,11,1|-d6dp80,10,10,0|-cx0nw1,10,10,0|-cx0nw0,11,11,1|-cnnmk1,11,11,1|-cnnmk0,10,10,0|-cchrw1,10,10,0|-cchrw0,11,11,1|-c4mfw1,11,11,1|-c4mfw0,10,10,0|-c1qns1,10,10,0|-c1qns0,1,1,1|-bxf3s1,1,1,1|-bxf3s0,10,10,0|-bujh81,10,10,0|-bujh80,11,11,1|-blwd81,11,11,1|-blwd80,10,10,0|-bbtek1,10,10,0|-bbtek0,11,11,1|-b36ak1,11,11,1|-b36ak0,10,10,0|-ati581,10,10,0|-ati580,11,11,1|-akg7w1,11,11,1|-akg7w0,10,10,0|4tps3z,10,10,0|4tps40,11,11,1|532tfz,11,11,1|532tg0,10,10,0|5cstfz,10,10,0|5cstg0,11,11,1|5lsw3z,11,11,1|5lsw40,10,10,0|5v5xfz,10,10,0|5v5xg0,11,11,1|64iyrz,11,11,1|64iys0,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Riga|,0,363,0|-1ayy74y,136,363,0|-qznlkz,136,363,0|-qznlky,154,364,1|-qrqewz,154,364,1|-qrqewy,136,363,0|-qhllkz,136,363,0|-qhllky,154,364,1|-qez5kz,154,364,1|-qez5ky,136,363,0|-ms0hsz,136,363,0|-ms0hsy,15,11,0|-fciw81,15,11,0|-fciw80,148,6,0|-evjv01,148,6,0|-evjv00,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d6dp81,11,11,1|-d6dp80,10,10,0|-d5thg1,10,10,0|-d5thg0,148,6,0|5vb6bz,148,6,0|5vb6c0,149,209,1|64pzjz,149,209,1|64pzk0,148,6,0|6e33nz,148,6,0|6e33o0,149,209,1|6nhwvz,149,209,1|6nhww0,148,6,0|6wv0zz,148,6,0|6wv100,149,209,1|769u7z,149,209,1|769u80,148,6,0|7foszz,148,6,0|7fot00,149,209,1|7p1zvz,149,209,1|7p1zw0,148,6,0|7yf17z,148,6,0|7yf180,149,209,1|87s2jz,149,209,1|87s2k0,148,6,0|8h53vz,148,6,0|8h53w0,149,209,1|8qi57z,149,209,1|8qi580,148,6,0|8zv6jz,148,6,0|8zv6k0,149,209,1|9987vz,149,209,1|9987w0,148,6,0|9il97z,148,6,0|9il980,149,209,1|9ryajz,149,209,1|9ryak0,148,6,0|a1bbvz,148,6,0|a1bbw0,16,6,1|aaofzz,16,6,1|aaog00,15,11,0|ak1hbz,15,11,0|ak1hc0,16,6,1|atrhbz,16,6,1|atrhc0,15,11,0|b34inz,15,11,0|b34io0,16,6,1|bchjzz,16,6,1|bchk00,15,11,0|blulbz,15,11,0|blulc0,16,6,1|bv7mnz,16,6,1|bv7mo0,15,11,0|c4knzz,15,11,0|c4ko00,16,6,1|cdxpbz,16,6,1|cdxpc0,15,11,0|cnaqnz,15,11,0|cnaqo0,16,6,1|cwnrzz,16,6,1|cwns00,15,11,0|d60tbz,15,11,0|d60tc0,16,6,1|dfdunz,16,6,1|dfduo0,15,11,0|dp3unz,15,11,0|dp3uo0,16,6,1|dygvzz,16,6,1|dygw00,15,11,0|e7u03z,15,11,0|e7u040,16,6,1|eimw3z,16,6,1|eimw40,15,11,0|eqk2rz,15,11,0|eqk2s0,16,6,1|f1cyrz,16,6,1|f1cys0,15,11,0|f9a5fz,15,11,0|f9a5g0,16,6,1|fkg03z,16,6,1|fkg040,15,11,0|gaqarz,15,11,0|gaqas0,16,6,1|glw5fz,16,6,1|glw5g0,15,11,0|gttc3z,15,11,0|gttc40,16,6,1|h4m83z,16,6,1|h4m840,15,11,0|hcjerz,15,11,0|hcjes0,16,6,1|hncarz,16,6,1|hncas0,15,11,0|hv9hfz,15,11,0|hv9hg0,16,6,1|i6fc3z,16,6,1|i6fc40,15,11,0|idzk3z,15,11,0|idzk40,16,6,1|ip5erz,16,6,1|ip5es0,15,11,0|iwpmrz,15,11,0|iwpms0,16,6,1|j7vhfz,16,6,1|j7vhg0,15,11,0|jffpfz,15,11,0|jffpg0,16,6,1|jqlk3z,16,6,1|jqlk40,15,11,0|jyiqrz,15,11,0|jyiqs0,16,6,1|k9bmrz,16,6,1|k9bms0,15,11,0|kh8tfz,15,11,0|kh8tg0,16,6,1|ks1pfz,16,6,1|ks1pg0,15,11,0|kzyw3z,15,11,0|kzyw40,16,6,1|lb4qrz,16,6,1|lb4qs0,15,11,0|lioyrz,15,11,0|lioys0,16,6,1|ltutfz,16,6,1|ltutg0,15,11,0|m1f1fz,15,11,0|m1f1g0,16,6,1|mckw3z,16,6,1|mckw40,15,11,0|mki2rz,15,11,0|mki2s0,16,6,1|mvayrz,16,6,1|mvays0,15,11,0|n385fz,15,11,0|n385g0,16,6,1|ne11fz,16,6,1|ne11g0,15,11,0|nly83z,15,11,0|nly840,16,6,1|nwr43z,16,6,1|nwr440,15,11,0|o4oarz,15,11,0|o4oas0,16,6,1|ofu5fz,16,6,1|ofu5g0,15,11,0|onedfz,15,11,0|onedg0,16,6,1|oyk83z,16,6,1|oyk840,15,11,0|p64g3z,15,11,0|p64g40,16,6,1|phaarz,16,6,1|phaas0,15,11,0|pp7hfz,15,11,0|pp7hg0,16,6,1|q00dfz,16,6,1|q00dg0,15,11,0|q7xk3z,15,11,0|q7xk40,16,6,1|qiqg3z,16,6,1|qiqg40,15,11,0|qqnmrz,15,11,0|qqnms0,16,6,1|r1thfz,16,6,1|r1thg0,15,11,0|r9dpfz,15,11,0|r9dpg0,16,6,1|rkjk3z,16,6,1|rkjk40,15,11,0|rs3s3z,15,11,0|rs3s40,16,6,1|s39mrz,16,6,1|s39ms0,15,11,0|sb6tfz,15,11,0|sb6tg0,16,6,1|slzpfz,16,6,1|slzpg0,15,11,0|stww3z,15,11,0|stww40,16,6,1|t4ps3z,16,6,1|t4ps40,15,11,0|tcmyrz,15,11,0|tcmys0,16,6,1|tnfurz,16,6,1|tnfus0,15,11,0|tvd1fz,15,11,0|tvd1g0,16,6,1|u6iw3z,16,6,1|u6iw40,15,11,0|ue343z,15,11,0|ue3440,16,6,1|up8yrz,16,6,1|up8ys0,15,11,0|uwt6rz,15,11,0|uwt6s0,16,6,1|v7z1fz,16,6,1|v7z1g0,15,11,0|vfw83z,15,11,0|vfw840,16,6,1|vqp43z,16,6,1|vqp440,15,11,0|vymarz,15,11,0|vymas0,16,6,1|w9f6rz,16,6,1|w9f6s0,15,11,0|whcdfz,15,11,0|whcdg0,16,6,1|wsi83z,16,6,1|wsi840,15,11,0|x02g3z,15,11,0|x02g40,16,6,1|xb8arz,16,6,1|xb8as0,15,11,0|xisirz,15,11,0|xisis0,16,6,1|xtydfz,16,6,1|xtydg0,15,11,0|y1ilfz,15,11,0|y1ilg0,16,6,1|ycog3z,16,6,1|ycog40,15,11,0|yklmrz,15,11,0|yklms0,16,6,1|yveirz,16,6,1|yveis0,15,11,0|z3bpfz,15,11,0|z3bpg0,16,6,1|ze4lfz,16,6,1|ze4lg0,15,11,0\",\"Europe/Rome|,0,365,0|-1hs7rn8,136,365,0|-13r0qs1,136,365,0|-13r0qs0,10,10,0|-rymys1,10,10,0|-rymys0,11,11,1|-rsio81,11,11,1|-rsio80,10,10,0|-rj5k41,10,10,0|-rj5k40,11,11,1|-r9qqw1,11,11,1|-r9qqw0,10,10,0|-r1idg1,10,10,0|-r1idg0,11,11,1|-qqnpk1,11,11,1|-qqnpk0,10,10,0|-qj59g1,10,10,0|-qj59g0,11,11,1|-q7zhk1,11,11,1|-q7zhk0,10,10,0|-pzcas1,10,10,0|-pzcas0,11,11,1|-ppzc81,11,11,1|-ppzc80,10,10,0|-ff59g1,10,10,0|-ff59g0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d75h81,11,11,1|-d75h80,10,10,0|-cx0nw1,10,10,0|-cx0nw0,11,11,1|-cohes1,11,11,1|-cohes0,10,10,0|-cf2d81,10,10,0|-cf2d80,11,11,1|-c4mfw1,11,11,1|-c4mfw0,10,10,0|-bwcg41,10,10,0|-bwcg40,11,11,1|-blwis1,11,11,1|-blwis0,10,10,0|-bec581,10,10,0|-bec580,11,11,1|-b36ak1,11,11,1|-b36ak0,10,10,0|-1vwis1,10,10,0|-1vwis0,11,11,1|-1pf9k1,11,11,1|-1pf9k0,10,10,0|-1cthg1,10,10,0|-1cthg0,11,11,1|-16p441,11,11,1|-16p440,10,10,0|-u3es1,10,10,0|-u3es0,11,11,1|-nz1g1,11,11,1|-nz1g0,10,10,0|-b0dg1,10,10,0|-b0dg0,11,11,1|-4w041,11,11,1|-4w040,10,10,0|7pp7z,10,10,0|7pp80,11,11,1|du2jz,11,11,1|du2k0,10,10,0|q2t7z,10,10,0|q2t80,11,11,1|wk57z,11,11,1|wk580,10,10,0|195ujz,10,10,0|195uk0,11,11,1|1fn6jz,11,11,1|1fn6k0,10,10,0|1s8vvz,10,10,0|1s8vw0,11,11,1|1yd97z,11,11,1|1yd980,10,10,0|2alzvz,10,10,0|2alzw0,11,11,1|2h3bvz,11,11,1|2h3bw0,10,10,0|2tp17z,10,10,0|2tp180,11,11,1|2ztejz,11,11,1|2ztek0,10,10,0|3cf3vz,10,10,0|3cf3w0,11,11,1|3ijh7z,11,11,1|3ijh80,10,10,0|3us7vz,10,10,0|3us7w0,11,11,1|419jvz,11,11,1|419jw0,10,10,0|4dv97z,10,10,0|4dv980,11,11,1|4kcl7z,11,11,1|4kcl80,10,10,0|4wlbvz,10,10,0|4wlbw0,11,11,1|532nvz,11,11,1|532nw0,10,10,0|5cstfz,10,10,0|5cstg0,11,11,1|5lsw3z,11,11,1|5lsw40,10,10,0|5v5xfz,10,10,0|5v5xg0,11,11,1|64iyrz,11,11,1|64iys0,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Samara|,0,366,0|-qcx400,100,6,0|-kmr4c1,100,6,0|-kmr4c0,105,209,0|5vb3jz,105,209,0|5vb3k0,92,194,1|64pwrz,92,194,1|64pws0,105,209,0|6e30vz,105,209,0|6e30w0,92,194,1|6nhu3z,92,194,1|6nhu40,105,209,0|6wuy7z,105,209,0|6wuy80,92,194,1|769rfz,92,194,1|769rg0,105,209,0|7foq7z,105,209,0|7foq80,92,194,1|7p1x3z,92,194,1|7p1x40,105,209,0|7yeyfz,105,209,0|7yeyg0,92,194,1|87rzrz,92,194,1|87rzs0,105,209,0|8h513z,105,209,0|8h5140,92,194,1|8qi2fz,92,194,1|8qi2g0,105,209,0|8zv3rz,105,209,0|8zv3s0,92,194,1|99853z,92,194,1|998540,105,209,0|9il6fz,105,209,0|9il6g0,92,194,1|9ry7rz,92,194,1|9ry7s0,105,209,0|a1b93z,105,209,0|a1b940,105,209,1|aaod7z,105,209,1|aaod80,100,6,0|ak1ejz,100,6,0|ak1ek0,105,209,1|atrejz,105,209,1|atrek0,100,6,0|b34fvz,100,6,0|b34fw0,100,6,1|bchjzz,100,6,1|bchk00,100,6,0|bdkfzz,100,6,0|bdkg00,105,209,0|blufrz,105,209,0|blufs0,92,194,1|bv7h3z,92,194,1|bv7h40,105,209,0|c4kifz,105,209,0|c4kig0,92,194,1|cdxjrz,92,194,1|cdxjs0,105,209,0|cnal3z,105,209,0|cnal40,92,194,1|cwnmfz,92,194,1|cwnmg0,105,209,0|d60nrz,105,209,0|d60ns0,92,194,1|dfdp3z,92,194,1|dfdp40,105,209,0|dp3p3z,105,209,0|dp3p40,92,194,1|dzwl3z,92,194,1|dzwl40,105,209,0|e7trrz,105,209,0|e7trs0,92,194,1|eimnrz,92,194,1|eimns0,105,209,0|eqjufz,105,209,0|eqjug0,92,194,1|f1cqfz,92,194,1|f1cqg0,105,209,0|f99x3z,105,209,0|f99x40,92,194,1|fkfrrz,92,194,1|fkfrs0,105,209,0|frzzrz,105,209,0|frzzs0,92,194,1|g35ufz,92,194,1|g35ug0,105,209,0|gaq2fz,105,209,0|gaq2g0,92,194,1|glvx3z,92,194,1|glvx40,105,209,0|gtt3rz,105,209,0|gtt3s0,92,194,1|h4lzrz,92,194,1|h4lzs0,105,209,0|hcj6fz,105,209,0|hcj6g0,92,194,1|hnc2fz,92,194,1|hnc2g0,105,209,0|hv993z,105,209,0|hv9940,92,194,1|i6f3rz,92,194,1|i6f3s0,105,209,0|idzbrz,105,209,0|idzbs0,92,194,1|ip56fz,92,194,1|ip56g0,105,209,0|iwpefz,105,209,0|iwpeg0,92,194,1|j7v93z,92,194,1|j7v940,105,209,0|jffh3z,105,209,0|jffh40,92,194,1|jqlbrz,92,194,1|jqlbs0,105,209,0|jyiifz,105,209,0|jyiig0,92,194,1|k9befz,92,194,1|k9beg0,105,209,0|kh8l3z,105,209,0|kh8l40,92,194,1|ks1h3z,92,194,1|ks1h40,105,209,0|kzynrz,105,209,0|kzyns0,105,209,1|lb4l7z,105,209,1|lb4l80,100,6,0|liot7z,100,6,0|liot80,105,209,0\",\"Europe/San_Marino|,0,365,0|-1hs7rn8,136,365,0|-13r0qs1,136,365,0|-13r0qs0,10,10,0|-rymys1,10,10,0|-rymys0,11,11,1|-rsio81,11,11,1|-rsio80,10,10,0|-rj5k41,10,10,0|-rj5k40,11,11,1|-r9qqw1,11,11,1|-r9qqw0,10,10,0|-r1idg1,10,10,0|-r1idg0,11,11,1|-qqnpk1,11,11,1|-qqnpk0,10,10,0|-qj59g1,10,10,0|-qj59g0,11,11,1|-q7zhk1,11,11,1|-q7zhk0,10,10,0|-pzcas1,10,10,0|-pzcas0,11,11,1|-ppzc81,11,11,1|-ppzc80,10,10,0|-ff59g1,10,10,0|-ff59g0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d75h81,11,11,1|-d75h80,10,10,0|-cx0nw1,10,10,0|-cx0nw0,11,11,1|-cohes1,11,11,1|-cohes0,10,10,0|-cf2d81,10,10,0|-cf2d80,11,11,1|-c4mfw1,11,11,1|-c4mfw0,10,10,0|-bwcg41,10,10,0|-bwcg40,11,11,1|-blwis1,11,11,1|-blwis0,10,10,0|-bec581,10,10,0|-bec580,11,11,1|-b36ak1,11,11,1|-b36ak0,10,10,0|-1vwis1,10,10,0|-1vwis0,11,11,1|-1pf9k1,11,11,1|-1pf9k0,10,10,0|-1cthg1,10,10,0|-1cthg0,11,11,1|-16p441,11,11,1|-16p440,10,10,0|-u3es1,10,10,0|-u3es0,11,11,1|-nz1g1,11,11,1|-nz1g0,10,10,0|-b0dg1,10,10,0|-b0dg0,11,11,1|-4w041,11,11,1|-4w040,10,10,0|7pp7z,10,10,0|7pp80,11,11,1|du2jz,11,11,1|du2k0,10,10,0|q2t7z,10,10,0|q2t80,11,11,1|wk57z,11,11,1|wk580,10,10,0|195ujz,10,10,0|195uk0,11,11,1|1fn6jz,11,11,1|1fn6k0,10,10,0|1s8vvz,10,10,0|1s8vw0,11,11,1|1yd97z,11,11,1|1yd980,10,10,0|2alzvz,10,10,0|2alzw0,11,11,1|2h3bvz,11,11,1|2h3bw0,10,10,0|2tp17z,10,10,0|2tp180,11,11,1|2ztejz,11,11,1|2ztek0,10,10,0|3cf3vz,10,10,0|3cf3w0,11,11,1|3ijh7z,11,11,1|3ijh80,10,10,0|3us7vz,10,10,0|3us7w0,11,11,1|419jvz,11,11,1|419jw0,10,10,0|4dv97z,10,10,0|4dv980,11,11,1|4kcl7z,11,11,1|4kcl80,10,10,0|4wlbvz,10,10,0|4wlbw0,11,11,1|532nvz,11,11,1|532nw0,10,10,0|5cstfz,10,10,0|5cstg0,11,11,1|5lsw3z,11,11,1|5lsw40,10,10,0|5v5xfz,10,10,0|5v5xg0,11,11,1|64iyrz,11,11,1|64iys0,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Sarajevo|,0,332,0|-18vsmgo,10,10,0|-ezayw1,10,10,0|-ezayw0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d6dp81,11,11,1|-d6dp80,10,10,0|-cv5zw1,10,10,0|-cv5zw0,11,11,1|-cofek1,11,11,1|-cofek0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Saratov|,0,367,0|-qcx400,100,6,0|-kmr4c1,100,6,0|-kmr4c0,105,209,0|5vb3jz,105,209,0|5vb3k0,92,194,1|64pwrz,92,194,1|64pws0,105,209,0|6e30vz,105,209,0|6e30w0,92,194,1|6nhu3z,92,194,1|6nhu40,105,209,0|6wuy7z,105,209,0|6wuy80,92,194,1|769rfz,92,194,1|769rg0,105,209,0|7foq7z,105,209,0|7foq80,92,194,1|7p1x3z,92,194,1|7p1x40,105,209,0|7yeyfz,105,209,0|7yeyg0,92,194,1|87rzrz,92,194,1|87rzs0,105,209,0|8h513z,105,209,0|8h5140,92,194,1|8qi2fz,92,194,1|8qi2g0,105,209,0|8zv3rz,105,209,0|8zv3s0,92,194,1|99853z,92,194,1|998540,105,209,0|9il6fz,105,209,0|9il6g0,105,209,1|9ryajz,105,209,1|9ryak0,100,6,0|a1bbvz,100,6,0|a1bbw0,105,209,1|aaod7z,105,209,1|aaod80,100,6,0|ak1ejz,100,6,0|ak1ek0,105,209,1|atrejz,105,209,1|atrek0,100,6,0|b34fvz,100,6,0|b34fw0,105,209,0|blufrz,105,209,0|blufs0,105,209,1|bv7jvz,105,209,1|bv7jw0,100,6,0|c4kl7z,100,6,0|c4kl80,105,209,1|cdxmjz,105,209,1|cdxmk0,100,6,0|cnanvz,100,6,0|cnanw0,105,209,1|cwnp7z,105,209,1|cwnp80,100,6,0|d60qjz,100,6,0|d60qk0,105,209,1|dfdrvz,105,209,1|dfdrw0,100,6,0|dp3rvz,100,6,0|dp3rw0,105,209,1|dzwnvz,105,209,1|dzwnw0,100,6,0|e7tujz,100,6,0|e7tuk0,105,209,1|eimqjz,105,209,1|eimqk0,100,6,0|eqjx7z,100,6,0|eqjx80,105,209,1|f1ct7z,105,209,1|f1ct80,100,6,0|f99zvz,100,6,0|f99zw0,105,209,1|fkfujz,105,209,1|fkfuk0,100,6,0|fs02jz,100,6,0|fs02k0,105,209,1|g35x7z,105,209,1|g35x80,100,6,0|gaq57z,100,6,0|gaq580,105,209,1|glvzvz,105,209,1|glvzw0,100,6,0|gtt6jz,100,6,0|gtt6k0,105,209,1|h4m2jz,105,209,1|h4m2k0,100,6,0|hcj97z,100,6,0|hcj980,105,209,1|hnc57z,105,209,1|hnc580,100,6,0|hv9bvz,100,6,0|hv9bw0,105,209,1|i6f6jz,105,209,1|i6f6k0,100,6,0|idzejz,100,6,0|idzek0,105,209,1|ip597z,105,209,1|ip5980,100,6,0|iwph7z,100,6,0|iwph80,105,209,1|j7vbvz,105,209,1|j7vbw0,100,6,0|jffjvz,100,6,0|jffjw0,105,209,1|jqlejz,105,209,1|jqlek0,100,6,0|jyil7z,100,6,0|jyil80,105,209,1|k9bh7z,105,209,1|k9bh80,100,6,0|kh8nvz,100,6,0|kh8nw0,105,209,1|ks1jvz,105,209,1|ks1jw0,100,6,0|kzyqjz,100,6,0|kzyqk0,105,209,1|lb4l7z,105,209,1|lb4l80,100,6,0|liot7z,100,6,0|liot80,105,209,0|ne0t3z,105,209,0|ne0t40,100,6,0|ohmt7z,100,6,0|ohmt80,105,209,0\",\"Europe/Simferopol|,0,368,0|-1ayy8zc,85,369,0|-nu12ap,85,369,0|-nu12ao,15,11,0|-kmr1k1,15,11,0|-kmr1k0,148,6,0|-ep8301,148,6,0|-ep8300,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-df8g81,11,11,1|-df8g80,148,6,0|5vb6bz,148,6,0|5vb6c0,149,209,1|64pzjz,149,209,1|64pzk0,148,6,0|6e33nz,148,6,0|6e33o0,149,209,1|6nhwvz,149,209,1|6nhww0,148,6,0|6wv0zz,148,6,0|6wv100,149,209,1|769u7z,149,209,1|769u80,148,6,0|7foszz,148,6,0|7fot00,149,209,1|7p1zvz,149,209,1|7p1zw0,148,6,0|7yf17z,148,6,0|7yf180,149,209,1|87s2jz,149,209,1|87s2k0,148,6,0|8h53vz,148,6,0|8h53w0,149,209,1|8qi57z,149,209,1|8qi580,148,6,0|8zv6jz,148,6,0|8zv6k0,149,209,1|9987vz,149,209,1|9987w0,148,6,0|9il97z,148,6,0|9il980,149,209,1|9ryajz,149,209,1|9ryak0,148,6,0|a1bbvz,148,6,0|a1bbw0,149,209,1|aaod7z,149,209,1|aaod80,148,6,0|ap2vvz,148,6,0|ap2vw0,15,11,0|blufrz,15,11,0|blufs0,16,6,1|bv7ebz,16,6,1|bv7ec0,15,11,0|c4kifz,15,11,0|c4kig0,16,6,1|cdxgzz,16,6,1|cdxh00,15,11,0|cnal3z,15,11,0|cnal40,16,6,1|cp3bnz,16,6,1|cp3bo0,149,209,1|cwngvz,149,209,1|cwngw0,148,6,0|d60kzz,148,6,0|d60l00,149,209,1|dfdjjz,149,209,1|dfdjk0,148,6,0|dp3mbz,148,6,0|dp3mc0,149,209,1|dzwqnz,149,209,1|dzwqo0,148,6,0|e7u03z,148,6,0|e7u040,16,6,1|eimw3z,16,6,1|eimw40,15,11,0|eqk2rz,15,11,0|eqk2s0,16,6,1|f1cyrz,16,6,1|f1cys0,15,11,0|f9a5fz,15,11,0|f9a5g0,16,6,1|fkg03z,16,6,1|fkg040,15,11,0|fs083z,15,11,0|fs0840,16,6,1|g362rz,16,6,1|g362s0,15,11,0|gaqarz,15,11,0|gaqas0,16,6,1|glw5fz,16,6,1|glw5g0,15,11,0|gttc3z,15,11,0|gttc40,16,6,1|h4m83z,16,6,1|h4m840,15,11,0|hcjerz,15,11,0|hcjes0,16,6,1|hncarz,16,6,1|hncas0,15,11,0|hv9hfz,15,11,0|hv9hg0,16,6,1|i6fc3z,16,6,1|i6fc40,15,11,0|idzk3z,15,11,0|idzk40,16,6,1|ip5erz,16,6,1|ip5es0,15,11,0|iwpmrz,15,11,0|iwpms0,16,6,1|j7vhfz,16,6,1|j7vhg0,15,11,0|jffpfz,15,11,0|jffpg0,16,6,1|jqlk3z,16,6,1|jqlk40,15,11,0|jyiqrz,15,11,0|jyiqs0,16,6,1|k9bmrz,16,6,1|k9bms0,15,11,0|kh8tfz,15,11,0|kh8tg0,16,6,1|ks1pfz,16,6,1|ks1pg0,15,11,0|kzyw3z,15,11,0|kzyw40,16,6,1|lb4qrz,16,6,1|lb4qs0,15,11,0|lioyrz,15,11,0|lioys0,16,6,1|ltutfz,16,6,1|ltutg0,15,11,0|m1f1fz,15,11,0|m1f1g0,16,6,1|mckw3z,16,6,1|mckw40,15,11,0|mki2rz,15,11,0|mki2s0,16,6,1|mvayrz,16,6,1|mvays0,15,11,0|n382nz,15,11,0|n382o0,148,209,0|ne0t3z,148,209,0|ne0t40,148,6,0\",\"Europe/Skopje|,0,332,0|-18vsmgo,10,10,0|-ezayw1,10,10,0|-ezayw0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d6dp81,11,11,1|-d6dp80,10,10,0|-cv5zw1,10,10,0|-cv5zw0,11,11,1|-cofek1,11,11,1|-cofek0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Sofia|,0,370,0|-1ayy6zg,117,350,0|-136r6qx,117,350,0|-136r6qw,15,11,0|-e6dzw1,15,11,0|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d6dp81,11,11,1|-d6dp80,10,10,0|-cx0l41,10,10,0|-cx0l40,15,11,0|4tpgzz,15,11,0|4tph00,16,6,1|534frz,16,6,1|534fs0,15,11,0|5csibz,15,11,0|5csic0,16,6,1|5luifz,16,6,1|5luig0,15,11,0|5vikzz,15,11,0|5vil00,16,6,1|64it7z,16,6,1|64it80,15,11,0|6e8nnz,15,11,0|6e8no0,16,6,1|6n8ynz,16,6,1|6n8yo0,15,11,0|6wlzzz,15,11,0|6wm000,16,6,1|75z1bz,16,6,1|75z1c0,15,11,0|7fc2nz,15,11,0|7fc2o0,16,6,1|7p22nz,16,6,1|7p22o0,15,11,0|7yf3zz,15,11,0|7yf400,16,6,1|87s5bz,16,6,1|87s5c0,15,11,0|8h56nz,15,11,0|8h56o0,16,6,1|8qi7zz,16,6,1|8qi800,15,11,0|8zv9bz,15,11,0|8zv9c0,16,6,1|998anz,16,6,1|998ao0,15,11,0|9ilbzz,15,11,0|9ilc00,16,6,1|9rydbz,16,6,1|9rydc0,15,11,0|a1benz,15,11,0|a1beo0,16,6,1|aaofzz,16,6,1|aaog00,15,11,0|ak1hbz,15,11,0|ak1hc0,16,6,1|atrhbz,16,6,1|atrhc0,15,11,0|b34d3z,15,11,0|b34d40,16,6,1|bchbnz,16,6,1|bchbo0,15,11,0|blufrz,15,11,0|blufs0,16,6,1|bv7ebz,16,6,1|bv7ec0,15,11,0|c4kifz,15,11,0|c4kig0,16,6,1|cdxgzz,16,6,1|cdxh00,15,11,0|cnal3z,15,11,0|cnal40,16,6,1|cwnjnz,16,6,1|cwnjo0,15,11,0|d60nrz,15,11,0|d60ns0,16,6,1|dfdmbz,16,6,1|dfdmc0,15,11,0|dp3p3z,15,11,0|dp3p40,16,6,1|dzwibz,16,6,1|dzwic0,15,11,0|e7u03z,15,11,0|e7u040,16,6,1|eimw3z,16,6,1|eimw40,15,11,0|eqk2rz,15,11,0|eqk2s0,16,6,1|f1cyrz,16,6,1|f1cys0,15,11,0|f9a5fz,15,11,0|f9a5g0,16,6,1|fkg03z,16,6,1|fkg040,15,11,0|fs083z,15,11,0|fs0840,16,6,1|g362rz,16,6,1|g362s0,15,11,0|gaqarz,15,11,0|gaqas0,16,6,1|glw5fz,16,6,1|glw5g0,15,11,0|gttc3z,15,11,0|gttc40,16,6,1|h4m83z,16,6,1|h4m840,15,11,0|hcjerz,15,11,0|hcjes0,16,6,1|hncarz,16,6,1|hncas0,15,11,0|hv9hfz,15,11,0|hv9hg0,16,6,1|i6fc3z,16,6,1|i6fc40,15,11,0|idzk3z,15,11,0|idzk40,16,6,1|ip5erz,16,6,1|ip5es0,15,11,0|iwpmrz,15,11,0|iwpms0,16,6,1|j7vhfz,16,6,1|j7vhg0,15,11,0|jffpfz,15,11,0|jffpg0,16,6,1|jqlk3z,16,6,1|jqlk40,15,11,0|jyiqrz,15,11,0|jyiqs0,16,6,1|k9bmrz,16,6,1|k9bms0,15,11,0|kh8tfz,15,11,0|kh8tg0,16,6,1|ks1pfz,16,6,1|ks1pg0,15,11,0|kzyw3z,15,11,0|kzyw40,16,6,1|lb4qrz,16,6,1|lb4qs0,15,11,0|lioyrz,15,11,0|lioys0,16,6,1|ltutfz,16,6,1|ltutg0,15,11,0|m1f1fz,15,11,0|m1f1g0,16,6,1|mckw3z,16,6,1|mckw40,15,11,0|mki2rz,15,11,0|mki2s0,16,6,1|mvayrz,16,6,1|mvays0,15,11,0|n385fz,15,11,0|n385g0,16,6,1|ne11fz,16,6,1|ne11g0,15,11,0|nly83z,15,11,0|nly840,16,6,1|nwr43z,16,6,1|nwr440,15,11,0|o4oarz,15,11,0|o4oas0,16,6,1|ofu5fz,16,6,1|ofu5g0,15,11,0|onedfz,15,11,0|onedg0,16,6,1|oyk83z,16,6,1|oyk840,15,11,0|p64g3z,15,11,0|p64g40,16,6,1|phaarz,16,6,1|phaas0,15,11,0|pp7hfz,15,11,0|pp7hg0,16,6,1|q00dfz,16,6,1|q00dg0,15,11,0|q7xk3z,15,11,0|q7xk40,16,6,1|qiqg3z,16,6,1|qiqg40,15,11,0|qqnmrz,15,11,0|qqnms0,16,6,1|r1thfz,16,6,1|r1thg0,15,11,0|r9dpfz,15,11,0|r9dpg0,16,6,1|rkjk3z,16,6,1|rkjk40,15,11,0|rs3s3z,15,11,0|rs3s40,16,6,1|s39mrz,16,6,1|s39ms0,15,11,0|sb6tfz,15,11,0|sb6tg0,16,6,1|slzpfz,16,6,1|slzpg0,15,11,0|stww3z,15,11,0|stww40,16,6,1|t4ps3z,16,6,1|t4ps40,15,11,0|tcmyrz,15,11,0|tcmys0,16,6,1|tnfurz,16,6,1|tnfus0,15,11,0|tvd1fz,15,11,0|tvd1g0,16,6,1|u6iw3z,16,6,1|u6iw40,15,11,0|ue343z,15,11,0|ue3440,16,6,1|up8yrz,16,6,1|up8ys0,15,11,0|uwt6rz,15,11,0|uwt6s0,16,6,1|v7z1fz,16,6,1|v7z1g0,15,11,0|vfw83z,15,11,0|vfw840,16,6,1|vqp43z,16,6,1|vqp440,15,11,0|vymarz,15,11,0|vymas0,16,6,1|w9f6rz,16,6,1|w9f6s0,15,11,0|whcdfz,15,11,0|whcdg0,16,6,1|wsi83z,16,6,1|wsi840,15,11,0|x02g3z,15,11,0|x02g40,16,6,1|xb8arz,16,6,1|xb8as0,15,11,0|xisirz,15,11,0|xisis0,16,6,1|xtydfz,16,6,1|xtydg0,15,11,0|y1ilfz,15,11,0|y1ilg0,16,6,1|ycog3z,16,6,1|ycog40,15,11,0|yklmrz,15,11,0|yklms0,16,6,1|yveirz,16,6,1|yveis0,15,11,0|z3bpfz,15,11,0|z3bpg0,16,6,1|ze4lfz,16,6,1|ze4lg0,15,11,0\",\"Europe/Stockholm|,0,371,0|-1bhq3cc,155,372,0|-10j6dgf,155,372,0|-10j6dge,10,10,0|-rzo2w1,10,10,0|-rzo2w0,11,11,1|-rsilg1,11,11,1|-rsilg0,10,10,0|5cstfz,10,10,0|5cstg0,11,11,1|5lsw3z,11,11,1|5lsw40,10,10,0|5v5xfz,10,10,0|5v5xg0,11,11,1|64iyrz,11,11,1|64iys0,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Tallinn|,0,373,0|-1ayy790,133,373,0|-r3exx1,133,373,0|-r3exx0,10,10,0|-qznjw1,10,10,0|-qznjw0,11,11,1|-qrqd81,11,11,1|-qrqd80,10,10,0|-qcx6s1,10,10,0|-qcx6s0,133,373,0|-peghx1,133,373,0|-peghx0,15,11,0|-fch1k1,15,11,0|-fch1k0,148,6,0|-ern4c1,148,6,0|-ern4c0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d6wg81,11,11,1|-d6wg80,148,6,0|5vb6bz,148,6,0|5vb6c0,149,209,1|64pzjz,149,209,1|64pzk0,148,6,0|6e33nz,148,6,0|6e33o0,149,209,1|6nhwvz,149,209,1|6nhww0,148,6,0|6wv0zz,148,6,0|6wv100,149,209,1|769u7z,149,209,1|769u80,148,6,0|7foszz,148,6,0|7fot00,149,209,1|7p1zvz,149,209,1|7p1zw0,148,6,0|7yf17z,148,6,0|7yf180,149,209,1|87s2jz,149,209,1|87s2k0,148,6,0|8h53vz,148,6,0|8h53w0,149,209,1|8qi57z,149,209,1|8qi580,148,6,0|8zv6jz,148,6,0|8zv6k0,149,209,1|9987vz,149,209,1|9987w0,148,6,0|9il97z,148,6,0|9il980,149,209,1|9ryajz,149,209,1|9ryak0,148,6,0|a1bbvz,148,6,0|a1bbw0,16,6,1|aaofzz,16,6,1|aaog00,15,11,0|ak1hbz,15,11,0|ak1hc0,16,6,1|atrhbz,16,6,1|atrhc0,15,11,0|b34inz,15,11,0|b34io0,16,6,1|bchjzz,16,6,1|bchk00,15,11,0|blulbz,15,11,0|blulc0,16,6,1|bv7mnz,16,6,1|bv7mo0,15,11,0|c4knzz,15,11,0|c4ko00,16,6,1|cdxpbz,16,6,1|cdxpc0,15,11,0|cnaqnz,15,11,0|cnaqo0,16,6,1|cwnrzz,16,6,1|cwns00,15,11,0|d60tbz,15,11,0|d60tc0,16,6,1|dfdunz,16,6,1|dfduo0,15,11,0|dp3unz,15,11,0|dp3uo0,16,6,1|dzwqnz,16,6,1|dzwqo0,15,11,0|e7txbz,15,11,0|e7txc0,16,6,1|eimtbz,16,6,1|eimtc0,15,11,0|eqjzzz,15,11,0|eqk000,16,6,1|f1cyrz,16,6,1|f1cys0,15,11,0|f9a5fz,15,11,0|f9a5g0,16,6,1|fkg03z,16,6,1|fkg040,15,11,0|gttc3z,15,11,0|gttc40,16,6,1|h4m83z,16,6,1|h4m840,15,11,0|hcjerz,15,11,0|hcjes0,16,6,1|hncarz,16,6,1|hncas0,15,11,0|hv9hfz,15,11,0|hv9hg0,16,6,1|i6fc3z,16,6,1|i6fc40,15,11,0|idzk3z,15,11,0|idzk40,16,6,1|ip5erz,16,6,1|ip5es0,15,11,0|iwpmrz,15,11,0|iwpms0,16,6,1|j7vhfz,16,6,1|j7vhg0,15,11,0|jffpfz,15,11,0|jffpg0,16,6,1|jqlk3z,16,6,1|jqlk40,15,11,0|jyiqrz,15,11,0|jyiqs0,16,6,1|k9bmrz,16,6,1|k9bms0,15,11,0|kh8tfz,15,11,0|kh8tg0,16,6,1|ks1pfz,16,6,1|ks1pg0,15,11,0|kzyw3z,15,11,0|kzyw40,16,6,1|lb4qrz,16,6,1|lb4qs0,15,11,0|lioyrz,15,11,0|lioys0,16,6,1|ltutfz,16,6,1|ltutg0,15,11,0|m1f1fz,15,11,0|m1f1g0,16,6,1|mckw3z,16,6,1|mckw40,15,11,0|mki2rz,15,11,0|mki2s0,16,6,1|mvayrz,16,6,1|mvays0,15,11,0|n385fz,15,11,0|n385g0,16,6,1|ne11fz,16,6,1|ne11g0,15,11,0|nly83z,15,11,0|nly840,16,6,1|nwr43z,16,6,1|nwr440,15,11,0|o4oarz,15,11,0|o4oas0,16,6,1|ofu5fz,16,6,1|ofu5g0,15,11,0|onedfz,15,11,0|onedg0,16,6,1|oyk83z,16,6,1|oyk840,15,11,0|p64g3z,15,11,0|p64g40,16,6,1|phaarz,16,6,1|phaas0,15,11,0|pp7hfz,15,11,0|pp7hg0,16,6,1|q00dfz,16,6,1|q00dg0,15,11,0|q7xk3z,15,11,0|q7xk40,16,6,1|qiqg3z,16,6,1|qiqg40,15,11,0|qqnmrz,15,11,0|qqnms0,16,6,1|r1thfz,16,6,1|r1thg0,15,11,0|r9dpfz,15,11,0|r9dpg0,16,6,1|rkjk3z,16,6,1|rkjk40,15,11,0|rs3s3z,15,11,0|rs3s40,16,6,1|s39mrz,16,6,1|s39ms0,15,11,0|sb6tfz,15,11,0|sb6tg0,16,6,1|slzpfz,16,6,1|slzpg0,15,11,0|stww3z,15,11,0|stww40,16,6,1|t4ps3z,16,6,1|t4ps40,15,11,0|tcmyrz,15,11,0|tcmys0,16,6,1|tnfurz,16,6,1|tnfus0,15,11,0|tvd1fz,15,11,0|tvd1g0,16,6,1|u6iw3z,16,6,1|u6iw40,15,11,0|ue343z,15,11,0|ue3440,16,6,1|up8yrz,16,6,1|up8ys0,15,11,0|uwt6rz,15,11,0|uwt6s0,16,6,1|v7z1fz,16,6,1|v7z1g0,15,11,0|vfw83z,15,11,0|vfw840,16,6,1|vqp43z,16,6,1|vqp440,15,11,0|vymarz,15,11,0|vymas0,16,6,1|w9f6rz,16,6,1|w9f6s0,15,11,0|whcdfz,15,11,0|whcdg0,16,6,1|wsi83z,16,6,1|wsi840,15,11,0|x02g3z,15,11,0|x02g40,16,6,1|xb8arz,16,6,1|xb8as0,15,11,0|xisirz,15,11,0|xisis0,16,6,1|xtydfz,16,6,1|xtydg0,15,11,0|y1ilfz,15,11,0|y1ilg0,16,6,1|ycog3z,16,6,1|ycog40,15,11,0|yklmrz,15,11,0|yklms0,16,6,1|yveirz,16,6,1|yveis0,15,11,0|z3bpfz,15,11,0|z3bpg0,16,6,1|ze4lfz,16,6,1|ze4lg0,15,11,0\",\"Europe/Tirane|,0,374,0|-t85vo8,10,10,0|-ff3es1,10,10,0|-ff3es0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dy7jw1,11,11,1|-dy7jw0,10,10,0|29h97z,10,10,0|29h980,11,11,1|2h8t3z,11,11,1|2h8t40,10,10,0|2s3mjz,10,10,0|2s3mk0,11,11,1|300qfz,11,11,1|300qg0,10,10,0|3az97z,10,10,0|3az980,11,11,1|3iwd3z,11,11,1|3iwd40,10,10,0|3u2ajz,10,10,0|3u2ak0,11,11,1|41mfrz,11,11,1|41mfs0,10,10,0|4cqijz,10,10,0|4cqik0,11,11,1|4kcifz,11,11,1|4kcig0,10,10,0|4vgl7z,10,10,0|4vgl80,11,11,1|532l3z,11,11,1|532l40,10,10,0|5e6nvz,10,10,0|5e6nw0,11,11,1|5m3rrz,11,11,1|5m3rs0,10,10,0|5wlmjz,10,10,0|5wlmk0,11,11,1|64iqfz,11,11,1|64iqg0,10,10,0|6fonvz,10,10,0|6fonw0,11,11,1|6nlrrz,11,11,1|6nlrs0,10,10,0|6xqnvz,10,10,0|6xqnw0,11,11,1|769zrz,11,11,1|769zs0,10,10,0|7foyjz,10,10,0|7foyk0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Ulyanovsk|,0,375,0|-qcx400,100,6,0|-kmr4c1,100,6,0|-kmr4c0,105,209,0|5vb3jz,105,209,0|5vb3k0,92,194,1|64pwrz,92,194,1|64pws0,105,209,0|6e30vz,105,209,0|6e30w0,92,194,1|6nhu3z,92,194,1|6nhu40,105,209,0|6wuy7z,105,209,0|6wuy80,92,194,1|769rfz,92,194,1|769rg0,105,209,0|7foq7z,105,209,0|7foq80,92,194,1|7p1x3z,92,194,1|7p1x40,105,209,0|7yeyfz,105,209,0|7yeyg0,92,194,1|87rzrz,92,194,1|87rzs0,105,209,0|8h513z,105,209,0|8h5140,92,194,1|8qi2fz,92,194,1|8qi2g0,105,209,0|8zv3rz,105,209,0|8zv3s0,92,194,1|99853z,92,194,1|998540,105,209,0|9il6fz,105,209,0|9il6g0,92,194,1|9ry7rz,92,194,1|9ry7s0,105,209,0|a1b93z,105,209,0|a1b940,105,209,1|aaod7z,105,209,1|aaod80,100,6,0|ak1ejz,100,6,0|ak1ek0,105,209,1|atrejz,105,209,1|atrek0,100,6,0|b34fvz,100,6,0|b34fw0,100,6,1|bchjzz,100,6,1|bchk00,101,11,0|bi8ynz,101,11,0|bi8yo0,100,6,0|bluijz,100,6,0|bluik0,105,209,1|bv7jvz,105,209,1|bv7jw0,100,6,0|c4kl7z,100,6,0|c4kl80,105,209,1|cdxmjz,105,209,1|cdxmk0,100,6,0|cnanvz,100,6,0|cnanw0,105,209,1|cwnp7z,105,209,1|cwnp80,100,6,0|d60qjz,100,6,0|d60qk0,105,209,1|dfdrvz,105,209,1|dfdrw0,100,6,0|dp3rvz,100,6,0|dp3rw0,105,209,1|dzwnvz,105,209,1|dzwnw0,100,6,0|e7tujz,100,6,0|e7tuk0,105,209,1|eimqjz,105,209,1|eimqk0,100,6,0|eqjx7z,100,6,0|eqjx80,105,209,1|f1ct7z,105,209,1|f1ct80,100,6,0|f99zvz,100,6,0|f99zw0,105,209,1|fkfujz,105,209,1|fkfuk0,100,6,0|fs02jz,100,6,0|fs02k0,105,209,1|g35x7z,105,209,1|g35x80,100,6,0|gaq57z,100,6,0|gaq580,105,209,1|glvzvz,105,209,1|glvzw0,100,6,0|gtt6jz,100,6,0|gtt6k0,105,209,1|h4m2jz,105,209,1|h4m2k0,100,6,0|hcj97z,100,6,0|hcj980,105,209,1|hnc57z,105,209,1|hnc580,100,6,0|hv9bvz,100,6,0|hv9bw0,105,209,1|i6f6jz,105,209,1|i6f6k0,100,6,0|idzejz,100,6,0|idzek0,105,209,1|ip597z,105,209,1|ip5980,100,6,0|iwph7z,100,6,0|iwph80,105,209,1|j7vbvz,105,209,1|j7vbw0,100,6,0|jffjvz,100,6,0|jffjw0,105,209,1|jqlejz,105,209,1|jqlek0,100,6,0|jyil7z,100,6,0|jyil80,105,209,1|k9bh7z,105,209,1|k9bh80,100,6,0|kh8nvz,100,6,0|kh8nw0,105,209,1|ks1jvz,105,209,1|ks1jw0,100,6,0|kzyqjz,100,6,0|kzyqk0,105,209,1|lb4l7z,105,209,1|lb4l80,100,6,0|liot7z,100,6,0|liot80,105,209,0|ne0t3z,105,209,0|ne0t40,100,6,0|o4o57z,100,6,0|o4o580,105,209,0\",\"Europe/Uzhgorod|,0,376,0|-15cztgo,10,10,0|-fizzw1,10,10,0|-fizzw0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d55hk1,11,11,1|-d55hk0,10,10,0|-cshus1,10,10,0|-cshus0,148,6,0|5vb6bz,148,6,0|5vb6c0,149,209,1|64pzjz,149,209,1|64pzk0,148,6,0|6e33nz,148,6,0|6e33o0,149,209,1|6nhwvz,149,209,1|6nhww0,148,6,0|6wv0zz,148,6,0|6wv100,149,209,1|769u7z,149,209,1|769u80,148,6,0|7foszz,148,6,0|7fot00,149,209,1|7p1zvz,149,209,1|7p1zw0,148,6,0|7yf17z,148,6,0|7yf180,149,209,1|87s2jz,149,209,1|87s2k0,148,6,0|8h53vz,148,6,0|8h53w0,149,209,1|8qi57z,149,209,1|8qi580,148,6,0|8zv6jz,148,6,0|8zv6k0,149,209,1|9987vz,149,209,1|9987w0,148,6,0|9il97z,148,6,0|9il980,149,209,1|9ryajz,149,209,1|9ryak0,148,6,0|a1bbvz,148,6,0|a1bbw0,149,209,1|aaod7z,149,209,1|aaod80,148,6,0|ap2vvz,148,6,0|ap2vw0,10,10,0|b34o7z,10,10,0|b34o80,15,11,0|blufrz,15,11,0|blufs0,16,6,1|bv7ebz,16,6,1|bv7ec0,15,11,0|c4kifz,15,11,0|c4kig0,16,6,1|cdxgzz,16,6,1|cdxh00,15,11,0|cnal3z,15,11,0|cnal40,16,6,1|cwnjnz,16,6,1|cwnjo0,15,11,0|d60w3z,15,11,0|d60w40,16,6,1|dfdxfz,16,6,1|dfdxg0,15,11,0|dp3xfz,15,11,0|dp3xg0,16,6,1|dzwtfz,16,6,1|dzwtg0,15,11,0|e7u03z,15,11,0|e7u040,16,6,1|eimw3z,16,6,1|eimw40,15,11,0|eqk2rz,15,11,0|eqk2s0,16,6,1|f1cyrz,16,6,1|f1cys0,15,11,0|f9a5fz,15,11,0|f9a5g0,16,6,1|fkg03z,16,6,1|fkg040,15,11,0|fs083z,15,11,0|fs0840,16,6,1|g362rz,16,6,1|g362s0,15,11,0|gaqarz,15,11,0|gaqas0,16,6,1|glw5fz,16,6,1|glw5g0,15,11,0|gttc3z,15,11,0|gttc40,16,6,1|h4m83z,16,6,1|h4m840,15,11,0|hcjerz,15,11,0|hcjes0,16,6,1|hncarz,16,6,1|hncas0,15,11,0|hv9hfz,15,11,0|hv9hg0,16,6,1|i6fc3z,16,6,1|i6fc40,15,11,0|idzk3z,15,11,0|idzk40,16,6,1|ip5erz,16,6,1|ip5es0,15,11,0|iwpmrz,15,11,0|iwpms0,16,6,1|j7vhfz,16,6,1|j7vhg0,15,11,0|jffpfz,15,11,0|jffpg0,16,6,1|jqlk3z,16,6,1|jqlk40,15,11,0|jyiqrz,15,11,0|jyiqs0,16,6,1|k9bmrz,16,6,1|k9bms0,15,11,0|kh8tfz,15,11,0|kh8tg0,16,6,1|ks1pfz,16,6,1|ks1pg0,15,11,0|kzyw3z,15,11,0|kzyw40,16,6,1|lb4qrz,16,6,1|lb4qs0,15,11,0|lioyrz,15,11,0|lioys0,16,6,1|ltutfz,16,6,1|ltutg0,15,11,0|m1f1fz,15,11,0|m1f1g0,16,6,1|mckw3z,16,6,1|mckw40,15,11,0|mki2rz,15,11,0|mki2s0,16,6,1|mvayrz,16,6,1|mvays0,15,11,0|n385fz,15,11,0|n385g0,16,6,1|ne11fz,16,6,1|ne11g0,15,11,0|nly83z,15,11,0|nly840,16,6,1|nwr43z,16,6,1|nwr440,15,11,0|o4oarz,15,11,0|o4oas0,16,6,1|ofu5fz,16,6,1|ofu5g0,15,11,0|onedfz,15,11,0|onedg0,16,6,1|oyk83z,16,6,1|oyk840,15,11,0|p64g3z,15,11,0|p64g40,16,6,1|phaarz,16,6,1|phaas0,15,11,0|pp7hfz,15,11,0|pp7hg0,16,6,1|q00dfz,16,6,1|q00dg0,15,11,0|q7xk3z,15,11,0|q7xk40,16,6,1|qiqg3z,16,6,1|qiqg40,15,11,0|qqnmrz,15,11,0|qqnms0,16,6,1|r1thfz,16,6,1|r1thg0,15,11,0|r9dpfz,15,11,0|r9dpg0,16,6,1|rkjk3z,16,6,1|rkjk40,15,11,0|rs3s3z,15,11,0|rs3s40,16,6,1|s39mrz,16,6,1|s39ms0,15,11,0|sb6tfz,15,11,0|sb6tg0,16,6,1|slzpfz,16,6,1|slzpg0,15,11,0|stww3z,15,11,0|stww40,16,6,1|t4ps3z,16,6,1|t4ps40,15,11,0|tcmyrz,15,11,0|tcmys0,16,6,1|tnfurz,16,6,1|tnfus0,15,11,0|tvd1fz,15,11,0|tvd1g0,16,6,1|u6iw3z,16,6,1|u6iw40,15,11,0|ue343z,15,11,0|ue3440,16,6,1|up8yrz,16,6,1|up8ys0,15,11,0|uwt6rz,15,11,0|uwt6s0,16,6,1|v7z1fz,16,6,1|v7z1g0,15,11,0|vfw83z,15,11,0|vfw840,16,6,1|vqp43z,16,6,1|vqp440,15,11,0|vymarz,15,11,0|vymas0,16,6,1|w9f6rz,16,6,1|w9f6s0,15,11,0|whcdfz,15,11,0|whcdg0,16,6,1|wsi83z,16,6,1|wsi840,15,11,0|x02g3z,15,11,0|x02g40,16,6,1|xb8arz,16,6,1|xb8as0,15,11,0|xisirz,15,11,0|xisis0,16,6,1|xtydfz,16,6,1|xtydg0,15,11,0|y1ilfz,15,11,0|y1ilg0,16,6,1|ycog3z,16,6,1|ycog40,15,11,0|yklmrz,15,11,0|yklms0,16,6,1|yveirz,16,6,1|yveis0,15,11,0|z3bpfz,15,11,0|z3bpg0,16,6,1|ze4lfz,16,6,1|ze4lg0,15,11,0\",\"Europe/Vaduz|,0,338,0|-1os49kw,53,339,0|-13g441n,53,339,0|-13g441m,10,10,0|-eyh6o1,10,10,0|-eyh6o0,11,11,1|-eqk001,11,11,1|-eqk000,10,10,0|-efr401,10,10,0|-efr400,11,11,1|-e7txc1,11,11,1|-e7txc0,10,10,0|5v5xfz,10,10,0|5v5xg0,11,11,1|64iyrz,11,11,1|64iys0,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Vatican|,0,365,0|-1hs7rn8,136,365,0|-13r0qs1,136,365,0|-13r0qs0,10,10,0|-rymys1,10,10,0|-rymys0,11,11,1|-rsio81,11,11,1|-rsio80,10,10,0|-rj5k41,10,10,0|-rj5k40,11,11,1|-r9qqw1,11,11,1|-r9qqw0,10,10,0|-r1idg1,10,10,0|-r1idg0,11,11,1|-qqnpk1,11,11,1|-qqnpk0,10,10,0|-qj59g1,10,10,0|-qj59g0,11,11,1|-q7zhk1,11,11,1|-q7zhk0,10,10,0|-pzcas1,10,10,0|-pzcas0,11,11,1|-ppzc81,11,11,1|-ppzc80,10,10,0|-ff59g1,10,10,0|-ff59g0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d75h81,11,11,1|-d75h80,10,10,0|-cx0nw1,10,10,0|-cx0nw0,11,11,1|-cohes1,11,11,1|-cohes0,10,10,0|-cf2d81,10,10,0|-cf2d80,11,11,1|-c4mfw1,11,11,1|-c4mfw0,10,10,0|-bwcg41,10,10,0|-bwcg40,11,11,1|-blwis1,11,11,1|-blwis0,10,10,0|-bec581,10,10,0|-bec580,11,11,1|-b36ak1,11,11,1|-b36ak0,10,10,0|-1vwis1,10,10,0|-1vwis0,11,11,1|-1pf9k1,11,11,1|-1pf9k0,10,10,0|-1cthg1,10,10,0|-1cthg0,11,11,1|-16p441,11,11,1|-16p440,10,10,0|-u3es1,10,10,0|-u3es0,11,11,1|-nz1g1,11,11,1|-nz1g0,10,10,0|-b0dg1,10,10,0|-b0dg0,11,11,1|-4w041,11,11,1|-4w040,10,10,0|7pp7z,10,10,0|7pp80,11,11,1|du2jz,11,11,1|du2k0,10,10,0|q2t7z,10,10,0|q2t80,11,11,1|wk57z,11,11,1|wk580,10,10,0|195ujz,10,10,0|195uk0,11,11,1|1fn6jz,11,11,1|1fn6k0,10,10,0|1s8vvz,10,10,0|1s8vw0,11,11,1|1yd97z,11,11,1|1yd980,10,10,0|2alzvz,10,10,0|2alzw0,11,11,1|2h3bvz,11,11,1|2h3bw0,10,10,0|2tp17z,10,10,0|2tp180,11,11,1|2ztejz,11,11,1|2ztek0,10,10,0|3cf3vz,10,10,0|3cf3w0,11,11,1|3ijh7z,11,11,1|3ijh80,10,10,0|3us7vz,10,10,0|3us7w0,11,11,1|419jvz,11,11,1|419jw0,10,10,0|4dv97z,10,10,0|4dv980,11,11,1|4kcl7z,11,11,1|4kcl80,10,10,0|4wlbvz,10,10,0|4wlbw0,11,11,1|532nvz,11,11,1|532nw0,10,10,0|5cstfz,10,10,0|5cstg0,11,11,1|5lsw3z,11,11,1|5lsw40,10,10,0|5v5xfz,10,10,0|5v5xg0,11,11,1|64iyrz,11,11,1|64iys0,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Vienna|,0,377,0|-14211ox,10,10,0|-s0e081,10,10,0|-s0e080,11,11,1|-rsilg1,11,11,1|-rsilg0,10,10,0|-ridmk1,10,10,0|-ridmk0,11,11,1|-ragfw1,11,11,1|-ragfw0,10,10,0|-qznjw1,10,10,0|-qznjw0,11,11,1|-qrqd81,11,11,1|-qrqd80,10,10,0|-pykd81,10,10,0|-pykd80,11,11,1|-pqa7w1,11,11,1|-pqa7w0,10,10,0|-fizzw1,10,10,0|-fizzw0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d6dp81,11,11,1|-d6dp80,10,10,0|-cx0nw1,10,10,0|-cx0nw0,11,11,1|-cwi581,11,11,1|-cwi580,10,10,0|-cdmik1,10,10,0|-cdmik0,11,11,1|-c4kl81,11,11,1|-c4kl80,10,10,0|-bv9ek1,10,10,0|-bv9ek0,11,11,1|-blwd81,11,11,1|-blwd80,10,10,0|-bbtek1,10,10,0|-bbtek0,11,11,1|-b36ak1,11,11,1|-b36ak0,10,10,0|5csnvz,10,10,0|5csnw0,11,11,1|5lsnrz,11,11,1|5lsns0,10,10,0|5v5xfz,10,10,0|5v5xg0,11,11,1|64iyrz,11,11,1|64iys0,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Vilnius|,0,378,0|-1ayy7cs,156,379,0|-rns981,156,379,0|-rns980,74,380,0|-q7q73d,74,380,0|-q7q73c,10,10,0|-ptj1g1,10,10,0|-ptj1g0,15,11,0|-poyaw1,15,11,0|-poyaw0,10,10,0|-fcmis1,10,10,0|-fcmis0,148,6,0|-evwto1,148,6,0|-evwto0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d9kqw1,11,11,1|-d9kqw0,148,6,0|5vb6bz,148,6,0|5vb6c0,149,209,1|64pzjz,149,209,1|64pzk0,148,6,0|6e33nz,148,6,0|6e33o0,149,209,1|6nhwvz,149,209,1|6nhww0,148,6,0|6wv0zz,148,6,0|6wv100,149,209,1|769u7z,149,209,1|769u80,148,6,0|7foszz,148,6,0|7fot00,149,209,1|7p1zvz,149,209,1|7p1zw0,148,6,0|7yf17z,148,6,0|7yf180,149,209,1|87s2jz,149,209,1|87s2k0,148,6,0|8h53vz,148,6,0|8h53w0,149,209,1|8qi57z,149,209,1|8qi580,148,6,0|8zv6jz,148,6,0|8zv6k0,149,209,1|9987vz,149,209,1|9987w0,148,6,0|9il97z,148,6,0|9il980,149,209,1|9ryajz,149,209,1|9ryak0,148,6,0|a1bbvz,148,6,0|a1bbw0,16,6,1|aaofzz,16,6,1|aaog00,15,11,0|ak1hbz,15,11,0|ak1hc0,16,6,1|atrhbz,16,6,1|atrhc0,15,11,0|b34inz,15,11,0|b34io0,16,6,1|bchjzz,16,6,1|bchk00,15,11,0|blulbz,15,11,0|blulc0,16,6,1|bv7mnz,16,6,1|bv7mo0,15,11,0|c4knzz,15,11,0|c4ko00,16,6,1|cdxpbz,16,6,1|cdxpc0,15,11,0|cnaqnz,15,11,0|cnaqo0,16,6,1|cwnrzz,16,6,1|cwns00,15,11,0|d60tbz,15,11,0|d60tc0,16,6,1|dfdunz,16,6,1|dfduo0,15,11,0|dp3unz,15,11,0|dp3uo0,16,6,1|dzwqnz,16,6,1|dzwqo0,15,11,0|e7txbz,15,11,0|e7txc0,16,6,1|eimtbz,16,6,1|eimtc0,15,11,0|eqk2rz,15,11,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,15,11,0|hcjerz,15,11,0|hcjes0,16,6,1|hncarz,16,6,1|hncas0,15,11,0|hv9hfz,15,11,0|hv9hg0,16,6,1|i6fc3z,16,6,1|i6fc40,15,11,0|idzk3z,15,11,0|idzk40,16,6,1|ip5erz,16,6,1|ip5es0,15,11,0|iwpmrz,15,11,0|iwpms0,16,6,1|j7vhfz,16,6,1|j7vhg0,15,11,0|jffpfz,15,11,0|jffpg0,16,6,1|jqlk3z,16,6,1|jqlk40,15,11,0|jyiqrz,15,11,0|jyiqs0,16,6,1|k9bmrz,16,6,1|k9bms0,15,11,0|kh8tfz,15,11,0|kh8tg0,16,6,1|ks1pfz,16,6,1|ks1pg0,15,11,0|kzyw3z,15,11,0|kzyw40,16,6,1|lb4qrz,16,6,1|lb4qs0,15,11,0|lioyrz,15,11,0|lioys0,16,6,1|ltutfz,16,6,1|ltutg0,15,11,0|m1f1fz,15,11,0|m1f1g0,16,6,1|mckw3z,16,6,1|mckw40,15,11,0|mki2rz,15,11,0|mki2s0,16,6,1|mvayrz,16,6,1|mvays0,15,11,0|n385fz,15,11,0|n385g0,16,6,1|ne11fz,16,6,1|ne11g0,15,11,0|nly83z,15,11,0|nly840,16,6,1|nwr43z,16,6,1|nwr440,15,11,0|o4oarz,15,11,0|o4oas0,16,6,1|ofu5fz,16,6,1|ofu5g0,15,11,0|onedfz,15,11,0|onedg0,16,6,1|oyk83z,16,6,1|oyk840,15,11,0|p64g3z,15,11,0|p64g40,16,6,1|phaarz,16,6,1|phaas0,15,11,0|pp7hfz,15,11,0|pp7hg0,16,6,1|q00dfz,16,6,1|q00dg0,15,11,0|q7xk3z,15,11,0|q7xk40,16,6,1|qiqg3z,16,6,1|qiqg40,15,11,0|qqnmrz,15,11,0|qqnms0,16,6,1|r1thfz,16,6,1|r1thg0,15,11,0|r9dpfz,15,11,0|r9dpg0,16,6,1|rkjk3z,16,6,1|rkjk40,15,11,0|rs3s3z,15,11,0|rs3s40,16,6,1|s39mrz,16,6,1|s39ms0,15,11,0|sb6tfz,15,11,0|sb6tg0,16,6,1|slzpfz,16,6,1|slzpg0,15,11,0|stww3z,15,11,0|stww40,16,6,1|t4ps3z,16,6,1|t4ps40,15,11,0|tcmyrz,15,11,0|tcmys0,16,6,1|tnfurz,16,6,1|tnfus0,15,11,0|tvd1fz,15,11,0|tvd1g0,16,6,1|u6iw3z,16,6,1|u6iw40,15,11,0|ue343z,15,11,0|ue3440,16,6,1|up8yrz,16,6,1|up8ys0,15,11,0|uwt6rz,15,11,0|uwt6s0,16,6,1|v7z1fz,16,6,1|v7z1g0,15,11,0|vfw83z,15,11,0|vfw840,16,6,1|vqp43z,16,6,1|vqp440,15,11,0|vymarz,15,11,0|vymas0,16,6,1|w9f6rz,16,6,1|w9f6s0,15,11,0|whcdfz,15,11,0|whcdg0,16,6,1|wsi83z,16,6,1|wsi840,15,11,0|x02g3z,15,11,0|x02g40,16,6,1|xb8arz,16,6,1|xb8as0,15,11,0|xisirz,15,11,0|xisis0,16,6,1|xtydfz,16,6,1|xtydg0,15,11,0|y1ilfz,15,11,0|y1ilg0,16,6,1|ycog3z,16,6,1|ycog40,15,11,0|yklmrz,15,11,0|yklms0,16,6,1|yveirz,16,6,1|yveis0,15,11,0|z3bpfz,15,11,0|z3bpg0,16,6,1|ze4lfz,16,6,1|ze4lg0,15,11,0\",\"Europe/Volgograd|,0,213,0|-q3cw84,100,6,0|-kmr4c1,100,6,0|-kmr4c0,105,209,0|5vb3jz,105,209,0|5vb3k0,92,194,1|64pwrz,92,194,1|64pws0,105,209,0|6e30vz,105,209,0|6e30w0,92,194,1|6nhu3z,92,194,1|6nhu40,105,209,0|6wuy7z,105,209,0|6wuy80,92,194,1|769rfz,92,194,1|769rg0,105,209,0|7foq7z,105,209,0|7foq80,92,194,1|7p1x3z,92,194,1|7p1x40,105,209,0|7yeyfz,105,209,0|7yeyg0,92,194,1|87rzrz,92,194,1|87rzs0,105,209,0|8h513z,105,209,0|8h5140,92,194,1|8qi2fz,92,194,1|8qi2g0,105,209,0|8zv3rz,105,209,0|8zv3s0,92,194,1|99853z,92,194,1|998540,105,209,0|9il6fz,105,209,0|9il6g0,105,209,1|9ryajz,105,209,1|9ryak0,100,6,0|a1bbvz,100,6,0|a1bbw0,105,209,1|aaod7z,105,209,1|aaod80,100,6,0|ak1ejz,100,6,0|ak1ek0,105,209,1|atrejz,105,209,1|atrek0,100,6,0|b34fvz,100,6,0|b34fw0,105,209,0|blufrz,105,209,0|blufs0,105,209,1|bv7jvz,105,209,1|bv7jw0,100,6,0|c4kl7z,100,6,0|c4kl80,105,209,1|cdxmjz,105,209,1|cdxmk0,100,6,0|cnanvz,100,6,0|cnanw0,105,209,1|cwnp7z,105,209,1|cwnp80,100,6,0|d60qjz,100,6,0|d60qk0,105,209,1|dfdrvz,105,209,1|dfdrw0,100,6,0|dp3rvz,100,6,0|dp3rw0,105,209,1|dzwnvz,105,209,1|dzwnw0,100,6,0|e7tujz,100,6,0|e7tuk0,105,209,1|eimqjz,105,209,1|eimqk0,100,6,0|eqjx7z,100,6,0|eqjx80,105,209,1|f1ct7z,105,209,1|f1ct80,100,6,0|f99zvz,100,6,0|f99zw0,105,209,1|fkfujz,105,209,1|fkfuk0,100,6,0|fs02jz,100,6,0|fs02k0,105,209,1|g35x7z,105,209,1|g35x80,100,6,0|gaq57z,100,6,0|gaq580,105,209,1|glvzvz,105,209,1|glvzw0,100,6,0|gtt6jz,100,6,0|gtt6k0,105,209,1|h4m2jz,105,209,1|h4m2k0,100,6,0|hcj97z,100,6,0|hcj980,105,209,1|hnc57z,105,209,1|hnc580,100,6,0|hv9bvz,100,6,0|hv9bw0,105,209,1|i6f6jz,105,209,1|i6f6k0,100,6,0|idzejz,100,6,0|idzek0,105,209,1|ip597z,105,209,1|ip5980,100,6,0|iwph7z,100,6,0|iwph80,105,209,1|j7vbvz,105,209,1|j7vbw0,100,6,0|jffjvz,100,6,0|jffjw0,105,209,1|jqlejz,105,209,1|jqlek0,100,6,0|jyil7z,100,6,0|jyil80,105,209,1|k9bh7z,105,209,1|k9bh80,100,6,0|kh8nvz,100,6,0|kh8nw0,105,209,1|ks1jvz,105,209,1|ks1jw0,100,6,0|kzyqjz,100,6,0|kzyqk0,105,209,1|lb4l7z,105,209,1|lb4l80,100,6,0|liot7z,100,6,0|liot80,105,209,0|ne0t3z,105,209,0|ne0t40,100,6,0|pha57z,100,6,0|pha580,105,209,0|qlyvrz,105,209,0|qlyvs0,100,6,0\",\"Europe/Warsaw|,0,379,0|-1ayy6k0,156,379,0|-se9yk1,156,379,0|-se9yk0,10,10,0|-s0e081,10,10,0|-s0e080,11,11,1|-rsilg1,11,11,1|-rsilg0,10,10,0|-ridmk1,10,10,0|-ridmk0,11,11,1|-ragfw1,11,11,1|-ragfw0,10,10,0|-qznjw1,10,10,0|-qznjw0,11,11,1|-qrqd81,11,11,1|-qrqd80,15,11,0|-qgvpc1,15,11,0|-qgvpc0,16,6,1|-q8yio1,16,6,1|-q8yio0,15,11,0|-ou36w1,15,11,0|-ou36w0,10,10,0|-feqak1,10,10,0|-feqak0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d6a2o1,11,11,1|-d6a2o0,10,10,0|-cvmtg1,10,10,0|-cvmtg0,11,11,1|-cm2g81,11,11,1|-cm2g80,10,10,0|-cdmo41,10,10,0|-cdmo40,11,11,1|-c4kl81,11,11,1|-c4kl80,10,10,0|-bttjw1,10,10,0|-bttjw0,11,11,1|-blwd81,11,11,1|-blwd80,10,10,0|-bbtek1,10,10,0|-bbtek0,11,11,1|-b36ak1,11,11,1|-b36ak0,10,10,0|-atgak1,10,10,0|-atgak0,11,11,1|-akg7w1,11,11,1|-akg7w0,10,10,0|-6kf401,10,10,0|-6kf400,11,11,1|-6eaqo1,11,11,1|-6eaqo0,10,10,0|-64xpc1,10,10,0|-64xpc0,11,11,1|-5vko01,11,11,1|-5vko00,10,10,0|-5iyyo1,10,10,0|-5iyyo0,11,11,1|-5chmo1,11,11,1|-5chmo0,10,10,0|-534lc1,10,10,0|-534lc0,11,11,1|-4trk01,11,11,1|-4trk00,10,10,0|-4hitc1,10,10,0|-4hitc0,11,11,1|-4b1hc1,11,11,1|-4b1hc0,10,10,0|-3ysqo1,10,10,0|-3ysqo0,11,11,1|-3sbeo1,11,11,1|-3sbeo0,10,10,0|-3g2o01,10,10,0|-3g2o00,11,11,1|-39lc01,11,11,1|-39lc00,10,10,0|-2wzmo1,10,10,0|-2wzmo0,11,11,1|-2qv9c1,11,11,1|-2qv9c0,10,10,0|3s9jzz,10,10,0|3s9k00,11,11,1|419mnz,11,11,1|419mo0,10,10,0|4azmnz,10,10,0|4azmo0,11,11,1|4kcnzz,11,11,1|4kco00,10,10,0|4tppbz,10,10,0|4tppc0,11,11,1|532qnz,11,11,1|532qo0,10,10,0|5csqnz,10,10,0|5csqo0,11,11,1|5lstbz,11,11,1|5lstc0,10,10,0|5v5unz,10,10,0|5v5uo0,11,11,1|64ivzz,11,11,1|64iw00,10,10,0|6dvxbz,10,10,0|6dvxc0,11,11,1|6n8ynz,11,11,1|6n8yo0,10,10,0|6wlzzz,10,10,0|6wm000,11,11,1|75z1bz,11,11,1|75z1c0,10,10,0|7fc2nz,10,10,0|7fc2o0,11,11,1|7p22nz,11,11,1|7p22o0,10,10,0|7yf3zz,10,10,0|7yf400,11,11,1|87s5bz,11,11,1|87s5c0,10,10,0|8h56nz,10,10,0|8h56o0,11,11,1|8qi7zz,11,11,1|8qi800,10,10,0|8zv9bz,10,10,0|8zv9c0,11,11,1|998anz,11,11,1|998ao0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Zagreb|,0,332,0|-18vsmgo,10,10,0|-ezayw1,10,10,0|-ezayw0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-dfqqk1,10,10,0|-dfqqk0,11,11,1|-d6dp81,11,11,1|-d6dp80,10,10,0|-cv5zw1,10,10,0|-cv5zw0,11,11,1|-cofek1,11,11,1|-cofek0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Europe/Zaporozhye|,0,250,0|-1ayy96g,157,381,0|-nu12hd,157,381,0|-nu12hc,15,11,0|-kmr1k1,15,11,0|-kmr1k0,148,6,0|-esq0c1,148,6,0|-esq0c0,11,11,1|-e6dzw1,11,11,1|-e6dzw0,10,10,0|-dytrw1,10,10,0|-dytrw0,11,11,1|-dp3rw1,11,11,1|-dp3rw0,10,10,0|-do11g1,10,10,0|-do11g0,148,6,0|5vb6bz,148,6,0|5vb6c0,149,209,1|64pzjz,149,209,1|64pzk0,148,6,0|6e33nz,148,6,0|6e33o0,149,209,1|6nhwvz,149,209,1|6nhww0,148,6,0|6wv0zz,148,6,0|6wv100,149,209,1|769u7z,149,209,1|769u80,148,6,0|7foszz,148,6,0|7fot00,149,209,1|7p1zvz,149,209,1|7p1zw0,148,6,0|7yf17z,148,6,0|7yf180,149,209,1|87s2jz,149,209,1|87s2k0,148,6,0|8h53vz,148,6,0|8h53w0,149,209,1|8qi57z,149,209,1|8qi580,148,6,0|8zv6jz,148,6,0|8zv6k0,149,209,1|9987vz,149,209,1|9987w0,148,6,0|9il97z,148,6,0|9il980,149,209,1|9ryajz,149,209,1|9ryak0,148,6,0|a1bbvz,148,6,0|a1bbw0,149,209,1|aaod7z,149,209,1|aaod80,148,6,0|ak1ejz,148,6,0|ak1ek0,149,209,1|atrejz,149,209,1|atrek0,148,6,0|b34fvz,148,6,0|b34fw0,16,6,1|bchbnz,16,6,1|bchbo0,15,11,0|blufrz,15,11,0|blufs0,16,6,1|bv7ebz,16,6,1|bv7ec0,15,11,0|c4kifz,15,11,0|c4kig0,16,6,1|cdxgzz,16,6,1|cdxh00,15,11,0|cnal3z,15,11,0|cnal40,16,6,1|cwnjnz,16,6,1|cwnjo0,15,11,0|d60w3z,15,11,0|d60w40,16,6,1|dfdxfz,16,6,1|dfdxg0,15,11,0|dp3xfz,15,11,0|dp3xg0,16,6,1|dzwtfz,16,6,1|dzwtg0,15,11,0|e7u03z,15,11,0|e7u040,16,6,1|eimw3z,16,6,1|eimw40,15,11,0|eqk2rz,15,11,0|eqk2s0,16,6,1|f1cyrz,16,6,1|f1cys0,15,11,0|f9a5fz,15,11,0|f9a5g0,16,6,1|fkg03z,16,6,1|fkg040,15,11,0|fs083z,15,11,0|fs0840,16,6,1|g362rz,16,6,1|g362s0,15,11,0|gaqarz,15,11,0|gaqas0,16,6,1|glw5fz,16,6,1|glw5g0,15,11,0|gttc3z,15,11,0|gttc40,16,6,1|h4m83z,16,6,1|h4m840,15,11,0|hcjerz,15,11,0|hcjes0,16,6,1|hncarz,16,6,1|hncas0,15,11,0|hv9hfz,15,11,0|hv9hg0,16,6,1|i6fc3z,16,6,1|i6fc40,15,11,0|idzk3z,15,11,0|idzk40,16,6,1|ip5erz,16,6,1|ip5es0,15,11,0|iwpmrz,15,11,0|iwpms0,16,6,1|j7vhfz,16,6,1|j7vhg0,15,11,0|jffpfz,15,11,0|jffpg0,16,6,1|jqlk3z,16,6,1|jqlk40,15,11,0|jyiqrz,15,11,0|jyiqs0,16,6,1|k9bmrz,16,6,1|k9bms0,15,11,0|kh8tfz,15,11,0|kh8tg0,16,6,1|ks1pfz,16,6,1|ks1pg0,15,11,0|kzyw3z,15,11,0|kzyw40,16,6,1|lb4qrz,16,6,1|lb4qs0,15,11,0|lioyrz,15,11,0|lioys0,16,6,1|ltutfz,16,6,1|ltutg0,15,11,0|m1f1fz,15,11,0|m1f1g0,16,6,1|mckw3z,16,6,1|mckw40,15,11,0|mki2rz,15,11,0|mki2s0,16,6,1|mvayrz,16,6,1|mvays0,15,11,0|n385fz,15,11,0|n385g0,16,6,1|ne11fz,16,6,1|ne11g0,15,11,0|nly83z,15,11,0|nly840,16,6,1|nwr43z,16,6,1|nwr440,15,11,0|o4oarz,15,11,0|o4oas0,16,6,1|ofu5fz,16,6,1|ofu5g0,15,11,0|onedfz,15,11,0|onedg0,16,6,1|oyk83z,16,6,1|oyk840,15,11,0|p64g3z,15,11,0|p64g40,16,6,1|phaarz,16,6,1|phaas0,15,11,0|pp7hfz,15,11,0|pp7hg0,16,6,1|q00dfz,16,6,1|q00dg0,15,11,0|q7xk3z,15,11,0|q7xk40,16,6,1|qiqg3z,16,6,1|qiqg40,15,11,0|qqnmrz,15,11,0|qqnms0,16,6,1|r1thfz,16,6,1|r1thg0,15,11,0|r9dpfz,15,11,0|r9dpg0,16,6,1|rkjk3z,16,6,1|rkjk40,15,11,0|rs3s3z,15,11,0|rs3s40,16,6,1|s39mrz,16,6,1|s39ms0,15,11,0|sb6tfz,15,11,0|sb6tg0,16,6,1|slzpfz,16,6,1|slzpg0,15,11,0|stww3z,15,11,0|stww40,16,6,1|t4ps3z,16,6,1|t4ps40,15,11,0|tcmyrz,15,11,0|tcmys0,16,6,1|tnfurz,16,6,1|tnfus0,15,11,0|tvd1fz,15,11,0|tvd1g0,16,6,1|u6iw3z,16,6,1|u6iw40,15,11,0|ue343z,15,11,0|ue3440,16,6,1|up8yrz,16,6,1|up8ys0,15,11,0|uwt6rz,15,11,0|uwt6s0,16,6,1|v7z1fz,16,6,1|v7z1g0,15,11,0|vfw83z,15,11,0|vfw840,16,6,1|vqp43z,16,6,1|vqp440,15,11,0|vymarz,15,11,0|vymas0,16,6,1|w9f6rz,16,6,1|w9f6s0,15,11,0|whcdfz,15,11,0|whcdg0,16,6,1|wsi83z,16,6,1|wsi840,15,11,0|x02g3z,15,11,0|x02g40,16,6,1|xb8arz,16,6,1|xb8as0,15,11,0|xisirz,15,11,0|xisis0,16,6,1|xtydfz,16,6,1|xtydg0,15,11,0|y1ilfz,15,11,0|y1ilg0,16,6,1|ycog3z,16,6,1|ycog40,15,11,0|yklmrz,15,11,0|yklms0,16,6,1|yveirz,16,6,1|yveis0,15,11,0|z3bpfz,15,11,0|z3bpg0,16,6,1|ze4lfz,16,6,1|ze4lg0,15,11,0\",\"Europe/Zurich|,0,338,0|-1os49kw,53,339,0|-13g441n,53,339,0|-13g441m,10,10,0|-eyh6o1,10,10,0|-eyh6o0,11,11,1|-eqk001,11,11,1|-eqk000,10,10,0|-efr401,10,10,0|-efr400,11,11,1|-e7txc1,11,11,1|-e7txc0,10,10,0|5v5xfz,10,10,0|5v5xg0,11,11,1|64iyrz,11,11,1|64iys0,10,10,0|6dw03z,10,10,0|6dw040,11,11,1|6n91fz,11,11,1|6n91g0,10,10,0|6wm2rz,10,10,0|6wm2s0,11,11,1|75z43z,11,11,1|75z440,10,10,0|7fc5fz,10,10,0|7fc5g0,11,11,1|7p25fz,11,11,1|7p25g0,10,10,0|7yf6rz,10,10,0|7yf6s0,11,11,1|87s83z,11,11,1|87s840,10,10,0|8h59fz,10,10,0|8h59g0,11,11,1|8qiarz,11,11,1|8qias0,10,10,0|8zvc3z,10,10,0|8zvc40,11,11,1|998dfz,11,11,1|998dg0,10,10,0|9ilerz,10,10,0|9iles0,11,11,1|9ryg3z,11,11,1|9ryg40,10,10,0|a1bhfz,10,10,0|a1bhg0,11,11,1|aaoirz,11,11,1|aaois0,10,10,0|ak1k3z,10,10,0|ak1k40,11,11,1|atrk3z,11,11,1|atrk40,10,10,0|b34lfz,10,10,0|b34lg0,11,11,1|bchmrz,11,11,1|bchms0,10,10,0|bluo3z,10,10,0|bluo40,11,11,1|bv7pfz,11,11,1|bv7pg0,10,10,0|c4kqrz,10,10,0|c4kqs0,11,11,1|cdxs3z,11,11,1|cdxs40,10,10,0|cnatfz,10,10,0|cnatg0,11,11,1|cwnurz,11,11,1|cwnus0,10,10,0|d60w3z,10,10,0|d60w40,11,11,1|dfdxfz,11,11,1|dfdxg0,10,10,0|dp3xfz,10,10,0|dp3xg0,11,11,1|dzwtfz,11,11,1|dzwtg0,10,10,0|e7u03z,10,10,0|e7u040,11,11,1|eimw3z,11,11,1|eimw40,10,10,0|eqk2rz,10,10,0|eqk2s0,11,11,1|f1cyrz,11,11,1|f1cys0,10,10,0|f9a5fz,10,10,0|f9a5g0,11,11,1|fkg03z,11,11,1|fkg040,10,10,0|fs083z,10,10,0|fs0840,11,11,1|g362rz,11,11,1|g362s0,10,10,0|gaqarz,10,10,0|gaqas0,11,11,1|glw5fz,11,11,1|glw5g0,10,10,0|gttc3z,10,10,0|gttc40,11,11,1|h4m83z,11,11,1|h4m840,10,10,0|hcjerz,10,10,0|hcjes0,11,11,1|hncarz,11,11,1|hncas0,10,10,0|hv9hfz,10,10,0|hv9hg0,11,11,1|i6fc3z,11,11,1|i6fc40,10,10,0|idzk3z,10,10,0|idzk40,11,11,1|ip5erz,11,11,1|ip5es0,10,10,0|iwpmrz,10,10,0|iwpms0,11,11,1|j7vhfz,11,11,1|j7vhg0,10,10,0|jffpfz,10,10,0|jffpg0,11,11,1|jqlk3z,11,11,1|jqlk40,10,10,0|jyiqrz,10,10,0|jyiqs0,11,11,1|k9bmrz,11,11,1|k9bms0,10,10,0|kh8tfz,10,10,0|kh8tg0,11,11,1|ks1pfz,11,11,1|ks1pg0,10,10,0|kzyw3z,10,10,0|kzyw40,11,11,1|lb4qrz,11,11,1|lb4qs0,10,10,0|lioyrz,10,10,0|lioys0,11,11,1|ltutfz,11,11,1|ltutg0,10,10,0|m1f1fz,10,10,0|m1f1g0,11,11,1|mckw3z,11,11,1|mckw40,10,10,0|mki2rz,10,10,0|mki2s0,11,11,1|mvayrz,11,11,1|mvays0,10,10,0|n385fz,10,10,0|n385g0,11,11,1|ne11fz,11,11,1|ne11g0,10,10,0|nly83z,10,10,0|nly840,11,11,1|nwr43z,11,11,1|nwr440,10,10,0|o4oarz,10,10,0|o4oas0,11,11,1|ofu5fz,11,11,1|ofu5g0,10,10,0|onedfz,10,10,0|onedg0,11,11,1|oyk83z,11,11,1|oyk840,10,10,0|p64g3z,10,10,0|p64g40,11,11,1|phaarz,11,11,1|phaas0,10,10,0|pp7hfz,10,10,0|pp7hg0,11,11,1|q00dfz,11,11,1|q00dg0,10,10,0|q7xk3z,10,10,0|q7xk40,11,11,1|qiqg3z,11,11,1|qiqg40,10,10,0|qqnmrz,10,10,0|qqnms0,11,11,1|r1thfz,11,11,1|r1thg0,10,10,0|r9dpfz,10,10,0|r9dpg0,11,11,1|rkjk3z,11,11,1|rkjk40,10,10,0|rs3s3z,10,10,0|rs3s40,11,11,1|s39mrz,11,11,1|s39ms0,10,10,0|sb6tfz,10,10,0|sb6tg0,11,11,1|slzpfz,11,11,1|slzpg0,10,10,0|stww3z,10,10,0|stww40,11,11,1|t4ps3z,11,11,1|t4ps40,10,10,0|tcmyrz,10,10,0|tcmys0,11,11,1|tnfurz,11,11,1|tnfus0,10,10,0|tvd1fz,10,10,0|tvd1g0,11,11,1|u6iw3z,11,11,1|u6iw40,10,10,0|ue343z,10,10,0|ue3440,11,11,1|up8yrz,11,11,1|up8ys0,10,10,0|uwt6rz,10,10,0|uwt6s0,11,11,1|v7z1fz,11,11,1|v7z1g0,10,10,0|vfw83z,10,10,0|vfw840,11,11,1|vqp43z,11,11,1|vqp440,10,10,0|vymarz,10,10,0|vymas0,11,11,1|w9f6rz,11,11,1|w9f6s0,10,10,0|whcdfz,10,10,0|whcdg0,11,11,1|wsi83z,11,11,1|wsi840,10,10,0|x02g3z,10,10,0|x02g40,11,11,1|xb8arz,11,11,1|xb8as0,10,10,0|xisirz,10,10,0|xisis0,11,11,1|xtydfz,11,11,1|xtydg0,10,10,0|y1ilfz,10,10,0|y1ilg0,11,11,1|ycog3z,11,11,1|ycog40,10,10,0|yklmrz,10,10,0|yklms0,11,11,1|yveirz,11,11,1|yveis0,10,10,0|z3bpfz,10,10,0|z3bpg0,11,11,1|ze4lfz,11,11,1|ze4lg0,10,10,0\",\"Indian/Antananarivo|,0,4,0|-w6p5hg,4,5,0|-lnsey1,4,5,0|-lnsey0,5,6,0|-kvcdo1,5,6,0|-kvcdo0,4,5,0|-h80ka1,4,5,0|-h80ka0,6,7,0|-eb6ib1,6,7,0|-eb6ib0,5,6,0\",\"Indian/Chagos|,0,382,0|-wvpc2s,92,194,0|dkgsrz,92,194,0|dkgss0,96,196,0\",\"Indian/Christmas|,0,383,0|-133iwws,91,193,0\",\"Indian/Cocos|,0,384,0|-10j6sm4,109,229,0\",\"Indian/Comoro|,0,4,0|-w6p5hg,4,5,0|-lnsey1,4,5,0|-lnsey0,5,6,0|-kvcdo1,5,6,0|-kvcdo0,4,5,0|-h80ka1,4,5,0|-h80ka0,6,7,0|-eb6ib1,6,7,0|-eb6ib0,5,6,0\",\"Indian/Kerguelen|,60,1,0|-afrs00,92,194,0\",\"Indian/Mahe|,0,385,0|-wvp8xo,105,209,0\",\"Indian/Maldives|,0,386,0|-1ayyga0,21,386,0|-57x6y1,21,386,0|-57x6y0,92,194,0\",\"Indian/Mauritius|,0,387,0|-wvp9bc,105,209,0|6nykvz,105,209,0|6nykw0,92,194,1|6wai3z,92,194,1|6wai40,105,209,0|k9befz,105,209,0|k9beg0,92,194,1|kh8ibz,92,194,1|kh8ic0,105,209,0\",\"Indian/Mayotte|,0,4,0|-w6p5hg,4,5,0|-lnsey1,4,5,0|-lnsey0,5,6,0|-kvcdo1,5,6,0|-kvcdo0,4,5,0|-h80ka1,4,5,0|-h80ka0,6,7,0|-eb6ib1,6,7,0|-eb6ib0,5,6,0\",\"Indian/Reunion|,0,388,0|-uks29s,105,209,0\",\"Pacific/Apia|,0,389,0|-14fxxj4,0,390,0|-usiiv5,0,390,0|-usiiv4,158,391,0|-afqw21,158,391,0|-afqw20,159,35,0|l9cp7z,159,35,0|l9cp80,160,36,1|lj12vz,160,36,1|lj12w0,159,35,0|ls15jz,159,35,0|ls15k0,160,36,1|lx0h3z,160,36,1|lx0h40,104,207,1|m1r5jz,104,207,1|m1r5k0,103,201,0|mb46vz,103,201,0|mb46w0,104,207,1|mku6vz,104,207,1|mku6w0,103,201,0|mtu9jz,103,201,0|mtu9k0,104,207,1|n3k9jz,104,207,1|n3k9k0,103,201,0|nckc7z,103,201,0|nckc80,104,207,1|nmac7z,104,207,1|nmac80,103,201,0|nvaevz,103,201,0|nvaew0,104,207,1|o50evz,104,207,1|o50ew0,103,201,0|oe0hjz,103,201,0|oe0hk0,104,207,1|onqhjz,104,207,1|onqhk0,103,201,0|owqk7z,103,201,0|owqk80,104,207,1|p6gk7z,104,207,1|p6gk80,103,201,0|pftljz,103,201,0|pftlk0,104,207,1|ppjljz,104,207,1|ppjlk0,103,201,0|pyjo7z,103,201,0|pyjo80,104,207,1|q89o7z,104,207,1|q89o80,103,201,0|qh9qvz,103,201,0|qh9qw0,104,207,1|qqzqvz,104,207,1|qqzqw0,103,201,0|qzztjz,103,201,0|qzztk0,104,207,1|r9ptjz,104,207,1|r9ptk0,103,201,0|ripw7z,103,201,0|ripw80,104,207,1|rsfw7z,104,207,1|rsfw80,103,201,0|s1fyvz,103,201,0|s1fyw0,104,207,1|sbixjz,104,207,1|sbixk0,103,201,0|skj07z,103,201,0|skj080,104,207,1|su907z,104,207,1|su9080,103,201,0|t392vz,103,201,0|t392w0,104,207,1|tcz2vz,104,207,1|tcz2w0,103,201,0|tlz5jz,103,201,0|tlz5k0,104,207,1|tvp5jz,104,207,1|tvp5k0,103,201,0|u4p87z,103,201,0|u4p880,104,207,1|uef87z,104,207,1|uef880,103,201,0|unfavz,103,201,0|unfaw0,104,207,1|ux5avz,104,207,1|ux5aw0,103,201,0|v6ic7z,103,201,0|v6ic80,104,207,1|vg8c7z,104,207,1|vg8c80,103,201,0|vp8evz,103,201,0|vp8ew0,104,207,1|vyyevz,104,207,1|vyyew0,103,201,0|w7yhjz,103,201,0|w7yhk0,104,207,1|whohjz,104,207,1|whohk0,103,201,0|wqok7z,103,201,0|wqok80,104,207,1|x0ek7z,104,207,1|x0ek80,103,201,0|x9emvz,103,201,0|x9emw0,104,207,1|xj4mvz,104,207,1|xj4mw0,103,201,0|xs4pjz,103,201,0|xs4pk0,104,207,1|y1upjz,104,207,1|y1upk0,103,201,0|yb7qvz,103,201,0|yb7qw0,104,207,1|ykxqvz,104,207,1|ykxqw0,103,201,0|ytxtjz,103,201,0|ytxtk0,104,207,1|z3ntjz,104,207,1|z3ntk0,103,201,0|zcnw7z,103,201,0|zcnw80,104,207,1\",\"Pacific/Auckland|,0,197,0|-1gsoz14,97,198,0|-m01p21,97,198,0|-m01p20,98,199,1|-ltxei1,98,199,1|-ltxei0,97,198,0|-lieie1,97,198,0|-lieie0,98,200,1|-lahd41,98,200,1|-lahd40,97,198,0|-kzofq1,97,198,0|-kzofq0,98,200,1|-krrag1,98,200,1|-krrag0,97,198,0|-kgyd21,97,198,0|-kgyd20,98,200,1|-k917s1,98,200,1|-k917s0,97,198,0|-jy8ae1,97,198,0|-jy8ae0,98,200,1|-jpy6g1,98,200,1|-jpy6g0,97,198,0|-jfi7q1,97,198,0|-jfi7q0,98,200,1|-j783s1,98,200,1|-j783s0,97,198,0|-iws521,97,198,0|-iws520,98,200,1|-imc941,98,200,1|-imc940,97,198,0|-ief121,97,198,0|-ief120,98,200,1|-i3m6g1,98,200,1|-i3m6g0,97,198,0|-hvoye1,97,198,0|-hvoye0,98,200,1|-hkw3s1,98,200,1|-hkw3s0,97,198,0|-hcyvq1,97,198,0|-hcyvq0,98,200,1|-h26141,98,200,1|-h26140,97,198,0|-gu8t21,97,198,0|-gu8t20,98,200,1|-gjfyg1,98,200,1|-gjfyg0,97,198,0|-gbiqe1,97,198,0|-gbiqe0,98,200,1|-g0cx41,98,200,1|-g0cx40,97,198,0|-fssnq1,97,198,0|-fssnq0,98,200,1|-fhmug1,98,200,1|-fhmug0,97,198,0|-f9pme1,97,198,0|-f9pme0,98,200,1|-ciy9c1,98,200,1|-ciy9c0,98,200,0|2ivg7z,98,200,0|2ivg80,99,201,1|2omuvz,99,201,1|2omuw0,98,200,0|318k7z,98,200,0|318k80,99,201,1|382uvz,99,201,1|382uw0,98,200,0|3kbljz,98,200,0|3kblk0,99,201,1|3qsxjz,99,201,1|3qsxk0,98,200,0|431o7z,98,200,0|431o80,99,201,1|49j07z,99,201,1|49j080,98,200,0|4lrqvz,98,200,0|4lrqw0,99,201,1|4s92vz,99,201,1|4s92w0,98,200,0|54htjz,98,200,0|54htk0,99,201,1|5az5jz,99,201,1|5az5k0,98,200,0|5n7w7z,98,200,0|5n7w80,99,201,1|5tp87z,99,201,1|5tp880,98,200,0|65xyvz,98,200,0|65xyw0,99,201,1|6cs9jz,99,201,1|6cs9k0,98,200,0|6p107z,98,200,0|6p1080,99,201,1|6vic7z,99,201,1|6vic80,98,200,0|77r2vz,98,200,0|77r2w0,99,201,1|7e8evz,99,201,1|7e8ew0,98,200,0|7qh5jz,98,200,0|7qh5k0,99,201,1|7wyhjz,99,201,1|7wyhk0,98,200,0|89787z,98,200,0|897880,99,201,1|8fok7z,99,201,1|8fok80,98,200,0|8rxavz,98,200,0|8rxaw0,99,201,1|8yemvz,99,201,1|8yemw0,98,200,0|9andjz,98,200,0|9andk0,99,201,1|9hho7z,99,201,1|9hho80,98,200,0|9tqevz,98,200,0|9tqew0,99,201,1|a07qvz,99,201,1|a07qw0,98,200,0|abdljz,98,200,0|abdlk0,99,201,1|ajnqvz,99,201,1|ajnqw0,98,200,0|au3o7z,98,200,0|au3o80,99,201,1|b2dtjz,99,201,1|b2dtk0,98,200,0|bctqvz,98,200,0|bctqw0,99,201,1|bl3w7z,99,201,1|bl3w80,98,200,0|bvjtjz,98,200,0|bvjtk0,99,201,1|c46xjz,99,201,1|c46xk0,98,200,0|ce9w7z,98,200,0|ce9w80,99,201,1|cmx07z,99,201,1|cmx080,98,200,0|cwzyvz,98,200,0|cwzyw0,99,201,1|d5n2vz,99,201,1|d5n2w0,98,200,0|dfq1jz,98,200,0|dfq1k0,99,201,1|dod5jz,99,201,1|dod5k0,98,200,0|dyt2vz,98,200,0|dyt2w0,99,201,1|e7387z,99,201,1|e73880,98,200,0|ehj5jz,98,200,0|ehj5k0,99,201,1|eptavz,99,201,1|eptaw0,98,200,0|f0987z,98,200,0|f09880,99,201,1|f8wc7z,99,201,1|f8wc80,98,200,0|fizavz,98,200,0|fizaw0,99,201,1|frmevz,99,201,1|frmew0,98,200,0|g1pdjz,98,200,0|g1pdk0,99,201,1|gachjz,99,201,1|gachk0,98,200,0|gksevz,98,200,0|gksew0,99,201,1|gt2k7z,99,201,1|gt2k80,98,200,0|h3ihjz,98,200,0|h3ihk0,99,201,1|hbsmvz,99,201,1|hbsmw0,98,200,0|hm8k7z,98,200,0|hm8k80,99,201,1|huvo7z,99,201,1|huvo80,98,200,0|i4ymvz,98,200,0|i4ymw0,99,201,1|idlqvz,99,201,1|idlqw0,98,200,0|inopjz,98,200,0|inopk0,99,201,1|iwbtjz,99,201,1|iwbtk0,98,200,0|j6es7z,98,200,0|j6es80,99,201,1|jf1w7z,99,201,1|jf1w80,98,200,0|jp4uvz,98,200,0|jp4uw0,99,201,1|jyuuvz,99,201,1|jyuuw0,98,200,0|k7uxjz,98,200,0|k7uxk0,99,201,1|khkxjz,99,201,1|khkxk0,98,200,0|kql07z,98,200,0|kql080,99,201,1|l0b07z,99,201,1|l0b080,98,200,0|l9b2vz,98,200,0|l9b2w0,99,201,1|lj12vz,99,201,1|lj12w0,98,200,0|ls15jz,98,200,0|ls15k0,99,201,1|m1r5jz,99,201,1|m1r5k0,98,200,0|mb46vz,98,200,0|mb46w0,99,201,1|mku6vz,99,201,1|mku6w0,98,200,0|mtu9jz,98,200,0|mtu9k0,99,201,1|n3k9jz,99,201,1|n3k9k0,98,200,0|nckc7z,98,200,0|nckc80,99,201,1|nmac7z,99,201,1|nmac80,98,200,0|nvaevz,98,200,0|nvaew0,99,201,1|o50evz,99,201,1|o50ew0,98,200,0|oe0hjz,98,200,0|oe0hk0,99,201,1|onqhjz,99,201,1|onqhk0,98,200,0|owqk7z,98,200,0|owqk80,99,201,1|p6gk7z,99,201,1|p6gk80,98,200,0|pftljz,98,200,0|pftlk0,99,201,1|ppjljz,99,201,1|ppjlk0,98,200,0|pyjo7z,98,200,0|pyjo80,99,201,1|q89o7z,99,201,1|q89o80,98,200,0|qh9qvz,98,200,0|qh9qw0,99,201,1|qqzqvz,99,201,1|qqzqw0,98,200,0|qzztjz,98,200,0|qzztk0,99,201,1|r9ptjz,99,201,1|r9ptk0,98,200,0|ripw7z,98,200,0|ripw80,99,201,1|rsfw7z,99,201,1|rsfw80,98,200,0|s1fyvz,98,200,0|s1fyw0,99,201,1|sbixjz,99,201,1|sbixk0,98,200,0|skj07z,98,200,0|skj080,99,201,1|su907z,99,201,1|su9080,98,200,0|t392vz,98,200,0|t392w0,99,201,1|tcz2vz,99,201,1|tcz2w0,98,200,0|tlz5jz,98,200,0|tlz5k0,99,201,1|tvp5jz,99,201,1|tvp5k0,98,200,0|u4p87z,98,200,0|u4p880,99,201,1|uef87z,99,201,1|uef880,98,200,0|unfavz,98,200,0|unfaw0,99,201,1|ux5avz,99,201,1|ux5aw0,98,200,0|v6ic7z,98,200,0|v6ic80,99,201,1|vg8c7z,99,201,1|vg8c80,98,200,0|vp8evz,98,200,0|vp8ew0,99,201,1|vyyevz,99,201,1|vyyew0,98,200,0|w7yhjz,98,200,0|w7yhk0,99,201,1|whohjz,99,201,1|whohk0,98,200,0|wqok7z,98,200,0|wqok80,99,201,1|x0ek7z,99,201,1|x0ek80,98,200,0|x9emvz,98,200,0|x9emw0,99,201,1|xj4mvz,99,201,1|xj4mw0,98,200,0|xs4pjz,98,200,0|xs4pk0,99,201,1|y1upjz,99,201,1|y1upk0,98,200,0|yb7qvz,98,200,0|yb7qw0,99,201,1|ykxqvz,99,201,1|ykxqw0,98,200,0|ytxtjz,98,200,0|ytxtk0,99,201,1|z3ntjz,99,201,1|z3ntk0,98,200,0|zcnw7z,98,200,0|zcnw80,99,201,1\",\"Pacific/Bougainville|,0,392,0|-1ayyvh4,161,393,0|-1354j8x,161,393,0|-1354j8w,93,195,0|-ecsh41,93,195,0|-ecsh40,107,224,0|-cpsbo1,107,224,0|-cpsbo0,93,195,0|nh90fz,93,195,0|nh90g0,90,192,0\",\"Pacific/Chatham|,0,394,0|-1gsp0n0,162,395,0|-ciya11,162,395,0|-ciya10,163,396,0|2ivg7z,163,396,0|2ivg80,164,397,1|2omuvz,164,397,1|2omuw0,163,396,0|318k7z,163,396,0|318k80,164,397,1|382uvz,164,397,1|382uw0,163,396,0|3kbljz,163,396,0|3kblk0,164,397,1|3qsxjz,164,397,1|3qsxk0,163,396,0|431o7z,163,396,0|431o80,164,397,1|49j07z,164,397,1|49j080,163,396,0|4lrqvz,163,396,0|4lrqw0,164,397,1|4s92vz,164,397,1|4s92w0,163,396,0|54htjz,163,396,0|54htk0,164,397,1|5az5jz,164,397,1|5az5k0,163,396,0|5n7w7z,163,396,0|5n7w80,164,397,1|5tp87z,164,397,1|5tp880,163,396,0|65xyvz,163,396,0|65xyw0,164,397,1|6cs9jz,164,397,1|6cs9k0,163,396,0|6p107z,163,396,0|6p1080,164,397,1|6vic7z,164,397,1|6vic80,163,396,0|77r2vz,163,396,0|77r2w0,164,397,1|7e8evz,164,397,1|7e8ew0,163,396,0|7qh5jz,163,396,0|7qh5k0,164,397,1|7wyhjz,164,397,1|7wyhk0,163,396,0|89787z,163,396,0|897880,164,397,1|8fok7z,164,397,1|8fok80,163,396,0|8rxavz,163,396,0|8rxaw0,164,397,1|8yemvz,164,397,1|8yemw0,163,396,0|9andjz,163,396,0|9andk0,164,397,1|9hho7z,164,397,1|9hho80,163,396,0|9tqevz,163,396,0|9tqew0,164,397,1|a07qvz,164,397,1|a07qw0,163,396,0|abdljz,163,396,0|abdlk0,164,397,1|ajnqvz,164,397,1|ajnqw0,163,396,0|au3o7z,163,396,0|au3o80,164,397,1|b2dtjz,164,397,1|b2dtk0,163,396,0|bctqvz,163,396,0|bctqw0,164,397,1|bl3w7z,164,397,1|bl3w80,163,396,0|bvjtjz,163,396,0|bvjtk0,164,397,1|c46xjz,164,397,1|c46xk0,163,396,0|ce9w7z,163,396,0|ce9w80,164,397,1|cmx07z,164,397,1|cmx080,163,396,0|cwzyvz,163,396,0|cwzyw0,164,397,1|d5n2vz,164,397,1|d5n2w0,163,396,0|dfq1jz,163,396,0|dfq1k0,164,397,1|dod5jz,164,397,1|dod5k0,163,396,0|dyt2vz,163,396,0|dyt2w0,164,397,1|e7387z,164,397,1|e73880,163,396,0|ehj5jz,163,396,0|ehj5k0,164,397,1|eptavz,164,397,1|eptaw0,163,396,0|f0987z,163,396,0|f09880,164,397,1|f8wc7z,164,397,1|f8wc80,163,396,0|fizavz,163,396,0|fizaw0,164,397,1|frmevz,164,397,1|frmew0,163,396,0|g1pdjz,163,396,0|g1pdk0,164,397,1|gachjz,164,397,1|gachk0,163,396,0|gksevz,163,396,0|gksew0,164,397,1|gt2k7z,164,397,1|gt2k80,163,396,0|h3ihjz,163,396,0|h3ihk0,164,397,1|hbsmvz,164,397,1|hbsmw0,163,396,0|hm8k7z,163,396,0|hm8k80,164,397,1|huvo7z,164,397,1|huvo80,163,396,0|i4ymvz,163,396,0|i4ymw0,164,397,1|idlqvz,164,397,1|idlqw0,163,396,0|inopjz,163,396,0|inopk0,164,397,1|iwbtjz,164,397,1|iwbtk0,163,396,0|j6es7z,163,396,0|j6es80,164,397,1|jf1w7z,164,397,1|jf1w80,163,396,0|jp4uvz,163,396,0|jp4uw0,164,397,1|jyuuvz,164,397,1|jyuuw0,163,396,0|k7uxjz,163,396,0|k7uxk0,164,397,1|khkxjz,164,397,1|khkxk0,163,396,0|kql07z,163,396,0|kql080,164,397,1|l0b07z,164,397,1|l0b080,163,396,0|l9b2vz,163,396,0|l9b2w0,164,397,1|lj12vz,164,397,1|lj12w0,163,396,0|ls15jz,163,396,0|ls15k0,164,397,1|m1r5jz,164,397,1|m1r5k0,163,396,0|mb46vz,163,396,0|mb46w0,164,397,1|mku6vz,164,397,1|mku6w0,163,396,0|mtu9jz,163,396,0|mtu9k0,164,397,1|n3k9jz,164,397,1|n3k9k0,163,396,0|nckc7z,163,396,0|nckc80,164,397,1|nmac7z,164,397,1|nmac80,163,396,0|nvaevz,163,396,0|nvaew0,164,397,1|o50evz,164,397,1|o50ew0,163,396,0|oe0hjz,163,396,0|oe0hk0,164,397,1|onqhjz,164,397,1|onqhk0,163,396,0|owqk7z,163,396,0|owqk80,164,397,1|p6gk7z,164,397,1|p6gk80,163,396,0|pftljz,163,396,0|pftlk0,164,397,1|ppjljz,164,397,1|ppjlk0,163,396,0|pyjo7z,163,396,0|pyjo80,164,397,1|q89o7z,164,397,1|q89o80,163,396,0|qh9qvz,163,396,0|qh9qw0,164,397,1|qqzqvz,164,397,1|qqzqw0,163,396,0|qzztjz,163,396,0|qzztk0,164,397,1|r9ptjz,164,397,1|r9ptk0,163,396,0|ripw7z,163,396,0|ripw80,164,397,1|rsfw7z,164,397,1|rsfw80,163,396,0|s1fyvz,163,396,0|s1fyw0,164,397,1|sbixjz,164,397,1|sbixk0,163,396,0|skj07z,163,396,0|skj080,164,397,1|su907z,164,397,1|su9080,163,396,0|t392vz,163,396,0|t392w0,164,397,1|tcz2vz,164,397,1|tcz2w0,163,396,0|tlz5jz,163,396,0|tlz5k0,164,397,1|tvp5jz,164,397,1|tvp5k0,163,396,0|u4p87z,163,396,0|u4p880,164,397,1|uef87z,164,397,1|uef880,163,396,0|unfavz,163,396,0|unfaw0,164,397,1|ux5avz,164,397,1|ux5aw0,163,396,0|v6ic7z,163,396,0|v6ic80,164,397,1|vg8c7z,164,397,1|vg8c80,163,396,0|vp8evz,163,396,0|vp8ew0,164,397,1|vyyevz,164,397,1|vyyew0,163,396,0|w7yhjz,163,396,0|w7yhk0,164,397,1|whohjz,164,397,1|whohk0,163,396,0|wqok7z,163,396,0|wqok80,164,397,1|x0ek7z,164,397,1|x0ek80,163,396,0|x9emvz,163,396,0|x9emw0,164,397,1|xj4mvz,164,397,1|xj4mw0,163,396,0|xs4pjz,163,396,0|xs4pk0,164,397,1|y1upjz,164,397,1|y1upk0,163,396,0|yb7qvz,163,396,0|yb7qw0,164,397,1|ykxqvz,164,397,1|ykxqw0,163,396,0|ytxtjz,163,396,0|ytxtk0,164,397,1|z3ntjz,164,397,1|z3ntk0,163,396,0|zcnw7z,163,396,0|zcnw80,164,397,1\",\"Pacific/Chuuk|,0,398,0|-1t8j2rw,0,399,0|-100f5fx,0,399,0|-100f5fw,93,195,0|-su4zs1,93,195,0|-su4zs0,107,224,0|-qknl01,107,224,0|-qknl00,93,195,0|-f08x41,93,195,0|-f08x40,107,224,0|-cqtd01,107,224,0|-cqtd00,93,195,0\",\"Pacific/Easter|,0,400,0|-15r0p2w,165,400,0|-jhfaex,165,400,0|-jhfaew,166,66,0|-lsvk1,166,66,0|-lsvk0,167,62,1|-e8qc1,167,62,1|-e8qc0,166,66,0|-1zww1,166,66,0|-1zww0,167,62,1|4hcbz,167,62,1|4hcc0,166,66,0|ekdrz,166,66,0|ekds0,167,62,1|mhhnz,167,62,1|mhho0,166,66,0|xagfz,166,66,0|xagg0,167,62,1|157kbz,167,62,1|157kc0,166,66,0|1gdhrz,166,66,0|1gdhs0,167,62,1|1nxmzz,167,62,1|1nxn00,166,66,0|1ydn3z,166,66,0|1ydn40,167,62,1|26npnz,167,62,1|26npo0,166,66,0|2htn3z,166,66,0|2htn40,167,62,1|2pdsbz,167,62,1|2pdsc0,166,66,0|30jprz,166,66,0|30jps0,167,62,1|38gtnz,167,62,1|38gto0,166,66,0|3j9sfz,166,66,0|3j9sg0,167,62,1|3r6wbz,167,62,1|3r6wc0,166,66,0|41zv3z,166,66,0|41zv40,167,62,1|49wyzz,167,62,1|49wz00,166,66,0|4l2wfz,166,66,0|4l2wg0,167,62,1|4sn1nz,167,62,1|4sn1o0,166,66,0|53sz3z,166,66,0|53sz40,167,62,1|5bd4bz,167,62,1|5bd4c0,166,66,0|5mj1rz,166,66,0|5mj1s0,167,62,1|5ug5nz,167,62,1|5ug5o0,166,66,0|6594fz,166,66,0|6594g0,167,62,1|6d68bz,167,62,1|6d68c0,167,62,0|6nz73z,167,62,0|6nz740,56,63,1|6vwazz,56,63,1|6vwb00,167,62,0|76p9rz,167,62,0|76p9s0,56,63,1|7emdnz,56,63,1|7emdo0,167,62,0|7psb3z,167,62,0|7psb40,56,63,1|7xcgbz,56,63,1|7xcgc0,167,62,0|88idrz,167,62,0|88ids0,56,63,1|8g2izz,56,63,1|8g2j00,167,62,0|8r8gfz,167,62,0|8r8gg0,56,63,1|90lezz,56,63,1|90lf00,167,62,0|99yj3z,167,62,0|99yj40,56,63,1|9hvmzz,56,63,1|9hvn00,167,62,0|9solrz,167,62,0|9sols0,56,63,1|a0lpnz,56,63,1|a0lpo0,167,62,0|abrn3z,167,62,0|abrn40,56,63,1|ajbsbz,56,63,1|ajbsc0,167,62,0|at1v3z,167,62,0|at1v40,56,63,1|b21uzz,56,63,1|b21v00,167,62,0|bd7sfz,167,62,0|bd7sg0,56,63,1|bl4wbz,56,63,1|bl4wc0,167,62,0|bvxv3z,167,62,0|bvxv40,56,63,1|c3uyzz,56,63,1|c3uz00,167,62,0|cenxrz,167,62,0|cenxs0,56,63,1|cml1nz,56,63,1|cml1o0,167,62,0|cxe0fz,167,62,0|cxe0g0,56,63,1|d5b4bz,56,63,1|d5b4c0,167,62,0|dgh1rz,167,62,0|dgh1s0,56,63,1|do16zz,56,63,1|do1700,167,62,0|dz74fz,167,62,0|dz74g0,56,63,1|e7u5nz,56,63,1|e7u5o0,167,62,0|ehx73z,167,62,0|ehx740,56,63,1|epuazz,56,63,1|epub00,167,62,0|ezxcfz,167,62,0|ezxcg0,56,63,1|f9n9nz,56,63,1|f9n9o0,167,62,0|fjdcfz,167,62,0|fjdcg0,56,63,1|fragbz,56,63,1|fragc0,167,62,0|g2gdrz,167,62,0|g2gds0,56,63,1|ga0izz,56,63,1|ga0j00,167,62,0|gl6gfz,167,62,0|gl6gg0,56,63,1|gsqlnz,56,63,1|gsqlo0,167,62,0|h3wj3z,167,62,0|h3wj40,56,63,1|hbgobz,56,63,1|hbgoc0,167,62,0|hmmlrz,167,62,0|hmmls0,56,63,1|hujpnz,56,63,1|hujpo0,167,62,0|i5cofz,167,62,0|i5cog0,56,63,1|id9sbz,56,63,1|id9sc0,167,62,0|io2r3z,167,62,0|io2r40,56,63,1|ivzuzz,56,63,1|ivzv00,167,62,0|j75sfz,167,62,0|j75sg0,56,63,1|jepxnz,56,63,1|jepxo0,167,62,0|jpvv3z,167,62,0|jpvv40,56,63,1|jyiwbz,56,63,1|jyiwc0,167,62,0|k8lxrz,167,62,0|k8lxs0,56,63,1|kgj1nz,56,63,1|kgj1o0,167,62,0|krc0fz,167,62,0|krc0g0,56,63,1|l0c0bz,56,63,1|l0c0c0,167,62,0|la233z,167,62,0|la2340,56,63,1|lkuwbz,56,63,1|lkuwc0,167,62,0|lq9f3z,167,62,0|lq9f40,56,63,1|m380bz,56,63,1|m380c0,167,62,0|m9pf3z,167,62,0|m9pf40,56,63,1|mly2zz,56,63,1|mly300,167,62,0|mssgfz,167,62,0|mssgg0,56,63,1|n4o5nz,56,63,1|n4o5o0,167,62,0|nbij3z,167,62,0|nbij40,56,63,1|o776zz,56,63,1|o77700,167,62,0|obvsfz,167,62,0|obvsg0,56,63,1|opx9nz,56,63,1|opx9o0,167,62,0|oulv3z,167,62,0|oulv40,56,63,1|p8ncbz,56,63,1|p8ncc0,167,62,0|pdbxrz,167,62,0|pdbxs0,56,63,1|ppklnz,56,63,1|ppklo0,167,62,0|pxhv3z,167,62,0|pxhv40,56,63,1|q8aobz,56,63,1|q8aoc0,167,62,0|qg7xrz,167,62,0|qg7xs0,56,63,1|qr0qzz,56,63,1|qr0r00,167,62,0|qyy0fz,167,62,0|qyy0g0,56,63,1|r9qtnz,56,63,1|r9qto0,167,62,0|rho33z,167,62,0|rho340,56,63,1|rsgwbz,56,63,1|rsgwc0,167,62,0|s0e5rz,167,62,0|s0e5s0,56,63,1|sbjxnz,56,63,1|sbjxo0,167,62,0|sjh73z,167,62,0|sjh740,56,63,1|sua0bz,56,63,1|sua0c0,167,62,0|t279rz,167,62,0|t279s0,56,63,1|td02zz,56,63,1|td0300,167,62,0|tkxcfz,167,62,0|tkxcg0,56,63,1|tvq5nz,56,63,1|tvq5o0,167,62,0|u3nf3z,167,62,0|u3nf40,56,63,1|ueg8bz,56,63,1|ueg8c0,167,62,0|umdhrz,167,62,0|umdhs0,56,63,1|uxj9nz,56,63,1|uxj9o0,167,62,0|v53kfz,167,62,0|v53kg0,56,63,1|vg9cbz,56,63,1|vg9cc0,167,62,0|vo6lrz,167,62,0|vo6ls0,56,63,1|vyzezz,56,63,1|vyzf00,167,62,0|w6wofz,167,62,0|w6wog0,56,63,1|whphnz,56,63,1|whpho0,167,62,0|wpmr3z,167,62,0|wpmr40,56,63,1|x0fkbz,56,63,1|x0fkc0,167,62,0|x8ctrz,167,62,0|x8cts0,56,63,1|xj5mzz,56,63,1|xj5n00,167,62,0|xr2wfz,167,62,0|xr2wg0,56,63,1|y28obz,56,63,1|y28oc0,167,62,0|y9sz3z,167,62,0|y9sz40,56,63,1|ykyqzz,56,63,1|ykyr00,167,62,0|ysw0fz,167,62,0|ysw0g0,56,63,1|z3otnz,56,63,1|z3oto0,167,62,0|zbm33z,167,62,0|zbm340,56,63,1\",\"Pacific/Efate|,0,401,0|-u964i4,90,192,0|22nynz,90,192,0|22nyo0,102,200,1|27pfzz,102,200,1|27pg00,90,192,0|75y6rz,90,192,0|75y6s0,102,200,1|7fb5bz,102,200,1|7fb5c0,90,192,0|7oo9fz,90,192,0|7oo9g0,102,200,1|7y17zz,102,200,1|7y1800,90,192,0|87rarz,90,192,0|87ras0,102,200,1|8granz,102,200,1|8grao0,90,192,0|8qhdfz,90,192,0|8qhdg0,102,200,1|8zubzz,102,200,1|8zuc00,90,192,0|997g3z,90,192,0|997g40,102,200,1|9ikenz,102,200,1|9ikeo0,90,192,0|9rxirz,90,192,0|9rxis0,102,200,1|a1ahbz,102,200,1|a1ahc0,90,192,0|aanlfz,90,192,0|aanlg0,102,200,1|ak0jzz,102,200,1|ak0k00,90,192,0|atdo3z,90,192,0|atdo40,102,200,1|b2qmnz,102,200,1|b2qmo0,90,192,0|bcgpfz,90,192,0|bcgpg0,102,200,1|bikzzz,102,200,1|bil000,90,192,0|bwmmrz,90,192,0|bwmms0,102,200,1|c1b2nz,102,200,1|c1b2o0,90,192,0\",\"Pacific/Enderbury|,0,402,0|-100dhng,168,403,0|535inz,168,403,0|535io0,159,35,0|d1o97z,159,35,0|d1o980,103,201,0\",\"Pacific/Fakaofo|,0,404,0|-100dhmg,159,35,0|lx0jvz,159,35,0|lx0jw0,103,201,0\",\"Pacific/Fiji|,0,405,0|-sa2x4w,102,200,0|f1p2vz,102,200,0|f1p2w0,103,201,1|f7tg7z,103,201,1|f7tg80,102,200,0|fks47z,102,200,0|fks480,103,201,1|fqjivz,103,201,1|fqjiw0,102,200,0|ktto7z,102,200,0|ktto80,103,201,1|kzy1jz,103,201,1|kzy1k0,102,200,0|laqxjz,102,200,0|laqxk0,103,201,1|lhl87z,103,201,1|lhl880,102,200,0|lth07z,102,200,0|lth080,103,201,1|ly5ivz,103,201,1|ly5iw0,102,200,0|mc72vz,102,200,0|mc72w0,103,201,1|mgvljz,103,201,1|mgvlk0,102,200,0|mva47z,102,200,0|mva480,103,201,1|mzllfz,103,201,1|mzllg0,102,200,0|ned5jz,102,200,0|ned5k0,103,201,1|nibqvz,103,201,1|nibqw0,102,200,0|nx387z,102,200,0|nx3880,103,201,1|o11tjz,103,201,1|o11tk0,102,200,0|og69jz,102,200,0|og69k0,103,201,1|ojrw7z,103,201,1|ojrw80,102,200,0|oywc7z,102,200,0|oywc80,103,201,1|p2hyvz,103,201,1|p2hyw0,102,200,0|phmevz,102,200,0|phmew0,103,201,1|pl81jz,103,201,1|pl81k0,102,200,0|q0pg7z,102,200,0|q0pg80,103,201,1|q3y47z,103,201,1|q3y480,102,200,0|qllavz,102,200,0|qllaw0,103,201,1|qn15jz,103,201,1|qn15k0,102,200,0|r2ik7z,102,200,0|r2ik80,103,201,1|r5r87z,103,201,1|r5r880,102,200,0|rl8mvz,102,200,0|rl8mw0,103,201,1|rohavz,103,201,1|rohaw0,102,200,0|s3ypjz,102,200,0|s3ypk0,103,201,1|s77djz,103,201,1|s77dk0,102,200,0|smos7z,102,200,0|smos80,103,201,1|spxg7z,103,201,1|spxg80,102,200,0|t5euvz,102,200,0|t5euw0,103,201,1|t90hjz,103,201,1|t90hk0,102,200,0|to4xjz,102,200,0|to4xk0,103,201,1|trqk7z,103,201,1|trqk80,102,200,0|u77yvz,102,200,0|u77yw0,103,201,1|uagmvz,103,201,1|uagmw0,102,200,0|upy1jz,102,200,0|upy1k0,103,201,1|ut6pjz,103,201,1|ut6pk0,102,200,0|v8o47z,102,200,0|v8o480,103,201,1|vbws7z,103,201,1|vbws80,102,200,0|vre6vz,102,200,0|vre6w0,103,201,1|vumuvz,103,201,1|vumuw0,102,200,0|wa49jz,102,200,0|wa49k0,103,201,1|wdpw7z,103,201,1|wdpw80,102,200,0|wt7avz,102,200,0|wt7aw0,103,201,1|wwfyvz,103,201,1|wwfyw0,102,200,0|xbxdjz,102,200,0|xbxdk0,103,201,1|xf61jz,103,201,1|xf61k0,102,200,0|xung7z,102,200,0|xung80,103,201,1|xxw47z,103,201,1|xxw480,102,200,0|yddivz,102,200,0|yddiw0,103,201,1|ygm6vz,103,201,1|ygm6w0,102,200,0|yw3ljz,102,200,0|yw3lk0,103,201,1|yzp87z,103,201,1|yzp880,102,200,0|zeto7z,102,200,0|zeto80,103,201,1\",\"Pacific/Funafuti|,0,406,0|-100fais,102,200,0\",\"Pacific/Galapagos|,0,407,0|-kcr62o,56,63,0|8cmlvz,56,63,0|8cmlw0,167,62,0|byewnz,167,62,0|byewo0,56,63,1|c1ylvz,56,63,1|c1ylw0,167,62,0\",\"Pacific/Gambier|,0,408,0|-tvndoc,169,37,0\",\"Pacific/Guadalcanal|,0,409,0|-tvowac,90,192,0\",\"Pacific/Guam|,0,410,0|-1t8j1h0,0,411,0|-100f451,0,411,0|-100f450,170,195,0|-en8eg1,170,195,0|-en8eg0,107,224,0|-d9n501,107,224,0|-d9n500,170,195,0|-5hlkw1,170,195,0|-5hlkw0,171,192,1|-4nnvo1,171,192,1|-4nnvo0,170,195,0|-17w8w1,170,195,0|-17w8w0,171,192,1|-hih6d,171,192,1|-hih6c,170,195,0|-9y0w1,170,195,0|-9y0w0,171,192,1|-6ch01,171,192,1|-6ch00,170,195,0|5wcfz,170,195,0|5wcg0,171,192,1|cqkbz,171,192,1|cqkc0,170,195,0|omf3z,170,195,0|omf40,171,192,1|vgmzz,171,192,1|vgn00,170,195,0|22bb3z,170,195,0|22bb40,171,192,1|25wuzz,171,192,1|25wv00,170,195,0|3c75rz,170,195,0|3c75s0,171,192,1|3gq1pn,171,192,1|3gq1po,170,195,0|3tbtrz,170,195,0|3tbts0,171,192,1|3zt2zz,171,192,1|3zt300,170,195,0|g5z2vz,170,195,0|g5z2w0,172,195,0\",\"Pacific/Honolulu|,0,412,0|-12lnw3m,30,413,0|-j50la1,30,413,0|-j50la0,31,414,1|-j3x0a1,31,414,1|-j3x0a0,30,413,0|-ek1pa1,30,413,0|-ek1pa0,173,414,1|-cq2tg1,173,414,1|-cq2tg0,174,414,1|-cnoo21,174,414,1|-cnoo20,30,413,0|-brzum1,30,413,0|-brzum0,30,36,0\",\"Pacific/Kiritimati|,0,415,0|-100dk74,175,416,0|535eyn,175,416,0|535eyo,160,36,0|d1o6fz,160,36,0|d1o6g0,104,207,0\",\"Pacific/Kosrae|,0,417,0|-1t8j4uk,0,418,0|-100f7il,0,418,0|-100f7ik,90,192,0|-su52k1,90,192,0|-su52k0,107,224,0|-qknl01,107,224,0|-qknl00,90,192,0|-h817w1,90,192,0|-h817w0,93,195,0|-f08x41,93,195,0|-f08x40,107,224,0|-cqtd01,107,224,0|-cqtd00,90,192,0|-4r7w1,90,192,0|-4r7w0,102,200,0|f4tvzz,102,200,0|f4tw00,90,192,0\",\"Pacific/Kwajalein|,0,419,0|-100f8bk,90,192,0|-h817w1,90,192,0|-h817w0,93,195,0|-f08x41,93,195,0|-f08x40,107,224,0|-dip2c1,107,224,0|-dip2c0,90,192,0|-4r7w1,90,192,0|-4r7w0,168,403,0|cc3ynz,168,403,0|cc3yo0,102,200,0\",\"Pacific/Majuro|,0,420,0|-100f91c,90,192,0|-su52k1,90,192,0|-su52k0,107,224,0|-qknl01,107,224,0|-qknl00,90,192,0|-h817w1,90,192,0|-h817w0,93,195,0|-f08x41,93,195,0|-f08x40,107,224,0|-dj2101,107,224,0|-dj2100,90,192,0|-4r7w1,90,192,0|-4r7w0,102,200,0\",\"Pacific/Marquesas|,0,421,0|-tvncu0,176,414,0\",\"Pacific/Midway|,0,422,0|-14fxxq0,0,423,0|-usij21,0,423,0|-usij20,177,35,0\",\"Pacific/Nauru|,0,424,0|-pjxiws,143,198,0|-e9rby1,143,198,0|-e9rby0,107,224,0|-couzo1,107,224,0|-couzo0,143,198,0|4r4dlz,143,198,0|4r4dm0,102,200,0\",\"Pacific/Niue|,0,425,0|-100dhv8,178,426,0|-9wyz6p,178,426,0|-9wyz6o,158,391,0|4kdjxz,158,391,0|4kdjy0,159,35,0\",\"Pacific/Norfolk|,0,427,0|-100f8fs,179,428,0|-9x0ps1,179,428,0|-9x0ps0,143,198,0|2iiixz,143,198,0|2iiiy0,180,199,1|2ozuxz,180,199,1|2ozuy0,143,198,0|nvnexz,143,198,0|nvney0,90,192,0|pywpnz,90,192,0|pywpo0,102,200,1|q89qzz,102,200,1|q89r00,90,192,0|qhmsbz,90,192,0|qhmsc0,102,200,1|qqztnz,102,200,1|qqzto0,90,192,0|r0cuzz,90,192,0|r0cv00,102,200,1|r9pwbz,102,200,1|r9pwc0,90,192,0|rj2xnz,90,192,0|rj2xo0,102,200,1|rsfyzz,102,200,1|rsfz00,90,192,0|s1t0bz,90,192,0|s1t0c0,102,200,1|sbj0bz,102,200,1|sbj0c0,90,192,0|skw1nz,90,192,0|skw1o0,102,200,1|su92zz,102,200,1|su9300,90,192,0|t3m4bz,90,192,0|t3m4c0,102,200,1|tcz5nz,102,200,1|tcz5o0,90,192,0|tmc6zz,90,192,0|tmc700,102,200,1|tvp8bz,102,200,1|tvp8c0,90,192,0|u529nz,90,192,0|u529o0,102,200,1|uefazz,102,200,1|uefb00,90,192,0|unscbz,90,192,0|unscc0,102,200,1|ux5dnz,102,200,1|ux5do0,90,192,0|v6vdnz,90,192,0|v6vdo0,102,200,1|vg8ezz,102,200,1|vg8f00,90,192,0|vplgbz,90,192,0|vplgc0,102,200,1|vyyhnz,102,200,1|vyyho0,90,192,0|w8bizz,90,192,0|w8bj00,102,200,1|whokbz,102,200,1|whokc0,90,192,0|wr1lnz,90,192,0|wr1lo0,102,200,1|x0emzz,102,200,1|x0en00,90,192,0|x9robz,90,192,0|x9roc0,102,200,1|xj4pnz,102,200,1|xj4po0,90,192,0|xshqzz,90,192,0|xshr00,102,200,1|y1usbz,102,200,1|y1usc0,90,192,0|ybksbz,90,192,0|ybksc0,102,200,1|ykxtnz,102,200,1|ykxto0,90,192,0|yuauzz,90,192,0|yuav00,102,200,1|z3nwbz,102,200,1|z3nwc0,90,192,0|zd0xnz,90,192,0|zd0xo0,102,200,1\",\"Pacific/Noumea|,0,429,0|-u9645o,90,192,0|44uerz,90,192,0|44ues0,102,200,1|497qnz,102,200,1|497qo0,90,192,0|4nkhfz,90,192,0|4nkhg0,102,200,1|4rznzz,102,200,1|4rzo00,90,192,0|e1ouzz,90,192,0|e1ov00,102,200,1|e6ddnz,102,200,1|e6ddo0,90,192,0\",\"Pacific/Pago_Pago|,0,422,0|-14fxxq0,0,423,0|-usij21,0,423,0|-usij20,177,35,0\",\"Pacific/Palau|,0,430,0|-1t8izkk,0,431,0|-100f28l,0,431,0|-100f28k,107,224,0\",\"Pacific/Pitcairn|,0,432,0|-100dp8s,181,433,0|es2cxz,181,433,0|es2cy0,182,40,0\",\"Pacific/Pohnpei|,0,434,0|-1t8j3ys,0,435,0|-100f6mt,0,435,0|-100f6ms,90,192,0|-su52k1,90,192,0|-su52k0,107,224,0|-qknl01,107,224,0|-qknl00,90,192,0|-h817w1,90,192,0|-h817w0,93,195,0|-f08x41,93,195,0|-f08x40,107,224,0|-cqtd01,107,224,0|-cqtd00,90,192,0\",\"Pacific/Port_Moresby|,0,436,0|-1ayytx4,161,393,0|-1354j8x,161,393,0|-1354j8w,93,195,0\",\"Pacific/Rarotonga|,0,437,0|-100djqw,183,413,0|4mj95z,183,413,0|4mj960,176,414,1|4sal1z,176,414,1|4sal20,160,36,0|54jd3z,160,36,0|54jd40,176,414,1|5b0npz,176,414,1|5b0nq0,160,36,0|5n9frz,160,36,0|5n9fs0,176,414,1|5tqqdz,176,414,1|5tqqe0,160,36,0|65zifz,160,36,0|65zig0,176,414,1|6ctrpz,176,414,1|6ctrq0,160,36,0|6p2jrz,160,36,0|6p2js0,176,414,1|6vjudz,176,414,1|6vjue0,160,36,0|77smfz,160,36,0|77smg0,176,414,1|7e9x1z,176,414,1|7e9x20,160,36,0|7qip3z,160,36,0|7qip40,176,414,1|7wzzpz,176,414,1|7wzzq0,160,36,0|898rrz,160,36,0|898rs0,176,414,1|8fq2dz,176,414,1|8fq2e0,160,36,0|8ryufz,160,36,0|8ryug0,176,414,1|8yg51z,176,414,1|8yg520,160,36,0|9aox3z,160,36,0|9aox40,176,414,1|9hj6dz,176,414,1|9hj6e0,160,36,0|9tryfz,160,36,0|9tryg0,176,414,1|a0991z,176,414,1|a09920,160,36,0|aci13z,160,36,0|aci140,176,414,1|aizbpz,176,414,1|aizbq0,160,36,0|av83rz,160,36,0|av83s0,176,414,1|b1pedz,176,414,1|b1pee0,160,36,0\",\"Pacific/Saipan|,0,410,0|-1t8j1h0,0,411,0|-100f451,0,411,0|-100f450,170,195,0|-en8eg1,170,195,0|-en8eg0,107,224,0|-d9n501,107,224,0|-d9n500,170,195,0|-5hlkw1,170,195,0|-5hlkw0,171,192,1|-4nnvo1,171,192,1|-4nnvo0,170,195,0|-17w8w1,170,195,0|-17w8w0,171,192,1|-hih6d,171,192,1|-hih6c,170,195,0|-9y0w1,170,195,0|-9y0w0,171,192,1|-6ch01,171,192,1|-6ch00,170,195,0|5wcfz,170,195,0|5wcg0,171,192,1|cqkbz,171,192,1|cqkc0,170,195,0|omf3z,170,195,0|omf40,171,192,1|vgmzz,171,192,1|vgn00,170,195,0|22bb3z,170,195,0|22bb40,171,192,1|25wuzz,171,192,1|25wv00,170,195,0|3c75rz,170,195,0|3c75s0,171,192,1|3gq1pn,171,192,1|3gq1po,170,195,0|3tbtrz,170,195,0|3tbts0,171,192,1|3zt2zz,171,192,1|3zt300,170,195,0|g5z2vz,170,195,0|g5z2w0,172,195,0\",\"Pacific/Tahiti|,0,438,0|-tvnayw,160,36,0\",\"Pacific/Tarawa|,0,439,0|-100f9dg,102,200,0\",\"Pacific/Tongatapu|,0,440,0|-100fbk8,184,441,0|-f4vrld,184,441,0|-f4vrlc,103,201,0|fj6mrz,103,201,0|fj6ms0,104,207,1|frmc3z,104,207,1|frmc40,103,201,0|g3i43z,103,201,0|g3i440,104,207,1|g7tlbz,104,207,1|g7tlc0,103,201,0|gm86rz,103,201,0|gm86s0,104,207,1|gqjnzz,104,207,1|gqjo00,103,201,0|og66rz,103,201,0|og66s0,104,207,1|ojrtfz,104,207,1|ojrtg0,103,201,0\",\"Pacific/Wake|,0,442,0|-100f86s,102,200,0\",\"Pacific/Wallis|,0,443,0|-100fbdk,102,200,0\"],\"abbrvs\":\"LMT|GMT|+0020|+0030|+0230|EAT|+0245|PMT|WET|WEST|CET|CEST|WAT|-01|CAT|EET|EEST|+00|+01|SAST|CAST|MMT|WAST|+0130|NST|NWT|NPT|BST|BDT|AHST|HST|HDT|AST|AWT|APT|AHDT|YST|AKST|AKDT|-03|-02|CMT|-04|-0430|AMT|CST|CDT|CWT|CPT|EST|MST|PST|MDT|BMT|ADT|-0530|-05|PDT|MWT|MPT|-00|MDDT|EDT|SJMT|YDT|YWT|YPT|YDDT|PWT|PPT|EWT|EPT|NDT|ADDT|KMT|QMT|-0345|HMT|PDDT|EDDT|FFMT|-0330|-0230|-0130|PPMT|SMT|CDDT|SDMT|NDDT|+08|+11|+07|+05|+10|AEST|AEDT|+06|NZMT|NZST|NZDT|+03|+02|+12|+13|+14|+04|+0730|+09|+0530|+0630|IST|IDT|PLMT|HKT|HKST|HKWT|JST|IMT|+0720|WIB|+0930|WIT|JMT|IDDT|+0430|PKT|PKST|+0545|+0820|WITA|KST|KDT|TBMT|TMT|+0330|JDT|RMT|FMT|ACST|ACDT|+0845|+0945|+1030|+1130|AWST|AWDT|+0120|CEMT|MSK|MSD|DMT|BDST|WEMT|MDST|LST|SET|WMT|+0220|-1130|-11|-10|PMMT|+1215|+1245|+1345|EMT|-07|-06|-12|-09|GST|GDT|ChST|HWT|HPT|-1040|-0930|SST|-1120|+1112|+1230|-0830|-08|-1030|+1220|GMT+14|GMT+13|GMT+12|GMT+11|GMT+10|GMT+9|GMT+8|GMT+7|GMT+6|GMT+5|GMT+4|GMT+3|GMT+2|GMT+1|GMT-1|GMT-2|GMT-3|GMT-4|GMT-5|GMT-6|GMT-7|GMT-8|GMT-9|GMT-10|GMT-11|GMT-12\",\"offsets\":\"-1g|0|xc|1e0|6tg|6y0|8c0|7n0|kc|fl|2s0|5k0|-qw|mn|-2vw|-2s0|618|5sl|-1ek|-zg|-2g0|56o|460|5us|60w|-1zw|-226|2sc|18w|-1p9|2fw|1vw|360|xya|-wpq|-uk0|-rs0|-p00|12wo|-rrc|-m80|-be4|-b40|-8xc|-8c0|-5k0|-ato|-bw0|-c6k|-c3c|-cdo|-cqs|-ctg|-c44|-cos|-cac|-c2s|-cnc|-crn|-ci0|-aog|-gys|-go0|-dw0|-74s|-jho|-jg0|-b1h|-8z8|-gc0|-fa0|-aks|-b8g|-dps|-lip|-a44|-g2g|-ce8|-ce4|-9ow|-eq8|-eso|-g8c|-jn8|-fkd|-lks|-adw|-3gg|-ptg|-m9k|-jfw|-fdn|-l0g|-cxs|-gio|-mpz|-74o|-b3o|-b6s|-9rg|-6zg|-9q0|-6y0|-d68|-e7y|-grg|-es8|-ejc|-ars|-af0|-bs0|-f94|-f9c|-kjs|-fye|-g1i|-fzn|-g5v|-g2f|-fr4|-g7j|-g1d|15rv|-ow5|-fvq|-fpo|-cmc|-9uc|-e9o|-eac|-lwa|-6m4|-fz8|-fzc|-b44|-bb8|-iio|-jpg|-g83|-glg|16au|-od6|-id0|-aeg|-bzw|-iks|-aer|-460|-ebu|-dpe|-gcg|101a|-umq|-604|-iuj|-irc|-is3|-9kw|-jc4|-a7s|-a84|-a7o|-kr6|-de8|-ddo|-bu0|-c8p|-d4s|-d3a|-hig|-6go|-jdo|-ck0|-a4o|-cy0|-cyo|-8ms|-42g|15lz|-p21|-jyw|-g5g|-cqk|-gj0|-lo4|-ep8|-mss|-p0c|-hzo|14sh|-pvj|m80|uk0|jg0|dw0|rs0|go0|wd4|vy0|yq0|xc0|1040|1zo|8ng|e90|6nk|wv8|12w0|9b4|b40|al4|at8|9m8|884|880|9jk|98c|im4|fic|6ko|dtc|la4|ku0|l0g|p00|l7c|esc|esk|fa0|i20|6q0|gqs|gcw|n98|a8o|cqo|6ac|6ds|6hz|jr4|jqu|l56|nm0|gz0|jb5|js0|kdc|q20|qe0|6iu|6ig|ctc|ci0|tdo|cf0|fss|fz0|p3p|gd4|eva|h72|ity|j8d|kfk|n5c|l0y|rxc|m40|-189c|meo|66g|g5c|fcs|dl6|9ic|k8w|nac|bs4|c4g|qfc|ceh|nig|mhj|sgs|mi0|ctz|8an|9iw|9q0|glo|pvn|fqf|jsk|g7w|qiu|of7|o0y|htb|b89|af5|88o|-4r4|-5aw|-c06|-986|-2uo|-4cs|-194|-34o|-42o|-6rk|-apo|pnw|t60|sc8|q70|ra4|o88|nv4|ob0|r30|rl8|tgk|qug|lgc|s04|wk|3ok|3pc|a4|8wc|4e4|3so|2h4|2o8|t6|4u0|3j8|1kw|1dm|5c8|5bo|2bw|-15o|-169|1lr|-zo|-23|4md|5d4|5ew|5ng|97c|150|-ok|2os|53s|53c|1d8|6yh|707|9s7|ck7|4gy|78y|2b8|99w|8j6|6bc|6ao|4bg|3cc|2se|4l0|3o8|8yo|44o|30x|4os|3w0|4fc|6hc|des|jks|hy4|a9o|dm0|anc|a9s|yv4|-vsw|-vy0|st4|r8w|xz0|y10|zf0|1270|-12k4|s3w|-k94|v64|-vok|-xc0|-vpk|x4w|x6s|-glc|-ozo|tmc|-13v0|qt0|-t8e|-t60|-qe0|-t4w|-tmo|-10hg|u6k|uzk|vpc|-pu0|z20|-vm0|uws|-vgs|-vhc|v3s|v40|uto|-15rg|owk|-o38|-nm0|-11d8|tas|r94|-tl4|-rp4|w1g|y88|y9c|uus|y1k\"}) \n}","// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.\nrequire('../../js/transition.js')\nrequire('../../js/alert.js')\nrequire('../../js/button.js')\nrequire('../../js/carousel.js')\nrequire('../../js/collapse.js')\nrequire('../../js/dropdown.js')\nrequire('../../js/modal.js')\nrequire('../../js/tooltip.js')\nrequire('../../js/popover.js')\nrequire('../../js/scrollspy.js')\nrequire('../../js/tab.js')\nrequire('../../js/affix.js')","/* ========================================================================\n * Bootstrap: transition.js v3.4.1\n * https://getbootstrap.com/docs/3.4/javascript/#transitions\n * ========================================================================\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // CSS TRANSITION SUPPORT (Shoutout: https://modernizr.com/)\n // ============================================================\n\n function transitionEnd() {\n var el = document.createElement('bootstrap')\n\n var transEndEventNames = {\n WebkitTransition : 'webkitTransitionEnd',\n MozTransition : 'transitionend',\n OTransition : 'oTransitionEnd otransitionend',\n transition : 'transitionend'\n }\n\n for (var name in transEndEventNames) {\n if (el.style[name] !== undefined) {\n return { end: transEndEventNames[name] }\n }\n }\n\n return false // explicit for ie8 ( ._.)\n }\n\n // https://blog.alexmaccaw.com/css-transitions\n $.fn.emulateTransitionEnd = function (duration) {\n var called = false\n var $el = this\n $(this).one('bsTransitionEnd', function () { called = true })\n var callback = function () { if (!called) $($el).trigger($.support.transition.end) }\n setTimeout(callback, duration)\n return this\n }\n\n $(function () {\n $.support.transition = transitionEnd()\n\n if (!$.support.transition) return\n\n $.event.special.bsTransitionEnd = {\n bindType: $.support.transition.end,\n delegateType: $.support.transition.end,\n handle: function (e) {\n if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)\n }\n }\n })\n\n}(jQuery);\n","/* ========================================================================\n * Bootstrap: alert.js v3.4.1\n * https://getbootstrap.com/docs/3.4/javascript/#alerts\n * ========================================================================\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // ALERT CLASS DEFINITION\n // ======================\n\n var dismiss = '[data-dismiss=\"alert\"]'\n var Alert = function (el) {\n $(el).on('click', dismiss, this.close)\n }\n\n Alert.VERSION = '3.4.1'\n\n Alert.TRANSITION_DURATION = 150\n\n Alert.prototype.close = function (e) {\n var $this = $(this)\n var selector = $this.attr('data-target')\n\n if (!selector) {\n selector = $this.attr('href')\n selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n }\n\n selector = selector === '#' ? [] : selector\n var $parent = $(document).find(selector)\n\n if (e) e.preventDefault()\n\n if (!$parent.length) {\n $parent = $this.closest('.alert')\n }\n\n $parent.trigger(e = $.Event('close.bs.alert'))\n\n if (e.isDefaultPrevented()) return\n\n $parent.removeClass('in')\n\n function removeElement() {\n // detach from parent, fire event then clean up data\n $parent.detach().trigger('closed.bs.alert').remove()\n }\n\n $.support.transition && $parent.hasClass('fade') ?\n $parent\n .one('bsTransitionEnd', removeElement)\n .emulateTransitionEnd(Alert.TRANSITION_DURATION) :\n removeElement()\n }\n\n\n // ALERT PLUGIN DEFINITION\n // =======================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.alert')\n\n if (!data) $this.data('bs.alert', (data = new Alert(this)))\n if (typeof option == 'string') data[option].call($this)\n })\n }\n\n var old = $.fn.alert\n\n $.fn.alert = Plugin\n $.fn.alert.Constructor = Alert\n\n\n // ALERT NO CONFLICT\n // =================\n\n $.fn.alert.noConflict = function () {\n $.fn.alert = old\n return this\n }\n\n\n // ALERT DATA-API\n // ==============\n\n $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)\n\n}(jQuery);\n","/* ========================================================================\n * Bootstrap: button.js v3.4.1\n * https://getbootstrap.com/docs/3.4/javascript/#buttons\n * ========================================================================\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // BUTTON PUBLIC CLASS DEFINITION\n // ==============================\n\n var Button = function (element, options) {\n this.$element = $(element)\n this.options = $.extend({}, Button.DEFAULTS, options)\n this.isLoading = false\n }\n\n Button.VERSION = '3.4.1'\n\n Button.DEFAULTS = {\n loadingText: 'loading...'\n }\n\n Button.prototype.setState = function (state) {\n var d = 'disabled'\n var $el = this.$element\n var val = $el.is('input') ? 'val' : 'html'\n var data = $el.data()\n\n state += 'Text'\n\n if (data.resetText == null) $el.data('resetText', $el[val]())\n\n // push to event loop to allow forms to submit\n setTimeout($.proxy(function () {\n $el[val](data[state] == null ? this.options[state] : data[state])\n\n if (state == 'loadingText') {\n this.isLoading = true\n $el.addClass(d).attr(d, d).prop(d, true)\n } else if (this.isLoading) {\n this.isLoading = false\n $el.removeClass(d).removeAttr(d).prop(d, false)\n }\n }, this), 0)\n }\n\n Button.prototype.toggle = function () {\n var changed = true\n var $parent = this.$element.closest('[data-toggle=\"buttons\"]')\n\n if ($parent.length) {\n var $input = this.$element.find('input')\n if ($input.prop('type') == 'radio') {\n if ($input.prop('checked')) changed = false\n $parent.find('.active').removeClass('active')\n this.$element.addClass('active')\n } else if ($input.prop('type') == 'checkbox') {\n if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false\n this.$element.toggleClass('active')\n }\n $input.prop('checked', this.$element.hasClass('active'))\n if (changed) $input.trigger('change')\n } else {\n this.$element.attr('aria-pressed', !this.$element.hasClass('active'))\n this.$element.toggleClass('active')\n }\n }\n\n\n // BUTTON PLUGIN DEFINITION\n // ========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.button')\n var options = typeof option == 'object' && option\n\n if (!data) $this.data('bs.button', (data = new Button(this, options)))\n\n if (option == 'toggle') data.toggle()\n else if (option) data.setState(option)\n })\n }\n\n var old = $.fn.button\n\n $.fn.button = Plugin\n $.fn.button.Constructor = Button\n\n\n // BUTTON NO CONFLICT\n // ==================\n\n $.fn.button.noConflict = function () {\n $.fn.button = old\n return this\n }\n\n\n // BUTTON DATA-API\n // ===============\n\n $(document)\n .on('click.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n var $btn = $(e.target).closest('.btn')\n Plugin.call($btn, 'toggle')\n if (!($(e.target).is('input[type=\"radio\"], input[type=\"checkbox\"]'))) {\n // Prevent double click on radios, and the double selections (so cancellation) on checkboxes\n e.preventDefault()\n // The target component still receive the focus\n if ($btn.is('input,button')) $btn.trigger('focus')\n else $btn.find('input:visible,button:visible').first().trigger('focus')\n }\n })\n .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))\n })\n\n}(jQuery);\n","/* ========================================================================\n * Bootstrap: carousel.js v3.4.1\n * https://getbootstrap.com/docs/3.4/javascript/#carousel\n * ========================================================================\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // CAROUSEL CLASS DEFINITION\n // =========================\n\n var Carousel = function (element, options) {\n this.$element = $(element)\n this.$indicators = this.$element.find('.carousel-indicators')\n this.options = options\n this.paused = null\n this.sliding = null\n this.interval = null\n this.$active = null\n this.$items = null\n\n this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))\n\n this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element\n .on('mouseenter.bs.carousel', $.proxy(this.pause, this))\n .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))\n }\n\n Carousel.VERSION = '3.4.1'\n\n Carousel.TRANSITION_DURATION = 600\n\n Carousel.DEFAULTS = {\n interval: 5000,\n pause: 'hover',\n wrap: true,\n keyboard: true\n }\n\n Carousel.prototype.keydown = function (e) {\n if (/input|textarea/i.test(e.target.tagName)) return\n switch (e.which) {\n case 37: this.prev(); break\n case 39: this.next(); break\n default: return\n }\n\n e.preventDefault()\n }\n\n Carousel.prototype.cycle = function (e) {\n e || (this.paused = false)\n\n this.interval && clearInterval(this.interval)\n\n this.options.interval\n && !this.paused\n && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))\n\n return this\n }\n\n Carousel.prototype.getItemIndex = function (item) {\n this.$items = item.parent().children('.item')\n return this.$items.index(item || this.$active)\n }\n\n Carousel.prototype.getItemForDirection = function (direction, active) {\n var activeIndex = this.getItemIndex(active)\n var willWrap = (direction == 'prev' && activeIndex === 0)\n || (direction == 'next' && activeIndex == (this.$items.length - 1))\n if (willWrap && !this.options.wrap) return active\n var delta = direction == 'prev' ? -1 : 1\n var itemIndex = (activeIndex + delta) % this.$items.length\n return this.$items.eq(itemIndex)\n }\n\n Carousel.prototype.to = function (pos) {\n var that = this\n var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))\n\n if (pos > (this.$items.length - 1) || pos < 0) return\n\n if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, \"slid\"\n if (activeIndex == pos) return this.pause().cycle()\n\n return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))\n }\n\n Carousel.prototype.pause = function (e) {\n e || (this.paused = true)\n\n if (this.$element.find('.next, .prev').length && $.support.transition) {\n this.$element.trigger($.support.transition.end)\n this.cycle(true)\n }\n\n this.interval = clearInterval(this.interval)\n\n return this\n }\n\n Carousel.prototype.next = function () {\n if (this.sliding) return\n return this.slide('next')\n }\n\n Carousel.prototype.prev = function () {\n if (this.sliding) return\n return this.slide('prev')\n }\n\n Carousel.prototype.slide = function (type, next) {\n var $active = this.$element.find('.item.active')\n var $next = next || this.getItemForDirection(type, $active)\n var isCycling = this.interval\n var direction = type == 'next' ? 'left' : 'right'\n var that = this\n\n if ($next.hasClass('active')) return (this.sliding = false)\n\n var relatedTarget = $next[0]\n var slideEvent = $.Event('slide.bs.carousel', {\n relatedTarget: relatedTarget,\n direction: direction\n })\n this.$element.trigger(slideEvent)\n if (slideEvent.isDefaultPrevented()) return\n\n this.sliding = true\n\n isCycling && this.pause()\n\n if (this.$indicators.length) {\n this.$indicators.find('.active').removeClass('active')\n var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])\n $nextIndicator && $nextIndicator.addClass('active')\n }\n\n var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, \"slid\"\n if ($.support.transition && this.$element.hasClass('slide')) {\n $next.addClass(type)\n if (typeof $next === 'object' && $next.length) {\n $next[0].offsetWidth // force reflow\n }\n $active.addClass(direction)\n $next.addClass(direction)\n $active\n .one('bsTransitionEnd', function () {\n $next.removeClass([type, direction].join(' ')).addClass('active')\n $active.removeClass(['active', direction].join(' '))\n that.sliding = false\n setTimeout(function () {\n that.$element.trigger(slidEvent)\n }, 0)\n })\n .emulateTransitionEnd(Carousel.TRANSITION_DURATION)\n } else {\n $active.removeClass('active')\n $next.addClass('active')\n this.sliding = false\n this.$element.trigger(slidEvent)\n }\n\n isCycling && this.cycle()\n\n return this\n }\n\n\n // CAROUSEL PLUGIN DEFINITION\n // ==========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.carousel')\n var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)\n var action = typeof option == 'string' ? option : options.slide\n\n if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))\n if (typeof option == 'number') data.to(option)\n else if (action) data[action]()\n else if (options.interval) data.pause().cycle()\n })\n }\n\n var old = $.fn.carousel\n\n $.fn.carousel = Plugin\n $.fn.carousel.Constructor = Carousel\n\n\n // CAROUSEL NO CONFLICT\n // ====================\n\n $.fn.carousel.noConflict = function () {\n $.fn.carousel = old\n return this\n }\n\n\n // CAROUSEL DATA-API\n // =================\n\n var clickHandler = function (e) {\n var $this = $(this)\n var href = $this.attr('href')\n if (href) {\n href = href.replace(/.*(?=#[^\\s]+$)/, '') // strip for ie7\n }\n\n var target = $this.attr('data-target') || href\n var $target = $(document).find(target)\n\n if (!$target.hasClass('carousel')) return\n\n var options = $.extend({}, $target.data(), $this.data())\n var slideIndex = $this.attr('data-slide-to')\n if (slideIndex) options.interval = false\n\n Plugin.call($target, options)\n\n if (slideIndex) {\n $target.data('bs.carousel').to(slideIndex)\n }\n\n e.preventDefault()\n }\n\n $(document)\n .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)\n .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)\n\n $(window).on('load', function () {\n $('[data-ride=\"carousel\"]').each(function () {\n var $carousel = $(this)\n Plugin.call($carousel, $carousel.data())\n })\n })\n\n}(jQuery);\n","/* ========================================================================\n * Bootstrap: collapse.js v3.4.1\n * https://getbootstrap.com/docs/3.4/javascript/#collapse\n * ========================================================================\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n/* jshint latedef: false */\n\n+function ($) {\n 'use strict';\n\n // COLLAPSE PUBLIC CLASS DEFINITION\n // ================================\n\n var Collapse = function (element, options) {\n this.$element = $(element)\n this.options = $.extend({}, Collapse.DEFAULTS, options)\n this.$trigger = $('[data-toggle=\"collapse\"][href=\"#' + element.id + '\"],' +\n '[data-toggle=\"collapse\"][data-target=\"#' + element.id + '\"]')\n this.transitioning = null\n\n if (this.options.parent) {\n this.$parent = this.getParent()\n } else {\n this.addAriaAndCollapsedClass(this.$element, this.$trigger)\n }\n\n if (this.options.toggle) this.toggle()\n }\n\n Collapse.VERSION = '3.4.1'\n\n Collapse.TRANSITION_DURATION = 350\n\n Collapse.DEFAULTS = {\n toggle: true\n }\n\n Collapse.prototype.dimension = function () {\n var hasWidth = this.$element.hasClass('width')\n return hasWidth ? 'width' : 'height'\n }\n\n Collapse.prototype.show = function () {\n if (this.transitioning || this.$element.hasClass('in')) return\n\n var activesData\n var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')\n\n if (actives && actives.length) {\n activesData = actives.data('bs.collapse')\n if (activesData && activesData.transitioning) return\n }\n\n var startEvent = $.Event('show.bs.collapse')\n this.$element.trigger(startEvent)\n if (startEvent.isDefaultPrevented()) return\n\n if (actives && actives.length) {\n Plugin.call(actives, 'hide')\n activesData || actives.data('bs.collapse', null)\n }\n\n var dimension = this.dimension()\n\n this.$element\n .removeClass('collapse')\n .addClass('collapsing')[dimension](0)\n .attr('aria-expanded', true)\n\n this.$trigger\n .removeClass('collapsed')\n .attr('aria-expanded', true)\n\n this.transitioning = 1\n\n var complete = function () {\n this.$element\n .removeClass('collapsing')\n .addClass('collapse in')[dimension]('')\n this.transitioning = 0\n this.$element\n .trigger('shown.bs.collapse')\n }\n\n if (!$.support.transition) return complete.call(this)\n\n var scrollSize = $.camelCase(['scroll', dimension].join('-'))\n\n this.$element\n .one('bsTransitionEnd', $.proxy(complete, this))\n .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])\n }\n\n Collapse.prototype.hide = function () {\n if (this.transitioning || !this.$element.hasClass('in')) return\n\n var startEvent = $.Event('hide.bs.collapse')\n this.$element.trigger(startEvent)\n if (startEvent.isDefaultPrevented()) return\n\n var dimension = this.dimension()\n\n this.$element[dimension](this.$element[dimension]())[0].offsetHeight\n\n this.$element\n .addClass('collapsing')\n .removeClass('collapse in')\n .attr('aria-expanded', false)\n\n this.$trigger\n .addClass('collapsed')\n .attr('aria-expanded', false)\n\n this.transitioning = 1\n\n var complete = function () {\n this.transitioning = 0\n this.$element\n .removeClass('collapsing')\n .addClass('collapse')\n .trigger('hidden.bs.collapse')\n }\n\n if (!$.support.transition) return complete.call(this)\n\n this.$element\n [dimension](0)\n .one('bsTransitionEnd', $.proxy(complete, this))\n .emulateTransitionEnd(Collapse.TRANSITION_DURATION)\n }\n\n Collapse.prototype.toggle = function () {\n this[this.$element.hasClass('in') ? 'hide' : 'show']()\n }\n\n Collapse.prototype.getParent = function () {\n return $(document).find(this.options.parent)\n .find('[data-toggle=\"collapse\"][data-parent=\"' + this.options.parent + '\"]')\n .each($.proxy(function (i, element) {\n var $element = $(element)\n this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)\n }, this))\n .end()\n }\n\n Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {\n var isOpen = $element.hasClass('in')\n\n $element.attr('aria-expanded', isOpen)\n $trigger\n .toggleClass('collapsed', !isOpen)\n .attr('aria-expanded', isOpen)\n }\n\n function getTargetFromTrigger($trigger) {\n var href\n var target = $trigger.attr('data-target')\n || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '') // strip for ie7\n\n return $(document).find(target)\n }\n\n\n // COLLAPSE PLUGIN DEFINITION\n // ==========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.collapse')\n var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false\n if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.collapse\n\n $.fn.collapse = Plugin\n $.fn.collapse.Constructor = Collapse\n\n\n // COLLAPSE NO CONFLICT\n // ====================\n\n $.fn.collapse.noConflict = function () {\n $.fn.collapse = old\n return this\n }\n\n\n // COLLAPSE DATA-API\n // =================\n\n $(document).on('click.bs.collapse.data-api', '[data-toggle=\"collapse\"]', function (e) {\n var $this = $(this)\n\n if (!$this.attr('data-target')) e.preventDefault()\n\n var $target = getTargetFromTrigger($this)\n var data = $target.data('bs.collapse')\n var option = data ? 'toggle' : $this.data()\n\n Plugin.call($target, option)\n })\n\n}(jQuery);\n","/* ========================================================================\n * Bootstrap: dropdown.js v3.4.1\n * https://getbootstrap.com/docs/3.4/javascript/#dropdowns\n * ========================================================================\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // DROPDOWN CLASS DEFINITION\n // =========================\n\n var backdrop = '.dropdown-backdrop'\n var toggle = '[data-toggle=\"dropdown\"]'\n var Dropdown = function (element) {\n $(element).on('click.bs.dropdown', this.toggle)\n }\n\n Dropdown.VERSION = '3.4.1'\n\n function getParent($this) {\n var selector = $this.attr('data-target')\n\n if (!selector) {\n selector = $this.attr('href')\n selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n }\n\n var $parent = selector !== '#' ? $(document).find(selector) : null\n\n return $parent && $parent.length ? $parent : $this.parent()\n }\n\n function clearMenus(e) {\n if (e && e.which === 3) return\n $(backdrop).remove()\n $(toggle).each(function () {\n var $this = $(this)\n var $parent = getParent($this)\n var relatedTarget = { relatedTarget: this }\n\n if (!$parent.hasClass('open')) return\n\n if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return\n\n $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))\n\n if (e.isDefaultPrevented()) return\n\n $this.attr('aria-expanded', 'false')\n $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))\n })\n }\n\n Dropdown.prototype.toggle = function (e) {\n var $this = $(this)\n\n if ($this.is('.disabled, :disabled')) return\n\n var $parent = getParent($this)\n var isActive = $parent.hasClass('open')\n\n clearMenus()\n\n if (!isActive) {\n if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {\n // if mobile we use a backdrop because click events don't delegate\n $(document.createElement('div'))\n .addClass('dropdown-backdrop')\n .insertAfter($(this))\n .on('click', clearMenus)\n }\n\n var relatedTarget = { relatedTarget: this }\n $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))\n\n if (e.isDefaultPrevented()) return\n\n $this\n .trigger('focus')\n .attr('aria-expanded', 'true')\n\n $parent\n .toggleClass('open')\n .trigger($.Event('shown.bs.dropdown', relatedTarget))\n }\n\n return false\n }\n\n Dropdown.prototype.keydown = function (e) {\n if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return\n\n var $this = $(this)\n\n e.preventDefault()\n e.stopPropagation()\n\n if ($this.is('.disabled, :disabled')) return\n\n var $parent = getParent($this)\n var isActive = $parent.hasClass('open')\n\n if (!isActive && e.which != 27 || isActive && e.which == 27) {\n if (e.which == 27) $parent.find(toggle).trigger('focus')\n return $this.trigger('click')\n }\n\n var desc = ' li:not(.disabled):visible a'\n var $items = $parent.find('.dropdown-menu' + desc)\n\n if (!$items.length) return\n\n var index = $items.index(e.target)\n\n if (e.which == 38 && index > 0) index-- // up\n if (e.which == 40 && index < $items.length - 1) index++ // down\n if (!~index) index = 0\n\n $items.eq(index).trigger('focus')\n }\n\n\n // DROPDOWN PLUGIN DEFINITION\n // ==========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.dropdown')\n\n if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))\n if (typeof option == 'string') data[option].call($this)\n })\n }\n\n var old = $.fn.dropdown\n\n $.fn.dropdown = Plugin\n $.fn.dropdown.Constructor = Dropdown\n\n\n // DROPDOWN NO CONFLICT\n // ====================\n\n $.fn.dropdown.noConflict = function () {\n $.fn.dropdown = old\n return this\n }\n\n\n // APPLY TO STANDARD DROPDOWN ELEMENTS\n // ===================================\n\n $(document)\n .on('click.bs.dropdown.data-api', clearMenus)\n .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })\n .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)\n .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)\n .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)\n\n}(jQuery);\n","/* ========================================================================\n * Bootstrap: modal.js v3.4.1\n * https://getbootstrap.com/docs/3.4/javascript/#modals\n * ========================================================================\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // MODAL CLASS DEFINITION\n // ======================\n\n var Modal = function (element, options) {\n this.options = options\n this.$body = $(document.body)\n this.$element = $(element)\n this.$dialog = this.$element.find('.modal-dialog')\n this.$backdrop = null\n this.isShown = null\n this.originalBodyPad = null\n this.scrollbarWidth = 0\n this.ignoreBackdropClick = false\n this.fixedContent = '.navbar-fixed-top, .navbar-fixed-bottom'\n\n if (this.options.remote) {\n this.$element\n .find('.modal-content')\n .load(this.options.remote, $.proxy(function () {\n this.$element.trigger('loaded.bs.modal')\n }, this))\n }\n }\n\n Modal.VERSION = '3.4.1'\n\n Modal.TRANSITION_DURATION = 300\n Modal.BACKDROP_TRANSITION_DURATION = 150\n\n Modal.DEFAULTS = {\n backdrop: true,\n keyboard: true,\n show: true\n }\n\n Modal.prototype.toggle = function (_relatedTarget) {\n return this.isShown ? this.hide() : this.show(_relatedTarget)\n }\n\n Modal.prototype.show = function (_relatedTarget) {\n var that = this\n var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })\n\n this.$element.trigger(e)\n\n if (this.isShown || e.isDefaultPrevented()) return\n\n this.isShown = true\n\n this.checkScrollbar()\n this.setScrollbar()\n this.$body.addClass('modal-open')\n\n this.escape()\n this.resize()\n\n this.$element.on('click.dismiss.bs.modal', '[data-dismiss=\"modal\"]', $.proxy(this.hide, this))\n\n this.$dialog.on('mousedown.dismiss.bs.modal', function () {\n that.$element.one('mouseup.dismiss.bs.modal', function (e) {\n if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true\n })\n })\n\n this.backdrop(function () {\n var transition = $.support.transition && that.$element.hasClass('fade')\n\n if (!that.$element.parent().length) {\n that.$element.appendTo(that.$body) // don't move modals dom position\n }\n\n that.$element\n .show()\n .scrollTop(0)\n\n that.adjustDialog()\n\n if (transition) {\n that.$element[0].offsetWidth // force reflow\n }\n\n that.$element.addClass('in')\n\n that.enforceFocus()\n\n var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })\n\n transition ?\n that.$dialog // wait for modal to slide in\n .one('bsTransitionEnd', function () {\n that.$element.trigger('focus').trigger(e)\n })\n .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n that.$element.trigger('focus').trigger(e)\n })\n }\n\n Modal.prototype.hide = function (e) {\n if (e) e.preventDefault()\n\n e = $.Event('hide.bs.modal')\n\n this.$element.trigger(e)\n\n if (!this.isShown || e.isDefaultPrevented()) return\n\n this.isShown = false\n\n this.escape()\n this.resize()\n\n $(document).off('focusin.bs.modal')\n\n this.$element\n .removeClass('in')\n .off('click.dismiss.bs.modal')\n .off('mouseup.dismiss.bs.modal')\n\n this.$dialog.off('mousedown.dismiss.bs.modal')\n\n $.support.transition && this.$element.hasClass('fade') ?\n this.$element\n .one('bsTransitionEnd', $.proxy(this.hideModal, this))\n .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n this.hideModal()\n }\n\n Modal.prototype.enforceFocus = function () {\n $(document)\n .off('focusin.bs.modal') // guard against infinite focus loop\n .on('focusin.bs.modal', $.proxy(function (e) {\n if (document !== e.target &&\n this.$element[0] !== e.target &&\n !this.$element.has(e.target).length) {\n this.$element.trigger('focus')\n }\n }, this))\n }\n\n Modal.prototype.escape = function () {\n if (this.isShown && this.options.keyboard) {\n this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {\n e.which == 27 && this.hide()\n }, this))\n } else if (!this.isShown) {\n this.$element.off('keydown.dismiss.bs.modal')\n }\n }\n\n Modal.prototype.resize = function () {\n if (this.isShown) {\n $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))\n } else {\n $(window).off('resize.bs.modal')\n }\n }\n\n Modal.prototype.hideModal = function () {\n var that = this\n this.$element.hide()\n this.backdrop(function () {\n that.$body.removeClass('modal-open')\n that.resetAdjustments()\n that.resetScrollbar()\n that.$element.trigger('hidden.bs.modal')\n })\n }\n\n Modal.prototype.removeBackdrop = function () {\n this.$backdrop && this.$backdrop.remove()\n this.$backdrop = null\n }\n\n Modal.prototype.backdrop = function (callback) {\n var that = this\n var animate = this.$element.hasClass('fade') ? 'fade' : ''\n\n if (this.isShown && this.options.backdrop) {\n var doAnimate = $.support.transition && animate\n\n this.$backdrop = $(document.createElement('div'))\n .addClass('modal-backdrop ' + animate)\n .appendTo(this.$body)\n\n this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {\n if (this.ignoreBackdropClick) {\n this.ignoreBackdropClick = false\n return\n }\n if (e.target !== e.currentTarget) return\n this.options.backdrop == 'static'\n ? this.$element[0].focus()\n : this.hide()\n }, this))\n\n if (doAnimate) this.$backdrop[0].offsetWidth // force reflow\n\n this.$backdrop.addClass('in')\n\n if (!callback) return\n\n doAnimate ?\n this.$backdrop\n .one('bsTransitionEnd', callback)\n .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n callback()\n\n } else if (!this.isShown && this.$backdrop) {\n this.$backdrop.removeClass('in')\n\n var callbackRemove = function () {\n that.removeBackdrop()\n callback && callback()\n }\n $.support.transition && this.$element.hasClass('fade') ?\n this.$backdrop\n .one('bsTransitionEnd', callbackRemove)\n .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n callbackRemove()\n\n } else if (callback) {\n callback()\n }\n }\n\n // these following methods are used to handle overflowing modals\n\n Modal.prototype.handleUpdate = function () {\n this.adjustDialog()\n }\n\n Modal.prototype.adjustDialog = function () {\n var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight\n\n this.$element.css({\n paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',\n paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''\n })\n }\n\n Modal.prototype.resetAdjustments = function () {\n this.$element.css({\n paddingLeft: '',\n paddingRight: ''\n })\n }\n\n Modal.prototype.checkScrollbar = function () {\n var fullWindowWidth = window.innerWidth\n if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8\n var documentElementRect = document.documentElement.getBoundingClientRect()\n fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)\n }\n this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth\n this.scrollbarWidth = this.measureScrollbar()\n }\n\n Modal.prototype.setScrollbar = function () {\n var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)\n this.originalBodyPad = document.body.style.paddingRight || ''\n var scrollbarWidth = this.scrollbarWidth\n if (this.bodyIsOverflowing) {\n this.$body.css('padding-right', bodyPad + scrollbarWidth)\n $(this.fixedContent).each(function (index, element) {\n var actualPadding = element.style.paddingRight\n var calculatedPadding = $(element).css('padding-right')\n $(element)\n .data('padding-right', actualPadding)\n .css('padding-right', parseFloat(calculatedPadding) + scrollbarWidth + 'px')\n })\n }\n }\n\n Modal.prototype.resetScrollbar = function () {\n this.$body.css('padding-right', this.originalBodyPad)\n $(this.fixedContent).each(function (index, element) {\n var padding = $(element).data('padding-right')\n $(element).removeData('padding-right')\n element.style.paddingRight = padding ? padding : ''\n })\n }\n\n Modal.prototype.measureScrollbar = function () { // thx walsh\n var scrollDiv = document.createElement('div')\n scrollDiv.className = 'modal-scrollbar-measure'\n this.$body.append(scrollDiv)\n var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth\n this.$body[0].removeChild(scrollDiv)\n return scrollbarWidth\n }\n\n\n // MODAL PLUGIN DEFINITION\n // =======================\n\n function Plugin(option, _relatedTarget) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.modal')\n var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n if (!data) $this.data('bs.modal', (data = new Modal(this, options)))\n if (typeof option == 'string') data[option](_relatedTarget)\n else if (options.show) data.show(_relatedTarget)\n })\n }\n\n var old = $.fn.modal\n\n $.fn.modal = Plugin\n $.fn.modal.Constructor = Modal\n\n\n // MODAL NO CONFLICT\n // =================\n\n $.fn.modal.noConflict = function () {\n $.fn.modal = old\n return this\n }\n\n\n // MODAL DATA-API\n // ==============\n\n $(document).on('click.bs.modal.data-api', '[data-toggle=\"modal\"]', function (e) {\n var $this = $(this)\n var href = $this.attr('href')\n var target = $this.attr('data-target') ||\n (href && href.replace(/.*(?=#[^\\s]+$)/, '')) // strip for ie7\n\n var $target = $(document).find(target)\n var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())\n\n if ($this.is('a')) e.preventDefault()\n\n $target.one('show.bs.modal', function (showEvent) {\n if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown\n $target.one('hidden.bs.modal', function () {\n $this.is(':visible') && $this.trigger('focus')\n })\n })\n Plugin.call($target, option, this)\n })\n\n}(jQuery);\n","/* ========================================================================\n * Bootstrap: tooltip.js v3.4.1\n * https://getbootstrap.com/docs/3.4/javascript/#tooltip\n * Inspired by the original jQuery.tipsy by Jason Frame\n * ========================================================================\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n+function ($) {\n 'use strict';\n\n var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']\n\n var uriAttrs = [\n 'background',\n 'cite',\n 'href',\n 'itemtype',\n 'longdesc',\n 'poster',\n 'src',\n 'xlink:href'\n ]\n\n var ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i\n\n var DefaultWhitelist = {\n // Global attributes allowed on any supplied element below.\n '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n a: ['target', 'href', 'title', 'rel'],\n area: [],\n b: [],\n br: [],\n col: [],\n code: [],\n div: [],\n em: [],\n hr: [],\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: [],\n i: [],\n img: ['src', 'alt', 'title', 'width', 'height'],\n li: [],\n ol: [],\n p: [],\n pre: [],\n s: [],\n small: [],\n span: [],\n sub: [],\n sup: [],\n strong: [],\n u: [],\n ul: []\n }\n\n /**\n * A pattern that recognizes a commonly useful subset of URLs that are safe.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\n var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi\n\n /**\n * A pattern that matches safe data URLs. Only matches image, video and audio types.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\n var DATA_URL_PATTERN = /^data:(?:image\\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\\/(?:mpeg|mp4|ogg|webm)|audio\\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i\n\n function allowedAttribute(attr, allowedAttributeList) {\n var attrName = attr.nodeName.toLowerCase()\n\n if ($.inArray(attrName, allowedAttributeList) !== -1) {\n if ($.inArray(attrName, uriAttrs) !== -1) {\n return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN))\n }\n\n return true\n }\n\n var regExp = $(allowedAttributeList).filter(function (index, value) {\n return value instanceof RegExp\n })\n\n // Check if a regular expression validates the attribute.\n for (var i = 0, l = regExp.length; i < l; i++) {\n if (attrName.match(regExp[i])) {\n return true\n }\n }\n\n return false\n }\n\n function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {\n if (unsafeHtml.length === 0) {\n return unsafeHtml\n }\n\n if (sanitizeFn && typeof sanitizeFn === 'function') {\n return sanitizeFn(unsafeHtml)\n }\n\n // IE 8 and below don't support createHTMLDocument\n if (!document.implementation || !document.implementation.createHTMLDocument) {\n return unsafeHtml\n }\n\n var createdDocument = document.implementation.createHTMLDocument('sanitization')\n createdDocument.body.innerHTML = unsafeHtml\n\n var whitelistKeys = $.map(whiteList, function (el, i) { return i })\n var elements = $(createdDocument.body).find('*')\n\n for (var i = 0, len = elements.length; i < len; i++) {\n var el = elements[i]\n var elName = el.nodeName.toLowerCase()\n\n if ($.inArray(elName, whitelistKeys) === -1) {\n el.parentNode.removeChild(el)\n\n continue\n }\n\n var attributeList = $.map(el.attributes, function (el) { return el })\n var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || [])\n\n for (var j = 0, len2 = attributeList.length; j < len2; j++) {\n if (!allowedAttribute(attributeList[j], whitelistedAttributes)) {\n el.removeAttribute(attributeList[j].nodeName)\n }\n }\n }\n\n return createdDocument.body.innerHTML\n }\n\n // TOOLTIP PUBLIC CLASS DEFINITION\n // ===============================\n\n var Tooltip = function (element, options) {\n this.type = null\n this.options = null\n this.enabled = null\n this.timeout = null\n this.hoverState = null\n this.$element = null\n this.inState = null\n\n this.init('tooltip', element, options)\n }\n\n Tooltip.VERSION = '3.4.1'\n\n Tooltip.TRANSITION_DURATION = 150\n\n Tooltip.DEFAULTS = {\n animation: true,\n placement: 'top',\n selector: false,\n template: '
',\n trigger: 'hover focus',\n title: '',\n delay: 0,\n html: false,\n container: false,\n viewport: {\n selector: 'body',\n padding: 0\n },\n sanitize : true,\n sanitizeFn : null,\n whiteList : DefaultWhitelist\n }\n\n Tooltip.prototype.init = function (type, element, options) {\n this.enabled = true\n this.type = type\n this.$element = $(element)\n this.options = this.getOptions(options)\n this.$viewport = this.options.viewport && $(document).find($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))\n this.inState = { click: false, hover: false, focus: false }\n\n if (this.$element[0] instanceof document.constructor && !this.options.selector) {\n throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')\n }\n\n var triggers = this.options.trigger.split(' ')\n\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i]\n\n if (trigger == 'click') {\n this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))\n } else if (trigger != 'manual') {\n var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'\n var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'\n\n this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))\n this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))\n }\n }\n\n this.options.selector ?\n (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :\n this.fixTitle()\n }\n\n Tooltip.prototype.getDefaults = function () {\n return Tooltip.DEFAULTS\n }\n\n Tooltip.prototype.getOptions = function (options) {\n var dataAttributes = this.$element.data()\n\n for (var dataAttr in dataAttributes) {\n if (dataAttributes.hasOwnProperty(dataAttr) && $.inArray(dataAttr, DISALLOWED_ATTRIBUTES) !== -1) {\n delete dataAttributes[dataAttr]\n }\n }\n\n options = $.extend({}, this.getDefaults(), dataAttributes, options)\n\n if (options.delay && typeof options.delay == 'number') {\n options.delay = {\n show: options.delay,\n hide: options.delay\n }\n }\n\n if (options.sanitize) {\n options.template = sanitizeHtml(options.template, options.whiteList, options.sanitizeFn)\n }\n\n return options\n }\n\n Tooltip.prototype.getDelegateOptions = function () {\n var options = {}\n var defaults = this.getDefaults()\n\n this._options && $.each(this._options, function (key, value) {\n if (defaults[key] != value) options[key] = value\n })\n\n return options\n }\n\n Tooltip.prototype.enter = function (obj) {\n var self = obj instanceof this.constructor ?\n obj : $(obj.currentTarget).data('bs.' + this.type)\n\n if (!self) {\n self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n $(obj.currentTarget).data('bs.' + this.type, self)\n }\n\n if (obj instanceof $.Event) {\n self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true\n }\n\n if (self.tip().hasClass('in') || self.hoverState == 'in') {\n self.hoverState = 'in'\n return\n }\n\n clearTimeout(self.timeout)\n\n self.hoverState = 'in'\n\n if (!self.options.delay || !self.options.delay.show) return self.show()\n\n self.timeout = setTimeout(function () {\n if (self.hoverState == 'in') self.show()\n }, self.options.delay.show)\n }\n\n Tooltip.prototype.isInStateTrue = function () {\n for (var key in this.inState) {\n if (this.inState[key]) return true\n }\n\n return false\n }\n\n Tooltip.prototype.leave = function (obj) {\n var self = obj instanceof this.constructor ?\n obj : $(obj.currentTarget).data('bs.' + this.type)\n\n if (!self) {\n self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n $(obj.currentTarget).data('bs.' + this.type, self)\n }\n\n if (obj instanceof $.Event) {\n self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false\n }\n\n if (self.isInStateTrue()) return\n\n clearTimeout(self.timeout)\n\n self.hoverState = 'out'\n\n if (!self.options.delay || !self.options.delay.hide) return self.hide()\n\n self.timeout = setTimeout(function () {\n if (self.hoverState == 'out') self.hide()\n }, self.options.delay.hide)\n }\n\n Tooltip.prototype.show = function () {\n var e = $.Event('show.bs.' + this.type)\n\n if (this.hasContent() && this.enabled) {\n this.$element.trigger(e)\n\n var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])\n if (e.isDefaultPrevented() || !inDom) return\n var that = this\n\n var $tip = this.tip()\n\n var tipId = this.getUID(this.type)\n\n this.setContent()\n $tip.attr('id', tipId)\n this.$element.attr('aria-describedby', tipId)\n\n if (this.options.animation) $tip.addClass('fade')\n\n var placement = typeof this.options.placement == 'function' ?\n this.options.placement.call(this, $tip[0], this.$element[0]) :\n this.options.placement\n\n var autoToken = /\\s?auto?\\s?/i\n var autoPlace = autoToken.test(placement)\n if (autoPlace) placement = placement.replace(autoToken, '') || 'top'\n\n $tip\n .detach()\n .css({ top: 0, left: 0, display: 'block' })\n .addClass(placement)\n .data('bs.' + this.type, this)\n\n this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element)\n this.$element.trigger('inserted.bs.' + this.type)\n\n var pos = this.getPosition()\n var actualWidth = $tip[0].offsetWidth\n var actualHeight = $tip[0].offsetHeight\n\n if (autoPlace) {\n var orgPlacement = placement\n var viewportDim = this.getPosition(this.$viewport)\n\n placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :\n placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :\n placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :\n placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :\n placement\n\n $tip\n .removeClass(orgPlacement)\n .addClass(placement)\n }\n\n var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)\n\n this.applyPlacement(calculatedOffset, placement)\n\n var complete = function () {\n var prevHoverState = that.hoverState\n that.$element.trigger('shown.bs.' + that.type)\n that.hoverState = null\n\n if (prevHoverState == 'out') that.leave(that)\n }\n\n $.support.transition && this.$tip.hasClass('fade') ?\n $tip\n .one('bsTransitionEnd', complete)\n .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n complete()\n }\n }\n\n Tooltip.prototype.applyPlacement = function (offset, placement) {\n var $tip = this.tip()\n var width = $tip[0].offsetWidth\n var height = $tip[0].offsetHeight\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt($tip.css('margin-top'), 10)\n var marginLeft = parseInt($tip.css('margin-left'), 10)\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0\n if (isNaN(marginLeft)) marginLeft = 0\n\n offset.top += marginTop\n offset.left += marginLeft\n\n // $.fn.offset doesn't round pixel values\n // so we use setOffset directly with our own function B-0\n $.offset.setOffset($tip[0], $.extend({\n using: function (props) {\n $tip.css({\n top: Math.round(props.top),\n left: Math.round(props.left)\n })\n }\n }, offset), 0)\n\n $tip.addClass('in')\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = $tip[0].offsetWidth\n var actualHeight = $tip[0].offsetHeight\n\n if (placement == 'top' && actualHeight != height) {\n offset.top = offset.top + height - actualHeight\n }\n\n var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)\n\n if (delta.left) offset.left += delta.left\n else offset.top += delta.top\n\n var isVertical = /top|bottom/.test(placement)\n var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight\n var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'\n\n $tip.offset(offset)\n this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)\n }\n\n Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {\n this.arrow()\n .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isVertical ? 'top' : 'left', '')\n }\n\n Tooltip.prototype.setContent = function () {\n var $tip = this.tip()\n var title = this.getTitle()\n\n if (this.options.html) {\n if (this.options.sanitize) {\n title = sanitizeHtml(title, this.options.whiteList, this.options.sanitizeFn)\n }\n\n $tip.find('.tooltip-inner').html(title)\n } else {\n $tip.find('.tooltip-inner').text(title)\n }\n\n $tip.removeClass('fade in top bottom left right')\n }\n\n Tooltip.prototype.hide = function (callback) {\n var that = this\n var $tip = $(this.$tip)\n var e = $.Event('hide.bs.' + this.type)\n\n function complete() {\n if (that.hoverState != 'in') $tip.detach()\n if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary.\n that.$element\n .removeAttr('aria-describedby')\n .trigger('hidden.bs.' + that.type)\n }\n callback && callback()\n }\n\n this.$element.trigger(e)\n\n if (e.isDefaultPrevented()) return\n\n $tip.removeClass('in')\n\n $.support.transition && $tip.hasClass('fade') ?\n $tip\n .one('bsTransitionEnd', complete)\n .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n complete()\n\n this.hoverState = null\n\n return this\n }\n\n Tooltip.prototype.fixTitle = function () {\n var $e = this.$element\n if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {\n $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')\n }\n }\n\n Tooltip.prototype.hasContent = function () {\n return this.getTitle()\n }\n\n Tooltip.prototype.getPosition = function ($element) {\n $element = $element || this.$element\n\n var el = $element[0]\n var isBody = el.tagName == 'BODY'\n\n var elRect = el.getBoundingClientRect()\n if (elRect.width == null) {\n // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })\n }\n var isSvg = window.SVGElement && el instanceof window.SVGElement\n // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3.\n // See https://github.com/twbs/bootstrap/issues/20280\n var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset())\n var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }\n var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null\n\n return $.extend({}, elRect, scroll, outerDims, elOffset)\n }\n\n Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {\n return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :\n placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :\n placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :\n /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }\n\n }\n\n Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {\n var delta = { top: 0, left: 0 }\n if (!this.$viewport) return delta\n\n var viewportPadding = this.options.viewport && this.options.viewport.padding || 0\n var viewportDimensions = this.getPosition(this.$viewport)\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll\n var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset\n }\n } else {\n var leftEdgeOffset = pos.left - viewportPadding\n var rightEdgeOffset = pos.left + viewportPadding + actualWidth\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset\n }\n }\n\n return delta\n }\n\n Tooltip.prototype.getTitle = function () {\n var title\n var $e = this.$element\n var o = this.options\n\n title = $e.attr('data-original-title')\n || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)\n\n return title\n }\n\n Tooltip.prototype.getUID = function (prefix) {\n do prefix += ~~(Math.random() * 1000000)\n while (document.getElementById(prefix))\n return prefix\n }\n\n Tooltip.prototype.tip = function () {\n if (!this.$tip) {\n this.$tip = $(this.options.template)\n if (this.$tip.length != 1) {\n throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')\n }\n }\n return this.$tip\n }\n\n Tooltip.prototype.arrow = function () {\n return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))\n }\n\n Tooltip.prototype.enable = function () {\n this.enabled = true\n }\n\n Tooltip.prototype.disable = function () {\n this.enabled = false\n }\n\n Tooltip.prototype.toggleEnabled = function () {\n this.enabled = !this.enabled\n }\n\n Tooltip.prototype.toggle = function (e) {\n var self = this\n if (e) {\n self = $(e.currentTarget).data('bs.' + this.type)\n if (!self) {\n self = new this.constructor(e.currentTarget, this.getDelegateOptions())\n $(e.currentTarget).data('bs.' + this.type, self)\n }\n }\n\n if (e) {\n self.inState.click = !self.inState.click\n if (self.isInStateTrue()) self.enter(self)\n else self.leave(self)\n } else {\n self.tip().hasClass('in') ? self.leave(self) : self.enter(self)\n }\n }\n\n Tooltip.prototype.destroy = function () {\n var that = this\n clearTimeout(this.timeout)\n this.hide(function () {\n that.$element.off('.' + that.type).removeData('bs.' + that.type)\n if (that.$tip) {\n that.$tip.detach()\n }\n that.$tip = null\n that.$arrow = null\n that.$viewport = null\n that.$element = null\n })\n }\n\n Tooltip.prototype.sanitizeHtml = function (unsafeHtml) {\n return sanitizeHtml(unsafeHtml, this.options.whiteList, this.options.sanitizeFn)\n }\n\n // TOOLTIP PLUGIN DEFINITION\n // =========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.tooltip')\n var options = typeof option == 'object' && option\n\n if (!data && /destroy|hide/.test(option)) return\n if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.tooltip\n\n $.fn.tooltip = Plugin\n $.fn.tooltip.Constructor = Tooltip\n\n\n // TOOLTIP NO CONFLICT\n // ===================\n\n $.fn.tooltip.noConflict = function () {\n $.fn.tooltip = old\n return this\n }\n\n}(jQuery);\n","/* ========================================================================\n * Bootstrap: popover.js v3.4.1\n * https://getbootstrap.com/docs/3.4/javascript/#popovers\n * ========================================================================\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // POPOVER PUBLIC CLASS DEFINITION\n // ===============================\n\n var Popover = function (element, options) {\n this.init('popover', element, options)\n }\n\n if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')\n\n Popover.VERSION = '3.4.1'\n\n Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {\n placement: 'right',\n trigger: 'click',\n content: '',\n template: '

'\n })\n\n\n // NOTE: POPOVER EXTENDS tooltip.js\n // ================================\n\n Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)\n\n Popover.prototype.constructor = Popover\n\n Popover.prototype.getDefaults = function () {\n return Popover.DEFAULTS\n }\n\n Popover.prototype.setContent = function () {\n var $tip = this.tip()\n var title = this.getTitle()\n var content = this.getContent()\n\n if (this.options.html) {\n var typeContent = typeof content\n\n if (this.options.sanitize) {\n title = this.sanitizeHtml(title)\n\n if (typeContent === 'string') {\n content = this.sanitizeHtml(content)\n }\n }\n\n $tip.find('.popover-title').html(title)\n $tip.find('.popover-content').children().detach().end()[\n typeContent === 'string' ? 'html' : 'append'\n ](content)\n } else {\n $tip.find('.popover-title').text(title)\n $tip.find('.popover-content').children().detach().end().text(content)\n }\n\n $tip.removeClass('fade top bottom left right in')\n\n // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do\n // this manually by checking the contents.\n if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()\n }\n\n Popover.prototype.hasContent = function () {\n return this.getTitle() || this.getContent()\n }\n\n Popover.prototype.getContent = function () {\n var $e = this.$element\n var o = this.options\n\n return $e.attr('data-content')\n || (typeof o.content == 'function' ?\n o.content.call($e[0]) :\n o.content)\n }\n\n Popover.prototype.arrow = function () {\n return (this.$arrow = this.$arrow || this.tip().find('.arrow'))\n }\n\n\n // POPOVER PLUGIN DEFINITION\n // =========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.popover')\n var options = typeof option == 'object' && option\n\n if (!data && /destroy|hide/.test(option)) return\n if (!data) $this.data('bs.popover', (data = new Popover(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.popover\n\n $.fn.popover = Plugin\n $.fn.popover.Constructor = Popover\n\n\n // POPOVER NO CONFLICT\n // ===================\n\n $.fn.popover.noConflict = function () {\n $.fn.popover = old\n return this\n }\n\n}(jQuery);\n","/* ========================================================================\n * Bootstrap: scrollspy.js v3.4.1\n * https://getbootstrap.com/docs/3.4/javascript/#scrollspy\n * ========================================================================\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // SCROLLSPY CLASS DEFINITION\n // ==========================\n\n function ScrollSpy(element, options) {\n this.$body = $(document.body)\n this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)\n this.options = $.extend({}, ScrollSpy.DEFAULTS, options)\n this.selector = (this.options.target || '') + ' .nav li > a'\n this.offsets = []\n this.targets = []\n this.activeTarget = null\n this.scrollHeight = 0\n\n this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))\n this.refresh()\n this.process()\n }\n\n ScrollSpy.VERSION = '3.4.1'\n\n ScrollSpy.DEFAULTS = {\n offset: 10\n }\n\n ScrollSpy.prototype.getScrollHeight = function () {\n return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)\n }\n\n ScrollSpy.prototype.refresh = function () {\n var that = this\n var offsetMethod = 'offset'\n var offsetBase = 0\n\n this.offsets = []\n this.targets = []\n this.scrollHeight = this.getScrollHeight()\n\n if (!$.isWindow(this.$scrollElement[0])) {\n offsetMethod = 'position'\n offsetBase = this.$scrollElement.scrollTop()\n }\n\n this.$body\n .find(this.selector)\n .map(function () {\n var $el = $(this)\n var href = $el.data('target') || $el.attr('href')\n var $href = /^#./.test(href) && $(href)\n\n return ($href\n && $href.length\n && $href.is(':visible')\n && [[$href[offsetMethod]().top + offsetBase, href]]) || null\n })\n .sort(function (a, b) { return a[0] - b[0] })\n .each(function () {\n that.offsets.push(this[0])\n that.targets.push(this[1])\n })\n }\n\n ScrollSpy.prototype.process = function () {\n var scrollTop = this.$scrollElement.scrollTop() + this.options.offset\n var scrollHeight = this.getScrollHeight()\n var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()\n var offsets = this.offsets\n var targets = this.targets\n var activeTarget = this.activeTarget\n var i\n\n if (this.scrollHeight != scrollHeight) {\n this.refresh()\n }\n\n if (scrollTop >= maxScroll) {\n return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)\n }\n\n if (activeTarget && scrollTop < offsets[0]) {\n this.activeTarget = null\n return this.clear()\n }\n\n for (i = offsets.length; i--;) {\n activeTarget != targets[i]\n && scrollTop >= offsets[i]\n && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])\n && this.activate(targets[i])\n }\n }\n\n ScrollSpy.prototype.activate = function (target) {\n this.activeTarget = target\n\n this.clear()\n\n var selector = this.selector +\n '[data-target=\"' + target + '\"],' +\n this.selector + '[href=\"' + target + '\"]'\n\n var active = $(selector)\n .parents('li')\n .addClass('active')\n\n if (active.parent('.dropdown-menu').length) {\n active = active\n .closest('li.dropdown')\n .addClass('active')\n }\n\n active.trigger('activate.bs.scrollspy')\n }\n\n ScrollSpy.prototype.clear = function () {\n $(this.selector)\n .parentsUntil(this.options.target, '.active')\n .removeClass('active')\n }\n\n\n // SCROLLSPY PLUGIN DEFINITION\n // ===========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.scrollspy')\n var options = typeof option == 'object' && option\n\n if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.scrollspy\n\n $.fn.scrollspy = Plugin\n $.fn.scrollspy.Constructor = ScrollSpy\n\n\n // SCROLLSPY NO CONFLICT\n // =====================\n\n $.fn.scrollspy.noConflict = function () {\n $.fn.scrollspy = old\n return this\n }\n\n\n // SCROLLSPY DATA-API\n // ==================\n\n $(window).on('load.bs.scrollspy.data-api', function () {\n $('[data-spy=\"scroll\"]').each(function () {\n var $spy = $(this)\n Plugin.call($spy, $spy.data())\n })\n })\n\n}(jQuery);\n","/* ========================================================================\n * Bootstrap: tab.js v3.4.1\n * https://getbootstrap.com/docs/3.4/javascript/#tabs\n * ========================================================================\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // TAB CLASS DEFINITION\n // ====================\n\n var Tab = function (element) {\n // jscs:disable requireDollarBeforejQueryAssignment\n this.element = $(element)\n // jscs:enable requireDollarBeforejQueryAssignment\n }\n\n Tab.VERSION = '3.4.1'\n\n Tab.TRANSITION_DURATION = 150\n\n Tab.prototype.show = function () {\n var $this = this.element\n var $ul = $this.closest('ul:not(.dropdown-menu)')\n var selector = $this.data('target')\n\n if (!selector) {\n selector = $this.attr('href')\n selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n }\n\n if ($this.parent('li').hasClass('active')) return\n\n var $previous = $ul.find('.active:last a')\n var hideEvent = $.Event('hide.bs.tab', {\n relatedTarget: $this[0]\n })\n var showEvent = $.Event('show.bs.tab', {\n relatedTarget: $previous[0]\n })\n\n $previous.trigger(hideEvent)\n $this.trigger(showEvent)\n\n if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return\n\n var $target = $(document).find(selector)\n\n this.activate($this.closest('li'), $ul)\n this.activate($target, $target.parent(), function () {\n $previous.trigger({\n type: 'hidden.bs.tab',\n relatedTarget: $this[0]\n })\n $this.trigger({\n type: 'shown.bs.tab',\n relatedTarget: $previous[0]\n })\n })\n }\n\n Tab.prototype.activate = function (element, container, callback) {\n var $active = container.find('> .active')\n var transition = callback\n && $.support.transition\n && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)\n\n function next() {\n $active\n .removeClass('active')\n .find('> .dropdown-menu > .active')\n .removeClass('active')\n .end()\n .find('[data-toggle=\"tab\"]')\n .attr('aria-expanded', false)\n\n element\n .addClass('active')\n .find('[data-toggle=\"tab\"]')\n .attr('aria-expanded', true)\n\n if (transition) {\n element[0].offsetWidth // reflow for transition\n element.addClass('in')\n } else {\n element.removeClass('fade')\n }\n\n if (element.parent('.dropdown-menu').length) {\n element\n .closest('li.dropdown')\n .addClass('active')\n .end()\n .find('[data-toggle=\"tab\"]')\n .attr('aria-expanded', true)\n }\n\n callback && callback()\n }\n\n $active.length && transition ?\n $active\n .one('bsTransitionEnd', next)\n .emulateTransitionEnd(Tab.TRANSITION_DURATION) :\n next()\n\n $active.removeClass('in')\n }\n\n\n // TAB PLUGIN DEFINITION\n // =====================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.tab')\n\n if (!data) $this.data('bs.tab', (data = new Tab(this)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.tab\n\n $.fn.tab = Plugin\n $.fn.tab.Constructor = Tab\n\n\n // TAB NO CONFLICT\n // ===============\n\n $.fn.tab.noConflict = function () {\n $.fn.tab = old\n return this\n }\n\n\n // TAB DATA-API\n // ============\n\n var clickHandler = function (e) {\n e.preventDefault()\n Plugin.call($(this), 'show')\n }\n\n $(document)\n .on('click.bs.tab.data-api', '[data-toggle=\"tab\"]', clickHandler)\n .on('click.bs.tab.data-api', '[data-toggle=\"pill\"]', clickHandler)\n\n}(jQuery);\n","/* ========================================================================\n * Bootstrap: affix.js v3.4.1\n * https://getbootstrap.com/docs/3.4/javascript/#affix\n * ========================================================================\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // AFFIX CLASS DEFINITION\n // ======================\n\n var Affix = function (element, options) {\n this.options = $.extend({}, Affix.DEFAULTS, options)\n\n var target = this.options.target === Affix.DEFAULTS.target ? $(this.options.target) : $(document).find(this.options.target)\n\n this.$target = target\n .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))\n .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))\n\n this.$element = $(element)\n this.affixed = null\n this.unpin = null\n this.pinnedOffset = null\n\n this.checkPosition()\n }\n\n Affix.VERSION = '3.4.1'\n\n Affix.RESET = 'affix affix-top affix-bottom'\n\n Affix.DEFAULTS = {\n offset: 0,\n target: window\n }\n\n Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {\n var scrollTop = this.$target.scrollTop()\n var position = this.$element.offset()\n var targetHeight = this.$target.height()\n\n if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false\n\n if (this.affixed == 'bottom') {\n if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'\n return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'\n }\n\n var initializing = this.affixed == null\n var colliderTop = initializing ? scrollTop : position.top\n var colliderHeight = initializing ? targetHeight : height\n\n if (offsetTop != null && scrollTop <= offsetTop) return 'top'\n if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'\n\n return false\n }\n\n Affix.prototype.getPinnedOffset = function () {\n if (this.pinnedOffset) return this.pinnedOffset\n this.$element.removeClass(Affix.RESET).addClass('affix')\n var scrollTop = this.$target.scrollTop()\n var position = this.$element.offset()\n return (this.pinnedOffset = position.top - scrollTop)\n }\n\n Affix.prototype.checkPositionWithEventLoop = function () {\n setTimeout($.proxy(this.checkPosition, this), 1)\n }\n\n Affix.prototype.checkPosition = function () {\n if (!this.$element.is(':visible')) return\n\n var height = this.$element.height()\n var offset = this.options.offset\n var offsetTop = offset.top\n var offsetBottom = offset.bottom\n var scrollHeight = Math.max($(document).height(), $(document.body).height())\n\n if (typeof offset != 'object') offsetBottom = offsetTop = offset\n if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)\n if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)\n\n var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)\n\n if (this.affixed != affix) {\n if (this.unpin != null) this.$element.css('top', '')\n\n var affixType = 'affix' + (affix ? '-' + affix : '')\n var e = $.Event(affixType + '.bs.affix')\n\n this.$element.trigger(e)\n\n if (e.isDefaultPrevented()) return\n\n this.affixed = affix\n this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null\n\n this.$element\n .removeClass(Affix.RESET)\n .addClass(affixType)\n .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')\n }\n\n if (affix == 'bottom') {\n this.$element.offset({\n top: scrollHeight - height - offsetBottom\n })\n }\n }\n\n\n // AFFIX PLUGIN DEFINITION\n // =======================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.affix')\n var options = typeof option == 'object' && option\n\n if (!data) $this.data('bs.affix', (data = new Affix(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.affix\n\n $.fn.affix = Plugin\n $.fn.affix.Constructor = Affix\n\n\n // AFFIX NO CONFLICT\n // =================\n\n $.fn.affix.noConflict = function () {\n $.fn.affix = old\n return this\n }\n\n\n // AFFIX DATA-API\n // ==============\n\n $(window).on('load', function () {\n $('[data-spy=\"affix\"]').each(function () {\n var $spy = $(this)\n var data = $spy.data()\n\n data.offset = data.offset || {}\n\n if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom\n if (data.offsetTop != null) data.offset.top = data.offsetTop\n\n Plugin.call($spy, data)\n })\n })\n\n}(jQuery);\n","/*! ========================================================================\n * Bootstrap Toggle: bootstrap-toggle.js v2.2.0\n * http://www.bootstraptoggle.com\n * ========================================================================\n * Copyright 2014 Min Hur, The New York Times Company\n * Licensed under MIT\n * ======================================================================== */\n\n\n +function ($) {\n \t'use strict';\n\n\t// TOGGLE PUBLIC CLASS DEFINITION\n\t// ==============================\n\n\tvar Toggle = function (element, options) {\n\t\tthis.$element = $(element)\n\t\tthis.options = $.extend({}, this.defaults(), options)\n\t\tthis.render()\n\t}\n\n\tToggle.VERSION = '2.2.0'\n\n\tToggle.DEFAULTS = {\n\t\ton: 'On',\n\t\toff: 'Off',\n\t\tonstyle: 'primary',\n\t\toffstyle: 'default',\n\t\tsize: 'normal',\n\t\tstyle: '',\n\t\twidth: null,\n\t\theight: null\n\t}\n\n\tToggle.prototype.defaults = function() {\n\t\treturn {\n\t\t\ton: this.$element.attr('data-on') || Toggle.DEFAULTS.on,\n\t\t\toff: this.$element.attr('data-off') || Toggle.DEFAULTS.off,\n\t\t\tonstyle: this.$element.attr('data-onstyle') || Toggle.DEFAULTS.onstyle,\n\t\t\toffstyle: this.$element.attr('data-offstyle') || Toggle.DEFAULTS.offstyle,\n\t\t\tsize: this.$element.attr('data-size') || Toggle.DEFAULTS.size,\n\t\t\tstyle: this.$element.attr('data-style') || Toggle.DEFAULTS.style,\n\t\t\twidth: this.$element.attr('data-width') || Toggle.DEFAULTS.width,\n\t\t\theight: this.$element.attr('data-height') || Toggle.DEFAULTS.height\n\t\t}\n\t}\n\n\tToggle.prototype.render = function () {\n\t\tthis._onstyle = 'btn-' + this.options.onstyle\n\t\tthis._offstyle = 'btn-' + this.options.offstyle\n\t\tvar size = this.options.size === 'large' ? 'btn-lg'\n\t\t\t: this.options.size === 'small' ? 'btn-sm'\n\t\t\t: this.options.size === 'mini' ? 'btn-xs'\n\t\t\t: ''\n\t\tvar $toggleOn = $('