提交 752d8bad 编写于 作者: F Fabian Reinartz 提交者: GitHub

Merge pull request #3056 from prometheus/mergemaster

Merge master into dev-2.0
## 1.7.1 / 2017-06-12
* [BUGFIX] Fix double prefix redirect.
## 1.7.0 / 2017-06-06 ## 1.7.0 / 2017-06-06
* [CHANGE] Compress remote storage requests and responses with unframed/raw snappy. * [CHANGE] Compress remote storage requests and responses with unframed/raw snappy.
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
Prometheus uses GitHub to manage reviews of pull requests. Prometheus uses GitHub to manage reviews of pull requests.
* If you are a new contributor see: [Steps to Contribute](#steps-to-contribute)
* If you have a trivial fix or improvement, go ahead and create a pull request, * If you have a trivial fix or improvement, go ahead and create a pull request,
addressing (with `@...`) a suitable maintainer of this repository (see addressing (with `@...`) a suitable maintainer of this repository (see
[MAINTAINERS.md](MAINTAINERS.md)) in the description of the pull request. [MAINTAINERS.md](MAINTAINERS.md)) in the description of the pull request.
...@@ -16,3 +18,34 @@ Prometheus uses GitHub to manage reviews of pull requests. ...@@ -16,3 +18,34 @@ Prometheus uses GitHub to manage reviews of pull requests.
and the _Formatting and style_ section of Peter Bourgon's [Go: Best and the _Formatting and style_ section of Peter Bourgon's [Go: Best
Practices for Production Practices for Production
Environments](http://peter.bourgon.org/go-in-production/#formatting-and-style). Environments](http://peter.bourgon.org/go-in-production/#formatting-and-style).
## Steps to Contribute
Should you wish to work on an issue, please claim it first by commenting on the GitHub issue that you want to work on it. This is to prevent duplicated efforts from contributors on the same issue.
Please check the [`low-hanging-fruit`](https://github.com/prometheus/prometheus/issues?q=is%3Aissue+is%3Aopen+label%3A%22low+hanging+fruit%22) label to find issues that are good for getting started. If you have questions about one of the issues, with or without the tag, please comment on them and one of the maintainers will clarify it. For a quicker response, contact us over [IRC](https://prometheus.io/community).
For complete instructions on how to compile see: [Building From Source](https://github.com/prometheus/prometheus#building-from-source)
For quickly compiling and testing your changes do:
```
# For building.
go build ./cmd/prometheus/
./prometheus
# For testing.
make test # Make sure all the tests pass before you commit and push :)
```
All our issues are regularly tagged so that you can also filter down the issues involving the components you want to work on. For our labelling policy refer [the wiki page](https://github.com/prometheus/prometheus/wiki/Label-Names-and-Descriptions).
## Pull Request Checklist
* Branch from the master branch and, if needed, rebase to the current master branch before submitting your pull request. If it doesn't merge cleanly with master you may be asked to rebase your changes.
* Commits should be as small as possible, while ensuring that each commit is correct independently (i.e., each commit should compile and pass tests).
* If your patch is not getting reviewed or you need a specific person to review it, you can @-reply a reviewer asking for a review in the pull request or a comment, or you can ask for a review on IRC channel [#prometheus](https://webchat.freenode.net/?channels=#prometheus) on irc.freenode.net (for the easiest start, [join via Riot](https://riot.im/app/#/room/#prometheus:matrix.org)).
* Add tests relevant to the fixed bug or new feature.
...@@ -329,6 +329,10 @@ func main() { ...@@ -329,6 +329,10 @@ func main() {
// Wait for reload or termination signals. // Wait for reload or termination signals.
close(hupReady) // Unblock SIGHUP handler. close(hupReady) // Unblock SIGHUP handler.
// Set web server to ready.
webHandler.Ready()
log.Info("Server is Ready to receive requests.")
term := make(chan os.Signal) term := make(chan os.Signal)
signal.Notify(term, os.Interrupt, syscall.SIGTERM) signal.Notify(term, os.Interrupt, syscall.SIGTERM)
select { select {
......
...@@ -173,6 +173,25 @@ var ( ...@@ -173,6 +173,25 @@ var (
// DefaultRemoteWriteConfig is the default remote write configuration. // DefaultRemoteWriteConfig is the default remote write configuration.
DefaultRemoteWriteConfig = RemoteWriteConfig{ DefaultRemoteWriteConfig = RemoteWriteConfig{
RemoteTimeout: model.Duration(30 * time.Second), RemoteTimeout: model.Duration(30 * time.Second),
QueueConfig: DefaultQueueConfig,
}
// DefaultQueueConfig is the default remote queue configuration.
DefaultQueueConfig = QueueConfig{
// With a maximum of 1000 shards, assuming an average of 100ms remote write
// time and 100 samples per batch, we will be able to push 1M samples/s.
MaxShards: 1000,
MaxSamplesPerSend: 100,
// By default, buffer 1000 batches, which at 100ms per batch is 1:40mins. At
// 1000 shards, this will buffer 100M samples total.
Capacity: 100 * 1000,
BatchSendDeadline: 5 * time.Second,
// Max number of times to retry a batch on recoverable errors.
MaxRetries: 10,
MinBackoff: 30 * time.Millisecond,
MaxBackoff: 100 * time.Millisecond,
} }
// DefaultRemoteReadConfig is the default remote read configuration. // DefaultRemoteReadConfig is the default remote read configuration.
...@@ -1390,13 +1409,14 @@ func (re Regexp) MarshalYAML() (interface{}, error) { ...@@ -1390,13 +1409,14 @@ func (re Regexp) MarshalYAML() (interface{}, error) {
// RemoteWriteConfig is the configuration for writing to remote storage. // RemoteWriteConfig is the configuration for writing to remote storage.
type RemoteWriteConfig struct { type RemoteWriteConfig struct {
URL *URL `yaml:"url,omitempty"` URL *URL `yaml:"url"`
RemoteTimeout model.Duration `yaml:"remote_timeout,omitempty"` RemoteTimeout model.Duration `yaml:"remote_timeout,omitempty"`
WriteRelabelConfigs []*RelabelConfig `yaml:"write_relabel_configs,omitempty"` WriteRelabelConfigs []*RelabelConfig `yaml:"write_relabel_configs,omitempty"`
// We cannot do proper Go type embedding below as the parser will then parse // We cannot do proper Go type embedding below as the parser will then parse
// values arbitrarily into the overflow maps of further-down types. // values arbitrarily into the overflow maps of further-down types.
HTTPClientConfig HTTPClientConfig `yaml:",inline"` HTTPClientConfig HTTPClientConfig `yaml:",inline"`
QueueConfig QueueConfig `yaml:"queue_config,omitempty"`
// Catches all undefined fields and must be empty after parsing. // Catches all undefined fields and must be empty after parsing.
XXX map[string]interface{} `yaml:",inline"` XXX map[string]interface{} `yaml:",inline"`
...@@ -1409,15 +1429,49 @@ func (c *RemoteWriteConfig) UnmarshalYAML(unmarshal func(interface{}) error) err ...@@ -1409,15 +1429,49 @@ func (c *RemoteWriteConfig) UnmarshalYAML(unmarshal func(interface{}) error) err
if err := unmarshal((*plain)(c)); err != nil { if err := unmarshal((*plain)(c)); err != nil {
return err return err
} }
if c.URL == nil {
return fmt.Errorf("url for remote_write is empty")
}
// The UnmarshalYAML method of HTTPClientConfig is not being called because it's not a pointer.
// We cannot make it a pointer as the parser panics for inlined pointer structs.
// Thus we just do its validation here.
if err := c.HTTPClientConfig.validate(); err != nil {
return err
}
if err := checkOverflow(c.XXX, "remote_write"); err != nil { if err := checkOverflow(c.XXX, "remote_write"); err != nil {
return err return err
} }
return nil return nil
} }
// QueueConfig is the configuration for the queue used to write to remote
// storage.
type QueueConfig struct {
// Number of samples to buffer per shard before we start dropping them.
Capacity int `yaml:"capacity,omitempty"`
// Max number of shards, i.e. amount of concurrency.
MaxShards int `yaml:"max_shards,omitempty"`
// Maximum number of samples per send.
MaxSamplesPerSend int `yaml:"max_samples_per_send,omitempty"`
// Maximum time sample will wait in buffer.
BatchSendDeadline time.Duration `yaml:"batch_send_deadline,omitempty"`
// Max number of times to retry a batch on recoverable errors.
MaxRetries int `yaml:"max_retries,omitempty"`
// On recoverable errors, backoff exponentially.
MinBackoff time.Duration `yaml:"min_backoff,omitempty"`
MaxBackoff time.Duration `yaml:"max_backoff,omitempty"`
}
// RemoteReadConfig is the configuration for reading from remote storage. // RemoteReadConfig is the configuration for reading from remote storage.
type RemoteReadConfig struct { type RemoteReadConfig struct {
URL *URL `yaml:"url,omitempty"` URL *URL `yaml:"url"`
RemoteTimeout model.Duration `yaml:"remote_timeout,omitempty"` RemoteTimeout model.Duration `yaml:"remote_timeout,omitempty"`
// We cannot do proper Go type embedding below as the parser will then parse // We cannot do proper Go type embedding below as the parser will then parse
...@@ -1435,6 +1489,17 @@ func (c *RemoteReadConfig) UnmarshalYAML(unmarshal func(interface{}) error) erro ...@@ -1435,6 +1489,17 @@ func (c *RemoteReadConfig) UnmarshalYAML(unmarshal func(interface{}) error) erro
if err := unmarshal((*plain)(c)); err != nil { if err := unmarshal((*plain)(c)); err != nil {
return err return err
} }
if c.URL == nil {
return fmt.Errorf("url for remote_read is empty")
}
// The UnmarshalYAML method of HTTPClientConfig is not being called because it's not a pointer.
// We cannot make it a pointer as the parser panics for inlined pointer structs.
// Thus we just do its validation here.
if err := c.HTTPClientConfig.validate(); err != nil {
return err
}
if err := checkOverflow(c.XXX, "remote_read"); err != nil { if err := checkOverflow(c.XXX, "remote_read"); err != nil {
return err return err
} }
......
...@@ -66,10 +66,12 @@ var expectedConf = &Config{ ...@@ -66,10 +66,12 @@ var expectedConf = &Config{
Action: RelabelDrop, Action: RelabelDrop,
}, },
}, },
QueueConfig: DefaultQueueConfig,
}, },
{ {
URL: mustParseURL("http://remote2/push"), URL: mustParseURL("http://remote2/push"),
RemoteTimeout: model.Duration(30 * time.Second), RemoteTimeout: model.Duration(30 * time.Second),
QueueConfig: DefaultQueueConfig,
}, },
}, },
...@@ -666,6 +668,12 @@ var expectedErrors = []struct { ...@@ -666,6 +668,12 @@ var expectedErrors = []struct {
}, { }, {
filename: "unknown_global_attr.bad.yml", filename: "unknown_global_attr.bad.yml",
errMsg: "unknown fields in global config: nonexistent_field", errMsg: "unknown fields in global config: nonexistent_field",
}, {
filename: "remote_read_url_missing.bad.yml",
errMsg: `url for remote_read is empty`,
}, {
filename: "remote_write_url_missing.bad.yml",
errMsg: `url for remote_write is empty`,
}, },
} }
......
### Service Discovery
This directory contains the service discovery (SD) component of Prometheus.
## Design of a Prometheus SD
There are many requests to add new SDs to Prometheus, this section looks at
what makes a good SD and covers some of the common implementation issues.
### Does this make sense as an SD?
The first question to be asked is does it make sense to add this particular
SD? An SD mechanism should be reasonably well established, and at a minimum in
use across multiple organisations. It should allow discovering of machines
and/or services running somewhere. When exactly an SD is popular enough to
justify being added to Prometheus natively is an open question.
It should not be a brand new SD mechanism, or a variant of an established
mechanism. We want to integrate Prometheus with the SD that's already there in
your infrastructure, not invent yet more ways to do service discovery. We also
do not add mechanisms to work around users lacking service discovery and/or
configuration management infrastructure.
SDs that merely discover other applications running the same software (e.g.
talk to one Kafka or Cassandra server to find the others) are not service
discovery. In that case the SD you should be looking at is whatever decides
that a machine is going to be a Kafka server, likely a machine database or
configuration management system.
If something is particularly custom or unusual, `file_sd` is the generic
mechanism provided for users to hook in. Generally with Prometheus we offer a
single generic mechanism for things with infinite variations, rather than
trying to support everything natively (see also, alertmanager webhook, remote
read, remote write, node exporter textfile collector). For example anything
that would involve talking to a relational database should use `file_sd`
instead.
For configuration management systems like Chef, while they do have a
database/API that'd in principle make sense to talk to for service discovery,
the idiomatic approach is to use Chef's templating facilities to write out a
file for use with `file_sd`.
### Mapping from SD to Prometheus
The general principle with SD is to extract all the potentially useful
information we can out of the SD, and let the user choose what they need of it
using
[relabelling](https://prometheus.io/docs/operating/configuration/#<relabel_config>).
This information is generally termed metadata.
Metadata is exposed as a set of key/value pairs (labels) per target. The keys
are prefixed with `__meta_<sdname>_<key>`, and there should also be an `__address__`
label with the host:port of the target (preferably an IP address to avoid DNS
lookups). No other labelnames should be exposed.
It is very common for initial pull requests for new SDs to include hardcoded
assumptions that make sense for the the author's setup. SD should be generic,
any customisation should be handled via relabelling. There should be basically
no business logic, filtering, or transformations of the data from the SD beyond
that which is needed to fit it into the metadata data model.
Arrays (e.g. a list of tags) should be converted to a single label with the
array values joined with a comma. Also prefix and suffix the value with a
comma. So for example the array `[a, b, c]` would become `,a,b,c,`. As
relabelling regexes are fully anchored, this makes it easier to write correct
regexes against (`.*,a,.*` works no matter where `a` appears in the list). The
canonical example of this is `__meta_consul_tags`.
Maps, hashes and other forms of key/value pairs should be all prefixed and
exposed as labels. For example for EC2 tags, there would be
`__meta_ec2_tag_Description=mydescription` for the Description tag. Labelnames
may only contain `[_a-zA-Z0-9]`, sanitize by replacing with underscores as needed.
For targets with multiple potential ports, you can a) expose them as a list, b)
if they're named expose them as a map or c) expose them each as their own
target. Kubernetes SD takes the target per port approach. a) and b) can be
combined.
For machine-like SDs (OpenStack, EC2, Kubernetes to some extent) there may
be multiple network interfaces for a target. Thus far reporting the details
of only the first/primary network interface has sufficed.
### Other implementation considerations
SDs are intended to dump all possible targets. For example the optional use of
EC2 service discovery would be to take the entire region's worth of EC2
instances it provides and do everything needed in one `scrape_config`. For
large deployments where you are only interested in a small proportion of the
returned targets, this may cause performance issues. If this occurs it is
acceptable to also offer filtering via whatever mechanisms the SD exposes. For
EC2 that would be the `Filter` option on `DescribeInstances`. Keep in mind that
this is a performance optimisation, it should be possible to do the same
filtering using relabelling alone. As with SD generally, we do not invent new
ways to filter targets (that is what relabelling is for), merely offer up
whatever functionality the SD itself offers.
It is a general rule with Prometheus that all configuration comes from the
configuration file. While the libraries you use to talk to the SD may also
offer other mechanisms for providing configuration/authentication under the
covers (EC2's use of environment variables being a prime example), using your SD
mechanism should not require this. Put another way, your SD implementation
should not read environment variables or files to obtain configuration.
Some SD mechanisms have rate limits that make them challenging to use. As an
example we have unfortunately had to reject Amazon ECS service discovery due to
the rate limits being so low that it would not be usable for anything beyond
small setups.
If a system offers multiple distinct types of SD, select which is in use with a
configuration option rather than returning them all from one mega SD that
requires relabelling to select just the one you want. So far we have only seen
this with Kubernetes. When a single SD with a selector vs. multiple distinct
SDs makes sense is an open question.
If there is a failure while processing talking to the SD, abort rather than
returning partial data. It is better to work from stale targets than partial
or incorrect metadata.
The information obtained from service discovery is not considered sensitive
security wise. Do not return secrets in metadata, anyone with access to
the Prometheus server will be able to see them.
## Writing an SD mechanism
### The SD interface
A Service Discovery (SD) mechanism has to discover targets and provide them to Prometheus. We expect similar targets to be grouped together, in the form of a [`TargetGroup`](https://godoc.org/github.com/prometheus/prometheus/config#TargetGroup). The SD mechanism sends the targets down to prometheus as list of `TargetGroups`.
An SD mechanism has to implement the `TargetProvider` Interface:
```go
type TargetProvider interface {
Run(ctx context.Context, up chan<- []*config.TargetGroup)
}
```
Prometheus will call the `Run()` method on a provider to initialise the discovery mechanism. The mechanism will then send *all* the `TargetGroup`s into the channel. Now the mechanism will watch for changes and then send only changed and new `TargetGroup`s down the channel.
For example if we had a discovery mechanism and it retrieves the following groups:
```
[]config.TargetGroup{
{
Targets: []model.LabelSet{
{
"__instance__": "10.11.150.1:7870",
"hostname": "demo-target-1",
"test": "simple-test",
},
{
"__instance__": "10.11.150.4:7870",
"hostname": "demo-target-2",
"test": "simple-test",
},
},
Labels: map[LabelName][LabelValue] {
"job": "mysql",
},
"Source": "file1",
},
{
Targets: []model.LabelSet{
{
"__instance__": "10.11.122.11:6001",
"hostname": "demo-postgres-1",
"test": "simple-test",
},
{
"__instance__": "10.11.122.15:6001",
"hostname": "demo-postgres-2",
"test": "simple-test",
},
},
Labels: map[LabelName][LabelValue] {
"job": "postgres",
},
"Source": "file2",
},
}
```
Here there are two `TargetGroups` one group with source `file1` and another with `file2`. The grouping is implementation specific and could even be one target per group. But, one has to make sure every target group sent by an SD instance should have a `Source` which is unique across all the `TargetGroup`s of that SD instance.
In this case, both the `TargetGroup`s are sent down the channel the first time `Run()` is called. Now, for an update, we need to send the whole _changed_ `TargetGroup` down the channel. i.e, if the target with `hostname: demo-postgres-2` goes away, we send:
```
&config.TargetGroup{
Targets: []model.LabelSet{
{
"__instance__": "10.11.122.11:6001",
"hostname": "demo-postgres-1",
"test": "simple-test",
},
},
Labels: map[LabelName][LabelValue] {
"job": "postgres",
},
"Source": "file2",
}
```
down the channel.
If all the targets in a group go away, we need to send the target groups with empty `Targets` down the channel. i.e, if all targets with `job: postgres` go away, we send:
```
&config.TargetGroup{
Targets: nil,
"Source": "file2",
}
```
down the channel.
<!-- TODO: Add best-practices -->
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
# #
# Kubernetes labels will be added as Prometheus labels on metrics via the # Kubernetes labels will be added as Prometheus labels on metrics via the
# `labelmap` relabeling action. # `labelmap` relabeling action.
#
# If you are using Kubernetes 1.7.2 or earlier, please take note of the comments
# for the kubernetes-cadvisor job; you will need to edit or remove this job.
# Scrape config for API servers. # Scrape config for API servers.
# #
...@@ -47,6 +50,12 @@ scrape_configs: ...@@ -47,6 +50,12 @@ scrape_configs:
action: keep action: keep
regex: default;kubernetes;https regex: default;kubernetes;https
# Scrape config for nodes (kubelet).
#
# Rather than connecting directly to the node, the scrape is proxied though the
# Kubernetes apiserver. This means it will work if Prometheus is running out of
# cluster, or can't connect to nodes for some other reason (e.g. because of
# firewalling).
- job_name: 'kubernetes-nodes' - job_name: 'kubernetes-nodes'
# Default to scraping over https. If required, just disable this or change to # Default to scraping over https. If required, just disable this or change to
...@@ -61,13 +70,6 @@ scrape_configs: ...@@ -61,13 +70,6 @@ scrape_configs:
# <kubernetes_sd_config>. # <kubernetes_sd_config>.
tls_config: tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
# If your node certificates are self-signed or use a different CA to the
# master CA, then disable certificate verification below. Note that
# certificate verification is an integral part of a secure infrastructure
# so this should only be disabled in a controlled environment. You can
# disable certificate verification by uncommenting the line below.
#
# insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
kubernetes_sd_configs: kubernetes_sd_configs:
...@@ -83,6 +85,49 @@ scrape_configs: ...@@ -83,6 +85,49 @@ scrape_configs:
target_label: __metrics_path__ target_label: __metrics_path__
replacement: /api/v1/nodes/${1}/proxy/metrics replacement: /api/v1/nodes/${1}/proxy/metrics
# Scrape config for Kubelet cAdvisor.
#
# This is required for Kubernetes 1.7.3 and later, where cAdvisor metrics
# (those whose names begin with 'container_') have been removed from the
# Kubelet metrics endpoint. This job scrapes the cAdvisor endpoint to
# retrieve those metrics.
#
# In Kubernetes 1.7.0-1.7.2, these metrics are only exposed on the cAdvisor
# HTTP endpoint; use "replacement: /api/v1/nodes/${1}:4194/proxy/metrics"
# in that case (and ensure cAdvisor's HTTP server hasn't been disabled with
# the --cadvisor-port=0 Kubelet flag).
#
# This job is not necessary and should be removed in Kubernetes 1.6 and
# earlier versions, or it will cause the metrics to be scraped twice.
- job_name: 'kubernetes-cadvisor'
# Default to scraping over https. If required, just disable this or change to
# `http`.
scheme: https
# This TLS & bearer token file config is used to connect to the actual scrape
# endpoints for cluster components. This is separate to discovery auth
# configuration because discovery & scraping are two separate concerns in
# Prometheus. The discovery auth config is automatic if Prometheus runs inside
# the cluster. Otherwise, more config options have to be provided within the
# <kubernetes_sd_config>.
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
kubernetes_sd_configs:
- role: node
relabel_configs:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- target_label: __address__
replacement: kubernetes.default.svc:443
- source_labels: [__meta_kubernetes_node_name]
regex: (.+)
target_label: __metrics_path__
replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
# Scrape config for service endpoints. # Scrape config for service endpoints.
# #
# The relabeling allows the actual service scrape endpoint to be configured # The relabeling allows the actual service scrape endpoint to be configured
......
...@@ -145,7 +145,7 @@ type query struct { ...@@ -145,7 +145,7 @@ type query struct {
stmt Statement stmt Statement
// Timer stats for the query execution. // Timer stats for the query execution.
stats *stats.TimerGroup stats *stats.TimerGroup
// Cancelation function for the query. // Cancellation function for the query.
cancel func() cancel func()
// The engine against which the query is executed. // The engine against which the query is executed.
...@@ -669,7 +669,7 @@ func (ev *evaluator) Eval(expr Expr) (v Value, err error) { ...@@ -669,7 +669,7 @@ func (ev *evaluator) Eval(expr Expr) (v Value, err error) {
// eval evaluates the given expression as the given AST expression node requires. // eval evaluates the given expression as the given AST expression node requires.
func (ev *evaluator) eval(expr Expr) Value { func (ev *evaluator) eval(expr Expr) Value {
// This is the top-level evaluation method. // This is the top-level evaluation method.
// Thus, we check for timeout/cancelation here. // Thus, we check for timeout/cancellation here.
if err := contextDone(ev.ctx, "expression evaluation"); err != nil { if err := contextDone(ev.ctx, "expression evaluation"); err != nil {
ev.error(err) ev.error(err)
} }
......
...@@ -194,7 +194,7 @@ func TestEngineShutdown(t *testing.T) { ...@@ -194,7 +194,7 @@ func TestEngineShutdown(t *testing.T) {
t.Fatalf("expected error on querying with canceled context but got none") t.Fatalf("expected error on querying with canceled context but got none")
} }
if _, ok := res2.Err.(ErrQueryCanceled); !ok { if _, ok := res2.Err.(ErrQueryCanceled); !ok {
t.Fatalf("expected cancelation error, got %q", res2.Err) t.Fatalf("expected cancellation error, got %q", res2.Err)
} }
} }
......
...@@ -699,7 +699,11 @@ func funcDeriv(ev *evaluator, args Expressions) Value { ...@@ -699,7 +699,11 @@ func funcDeriv(ev *evaluator, args Expressions) Value {
if len(samples.Points) < 2 { if len(samples.Points) < 2 {
continue continue
} }
slope, _ := linearRegression(samples.Points, 0)
// We pass in an arbitrary timestamp that is near the values in use
// to avoid floating point accuracy issues, see
// https://github.com/prometheus/prometheus/issues/2674
slope, _ := linearRegression(samples.Points, samples.Points[0].T)
resultSample := Sample{ resultSample := Sample{
Metric: dropMetricName(samples.Metric), Metric: dropMetricName(samples.Metric),
Point: Point{V: slope, T: ev.Timestamp}, Point: Point{V: slope, T: ev.Timestamp},
......
...@@ -13,7 +13,14 @@ ...@@ -13,7 +13,14 @@
package promql package promql
import "testing" import (
"context"
"testing"
"github.com/prometheus/prometheus/pkg/labels"
"github.com/prometheus/prometheus/pkg/timestamp"
"github.com/prometheus/prometheus/util/testutil"
)
func BenchmarkHoltWinters4Week5Min(b *testing.B) { func BenchmarkHoltWinters4Week5Min(b *testing.B) {
input := ` input := `
...@@ -71,3 +78,41 @@ eval instant at 1d changes(http_requests[1d]) ...@@ -71,3 +78,41 @@ eval instant at 1d changes(http_requests[1d])
bench := NewBenchmark(b, input) bench := NewBenchmark(b, input)
bench.Run() bench.Run()
} }
func TestDeriv(t *testing.T) {
// https://github.com/prometheus/prometheus/issues/2674#issuecomment-315439393
// This requires more precision than the usual test system offers,
// so we test it by hand.
storage := testutil.NewStorage(t)
defer storage.Close()
engine := NewEngine(storage, nil)
a, err := storage.Appender()
if err != nil {
t.Fatal(err)
}
metric := labels.FromStrings("__name__", "foo")
a.Add(metric, 1493712816939, 1.0)
a.Add(metric, 1493712846939, 1.0)
if err := a.Commit(); err != nil {
t.Fatal(err)
}
query, err := engine.NewInstantQuery("deriv(foo[30m])", timestamp.Time(1493712846939))
if err != nil {
t.Fatalf("Error parsing query: %s", err)
}
result := query.Exec(context.Background())
if result.Err != nil {
t.Fatalf("Error running query: %s", result.Err)
}
vec, _ := result.Vector()
if len(vec) != 1 {
t.Fatalf("Expected 1 result, got %d", len(vec))
}
if vec[0].V != 0.0 {
t.Fatalf("Expected 0.0 as value, got %f", vec[0].V)
}
}
...@@ -18,9 +18,7 @@ import ( ...@@ -18,9 +18,7 @@ import (
"crypto/x509" "crypto/x509"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net"
"net/http" "net/http"
"net/url"
"strings" "strings"
"time" "time"
...@@ -75,33 +73,6 @@ func NewClientFromConfig(cfg config.HTTPClientConfig) (*http.Client, error) { ...@@ -75,33 +73,6 @@ func NewClientFromConfig(cfg config.HTTPClientConfig) (*http.Client, error) {
return NewClient(rt), nil return NewClient(rt), nil
} }
// NewDeadlineRoundTripper returns a new http.RoundTripper which will time out
// long running requests.
func NewDeadlineRoundTripper(timeout time.Duration, proxyURL *url.URL) http.RoundTripper {
return &http.Transport{
// Set proxy (if null, then becomes a direct connection)
Proxy: http.ProxyURL(proxyURL),
// We need to disable keepalive, because we set a deadline on the
// underlying connection.
DisableKeepAlives: true,
Dial: func(netw, addr string) (c net.Conn, err error) {
start := time.Now()
c, err = net.DialTimeout(netw, addr, timeout)
if err != nil {
return nil, err
}
if err = c.SetDeadline(start.Add(timeout)); err != nil {
c.Close()
return nil, err
}
return c, nil
},
}
}
type bearerAuthRoundTripper struct { type bearerAuthRoundTripper struct {
bearerToken string bearerToken string
rt http.RoundTripper rt http.RoundTripper
......
// Copyright 2017 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package httputil
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"reflect"
"strings"
"testing"
"github.com/prometheus/prometheus/config"
"github.com/prometheus/prometheus/util/testutil"
)
const (
TLSCAChainPath = "testdata/tls-ca-chain.pem"
ServerCertificatePath = "testdata/server.crt"
ServerKeyPath = "testdata/server.key"
BarneyCertificatePath = "testdata/barney.crt"
BarneyKeyNoPassPath = "testdata/barney-no-pass.key"
MissingCA = "missing/ca.crt"
MissingCert = "missing/cert.crt"
MissingKey = "missing/secret.key"
ExpectedMessage = "I'm here to serve you!!!"
BearerToken = "theanswertothegreatquestionoflifetheuniverseandeverythingisfortytwo"
BearerTokenFile = "testdata/bearer.token"
MissingBearerTokenFile = "missing/bearer.token"
ExpectedBearer = "Bearer " + BearerToken
ExpectedUsername = "arthurdent"
ExpectedPassword = "42"
)
func newTestServer(handler func(w http.ResponseWriter, r *http.Request)) (*httptest.Server, error) {
testServer := httptest.NewUnstartedServer(http.HandlerFunc(handler))
tlsCAChain, err := ioutil.ReadFile(TLSCAChainPath)
if err != nil {
return nil, fmt.Errorf("Can't read %s", TLSCAChainPath)
}
serverCertificate, err := tls.LoadX509KeyPair(ServerCertificatePath, ServerKeyPath)
if err != nil {
return nil, fmt.Errorf("Can't load X509 key pair %s - %s", ServerCertificatePath, ServerKeyPath)
}
rootCAs := x509.NewCertPool()
rootCAs.AppendCertsFromPEM(tlsCAChain)
testServer.TLS = &tls.Config{
Certificates: make([]tls.Certificate, 1),
RootCAs: rootCAs,
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: rootCAs}
testServer.TLS.Certificates[0] = serverCertificate
testServer.TLS.BuildNameToCertificate()
testServer.StartTLS()
return testServer, nil
}
func TestNewClientFromConfig(t *testing.T) {
var newClientValidConfig = []struct {
clientConfig config.HTTPClientConfig
handler func(w http.ResponseWriter, r *http.Request)
}{
{
clientConfig: config.HTTPClientConfig{
TLSConfig: config.TLSConfig{
CAFile: "",
CertFile: BarneyCertificatePath,
KeyFile: BarneyKeyNoPassPath,
ServerName: "",
InsecureSkipVerify: true},
},
handler: func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, ExpectedMessage)
},
}, {
clientConfig: config.HTTPClientConfig{
TLSConfig: config.TLSConfig{
CAFile: TLSCAChainPath,
CertFile: BarneyCertificatePath,
KeyFile: BarneyKeyNoPassPath,
ServerName: "",
InsecureSkipVerify: false},
},
handler: func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, ExpectedMessage)
},
}, {
clientConfig: config.HTTPClientConfig{
BearerToken: BearerToken,
TLSConfig: config.TLSConfig{
CAFile: TLSCAChainPath,
CertFile: BarneyCertificatePath,
KeyFile: BarneyKeyNoPassPath,
ServerName: "",
InsecureSkipVerify: false},
},
handler: func(w http.ResponseWriter, r *http.Request) {
bearer := r.Header.Get("Authorization")
if bearer != ExpectedBearer {
fmt.Fprintf(w, "The expected Bearer Authorization (%s) differs from the obtained Bearer Authorization (%s)",
ExpectedBearer, bearer)
} else {
fmt.Fprint(w, ExpectedMessage)
}
},
}, {
clientConfig: config.HTTPClientConfig{
BearerTokenFile: BearerTokenFile,
TLSConfig: config.TLSConfig{
CAFile: TLSCAChainPath,
CertFile: BarneyCertificatePath,
KeyFile: BarneyKeyNoPassPath,
ServerName: "",
InsecureSkipVerify: false},
},
handler: func(w http.ResponseWriter, r *http.Request) {
bearer := r.Header.Get("Authorization")
if bearer != ExpectedBearer {
fmt.Fprintf(w, "The expected Bearer Authorization (%s) differs from the obtained Bearer Authorization (%s)",
ExpectedBearer, bearer)
} else {
fmt.Fprint(w, ExpectedMessage)
}
},
}, {
clientConfig: config.HTTPClientConfig{
BasicAuth: &config.BasicAuth{
Username: ExpectedUsername,
Password: ExpectedPassword,
},
TLSConfig: config.TLSConfig{
CAFile: TLSCAChainPath,
CertFile: BarneyCertificatePath,
KeyFile: BarneyKeyNoPassPath,
ServerName: "",
InsecureSkipVerify: false},
},
handler: func(w http.ResponseWriter, r *http.Request) {
username, password, ok := r.BasicAuth()
if ok == false {
fmt.Fprintf(w, "The Authorization header wasn't set")
} else if ExpectedUsername != username {
fmt.Fprintf(w, "The expected username (%s) differs from the obtained username (%s).", ExpectedUsername, username)
} else if ExpectedPassword != password {
fmt.Fprintf(w, "The expected password (%s) differs from the obtained password (%s).", ExpectedPassword, password)
} else {
fmt.Fprint(w, ExpectedMessage)
}
},
},
}
for _, validConfig := range newClientValidConfig {
testServer, err := newTestServer(validConfig.handler)
if err != nil {
t.Fatal(err.Error())
}
defer testServer.Close()
client, err := NewClientFromConfig(validConfig.clientConfig)
if err != nil {
t.Errorf("Can't create a client from this config: %+v", validConfig.clientConfig)
continue
}
response, err := client.Get(testServer.URL)
if err != nil {
t.Errorf("Can't connect to the test server using this config: %+v", validConfig.clientConfig)
continue
}
message, err := ioutil.ReadAll(response.Body)
response.Body.Close()
if err != nil {
t.Errorf("Can't read the server response body using this config: %+v", validConfig.clientConfig)
continue
}
trimMessage := strings.TrimSpace(string(message))
if ExpectedMessage != trimMessage {
t.Errorf("The expected message (%s) differs from the obtained message (%s) using this config: %+v",
ExpectedMessage, trimMessage, validConfig.clientConfig)
}
}
}
func TestNewClientFromInvalidConfig(t *testing.T) {
var newClientInvalidConfig = []struct {
clientConfig config.HTTPClientConfig
errorMsg string
}{
{
clientConfig: config.HTTPClientConfig{
TLSConfig: config.TLSConfig{
CAFile: MissingCA,
CertFile: "",
KeyFile: "",
ServerName: "",
InsecureSkipVerify: true},
},
errorMsg: fmt.Sprintf("unable to use specified CA cert %s:", MissingCA),
}, {
clientConfig: config.HTTPClientConfig{
BearerTokenFile: MissingBearerTokenFile,
TLSConfig: config.TLSConfig{
CAFile: TLSCAChainPath,
CertFile: BarneyCertificatePath,
KeyFile: BarneyKeyNoPassPath,
ServerName: "",
InsecureSkipVerify: false},
},
errorMsg: fmt.Sprintf("unable to read bearer token file %s:", MissingBearerTokenFile),
},
}
for _, invalidConfig := range newClientInvalidConfig {
client, err := NewClientFromConfig(invalidConfig.clientConfig)
if client != nil {
t.Errorf("A client instance was returned instead of nil using this config: %+v", invalidConfig.clientConfig)
}
if err == nil {
t.Errorf("No error was returned using this config: %+v", invalidConfig.clientConfig)
}
if !strings.Contains(err.Error(), invalidConfig.errorMsg) {
t.Errorf("Expected error %s does not contain %s", err.Error(), invalidConfig.errorMsg)
}
}
}
func TestBearerAuthRoundTripper(t *testing.T) {
const (
newBearerToken = "goodbyeandthankyouforthefish"
)
fakeRoundTripper := testutil.NewRoundTripCheckRequest(func(req *http.Request) {
bearer := req.Header.Get("Authorization")
if bearer != ExpectedBearer {
t.Errorf("The expected Bearer Authorization (%s) differs from the obtained Bearer Authorization (%s)",
ExpectedBearer, bearer)
}
}, nil, nil)
//Normal flow
bearerAuthRoundTripper := NewBearerAuthRoundTripper(BearerToken, fakeRoundTripper)
request, _ := http.NewRequest("GET", "/hitchhiker", nil)
request.Header.Set("User-Agent", "Douglas Adams mind")
bearerAuthRoundTripper.RoundTrip(request)
//Should honor already Authorization header set
bearerAuthRoundTripperShouldNotModifyExistingAuthorization := NewBearerAuthRoundTripper(newBearerToken, fakeRoundTripper)
request, _ = http.NewRequest("GET", "/hitchhiker", nil)
request.Header.Set("Authorization", ExpectedBearer)
bearerAuthRoundTripperShouldNotModifyExistingAuthorization.RoundTrip(request)
}
func TestBasicAuthRoundTripper(t *testing.T) {
const (
newUsername = "fordprefect"
newPassword = "towel"
)
fakeRoundTripper := testutil.NewRoundTripCheckRequest(func(req *http.Request) {
username, password, ok := req.BasicAuth()
if ok == false {
t.Errorf("The Authorization header wasn't set")
}
if ExpectedUsername != username {
t.Errorf("The expected username (%s) differs from the obtained username (%s).", ExpectedUsername, username)
}
if ExpectedPassword != password {
t.Errorf("The expected password (%s) differs from the obtained password (%s).", ExpectedPassword, password)
}
}, nil, nil)
//Normal flow
basicAuthRoundTripper := NewBasicAuthRoundTripper(ExpectedUsername,
ExpectedPassword, fakeRoundTripper)
request, _ := http.NewRequest("GET", "/hitchhiker", nil)
request.Header.Set("User-Agent", "Douglas Adams mind")
basicAuthRoundTripper.RoundTrip(request)
//Should honor already Authorization header set
basicAuthRoundTripperShouldNotModifyExistingAuthorization := NewBasicAuthRoundTripper(newUsername,
newPassword, fakeRoundTripper)
request, _ = http.NewRequest("GET", "/hitchhiker", nil)
request.SetBasicAuth(ExpectedUsername, ExpectedPassword)
basicAuthRoundTripperShouldNotModifyExistingAuthorization.RoundTrip(request)
}
func TestTLSConfig(t *testing.T) {
configTLSConfig := config.TLSConfig{
CAFile: TLSCAChainPath,
CertFile: BarneyCertificatePath,
KeyFile: BarneyKeyNoPassPath,
ServerName: "localhost",
InsecureSkipVerify: false}
tlsCAChain, err := ioutil.ReadFile(TLSCAChainPath)
if err != nil {
t.Fatalf("Can't read the CA certificate chain (%s)",
TLSCAChainPath)
}
rootCAs := x509.NewCertPool()
rootCAs.AppendCertsFromPEM(tlsCAChain)
barneyCertificate, err := tls.LoadX509KeyPair(BarneyCertificatePath, BarneyKeyNoPassPath)
if err != nil {
t.Fatalf("Can't load the client key pair ('%s' and '%s'). Reason: %s",
BarneyCertificatePath, BarneyKeyNoPassPath, err)
}
expectedTLSConfig := &tls.Config{
RootCAs: rootCAs,
Certificates: []tls.Certificate{barneyCertificate},
ServerName: configTLSConfig.ServerName,
InsecureSkipVerify: configTLSConfig.InsecureSkipVerify}
expectedTLSConfig.BuildNameToCertificate()
tlsConfig, err := NewTLSConfig(configTLSConfig)
if err != nil {
t.Fatalf("Can't create a new TLS Config from a configuration (%s).", err)
}
if !reflect.DeepEqual(tlsConfig, expectedTLSConfig) {
t.Fatalf("Unexpected TLS Config result: \n\n%+v\n expected\n\n%+v", tlsConfig, expectedTLSConfig)
}
}
func TestTLSConfigEmpty(t *testing.T) {
configTLSConfig := config.TLSConfig{
CAFile: "",
CertFile: "",
KeyFile: "",
ServerName: "",
InsecureSkipVerify: true}
expectedTLSConfig := &tls.Config{
InsecureSkipVerify: configTLSConfig.InsecureSkipVerify}
expectedTLSConfig.BuildNameToCertificate()
tlsConfig, err := NewTLSConfig(configTLSConfig)
if err != nil {
t.Fatalf("Can't create a new TLS Config from a configuration (%s).", err)
}
if !reflect.DeepEqual(tlsConfig, expectedTLSConfig) {
t.Fatalf("Unexpected TLS Config result: \n\n%+v\n expected\n\n%+v", tlsConfig, expectedTLSConfig)
}
}
func TestTLSConfigInvalidCA(t *testing.T) {
var invalidTLSConfig = []struct {
configTLSConfig config.TLSConfig
errorMessage string
}{
{
configTLSConfig: config.TLSConfig{
CAFile: MissingCA,
CertFile: "",
KeyFile: "",
ServerName: "",
InsecureSkipVerify: false},
errorMessage: fmt.Sprintf("unable to use specified CA cert %s:", MissingCA),
}, {
configTLSConfig: config.TLSConfig{
CAFile: "",
CertFile: MissingCert,
KeyFile: BarneyKeyNoPassPath,
ServerName: "",
InsecureSkipVerify: false},
errorMessage: fmt.Sprintf("unable to use specified client cert (%s) & key (%s):", MissingCert, BarneyKeyNoPassPath),
}, {
configTLSConfig: config.TLSConfig{
CAFile: "",
CertFile: BarneyCertificatePath,
KeyFile: MissingKey,
ServerName: "",
InsecureSkipVerify: false},
errorMessage: fmt.Sprintf("unable to use specified client cert (%s) & key (%s):", BarneyCertificatePath, MissingKey),
},
}
for _, anInvalididTLSConfig := range invalidTLSConfig {
tlsConfig, err := NewTLSConfig(anInvalididTLSConfig.configTLSConfig)
if tlsConfig != nil && err == nil {
t.Errorf("The TLS Config could be created even with this %+v", anInvalididTLSConfig.configTLSConfig)
continue
}
if !strings.Contains(err.Error(), anInvalididTLSConfig.errorMessage) {
t.Errorf("The expected error should contain %s, but got %s", anInvalididTLSConfig.errorMessage, err)
}
}
}
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAxmYjfBZhZbAup9uSULehoqPCv/U+77ETxUNyS2nviWEHDAb/
pFS8Btx4oCQ1ECVSyxcUmXSlrvDjMY4sisOHvndNRlGi274M5a8Q5yD1BUqvxq3u
XB/+SYNVShBzaswrSjpzMe89AlOPxPjnE14OXh00j2hHunOG4jhlWgJnY0YyvUQQ
YWO6KrmKMiZ4MgmY0SWh/ZhlkDJPtkp3aUVM2sheCru/70E9viLGfdlhc2pIMshy
wNp4/5IkHBZwbqXFFGX4sRtSXI/auZNvcHOBse+3e3BonWvBWS2lIYbzpX3vLB7B
E9BGIxWn1fgNQr14yFPaccSszBvgtmEUONolnwIDAQABAoIBAQC7nBhQHgXKGBl2
Z97rb0pstrjRtsLl/Cg68LWi9LEr0tHMIM4bgnkvb8qtfK+k7fZl0BSNrE2EqYvd
75jVO2MgzEYJieccLpKZm7u7JGIut9qSYSU2fpaCw6uiVv4dbqY9EhqejKG/km8w
j0JMATRK8Qkj1zOE7/wL7dKBlCZaK3u+OT17spuA/21PG/cLiPaSGSA3CU/eqbkU
BD6JeBxp33XNTytwWoOvarsigpL0dGqQ7+qhGq6t69qFfWoe9rimV7Ya+tB9zF/U
HzOIEspOYvzxe+C7VJjlVFr4haMYmsrO9qRUJ2ofp49OLVdfEANsdVISSvS63BEp
gBZN8Ko5AoGBAO1z8y8YCsI+2vBG6nxZ1eMba0KHi3bS8db1TaenJBV22w6WQATh
hEaU6VLMFcMvrOUjXN/7HJfnEMyvFT6gb9obPDVEMZw88s9lVN6njgGLZR/jodyN
7N7utLopN043Ra0WfEILAXPSz8esT1yn05OZV6AFHxJEWMrX3/4+spCLAoGBANXl
RomieVY4u3FF/uzhbzKNNb9ETxrQuexfbangKp5eLniwnr2SQWIbyPzeurwp15J8
HvxB2vpNvs1khSwNx9dQfMdiUVPGLWj7MimAHTHsnQ9LVV9W28ghuSWbjQDGTUt1
WCCu1MkKIOzupbi+zgsNlI33yilRQKAb9SRxdy29AoGBAOKpvyZiPcrkMxwPpb/k
BU7QGpgcSR25CQ+Xg3QZEVHH7h1DgYLnPtwdQ4g8tj1mohTsp7hKvSWndRrdulrY
zUyWmOeD3BN2/pTI9rW/nceNp49EPHsLo2O+2xelRlzMWB98ikqEtPM59gt1SSB6
N3X6d3GR0fIe+d9PKEtK0Cs3AoGAZ9r8ReXSvm+ra5ON9Nx8znHMEAON2TpRnBi1
uY7zgpO+QrGXUfqKrqVJEKbgym4SkribnuYm+fP32eid1McYKk6VV4ZAcMm/0MJv
F8Fx64S0ufFdEX6uFl1xdXYyn5apfyMJ2EyrWrYFSKWTZ8GVb753S/tteGRQWa1Z
eQly0Y0CgYEAnI6G9KFvXI+MLu5y2LPYAwsesDFzaWwyDl96ioQTA9hNSrjR33Vw
xwpiEe0T/WKF8NQ0QWnrQDbTvuCvZUK37TVxscYWuItL6vnBrYqr4Ck0j1BcGwV5
jT581A/Vw8JJiR/vfcxgmrFYqoUmkMKDmCN1oImfz09GtQ4jQ1rlxz8=
-----END RSA PRIVATE KEY-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 2 (0x2)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=NO, O=Green AS, OU=Green Certificate Authority, CN=Green TLS CA
Validity
Not Before: Jul 13 04:02:47 2017 GMT
Not After : Jul 13 04:02:47 2019 GMT
Subject: C=NO, O=Telenor AS, OU=Support, CN=Barney Rubble
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:c6:66:23:7c:16:61:65:b0:2e:a7:db:92:50:b7:
a1:a2:a3:c2:bf:f5:3e:ef:b1:13:c5:43:72:4b:69:
ef:89:61:07:0c:06:ff:a4:54:bc:06:dc:78:a0:24:
35:10:25:52:cb:17:14:99:74:a5:ae:f0:e3:31:8e:
2c:8a:c3:87:be:77:4d:46:51:a2:db:be:0c:e5:af:
10:e7:20:f5:05:4a:af:c6:ad:ee:5c:1f:fe:49:83:
55:4a:10:73:6a:cc:2b:4a:3a:73:31:ef:3d:02:53:
8f:c4:f8:e7:13:5e:0e:5e:1d:34:8f:68:47:ba:73:
86:e2:38:65:5a:02:67:63:46:32:bd:44:10:61:63:
ba:2a:b9:8a:32:26:78:32:09:98:d1:25:a1:fd:98:
65:90:32:4f:b6:4a:77:69:45:4c:da:c8:5e:0a:bb:
bf:ef:41:3d:be:22:c6:7d:d9:61:73:6a:48:32:c8:
72:c0:da:78:ff:92:24:1c:16:70:6e:a5:c5:14:65:
f8:b1:1b:52:5c:8f:da:b9:93:6f:70:73:81:b1:ef:
b7:7b:70:68:9d:6b:c1:59:2d:a5:21:86:f3:a5:7d:
ef:2c:1e:c1:13:d0:46:23:15:a7:d5:f8:0d:42:bd:
78:c8:53:da:71:c4:ac:cc:1b:e0:b6:61:14:38:da:
25:9f
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature
X509v3 Basic Constraints:
CA:FALSE
X509v3 Extended Key Usage:
TLS Web Client Authentication
X509v3 Subject Key Identifier:
F4:17:02:DD:1B:01:AB:C5:BC:17:A4:5C:4B:75:8E:EC:B1:E0:C8:F1
X509v3 Authority Key Identifier:
keyid:AE:42:88:75:DD:05:A6:8E:48:7F:50:69:F9:B7:34:23:49:B8:B4:71
Authority Information Access:
CA Issuers - URI:http://green.no/ca/tls-ca.cer
X509v3 CRL Distribution Points:
Full Name:
URI:http://green.no/ca/tls-ca.crl
X509v3 Subject Alternative Name:
email:barney@telenor.no
Signature Algorithm: sha1WithRSAEncryption
96:9a:c5:41:8a:2f:4a:c4:80:d9:2b:1a:cf:07:85:e9:b6:18:
01:20:41:b9:c3:d4:ca:d3:2d:66:c3:1d:52:7f:25:d7:92:0c:
e9:a9:ae:e6:2e:fa:9d:0a:cf:84:b9:03:f2:63:e3:d3:c9:70:
6a:ac:04:5e:a9:2d:a2:43:7a:34:60:f7:a9:32:e1:48:ec:c6:
03:ac:b3:06:2e:48:6e:d0:35:11:31:3d:0c:04:66:41:e6:b2:
ec:8c:68:f8:e4:bc:47:85:39:60:69:a9:8a:ee:2f:56:88:8a:
19:45:d0:84:8e:c2:27:2c:82:9c:07:6c:34:ae:41:61:63:f9:
32:cb:8b:33:ea:2c:15:5f:f9:35:b0:3c:51:4d:5f:30:de:0b:
88:28:94:79:f3:bd:69:37:ad:12:20:e1:6b:1d:b6:77:d9:83:
db:81:a4:53:6c:0f:6a:17:5e:2b:c1:94:c6:42:e3:73:cd:9e:
79:1b:8c:89:cd:da:ce:b0:f4:21:c5:32:25:04:6e:68:9f:a7:
ca:f4:c5:86:e5:4e:d9:fd:69:73:e6:15:50:6e:76:0f:73:5e:
7a:a3:f4:dc:15:4a:ab:bb:3c:9a:fa:9f:01:7a:5c:47:a9:a3:
68:1c:49:e0:37:37:77:af:87:07:16:e4:e1:d7:98:39:15:a6:
51:5d:4c:db
-----BEGIN CERTIFICATE-----
MIIEITCCAwmgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBdMQswCQYDVQQGEwJOTzER
MA8GA1UECgwIR3JlZW4gQVMxJDAiBgNVBAsMG0dyZWVuIENlcnRpZmljYXRlIEF1
dGhvcml0eTEVMBMGA1UEAwwMR3JlZW4gVExTIENBMB4XDTE3MDcxMzA0MDI0N1oX
DTE5MDcxMzA0MDI0N1owTDELMAkGA1UEBhMCTk8xEzARBgNVBAoMClRlbGVub3Ig
QVMxEDAOBgNVBAsMB1N1cHBvcnQxFjAUBgNVBAMMDUJhcm5leSBSdWJibGUwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGZiN8FmFlsC6n25JQt6Gio8K/
9T7vsRPFQ3JLae+JYQcMBv+kVLwG3HigJDUQJVLLFxSZdKWu8OMxjiyKw4e+d01G
UaLbvgzlrxDnIPUFSq/Gre5cH/5Jg1VKEHNqzCtKOnMx7z0CU4/E+OcTXg5eHTSP
aEe6c4biOGVaAmdjRjK9RBBhY7oquYoyJngyCZjRJaH9mGWQMk+2SndpRUzayF4K
u7/vQT2+IsZ92WFzakgyyHLA2nj/kiQcFnBupcUUZfixG1Jcj9q5k29wc4Gx77d7
cGida8FZLaUhhvOlfe8sHsET0EYjFafV+A1CvXjIU9pxxKzMG+C2YRQ42iWfAgMB
AAGjgfwwgfkwDgYDVR0PAQH/BAQDAgeAMAkGA1UdEwQCMAAwEwYDVR0lBAwwCgYI
KwYBBQUHAwIwHQYDVR0OBBYEFPQXAt0bAavFvBekXEt1juyx4MjxMB8GA1UdIwQY
MBaAFK5CiHXdBaaOSH9Qafm3NCNJuLRxMDkGCCsGAQUFBwEBBC0wKzApBggrBgEF
BQcwAoYdaHR0cDovL2dyZWVuLm5vL2NhL3Rscy1jYS5jZXIwLgYDVR0fBCcwJTAj
oCGgH4YdaHR0cDovL2dyZWVuLm5vL2NhL3Rscy1jYS5jcmwwHAYDVR0RBBUwE4ER
YmFybmV5QHRlbGVub3Iubm8wDQYJKoZIhvcNAQEFBQADggEBAJaaxUGKL0rEgNkr
Gs8Hhem2GAEgQbnD1MrTLWbDHVJ/JdeSDOmpruYu+p0Kz4S5A/Jj49PJcGqsBF6p
LaJDejRg96ky4UjsxgOsswYuSG7QNRExPQwEZkHmsuyMaPjkvEeFOWBpqYruL1aI
ihlF0ISOwicsgpwHbDSuQWFj+TLLizPqLBVf+TWwPFFNXzDeC4golHnzvWk3rRIg
4WsdtnfZg9uBpFNsD2oXXivBlMZC43PNnnkbjInN2s6w9CHFMiUEbmifp8r0xYbl
Ttn9aXPmFVBudg9zXnqj9NwVSqu7PJr6nwF6XEepo2gcSeA3N3evhwcW5OHXmDkV
plFdTNs=
-----END CERTIFICATE-----
theanswertothegreatquestionoflifetheuniverseandeverythingisfortytwo
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4 (0x4)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=NO, O=Green AS, OU=Green Certificate Authority, CN=Green TLS CA
Validity
Not Before: Jul 26 12:47:08 2017 GMT
Not After : Jul 26 12:47:08 2019 GMT
Subject: C=NO, O=Green AS, OU=Green Certificate Authority, CN=Green TLS CA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:97:43:c5:f6:24:b8:ce:30:12:70:ea:17:9c:c0:
ce:f2:ef:58:8b:12:7d:46:5e:01:f1:1a:93:b2:3e:
d8:cf:99:bc:10:32:f1:12:b0:ef:00:6c:d6:c4:45:
85:a8:33:7b:cd:ec:8f:4a:92:d0:5a:4a:41:69:7f:
e3:dd:7e:71:d2:21:9c:df:43:b5:6c:60:bb:2a:12:
a8:08:cf:c5:ee:08:7d:48:ea:4b:54:e4:82:d9:88:
b0:b8:5e:02:12:cb:0e:09:99:b7:5f:42:b6:d7:26:
34:0f:4a:e7:fc:ac:9c:59:cd:a1:50:4c:88:5f:f1:
d2:7e:5b:21:41:f0:37:50:80:48:71:50:26:61:26:
79:64:4b:7e:91:8d:0e:f4:27:fe:19:80:bf:39:55:
b7:f3:d0:cd:61:6c:d8:c1:c7:d3:26:77:92:1a:14:
42:56:cb:bc:fd:1a:4a:eb:17:d8:8d:af:d1:c0:46:
9f:f0:40:5e:0e:34:2f:e7:db:be:66:fd:89:0b:6b:
8c:71:c1:0b:0a:c5:c4:c4:eb:7f:44:c1:75:36:23:
fd:ed:b6:ee:87:d9:88:47:e1:4b:7c:60:53:e7:85:
1c:2f:82:4b:2b:5e:63:1a:49:17:36:2c:fc:39:23:
49:22:4d:43:b5:51:22:12:24:9e:31:44:d8:16:4e:
a8:eb
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Basic Constraints:
CA:FALSE
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Subject Key Identifier:
70:A9:FB:44:66:3C:63:96:E6:05:B2:74:47:C8:18:7E:43:6D:EE:8B
X509v3 Authority Key Identifier:
keyid:AE:42:88:75:DD:05:A6:8E:48:7F:50:69:F9:B7:34:23:49:B8:B4:71
Authority Information Access:
CA Issuers - URI:http://green.no/ca/tls-ca.cer
X509v3 CRL Distribution Points:
Full Name:
URI:http://green.no/ca/tls-ca.crl
X509v3 Subject Alternative Name:
IP Address:127.0.0.1, IP Address:127.0.0.0, DNS:localhost
Signature Algorithm: sha1WithRSAEncryption
56:1e:b8:52:ba:f5:72:42:ad:15:71:c1:5e:00:63:c9:4d:56:
f2:8d:a3:a9:91:db:d0:b5:1b:88:80:93:80:28:48:b2:d0:a9:
d0:ea:de:40:78:cc:57:8c:00:b8:65:99:68:95:98:9b:fb:a2:
43:21:ea:00:37:01:77:c7:3b:1a:ec:58:2d:25:9c:ad:23:41:
5e:ae:fd:ac:2f:26:81:b8:a7:49:9b:5a:10:fe:ad:c3:86:ab:
59:67:b0:c7:81:72:95:60:b5:cb:fc:9f:ad:27:16:50:85:76:
33:16:20:2c:1f:c6:14:09:0c:48:9f:c0:19:16:c9:fa:b0:d8:
bf:b7:8d:a7:aa:eb:fe:f8:6f:dd:2b:83:ee:c7:8a:df:c8:59:
e6:2e:13:1f:57:cc:6f:31:db:f7:b7:5c:3f:78:ad:22:2c:48:
bb:6d:c4:ab:dc:c1:76:34:29:d9:1e:67:e0:ac:37:2b:90:f9:
71:bd:cf:a1:01:b9:eb:0b:0b:79:2e:8b:52:3d:8e:13:97:c8:
05:a3:ef:68:82:49:12:2a:25:1a:48:49:b8:7c:3c:66:0d:74:
f9:00:8c:5b:57:d7:76:b1:26:95:86:b2:2e:a3:b2:9c:e0:eb:
2d:fc:77:03:8f:cd:56:46:3a:c9:6a:fa:72:e3:19:d8:ef:de:
4b:36:95:79
-----BEGIN CERTIFICATE-----
MIIEQjCCAyqgAwIBAgIBBDANBgkqhkiG9w0BAQUFADBdMQswCQYDVQQGEwJOTzER
MA8GA1UECgwIR3JlZW4gQVMxJDAiBgNVBAsMG0dyZWVuIENlcnRpZmljYXRlIEF1
dGhvcml0eTEVMBMGA1UEAwwMR3JlZW4gVExTIENBMB4XDTE3MDcyNjEyNDcwOFoX
DTE5MDcyNjEyNDcwOFowXTELMAkGA1UEBhMCTk8xETAPBgNVBAoMCEdyZWVuIEFT
MSQwIgYDVQQLDBtHcmVlbiBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFTATBgNVBAMM
DEdyZWVuIFRMUyBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJdD
xfYkuM4wEnDqF5zAzvLvWIsSfUZeAfEak7I+2M+ZvBAy8RKw7wBs1sRFhagze83s
j0qS0FpKQWl/491+cdIhnN9DtWxguyoSqAjPxe4IfUjqS1TkgtmIsLheAhLLDgmZ
t19CttcmNA9K5/ysnFnNoVBMiF/x0n5bIUHwN1CASHFQJmEmeWRLfpGNDvQn/hmA
vzlVt/PQzWFs2MHH0yZ3khoUQlbLvP0aSusX2I2v0cBGn/BAXg40L+fbvmb9iQtr
jHHBCwrFxMTrf0TBdTYj/e227ofZiEfhS3xgU+eFHC+CSyteYxpJFzYs/DkjSSJN
Q7VRIhIknjFE2BZOqOsCAwEAAaOCAQswggEHMA4GA1UdDwEB/wQEAwIFoDAJBgNV
HRMEAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU
cKn7RGY8Y5bmBbJ0R8gYfkNt7oswHwYDVR0jBBgwFoAUrkKIdd0Fpo5If1Bp+bc0
I0m4tHEwOQYIKwYBBQUHAQEELTArMCkGCCsGAQUFBzAChh1odHRwOi8vZ3JlZW4u
bm8vY2EvdGxzLWNhLmNlcjAuBgNVHR8EJzAlMCOgIaAfhh1odHRwOi8vZ3JlZW4u
bm8vY2EvdGxzLWNhLmNybDAgBgNVHREEGTAXhwR/AAABhwR/AAAAgglsb2NhbGhv
c3QwDQYJKoZIhvcNAQEFBQADggEBAFYeuFK69XJCrRVxwV4AY8lNVvKNo6mR29C1
G4iAk4AoSLLQqdDq3kB4zFeMALhlmWiVmJv7okMh6gA3AXfHOxrsWC0lnK0jQV6u
/awvJoG4p0mbWhD+rcOGq1lnsMeBcpVgtcv8n60nFlCFdjMWICwfxhQJDEifwBkW
yfqw2L+3jaeq6/74b90rg+7Hit/IWeYuEx9XzG8x2/e3XD94rSIsSLttxKvcwXY0
KdkeZ+CsNyuQ+XG9z6EBuesLC3kui1I9jhOXyAWj72iCSRIqJRpISbh8PGYNdPkA
jFtX13axJpWGsi6jspzg6y38dwOPzVZGOslq+nLjGdjv3ks2lXk=
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXQ8X2JLjOMBJw
6hecwM7y71iLEn1GXgHxGpOyPtjPmbwQMvESsO8AbNbERYWoM3vN7I9KktBaSkFp
f+PdfnHSIZzfQ7VsYLsqEqgIz8XuCH1I6ktU5ILZiLC4XgISyw4JmbdfQrbXJjQP
Suf8rJxZzaFQTIhf8dJ+WyFB8DdQgEhxUCZhJnlkS36RjQ70J/4ZgL85Vbfz0M1h
bNjBx9Mmd5IaFEJWy7z9GkrrF9iNr9HARp/wQF4ONC/n275m/YkLa4xxwQsKxcTE
639EwXU2I/3ttu6H2YhH4Ut8YFPnhRwvgksrXmMaSRc2LPw5I0kiTUO1USISJJ4x
RNgWTqjrAgMBAAECggEAVurwo4FyV7gzwIIi00XPJLT3ceJL7dUy1HHrEG8gchnq
gHxlHdJhYyMnPVydcosyxp75r2YxJtCoSZDdRHbVvGLoGzpy0zW6FnDl8TpCh4aF
RxKp+rvbnFf5A9ew5U+cX1PelHRnT7V6EJeAOiaNKOUJnnR7oHX59/UxZQw9HJnX
3H4xUdRDmSS3BGKXEswbd7beQjqJtEIkbConfaw32yEod0w2MC0LI4miZ87/6Hsk
pyvfpeYxXp4z3BTvFBbf/GEBFuozu63VWHayB9PDmEN/TlphoQpJQihdR2r1lz/H
I5QwVlFTDvUSFitNLu+FoaHOfgLprQndbojBXb+tcQKBgQDHCPyM4V7k97RvJgmB
ELgZiDYufDrjRLXvFzrrZ7ySU3N+nx3Gz/EhtgbHicDjnRVagHBIwi/QAfBJksCd
xcioY5k2OW+8PSTsfFZTAA6XwJp/LGfJik/JjvAVv5CnxBu9lYG4WiSBJFp59ojC
zTmfEuB4GPwrjQvzjlqaSpij9QKBgQDCjriwAB2UJIdlgK+DkryLqgim5I4cteB3
+juVKz+S8ufFmVvmIXkyDcpyy/26VLC6esy8dV0JoWc4EeitoJvQD1JVZ5+CBTY+
r9umx18oe2A/ZgcEf/A3Zd94jM1MwriF6YC+eIOhwhpi7T1xTLf3hc9B0OJ5B1mA
vob9rGDtXwKBgD4rkW+UCictNIAvenKFPWxEPuBgT6ij0sx/DhlwCtgOFxprK0rp
syFbkVyMq+KtM3lUez5O4c5wfJUOsPnXSOlISxhD8qHy23C/GdvNPcGrGNc2kKjE
ek20R0wTzWSJ/jxG0gE6rwJjz5sfJfLrVd9ZbyI0c7hK03vdcHGXcXxtAoGAeGHl
BwnbQ3niyTx53VijD2wTVGjhQgSLstEDowYSnTNtk8eTpG6b1gvQc32jLnMOsyQe
oJGiEr5q5re2GBDjuDZyxGOMv9/Hs7wOlkCQsbS9Vh0kRHWBRlXjk2zT7yYhFMLp
pXFeSW2X9BRFS2CkCCUkm93K9AZHLDE3x6ishNMCgYEAsDsUCzGhI49Aqe+CMP2l
WPZl7SEMYS5AtdC5sLtbLYBl8+rMXVGL2opKXqVFYBYkqMJiHGdX3Ub6XSVKLYkN
vm4PWmlQS24ZT+jlUl4jk6JU6SAlM/o6ixZl5KNR7yQm6zN2O/RHDeYm0urUQ9tF
9dux7LbIFeOoJmoDTWG2+fI=
-----END PRIVATE KEY-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 2 (0x2)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=NO, O=Green AS, OU=Green Certificate Authority, CN=Green Root CA
Validity
Not Before: Jul 13 03:47:20 2017 GMT
Not After : Jul 13 03:47:20 2027 GMT
Subject: C=NO, O=Green AS, OU=Green Certificate Authority, CN=Green TLS CA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:b5:5a:b3:7a:7f:6a:5b:e9:ee:62:ee:4f:61:42:
79:93:06:bf:81:fc:9a:1f:b5:80:83:7c:b3:a6:94:
54:58:8a:b1:74:cb:c3:b8:3c:23:a8:69:1f:ca:2b:
af:be:97:ba:31:73:b5:b8:ce:d9:bf:bf:9a:7a:cf:
3a:64:51:83:c9:36:d2:f7:3b:3a:0e:4c:c7:66:2e:
bf:1a:df:ce:10:aa:3d:0f:19:74:03:7e:b5:10:bb:
e8:37:bd:62:f0:42:2d:df:3d:ca:70:50:10:17:ce:
a9:ec:55:8e:87:6f:ce:9a:04:36:14:96:cb:d1:a5:
48:d5:d2:87:02:62:93:4e:21:4a:ff:be:44:f1:d2:
7e:ed:74:da:c2:51:26:8e:03:a0:c2:bd:bd:5f:b0:
50:11:78:fd:ab:1d:04:86:6c:c1:8d:20:bd:05:5f:
51:67:c6:d3:07:95:92:2d:92:90:00:c6:9f:2d:dd:
36:5c:dc:78:10:7c:f6:68:39:1d:2c:e0:e1:26:64:
4f:36:34:66:a7:84:6a:90:15:3a:94:b7:79:b1:47:
f5:d2:51:95:54:bf:92:76:9a:b9:88:ee:63:f9:6c:
0d:38:c6:b6:1c:06:43:ed:24:1d:bb:6c:72:48:cc:
8c:f4:35:bc:43:fe:a6:96:4c:31:5f:82:0d:0d:20:
2a:3d
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
X509v3 Basic Constraints: critical
CA:TRUE, pathlen:0
X509v3 Subject Key Identifier:
AE:42:88:75:DD:05:A6:8E:48:7F:50:69:F9:B7:34:23:49:B8:B4:71
X509v3 Authority Key Identifier:
keyid:60:93:53:2F:C7:CF:2A:D7:F3:09:28:F6:3C:AE:9C:50:EC:93:63:E5
Authority Information Access:
CA Issuers - URI:http://green.no/ca/root-ca.cer
X509v3 CRL Distribution Points:
Full Name:
URI:http://green.no/ca/root-ca.crl
Signature Algorithm: sha1WithRSAEncryption
15:a7:ac:d7:25:9e:2a:d4:d1:14:b4:99:38:3d:2f:73:61:2a:
d9:b6:8b:13:ea:fe:db:78:d9:0a:6c:df:26:6e:c1:d5:4a:97:
42:19:dd:97:05:03:e4:2b:fc:1e:1f:38:3c:4e:b0:3b:8c:38:
ad:2b:65:fa:35:2d:81:8e:e0:f6:0a:89:4c:38:97:01:4b:9c:
ac:4e:e1:55:17:ef:0a:ad:a7:eb:1e:4b:86:23:12:f1:52:69:
cb:a3:8a:ce:fb:14:8b:86:d7:bb:81:5e:bd:2a:c7:a7:79:58:
00:10:c0:db:ff:d4:a5:b9:19:74:b3:23:19:4a:1f:78:4b:a8:
b6:f6:20:26:c1:69:f9:89:7f:b8:1c:3b:a2:f9:37:31:80:2c:
b0:b6:2b:d2:84:44:d7:42:e4:e6:44:51:04:35:d9:1c:a4:48:
c6:b7:35:de:f2:ae:da:4b:ba:c8:09:42:8d:ed:7a:81:dc:ed:
9d:f0:de:6e:21:b9:01:1c:ad:64:3d:25:4c:91:94:f1:13:18:
bb:89:e9:48:ac:05:73:07:c8:db:bd:69:8e:6f:02:9d:b0:18:
c0:b9:e1:a8:b1:17:50:3d:ac:05:6e:6f:63:4f:b1:73:33:60:
9a:77:d2:81:8a:01:38:43:e9:4c:3c:90:63:a4:99:4b:d2:1b:
f9:1b:ec:ee
-----BEGIN CERTIFICATE-----
MIIECzCCAvOgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJOTzER
MA8GA1UECgwIR3JlZW4gQVMxJDAiBgNVBAsMG0dyZWVuIENlcnRpZmljYXRlIEF1
dGhvcml0eTEWMBQGA1UEAwwNR3JlZW4gUm9vdCBDQTAeFw0xNzA3MTMwMzQ3MjBa
Fw0yNzA3MTMwMzQ3MjBaMF0xCzAJBgNVBAYTAk5PMREwDwYDVQQKDAhHcmVlbiBB
UzEkMCIGA1UECwwbR3JlZW4gQ2VydGlmaWNhdGUgQXV0aG9yaXR5MRUwEwYDVQQD
DAxHcmVlbiBUTFMgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1
WrN6f2pb6e5i7k9hQnmTBr+B/JoftYCDfLOmlFRYirF0y8O4PCOoaR/KK6++l7ox
c7W4ztm/v5p6zzpkUYPJNtL3OzoOTMdmLr8a384Qqj0PGXQDfrUQu+g3vWLwQi3f
PcpwUBAXzqnsVY6Hb86aBDYUlsvRpUjV0ocCYpNOIUr/vkTx0n7tdNrCUSaOA6DC
vb1fsFAReP2rHQSGbMGNIL0FX1FnxtMHlZItkpAAxp8t3TZc3HgQfPZoOR0s4OEm
ZE82NGanhGqQFTqUt3mxR/XSUZVUv5J2mrmI7mP5bA04xrYcBkPtJB27bHJIzIz0
NbxD/qaWTDFfgg0NICo9AgMBAAGjgdQwgdEwDgYDVR0PAQH/BAQDAgEGMBIGA1Ud
EwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFK5CiHXdBaaOSH9Qafm3NCNJuLRxMB8G
A1UdIwQYMBaAFGCTUy/HzyrX8wko9jyunFDsk2PlMDoGCCsGAQUFBwEBBC4wLDAq
BggrBgEFBQcwAoYeaHR0cDovL2dyZWVuLm5vL2NhL3Jvb3QtY2EuY2VyMC8GA1Ud
HwQoMCYwJKAioCCGHmh0dHA6Ly9ncmVlbi5uby9jYS9yb290LWNhLmNybDANBgkq
hkiG9w0BAQUFAAOCAQEAFaes1yWeKtTRFLSZOD0vc2Eq2baLE+r+23jZCmzfJm7B
1UqXQhndlwUD5Cv8Hh84PE6wO4w4rStl+jUtgY7g9gqJTDiXAUucrE7hVRfvCq2n
6x5LhiMS8VJpy6OKzvsUi4bXu4FevSrHp3lYABDA2//UpbkZdLMjGUofeEuotvYg
JsFp+Yl/uBw7ovk3MYAssLYr0oRE10Lk5kRRBDXZHKRIxrc13vKu2ku6yAlCje16
gdztnfDebiG5ARytZD0lTJGU8RMYu4npSKwFcwfI271pjm8CnbAYwLnhqLEXUD2s
BW5vY0+xczNgmnfSgYoBOEPpTDyQY6SZS9Ib+Rvs7g==
-----END CERTIFICATE-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=NO, O=Green AS, OU=Green Certificate Authority, CN=Green Root CA
Validity
Not Before: Jul 13 03:44:39 2017 GMT
Not After : Dec 31 23:59:59 2030 GMT
Subject: C=NO, O=Green AS, OU=Green Certificate Authority, CN=Green Root CA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:a7:e8:ed:de:d4:54:08:41:07:40:d5:c0:43:d6:
ab:d3:9e:21:87:c6:13:bf:a7:cf:3d:08:4f:c1:fe:
8f:e5:6c:c5:89:97:e5:27:75:26:c3:2a:73:2d:34:
7c:6f:35:8d:40:66:61:05:c0:eb:e9:b3:38:47:f8:
8b:26:35:2c:df:dc:24:31:fe:72:e3:87:10:d1:f7:
a0:57:b7:f3:b1:1a:fe:c7:4b:f8:7b:14:6d:73:08:
54:eb:63:3c:0c:ce:22:95:5f:3f:f2:6f:89:ae:63:
da:80:74:36:21:13:e8:91:01:58:77:cc:c2:f2:42:
bf:eb:b3:60:a7:21:ed:88:24:7f:eb:ff:07:41:9b:
93:c8:5f:6a:8e:a6:1a:15:3c:bc:e7:0d:fd:05:fd:
3c:c1:1c:1d:1f:57:2b:40:27:62:a1:7c:48:63:c1:
45:e7:2f:20:ed:92:1c:42:94:e4:58:70:7a:b6:d2:
85:c5:61:d8:cd:c6:37:6b:72:3b:7f:af:55:81:d6:
9d:dc:10:c9:d8:0e:81:e4:5e:40:13:2f:20:e8:6b:
46:81:ce:88:47:dd:38:71:3d:ef:21:cc:c0:67:cf:
0a:f4:e9:3f:a8:9d:26:25:2e:23:1e:a3:11:18:cb:
d1:70:1c:9e:7d:09:b1:a4:20:dc:95:15:1d:49:cf:
1b:ad
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Subject Key Identifier:
60:93:53:2F:C7:CF:2A:D7:F3:09:28:F6:3C:AE:9C:50:EC:93:63:E5
X509v3 Authority Key Identifier:
keyid:60:93:53:2F:C7:CF:2A:D7:F3:09:28:F6:3C:AE:9C:50:EC:93:63:E5
Signature Algorithm: sha1WithRSAEncryption
a7:77:71:8b:1a:e5:5a:5b:87:54:08:bf:07:3e:cb:99:2f:dc:
0e:8d:63:94:95:83:19:c9:92:82:d5:cb:5b:8f:1f:86:55:bc:
70:01:1d:33:46:ec:99:de:6b:1f:c3:c2:7a:dd:ef:69:ab:96:
58:ec:6c:6f:6c:70:82:71:8a:7f:f0:3b:80:90:d5:64:fa:80:
27:b8:7b:50:69:98:4b:37:99:ad:bf:a2:5b:93:22:5e:96:44:
3c:5a:cf:0c:f4:62:63:4a:6f:72:a7:f6:89:1d:09:26:3d:8f:
a8:86:d4:b4:bc:dd:b3:38:ca:c0:59:16:8c:20:1f:89:35:12:
b4:2d:c0:e9:de:93:e0:39:76:32:fc:80:db:da:44:26:fd:01:
32:74:97:f8:44:ae:fe:05:b1:34:96:13:34:56:73:b4:93:a5:
55:56:d1:01:51:9d:9c:55:e7:38:53:28:12:4e:38:72:0c:8f:
bd:91:4c:45:48:3b:e1:0d:03:5f:58:40:c9:d3:a0:ac:b3:89:
ce:af:27:8a:0f:ab:ec:72:4d:40:77:30:6b:36:fd:32:46:9f:
ee:f9:c4:f5:17:06:0f:4b:d3:88:f5:a4:2f:3d:87:9e:f5:26:
74:f0:c9:dc:cb:ad:d9:a7:8a:d3:71:15:00:d3:5d:9f:4c:59:
3e:24:63:f5
-----BEGIN CERTIFICATE-----
MIIDnDCCAoSgAwIBAgIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJOTzER
MA8GA1UECgwIR3JlZW4gQVMxJDAiBgNVBAsMG0dyZWVuIENlcnRpZmljYXRlIEF1
dGhvcml0eTEWMBQGA1UEAwwNR3JlZW4gUm9vdCBDQTAgFw0xNzA3MTMwMzQ0Mzla
GA8yMDMwMTIzMTIzNTk1OVowXjELMAkGA1UEBhMCTk8xETAPBgNVBAoMCEdyZWVu
IEFTMSQwIgYDVQQLDBtHcmVlbiBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFjAUBgNV
BAMMDUdyZWVuIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQCn6O3e1FQIQQdA1cBD1qvTniGHxhO/p889CE/B/o/lbMWJl+UndSbDKnMtNHxv
NY1AZmEFwOvpszhH+IsmNSzf3CQx/nLjhxDR96BXt/OxGv7HS/h7FG1zCFTrYzwM
ziKVXz/yb4muY9qAdDYhE+iRAVh3zMLyQr/rs2CnIe2IJH/r/wdBm5PIX2qOphoV
PLznDf0F/TzBHB0fVytAJ2KhfEhjwUXnLyDtkhxClORYcHq20oXFYdjNxjdrcjt/
r1WB1p3cEMnYDoHkXkATLyDoa0aBzohH3ThxPe8hzMBnzwr06T+onSYlLiMeoxEY
y9FwHJ59CbGkINyVFR1JzxutAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRgk1Mvx88q1/MJKPY8rpxQ7JNj5TAfBgNV
HSMEGDAWgBRgk1Mvx88q1/MJKPY8rpxQ7JNj5TANBgkqhkiG9w0BAQUFAAOCAQEA
p3dxixrlWluHVAi/Bz7LmS/cDo1jlJWDGcmSgtXLW48fhlW8cAEdM0bsmd5rH8PC
et3vaauWWOxsb2xwgnGKf/A7gJDVZPqAJ7h7UGmYSzeZrb+iW5MiXpZEPFrPDPRi
Y0pvcqf2iR0JJj2PqIbUtLzdszjKwFkWjCAfiTUStC3A6d6T4Dl2MvyA29pEJv0B
MnSX+ESu/gWxNJYTNFZztJOlVVbRAVGdnFXnOFMoEk44cgyPvZFMRUg74Q0DX1hA
ydOgrLOJzq8nig+r7HJNQHcwazb9Mkaf7vnE9RcGD0vTiPWkLz2HnvUmdPDJ3Mut
2aeK03EVANNdn0xZPiRj9Q==
-----END CERTIFICATE-----
// Copyright 2017 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package testutil
import (
"net/http"
)
type roundTrip struct {
theResponse *http.Response
theError error
}
func (rt *roundTrip) RoundTrip(r *http.Request) (*http.Response, error) {
return rt.theResponse, rt.theError
}
type roundTripCheckRequest struct {
checkRequest func(*http.Request)
roundTrip
}
func (rt *roundTripCheckRequest) RoundTrip(r *http.Request) (*http.Response, error) {
rt.checkRequest(r)
return rt.theResponse, rt.theError
}
// NewRoundTripCheckRequest creates a new instance of a type that implements http.RoundTripper,
// wich before returning theResponse and theError, executes checkRequest against a http.Request.
func NewRoundTripCheckRequest(checkRequest func(*http.Request), theResponse *http.Response, theError error) http.RoundTripper {
return &roundTripCheckRequest{
checkRequest: checkRequest,
roundTrip: roundTrip{
theResponse: theResponse,
theError: theError}}
}
...@@ -12,12 +12,14 @@ ...@@ -12,12 +12,14 @@
// web/ui/static/css/graph.css // web/ui/static/css/graph.css
// web/ui/static/css/prom_console.css // web/ui/static/css/prom_console.css
// web/ui/static/css/prometheus.css // web/ui/static/css/prometheus.css
// web/ui/static/css/targets.css
// web/ui/static/img/ajax-loader.gif // web/ui/static/img/ajax-loader.gif
// web/ui/static/img/favicon.ico // web/ui/static/img/favicon.ico
// web/ui/static/js/alerts.js // web/ui/static/js/alerts.js
// web/ui/static/js/graph.js // web/ui/static/js/graph.js
// web/ui/static/js/graph_template.handlebar // web/ui/static/js/graph_template.handlebar
// web/ui/static/js/prom_console.js // web/ui/static/js/prom_console.js
// web/ui/static/js/targets.js
// web/ui/static/vendor/bootstrap-3.3.1/css/bootstrap-theme.min.css // web/ui/static/vendor/bootstrap-3.3.1/css/bootstrap-theme.min.css
// web/ui/static/vendor/bootstrap-3.3.1/css/bootstrap.min.css // web/ui/static/vendor/bootstrap-3.3.1/css/bootstrap.min.css
// web/ui/static/vendor/bootstrap-3.3.1/fonts/glyphicons-halflings-regular.eot // web/ui/static/vendor/bootstrap-3.3.1/fonts/glyphicons-halflings-regular.eot
...@@ -141,7 +143,7 @@ func webUiTemplatesAlertsHtml() (*asset, error) { ...@@ -141,7 +143,7 @@ func webUiTemplatesAlertsHtml() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "web/ui/templates/alerts.html", size: 1836, mode: os.FileMode(420), modTime: time.Unix(1499786499, 0)} info := bindataFileInfo{name: "web/ui/templates/alerts.html", size: 1836, mode: os.FileMode(420), modTime: time.Unix(1502369604, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
...@@ -221,7 +223,7 @@ func webUiTemplatesRulesHtml() (*asset, error) { ...@@ -221,7 +223,7 @@ func webUiTemplatesRulesHtml() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "web/ui/templates/rules.html", size: 283, mode: os.FileMode(420), modTime: time.Unix(1499786499, 0)} info := bindataFileInfo{name: "web/ui/templates/rules.html", size: 283, mode: os.FileMode(420), modTime: time.Unix(1502369604, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
...@@ -246,7 +248,7 @@ func webUiTemplatesStatusHtml() (*asset, error) { ...@@ -246,7 +248,7 @@ func webUiTemplatesStatusHtml() (*asset, error) {
return a, nil return a, nil
} }
var _webUiTemplatesTargetsHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x56\x4f\x6f\xdb\x36\x14\xbf\xfb\x53\xbc\x71\xc1\x4e\x95\x05\x14\xd8\x25\xa3\x74\xd8\x56\xa0\x03\xb2\xa1\x6b\xda\xcb\x2e\x05\x25\x3e\x4b\x4c\x19\x52\x23\x9f\x8c\x06\x2c\xbf\xfb\x40\x4a\x72\x6c\xd9\x1e\xda\x15\x58\x0e\x0c\xdf\xff\x7f\xbf\x47\x39\x04\x89\x3b\x65\x10\x58\x8f\x42\xb2\x18\xf9\x77\x45\x01\x46\x7d\x82\xa2\xa8\x43\x40\x23\x63\xdc\x6c\x9e\xb5\x5a\x6b\x08\x0d\xb1\x18\x37\x00\x5c\xaa\x3d\xb4\x5a\x78\x5f\x65\x81\x50\x06\x5d\xb1\xd3\xa3\x92\xac\xde\x00\x00\xf0\xfe\x25\x28\x59\x31\x12\xae\x43\xf2\xac\x7e\x37\x5d\x78\xd9\xbf\x9c\x34\x00\x38\x89\x46\xe3\xe2\x67\x22\xf2\x59\xb4\xd6\x48\x34\x1e\xe5\x4c\x37\xd6\x49\x74\x07\xd2\x93\x53\xc3\x81\xea\xed\x1e\x1d\x5b\x9c\x02\x84\xe0\x84\xe9\x10\x6e\x1e\x6c\xf3\x02\x6e\x06\x6b\x35\xdc\x56\xb0\x9d\x32\x78\x63\xad\xf6\x90\xab\x58\xfe\x38\xa5\x16\xd4\x47\x9c\xc4\x73\x35\xa7\x1e\x5a\xab\xfd\x20\x4c\xc5\x7e\x64\x4b\xa2\x0f\xb6\xf9\x90\x0c\x52\x50\x2e\x72\x95\x0f\xb6\x29\x42\x48\x01\x63\x64\xd0\x3b\xdc\x55\xec\xfb\x13\x66\xbd\xdc\x78\x29\x6a\x5e\x52\x9f\x0e\x77\x1e\xf3\x84\x91\x53\xab\x5f\x19\x39\x58\x65\x28\x5b\x5d\x90\xdf\x93\x20\xbc\x26\xbc\x13\x0d\x6a\x7f\x5d\xea\x09\xee\x5b\x27\x86\xab\x0e\x5e\x39\x67\xdd\xb9\x70\x9d\x7d\xd2\x58\x35\x91\x53\x63\xe5\xd3\x31\xe7\x30\x99\x34\x93\x93\x11\x5c\x29\x5e\x9e\xb1\xc4\xdc\xdd\x10\xb6\xef\xdf\xde\xc1\x67\xe8\xb4\x6d\x84\x7e\xff\xf6\x6e\x6a\x72\xe2\x6e\xef\xdb\x1e\x1f\x31\xc6\xdb\xb2\x9c\x39\xaf\xad\xa7\x18\x67\xe2\x8d\xa0\x7e\x1e\x44\x73\x16\xf4\x28\x4b\x9d\x7a\xf7\x02\x6e\xf6\x42\x8f\xe8\x33\x86\x92\xf9\x9f\x23\xba\x27\x58\xa5\xbf\x32\x55\x8b\x59\xb2\x9a\x1d\x5c\xb4\x00\xe0\x09\x5f\x0b\xb6\x72\x48\xc8\x67\x31\x38\xf5\x28\xdc\x53\x86\x4e\xe6\xc4\x98\xea\x9e\xbc\xc5\xc8\x78\x99\x2c\xcf\xf3\x4f\x69\x4c\xeb\xfb\x65\x7c\x5e\x5e\xe8\xf3\x39\x6b\x95\xa9\xd0\xe8\x08\xf2\x59\x84\x00\xdb\xd7\x28\x34\xf5\xf0\x19\xfa\x7c\x79\x67\x7f\x49\x7a\x10\x23\xf8\x84\xcf\x0f\xca\x48\xd5\x0a\xb2\x0e\x08\x3f\x51\x31\x0e\x03\xba\x56\x78\x64\x97\x0b\x98\xfd\x5d\x28\xe2\x72\xd9\xff\xad\x88\x76\x74\xde\xba\x22\xaf\x17\x3a\x06\x52\x90\x28\xc8\x76\x9d\xc6\x8a\x91\xb5\x9a\xd4\xc0\x80\x14\x25\x7a\x16\xf7\xf4\xa8\x2b\x72\x23\x4e\xa4\x75\xaa\x53\x46\xe8\x62\xd6\xe2\x4d\xfd\x33\xee\xac\x43\x70\x98\xa7\xa6\x4c\x77\xcb\xcb\xa6\x3e\x60\xe3\x63\xc2\x46\x46\xd3\xaf\xca\xb7\xe9\xf1\x42\x39\xad\xe9\xf6\x77\x31\xc4\x98\x40\x19\xc2\xcd\xc7\xd4\x4b\x7a\xd4\xf3\xbf\x18\xab\x1f\xfe\x1e\x2d\xfd\x94\x10\xb0\x16\x2d\x92\x3c\xde\x2b\x1d\x9d\x30\x94\x61\x9c\xdf\xcf\x29\x24\x6c\x9f\x43\x43\x7a\xc7\xd8\xbf\x03\xfb\x64\x27\x32\xb8\x27\xb7\xff\x2b\xb8\xb5\xc7\xaf\x8d\x27\x71\x27\x46\x4d\xac\x36\xd6\xe0\xd7\x6f\xce\x37\x82\x2e\x04\xb5\x4b\x9d\xf6\x34\x3d\xb6\xdb\xdf\xfc\x5f\xe8\x6c\x8c\x7f\xe0\x1e\xdd\x52\x51\x08\x5e\x99\x16\x8f\x15\x63\x04\xd1\xd9\x6f\xdc\xdb\xe7\xe8\xf9\x31\xbf\x54\xde\xb5\xcd\x96\x69\xea\x6e\xbd\xc2\xf9\xa1\x3d\xf2\x77\xad\x9f\x5f\x9a\xf7\xfa\x63\x72\x6e\xc7\xcb\xd5\xc7\xe4\x54\x85\x97\xf9\xa7\x40\x12\xf3\x52\xaa\x7d\xbd\x59\xe4\xff\x04\x00\x00\xff\xff\xdf\x77\xb1\xd0\xe7\x08\x00\x00") var _webUiTemplatesTargetsHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x56\x4d\x6f\xe3\x36\x13\xbe\xfb\x57\x0c\xf4\x06\x2f\x5a\x60\x65\x01\x0b\xf4\x92\x52\x2a\xd0\x76\x81\x2d\x90\x16\xe9\x66\xb7\x87\x5e\x16\x94\x38\xb6\x98\x30\xa4\x4a\x8e\x8c\x35\xb8\xfc\xef\x05\x29\xc9\x76\x12\xc9\x69\xd3\x2e\x7a\x91\x4d\xce\xcc\x43\x3e\xc3\xf9\xf2\x5e\xe0\x46\x6a\x84\xac\x45\x2e\xb2\x10\x56\x4c\x49\x7d\x07\xb4\xef\xb0\xcc\x08\x3f\x51\xd1\x38\x97\x81\x45\x55\x66\x8e\xf6\x0a\x5d\x8b\x48\x19\xb4\x16\x37\x65\xe6\x3d\x74\x9c\xda\x6b\x8b\x1b\xf9\x09\x42\x28\x1c\x71\x92\x4d\xb4\x29\x88\xdb\x2d\x92\x5b\x37\xce\x7d\xb7\x2b\xbd\x87\xba\x97\x4a\xfc\x86\xd6\x49\xa3\x21\x84\xac\x5a\x31\xd7\x58\xd9\x11\x38\xdb\x2c\x63\xdd\x1e\xa1\x6e\x97\x90\x58\x31\x20\x55\x2b\xef\x51\x8b\x10\x56\xab\x23\xb3\xc6\x68\x42\x4d\x91\x1c\x00\x13\x72\x07\x8d\xe2\xce\x95\x49\xc0\xa5\x46\x9b\x6f\x54\x2f\x45\x56\xad\x00\x00\x58\xfb\x1a\xa4\x28\xb3\xf1\xd0\xac\x7a\x3f\xfc\x61\x45\xfb\x7a\xd0\x00\x60\xc4\x6b\x85\x13\xce\xb0\x48\xdf\xbc\x31\x5a\xa0\x76\x28\xc6\x75\x6d\xac\x40\x7b\x58\xb6\x66\x87\x36\x9b\x60\x00\xbc\xb7\x5c\x6f\x11\x2e\x6e\x4d\xfd\x0a\x2e\x3a\x63\x14\x5c\x96\xb0\x1e\xce\xbc\x36\x46\x39\x48\xf7\x3e\x1a\x5c\xb4\xc8\x15\xb5\xfb\xa8\xa7\xfb\xfb\xb7\xe3\x2a\xd9\x3e\x56\x25\x43\x3c\x01\x2a\xd4\x33\x1a\x91\x88\x9d\x58\xdc\x9a\xfa\x63\x0c\x02\xb4\xde\xcb\x0d\x28\x82\xc3\x49\x03\x4e\x08\x20\xe2\x65\xed\xe8\xe3\x13\x1a\x13\x98\x80\xc6\x28\xd7\x71\x5d\x66\xdf\x3c\x11\x03\x30\x39\x1d\x26\x1b\xa3\xf3\xa6\xc5\x9d\x35\x3a\xef\xbb\xf8\x82\xb2\x62\x3c\x39\xfe\xd6\xd4\xb9\xf7\xd1\x23\x21\x4c\x81\xf6\xbf\x07\x9b\xd5\xf4\x0f\xbe\x3a\xfa\x23\x84\x62\x62\x1c\x02\xf4\xdd\xd7\xac\xe0\x4f\x6e\x58\x90\x78\xb8\xc7\x0a\xb2\xd5\xbc\x4b\xa0\x84\xe4\x14\x81\xc4\xa5\x72\x73\x74\x67\x28\xbe\x34\x32\x1c\x59\xd9\x2d\xc6\xc9\xe9\x01\xf1\x91\xe6\x24\xe9\xea\xf3\x82\x64\x56\xbd\xd1\xa2\x33\x52\x13\x2b\xa8\x3d\xa7\x77\x43\x9c\xf0\x39\xa5\x2b\x5e\xa3\x72\xcf\x6b\x39\x82\x9b\xc6\xf2\xee\x59\xc0\x37\xd6\x1a\xbb\xac\xf4\xf4\xa1\x0e\xfb\x4b\x0e\x61\x54\x1b\xb1\x9f\x93\x1c\xd2\x6e\x26\x25\x8e\xd6\x67\x9c\xb9\xf0\x00\x49\xc8\x0f\xc5\x71\xfd\xe1\xdd\x15\x7c\x86\xad\x32\x35\x57\x1f\xde\x5d\x0d\xa1\x1b\x77\xd7\x37\x4d\x8b\xf7\x18\xc2\x65\x51\x8c\x3b\x6f\x8d\xa3\x10\xc6\xc5\x35\xa7\x36\x84\x18\xc1\xac\x5e\xbc\xc6\x09\x0f\x15\x5f\xe3\x15\x5c\xec\xb8\xea\xd1\xa5\x12\x12\x61\x7e\xed\xd1\xee\x61\x81\xe0\x23\x08\x39\x99\x47\xeb\x11\xe8\xac\x25\x00\x8b\xa9\x3e\xc5\x7a\xba\x02\xa4\x6f\xde\x59\x79\xcf\xed\x3e\x25\x6a\xda\x09\x21\xfa\x63\x40\x0d\x21\x63\x45\xb4\x5c\xe6\x15\xaf\x35\xd4\xf1\x97\xc9\x9f\xe6\xf9\x89\xec\xec\xe3\x9d\x32\xe2\x0a\x2d\x41\xfa\xe6\xde\xc3\x7a\x28\xb5\xf0\x19\x86\x8a\xf3\xde\xfc\x90\xca\x44\x08\x10\x5b\x15\x7e\x94\x5a\xc8\x86\x93\xb1\x10\x1b\x67\xde\x77\x1d\xda\x86\x3b\x9c\xcd\xe3\x23\x91\x11\xf7\x0c\xd9\xf3\xee\xfa\x77\xc8\x36\xbd\x75\xc6\xe6\xa9\x40\xa0\xcd\x40\x70\xe2\x39\x99\xed\x56\xc5\x41\xc0\x18\x45\xb2\xcb\x80\x24\xc5\xf5\x28\x6e\xe9\x5e\x95\x64\x7b\x1c\x96\xc6\xca\xad\xd4\x5c\xe5\xa3\x16\xab\xab\xef\x71\x63\x2c\xc6\xf1\x21\x46\x81\xd4\xdb\x4b\x56\xd4\xd5\x21\xe6\xee\x62\xcc\xa5\x68\xfd\x51\xba\x26\xd6\x3c\x14\x43\x61\x09\x21\x06\xbe\xf7\x17\x77\xd1\xdf\x74\xaf\xc6\x9f\x10\xca\xff\xff\xd1\x1b\xfa\x36\x46\xd3\x63\xd1\x24\x99\x6f\x4f\x0f\xbd\x3e\xc4\x65\x4a\x95\x54\x7a\x87\x63\x61\x3d\xfc\xae\x7f\xe6\x5d\xaa\xfe\xd9\x5f\x4b\x9e\x07\xf9\x97\x12\x48\x8d\x34\xfe\xc3\x04\x52\x0e\x5f\x7a\xbe\xc0\x0d\xef\x15\x65\x95\x36\x1a\xff\x79\xb6\x7e\xa1\x00\x4e\x83\xca\x3a\xf6\x98\xa1\xc5\xac\x7f\x72\xbf\xa3\x35\x21\xfc\x82\xbb\x34\xa6\x24\x0f\x78\xef\xa4\x6e\xf0\x54\x31\x04\xe0\x5b\xf3\x85\x6a\xc8\xf1\x56\xa9\xa5\x9d\x73\xcb\x52\xb5\x19\xe6\xac\xc7\x65\x25\x35\x8f\x13\xdc\xe7\xde\xe5\xa5\xfc\x96\x5a\xed\x32\x1e\x2b\x16\x5a\x2d\x2b\xd2\x3c\xf3\x77\xe7\xb0\x87\x27\x9d\x80\xb0\x42\xc8\xdd\x61\xca\xff\x33\x00\x00\xff\xff\x65\x7b\xa9\x65\xbe\x0c\x00\x00")
func webUiTemplatesTargetsHtmlBytes() ([]byte, error) { func webUiTemplatesTargetsHtmlBytes() ([]byte, error) {
return bindataRead( return bindataRead(
...@@ -261,7 +263,7 @@ func webUiTemplatesTargetsHtml() (*asset, error) { ...@@ -261,7 +263,7 @@ func webUiTemplatesTargetsHtml() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "web/ui/templates/targets.html", size: 2279, mode: os.FileMode(420), modTime: time.Unix(1499786499, 0)} info := bindataFileInfo{name: "web/ui/templates/targets.html", size: 3262, mode: os.FileMode(420), modTime: time.Unix(1502370142, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
...@@ -326,7 +328,7 @@ func webUiStaticCssProm_consoleCss() (*asset, error) { ...@@ -326,7 +328,7 @@ func webUiStaticCssProm_consoleCss() (*asset, error) {
return a, nil return a, nil
} }
var _webUiStaticCssPrometheusCss = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\x8f\xcd\x6a\xeb\x40\x0c\x85\xf7\x7e\x8a\xb3\x0e\x38\x3f\x97\xdb\xcd\xf4\x19\xfa\x0c\x41\xf6\xc8\xb1\xca\x58\x1a\x3c\x72\xe2\xb4\xf4\xdd\x4b\x62\x87\x86\x42\x37\x5a\x7c\x7c\xe7\x70\xb4\xdb\xe0\xcd\xce\x8c\x68\x17\x45\x6b\xea\xac\x8e\x86\x5b\x9a\x0a\xe3\xc2\xe8\xe9\xcc\x20\x74\x32\x73\x84\xd2\xb9\xa1\x11\xde\x93\x43\x0a\x5e\xf6\x79\x86\x53\x4a\xd8\xec\xaa\xc6\xe2\x15\x9f\x15\x90\x29\x46\xd1\x53\xed\x96\xc3\x5d\x79\x7d\x82\x8d\xb9\xdb\x10\xf0\xef\xce\xbf\xaa\xca\xfb\xed\xbb\x35\xc7\x9e\x29\xf2\x78\xcf\x77\xa6\x5e\x17\xf9\xe0\x87\xf5\xab\xf2\xf0\x47\xe5\xe1\x51\xb9\x2d\x4e\xce\x47\xd1\x28\x2d\xb9\x8d\xcf\xab\x02\xf6\xf8\x9f\xe7\xe5\x2e\x76\x12\xe7\x91\xd2\xd1\x26\xcf\x93\xc3\xe3\xcf\x8a\x8e\x06\x49\xd7\x80\xc1\xd4\x4a\xa6\x96\x97\x44\x3b\x8d\xc5\xc6\x3a\x9b\xa8\xaf\xa3\x17\x14\xb0\xb2\xc5\x73\xb3\xe4\x92\x6b\x51\x5d\xb5\x81\xe6\xfa\x22\xd1\xfb\x00\x35\xe5\xdb\x1b\xce\xb3\xd7\x94\xe4\xa4\x01\x89\x3b\xbf\x45\xbf\x03\x00\x00\xff\xff\x86\xf0\x99\x9a\x95\x01\x00\x00") var _webUiStaticCssPrometheusCss = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x4c\x8f\x4d\x6a\xc3\x40\x0c\x46\xf7\x3e\xc5\xb7\x0e\x4c\x13\x4a\xbb\x99\x9e\xa1\x67\x08\xb2\x47\x8e\x05\x63\x69\xb0\xe5\x9f\x50\x7a\xf7\x10\x4f\x16\xd9\x68\xf1\x78\xdf\x03\x9d\x4f\xf8\xb5\x95\x91\x6c\x53\x74\xa6\xce\xea\x68\xb9\xa3\x65\x66\x6c\x8c\x81\x56\x06\xa1\x97\x9d\x13\x94\xd6\x96\x26\xf8\x40\x0e\x99\xf1\x7d\x29\x3b\x9c\x72\xc6\xe9\xdc\xb4\x96\xee\xf8\x6b\x80\x42\x29\x89\xde\x82\x5b\x89\x87\xf2\xf3\x06\x5b\x73\xb7\x31\xe2\xf3\xe0\xff\x4d\xf3\x31\x3b\x39\x5f\x45\x93\x74\xe4\x36\xbd\x27\x22\x2e\xf8\x2a\x7b\xbd\xd5\xce\xe2\x3c\x51\xbe\xda\xe2\x65\x71\x78\x3a\xfc\xde\xd4\x43\x4f\xa3\xe4\x7b\xc4\x68\x6a\x73\xa1\x8e\xeb\xa2\x5b\xa6\xd9\xa6\x50\x4c\xd4\xb9\xe6\x2b\x8a\x78\xb1\xea\xb9\x59\x76\x29\x41\x54\x5f\xda\x48\x7b\xd8\x24\xf9\x10\xa1\xa6\xfc\x7c\xc3\x79\xf7\x40\x59\x6e\x1a\x91\xb9\xf7\xe7\xf4\x11\x00\x00\xff\xff\xa0\xeb\x4b\x6c\x42\x01\x00\x00")
func webUiStaticCssPrometheusCssBytes() ([]byte, error) { func webUiStaticCssPrometheusCssBytes() ([]byte, error) {
return bindataRead( return bindataRead(
...@@ -341,7 +343,27 @@ func webUiStaticCssPrometheusCss() (*asset, error) { ...@@ -341,7 +343,27 @@ func webUiStaticCssPrometheusCss() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "web/ui/static/css/prometheus.css", size: 405, mode: os.FileMode(420), modTime: time.Unix(1462274250, 0)} info := bindataFileInfo{name: "web/ui/static/css/prometheus.css", size: 322, mode: os.FileMode(420), modTime: time.Unix(1502369610, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var _webUiStaticCssTargetsCss = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x54\x8e\x51\xaa\xc2\x30\x10\x45\xff\xb3\x8a\xfb\x16\xd0\x47\xf5\x33\x05\xb7\x22\xa9\x33\xb6\x23\x6d\x26\x4c\x46\x14\x4b\xf7\x2e\x14\x91\xfa\x7b\x38\xf7\x72\xdc\xfe\x6f\xda\x9f\x47\x4e\xc4\x86\x25\x00\xc0\x55\xb3\x37\x55\x5e\x1c\x71\x6c\xcb\xb3\xdb\x60\x49\x44\x92\x87\xc6\xb5\x44\x1c\xbe\x78\x73\x1f\x2c\xc3\xe8\x11\xbd\x4e\xf4\x6b\xf7\xea\xae\xf3\x7e\x70\xb9\x5b\x55\x8b\x28\x2a\xd9\xd9\xba\xb0\x86\xf0\x89\x20\xf6\x24\x53\xc5\x09\x4e\xcb\xfe\x26\xa2\xc5\x9f\xcc\x45\xcd\x53\xf6\x2e\xac\xef\x00\x00\x00\xff\xff\x62\x16\x77\x5a\xb6\x00\x00\x00")
func webUiStaticCssTargetsCssBytes() ([]byte, error) {
return bindataRead(
_webUiStaticCssTargetsCss,
"web/ui/static/css/targets.css",
)
}
func webUiStaticCssTargetsCss() (*asset, error) {
bytes, err := webUiStaticCssTargetsCssBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "web/ui/static/css/targets.css", size: 182, mode: os.FileMode(420), modTime: time.Unix(1502369610, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
...@@ -406,7 +428,7 @@ func webUiStaticJsAlertsJs() (*asset, error) { ...@@ -406,7 +428,7 @@ func webUiStaticJsAlertsJs() (*asset, error) {
return a, nil return a, nil
} }
var _webUiStaticJsGraphJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xe4\x7d\x6b\x77\xdb\x38\xb2\xe0\x77\xff\x8a\x0a\x3b\x27\xa2\xda\x32\x65\xa7\x6f\xf7\xde\x91\x2d\xf7\xa6\xf3\x98\x64\x26\xaf\x71\xdc\xaf\xe3\x78\x7c\x20\x12\x12\x19\x53\x24\x07\x00\x6d\xab\x13\xfd\xf7\x3d\x28\x3c\x08\x90\x94\xa5\xee\x9e\x9d\xb3\x7b\xae\x3f\xc8\x16\x1e\x85\x42\x55\xa1\x50\xa8\x2a\xc0\x37\x84\xc1\x7b\x56\x2e\xa9\x48\x69\xcd\x61\xea\x7e\xf9\xf2\x05\x3e\xaf\x8f\xf7\x64\x93\x05\x23\x55\x7a\x4e\x97\x55\x4e\x04\x3d\xde\xc3\xb2\x0f\xcf\x9f\xbe\x7b\xfb\x0c\xa6\x70\x74\x78\x78\x78\xbc\xb7\xd7\xf4\x8c\xfe\x2a\x9b\xc3\x14\xe6\x75\x11\x8b\xac\x2c\x42\x9a\xd3\x25\x2d\xc4\x08\xca\x4a\x7e\xe7\x23\x48\x49\x91\xe4\xf4\x69\x4a\x8a\x05\x35\xdf\xce\xe8\xb2\xbc\xa1\x43\xf8\xbc\x07\x20\xd2\x8c\x47\x34\x87\x29\xe8\xbe\xc7\xa6\x10\x71\x79\x79\xfe\xe6\x35\x4c\xa1\xa8\xf3\xdc\x56\x68\xd8\x30\x35\xa3\xd8\x1a\x77\x30\x98\x7a\x63\xb7\xda\x28\x14\x5c\xd4\x15\x3a\xe0\xa1\x18\xca\x1e\x43\xd9\x75\x6d\xfb\xb3\x2c\xbe\xe6\x29\xb9\x35\x73\xf7\x50\x4b\x88\x20\x30\x85\x8b\xcb\xe3\x3d\x53\x94\x15\x99\xc8\x48\x9e\xfd\x46\xc3\xe1\xf1\xde\xba\x87\x80\x91\xc8\x96\xf4\x05\x89\x45\xc9\xe4\xa4\x24\x1a\xc1\x2a\x98\xc0\x77\x87\xf0\xb5\xfa\x78\xfc\x5f\xf0\x35\x7c\xf3\xdd\xb7\x23\x59\x75\xdb\xad\xfa\x5f\x58\x91\xb4\x2a\xb0\x30\x6d\x0a\xf1\xfb\x12\xbf\xe3\x9f\x3c\x98\xc0\x51\x3f\x46\x5c\xd0\xea\x27\x92\xd7\x54\x22\x74\x21\x1b\x1f\xf1\x60\x04\xc1\xd1\xa1\xfa\xb5\x94\x9f\xdf\xe2\xe7\x91\xfa\xf5\xcd\xa1\xfa\x96\xca\xcf\xc7\xf8\xf9\x1d\x7e\x1e\xa9\x2f\x47\x09\x56\x24\x01\x0e\x7d\x74\x8b\xdf\xf0\xf3\xbf\xf0\xf3\xbf\xf1\xf3\x68\x85\xe5\xab\x60\xef\xb2\x0f\xad\xa2\x5e\xe2\x1f\x12\xab\x3e\x51\x8c\x2a\x56\x8a\x52\xac\x2a\xea\x90\xbd\xcb\x64\x29\xd5\x9c\xe6\x73\x98\x22\x8b\x24\xf7\xe4\xd7\x28\x4b\xbc\x85\xd1\x1e\x74\x7f\x1f\xb9\x3a\x1e\xc3\x07\x2a\x20\xa1\x73\x52\xe7\xc2\xc8\x60\x64\x80\x98\xef\x08\x4c\x83\x3d\x6e\x57\x32\x29\x92\x57\x59\x51\xd5\xc2\xb4\xea\xab\xfa\xf2\x05\x29\x2a\xbb\x67\x73\x08\xbd\x76\x82\xcc\x60\x3a\x9d\x42\x5d\x24\x74\x9e\x15\x34\x31\x02\xdc\x6d\x05\x47\x28\xc2\x1a\xf9\x67\x8c\xdc\xaa\x85\x0e\x71\x59\x08\x56\xe6\x1c\x48\x91\xe0\x17\x92\x15\x94\xc1\x9c\x95\x4b\x78\x89\xeb\x60\x46\x18\x07\xa1\x15\x42\xb4\xa7\x89\xd7\xac\x40\x35\xe4\xa0\x22\x22\x7d\xcf\xe8\x3c\xbb\x1b\x4c\xe0\xfd\x93\xf3\x97\x57\xef\xcf\x9e\xbf\x78\xf5\xcb\x48\x55\xcf\xea\x2c\x4f\x7e\xa2\x8c\x67\x65\x31\x98\xc0\x0f\x3f\xbe\x7a\xfd\xec\xea\xa7\xe7\x67\x1f\x5e\xbd\x7b\x6b\x16\xd7\xa7\x7f\xd4\x94\xad\x22\x7a\x27\x68\x91\x84\x56\x7f\xb8\xb3\x19\x5a\x3a\xba\xba\xe1\x61\xf8\xa6\xe6\x82\xc4\x29\x8d\x18\x2d\x12\xca\x42\x4f\x8b\x59\x5d\x34\x6c\xba\xd3\x3c\x22\x55\x25\xc7\xf1\xa1\x0d\x0d\x83\xff\x4a\x05\x30\x3a\xa7\x8c\x16\x31\xe5\x20\x4a\x20\x79\x0e\x22\xa5\x90\x15\x82\x32\xca\x45\x56\x2c\x8c\xc6\xe2\x90\x15\x58\xd7\x10\x55\xd1\x91\x14\x89\x02\x37\xcb\x8a\x04\xe8\x0d\x2d\x84\x56\x2f\x0c\xe5\xc5\x6a\xdc\x9f\x99\x44\x87\x19\x51\xa0\x79\x34\xcf\x8a\x24\x0c\xbe\xc2\xda\xab\x5b\x55\x1d\xc0\xbe\x11\xa8\x66\x2a\xff\x92\x54\x7b\x51\xb2\x25\x4c\x3d\x58\x1a\x82\xaa\xbf\x9a\x97\x6c\x19\xa8\xd9\xa9\x11\xee\x2a\xd6\xdf\x41\xd0\x3b\x41\x18\x25\x17\x05\x59\xd2\xa9\x6c\x77\x19\x38\x84\xbb\xab\x58\x74\x4d\x57\x15\xa3\x9c\x87\x8d\xda\x37\xb2\x37\x1e\xc3\x73\x49\x20\xb8\x25\x1c\xb0\x11\x4d\xe0\x36\x13\x69\x59\x0b\x24\x11\x4f\xb3\xb9\x80\x6b\xba\x8a\xb0\xbd\x94\x6a\x1a\xdd\xa6\x59\x9c\xc2\x74\x0a\x47\xdf\xc0\xa3\x47\xf0\x80\x46\xd8\xec\xef\x74\x65\xe0\xb6\x27\x1b\xf1\x7a\xb6\xcc\x44\x88\x98\xc9\x1f\x1a\x55\x0c\x09\xfc\x4c\x2d\x4b\x53\x83\x42\x8f\x78\x3d\xa9\x45\x79\xc0\x28\x97\x1a\x41\x62\x22\x27\x0a\x72\xa6\x50\x16\x80\xcb\x4d\xa1\x84\xf2\x3d\x9f\x73\x2a\xb4\x7a\x88\xd4\xb7\x97\x34\x5b\xa4\x02\x0e\x54\x59\x9c\x67\xb4\xd0\x65\xc7\xb6\x9f\x02\x7f\xae\x49\xe8\x6f\x8c\xcd\x54\x00\x1e\xca\xef\x51\xcc\x79\x38\x48\x11\xc4\x60\x04\x03\x52\x8b\x72\xd0\x2e\xa5\x79\xc4\x63\x56\xe6\xb9\x1e\x7e\x5f\xe3\x66\xa6\xa7\x7e\x3d\x54\x1b\x55\x54\x16\xe1\xe0\x9a\xae\xea\x4a\x4d\x68\x30\xf2\x34\x5f\x0b\x3d\xbd\xb9\xc1\x5a\x6d\x70\x2d\x26\xc7\xb8\x6b\xaa\xf5\xe1\xee\xa3\x8e\x10\xa1\xa6\x7a\xe5\xea\xb0\x86\x3f\x4a\x98\x10\x0b\x25\x49\x8e\x5a\x73\x05\x4a\x2e\xdc\x6b\x9a\xfc\x20\x8a\x4d\x30\x4c\x93\xab\x99\x28\xba\x1d\x77\x18\x59\xb7\x74\x47\xcd\x0a\x4e\x99\x78\x43\x05\xcb\xe2\x4d\x10\x38\xcd\x69\xac\x41\xa8\xf6\x57\x4b\xec\xe0\x02\x62\x74\xce\x28\x4f\x5f\x49\x99\xbf\x21\xf9\x2e\xb0\x74\x97\x4b\x77\x39\xc6\x65\xc1\xcb\x9c\x9e\xa3\xb2\xee\x5b\xc5\xba\x41\xd0\xd2\x80\xb2\x03\x6c\xe8\xa2\x54\x87\x55\x46\xee\x70\x82\xcc\x78\x7f\x2f\x72\x21\x2d\x98\x03\x51\x2e\x16\x39\x9d\x0e\x04\x99\x0d\xdc\xe9\xca\x8e\x11\xfd\x57\x67\x23\x1a\xca\x8f\x30\xe0\x69\x79\xdb\x6e\x5d\x16\xaa\xbc\x88\x66\xd8\x34\x70\x64\xd2\xaa\x0d\xb9\x76\x04\x61\x0b\x5c\x73\x0f\x43\x1a\xa9\x2f\x5a\xc8\x7b\x36\x34\x55\x1f\x55\x84\xd1\x42\x84\xc3\x28\x2b\x12\x7a\x17\xba\xed\x5d\x99\x35\x15\x52\xdb\x3c\x0c\x83\xaf\xa4\x22\xd5\x10\x88\x10\x2c\x0c\x08\xcb\xc8\x81\xd9\x0c\x83\xe1\x30\x4a\x09\x7f\x9a\x13\xce\xc3\x80\xd1\xbc\x24\x49\x30\x6c\x69\x22\xa5\x7f\x70\xcb\x6a\x54\x8d\x5a\x45\x4a\xe5\x9f\x51\x51\xb3\x02\xa4\x15\xc9\x61\x5e\xc6\x35\x87\x19\x89\xaf\xe5\x56\x82\xca\x37\x2b\xb8\xa0\x24\x81\x72\x0e\x0a\x96\xdc\x51\xa2\x3e\x01\x8d\x66\xc8\x9a\x6b\xba\x4a\xca\xdb\x42\xda\x47\x0c\x61\xf7\x52\xb2\x59\xc0\x38\xa6\x47\x12\x2c\xbe\x21\x79\xe8\x7f\x1b\xea\x36\x0a\xea\x06\x4d\xba\x1e\x36\x7b\x07\x63\xe5\x86\xcd\x43\xd5\x05\xc3\x28\xcd\x12\x4d\xf5\x46\x58\x9f\x28\x95\xb8\x59\x56\xa5\x52\x6a\x4b\xb8\x59\x51\x16\x82\xd7\xc5\x69\xbd\x7a\x72\x97\xf1\x8d\xad\x57\x57\xe4\x2e\xe3\x4e\xf3\x9c\x2e\x68\x91\x6c\x40\x47\x55\xba\xca\xa6\xca\x8a\x82\x6e\x9a\xb4\xae\x75\xb7\xc9\x1b\x92\x7f\x10\x44\x6c\x58\x65\x58\x7f\xc5\x65\x03\x6f\x53\x2e\x92\x67\x44\xd0\xfe\x3e\x8e\x42\xa3\x45\xd2\x55\xa4\xba\xb3\x3c\x81\x50\x79\x9e\xa8\xb2\xf8\x9a\xb2\x50\x49\x45\x5e\xc6\x24\xa7\x13\x18\xd0\x62\xa0\x4c\x32\x69\x10\x10\x31\x81\xc1\xaf\xbf\xfe\xfa\xeb\xc1\x9b\x37\x07\xcf\x9e\xc1\xcb\x97\x93\xe5\x52\xd7\x8b\xb2\xcc\x67\x84\xbd\xcf\x49\x8c\x36\xce\x04\x06\xb3\x52\x88\xd2\xd4\xf3\x2c\xa1\x3f\xac\x3e\x64\x09\x9d\x80\x60\x35\xd5\xa5\x69\x79\x7b\x5e\x26\x64\xf5\x43\x2d\x44\x59\xb4\xab\x9e\xe6\x94\xb0\x6e\x61\xc9\x1d\x20\x6a\x1f\xea\x58\xbb\x76\xce\xbe\xa0\x37\x93\x26\xe1\x40\xfe\x79\x9e\x2d\xe9\x7b\x9c\xfa\x60\x88\xb4\xd8\x04\x46\x59\xc4\x2d\x38\x52\x59\x25\x95\xde\xfb\x82\xd6\xee\xd9\xb3\xee\xdd\x5d\xb3\xb5\x15\x98\x0d\xb4\x0b\xa2\xae\x24\x5e\x67\xaa\xb9\x01\x62\x17\x3e\xff\x60\x37\xb6\xce\xd1\x54\xaf\x50\x77\xff\x53\x2b\x18\x0f\x02\x83\xa3\x81\x3e\xa9\x9a\x23\x8e\x58\xe5\x14\xc1\xa9\xed\xb5\x03\x4f\x36\xca\xe2\xd2\x6e\xbd\xcd\x66\xac\x84\x6e\x10\x2d\xf2\x55\x95\xca\x26\x03\x47\x85\xfa\x88\x86\x1d\xd5\xd8\x40\x21\x49\xa2\xd5\xe8\x4c\x14\x07\x15\xcb\x96\x84\xad\x02\x6b\xb4\x49\xc0\x4e\x1b\x3b\xd8\x41\x9c\xd2\xf8\xba\xd5\x8e\xe1\x89\xbc\xd3\xb4\x2e\xb0\x31\x4d\x4c\xf3\x35\xd0\x9c\xd3\x8d\x28\x79\x60\x7e\x1f\x56\x9d\xa1\xee\xc7\xcc\x9b\xc4\xda\x1c\x73\x3c\xa6\x84\x0e\xe7\x1d\x1c\xe3\x3c\x8b\xaf\xc3\x0e\xbb\xfa\x68\x2f\xed\xe5\x46\xe5\xfd\xed\xc3\xbb\xb7\x0d\x37\xc6\x63\x78\x35\x77\x0e\x26\xd2\x26\xd7\xa3\x8c\xb0\xb8\x64\xd9\x22\x2b\x48\x0e\x9c\xb2\x8c\x72\x40\xef\xc5\xa2\x14\xb0\xac\x05\x11\x34\x69\xe0\x84\x5c\x2a\x90\x64\x88\x07\xc5\x5b\x0a\x05\xa5\x89\xdc\xca\x18\x95\x96\x89\x60\x75\x2c\x20\x13\xea\xe0\xe8\x41\x96\x18\x21\xdc\xc8\xe5\x87\x76\x93\x28\x2b\x81\x91\x82\x4b\x75\xf4\x4c\x2e\xe2\xd6\x5c\x1a\xe2\x41\x57\xec\x3b\xb4\xf8\x1e\x06\x87\x03\x98\xc8\x95\x60\xf6\xbd\x36\xb5\x2d\x20\xb5\x0a\xf1\x60\x1f\x5a\x03\xb8\x73\xa8\x32\xe7\x8c\x0e\x2f\x5a\x66\x9b\x23\x2f\xc6\x60\x70\xc6\x32\xb6\xda\xfd\xad\x7a\x4c\x0a\xbd\xe0\xe7\x24\xe7\xb4\x65\xa4\xeb\x4d\xc7\xee\xb4\x5d\xd4\xd5\xbe\x31\x43\x4d\x6c\xcc\xd8\xf8\x0a\xed\xf0\xcb\x60\xd8\x23\x64\xc6\xf4\x88\x19\x25\x9c\x9e\x69\xcb\xc9\x1d\xf4\x3e\xe0\x09\xdd\x01\x78\x42\x7b\x80\xef\x8a\x3a\x2d\x92\x5d\x10\x7f\x5e\x24\xbf\x13\xed\x2d\x80\x0d\xd2\x0e\xe0\x5e\x3b\xad\x47\xe3\xb7\x8c\x2f\x75\x0e\x90\x75\x01\xa3\x95\xdc\x5b\x83\x11\x7c\x96\x27\xd1\x49\x0f\x3c\x54\xed\x23\x58\x96\x72\x93\x0d\x66\x74\x5e\x32\x1a\xac\x3b\x16\x9d\x31\xf4\xe4\x3a\x65\x14\xbf\x65\xc5\xa2\x91\x68\x75\x30\x95\x2a\x4a\x6d\x03\x3d\xc6\x85\x39\x99\xc8\x46\xda\xa8\xb0\x3d\x36\x69\x23\xbd\xe9\xa1\x9b\xf4\x1e\x71\x35\x94\xaa\xca\xaa\xce\x89\xa0\xaf\x70\x86\x64\x96\x53\x35\x4b\xae\x85\xd7\x2a\x37\xc7\x2e\x75\x47\xea\xac\x8e\x75\xbf\xe7\xb2\xf1\x00\x6e\x1c\x71\x27\x87\xe0\xc3\x88\x7c\x22\x77\xa1\xd1\xa5\x72\x90\x32\x99\x40\xf0\xd7\xe7\xe7\xc1\x48\x17\xd6\x2c\xf7\xbc\x5d\xb0\x0f\xc1\x98\x54\xd9\xf8\xe6\x68\x9c\x93\x19\xcd\xc7\x57\x57\x92\xb2\x57\x57\xe3\x1b\x74\xa6\xda\x9e\x52\x01\x9e\xaf\x2a\xc9\xd7\x4f\xbc\x2c\x6c\x39\xaf\xe3\x98\x72\x3e\x69\x10\x94\xd5\x23\x74\x56\x48\x83\xb2\xe6\xae\x1b\x41\xd2\x4c\xd6\x4b\xad\x28\x6a\x0e\x0f\xa6\x53\x08\x34\x88\xc0\x6d\x68\x68\x98\x96\xb7\xcf\xa5\x85\x1e\x06\xf8\x0b\xa4\x0e\xca\x8a\x05\x90\x1b\x92\xe5\x92\x42\xa0\x8e\xb8\xfc\x41\xb3\xc5\x35\x8c\x6d\x4a\xd6\xf6\x2f\x49\xb9\xa5\x25\x2b\x22\x23\xe7\xd6\x34\x9d\x97\x0c\x42\x34\x34\xd0\x67\x0b\x19\x9c\x98\x0e\x51\x4e\x8b\x85\x48\x8f\x21\xdb\xdf\xef\xc1\xd6\x5d\x0b\x17\x87\x97\xd6\x86\x23\x49\x12\x16\xf4\x16\xde\xe1\xf7\x50\x03\xbb\xc8\x2e\x47\xd0\xfc\x3d\x1c\xba\xd8\xee\x79\x80\xe7\xf5\x6f\xbf\xad\xce\x28\xaf\x73\x61\x3d\x98\xea\x07\x15\xc5\x04\x5d\xfa\x23\x6f\xfa\xb2\x6d\xb7\x7c\x49\xaa\x09\x7c\x5e\x6f\x1c\x08\x45\x59\xca\x22\x49\x29\x49\x42\x6f\x86\x65\xcd\x62\x3a\x31\x18\xbb\x50\x33\x41\x97\x7c\x02\x01\xc9\xf3\xc0\x1f\x4d\xc4\x29\x65\x8e\x6c\xc8\x96\x3e\xe1\xcc\xa6\x7f\x4b\x21\x25\x37\x54\x63\x8e\x4c\x88\x6b\x26\x0f\xcb\x6a\x8e\x23\xe0\xd7\x59\xe5\x75\xb4\x0b\xd0\x21\x8f\xd2\x9c\x28\x57\xe8\xf5\xc2\xaf\xed\x11\xbb\x54\xd5\xdd\xdc\x4e\xc7\xdb\xba\x2c\x49\x25\x99\xb1\xde\xda\x90\x19\xc6\x61\x61\x34\xcf\x72\x41\x59\xd8\x8c\x14\x69\xcd\x1a\x8e\x61\xbc\x18\xc1\x60\x30\xb4\x72\x31\xea\x60\x0e\x50\x31\x79\x2e\x3a\xe1\x82\x95\xc5\xe2\x74\x30\xea\x36\x28\xb9\x3c\xfd\x9c\x8c\x4d\x93\x56\x8b\xf5\x70\x47\x94\xa3\x79\xc9\x9e\x93\x38\x6d\x54\x29\xeb\x92\xb2\x9f\x32\x17\x2c\x32\x16\xd5\x25\x4c\x81\xb5\x47\x6c\xe3\xe0\x08\x22\x34\x7a\x59\x8a\x0b\x64\x45\xef\x08\x6e\xff\xf5\x68\xcf\x93\x54\x26\x3a\x52\xc7\xdb\x98\x63\x61\x24\xdb\x36\xd3\x23\xa3\x59\x77\x82\x46\x15\xf4\x4e\x73\x76\x19\xf1\xb8\x64\x14\x0e\xfa\xeb\x89\xae\x6f\xcf\xdf\x4c\x10\xcf\x41\x87\xf0\x3d\x90\x48\x1d\x79\x9f\x96\xcb\x8a\x30\x1a\xce\x86\x30\x81\xac\x45\xa4\x16\xd1\x1c\x2a\xf1\xcd\xe4\x48\xb3\x45\x9a\x67\x8b\xd4\xa3\x09\xf4\x2e\x45\x0d\xf0\x61\x38\x38\x49\xb2\x9b\xd3\x81\x71\xdf\xb7\x67\x25\xfb\x5e\x46\x5c\x30\xa9\x8a\xf7\xa5\xa8\x61\xf3\xa1\x8f\x43\x1f\xda\xe3\x31\x9c\xa7\x19\x47\x73\x1c\xa3\x14\x29\x86\x35\x80\xcc\x05\x65\x40\x84\x20\x71\x2a\x81\xa2\xbf\xdb\xe8\x21\xa8\xf2\x7a\x91\x15\x23\x20\x1c\x32\xe1\xc2\x2a\x45\x4a\xd9\x6d\xc6\x29\xcc\x18\x25\xd7\xbc\xd5\xcf\xcc\x96\xe4\x99\x58\x45\x3d\xaa\xce\x73\x39\x39\x48\xa3\x57\x68\xd2\x3d\x7f\xc2\x9f\xda\x98\xd6\xc6\x5d\xb0\xc5\x0e\x58\x50\xf1\xce\xc6\xab\xb6\x6f\xfc\xad\xf8\x56\x73\x9c\x56\x85\xe8\xef\x36\x51\x51\x80\xc0\xf1\x6b\x6b\x6d\x1d\x58\x27\x83\x29\xe0\x82\x56\xed\x12\x3c\xb3\x04\x7b\x00\x97\x9b\x0d\x60\xd5\x65\x18\x51\x4f\x6b\xa0\xaf\x73\x64\x82\x4f\xee\x59\x5e\xda\x1a\x4d\x20\x3d\x92\x5f\x1d\xc7\x67\x94\x15\x4f\x18\x23\xab\x50\x96\x8f\xbc\xe9\x0c\xe1\x74\x0a\x87\x0d\x5b\x30\x2c\xa3\xa1\xa0\xe5\xa2\xb7\x6a\x38\x75\x5b\x81\xa1\x13\x9a\x8f\x97\xce\xc8\xd8\xc7\xf2\xc9\xf3\x8e\xda\x4e\x26\x06\xd5\x32\xfa\xdc\x16\xca\xd7\xdb\x76\xff\x2a\xeb\x14\x97\x96\x8d\xff\x6f\x33\x05\x09\xe3\xf4\x59\xcd\x08\x2e\x56\x47\x0a\x90\x7b\xe7\xf4\x4e\x34\xe2\x80\x45\x67\xcf\x61\x0a\xd2\xc8\x38\xa3\x8b\xe7\x77\x55\x18\xfc\x33\xbc\x38\x3c\xf8\xcb\xe5\xfe\x30\xbc\x58\xdd\x26\xe9\x92\x5f\xee\x0f\x1f\x2a\x59\x44\x13\x08\xf7\x66\x29\x16\x16\x62\x84\x65\xa1\x06\x67\xbd\x5a\x0f\x74\x53\x15\x8f\x41\xb3\x0a\x69\x23\xeb\x74\x95\x21\xf6\x83\x29\x7c\xd3\x72\xfd\x7c\x77\x68\xfc\x56\x72\x54\x24\x33\x4c\x01\xa7\xf7\xaa\x10\x06\xc0\xc5\xd1\xa5\xc5\xac\x2e\x32\xb9\x59\x9a\x9a\xc7\x97\x0e\xf9\x54\xff\xaf\xbb\x21\x6f\x27\x21\xe1\x42\x02\xb8\xdc\x4a\x61\xef\xd4\xb8\xf3\x3a\x43\xe2\x7c\xa0\x71\x59\x24\xd6\x77\xeb\xf1\x2a\x6c\x05\x9a\x1c\x87\x75\x9f\x61\x79\x4f\x1e\x43\x9f\xb1\x29\x69\xee\xa1\x70\xd2\x87\xc2\x3d\x40\xd1\xd0\xf4\x5d\x4d\x2d\x5c\xb7\x74\x3e\x76\x16\xdc\x86\xd3\x0f\xdc\xe3\x1f\x68\x2c\x71\xd7\x42\x5f\xef\x72\x3a\xf2\x4e\xe2\xff\x79\x86\x6d\xe7\x14\x1c\xc0\x91\xe4\xea\xa9\xe2\xee\xc1\xc1\x46\xae\x9d\xfe\xcf\xe1\xda\x82\x8a\xe7\x36\x4a\xb0\x9d\x65\xa8\x70\xbc\xd8\xc2\x97\x2f\xe0\x15\xf8\x58\x33\x13\xb4\x5a\x62\x58\xcd\xe8\x1a\xd7\xef\xbc\x8b\xcb\x7d\xb7\x3d\x99\x7d\xf8\x7d\x93\x91\x45\x89\x6a\xac\xbc\x6a\xb6\xbb\x13\x69\xe2\x4d\xa1\x6c\x3b\x74\xb4\x5d\x82\x29\x6d\x5b\x10\xe3\xbd\x38\x21\xa8\x7b\x53\x87\x76\x21\x8b\x46\x68\x47\x4d\xfa\xbc\xe8\x89\x01\x6c\x20\x4b\x41\x6f\x35\xca\x9a\x75\x86\x40\x2e\x91\xf5\x32\xd4\x6d\xf1\x18\xbd\xf3\xfa\x85\x31\x3c\x1e\xc1\x80\xab\x15\x37\xe8\xa5\xb7\x06\xec\xd4\xf9\xa2\xbf\xa3\x42\xfa\xbf\x3d\x6f\x5e\xcf\x04\x23\xb1\xf8\x7f\x6a\xf2\x4e\xeb\xdd\xd3\xd5\xe2\x9c\x12\xa6\xcc\xe6\x61\x6b\xb5\x77\xf4\x51\xa3\x69\xd6\x7b\x6d\x17\xb2\xb4\xbe\xc3\x9e\xe0\x65\x44\x97\x95\x58\x85\x43\x27\xa0\x44\x98\x90\x72\xad\x8d\x23\x45\x5d\x49\x6f\x59\x18\x0e\xff\x1d\xbb\x84\x4e\xa3\x29\xf3\x5a\xdb\x6a\xd6\xb8\xd9\x6c\x22\x9b\x3c\x0f\x63\x65\x5f\x06\x43\x33\xfb\x2f\x5f\xe0\x0d\x11\x69\xb4\x24\x77\x21\xfe\x31\xcf\xcb\x92\xf9\xfb\xc7\x18\x1e\x7f\x7b\x38\x1c\xc1\x91\x45\xa0\x89\xc4\x76\x34\x0d\x8c\x4d\x1e\xac\xa3\xff\x11\xab\x5f\x52\xe6\x79\x2c\x4d\x61\x44\x66\xf2\x58\x3c\x74\x2d\xb7\x9a\xe5\x66\x2c\xed\xaf\x33\x5f\x2b\xc2\xc8\xb2\xc9\xac\x0b\x10\x4a\x30\x69\x9b\xc9\x26\x9c\xb4\x31\x2d\xd0\xda\xe9\x0a\x60\x84\xbc\x93\x26\xba\x9e\xda\x81\xc7\xa5\x63\xb7\xa9\x0a\x8c\xeb\x86\xc7\x3e\x10\x5a\x49\x1b\xd7\xf2\x47\xd5\xd6\x2c\x97\x5b\x7a\xbf\x23\x54\x25\xa0\xe1\x60\x81\x76\x5d\xab\x19\xbb\x82\xde\xe3\xe5\x74\xd3\x38\x70\xb9\x9c\x51\x5e\x95\x05\xa7\xdd\xc6\xc7\x8a\x16\x5e\xe4\x4f\x63\x2c\x94\xb4\x36\x92\x6b\xd8\xb7\x1b\xde\x7f\x18\xe3\xa7\x2a\x34\xb4\x1d\x67\xeb\x1f\x37\x7c\x57\x7f\xb4\x0e\x85\xbf\xa4\xf2\xa8\xb4\xc1\x27\xdd\x5a\x18\x2a\xa5\x45\x55\x06\x43\xcf\x57\x5d\xb3\x7c\x9b\x07\x5a\x96\x4f\x34\x12\xff\x69\xaf\x34\xf6\x42\x67\xc1\x8e\xde\x67\x0d\x35\xb4\x7e\x67\x9f\xc4\xdb\xfc\x10\x77\x29\x1b\x49\x61\xae\xda\xe8\xcb\x32\x79\xfc\x0a\x70\xe9\xb6\x90\x46\x05\xc1\x3c\x1f\x9c\xec\x73\x97\xb2\x88\x69\x76\x63\xd4\xf3\x41\x5f\x72\xae\xf9\xa1\x4c\x32\xb4\xdd\x47\x4d\xde\x73\x3e\xf9\xd1\xec\x76\x67\x45\x62\x79\xdc\xf4\x3a\x6d\x75\xfc\xd3\x3b\x1a\xd7\x98\xc3\xaa\x5d\xde\x01\xec\x4b\xb0\xc3\x2e\x95\x2d\xf5\xe2\x72\x59\xe5\x54\xd0\x9d\x09\x38\xdd\x40\xc0\xfb\xa3\x09\x49\x73\x4c\xef\xdb\x63\xe0\xa0\x59\xcc\xc7\x5e\x47\x51\x0a\x92\xcb\xe2\x0f\x2a\x9a\x8d\x29\xe2\xf7\x71\x48\x85\xa1\xef\x61\xd3\xc6\x4e\xda\xa3\x2b\xd7\x0f\x2a\xdb\x80\xc7\x24\x27\x2c\x68\x73\xb9\x8b\xd2\xd1\x56\xe6\x76\xfb\xdc\x87\x82\x39\xd6\xf6\x72\x7f\xdd\xf2\xd1\xd9\x8d\x3d\x15\xcb\x3c\x0c\x5e\x97\x24\x01\xa9\x20\x15\xfb\x2d\xe1\xf7\x21\x58\x72\x38\x99\x31\x18\x9f\xc2\x99\xd5\xf5\xaa\x95\xb3\x37\xef\x43\x60\x9a\xc9\x9a\xe0\x5c\x62\x8e\x00\x75\x42\x81\xea\xd1\x9a\x90\x23\x62\xbd\x81\xec\x06\xf5\x1d\x7c\x7b\x56\xb0\x5d\xd5\xbc\xe4\x8b\x2d\xc6\xba\xec\x11\x49\x4d\x81\x6d\x5b\xe5\xc6\x1c\xda\x32\x74\x63\x7d\xfd\xd1\xb1\x07\x83\xf6\xd0\x86\x06\x5b\x86\xf6\x32\x88\x76\xb0\x17\x5d\x3b\x41\xb2\xa7\xac\xc5\xab\x67\x46\x56\x6f\xb3\x22\x29\x6f\xd5\x74\xce\x55\x65\xbb\xa5\x35\x1b\xb3\x56\x9e\x6b\x9f\x51\xd7\x4a\x83\x6a\x2c\x3b\x34\x4f\x0d\x04\xdf\xfd\x65\x33\x46\xcd\x90\x30\x35\x78\x71\xb5\xf0\x25\x56\xfd\x21\xe8\x9e\x03\x76\x6f\x9a\x95\x9c\xc3\xa8\x99\xc1\xd7\xfa\x5e\xd3\x76\x6a\xab\x4b\x05\xaf\xc9\x8c\xe6\x9e\x05\x80\x11\x5e\xde\x90\x1c\xbf\x7f\x40\x2f\x3e\xd7\x77\x80\x1c\xa7\x07\xd6\x42\x56\x80\xdb\x4d\x11\x45\x55\xc9\xed\xc6\x84\x8b\x1d\x45\xe2\x42\x8d\xaa\x9a\xa7\x61\x60\x82\x55\x72\x71\xa9\xbe\xfb\x10\xd8\xf8\x94\xd6\xe5\x3c\x26\x15\x7d\x79\xfe\xe6\xb5\xc6\xf3\x02\x7f\xd9\xb8\xe8\xda\x3f\xda\xe7\x66\x76\xc1\x49\x92\xdd\x40\x9c\x13\xce\xa7\x1f\x03\x55\xfc\x31\x68\x86\x32\x98\x7c\x2a\xb3\x22\x0c\x4e\x66\xec\x34\x18\xaa\xe1\x93\xec\xe6\x34\xd8\x4a\x4c\xe5\xc6\x3f\x2f\xcf\xf9\x5b\xe5\xac\xde\x48\x4e\x61\x5a\xe8\x9a\xc8\x10\x47\xda\xf4\x83\x01\x8e\xfa\x39\x38\xbe\x8f\xf8\x5b\xa9\xbf\x9d\xfc\x3d\xf4\xb7\x24\x9f\x7e\x0c\x2c\x5d\x0c\x7d\x65\xf9\xc7\xc0\x06\x29\x50\x03\xcb\x0f\x3d\x9b\xfd\x69\x1f\x19\x47\x8a\x86\xeb\xc0\xf1\x56\xa8\x0e\xbb\x79\xb6\x7f\xd2\x7e\x60\x4b\x4b\x74\xec\x36\xa4\x54\x2b\x16\x9b\xbe\xc8\x4b\x22\x74\xbd\x59\x94\x19\x7f\x4b\xde\xca\xb2\xa1\x73\x8d\x23\xd8\x7f\x55\xcc\x83\x11\x04\x07\xfa\x37\x7e\x87\xdb\x2c\xcf\x61\x46\x15\xb0\x44\x2e\xa7\x12\xde\x92\xb7\x30\x5b\xb9\xf0\x87\x11\x9c\xa7\xd4\x80\x8a\x49\x31\x10\xb2\x13\x66\x9e\xd0\x64\x04\xbc\xc4\xd4\x4f\x10\x29\x5d\x02\xe1\xb0\x20\x15\x87\xb0\xa8\xf3\x7c\x18\xb9\x8e\x28\x73\xb7\x6e\xed\xf9\xac\xb7\x12\xc5\x4b\x29\x6b\x1b\xed\xf7\x3a\x14\x2a\x92\x53\x21\xcc\xf9\xf6\x4c\x5f\xf5\x8b\x9e\x96\x79\xc9\xa2\xf7\xaa\xb2\x39\x6c\xa3\xd9\xe9\x98\x02\x52\x86\x96\x44\xb0\xec\x2e\xf0\x55\x54\x63\x7e\xe9\xb4\x83\x8c\x43\x51\x0a\x28\xe7\xa0\xda\x63\x94\xed\x01\xbc\xcf\x29\xe1\x14\x28\x5e\xa1\x21\x10\x97\x8c\xd1\x58\x60\xc2\x38\xe5\x3c\x2b\x8b\x28\xf0\x53\x6d\x94\x9c\xaf\x1b\xef\x18\x31\x59\x18\xcc\xc6\x17\x1b\xbd\x29\x78\x3b\x5a\x74\x6c\xbf\x29\x29\x6e\xc2\x45\x82\xeb\xb5\x8a\x06\x0e\xb2\xc6\x2e\x0a\x1d\x67\x32\x56\xcf\xb1\xab\xaa\xb8\x13\xc5\x6f\xd9\x37\x26\x3c\xd5\xa8\x26\xa4\x8e\xaf\x12\x9a\x81\x9b\x14\x0e\x0b\xd8\xd6\xb9\x79\x81\x9a\x14\xee\x28\x13\xfc\x1c\x79\xdd\x27\xfa\xb7\x7f\xd0\x11\x5c\x05\xab\xb8\x4f\x29\x67\x01\xa9\x9f\xd6\x20\xf2\xe7\x6e\xa2\x02\x28\x17\x87\x97\x6e\xd6\xc0\x6a\xe2\xec\x8d\xb8\x32\x15\xb4\x8b\xa3\xcb\x26\xa2\x6b\xd3\x1c\xd6\xc3\xc6\xbc\xce\xe5\xe1\x44\x4b\x60\x84\x5f\x43\xd5\x63\xdd\xe4\xfe\xa1\xe9\xd7\x49\x24\xe0\xce\xc2\x55\xe9\x4e\xc8\x31\x8e\x0a\x90\xe4\x39\x2c\x33\xce\xa5\xb5\x2f\x0f\xf0\xbc\xb9\xe7\x54\xd0\x5b\x6b\x65\x6a\x95\xa9\x96\x41\xe9\x98\xcf\x56\x89\x0a\x67\xdb\xb7\x2e\x85\x63\x10\x70\xe2\x97\xd3\x22\x91\xa5\xfb\xed\xd6\xb4\xf2\x72\x53\x9f\xe4\x79\x79\x8b\xd0\xe7\x52\x69\x48\xf4\xaa\x32\x2b\x04\x64\x05\x89\xe3\x9a\x91\xd8\x06\x99\xd1\x7a\x51\x66\xaf\x0d\x44\x4a\x1c\x1f\x3d\x02\x55\x7c\x51\x95\xfc\x32\xba\x83\x13\x39\x6e\x67\x58\x75\xe8\x77\xd9\x69\x27\xae\x54\xba\x03\xc4\x31\x4f\xab\x12\xaf\x7c\x6a\x46\xb5\x6d\xf5\x16\x88\xcf\x77\x13\x10\x23\xd0\xd9\x43\xeb\x61\x37\xfa\x09\x60\xef\x07\xdb\xbe\x0d\x63\x1b\x27\x35\xd9\xd1\xfe\xeb\x5c\xbe\xbe\x37\x0c\x60\xf3\x6e\x0d\x05\x8d\x93\xc8\x37\xc3\xf0\xe6\x0a\x5e\x8d\x26\xc5\x0a\x04\x23\x31\xe5\x52\x4d\x91\x02\xe8\x5d\xa6\xae\x3d\xa2\x1a\x8f\xfc\x9b\x14\x8d\xaf\xd0\x19\xae\xb9\x86\x11\xa7\x59\x9e\x30\x5a\x84\xc3\x9e\x48\x72\xd3\xb6\x95\x4f\x88\x15\x78\xb1\xc3\xab\x58\xb7\x6f\x88\xe8\x0c\x0b\x6d\xb6\x04\xea\x6a\xc8\xa9\x49\xa3\x38\x6e\x5f\x11\x69\x35\xd7\x77\x43\xba\xed\x1b\xf4\x3b\x97\x45\xb7\x35\xc2\xa1\x1a\xc7\x29\x2d\x12\xed\x36\xdd\xe8\x4f\x94\x94\x7f\x5a\x16\x37\x72\xed\x8a\x12\x7e\x7c\xfb\xea\x17\x3c\x4a\x71\x41\x96\x95\xb9\x2c\xea\x9c\x8d\x77\xf7\x5e\x7f\xf9\x02\xdf\x7c\xa7\x47\x38\x4a\xcd\xbd\xe5\xa8\xc7\xa7\x6b\xd0\x3c\xb0\x03\xd9\x69\x6e\xd7\x3b\xef\x49\x82\x29\x1b\x3a\x97\xfc\x36\x13\x29\x64\xc5\x4d\xc6\xb3\x59\x4e\x21\x90\xab\x22\x50\x0a\x93\x03\x51\x97\x41\xe3\xb2\x98\x67\x8b\x9a\xd1\x04\xee\x0e\x24\x13\x60\x56\xd6\x45\x42\x10\x00\x2d\x78\xcd\x28\x37\xe0\x45\x4a\x84\x92\x3c\x0e\x84\x51\x48\x32\x5e\xe5\x64\xa5\xaf\x97\x02\x81\x79\x76\xd7\xc0\x41\x2a\x78\x77\xac\x0a\x52\x55\x98\x0a\x53\xe2\xd0\x36\xb1\xc4\xc2\x97\x13\x37\xdd\xb0\x49\x93\xb5\xde\xa8\x9f\x8b\x43\xa9\x65\x4e\x1b\xaa\x39\x71\x44\x45\xa3\xba\xc0\xbb\xab\xa8\x0f\x6c\xab\x8e\x5e\x58\xb7\xe1\xfa\xda\xed\x00\x8e\x94\x36\xd3\x1c\xe9\x8c\x62\x55\x8e\x6e\xd0\x3b\x40\x73\x19\xed\x6d\x79\x0b\x31\xa3\x44\xa8\xab\xaf\xd2\xb6\xf1\x17\x71\xe7\x51\x03\xd7\xfa\x51\x49\xf2\x0a\x03\x9d\xe1\x31\x71\x84\xdf\xee\x7f\xea\xd2\xea\xa4\x71\xb8\x3b\x0b\x1b\xcf\xf8\xea\x0e\x6b\x38\x1c\xa1\x3a\x1e\xe9\xe3\x67\x22\xd2\x7b\xfa\xfc\x2c\xeb\xd1\xed\xf3\xdf\x87\x23\x78\x6c\xfb\xa9\x53\x19\x65\x93\x9e\x3b\x11\xdf\xeb\x04\x9b\x00\x26\x10\xe4\x59\x41\x8d\x1b\x14\x4f\x7f\x55\x99\x13\xed\xcf\x90\x75\x84\x69\xdf\xa7\xf1\x59\x58\x79\x57\xc5\xcb\x4c\xb6\x24\xb5\x28\x83\x91\x47\xd4\x17\x59\x91\xe0\x7d\x08\x4e\xb5\x64\x0e\x38\x2c\xc9\xdd\x78\x99\x15\x7b\x1b\x6e\x6b\x48\xa5\x2b\x58\xed\xde\x97\xfe\x39\xa5\x85\xb9\x96\x21\xed\x42\x75\xf7\x32\xb1\x7b\xf1\x92\xdc\x35\x7b\xf1\x3d\x6b\x51\x34\x1e\x16\x2b\x2d\xb2\x7f\x5c\x33\xa6\xca\xdf\xb8\x90\x00\x9a\x0e\x1b\x20\xca\xd2\xf7\x72\x47\x6e\x7b\xf7\x6c\x45\xb4\x82\xd3\xd6\x00\x8f\x1e\x81\x5b\xfd\xa0\x6d\x3b\xa2\xa9\xd3\x42\xc9\xe9\xd0\xe3\x7f\xb4\x5b\xa9\xa4\xc4\xfe\xd4\xef\xad\xa5\xdd\xdd\x30\x3c\x59\x8e\x14\xf9\x96\xe4\xee\xeb\xa3\xe8\xf0\xdb\xcd\xcd\xb2\xc2\xd0\xc6\xdb\xe9\x91\x03\x58\xf7\xaa\x98\x67\x45\x26\x56\xc7\x2d\xce\x1c\xf8\x15\xbf\x93\x43\xff\x1e\x26\x9c\x20\x8e\xbb\x90\x5e\xcd\xe5\x5e\x82\xf7\xf1\x78\xb9\x23\x67\x97\xbb\xf3\x73\xed\xdc\x28\x43\xac\xa6\xc8\xa6\x76\x62\x46\x3f\x33\x61\xbf\xf1\xa4\x6e\xe4\xa6\xfc\x3c\x30\xed\xfa\xae\x85\x6d\x06\x1e\x1e\x46\x47\x5f\xab\x80\x21\x99\xf1\x50\x16\x1e\x48\x78\xc3\xe6\x50\xb2\x65\xd8\xad\x10\xd6\xc6\xa9\x26\x45\xe9\x4e\x9b\x26\x5d\xbd\x1b\xa1\xf9\x83\xbe\xef\xcf\x4a\xcb\x4c\xfa\x54\xb6\x73\xd7\x63\xb5\x05\xd6\xaf\x5a\x95\x6f\x04\xa6\xf4\x5e\xc9\x32\x5a\x08\xab\x29\xe9\xdc\x24\x2f\x8a\x2c\xbe\x7e\xa1\xaf\x8f\x5a\xf8\x2f\xb2\x3b\x21\xb7\xeb\xe8\x6d\xbd\x9c\x51\x16\xa9\xfb\xa5\x7f\x7f\xf3\xc3\xf9\xa8\x67\xdf\x40\x14\xf5\xbe\xe1\x5e\x12\xf1\xc9\xa9\x5f\xf3\x68\x66\x96\x96\x37\x94\x3d\xa3\x82\x64\x79\xff\xfc\x5e\x36\x0d\x76\x9b\xa4\x42\xd3\xcf\x6f\x56\xfb\xc0\x08\xee\x46\xb0\xf2\x55\xa9\xce\x3e\x19\x9c\xf0\x8a\x14\xc6\x7c\x94\x85\x01\x26\xf7\xda\x70\xc5\x1d\x7c\x8d\x46\xdd\x30\x12\xe5\x8f\xe7\x4f\x95\xb3\x27\x1c\xaa\xdc\x5e\xd9\xf7\x74\x70\xec\x80\xe5\xb7\x44\xc4\x69\x17\x30\xce\xe3\x4a\xd5\x06\xea\x2a\xdb\x34\x98\x91\xf8\x7a\xc1\xa4\x99\x74\xa0\x4f\x8c\x2a\xaf\x18\x55\x08\x96\xc8\x61\xa4\x35\xdb\x1d\x28\x2e\x0b\x41\x0b\x3c\xc6\xa9\x21\xf7\x41\xcf\x36\xea\xf3\xb1\xa1\xb1\xa6\x1c\x6d\x13\x70\x9d\x8e\x2b\x3d\x13\x9d\x10\x6f\x86\x70\xf2\x6c\xb0\xc1\x8c\x21\x59\xcc\xa8\x4e\x91\xf6\x14\x37\x7e\x55\x1f\x8d\xae\x0d\x83\x1e\x0a\x73\x65\xbb\x87\xf1\xaf\xb1\xae\xd7\x46\x51\xdd\xac\x91\x72\xaf\x40\x38\xa3\x39\x79\xde\xfd\x43\xfe\x40\x53\x72\x93\x95\x2c\xd2\xea\xfb\xa5\xe9\x10\xc2\x4e\xa2\xa7\xf0\x9a\xe8\xdf\xfe\xe0\x3c\xa5\xf9\x8d\xb4\x56\x77\x1a\xf9\x1c\x2d\x86\xdd\x04\x7e\xd3\xa8\x6e\xe8\xda\xbe\x99\xb0\xd5\x31\xce\xb3\xdf\xfe\xc8\x31\xd4\x57\x5d\x0f\x5a\xfe\xa5\x1e\x4d\x60\x0f\x0a\x36\xf6\xfd\x47\xcd\xc6\x7b\x2c\x85\x46\xdd\xec\x90\x88\xd7\x93\x97\xb0\x25\x3b\xa0\x9f\x26\xf2\xbc\xad\xb1\xd0\xb7\x6e\x39\x54\x04\x9f\xcd\x71\x2f\xe5\xce\x4b\x66\x6d\x44\x75\x08\x42\x27\xaa\x73\x13\x97\x93\x1b\xba\xa7\x4f\x4a\xce\xfd\xdb\x27\x7f\x7b\xf2\x0b\x98\xe0\xa1\x3c\xd9\x94\x2c\xa1\x4c\x5d\xdd\x3d\xb0\x7e\x52\xc8\x84\x72\xe5\x3a\x63\x2a\x60\xb7\xd2\x3a\x95\x10\x6b\x4e\x99\x3c\x74\xc9\x33\x93\xba\x18\x80\xf8\xb8\x8f\x56\xd8\x6b\xbb\xda\x07\xe9\x1d\x1e\xfb\xaf\xfb\xa2\x43\x76\xab\x8b\xa2\xd7\x93\xfa\xb6\x44\x34\xd1\x65\xc4\x61\x2e\x35\x62\xcb\x3b\xda\xf5\x15\x9c\x93\x99\x7f\x5b\xdb\xbd\x86\xeb\x44\x8d\xec\xb5\xe0\x9d\xa4\xa0\x95\xeb\xd1\x4a\x1c\x24\x3b\xc9\x81\x4a\xe8\x6a\xee\x13\xdf\x8f\xa5\x4b\x69\xe5\x23\x37\x41\x93\x1f\xca\x64\x65\x48\xed\x80\xf3\x9f\x91\xb9\xc2\xdb\x90\x20\x66\x65\xa2\xef\xbd\x63\x3f\x2f\xdf\x8b\xdf\x66\x22\x4e\xc3\x56\xb4\x5b\xe1\x1f\x13\x4e\x21\xb8\xa1\xb1\x28\x59\x30\xd9\x73\x4d\x46\x3f\x2c\xed\x73\xd0\x0c\xa3\x1d\x25\xc1\x89\x60\xa7\x27\x22\x81\xb8\xcc\xe5\x5e\x35\x1d\x3c\x1e\x9c\x9e\x64\xa7\x85\x62\xec\xc9\x38\x3b\x3d\x19\x8b\x44\x7e\xb0\xd3\xe6\xda\x47\x3b\x67\xb6\x3f\x13\xbc\x27\x44\xee\x5f\x33\x44\x1e\x68\x5b\x55\x37\xbc\xc8\x2e\xdd\xdd\xd2\x06\xa0\xfa\xbc\xd4\xd6\x49\x7d\x7c\xdf\xd4\x4e\x5b\xa1\x38\x05\x52\x07\xcc\xe4\xd4\x74\x13\xed\x84\xbe\x38\xba\x6c\xaa\xdc\x59\xab\x79\xe2\xa5\x9c\x63\x4b\x7f\x1d\x69\xf8\xff\x98\xfe\x37\x7f\x9c\xfe\x37\x6d\xfa\xdb\xfb\x10\xe7\xf4\x4e\x5a\x38\x81\x0d\x4b\x58\xf4\x3e\x29\xf4\x3e\xc1\x09\xdc\x18\xaf\xbf\xc1\xed\x93\x7f\x05\xb5\x81\xb4\x3f\xb5\x8d\x2f\x3e\x5d\x6a\x0e\xc1\xff\x96\x5c\x73\xcb\x0f\x15\xe7\x66\x6c\x7c\x1a\xf8\xae\xdf\x3f\x29\x1a\x0e\x26\x3b\x4b\x86\x8e\xcb\x28\xc9\xe8\x1f\x5d\x35\xf1\x46\x72\x39\xb1\x49\x10\xdb\x03\xa1\x65\x7b\xff\x40\xd8\xc4\x1b\xc8\x99\xb5\x3f\xe6\x70\xcb\xa0\xda\x75\x39\xe9\xdd\x0f\x7e\x2c\x78\x5d\x55\x25\x13\x34\xd1\x17\x5b\x30\xa6\xd6\x01\xb2\x75\x6b\x67\x1b\x9e\x06\xed\xbb\x24\xde\x7e\x3f\xd0\xf3\x53\x3b\x36\xd5\x59\x7f\xb1\x6f\x6a\xd9\xdb\x84\x6e\x84\x0c\xc9\xd7\x20\x40\x0b\x91\x89\xd5\x1b\x75\x59\x16\x27\x16\x3c\x0a\x26\x10\x3c\x22\xcb\xea\xd8\xdc\x2e\x3b\xc1\x92\x5c\xd8\x82\x53\x2c\x58\xd8\x82\x41\x30\x98\xc0\xe0\xd1\xbf\xea\x52\x1c\xeb\x2b\xaf\xc1\x20\x90\x45\x5f\x7d\xf3\x17\x5b\x32\x56\x25\x77\x8f\x5f\x1c\x0f\xec\xc3\x32\xda\xc8\xd7\x67\x1a\x8d\x5e\x73\xe7\xf6\xe2\xd1\xc9\x69\x30\xf8\x38\xbe\x1c\x2f\x46\xce\xf5\x48\xde\xba\x61\x60\xa7\x71\xc1\x2f\x4d\x0c\x64\xed\x71\xe5\x3d\xe9\xbb\x96\xd2\x3c\x0c\x6b\x42\x56\x2d\x66\xca\x6e\xad\x57\x40\xfb\x39\x89\x40\x9a\x7b\x81\x08\x18\xdd\xe9\x3f\x9e\xbd\x6e\xc2\x18\x6e\xab\x5e\x9d\xea\x35\x50\x5e\xd9\x75\x93\x2f\xe3\xd5\x1a\xd7\x0e\x0e\x45\x92\x44\x59\xe5\xa0\x9f\x98\x45\x69\x0a\xbe\x22\x49\x72\xa5\x9f\xb6\xd2\x0f\x2f\x78\xcd\xd5\x5b\x60\xb2\x68\x04\x9f\xd7\xc3\xae\x85\xd2\x9a\xbf\x99\x51\x97\x06\x72\x76\x3a\xc5\x26\x2f\x63\x3c\xe6\x47\x9c\x12\xa6\x1e\x62\x0c\x82\x16\xc3\x4c\xa0\x59\x53\x0f\xb3\x06\xdf\x9b\x94\xd5\x7e\x38\x11\xaf\x67\x4a\x3e\xc2\xa3\x61\xc4\xab\x3c\x13\xe1\xe0\xd1\xc0\x26\x59\x37\x30\x5e\xd2\xbc\xb2\xc7\xac\xf6\x64\xfe\xd1\x6a\x16\xba\xe1\xb2\x36\x0c\x35\xe1\xa6\x0b\x0f\x1d\x4c\xb7\x52\xcb\x50\xd9\xa5\x96\x79\x3c\xd4\x17\x9c\x2e\xae\xca\x64\x44\x92\x3d\xb4\x0f\x77\x3a\xaf\xef\x69\xa7\x8a\x7e\xd6\x54\x29\x4c\xc9\x59\x65\x70\xfe\x78\xf6\xba\x61\xed\xd0\xa9\x56\xfa\xa4\xc5\xfb\xe1\x1e\xc0\xb0\x79\x61\x58\xad\x07\x25\x7d\x4d\x74\xea\xa1\x66\xef\x50\x9f\xd3\xba\xe9\x53\x26\xe4\x66\x4f\x71\xcd\x43\x38\x92\x4e\xe3\x31\xbc\x7d\x77\xfe\x7c\xd2\xba\x62\x3c\xa3\x70\x4d\x2b\x81\x17\xc9\x57\x45\xac\xc2\x2f\xe3\x5a\x64\xf9\x98\x0b\x66\x7e\xc7\x65\x71\x13\x2d\xca\x09\xc2\x7d\x9d\x15\xd7\x2f\x4a\xf6\xdc\xa6\x31\xdc\xc3\x03\x4b\x8f\xfe\x65\x8b\xec\x54\xca\xc7\xac\x5a\x3d\x7d\x2f\x7e\xbf\x50\x6b\x0b\xaf\xca\xba\x39\x0f\xad\x55\xaf\x28\xd0\x5c\x10\x36\x81\xc7\x3f\x2d\x9e\x0e\x88\x77\xb3\x4f\x34\x96\x4a\xa8\x23\xab\x0b\x5a\x50\x46\x84\x12\x57\xd5\xcc\x53\x38\x06\x7f\x2f\xe3\xe3\xa1\x0a\x6c\x87\x0e\x6c\x93\xdb\xa6\xde\x00\x55\x29\x45\x8f\xf4\xc3\x72\x69\xc6\x45\xc9\x56\x28\x1c\xf2\x08\x42\xc3\xcf\xeb\x11\x04\xc1\x08\x54\x98\xf4\x7b\xb9\x21\x3b\x44\xdd\xba\x46\x1c\x81\x74\x39\xa4\xe4\xae\x47\x47\xbb\x2c\xd2\x6f\x35\x34\x9d\x86\xf0\x59\x4f\x6b\x81\x6e\x00\x6c\xd7\x93\xf6\xd9\x4b\xe9\x96\x80\xec\xd2\xa5\xad\x19\xff\xe1\xa9\x31\x0b\xcd\xd5\x19\x56\xf2\xf0\xe0\x4c\x13\xbf\x0b\xce\x4e\x4d\xeb\x55\x71\x43\xf2\x2c\xe9\x51\x3b\xea\x59\x04\x57\x6d\xa9\x6e\x54\xc4\x86\xd5\x2f\x58\xb9\x7c\xa7\x06\xd0\x00\xba\xc3\x8d\xe0\x70\x47\xca\x44\xcd\xe8\xca\x51\x0b\x53\x18\xff\x73\xf1\x31\xd9\xff\x18\x45\xfb\xd3\x68\xff\xe1\xf8\xf7\x11\xab\x67\x86\x2e\xbd\x50\x22\xcf\xeb\x2a\x37\x91\x0d\x3d\x4d\xa7\xbc\xc3\xfb\xa6\xae\xb5\xd3\xfc\xee\xc9\x45\x82\x72\xe1\xc2\x3b\xee\xcf\x1d\xde\x3a\xc9\xfb\xf8\xb1\x41\x3c\x46\x4a\x64\x5f\x35\x7a\x46\xee\xab\x4e\x83\xc6\x68\x68\x6c\x86\xfe\x2d\xb5\xc2\xe7\xb3\xdf\xcd\xa5\xb6\x45\x78\xde\xfb\x29\x08\x4d\xbd\xb0\x1d\x3a\x43\x9a\xbd\xb4\x40\xaf\xfb\xbb\xb9\x1a\xf4\x45\xc9\x24\x14\xb3\x48\x5d\x74\x76\x66\x43\x53\xa1\xf2\x7c\xf8\xcf\x99\x48\xc3\x0e\x92\x9a\xd8\x36\x0d\x5d\x53\xe0\x3e\x7c\xb6\x53\x62\xdb\x24\xa4\x2d\x11\xd3\xf0\x70\x74\xcf\xbc\x95\xfa\xeb\x05\xd5\x2d\xf4\x37\x8f\x9d\x68\x62\x6d\x9b\x0e\x49\x34\x2d\xdc\x47\xe5\xfc\x37\x25\x1a\x5b\xd3\x59\xdd\xef\xe6\xef\x0a\xbd\x0b\x77\xf1\xb3\x7c\x56\x40\x9e\xc4\x71\xbd\xac\x73\x22\x30\xf7\x7c\x07\x65\xb2\x41\x62\x61\x5f\xdf\x79\xeb\x80\xb5\x69\x0c\xcd\xcb\xeb\xed\x57\x17\x9c\xd6\xbf\x7b\xa9\x6d\x9e\xfc\x76\x35\xec\x3d\xcd\x01\xbe\x70\x77\x22\xae\x2e\x13\x9b\xde\xf2\xa4\xfd\xa4\x48\x4c\xda\xac\x50\x1c\x55\x06\xea\x74\xe0\x6c\xe0\x4d\x73\xfb\xcf\x26\xdc\xbe\x17\x87\xea\xf1\x0e\xb7\xb1\x01\x9a\xd0\xb8\x4c\xe8\x8f\x67\xaf\x9e\x96\xcb\xaa\x2c\x68\x61\x68\xe9\x01\x38\xba\x6c\x8e\x4e\x1f\xf7\xe5\x99\x29\x80\x60\x38\xd4\x50\xe5\x4a\x72\x51\x98\x42\x20\xc8\xcc\xc9\x4e\xf6\x87\xb4\x37\x25\x9d\x62\xf5\x2c\x9c\x20\x33\xc8\x38\xa6\x3f\x2c\x28\xd3\x8e\x03\xd7\x20\xbd\x68\x86\xb9\xb4\x53\xfd\xc9\xbc\xe2\xb1\xee\x61\x7f\xf7\xd1\x8d\x6d\x4c\x6f\xeb\x31\x97\xd5\x8e\xa1\xa6\x47\x09\x16\xd2\x32\xc9\xb4\x98\x06\x51\x37\xb5\x7c\xdb\x78\x3d\xe6\x55\xc7\x62\x69\x59\x5a\x56\xca\x2a\x83\x61\xbf\x06\xce\x3c\xe5\xeb\x9b\x79\x4a\x2c\xd5\xd7\xe8\x9a\xae\xb8\x37\xd2\xb0\x2b\xa4\xd7\xcd\x33\xf7\x0e\xa4\x0b\x8d\xc2\x3e\x5c\xd3\xd5\xa5\xb1\x55\x35\x94\x0b\x59\xd6\xc9\x1d\x74\x7a\xb7\x1c\x0a\xf2\x18\xac\x8d\x68\x75\x87\xf0\x03\x15\x75\xa5\x83\x29\x31\x89\x53\x3a\x51\xaf\xf6\x35\xcc\xf6\xee\x1a\xf6\x3e\x74\xc7\x05\x11\x59\x3c\xfe\xc4\xc7\xea\xb0\x63\xff\x4b\x44\x6a\xfe\x73\xc4\xf7\x37\x53\xc9\x44\xef\xdf\x3d\xe8\x5c\x9b\xce\x8d\xc2\x84\x08\x22\x31\xd4\x92\xed\xfd\x0b\x07\xed\x26\x34\x7e\x35\xfb\xef\x1e\x50\xe0\x55\x4f\x53\xa7\xf2\xd9\x9f\xd1\x8a\xd1\x98\x08\xaa\xce\x73\x78\xa4\xf7\xb3\x79\x93\x8c\xd1\x58\x9c\x97\x6f\xb2\x85\x94\x91\xc4\x9e\xfa\xa1\x2f\xd7\x13\xff\x7b\x8e\x72\x48\xf4\x9c\x01\x42\x27\x67\x14\x85\x52\x91\xbb\x9b\x01\xaa\xbd\x1c\x78\xb4\x3a\x4f\x29\xa7\x20\x6e\x4b\x7d\x8d\x93\xf7\xe3\x8d\x09\x46\xbd\xe8\x0e\x25\x14\xc2\x28\x90\x24\xa1\x09\x94\x45\xbe\x42\x57\xe7\x8c\xc4\xd7\xb7\x84\x25\x78\x5f\x8f\x88\x6c\x96\xe5\x99\x58\xc9\x93\x5b\x99\x27\x4a\x46\x74\xd8\x3b\x72\x04\xa4\x97\x64\x1b\x1d\x05\x29\xe1\xe9\x3d\x96\x4d\xf3\x00\xa4\xd9\xfc\x94\x36\x4c\x5e\x30\xb2\x58\xaa\x08\x74\x8f\x7e\xec\x1b\x45\x45\x27\xd8\xca\x32\x03\x2f\xc0\x69\xc6\xfb\x40\xf5\x9e\x1c\x1e\x0d\x95\xd2\x4b\x58\x59\x61\xa0\x4a\xc2\x81\xaf\x30\xb3\x27\xc6\xb0\x77\xe8\x24\xd4\x75\x51\x6e\xac\x74\x26\xd5\xdf\xda\x59\x47\x1b\xe4\xc6\xaa\x8d\x3f\x37\xcd\x9e\x03\xea\x9f\x99\x6d\xbf\x6a\x6a\x7b\xa5\x3c\xcb\xa7\xf4\xd5\x61\xb3\x6f\x5a\x7d\xd8\xa3\x96\x65\x1b\x57\xdd\x95\xbb\x68\xba\xfb\x75\x5d\xd9\x52\x73\xe0\xfd\x93\x0a\x3b\x31\xbc\x12\xdd\x7f\x1c\x6e\x11\x59\x62\x3e\x6e\x1d\x78\x91\xb5\x0f\x43\xb9\x58\x87\xc7\x7b\xff\x27\x00\x00\xff\xff\x57\xd6\x43\xf5\x21\x6b\x00\x00") var _webUiStaticJsGraphJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xe4\x7d\x6b\x77\xdb\x38\xb2\xe0\x77\xff\x8a\x0a\x3b\x27\xa2\xda\x32\x65\xa7\x6f\xf7\xde\x91\x2d\xf7\xa6\xf3\x98\x64\x26\xaf\x71\xdc\xaf\xe3\x78\x7c\x20\x12\x12\x19\x53\x24\x07\x00\x6d\xab\x13\xfd\xf7\x3d\x28\x3c\x08\x90\x94\xa5\xee\x9e\x9d\xb3\x7b\xae\x3f\xc8\x16\x1e\x85\x42\x55\xa1\x50\xa8\x2a\xc0\x37\x84\xc1\x7b\x56\x2e\xa9\x48\x69\xcd\x61\xea\x7e\xf9\xf2\x05\x3e\xaf\x8f\xf7\x64\x93\x05\x23\x55\x7a\x4e\x97\x55\x4e\x04\x3d\xde\xc3\xb2\x0f\xcf\x9f\xbe\x7b\xfb\x0c\xa6\x70\x74\x78\x78\x78\xbc\xb7\xd7\xf4\x8c\xfe\x2a\x9b\xc3\x14\xe6\x75\x11\x8b\xac\x2c\x42\x9a\xd3\x25\x2d\xc4\x08\xca\x4a\x7e\xe7\x23\x48\x49\x91\xe4\xf4\x69\x4a\x8a\x05\x35\xdf\xce\xe8\xb2\xbc\xa1\x43\xf8\xbc\x07\x20\xd2\x8c\x47\x34\x87\x29\xe8\xbe\xc7\xa6\x10\x71\x79\x79\xfe\xe6\x35\x4c\xa1\xa8\xf3\xdc\x56\x68\xd8\x30\x35\xa3\xd8\x1a\x77\x30\x98\x7a\x63\xb7\xda\x28\x14\x5c\xd4\x15\x3a\xe0\xa1\x18\xca\x1e\x43\xd9\x75\x6d\xfb\xb3\x2c\xbe\xe6\x29\xb9\x35\x73\xf7\x50\x4b\x88\x20\x30\x85\x8b\xcb\xe3\x3d\x53\x94\x15\x99\xc8\x48\x9e\xfd\x46\xc3\xe1\xf1\xde\xba\x87\x80\x91\xc8\x96\xf4\x05\x89\x45\xc9\xe4\xa4\x24\x1a\xc1\x2a\x98\xc0\x77\x87\xf0\xb5\xfa\x78\xfc\x5f\xf0\x35\x7c\xf3\xdd\xb7\x23\x59\x75\xdb\xad\xfa\x5f\x58\x91\xb4\x2a\xb0\x30\x6d\x0a\xf1\xfb\x12\xbf\xe3\x9f\x3c\x98\xc0\x51\x3f\x46\x5c\xd0\xea\x27\x92\xd7\x54\x22\x74\x21\x1b\x1f\xf1\x60\x04\xc1\xd1\xa1\xfa\xb5\x94\x9f\xdf\xe2\xe7\x91\xfa\xf5\xcd\xa1\xfa\x96\xca\xcf\xc7\xf8\xf9\x1d\x7e\x1e\xa9\x2f\x47\x09\x56\x24\x01\x0e\x7d\x74\x8b\xdf\xf0\xf3\xbf\xf0\xf3\xbf\xf1\xf3\x68\x85\xe5\xab\x60\xef\xb2\x0f\xad\xa2\x5e\xe2\x1f\x12\xab\x3e\x51\x8c\x2a\x56\x8a\x52\xac\x2a\xea\x90\xbd\xcb\x64\x29\xd5\x9c\xe6\x73\x98\x22\x8b\x24\xf7\xe4\xd7\x28\x4b\xbc\x85\xd1\x1e\x74\x7f\x1f\xb9\x3a\x1e\xc3\x07\x2a\x20\xa1\x73\x52\xe7\xc2\xc8\x60\x64\x80\x98\xef\x08\x4c\x83\x3d\x6e\x57\x32\x29\x92\x57\x59\x51\xd5\xc2\xb4\xea\xab\xfa\xf2\x05\x29\x2a\xbb\x67\x73\x08\xbd\x76\x82\xcc\x60\x3a\x9d\x42\x5d\x24\x74\x9e\x15\x34\x31\x02\xdc\x6d\x05\x47\x28\xc2\x1a\xf9\x67\x8c\xdc\xaa\x85\x0e\x71\x59\x08\x56\xe6\x1c\x48\x91\xe0\x17\x92\x15\x94\xc1\x9c\x95\x4b\x78\x89\xeb\x60\x46\x18\x07\xa1\x15\x42\xb4\xa7\x89\xd7\xac\x40\x35\xe4\xa0\x22\x22\x7d\xcf\xe8\x3c\xbb\x1b\x4c\xe0\xfd\x93\xf3\x97\x57\xef\xcf\x9e\xbf\x78\xf5\xcb\x48\x55\xcf\xea\x2c\x4f\x7e\xa2\x8c\x67\x65\x31\x98\xc0\x0f\x3f\xbe\x7a\xfd\xec\xea\xa7\xe7\x67\x1f\x5e\xbd\x7b\x6b\x16\xd7\xa7\x7f\xd4\x94\xad\x22\x7a\x27\x68\x91\x84\x56\x7f\xb8\xb3\x19\x5a\x3a\xba\xba\xe1\x61\xf8\xa6\xe6\x82\xc4\x29\x8d\x18\x2d\x12\xca\x42\x4f\x8b\x59\x5d\x34\x6c\xba\xd3\x3c\x22\x55\x25\xc7\xf1\xa1\x0d\x0d\x83\xff\x4a\x05\x30\x3a\xa7\x8c\x16\x31\xe5\x20\x4a\x20\x79\x0e\x22\xa5\x90\x15\x82\x32\xca\x45\x56\x2c\x8c\xc6\xe2\x90\x15\x58\xd7\x10\x55\xd1\x91\x14\x89\x02\x37\xcb\x8a\x04\xe8\x0d\x2d\x84\x56\x2f\x0c\xe5\xc5\x6a\xdc\x9f\x99\x44\x87\x19\x51\xa0\x79\x34\xcf\x8a\x24\x0c\xbe\xc2\xda\xab\x5b\x55\x1d\xc0\xbe\x11\xa8\x66\x2a\xff\x92\x54\x7b\x51\xb2\x25\x4c\x3d\x58\x1a\x82\xaa\xbf\x9a\x97\x6c\x19\xa8\xd9\xa9\x11\xee\x2a\xd6\xdf\x41\xd0\x3b\x41\x18\x25\x17\x05\x59\xd2\xa9\x6c\x77\x19\x38\x84\xbb\xab\x58\x74\x4d\x57\x15\xa3\x9c\x87\x8d\xda\x37\xb2\x37\x1e\xc3\x73\x49\x20\xb8\x25\x1c\xb0\x11\x4d\xe0\x36\x13\x69\x59\x0b\x24\x11\x4f\xb3\xb9\x80\x6b\xba\x8a\xb0\xbd\x94\x6a\x1a\xdd\xa6\x59\x9c\xc2\x74\x0a\x47\xdf\xc0\xa3\x47\xf0\x80\x46\xd8\xec\xef\x74\x65\xe0\xb6\x27\x1b\xf1\x7a\xb6\xcc\x44\x88\x98\xc9\x1f\x1a\x55\x0c\x09\xfc\x4c\x2d\x4b\x53\x83\x42\x8f\x78\x3d\xa9\x45\x79\xc0\x28\x97\x1a\x41\x62\x22\x27\x0a\x72\xa6\x50\x16\x80\xcb\x4d\xa1\x84\xf2\x3d\x9f\x73\x2a\xb4\x7a\x88\xd4\xb7\x97\x34\x5b\xa4\x02\x0e\x54\x59\x9c\x67\xb4\xd0\x65\xc7\xb6\x9f\x02\x7f\xae\x49\xe8\x6f\x8c\xcd\x54\x00\x1e\xca\xef\x51\xcc\x79\x38\x48\x11\xc4\x60\x04\x03\x52\x8b\x72\xd0\x2e\xa5\x79\xc4\x63\x56\xe6\xb9\x1e\x7e\x5f\xe3\x66\xa6\xa7\x7e\x3d\x54\x1b\x55\x54\x16\xe1\xe0\x9a\xae\xea\x4a\x4d\x68\x30\xf2\x34\x5f\x0b\x3d\xbd\xb9\xc1\x5a\x6d\x70\x2d\x26\xc7\xb8\x6b\xaa\xf5\xe1\xee\xa3\x8e\x10\xa1\xa6\x7a\xe5\xea\xb0\x86\x3f\x4a\x98\x10\x0b\x25\x49\x8e\x5a\x73\x05\x4a\x2e\xdc\x6b\x9a\xfc\x20\x8a\x4d\x30\x4c\x93\xab\x99\x28\xba\x1d\x77\x18\x59\xb7\x74\x47\xcd\x0a\x4e\x99\x78\x43\x05\xcb\xe2\x4d\x10\x38\xcd\x69\xac\x41\xa8\xf6\x57\x4b\xec\xe0\x02\x62\x74\xce\x28\x4f\x5f\x49\x99\xbf\x21\xf9\x2e\xb0\x74\x97\x4b\x77\x39\xc6\x65\xc1\xcb\x9c\x9e\xa3\xb2\xee\x5b\xc5\xba\x41\xd0\xd2\x80\xb2\x03\x6c\xe8\xa2\x54\x87\x55\x46\xee\x70\x82\xcc\x78\x7f\x2f\x72\x21\x2d\x98\x03\x51\x2e\x16\x39\x9d\x0e\x04\x99\x0d\xdc\xe9\xca\x8e\x11\xfd\x57\x67\x23\x1a\xca\x8f\x30\xe0\x69\x79\xdb\x6e\x5d\x16\xaa\xbc\x88\x66\xd8\x34\x70\x64\xd2\xaa\x0d\xb9\x76\x04\x61\x0b\x5c\x73\x0f\x43\x1a\xa9\x2f\x5a\xc8\x7b\x36\x34\x55\x1f\x55\x84\xd1\x42\x84\xc3\x28\x2b\x12\x7a\x17\xba\xed\x5d\x99\x35\x15\x52\xdb\x3c\x0c\x83\xaf\xa4\x22\xd5\x10\x88\x10\x2c\x0c\x08\xcb\xc8\x81\xd9\x0c\x83\xe1\x30\x4a\x09\x7f\x9a\x13\xce\xc3\x80\xd1\xbc\x24\x49\x30\x6c\x69\x22\xa5\x7f\x70\xcb\x6a\x54\x8d\x5a\x45\x4a\xe5\x9f\x51\x51\xb3\x02\xa4\x15\xc9\x61\x5e\xc6\x35\x87\x19\x89\xaf\xe5\x56\x82\xca\x37\x2b\xb8\xa0\x24\x81\x72\x0e\x0a\x96\xdc\x51\xa2\x3e\x01\x8d\x66\xc8\x9a\x6b\xba\x4a\xca\xdb\x42\xda\x47\x0c\x61\xf7\x52\xb2\x59\xc0\x38\xa6\x47\x12\x2c\xbe\x21\x79\xe8\x7f\x1b\xea\x36\x0a\xea\x06\x4d\xba\x1e\x36\x7b\x07\x63\xe5\x86\xcd\x43\xd5\x05\xc3\x28\xcd\x12\x4d\xf5\x46\x58\x9f\x28\x95\xb8\x59\x56\xa5\x52\x6a\x4b\xb8\x59\x51\x16\x82\xd7\xc5\x69\xbd\x7a\x72\x97\xf1\x8d\xad\x57\x57\xe4\x2e\xe3\x4e\xf3\x9c\x2e\x68\x91\x6c\x40\x47\x55\xba\xca\xa6\xca\x8a\x82\x6e\x9a\xb4\xae\x75\xb7\xc9\x1b\x92\x7f\x10\x44\x6c\x58\x65\x58\x7f\xc5\x65\x03\x6f\x53\x2e\x92\x67\x44\xd0\xfe\x3e\x8e\x42\xa3\x45\xd2\x55\xa4\xba\xb3\x3c\x81\x50\x79\x9e\xa8\xb2\xf8\x9a\xb2\x50\x49\x45\x5e\xc6\x24\xa7\x13\x18\xd0\x62\xa0\x4c\x32\x69\x10\x10\x31\x81\xc1\xaf\xbf\xfe\xfa\xeb\xc1\x9b\x37\x07\xcf\x9e\xc1\xcb\x97\x93\xe5\x52\xd7\x8b\xb2\xcc\x67\x84\xbd\xcf\x49\x8c\x36\xce\x04\x06\xb3\x52\x88\xd2\xd4\xf3\x2c\xa1\x3f\xac\x3e\x64\x09\x9d\x80\x60\x35\xd5\xa5\x69\x79\x7b\x5e\x26\x64\xf5\x43\x2d\x44\x59\xb4\xab\x9e\xe6\x94\xb0\x6e\x61\xc9\x1d\x20\x6a\x1f\xea\x58\xbb\x76\xce\xbe\xa0\x37\x93\x26\xe1\x40\xfe\x79\x9e\x2d\xe9\x7b\x9c\xfa\x60\x88\xb4\xd8\x04\x46\x59\xc4\x2d\x38\x52\x59\x25\x95\xde\xfb\x82\xd6\xee\xd9\xb3\xee\xdd\x5d\xb3\xb5\x15\x98\x0d\xb4\x0b\xa2\xae\x24\x5e\x67\xaa\xb9\x01\x62\x17\x3e\xff\x60\x37\xb6\xce\xd1\x54\xaf\x50\x77\xff\x53\x2b\x18\x0f\x02\x83\xa3\x81\x3e\xa9\x9a\x23\x8e\x58\xe5\x14\xc1\xa9\xed\xb5\x03\x4f\x36\xca\xe2\xd2\x6e\xbd\xcd\x66\xac\x84\x6e\x10\x2d\xf2\x55\x95\xca\x26\x03\x47\x85\xfa\x88\x86\x1d\xd5\xd8\x40\x21\x49\xa2\xd5\xe8\x4c\x14\x07\x15\xcb\x96\x84\xad\x02\x6b\xb4\x49\xc0\x4e\x1b\x3b\xd8\x41\x9c\xd2\xf8\xba\xd5\x8e\xe1\x89\xbc\xd3\xb4\x2e\xb0\x31\x4d\x4c\xf3\x35\xd0\x9c\xd3\x8d\x28\x79\x60\x7e\x1f\x56\x9d\xa1\xee\xc7\xcc\x9b\xc4\xda\x1c\x73\x3c\xa6\x84\x0e\xe7\x1d\x1c\xe3\x3c\x8b\xaf\xc3\x0e\xbb\xfa\x68\x2f\xed\xe5\x46\xe5\xfd\xed\xc3\xbb\xb7\x0d\x37\xc6\x63\x78\x35\x77\x0e\x26\xd2\x26\xd7\xa3\x8c\xb0\xb8\x64\xd9\x22\x2b\x48\x0e\x9c\xb2\x8c\x72\x40\xef\xc5\xa2\x14\xb0\xac\x05\x11\x34\x69\xe0\x84\x5c\x2a\x90\x64\x88\x07\xc5\x5b\x0a\x05\xa5\x89\xdc\xca\x18\x95\x96\x89\x60\x75\x2c\x20\x13\xea\xe0\xe8\x41\x96\x18\x21\xdc\xc8\xe5\x87\x76\x93\x28\x2b\x81\x91\x82\x4b\x75\xf4\x4c\x2e\xe2\xd6\x5c\x1a\xe2\x41\x57\xec\x3b\xb4\xf8\x1e\x06\x87\x03\x98\xc8\x95\x60\xf6\xbd\x36\xb5\x2d\x20\xb5\x0a\xf1\x60\x1f\x5a\x03\xb8\x73\xa8\x32\xe7\x8c\x0e\x2f\x5a\x66\x9b\x23\x2f\xc6\x60\x70\xc6\x32\xb6\xda\xfd\xad\x7a\x4c\x0a\xbd\xe0\xe7\x24\xe7\xb4\x65\xa4\xeb\x4d\xc7\xee\xb4\x5d\xd4\xd5\xbe\x31\x43\x4d\x6c\xcc\xd8\xf8\x0a\xed\xf0\xcb\x60\xd8\x23\x64\xc6\xf4\x88\x19\x25\x9c\x9e\x69\xcb\xc9\x1d\xf4\x3e\xe0\x09\xdd\x01\x78\x42\x7b\x80\xef\x8a\x3a\x2d\x92\x5d\x10\x7f\x5e\x24\xbf\x13\xed\x2d\x80\x0d\xd2\x0e\xe0\x5e\x3b\xad\x47\xe3\xb7\x8c\x2f\x75\x0e\x90\x75\x01\xa3\x95\xdc\x5b\x83\x11\x7c\x96\x27\xd1\x49\x0f\x3c\x54\xed\x23\x58\x96\x72\x93\x0d\x66\x74\x5e\x32\x1a\xac\x3b\x16\x9d\x31\xf4\xe4\x3a\x65\x14\xbf\x65\xc5\xa2\x91\x68\x75\x30\x95\x2a\x4a\x6d\x03\x3d\xc6\x85\x39\x99\xc8\x46\xda\xa8\xb0\x3d\x36\x69\x23\xbd\xe9\xa1\x9b\xf4\x1e\x71\x35\x94\xaa\xca\xaa\xce\x89\xa0\xaf\x70\x86\x64\x96\x53\x35\x4b\xae\x85\xd7\x2a\x37\xc7\x2e\x75\x47\xea\xac\x8e\x75\xbf\xe7\xb2\xf1\x00\x6e\x1c\x71\x27\x87\xe0\xc3\x88\x7c\x22\x77\xa1\xd1\xa5\x72\x90\x32\x99\x40\xf0\xd7\xe7\xe7\xc1\x48\x17\xd6\x2c\xf7\xbc\x5d\xb0\x0f\xc1\x98\x54\xd9\xf8\xe6\x68\x9c\x93\x19\xcd\xc7\x57\x57\x92\xb2\x57\x57\xe3\x1b\x74\xa6\xda\x9e\x52\x01\x9e\xaf\x2a\xc9\xd7\x4f\xbc\x2c\x6c\x39\xaf\xe3\x98\x72\x3e\x69\x10\x94\xd5\x23\x74\x56\x48\x83\xb2\xe6\xae\x1b\x41\xd2\x4c\xd6\x4b\xad\x28\x6a\x0e\x0f\xa6\x53\x08\x34\x88\xc0\x6d\x68\x68\x98\x96\xb7\xcf\xa5\x85\x1e\x06\xf8\x0b\xa4\x0e\xca\x8a\x05\x90\x1b\x92\xe5\x92\x42\xa0\x8e\xb8\xfc\x41\xb3\xc5\x35\x8c\x6d\x4a\xd6\xf6\x2f\x49\xb9\xa5\x25\x2b\x22\x23\xe7\xd6\x34\x9d\x97\x0c\x42\x34\x34\xd0\x67\x0b\x19\x9c\x98\x0e\x51\x4e\x8b\x85\x48\x8f\x21\xdb\xdf\xef\xc1\xd6\x5d\x0b\x17\x87\x97\xd6\x86\x23\x49\x12\x16\xf4\x16\xde\xe1\xf7\x50\x03\xbb\xc8\x2e\x47\xd0\xfc\x3d\x1c\xba\xd8\xee\x79\x80\xe7\xf5\x6f\xbf\xad\xce\x28\xaf\x73\x61\x3d\x98\xea\x07\x15\xc5\x04\x5d\xfa\x23\x6f\xfa\xb2\x6d\xb7\x7c\x49\xaa\x09\x7c\x5e\x6f\x1c\x08\x45\x59\xca\x22\x49\x29\x49\x42\x6f\x86\x65\xcd\x62\x3a\x31\x18\xbb\x50\x33\x41\x97\x7c\x02\x01\xc9\xf3\xc0\x1f\x4d\xc4\x29\x65\x8e\x6c\xc8\x96\x3e\xe1\xcc\xa6\x7f\x4b\x21\x25\x37\x54\x63\x8e\x4c\x88\x6b\x26\x0f\xcb\x6a\x8e\x23\xe0\xd7\x59\xe5\x75\xb4\x0b\xd0\x21\x8f\xd2\x9c\x28\x57\xe8\xf5\xc2\xaf\xed\x11\xbb\x54\xd5\xdd\xdc\x4e\xc7\xdb\xba\x2c\x49\x25\x99\xb1\xde\xda\x90\x19\xc6\x61\x61\x34\xcf\x72\x41\x59\xd8\x8c\x14\x69\xcd\x1a\x8e\x61\xbc\x18\xc1\x60\x30\xb4\x72\x31\xea\x60\x0e\x50\x31\x79\x2e\x3a\xe1\x82\x95\xc5\xe2\x74\x30\xea\x36\x28\xb9\x3c\xfd\x9c\x8c\x4d\x93\x56\x8b\xf5\x70\x47\x94\xa3\x79\xc9\x9e\x93\x38\x6d\x54\x29\xeb\x92\xb2\x9f\x32\x17\x2c\x32\x16\xd5\x25\x4c\x81\xb5\x47\x6c\xe3\xe0\x08\x22\x34\x7a\x59\x8a\x0b\x64\x45\xef\x08\x6e\xff\xf5\x68\xcf\x93\x54\x26\x3a\x52\xc7\xdb\x98\x63\x61\x24\xdb\x36\xd3\x23\xa3\x59\x77\x82\x46\x15\xf4\x4e\x73\x76\x19\xf1\xb8\x64\x14\x0e\xfa\xeb\x89\xae\x6f\xcf\xdf\x4c\x10\xcf\x41\x87\xf0\x3d\x90\x48\x1d\x79\x9f\x96\xcb\x8a\x30\x1a\xce\x86\x30\x81\xac\x45\xa4\x16\xd1\x1c\x2a\xf1\xcd\xe4\x48\xb3\x45\x9a\x67\x8b\xd4\xa3\x09\xf4\x2e\x45\x0d\xf0\x61\x38\x38\x49\xb2\x9b\xd3\x81\x71\xdf\xb7\x67\x25\xfb\x5e\x46\x5c\x30\xa9\x8a\xf7\xa5\xa8\x61\xf3\xa1\x8f\x43\x1f\xda\xe3\x31\x9c\xa7\x19\x47\x73\x1c\xa3\x14\x29\x86\x35\x80\xcc\x05\x65\x40\x84\x20\x71\x2a\x81\xa2\xbf\xdb\xe8\x21\xa8\xf2\x7a\x91\x15\x23\x20\x1c\x32\xe1\xc2\x2a\x45\x4a\xd9\x6d\xc6\x29\xcc\x18\x25\xd7\xbc\xd5\xcf\xcc\x96\xe4\x99\x58\x45\x3d\xaa\xce\x73\x39\x39\x48\xa3\x57\x68\xd2\x3d\x7f\xc2\x9f\xda\x98\xd6\xc6\x5d\xb0\xc5\x0e\x58\x50\xf1\xce\xc6\xab\xb6\x6f\xfc\xad\xf8\x56\x73\x9c\x56\x85\xe8\xef\x36\x51\x51\x80\xc0\xf1\x6b\x6b\x6d\x1d\x58\x27\x83\x29\xe0\x82\x56\xed\x12\x3c\xb3\x04\x7b\x00\x97\x9b\x0d\x60\xd5\x65\x18\x51\x4f\x6b\xa0\xaf\x73\x64\x82\x4f\xee\x59\x5e\xda\x1a\x4d\x20\x3d\x92\x5f\x1d\xc7\x67\x94\x15\x4f\x18\x23\xab\x50\x96\x8f\xbc\xe9\x0c\xe1\x74\x0a\x87\x0d\x5b\x30\x2c\xa3\xa1\xa0\xe5\xa2\xb7\x6a\x38\x75\x5b\x81\xa1\x13\x9a\x8f\x97\xce\xc8\xd8\xc7\xf2\xc9\xf3\x8e\xda\x4e\x26\x06\xd5\x32\xfa\xdc\x16\xca\xd7\xdb\x76\xff\x2a\xeb\x14\x97\x96\x8d\xff\x6f\x33\x05\x09\xe3\xf4\x59\xcd\x08\x2e\x56\x47\x0a\x90\x7b\xe7\xf4\x4e\x34\xe2\x80\x45\x67\xcf\x61\x0a\xd2\xc8\x38\xa3\x8b\xe7\x77\x55\x18\xfc\x33\xbc\x38\x3c\xf8\xcb\xe5\xfe\x30\xbc\x58\xdd\x26\xe9\x92\x5f\xee\x0f\x1f\x2a\x59\x44\x13\x08\xf7\x66\x29\x16\x16\x62\x84\x65\xa1\x06\x67\xbd\x5a\x0f\x74\x53\x15\x8f\x41\xb3\x0a\x69\x23\xeb\x74\x95\x21\xf6\x83\x29\x7c\xd3\x72\xfd\x7c\x77\x68\xfc\x56\x72\x54\x24\x33\x4c\x01\xa7\xf7\xaa\x10\x06\xc0\xc5\xd1\xa5\xc5\xac\x2e\x32\xb9\x59\x9a\x9a\xc7\x97\x0e\xf9\x54\xff\xaf\xbb\x21\x6f\x27\x21\xe1\x42\x02\xb8\xdc\x4a\x61\xef\xd4\xb8\xf3\x3a\x43\xe2\x7c\xa0\x71\x59\x24\xd6\x77\xeb\xf1\x2a\x6c\x05\x9a\x1c\x87\x75\x9f\x61\x79\x4f\x1e\x43\x9f\xb1\x29\x69\xee\xa1\x70\xd2\x87\xc2\x3d\x40\xd1\xd0\xf4\x5d\x4d\x2d\x5c\xb7\x74\x3e\x76\x16\xdc\x86\xd3\x0f\xdc\xe3\x1f\x68\x2c\x71\xd7\x42\x5f\xef\x72\x3a\xf2\x4e\xe2\xff\x79\x86\x6d\xe7\x14\x1c\xc0\x91\xe4\xea\xa9\xe2\xee\xc1\xc1\x46\xae\x9d\xfe\xcf\xe1\xda\x82\x8a\xe7\x36\x4a\xb0\x9d\x65\xa8\x70\xbc\xd8\xc2\x97\x2f\xe0\x15\xf8\x58\x33\x13\xb4\x5a\x62\x58\xcd\xe8\x1a\xd7\xef\xbc\x8b\xcb\x7d\xb7\x3d\x99\x7d\xf8\x7d\x93\x91\x45\x89\x6a\xac\xbc\x6a\xb6\xbb\x13\x69\xe2\x4d\xa1\x6c\x3b\x74\xb4\x5d\x82\x29\x6d\x5b\x10\xe3\xbd\x38\x21\xa8\x7b\x53\x87\x76\x21\x8b\x46\x68\x47\x4d\xfa\xbc\xe8\x89\x01\x6c\x20\x4b\x41\x6f\x35\xca\x9a\x75\x86\x40\x2e\x91\xf5\x32\xd4\x6d\xf1\x18\xbd\xf3\xfa\x85\x31\x3c\x1e\xc1\x80\xab\x15\x37\xe8\xa5\xb7\x06\xec\xd4\xf9\xa2\xbf\xa3\x42\xfa\xbf\x3d\x6f\x5e\xcf\x04\x23\xb1\xf8\x7f\x6a\xf2\x4e\xeb\xdd\xd3\xd5\xe2\x9c\x12\xa6\xcc\xe6\x61\x6b\xb5\x77\xf4\x51\xa3\x69\xd6\x7b\x6d\x17\xb2\xb4\xbe\xc3\x9e\xe0\x65\x44\x97\x95\x58\x85\x43\x27\xa0\x44\x98\x90\x72\xad\x8d\x23\x45\x5d\x49\x6f\x59\x18\x0e\xff\x1d\xbb\x84\x4e\xa3\x29\xf3\x5a\xdb\x6a\xd6\xb8\xd9\x6c\x22\x9b\x3c\x0f\x63\x65\x5f\x06\x43\x33\xfb\x2f\x5f\xe0\x0d\x11\x69\xb4\x24\x77\x21\xfe\x31\xcf\xcb\x92\xf9\xfb\xc7\x18\x1e\x7f\x7b\x38\x1c\xc1\x91\x45\xa0\x89\xc4\x76\x34\x0d\x8c\x4d\x1e\xac\xa3\xff\x11\xab\x5f\x52\xe6\x79\x2c\x4d\x61\x44\x66\xf2\x58\x3c\x74\x2d\xb7\x9a\xe5\x66\x2c\xed\xaf\x33\x5f\x2b\xc2\xc8\xb2\xc9\xac\x0b\x10\x4a\x30\x69\x9b\xc9\x26\x9c\xb4\x31\x2d\xd0\xda\xe9\x0a\x60\x84\xbc\x93\x26\xba\x9e\xda\x81\xc7\xa5\x63\xb7\xa9\x0a\x8c\xeb\x86\xc7\x3e\x10\x5a\x49\x1b\xd7\xf2\x47\xd5\xd6\x2c\x97\x5b\x7a\xbf\x23\x54\x25\xa0\xe1\x60\x81\x76\x5d\xab\x19\xbb\x82\xde\xe3\xe5\x74\xd3\x38\x70\xb9\x9c\x51\x5e\x95\x05\xa7\xdd\xc6\xc7\x8a\x16\x5e\xe4\x4f\x63\x2c\x94\xb4\x36\x92\x6b\xd8\xb7\x1b\xde\x7f\x18\xe3\xa7\x2a\x34\xb4\x1d\x67\xeb\x1f\x37\x7c\x57\x7f\xb4\x0e\x85\xbf\xa4\xf2\xa8\xb4\xc1\x27\xdd\x5a\x18\x2a\xa5\x45\x55\x06\x43\xcf\x57\x5d\xb3\x7c\x9b\x07\x5a\x96\x4f\x34\x12\xff\x69\xaf\x34\xf6\x42\x67\xc1\x8e\xde\x67\x0d\x35\xb4\x7e\x67\x9f\xc4\xdb\xfc\x10\x77\x29\x1b\x49\x61\xae\xda\xe8\xcb\x32\x79\xfc\x0a\x70\xe9\xb6\x90\x46\x05\xc1\x3c\x1f\x9c\xec\x73\x97\xb2\x88\x69\x76\x63\xd4\xf3\x41\x5f\x72\xae\xf9\xa1\x4c\x32\xb4\xdd\x47\x4d\xde\x73\x3e\xf9\xd1\xec\x76\x67\x45\x62\x79\xdc\xf4\x3a\x6d\x75\xfc\xd3\x3b\x1a\xd7\x98\xc3\xaa\x5d\xde\x01\xec\x4b\xb0\xc3\x2e\x95\x2d\xf5\xe2\x72\x59\xe5\x54\xd0\x9d\x09\x38\xdd\x40\xc0\xfb\xa3\x09\x49\x73\x4c\xef\xdb\x63\xe0\xa0\x59\xcc\xc7\x5e\x47\x51\x0a\x92\xcb\xe2\x0f\x2a\x9a\x8d\x29\xe2\xf7\x71\x48\x85\xa1\xef\x61\xd3\xc6\x4e\xda\xa3\x2b\xd7\x0f\x2a\xdb\x80\xc7\x24\x27\x2c\x68\x73\xb9\x8b\xd2\xd1\x56\xe6\x76\xfb\xdc\x87\x82\x39\xd6\xf6\x72\x7f\xdd\xf2\xd1\xd9\x8d\x3d\x15\xcb\x3c\x0c\x5e\x97\x24\x01\xa9\x20\x15\xfb\x2d\xe1\xf7\x21\x58\x72\x38\x99\x31\x18\x9f\xc2\x99\xd5\xf5\xaa\x95\xb3\x37\xef\x43\x60\x9a\xc9\x9a\xe0\x5c\x62\x8e\x00\x75\x42\x81\xea\xd1\x9a\x90\x23\x62\xbd\x81\xec\x06\xf5\x1d\x7c\x7b\x56\xb0\x5d\xd5\xbc\xe4\x8b\x2d\xc6\xba\xec\x11\x49\x4d\x81\x6d\x5b\xe5\xc6\x1c\xda\x32\x74\x63\x7d\xfd\xd1\xb1\x07\x83\xf6\xd0\x86\x06\x5b\x86\xf6\x32\x88\x76\xb0\x17\x5d\x3b\x41\xb2\xa7\xac\xc5\xab\x67\x46\x56\x6f\xb3\x22\x29\x6f\xd5\x74\xce\x55\x65\xbb\xa5\x35\x1b\xb3\x56\x9e\x6b\x9f\x51\xd7\x4a\x83\x6a\x2c\x3b\x34\x4f\x0d\x04\xdf\xfd\x65\x33\x46\xcd\x90\x30\x35\x78\x71\xb5\xf0\x25\x56\xfd\x21\xe8\x9e\x03\x76\x6f\x9a\x95\x9c\xc3\xa8\x99\xc1\xd7\xfa\x5e\xd3\x76\x6a\xab\x4b\x05\xaf\xc9\x8c\xe6\x9e\x05\x80\x11\x5e\xde\x90\x1c\xbf\x7f\x40\x2f\x3e\xd7\x77\x80\x1c\xa7\x07\xd6\x42\x56\x80\xdb\x4d\x11\x45\x55\xc9\xed\xc6\x84\x8b\x1d\x45\xe2\x42\x8d\xaa\x9a\xa7\x61\x60\x82\x55\x72\x71\xa9\xbe\xfb\x10\xd8\xf8\x94\xd6\xe5\x3c\x26\x15\x7d\x79\xfe\xe6\xb5\xc6\xf3\x02\x7f\xd9\xb8\xe8\xda\x3f\xda\xe7\x66\x76\xc1\x49\x92\xdd\x40\x9c\x13\xce\xa7\x1f\x03\x55\xfc\x31\x68\x86\x32\x98\x7c\x2a\xb3\x22\x0c\x4e\x66\xec\x34\x18\xaa\xe1\x93\xec\xe6\x34\xd8\x4a\x4c\xe5\xc6\x3f\x2f\xcf\xf9\x5b\xe5\xac\xde\x48\x4e\x61\x5a\xe8\x9a\xc8\x10\x47\xda\xf4\x83\x01\x8e\xfa\x39\x38\xbe\x8f\xf8\x5b\xa9\xbf\x9d\xfc\x3d\xf4\xb7\x24\x9f\x7e\x0c\x2c\x5d\x0c\x7d\x65\xf9\xc7\xc0\x06\x29\x50\x03\xcb\x0f\x3d\x9b\xfd\x69\x1f\x19\x47\x8a\x86\xeb\xc0\xf1\x56\xa8\x0e\xbb\x79\xb6\x7f\xd2\x7e\x60\x4b\x4b\x74\xec\x36\xa4\x54\x2b\x16\x9b\xbe\xc8\x4b\x22\x74\xbd\x59\x94\x19\x7f\x4b\xde\xca\xb2\xa1\x73\x8d\x23\xd8\x7f\x55\xcc\x83\x11\x04\x07\xfa\x37\x7e\x87\xdb\x2c\xcf\x61\x46\x15\xb0\x44\x2e\xa7\x12\xde\x92\xb7\x30\x5b\xb9\xf0\x87\x11\x9c\xa7\xd4\x80\x8a\x49\x31\x10\xb2\x13\x66\x9e\xd0\x64\x04\xbc\xc4\xd4\x4f\x10\x29\x5d\x02\xe1\xb0\x20\x15\x87\xb0\xa8\xf3\x7c\x18\xb9\x8e\x28\x73\xb7\x6e\xed\xf9\xac\xb7\x12\xc5\x4b\x29\x6b\x1b\xed\xf7\x3a\x14\x2a\x92\x53\x21\xcc\xf9\xf6\x4c\x5f\xf5\x8b\x9e\x96\x79\xc9\xa2\xf7\xaa\xb2\x39\x6c\xa3\xd9\xe9\x98\x02\x52\x86\x96\x44\xb0\xec\x2e\xf0\x55\x54\x63\x7e\xe9\xb4\x83\x8c\x43\x51\x0a\x28\xe7\xa0\xda\x63\x94\xed\x01\xbc\xcf\x29\xe1\x14\x28\x5e\xa1\x21\x10\x97\x8c\xd1\x58\x60\xc2\x38\xe5\x3c\x2b\x8b\x28\xf0\x53\x6d\x94\x9c\xaf\x1b\xef\x18\x31\x59\x18\xcc\xc6\x17\x1b\xbd\x29\x78\x3b\x5a\x74\x6c\xbf\x29\x29\x6e\xc2\x45\x82\xeb\xb5\x8a\x06\x0e\xb2\xc6\x2e\x0a\x1d\x67\x32\x56\xcf\xb1\xab\xaa\xb8\x13\xc5\x6f\xd9\x37\x26\x3c\xd5\xa8\x26\xa4\x8e\xaf\x12\x9a\x81\x9b\x14\x0e\x0b\xd8\xd6\xb9\x79\x81\x9a\x14\xee\x28\x13\xfc\x1c\x79\xdd\x27\xfa\xb7\x7f\xd0\x11\x5c\x05\xab\xb8\x4f\x29\x67\x01\xa9\x9f\xd6\x20\xf2\xe7\x6e\xa2\x02\x28\x17\x87\x97\x6e\xd6\xc0\x6a\xe2\xec\x8d\xb8\x32\x15\xb4\x8b\xa3\xcb\x26\xa2\x6b\xd3\x1c\xd6\xc3\xc6\xbc\xce\xe5\xe1\x44\x4b\x60\x84\x5f\x43\xd5\x63\xdd\xe4\xfe\xa1\xe9\xd7\x49\x24\xe0\xce\xc2\x55\xe9\x4e\xc8\x31\x8e\x0a\x90\xe4\x39\x2c\x33\xce\xa5\xb5\x2f\x0f\xf0\xbc\xb9\xe7\x54\xd0\x5b\x6b\x65\x6a\x95\xa9\x96\x41\xe9\x98\xcf\x56\x89\x0a\x67\xdb\xb7\x2e\x85\x63\x10\x70\xe2\x97\xd3\x22\x91\xa5\xfb\xed\xd6\xb4\xf2\x72\x53\x9f\xe4\x79\x79\x8b\xd0\xe7\x52\x69\x48\xf4\xaa\x32\x2b\x04\x64\x05\x89\xe3\x9a\x91\xd8\x06\x99\xd1\x7a\x51\x66\xaf\x0d\x44\x4a\x1c\x1f\x3d\x02\x55\x7c\x51\x95\xfc\x32\xba\x83\x13\x39\x6e\x67\x58\x75\xe8\x77\xd9\x69\x27\xae\x54\xba\x03\xc4\x31\x4f\xab\x12\xaf\x7c\x6a\x46\xb5\x6d\xf5\x16\x88\xcf\x77\x13\x10\x23\xd0\xd9\x43\xeb\x61\x37\xfa\x09\x60\xef\x07\xdb\xbe\x0d\x63\x1b\x27\x35\xd9\xd1\xfe\xeb\x5c\xbe\xbe\x37\x0c\x60\xf3\x6e\x0d\x05\x8d\x93\xc8\x37\xc3\xf0\xe6\x0a\x5e\x8d\x26\xc5\x0a\x04\x23\x31\xe5\x52\x4d\x91\x02\xe8\x5d\xa6\xae\x3d\xa2\x1a\x8f\xfc\x9b\x14\x8d\xaf\xd0\x19\xae\xb9\x86\x11\xa7\x59\x9e\x30\x5a\x84\xc3\x9e\x48\x72\xd3\xb6\x95\x4f\x88\x15\x78\xb1\xc3\xab\x58\xb7\x6f\x88\xe8\x0c\x0b\x6d\xb6\x04\xea\x6a\xc8\xa9\x49\xa3\x38\x6e\x5f\x11\x69\x35\xd7\x77\x43\xba\xed\x1b\xf4\x3b\x97\x45\xb7\x35\xc2\xa1\x1a\xc7\x29\x2d\x12\xed\x36\xdd\xe8\x4f\x94\x94\x7f\x5a\x16\x37\x72\xed\x8a\x12\x7e\x7c\xfb\xea\x17\x3c\x4a\x71\x41\x96\x95\xb9\x2c\xea\x9c\x8d\x77\xf7\x5e\x7f\xf9\x02\xdf\x7c\xa7\x47\x38\x4a\xcd\xbd\xe5\xa8\xc7\xa7\x6b\xd0\x3c\xb0\x03\xd9\x69\x6e\xd7\x3b\xef\x49\x82\x29\x1b\x3a\x97\xfc\x36\x13\x29\x64\xc5\x4d\xc6\xb3\x59\x4e\x21\x90\xab\x22\x50\x0a\x93\x03\x51\x97\x41\xe3\xb2\x98\x67\x8b\x9a\xd1\x04\xee\x0e\x24\x13\x60\x56\xd6\x45\x42\x10\x00\x2d\x78\xcd\x28\x37\xe0\x45\x4a\x84\x92\x3c\x0e\x84\x51\x48\x32\x5e\xe5\x64\xa5\xaf\x97\x02\x81\x79\x76\xd7\xc0\x41\x2a\x78\x77\xac\x0a\x52\x55\x98\x0a\x53\xe2\xd0\x36\xb1\xc4\xc2\x97\x13\x37\xdd\xb0\x49\x93\xb5\xde\xa8\x9f\x8b\x43\xa9\x65\x4e\x1b\xaa\x39\x71\x44\x45\xa3\xba\xc0\xbb\xab\xa8\x0f\x6c\xab\x8e\x5e\x58\xb7\xe1\xfa\xda\xed\x00\x8e\x94\x36\xd3\x1c\xe9\x8c\x62\x55\x8e\x6e\xd0\x3b\x40\x73\x19\xed\x6d\x79\x0b\x31\xa3\x44\xa8\xab\xaf\xd2\xb6\xf1\x17\x71\xe7\x51\x03\xd7\xfa\x51\x49\xf2\x0a\x03\x9d\xe1\x31\x71\x84\xdf\xee\x7f\xea\xd2\xea\xa4\x71\xb8\x3b\x0b\x1b\xcf\xf8\xea\x0e\x6b\x38\x1c\xa1\x3a\x1e\xe9\xe3\x67\x22\xd2\x7b\xfa\xfc\x2c\xeb\xd1\xed\xf3\xdf\x87\x23\x78\x6c\xfb\xa9\x53\x19\x65\x93\x9e\x3b\x11\xdf\xeb\x04\x9b\x00\x26\x10\xe4\x59\x41\x8d\x1b\x14\x4f\x7f\x55\x99\x13\xed\xcf\x90\x75\x84\x69\xdf\xa7\xf1\x59\x58\x79\x57\xc5\xcb\x4c\xb6\x24\xb5\x28\x83\x91\x47\xd4\x17\x59\x91\xe0\x7d\x08\x4e\xb5\x64\x0e\x38\x2c\xc9\xdd\x78\x99\x15\x7b\x1b\x6e\x6b\x48\xa5\x2b\x58\xed\xde\x97\xfe\x39\xa5\x85\xb9\x96\x21\xed\x42\x75\xf7\x32\xb1\x7b\xf1\x92\xdc\x35\x7b\xf1\x3d\x6b\x51\x34\x1e\x16\x2b\x2d\xb2\x7f\x5c\x33\xa6\xca\xdf\xb8\x90\x00\x9a\x0e\x1b\x20\xca\xd2\xf7\x72\x47\x6e\x7b\xf7\x6c\x45\xb4\x82\xd3\xd6\x00\x8f\x1e\x81\x5b\xfd\xa0\x6d\x3b\xa2\xa9\xd3\x42\xc9\xe9\xd0\xe3\x7f\xb4\x5b\xa9\xa4\xc4\xfe\xd4\xef\xad\xa5\xdd\xdd\x30\x3c\x59\x8e\x14\xf9\x96\xe4\xee\xeb\xa3\xe8\xf0\xdb\xcd\xcd\xb2\xc2\xd0\xc6\xdb\xe9\x91\x03\x58\xf7\xaa\x98\x67\x45\x26\x56\xc7\x2d\xce\x1c\xf8\x15\xbf\x93\x43\xff\x1e\x26\x9c\x20\x8e\xbb\x90\x5e\xcd\xe5\x5e\x82\xf7\xf1\x78\xb9\x23\x67\x97\xbb\xf3\x73\xed\xdc\x28\x43\xac\xa6\xc8\xa6\x76\x62\x46\x3f\x33\x61\xbf\xf1\xa4\x6e\xe4\xa6\xfc\x3c\x30\xed\xfa\xae\x85\x6d\x06\x1e\x1e\x46\x47\x5f\xab\x80\x21\x99\xf1\x50\x16\x1e\x48\x78\xc3\xe6\x50\xb2\x65\xd8\xad\x10\xd6\xc6\xa9\x26\x45\xe9\x4e\x9b\x26\x5d\xbd\x1b\xa1\xf9\x83\xbe\xef\xcf\x4a\xcb\x4c\xfa\x54\xb6\x73\xd7\x63\xb5\x05\xd6\xaf\x5a\x95\x6f\x04\xa6\xf4\x5e\xc9\x32\x5a\x08\xab\x29\xe9\xdc\x24\x2f\x8a\x2c\xbe\x7e\xa1\xaf\x8f\x5a\xf8\x2f\xb2\x3b\x21\xb7\xeb\xe8\x6d\xbd\x9c\x51\x16\xa9\xfb\xa5\x7f\x7f\xf3\xc3\xf9\xa8\x67\xdf\x40\x14\xf5\xbe\xe1\x5e\x12\xf1\xc9\xa9\x5f\xf3\x68\x66\x96\x96\x37\x94\x3d\xa3\x82\x64\x79\xff\xfc\x5e\x36\x0d\x76\x9b\xa4\x42\xd3\xcf\x6f\x56\xfb\xc0\x08\xee\x46\xb0\xf2\x55\xa9\xce\x3e\x19\x9c\xf0\x8a\x14\xc6\x7c\x94\x85\x01\x26\xf7\xda\x70\xc5\x1d\x7c\x8d\x46\xdd\x30\x12\xe5\x8f\xe7\x4f\x95\xb3\x27\x1c\xaa\xdc\x5e\xd9\xf7\x74\x70\xec\x80\xe5\xb7\x44\xc4\x69\x17\x30\xce\xe3\x4a\xd5\x06\xea\x2a\xdb\x34\x98\x91\xf8\x7a\xc1\xa4\x99\x74\xa0\x4f\x8c\x2a\xaf\x18\x55\x08\x96\xc8\x61\xa4\x35\xdb\x1d\x28\x2e\x0b\x41\x0b\x3c\xc6\xa9\x21\xf7\x41\xcf\x36\xea\xf3\xb1\xa1\xb1\xa6\x1c\x6d\x13\x70\x9d\x8e\x2b\x3d\x13\x9d\x10\x6f\x86\x70\xf2\x6c\xb0\xc1\x8c\x21\x59\xcc\xa8\x4e\x91\xf6\x14\x37\x7e\x55\x1f\x8d\xae\x0d\x83\x1e\x0a\x73\x65\xbb\x87\xf1\xaf\xb1\xae\xd7\x46\x51\xdd\xac\x91\x72\xaf\x40\x38\xa3\x39\x79\xde\xfd\x43\xfe\x40\x53\x72\x93\x95\x2c\xd2\xea\xfb\xa5\xe9\x10\xc2\x4e\xa2\xa7\xf0\x9a\xe8\xdf\xfe\xe0\x3c\xa5\xf9\x8d\xb4\x56\x77\x1a\xf9\x1c\x2d\x86\xdd\x04\x7e\xd3\xa8\x6e\xe8\xda\xbe\x99\xb0\xd5\x31\xce\xb3\xdf\xfe\xc8\x31\xd4\x57\x5d\x0f\x5a\xfe\xa5\x1e\x4d\x60\x0f\x0a\x36\xf6\xfd\x47\xcd\xc6\x7b\x2c\x85\x46\xdd\xec\x90\x88\xd7\x93\x97\xb0\x25\x3b\xa0\x9f\x26\xf2\xbc\xad\xb1\xd0\xb7\x6e\x39\x54\x04\x9f\xcd\x71\x2f\xe5\xce\x4b\x66\x6d\x44\x75\x08\x42\x27\xaa\x73\x13\x97\x93\x1b\xba\xa7\x4f\x4a\xce\xfd\xdb\x27\x7f\x7b\xf2\x0b\x98\xe0\xa1\x3c\xd9\x94\x2c\xa1\x4c\x5d\xdd\x3d\xb0\x7e\x52\xc8\x84\x72\xe5\x3a\x63\x2a\x60\xb7\xd2\x3a\x95\x10\x6b\x4e\x99\x3c\x74\xc9\x33\x93\xba\x18\x80\xf8\xb8\x8f\x56\xd8\x6b\xbb\xda\x07\xe9\x1d\x1e\xfb\xaf\xfb\xa2\x43\x76\xab\x8b\xa2\xd7\x93\xfa\xb6\x44\x34\xd1\x65\xc4\x61\x2e\x35\x62\xcb\x3b\xda\xf5\x15\x9c\x93\x99\x7f\x5b\xdb\xbd\x86\xeb\x44\x8d\xec\xb5\xe0\x9d\xa4\xa0\x95\xeb\xd1\x4a\x1c\x24\x3b\xc9\x81\x4a\xe8\x6a\xee\x13\xdf\x8f\xa5\x4b\x69\xe5\x23\x37\x41\x93\x1f\xca\x64\x65\x48\xed\x80\xf3\x9f\x91\xb9\xc2\xdb\x90\x20\x66\x65\xa2\xef\xbd\x63\x3f\x2f\xdf\x8b\xdf\x66\x22\x4e\xc3\x56\xb4\x5b\xe1\x1f\x13\x4e\x21\xb8\xa1\xb1\x28\x59\x30\xd9\x73\x4d\x46\x3f\x2c\xed\x73\xd0\x0c\xa3\x1d\x25\xc1\x89\x60\xa7\x27\x22\x81\xb8\xcc\xe5\x5e\x35\x1d\x3c\x1e\x9c\x9e\x64\xa7\x85\x62\xec\xc9\x38\x3b\x3d\x19\x8b\x44\x7e\xb0\xd3\xe6\xda\x47\x3b\x67\xb6\x3f\x13\xbc\x27\x44\xee\x5f\x33\x44\x1e\x68\x5b\x55\x37\xbc\xc8\x2e\xdd\xdd\xd2\x06\xa0\xfa\xbc\xd4\xd6\x49\x7d\x7c\xdf\xd4\x4e\x5b\xa1\x38\x05\x52\x07\xcc\xe4\xd4\x74\x13\xed\x84\xbe\x38\xba\x6c\xaa\xdc\x59\xab\x79\xe2\xa5\x9c\x63\x4b\x7f\x1d\x69\xf8\xff\x98\xfe\x37\x7f\x9c\xfe\x37\x6d\xfa\xdb\xfb\x10\xe7\xf4\x4e\x5a\x38\x81\x0d\x4b\x58\xf4\x3e\x29\xf4\x3e\xc1\x09\xdc\x18\xaf\xbf\xc1\xed\x93\x7f\x05\xb5\x81\xb4\x3f\xb5\x8d\x2f\x3e\x5d\x6a\x0e\xc1\xff\x96\x5c\x73\xcb\x0f\x15\xe7\x66\x6c\x7c\x1a\xf8\xae\xdf\x3f\x29\x1a\x0e\x26\x3b\x4b\x86\x8e\xcb\x28\xc9\xe8\x1f\x5d\x35\xf1\x46\x72\x39\xb1\x49\x10\xdb\x03\xa1\x65\x7b\xff\x40\xd8\xc4\x1b\xc8\x99\xb5\x3f\xe6\x70\xcb\xa0\xda\x75\x39\xe9\xdd\x0f\x7e\x2c\x78\x5d\x55\x25\x13\x34\xd1\x17\x5b\x30\xa6\xd6\x01\xb2\x75\x6b\x67\x1b\x9e\x06\xed\xbb\x24\xde\x7e\x3f\xd0\xf3\x53\x3b\x36\xd5\x59\x7f\xb1\x6f\x6a\xd9\xdb\x84\x6e\x84\x0c\xc9\xd7\x20\x40\x0b\x91\x89\xd5\x1b\x75\x59\x16\x27\x16\x3c\x0a\x26\x10\x3c\x22\xcb\xea\xd8\xdc\x2e\x3b\xc1\x92\x5c\xd8\x82\x53\x2c\x58\xd8\x82\x41\x30\x98\xc0\xe0\xd1\xbf\xea\x52\x1c\xeb\x2b\xaf\xc1\x20\x90\x45\x5f\x7d\xf3\x17\x5b\x32\x56\x25\x77\x8f\x5f\x1c\x0f\xec\xc3\x32\xda\xc8\xd7\x67\x1a\x8d\x5e\x73\xe7\xf6\xe2\xd1\xc9\x69\x30\xf8\x38\xbe\x1c\x2f\x46\xce\xf5\x48\xde\xba\x61\x60\xa7\x71\xc1\x2f\x4d\x0c\x64\xed\x71\xe5\x3d\xe9\xbb\x96\xd2\x3c\x0c\x6b\x42\x56\x2d\x66\xca\x6e\xad\x57\x40\xfb\x39\x89\x40\x9a\x7b\x81\x08\x18\xdd\xe9\x3f\x9e\xbd\x6e\xc2\x18\x6e\xab\x5e\x9d\xea\x35\x50\x5e\xd9\x75\x93\x2f\xe3\xd5\x1a\xd7\x0e\x0e\x45\x92\x44\x59\xe5\xa0\x9f\x98\x45\x69\x0a\xbe\x22\x49\x72\xa5\x9f\xb6\xd2\x0f\x2f\x78\xcd\xd5\x5b\x60\xb2\x68\x04\x9f\xd7\xc3\xae\x85\xd2\x9a\xbf\x99\x51\x97\x06\x72\x76\x3a\xc5\x26\x2f\x63\x3c\xe6\x47\x9c\x12\xa6\x1e\x62\x0c\x82\x16\xc3\x4c\xa0\x59\x53\x0f\xb3\x06\xdf\x9b\x94\xd5\x7e\x38\x11\xaf\x67\x4a\x3e\xc2\xa3\x61\xc4\xab\x3c\x13\xe1\xe0\xd1\xc0\x26\x59\x37\x30\x5e\xd2\xbc\xb2\xc7\xac\xf6\x64\xfe\xd1\x6a\x16\xba\xe1\xb2\x36\x0c\x35\xe1\xa6\x0b\x0f\x1d\x4c\xb7\x52\xcb\x50\xd9\xa5\x96\x79\x3c\xd4\x17\x9c\x2e\xae\xca\x64\x44\x92\x3d\xb4\x0f\x77\x3a\xaf\xef\x69\xa7\x8a\x7e\xd6\x54\x29\x4c\xc9\x59\x65\x70\xfe\x78\xf6\xba\x61\xed\xd0\xa9\x56\xfa\xa4\xc5\xfb\xe1\x1e\xc0\xb0\x79\x61\x58\xad\x07\x25\x7d\x4d\x74\xea\xa1\x66\xef\x50\x9f\xd3\xba\xe9\x53\x26\xe4\x66\x4f\x71\xcd\x43\x38\x92\x4e\xe3\x31\xbc\x7d\x77\xfe\x7c\xd2\xba\x62\x3c\xa3\x70\x4d\x2b\x81\x17\xc9\x57\x45\xac\xc2\x2f\xe3\x5a\x64\xf9\x98\x0b\x66\x7e\xc7\x65\x71\x13\x2d\xca\x09\xc2\x7d\x9d\x15\xd7\x2f\x4a\xf6\xdc\xa6\x31\xdc\xc3\x03\x4b\x8f\xfe\x65\x8b\xec\x54\xca\xc7\xac\x5a\x3d\x7d\x2f\x7e\xbf\x50\x6b\x0b\xaf\xca\xba\x39\x0f\xad\x55\xaf\x28\xd0\x5c\x10\x36\x81\xc7\x3f\x2d\x9e\x0e\x88\x77\xb3\x4f\x34\x96\x4a\xa8\x23\xab\x0b\x5a\x50\x46\x84\x12\x57\xd5\xcc\x53\x38\x06\x7f\x2f\xe3\xe3\xa1\x0a\x6c\x87\x0e\x6c\x93\xdb\xa6\xde\x00\x55\x29\x45\x8f\xf4\xc3\x72\x69\xc6\x45\xc9\x56\x28\x1c\xf2\x08\x42\xc3\xcf\xeb\x11\x04\xc1\x08\x54\x98\xf4\x7b\xb9\x21\x3b\x44\xdd\xba\x46\x1c\x81\x74\x39\xa4\xe4\xae\x47\x47\xbb\x2c\xd2\x6f\x35\x34\x9d\x86\xf0\x59\x4f\x6b\x81\x6e\x00\x6c\xd7\x93\xf6\xd9\x4b\xe9\x96\x80\xec\xd2\xa5\xad\x19\xff\xe1\xa9\x31\x0b\xcd\xd5\x19\x56\xf2\xf0\xe0\x4c\x13\xbf\x0b\xce\x4e\x4d\xeb\x55\x71\x43\xf2\x2c\xe9\x51\x3b\xea\x59\x04\x57\x6d\xa9\x6e\x54\xc4\x86\xd5\x2f\x58\xb9\x7c\xa7\x06\xd0\x00\xba\xc3\x8d\xe0\x70\x47\xca\x44\xcd\xe8\xca\x51\x0b\x53\x18\xff\x73\xf1\x31\xd9\xff\x18\x45\xfb\xd3\x68\xff\xe1\xf8\xf7\x11\xab\x67\x86\x2e\xbd\x50\x22\xcf\xeb\x2a\x37\x91\x0d\x3d\x4d\xa7\xbc\xc3\xfb\xa6\xae\xb5\xd3\xfc\xee\xc9\x45\x82\x72\xe1\xc2\x3b\xee\xcf\x1d\xde\x3a\xc9\xfb\xf8\xb1\x41\x3c\x46\x4a\x64\x5f\x35\x7a\x46\xee\xab\x4e\x83\xc6\x68\x68\x6c\x86\xfe\x2d\xb5\xc2\xe7\xb3\xdf\xcd\xa5\xb6\x45\x78\xde\xfb\x29\x08\x4d\xbd\xb0\x1d\x3a\x43\x9a\xbd\xb4\x40\xaf\xfb\xbb\xb9\x1a\xf4\x45\xc9\x24\x14\xb3\x48\x5d\x74\x76\x66\x43\x53\xa1\xf2\x7c\xf8\xcf\x99\x48\xc3\x0e\x92\x9a\xd8\x36\x0d\x5d\x53\xe0\x3e\x7c\xb6\x53\x62\xdb\x24\xa4\x2d\x11\xd3\xf0\x70\x74\xcf\xbc\x95\xfa\xeb\x05\xd5\x2d\xf4\x37\x8f\x9d\x68\x62\x6d\x9b\x0e\x49\x34\x2d\xdc\x47\xe5\xfc\x37\x25\x1a\x5b\xd3\x59\xdd\xef\xe6\xef\x0a\xbd\x0b\x77\xf1\xb3\x7c\x56\x40\x9e\xc4\x71\xbd\xac\x73\x22\x30\xf7\x7c\x07\x65\xb2\x41\x62\x61\x5f\xdf\x79\xeb\x80\xb5\x69\x0c\xcd\xcb\xeb\xed\x57\x17\x9c\xd6\xbf\x7b\xa9\x6d\x9e\xfc\x76\x35\xec\x3d\xcd\x01\xbe\x70\x77\x22\xae\x2e\x13\x9b\xde\xf2\xa4\xfd\xa4\x48\x4c\xda\xac\x50\x1c\x55\x06\xea\x74\xe0\x6c\xe0\x4d\x73\xfb\xcf\x26\xdc\xbe\x17\x87\xea\xf1\x0e\xb7\xb1\x01\x9a\xd0\xb8\x4c\xe8\x8f\x67\xaf\x9e\x96\xcb\xaa\x2c\x68\x61\x68\xe9\x01\x38\xba\x6c\x8e\x4e\x1f\xf7\xe5\x99\x29\x80\x60\x38\xd4\x50\xe5\x4a\x72\x51\x98\x42\x20\xc8\xcc\xc9\x4e\xf6\x87\xb4\x37\x25\x9d\x62\xf5\x2c\x9c\x20\x33\xc8\x38\xa6\x3f\x2c\x28\xd3\x8e\x03\xd7\x20\xbd\x68\x86\xb9\xb4\x53\xfd\xc9\xbc\xe2\xb1\xee\x61\x7f\xf7\xd1\x8d\x6d\x4c\x6f\xeb\x31\x97\xd5\x8e\xa1\xa6\x47\x09\x16\xd2\x32\xc9\xb4\x98\x06\x51\x37\xb5\x7c\xdb\x78\x3d\xe6\x55\xc7\x62\x69\x59\x5a\x56\xca\x2a\x83\x61\xbf\x06\xce\x3c\xe5\xeb\x9b\x79\x4a\x2c\xd5\xd7\xe8\x9a\xae\xb8\x37\xd2\xb0\x2b\xa4\xd7\xcd\x33\xf7\x0e\xa4\x0b\x8d\xc2\x3e\x5c\xd3\xd5\xa5\xb1\x55\x35\x94\x0b\x59\xd6\xc9\x1d\x74\x7a\xb7\x1c\x0a\xf2\x18\xac\x8d\x68\x75\x87\xf0\x03\x15\x75\xa5\x83\x29\x31\x89\x53\x3a\x51\xaf\xf6\x35\xcc\xf6\xee\x1a\xf6\x3e\x74\xc7\x05\x11\x59\x3c\xfe\xc4\xc7\xea\xb0\x63\xff\x4b\x44\x6a\xfe\x73\xc4\xf7\x37\x53\xc9\x44\xef\xdf\x3d\xe8\x5c\x9b\xce\x8d\xc2\x84\x08\x22\x31\xd4\x92\xed\xfd\x0b\x07\xed\x26\x34\x7e\x35\xfb\xef\x1e\x50\xe0\x55\x4f\x53\xa7\xf2\xd9\x9f\xd1\x8a\xd1\x98\x08\xaa\xce\x73\x78\xa4\xf7\xb3\x79\x93\x8c\xd1\x58\x9c\x97\x6f\xb2\x85\x94\x91\xc4\x9e\xfa\xa1\x2f\xd7\x13\xff\x7b\x8e\x72\x48\xf4\x9c\x01\x42\x27\x67\x14\x85\x52\x91\xbb\x9b\x01\xaa\xbd\x1c\x78\xb4\x3a\x4f\x29\xa7\x20\x6e\x4b\x7d\x8d\x93\xf7\xe3\x8d\x09\x46\xbd\xe8\x0e\x25\x14\xc2\x28\x90\x24\xa1\x09\x94\x45\xbe\x42\x57\xe7\x8c\xc4\xd7\xb7\x84\x25\x78\x5f\x8f\x88\x6c\x96\xe5\x99\x58\xc9\x93\x5b\x99\x27\x4a\x46\x74\xd8\x3b\x72\x04\xa4\x97\x64\x1b\x1d\x05\x29\xe1\xe9\x3d\x96\x4d\xf3\x00\xa4\xd9\xfc\x94\x36\x4c\x5e\x30\xb2\x58\xaa\x08\x74\x8f\x7e\xec\x1b\x45\x45\x27\xd8\xca\x32\x03\x2f\xc0\x69\xc6\xfb\x40\xf5\x9e\x1c\x1e\x0d\x95\xd2\x4b\x58\x59\x61\xa0\x4a\xc2\x81\xaf\x30\xb3\x27\xc6\xb0\x77\xe8\x24\xd4\x75\x51\x6e\xac\x74\x26\xd5\xdf\xda\x59\x47\x1b\xe4\xc6\xaa\x8d\x3f\x37\xcd\x9e\x03\xea\x9f\x99\x6d\xbf\x6a\x6a\x7b\xa5\x3c\xcb\xa7\xf4\xd5\x61\xb3\x6f\x5a\x7d\xd8\xa3\x96\x65\x1b\x57\xdd\x95\xbb\x68\xba\xfb\x75\x5d\xd9\x52\x73\xe0\xfd\x93\x0a\x3b\x31\xbc\x12\xdd\x7f\x1c\x6e\x11\xb9\xe7\x9a\x77\xeb\xf8\x8b\x8c\x7e\x18\xca\xa5\x3b\x3c\xde\xfb\x3f\x01\x00\x00\xff\xff\x8b\x69\x4a\x7d\x2f\x6b\x00\x00")
func webUiStaticJsGraphJsBytes() ([]byte, error) { func webUiStaticJsGraphJsBytes() ([]byte, error) {
return bindataRead( return bindataRead(
...@@ -421,7 +443,7 @@ func webUiStaticJsGraphJs() (*asset, error) { ...@@ -421,7 +443,7 @@ func webUiStaticJsGraphJs() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "web/ui/static/js/graph.js", size: 27425, mode: os.FileMode(420), modTime: time.Unix(1499264549, 0)} info := bindataFileInfo{name: "web/ui/static/js/graph.js", size: 27439, mode: os.FileMode(420), modTime: time.Unix(1502369610, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
...@@ -461,7 +483,27 @@ func webUiStaticJsProm_consoleJs() (*asset, error) { ...@@ -461,7 +483,27 @@ func webUiStaticJsProm_consoleJs() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "web/ui/static/js/prom_console.js", size: 22477, mode: os.FileMode(420), modTime: time.Unix(1499786501, 0)} info := bindataFileInfo{name: "web/ui/static/js/prom_console.js", size: 22477, mode: os.FileMode(420), modTime: time.Unix(1499860266, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var _webUiStaticJsTargetsJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x93\x4d\x8e\x9c\x30\x10\x85\xf7\x9c\xa2\x62\xf5\xc2\x96\x18\x2b\xfb\x16\xab\xac\x66\x9d\x03\x44\xc6\x14\x60\xe2\xb1\x5b\x76\xd1\x19\x29\xe2\xee\x91\x01\x37\x3f\x33\x69\x4d\x2d\x71\xbd\x72\xbd\xef\x99\x76\x74\x9a\x8c\x77\x40\xbe\xeb\x2c\x72\x5f\x0f\x25\x44\x52\x84\xe2\x6f\x01\x00\x70\x57\x01\x8c\xf6\x0e\x2a\xb8\xa4\x53\x21\x5b\xe3\x1a\xce\x0c\x13\xd7\xb9\xc1\xb4\xc0\x53\x83\xb4\xe8\x3a\xea\xa1\xaa\x2a\xf8\x0e\x02\x16\x79\xaa\x80\x34\x06\xb7\x74\x4f\xc5\x43\x34\xdf\x32\xb7\x53\x18\x71\x2f\x98\xc7\x05\x7c\xf3\x77\xfc\x61\x55\x8c\x9c\xa5\x2f\x2f\xba\xc7\x7b\xf0\xee\xa5\xf1\x7f\x1c\x13\x52\x35\xcd\x67\xa7\xe3\x2d\x6f\x36\x01\xda\x88\x5f\x9f\x9b\x94\xff\x9b\xba\xdc\x79\xf0\xb0\xe2\x70\xf8\x4e\x5c\xc8\x95\xdf\x82\xee\x5a\x4c\x45\xf1\x40\x6b\x9c\x21\x9e\xfd\x5d\x38\x93\x83\xaf\x7f\xf5\xa8\x1a\x0c\x4c\x48\x6d\x8d\xfe\xcd\x73\x33\xdf\x73\x48\xec\x07\x5f\xcf\xe8\xa9\x37\x31\xb3\x57\x69\x4f\xa2\xc0\x99\x69\x98\x28\x1f\xfd\xa9\xf0\xfd\xa6\x5c\x83\xe1\x35\x67\xb6\x17\x1a\xf9\xa9\xa9\x0d\x50\x0b\x7c\x3f\x20\x67\xfa\x2d\x65\xba\xdf\x2c\x95\xf5\x5a\xd9\x9f\xe4\x83\xea\x50\x46\xa4\x57\xc2\x37\x3e\xf8\xba\x84\x56\xd9\x88\x2b\xac\x5c\x2b\x9f\xb4\x4d\xb9\x04\xbe\x9d\x7f\x08\xea\xf9\xf8\x93\xfa\xc3\xf4\xf3\xf5\xd3\x92\x5a\x36\x7a\x4c\x00\x12\x4c\x54\xba\xdf\x22\x30\x25\xa4\x64\x4f\x41\x44\xb4\xa8\xc9\x87\xed\x47\xd8\x22\xb8\x1e\x08\x1e\x36\xef\xd6\xcd\xb3\x5c\xcc\x2f\x9e\x25\x0f\xec\x48\x74\xf5\x90\x13\xbb\xa9\x80\x8e\xe2\xe9\xb9\x3c\x73\x37\x15\xc5\x85\xa7\xc7\x26\xae\xff\x02\x00\x00\xff\xff\xc9\x97\xfe\x65\xd7\x03\x00\x00")
func webUiStaticJsTargetsJsBytes() ([]byte, error) {
return bindataRead(
_webUiStaticJsTargetsJs,
"web/ui/static/js/targets.js",
)
}
func webUiStaticJsTargetsJs() (*asset, error) {
bytes, err := webUiStaticJsTargetsJsBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "web/ui/static/js/targets.js", size: 983, mode: os.FileMode(420), modTime: time.Unix(1502369610, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
...@@ -950,12 +992,14 @@ var _bindata = map[string]func() (*asset, error){ ...@@ -950,12 +992,14 @@ var _bindata = map[string]func() (*asset, error){
"web/ui/static/css/graph.css": webUiStaticCssGraphCss, "web/ui/static/css/graph.css": webUiStaticCssGraphCss,
"web/ui/static/css/prom_console.css": webUiStaticCssProm_consoleCss, "web/ui/static/css/prom_console.css": webUiStaticCssProm_consoleCss,
"web/ui/static/css/prometheus.css": webUiStaticCssPrometheusCss, "web/ui/static/css/prometheus.css": webUiStaticCssPrometheusCss,
"web/ui/static/css/targets.css": webUiStaticCssTargetsCss,
"web/ui/static/img/ajax-loader.gif": webUiStaticImgAjaxLoaderGif, "web/ui/static/img/ajax-loader.gif": webUiStaticImgAjaxLoaderGif,
"web/ui/static/img/favicon.ico": webUiStaticImgFaviconIco, "web/ui/static/img/favicon.ico": webUiStaticImgFaviconIco,
"web/ui/static/js/alerts.js": webUiStaticJsAlertsJs, "web/ui/static/js/alerts.js": webUiStaticJsAlertsJs,
"web/ui/static/js/graph.js": webUiStaticJsGraphJs, "web/ui/static/js/graph.js": webUiStaticJsGraphJs,
"web/ui/static/js/graph_template.handlebar": webUiStaticJsGraph_templateHandlebar, "web/ui/static/js/graph_template.handlebar": webUiStaticJsGraph_templateHandlebar,
"web/ui/static/js/prom_console.js": webUiStaticJsProm_consoleJs, "web/ui/static/js/prom_console.js": webUiStaticJsProm_consoleJs,
"web/ui/static/js/targets.js": webUiStaticJsTargetsJs,
"web/ui/static/vendor/bootstrap-3.3.1/css/bootstrap-theme.min.css": webUiStaticVendorBootstrap331CssBootstrapThemeMinCss, "web/ui/static/vendor/bootstrap-3.3.1/css/bootstrap-theme.min.css": webUiStaticVendorBootstrap331CssBootstrapThemeMinCss,
"web/ui/static/vendor/bootstrap-3.3.1/css/bootstrap.min.css": webUiStaticVendorBootstrap331CssBootstrapMinCss, "web/ui/static/vendor/bootstrap-3.3.1/css/bootstrap.min.css": webUiStaticVendorBootstrap331CssBootstrapMinCss,
"web/ui/static/vendor/bootstrap-3.3.1/fonts/glyphicons-halflings-regular.eot": webUiStaticVendorBootstrap331FontsGlyphiconsHalflingsRegularEot, "web/ui/static/vendor/bootstrap-3.3.1/fonts/glyphicons-halflings-regular.eot": webUiStaticVendorBootstrap331FontsGlyphiconsHalflingsRegularEot,
...@@ -1028,6 +1072,7 @@ var _bintree = &bintree{nil, map[string]*bintree{ ...@@ -1028,6 +1072,7 @@ var _bintree = &bintree{nil, map[string]*bintree{
"graph.css": &bintree{webUiStaticCssGraphCss, map[string]*bintree{}}, "graph.css": &bintree{webUiStaticCssGraphCss, map[string]*bintree{}},
"prom_console.css": &bintree{webUiStaticCssProm_consoleCss, map[string]*bintree{}}, "prom_console.css": &bintree{webUiStaticCssProm_consoleCss, map[string]*bintree{}},
"prometheus.css": &bintree{webUiStaticCssPrometheusCss, map[string]*bintree{}}, "prometheus.css": &bintree{webUiStaticCssPrometheusCss, map[string]*bintree{}},
"targets.css": &bintree{webUiStaticCssTargetsCss, map[string]*bintree{}},
}}, }},
"img": &bintree{nil, map[string]*bintree{ "img": &bintree{nil, map[string]*bintree{
"ajax-loader.gif": &bintree{webUiStaticImgAjaxLoaderGif, map[string]*bintree{}}, "ajax-loader.gif": &bintree{webUiStaticImgAjaxLoaderGif, map[string]*bintree{}},
...@@ -1038,6 +1083,7 @@ var _bintree = &bintree{nil, map[string]*bintree{ ...@@ -1038,6 +1083,7 @@ var _bintree = &bintree{nil, map[string]*bintree{
"graph.js": &bintree{webUiStaticJsGraphJs, map[string]*bintree{}}, "graph.js": &bintree{webUiStaticJsGraphJs, map[string]*bintree{}},
"graph_template.handlebar": &bintree{webUiStaticJsGraph_templateHandlebar, map[string]*bintree{}}, "graph_template.handlebar": &bintree{webUiStaticJsGraph_templateHandlebar, map[string]*bintree{}},
"prom_console.js": &bintree{webUiStaticJsProm_consoleJs, map[string]*bintree{}}, "prom_console.js": &bintree{webUiStaticJsProm_consoleJs, map[string]*bintree{}},
"targets.js": &bintree{webUiStaticJsTargetsJs, map[string]*bintree{}},
}}, }},
"vendor": &bintree{nil, map[string]*bintree{ "vendor": &bintree{nil, map[string]*bintree{
"bootstrap-3.3.1": &bintree{nil, map[string]*bintree{ "bootstrap-3.3.1": &bintree{nil, map[string]*bintree{
...@@ -4,12 +4,6 @@ body { ...@@ -4,12 +4,6 @@ body {
padding-bottom: 20px; padding-bottom: 20px;
} }
th.job_header {
font-size: 20px;
padding-top: 10px;
padding-bottom: 10px;
}
.state_indicator { .state_indicator {
padding: 0 4px 0 4px; padding: 0 4px 0 4px;
} }
......
tr.job_header {
font-size: 20px;
padding-top: 10px;
font-weight: bold;
padding-bottom: 10px;
cursor: pointer;
}
tr.job_details > td{
padding: 0 !important;
}
\ No newline at end of file
...@@ -927,7 +927,7 @@ function redirectToMigratedURL() { ...@@ -927,7 +927,7 @@ function redirectToMigratedURL() {
}); });
}); });
var query = $.param(queryObject); var query = $.param(queryObject);
window.location = "/graph?" + query; window.location = PATH_PREFIX + "/graph?" + query;
} }
$(init); $(init);
function toggle(obj, state){
var icon = $(obj).find("i");
if (icon.length === 0 ) {
return;
}
if (state === true) {
icon.removeClass("icon-chevron-down").addClass("icon-chevron-up");
} else {
icon.removeClass("icon-chevron-up").addClass("icon-chevron-down");
}
$(obj).next().toggle(state);
}
function init() {
$(".job_header").click(function() {
var job = $(this).find("a").attr("id"),
expanderIcon = $(this).find("i.icon-chevron-down");
if (expanderIcon.length !== 0) {
localStorage.setItem(job, false);
toggle(this, true);
} else {
localStorage.setItem(job, true);
toggle(this, false);
}
});
$(".job_header a").each(function(i, obj) {
var selector = $(obj).attr("id");
if (localStorage.getItem(selector) === "true") {
toggle($(this).parents(".job_header"), false);
}
});
}
$(init);
\ No newline at end of file
{{define "head"}}<!-- nix -->{{end}} {{define "head"}}
<link type="text/css" rel="stylesheet" href="{{ pathPrefix }}/static/css/targets.css?v={{ buildVersion }}">
<script src="{{ pathPrefix }}/static/js/targets.js?v={{ buildVersion }}"></script>
{{end}}
{{define "content"}} {{define "content"}}
<div class="container-fluid"> <div class="container-fluid">
<h2 id="targets">Targets</h2> <h2 id="targets">Targets</h2>
<table class="table table-condensed table-bordered table-striped table-hover"> <table class="table table-condensed table-bordered table-hover">
{{range $job, $pool := .TargetPools }} {{range $job, $pool := .TargetPools }}
<thead> {{$healthy := numHealthy $pool}}
<tr><th colspan="5" class="job_header"><a id="job-{{$job}}" href="#job-{{$job}}">{{$job}}</a></th></tr> {{$total := len $pool}}
<tr> <tr class="job_header{{if lt $healthy $total}} danger{{end}}">
<th>Endpoint</th> <td colspan="5">
<th>State</th> <i class="icon-chevron-up"></i><a id="job-{{$job}}" href="#job-{{$job}}">{{$job}} ({{$healthy}}/{{$total}} up)</a>
<th>Labels</th>
<th>Last Scrape</th>
<th>Error</th>
</tr>
</thead>
<tbody>
{{range $pool}}
<tr>
<td>
<a href="{{.URL | globalURL}}">{{.URL.Scheme}}://{{.URL.Host}}{{.URL.Path}}</a><br>
{{range $label, $values := .URL.Query }}
{{range $i, $value := $values}}
<span class="label label-primary">{{$label}}="{{$value}}"</span>
{{end}}
{{end}}
</td>
<td>
<span class="alert alert-{{ .Health | healthToClass }} state_indicator text-uppercase">
{{.Health}}
</span>
</td> </td>
</tr>
<tr class = "job_details">
<td> <td>
<span class="cursor-pointer" data-toggle="tooltip" title="" data-html=true data-original-title="<b>Before relabeling:</b>{{range $k, $v := .DiscoveredLabels.Map}}<br>{{$k | html | html}}=&quot;{{$v | html | html}}&quot;{{end}}"> <table class="table table-condensed table-bordered table-striped table-hover">
{{$labels := stripLabels .Labels.Map "job"}} <thead>
{{range $label, $value := $labels}} <tr>
<span class="label label-primary">{{$label}}="{{$value}}"</span> <th>Endpoint</th>
{{else}} <th>State</th>
<span class="label label-default">none</span> <th>Labels</th>
<th>Last Scrape</th>
<th>Error</th>
</tr>
</thead>
<tbody>
{{range $pool}}
<tr>
<td>
<a href="{{.URL | globalURL}}">{{.URL.Scheme}}://{{.URL.Host}}{{.URL.Path}}</a><br>
{{range $label, $values := .URL.Query }}
{{range $i, $value := $values}}
<span class="label label-primary">{{$label}}="{{$value}}"</span>
{{end}}
{{end}}
</td>
<td>
<span class="alert alert-{{ .Health | healthToClass }} state_indicator text-uppercase">
{{.Health}}
</span>
</td>
<td>
<span class="cursor-pointer" data-toggle="tooltip" title="" data-html=true data-original-title="<b>Before relabeling:</b>{{range $k, $v := .DiscoveredLabels}}<br>{{$k | html | html}}=&quot;{{$v | html | html}}&quot;{{end}}">
{{$labels := stripLabels .Labels.Map "job"}}
{{range $label, $value := $labels}}
<span class="label label-primary">{{$label}}="{{$value}}"</span>
{{else}}
<span class="label label-default">none</span>
{{end}}
</span>
</td>
<td>
{{if .LastScrape.IsZero}}Never{{else}}{{since .LastScrape}} ago{{end}}
</td>
<td>
{{if .LastError}}
<span class="alert alert-danger state_indicator">{{.LastError}}</span>
{{end}}
</td>
</tr>
{{end}} {{end}}
</span> </tbody>
</td> </table>
<td>
{{if .LastScrape.IsZero}}Never{{else}}{{since .LastScrape}} ago{{end}}
</td>
<td>
{{if .LastError}}
<span class="alert alert-danger state_indicator">{{.LastError}}</span>
{{end}}
</td> </td>
</tr> </tr>
{{end}}
</tbody>
{{end}} {{end}}
</table> </table>
</div> </div>
{{end}} {{end}}
\ No newline at end of file
...@@ -28,6 +28,7 @@ import ( ...@@ -28,6 +28,7 @@ import (
"sort" "sort"
"strings" "strings"
"sync" "sync"
"sync/atomic"
"time" "time"
"google.golang.org/grpc" "google.golang.org/grpc"
...@@ -88,6 +89,8 @@ type Handler struct { ...@@ -88,6 +89,8 @@ type Handler struct {
externalLabels model.LabelSet externalLabels model.LabelSet
mtx sync.RWMutex mtx sync.RWMutex
now func() model.Time now func() model.Time
ready uint32 // ready is uint32 rather than boolean to be able to use atomic functions.
} }
// ApplyConfig updates the status state as the new config requires. // ApplyConfig updates the status state as the new config requires.
...@@ -162,7 +165,9 @@ func New(o *Options) *Handler { ...@@ -162,7 +165,9 @@ func New(o *Options) *Handler {
tsdb: o.Storage, tsdb: o.Storage,
storage: ptsdb.Adapter(o.Storage), storage: ptsdb.Adapter(o.Storage),
notifier: o.Notifier, notifier: o.Notifier,
now: model.Now,
now: model.Now,
ready: 0,
} }
h.apiV1 = api_v1.NewAPI(h.queryEngine, h.storage, h.targetManager, h.notifier) h.apiV1 = api_v1.NewAPI(h.queryEngine, h.storage, h.targetManager, h.notifier)
...@@ -177,48 +182,49 @@ func New(o *Options) *Handler { ...@@ -177,48 +182,49 @@ func New(o *Options) *Handler {
instrh := prometheus.InstrumentHandler instrh := prometheus.InstrumentHandler
instrf := prometheus.InstrumentHandlerFunc instrf := prometheus.InstrumentHandlerFunc
readyf := h.testReady
router.Get("/", func(w http.ResponseWriter, r *http.Request) { router.Get("/", func(w http.ResponseWriter, r *http.Request) {
router.Redirect(w, r, path.Join(o.ExternalURL.Path, "/graph"), http.StatusFound) router.Redirect(w, r, path.Join(o.ExternalURL.Path, "/graph"), http.StatusFound)
}) })
router.Get("/alerts", instrf("alerts", h.alerts)) router.Get("/alerts", readyf(instrf("alerts", h.alerts)))
router.Get("/graph", instrf("graph", h.graph)) router.Get("/graph", readyf(instrf("graph", h.graph)))
router.Get("/status", instrf("status", h.status)) router.Get("/status", readyf(instrf("status", h.status)))
router.Get("/flags", instrf("flags", h.flags)) router.Get("/flags", readyf(instrf("flags", h.flags)))
router.Get("/config", instrf("config", h.config)) router.Get("/config", readyf(instrf("config", h.config)))
router.Get("/rules", instrf("rules", h.rules)) router.Get("/rules", readyf(instrf("rules", h.rules)))
router.Get("/targets", instrf("targets", h.targets)) router.Get("/targets", readyf(instrf("targets", h.targets)))
router.Get("/version", instrf("version", h.version)) router.Get("/version", readyf(instrf("version", h.version)))
router.Get("/heap", instrf("heap", dumpHeap)) router.Get("/heap", readyf(instrf("heap", dumpHeap)))
router.Get("/metrics", prometheus.Handler().ServeHTTP) router.Get("/metrics", prometheus.Handler().ServeHTTP)
router.Get("/federate", instrh("federate", httputil.CompressionHandler{ router.Get("/federate", readyf(instrh("federate", httputil.CompressionHandler{
Handler: http.HandlerFunc(h.federation), Handler: http.HandlerFunc(h.federation),
})) })))
router.Get("/consoles/*filepath", instrf("consoles", h.consoles)) router.Get("/consoles/*filepath", readyf(instrf("consoles", h.consoles)))
router.Get("/static/*filepath", instrf("static", serveStaticAsset)) router.Get("/static/*filepath", readyf(instrf("static", serveStaticAsset)))
if o.UserAssetsPath != "" { if o.UserAssetsPath != "" {
router.Get("/user/*filepath", instrf("user", route.FileServe(o.UserAssetsPath))) router.Get("/user/*filepath", readyf(instrf("user", route.FileServe(o.UserAssetsPath))))
} }
if o.EnableLifecycle { if o.EnableLifecycle {
router.Post("/-/quit", h.quit) router.Post("/-/quit", h.quit)
router.Post("/-/reload", h.reload) router.Post("/-/reload", h.reload)
} else { } else {
router.Post("/-/quit", func(w http.ResponseWriter, _ *http.Request) { router.Post("/-/quit", readyf(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusForbidden) w.WriteHeader(http.StatusForbidden)
w.Write([]byte("Lifecycle APIs are not enabled")) w.Write([]byte("Lifecycle APIs are not enabled"))
}) }))
router.Post("/-/reload", func(w http.ResponseWriter, _ *http.Request) { router.Post("/-/reload", readyf(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusForbidden) w.WriteHeader(http.StatusForbidden)
w.Write([]byte("Lifecycle APIs are not enabled")) w.Write([]byte("Lifecycle APIs are not enabled"))
}) }))
} }
router.Get("/-/quit", func(w http.ResponseWriter, _ *http.Request) { router.Get("/-/quit", func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusMethodNotAllowed) w.WriteHeader(http.StatusMethodNotAllowed)
...@@ -229,8 +235,17 @@ func New(o *Options) *Handler { ...@@ -229,8 +235,17 @@ func New(o *Options) *Handler {
w.Write([]byte("Only POST requests allowed")) w.Write([]byte("Only POST requests allowed"))
}) })
router.Get("/debug/*subpath", http.DefaultServeMux.ServeHTTP) router.Get("/debug/*subpath", readyf(http.DefaultServeMux.ServeHTTP))
router.Post("/debug/*subpath", http.DefaultServeMux.ServeHTTP) router.Post("/debug/*subpath", readyf(http.DefaultServeMux.ServeHTTP))
router.Get("/-/healthy", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "Prometheus is Healthy.\n")
})
router.Get("/-/ready", readyf(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "Prometheus is Ready.\n")
}))
return h return h
} }
...@@ -271,6 +286,32 @@ func serveStaticAsset(w http.ResponseWriter, req *http.Request) { ...@@ -271,6 +286,32 @@ func serveStaticAsset(w http.ResponseWriter, req *http.Request) {
http.ServeContent(w, req, info.Name(), info.ModTime(), bytes.NewReader(file)) http.ServeContent(w, req, info.Name(), info.ModTime(), bytes.NewReader(file))
} }
// Ready sets Handler to be ready.
func (h *Handler) Ready() {
atomic.StoreUint32(&h.ready, 1)
}
// Verifies whether the server is ready or not.
func (h *Handler) isReady() bool {
ready := atomic.LoadUint32(&h.ready)
if ready == 0 {
return false
}
return true
}
// Checks if server is ready, calls f if it is, returns 503 if it is not.
func (h *Handler) testReady(f http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if h.isReady() {
f(w, r)
} else {
w.WriteHeader(http.StatusServiceUnavailable)
fmt.Fprintf(w, "Service Unavailable")
}
}
}
// Quit returns the receive-only quit channel. // Quit returns the receive-only quit channel.
func (h *Handler) Quit() <-chan struct{} { func (h *Handler) Quit() <-chan struct{} {
return h.quitCh return h.quitCh
...@@ -564,6 +605,16 @@ func tmplFuncs(consolesPath string, opts *Options) template_text.FuncMap { ...@@ -564,6 +605,16 @@ func tmplFuncs(consolesPath string, opts *Options) template_text.FuncMap {
} }
return u return u
}, },
"numHealthy": func(pool []*retrieval.Target) int {
alive := len(pool)
for _, p := range pool {
if p.Health() != retrieval.HealthGood {
alive--
}
}
return alive
},
"healthToClass": func(th retrieval.TargetHealth) string { "healthToClass": func(th retrieval.TargetHealth) string {
switch th { switch th {
case retrieval.HealthUnknown: case retrieval.HealthUnknown:
......
...@@ -14,8 +14,11 @@ ...@@ -14,8 +14,11 @@
package web package web
import ( import (
"context"
"net/http"
"net/url" "net/url"
"testing" "testing"
"time"
) )
func TestGlobalURL(t *testing.T) { func TestGlobalURL(t *testing.T) {
...@@ -67,3 +70,80 @@ func TestGlobalURL(t *testing.T) { ...@@ -67,3 +70,80 @@ func TestGlobalURL(t *testing.T) {
} }
} }
} }
func TestReadyAndHealthy(t *testing.T) {
opts := &Options{
ListenAddress: ":9090",
ReadTimeout: 30 * time.Second,
MaxConnections: 512,
Context: nil,
Storage: nil,
QueryEngine: nil,
TargetManager: nil,
RuleManager: nil,
Notifier: nil,
RoutePrefix: "/",
MetricsPath: "/metrics/",
}
opts.Flags = map[string]string{}
webHandler := New(opts)
go webHandler.Run(context.Background())
// Give some time for the web goroutine to run since we need the server
// to be up before starting tests.
time.Sleep(5 * time.Second)
resp, err := http.Get("http://localhost:9090/-/healthy")
if err != nil {
t.Fatalf("Unexpected HTTP error %s", err)
}
if resp.StatusCode != http.StatusOK {
t.Fatalf("Path /-/healthy with server unready test, Expected status 200 got: %s", resp.Status)
}
resp, err = http.Get("http://localhost:9090/-/ready")
if err != nil {
t.Fatalf("Unexpected HTTP error %s", err)
}
if resp.StatusCode != http.StatusServiceUnavailable {
t.Fatalf("Path /-/ready with server unready test, Expected status 503 got: %s", resp.Status)
}
resp, err = http.Get("http://localhost:9090/version")
if err != nil {
t.Fatalf("Unexpected HTTP error %s", err)
}
if resp.StatusCode != http.StatusServiceUnavailable {
t.Fatalf("Path /version with server unready test, Expected status 503 got: %s", resp.Status)
}
// Set to ready.
webHandler.Ready()
resp, err = http.Get("http://localhost:9090/-/healthy")
if err != nil {
t.Fatalf("Unexpected HTTP error %s", err)
}
if resp.StatusCode != http.StatusOK {
t.Fatalf("Path /-/healthy with server ready test, Expected status 200 got: %s", resp.Status)
}
resp, err = http.Get("http://localhost:9090/-/ready")
if err != nil {
t.Fatalf("Unexpected HTTP error %s", err)
}
if resp.StatusCode != http.StatusOK {
t.Fatalf("Path /-/ready with server ready test, Expected status 200 got: %s", resp.Status)
}
resp, err = http.Get("http://localhost:9090/version")
if err != nil {
t.Fatalf("Unexpected HTTP error %s", err)
}
if resp.StatusCode != http.StatusOK {
t.Fatalf("Path /version with server ready test, Expected status 200 got: %s", resp.Status)
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册