From 0bb194c956ac41eed5445c962b33f56d904b7759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Mon, 16 Oct 2017 16:30:13 +0300 Subject: [PATCH 1/3] cmd/faucet: support twitter, google+ and facebook auth too --- cmd/faucet/faucet.go | 255 +++++++++++++++++++++++++++++++---------- cmd/faucet/faucet.html | 25 +++- cmd/faucet/website.go | 2 +- 3 files changed, 215 insertions(+), 67 deletions(-) diff --git a/cmd/faucet/faucet.go b/cmd/faucet/faucet.go index 8cd62441e..6b2987315 100644 --- a/cmd/faucet/faucet.go +++ b/cmd/faucet/faucet.go @@ -21,8 +21,10 @@ package main import ( "bytes" + "compress/zlib" "context" "encoding/json" + "errors" "flag" "fmt" "html/template" @@ -33,6 +35,7 @@ import ( "net/url" "os" "path/filepath" + "regexp" "strconv" "strings" "sync" @@ -181,10 +184,10 @@ func main() { // request represents an accepted funding request. type request struct { - Username string `json:"username"` // GitHub user for displaying an avatar - Account common.Address `json:"account"` // Ethereum address being funded - Time time.Time `json:"time"` // Timestamp when te request was accepted - Tx *types.Transaction `json:"tx"` // Transaction funding the account + Avatar string `json:"avatar"` // Avatar URL to make the UI nicer + Account common.Address `json:"account"` // Ethereum address being funded + Time time.Time `json:"time"` // Timestamp when te request was accepted + Tx *types.Transaction `json:"tx"` // Transaction funding the account } // faucet represents a crypto faucet backed by an Ethereum light client. @@ -344,15 +347,16 @@ func (f *faucet) apiHandler(conn *websocket.Conn) { if err := websocket.JSON.Receive(conn, &msg); err != nil { return } - if !strings.HasPrefix(msg.URL, "https://gist.github.com/") { - websocket.JSON.Send(conn, map[string]string{"error": "URL doesn't link to GitHub Gists"}) + if !strings.HasPrefix(msg.URL, "https://gist.github.com/") && !strings.HasPrefix(msg.URL, "https://twitter.com/") && + !strings.HasPrefix(msg.URL, "https://plus.google.com/") && !strings.HasPrefix(msg.URL, "https://www.facebook.com/") { + websocket.JSON.Send(conn, map[string]string{"error": "URL doesn't link to supported services"}) continue } if msg.Tier >= uint(*tiersFlag) { websocket.JSON.Send(conn, map[string]string{"error": "Invalid funding tier requested"}) continue } - log.Info("Faucet funds requested", "gist", msg.URL, "tier", msg.Tier) + log.Info("Faucet funds requested", "url", msg.URL, "tier", msg.Tier) // If captcha verifications are enabled, make sure we're not dealing with a robot if *captchaToken != "" { @@ -381,65 +385,37 @@ func (f *faucet) apiHandler(conn *websocket.Conn) { continue } } - // Retrieve the gist from the GitHub Gist APIs - parts := strings.Split(msg.URL, "/") - req, _ := http.NewRequest("GET", "https://api.github.com/gists/"+parts[len(parts)-1], nil) - if *githubUser != "" { - req.SetBasicAuth(*githubUser, *githubToken) + // Retrieve the Ethereum address to fund, the requesting user and a profile picture + var ( + username string + avatar string + address common.Address + ) + switch { + case strings.HasPrefix(msg.URL, "https://gist.github.com/"): + username, avatar, address, err = authGitHub(msg.URL) + case strings.HasPrefix(msg.URL, "https://twitter.com/"): + username, avatar, address, err = authTwitter(msg.URL) + case strings.HasPrefix(msg.URL, "https://plus.google.com/"): + username, avatar, address, err = authGooglePlus(msg.URL) + case strings.HasPrefix(msg.URL, "https://www.facebook.com/"): + username, avatar, address, err = authFacebook(msg.URL) + default: + err = errors.New("Something funky happened, please open an issue at https://github.com/ethereum/go-ethereum/issues") } - res, err := http.DefaultClient.Do(req) if err != nil { websocket.JSON.Send(conn, map[string]string{"error": err.Error()}) continue } - var gist struct { - Owner struct { - Login string `json:"login"` - } `json:"owner"` - Files map[string]struct { - Content string `json:"content"` - } `json:"files"` - } - err = json.NewDecoder(res.Body).Decode(&gist) - res.Body.Close() - if err != nil { - websocket.JSON.Send(conn, map[string]string{"error": err.Error()}) - continue - } - if gist.Owner.Login == "" { - websocket.JSON.Send(conn, map[string]string{"error": "Anonymous Gists not allowed"}) - continue - } - // Iterate over all the files and look for Ethereum addresses - var address common.Address - for _, file := range gist.Files { - content := strings.TrimSpace(file.Content) - if len(content) == 2+common.AddressLength*2 { - address = common.HexToAddress(content) - } - } - if address == (common.Address{}) { - websocket.JSON.Send(conn, map[string]string{"error": "No Ethereum address found to fund"}) - continue - } - // Validate the user's existence since the API is unhelpful here - if res, err = http.Head("https://github.com/" + gist.Owner.Login); err != nil { - websocket.JSON.Send(conn, map[string]string{"error": err.Error()}) - continue - } - res.Body.Close() + log.Info("Faucet request valid", "url", msg.URL, "tier", msg.Tier, "user", username, "address", address) - if res.StatusCode != 200 { - websocket.JSON.Send(conn, map[string]string{"error": "Invalid user... boom!"}) - continue - } // Ensure the user didn't request funds too recently f.lock.Lock() var ( fund bool timeout time.Time ) - if timeout = f.timeouts[gist.Owner.Login]; time.Now().After(timeout) { + if timeout = f.timeouts[username]; time.Now().After(timeout) { // User wasn't funded recently, create the funding transaction amount := new(big.Int).Mul(big.NewInt(int64(*payoutFlag)), ether) amount = new(big.Int).Mul(amount, new(big.Int).Exp(big.NewInt(5), big.NewInt(int64(msg.Tier)), nil)) @@ -459,12 +435,12 @@ func (f *faucet) apiHandler(conn *websocket.Conn) { continue } f.reqs = append(f.reqs, &request{ - Username: gist.Owner.Login, - Account: address, - Time: time.Now(), - Tx: signed, + Avatar: avatar, + Account: address, + Time: time.Now(), + Tx: signed, }) - f.timeouts[gist.Owner.Login] = time.Now().Add(time.Duration(*minutesFlag*int(math.Pow(3, float64(msg.Tier)))) * time.Minute) + f.timeouts[username] = time.Now().Add(time.Duration(*minutesFlag*int(math.Pow(3, float64(msg.Tier)))) * time.Minute) fund = true } f.lock.Unlock() @@ -474,7 +450,7 @@ func (f *faucet) apiHandler(conn *websocket.Conn) { websocket.JSON.Send(conn, map[string]string{"error": fmt.Sprintf("%s left until next allowance", common.PrettyDuration(timeout.Sub(time.Now())))}) continue } - websocket.JSON.Send(conn, map[string]string{"success": fmt.Sprintf("Funding request accepted for %s into %s", gist.Owner.Login, address.Hex())}) + websocket.JSON.Send(conn, map[string]string{"success": fmt.Sprintf("Funding request accepted for %s into %s", username, address.Hex())}) select { case f.update <- struct{}{}: default: @@ -542,3 +518,162 @@ func (f *faucet) loop() { } } } + +// authGitHub tries to authenticate a faucet request using GitHub gists, returning +// the username, avatar URL and Ethereum address to fund on success. +func authGitHub(url string) (string, string, common.Address, error) { + // Retrieve the gist from the GitHub Gist APIs + parts := strings.Split(url, "/") + req, _ := http.NewRequest("GET", "https://api.github.com/gists/"+parts[len(parts)-1], nil) + if *githubUser != "" { + req.SetBasicAuth(*githubUser, *githubToken) + } + res, err := http.DefaultClient.Do(req) + if err != nil { + return "", "", common.Address{}, err + } + var gist struct { + Owner struct { + Login string `json:"login"` + } `json:"owner"` + Files map[string]struct { + Content string `json:"content"` + } `json:"files"` + } + err = json.NewDecoder(res.Body).Decode(&gist) + res.Body.Close() + if err != nil { + return "", "", common.Address{}, err + } + if gist.Owner.Login == "" { + return "", "", common.Address{}, errors.New("Anonymous Gists not allowed") + } + // Iterate over all the files and look for Ethereum addresses + var address common.Address + for _, file := range gist.Files { + content := strings.TrimSpace(file.Content) + if len(content) == 2+common.AddressLength*2 { + address = common.HexToAddress(content) + } + } + if address == (common.Address{}) { + return "", "", common.Address{}, errors.New("No Ethereum address found to fund") + } + // Validate the user's existence since the API is unhelpful here + if res, err = http.Head("https://github.com/" + gist.Owner.Login); err != nil { + return "", "", common.Address{}, err + } + res.Body.Close() + + if res.StatusCode != 200 { + return "", "", common.Address{}, errors.New("Invalid user... boom!") + } + // Everything passed validation, return the gathered infos + return gist.Owner.Login + "@github", fmt.Sprintf("https://github.com/%s.png?size=64", gist.Owner.Login), address, nil +} + +// authTwitter tries to authenticate a faucet request using Twitter posts, returning +// the username, avatar URL and Ethereum address to fund on success. +func authTwitter(url string) (string, string, common.Address, error) { + // Ensure the user specified a meaningful URL, no fancy nonsense + parts := strings.Split(url, "/") + if len(parts) < 4 || parts[len(parts)-2] != "status" { + return "", "", common.Address{}, errors.New("Invalid Twitter status URL") + } + username := parts[len(parts)-3] + + // Twitter's API isn't really friendly with direct links. Still, we don't + // want to do ask read permissions from users, so just load the public posts and + // scrape it for the Ethereum address and profile URL. + res, err := http.Get(url) + if err != nil { + return "", "", common.Address{}, err + } + defer res.Body.Close() + + reader, err := zlib.NewReader(res.Body) + if err != nil { + return "", "", common.Address{}, err + } + body, err := ioutil.ReadAll(reader) + if err != nil { + return "", "", common.Address{}, err + } + address := common.HexToAddress(string(regexp.MustCompile("0x[0-9a-fA-F]{40}").Find(body))) + if address == (common.Address{}) { + return "", "", common.Address{}, errors.New("No Ethereum address found to fund") + } + var avatar string + if parts = regexp.MustCompile("src=\"([^\"]+twimg.com/profile_images[^\"]+)\"").FindStringSubmatch(string(body)); len(parts) == 2 { + avatar = parts[1] + } + return username + "@twitter", avatar, address, nil +} + +// authGooglePlus tries to authenticate a faucet request using GooglePlus posts, +// returning the username, avatar URL and Ethereum address to fund on success. +func authGooglePlus(url string) (string, string, common.Address, error) { + // Ensure the user specified a meaningful URL, no fancy nonsense + parts := strings.Split(url, "/") + if len(parts) < 4 || parts[len(parts)-2] != "posts" { + return "", "", common.Address{}, errors.New("Invalid Google+ post URL") + } + username := parts[len(parts)-3] + + // Google's API isn't really friendly with direct links. Still, we don't + // want to do ask read permissions from users, so just load the public posts and + // scrape it for the Ethereum address and profile URL. + res, err := http.Get(url) + if err != nil { + return "", "", common.Address{}, err + } + defer res.Body.Close() + + body, err := ioutil.ReadAll(res.Body) + if err != nil { + return "", "", common.Address{}, err + } + address := common.HexToAddress(string(regexp.MustCompile("0x[0-9a-fA-F]{40}").Find(body))) + if address == (common.Address{}) { + return "", "", common.Address{}, errors.New("No Ethereum address found to fund") + } + var avatar string + if parts = regexp.MustCompile("src=\"([^\"]+googleusercontent.com[^\"]+photo.jpg)\"").FindStringSubmatch(string(body)); len(parts) == 2 { + avatar = parts[1] + } + return username + "@google+", avatar, address, nil +} + +// authFacebook tries to authenticate a faucet request using Facebook posts, +// returning the username, avatar URL and Ethereum address to fund on success. +func authFacebook(url string) (string, string, common.Address, error) { + // Ensure the user specified a meaningful URL, no fancy nonsense + parts := strings.Split(url, "/") + if len(parts) < 4 || parts[len(parts)-2] != "posts" { + return "", "", common.Address{}, errors.New("Invalid Facebook post URL") + } + username := parts[len(parts)-3] + + // Facebook's Graph API isn't really friendly with direct links. Still, we don't + // want to do ask read permissions from users, so just load the public posts and + // scrape it for the Ethereum address and profile URL. + res, err := http.Get(url) + if err != nil { + return "", "", common.Address{}, err + } + defer res.Body.Close() + + body, err := ioutil.ReadAll(res.Body) + if err != nil { + return "", "", common.Address{}, err + } + address := common.HexToAddress(string(regexp.MustCompile("0x[0-9a-fA-F]{40}").Find(body))) + if address == (common.Address{}) { + return "", "", common.Address{}, errors.New("No Ethereum address found to fund") + } + var avatar string + if parts = regexp.MustCompile("src=\"([^\"]+fbcdn.net[^\"]+)\"").FindStringSubmatch(string(body)); len(parts) == 2 { + avatar = parts[1] + } + return username + "@facebook", avatar, address, nil +} diff --git a/cmd/faucet/faucet.html b/cmd/faucet/faucet.html index 56dd37623..3b928d636 100644 --- a/cmd/faucet/faucet.html +++ b/cmd/faucet/faucet.html @@ -5,7 +5,7 @@ - {{.Network}}: GitHub Faucet + {{.Network}}: Authenticated Faucet @@ -43,13 +43,13 @@
-

{{.Network}} GitHub Authenticated Faucet

+

{{.Network}} Authenticated Faucet

- +
" + msg.requests[i].account + "
" + moment.duration(moment(msg.requests[i].time).unix()-moment().unix(), 'seconds').humanize(true) + ""; + content += "
" + msg.requests[i].account + "
" + moment.duration(moment(msg.requests[i].time).unix()-moment().unix(), 'seconds').humanize(true) + ""; } $("#requests").html("" + content + ""); } diff --git a/cmd/faucet/website.go b/cmd/faucet/website.go index 3151ab584..5a80cb0a7 100644 --- a/cmd/faucet/website.go +++ b/cmd/faucet/website.go @@ -68,7 +68,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _faucetHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x59\x6d\x6f\xdc\x36\x12\xfe\xec\xfc\x8a\xa9\x2e\xad\x77\x61\x4b\xb2\xe3\x20\x2d\xd6\xd2\x16\x41\x9a\x4b\x7b\x38\xb4\x45\x9b\xe2\xae\x68\x8b\x03\x25\xcd\x4a\x8c\x29\x52\x25\x87\xbb\xde\x1a\xfb\xdf\x0f\x24\x25\xad\x76\x6d\xa7\xb9\x4b\xf3\x61\x23\x92\x33\xcf\xbc\x51\xf3\x22\x67\x9f\x7c\xf5\xdd\xab\xb7\x3f\x7f\xff\x1a\x1a\x6a\xc5\xf2\x49\xe6\xfe\x03\xc1\x64\x9d\x47\x28\xa3\xe5\x93\x93\xac\x41\x56\x2d\x9f\x9c\x9c\x64\x2d\x12\x83\xb2\x61\xda\x20\xe5\x91\xa5\x55\xfc\x45\xb4\x3f\x68\x88\xba\x18\x7f\xb7\x7c\x9d\x47\xff\x8e\x7f\x7a\x19\xbf\x52\x6d\xc7\x88\x17\x02\x23\x28\x95\x24\x94\x94\x47\xdf\xbc\xce\xb1\xaa\x71\xc2\x27\x59\x8b\x79\xb4\xe6\xb8\xe9\x94\xa6\x09\xe9\x86\x57\xd4\xe4\x15\xae\x79\x89\xb1\x5f\x9c\x03\x97\x9c\x38\x13\xb1\x29\x99\xc0\xfc\x32\x5a\x3e\x71\x38\xc4\x49\xe0\xf2\xee\x2e\xf9\x16\x69\xa3\xf4\xcd\x6e\xb7\x80\x37\x9c\xbe\xb6\x05\xfc\x9d\xd9\x12\x29\x4b\x03\x89\xa7\x16\x5c\xde\x40\xa3\x71\x95\x47\x4e\x67\xb3\x48\xd3\xb2\x92\xef\x4c\x52\x0a\x65\xab\x95\x60\x1a\x93\x52\xb5\x29\x7b\xc7\x6e\x53\xc1\x0b\x93\xd2\x86\x13\xa1\x8e\x0b\xa5\xc8\x90\x66\x5d\x7a\x95\x5c\x25\x9f\xa7\xa5\x31\xe9\xb8\x97\xb4\x5c\x26\xa5\x31\x11\x68\x14\x79\x64\x68\x2b\xd0\x34\x88\x14\x41\xba\xfc\xff\xe4\xae\x94\xa4\x98\x6d\xd0\xa8\x16\xd3\xe7\xc9\xe7\xc9\x85\x17\x39\xdd\x7e\xbf\x54\x27\xd6\x94\x9a\x77\x04\x46\x97\x1f\x2c\xf7\xdd\xef\x16\xf5\x36\xbd\x4a\x2e\x93\xcb\x7e\xe1\xe5\xbc\x33\xd1\x32\x4b\x03\xe0\xf2\xa3\xb0\x63\xa9\x68\x9b\x3e\x4b\x9e\x27\x97\x69\xc7\xca\x1b\x56\x63\x35\x48\x72\x47\xc9\xb0\xf9\x97\xc9\x7d\x2c\x86\xef\x8e\x43\xf8\x57\x08\x6b\x55\x8b\x92\x92\x77\x26\x7d\x96\x5c\x7e\x91\x5c\x0c\x1b\xf7\xf1\xbd\x00\x17\x34\x27\xea\x24\x59\xa3\x26\x5e\x32\x11\x97\x28\x09\x35\xdc\xb9\xdd\x93\x96\xcb\xb8\x41\x5e\x37\xb4\x80\xcb\x8b\x8b\x4f\xaf\x1f\xda\x5d\x37\x61\xbb\xe2\xa6\x13\x6c\xbb\x80\x95\xc0\xdb\xb0\xc5\x04\xaf\x65\xcc\x09\x5b\xb3\x80\x80\xec\x0f\x76\x5e\x66\xa7\x55\xad\xd1\x98\x5e\x58\xa7\x0c\x27\xae\xe4\xc2\xdd\x28\x46\x7c\x8d\x0f\xd1\x9a\x8e\xc9\x7b\x0c\xac\x30\x4a\x58\xc2\x23\x45\x0a\xa1\xca\x9b\xb0\xe7\x5f\xe3\xa9\x11\xa5\x12\x4a\x2f\x60\xd3\xf0\x9e\x0d\xbc\x20\xe8\x34\xf6\xf0\xd0\xb1\xaa\xe2\xb2\x5e\xc0\x8b\xae\xb7\x07\x5a\xa6\x6b\x2e\x17\x70\xb1\x67\xc9\xd2\xc1\x8d\x59\x1a\x32\xd6\x93\x93\xac\x50\xd5\xd6\xc7\xb0\xe2\x6b\x28\x05\x33\x26\x8f\x8e\x5c\xec\x33\xd1\x01\x81\x4b\x40\x8c\xcb\xe1\xe8\xe0\x4c\xab\x4d\x04\x5e\x50\x1e\x05\x25\xe2\x42\x11\xa9\x76\x01\x97\x4e\xbd\x9e\xe5\x08\x4f\xc4\xa2\x8e\x2f\x9f\x0d\x87\x27\x59\x73\x39\x80\x10\xde\x52\xec\xe3\x33\x46\x26\x5a\x66\x7c\xe0\x5d\x31\x58\xb1\xb8\x60\xd4\x44\xc0\x34\x67\x71\xc3\xab\x0a\x65\x1e\x91\xb6\xe8\xee\x11\x5f\xc2\x34\xef\x0d\x69\xef\xa5\xa5\x06\xa5\xb3\x93\xb0\xea\x93\x20\x1c\xc3\xd6\x9c\x1a\x5b\xc4\x4c\xd0\xa3\xe0\x59\xda\x5c\x0e\x26\xa5\x15\x5f\xf7\x1e\x99\x3c\x1e\x39\xe7\x71\xfb\xbf\x80\xfe\x41\xad\x56\x06\x29\x9e\xb8\x63\x42\xcc\x65\x67\x29\xae\xb5\xb2\xdd\x78\x7e\x92\xf9\x5d\xe0\x55\x1e\xd5\xdc\x50\x04\xb4\xed\x7a\xdf\x45\xa3\x49\x4a\xb7\xb1\x0b\x9d\x56\x22\x82\x4e\xb0\x12\x1b\x25\x2a\xd4\x79\xd4\xfb\xe4\x0d\x37\x04\x3f\xfd\xf0\x4f\xe8\x03\xcc\x65\x0d\x5b\x65\x35\xbc\xa6\x06\x35\xda\x16\x58\x55\xb9\xcb\x9d\x24\xc9\x44\xb6\xbf\xe9\xf7\xb5\x8b\x0b\x92\x7b\xaa\x93\xac\xb0\x44\x6a\x24\x2c\x48\x42\x41\x32\xae\x70\xc5\xac\x20\xa8\xb4\xea\x2a\xb5\x91\x31\xa9\xba\x76\x05\x31\x58\x10\x98\x22\xa8\x18\xb1\xfe\x28\x8f\x06\xda\x21\x28\xcc\x74\xaa\xb3\x5d\x1f\x96\xb0\x89\xb7\x1d\x93\x15\x56\x2e\x94\xc2\x60\xb4\x7c\xc3\xd7\x08\x2d\x06\x5b\x4e\x8e\x23\x5d\x32\x8d\x14\x4f\x41\x1f\x88\x74\x50\x26\x98\x04\xfd\xbf\xcc\x8a\x01\x69\x34\xa1\x45\x69\xe1\x60\x15\x6b\x97\x85\xa2\xe5\xdd\x9d\x66\xb2\x46\x78\xca\xab\xdb\x73\x78\xca\x5a\x65\x25\xc1\x22\x87\xe4\xa5\x7f\x34\xbb\xdd\x01\x3a\x40\x26\xf8\x32\x63\xef\x7b\x19\x40\xc9\x52\xf0\xf2\x26\x8f\x88\xa3\xce\xef\xee\x1c\xf8\x6e\x77\x0d\x77\x77\x7c\x05\x4f\x93\x1f\xb0\x64\x1d\x95\x0d\xdb\xed\x6a\x3d\x3c\x27\x78\x8b\xa5\x25\x9c\xcd\xef\xee\x50\x18\xdc\xed\x8c\x2d\x5a\x4e\xb3\x81\xdd\xed\xcb\x6a\xb7\x73\x3a\xf7\x7a\xee\x76\x90\x3a\x50\x59\xe1\x2d\x3c\x4d\xbe\x47\xcd\x55\x65\x20\xd0\x67\x29\x5b\x66\xa9\xe0\xcb\x9e\xef\xd0\x49\xa9\x15\xfb\xfb\x92\xba\x0b\x33\x5e\x6d\xff\xa6\x78\x55\xa7\x9a\x3e\x70\xf1\xeb\x78\xd4\xbe\xbf\x0f\x86\x13\xde\xe0\x36\x8f\xee\xee\xa6\xbc\xfd\x69\xc9\x84\x28\x98\xf3\x4b\x30\x6d\x64\xfa\x03\xdd\x3d\x5d\x73\xe3\x3b\xaf\xe5\xa0\xc1\x5e\xed\x0f\x7c\x93\x8f\xd2\x1c\xa9\x6e\x01\x57\xcf\x26\x39\xee\xa1\x97\xfc\xc5\xd1\x4b\x7e\xf5\x20\x71\xc7\x24\x0a\xf0\xbf\xb1\x69\x99\x18\x9e\xfb\xb7\x65\xf2\xf2\x1d\x33\xc5\x2e\xa3\x8f\xaa\x8d\x95\xe1\xe2\x1a\xd4\x1a\xf5\x4a\xa8\xcd\x02\x98\x25\x75\x0d\x2d\xbb\x1d\xab\xe3\xd5\xc5\xc5\x54\x6f\xd7\x31\xb2\x42\xa0\x4f\x28\x1a\x7f\xb7\x68\xc8\x8c\x89\x24\x1c\xf9\x5f\x97\x4f\x2a\x94\x06\xab\x23\x6f\x38\x89\xce\xb5\x9e\x6a\x12\xfa\xd1\x99\x0f\xea\xbe\x52\x6a\x2c\x38\x53\x35\x7a\xe8\x49\x6d\x8c\x96\x19\xe9\x3d\xdd\x49\x46\xd5\xff\x54\x30\xb4\x6b\x08\x1f\xab\x17\x21\xa3\x39\xdb\x3b\x44\x1d\xba\x11\x77\x65\xc1\x2f\xb3\x94\xaa\x8f\x90\xec\x2e\x61\xc1\x0c\x7e\x88\x78\xdf\x17\xec\xc5\xfb\xe5\xc7\xca\x6f\x90\x69\x2a\x90\x3d\x5e\xd2\x26\x0a\xac\xac\xac\x26\xf6\xfb\xdc\xf9\xb1\x0a\x58\xc9\xd7\xa8\x0d\xa7\xed\x87\x6a\x80\xd5\x5e\x85\xb0\x3e\x54\x21\x4b\x49\xbf\xff\xae\x4d\x17\x7f\xd1\xcb\xfd\x67\x0d\xcc\xd5\xf2\x6b\xb5\x81\x4a\xa1\x01\x6a\xb8\x01\xd7\x7e\x7c\x99\xa5\xcd\xd5\x48\xd2\x2d\xdf\xba\x03\xef\x54\x58\x85\x0e\x84\x1b\xd0\x56\xfa\xca\xab\x24\x50\x83\x87\xcd\x8b\x0c\x4f\x09\xbc\x55\xae\x01\x5c\xa3\x24\x68\x99\xe0\x25\x57\xd6\x00\x2b\x49\x69\x03\x2b\xad\x5a\xc0\xdb\x86\x59\x43\x0e\xc8\xa5\x0f\xb6\x66\x5c\xf8\x77\xc9\x87\x14\x94\x06\x56\x96\xb6\xb5\xae\x81\x95\x35\xa0\x54\xb6\x6e\x7a\x5d\x48\x41\x28\x4c\x42\xc9\x7a\xd4\xc7\x74\xac\x05\x46\xc4\xca\x1b\x73\x0e\x43\x56\x00\xa6\x11\x88\x63\xe5\xb8\xfa\x3e\x82\x95\xa5\x2f\x66\x09\xbc\x94\x5b\x25\x11\x1a\xb6\xf6\x8a\x1c\x11\x40\xcb\xb6\x03\x50\xaf\xd7\x86\x53\xc3\x83\xe1\x1d\xea\xd6\x4d\x24\x15\x08\xde\x72\x32\x49\x96\x76\x53\xdf\xa9\x43\xd6\x73\x30\xbc\xed\xc4\x16\x4a\x8d\x8c\x10\x18\x64\xec\x68\x98\x74\xad\x51\x12\x7a\x3a\x3f\x8e\x44\x40\x4c\xd7\x6e\x54\xff\x0f\x2b\x94\xa5\x45\x21\x98\xbc\x71\xad\xc2\xd8\x0e\xb9\xb2\xe6\x95\x7a\xb8\x11\x82\x8e\x19\xa7\x21\x97\xa4\xbc\xd2\xfd\x6c\x6e\x60\xe6\x56\x2b\x2e\xd0\x8f\xef\xfe\x1e\xc8\x53\x67\xb1\x9b\xb1\xe6\xe7\x50\xaa\x6e\x1b\xb8\x3d\x9f\x53\xcd\xf8\xde\x6b\x84\x62\x85\x5a\x23\x84\xc6\xae\x50\xb7\xc0\x64\x05\x2b\xae\x11\xd8\x86\x6d\x3f\x81\x9f\x95\x85\x92\x49\x20\xcd\xca\x9b\x20\xdb\x6a\xed\x2e\x44\x87\xd2\x25\xfd\x7d\x88\x0a\x14\x6a\xe3\x49\x02\xda\x8a\xa3\xf0\xf1\x32\x88\xd0\xa8\x0d\xb4\xb6\xf4\x06\xba\x40\xa1\x3b\xd8\x30\x4e\x60\x25\x71\x11\xec\x26\xab\x25\x94\xaa\xc5\x83\x28\xdc\xab\xda\x19\xb6\xcb\xb7\xce\xee\x7b\x97\x79\xac\xb7\xa0\xf1\x55\x20\x87\x4e\x2b\xc2\xd2\x0d\x46\xc0\x6a\xc6\xa5\x71\x76\xfa\x38\x63\xfb\x01\xf5\x78\x7c\xea\x1f\xf6\x93\xa8\x3f\x4e\x53\x78\x23\x54\xc1\x04\xac\x5d\x96\x29\x84\x7b\x11\x15\xb8\x96\xf7\xc0\x5b\x86\x18\x59\x03\x6a\xe5\x77\x83\xe6\x8e\x7f\xcd\xb4\xbb\xed\xd8\x76\x04\x79\x3f\x47\xb9\x3d\x83\x7a\xdd\x4f\x87\x6e\xe9\x7a\xae\x70\xde\x0b\xfd\x0a\x57\x5c\x86\xa0\xae\xac\x0c\xe6\x51\xc3\x08\x42\x17\x62\x80\xf9\x60\x83\xd5\x02\xfa\x48\x07\xc8\x51\x80\xa7\x83\x7c\x64\x9f\xdd\xf3\x73\xff\xd0\xfb\x68\xde\xcf\x81\x01\x26\x31\x28\xab\xd9\x3f\x7e\xfc\xee\xdb\xc4\x90\xe6\xb2\xe6\xab\xed\xec\xce\x6a\xb1\x80\xa7\xb3\xe8\x6f\x7e\x3c\x98\xff\x72\xf1\x5b\xb2\x66\xc2\xe2\xb9\x37\x60\xe1\x7f\xef\x89\x39\x87\xfe\x71\x01\x87\x12\x77\xf3\xf9\xf5\xc3\x2d\xdb\xa4\xc3\xd4\x68\x90\x66\x8e\x70\x8c\xe4\xee\xfa\xd0\x49\x0c\x5a\xa4\x46\xf9\xbb\xa8\xb1\x54\x52\x62\x49\x60\x3b\x25\x7b\x9f\x80\x50\xc6\x0c\x8e\xd9\x53\x4c\x7c\x33\x18\xcf\x57\x30\x1b\xc2\xf5\x29\x3c\x83\x3c\x87\x8b\xe1\xac\xf7\x0c\xe4\x20\x71\x03\xff\xc2\xe2\x47\x55\xde\x20\xcd\xa2\x8d\x71\x69\x21\x82\x33\x10\xaa\x64\x0e\x2f\x69\x94\x21\x38\x83\x28\x65\x1d\x8f\xe6\x61\x9a\xde\x81\x6b\x91\xff\x1c\xec\x83\xb0\xc2\xf7\x86\xa0\xe9\xd9\x59\xb8\x36\x43\xe8\x94\x6c\xd1\x18\x56\xe3\xd4\x42\x9f\xe5\x47\x53\x9c\x23\x5a\x53\x43\x0e\x3e\xc4\x1d\xd3\x06\x03\x49\xe2\x3a\x8b\x5e\x8a\x77\x87\x27\xcb\x73\x90\x56\x88\x91\xff\x44\xa3\x7b\x99\x7b\xb2\xdd\x93\x03\xf2\x24\x24\xe1\x4f\xf2\x1c\x5c\x99\x75\x31\xaa\xf6\x9c\xee\xfa\x84\x86\x60\x9e\xb8\x4a\xbf\xe7\x98\x8f\x70\xf7\xd0\xb0\xfa\x33\x38\xac\x8e\xf1\xb0\x7a\x04\xd0\xf7\x5f\xef\xc3\x0b\xfd\xda\x04\xce\x6f\x3c\x82\x26\x6d\x5b\xa0\x7e\x1f\x5c\xe8\xbf\x7a\x38\xef\xea\x6f\x24\x4d\x78\xcf\xe1\xf2\xc5\xfc\x11\x74\xd4\x5a\x3d\x0a\x2e\x15\x6d\x67\x77\x82\x6d\x5d\xd5\x81\x53\x52\xdd\x2b\xdf\x2e\x9d\x9e\x83\x93\xb5\x80\x11\xe1\xdc\x0f\xc2\x0b\x38\xf5\xab\xd3\xdd\x23\xd2\x8c\x2d\x4b\x57\x8f\x3e\x46\x5e\x8f\x31\x4a\xec\xd7\x8f\xca\x1c\xeb\xcb\x81\x50\xf8\xec\x33\xb8\x77\x7a\x78\x05\xdd\x1d\xee\x0b\x25\xe4\x10\x45\x3d\xfc\xc9\x4a\x69\x98\xb9\x43\x9e\x5f\x5c\x03\xcf\xa6\x30\x89\x40\x59\x53\x73\x0d\xfc\xec\x6c\x8f\x74\x32\xc0\x9c\xe5\x10\xb9\x89\x20\xa3\x6a\xe9\x3b\xb3\xd0\xbe\xfd\x1a\xb9\x09\xb0\xd6\xca\xca\x6a\xe1\x52\xee\xec\x74\xdf\x0c\x4c\xfa\x80\xb3\x03\x95\x7f\xe1\xbf\x25\xd6\xa0\xf6\x95\xfb\x0c\xa2\xa4\x93\xf5\x97\x7e\x6e\x7c\xf1\xfc\x74\x7e\x0d\x7b\x4c\x3f\x4d\x2e\xa0\x74\xb3\xd5\x35\x84\xf9\xc4\x77\x89\x30\x4e\x56\x7e\x55\x28\x5d\xa1\x8e\x35\xab\xb8\x35\x0b\x78\xde\xdd\x5e\xff\x3a\x4c\x9e\xbe\x97\xf5\x7a\x77\x1a\x97\x0f\xe9\x32\xb4\x4b\x67\x10\x65\xa9\x23\x1a\x58\x46\x2b\xa7\x5f\x0d\xe1\x81\x2e\x1c\xc6\x6f\x7a\xfd\x7e\xcb\xab\x4a\xa0\x53\xc2\x0b\x0c\x1f\x5f\x2b\xab\x7d\xe2\x9a\x85\xf5\xec\x58\x0f\xe2\x2d\xce\x13\x2b\xf9\xed\x6c\x1e\xf7\x34\xc3\xfa\x1c\x4e\x8d\xcb\xcf\x95\x39\x9d\x27\x8d\x6d\x99\xe4\x7f\xe0\xcc\xb5\xf4\xf3\xa0\xb7\xd3\xd8\xf5\xe9\x63\xb4\x77\x93\x17\x6d\x9c\x31\xe7\x49\x43\xad\x98\x45\x19\xf9\x2f\x93\x4e\xb9\x31\xc4\x1e\x25\x6c\x1f\xde\xc8\xdd\x61\x0e\x2d\x85\x32\x78\x54\x23\xc0\x20\xbd\xe5\x2d\x2a\x4b\xb3\xb1\x8e\x9c\xbb\xb9\xf7\x62\x7e\x0d\xbb\xfd\x07\xdc\x34\x85\xd7\xc6\x4d\x12\xdc\x34\xc0\x60\x83\x85\xf1\xf9\x1d\x7a\x1e\x5f\xce\x43\xd9\x7e\xf9\xfd\x37\x93\xd2\x3d\xa2\xce\xbc\x72\xe3\x07\xec\x87\xea\xe4\x83\x5f\xcc\x37\x9b\x4d\x52\x2b\x55\x8b\xf0\xad\x7c\x2c\xa4\xae\x7a\x24\xef\xdc\xb8\x6a\xb6\xb2\x84\x0a\x57\xa8\x97\x13\xf8\xbe\xba\x66\x69\xf8\x96\x9b\xa5\xe1\xef\x54\xff\x0d\x00\x00\xff\xff\x71\x50\x77\xf3\xb8\x1a\x00\x00") +var _faucetHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x3a\x7f\x73\xe3\xb6\xb1\x7f\xfb\x3e\xc5\x86\xef\x5c\x4b\x63\x93\x94\xe5\xcb\xd5\x4f\x26\x95\xb9\xb9\xa6\x69\xde\xbc\x69\x6f\x92\xeb\xbc\xd7\x69\x3b\x6f\x40\x72\x45\xe2\x0c\x02\x0c\xb0\x94\xac\x78\xf4\xdd\xdf\x00\x20\x29\x4a\xb6\xef\x9c\xbb\x4c\x9b\xfb\xc3\x21\x80\xfd\xbd\x8b\xdd\xc5\x2a\xc9\x57\x7f\xf8\xcb\xdb\xf7\x7f\x7b\xf7\x2d\x54\x54\x8b\xe5\x8b\xc4\xfe\x07\x04\x93\x65\x1a\xa0\x0c\x96\x2f\x4e\x92\x0a\x59\xb1\x7c\x71\x72\x92\xd4\x48\x0c\xf2\x8a\x69\x83\x94\x06\x2d\xad\xc2\xeb\x60\x7f\x50\x11\x35\x21\xfe\xd4\xf2\x75\x1a\xfc\x6f\xf8\xd7\x37\xe1\x5b\x55\x37\x8c\x78\x26\x30\x80\x5c\x49\x42\x49\x69\xf0\xfd\xb7\x29\x16\x25\x8e\xf0\x24\xab\x31\x0d\xd6\x1c\x37\x8d\xd2\x34\x02\xdd\xf0\x82\xaa\xb4\xc0\x35\xcf\x31\x74\x8b\x0b\xe0\x92\x13\x67\x22\x34\x39\x13\x98\x5e\x06\xcb\x17\x96\x0e\x71\x12\xb8\xbc\xbf\x8f\xfe\x8c\xb4\x51\xfa\x76\xb7\x5b\xc0\x9b\x96\x2a\x94\xc4\x73\x46\x58\xc0\x1f\x59\x9b\x23\x25\xb1\x87\x74\x48\x82\xcb\x5b\xa8\x34\xae\xd2\xc0\x8a\x6e\x16\x71\x9c\x17\xf2\x83\x89\x72\xa1\xda\x62\x25\x98\xc6\x28\x57\x75\xcc\x3e\xb0\xbb\x58\xf0\xcc\xc4\xb4\xe1\x44\xa8\xc3\x4c\x29\x32\xa4\x59\x13\x5f\x45\x57\xd1\xef\xe3\xdc\x98\x78\xd8\x8b\x6a\x2e\xa3\xdc\x98\x00\x34\x8a\x34\x30\xb4\x15\x68\x2a\x44\x0a\x20\x5e\x7e\x1e\xdf\x95\x92\x14\xb2\x0d\x1a\x55\x63\xfc\x2a\xfa\x7d\x34\x73\x2c\xc7\xdb\x1f\xe7\x6a\xd9\x9a\x5c\xf3\x86\xc0\xe8\xfc\xd9\x7c\x3f\xfc\xd4\xa2\xde\xc6\x57\xd1\x65\x74\xd9\x2d\x1c\x9f\x0f\x26\x58\x26\xb1\x27\xb8\xfc\x22\xda\xa1\x54\xb4\x8d\xe7\xd1\xab\xe8\x32\x6e\x58\x7e\xcb\x4a\x2c\x7a\x4e\xf6\x28\xea\x37\x7f\x35\xbe\x4f\xf9\xf0\xc3\xb1\x0b\x7f\x0d\x66\xb5\xaa\x51\x52\xf4\xc1\xc4\xf3\xe8\xf2\x3a\x9a\xf5\x1b\x0f\xe9\x3b\x06\xd6\x69\x96\xd5\x49\xb4\x46\x6d\x23\x57\x84\x39\x4a\x42\x0d\xf7\x76\xf7\xa4\xe6\x32\xac\x90\x97\x15\x2d\xe0\x72\x36\x3b\xbd\x79\x6c\x77\x5d\xf9\xed\x82\x9b\x46\xb0\xed\x02\x56\x02\xef\xfc\x16\x13\xbc\x94\x21\x27\xac\xcd\x02\x3c\x65\x77\xb0\x73\x3c\x1b\xad\x4a\x8d\xc6\x74\xcc\x1a\x65\x38\x71\x25\x17\x36\xa2\x18\xf1\x35\x3e\x06\x6b\x1a\x26\x1f\x20\xb0\xcc\x28\xd1\x12\x1e\x09\x92\x09\x95\xdf\xfa\x3d\x77\x9b\xc7\x4a\xe4\x4a\x28\xbd\x80\x4d\xc5\x3b\x34\x70\x8c\xa0\xd1\xd8\x91\x87\x86\x15\x05\x97\xe5\x02\x5e\x37\x9d\x3e\x50\x33\x5d\x72\xb9\x80\xd9\x1e\x25\x89\x7b\x33\x26\xb1\x4f\x5c\x2f\x4e\x92\x4c\x15\x5b\xe7\xc3\x82\xaf\x21\x17\xcc\x98\x34\x38\x32\xb1\x4b\x48\x07\x00\x36\x0f\x31\x2e\xfb\xa3\x83\x33\xad\x36\x01\x38\x46\x69\xe0\x85\x08\x33\x45\xa4\xea\x05\x5c\x5a\xf1\x3a\x94\x23\x7a\x22\x14\x65\x78\x39\xef\x0f\x4f\x92\xea\xb2\x27\x42\x78\x47\xa1\xf3\xcf\xe0\x99\x60\x99\xf0\x1e\x77\xc5\x60\xc5\xc2\x8c\x51\x15\x00\xd3\x9c\x85\x15\x2f\x0a\x94\x69\x40\xba\x45\x1b\x47\x7c\x09\xe3\xf4\xf7\x44\xf6\xab\x2e\x7b\xb9\xe2\x82\xaf\x3b\xb5\x46\x9f\x47\x1a\x3e\xad\xc4\x35\x74\x1f\x6a\xb5\x32\x48\xe1\x48\xa7\x11\x30\x97\x4d\x4b\x61\xa9\x55\xdb\x0c\xe7\x27\x89\xdb\x05\x5e\xa4\x41\xc9\x0d\x05\x40\xdb\xa6\x33\x40\x30\xa8\xab\x74\x1d\x5a\xfb\x6b\x25\x02\x68\x04\xcb\xb1\x52\xa2\x40\x9d\x06\x3f\xaa\x9c\x33\x01\xd2\x6b\x0a\x7f\xfd\xe1\xbf\xa1\x73\x14\x97\x25\x6c\x55\xab\xe1\x5b\xaa\x50\x63\x5b\x03\x2b\x0a\x1b\xa4\x51\x14\x8d\xd8\xbb\x88\x7d\x28\x60\x98\x91\xdc\x43\x9d\x24\x59\x4b\xa4\x06\xc0\x8c\x24\x64\x24\xc3\x02\x57\xac\x15\x04\x85\x56\x4d\xa1\x36\x32\x24\x55\x96\xb6\xbe\x79\x25\x3c\x52\x00\x05\x23\xd6\x1d\xa5\x41\x0f\xdb\x7b\x8e\x99\x46\x35\x6d\xd3\xf9\xce\x6f\xe2\x5d\xc3\x64\x81\x85\xf5\xb4\x30\x18\x2c\xbf\xe3\x6b\x84\x1a\xbd\x2e\x27\xc7\x81\x90\x33\x8d\x14\x8e\x89\x3e\x08\x87\x24\xf6\xc2\x78\x95\xa0\xfb\x97\xb4\xa2\xa7\x34\xa8\x50\xa3\x6c\xe1\x60\x15\x6a\x9b\x4d\x82\xe5\xfd\xbd\x66\xb2\x44\x78\xc9\x8b\xbb\x0b\x78\xc9\x6a\xd5\x4a\x82\x45\x0a\xd1\x1b\xf7\x69\x76\xbb\x03\xea\x00\x89\xe0\xcb\x84\x7d\x2c\xa8\x41\xc9\x5c\xf0\xfc\x36\x0d\x88\xa3\x4e\xef\xef\x2d\xf1\xdd\xee\x06\xee\xef\xf9\x0a\x5e\x46\x3f\x60\xce\x1a\xca\x2b\xb6\xdb\x95\xba\xff\x8e\xf0\x0e\xf3\x96\x70\x32\xbd\xbf\x47\x61\x70\xb7\x33\x6d\x56\x73\x9a\xf4\xe8\x76\x5f\x16\xbb\x9d\x95\xb9\x93\x73\xb7\x83\xd8\x12\x95\x05\xde\xc1\xcb\xe8\x1d\x6a\xae\x0a\x03\x1e\x3e\x89\xd9\x32\x89\x05\x5f\x76\x78\x87\x46\x8a\x5b\xb1\x8f\x97\xd8\x06\xcc\x10\xdd\xee\xb2\x38\x51\xc7\x92\x3e\x12\xfb\x65\x38\x48\xdf\xc5\x83\xe1\x84\xb7\xb8\x4d\x83\xfb\xfb\x31\x6e\x77\x9a\x33\x21\x32\x66\xed\xe2\x55\x1b\x90\x7e\x46\x1b\xa7\x6b\x6e\x5c\x23\xb5\xec\x25\xd8\x8b\xfd\xcc\xcb\x7c\x94\xae\x48\x35\x0b\xb8\x9a\x8f\x72\xd5\x63\xf7\xfc\xf5\xd1\x3d\xbf\x7a\x14\xb8\x61\x12\x05\xb8\xbf\xa1\xa9\x99\xe8\xbf\xbb\xdb\x32\xba\x7c\xc7\x48\xa1\xcd\xcc\x83\x68\x43\x86\x9f\xdd\x80\x5a\xa3\x5e\x09\xb5\x59\x00\x6b\x49\xdd\x40\xcd\xee\x86\x2a\x77\x35\x9b\x8d\xe5\xb6\x0d\x20\xcb\x04\xba\x9c\xa2\xf1\xa7\x16\x0d\x99\x21\x97\xf8\x23\xf7\xd7\xa6\x94\x02\xa5\xc1\xe2\xc8\x1a\x96\xa3\x35\xad\x83\x1a\xb9\x7e\x30\xe6\xa3\xb2\xaf\x94\x1a\x0a\xc7\x58\x8c\x8e\xf4\xa8\xc6\x05\xcb\x84\xf4\x1e\xee\x24\xa1\xe2\x17\x25\x7e\x6d\x1b\xbb\xa7\xf2\xbe\xcf\x68\x56\xf7\x06\x51\xfb\xae\xc2\x86\x2c\xb8\x65\x12\x53\xf1\x05\x9c\x6d\x10\x66\xcc\xe0\x73\xd8\xbb\xfa\xbe\x67\xef\x96\x5f\xca\xbf\x42\xa6\x29\x43\x46\xcf\x11\x60\xd5\xca\x62\xa4\xbf\xcb\x9d\x5f\x2a\x40\x2b\xf9\x1a\xb5\xe1\xb4\x7d\xae\x04\x58\xec\x45\xf0\xeb\x43\x11\x92\x98\xf4\xc7\x63\x6d\xbc\xf8\x95\x2e\xf7\xa7\x1a\x91\xab\xe5\x9f\xd4\x06\x0a\x85\x06\xa8\xe2\x06\x6c\x71\xfd\x26\x89\xab\xab\x01\xa4\x59\xbe\xb7\x07\xce\xa8\xb0\x72\x0d\x05\x70\x03\xba\x95\xae\xf2\x2a\x09\x54\xe1\x61\x13\xd2\x15\xe9\x08\xde\x2b\xdb\xc8\xad\x51\x12\xd4\x4c\xf0\x9c\xab\xd6\x00\xcb\x49\x69\x03\x2b\xad\x6a\xc0\xbb\x8a\xb5\x86\x2c\x21\x9b\x3e\xd8\x9a\x71\xe1\xee\x92\x73\x29\x28\x0d\x2c\xcf\xdb\xba\xb5\x8d\xa8\x2c\x01\xa5\x6a\xcb\xaa\x93\x85\x14\xf8\xc2\x24\x94\x2c\x07\x79\x4c\xc3\x6a\x60\x44\x2c\xbf\x35\x17\xd0\x67\x05\x60\x1a\x81\x38\x16\x16\x2b\x47\x6d\xfb\x06\xc8\x55\x5d\x2b\x09\x57\xba\x80\x86\x69\xda\x5a\x5e\xae\xbc\x45\xf0\x46\x6e\x95\x44\xa8\xd8\xda\x89\x06\xdf\x71\xfa\x53\x9b\x5d\xc0\x7b\xff\x8a\xb8\x80\xef\x94\x2a\x05\x9e\x5b\x09\xff\xc8\x72\xcc\x94\xba\xed\xd1\xa1\x66\xdb\x9e\x71\xa7\xc7\x86\x53\xc5\xbd\xa1\x1a\xd4\xb5\xa5\x51\x80\xe0\x35\x27\x13\x25\x71\xb3\xcf\xad\xfb\x2a\x2d\xc2\x4a\x69\xfe\xb3\x6d\x71\xc4\xe0\x2f\x80\xa4\xa0\xa3\x3c\xd3\xa7\x49\x17\x00\x02\x57\xb4\x80\x57\x3e\x4d\x1e\x87\x74\xc9\xa9\x6a\xb3\x90\x89\x47\x2f\x55\x4f\xd6\xbd\x2e\x6d\xf9\x59\xc0\x95\x6f\x69\x7d\x5b\x51\xd0\x28\x25\x16\x47\x81\xe7\xf9\x5e\x5f\x37\x77\x83\x28\x43\x5f\x3c\x1b\x88\xd8\x78\x38\x34\xcc\x9a\xef\x6d\x9b\x6b\x64\x84\xc0\x20\x61\x47\xcf\x64\xdb\x2f\x46\x5e\x7a\xf7\xd0\x0a\x80\x98\x2e\x91\xd2\xe0\xff\x58\xa6\x5a\x5a\x64\x82\xc9\xdb\x60\x69\xe1\x6c\x85\x77\xf6\x7e\xbc\x27\x04\xac\x33\x2c\x0a\x2c\x80\x4b\x52\xce\x23\xdd\xdc\x01\x26\x76\xb1\xe2\x02\xdd\x64\xc2\xdd\x09\x79\x66\xbd\x69\x3d\x3e\x8d\x92\x4c\xc7\xcb\xb7\xaa\xd9\x86\x0d\x33\x84\x0e\xd5\x32\x34\xae\x17\x1d\xa8\xb1\x4c\xad\x11\x7c\xaf\x9b\xa9\x3b\x60\xb2\x80\x15\xd7\x08\x6c\xc3\xb6\x5f\x25\x71\xe1\x5e\x26\xbd\x1d\x3f\xdf\x99\xdd\x7b\xf6\x37\xe5\xc9\xe1\x76\xd4\xec\xf6\x51\x47\x76\x42\x3b\x27\x72\x67\xf5\x98\x36\x88\xf4\x8d\x4d\xc9\xe9\x0f\x9e\x20\x97\xe5\xe9\x7c\xe6\x33\x8d\xfd\xb0\xe4\x4f\xe7\x33\x6b\xe1\xd3\xf9\x6c\x76\x37\x7b\xe6\xbf\xd3\xf9\x4c\xc9\xd3\xf9\x8c\x2a\x3c\x9d\xcf\x4e\xe7\x57\xe3\x1c\xe5\x77\xfa\xe8\xb0\x50\x68\x2c\xb7\x3e\x75\x3d\x15\x62\x4e\xdc\x4f\xc5\x98\x0b\x90\x87\x11\x66\x60\x62\x5a\xad\x55\x2b\x6d\xb7\x03\x56\xe7\x67\x45\xd9\x03\x33\x9a\xb6\x69\x94\xa6\x68\x6c\x4e\x66\x5f\xb5\x02\x4d\x7c\x3d\xfb\xfa\xfa\xf5\x47\xc5\x77\x11\xeb\x74\xf8\x97\x47\x6d\xe9\xd2\x66\xd8\x88\xd6\xd8\xd6\x92\xdb\x37\xdd\x6f\x2a\x84\x7d\x5e\x87\x77\xa2\x35\x17\xd0\xb4\x99\xe0\xa6\x02\x06\x12\x37\x90\x18\xd2\x4a\x96\x4b\xb7\x9b\x27\x71\xb7\x84\x46\x19\xfa\xcc\x8c\xf3\x59\xe1\x60\xf9\xfd\x9b\x92\xce\xaa\x2b\x75\xbf\x29\x97\xf5\xf5\xf7\x17\xf9\x4b\xc9\x7f\xa5\xcb\x1e\xdc\xe0\xcd\x66\x13\xf5\xc6\x74\xd7\xb7\x42\xd1\xc4\xb6\x21\x69\x25\xa7\x6d\xec\x13\xa1\x92\xf1\x37\xbc\x48\xe7\xd7\xf3\xd7\xaf\xe7\xaf\xfe\xf3\xfa\xeb\xaf\xe7\xd7\xaf\xbe\x7e\xea\x6e\x0f\x71\xf1\xcb\xaf\xf6\xd0\x7e\x8a\x51\xdb\xf7\x37\xd5\x42\xce\x24\x90\x66\xf9\xad\x37\x42\xab\xb5\x35\x42\x83\x5e\xff\xa1\xbb\xca\x50\xa8\x8d\x03\xf1\x7c\x56\x1c\x85\x6b\xb5\x0c\x22\x54\x6a\x03\x75\x9b\x3b\x5b\xdb\x8e\x0a\xed\xc1\x86\x71\x82\x56\x12\x17\xde\x05\xd4\x6a\xd7\x90\xe1\x41\x43\xf4\xe0\xc1\x9d\x60\xbd\x7c\x6f\xcb\xf4\x83\x3e\x74\x78\x2a\x83\xc6\xb7\x1e\x1c\x1a\xad\x08\x73\x6b\x47\x60\x25\xe3\xd2\x58\x0b\xb8\x96\x0b\xeb\x67\x3c\xa5\x87\xaf\xee\x63\x3f\x0c\x76\xc7\x71\x0c\xdf\x09\x95\x31\x01\x6b\x7b\x1b\x32\x61\x7b\x68\x05\x95\xb2\xaa\x8f\xac\x65\x88\x51\x6b\x40\xad\xdc\xae\x97\xdc\xe2\xaf\x99\xb6\x8d\x2a\xd6\x0d\x41\xda\x8d\x32\xed\x9e\x41\xbd\xee\x06\xb4\x76\x49\x1c\xb5\x3f\xef\x98\xfe\x01\x57\x5c\xfa\xb8\x5a\xb5\xd2\xab\x47\x15\x23\xf0\x03\x04\x03\xcc\xf5\x25\xd0\x6a\x01\x5d\x0c\x78\x92\x03\x03\x07\x07\xe9\x80\x3e\x79\x60\xe7\xee\xa3\xb3\xd1\xb4\x1b\xc5\x7a\x32\x91\x41\x59\x4c\xfe\xeb\xc7\xbf\xfc\x39\x32\xa4\xb9\x2c\xf9\x6a\x3b\xb9\x6f\xb5\x58\xc0\xcb\x49\xf0\x1f\x6e\xb8\x37\xfd\xfb\xec\x9f\xd1\x9a\x89\x16\x2f\x9c\x02\x0b\xf7\xf7\x01\x9b\x0b\xe8\x3e\x17\x70\xc8\x71\x37\x9d\xde\x3c\x3e\x6d\x19\x0d\x87\x34\x1a\xa4\x89\x05\x1c\x3c\xb9\xbb\x39\x34\x12\x83\x1a\xa9\x52\x2e\x16\x35\xe6\x4a\x4a\xcc\x09\xda\x46\xc9\xce\x26\x20\x94\x31\xbd\x61\xf6\x10\x23\xdb\xf4\xca\xf3\x15\x4c\x7a\x77\x9d\xc2\x1c\xd2\x14\x66\xfd\x59\x67\x19\x48\x5d\xe2\xf9\x1f\xcc\x7e\x54\xf9\x2d\xd2\x24\xd8\x18\x7b\xdb\x03\x38\x07\xa1\x72\x66\xe9\x45\x95\x4d\x3f\xe7\x10\xc4\xac\xe1\xc1\xd4\x0f\xb4\x77\x80\xc2\xe0\xa7\x89\x3d\x8b\x96\x1f\xf9\x7b\x49\xcf\xcf\x7d\xd8\xf4\xae\x53\xb2\x46\x63\x58\x89\x63\x0d\xdd\x03\x6d\x50\xc5\x1a\xa2\x36\x25\xa4\xe0\x5c\xdc\x30\x6d\xd0\x83\x44\x05\x23\xd6\x71\x71\xe6\x70\x60\x69\x0a\xb2\x15\x62\xc0\x3f\xd1\x68\x2f\x73\x07\xb6\x7b\x71\x00\x1e\xf9\xb4\xfd\x55\x9a\x82\x7d\x21\x5b\x1f\x15\x7b\x4c\x1b\x3e\xfe\x2d\x3f\x8d\x6c\x6e\xdd\x63\x4c\x07\x72\x0f\xa8\x61\xf1\x29\x72\x58\x1c\xd3\xc3\xe2\x09\x82\x6e\x74\xf2\x31\x7a\x7e\xd4\x32\x22\xe7\x36\x9e\xa0\x26\xdb\x3a\x43\xfd\x31\x72\x7e\x74\xd2\x91\x73\xa6\xfe\x5e\xd2\x08\xf7\x02\x2e\x5f\x4f\x9f\xa0\x8e\x5a\xab\x27\x89\x4b\x45\xdb\xc9\xbd\x60\x5b\x5b\x20\xe0\x8c\x54\xf3\xd6\x4d\x3a\xce\x2e\x5c\xd5\x5a\xc0\x40\xe1\xc2\xcd\xb0\x17\x70\xe6\x56\x67\xbb\x27\xb8\x99\x36\xcf\x6d\x69\xfc\x12\x7e\x1d\x8d\x81\x63\xb7\x7e\x92\xe7\x50\x5f\x0e\x98\xc2\xef\x7e\x07\x0f\x4e\x0f\x43\xd0\xc6\x70\x5f\xb1\x53\x08\x82\x8e\xfc\xc9\x4a\x69\x98\xd8\x43\x9e\xce\x6e\x80\x27\x63\x32\x91\x40\x59\x52\x75\x03\xfc\xfc\x7c\x4f\xe9\xa4\x27\x73\x9e\x42\x90\x90\x5e\x26\x54\x2c\xdd\x50\xc5\x37\x30\xff\x08\x32\x96\xdf\x96\xae\x25\x58\xd8\x94\x3b\x39\xb3\x37\x74\x4c\xf8\xef\xfc\x9f\x11\x5b\x33\x62\xda\x5e\xd5\xb3\xe9\x0d\xec\x51\xba\x46\x29\x57\x36\xe3\x83\xef\xc7\xdc\xfc\x06\x86\x99\xa7\x5b\x65\x4a\x17\xa8\x43\xcd\x0a\xde\x9a\x05\xbc\x6a\xee\x6e\xfe\xd1\xcf\x84\xdd\x94\xc9\x89\xd5\x68\x5c\x3e\xca\xbd\x1b\x4c\x9c\x43\x90\xc4\x16\xa8\x47\x19\x94\x18\xff\x2e\x07\x8f\xcc\xc7\x60\xf8\xd5\xac\xdb\xaf\x79\x51\x08\xb4\x42\x38\x86\xfe\xe7\xcd\xa2\xd5\x2e\x2f\x4d\xfc\x7a\x72\x2c\x07\xf1\x1a\xa7\x51\x2b\xf9\xdd\x64\x1a\x76\x30\xfd\xfa\x02\xce\x8c\x4d\xbf\x85\x39\x9b\x46\x55\x5b\x33\xc9\x7f\xc6\x89\xed\x2c\xa7\x5e\x6e\x2b\x71\x4c\x7a\x39\x38\x73\x37\xba\x47\xc3\xf4\x77\x1a\x55\x54\x8b\x49\x90\x90\xfb\xed\xcf\x0a\x37\x78\xd0\x51\xf1\xdb\x87\x01\xb7\x3b\x4c\x91\xb9\x50\x06\x8f\x4a\x00\x18\xa4\xf7\xbc\x46\xd5\xd2\x64\x28\x13\x17\x70\x35\x9b\xcd\xa6\x37\xb0\xdb\xff\x44\x1a\xc7\xf0\xad\x21\xd6\x37\xa2\x1b\xcc\x8c\x4b\xdf\xd0\xe1\xb8\x6a\xed\xab\xf2\x9b\x77\xdf\x8f\x2a\xf3\x40\x75\xe2\x84\x1b\x7e\x22\x7e\xac\x0c\x3e\xfa\x9b\xb4\xed\x29\xfd\xfb\xca\x75\x94\x43\x9d\xb4\xc5\x21\xfa\x60\x02\x60\x66\x2b\x73\x28\x70\x85\x7a\x39\x22\xdf\x15\xcf\x24\xf6\xbf\x96\x26\xb1\xff\x1f\x42\xfe\x3f\x00\x00\xff\xff\x1f\xb2\x73\x97\x21\x22\x00\x00") func faucetHtmlBytes() ([]byte, error) { return bindataRead( From 7f7abfe4d1d7c51d968c0ead48b93fdb3cf2909f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 17 Oct 2017 12:08:57 +0300 Subject: [PATCH 2/3] cmd/faucet: proper error handling all over --- cmd/faucet/faucet.go | 165 ++++++++++++++++++++++++++++++++--------- cmd/faucet/faucet.html | 4 +- cmd/faucet/website.go | 2 +- 3 files changed, 135 insertions(+), 36 deletions(-) diff --git a/cmd/faucet/faucet.go b/cmd/faucet/faucet.go index 6b2987315..715f3dec9 100644 --- a/cmd/faucet/faucet.go +++ b/cmd/faucet/faucet.go @@ -302,6 +302,8 @@ func (f *faucet) webHandler(w http.ResponseWriter, r *http.Request) { // apiHandler handles requests for Ether grants and transaction statuses. func (f *faucet) apiHandler(conn *websocket.Conn) { // Start tracking the connection and drop at the end + defer conn.Close() + f.lock.Lock() f.conns = append(f.conns, conn) f.lock.Unlock() @@ -316,25 +318,50 @@ func (f *faucet) apiHandler(conn *websocket.Conn) { } f.lock.Unlock() }() - // Send a few initial stats to the client - balance, _ := f.client.BalanceAt(context.Background(), f.account.Address, nil) - nonce, _ := f.client.NonceAt(context.Background(), f.account.Address, nil) + // Gather the initial stats from the network to report + var ( + head *types.Header + balance *big.Int + nonce uint64 + err error + ) + for { + // Attempt to retrieve the stats, may error on no faucet connectivity + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + head, err = f.client.HeaderByNumber(ctx, nil) + if err == nil { + balance, err = f.client.BalanceAt(ctx, f.account.Address, head.Number) + if err == nil { + nonce, err = f.client.NonceAt(ctx, f.account.Address, nil) + } + } + cancel() - websocket.JSON.Send(conn, map[string]interface{}{ + // If stats retrieval failed, wait a bit and retry + if err != nil { + if err = sendError(conn, errors.New("Faucet offline: "+err.Error())); err != nil { + log.Warn("Failed to send faucet error to client", "err", err) + return + } + time.Sleep(3 * time.Second) + continue + } + // Initial stats reported successfully, proceed with user interaction + break + } + // Send over the initial stats and the latest header + if err = send(conn, map[string]interface{}{ "funds": balance.Div(balance, ether), "funded": nonce, "peers": f.stack.Server().PeerCount(), "requests": f.reqs, - }) - // Send the initial block to the client - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - header, err := f.client.HeaderByNumber(ctx, nil) - cancel() - - if err != nil { - log.Error("Failed to retrieve latest header", "err", err) - } else { - websocket.JSON.Send(conn, header) + }, 3*time.Second); err != nil { + log.Warn("Failed to send initial stats to client", "err", err) + return + } + if err = send(conn, head, 3*time.Second); err != nil { + log.Warn("Failed to send initial header to client", "err", err) + return } // Keep reading requests from the websocket until the connection breaks for { @@ -344,16 +371,22 @@ func (f *faucet) apiHandler(conn *websocket.Conn) { Tier uint `json:"tier"` Captcha string `json:"captcha"` } - if err := websocket.JSON.Receive(conn, &msg); err != nil { + if err = websocket.JSON.Receive(conn, &msg); err != nil { return } if !strings.HasPrefix(msg.URL, "https://gist.github.com/") && !strings.HasPrefix(msg.URL, "https://twitter.com/") && !strings.HasPrefix(msg.URL, "https://plus.google.com/") && !strings.HasPrefix(msg.URL, "https://www.facebook.com/") { - websocket.JSON.Send(conn, map[string]string{"error": "URL doesn't link to supported services"}) + if err = sendError(conn, errors.New("URL doesn't link to supported services")); err != nil { + log.Warn("Failed to send URL error to client", "err", err) + return + } continue } if msg.Tier >= uint(*tiersFlag) { - websocket.JSON.Send(conn, map[string]string{"error": "Invalid funding tier requested"}) + if err = sendError(conn, errors.New("Invalid funding tier requested")); err != nil { + log.Warn("Failed to send tier error to client", "err", err) + return + } continue } log.Info("Faucet funds requested", "url", msg.URL, "tier", msg.Tier) @@ -366,7 +399,10 @@ func (f *faucet) apiHandler(conn *websocket.Conn) { res, err := http.PostForm("https://www.google.com/recaptcha/api/siteverify", form) if err != nil { - websocket.JSON.Send(conn, map[string]string{"error": err.Error()}) + if err = sendError(conn, err); err != nil { + log.Warn("Failed to send captcha post error to client", "err", err) + return + } continue } var result struct { @@ -376,12 +412,18 @@ func (f *faucet) apiHandler(conn *websocket.Conn) { err = json.NewDecoder(res.Body).Decode(&result) res.Body.Close() if err != nil { - websocket.JSON.Send(conn, map[string]string{"error": err.Error()}) + if err = sendError(conn, err); err != nil { + log.Warn("Failed to send captcha decode error to client", "err", err) + return + } continue } if !result.Success { log.Warn("Captcha verification failed", "err", string(result.Errors)) - websocket.JSON.Send(conn, map[string]string{"error": "Beep-bop, you're a robot!"}) + if err = sendError(conn, errors.New("Beep-bop, you're a robot!")); err != nil { + log.Warn("Failed to send captcha failure to client", "err", err) + return + } continue } } @@ -404,7 +446,10 @@ func (f *faucet) apiHandler(conn *websocket.Conn) { err = errors.New("Something funky happened, please open an issue at https://github.com/ethereum/go-ethereum/issues") } if err != nil { - websocket.JSON.Send(conn, map[string]string{"error": err.Error()}) + if err = sendError(conn, err); err != nil { + log.Warn("Failed to send prefix error to client", "err", err) + return + } continue } log.Info("Faucet request valid", "url", msg.URL, "tier", msg.Tier, "user", username, "address", address) @@ -424,14 +469,20 @@ func (f *faucet) apiHandler(conn *websocket.Conn) { tx := types.NewTransaction(f.nonce+uint64(len(f.reqs)), address, amount, big.NewInt(21000), f.price, nil) signed, err := f.keystore.SignTx(f.account, tx, f.config.ChainId) if err != nil { - websocket.JSON.Send(conn, map[string]string{"error": err.Error()}) f.lock.Unlock() + if err = sendError(conn, err); err != nil { + log.Warn("Failed to send transaction creation error to client", "err", err) + return + } continue } // Submit the transaction and mark as funded if successful if err := f.client.SendTransaction(context.Background(), signed); err != nil { - websocket.JSON.Send(conn, map[string]string{"error": err.Error()}) f.lock.Unlock() + if err = sendError(conn, err); err != nil { + log.Warn("Failed to send transaction transmission error to client", "err", err) + return + } continue } f.reqs = append(f.reqs, &request{ @@ -447,10 +498,16 @@ func (f *faucet) apiHandler(conn *websocket.Conn) { // Send an error if too frequent funding, othewise a success if !fund { - websocket.JSON.Send(conn, map[string]string{"error": fmt.Sprintf("%s left until next allowance", common.PrettyDuration(timeout.Sub(time.Now())))}) + if err = sendError(conn, fmt.Errorf("%s left until next allowance", common.PrettyDuration(timeout.Sub(time.Now())))); err != nil { + log.Warn("Failed to send funding error to client", "err", err) + return + } continue } - websocket.JSON.Send(conn, map[string]string{"success": fmt.Sprintf("Funding request accepted for %s into %s", username, address.Hex())}) + if err = sendSuccess(conn, fmt.Sprintf("Funding request accepted for %s into %s", username, address.Hex())); err != nil { + log.Warn("Failed to send funding success to client", "err", err) + return + } select { case f.update <- struct{}{}: default: @@ -473,11 +530,31 @@ func (f *faucet) loop() { select { case head := <-heads: // New chain head arrived, query the current stats and stream to clients - balance, _ := f.client.BalanceAt(context.Background(), f.account.Address, nil) - balance = new(big.Int).Div(balance, ether) + var ( + balance *big.Int + nonce uint64 + price *big.Int + err error + ) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + balance, err = f.client.BalanceAt(ctx, f.account.Address, head.Number) + if err == nil { + nonce, err = f.client.NonceAt(ctx, f.account.Address, nil) + if err == nil { + price, err = f.client.SuggestGasPrice(ctx) + } + } + cancel() - price, _ := f.client.SuggestGasPrice(context.Background()) - nonce, _ := f.client.NonceAt(context.Background(), f.account.Address, nil) + // If querying the data failed, try for the next block + if err != nil { + log.Warn("Failed to update faucet state", "block", head.Number, "hash", head.Hash(), "err", err) + continue + } else { + log.Info("Updated faucet state", "block", head.Number, "hash", head.Hash(), "balance", balance, "nonce", nonce, "price", price) + } + // Faucet state retrieved, update locally and send to clients + balance = new(big.Int).Div(balance, ether) f.lock.Lock() f.price, f.nonce = price, nonce @@ -488,17 +565,17 @@ func (f *faucet) loop() { f.lock.RLock() for _, conn := range f.conns { - if err := websocket.JSON.Send(conn, map[string]interface{}{ + if err := send(conn, map[string]interface{}{ "funds": balance, "funded": f.nonce, "peers": f.stack.Server().PeerCount(), "requests": f.reqs, - }); err != nil { + }, time.Second); err != nil { log.Warn("Failed to send stats to client", "err", err) conn.Close() continue } - if err := websocket.JSON.Send(conn, head); err != nil { + if err := send(conn, head, time.Second); err != nil { log.Warn("Failed to send header to client", "err", err) conn.Close() } @@ -509,7 +586,7 @@ func (f *faucet) loop() { // Pending requests updated, stream to clients f.lock.RLock() for _, conn := range f.conns { - if err := websocket.JSON.Send(conn, map[string]interface{}{"requests": f.reqs}); err != nil { + if err := send(conn, map[string]interface{}{"requests": f.reqs}, time.Second); err != nil { log.Warn("Failed to send requests to client", "err", err) conn.Close() } @@ -519,6 +596,28 @@ func (f *faucet) loop() { } } +// sends transmits a data packet to the remote end of the websocket, but also +// setting a write deadline to prevent waiting forever on the node. +func send(conn *websocket.Conn, value interface{}, timeout time.Duration) error { + if timeout == 0 { + timeout = 60 * time.Second + } + conn.SetWriteDeadline(time.Now().Add(timeout)) + return websocket.JSON.Send(conn, value) +} + +// sendError transmits an error to the remote end of the websocket, also setting +// the write deadline to 1 second to prevent waiting forever. +func sendError(conn *websocket.Conn, err error) error { + return send(conn, map[string]string{"error": err.Error()}, time.Second) +} + +// sendSuccess transmits a success message to the remote end of the websocket, also +// setting the write deadline to 1 second to prevent waiting forever. +func sendSuccess(conn *websocket.Conn, msg string) error { + return send(conn, map[string]string{"success": msg}, time.Second) +} + // authGitHub tries to authenticate a faucet request using GitHub gists, returning // the username, avatar URL and Ethereum address to fund on success. func authGitHub(url string) (string, string, common.Address, error) { diff --git a/cmd/faucet/faucet.html b/cmd/faucet/faucet.html index 3b928d636..75dad0bdf 100644 --- a/cmd/faucet/faucet.html +++ b/cmd/faucet/faucet.html @@ -140,10 +140,10 @@ $("#block").text(parseInt(msg.number, 16)); } if (msg.error !== undefined) { - noty({layout: 'topCenter', text: msg.error, type: 'error'}); + noty({layout: 'topCenter', text: msg.error, type: 'error', timeout: 5000, progressBar: true}); } if (msg.success !== undefined) { - noty({layout: 'topCenter', text: msg.success, type: 'success'}); + noty({layout: 'topCenter', text: msg.success, type: 'success', timeout: 15000, progressBar: true}); } if (msg.requests !== undefined && msg.requests !== null) { var content = ""; diff --git a/cmd/faucet/website.go b/cmd/faucet/website.go index 5a80cb0a7..f99c69abf 100644 --- a/cmd/faucet/website.go +++ b/cmd/faucet/website.go @@ -68,7 +68,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _faucetHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x3a\x7f\x73\xe3\xb6\xb1\x7f\xfb\x3e\xc5\x86\xef\x5c\x4b\x63\x93\x94\xe5\xcb\xd5\x4f\x26\x95\xb9\xb9\xa6\x69\xde\xbc\x69\x6f\x92\xeb\xbc\xd7\x69\x3b\x6f\x40\x72\x45\xe2\x0c\x02\x0c\xb0\x94\xac\x78\xf4\xdd\xdf\x00\x20\x29\x4a\xb6\xef\x9c\xbb\x4c\x9b\xfb\xc3\x21\x80\xfd\xbd\x8b\xdd\xc5\x2a\xc9\x57\x7f\xf8\xcb\xdb\xf7\x7f\x7b\xf7\x2d\x54\x54\x8b\xe5\x8b\xc4\xfe\x07\x04\x93\x65\x1a\xa0\x0c\x96\x2f\x4e\x92\x0a\x59\xb1\x7c\x71\x72\x92\xd4\x48\x0c\xf2\x8a\x69\x83\x94\x06\x2d\xad\xc2\xeb\x60\x7f\x50\x11\x35\x21\xfe\xd4\xf2\x75\x1a\xfc\x6f\xf8\xd7\x37\xe1\x5b\x55\x37\x8c\x78\x26\x30\x80\x5c\x49\x42\x49\x69\xf0\xfd\xb7\x29\x16\x25\x8e\xf0\x24\xab\x31\x0d\xd6\x1c\x37\x8d\xd2\x34\x02\xdd\xf0\x82\xaa\xb4\xc0\x35\xcf\x31\x74\x8b\x0b\xe0\x92\x13\x67\x22\x34\x39\x13\x98\x5e\x06\xcb\x17\x96\x0e\x71\x12\xb8\xbc\xbf\x8f\xfe\x8c\xb4\x51\xfa\x76\xb7\x5b\xc0\x9b\x96\x2a\x94\xc4\x73\x46\x58\xc0\x1f\x59\x9b\x23\x25\xb1\x87\x74\x48\x82\xcb\x5b\xa8\x34\xae\xd2\xc0\x8a\x6e\x16\x71\x9c\x17\xf2\x83\x89\x72\xa1\xda\x62\x25\x98\xc6\x28\x57\x75\xcc\x3e\xb0\xbb\x58\xf0\xcc\xc4\xb4\xe1\x44\xa8\xc3\x4c\x29\x32\xa4\x59\x13\x5f\x45\x57\xd1\xef\xe3\xdc\x98\x78\xd8\x8b\x6a\x2e\xa3\xdc\x98\x00\x34\x8a\x34\x30\xb4\x15\x68\x2a\x44\x0a\x20\x5e\x7e\x1e\xdf\x95\x92\x14\xb2\x0d\x1a\x55\x63\xfc\x2a\xfa\x7d\x34\x73\x2c\xc7\xdb\x1f\xe7\x6a\xd9\x9a\x5c\xf3\x86\xc0\xe8\xfc\xd9\x7c\x3f\xfc\xd4\xa2\xde\xc6\x57\xd1\x65\x74\xd9\x2d\x1c\x9f\x0f\x26\x58\x26\xb1\x27\xb8\xfc\x22\xda\xa1\x54\xb4\x8d\xe7\xd1\xab\xe8\x32\x6e\x58\x7e\xcb\x4a\x2c\x7a\x4e\xf6\x28\xea\x37\x7f\x35\xbe\x4f\xf9\xf0\xc3\xb1\x0b\x7f\x0d\x66\xb5\xaa\x51\x52\xf4\xc1\xc4\xf3\xe8\xf2\x3a\x9a\xf5\x1b\x0f\xe9\x3b\x06\xd6\x69\x96\xd5\x49\xb4\x46\x6d\x23\x57\x84\x39\x4a\x42\x0d\xf7\x76\xf7\xa4\xe6\x32\xac\x90\x97\x15\x2d\xe0\x72\x36\x3b\xbd\x79\x6c\x77\x5d\xf9\xed\x82\x9b\x46\xb0\xed\x02\x56\x02\xef\xfc\x16\x13\xbc\x94\x21\x27\xac\xcd\x02\x3c\x65\x77\xb0\x73\x3c\x1b\xad\x4a\x8d\xc6\x74\xcc\x1a\x65\x38\x71\x25\x17\x36\xa2\x18\xf1\x35\x3e\x06\x6b\x1a\x26\x1f\x20\xb0\xcc\x28\xd1\x12\x1e\x09\x92\x09\x95\xdf\xfa\x3d\x77\x9b\xc7\x4a\xe4\x4a\x28\xbd\x80\x4d\xc5\x3b\x34\x70\x8c\xa0\xd1\xd8\x91\x87\x86\x15\x05\x97\xe5\x02\x5e\x37\x9d\x3e\x50\x33\x5d\x72\xb9\x80\xd9\x1e\x25\x89\x7b\x33\x26\xb1\x4f\x5c\x2f\x4e\x92\x4c\x15\x5b\xe7\xc3\x82\xaf\x21\x17\xcc\x98\x34\x38\x32\xb1\x4b\x48\x07\x00\x36\x0f\x31\x2e\xfb\xa3\x83\x33\xad\x36\x01\x38\x46\x69\xe0\x85\x08\x33\x45\xa4\xea\x05\x5c\x5a\xf1\x3a\x94\x23\x7a\x22\x14\x65\x78\x39\xef\x0f\x4f\x92\xea\xb2\x27\x42\x78\x47\xa1\xf3\xcf\xe0\x99\x60\x99\xf0\x1e\x77\xc5\x60\xc5\xc2\x8c\x51\x15\x00\xd3\x9c\x85\x15\x2f\x0a\x94\x69\x40\xba\x45\x1b\x47\x7c\x09\xe3\xf4\xf7\x44\xf6\xab\x2e\x7b\xb9\xe2\x82\xaf\x3b\xb5\x46\x9f\x47\x1a\x3e\xad\xc4\x35\x74\x1f\x6a\xb5\x32\x48\xe1\x48\xa7\x11\x30\x97\x4d\x4b\x61\xa9\x55\xdb\x0c\xe7\x27\x89\xdb\x05\x5e\xa4\x41\xc9\x0d\x05\x40\xdb\xa6\x33\x40\x30\xa8\xab\x74\x1d\x5a\xfb\x6b\x25\x02\x68\x04\xcb\xb1\x52\xa2\x40\x9d\x06\x3f\xaa\x9c\x33\x01\xd2\x6b\x0a\x7f\xfd\xe1\xbf\xa1\x73\x14\x97\x25\x6c\x55\xab\xe1\x5b\xaa\x50\x63\x5b\x03\x2b\x0a\x1b\xa4\x51\x14\x8d\xd8\xbb\x88\x7d\x28\x60\x98\x91\xdc\x43\x9d\x24\x59\x4b\xa4\x06\xc0\x8c\x24\x64\x24\xc3\x02\x57\xac\x15\x04\x85\x56\x4d\xa1\x36\x32\x24\x55\x96\xb6\xbe\x79\x25\x3c\x52\x00\x05\x23\xd6\x1d\xa5\x41\x0f\xdb\x7b\x8e\x99\x46\x35\x6d\xd3\xf9\xce\x6f\xe2\x5d\xc3\x64\x81\x85\xf5\xb4\x30\x18\x2c\xbf\xe3\x6b\x84\x1a\xbd\x2e\x27\xc7\x81\x90\x33\x8d\x14\x8e\x89\x3e\x08\x87\x24\xf6\xc2\x78\x95\xa0\xfb\x97\xb4\xa2\xa7\x34\xa8\x50\xa3\x6c\xe1\x60\x15\x6a\x9b\x4d\x82\xe5\xfd\xbd\x66\xb2\x44\x78\xc9\x8b\xbb\x0b\x78\xc9\x6a\xd5\x4a\x82\x45\x0a\xd1\x1b\xf7\x69\x76\xbb\x03\xea\x00\x89\xe0\xcb\x84\x7d\x2c\xa8\x41\xc9\x5c\xf0\xfc\x36\x0d\x88\xa3\x4e\xef\xef\x2d\xf1\xdd\xee\x06\xee\xef\xf9\x0a\x5e\x46\x3f\x60\xce\x1a\xca\x2b\xb6\xdb\x95\xba\xff\x8e\xf0\x0e\xf3\x96\x70\x32\xbd\xbf\x47\x61\x70\xb7\x33\x6d\x56\x73\x9a\xf4\xe8\x76\x5f\x16\xbb\x9d\x95\xb9\x93\x73\xb7\x83\xd8\x12\x95\x05\xde\xc1\xcb\xe8\x1d\x6a\xae\x0a\x03\x1e\x3e\x89\xd9\x32\x89\x05\x5f\x76\x78\x87\x46\x8a\x5b\xb1\x8f\x97\xd8\x06\xcc\x10\xdd\xee\xb2\x38\x51\xc7\x92\x3e\x12\xfb\x65\x38\x48\xdf\xc5\x83\xe1\x84\xb7\xb8\x4d\x83\xfb\xfb\x31\x6e\x77\x9a\x33\x21\x32\x66\xed\xe2\x55\x1b\x90\x7e\x46\x1b\xa7\x6b\x6e\x5c\x23\xb5\xec\x25\xd8\x8b\xfd\xcc\xcb\x7c\x94\xae\x48\x35\x0b\xb8\x9a\x8f\x72\xd5\x63\xf7\xfc\xf5\xd1\x3d\xbf\x7a\x14\xb8\x61\x12\x05\xb8\xbf\xa1\xa9\x99\xe8\xbf\xbb\xdb\x32\xba\x7c\xc7\x48\xa1\xcd\xcc\x83\x68\x43\x86\x9f\xdd\x80\x5a\xa3\x5e\x09\xb5\x59\x00\x6b\x49\xdd\x40\xcd\xee\x86\x2a\x77\x35\x9b\x8d\xe5\xb6\x0d\x20\xcb\x04\xba\x9c\xa2\xf1\xa7\x16\x0d\x99\x21\x97\xf8\x23\xf7\xd7\xa6\x94\x02\xa5\xc1\xe2\xc8\x1a\x96\xa3\x35\xad\x83\x1a\xb9\x7e\x30\xe6\xa3\xb2\xaf\x94\x1a\x0a\xc7\x58\x8c\x8e\xf4\xa8\xc6\x05\xcb\x84\xf4\x1e\xee\x24\xa1\xe2\x17\x25\x7e\x6d\x1b\xbb\xa7\xf2\xbe\xcf\x68\x56\xf7\x06\x51\xfb\xae\xc2\x86\x2c\xb8\x65\x12\x53\xf1\x05\x9c\x6d\x10\x66\xcc\xe0\x73\xd8\xbb\xfa\xbe\x67\xef\x96\x5f\xca\xbf\x42\xa6\x29\x43\x46\xcf\x11\x60\xd5\xca\x62\xa4\xbf\xcb\x9d\x5f\x2a\x40\x2b\xf9\x1a\xb5\xe1\xb4\x7d\xae\x04\x58\xec\x45\xf0\xeb\x43\x11\x92\x98\xf4\xc7\x63\x6d\xbc\xf8\x95\x2e\xf7\xa7\x1a\x91\xab\xe5\x9f\xd4\x06\x0a\x85\x06\xa8\xe2\x06\x6c\x71\xfd\x26\x89\xab\xab\x01\xa4\x59\xbe\xb7\x07\xce\xa8\xb0\x72\x0d\x05\x70\x03\xba\x95\xae\xf2\x2a\x09\x54\xe1\x61\x13\xd2\x15\xe9\x08\xde\x2b\xdb\xc8\xad\x51\x12\xd4\x4c\xf0\x9c\xab\xd6\x00\xcb\x49\x69\x03\x2b\xad\x6a\xc0\xbb\x8a\xb5\x86\x2c\x21\x9b\x3e\xd8\x9a\x71\xe1\xee\x92\x73\x29\x28\x0d\x2c\xcf\xdb\xba\xb5\x8d\xa8\x2c\x01\xa5\x6a\xcb\xaa\x93\x85\x14\xf8\xc2\x24\x94\x2c\x07\x79\x4c\xc3\x6a\x60\x44\x2c\xbf\x35\x17\xd0\x67\x05\x60\x1a\x81\x38\x16\x16\x2b\x47\x6d\xfb\x06\xc8\x55\x5d\x2b\x09\x57\xba\x80\x86\x69\xda\x5a\x5e\xae\xbc\x45\xf0\x46\x6e\x95\x44\xa8\xd8\xda\x89\x06\xdf\x71\xfa\x53\x9b\x5d\xc0\x7b\xff\x8a\xb8\x80\xef\x94\x2a\x05\x9e\x5b\x09\xff\xc8\x72\xcc\x94\xba\xed\xd1\xa1\x66\xdb\x9e\x71\xa7\xc7\x86\x53\xc5\xbd\xa1\x1a\xd4\xb5\xa5\x51\x80\xe0\x35\x27\x13\x25\x71\xb3\xcf\xad\xfb\x2a\x2d\xc2\x4a\x69\xfe\xb3\x6d\x71\xc4\xe0\x2f\x80\xa4\xa0\xa3\x3c\xd3\xa7\x49\x17\x00\x02\x57\xb4\x80\x57\x3e\x4d\x1e\x87\x74\xc9\xa9\x6a\xb3\x90\x89\x47\x2f\x55\x4f\xd6\xbd\x2e\x6d\xf9\x59\xc0\x95\x6f\x69\x7d\x5b\x51\xd0\x28\x25\x16\x47\x81\xe7\xf9\x5e\x5f\x37\x77\x83\x28\x43\x5f\x3c\x1b\x88\xd8\x78\x38\x34\xcc\x9a\xef\x6d\x9b\x6b\x64\x84\xc0\x20\x61\x47\xcf\x64\xdb\x2f\x46\x5e\x7a\xf7\xd0\x0a\x80\x98\x2e\x91\xd2\xe0\xff\x58\xa6\x5a\x5a\x64\x82\xc9\xdb\x60\x69\xe1\x6c\x85\x77\xf6\x7e\xbc\x27\x04\xac\x33\x2c\x0a\x2c\x80\x4b\x52\xce\x23\xdd\xdc\x01\x26\x76\xb1\xe2\x02\xdd\x64\xc2\xdd\x09\x79\x66\xbd\x69\x3d\x3e\x8d\x92\x4c\xc7\xcb\xb7\xaa\xd9\x86\x0d\x33\x84\x0e\xd5\x32\x34\xae\x17\x1d\xa8\xb1\x4c\xad\x11\x7c\xaf\x9b\xa9\x3b\x60\xb2\x80\x15\xd7\x08\x6c\xc3\xb6\x5f\x25\x71\xe1\x5e\x26\xbd\x1d\x3f\xdf\x99\xdd\x7b\xf6\x37\xe5\xc9\xe1\x76\xd4\xec\xf6\x51\x47\x76\x42\x3b\x27\x72\x67\xf5\x98\x36\x88\xf4\x8d\x4d\xc9\xe9\x0f\x9e\x20\x97\xe5\xe9\x7c\xe6\x33\x8d\xfd\xb0\xe4\x4f\xe7\x33\x6b\xe1\xd3\xf9\x6c\x76\x37\x7b\xe6\xbf\xd3\xf9\x4c\xc9\xd3\xf9\x8c\x2a\x3c\x9d\xcf\x4e\xe7\x57\xe3\x1c\xe5\x77\xfa\xe8\xb0\x50\x68\x2c\xb7\x3e\x75\x3d\x15\x62\x4e\xdc\x4f\xc5\x98\x0b\x90\x87\x11\x66\x60\x62\x5a\xad\x55\x2b\x6d\xb7\x03\x56\xe7\x67\x45\xd9\x03\x33\x9a\xb6\x69\x94\xa6\x68\x6c\x4e\x66\x5f\xb5\x02\x4d\x7c\x3d\xfb\xfa\xfa\xf5\x47\xc5\x77\x11\xeb\x74\xf8\x97\x47\x6d\xe9\xd2\x66\xd8\x88\xd6\xd8\xd6\x92\xdb\x37\xdd\x6f\x2a\x84\x7d\x5e\x87\x77\xa2\x35\x17\xd0\xb4\x99\xe0\xa6\x02\x06\x12\x37\x90\x18\xd2\x4a\x96\x4b\xb7\x9b\x27\x71\xb7\x84\x46\x19\xfa\xcc\x8c\xf3\x59\xe1\x60\xf9\xfd\x9b\x92\xce\xaa\x2b\x75\xbf\x29\x97\xf5\xf5\xf7\x17\xf9\x4b\xc9\x7f\xa5\xcb\x1e\xdc\xe0\xcd\x66\x13\xf5\xc6\x74\xd7\xb7\x42\xd1\xc4\xb6\x21\x69\x25\xa7\x6d\xec\x13\xa1\x92\xf1\x37\xbc\x48\xe7\xd7\xf3\xd7\xaf\xe7\xaf\xfe\xf3\xfa\xeb\xaf\xe7\xd7\xaf\xbe\x7e\xea\x6e\x0f\x71\xf1\xcb\xaf\xf6\xd0\x7e\x8a\x51\xdb\xf7\x37\xd5\x42\xce\x24\x90\x66\xf9\xad\x37\x42\xab\xb5\x35\x42\x83\x5e\xff\xa1\xbb\xca\x50\xa8\x8d\x03\xf1\x7c\x56\x1c\x85\x6b\xb5\x0c\x22\x54\x6a\x03\x75\x9b\x3b\x5b\xdb\x8e\x0a\xed\xc1\x86\x71\x82\x56\x12\x17\xde\x05\xd4\x6a\xd7\x90\xe1\x41\x43\xf4\xe0\xc1\x9d\x60\xbd\x7c\x6f\xcb\xf4\x83\x3e\x74\x78\x2a\x83\xc6\xb7\x1e\x1c\x1a\xad\x08\x73\x6b\x47\x60\x25\xe3\xd2\x58\x0b\xb8\x96\x0b\xeb\x67\x3c\xa5\x87\xaf\xee\x63\x3f\x0c\x76\xc7\x71\x0c\xdf\x09\x95\x31\x01\x6b\x7b\x1b\x32\x61\x7b\x68\x05\x95\xb2\xaa\x8f\xac\x65\x88\x51\x6b\x40\xad\xdc\xae\x97\xdc\xe2\xaf\x99\xb6\x8d\x2a\xd6\x0d\x41\xda\x8d\x32\xed\x9e\x41\xbd\xee\x06\xb4\x76\x49\x1c\xb5\x3f\xef\x98\xfe\x01\x57\x5c\xfa\xb8\x5a\xb5\xd2\xab\x47\x15\x23\xf0\x03\x04\x03\xcc\xf5\x25\xd0\x6a\x01\x5d\x0c\x78\x92\x03\x03\x07\x07\xe9\x80\x3e\x79\x60\xe7\xee\xa3\xb3\xd1\xb4\x1b\xc5\x7a\x32\x91\x41\x59\x4c\xfe\xeb\xc7\xbf\xfc\x39\x32\xa4\xb9\x2c\xf9\x6a\x3b\xb9\x6f\xb5\x58\xc0\xcb\x49\xf0\x1f\x6e\xb8\x37\xfd\xfb\xec\x9f\xd1\x9a\x89\x16\x2f\x9c\x02\x0b\xf7\xf7\x01\x9b\x0b\xe8\x3e\x17\x70\xc8\x71\x37\x9d\xde\x3c\x3e\x6d\x19\x0d\x87\x34\x1a\xa4\x89\x05\x1c\x3c\xb9\xbb\x39\x34\x12\x83\x1a\xa9\x52\x2e\x16\x35\xe6\x4a\x4a\xcc\x09\xda\x46\xc9\xce\x26\x20\x94\x31\xbd\x61\xf6\x10\x23\xdb\xf4\xca\xf3\x15\x4c\x7a\x77\x9d\xc2\x1c\xd2\x14\x66\xfd\x59\x67\x19\x48\x5d\xe2\xf9\x1f\xcc\x7e\x54\xf9\x2d\xd2\x24\xd8\x18\x7b\xdb\x03\x38\x07\xa1\x72\x66\xe9\x45\x95\x4d\x3f\xe7\x10\xc4\xac\xe1\xc1\xd4\x0f\xb4\x77\x80\xc2\xe0\xa7\x89\x3d\x8b\x96\x1f\xf9\x7b\x49\xcf\xcf\x7d\xd8\xf4\xae\x53\xb2\x46\x63\x58\x89\x63\x0d\xdd\x03\x6d\x50\xc5\x1a\xa2\x36\x25\xa4\xe0\x5c\xdc\x30\x6d\xd0\x83\x44\x05\x23\xd6\x71\x71\xe6\x70\x60\x69\x0a\xb2\x15\x62\xc0\x3f\xd1\x68\x2f\x73\x07\xb6\x7b\x71\x00\x1e\xf9\xb4\xfd\x55\x9a\x82\x7d\x21\x5b\x1f\x15\x7b\x4c\x1b\x3e\xfe\x2d\x3f\x8d\x6c\x6e\xdd\x63\x4c\x07\x72\x0f\xa8\x61\xf1\x29\x72\x58\x1c\xd3\xc3\xe2\x09\x82\x6e\x74\xf2\x31\x7a\x7e\xd4\x32\x22\xe7\x36\x9e\xa0\x26\xdb\x3a\x43\xfd\x31\x72\x7e\x74\xd2\x91\x73\xa6\xfe\x5e\xd2\x08\xf7\x02\x2e\x5f\x4f\x9f\xa0\x8e\x5a\xab\x27\x89\x4b\x45\xdb\xc9\xbd\x60\x5b\x5b\x20\xe0\x8c\x54\xf3\xd6\x4d\x3a\xce\x2e\x5c\xd5\x5a\xc0\x40\xe1\xc2\xcd\xb0\x17\x70\xe6\x56\x67\xbb\x27\xb8\x99\x36\xcf\x6d\x69\xfc\x12\x7e\x1d\x8d\x81\x63\xb7\x7e\x92\xe7\x50\x5f\x0e\x98\xc2\xef\x7e\x07\x0f\x4e\x0f\x43\xd0\xc6\x70\x5f\xb1\x53\x08\x82\x8e\xfc\xc9\x4a\x69\x98\xd8\x43\x9e\xce\x6e\x80\x27\x63\x32\x91\x40\x59\x52\x75\x03\xfc\xfc\x7c\x4f\xe9\xa4\x27\x73\x9e\x42\x90\x90\x5e\x26\x54\x2c\xdd\x50\xc5\x37\x30\xff\x08\x32\x96\xdf\x96\xae\x25\x58\xd8\x94\x3b\x39\xb3\x37\x74\x4c\xf8\xef\xfc\x9f\x11\x5b\x33\x62\xda\x5e\xd5\xb3\xe9\x0d\xec\x51\xba\x46\x29\x57\x36\xe3\x83\xef\xc7\xdc\xfc\x06\x86\x99\xa7\x5b\x65\x4a\x17\xa8\x43\xcd\x0a\xde\x9a\x05\xbc\x6a\xee\x6e\xfe\xd1\xcf\x84\xdd\x94\xc9\x89\xd5\x68\x5c\x3e\xca\xbd\x1b\x4c\x9c\x43\x90\xc4\x16\xa8\x47\x19\x94\x18\xff\x2e\x07\x8f\xcc\xc7\x60\xf8\xd5\xac\xdb\xaf\x79\x51\x08\xb4\x42\x38\x86\xfe\xe7\xcd\xa2\xd5\x2e\x2f\x4d\xfc\x7a\x72\x2c\x07\xf1\x1a\xa7\x51\x2b\xf9\xdd\x64\x1a\x76\x30\xfd\xfa\x02\xce\x8c\x4d\xbf\x85\x39\x9b\x46\x55\x5b\x33\xc9\x7f\xc6\x89\xed\x2c\xa7\x5e\x6e\x2b\x71\x4c\x7a\x39\x38\x73\x37\xba\x47\xc3\xf4\x77\x1a\x55\x54\x8b\x49\x90\x90\xfb\xed\xcf\x0a\x37\x78\xd0\x51\xf1\xdb\x87\x01\xb7\x3b\x4c\x91\xb9\x50\x06\x8f\x4a\x00\x18\xa4\xf7\xbc\x46\xd5\xd2\x64\x28\x13\x17\x70\x35\x9b\xcd\xa6\x37\xb0\xdb\xff\x44\x1a\xc7\xf0\xad\x21\xd6\x37\xa2\x1b\xcc\x8c\x4b\xdf\xd0\xe1\xb8\x6a\xed\xab\xf2\x9b\x77\xdf\x8f\x2a\xf3\x40\x75\xe2\x84\x1b\x7e\x22\x7e\xac\x0c\x3e\xfa\x9b\xb4\xed\x29\xfd\xfb\xca\x75\x94\x43\x9d\xb4\xc5\x21\xfa\x60\x02\x60\x66\x2b\x73\x28\x70\x85\x7a\x39\x22\xdf\x15\xcf\x24\xf6\xbf\x96\x26\xb1\xff\x1f\x42\xfe\x3f\x00\x00\xff\xff\x1f\xb2\x73\x97\x21\x22\x00\x00") +var _faucetHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x3a\xed\x72\xdb\x38\x92\xbf\x9d\xa7\xe8\xe1\xc5\x6b\xa9\x6c\x92\xb2\x9c\x64\x7d\x32\xa9\xa9\x5c\x76\x76\x76\xae\xae\x76\xa7\x66\xb2\x75\xb7\xb5\xbb\x75\x05\x92\x2d\x12\x31\x08\x70\x80\xa6\x64\x8d\x4b\xef\x7e\x05\x80\xa4\x28\xd9\xce\x78\x92\xa9\xdb\xf8\x87\x42\x02\xfd\xdd\x8d\xee\x46\x33\xc9\x57\x7f\xf8\xcb\xbb\xf7\x7f\xfb\xfe\x1b\xa8\xa8\x16\xcb\x17\x89\xfd\x07\x04\x93\x65\x1a\xa0\x0c\x96\x2f\x4e\x92\x0a\x59\xb1\x7c\x71\x72\x92\xd4\x48\x0c\xf2\x8a\x69\x83\x94\x06\x2d\xad\xc2\xeb\x60\xbf\x51\x11\x35\x21\xfe\xd4\xf2\x75\x1a\xfc\x4f\xf8\xd7\xb7\xe1\x3b\x55\x37\x8c\x78\x26\x30\x80\x5c\x49\x42\x49\x69\xf0\xdd\x37\x29\x16\x25\x8e\xf0\x24\xab\x31\x0d\xd6\x1c\x37\x8d\xd2\x34\x02\xdd\xf0\x82\xaa\xb4\xc0\x35\xcf\x31\x74\x2f\x17\xc0\x25\x27\xce\x44\x68\x72\x26\x30\xbd\x0c\x96\x2f\x2c\x1d\xe2\x24\x70\x79\x7f\x1f\xfd\x19\x69\xa3\xf4\xed\x6e\xb7\x80\xb7\x2d\x55\x28\x89\xe7\x8c\xb0\x80\x3f\xb2\x36\x47\x4a\x62\x0f\xe9\x90\x04\x97\xb7\x50\x69\x5c\xa5\x81\x15\xdd\x2c\xe2\x38\x2f\xe4\x07\x13\xe5\x42\xb5\xc5\x4a\x30\x8d\x51\xae\xea\x98\x7d\x60\x77\xb1\xe0\x99\x89\x69\xc3\x89\x50\x87\x99\x52\x64\x48\xb3\x26\xbe\x8a\xae\xa2\xdf\xc7\xb9\x31\xf1\xb0\x16\xd5\x5c\x46\xb9\x31\x01\x68\x14\x69\x60\x68\x2b\xd0\x54\x88\x14\x40\xbc\xfc\x34\xbe\x2b\x25\x29\x64\x1b\x34\xaa\xc6\xf8\x55\xf4\xfb\x68\xe6\x58\x8e\x97\x3f\xce\xd5\xb2\x35\xb9\xe6\x0d\x81\xd1\xf9\xb3\xf9\x7e\xf8\xa9\x45\xbd\x8d\xaf\xa2\xcb\xe8\xb2\x7b\x71\x7c\x3e\x98\x60\x99\xc4\x9e\xe0\xf2\xb3\x68\x87\x52\xd1\x36\x9e\x47\xaf\xa2\xcb\xb8\x61\xf9\x2d\x2b\xb1\xe8\x39\xd9\xad\xa8\x5f\xfc\xcd\xf8\x3e\xe5\xc3\x0f\xc7\x2e\xfc\x2d\x98\xd5\xaa\x46\x49\xd1\x07\x13\xcf\xa3\xcb\xeb\x68\xd6\x2f\x3c\xa4\xef\x18\x58\xa7\x59\x56\x27\xd1\x1a\xb5\x8d\x5c\x11\xe6\x28\x09\x35\xdc\xdb\xd5\x93\x9a\xcb\xb0\x42\x5e\x56\xb4\x80\xcb\xd9\xec\xf4\xe6\xb1\xd5\x75\xe5\x97\x0b\x6e\x1a\xc1\xb6\x0b\x58\x09\xbc\xf3\x4b\x4c\xf0\x52\x86\x9c\xb0\x36\x0b\xf0\x94\xdd\xc6\xce\xf1\x6c\xb4\x2a\x35\x1a\xd3\x31\x6b\x94\xe1\xc4\x95\x5c\xd8\x88\x62\xc4\xd7\xf8\x18\xac\x69\x98\x7c\x80\xc0\x32\xa3\x44\x4b\x78\x24\x48\x26\x54\x7e\xeb\xd7\xdc\x69\x1e\x2b\x91\x2b\xa1\xf4\x02\x36\x15\xef\xd0\xc0\x31\x82\x46\x63\x47\x1e\x1a\x56\x14\x5c\x96\x0b\x78\xd3\x74\xfa\x40\xcd\x74\xc9\xe5\x02\x66\x7b\x94\x24\xee\xcd\x98\xc4\x3e\x71\xbd\x38\x49\x32\x55\x6c\x9d\x0f\x0b\xbe\x86\x5c\x30\x63\xd2\xe0\xc8\xc4\x2e\x21\x1d\x00\xd8\x3c\xc4\xb8\xec\xb7\x0e\xf6\xb4\xda\x04\xe0\x18\xa5\x81\x17\x22\xcc\x14\x91\xaa\x17\x70\x69\xc5\xeb\x50\x8e\xe8\x89\x50\x94\xe1\xe5\xbc\xdf\x3c\x49\xaa\xcb\x9e\x08\xe1\x1d\x85\xce\x3f\x83\x67\x82\x65\xc2\x7b\xdc\x15\x83\x15\x0b\x33\x46\x55\x00\x4c\x73\x16\x56\xbc\x28\x50\xa6\x01\xe9\x16\x6d\x1c\xf1\x25\x8c\xd3\xdf\x13\xd9\xaf\xba\xec\xe5\x8a\x0b\xbe\xee\xd4\x1a\x3d\x1e\x69\xf8\xb4\x12\xd7\xd0\x3d\xa8\xd5\xca\x20\x85\x23\x9d\x46\xc0\x5c\x36\x2d\x85\xa5\x56\x6d\x33\xec\x9f\x24\x6e\x15\x78\x91\x06\x25\x37\x14\x00\x6d\x9b\xce\x00\xc1\xa0\xae\xd2\x75\x68\xed\xaf\x95\x08\xa0\x11\x2c\xc7\x4a\x89\x02\x75\x1a\xfc\xa8\x72\xce\x04\x48\xaf\x29\xfc\xf5\x87\xff\x82\xce\x51\x5c\x96\xb0\x55\xad\x86\x6f\xa8\x42\x8d\x6d\x0d\xac\x28\x6c\x90\x46\x51\x34\x62\xef\x22\xf6\xa1\x80\x61\x46\x72\x0f\x75\x92\x64\x2d\x91\x1a\x00\x33\x92\x90\x91\x0c\x0b\x5c\xb1\x56\x10\x14\x5a\x35\x85\xda\xc8\x90\x54\x59\xda\xfa\xe6\x95\xf0\x48\x01\x14\x8c\x58\xb7\x95\x06\x3d\x6c\xef\x39\x66\x1a\xd5\xb4\x4d\xe7\x3b\xbf\x88\x77\x0d\x93\x05\x16\xd6\xd3\xc2\x60\xb0\xfc\x96\xaf\x11\x6a\xf4\xba\x9c\x1c\x07\x42\xce\x34\x52\x38\x26\xfa\x20\x1c\x92\xd8\x0b\xe3\x55\x82\xee\x2f\x69\x45\x4f\x69\x50\xa1\x46\xd9\xc2\xc1\x5b\xa8\x6d\x36\x09\x96\xf7\xf7\x9a\xc9\x12\xe1\x25\x2f\xee\x2e\xe0\x25\xab\x55\x2b\x09\x16\x29\x44\x6f\xdd\xa3\xd9\xed\x0e\xa8\x03\x24\x82\x2f\x13\xf6\xb1\xa0\x06\x25\x73\xc1\xf3\xdb\x34\x20\x8e\x3a\xbd\xbf\xb7\xc4\x77\xbb\x1b\xb8\xbf\xe7\x2b\x78\x19\xfd\x80\x39\x6b\x28\xaf\xd8\x6e\x57\xea\xfe\x39\xc2\x3b\xcc\x5b\xc2\xc9\xf4\xfe\x1e\x85\xc1\xdd\xce\xb4\x59\xcd\x69\xd2\xa3\xdb\x75\x59\xec\x76\x56\xe6\x4e\xce\xdd\x0e\x62\x4b\x54\x16\x78\x07\x2f\xa3\xef\x51\x73\x55\x18\xf0\xf0\x49\xcc\x96\x49\x2c\xf8\xb2\xc3\x3b\x34\x52\xdc\x8a\x7d\xbc\xc4\x36\x60\x86\xe8\x76\x87\xc5\x89\x3a\x96\xf4\x91\xd8\x2f\xc3\x41\xfa\x2e\x1e\x0c\x27\xbc\xc5\x6d\x1a\xdc\xdf\x8f\x71\xbb\xdd\x9c\x09\x91\x31\x6b\x17\xaf\xda\x80\xf4\x33\xda\x38\x5d\x73\xe3\x1a\xa9\x65\x2f\xc1\x5e\xec\x67\x1e\xe6\xa3\x74\x45\xaa\x59\xc0\xd5\x7c\x94\xab\x1e\x3b\xe7\x6f\x8e\xce\xf9\xd5\xa3\xc0\x0d\x93\x28\xc0\xfd\x86\xa6\x66\xa2\x7f\xee\x4e\xcb\xe8\xf0\x1d\x23\x85\x36\x33\x0f\xa2\x0d\x19\x7e\x76\x03\x6a\x8d\x7a\x25\xd4\x66\x01\xac\x25\x75\x03\x35\xbb\x1b\xaa\xdc\xd5\x6c\x36\x96\xdb\x36\x80\x2c\x13\xe8\x72\x8a\xc6\x9f\x5a\x34\x64\x86\x5c\xe2\xb7\xdc\xaf\x4d\x29\x05\x4a\x83\xc5\x91\x35\x2c\x47\x6b\x5a\x07\x35\x72\xfd\x60\xcc\x47\x65\x5f\x29\x35\x14\x8e\xb1\x18\x1d\xe9\x51\x8d\x0b\x96\x09\xe9\x3d\xdc\x49\x42\xc5\xaf\x4a\xfc\xda\x36\x76\x4f\xe5\x7d\x9f\xd1\xac\xee\x0d\xa2\xf6\x5d\x85\x0d\x59\x70\xaf\x49\x4c\xc5\x67\x70\xb6\x41\x98\x31\x83\xcf\x61\xef\xea\xfb\x9e\xbd\x7b\xfd\x5c\xfe\x15\x32\x4d\x19\x32\x7a\x8e\x00\xab\x56\x16\x23\xfd\x5d\xee\xfc\x5c\x01\x5a\xc9\xd7\xa8\x0d\xa7\xed\x73\x25\xc0\x62\x2f\x82\x7f\x3f\x14\x21\x89\x49\x7f\x3c\xd6\xc6\x2f\xbf\xd1\xe1\xfe\xa5\x46\xe4\x6a\xf9\x27\xb5\x81\x42\xa1\x01\xaa\xb8\x01\x5b\x5c\xbf\x4e\xe2\xea\x6a\x00\x69\x96\xef\xed\x86\x33\x2a\xac\x5c\x43\x01\xdc\x80\x6e\xa5\xab\xbc\x4a\x02\x55\x78\xd8\x84\x74\x45\x3a\x82\xf7\xca\x36\x72\x6b\x94\x04\x35\x13\x3c\xe7\xaa\x35\xc0\x72\x52\xda\xc0\x4a\xab\x1a\xf0\xae\x62\xad\x21\x4b\xc8\xa6\x0f\xb6\x66\x5c\xb8\xb3\xe4\x5c\x0a\x4a\x03\xcb\xf3\xb6\x6e\x6d\x23\x2a\x4b\x40\xa9\xda\xb2\xea\x64\x21\x05\xbe\x30\x09\x25\xcb\x41\x1e\xd3\xb0\x1a\x18\x11\xcb\x6f\xcd\x05\xf4\x59\x01\x98\x46\x20\x8e\x85\xc5\xca\x51\xdb\xbe\x01\x72\x55\xd7\x4a\xc2\x95\x2e\xa0\x61\x9a\xb6\x96\x97\x2b\x6f\x11\xbc\x95\x5b\x25\x11\x2a\xb6\x76\xa2\xc1\xb7\x9c\xfe\xd4\x66\x17\xf0\xde\xdf\x22\x2e\xe0\x5b\xa5\x4a\x81\xe7\x56\xc2\x3f\xb2\x1c\x33\xa5\x6e\x7b\x74\xa8\xd9\xb6\x67\xdc\xe9\xb1\xe1\x54\x71\x6f\xa8\x06\x75\x6d\x69\x14\x20\x78\xcd\xc9\x44\x49\xdc\xec\x73\xeb\xbe\x4a\x8b\xb0\x52\x9a\xff\x6c\x5b\x1c\x31\xf8\x0b\x20\x29\xe8\x28\xcf\xf4\x69\xd2\x05\x80\xc0\x15\x2d\xe0\x95\x4f\x93\xc7\x21\x5d\x72\xaa\xda\x2c\x64\xe2\xd1\x43\xd5\x93\x75\xb7\x4b\x5b\x7e\x16\x70\xe5\x5b\x5a\xdf\x56\x14\x34\x4a\x89\xc5\x51\xe0\x79\xbe\xd7\xd7\xcd\xdd\x20\xca\xd0\x17\xcf\x06\x22\x36\x1e\x0e\x0d\xb3\xe6\x7b\xdb\xe6\x1a\x19\x21\x30\x48\xd8\xd1\x35\xd9\xf6\x8b\x91\x97\xde\x5d\xb4\x02\x20\xa6\x4b\xa4\x34\xf8\x5f\x96\xa9\x96\x16\x99\x60\xf2\x36\x58\x5a\x38\x5b\xe1\x9d\xbd\x1f\xef\x09\x01\xeb\x0c\x8b\x02\x0b\xe0\x92\x94\xf3\x48\x37\x77\x80\x89\x7d\x59\x71\x81\x6e\x32\xe1\xce\x84\x3c\xb3\xde\xb4\x1e\x9f\x46\x49\xa6\xe3\xe5\x3b\xd5\x6c\xc3\x86\x19\x42\x87\x6a\x19\x1a\xd7\x8b\x0e\xd4\x58\xa6\xd6\x08\xbe\xd7\xcd\xd4\x1d\x30\x59\xc0\x8a\x6b\x04\xb6\x61\xdb\xaf\x92\xb8\x70\x37\x93\xde\x8e\x9f\xee\xcc\xee\x3e\xfb\x45\x79\x72\x38\x1d\x35\xbb\x7d\xd4\x91\x9d\xd0\xce\x89\xdc\x59\x3d\xa6\x0d\x22\x7d\x6d\x53\x72\xfa\x83\x27\xc8\x65\x79\x3a\x9f\xf9\x4c\x63\x1f\x2c\xf9\xd3\xf9\xcc\x5a\xf8\x74\x3e\x9b\xdd\xcd\x9e\xf9\x77\x3a\x9f\x29\x79\x3a\x9f\x51\x85\xa7\xf3\xd9\xe9\xfc\x6a\x9c\xa3\xfc\x4a\x1f\x1d\x16\x0a\x8d\xe5\xd6\xa7\xae\xa7\x42\xcc\x89\xfb\x4b\x31\xe6\x02\xe4\x61\x84\x19\x98\x98\x56\x6b\xd5\x4a\xdb\xed\x80\xd5\xf9\x59\x51\xf6\xc0\x8c\xa6\x6d\x1a\xa5\x29\x1a\x9b\x93\xd9\x5b\xad\x40\x13\x5f\xcf\x5e\x5f\xbf\xf9\xa8\xf8\x2e\x62\x9d\x0e\xff\xef\x51\x5b\xba\xb4\x19\x36\xa2\x35\xb6\xb5\xe4\xf6\x4e\xf7\x45\x85\xb0\xcf\xeb\xf0\xbd\x68\xcd\x05\x34\x6d\x26\xb8\xa9\x80\x81\xc4\x0d\x24\x86\xb4\x92\xe5\xd2\xad\xe6\x49\xdc\xbd\x42\xa3\x0c\x7d\x62\xc6\xf9\xa4\x70\xb0\xfc\xfe\x45\x49\x67\xd5\x95\xba\x2f\xca\x65\x7d\xfd\xfd\x52\xfd\xf5\xe0\xf8\x6e\x36\x9b\xa8\xb7\xa4\x3b\xbb\x15\x8a\x26\xb6\xdd\x48\x2b\x39\x6d\x63\x9f\x05\x95\x8c\xbf\xe6\x45\x3a\xbf\x9e\xbf\x79\x33\x7f\xf5\xef\xd7\xaf\x5f\xcf\xaf\x5f\xbd\x7e\xea\x60\x0f\x41\xf1\xeb\xcf\xf5\xd0\x7b\x8a\x51\xcf\xf7\x37\xd5\x42\xce\x24\x90\x66\xf9\xad\x37\x42\xab\xb5\x35\x42\x83\x5e\xff\xa1\xb5\xca\x50\xa8\x8d\x03\xf1\x7c\x56\x1c\x85\xeb\xb3\x0c\x22\x54\x6a\x03\x75\x9b\x3b\x5b\xdb\x76\x0a\xed\xc6\x86\x71\x82\x56\x12\x17\xde\x05\xd4\x6a\xd7\x8d\xe1\x41\x37\xf4\xe0\xb6\x9d\x60\xbd\x7c\x6f\x6b\xf4\x83\x26\x74\xb8\x27\x83\xc6\x77\x1e\x1c\x1a\xad\x08\x73\x6b\x47\x60\x25\xe3\xd2\x58\x0b\xb8\x7e\x0b\xeb\x67\xdc\xa3\x87\xa7\xee\x61\x3f\x09\x76\xdb\x71\x0c\xdf\x0a\x95\x31\x01\x6b\x7b\x14\x32\x61\x1b\x68\x05\x95\xb2\xaa\x8f\xac\x65\x88\x51\x6b\x40\xad\xdc\xaa\x97\xdc\xe2\xaf\x99\xb6\x5d\x2a\xd6\x0d\x41\xda\xcd\x31\xed\x9a\x41\xbd\xee\xa6\xb3\xf6\x95\x38\x6a\xbf\xdf\x31\xfd\x03\xae\xb8\xf4\x71\xb5\x6a\xa5\x57\x8f\x2a\x46\xe0\xa7\x07\x06\x98\x6b\x4a\xa0\xd5\x02\xba\x18\xf0\x24\x07\x06\x0e\x0e\xd2\x01\x7d\xf2\xc0\xce\xdd\x43\x67\xa3\x69\x37\x87\xf5\x64\x22\x83\xb2\x98\xfc\xe7\x8f\x7f\xf9\x73\x64\x48\x73\x59\xf2\xd5\x76\x72\xdf\x6a\xb1\x80\x97\x93\xe0\xdf\xdc\x64\x6f\xfa\xf7\xd9\x3f\xa3\x35\x13\x2d\x5e\x38\x05\x16\xee\xf7\x01\x9b\x0b\xe8\x1e\x17\x70\xc8\x71\x37\x9d\xde\x3c\x3e\x6a\x19\x4d\x86\x34\x1a\xa4\x89\x05\x1c\x3c\xb9\xbb\x39\x34\x12\x83\x1a\xa9\x52\x2e\x16\x35\xe6\x4a\x4a\xcc\x09\xda\x46\xc9\xce\x26\x20\x94\x31\xbd\x61\xf6\x10\x23\xdb\xf4\xca\xf3\x15\x4c\x7a\x77\x9d\xc2\x1c\xd2\x14\x66\xfd\x5e\x67\x19\x48\x5d\xd6\xf9\x6f\xcc\x7e\x54\xf9\x2d\xd2\x24\xd8\x18\x7b\xda\x03\x38\x07\xa1\x72\x66\xe9\x45\x95\xcd\x3d\xe7\x10\xc4\xac\xe1\xc1\xd4\x4f\xb3\x77\x80\xc2\xe0\x2f\x13\x7b\x16\x2d\x3f\xef\xf7\x92\x9e\x9f\xfb\xb0\xe9\x5d\xa7\x64\x8d\xc6\xb0\x12\xc7\x1a\xba\xdb\xd9\xa0\x8a\x35\x44\x6d\x4a\x48\xc1\xb9\xb8\x61\xda\xa0\x07\x89\x0a\x46\xac\xe3\xe2\xcc\xe1\xc0\xd2\x14\x64\x2b\xc4\x80\x7f\xa2\xd1\x1e\xe6\x0e\x6c\xf7\xe2\x00\x3c\xf2\x39\xfb\xab\x34\x05\x7b\x3d\xb6\x3e\x2a\xf6\x98\x36\x7c\xfc\x45\x7e\x1a\xd9\xdc\xba\xc7\x98\x0e\xe4\x1e\x50\xc3\xe2\x97\xc8\x61\x71\x4c\x0f\x8b\x27\x08\xba\xb9\xc9\xc7\xe8\xf9\x39\xcb\x88\x9c\x5b\x78\x82\x9a\x6c\xeb\x0c\xf5\xc7\xc8\xf9\xb9\x49\x47\xce\x99\xfa\x3b\x49\x23\xdc\x0b\xb8\x7c\x33\x7d\x82\x3a\x6a\xad\x9e\x24\x2e\x15\x6d\x27\xf7\x82\x6d\x6d\x81\x80\x33\x52\xcd\x3b\x37\xe6\x38\xbb\x70\x55\x6b\x01\x03\x85\x0b\x37\xc0\x5e\xc0\x99\x7b\xb3\xfb\xbc\x46\x87\xf5\x7a\x36\x9b\x5d\x40\xff\xbd\xe7\x3f\x98\x3d\xc5\xba\xc5\xdd\x13\xf2\x98\x36\xcf\x6d\xf1\xfc\x1c\x89\x3a\x1a\x83\x4c\xdd\xfb\x58\xaa\xcb\x5f\x29\xd6\x50\xa4\x0e\xe4\x82\xdf\xfd\x0e\x1e\xec\x1e\xc6\xb1\x3d\x08\x7d\xd9\x4f\x21\x08\x3a\xf2\x27\x2b\xa5\x61\x62\x37\x79\x3a\xbb\x01\x9e\x8c\xc9\x44\x02\x65\x49\xd5\x0d\xf0\xf3\xf3\x3d\xa5\x93\x9e\xcc\x79\x0a\x41\x42\x7a\x99\x50\xb1\x74\x63\x19\xdf\x02\xfd\x23\xc8\x58\x7e\x5b\xba\xbe\x62\x61\xf3\xf6\xe4\xcc\x1e\xf3\x31\xe1\xbf\xf3\x7f\x46\x6c\xcd\x88\x69\x7b\xde\xcf\xa6\x37\xb0\x47\xe9\x5a\xad\x5c\xd9\xb2\x01\xbe\xa3\x73\x13\x20\x18\xa6\xa6\xee\x2d\x53\xba\x40\x1d\x6a\x56\xf0\xd6\x2c\xe0\x55\x73\x77\xf3\x8f\x7e\xaa\xec\xe6\x54\x4e\xac\x46\xe3\xf2\x51\xee\xdd\x68\xe3\x1c\x82\x24\xb6\x40\x3d\xca\xa0\xc4\xf8\xcb\x1e\x3c\x32\x61\x83\xe1\xbb\x5b\xb7\x5e\xf3\xa2\x10\x68\x85\x70\x0c\xfd\x07\xd2\xa2\xd5\x2e\xb9\x4d\xfc\xfb\xe4\x58\x0e\x1b\x08\xd3\xa8\x95\xfc\x6e\x32\x0d\x3b\x98\xfe\xfd\x02\xce\x8c\xcd\xe1\x85\x39\x9b\x46\x55\x5b\x33\xc9\x7f\xc6\x89\x8d\x8e\xa9\x97\xdb\x4a\x1c\x93\x5e\x0e\xce\xdc\x8d\x0e\xe3\x30\x3f\x9e\x46\x15\xd5\x62\x12\x24\xe4\xbe\x1e\x5a\xe1\x06\x0f\x3a\x2a\x7e\xf9\x30\xe0\x76\x87\x79\x36\x17\xca\xe0\x51\x1d\x01\x83\xf4\xde\xc7\xf1\x64\xa8\x35\x17\x70\x35\x9b\xcd\xa6\x37\xb0\xdb\x7f\x64\x8d\x63\xf8\xc6\x10\xeb\x5b\xd9\x0d\x66\xc6\xd5\x00\xe8\x70\x5c\xc9\xf7\xa5\xfd\xed\xf7\xdf\x8d\xca\xfb\x40\x75\xe2\x84\x1b\x3e\x32\x3f\x56\x4b\x1f\xfd\xaa\x6d\x1b\x53\x7f\x43\x73\x6d\xe9\x50\x6c\x6d\x85\x89\x3e\x98\x00\x98\xd9\xca\x1c\x0a\x5c\xa1\x5e\x8e\xc8\x77\x15\x38\x89\xfd\xf7\xd6\x24\xf6\xff\xa5\xe4\xff\x02\x00\x00\xff\xff\x06\xe6\xbb\xe1\x63\x22\x00\x00") func faucetHtmlBytes() ([]byte, error) { return bindataRead( From 5d2c947060b55089adc64dbe0b3cbbe1644f73ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 17 Oct 2017 14:55:21 +0300 Subject: [PATCH 3/3] cmd/faucet: dynamic funding progress and visual feedback --- cmd/faucet/faucet.go | 2 +- cmd/faucet/faucet.html | 86 +++++++++++++++++++++++++++++++++++++++--- cmd/faucet/website.go | 2 +- 3 files changed, 83 insertions(+), 7 deletions(-) diff --git a/cmd/faucet/faucet.go b/cmd/faucet/faucet.go index 715f3dec9..72098e68d 100644 --- a/cmd/faucet/faucet.go +++ b/cmd/faucet/faucet.go @@ -186,7 +186,7 @@ func main() { type request struct { Avatar string `json:"avatar"` // Avatar URL to make the UI nicer Account common.Address `json:"account"` // Ethereum address being funded - Time time.Time `json:"time"` // Timestamp when te request was accepted + Time time.Time `json:"time"` // Timestamp when the request was accepted Tx *types.Transaction `json:"tx"` // Transaction funding the account } diff --git a/cmd/faucet/faucet.html b/cmd/faucet/faucet.html index 75dad0bdf..5d3b8741b 100644 --- a/cmd/faucet/faucet.html +++ b/cmd/faucet/faucet.html @@ -49,7 +49,7 @@
- +
" + msg.requests[i].account + "
" + moment.duration(moment(msg.requests[i].time).unix()-moment().unix(), 'seconds').humanize(true) + ""; + for (var i=0; i"; + content += "
"; + content += "
" + requests[i].account + "
"; + content += " "; + if (done) { + content += " funded"; + } else { + content += " " + moment.duration(-elapsed, 'seconds').humanize(true) + ""; + } + content += "
"; + if (done) { + content += "
"; + } else if (elapsed > 30) { + content += "
"; + } else { + content += "
"; + } + content += "
"; + content += " "; + content += ""; } $("#requests").html("" + content + ""); } } server.onclose = function() { setTimeout(reconnect, 3000); }; } + // Start a UI updater to push the progress bars forward until they are done + setInterval(function() { + $('.progress-bar').each(function() { + var progress = Number($(this).attr('aria-valuenow')) + 1; + if (progress < 30) { + $(this).attr('aria-valuenow', progress); + $(this).css('width', (progress * 100 / 30) + '%'); + } else if (progress == 30) { + $(this).css('width', '100%'); + $(this).addClass("progress-bar-danger"); + } + }) + $('.timer').each(function() { + var index = Number($(this).attr('id').substring(5)); + $(this).html(moment.duration(moment(requests[index].time).unix()-moment().unix(), 'seconds').humanize(true)); + }) + }, 1000); + // Establish a websocket connection to the API server reconnect(); {{if .Recaptcha}} diff --git a/cmd/faucet/website.go b/cmd/faucet/website.go index f99c69abf..eeb8e410e 100644 --- a/cmd/faucet/website.go +++ b/cmd/faucet/website.go @@ -68,7 +68,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _faucetHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x3a\xed\x72\xdb\x38\x92\xbf\x9d\xa7\xe8\xe1\xc5\x6b\xa9\x6c\x92\xb2\x9c\x64\x7d\x32\xa9\xa9\x5c\x76\x76\x76\xae\xae\x76\xa7\x66\xb2\x75\xb7\xb5\xbb\x75\x05\x92\x2d\x12\x31\x08\x70\x80\xa6\x64\x8d\x4b\xef\x7e\x05\x80\xa4\x28\xd9\xce\x78\x92\xa9\xdb\xf8\x87\x42\x02\xfd\xdd\x8d\xee\x46\x33\xc9\x57\x7f\xf8\xcb\xbb\xf7\x7f\xfb\xfe\x1b\xa8\xa8\x16\xcb\x17\x89\xfd\x07\x04\x93\x65\x1a\xa0\x0c\x96\x2f\x4e\x92\x0a\x59\xb1\x7c\x71\x72\x92\xd4\x48\x0c\xf2\x8a\x69\x83\x94\x06\x2d\xad\xc2\xeb\x60\xbf\x51\x11\x35\x21\xfe\xd4\xf2\x75\x1a\xfc\x4f\xf8\xd7\xb7\xe1\x3b\x55\x37\x8c\x78\x26\x30\x80\x5c\x49\x42\x49\x69\xf0\xdd\x37\x29\x16\x25\x8e\xf0\x24\xab\x31\x0d\xd6\x1c\x37\x8d\xd2\x34\x02\xdd\xf0\x82\xaa\xb4\xc0\x35\xcf\x31\x74\x2f\x17\xc0\x25\x27\xce\x44\x68\x72\x26\x30\xbd\x0c\x96\x2f\x2c\x1d\xe2\x24\x70\x79\x7f\x1f\xfd\x19\x69\xa3\xf4\xed\x6e\xb7\x80\xb7\x2d\x55\x28\x89\xe7\x8c\xb0\x80\x3f\xb2\x36\x47\x4a\x62\x0f\xe9\x90\x04\x97\xb7\x50\x69\x5c\xa5\x81\x15\xdd\x2c\xe2\x38\x2f\xe4\x07\x13\xe5\x42\xb5\xc5\x4a\x30\x8d\x51\xae\xea\x98\x7d\x60\x77\xb1\xe0\x99\x89\x69\xc3\x89\x50\x87\x99\x52\x64\x48\xb3\x26\xbe\x8a\xae\xa2\xdf\xc7\xb9\x31\xf1\xb0\x16\xd5\x5c\x46\xb9\x31\x01\x68\x14\x69\x60\x68\x2b\xd0\x54\x88\x14\x40\xbc\xfc\x34\xbe\x2b\x25\x29\x64\x1b\x34\xaa\xc6\xf8\x55\xf4\xfb\x68\xe6\x58\x8e\x97\x3f\xce\xd5\xb2\x35\xb9\xe6\x0d\x81\xd1\xf9\xb3\xf9\x7e\xf8\xa9\x45\xbd\x8d\xaf\xa2\xcb\xe8\xb2\x7b\x71\x7c\x3e\x98\x60\x99\xc4\x9e\xe0\xf2\xb3\x68\x87\x52\xd1\x36\x9e\x47\xaf\xa2\xcb\xb8\x61\xf9\x2d\x2b\xb1\xe8\x39\xd9\xad\xa8\x5f\xfc\xcd\xf8\x3e\xe5\xc3\x0f\xc7\x2e\xfc\x2d\x98\xd5\xaa\x46\x49\xd1\x07\x13\xcf\xa3\xcb\xeb\x68\xd6\x2f\x3c\xa4\xef\x18\x58\xa7\x59\x56\x27\xd1\x1a\xb5\x8d\x5c\x11\xe6\x28\x09\x35\xdc\xdb\xd5\x93\x9a\xcb\xb0\x42\x5e\x56\xb4\x80\xcb\xd9\xec\xf4\xe6\xb1\xd5\x75\xe5\x97\x0b\x6e\x1a\xc1\xb6\x0b\x58\x09\xbc\xf3\x4b\x4c\xf0\x52\x86\x9c\xb0\x36\x0b\xf0\x94\xdd\xc6\xce\xf1\x6c\xb4\x2a\x35\x1a\xd3\x31\x6b\x94\xe1\xc4\x95\x5c\xd8\x88\x62\xc4\xd7\xf8\x18\xac\x69\x98\x7c\x80\xc0\x32\xa3\x44\x4b\x78\x24\x48\x26\x54\x7e\xeb\xd7\xdc\x69\x1e\x2b\x91\x2b\xa1\xf4\x02\x36\x15\xef\xd0\xc0\x31\x82\x46\x63\x47\x1e\x1a\x56\x14\x5c\x96\x0b\x78\xd3\x74\xfa\x40\xcd\x74\xc9\xe5\x02\x66\x7b\x94\x24\xee\xcd\x98\xc4\x3e\x71\xbd\x38\x49\x32\x55\x6c\x9d\x0f\x0b\xbe\x86\x5c\x30\x63\xd2\xe0\xc8\xc4\x2e\x21\x1d\x00\xd8\x3c\xc4\xb8\xec\xb7\x0e\xf6\xb4\xda\x04\xe0\x18\xa5\x81\x17\x22\xcc\x14\x91\xaa\x17\x70\x69\xc5\xeb\x50\x8e\xe8\x89\x50\x94\xe1\xe5\xbc\xdf\x3c\x49\xaa\xcb\x9e\x08\xe1\x1d\x85\xce\x3f\x83\x67\x82\x65\xc2\x7b\xdc\x15\x83\x15\x0b\x33\x46\x55\x00\x4c\x73\x16\x56\xbc\x28\x50\xa6\x01\xe9\x16\x6d\x1c\xf1\x25\x8c\xd3\xdf\x13\xd9\xaf\xba\xec\xe5\x8a\x0b\xbe\xee\xd4\x1a\x3d\x1e\x69\xf8\xb4\x12\xd7\xd0\x3d\xa8\xd5\xca\x20\x85\x23\x9d\x46\xc0\x5c\x36\x2d\x85\xa5\x56\x6d\x33\xec\x9f\x24\x6e\x15\x78\x91\x06\x25\x37\x14\x00\x6d\x9b\xce\x00\xc1\xa0\xae\xd2\x75\x68\xed\xaf\x95\x08\xa0\x11\x2c\xc7\x4a\x89\x02\x75\x1a\xfc\xa8\x72\xce\x04\x48\xaf\x29\xfc\xf5\x87\xff\x82\xce\x51\x5c\x96\xb0\x55\xad\x86\x6f\xa8\x42\x8d\x6d\x0d\xac\x28\x6c\x90\x46\x51\x34\x62\xef\x22\xf6\xa1\x80\x61\x46\x72\x0f\x75\x92\x64\x2d\x91\x1a\x00\x33\x92\x90\x91\x0c\x0b\x5c\xb1\x56\x10\x14\x5a\x35\x85\xda\xc8\x90\x54\x59\xda\xfa\xe6\x95\xf0\x48\x01\x14\x8c\x58\xb7\x95\x06\x3d\x6c\xef\x39\x66\x1a\xd5\xb4\x4d\xe7\x3b\xbf\x88\x77\x0d\x93\x05\x16\xd6\xd3\xc2\x60\xb0\xfc\x96\xaf\x11\x6a\xf4\xba\x9c\x1c\x07\x42\xce\x34\x52\x38\x26\xfa\x20\x1c\x92\xd8\x0b\xe3\x55\x82\xee\x2f\x69\x45\x4f\x69\x50\xa1\x46\xd9\xc2\xc1\x5b\xa8\x6d\x36\x09\x96\xf7\xf7\x9a\xc9\x12\xe1\x25\x2f\xee\x2e\xe0\x25\xab\x55\x2b\x09\x16\x29\x44\x6f\xdd\xa3\xd9\xed\x0e\xa8\x03\x24\x82\x2f\x13\xf6\xb1\xa0\x06\x25\x73\xc1\xf3\xdb\x34\x20\x8e\x3a\xbd\xbf\xb7\xc4\x77\xbb\x1b\xb8\xbf\xe7\x2b\x78\x19\xfd\x80\x39\x6b\x28\xaf\xd8\x6e\x57\xea\xfe\x39\xc2\x3b\xcc\x5b\xc2\xc9\xf4\xfe\x1e\x85\xc1\xdd\xce\xb4\x59\xcd\x69\xd2\xa3\xdb\x75\x59\xec\x76\x56\xe6\x4e\xce\xdd\x0e\x62\x4b\x54\x16\x78\x07\x2f\xa3\xef\x51\x73\x55\x18\xf0\xf0\x49\xcc\x96\x49\x2c\xf8\xb2\xc3\x3b\x34\x52\xdc\x8a\x7d\xbc\xc4\x36\x60\x86\xe8\x76\x87\xc5\x89\x3a\x96\xf4\x91\xd8\x2f\xc3\x41\xfa\x2e\x1e\x0c\x27\xbc\xc5\x6d\x1a\xdc\xdf\x8f\x71\xbb\xdd\x9c\x09\x91\x31\x6b\x17\xaf\xda\x80\xf4\x33\xda\x38\x5d\x73\xe3\x1a\xa9\x65\x2f\xc1\x5e\xec\x67\x1e\xe6\xa3\x74\x45\xaa\x59\xc0\xd5\x7c\x94\xab\x1e\x3b\xe7\x6f\x8e\xce\xf9\xd5\xa3\xc0\x0d\x93\x28\xc0\xfd\x86\xa6\x66\xa2\x7f\xee\x4e\xcb\xe8\xf0\x1d\x23\x85\x36\x33\x0f\xa2\x0d\x19\x7e\x76\x03\x6a\x8d\x7a\x25\xd4\x66\x01\xac\x25\x75\x03\x35\xbb\x1b\xaa\xdc\xd5\x6c\x36\x96\xdb\x36\x80\x2c\x13\xe8\x72\x8a\xc6\x9f\x5a\x34\x64\x86\x5c\xe2\xb7\xdc\xaf\x4d\x29\x05\x4a\x83\xc5\x91\x35\x2c\x47\x6b\x5a\x07\x35\x72\xfd\x60\xcc\x47\x65\x5f\x29\x35\x14\x8e\xb1\x18\x1d\xe9\x51\x8d\x0b\x96\x09\xe9\x3d\xdc\x49\x42\xc5\xaf\x4a\xfc\xda\x36\x76\x4f\xe5\x7d\x9f\xd1\xac\xee\x0d\xa2\xf6\x5d\x85\x0d\x59\x70\xaf\x49\x4c\xc5\x67\x70\xb6\x41\x98\x31\x83\xcf\x61\xef\xea\xfb\x9e\xbd\x7b\xfd\x5c\xfe\x15\x32\x4d\x19\x32\x7a\x8e\x00\xab\x56\x16\x23\xfd\x5d\xee\xfc\x5c\x01\x5a\xc9\xd7\xa8\x0d\xa7\xed\x73\x25\xc0\x62\x2f\x82\x7f\x3f\x14\x21\x89\x49\x7f\x3c\xd6\xc6\x2f\xbf\xd1\xe1\xfe\xa5\x46\xe4\x6a\xf9\x27\xb5\x81\x42\xa1\x01\xaa\xb8\x01\x5b\x5c\xbf\x4e\xe2\xea\x6a\x00\x69\x96\xef\xed\x86\x33\x2a\xac\x5c\x43\x01\xdc\x80\x6e\xa5\xab\xbc\x4a\x02\x55\x78\xd8\x84\x74\x45\x3a\x82\xf7\xca\x36\x72\x6b\x94\x04\x35\x13\x3c\xe7\xaa\x35\xc0\x72\x52\xda\xc0\x4a\xab\x1a\xf0\xae\x62\xad\x21\x4b\xc8\xa6\x0f\xb6\x66\x5c\xb8\xb3\xe4\x5c\x0a\x4a\x03\xcb\xf3\xb6\x6e\x6d\x23\x2a\x4b\x40\xa9\xda\xb2\xea\x64\x21\x05\xbe\x30\x09\x25\xcb\x41\x1e\xd3\xb0\x1a\x18\x11\xcb\x6f\xcd\x05\xf4\x59\x01\x98\x46\x20\x8e\x85\xc5\xca\x51\xdb\xbe\x01\x72\x55\xd7\x4a\xc2\x95\x2e\xa0\x61\x9a\xb6\x96\x97\x2b\x6f\x11\xbc\x95\x5b\x25\x11\x2a\xb6\x76\xa2\xc1\xb7\x9c\xfe\xd4\x66\x17\xf0\xde\xdf\x22\x2e\xe0\x5b\xa5\x4a\x81\xe7\x56\xc2\x3f\xb2\x1c\x33\xa5\x6e\x7b\x74\xa8\xd9\xb6\x67\xdc\xe9\xb1\xe1\x54\x71\x6f\xa8\x06\x75\x6d\x69\x14\x20\x78\xcd\xc9\x44\x49\xdc\xec\x73\xeb\xbe\x4a\x8b\xb0\x52\x9a\xff\x6c\x5b\x1c\x31\xf8\x0b\x20\x29\xe8\x28\xcf\xf4\x69\xd2\x05\x80\xc0\x15\x2d\xe0\x95\x4f\x93\xc7\x21\x5d\x72\xaa\xda\x2c\x64\xe2\xd1\x43\xd5\x93\x75\xb7\x4b\x5b\x7e\x16\x70\xe5\x5b\x5a\xdf\x56\x14\x34\x4a\x89\xc5\x51\xe0\x79\xbe\xd7\xd7\xcd\xdd\x20\xca\xd0\x17\xcf\x06\x22\x36\x1e\x0e\x0d\xb3\xe6\x7b\xdb\xe6\x1a\x19\x21\x30\x48\xd8\xd1\x35\xd9\xf6\x8b\x91\x97\xde\x5d\xb4\x02\x20\xa6\x4b\xa4\x34\xf8\x5f\x96\xa9\x96\x16\x99\x60\xf2\x36\x58\x5a\x38\x5b\xe1\x9d\xbd\x1f\xef\x09\x01\xeb\x0c\x8b\x02\x0b\xe0\x92\x94\xf3\x48\x37\x77\x80\x89\x7d\x59\x71\x81\x6e\x32\xe1\xce\x84\x3c\xb3\xde\xb4\x1e\x9f\x46\x49\xa6\xe3\xe5\x3b\xd5\x6c\xc3\x86\x19\x42\x87\x6a\x19\x1a\xd7\x8b\x0e\xd4\x58\xa6\xd6\x08\xbe\xd7\xcd\xd4\x1d\x30\x59\xc0\x8a\x6b\x04\xb6\x61\xdb\xaf\x92\xb8\x70\x37\x93\xde\x8e\x9f\xee\xcc\xee\x3e\xfb\x45\x79\x72\x38\x1d\x35\xbb\x7d\xd4\x91\x9d\xd0\xce\x89\xdc\x59\x3d\xa6\x0d\x22\x7d\x6d\x53\x72\xfa\x83\x27\xc8\x65\x79\x3a\x9f\xf9\x4c\x63\x1f\x2c\xf9\xd3\xf9\xcc\x5a\xf8\x74\x3e\x9b\xdd\xcd\x9e\xf9\x77\x3a\x9f\x29\x79\x3a\x9f\x51\x85\xa7\xf3\xd9\xe9\xfc\x6a\x9c\xa3\xfc\x4a\x1f\x1d\x16\x0a\x8d\xe5\xd6\xa7\xae\xa7\x42\xcc\x89\xfb\x4b\x31\xe6\x02\xe4\x61\x84\x19\x98\x98\x56\x6b\xd5\x4a\xdb\xed\x80\xd5\xf9\x59\x51\xf6\xc0\x8c\xa6\x6d\x1a\xa5\x29\x1a\x9b\x93\xd9\x5b\xad\x40\x13\x5f\xcf\x5e\x5f\xbf\xf9\xa8\xf8\x2e\x62\x9d\x0e\xff\xef\x51\x5b\xba\xb4\x19\x36\xa2\x35\xb6\xb5\xe4\xf6\x4e\xf7\x45\x85\xb0\xcf\xeb\xf0\xbd\x68\xcd\x05\x34\x6d\x26\xb8\xa9\x80\x81\xc4\x0d\x24\x86\xb4\x92\xe5\xd2\xad\xe6\x49\xdc\xbd\x42\xa3\x0c\x7d\x62\xc6\xf9\xa4\x70\xb0\xfc\xfe\x45\x49\x67\xd5\x95\xba\x2f\xca\x65\x7d\xfd\xfd\x52\xfd\xf5\xe0\xf8\x6e\x36\x9b\xa8\xb7\xa4\x3b\xbb\x15\x8a\x26\xb6\xdd\x48\x2b\x39\x6d\x63\x9f\x05\x95\x8c\xbf\xe6\x45\x3a\xbf\x9e\xbf\x79\x33\x7f\xf5\xef\xd7\xaf\x5f\xcf\xaf\x5f\xbd\x7e\xea\x60\x0f\x41\xf1\xeb\xcf\xf5\xd0\x7b\x8a\x51\xcf\xf7\x37\xd5\x42\xce\x24\x90\x66\xf9\xad\x37\x42\xab\xb5\x35\x42\x83\x5e\xff\xa1\xb5\xca\x50\xa8\x8d\x03\xf1\x7c\x56\x1c\x85\xeb\xb3\x0c\x22\x54\x6a\x03\x75\x9b\x3b\x5b\xdb\x76\x0a\xed\xc6\x86\x71\x82\x56\x12\x17\xde\x05\xd4\x6a\xd7\x8d\xe1\x41\x37\xf4\xe0\xb6\x9d\x60\xbd\x7c\x6f\x6b\xf4\x83\x26\x74\xb8\x27\x83\xc6\x77\x1e\x1c\x1a\xad\x08\x73\x6b\x47\x60\x25\xe3\xd2\x58\x0b\xb8\x7e\x0b\xeb\x67\xdc\xa3\x87\xa7\xee\x61\x3f\x09\x76\xdb\x71\x0c\xdf\x0a\x95\x31\x01\x6b\x7b\x14\x32\x61\x1b\x68\x05\x95\xb2\xaa\x8f\xac\x65\x88\x51\x6b\x40\xad\xdc\xaa\x97\xdc\xe2\xaf\x99\xb6\x5d\x2a\xd6\x0d\x41\xda\xcd\x31\xed\x9a\x41\xbd\xee\xa6\xb3\xf6\x95\x38\x6a\xbf\xdf\x31\xfd\x03\xae\xb8\xf4\x71\xb5\x6a\xa5\x57\x8f\x2a\x46\xe0\xa7\x07\x06\x98\x6b\x4a\xa0\xd5\x02\xba\x18\xf0\x24\x07\x06\x0e\x0e\xd2\x01\x7d\xf2\xc0\xce\xdd\x43\x67\xa3\x69\x37\x87\xf5\x64\x22\x83\xb2\x98\xfc\xe7\x8f\x7f\xf9\x73\x64\x48\x73\x59\xf2\xd5\x76\x72\xdf\x6a\xb1\x80\x97\x93\xe0\xdf\xdc\x64\x6f\xfa\xf7\xd9\x3f\xa3\x35\x13\x2d\x5e\x38\x05\x16\xee\xf7\x01\x9b\x0b\xe8\x1e\x17\x70\xc8\x71\x37\x9d\xde\x3c\x3e\x6a\x19\x4d\x86\x34\x1a\xa4\x89\x05\x1c\x3c\xb9\xbb\x39\x34\x12\x83\x1a\xa9\x52\x2e\x16\x35\xe6\x4a\x4a\xcc\x09\xda\x46\xc9\xce\x26\x20\x94\x31\xbd\x61\xf6\x10\x23\xdb\xf4\xca\xf3\x15\x4c\x7a\x77\x9d\xc2\x1c\xd2\x14\x66\xfd\x5e\x67\x19\x48\x5d\xd6\xf9\x6f\xcc\x7e\x54\xf9\x2d\xd2\x24\xd8\x18\x7b\xda\x03\x38\x07\xa1\x72\x66\xe9\x45\x95\xcd\x3d\xe7\x10\xc4\xac\xe1\xc1\xd4\x4f\xb3\x77\x80\xc2\xe0\x2f\x13\x7b\x16\x2d\x3f\xef\xf7\x92\x9e\x9f\xfb\xb0\xe9\x5d\xa7\x64\x8d\xc6\xb0\x12\xc7\x1a\xba\xdb\xd9\xa0\x8a\x35\x44\x6d\x4a\x48\xc1\xb9\xb8\x61\xda\xa0\x07\x89\x0a\x46\xac\xe3\xe2\xcc\xe1\xc0\xd2\x14\x64\x2b\xc4\x80\x7f\xa2\xd1\x1e\xe6\x0e\x6c\xf7\xe2\x00\x3c\xf2\x39\xfb\xab\x34\x05\x7b\x3d\xb6\x3e\x2a\xf6\x98\x36\x7c\xfc\x45\x7e\x1a\xd9\xdc\xba\xc7\x98\x0e\xe4\x1e\x50\xc3\xe2\x97\xc8\x61\x71\x4c\x0f\x8b\x27\x08\xba\xb9\xc9\xc7\xe8\xf9\x39\xcb\x88\x9c\x5b\x78\x82\x9a\x6c\xeb\x0c\xf5\xc7\xc8\xf9\xb9\x49\x47\xce\x99\xfa\x3b\x49\x23\xdc\x0b\xb8\x7c\x33\x7d\x82\x3a\x6a\xad\x9e\x24\x2e\x15\x6d\x27\xf7\x82\x6d\x6d\x81\x80\x33\x52\xcd\x3b\x37\xe6\x38\xbb\x70\x55\x6b\x01\x03\x85\x0b\x37\xc0\x5e\xc0\x99\x7b\xb3\xfb\xbc\x46\x87\xf5\x7a\x36\x9b\x5d\x40\xff\xbd\xe7\x3f\x98\x3d\xc5\xba\xc5\xdd\x13\xf2\x98\x36\xcf\x6d\xf1\xfc\x1c\x89\x3a\x1a\x83\x4c\xdd\xfb\x58\xaa\xcb\x5f\x29\xd6\x50\xa4\x0e\xe4\x82\xdf\xfd\x0e\x1e\xec\x1e\xc6\xb1\x3d\x08\x7d\xd9\x4f\x21\x08\x3a\xf2\x27\x2b\xa5\x61\x62\x37\x79\x3a\xbb\x01\x9e\x8c\xc9\x44\x02\x65\x49\xd5\x0d\xf0\xf3\xf3\x3d\xa5\x93\x9e\xcc\x79\x0a\x41\x42\x7a\x99\x50\xb1\x74\x63\x19\xdf\x02\xfd\x23\xc8\x58\x7e\x5b\xba\xbe\x62\x61\xf3\xf6\xe4\xcc\x1e\xf3\x31\xe1\xbf\xf3\x7f\x46\x6c\xcd\x88\x69\x7b\xde\xcf\xa6\x37\xb0\x47\xe9\x5a\xad\x5c\xd9\xb2\x01\xbe\xa3\x73\x13\x20\x18\xa6\xa6\xee\x2d\x53\xba\x40\x1d\x6a\x56\xf0\xd6\x2c\xe0\x55\x73\x77\xf3\x8f\x7e\xaa\xec\xe6\x54\x4e\xac\x46\xe3\xf2\x51\xee\xdd\x68\xe3\x1c\x82\x24\xb6\x40\x3d\xca\xa0\xc4\xf8\xcb\x1e\x3c\x32\x61\x83\xe1\xbb\x5b\xb7\x5e\xf3\xa2\x10\x68\x85\x70\x0c\xfd\x07\xd2\xa2\xd5\x2e\xb9\x4d\xfc\xfb\xe4\x58\x0e\x1b\x08\xd3\xa8\x95\xfc\x6e\x32\x0d\x3b\x98\xfe\xfd\x02\xce\x8c\xcd\xe1\x85\x39\x9b\x46\x55\x5b\x33\xc9\x7f\xc6\x89\x8d\x8e\xa9\x97\xdb\x4a\x1c\x93\x5e\x0e\xce\xdc\x8d\x0e\xe3\x30\x3f\x9e\x46\x15\xd5\x62\x12\x24\xe4\xbe\x1e\x5a\xe1\x06\x0f\x3a\x2a\x7e\xf9\x30\xe0\x76\x87\x79\x36\x17\xca\xe0\x51\x1d\x01\x83\xf4\xde\xc7\xf1\x64\xa8\x35\x17\x70\x35\x9b\xcd\xa6\x37\xb0\xdb\x7f\x64\x8d\x63\xf8\xc6\x10\xeb\x5b\xd9\x0d\x66\xc6\xd5\x00\xe8\x70\x5c\xc9\xf7\xa5\xfd\xed\xf7\xdf\x8d\xca\xfb\x40\x75\xe2\x84\x1b\x3e\x32\x3f\x56\x4b\x1f\xfd\xaa\x6d\x1b\x53\x7f\x43\x73\x6d\xe9\x50\x6c\x6d\x85\x89\x3e\x98\x00\x98\xd9\xca\x1c\x0a\x5c\xa1\x5e\x8e\xc8\x77\x15\x38\x89\xfd\xf7\xd6\x24\xf6\xff\xa5\xe4\xff\x02\x00\x00\xff\xff\x06\xe6\xbb\xe1\x63\x22\x00\x00") +var _faucetHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x3a\x7f\x73\xdb\xb6\x92\x7f\x3b\x9f\x62\xcb\x8b\x9f\xa4\xb3\x48\xca\x76\x92\xe7\x93\x48\x75\x72\x79\x7d\x7d\xb9\xb9\xeb\xeb\xb4\xe9\xdc\xbd\x69\x3b\x37\x20\xb1\x12\x11\x83\x00\x0b\x80\x92\x55\x8f\xbe\xfb\x0d\x00\x92\xa2\x7e\xd8\x71\x9a\xdc\x5d\xfc\x87\x4c\x00\x8b\xdd\xc5\xfe\xc6\x92\xc9\x57\x7f\xf9\xfb\x9b\x77\xff\xf8\xfe\x1b\x28\x4c\xc9\xe7\xcf\x12\xfb\x0f\x38\x11\xcb\x34\x40\x11\xcc\x9f\x9d\x25\x05\x12\x3a\x7f\x76\x76\x96\x94\x68\x08\xe4\x05\x51\x1a\x4d\x1a\xd4\x66\x11\xde\x04\xbb\x85\xc2\x98\x2a\xc4\xdf\x6a\xb6\x4a\x83\xff\x0a\x7f\x7a\x1d\xbe\x91\x65\x45\x0c\xcb\x38\x06\x90\x4b\x61\x50\x98\x34\x78\xfb\x4d\x8a\x74\x89\xbd\x7d\x82\x94\x98\x06\x2b\x86\xeb\x4a\x2a\xd3\x03\x5d\x33\x6a\x8a\x94\xe2\x8a\xe5\x18\xba\xc1\x18\x98\x60\x86\x11\x1e\xea\x9c\x70\x4c\x2f\x83\xf9\x33\x8b\xc7\x30\xc3\x71\x7e\x7f\x1f\x7d\x87\x66\x2d\xd5\xed\x76\x3b\x85\xd7\xb5\x29\x50\x18\x96\x13\x83\x14\xfe\x4a\xea\x1c\x4d\x12\x7b\x48\xb7\x89\x33\x71\x0b\x85\xc2\x45\x1a\x58\xd6\xf5\x34\x8e\x73\x2a\xde\xeb\x28\xe7\xb2\xa6\x0b\x4e\x14\x46\xb9\x2c\x63\xf2\x9e\xdc\xc5\x9c\x65\x3a\x36\x6b\x66\x0c\xaa\x30\x93\xd2\x68\xa3\x48\x15\x5f\x47\xd7\xd1\x9f\xe3\x5c\xeb\xb8\x9b\x8b\x4a\x26\xa2\x5c\xeb\x00\x14\xf2\x34\xd0\x66\xc3\x51\x17\x88\x26\x80\x78\xfe\xc7\xe8\x2e\xa4\x30\x21\x59\xa3\x96\x25\xc6\x2f\xa2\x3f\x47\x13\x47\xb2\x3f\xfd\x38\x55\x4b\x56\xe7\x8a\x55\x06\xb4\xca\x9f\x4c\xf7\xfd\x6f\x35\xaa\x4d\x7c\x1d\x5d\x46\x97\xcd\xc0\xd1\x79\xaf\x83\x79\x12\x7b\x84\xf3\x4f\xc2\x1d\x0a\x69\x36\xf1\x55\xf4\x22\xba\x8c\x2b\x92\xdf\x92\x25\xd2\x96\x92\x5d\x8a\xda\xc9\xcf\x46\xf7\x21\x1d\xbe\x3f\x54\xe1\xe7\x20\x56\xca\x12\x85\x89\xde\xeb\xf8\x2a\xba\xbc\x89\x26\xed\xc4\x31\x7e\x47\xc0\x2a\xcd\x92\x3a\x8b\x56\xa8\xac\xe5\xf2\x30\x47\x61\x50\xc1\xbd\x9d\x3d\x2b\x99\x08\x0b\x64\xcb\xc2\x4c\xe1\x72\x32\x39\x9f\x9d\x9a\x5d\x15\x7e\x9a\x32\x5d\x71\xb2\x99\xc2\x82\xe3\x9d\x9f\x22\x9c\x2d\x45\xc8\x0c\x96\x7a\x0a\x1e\xb3\x5b\xd8\x3a\x9a\x95\x92\x4b\x85\x5a\x37\xc4\x2a\xa9\x99\x61\x52\x4c\xad\x45\x11\xc3\x56\x78\x0a\x56\x57\x44\x1c\x6d\x20\x99\x96\xbc\x36\x78\xc0\x48\xc6\x65\x7e\xeb\xe7\x9c\x37\xf7\x0f\x91\x4b\x2e\xd5\x14\xd6\x05\x6b\xb6\x81\x23\x04\x95\xc2\x06\x3d\x54\x84\x52\x26\x96\x53\x78\x55\x35\xe7\x81\x92\xa8\x25\x13\x53\x98\xec\xb6\x24\x71\x2b\xc6\x24\xf6\x81\xeb\xd9\x59\x92\x49\xba\x71\x3a\xa4\x6c\x05\x39\x27\x5a\xa7\xc1\x81\x88\x5d\x40\xda\x03\xb0\x71\x88\x30\xd1\x2e\xed\xad\x29\xb9\x0e\xc0\x11\x4a\x03\xcf\x44\x98\x49\x63\x64\x39\x85\x4b\xcb\x5e\xb3\xe5\x00\x1f\x0f\xf9\x32\xbc\xbc\x6a\x17\xcf\x92\xe2\xb2\x45\x62\xf0\xce\x84\x4e\x3f\x9d\x66\x82\x79\xc2\xda\xbd\x0b\x02\x0b\x12\x66\xc4\x14\x01\x10\xc5\x48\x58\x30\x4a\x51\xa4\x81\x51\x35\x5a\x3b\x62\x73\xe8\x87\xbf\x07\xa2\x5f\x71\xd9\xf2\x15\x53\xb6\x6a\x8e\xd5\x7b\x3c\x38\xe1\xc3\x87\xb8\x81\xe6\x41\x2e\x16\x1a\x4d\xd8\x3b\x53\x0f\x98\x89\xaa\x36\xe1\x52\xc9\xba\xea\xd6\xcf\x12\x37\x0b\x8c\xa6\x41\xad\x78\xd0\x84\x7f\xf7\x68\x36\x55\x23\x8a\xa0\x3b\xb8\x54\x65\x68\x35\xa1\x24\x0f\xa0\xe2\x24\xc7\x42\x72\x8a\x2a\x0d\x7e\x94\x39\x23\x1c\x84\x3f\x33\xfc\xf4\xc3\xbf\x43\xa3\x32\x26\x96\xb0\x91\xb5\x82\x6f\x4c\x81\x0a\xeb\x12\x08\xa5\xd6\x5c\xa3\x28\xea\x31\xe2\x6c\xf7\x98\xd5\x30\x33\x62\x07\x75\x96\x64\xb5\x31\xb2\x03\xcc\x8c\x80\xcc\x88\x90\xe2\x82\xd4\xdc\x00\x55\xb2\xa2\x72\x2d\x42\x23\x97\x4b\x9b\xe9\xfc\x21\xfc\xa6\x00\x28\x31\xa4\x59\x4a\x83\x16\xb6\xd5\x21\xd1\x95\xac\xea\xaa\xd1\xa2\x9f\xc4\xbb\x8a\x08\x8a\xd4\xea\x9c\x6b\x0c\xe6\xdf\xb2\x15\x42\x89\xfe\x2c\x67\x87\x26\x91\x13\x85\x26\xec\x23\x3d\x32\x8c\x24\xf6\xcc\xf8\x23\x41\xf3\x97\xd4\xbc\xc5\xd4\x1d\xa1\x44\x51\xc3\xde\x28\x54\x36\xae\x04\xf3\xfb\x7b\x45\xc4\x12\xe1\x39\xa3\x77\x63\x78\x4e\x4a\x59\x0b\x03\xd3\x14\xa2\xd7\xee\x51\x6f\xb7\x7b\xd8\x01\x12\xce\xe6\x09\x79\xcc\xbc\x41\x8a\x9c\xb3\xfc\x36\x0d\x0c\x43\x95\xde\xdf\x5b\xe4\xdb\xed\x0c\xee\xef\xd9\x02\x9e\x47\x3f\x60\x4e\x2a\x93\x17\x64\xbb\x5d\xaa\xf6\x39\xc2\x3b\xcc\x6b\x83\xc3\xd1\xfd\x3d\x72\x8d\xdb\xad\xae\xb3\x92\x99\x61\xbb\xdd\xce\x0b\xba\xdd\x5a\x9e\x1b\x3e\xb7\x5b\x88\x2d\x52\x41\xf1\x0e\x9e\x47\xdf\xa3\x62\x92\x6a\xf0\xf0\x49\x4c\xe6\x49\xcc\xd9\xbc\xd9\xb7\x2f\xa4\xb8\xe6\x3b\x7b\x89\xad\xc1\x74\x76\xee\xdc\xc6\xb1\xda\xe7\xf4\x84\x17\x2c\xc3\x8e\xfb\xc6\x1e\x34\x33\x78\x8b\x9b\x34\xb8\xbf\xef\xef\x6d\x56\x73\xc2\x79\x46\xac\x5c\xfc\xd1\xba\x4d\xbf\xa3\xb5\xd3\x15\xd3\xae\xa4\x9a\xb7\x1c\xec\xd8\x7e\xa2\x5b\x1f\x04\x2e\x23\xab\x29\x5c\x5f\xf5\xa2\xd6\x29\x8f\x7f\x75\xe0\xf1\xd7\x27\x81\x2b\x22\x90\x83\xfb\x0d\x75\x49\x78\xfb\xdc\x78\x4b\xcf\xf9\x0e\x37\x85\x36\x46\x77\xac\x75\xb1\x7e\x32\x03\xb9\x42\xb5\xe0\x72\x3d\x05\x52\x1b\x39\x83\x92\xdc\x75\xf9\xee\x7a\x32\xe9\xf3\x6d\x4b\x41\x92\x71\x74\xd1\x45\xe1\x6f\x35\x6a\xa3\xbb\x58\xe2\x97\xdc\xaf\x0d\x29\x14\x85\x46\x7a\x20\x0d\x4b\xd1\x8a\xd6\x41\xf5\x54\xdf\x09\xf3\x24\xef\x0b\x29\xbb\x14\xd2\x67\xa3\x41\xdd\xcb\x76\xc1\x3c\x31\x6a\x07\x77\x96\x18\xfa\x51\x29\x40\xd9\x12\xef\xa1\x0c\xe0\x23\x9a\x3d\x7b\x85\xa8\x7c\x7d\x61\x4d\x16\xdc\x30\x89\x0d\xfd\x04\xca\xd6\x08\x33\xa2\xf1\x29\xe4\x5d\xa6\xdf\x91\x77\xc3\x4f\xa5\x5f\x20\x51\x26\x43\x62\x9e\xc2\xc0\xa2\x16\xb4\x77\x7e\x17\x3b\x3f\x95\x81\x5a\xb0\x15\x2a\xcd\xcc\xe6\xa9\x1c\x20\xdd\xb1\xe0\xc7\xfb\x2c\x24\xb1\x51\x8f\xdb\x5a\x7f\xf0\x99\x9c\xfb\x43\x25\xc9\xf5\xfc\x6f\x72\x0d\x54\xa2\x06\x53\x30\x0d\x36\xb9\x7e\x9d\xc4\xc5\x75\x07\x52\xcd\xdf\xd9\x05\x27\x54\x58\xb8\xd2\x02\x98\x06\x55\x0b\x97\x79\xa5\x00\x53\xe0\x7e\x39\xd2\x24\xe9\x08\xde\x49\x5b\xd2\xad\x50\x18\x28\x09\x67\x39\x93\xb5\x06\x92\x1b\xa9\x34\x2c\x94\x2c\x01\xef\x0a\x52\x6b\x63\x11\xd9\xf0\x41\x56\x84\x71\xe7\x4b\x4e\xa5\x20\x15\x90\x3c\xaf\xcb\xda\x96\xa4\x62\x09\x28\x64\xbd\x2c\x1a\x5e\x8c\x04\x9f\x98\xb8\x14\xcb\x8e\x1f\x5d\x91\x12\x88\x31\x24\xbf\xd5\x63\x68\xa3\x02\x10\x85\x60\x18\x52\xbb\x2b\x47\x65\xeb\x06\xc8\x65\x59\x4a\x01\xd7\x8a\x42\x45\x94\xd9\x58\x5a\x2e\xbd\x45\xf0\x5a\x6c\xa4\x40\x28\xc8\xca\xb1\x06\xdf\x32\xf3\xb7\x3a\x1b\xc3\x3b\x7f\x9f\x18\xc3\xb7\x52\x2e\x39\x5e\x58\x0e\xff\x4a\x72\xcc\xa4\xbc\x6d\xb7\x43\x49\x36\x2d\xe1\xe6\x1c\x6b\x66\x0a\xe6\x05\x55\xa1\x2a\x2d\x0e\x0a\x9c\x95\xcc\xe8\x28\x89\xab\x5d\x6c\xdd\x65\x69\x1e\x16\x52\xb1\xdf\x6d\x89\xc3\x3b\x7d\x01\x24\xd4\x1c\xc4\x99\x36\x4c\x3a\x03\xe0\xb8\x30\x53\x78\xe1\xc3\xe4\xa1\x49\x2f\x99\x29\xea\x2c\x24\xfc\xa4\x53\xb5\x68\xdd\x3d\xd3\xa6\x9f\x29\x5c\xfb\xe2\xd6\x97\x15\xd4\xf4\x42\x22\x3d\x30\x3c\x4f\xf7\xe6\xa6\xba\xeb\x58\xe9\x2a\xe4\x49\x87\xc4\xda\xc3\xbe\x60\x56\x6c\x27\xdb\x5c\x21\x31\x08\x04\x12\x72\x70\x61\x5e\x32\x6d\x22\xcf\xbd\xbb\x72\x05\x60\x88\x5a\xa2\x49\x83\xff\x26\x99\xac\xcd\x34\xe3\x44\xdc\x06\x73\x0b\x67\x33\xbc\x93\xf7\xe9\x9a\x10\xb0\xcc\x90\x52\xa4\xc0\x84\x91\x4e\x23\x4d\x07\x02\x86\x76\xb0\x60\x1c\x5d\x91\xea\x7c\x42\x0c\xac\x36\xad\xc6\x47\x51\x92\xa9\x78\xfe\x46\x56\x9b\xb0\x22\xda\xa0\xdb\x6a\x09\x6a\x57\x8b\x76\xd8\x48\x26\x57\x08\xbe\xea\xcd\xe4\x1d\x10\x41\x61\xc1\x14\x02\x59\x93\xcd\x57\x49\x4c\xdd\x1d\xa5\x95\xe3\x1f\x57\x66\x73\xb3\xfd\xa2\x34\xd9\x79\x47\x49\x6e\x4f\x2a\xb2\x61\xda\x29\x91\x39\xa9\xc7\x66\x8d\x68\xbe\xb6\x21\x39\xfd\xc1\x23\x64\x62\x79\x7e\x35\xf1\x91\xc6\x3e\x58\xf4\xe7\x57\x13\x2b\xe1\xf3\xab\xc9\xe4\x6e\xf2\xc4\xbf\xf3\xab\x89\x14\xe7\x57\x13\x53\xe0\xf9\xd5\xe4\xfc\xea\xba\x1f\xa3\xfc\x4c\x6b\x1d\x16\x0a\xb5\xa5\xd6\x86\xae\x87\x4c\xcc\xb1\xfb\x21\x1b\x73\x06\x72\x6c\x61\x1a\x86\xba\x56\x4a\xd6\xc2\x56\x3b\x60\xcf\xfc\x24\x2b\x3b\x12\xa3\xae\xab\x4a\x2a\x13\xf5\xc5\x49\xec\xfd\x96\xa3\x8e\x6f\x26\x2f\x6f\x5e\x3d\xca\xbe\xb3\x58\x77\x86\xff\x73\xab\x5d\xba\xb0\x19\x56\xbc\xd6\xb6\xb4\x64\xf6\x4e\xf7\x45\x99\xb0\x8f\xeb\xf0\x3d\xaf\xf5\x18\xaa\x3a\xe3\x4c\x17\x40\x40\xe0\x1a\x12\x6d\x94\x14\xcb\xb9\x9b\xcd\x93\xb8\x19\x42\x25\xb5\xf9\x83\x11\xe7\x0f\x99\x83\xa5\xf7\xff\x14\x74\x16\x4d\xaa\xfb\xa2\x54\xd6\xe6\xdf\x2f\x55\x5f\x47\xee\xbb\x5e\xaf\xa3\x56\x92\xce\x77\x0b\xe4\x55\x6c\xab\x91\x5a\x30\xb3\x89\x7d\x14\x94\x22\xfe\x9a\xd1\xf4\xea\xe6\xea\xd5\xab\xab\x17\xff\x72\xf3\xf2\xe5\xd5\xcd\x8b\x97\x0f\x39\x76\x67\x14\x1f\xef\xd7\x5d\xed\xc9\x7b\x35\xdf\x3f\x64\x0d\x39\x11\x60\x14\xc9\x6f\xbd\x10\x6a\xa5\xac\x10\x2a\xf4\xe7\xef\x4a\xab\x0c\xb9\x5c\x3b\x10\x4f\x67\xc1\x90\xbb\x3a\x4b\x23\x42\x21\xd7\x50\xd6\xb9\x93\xb5\x2d\xa7\xd0\x2e\xac\x09\x33\x50\x0b\xc3\xb8\x57\x81\xa9\x95\xab\xc6\x70\xaf\x1a\x3a\xba\x6d\x27\x58\xce\xdf\xd9\x1c\x7d\x54\x84\x76\xf7\x64\x50\xf8\xc6\x83\x43\xa5\xa4\xc1\xdc\xca\x11\xc8\x92\x30\xa1\xad\x04\x5c\xbd\x85\xe5\x13\xee\xd1\xdd\x53\xf3\xb0\xeb\x09\xbb\xe5\x38\x86\x6f\xb9\xcc\x08\x87\x95\x75\x85\x8c\xdb\x02\x5a\x42\x21\xed\xd1\x7b\xd2\xd2\x86\x98\x5a\x83\x5c\xb8\x59\xcf\xb9\xdd\xbf\x22\xca\x56\xa9\x58\x56\x06\xd2\xa6\xa3\x69\xe7\x34\xaa\x55\xd3\xa7\xb5\x43\xc3\x50\xed\xad\x77\x52\x4f\xe1\xe7\x5f\x67\xcf\x1a\x56\xfe\x82\x0b\x26\x6c\xc6\x5d\xd4\xc2\x1f\xd9\x14\xc4\x34\x15\x95\x86\x9c\x4b\x5d\x2b\xcf\x21\x55\xb2\x02\xcb\x65\x8b\xa9\xc5\x6c\x17\x2a\x47\xad\x45\x32\x2c\x88\x2e\x46\x4d\x43\x56\xa1\xd3\x52\xb7\xd6\xce\x9f\x2d\xa4\x82\xa1\x45\xc0\xd2\xc9\x0c\x58\xd2\xe2\x8d\x38\x8a\xa5\x29\x66\xc0\x2e\x2e\x3a\xe0\x33\xb6\x80\x61\x0b\xf1\x33\xfb\x35\x32\x77\x91\xa5\x02\x69\x0a\x7d\x6a\x8e\x60\x83\x47\x57\x9c\xe5\x38\x64\x63\xb8\x1c\xcd\xda\xd5\x4c\x21\xb9\x6d\x47\x8d\x1e\xfd\x3f\xf7\xbb\x9d\xed\x4b\xc6\x09\x7f\x4f\x36\xbe\xdb\xa2\x81\xb8\x22\x0e\x6a\xc5\xa1\xf1\x19\xaf\x82\x4e\x21\x0e\xae\x2f\x95\x23\xbb\x6c\x1e\x1a\x9b\x6a\x8f\xe0\xd1\x44\x1a\x05\x1d\xfe\xdb\x8f\x7f\xff\x2e\xd2\x46\x31\xb1\x64\x8b\xcd\xf0\xbe\x56\x7c\x0a\xcf\x87\xc1\x3f\xd5\x8a\x07\xa3\x9f\x27\xbf\x46\x2b\xc2\x6b\x1c\x3b\x7d\x4f\xdd\xef\x11\x95\x31\x34\x8f\x53\xd8\x27\xb8\x1d\x8d\x66\xa7\x3b\x53\xbd\x46\x9a\x42\x8d\x66\x68\x01\x3b\xc3\x3f\x94\x11\x81\x12\x4d\x21\x9d\xeb\x2a\xcc\xa5\x10\x98\x1b\xa8\x2b\x29\x1a\x91\x00\x97\x5a\xef\x0c\xb1\x85\x48\x8f\x8d\xc2\x6a\xb9\xb5\xee\x73\xb8\xb2\xda\x9d\x74\xaa\x6d\x90\xa5\x2e\x48\xff\x27\x66\x3f\xca\xfc\x16\xcd\x30\x58\x6b\x1b\x1c\x03\xb8\x00\x2e\x73\x62\xf1\x45\x85\x0d\xd5\x17\x10\xc4\xa4\x62\x41\xa3\xfc\x2d\x20\xd7\xf8\x61\x64\x4f\xc2\xe5\x5f\x94\x78\x4e\x2f\x2e\xbc\x3f\xb5\x9a\x93\xa2\x44\xad\xc9\x12\xfb\x27\x74\x97\xd9\xee\x28\x56\x10\xa5\x5e\x42\x0a\x4e\xc3\x15\x51\x1a\x3d\x48\x44\x89\x21\xad\xb9\x5a\x71\x38\xb0\x34\x05\x51\x73\xbe\xb3\x72\xef\x55\xb3\xd6\x7e\xf7\xc0\x23\x9f\xe2\xbe\x4a\x53\xa8\x05\x75\x3a\xa2\xbb\x9d\xd6\x7a\x7c\xdf\x63\x14\xd9\x54\xb4\xdb\x31\x9a\xf5\xdd\x61\x0f\x1b\xd2\x0f\xa1\x43\x7a\x88\x0f\xe9\x03\x08\x5d\x9b\xe9\x31\x7c\xbe\x2d\xd5\x43\xe7\x26\x1e\xc0\x26\xea\x32\x43\xf5\x18\x3a\xdf\x66\x6a\xd0\x39\x51\xbf\x15\xa6\xb7\x77\x0c\x97\xaf\x46\x0f\x60\x47\xa5\xe4\x83\xc8\x85\x34\x9b\xe1\x3d\x27\x1b\x9b\x4f\x61\x60\x64\xf5\xc6\x75\x85\x06\x63\x97\xe4\xa7\xd0\x61\x18\xbb\x7e\xff\x14\x06\x6e\x64\xd7\x59\x89\x6e\xd7\xcb\xc9\x64\x32\x86\xf6\x45\xd9\xbf\x12\xeb\xc5\xaa\xc6\xed\x03\xfc\xe8\x3a\xcf\x6d\xad\xf1\x29\x1c\x35\x38\x3a\x9e\x9a\xf1\x27\x70\xd5\x25\x97\x3d\xb6\xe0\x4f\x7f\x82\xa3\xd5\x7d\x33\x8e\x63\xf8\x0f\xa2\x6e\x5d\x0f\xa7\x52\xb8\x72\x7d\x9e\x0e\xbe\x64\x5a\xbb\x36\x8a\x06\x2a\x05\x36\x7b\x3e\x2e\x6f\x1c\xf1\xd8\x80\xc1\x1c\x26\x87\x0c\xda\x78\xda\xcb\x2b\x27\xd2\x4d\x0f\xef\x7e\x26\x69\x25\x72\x22\x51\xb1\x12\xe1\xab\x14\x82\xa0\xbf\xf9\x08\xc2\x02\x74\xc8\xce\x34\x9a\x77\x5e\x17\xc3\x26\xbd\x9e\x4a\x7e\xa3\x31\x5c\x4f\x26\x93\xd1\x11\x13\xdb\x9d\x78\x5f\x57\xb6\xee\x02\x22\x36\x2e\xd2\x75\xb2\x75\x95\x9e\xad\xa1\x6c\x9c\xe3\x90\x4b\xce\x7d\xd1\xd3\x6c\xb5\x02\x6e\xfa\x5c\x29\x84\x97\xb3\x13\x69\xb8\x27\xc9\xde\xd1\x0e\xd5\x73\x42\xf6\x87\x2a\xda\x97\xd9\x01\x70\x78\xb9\xa7\x94\x3d\x7d\x9d\x56\xcc\x59\xc7\x37\xdb\x49\xf4\x40\x5d\x3b\x7d\x1d\xca\xac\xc7\xbf\xc7\x73\x71\xf9\xc4\x63\x74\xcb\x55\xad\x8b\xe1\x01\xa3\xa3\xd9\xb1\x6e\xde\x1a\x54\xc4\xa0\x7b\x75\xe1\x74\x81\xc2\xd8\x1a\xfb\x50\x25\xae\xfa\x56\x18\x2a\x14\x14\x55\x5b\x93\xf8\xcb\x84\xad\x20\xf7\x54\xe6\x6f\x1c\x7d\x73\xfa\x48\x87\x71\x35\x9d\x14\x08\x00\x70\xe0\x04\xce\x50\xf7\x2c\xd5\x02\x23\x27\x95\x46\x0a\x29\xf8\xef\x16\x86\xa3\xa8\x16\xec\x6e\x38\x0a\x9b\xf1\x21\x8e\x76\x7d\xd6\xdd\x2d\x5b\xb6\x2f\x52\x08\x12\xa3\x80\xd1\x74\x60\x93\xf0\xa9\x8a\xef\x02\x82\xc1\x7c\xc7\x41\x7f\x2b\x40\x62\xe8\xdc\xb5\xae\xfd\x35\xf1\x97\x20\x23\xf9\xed\xd2\xdd\xbd\xa6\xb6\x56\x1b\x1e\xa1\x25\x2b\x62\x88\x72\x58\x47\x33\xd8\x81\x37\x57\xd1\xdc\x2a\x67\x06\xfe\xc6\xeb\x3a\xe4\xd0\xbd\x55\x72\xa3\x4c\x2a\x8a\x2a\x54\x84\xb2\x5a\x4f\xe1\x45\x75\x37\xfb\xa5\x7d\xeb\xe6\xfa\xf8\x8f\xb2\x5a\x29\x9c\x1f\x71\xd4\xb4\x83\x2f\x20\x48\x62\x0b\xf0\x21\x34\xdd\x61\xfb\xdf\x4b\xc0\x89\xb7\x15\xd0\x7d\xcd\xd0\xcc\x97\x8c\x52\x8e\x96\xe1\x1d\x7a\xeb\x8c\x56\xff\x7d\x97\xda\x27\x09\xcd\x6b\x8a\xdd\x9e\xfd\xda\xea\xc4\x86\xee\x8d\xc7\xc0\x1a\x40\x68\x8f\xcc\x9c\xcc\x9b\x3e\x81\x9b\x56\x03\x27\x8b\xe6\xeb\x17\x5a\x2b\x57\x80\x0d\xc3\xc6\xc0\xc6\x30\xd0\xb6\x78\xa4\x7a\x30\x8a\x8a\xba\x24\x82\xfd\x8e\x43\x9b\x97\x46\x5e\x56\xee\x15\x4a\x70\x1c\x92\x8f\x98\xd9\xbd\xdb\x18\xb4\x39\x6e\xd0\x08\x71\xd0\x6a\xf7\xc5\xae\xa5\x30\x85\xc9\x6c\xf0\x91\x12\x3a\x4d\x25\xcc\x88\x82\xfe\x20\x6c\x93\x2f\x28\x69\xa9\xb7\x6b\x19\x51\x03\xdf\x2b\x71\x05\xbe\x90\xeb\x74\x70\x3d\xe9\x98\xf4\x8a\x76\x7a\x1e\x34\xb6\x76\xa4\x0c\xcb\x65\xeb\x9a\x73\xb8\x9e\x7c\x0e\x6e\x29\x11\x4b\x3c\x3c\x81\x51\xac\x42\x0a\x24\x37\x6c\x85\xff\x0b\x07\xf9\x0c\x42\xfe\x68\x16\xad\x1d\xb6\xc2\x73\x66\xba\xc7\xaf\x5d\xed\x64\xfb\xcf\xd6\xdf\x20\x76\x12\xbe\x80\xe0\xe4\x41\x1e\xb4\xc4\x03\xc0\x03\xd7\x7e\xd8\xef\xdd\x3b\xc1\xe0\x30\xa7\xd8\x6a\xb7\x7b\x9f\x3d\x8a\x0a\x53\xf2\x61\x90\x18\xf7\x5d\x93\xe5\xb9\xc3\xe0\x10\xf8\xe9\xfd\x92\x6e\xbb\x7f\x91\xc9\xb9\xd4\x78\x70\x51\x83\x5e\x71\xd2\x5d\xe6\xda\x4a\x04\xb6\xbb\xcf\xbf\xe2\x18\x7e\x34\x44\x19\x20\xf0\xd3\x5b\xa8\x2b\x4a\x8c\x7f\xfb\x66\xf3\xa3\xef\x48\xb6\xdf\x87\x65\x44\x69\x58\x48\xb5\x26\x8a\x36\x0d\x1e\x53\xe0\xc6\xbd\x7d\x6b\x4b\x3f\x8d\xe6\xad\x8d\x62\x2b\xc2\x87\x47\x17\xc7\xe7\xc3\x41\xd4\x57\xf9\x60\x14\x21\xc9\x8b\x63\x40\x97\xb1\x3a\xba\x29\x7c\xe7\xae\x00\xc3\xe7\x43\x53\x30\x3d\x8a\x88\x31\x6a\x38\xd8\x33\x86\xc1\xc8\xea\xf5\xb2\x77\x25\xeb\xb6\x27\x7b\x6e\xf5\x18\x8e\x5d\x31\xdd\x15\x02\x2d\x78\xae\xf5\xd0\xdb\xd5\x60\xdc\xc3\xbd\x6f\x56\x83\xf3\x41\xa7\xa8\x9d\x7b\xef\xce\x91\x9e\xe4\x64\x0f\xf5\xc0\x7a\xd9\xe0\x88\x3c\xa1\xf4\x8d\xf5\x9f\x61\x70\xc2\xd3\x0f\xad\x63\xd4\x09\xdb\xc7\xeb\x47\xa5\xec\xbf\xa4\x79\x40\xc4\x8c\x0e\x46\x91\xae\x33\xdf\xdc\x18\xbe\xec\x2e\x60\x2d\x98\x33\xde\xc3\x54\x70\x54\x50\x58\x12\xfb\x45\x45\x78\x50\x84\x3c\x92\x35\xda\xcb\xbc\x3b\xd5\x76\x6c\x05\x3e\x19\x75\xbd\xb1\x6f\xb4\x2d\xae\x7c\x5b\x78\x8d\x99\x76\x0d\x02\x68\xec\xdd\xb5\x83\x7c\xdb\xe7\xf5\xf7\x6f\x7b\xad\x9f\xce\x23\x86\x0e\x7b\xf7\xe9\xe6\xa9\x46\xcb\xc9\x6f\x45\xd7\xeb\x75\xe4\xdf\x76\xb8\x16\x6f\xd7\x89\x89\x49\xc5\xa2\xf7\x3a\x00\xa2\x37\x22\x07\x8a\x0b\x54\xf3\x1e\xfa\xa6\x3d\x93\xc4\xfe\x2b\xc6\x24\xf6\x1f\x6a\xff\x4f\x00\x00\x00\xff\xff\xf1\xa6\xb6\xb8\xb9\x2d\x00\x00") func faucetHtmlBytes() ([]byte, error) { return bindataRead(